return 0;
}
+static void HSBDGetBufferForTXInIDSMode(DetectEngineThreadCtx *det_ctx,
+ HtpState *htp_state, HtpBodyChunk *cur,
+ HtpTxUserData *htud, int index)
+{
+ int first = 1;
+ while (cur != NULL) {
+ /* see if we can filter out chunks */
+ if (htud->response_body.body_inspected > 0) {
+ if (cur->stream_offset < htud->response_body.body_inspected) {
+ if ((htud->response_body.body_inspected - cur->stream_offset) > htp_state->cfg->response_inspect_window) {
+ cur = cur->next;
+ continue;
+ } else {
+ /* include this one */
+ }
+ } else {
+ /* include this one */
+ }
+ }
+
+ if (first) {
+ det_ctx->hsbd[index].offset = cur->stream_offset;
+ first = 0;
+ }
+
+ /* see if we need to grow the buffer */
+ if (det_ctx->hsbd[index].buffer == NULL || (det_ctx->hsbd[index].buffer_len + cur->len) > det_ctx->hsbd[index].buffer_size) {
+ void *ptmp;
+ det_ctx->hsbd[index].buffer_size += cur->len * 2;
+
+ if ((ptmp = SCRealloc(det_ctx->hsbd[index].buffer, det_ctx->hsbd[index].buffer_size)) == NULL) {
+ SCFree(det_ctx->hsbd[index].buffer);
+ det_ctx->hsbd[index].buffer = NULL;
+ det_ctx->hsbd[index].buffer_size = 0;
+ det_ctx->hsbd[index].buffer_len = 0;
+ return;
+ }
+ det_ctx->hsbd[index].buffer = ptmp;
+ }
+ memcpy(det_ctx->hsbd[index].buffer + det_ctx->hsbd[index].buffer_len, cur->data, cur->len);
+ det_ctx->hsbd[index].buffer_len += cur->len;
+
+ cur = cur->next;
+ }
+
+ /* update inspected tracker */
+ htud->response_body.body_inspected = htud->response_body.last->stream_offset + htud->response_body.last->len;
+}
+
+static void HSBDGetBufferForTXInIPSMode(DetectEngineThreadCtx *det_ctx,
+ HtpState *htp_state, HtpBodyChunk *cur,
+ HtpTxUserData *htud, int index)
+{
+ uint32_t window_size = 0;
+ uint32_t extra_size = 0;
+ int resize = 0;
+
+ if (htud->response_body.content_len_so_far <= htp_state->cfg->response_inspect_min_size) {
+ resize = 1;
+ window_size = htp_state->cfg->response_inspect_min_size;
+ } else {
+ resize = 1;
+ window_size = htp_state->cfg->response_inspect_window;
+ }
+
+ int first = 1;
+ while (cur != NULL) {
+ /* see if we need to grow the buffer */
+ if (cur->len > window_size) {
+ extra_size = window_size * 0.25;
+ window_size = cur->len;
+ resize = 1;
+ } else if (cur->len == window_size) {
+ window_size = window_size * 1.25;
+ resize = 1;
+ }
+
+ if (det_ctx->hsbd[index].buffer == NULL || resize) {
+ void *ptmp;
+
+ if ((ptmp = SCRealloc(det_ctx->hsbd[index].buffer, window_size + extra_size)) == NULL) {
+ SCFree(det_ctx->hsbd[index].buffer);
+ det_ctx->hsbd[index].buffer = NULL;
+ det_ctx->hsbd[index].buffer_size = 0;
+ det_ctx->hsbd[index].buffer_len = 0;
+ return;
+ }
+ det_ctx->hsbd[index].buffer = ptmp;
+ resize = 0;
+ }
+
+ if (first) {
+ det_ctx->hsbd[index].offset = cur->stream_offset;
+ first = 0;
+ }
+
+ /*
+ * Copy a part of the previous buffer before the current chunk on.
+ * For example, let's have the chunks [123], [456].
+ * When the current chunk is [456], this copy [3] before.
+ */
+ if (det_ctx->hsbd[index].buffer_len + cur->len > window_size + extra_size) {
+ uint32_t offset = (det_ctx->hsbd[index].buffer_len + cur->len) - (window_size + extra_size);
+ /* we use memmove to avoid memory overlap */
+ memmove(det_ctx->hsbd[index].buffer, det_ctx->hsbd[index].buffer + offset, det_ctx->hsbd[index].buffer_len - offset);
+ det_ctx->hsbd[index].buffer_len -= offset;
+ det_ctx->hsbd[index].offset += offset;
+ }
+ memcpy(det_ctx->hsbd[index].buffer + det_ctx->hsbd[index].buffer_len, cur->data, cur->len);
+ det_ctx->hsbd[index].buffer_len += cur->len;
+
+ cur = cur->next;
+ }
+
+ /* update inspected tracker */
+ htud->response_body.body_inspected = htud->response_body.last->stream_offset + htud->response_body.last->len;
+}
static uint8_t *DetectEngineHSBDGetBufferForTX(htp_tx_t *tx, uint64_t tx_id,
DetectEngineCtx *de_ctx,
flags & STREAM_EOF ? "true" : "false",
(AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, STREAM_TOCLIENT) > HTP_RESPONSE_BODY) ? "true" : "false");
- /* inspect the body if the transfer is complete or we have hit
- * our body size limit */
- if ((htp_state->cfg->response_body_limit == 0 ||
- htud->response_body.content_len_so_far < htp_state->cfg->response_body_limit) &&
- htud->response_body.content_len_so_far < htp_state->cfg->response_inspect_min_size &&
- !(AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, STREAM_TOCLIENT) > HTP_RESPONSE_BODY) &&
- !(flags & STREAM_EOF)) {
- SCLogDebug("we still haven't seen the entire response body. "
- "Let's defer body inspection till we see the "
- "entire body.");
- goto end;
- }
-
- int first = 1;
- while (cur != NULL) {
- /* see if we can filter out chunks */
- if (htud->response_body.body_inspected > 0) {
- if (cur->stream_offset < htud->response_body.body_inspected) {
- if ((htud->response_body.body_inspected - cur->stream_offset) > htp_state->cfg->response_inspect_window) {
- cur = cur->next;
- continue;
- } else {
- /* include this one */
- }
- } else {
- /* include this one */
- }
- }
-
- if (first) {
- det_ctx->hsbd[index].offset = cur->stream_offset;
- first = 0;
- }
-
- /* see if we need to grow the buffer */
- if (det_ctx->hsbd[index].buffer == NULL || (det_ctx->hsbd[index].buffer_len + cur->len) > det_ctx->hsbd[index].buffer_size) {
- void *ptmp;
- det_ctx->hsbd[index].buffer_size += cur->len * 2;
-
- if ((ptmp = SCRealloc(det_ctx->hsbd[index].buffer, det_ctx->hsbd[index].buffer_size)) == NULL) {
- SCFree(det_ctx->hsbd[index].buffer);
- det_ctx->hsbd[index].buffer = NULL;
- det_ctx->hsbd[index].buffer_size = 0;
- det_ctx->hsbd[index].buffer_len = 0;
- goto end;
- }
- det_ctx->hsbd[index].buffer = ptmp;
+ if (!htp_state->cfg->http_body_inline) {
+ /* inspect the body if the transfer is complete or we have hit
+ * our body size limit */
+ if ((htp_state->cfg->response_body_limit == 0 ||
+ htud->response_body.content_len_so_far < htp_state->cfg->response_body_limit) &&
+ htud->response_body.content_len_so_far < htp_state->cfg->response_inspect_min_size &&
+ !(AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, STREAM_TOCLIENT) > HTP_RESPONSE_BODY) &&
+ !(flags & STREAM_EOF)) {
+ SCLogDebug("we still haven't seen the entire response body. "
+ "Let's defer body inspection till we see the "
+ "entire body.");
+ goto end;
}
- memcpy(det_ctx->hsbd[index].buffer + det_ctx->hsbd[index].buffer_len, cur->data, cur->len);
- det_ctx->hsbd[index].buffer_len += cur->len;
-
- cur = cur->next;
+ HSBDGetBufferForTXInIDSMode(det_ctx, htp_state, cur, htud, index);
+ } else {
+ HSBDGetBufferForTXInIPSMode(det_ctx, htp_state, cur, htud, index);
}
- /* update inspected tracker */
- htud->response_body.body_inspected = htud->response_body.last->stream_offset + htud->response_body.last->len;
-
buffer = det_ctx->hsbd[index].buffer;
*buffer_len = det_ctx->hsbd[index].buffer_len;
*stream_start_offset = det_ctx->hsbd[index].offset;
return result;
}
+/*
+ * Tests buffer inspection like in ips mode,
+ * here all chunks size are smaller than the window_size.
+
+ * in: buffer:
+ * [ab] [ab]
+ * [cd] [abcd]
+ * [ef] [cdef]
+*/
+static int DetectEngineHttpServerBodyFileDataTest04(void)
+{
+
+ char input[] = "\
+%YAML 1.1\n\
+---\n\
+libhtp:\n\
+\n\
+ default-config:\n\
+\n\
+ http-body-inline: yes\n\
+ response-body-minimal-inspect-size: 1\n\
+ response-body-inspect-window: 4\n\
+";
+
+ ConfCreateContextBackup();
+ ConfInit();
+ HtpConfigCreateBackup();
+
+ ConfYamlLoadString(input, strlen(input));
+ HTPConfigure();
+ EngineModeSetIPS();
+ TcpSession ssn;
+ Packet *p1 = NULL;
+ Packet *p2 = NULL;
+ ThreadVars th_v;
+ DetectEngineCtx *de_ctx = NULL;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ HtpState *http_state = NULL;
+ Flow f;
+ uint8_t http_buf1[] =
+ "GET /index.html HTTP/1.0\r\n"
+ "Host: www.openinfosecfoundation.org\r\n"
+ "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
+ "\r\n";
+ uint32_t http_len1 = sizeof(http_buf1) - 1;
+ uint8_t http_buf2[] =
+ "HTTP/1.0 200 ok\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 6\r\n"
+ "\r\n"
+ "ab";
+ uint32_t http_len2 = sizeof(http_buf2) - 1;
+ uint8_t http_buf3[] = "cd";
+ uint32_t http_len3 = sizeof(http_buf3) - 1;
+ uint8_t http_buf4[] = "ef";
+ uint32_t http_len4 = sizeof(http_buf4) - 1;
+
+ int result = 0;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&th_v, 0, sizeof(th_v));
+ memset(&f, 0, sizeof(f));
+ memset(&ssn, 0, sizeof(ssn));
+
+ p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
+ p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p1->flow = &f;
+ p1->flowflags |= FLOW_PKT_TOSERVER;
+ p1->flowflags |= FLOW_PKT_ESTABLISHED;
+ p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p2->flow = &f;
+ p2->flowflags |= FLOW_PKT_TOCLIENT;
+ p2->flowflags |= FLOW_PKT_ESTABLISHED;
+ p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ f.alproto = ALPROTO_HTTP;
+
+ StreamTcpInitConfig(TRUE);
+
+ de_ctx = DetectEngineCtxInit();
+ if (de_ctx == NULL)
+ goto end;
+
+ de_ctx->flags |= DE_QUIET;
+
+ if (!(DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
+ "(msg:\"http server body test\"; "
+ "file_data; content:\"ab\"; sid:1;)")))
+ goto end;
+ if (!(DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
+ "(msg:\"http server body test\"; "
+ "file_data; content:\"bc\"; sid:2;)")))
+ goto end;
+ if (!(DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
+ "(msg:\"http server body test\"; "
+ "file_data; content:\"cdef\"; sid:3;)")))
+ goto end;
+ if (!(DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
+ "(msg:\"http server body test\"; "
+ "file_data; content:\"ef\"; sid:4;)")))
+ goto end;
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+ SCMutexLock(&f.m);
+ int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ SCMutexUnlock(&f.m);
+ goto end;
+ }
+ SCMutexUnlock(&f.m);
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: \n");
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+
+ if (PacketAlertCheck(p1, 1)) {
+ printf("sid 1 matched but shouldn't have: ");
+ goto end;
+ }
+
+ SCMutexLock(&f.m);
+ r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ SCMutexUnlock(&f.m);
+ goto end;
+ }
+ SCMutexUnlock(&f.m);
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (!PacketAlertCheck(p2, 1)) {
+ printf("sid 1 did not match but should have: ");
+ goto end;
+ }
+
+ SCMutexLock(&f.m);
+ r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf3, http_len3);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ SCMutexUnlock(&f.m);
+ goto end;
+ }
+ SCMutexUnlock(&f.m);
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (!PacketAlertCheck(p2, 2)) {
+ printf("sid 2 did not match but should have: ");
+ goto end;
+ }
+
+ SCMutexLock(&f.m);
+ r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf4, http_len4);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ SCMutexUnlock(&f.m);
+ goto end;
+ }
+ SCMutexUnlock(&f.m);
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (!PacketAlertCheck(p2, 3)) {
+ printf("sid 3 did not match but should have: ");
+ goto end;
+ }
+
+ if (!PacketAlertCheck(p2, 4)) {
+ printf("sid 4 did not match but should have: ");
+ goto end;
+ }
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ SigCleanSignatures(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(TRUE);
+ FLOW_DESTROY(&f);
+ UTHFreePackets(&p1, 1);
+ UTHFreePackets(&p2, 1);
+ EngineModeSetIDS();
+ ConfDeInit();
+ ConfRestoreContextBackup();
+ return result;
+}
+
+/*
+ * Tests buffer inspection like in ips mode,
+ * here the last chunk size is greater than the window size.
+
+ * in: buffer:
+ * [ab] [ab]
+ * [cd] [abcd]
+ * [12345678] [d12345678]
+*/
+static int DetectEngineHttpServerBodyFileDataTest05(void)
+{
+
+ char input[] = "\
+%YAML 1.1\n\
+---\n\
+libhtp:\n\
+\n\
+ default-config:\n\
+\n\
+ http-body-inline: yes\n\
+ response-body-minimal-inspect-size: 1\n\
+ response-body-inspect-window: 4\n\
+";
+
+ ConfCreateContextBackup();
+ ConfInit();
+ HtpConfigCreateBackup();
+
+ ConfYamlLoadString(input, strlen(input));
+ HTPConfigure();
+ EngineModeSetIPS();
+ TcpSession ssn;
+ Packet *p1 = NULL;
+ Packet *p2 = NULL;
+ ThreadVars th_v;
+ DetectEngineCtx *de_ctx = NULL;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ HtpState *http_state = NULL;
+ Flow f;
+ uint8_t http_buf1[] =
+ "GET /index.html HTTP/1.0\r\n"
+ "Host: www.openinfosecfoundation.org\r\n"
+ "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
+ "\r\n";
+ uint32_t http_len1 = sizeof(http_buf1) - 1;
+ uint8_t http_buf2[] =
+ "HTTP/1.0 200 ok\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 12\r\n"
+ "\r\n"
+ "ab";
+ uint32_t http_len2 = sizeof(http_buf2) - 1;
+ uint8_t http_buf3[] = "cd";
+ uint32_t http_len3 = sizeof(http_buf3) - 1;
+ uint8_t http_buf4[] = "12345678";
+ uint32_t http_len4 = sizeof(http_buf4) - 1;
+
+ int result = 0;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&th_v, 0, sizeof(th_v));
+ memset(&f, 0, sizeof(f));
+ memset(&ssn, 0, sizeof(ssn));
+
+ p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
+ p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p1->flow = &f;
+ p1->flowflags |= FLOW_PKT_TOSERVER;
+ p1->flowflags |= FLOW_PKT_ESTABLISHED;
+ p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p2->flow = &f;
+ p2->flowflags |= FLOW_PKT_TOCLIENT;
+ p2->flowflags |= FLOW_PKT_ESTABLISHED;
+ p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ f.alproto = ALPROTO_HTTP;
+
+ StreamTcpInitConfig(TRUE);
+
+ de_ctx = DetectEngineCtxInit();
+ if (de_ctx == NULL)
+ goto end;
+
+ de_ctx->flags |= DE_QUIET;
+
+ if (!(DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
+ "(msg:\"http server body test\"; "
+ "file_data; content:\"ab\"; sid:1;)")))
+ goto end;
+
+ if (!(DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
+ "(msg:\"http server body test\"; "
+ "file_data; content:\"abcd\"; sid:2;)")))
+ goto end;
+ if (!(DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
+ "(msg:\"http server body test\"; "
+ "file_data; content:\"d12345678\"; sid:3;)")))
+ goto end;
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+ SCMutexLock(&f.m);
+ int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ SCMutexUnlock(&f.m);
+ goto end;
+ }
+ SCMutexUnlock(&f.m);
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: \n");
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+
+ if (PacketAlertCheck(p1, 1)) {
+ printf("sid 1 matched but shouldn't have: ");
+ goto end;
+ }
+
+ SCMutexLock(&f.m);
+ r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ SCMutexUnlock(&f.m);
+ goto end;
+ }
+ SCMutexUnlock(&f.m);
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+
+ if (!PacketAlertCheck(p2, 1)) {
+ printf("sid 1 did not match but should have: ");
+ goto end;
+ }
+
+ SCMutexLock(&f.m);
+ r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf3, http_len3);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ SCMutexUnlock(&f.m);
+ goto end;
+ }
+ SCMutexUnlock(&f.m);
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (!PacketAlertCheck(p2, 2)) {
+ printf("sid 2 did not match but should have: ");
+ goto end;
+ }
+
+ SCMutexLock(&f.m);
+ r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf4, http_len4);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ SCMutexUnlock(&f.m);
+ goto end;
+ }
+ SCMutexUnlock(&f.m);
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (!PacketAlertCheck(p2, 3)) {
+ printf("sid 3 did not match but should have: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ SigCleanSignatures(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(TRUE);
+ FLOW_DESTROY(&f);
+ UTHFreePackets(&p1, 1);
+ UTHFreePackets(&p2, 1);
+ EngineModeSetIDS();
+ HTPFreeConfig();
+ ConfDeInit();
+ ConfRestoreContextBackup();
+ HtpConfigRestoreBackup();
+ return result;
+}
+
+/**
+ * in: buffer:
+ * [123] [123]
+ * [456] [3456]
+ */
+static int DetectEngineHttpServerBodyFileDataTest06(void)
+{
+
+ char input[] = "\
+%YAML 1.1\n\
+---\n\
+libhtp:\n\
+\n\
+ default-config:\n\
+\n\
+ http-body-inline: yes\n\
+ response-body-minimal-inspect-size: 1\n\
+ response-body-inspect-window: 4\n\
+";
+
+ ConfCreateContextBackup();
+ ConfInit();
+ HtpConfigCreateBackup();
+
+ ConfYamlLoadString(input, strlen(input));
+ HTPConfigure();
+ EngineModeSetIPS();
+ TcpSession ssn;
+ Packet *p1 = NULL;
+ Packet *p2 = NULL;
+ ThreadVars th_v;
+ DetectEngineCtx *de_ctx = NULL;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ HtpState *http_state = NULL;
+ Flow f;
+ uint8_t http_buf1[] =
+ "GET /index.html HTTP/1.0\r\n"
+ "Host: www.openinfosecfoundation.org\r\n"
+ "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
+ "\r\n";
+ uint32_t http_len1 = sizeof(http_buf1) - 1;
+ uint8_t http_buf2[] =
+ "HTTP/1.0 200 ok\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 6\r\n"
+ "\r\n"
+ "123";
+ uint32_t http_len2 = sizeof(http_buf2) - 1;
+ uint8_t http_buf3[] = "456";
+ uint32_t http_len3 = sizeof(http_buf3) - 1;
+
+ int result = 0;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&th_v, 0, sizeof(th_v));
+ memset(&f, 0, sizeof(f));
+ memset(&ssn, 0, sizeof(ssn));
+
+ p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
+ p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p1->flow = &f;
+ p1->flowflags |= FLOW_PKT_TOSERVER;
+ p1->flowflags |= FLOW_PKT_ESTABLISHED;
+ p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p2->flow = &f;
+ p2->flowflags |= FLOW_PKT_TOCLIENT;
+ p2->flowflags |= FLOW_PKT_ESTABLISHED;
+ p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ f.alproto = ALPROTO_HTTP;
+
+ StreamTcpInitConfig(TRUE);
+
+ de_ctx = DetectEngineCtxInit();
+ if (de_ctx == NULL)
+ goto end;
+
+ de_ctx->flags |= DE_QUIET;
+
+ if (!(DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
+ "(msg:\"http server body test\"; "
+ "file_data; content:\"123\"; sid:1;)")))
+ goto end;
+
+ if (!(DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
+ "(msg:\"http server body test\"; "
+ "file_data; content:\"3456\"; sid:2;)")))
+ goto end;
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+ SCMutexLock(&f.m);
+ int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ SCMutexUnlock(&f.m);
+ goto end;
+ }
+ SCMutexUnlock(&f.m);
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: \n");
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+
+ if (PacketAlertCheck(p1, 1)) {
+ printf("sid 1 matched but shouldn't have: ");
+ goto end;
+ }
+
+ SCMutexLock(&f.m);
+ r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ SCMutexUnlock(&f.m);
+ goto end;
+ }
+ SCMutexUnlock(&f.m);
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+
+ if (!PacketAlertCheck(p2, 1)) {
+ printf("sid 1 did not match but should have: ");
+ goto end;
+ }
+
+ SCMutexLock(&f.m);
+ r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf3, http_len3);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ SCMutexUnlock(&f.m);
+ goto end;
+ }
+ SCMutexUnlock(&f.m);
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (!PacketAlertCheck(p2, 2)) {
+ printf("sid 2 did not match but should have: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ SigCleanSignatures(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(TRUE);
+ FLOW_DESTROY(&f);
+ UTHFreePackets(&p1, 1);
+ UTHFreePackets(&p2, 1);
+ EngineModeSetIDS();
+ HTPFreeConfig();
+ ConfDeInit();
+ ConfRestoreContextBackup();
+ HtpConfigRestoreBackup();
+ return result;
+}
+
+/**
+ * in: buffer:
+ * [ab] [ab]
+ * [c] [abc]
+ * [de] [bcde]
+ */
+static int DetectEngineHttpServerBodyFileDataTest07(void)
+{
+
+ char input[] = "\
+%YAML 1.1\n\
+---\n\
+libhtp:\n\
+\n\
+ default-config:\n\
+\n\
+ http-body-inline: yes\n\
+ response-body-minimal-inspect-size: 1\n\
+ response-body-inspect-window: 4\n\
+";
+
+ ConfCreateContextBackup();
+ ConfInit();
+ HtpConfigCreateBackup();
+
+ ConfYamlLoadString(input, strlen(input));
+ HTPConfigure();
+ EngineModeSetIPS();
+ TcpSession ssn;
+ Packet *p1 = NULL;
+ Packet *p2 = NULL;
+ ThreadVars th_v;
+ DetectEngineCtx *de_ctx = NULL;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ HtpState *http_state = NULL;
+ Flow f;
+ uint8_t http_buf1[] =
+ "GET /index.html HTTP/1.0\r\n"
+ "Host: www.openinfosecfoundation.org\r\n"
+ "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
+ "\r\n";
+ uint32_t http_len1 = sizeof(http_buf1) - 1;
+ uint8_t http_buf2[] =
+ "HTTP/1.0 200 ok\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 5\r\n"
+ "\r\n"
+ "ab";
+ uint32_t http_len2 = sizeof(http_buf2) - 1;
+ uint8_t http_buf3[] = "c";
+ uint32_t http_len3 = sizeof(http_buf3) - 1;
+ uint8_t http_buf4[] = "de";
+ uint32_t http_len4 = sizeof(http_buf4) - 1;
+
+ int result = 0;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&th_v, 0, sizeof(th_v));
+ memset(&f, 0, sizeof(f));
+ memset(&ssn, 0, sizeof(ssn));
+
+ p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
+ p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p1->flow = &f;
+ p1->flowflags |= FLOW_PKT_TOSERVER;
+ p1->flowflags |= FLOW_PKT_ESTABLISHED;
+ p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p2->flow = &f;
+ p2->flowflags |= FLOW_PKT_TOCLIENT;
+ p2->flowflags |= FLOW_PKT_ESTABLISHED;
+ p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ f.alproto = ALPROTO_HTTP;
+
+ StreamTcpInitConfig(TRUE);
+
+ de_ctx = DetectEngineCtxInit();
+ if (de_ctx == NULL)
+ goto end;
+
+ de_ctx->flags |= DE_QUIET;
+
+ if (!(DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
+ "(msg:\"http server body test\"; "
+ "file_data; content:\"ab\"; sid:1;)")))
+ goto end;
+
+ if (!(DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
+ "(msg:\"http server body test\"; "
+ "file_data; content:\"abc\"; sid:2;)")))
+ goto end;
+
+ if (!(DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
+ "(msg:\"http server body test\"; "
+ "file_data; content:\"bcde\"; sid:3;)")))
+ goto end;
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+ SCMutexLock(&f.m);
+ int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ SCMutexUnlock(&f.m);
+ goto end;
+ }
+ SCMutexUnlock(&f.m);
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: \n");
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+
+ if (PacketAlertCheck(p1, 1)) {
+ printf("sid 1 matched but shouldn't have: ");
+ goto end;
+ }
+
+ SCMutexLock(&f.m);
+ r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ SCMutexUnlock(&f.m);
+ goto end;
+ }
+ SCMutexUnlock(&f.m);
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+
+ if (!PacketAlertCheck(p2, 1)) {
+ printf("sid 1 did not match but should have: ");
+ goto end;
+ }
+
+ SCMutexLock(&f.m);
+ r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf3, http_len3);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ SCMutexUnlock(&f.m);
+ goto end;
+ }
+ SCMutexUnlock(&f.m);
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (!PacketAlertCheck(p2, 2)) {
+ printf("sid 2 did not match but should have: ");
+ goto end;
+ }
+
+ SCMutexLock(&f.m);
+ r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf4, http_len4);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ SCMutexUnlock(&f.m);
+ goto end;
+ }
+ SCMutexUnlock(&f.m);
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (!PacketAlertCheck(p2, 3)) {
+ printf("sid 2 did not match but should have: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ SigCleanSignatures(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(TRUE);
+ FLOW_DESTROY(&f);
+ UTHFreePackets(&p1, 1);
+ UTHFreePackets(&p2, 1);
+ EngineModeSetIDS();
+ HTPFreeConfig();
+ ConfDeInit();
+ ConfRestoreContextBackup();
+ HtpConfigRestoreBackup();
+ return result;
+}
+
+/**
+ * in: buffer:
+ * [abcd] [abcd]
+ * [efgh] [defgh]
+ */
+static int DetectEngineHttpServerBodyFileDataTest08(void)
+{
+
+ char input[] = "\
+%YAML 1.1\n\
+---\n\
+libhtp:\n\
+\n\
+ default-config:\n\
+\n\
+ http-body-inline: yes\n\
+ response-body-minimal-inspect-size: 1\n\
+ response-body-inspect-window: 4\n\
+";
+
+ ConfCreateContextBackup();
+ ConfInit();
+ HtpConfigCreateBackup();
+
+ ConfYamlLoadString(input, strlen(input));
+ HTPConfigure();
+ EngineModeSetIPS();
+ TcpSession ssn;
+ Packet *p1 = NULL;
+ Packet *p2 = NULL;
+ ThreadVars th_v;
+ DetectEngineCtx *de_ctx = NULL;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ HtpState *http_state = NULL;
+ Flow f;
+ uint8_t http_buf1[] =
+ "GET /index.html HTTP/1.0\r\n"
+ "Host: www.openinfosecfoundation.org\r\n"
+ "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
+ "\r\n";
+ uint32_t http_len1 = sizeof(http_buf1) - 1;
+ uint8_t http_buf2[] =
+ "HTTP/1.0 200 ok\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 8\r\n"
+ "\r\n"
+ "abcd";
+ uint32_t http_len2 = sizeof(http_buf2) - 1;
+ uint8_t http_buf3[] = "efgh";
+ uint32_t http_len3 = sizeof(http_buf3) - 1;
+
+ int result = 0;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&th_v, 0, sizeof(th_v));
+ memset(&f, 0, sizeof(f));
+ memset(&ssn, 0, sizeof(ssn));
+
+ p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
+ p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p1->flow = &f;
+ p1->flowflags |= FLOW_PKT_TOSERVER;
+ p1->flowflags |= FLOW_PKT_ESTABLISHED;
+ p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p2->flow = &f;
+ p2->flowflags |= FLOW_PKT_TOCLIENT;
+ p2->flowflags |= FLOW_PKT_ESTABLISHED;
+ p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ f.alproto = ALPROTO_HTTP;
+
+ StreamTcpInitConfig(TRUE);
+
+ de_ctx = DetectEngineCtxInit();
+ if (de_ctx == NULL)
+ goto end;
+
+ de_ctx->flags |= DE_QUIET;
+
+ if (!(DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
+ "(msg:\"http server body test\"; "
+ "file_data; content:\"abcd\"; sid:1;)")))
+ goto end;
+
+ if (!(DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
+ "(msg:\"http server body test\"; "
+ "file_data; content:\"defgh\"; sid:2;)")))
+ goto end;
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+ SCMutexLock(&f.m);
+ int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ SCMutexUnlock(&f.m);
+ goto end;
+ }
+ SCMutexUnlock(&f.m);
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: \n");
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+
+ if (PacketAlertCheck(p1, 1)) {
+ printf("sid 1 matched but shouldn't have: ");
+ goto end;
+ }
+
+ SCMutexLock(&f.m);
+ r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ SCMutexUnlock(&f.m);
+ goto end;
+ }
+ SCMutexUnlock(&f.m);
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+
+ if (!PacketAlertCheck(p2, 1)) {
+ printf("sid 1 did not match but should have: ");
+ goto end;
+ }
+
+ SCMutexLock(&f.m);
+ r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf3, http_len3);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ SCMutexUnlock(&f.m);
+ goto end;
+ }
+ SCMutexUnlock(&f.m);
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (!PacketAlertCheck(p2, 2)) {
+ printf("sid 2 did not match but should have: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ SigCleanSignatures(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(TRUE);
+ FLOW_DESTROY(&f);
+ UTHFreePackets(&p1, 1);
+ UTHFreePackets(&p2, 1);
+ EngineModeSetIDS();
+ HTPFreeConfig();
+ ConfDeInit();
+ ConfRestoreContextBackup();
+ HtpConfigRestoreBackup();
+ return result;
+}
+
+/**
+ * in: buffer:
+ * [a] [a]
+ * [b] [ab]
+ * [c] [abc]
+ * [d] [abcd]
+ * [efghijklm] [defghijklm]
+ */
+static int DetectEngineHttpServerBodyFileDataTest09(void)
+{
+
+ char input[] = "\
+%YAML 1.1\n\
+---\n\
+libhtp:\n\
+\n\
+ default-config:\n\
+\n\
+ http-body-inline: yes\n\
+ response-body-minimal-inspect-size: 1\n\
+ response-body-inspect-window: 4\n\
+";
+
+ ConfCreateContextBackup();
+ ConfInit();
+ HtpConfigCreateBackup();
+
+ ConfYamlLoadString(input, strlen(input));
+ HTPConfigure();
+ EngineModeSetIPS();
+ TcpSession ssn;
+ Packet *p1 = NULL;
+ Packet *p2 = NULL;
+ ThreadVars th_v;
+ DetectEngineCtx *de_ctx = NULL;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ HtpState *http_state = NULL;
+ Flow f;
+ uint8_t http_buf1[] =
+ "GET /index.html HTTP/1.0\r\n"
+ "Host: www.openinfosecfoundation.org\r\n"
+ "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
+ "\r\n";
+ uint32_t http_len1 = sizeof(http_buf1) - 1;
+ uint8_t http_buf2[] =
+ "HTTP/1.0 200 ok\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 13\r\n"
+ "\r\n"
+ "a";
+ uint32_t http_len2 = sizeof(http_buf2) - 1;
+ uint8_t http_buf3[] = "b";
+ uint32_t http_len3 = sizeof(http_buf3) - 1;
+ uint8_t http_buf4[] = "c";
+ uint32_t http_len4 = sizeof(http_buf4) - 1;
+ uint8_t http_buf5[] = "d";
+ uint32_t http_len5 = sizeof(http_buf5) - 1;
+ uint8_t http_buf6[] = "efghijklm";
+ uint32_t http_len6 = sizeof(http_buf6) - 1;
+
+ int result = 0;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&th_v, 0, sizeof(th_v));
+ memset(&f, 0, sizeof(f));
+ memset(&ssn, 0, sizeof(ssn));
+
+ p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
+ p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p1->flow = &f;
+ p1->flowflags |= FLOW_PKT_TOSERVER;
+ p1->flowflags |= FLOW_PKT_ESTABLISHED;
+ p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p2->flow = &f;
+ p2->flowflags |= FLOW_PKT_TOCLIENT;
+ p2->flowflags |= FLOW_PKT_ESTABLISHED;
+ p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ f.alproto = ALPROTO_HTTP;
+
+ StreamTcpInitConfig(TRUE);
+
+ de_ctx = DetectEngineCtxInit();
+ if (de_ctx == NULL)
+ goto end;
+
+ de_ctx->flags |= DE_QUIET;
+
+ if (!(DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
+ "(msg:\"http server body test\"; "
+ "file_data; content:\"abcd\"; sid:1;)")))
+ goto end;
+
+ if (!(DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
+ "(msg:\"http server body test\"; "
+ "file_data; content:\"defghijklm\"; sid:2;)")))
+ goto end;
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+ SCMutexLock(&f.m);
+ int r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_len1);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ SCMutexUnlock(&f.m);
+ goto end;
+ }
+ SCMutexUnlock(&f.m);
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: \n");
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+
+ if (PacketAlertCheck(p1, 1)) {
+ printf("sid 1 matched but shouldn't have: ");
+ goto end;
+ }
+
+ SCMutexLock(&f.m);
+ r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf2, http_len2);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ SCMutexUnlock(&f.m);
+ goto end;
+ }
+ SCMutexUnlock(&f.m);
+
+ SCMutexLock(&f.m);
+ r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf3, http_len3);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ SCMutexUnlock(&f.m);
+ goto end;
+ }
+ SCMutexUnlock(&f.m);
+
+ SCMutexLock(&f.m);
+ r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf4, http_len4);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ SCMutexUnlock(&f.m);
+ goto end;
+ }
+ SCMutexUnlock(&f.m);
+
+ SCMutexLock(&f.m);
+ r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf5, http_len5);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ SCMutexUnlock(&f.m);
+ goto end;
+ }
+ SCMutexUnlock(&f.m);
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (!PacketAlertCheck(p2, 1)) {
+ printf("sid 1 did not match but should have: ");
+ goto end;
+ }
+
+ SCMutexLock(&f.m);
+ r = AppLayerParserParse(alp_tctx, &f, ALPROTO_HTTP, STREAM_TOCLIENT, http_buf6, http_len6);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ SCMutexUnlock(&f.m);
+ goto end;
+ }
+ SCMutexUnlock(&f.m);
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (!PacketAlertCheck(p2, 2)) {
+ printf("sid 1 did not match but should have: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ SigCleanSignatures(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(TRUE);
+ FLOW_DESTROY(&f);
+ UTHFreePackets(&p1, 1);
+ UTHFreePackets(&p2, 1);
+ EngineModeSetIDS();
+ HTPFreeConfig();
+ ConfDeInit();
+ ConfRestoreContextBackup();
+ HtpConfigRestoreBackup();
+ return result;
+}
#endif /* UNITTESTS */
void DetectEngineHttpServerBodyRegisterTests(void)
DetectEngineHttpServerBodyFileDataTest02, 1);
UtRegisterTest("DetectEngineHttpServerBodyFileDataTest03",
DetectEngineHttpServerBodyFileDataTest03, 1);
+ UtRegisterTest("DetectEngineHttpServerBodyFileDataTest04",
+ DetectEngineHttpServerBodyFileDataTest04, 1);
+ UtRegisterTest("DetectEngineHttpServerBodyFileDataTest05",
+ DetectEngineHttpServerBodyFileDataTest05, 1);
+ UtRegisterTest("DetectEngineHttpServerBodyFileDataTest06",
+ DetectEngineHttpServerBodyFileDataTest06, 1);
+ UtRegisterTest("DetectEngineHttpServerBodyFileDataTest07",
+ DetectEngineHttpServerBodyFileDataTest07, 1);
+ UtRegisterTest("DetectEngineHttpServerBodyFileDataTest08",
+ DetectEngineHttpServerBodyFileDataTest08, 1);
+ UtRegisterTest("DetectEngineHttpServerBodyFileDataTest09",
+ DetectEngineHttpServerBodyFileDataTest09, 1);
#endif /* UNITTESTS */
return;