filemd5: add support code for md5 handling for signatures.

remotes/origin/HEAD
Victor Julien 13 years ago
parent 8cd460dde5
commit c9e93ec52c

@ -112,6 +112,11 @@ int HTPFileOpen(HtpState *s, uint8_t *filename, uint16_t filename_len,
flags |= FILE_NOMAGIC;
}
if (s->f->flags & FLOW_FILE_NO_MD5_TC) {
SCLogDebug("no md5 for this flow in toclient direction, so none for this file");
flags |= FILE_NOMD5;
}
if (!(flags & FILE_STORE) && s->f->flags & FLOW_FILE_NO_STORE_TC) {
flags |= FILE_NOSTORE;
}
@ -136,6 +141,11 @@ int HTPFileOpen(HtpState *s, uint8_t *filename, uint16_t filename_len,
flags |= FILE_NOMAGIC;
}
if (s->f->flags & FLOW_FILE_NO_MD5_TS) {
SCLogDebug("no md5 for this flow in toserver direction, so none for this file");
flags |= FILE_NOMD5;
}
if (!(flags & FILE_STORE) && s->f->flags & FLOW_FILE_NO_STORE_TS) {
flags |= FILE_NOSTORE;
}

@ -120,7 +120,7 @@ static int DetectFileInspect(ThreadVars *tv, DetectEngineThreadCtx *det_ctx,
break;
}
if (s->file_flags & FILE_SIG_NEED_FILEMD5 && (!(file->flags & FILE_MD5))) {
if (s->file_flags & FILE_SIG_NEED_MD5 && (!(file->flags & FILE_MD5))) {
SCLogDebug("sig needs file md5, but we don't have any");
r = 0;
break;

@ -1573,10 +1573,10 @@ int SigGroupHeadBuildMatchArray(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
}
/**
* \brief Set the filestore_cnt in the sgh.
* \brief Set the need md5 flag in the sgh.
*
* \param de_ctx detection engine ctx for the signatures
* \param sgh sig group head to set the counter in
* \param sgh sig group head to set the flag in
*/
void SigGroupHeadSetFilemagicFlag(DetectEngineCtx *de_ctx, SigGroupHead *sgh) {
Signature *s = NULL;
@ -1599,6 +1599,34 @@ void SigGroupHeadSetFilemagicFlag(DetectEngineCtx *de_ctx, SigGroupHead *sgh) {
return;
}
/**
* \brief Set the need magic flag in the sgh.
*
* \param de_ctx detection engine ctx for the signatures
* \param sgh sig group head to set the flag in
*/
void SigGroupHeadSetFileMd5Flag(DetectEngineCtx *de_ctx, SigGroupHead *sgh) {
Signature *s = NULL;
uint32_t sig = 0;
if (sgh == NULL)
return;
for (sig = 0; sig < sgh->sig_cnt; sig++) {
s = sgh->match_array[sig];
if (s == NULL)
continue;
if (SignatureIsFileMd5Inspecting(s)) {
sgh->flags |= SIG_GROUP_HEAD_HAVEFILEMD5;
SCLogDebug("sgh %p has filemd5", sgh);
break;
}
}
return;
}
/**
* \brief Set the filestore_cnt in the sgh.
*

@ -88,5 +88,6 @@ void SigGroupHeadStore(DetectEngineCtx *, SigGroupHead *);
int SigGroupHeadBuildHeadArray(DetectEngineCtx *, SigGroupHead *);
void SigGroupHeadSetFilemagicFlag(DetectEngineCtx *, SigGroupHead *);
void SigGroupHeadSetFilestoreCount(DetectEngineCtx *, SigGroupHead *);
void SigGroupHeadSetFileMd5Flag(DetectEngineCtx *, SigGroupHead *);
#endif /* __DETECT_ENGINE_SIGGROUP_H__ */

@ -325,7 +325,7 @@ static int DetectFileMd5Setup (DetectEngineCtx *de_ctx, Signature *s, char *str)
/** \todo remove this once we support more than http */
s->alproto = ALPROTO_HTTP;
s->file_flags |= (FILE_SIG_NEED_FILE|FILE_SIG_NEED_FILEMD5);
s->file_flags |= (FILE_SIG_NEED_FILE|FILE_SIG_NEED_MD5);
return 0;
error:

@ -1877,6 +1877,14 @@ end:
SCLogDebug("disabling magic for flow");
FileDisableMagic(p->flow, STREAM_TOSERVER);
}
/* see if this sgh requires us to consider file md5 */
if (!FileForceMd5() && (p->flow->sgh_toserver == NULL ||
!(p->flow->sgh_toserver->flags & SIG_GROUP_HEAD_HAVEFILEMD5)))
{
SCLogDebug("disabling md5 for flow");
FileDisableMd5(p->flow, STREAM_TOSERVER);
}
} else if (p->flowflags & FLOW_PKT_TOCLIENT && !(p->flow->flags & FLOW_SGH_TOCLIENT)) {
p->flow->sgh_toclient = det_ctx->sgh;
p->flow->flags |= FLOW_SGH_TOCLIENT;
@ -1892,6 +1900,14 @@ end:
SCLogDebug("disabling magic for flow");
FileDisableMagic(p->flow, STREAM_TOCLIENT);
}
/* check if this flow needs md5, if not disable it */
if (!FileForceMd5() && (p->flow->sgh_toclient == NULL ||
!(p->flow->sgh_toclient->flags & SIG_GROUP_HEAD_HAVEFILEMD5)))
{
SCLogDebug("disabling md5 for flow");
FileDisableMd5(p->flow, STREAM_TOCLIENT);
}
}
}
@ -2049,6 +2065,24 @@ int SignatureIsFilemagicInspecting(Signature *s) {
return 0;
}
/**
* \brief Check if a signature contains the filemd5 keyword.
*
* \param s signature
*
* \retval 0 no
* \retval 1 yes
*/
int SignatureIsFileMd5Inspecting(Signature *s) {
if (s == NULL)
return 0;
if (s->file_flags & FILE_SIG_NEED_MD5)
return 1;
return 0;
}
/** \brief Test is a initialized signature is IP only
* \param de_ctx detection engine ctx
* \param s the signature
@ -4008,6 +4042,7 @@ int SigAddressPrepareStage4(DetectEngineCtx *de_ctx) {
SigGroupHeadBuildHeadArray(de_ctx, sgh);
SigGroupHeadSetFilemagicFlag(de_ctx, sgh);
SigGroupHeadSetFileMd5Flag(de_ctx, sgh);
SigGroupHeadSetFilestoreCount(de_ctx, sgh);
SCLogDebug("filestore count %u", sgh->filestore_cnt);
}

@ -291,7 +291,7 @@ typedef struct DetectPort_ {
#define FILE_SIG_NEED_TYPE 0x04
#define FILE_SIG_NEED_MAGIC 0x08 /**< need the start of the file */
#define FILE_SIG_NEED_FILECONTENT 0x10
#define FILE_SIG_NEED_FILEMD5 0x20
#define FILE_SIG_NEED_MD5 0x20
/* Detection Engine flags */
#define DE_QUIET 0x01 /**< DE is quiet (esp for unittests) */
@ -829,6 +829,7 @@ typedef struct SigTableElmt_ {
#define SIG_GROUP_HEAD_MPM_HSMD (1 << 16)
#define SIG_GROUP_HEAD_MPM_HSCD (1 << 17)
#define SIG_GROUP_HEAD_MPM_HUAD (1 << 18)
#define SIG_GROUP_HEAD_HAVEFILEMD5 (1 << 19)
typedef struct SigGroupHeadInitData_ {
/* list of content containers
@ -1065,6 +1066,7 @@ Signature *DetectGetTagSignature(void);
int SignatureIsFilestoring(Signature *);
int SignatureIsFilemagicInspecting(Signature *);
int SignatureIsFileMd5Inspecting(Signature *);
#endif /* __DETECT_H__ */

@ -98,6 +98,10 @@
/** flow is ipv6 */
#define FLOW_IPV6 0x08000000
/** no md5 on files in this flow */
#define FLOW_FILE_NO_MD5_TS 0x10000000
#define FLOW_FILE_NO_MD5_TC 0x20000000
#define FLOW_IS_IPV4(f) \
(((f)->flags & FLOW_IPV4) == FLOW_IPV4)
#define FLOW_IS_IPV6(f) \

@ -438,6 +438,7 @@ static OutputCtx *LogFileLogInitCtx(ConfNode *conf)
#endif
}
FileForceTrackingEnable();
SCReturnPtr(output_ctx, "OutputCtx");
}

@ -1,4 +1,4 @@
/* Copyright (C) 2007-2011 Open Information Security Foundation
/* Copyright (C) 2007-2012 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
@ -45,6 +45,11 @@ static int g_file_force_magic = 0;
*/
static int g_file_force_md5 = 0;
/** \brief switch to force tracking off all files
* regardless of the rules.
*/
static int g_file_force_tracking = 0;
/* prototypes */
static void FileFree(File *);
static void FileDataFree(FileData *);
@ -65,6 +70,10 @@ int FileForceMd5(void) {
return g_file_force_md5;
}
void FileForceTrackingEnable(void) {
g_file_force_tracking = 1;
}
int FileMagicSize(void) {
/** \todo make this size configurable */
return 512;
@ -295,14 +304,6 @@ static File *FileAlloc(uint8_t *name, uint16_t name_len) {
new->name_len = name_len;
memcpy(new->name, name, name_len);
#ifdef HAVE_NSS
if (g_file_force_md5) {
new->md5_ctx = HASH_Create(HASH_AlgMD5);
if (new->md5_ctx != NULL) {
HASH_Begin(new->md5_ctx);
}
}
#endif
return new;
}
@ -424,7 +425,7 @@ int FileAppendData(FileContainer *ffc, uint8_t *data, uint32_t data_len) {
if (FileStoreNoStoreCheck(ffc->tail) == 1) {
#ifdef HAVE_NSS
/* no storage but forced md5 */
if (g_file_force_md5) {
if (g_file_force_tracking || ffc->tail->md5_ctx) {
if (ffc->tail->md5_ctx)
HASH_Update(ffc->tail->md5_ctx, data, data_len);
@ -432,8 +433,8 @@ int FileAppendData(FileContainer *ffc, uint8_t *data, uint32_t data_len) {
SCReturnInt(0);
}
#endif
ffc->tail->state = FILE_STATE_CLOSED;
SCLogDebug("flowfile state transitioned to FILE_STATE_CLOSED");
ffc->tail->state = FILE_STATE_TRUNCATED;
SCLogDebug("flowfile state transitioned to FILE_STATE_TRUNCATED");
SCReturnInt(-2);
}
@ -486,9 +487,22 @@ File *FileOpenFile(FileContainer *ffc, uint8_t *name,
ff->store = -1;
}
if (flags & FILE_NOMAGIC) {
SCLogDebug("no doing magic for this file");
SCLogDebug("not doing magic for this file");
ff->flags |= FILE_NOMAGIC;
}
if (flags & FILE_NOMD5) {
SCLogDebug("not doing md5 for this file");
ff->flags |= FILE_NOMD5;
}
#ifdef HAVE_NSS
if (!(ff->flags & FILE_NOMD5) || g_file_force_md5) {
ff->md5_ctx = HASH_Create(HASH_AlgMD5);
if (ff->md5_ctx != NULL) {
HASH_Begin(ff->md5_ctx);
}
}
#endif
ff->state = FILE_STATE_OPENED;
SCLogDebug("flowfile state transitioned to FILE_STATE_OPENED");
@ -533,14 +547,11 @@ static int FileCloseFilePtr(File *ff, uint8_t *data,
if (ff->store == -1) {
#ifdef HAVE_NSS
/* no storage but forced md5 */
if (g_file_force_md5) {
if (ff->md5_ctx)
HASH_Update(ff->md5_ctx, data, data_len);
ff->size += data_len;
}
/* no storage but md5 */
if (ff->md5_ctx)
HASH_Update(ff->md5_ctx, data, data_len);
#endif
ff->size += data_len;
} else {
FileData *ffd = FileDataAlloc(data, data_len);
if (ffd == NULL) {
@ -666,6 +677,42 @@ void FileDisableMagic(Flow *f, uint8_t direction) {
SCReturn;
}
/**
* \brief disable file md5 calc for this flow
*
* \param f *LOCKED* flow
* \param direction flow direction
*/
void FileDisableMd5(Flow *f, uint8_t direction) {
File *ptr = NULL;
SCEnter();
DEBUG_ASSERT_FLOW_LOCKED(f);
if (direction == STREAM_TOSERVER)
f->flags |= FLOW_FILE_NO_MD5_TS;
else
f->flags |= FLOW_FILE_NO_MD5_TC;
FileContainer *ffc = AppLayerGetFilesFromFlow(f, direction);
if (ffc != NULL) {
for (ptr = ffc->head; ptr != NULL; ptr = ptr->next) {
SCLogDebug("disabling md5 for file %p from direction %s",
ptr, direction == STREAM_TOSERVER ? "toserver":"toclient");
ptr->flags |= FILE_NOMD5;
/* destroy any ctx we may have so far */
if (ptr->md5_ctx != NULL) {
HASH_Destroy(ptr->md5_ctx);
ptr->md5_ctx = NULL;
}
}
}
SCReturn;
}
/**
* \brief set no store flag, close file if needed
*

@ -36,6 +36,7 @@
#define FILE_MD5 0x10
#define FILE_LOGGED 0x20
#define FILE_STORED 0x40
#define FILE_NOMD5 0x80
typedef enum FileState_ {
FILE_STATE_NONE = 0, /**< no state */
@ -163,17 +164,20 @@ void FileDisableStoring(struct Flow_ *, uint8_t);
*/
void FileDisableStoringForTransaction(struct Flow_ *, uint8_t, uint16_t);
void FileDisableMagic(Flow *f, uint8_t);
void FlowFileDisableStoringForTransaction(struct Flow_ *f, uint16_t tx_id);
void FilePrune(FileContainer *ffc);
void FileDisableMagic(Flow *f, uint8_t);
void FileForceMagicEnable(void);
int FileForceMagic(void);
void FileDisableMd5(Flow *f, uint8_t);
void FileForceMd5Enable(void);
int FileForceMd5(void);
void FileForceTrackingEnable(void);
void FileStoreAllFiles(FileContainer *);
void FileStoreAllFilesForTx(FileContainer *, uint16_t);
void FileStoreFileById(FileContainer *fc, uint16_t);

Loading…
Cancel
Save