Make sure filemagic works properly regardless of filestore being in use for a flow.

remotes/origin/master-1.2.x
Victor Julien 15 years ago
parent 5945e652d6
commit 9b62ec65ab

@ -81,15 +81,12 @@ int HTPFileOpen(Flow *f, uint8_t *filename, uint16_t filename_len,
{
int retval = 0;
uint16_t txid;
uint8_t flags = 0;
if (f == NULL) {
SCReturnInt(-1);
}
if (f->flags & FLOW_FILE_NO_HANDLING) {
SCReturnInt(-2);
}
txid = AppLayerTransactionGetAvailId(f) - 1;
SCMutexLock(&f->files_m);
@ -102,8 +99,12 @@ int HTPFileOpen(Flow *f, uint8_t *filename, uint16_t filename_len,
}
}
if (f->flags & FLOW_FILE_NO_HANDLING) {
flags |= FLOW_FILE_NOSTORE;
}
if (FlowFileOpenFile(f->files, filename, filename_len,
data, data_len) == NULL)
data, data_len, flags) == NULL)
{
retval = -1;
}
@ -137,10 +138,6 @@ int HTPFileStoreChunk(Flow *f, uint8_t *data, uint32_t data_len) {
SCReturnInt(-1);
}
if (f->flags & FLOW_FILE_NO_HANDLING) {
SCReturnInt(-2);
}
SCMutexLock(&f->files_m);
{
if (f->files == NULL) {

@ -104,6 +104,12 @@ static int DetectFileInspect(ThreadVars *tv, DetectEngineThreadCtx *det_ctx, Flo
break;
}
if (s->file_flags & FILE_SIG_NEED_MAGIC && file->chunks_head == NULL) {
SCLogDebug("sig needs file content, but we don't have any");
r = 0;
break;
}
if (s->file_flags & FILE_SIG_NEED_FILECONTENT && file->chunks_head == NULL) {
SCLogDebug("sig needs file content, but we don't have any");
r = 0;

@ -1585,6 +1585,33 @@ int SigGroupHeadBuildMatchArray(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
return 0;
}
/**
* \brief Set the filestore_cnt in the sgh.
*
* \param de_ctx detection engine ctx for the signatures
* \param sgh sig group head to set the counter in
*/
void SigGroupHeadSetFilemagicFlag(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 (SignatureIsFilemagicInspecting(s)) {
sgh->flags |= SIG_GROUP_HEAD_HAVEFILEMAGIC;
break;
}
}
return;
}
/**
* \brief Set the filestore_cnt in the sgh.
*

@ -86,6 +86,7 @@ void SigGroupHeadPrintSigs(DetectEngineCtx *de_ctx, SigGroupHead *sgh);
void SigGroupHeadStore(DetectEngineCtx *, SigGroupHead *);
int SigGroupHeadBuildHeadArray(DetectEngineCtx *, SigGroupHead *);
void SigGroupHeadSetFilemagicFlag(DetectEngineCtx *, SigGroupHead *);
void SigGroupHeadSetFilestoreCount(DetectEngineCtx *, SigGroupHead *);
#endif /* __DETECT_ENGINE_SIGGROUP_H__ */

@ -273,7 +273,7 @@ static int DetectFilemagicSetup (DetectEngineCtx *de_ctx, Signature *s, char *st
s->alproto = ALPROTO_HTTP;
s->file_flags |= (FILE_SIG_NEED_FILE|FILE_SIG_NEED_FILECONTENT);
s->file_flags |= (FILE_SIG_NEED_FILE|FILE_SIG_NEED_MAGIC);
return 0;
error:

@ -1778,10 +1778,12 @@ end:
/* if we know both sides of the flow have had their sgh check
* and both are null, we will never decide to store. So disable
* storage completely. */
if (p->flow->flags & FLOW_SGH_TOCLIENT &&
p->flow->flags & FLOW_SGH_TOSERVER &&
(p->flow->sgh_toserver == NULL || p->flow->sgh_toserver->filestore_cnt == 0) &&
(p->flow->sgh_toclient == NULL || p->flow->sgh_toclient->filestore_cnt == 0))
if (p->flow->flags & FLOW_SGH_TOCLIENT && p->flow->flags & FLOW_SGH_TOSERVER &&
(p->flow->sgh_toserver == NULL ||
p->flow->sgh_toserver->filestore_cnt == 0)
&&
(p->flow->sgh_toclient == NULL ||
p->flow->sgh_toclient->filestore_cnt == 0))
{
FlowFileDisableStoring(p->flow);
}
@ -1920,6 +1922,24 @@ int SignatureIsFilestoring(Signature *s) {
return 0;
}
/**
* \brief Check if a signature contains the filemagic keyword.
*
* \param s signature
*
* \retval 0 no
* \retval 1 yes
*/
int SignatureIsFilemagicInspecting(Signature *s) {
if (s == NULL)
return 0;
if (s->file_flags & FILE_SIG_NEED_MAGIC)
return 1;
return 0;
}
/** \brief Test is a initialized signature is IP only
* \param de_ctx detection engine ctx
* \param s the signature
@ -3765,6 +3785,7 @@ int SigAddressPrepareStage4(DetectEngineCtx *de_ctx) {
continue;
SigGroupHeadBuildHeadArray(de_ctx, sgh);
SigGroupHeadSetFilemagicFlag(de_ctx, sgh);
SigGroupHeadSetFilestoreCount(de_ctx, sgh);
SCLogInfo("filestore count %u", sgh->filestore_cnt);
}

@ -291,7 +291,8 @@ typedef struct DetectPort_ {
#define FILE_SIG_NEED_FILE 0x01
#define FILE_SIG_NEED_FILENAME 0x02
#define FILE_SIG_NEED_TYPE 0x04
#define FILE_SIG_NEED_FILECONTENT 0x08
#define FILE_SIG_NEED_MAGIC 0x08 /**< need the start of the file */
#define FILE_SIG_NEED_FILECONTENT 0x10
/* Detection Engine flags */
#define DE_QUIET 0x01 /**< DE is quiet (esp for unittests) */
@ -861,6 +862,7 @@ typedef struct SigTableElmt_ {
#define SIG_GROUP_HEAD_MPM_HCD 0x00100000
#define SIG_GROUP_HEAD_MPM_HRUD 0x00200000
#define SIG_GROUP_HEAD_REFERENCED 0x00400000 /**< sgh is being referenced by others, don't clear */
#define SIG_GROUP_HEAD_HAVEFILEMAGIC 0x00800000
typedef struct SigGroupHeadInitData_ {
/* list of content containers
@ -1076,6 +1078,7 @@ SigGroupHead *SigMatchSignaturesGetSgh(DetectEngineCtx *de_ctx, DetectEngineThre
Signature *DetectGetTagSignature(void);
int SignatureIsFilestoring(Signature *);
int SignatureIsFilemagicInspecting(Signature *);
#endif /* __DETECT_H__ */

@ -36,6 +36,37 @@
/* prototypes */
static void FlowFileFree(FlowFile *);
int FlowFileMagicSize(void) {
return 512;
}
/**
* \brief check if we have stored enough
*
* \param ff file
*
* \retval 0 limit not reached yet
* \retval 1 limit reached
*/
static int FlowFileStoreNoStoreCheck(FlowFile *ff) {
SCEnter();
if (ff == NULL) {
SCReturnInt(0);
}
if (ff->store == -1) {
if (ff->state == FLOWFILE_STATE_OPENED &&
ff->size >= (uint64_t)FlowFileMagicSize())
{
SCReturnInt(1);
}
}
SCReturnInt(0);
}
/**
* \brief allocate a FlowFileContainer
*
@ -153,6 +184,9 @@ static int FlowFileAppendFlowFileDataFilePtr(FlowFile *ff, FlowFileData *ffd) {
ff->chunks_tail = ffd;
}
ff->size += ffd->len;
SCLogDebug("file size %"PRIu64, ff->size);
SCReturnInt(0);
}
@ -230,13 +264,14 @@ void FlowFileContainerAdd(FlowFileContainer *ffc, FlowFile *ff) {
* \param name_len filename len
* \param data initial data
* \param data_len initial data len
* \param flags open flags
*
* \retval ff flowfile object
*
* \note filename is not a string, so it's not nul terminated.
*/
FlowFile *FlowFileOpenFile(FlowFileContainer *ffc, uint8_t *name,
uint16_t name_len, uint8_t *data, uint32_t data_len)
uint16_t name_len, uint8_t *data, uint32_t data_len, uint8_t flags)
{
SCEnter();
@ -247,6 +282,10 @@ FlowFile *FlowFileOpenFile(FlowFileContainer *ffc, uint8_t *name,
SCReturnPtr(NULL, "FlowFile");
}
if (flags & FLOW_FILE_NOSTORE) {
ff->store = -1;
}
ff->state = FLOWFILE_STATE_OPENED;
SCLogDebug("flowfile state transitioned to FLOWFILE_STATE_OPENED");
@ -370,6 +409,12 @@ int FlowFileAppendData(FlowFileContainer *ffc, uint8_t *data, uint32_t data_len)
SCReturnInt(-1);
}
if (FlowFileStoreNoStoreCheck(ffc->tail) == 1) {
ffc->tail->state = FLOWFILE_STATE_CLOSED;
SCLogDebug("flowfile state transitioned to FLOWFILE_STATE_CLOSED");
SCReturnInt(-2);
}
SCLogDebug("appending %"PRIu32" bytes", data_len);
FlowFileData *ffd = FlowFileDataAlloc(data, data_len);
@ -424,8 +469,12 @@ void FlowFileDisableStoring(Flow *f) {
if (f->files != NULL) {
for (ptr = f->files->head; ptr != NULL; ptr = ptr->next) {
if (ptr->state == FLOWFILE_STATE_OPENED) {
ptr->state = FLOWFILE_STATE_CLOSED;
SCLogDebug("flowfile state transitioned to FLOWFILE_STATE_CLOSED");
if (ptr->store == 0) {
ptr->store = -1;
}
// ptr->state = FLOWFILE_STATE_CLOSED;
// SCLogDebug("flowfile state transitioned to FLOWFILE_STATE_CLOSED");
}
}
}
@ -433,6 +482,26 @@ void FlowFileDisableStoring(Flow *f) {
SCReturn;
}
/**
* \brief set no store flag, close file if needed
*
* \param ff file
*/
static void FlowFileDisableStoringForFile(FlowFile *ff) {
SCEnter();
if (ff == NULL) {
SCReturn;
}
ff->store = -1;
if (ff->state == FLOWFILE_STATE_OPENED && ff->size >= (uint64_t)FlowFileMagicSize()) {
(void)FlowFileCloseFilePtr(ff, NULL, 0,
(FLOW_FILE_TRUNCATED|FLOW_FILE_NOSTORE));
}
}
/**
* \brief disable file storing for files in a transaction
*
@ -452,8 +521,7 @@ void FlowFileDisableStoringForTransaction(struct Flow_ *f, uint16_t tx_id) {
/* weird, already storing -- let it continue*/
SCLogDebug("file is already being stored");
} else {
(void)FlowFileCloseFilePtr(ptr, NULL, 0,
(FLOW_FILE_TRUNCATED|FLOW_FILE_NOSTORE));
FlowFileDisableStoringForFile(ptr);
}
}
}

@ -58,6 +58,7 @@ typedef struct FlowFile_ {
uint16_t name_len;
int16_t state;
int fd; /**< file discriptor for storing files */
uint64_t size; /**< size tracked so far */
const char *magic;
FlowFileData *chunks_head;
FlowFileData *chunks_tail;
@ -84,13 +85,14 @@ void FlowFileContainerAdd(FlowFileContainer *, FlowFile *);
* \param name_len filename len
* \param data initial data
* \param data_len initial data len
* \param flags open flags
*
* \retval ff flowfile object
*
* \note filename is not a string, so it's not nul terminated.
*/
FlowFile *FlowFileOpenFile(FlowFileContainer *, uint8_t *name, uint16_t name_len,
uint8_t *data, uint32_t data_len);
uint8_t *data, uint32_t data_len, uint8_t flags);
/**
* \brief Close a FlowFile
*

Loading…
Cancel
Save