file handling: improve filestore keyword handling

In stateful detection only inspect the file portion of the rule after all
other conditions matched. This to prevent "filestore" from tagging files
for storage during a partial match.

Add a couple of unittests to test the behaviour change.
remotes/origin/master-1.2.x
Victor Julien 14 years ago
parent 4cbe7519fa
commit b74c73309b

@ -78,15 +78,19 @@ static uint32_t al_result_pool_elmts = 0;
* \retval direction flow direction, either STREAM_TOCLIENT or STREAM_TOSERVER
* \retval NULL in case we have no state */
FileContainer *AppLayerGetFilesFromFlow(Flow *f, uint8_t direction) {
SCEnter();
uint16_t alproto = f->alproto;
if (alproto == ALPROTO_UNKNOWN)
return NULL;
SCReturnPtr(NULL, "FileContainer");
if (al_proto_table[alproto].StateGetFiles != NULL)
return al_proto_table[alproto].StateGetFiles(AppLayerGetProtoStateFromFlow(f), direction);
else
return NULL;
if (al_proto_table[alproto].StateGetFiles != NULL) {
FileContainer *ptr = al_proto_table[alproto].StateGetFiles(AppLayerGetProtoStateFromFlow(f), direction);
SCReturnPtr(ptr, "FileContainer");
} else {
SCReturnPtr(NULL, "FileContainer");
}
}
/** \brief Alloc a AppLayerParserResultElmt func for the pool */

@ -464,17 +464,24 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
}
SCLogDebug("inspecting http raw uri");
}
if (s->sm_lists[DETECT_SM_LIST_FILEMATCH] != NULL) {
inspect_flags |= DE_STATE_FLAG_FILE_TS_INSPECT;
match = DetectFileInspectHttp(tv, det_ctx, f, s, alstate, flags);
if (match == 1) {
match_flags |= DE_STATE_FLAG_FILE_TS_MATCH;
} else if (match == 2) {
match_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
} else if (match == 3) {
match_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
file_no_match++;
SCLogDebug("file inspection");
if (match_flags == inspect_flags) {
SCLogDebug("ready to inspect files");
inspect_flags |= DE_STATE_FLAG_FILE_TS_INSPECT;
match = DetectFileInspectHttp(tv, det_ctx, f, s, alstate, flags);
if (match == 1) {
match_flags |= DE_STATE_FLAG_FILE_TS_MATCH;
} else if (match == 2) {
match_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
} else if (match == 3) {
match_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
file_no_match++;
}
} else {
SCLogDebug("skipping file inspection as we're not yet done with the other inspection");
}
}
} else if (flags & STREAM_TOCLIENT) {
@ -518,17 +525,24 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
inspect_flags |= DE_STATE_FLAG_HRUD_INSPECT;
}
if (s->sm_lists[DETECT_SM_LIST_FILEMATCH] != NULL) {
inspect_flags |= DE_STATE_FLAG_FILE_TC_INSPECT;
match = DetectFileInspectHttp(tv, det_ctx, f, s, alstate, flags);
SCLogDebug("match %d", match);
if (match == 1) {
match_flags |= DE_STATE_FLAG_FILE_TC_MATCH;
} else if (match == 2) {
match_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
} else if (match == 3) {
match_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
file_no_match++;
SCLogDebug("file inspection");
if (match_flags == inspect_flags) {
SCLogDebug("ready to inspect files");
inspect_flags |= DE_STATE_FLAG_FILE_TC_INSPECT;
match = DetectFileInspectHttp(tv, det_ctx, f, s, alstate, flags);
SCLogDebug("match %d", match);
if (match == 1) {
match_flags |= DE_STATE_FLAG_FILE_TC_MATCH;
} else if (match == 2) {
match_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
} else if (match == 3) {
match_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
file_no_match++;
}
} else {
SCLogDebug("skipping file inspection as we're not yet done with the other inspection");
}
}
}
@ -616,6 +630,13 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx,
DeStateSignatureAppend(f->de_state, s, sm, match_flags);
DeStateStoreStateVersion(f->de_state, flags, alversion);
DeStateStoreFileNoMatch(f->de_state, flags, file_no_match);
if (DeStateStoreFilestoreSigsCantMatch(det_ctx->sgh, f->de_state, flags) == 1) {
SCLogDebug("disabling file storage for transaction %u", det_ctx->tx_id);
FileDisableStoringForTransaction(f, flags & (STREAM_TOCLIENT|STREAM_TOSERVER),
det_ctx->tx_id);
f->de_state->flags |= DE_STATE_FILE_STORE_DISABLED;
}
}
SCMutexUnlock(&f->de_state_m);
@ -811,16 +832,23 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete
if (s->sm_lists[DETECT_SM_LIST_FILEMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_FILE_TS_MATCH)) {
inspect_flags |= DE_STATE_FLAG_FILE_TS_INSPECT;
match = DetectFileInspectHttp(tv, det_ctx, f, s, alstate, flags);
if (match == 1) {
match_flags |= DE_STATE_FLAG_FILE_TS_MATCH;
} else if (match == 2) {
match_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
} else if (match == 3) {
match_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
file_no_match++;
SCLogDebug("file inspection");
if (match_flags == inspect_flags) {
SCLogDebug("ready to inspect files");
inspect_flags |= DE_STATE_FLAG_FILE_TS_INSPECT;
match = DetectFileInspectHttp(tv, det_ctx, f, s, alstate, flags);
if (match == 1) {
match_flags |= DE_STATE_FLAG_FILE_TS_MATCH;
} else if (match == 2) {
match_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
} else if (match == 3) {
match_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
file_no_match++;
}
} else {
SCLogDebug("skipping file inspection as we're not yet done with the other inspection");
}
}
}
@ -866,16 +894,23 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete
}
if (s->sm_lists[DETECT_SM_LIST_FILEMATCH] != NULL) {
if (!(item->flags & DE_STATE_FLAG_FILE_TC_MATCH)) {
inspect_flags |= DE_STATE_FLAG_FILE_TC_INSPECT;
match = DetectFileInspectHttp(tv, det_ctx, f, s, alstate, flags);
if (match == 1) {
match_flags |= DE_STATE_FLAG_FILE_TC_MATCH;
} else if (match == 2) {
match_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
} else if (match == 3) {
match_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
file_no_match++;
SCLogDebug("file inspection");
if (match_flags == inspect_flags) {
SCLogDebug("ready to inspect files");
inspect_flags |= DE_STATE_FLAG_FILE_TC_INSPECT;
match = DetectFileInspectHttp(tv, det_ctx, f, s, alstate, flags);
if (match == 1) {
match_flags |= DE_STATE_FLAG_FILE_TC_MATCH;
} else if (match == 2) {
match_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
} else if (match == 3) {
match_flags |= DE_STATE_FLAG_SIG_CANT_MATCH;
file_no_match++;
}
} else {
SCLogDebug("skipping file inspection as we're not yet done with the other inspection");
}
}
}
@ -1466,6 +1501,599 @@ end:
UTHFreePacket(p);
return result;
}
static int DeStateSigTest03(void) {
uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
"Host: www.server.lan\r\n"
"Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
"Content-Length: 215\r\n"
"\r\n"
"-----------------------------277531038314945\r\n"
"Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
"Content-Type: image/jpeg\r\n"
"\r\n"
"filecontent\r\n"
"-----------------------------277531038314945--";
uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
ThreadVars th_v;
TcpSession ssn;
int result = 0;
Flow *f = NULL;
Packet *p = NULL;
HtpState *http_state = NULL;
memset(&th_v, 0, sizeof(th_v));
memset(&ssn, 0, sizeof(ssn));
DetectEngineThreadCtx *det_ctx = NULL;
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->flags |= DE_QUIET;
Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"POST\"; http_method; content:\"upload.cgi\"; http_uri; filestore; sid:1; rev:1;)");
if (s == NULL) {
printf("sig parse failed: ");
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
if (f == NULL)
goto end;
f->protoctx = &ssn;
f->alproto = ALPROTO_HTTP;
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
if (p == NULL)
goto end;
p->flow = f;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
StreamTcpInitConfig(TRUE);
int r = AppLayerParse(NULL, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START|STREAM_EOF, httpbuf1, httplen1);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (!(PacketAlertCheck(p, 1))) {
printf("sig 1 didn't alert: ");
goto end;
}
http_state = f->alstate;
if (http_state == NULL) {
printf("no http state: ");
result = 0;
goto end;
}
if (http_state->files_ts == NULL) {
printf("no files in state: ");
goto end;
}
FileContainer *files = AppLayerGetFilesFromFlow(p->flow, STREAM_TOSERVER);
if (files == NULL) {
printf("no stored files: ");
goto end;
}
File *file = files->head;
if (file == NULL) {
printf("no file: ");
goto end;
}
if (file->store != 1) {
printf("file is set to store, but sig didn't match: ");
goto end;
}
result = 1;
end:
UTHFreeFlow(f);
if (det_ctx != NULL) {
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
}
if (de_ctx != NULL) {
SigGroupCleanup(de_ctx);
DetectEngineCtxFree(de_ctx);
}
StreamTcpFreeConfig(TRUE);
return result;
}
static int DeStateSigTest04(void) {
uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
"Host: www.server.lan\r\n"
"Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
"Content-Length: 215\r\n"
"\r\n"
"-----------------------------277531038314945\r\n"
"Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
"Content-Type: image/jpeg\r\n"
"\r\n"
"filecontent\r\n"
"-----------------------------277531038314945--";
uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
ThreadVars th_v;
TcpSession ssn;
int result = 0;
Flow *f = NULL;
Packet *p = NULL;
HtpState *http_state = NULL;
memset(&th_v, 0, sizeof(th_v));
memset(&ssn, 0, sizeof(ssn));
DetectEngineThreadCtx *det_ctx = NULL;
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->flags |= DE_QUIET;
Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"GET\"; http_method; content:\"upload.cgi\"; http_uri; filestore; sid:1; rev:1;)");
if (s == NULL) {
printf("sig parse failed: ");
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
if (f == NULL)
goto end;
f->protoctx = &ssn;
f->alproto = ALPROTO_HTTP;
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
if (p == NULL)
goto end;
p->flow = f;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
StreamTcpInitConfig(TRUE);
int r = AppLayerParse(NULL, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START|STREAM_EOF, httpbuf1, httplen1);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (PacketAlertCheck(p, 1)) {
printf("sig 1 alerted: ");
goto end;
}
http_state = f->alstate;
if (http_state == NULL) {
printf("no http state: ");
result = 0;
goto end;
}
if (http_state->files_ts == NULL) {
printf("no files in state: ");
goto end;
}
FileContainer *files = AppLayerGetFilesFromFlow(p->flow, STREAM_TOSERVER);
if (files == NULL) {
printf("no stored files: ");
goto end;
}
File *file = files->head;
if (file == NULL) {
printf("no file: ");
goto end;
}
if (file->store == 1) {
printf("file is set to store, but sig didn't match: ");
goto end;
}
result = 1;
end:
UTHFreeFlow(f);
if (det_ctx != NULL) {
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
}
if (de_ctx != NULL) {
SigGroupCleanup(de_ctx);
DetectEngineCtxFree(de_ctx);
}
StreamTcpFreeConfig(TRUE);
return result;
}
static int DeStateSigTest05(void) {
uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
"Host: www.server.lan\r\n"
"Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
"Content-Length: 215\r\n"
"\r\n"
"-----------------------------277531038314945\r\n"
"Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
"Content-Type: image/jpeg\r\n"
"\r\n"
"filecontent\r\n"
"-----------------------------277531038314945--";
uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
ThreadVars th_v;
TcpSession ssn;
int result = 0;
Flow *f = NULL;
Packet *p = NULL;
HtpState *http_state = NULL;
memset(&th_v, 0, sizeof(th_v));
memset(&ssn, 0, sizeof(ssn));
DetectEngineThreadCtx *det_ctx = NULL;
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->flags |= DE_QUIET;
Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"GET\"; http_method; content:\"upload.cgi\"; http_uri; filename:\"nomatch\"; sid:1; rev:1;)");
if (s == NULL) {
printf("sig parse failed: ");
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
if (f == NULL)
goto end;
f->protoctx = &ssn;
f->alproto = ALPROTO_HTTP;
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
if (p == NULL)
goto end;
p->flow = f;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
StreamTcpInitConfig(TRUE);
int r = AppLayerParse(NULL, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START|STREAM_EOF, httpbuf1, httplen1);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (PacketAlertCheck(p, 1)) {
printf("sig 1 alerted: ");
goto end;
}
http_state = f->alstate;
if (http_state == NULL) {
printf("no http state: ");
result = 0;
goto end;
}
if (http_state->files_ts == NULL) {
printf("no files in state: ");
goto end;
}
FileContainer *files = AppLayerGetFilesFromFlow(p->flow, STREAM_TOSERVER);
if (files == NULL) {
printf("no stored files: ");
goto end;
}
File *file = files->head;
if (file == NULL) {
printf("no file: ");
goto end;
}
if (file->store != -1) {
printf("file is not set to \"no store\", but %d: ", file->store);
goto end;
}
result = 1;
end:
UTHFreeFlow(f);
if (det_ctx != NULL) {
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
}
if (de_ctx != NULL) {
SigGroupCleanup(de_ctx);
DetectEngineCtxFree(de_ctx);
}
StreamTcpFreeConfig(TRUE);
return result;
}
static int DeStateSigTest06(void) {
uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
"Host: www.server.lan\r\n"
"Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
"Content-Length: 215\r\n"
"\r\n"
"-----------------------------277531038314945\r\n"
"Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
"Content-Type: image/jpeg\r\n"
"\r\n"
"filecontent\r\n"
"-----------------------------277531038314945--";
uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
ThreadVars th_v;
TcpSession ssn;
int result = 0;
Flow *f = NULL;
Packet *p = NULL;
HtpState *http_state = NULL;
memset(&th_v, 0, sizeof(th_v));
memset(&ssn, 0, sizeof(ssn));
DetectEngineThreadCtx *det_ctx = NULL;
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->flags |= DE_QUIET;
Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"POST\"; http_method; content:\"upload.cgi\"; http_uri; filename:\"nomatch\"; filestore; sid:1; rev:1;)");
if (s == NULL) {
printf("sig parse failed: ");
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
if (f == NULL)
goto end;
f->protoctx = &ssn;
f->alproto = ALPROTO_HTTP;
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
if (p == NULL)
goto end;
p->flow = f;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
StreamTcpInitConfig(TRUE);
int r = AppLayerParse(NULL, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START|STREAM_EOF, httpbuf1, httplen1);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (PacketAlertCheck(p, 1)) {
printf("sig 1 alerted: ");
goto end;
}
http_state = f->alstate;
if (http_state == NULL) {
printf("no http state: ");
result = 0;
goto end;
}
if (http_state->files_ts == NULL) {
printf("no files in state: ");
goto end;
}
FileContainer *files = AppLayerGetFilesFromFlow(p->flow, STREAM_TOSERVER);
if (files == NULL) {
printf("no stored files: ");
goto end;
}
File *file = files->head;
if (file == NULL) {
printf("no file: ");
goto end;
}
if (file->store != -1) {
printf("file is not set to \"no store\", but %d: ", file->store);
goto end;
}
result = 1;
end:
UTHFreeFlow(f);
if (det_ctx != NULL) {
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
}
if (de_ctx != NULL) {
SigGroupCleanup(de_ctx);
DetectEngineCtxFree(de_ctx);
}
StreamTcpFreeConfig(TRUE);
return result;
}
static int DeStateSigTest07(void) {
uint8_t httpbuf1[] = "POST /upload.cgi HTTP/1.1\r\n"
"Host: www.server.lan\r\n"
"Content-Type: multipart/form-data; boundary=---------------------------277531038314945\r\n"
"Content-Length: 215\r\n"
"\r\n"
"-----------------------------277531038314945\r\n"
"Content-Disposition: form-data; name=\"uploadfile_0\"; filename=\"somepicture1.jpg\"\r\n"
"Content-Type: image/jpeg\r\n"
"\r\n";
uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
uint8_t httpbuf2[] = "filecontent\r\n"
"-----------------------------277531038314945--";
uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */
ThreadVars th_v;
TcpSession ssn;
int result = 0;
Flow *f = NULL;
Packet *p = NULL;
HtpState *http_state = NULL;
memset(&th_v, 0, sizeof(th_v));
memset(&ssn, 0, sizeof(ssn));
DetectEngineThreadCtx *det_ctx = NULL;
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->flags |= DE_QUIET;
Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any (content:\"GET\"; http_method; content:\"upload.cgi\"; http_uri; filestore; sid:1; rev:1;)");
if (s == NULL) {
printf("sig parse failed: ");
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 1024, 80);
if (f == NULL)
goto end;
f->protoctx = &ssn;
f->alproto = ALPROTO_HTTP;
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
if (p == NULL)
goto end;
p->flow = f;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
StreamTcpInitConfig(TRUE);
SCLogDebug("\n>>>> processing chunk 1 <<<<\n");
int r = AppLayerParse(NULL, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_START, httpbuf1, httplen1);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (PacketAlertCheck(p, 1)) {
printf("sig 1 alerted: ");
goto end;
}
SCLogDebug("\n>>>> processing chunk 2 size %u <<<<\n", httplen2);
r = AppLayerParse(NULL, f, ALPROTO_HTTP, STREAM_TOSERVER|STREAM_EOF, httpbuf2, httplen2);
if (r != 0) {
printf("toserver chunk 2 returned %" PRId32 ", expected 0: ", r);
result = 0;
goto end;
}
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (PacketAlertCheck(p, 1)) {
printf("sig 1 alerted: ");
goto end;
}
http_state = f->alstate;
if (http_state == NULL) {
printf("no http state: ");
result = 0;
goto end;
}
if (http_state->files_ts == NULL) {
printf("no files in state: ");
goto end;
}
FileContainer *files = AppLayerGetFilesFromFlow(p->flow, STREAM_TOSERVER);
if (files == NULL) {
printf("no stored files: ");
goto end;
}
File *file = files->head;
if (file == NULL) {
printf("no file: ");
goto end;
}
if (file->store == 1) {
printf("file is set to store, but sig didn't match: ");
goto end;
}
result = 1;
end:
UTHFreeFlow(f);
if (det_ctx != NULL) {
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
}
if (de_ctx != NULL) {
SigGroupCleanup(de_ctx);
DetectEngineCtxFree(de_ctx);
}
StreamTcpFreeConfig(TRUE);
return result;
}
#endif
void DeStateRegisterTests(void) {
@ -1475,6 +2103,11 @@ void DeStateRegisterTests(void) {
UtRegisterTest("DeStateTest03", DeStateTest03, 1);
UtRegisterTest("DeStateSigTest01", DeStateSigTest01, 1);
UtRegisterTest("DeStateSigTest02", DeStateSigTest02, 1);
UtRegisterTest("DeStateSigTest03", DeStateSigTest03, 1);
UtRegisterTest("DeStateSigTest04", DeStateSigTest04, 1);
UtRegisterTest("DeStateSigTest05", DeStateSigTest05, 1);
UtRegisterTest("DeStateSigTest06", DeStateSigTest06, 1);
UtRegisterTest("DeStateSigTest07", DeStateSigTest07, 1);
#endif
}

@ -554,11 +554,8 @@ void FileDisableStoring(Flow *f, uint8_t direction) {
FileContainer *ffc = AppLayerGetFilesFromFlow(f, direction);
if (ffc != NULL) {
for (ptr = ffc->head; ptr != NULL; ptr = ptr->next) {
if (ptr->state == FILE_STATE_OPENED) {
if (ptr->store == 0) {
ptr->store = -1;
}
if (ptr->store == 0) {
ptr->store = -1;
}
}
}
@ -623,7 +620,7 @@ void FileDisableStoringForTransaction(Flow *f, uint8_t direction, uint16_t tx_id
FileContainer *ffc = AppLayerGetFilesFromFlow(f, direction);
if (ffc != NULL) {
for (ptr = ffc->head; ptr != NULL; ptr = ptr->next) {
if (ptr->state == FILE_STATE_OPENED && ptr->txid == tx_id) {
if (ptr->txid == tx_id) {
if (ptr->store == 1) {
/* weird, already storing -- let it continue*/
SCLogDebug("file is already being stored");

@ -464,7 +464,6 @@ Flow *UTHBuildFlow(int family, char *src, char *dst, Port sp, Port dp) {
void UTHFreeFlow(Flow *flow) {
if (flow != NULL) {
FLOW_DESTROY(flow);
FlowFree(flow);
}
}

Loading…
Cancel
Save