From b9bcd4e115b32a28f5808df2abede342c8190909 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Wed, 28 Nov 2018 08:53:41 +0100 Subject: [PATCH] detect/http_header: move tests into tests/ --- src/detect-http-header.c | 5393 +------------------------------- src/tests/detect-http-header.c | 5244 +++++++++++++++++++++++++++++++ 2 files changed, 5250 insertions(+), 5387 deletions(-) create mode 100644 src/tests/detect-http-header.c diff --git a/src/detect-http-header.c b/src/detect-http-header.c index 2219cddf1e..b38f829593 100644 --- a/src/detect-http-header.c +++ b/src/detect-http-header.c @@ -44,14 +44,7 @@ #include "detect-content.h" #include "detect-pcre.h" -#include "flow.h" -#include "flow-var.h" -#include "flow-util.h" - #include "util-debug.h" -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "util-spm.h" #include "util-print.h" #include "util-memcmp.h" @@ -61,10 +54,11 @@ #include "app-layer-htp.h" #include "detect-http-header.h" #include "detect-http-header-common.h" -#include "stream-tcp.h" static int DetectHttpHeaderSetup(DetectEngineCtx *, Signature *, const char *); +#ifdef UNITTESTS static void DetectHttpHeaderRegisterTests(void); +#endif static int g_http_header_buffer_id = 0; static int g_keyword_thread_id = 0; @@ -399,8 +393,9 @@ void DetectHttpHeaderRegister(void) sigmatch_table[DETECT_AL_HTTP_HEADER].desc = "content modifier to match only on the HTTP header-buffer"; sigmatch_table[DETECT_AL_HTTP_HEADER].url = DOC_URL DOC_VERSION "/rules/http-keywords.html#http-header-and-http-raw-header"; sigmatch_table[DETECT_AL_HTTP_HEADER].Setup = DetectHttpHeaderSetup; +#ifdef UNITTESTS sigmatch_table[DETECT_AL_HTTP_HEADER].RegisterTests = DetectHttpHeaderRegisterTests; - +#endif sigmatch_table[DETECT_AL_HTTP_HEADER].flags |= SIGMATCH_NOOPT ; DetectAppLayerInspectEngineRegister2("http_header", ALPROTO_HTTP, @@ -429,5385 +424,9 @@ void DetectHttpHeaderRegister(void) /************************************Unittests*********************************/ #ifdef UNITTESTS +#include "tests/detect-http-header.c" +#endif -#include "detect-isdataat.h" -#include "stream-tcp-reassemble.h" - -/** - * \test Test that a signature containting a http_header is correctly parsed - * and the keyword is registered. - */ -static int DetectHttpHeaderTest01(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - SigMatch *sm = NULL; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_header\"; " - "content:\"one\"; http_header; sid:1;)"); - if (de_ctx->sig_list != NULL) { - result = 1; - } else { - printf("Error parsing signature: "); - goto end; - } - - sm = de_ctx->sig_list->sm_lists[g_http_header_buffer_id]; - if (sm != NULL) { - result &= (sm->type == DETECT_CONTENT); - result &= (sm->next == NULL); - } else { - result = 0; - printf("Error updating content pattern to http_header pattern: "); - } - - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that a signature containing an valid http_header entry is - * parsed. - */ -static int DetectHttpHeaderTest02(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_header\"; " - "content:\"one\"; http_header:; sid:1;)"); - if (de_ctx->sig_list != NULL) - result = 1; - else - printf("Error parsing signature: "); - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that an invalid signature containing no content but a http_header - * is invalidated. - */ -static int DetectHttpHeaderTest03(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_header\"; " - "http_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - result = 1; - else - printf("Error parsing signature: "); - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that an invalid signature containing a rawbytes along with a - * http_header is invalidated. - */ -static int DetectHttpHeaderTest04(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_header\"; " - "content:\"one\"; rawbytes; http_header; sid:1;)"); - if (de_ctx->sig_list == NULL) - result = 1; - else - printf("Error parsing signature: "); - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - * \test Test that an invalid signature containing a rawbytes along with a - * http_header is invalidated. - */ -static int DetectHttpHeaderTest05(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_header\"; " - "content:\"one\"; nocase; http_header; sid:1;)"); - if (de_ctx->sig_list != NULL) - result = 1; - else - printf("Error parsing signature: "); - - end: - SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectHttpHeaderTest06(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "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" - "Content-Type: text/html\r\n" - "Content-Length: 26\r\n" - "\r\n" - "This is dummy message body\r\n"; - uint32_t http_len = sizeof(http_buf) - 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)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"Content-Type: text/html\"; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't 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(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectHttpHeaderTest07(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - Packet *p2 = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n" - "User-Agent: Mozi"; - uint8_t http2_buf[] = - "lla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\nContent-Type: text/html\r\n" - "Content-Length: 67\r\n" - "\r\n" - "This is dummy message body1"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - FAIL_IF_NULL(alp_tctx); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - FAIL_IF_NULL(p1); - p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - FAIL_IF_NULL(p2); - - 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_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - FAIL_IF_NULL(de_ctx); - de_ctx->flags |= DE_QUIET; - - Signature *s = DetectEngineAppendSig(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"Mozilla\"; http_header; " - "sid:1;)"); - FAIL_IF_NULL(s); - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - FAIL_IF_NULL(det_ctx); - - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http1_buf, http1_len); - FAIL_IF(r != 0); - - HtpState *http_state = f.alstate; - FAIL_IF_NULL(http_state); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - FAIL_IF( (PacketAlertCheck(p1, 1))); - - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http2_buf, http2_len); - FAIL_IF(r != 0); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - FAIL_IF(!(PacketAlertCheck(p2, 1))); - - AppLayerParserThreadCtxFree(alp_tctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - PASS; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectHttpHeaderTest08(void) -{ - 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 http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.openinfosecfoundation.org\r\n"; - uint8_t http2_buf[] = - "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 67\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 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_TOSERVER; - 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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"Gecko/20091221 Firefox/3.5.7\"; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - FLOWLOCK_WRLOCK(&f); - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't 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); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content, against a cross boundary present pattern. - */ -static int DetectHttpHeaderTest09(void) -{ - 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 http1_buf[] = - "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"; - uint8_t http2_buf[] = - "Content-Type: text/html\r\n" - "Content-Length: 67\r\n" - "\r\n" - "This is dummy body\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 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_TOSERVER; - 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; - de_ctx->mpm_matcher = mpm_default_matcher; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"Firefox/3.5.7|0D 0A|Content\"; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - 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; - } - - FLOWLOCK_WRLOCK(&f); - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't 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); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * against a case insensitive pattern. - */ -static int DetectHttpHeaderTest10(void) -{ - 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 http1_buf[] = - "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"; - uint8_t http2_buf[] = - "Content-Type: text/html\r\n" - "Content-Length: 67\r\n" - "\r\n" - "This is dummy body"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 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_TOSERVER; - 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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"firefox/3.5.7|0D 0A|content\"; nocase; http_header;" - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - if ((PacketAlertCheck(p1, 1))) { - printf("sid 1 didn't match but should have: "); - goto end; - } - - FLOWLOCK_WRLOCK(&f); - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!(PacketAlertCheck(p2, 1))) { - printf("sid 1 didn't 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); - return result; -} - -/** - *\test Test that the negated http_header content matches against a - * http request which doesn't hold the content. - */ -static int DetectHttpHeaderTest11(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "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" - "Content-Type: text/html\r\n" - "Content-Length: 26\r\n" - "\r\n" - "This is dummy message body\r\n"; - uint32_t http_len = sizeof(http_buf) - 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)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:!\"lalalalala\"; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't 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(&p, 1); - return result; -} - -/** - *\test Negative test that the negated http_header content matches against a - * http request which holds hold the content. - */ -static int DetectHttpHeaderTest12(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "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" - "Content-Type: text/html\r\n" - "Content-Length: 26\r\n" - "\r\n" - "This is dummy message body\r\n"; - uint32_t http_len = sizeof(http_buf) - 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)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:!\"User-Agent: Mozilla/5.0 \"; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if ((PacketAlertCheck(p, 1))) { - printf("sid 1 didn't 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(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectHttpHeaderTest13(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "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" - "Content-Type: text/html\r\n" - "Content-Length: 100\r\n" - "\r\n" - "longbufferabcdefghijklmnopqrstuvwxyz0123456789bufferend\r\n"; - uint32_t http_len = sizeof(http_buf) - 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)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"Host: www.openinfosecfoundation.org\"; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't 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(&p, 1); - return result; -} - -static int DetectHttpHeaderTest20(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; " - "content:\"two\"; distance:0; http_header; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL) { - printf("de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL\n"); - goto end; - } - - DetectContentData *hhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->ctx; - DetectContentData *hhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->ctx; - if (hhd1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(hhd1->content, "one", hhd1->content_len) != 0 || - hhd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(hhd2->content, "two", hhd1->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -static int DetectHttpHeaderTest21(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; " - "content:\"two\"; within:5; http_header; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL) { - printf("de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL\n"); - goto end; - } - - DetectContentData *hhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->ctx; - DetectContentData *hhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->ctx; - if (hhd1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(hhd1->content, "one", hhd1->content_len) != 0 || - hhd2->flags != DETECT_CONTENT_WITHIN || - memcmp(hhd2->content, "two", hhd1->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -static int DetectHttpHeaderTest22(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; within:5; http_header; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -static int DetectHttpHeaderTest23(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; http_header; within:5; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -static int DetectHttpHeaderTest24(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"one\"; within:5; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -static int DetectHttpHeaderTest25(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(pcre:/one/H; " - "content:\"two\"; within:5; http_header; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL) { - printf("de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id] == NULL || - de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->type != DETECT_CONTENT || - de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev == NULL || - de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->type != DETECT_PCRE) { - - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->ctx; - DetectContentData *hhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->ctx; - if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) || - hhd2->flags != DETECT_CONTENT_WITHIN || - memcmp(hhd2->content, "two", hhd2->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -static int DetectHttpHeaderTest26(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(content:\"two\"; http_header; " - "pcre:/one/HR; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL) { - printf("de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id] == NULL || - de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->type != DETECT_PCRE || - de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev == NULL || - de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->type != DETECT_CONTENT) { - - goto end; - } - - DetectContentData *hhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->ctx; - DetectPcreData *pd2 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->ctx; - if (pd2->flags != (DETECT_PCRE_RELATIVE) || - hhd1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(hhd1->content, "two", hhd1->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -static int DetectHttpHeaderTest27(void) -{ - DetectEngineCtx *de_ctx = NULL; - int result = 0; - - if ( (de_ctx = DetectEngineCtxInit()) == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " - "(pcre:/one/H; " - "content:\"two\"; distance:5; http_header; sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("de_ctx->sig_list == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { - printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL) { - printf("de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id] == NULL || - de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->type != DETECT_CONTENT || - de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev == NULL || - de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->type != DETECT_PCRE) { - - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->ctx; - DetectContentData *hhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->ctx; - if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) || - hhd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(hhd2->content, "two", hhd2->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test app-layer-event:http.host_header_ambiguous should not be set - * \bug 640*/ -static int DetectHttpHeaderTest28(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - uint8_t http_buf[] = - "POST http://xxx.intranet.local:8000/xxx HTTP/1.1\r\n" - "User-Agent: Mozilla/4.0 (Windows XP 5.1) Java/1.6.0_29\r\n" - "Host: xxx.intranet.local:8000\r\n" - "\r\n"; - uint32_t http_len = sizeof(http_buf) - 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)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(app-layer-event:http.host_header_ambiguous; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldnt 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(&p, 1); - return result; -} - -/** \test app-layer-event:http.host_header_ambiguous should be set - * \bug 640*/ -static int DetectHttpHeaderTest29(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - uint8_t http_buf[] = - "POST http://xxx.intranet.local:8001/xxx HTTP/1.1\r\n" - "User-Agent: Mozilla/4.0 (Windows XP 5.1) Java/1.6.0_29\r\n" - "Host: xxx.intranet.local:8000\r\n" - "\r\n"; - uint32_t http_len = sizeof(http_buf) - 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)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(app-layer-event:http.host_header_ambiguous; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't 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(&p, 1); - return result; -} - -/** \test app-layer-event:http.host_header_ambiguous should be set - * \bug 640*/ -static int DetectHttpHeaderTest30(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - Flow f; - uint8_t http_buf[] = - "POST http://xxx.intranet.local:8000/xxx HTTP/1.1\r\n" - "User-Agent: Mozilla/4.0 (Windows XP 5.1) Java/1.6.0_29\r\n" - "Host: xyz.intranet.local:8000\r\n" - "\r\n"; - uint32_t http_len = sizeof(http_buf) - 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)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(app-layer-event:http.host_header_ambiguous; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't 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(&p, 1); - return result; -} - -static int DetectHttpHeaderIsdataatParseTest(void) -{ - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - FAIL_IF_NULL(de_ctx); - de_ctx->flags |= DE_QUIET; - - Signature *s = DetectEngineAppendSig(de_ctx, - "alert tcp any any -> any any (" - "flow:to_server; " - "content:\"one\"; http_header; " - "isdataat:!4,relative; sid:1;)"); - FAIL_IF_NULL(s); - - SigMatch *sm = s->init_data->smlists_tail[g_http_header_buffer_id]; - FAIL_IF_NULL(sm); - FAIL_IF_NOT(sm->type == DETECT_ISDATAAT); - - DetectIsdataatData *data = (DetectIsdataatData *)sm->ctx; - FAIL_IF_NOT(data->flags & ISDATAAT_RELATIVE); - FAIL_IF_NOT(data->flags & ISDATAAT_NEGATED); - FAIL_IF(data->flags & ISDATAAT_RAWBYTES); - - DetectEngineCtxFree(de_ctx); - PASS; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest01(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 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)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"one\"; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't 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(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest02(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 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)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"one\"; depth:15; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't 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(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest03(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 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)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:!\"one\"; depth:5; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't 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(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest04(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 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)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"one\"; depth:5; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't 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(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest05(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 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)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:!\"one\"; depth:15; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't 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(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest06(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 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)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"one\"; offset:10; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't 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(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest07(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 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)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:!\"one\"; offset:15; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't 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(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest08(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 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)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"one\"; offset:15; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't 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(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest09(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 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)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:!\"one\"; offset:10; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't 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(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest10(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 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)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"one\"; http_header; content:\"three\"; http_header; within:10; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't 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(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest11(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 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)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"one\"; http_header; content:!\"three\"; http_header; within:5; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't 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(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest12(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 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)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"one\"; http_header; content:!\"three\"; http_header; within:10; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't 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(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest13(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 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)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"one\"; http_header; content:\"three\"; http_header; within:5; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't 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(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest14(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 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)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"one\"; http_header; content:\"five\"; http_header; distance:7; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't 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(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest15(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 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)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"one\"; http_header; content:!\"five\"; http_header; distance:15; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (!(PacketAlertCheck(p, 1))) { - printf("sid 1 didn't 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(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest16(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 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)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"one\"; http_header; content:!\"five\"; http_header; distance:7; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't 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(&p, 1); - return result; -} - -/** - *\test Test that the http_header content matches against a http request - * which holds the content. - */ -static int DetectEngineHttpHeaderTest17(void) -{ - TcpSession ssn; - Packet *p = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; - uint32_t http_len = sizeof(http_buf) - 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)); - - p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - - FLOW_INITIALIZE(&f); - f.protoctx = (void *)&ssn; - f.proto = IPPROTO_TCP; - f.flags |= FLOW_IPV4; - p->flow = &f; - p->flowflags |= FLOW_PKT_TOSERVER; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"one\"; http_header; content:\"five\"; http_header; distance:15; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf, http_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - http_state = f.alstate; - if (http_state == NULL) { - printf("no http state: "); - result = 0; - goto end; - } - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p); - - if (PacketAlertCheck(p, 1)) { - printf("sid 1 matched but shouldn't 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(&p, 1); - return result; -} - -static int DetectEngineHttpHeaderTest20(void) -{ - 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 http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: This_is_dummy_body1"; - uint8_t http2_buf[] = - "This_is_dummy_message_body2\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 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_TOSERVER; - 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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "pcre:/body1/H; " - "content:!\"dummy\"; http_header; within:7; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - 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\n"); - goto end; - } - - FLOWLOCK_WRLOCK(&f); - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but shouldn't 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); - return result; -} - -static int DetectEngineHttpHeaderTest21(void) -{ - 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 http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: This_is_dummy_body1"; - uint8_t http2_buf[] = - "This_is_dummy_message_body2\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 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_TOSERVER; - 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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "pcre:/body1/H; " - "content:!\"dummy\"; within:7; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - 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\n"); - goto end; - } - - FLOWLOCK_WRLOCK(&f); - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't match but shouldn't 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); - return result; -} - -static int DetectEngineHttpHeaderTest22(void) -{ - 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 http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: This_is_dummy_body1"; - uint8_t http2_buf[] = - "This_is_dummy_message_body2\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 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_TOSERVER; - 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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "pcre:/body1/H; " - "content:!\"dummy\"; distance:3; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - 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\n"); - goto end; - } - - FLOWLOCK_WRLOCK(&f); - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't 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); - return result; -} - -static int DetectEngineHttpHeaderTest23(void) -{ - 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 http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: This_is_dummy_body1"; - uint8_t http2_buf[] = - "This_is_dummy_message_body2\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 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_TOSERVER; - 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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "pcre:/body1/H; " - "content:!\"dummy\"; distance:13; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - 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\n"); - goto end; - } - - FLOWLOCK_WRLOCK(&f); - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't 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); - return result; -} - -static int DetectEngineHttpHeaderTest24(void) -{ - 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 http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: This_is_dummy_body1"; - uint8_t http2_buf[] = - "This_is_dummy_message_body2\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 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_TOSERVER; - 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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "pcre:/body1/H; " - "content:\"dummy\"; within:15; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - 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\n"); - goto end; - } - - FLOWLOCK_WRLOCK(&f); - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't 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); - return result; -} - -static int DetectEngineHttpHeaderTest25(void) -{ - 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 http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: This_is_dummy_body1"; - uint8_t http2_buf[] = - "This_is_dummy_message_body2\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 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_TOSERVER; - 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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "pcre:/body1/H; " - "content:\"dummy\"; within:10; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - 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\n"); - goto end; - } - - FLOWLOCK_WRLOCK(&f); - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't 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); - return result; -} - -static int DetectEngineHttpHeaderTest26(void) -{ - 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 http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: This_is_dummy_body1"; - uint8_t http2_buf[] = - "This_is_dummy_message_body2\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 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_TOSERVER; - 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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "pcre:/body1/H; " - "content:\"dummy\"; distance:8; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - 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\n"); - goto end; - } - - FLOWLOCK_WRLOCK(&f); - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (!PacketAlertCheck(p2, 1)) { - printf("sid 1 didn't 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); - return result; -} - -static int DetectEngineHttpHeaderTest27(void) -{ - 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 http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Host: This_is_dummy_body1"; - uint8_t http2_buf[] = - "This_is_dummy_message_body2\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 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_TOSERVER; - 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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http client body test\"; " - "pcre:/body1/H; " - "content:\"dummy\"; distance:14; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - 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\n"); - goto end; - } - - FLOWLOCK_WRLOCK(&f); - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http2_buf, http2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't 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); - return result; -} - -static int DetectEngineHttpHeaderTest28(void) -{ - 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_buf1_len = 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" - "abcdef"; - uint32_t http_buf2_len = sizeof(http_buf2) - 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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"Content-Length: 6\"; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - 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\n"); - goto end; - } - - FLOWLOCK_WRLOCK(&f); - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOCLIENT, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - FAIL_IF(!PacketAlertCheck(p2, 1)); - - 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); - return result; -} - -static int DetectEngineHttpHeaderTest29(void) -{ - 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_buf1_len = 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" - "abcdef"; - uint32_t http_buf2_len = sizeof(http_buf2) - 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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"Content-Length: 7\"; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - 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\n"); - goto end; - } - - FLOWLOCK_WRLOCK(&f); - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOCLIENT, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't 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); - return result; -} - -#if 0 - -static int DetectEngineHttpHeaderTest30(void) -{ - int result = 0; - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - - if (de_ctx == NULL) { - goto end; - } - - de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"Content-Length: 6\"; http_header; " - "content:\"User-Agent: Mozilla\"; http_header; " - "sid:1;)"); - if (de_ctx->sig_list != NULL) { - goto end; - } - - result = 1; - - end: - if (de_ctx != NULL) - SigCleanSignatures(de_ctx); - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -#endif /* #if 0 */ - -static int DetectEngineHttpHeaderTest30(void) -{ - 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_buf1_len = sizeof(http_buf1) - 1; - uint8_t http_buf2[] = - "HTTP/1.0 200 ok\r\n" - "Set-Cookie: dummycookieset\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 6\r\n" - "\r\n" - "abcdef"; - uint32_t http_buf2_len = sizeof(http_buf2) - 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; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; " - "content:\"dummycookieset\"; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http_buf1, http_buf1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - 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\n"); - goto end; - } - - FLOWLOCK_WRLOCK(&f); - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOCLIENT, http_buf2, http_buf2_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - if (PacketAlertCheck(p2, 1)) { - printf("sid 1 matched but shouldn't have\n"); - 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); - return result; -} - -/** \test reassembly bug where headers with names of length 6 were - * skipped - */ -static int DetectEngineHttpHeaderTest31(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "Accept: blah\r\n" - "Cookie: blah\r\n" - "Crazy6: blah\r\n" - "SixZix: blah\r\n\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 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); - - 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; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(content:\"Accept|3a|\"; http_header; " - "content:!\"Cookie|3a|\"; http_header; " - "content:\"Crazy6|3a|\"; http_header; " - "content:\"SixZix|3a|\"; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - 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 didn't 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); - return result; -} - -/** - * \test Trailing headers. - */ -static int DetectEngineHttpHeaderTest32(void) -{ - TcpSession ssn; - Packet *p1 = NULL; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "host: boom\r\n" - "Transfer-Encoding: chunked\r\n" - "\r\n" - "13\r\n" - "This is dummy body1\r\n" - "0\r\n" - "Dummy-Header: kaboom\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 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); - - 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; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) - goto end; - - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(content:\"Dummy\"; http_header; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - FLOWLOCK_WRLOCK(&f); - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http1_buf, http1_len); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - FLOWLOCK_UNLOCK(&f); - - 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 didn't 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); - return result; -} - -/** - * \test Trailing headers. - */ -static int DetectEngineHttpHeaderTest33(void) -{ - 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 http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "host: boom\r\n" - "Transfer-Encoding: chunked\r\n" - "\r\n" - "13\r\n" - "This is dummy body1\r\n" - "0\r\n"; - uint8_t http2_buf[] = - "Dummy-Header: kaboom\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - FAIL_IF_NULL(alp_tctx); - - 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_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - FAIL_IF(de_ctx == NULL); - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(content:\"Dummy\"; http_header; " - "sid:1;)"); - FAIL_IF(de_ctx->sig_list == NULL); - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http1_buf, http1_len); - FAIL_IF_NOT(r == 0); - - http_state = f.alstate; - FAIL_IF(http_state == NULL); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - - FAIL_IF(PacketAlertCheck(p1, 1)); - - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http2_buf, http2_len); - FAIL_IF_NOT(r == 0); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - - FAIL_IF(!PacketAlertCheck(p2, 1)); - - AppLayerParserThreadCtxFree(alp_tctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - PASS; -} - -/** - * \test Trailing headers. - */ -static int DetectEngineHttpHeaderTest34(void) -{ - TcpSession ssn; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "host: boom\r\n" - "Dummy-Header1: blah\r\n" - "Transfer-Encoding: chunked\r\n" - "\r\n"; - uint8_t http2_buf[] = - "13\r\n" - "This is dummy body1\r\n" - "0\r\n"; - uint8_t http3_buf[] = - "Dummy-Header2: kaboom\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - uint32_t http3_len = sizeof(http3_buf) - 1; - - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - FAIL_IF_NULL(alp_tctx); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - Packet *p3 = 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; - p1->pcap_cnt = 1; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->pcap_cnt = 2; - p3->flow = &f; - p3->flowflags |= FLOW_PKT_TOSERVER; - p3->flowflags |= FLOW_PKT_ESTABLISHED; - p3->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p3->pcap_cnt = 3; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - FAIL_IF(de_ctx == NULL); - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(content:\"Dummy\"; http_header; content:\"Header2\"; http_header; within:8; " - "sid:1;)"); - FAIL_IF(de_ctx->sig_list == NULL); - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http1_buf, http1_len); - FAIL_IF_NOT(r == 0); - - http_state = f.alstate; - FAIL_IF(http_state == NULL); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - FAIL_IF(PacketAlertCheck(p1, 1)); - - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http2_buf, http2_len); - FAIL_IF_NOT(r == 0); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - FAIL_IF(PacketAlertCheck(p2, 1)); - - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http3_buf, http3_len); - FAIL_IF_NOT(r == 0); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p3); - FAIL_IF(!PacketAlertCheck(p3, 1)); /* should match in trailer */ - - AppLayerParserThreadCtxFree(alp_tctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - UTHFreePackets(&p3, 1); - PASS; -} - -/** - * \test Trailing headers. - */ -static int DetectEngineHttpHeaderTest35(void) -{ - TcpSession ssn; - ThreadVars th_v; - DetectEngineCtx *de_ctx = NULL; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - Flow f; - uint8_t http1_buf[] = - "GET /index.html HTTP/1.0\r\n" - "host: boom\r\n" - "Dummy-Header1: blah\r\n" - "Transfer-Encoding: chunked\r\n" - "\r\n"; - uint8_t http2_buf[] = - "13\r\n" - "This is dummy body1\r\n" - "0\r\n"; - uint8_t http3_buf[] = - "Dummy-Header2: kaboom\r\n" - "\r\n"; - uint32_t http1_len = sizeof(http1_buf) - 1; - uint32_t http2_len = sizeof(http2_buf) - 1; - uint32_t http3_len = sizeof(http3_buf) - 1; - - AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); - FAIL_IF_NULL(alp_tctx); - - memset(&th_v, 0, sizeof(th_v)); - memset(&f, 0, sizeof(f)); - memset(&ssn, 0, sizeof(ssn)); - - Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); - Packet *p3 = 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; - p1->pcap_cnt = 1; - p2->flow = &f; - p2->flowflags |= FLOW_PKT_TOSERVER; - p2->flowflags |= FLOW_PKT_ESTABLISHED; - p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p2->pcap_cnt = 2; - p3->flow = &f; - p3->flowflags |= FLOW_PKT_TOSERVER; - p3->flowflags |= FLOW_PKT_ESTABLISHED; - p3->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - p3->pcap_cnt = 3; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - de_ctx = DetectEngineCtxInit(); - FAIL_IF(de_ctx == NULL); - de_ctx->flags |= DE_QUIET; - - de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(content:\"Dummy\"; http_header; fast_pattern; content:\"Header2\"; http_header; within:8; " - "sid:1;)"); - FAIL_IF(de_ctx->sig_list == NULL); - - SigGroupBuild(de_ctx); - DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); - - int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http1_buf, http1_len); - FAIL_IF_NOT(r == 0); - - http_state = f.alstate; - FAIL_IF(http_state == NULL); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); - FAIL_IF(PacketAlertCheck(p1, 1)); - - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http2_buf, http2_len); - FAIL_IF_NOT(r == 0); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); - FAIL_IF(PacketAlertCheck(p2, 1)); - - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOSERVER, http3_buf, http3_len); - FAIL_IF_NOT(r == 0); - - /* do detect */ - SigMatchSignatures(&th_v, de_ctx, det_ctx, p3); - FAIL_IF(!PacketAlertCheck(p3, 1)); /* should match in trailer */ - - AppLayerParserThreadCtxFree(alp_tctx); - DetectEngineCtxFree(de_ctx); - - StreamTcpFreeConfig(TRUE); - FLOW_DESTROY(&f); - UTHFreePackets(&p1, 1); - UTHFreePackets(&p2, 1); - UTHFreePackets(&p3, 1); - PASS; -} - -#endif /* UNITTESTS */ - -void DetectHttpHeaderRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectHttpHeaderTest01", DetectHttpHeaderTest01); - UtRegisterTest("DetectHttpHeaderTest02", DetectHttpHeaderTest02); - UtRegisterTest("DetectHttpHeaderTest03", DetectHttpHeaderTest03); - UtRegisterTest("DetectHttpHeaderTest04", DetectHttpHeaderTest04); - UtRegisterTest("DetectHttpHeaderTest05", DetectHttpHeaderTest05); - UtRegisterTest("DetectHttpHeaderTest06", DetectHttpHeaderTest06); - UtRegisterTest("DetectHttpHeaderTest07", DetectHttpHeaderTest07); - UtRegisterTest("DetectHttpHeaderTest08", DetectHttpHeaderTest08); - UtRegisterTest("DetectHttpHeaderTest09", DetectHttpHeaderTest09); - UtRegisterTest("DetectHttpHeaderTest10", DetectHttpHeaderTest10); - UtRegisterTest("DetectHttpHeaderTest11", DetectHttpHeaderTest11); - UtRegisterTest("DetectHttpHeaderTest12", DetectHttpHeaderTest12); - UtRegisterTest("DetectHttpHeaderTest13", DetectHttpHeaderTest13); - UtRegisterTest("DetectHttpHeaderTest20", DetectHttpHeaderTest20); - UtRegisterTest("DetectHttpHeaderTest21", DetectHttpHeaderTest21); - UtRegisterTest("DetectHttpHeaderTest22", DetectHttpHeaderTest22); - UtRegisterTest("DetectHttpHeaderTest23", DetectHttpHeaderTest23); - UtRegisterTest("DetectHttpHeaderTest24", DetectHttpHeaderTest24); - UtRegisterTest("DetectHttpHeaderTest25", DetectHttpHeaderTest25); - UtRegisterTest("DetectHttpHeaderTest26", DetectHttpHeaderTest26); - UtRegisterTest("DetectHttpHeaderTest27", DetectHttpHeaderTest27); - UtRegisterTest("DetectHttpHeaderTest28", DetectHttpHeaderTest28); - UtRegisterTest("DetectHttpHeaderTest29", DetectHttpHeaderTest29); - UtRegisterTest("DetectHttpHeaderTest30", DetectHttpHeaderTest30); - - UtRegisterTest("DetectHttpHeaderIsdataatParseTest", - DetectHttpHeaderIsdataatParseTest); - - UtRegisterTest("DetectEngineHttpHeaderTest01", - DetectEngineHttpHeaderTest01); - UtRegisterTest("DetectEngineHttpHeaderTest02", - DetectEngineHttpHeaderTest02); - UtRegisterTest("DetectEngineHttpHeaderTest03", - DetectEngineHttpHeaderTest03); - UtRegisterTest("DetectEngineHttpHeaderTest04", - DetectEngineHttpHeaderTest04); - UtRegisterTest("DetectEngineHttpHeaderTest05", - DetectEngineHttpHeaderTest05); - UtRegisterTest("DetectEngineHttpHeaderTest06", - DetectEngineHttpHeaderTest06); - UtRegisterTest("DetectEngineHttpHeaderTest07", - DetectEngineHttpHeaderTest07); - UtRegisterTest("DetectEngineHttpHeaderTest08", - DetectEngineHttpHeaderTest08); - UtRegisterTest("DetectEngineHttpHeaderTest09", - DetectEngineHttpHeaderTest09); - UtRegisterTest("DetectEngineHttpHeaderTest10", - DetectEngineHttpHeaderTest10); - UtRegisterTest("DetectEngineHttpHeaderTest11", - DetectEngineHttpHeaderTest11); - UtRegisterTest("DetectEngineHttpHeaderTest12", - DetectEngineHttpHeaderTest12); - UtRegisterTest("DetectEngineHttpHeaderTest13", - DetectEngineHttpHeaderTest13); - UtRegisterTest("DetectEngineHttpHeaderTest14", - DetectEngineHttpHeaderTest14); - UtRegisterTest("DetectEngineHttpHeaderTest15", - DetectEngineHttpHeaderTest15); - UtRegisterTest("DetectEngineHttpHeaderTest16", - DetectEngineHttpHeaderTest16); - UtRegisterTest("DetectEngineHttpHeaderTest17", - DetectEngineHttpHeaderTest17); - UtRegisterTest("DetectEngineHttpHeaderTest20", - DetectEngineHttpHeaderTest20); - UtRegisterTest("DetectEngineHttpHeaderTest21", - DetectEngineHttpHeaderTest21); - UtRegisterTest("DetectEngineHttpHeaderTest22", - DetectEngineHttpHeaderTest22); - UtRegisterTest("DetectEngineHttpHeaderTest23", - DetectEngineHttpHeaderTest23); - UtRegisterTest("DetectEngineHttpHeaderTest24", - DetectEngineHttpHeaderTest24); - UtRegisterTest("DetectEngineHttpHeaderTest25", - DetectEngineHttpHeaderTest25); - UtRegisterTest("DetectEngineHttpHeaderTest26", - DetectEngineHttpHeaderTest26); - UtRegisterTest("DetectEngineHttpHeaderTest27", - DetectEngineHttpHeaderTest27); - UtRegisterTest("DetectEngineHttpHeaderTest28", - DetectEngineHttpHeaderTest28); - UtRegisterTest("DetectEngineHttpHeaderTest29", - DetectEngineHttpHeaderTest29); - UtRegisterTest("DetectEngineHttpHeaderTest30", - DetectEngineHttpHeaderTest30); - UtRegisterTest("DetectEngineHttpHeaderTest31", - DetectEngineHttpHeaderTest31); -#if 0 - UtRegisterTest("DetectEngineHttpHeaderTest30", - DetectEngineHttpHeaderTest30, 1); -#endif - UtRegisterTest("DetectEngineHttpHeaderTest32", - DetectEngineHttpHeaderTest32); - UtRegisterTest("DetectEngineHttpHeaderTest33 -- Trailer", - DetectEngineHttpHeaderTest33); - UtRegisterTest("DetectEngineHttpHeaderTest34 -- Trailer", - DetectEngineHttpHeaderTest34); - UtRegisterTest("DetectEngineHttpHeaderTest35 -- Trailer", - DetectEngineHttpHeaderTest35); -#endif /* UNITTESTS */ - - return; -} /** * @} */ diff --git a/src/tests/detect-http-header.c b/src/tests/detect-http-header.c new file mode 100644 index 0000000000..9738eb1be2 --- /dev/null +++ b/src/tests/detect-http-header.c @@ -0,0 +1,5244 @@ +/* Copyright (C) 2007-2018 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 + * Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** + * \ingroup httplayer + * + * @{ + */ + + +/** + * \file + * + * \author Pablo Rincon + * + * Implements support for http_header keyword. + */ + +#include "../suricata-common.h" +#include "../flow.h" +#include "../flow-var.h" +#include "../flow-util.h" + +#include "../app-layer.h" +#include "../app-layer-parser.h" + +#include "../app-layer-htp.h" +#include "../detect-http-header.h" +#include "../detect-http-header-common.h" + +#include "../detect-isdataat.h" + +#include "../stream-tcp.h" + +#include "../util-unittest.h" +#include "../util-unittest-helper.h" + +/** + * \test Test that a signature containting a http_header is correctly parsed + * and the keyword is registered. + */ +static int DetectHttpHeaderTest01(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + SigMatch *sm = NULL; + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " + "(msg:\"Testing http_header\"; " + "content:\"one\"; http_header; sid:1;)"); + if (de_ctx->sig_list != NULL) { + result = 1; + } else { + printf("Error parsing signature: "); + goto end; + } + + sm = de_ctx->sig_list->sm_lists[g_http_header_buffer_id]; + if (sm != NULL) { + result &= (sm->type == DETECT_CONTENT); + result &= (sm->next == NULL); + } else { + result = 0; + printf("Error updating content pattern to http_header pattern: "); + } + + + end: + DetectEngineCtxFree(de_ctx); + + return result; +} + +/** + * \test Test that a signature containing an valid http_header entry is + * parsed. + */ +static int DetectHttpHeaderTest02(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " + "(msg:\"Testing http_header\"; " + "content:\"one\"; http_header:; sid:1;)"); + if (de_ctx->sig_list != NULL) + result = 1; + else + printf("Error parsing signature: "); + + end: + DetectEngineCtxFree(de_ctx); + + return result; +} + +/** + * \test Test that an invalid signature containing no content but a http_header + * is invalidated. + */ +static int DetectHttpHeaderTest03(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " + "(msg:\"Testing http_header\"; " + "http_header; sid:1;)"); + if (de_ctx->sig_list == NULL) + result = 1; + else + printf("Error parsing signature: "); + + end: + DetectEngineCtxFree(de_ctx); + + return result; +} + +/** + * \test Test that an invalid signature containing a rawbytes along with a + * http_header is invalidated. + */ +static int DetectHttpHeaderTest04(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " + "(msg:\"Testing http_header\"; " + "content:\"one\"; rawbytes; http_header; sid:1;)"); + if (de_ctx->sig_list == NULL) + result = 1; + else + printf("Error parsing signature: "); + + end: + DetectEngineCtxFree(de_ctx); + + return result; +} + +/** + * \test Test that an invalid signature containing a rawbytes along with a + * http_header is invalidated. + */ +static int DetectHttpHeaderTest05(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " + "(msg:\"Testing http_header\"; " + "content:\"one\"; nocase; http_header; sid:1;)"); + if (de_ctx->sig_list != NULL) + result = 1; + else + printf("Error parsing signature: "); + + end: + DetectEngineCtxFree(de_ctx); + + return result; +} + +/** + *\test Test that the http_header content matches against a http request + * which holds the content. + */ +static int DetectHttpHeaderTest06(void) +{ + TcpSession ssn; + Packet *p = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http_buf[] = + "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" + "Content-Type: text/html\r\n" + "Content-Length: 26\r\n" + "\r\n" + "This is dummy message body\r\n"; + uint32_t http_len = sizeof(http_buf) - 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)); + + p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.proto = IPPROTO_TCP; + f.flags |= FLOW_IPV4; + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + p->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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http header test\"; " + "content:\"Content-Type: text/html\"; http_header; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http_buf, http_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: "); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (!(PacketAlertCheck(p, 1))) { + printf("sid 1 didn't match but should have: "); + goto end; + } + + result = 1; +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p, 1); + return result; +} + +/** + *\test Test that the http_header content matches against a http request + * which holds the content. + */ +static int DetectHttpHeaderTest07(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + Packet *p2 = NULL; + ThreadVars th_v; + DetectEngineThreadCtx *det_ctx = NULL; + Flow f; + uint8_t http1_buf[] = + "GET /index.html HTTP/1.0\r\n" + "Host: www.openinfosecfoundation.org\r\n" + "User-Agent: Mozi"; + uint8_t http2_buf[] = + "lla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\nContent-Type: text/html\r\n" + "Content-Length: 67\r\n" + "\r\n" + "This is dummy message body1"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 1; + + AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); + FAIL_IF_NULL(alp_tctx); + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + FAIL_IF_NULL(p1); + p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + FAIL_IF_NULL(p2); + + 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_TOSERVER; + p2->flowflags |= FLOW_PKT_ESTABLISHED; + p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + + DetectEngineCtx *de_ctx = DetectEngineCtxInit(); + FAIL_IF_NULL(de_ctx); + de_ctx->flags |= DE_QUIET; + + Signature *s = DetectEngineAppendSig(de_ctx,"alert http any any -> any any " + "(msg:\"http header test\"; " + "content:\"Mozilla\"; http_header; " + "sid:1;)"); + FAIL_IF_NULL(s); + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + FAIL_IF_NULL(det_ctx); + + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http1_buf, http1_len); + FAIL_IF(r != 0); + + HtpState *http_state = f.alstate; + FAIL_IF_NULL(http_state); + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + FAIL_IF( (PacketAlertCheck(p1, 1))); + + r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http2_buf, http2_len); + FAIL_IF(r != 0); + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + FAIL_IF(!(PacketAlertCheck(p2, 1))); + + AppLayerParserThreadCtxFree(alp_tctx); + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + PASS; +} + +/** + *\test Test that the http_header content matches against a http request + * which holds the content. + */ +static int DetectHttpHeaderTest08(void) +{ + 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 http1_buf[] = + "GET /index.html HTTP/1.0\r\n" + "Host: www.openinfosecfoundation.org\r\n"; + uint8_t http2_buf[] = + "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 67\r\n" + "\r\n"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 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_TOSERVER; + 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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http header test\"; " + "content:\"Gecko/20091221 Firefox/3.5.7\"; http_header; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: "); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + + if ((PacketAlertCheck(p1, 1))) { + printf("sid 1 didn't match but should have: "); + goto end; + } + + FLOWLOCK_WRLOCK(&f); + r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (!(PacketAlertCheck(p2, 1))) { + printf("sid 1 didn't match but should have: "); + goto end; + } + + result = 1; +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +/** + *\test Test that the http_header content matches against a http request + * which holds the content, against a cross boundary present pattern. + */ +static int DetectHttpHeaderTest09(void) +{ + 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 http1_buf[] = + "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"; + uint8_t http2_buf[] = + "Content-Type: text/html\r\n" + "Content-Length: 67\r\n" + "\r\n" + "This is dummy body\r\n"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 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_TOSERVER; + 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; + de_ctx->mpm_matcher = mpm_default_matcher; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http header test\"; " + "content:\"Firefox/3.5.7|0D 0A|Content\"; http_header; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: "); + 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; + } + + FLOWLOCK_WRLOCK(&f); + r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (!(PacketAlertCheck(p2, 1))) { + printf("sid 1 didn't match but should have: "); + goto end; + } + + result = 1; +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +/** + *\test Test that the http_header content matches against a http request + * against a case insensitive pattern. + */ +static int DetectHttpHeaderTest10(void) +{ + 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 http1_buf[] = + "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"; + uint8_t http2_buf[] = + "Content-Type: text/html\r\n" + "Content-Length: 67\r\n" + "\r\n" + "This is dummy body"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 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_TOSERVER; + 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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http header test\"; " + "content:\"firefox/3.5.7|0D 0A|content\"; nocase; http_header;" + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: "); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + + if ((PacketAlertCheck(p1, 1))) { + printf("sid 1 didn't match but should have: "); + goto end; + } + + FLOWLOCK_WRLOCK(&f); + r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (!(PacketAlertCheck(p2, 1))) { + printf("sid 1 didn't match but should have: "); + goto end; + } + + result = 1; +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +/** + *\test Test that the negated http_header content matches against a + * http request which doesn't hold the content. + */ +static int DetectHttpHeaderTest11(void) +{ + TcpSession ssn; + Packet *p = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http_buf[] = + "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" + "Content-Type: text/html\r\n" + "Content-Length: 26\r\n" + "\r\n" + "This is dummy message body\r\n"; + uint32_t http_len = sizeof(http_buf) - 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)); + + p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.proto = IPPROTO_TCP; + f.flags |= FLOW_IPV4; + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + p->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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http header test\"; " + "content:!\"lalalalala\"; http_header; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http_buf, http_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: "); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (!(PacketAlertCheck(p, 1))) { + printf("sid 1 didn't match but should have: "); + goto end; + } + + result = 1; +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p, 1); + return result; +} + +/** + *\test Negative test that the negated http_header content matches against a + * http request which holds hold the content. + */ +static int DetectHttpHeaderTest12(void) +{ + TcpSession ssn; + Packet *p = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http_buf[] = + "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" + "Content-Type: text/html\r\n" + "Content-Length: 26\r\n" + "\r\n" + "This is dummy message body\r\n"; + uint32_t http_len = sizeof(http_buf) - 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)); + + p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.proto = IPPROTO_TCP; + f.flags |= FLOW_IPV4; + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + p->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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http header test\"; " + "content:!\"User-Agent: Mozilla/5.0 \"; http_header; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http_buf, http_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: "); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if ((PacketAlertCheck(p, 1))) { + printf("sid 1 didn't match but should have: "); + goto end; + } + + result = 1; +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p, 1); + return result; +} + +/** + *\test Test that the http_header content matches against a http request + * which holds the content. + */ +static int DetectHttpHeaderTest13(void) +{ + TcpSession ssn; + Packet *p = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http_buf[] = + "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" + "Content-Type: text/html\r\n" + "Content-Length: 100\r\n" + "\r\n" + "longbufferabcdefghijklmnopqrstuvwxyz0123456789bufferend\r\n"; + uint32_t http_len = sizeof(http_buf) - 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)); + + p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.proto = IPPROTO_TCP; + f.flags |= FLOW_IPV4; + + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + p->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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http header test\"; " + "content:\"Host: www.openinfosecfoundation.org\"; http_header; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http_buf, http_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: "); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (!(PacketAlertCheck(p, 1))) { + printf("sid 1 didn't match but should have: "); + goto end; + } + + result = 1; +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p, 1); + return result; +} + +static int DetectHttpHeaderTest20(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:\"one\"; http_header; " + "content:\"two\"; distance:0; http_header; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { + printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL) { + printf("de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL\n"); + goto end; + } + + DetectContentData *hhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->ctx; + DetectContentData *hhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->ctx; + if (hhd1->flags != DETECT_CONTENT_RELATIVE_NEXT || + memcmp(hhd1->content, "one", hhd1->content_len) != 0 || + hhd2->flags != DETECT_CONTENT_DISTANCE || + memcmp(hhd2->content, "two", hhd1->content_len) != 0) { + goto end; + } + + result = 1; + + end: + DetectEngineCtxFree(de_ctx); + return result; +} + +static int DetectHttpHeaderTest21(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:\"one\"; http_header; " + "content:\"two\"; within:5; http_header; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { + printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL) { + printf("de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL\n"); + goto end; + } + + DetectContentData *hhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->ctx; + DetectContentData *hhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->ctx; + if (hhd1->flags != DETECT_CONTENT_RELATIVE_NEXT || + memcmp(hhd1->content, "one", hhd1->content_len) != 0 || + hhd2->flags != DETECT_CONTENT_WITHIN || + memcmp(hhd2->content, "two", hhd1->content_len) != 0) { + goto end; + } + + result = 1; + + end: + DetectEngineCtxFree(de_ctx); + return result; +} + +static int DetectHttpHeaderTest22(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:\"one\"; within:5; http_header; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + result = 1; + + end: + DetectEngineCtxFree(de_ctx); + return result; +} + +static int DetectHttpHeaderTest23(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:\"one\"; http_header; within:5; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + result = 1; + + end: + DetectEngineCtxFree(de_ctx); + return result; +} + +static int DetectHttpHeaderTest24(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:\"one\"; within:5; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + result = 1; + + end: + DetectEngineCtxFree(de_ctx); + return result; +} + +static int DetectHttpHeaderTest25(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(pcre:/one/H; " + "content:\"two\"; within:5; http_header; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { + printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL) { + printf("de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id] == NULL || + de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->type != DETECT_CONTENT || + de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev == NULL || + de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->type != DETECT_PCRE) { + + goto end; + } + + DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->ctx; + DetectContentData *hhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->ctx; + if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) || + hhd2->flags != DETECT_CONTENT_WITHIN || + memcmp(hhd2->content, "two", hhd2->content_len) != 0) { + goto end; + } + + result = 1; + + end: + DetectEngineCtxFree(de_ctx); + return result; +} + +static int DetectHttpHeaderTest26(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(content:\"two\"; http_header; " + "pcre:/one/HR; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { + printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL) { + printf("de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id] == NULL || + de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->type != DETECT_PCRE || + de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev == NULL || + de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->type != DETECT_CONTENT) { + + goto end; + } + + DetectContentData *hhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->ctx; + DetectPcreData *pd2 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->ctx; + if (pd2->flags != (DETECT_PCRE_RELATIVE) || + hhd1->flags != DETECT_CONTENT_RELATIVE_NEXT || + memcmp(hhd1->content, "two", hhd1->content_len) != 0) { + goto end; + } + + result = 1; + + end: + DetectEngineCtxFree(de_ctx); + return result; +} + +static int DetectHttpHeaderTest27(void) +{ + DetectEngineCtx *de_ctx = NULL; + int result = 0; + + if ( (de_ctx = DetectEngineCtxInit()) == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert icmp any any -> any any " + "(pcre:/one/H; " + "content:\"two\"; distance:5; http_header; sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("de_ctx->sig_list == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) { + printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL) { + printf("de_ctx->sig_list->sm_lists[g_http_header_buffer_id] == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id] == NULL || + de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->type != DETECT_CONTENT || + de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev == NULL || + de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->type != DETECT_PCRE) { + + goto end; + } + + DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->prev->ctx; + DetectContentData *hhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_header_buffer_id]->ctx; + if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) || + hhd2->flags != DETECT_CONTENT_DISTANCE || + memcmp(hhd2->content, "two", hhd2->content_len) != 0) { + goto end; + } + + result = 1; + + end: + DetectEngineCtxFree(de_ctx); + return result; +} + +/** \test app-layer-event:http.host_header_ambiguous should not be set + * \bug 640*/ +static int DetectHttpHeaderTest28(void) +{ + TcpSession ssn; + Packet *p = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + Flow f; + uint8_t http_buf[] = + "POST http://xxx.intranet.local:8000/xxx HTTP/1.1\r\n" + "User-Agent: Mozilla/4.0 (Windows XP 5.1) Java/1.6.0_29\r\n" + "Host: xxx.intranet.local:8000\r\n" + "\r\n"; + uint32_t http_len = sizeof(http_buf) - 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)); + + p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.proto = IPPROTO_TCP; + f.flags |= FLOW_IPV4; + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + p->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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(app-layer-event:http.host_header_ambiguous; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http_buf, http_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (PacketAlertCheck(p, 1)) { + printf("sid 1 matched but shouldnt have: "); + goto end; + } + + result = 1; + end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p, 1); + return result; +} + +/** \test app-layer-event:http.host_header_ambiguous should be set + * \bug 640*/ +static int DetectHttpHeaderTest29(void) +{ + TcpSession ssn; + Packet *p = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + Flow f; + uint8_t http_buf[] = + "POST http://xxx.intranet.local:8001/xxx HTTP/1.1\r\n" + "User-Agent: Mozilla/4.0 (Windows XP 5.1) Java/1.6.0_29\r\n" + "Host: xxx.intranet.local:8000\r\n" + "\r\n"; + uint32_t http_len = sizeof(http_buf) - 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)); + + p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.proto = IPPROTO_TCP; + f.flags |= FLOW_IPV4; + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + p->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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(app-layer-event:http.host_header_ambiguous; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http_buf, http_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (!(PacketAlertCheck(p, 1))) { + printf("sid 1 didn't match but should have: "); + goto end; + } + + result = 1; + end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p, 1); + return result; +} + +/** \test app-layer-event:http.host_header_ambiguous should be set + * \bug 640*/ +static int DetectHttpHeaderTest30(void) +{ + TcpSession ssn; + Packet *p = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + Flow f; + uint8_t http_buf[] = + "POST http://xxx.intranet.local:8000/xxx HTTP/1.1\r\n" + "User-Agent: Mozilla/4.0 (Windows XP 5.1) Java/1.6.0_29\r\n" + "Host: xyz.intranet.local:8000\r\n" + "\r\n"; + uint32_t http_len = sizeof(http_buf) - 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)); + + p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.proto = IPPROTO_TCP; + f.flags |= FLOW_IPV4; + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + p->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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(app-layer-event:http.host_header_ambiguous; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http_buf, http_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (!(PacketAlertCheck(p, 1))) { + printf("sid 1 didn't match but should have: "); + goto end; + } + + result = 1; + end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p, 1); + return result; +} + +static int DetectHttpHeaderIsdataatParseTest(void) +{ + DetectEngineCtx *de_ctx = DetectEngineCtxInit(); + FAIL_IF_NULL(de_ctx); + de_ctx->flags |= DE_QUIET; + + Signature *s = DetectEngineAppendSig(de_ctx, + "alert tcp any any -> any any (" + "flow:to_server; " + "content:\"one\"; http_header; " + "isdataat:!4,relative; sid:1;)"); + FAIL_IF_NULL(s); + + SigMatch *sm = s->init_data->smlists_tail[g_http_header_buffer_id]; + FAIL_IF_NULL(sm); + FAIL_IF_NOT(sm->type == DETECT_ISDATAAT); + + DetectIsdataatData *data = (DetectIsdataatData *)sm->ctx; + FAIL_IF_NOT(data->flags & ISDATAAT_RELATIVE); + FAIL_IF_NOT(data->flags & ISDATAAT_NEGATED); + FAIL_IF(data->flags & ISDATAAT_RAWBYTES); + + DetectEngineCtxFree(de_ctx); + PASS; +} + +/** + *\test Test that the http_header content matches against a http request + * which holds the content. + */ +static int DetectEngineHttpHeaderTest01(void) +{ + TcpSession ssn; + Packet *p = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http_buf[] = + "GET /index.html HTTP/1.0\r\n" + "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; + uint32_t http_len = sizeof(http_buf) - 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)); + + p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.proto = IPPROTO_TCP; + f.flags |= FLOW_IPV4; + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + p->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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http header test\"; " + "content:\"one\"; http_header; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http_buf, http_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: "); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (!(PacketAlertCheck(p, 1))) { + printf("sid 1 didn't match but should have: "); + goto end; + } + + result = 1; +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p, 1); + return result; +} + +/** + *\test Test that the http_header content matches against a http request + * which holds the content. + */ +static int DetectEngineHttpHeaderTest02(void) +{ + TcpSession ssn; + Packet *p = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http_buf[] = + "GET /index.html HTTP/1.0\r\n" + "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; + uint32_t http_len = sizeof(http_buf) - 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)); + + p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.proto = IPPROTO_TCP; + f.flags |= FLOW_IPV4; + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + p->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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http header test\"; " + "content:\"one\"; depth:15; http_header; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http_buf, http_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: "); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (!(PacketAlertCheck(p, 1))) { + printf("sid 1 didn't match but should have: "); + goto end; + } + + result = 1; +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p, 1); + return result; +} + +/** + *\test Test that the http_header content matches against a http request + * which holds the content. + */ +static int DetectEngineHttpHeaderTest03(void) +{ + TcpSession ssn; + Packet *p = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http_buf[] = + "GET /index.html HTTP/1.0\r\n" + "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; + uint32_t http_len = sizeof(http_buf) - 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)); + + p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.proto = IPPROTO_TCP; + f.flags |= FLOW_IPV4; + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + p->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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http header test\"; " + "content:!\"one\"; depth:5; http_header; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http_buf, http_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: "); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (!(PacketAlertCheck(p, 1))) { + printf("sid 1 didn't match but should have: "); + goto end; + } + + result = 1; +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p, 1); + return result; +} + +/** + *\test Test that the http_header content matches against a http request + * which holds the content. + */ +static int DetectEngineHttpHeaderTest04(void) +{ + TcpSession ssn; + Packet *p = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http_buf[] = + "GET /index.html HTTP/1.0\r\n" + "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; + uint32_t http_len = sizeof(http_buf) - 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)); + + p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.proto = IPPROTO_TCP; + f.flags |= FLOW_IPV4; + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + p->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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http header test\"; " + "content:\"one\"; depth:5; http_header; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http_buf, http_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: "); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (PacketAlertCheck(p, 1)) { + printf("sid 1 matched but shouldn't have: "); + goto end; + } + + result = 1; +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p, 1); + return result; +} + +/** + *\test Test that the http_header content matches against a http request + * which holds the content. + */ +static int DetectEngineHttpHeaderTest05(void) +{ + TcpSession ssn; + Packet *p = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http_buf[] = + "GET /index.html HTTP/1.0\r\n" + "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; + uint32_t http_len = sizeof(http_buf) - 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)); + + p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.proto = IPPROTO_TCP; + f.flags |= FLOW_IPV4; + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + p->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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http header test\"; " + "content:!\"one\"; depth:15; http_header; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http_buf, http_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: "); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (PacketAlertCheck(p, 1)) { + printf("sid 1 matched but shouldn't have: "); + goto end; + } + + result = 1; +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p, 1); + return result; +} + +/** + *\test Test that the http_header content matches against a http request + * which holds the content. + */ +static int DetectEngineHttpHeaderTest06(void) +{ + TcpSession ssn; + Packet *p = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http_buf[] = + "GET /index.html HTTP/1.0\r\n" + "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; + uint32_t http_len = sizeof(http_buf) - 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)); + + p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.proto = IPPROTO_TCP; + f.flags |= FLOW_IPV4; + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + p->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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http header test\"; " + "content:\"one\"; offset:10; http_header; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http_buf, http_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: "); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (!(PacketAlertCheck(p, 1))) { + printf("sid 1 didn't match but should have: "); + goto end; + } + + result = 1; +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p, 1); + return result; +} + +/** + *\test Test that the http_header content matches against a http request + * which holds the content. + */ +static int DetectEngineHttpHeaderTest07(void) +{ + TcpSession ssn; + Packet *p = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http_buf[] = + "GET /index.html HTTP/1.0\r\n" + "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; + uint32_t http_len = sizeof(http_buf) - 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)); + + p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.proto = IPPROTO_TCP; + f.flags |= FLOW_IPV4; + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + p->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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http header test\"; " + "content:!\"one\"; offset:15; http_header; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http_buf, http_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: "); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (!(PacketAlertCheck(p, 1))) { + printf("sid 1 didn't match but should have: "); + goto end; + } + + result = 1; +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p, 1); + return result; +} + +/** + *\test Test that the http_header content matches against a http request + * which holds the content. + */ +static int DetectEngineHttpHeaderTest08(void) +{ + TcpSession ssn; + Packet *p = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http_buf[] = + "GET /index.html HTTP/1.0\r\n" + "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; + uint32_t http_len = sizeof(http_buf) - 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)); + + p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.proto = IPPROTO_TCP; + f.flags |= FLOW_IPV4; + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + p->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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http header test\"; " + "content:\"one\"; offset:15; http_header; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http_buf, http_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: "); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (PacketAlertCheck(p, 1)) { + printf("sid 1 matched but shouldn't have: "); + goto end; + } + + result = 1; +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p, 1); + return result; +} + +/** + *\test Test that the http_header content matches against a http request + * which holds the content. + */ +static int DetectEngineHttpHeaderTest09(void) +{ + TcpSession ssn; + Packet *p = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http_buf[] = + "GET /index.html HTTP/1.0\r\n" + "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; + uint32_t http_len = sizeof(http_buf) - 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)); + + p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.proto = IPPROTO_TCP; + f.flags |= FLOW_IPV4; + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + p->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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http header test\"; " + "content:!\"one\"; offset:10; http_header; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http_buf, http_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: "); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (PacketAlertCheck(p, 1)) { + printf("sid 1 matched but shouldn't have: "); + goto end; + } + + result = 1; +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p, 1); + return result; +} + +/** + *\test Test that the http_header content matches against a http request + * which holds the content. + */ +static int DetectEngineHttpHeaderTest10(void) +{ + TcpSession ssn; + Packet *p = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http_buf[] = + "GET /index.html HTTP/1.0\r\n" + "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; + uint32_t http_len = sizeof(http_buf) - 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)); + + p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.proto = IPPROTO_TCP; + f.flags |= FLOW_IPV4; + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + p->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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http header test\"; " + "content:\"one\"; http_header; content:\"three\"; http_header; within:10; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http_buf, http_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: "); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (!(PacketAlertCheck(p, 1))) { + printf("sid 1 didn't match but should have: "); + goto end; + } + + result = 1; +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p, 1); + return result; +} + +/** + *\test Test that the http_header content matches against a http request + * which holds the content. + */ +static int DetectEngineHttpHeaderTest11(void) +{ + TcpSession ssn; + Packet *p = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http_buf[] = + "GET /index.html HTTP/1.0\r\n" + "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; + uint32_t http_len = sizeof(http_buf) - 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)); + + p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.proto = IPPROTO_TCP; + f.flags |= FLOW_IPV4; + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + p->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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http header test\"; " + "content:\"one\"; http_header; content:!\"three\"; http_header; within:5; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http_buf, http_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: "); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (!(PacketAlertCheck(p, 1))) { + printf("sid 1 didn't match but should have: "); + goto end; + } + + result = 1; +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p, 1); + return result; +} + +/** + *\test Test that the http_header content matches against a http request + * which holds the content. + */ +static int DetectEngineHttpHeaderTest12(void) +{ + TcpSession ssn; + Packet *p = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http_buf[] = + "GET /index.html HTTP/1.0\r\n" + "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; + uint32_t http_len = sizeof(http_buf) - 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)); + + p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.proto = IPPROTO_TCP; + f.flags |= FLOW_IPV4; + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + p->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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http header test\"; " + "content:\"one\"; http_header; content:!\"three\"; http_header; within:10; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http_buf, http_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: "); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (PacketAlertCheck(p, 1)) { + printf("sid 1 matched but shouldn't have: "); + goto end; + } + + result = 1; +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p, 1); + return result; +} + +/** + *\test Test that the http_header content matches against a http request + * which holds the content. + */ +static int DetectEngineHttpHeaderTest13(void) +{ + TcpSession ssn; + Packet *p = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http_buf[] = + "GET /index.html HTTP/1.0\r\n" + "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; + uint32_t http_len = sizeof(http_buf) - 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)); + + p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.proto = IPPROTO_TCP; + f.flags |= FLOW_IPV4; + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + p->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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http header test\"; " + "content:\"one\"; http_header; content:\"three\"; http_header; within:5; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http_buf, http_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: "); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (PacketAlertCheck(p, 1)) { + printf("sid 1 matched but shouldn't have: "); + goto end; + } + + result = 1; +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p, 1); + return result; +} + +/** + *\test Test that the http_header content matches against a http request + * which holds the content. + */ +static int DetectEngineHttpHeaderTest14(void) +{ + TcpSession ssn; + Packet *p = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http_buf[] = + "GET /index.html HTTP/1.0\r\n" + "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; + uint32_t http_len = sizeof(http_buf) - 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)); + + p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.proto = IPPROTO_TCP; + f.flags |= FLOW_IPV4; + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + p->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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http header test\"; " + "content:\"one\"; http_header; content:\"five\"; http_header; distance:7; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http_buf, http_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: "); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (!(PacketAlertCheck(p, 1))) { + printf("sid 1 didn't match but should have: "); + goto end; + } + + result = 1; +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p, 1); + return result; +} + +/** + *\test Test that the http_header content matches against a http request + * which holds the content. + */ +static int DetectEngineHttpHeaderTest15(void) +{ + TcpSession ssn; + Packet *p = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http_buf[] = + "GET /index.html HTTP/1.0\r\n" + "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; + uint32_t http_len = sizeof(http_buf) - 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)); + + p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.proto = IPPROTO_TCP; + f.flags |= FLOW_IPV4; + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + p->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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http header test\"; " + "content:\"one\"; http_header; content:!\"five\"; http_header; distance:15; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http_buf, http_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: "); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (!(PacketAlertCheck(p, 1))) { + printf("sid 1 didn't match but should have: "); + goto end; + } + + result = 1; +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p, 1); + return result; +} + +/** + *\test Test that the http_header content matches against a http request + * which holds the content. + */ +static int DetectEngineHttpHeaderTest16(void) +{ + TcpSession ssn; + Packet *p = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http_buf[] = + "GET /index.html HTTP/1.0\r\n" + "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; + uint32_t http_len = sizeof(http_buf) - 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)); + + p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.proto = IPPROTO_TCP; + f.flags |= FLOW_IPV4; + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + p->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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http header test\"; " + "content:\"one\"; http_header; content:!\"five\"; http_header; distance:7; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http_buf, http_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: "); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (PacketAlertCheck(p, 1)) { + printf("sid 1 matched but shouldn't have: "); + goto end; + } + + result = 1; +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p, 1); + return result; +} + +/** + *\test Test that the http_header content matches against a http request + * which holds the content. + */ +static int DetectEngineHttpHeaderTest17(void) +{ + TcpSession ssn; + Packet *p = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http_buf[] = + "GET /index.html HTTP/1.0\r\n" + "Host: www.onetwothreefourfivesixseven.org\r\n\r\n"; + uint32_t http_len = sizeof(http_buf) - 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)); + + p = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + + FLOW_INITIALIZE(&f); + f.protoctx = (void *)&ssn; + f.proto = IPPROTO_TCP; + f.flags |= FLOW_IPV4; + p->flow = &f; + p->flowflags |= FLOW_PKT_TOSERVER; + p->flowflags |= FLOW_PKT_ESTABLISHED; + p->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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http header test\"; " + "content:\"one\"; http_header; content:\"five\"; http_header; distance:15; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http_buf, http_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + http_state = f.alstate; + if (http_state == NULL) { + printf("no http state: "); + result = 0; + goto end; + } + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p); + + if (PacketAlertCheck(p, 1)) { + printf("sid 1 matched but shouldn't have: "); + goto end; + } + + result = 1; +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p, 1); + return result; +} + +static int DetectEngineHttpHeaderTest20(void) +{ + 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 http1_buf[] = + "GET /index.html HTTP/1.0\r\n" + "Host: This_is_dummy_body1"; + uint8_t http2_buf[] = + "This_is_dummy_message_body2\r\n" + "\r\n"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 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_TOSERVER; + 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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http client body test\"; " + "pcre:/body1/H; " + "content:!\"dummy\"; http_header; within:7; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + 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\n"); + goto end; + } + + FLOWLOCK_WRLOCK(&f); + r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (!PacketAlertCheck(p2, 1)) { + printf("sid 1 didn't match but shouldn't have"); + goto end; + } + + result = 1; + +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpHeaderTest21(void) +{ + 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 http1_buf[] = + "GET /index.html HTTP/1.0\r\n" + "Host: This_is_dummy_body1"; + uint8_t http2_buf[] = + "This_is_dummy_message_body2\r\n" + "\r\n"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 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_TOSERVER; + 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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http client body test\"; " + "pcre:/body1/H; " + "content:!\"dummy\"; within:7; http_header; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + 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\n"); + goto end; + } + + FLOWLOCK_WRLOCK(&f); + r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (!PacketAlertCheck(p2, 1)) { + printf("sid 1 didn't match but shouldn't have"); + goto end; + } + + result = 1; + +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpHeaderTest22(void) +{ + 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 http1_buf[] = + "GET /index.html HTTP/1.0\r\n" + "Host: This_is_dummy_body1"; + uint8_t http2_buf[] = + "This_is_dummy_message_body2\r\n" + "\r\n"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 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_TOSERVER; + 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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http client body test\"; " + "pcre:/body1/H; " + "content:!\"dummy\"; distance:3; http_header; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + 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\n"); + goto end; + } + + FLOWLOCK_WRLOCK(&f); + r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (PacketAlertCheck(p2, 1)) { + printf("sid 1 matched but shouldn't have"); + goto end; + } + + result = 1; + +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpHeaderTest23(void) +{ + 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 http1_buf[] = + "GET /index.html HTTP/1.0\r\n" + "Host: This_is_dummy_body1"; + uint8_t http2_buf[] = + "This_is_dummy_message_body2\r\n" + "\r\n"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 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_TOSERVER; + 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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http client body test\"; " + "pcre:/body1/H; " + "content:!\"dummy\"; distance:13; http_header; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + 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\n"); + goto end; + } + + FLOWLOCK_WRLOCK(&f); + r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (!PacketAlertCheck(p2, 1)) { + printf("sid 1 didn't match but should have"); + goto end; + } + + result = 1; + +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpHeaderTest24(void) +{ + 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 http1_buf[] = + "GET /index.html HTTP/1.0\r\n" + "Host: This_is_dummy_body1"; + uint8_t http2_buf[] = + "This_is_dummy_message_body2\r\n" + "\r\n"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 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_TOSERVER; + 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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http client body test\"; " + "pcre:/body1/H; " + "content:\"dummy\"; within:15; http_header; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + 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\n"); + goto end; + } + + FLOWLOCK_WRLOCK(&f); + r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (!PacketAlertCheck(p2, 1)) { + printf("sid 1 didn't match but should have"); + goto end; + } + + result = 1; + +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpHeaderTest25(void) +{ + 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 http1_buf[] = + "GET /index.html HTTP/1.0\r\n" + "Host: This_is_dummy_body1"; + uint8_t http2_buf[] = + "This_is_dummy_message_body2\r\n" + "\r\n"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 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_TOSERVER; + 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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http client body test\"; " + "pcre:/body1/H; " + "content:\"dummy\"; within:10; http_header; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + 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\n"); + goto end; + } + + FLOWLOCK_WRLOCK(&f); + r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (PacketAlertCheck(p2, 1)) { + printf("sid 1 matched but shouldn't have"); + goto end; + } + + result = 1; + +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpHeaderTest26(void) +{ + 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 http1_buf[] = + "GET /index.html HTTP/1.0\r\n" + "Host: This_is_dummy_body1"; + uint8_t http2_buf[] = + "This_is_dummy_message_body2\r\n" + "\r\n"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 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_TOSERVER; + 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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http client body test\"; " + "pcre:/body1/H; " + "content:\"dummy\"; distance:8; http_header; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + 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\n"); + goto end; + } + + FLOWLOCK_WRLOCK(&f); + r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (!PacketAlertCheck(p2, 1)) { + printf("sid 1 didn't match but should have"); + goto end; + } + + result = 1; + +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpHeaderTest27(void) +{ + 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 http1_buf[] = + "GET /index.html HTTP/1.0\r\n" + "Host: This_is_dummy_body1"; + uint8_t http2_buf[] = + "This_is_dummy_message_body2\r\n" + "\r\n"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 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_TOSERVER; + 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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http client body test\"; " + "pcre:/body1/H; " + "content:\"dummy\"; distance:14; http_header; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + 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\n"); + goto end; + } + + FLOWLOCK_WRLOCK(&f); + r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http2_buf, http2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (PacketAlertCheck(p2, 1)) { + printf("sid 1 matched but shouldn't have"); + goto end; + } + + result = 1; + +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpHeaderTest28(void) +{ + 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_buf1_len = 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" + "abcdef"; + uint32_t http_buf2_len = sizeof(http_buf2) - 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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http header test\"; " + "content:\"Content-Length: 6\"; http_header; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http_buf1, http_buf1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + 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\n"); + goto end; + } + + FLOWLOCK_WRLOCK(&f); + r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOCLIENT, http_buf2, http_buf2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + FAIL_IF(!PacketAlertCheck(p2, 1)); + + result = 1; + +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +static int DetectEngineHttpHeaderTest29(void) +{ + 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_buf1_len = 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" + "abcdef"; + uint32_t http_buf2_len = sizeof(http_buf2) - 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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http header test\"; " + "content:\"Content-Length: 7\"; http_header; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http_buf1, http_buf1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + 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\n"); + goto end; + } + + FLOWLOCK_WRLOCK(&f); + r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOCLIENT, http_buf2, http_buf2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (PacketAlertCheck(p2, 1)) { + printf("sid 1 matched but shouldn't have"); + goto end; + } + + result = 1; + +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +#if 0 + +static int DetectEngineHttpHeaderTest30(void) +{ + int result = 0; + DetectEngineCtx *de_ctx = DetectEngineCtxInit(); + + if (de_ctx == NULL) { + goto end; + } + + de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any " + "(msg:\"http header test\"; " + "content:\"Content-Length: 6\"; http_header; " + "content:\"User-Agent: Mozilla\"; http_header; " + "sid:1;)"); + if (de_ctx->sig_list != NULL) { + goto end; + } + + result = 1; + + end: + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + return result; +} + +#endif /* #if 0 */ + +static int DetectEngineHttpHeaderTest30(void) +{ + 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_buf1_len = sizeof(http_buf1) - 1; + uint8_t http_buf2[] = + "HTTP/1.0 200 ok\r\n" + "Set-Cookie: dummycookieset\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 6\r\n" + "\r\n" + "abcdef"; + uint32_t http_buf2_len = sizeof(http_buf2) - 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; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http header test\"; " + "content:\"dummycookieset\"; http_header; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http_buf1, http_buf1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + 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\n"); + goto end; + } + + FLOWLOCK_WRLOCK(&f); + r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOCLIENT, http_buf2, http_buf2_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + if (PacketAlertCheck(p2, 1)) { + printf("sid 1 matched but shouldn't have\n"); + goto end; + } + + result = 1; + +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + return result; +} + +/** \test reassembly bug where headers with names of length 6 were + * skipped + */ +static int DetectEngineHttpHeaderTest31(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http1_buf[] = + "GET /index.html HTTP/1.0\r\n" + "Accept: blah\r\n" + "Cookie: blah\r\n" + "Crazy6: blah\r\n" + "SixZix: blah\r\n\r\n"; + uint32_t http1_len = sizeof(http1_buf) - 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); + + 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; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(content:\"Accept|3a|\"; http_header; " + "content:!\"Cookie|3a|\"; http_header; " + "content:\"Crazy6|3a|\"; http_header; " + "content:\"SixZix|3a|\"; http_header; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + 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 didn't match but should have: "); + goto end; + } + + result = 1; + +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + return result; +} + +/** + * \test Trailing headers. + */ +static int DetectEngineHttpHeaderTest32(void) +{ + TcpSession ssn; + Packet *p1 = NULL; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http1_buf[] = + "GET /index.html HTTP/1.0\r\n" + "host: boom\r\n" + "Transfer-Encoding: chunked\r\n" + "\r\n" + "13\r\n" + "This is dummy body1\r\n" + "0\r\n" + "Dummy-Header: kaboom\r\n" + "\r\n"; + uint32_t http1_len = sizeof(http1_buf) - 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); + + 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; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(content:\"Dummy\"; http_header; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + FLOWLOCK_WRLOCK(&f); + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http1_buf, http1_len); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); + + 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 didn't match but should have: "); + goto end; + } + + result = 1; + +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + return result; +} + +/** + * \test Trailing headers. + */ +static int DetectEngineHttpHeaderTest33(void) +{ + 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 http1_buf[] = + "GET /index.html HTTP/1.0\r\n" + "host: boom\r\n" + "Transfer-Encoding: chunked\r\n" + "\r\n" + "13\r\n" + "This is dummy body1\r\n" + "0\r\n"; + uint8_t http2_buf[] = + "Dummy-Header: kaboom\r\n" + "\r\n"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 1; + + AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); + FAIL_IF_NULL(alp_tctx); + + 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_TOSERVER; + p2->flowflags |= FLOW_PKT_ESTABLISHED; + p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + + de_ctx = DetectEngineCtxInit(); + FAIL_IF(de_ctx == NULL); + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(content:\"Dummy\"; http_header; " + "sid:1;)"); + FAIL_IF(de_ctx->sig_list == NULL); + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http1_buf, http1_len); + FAIL_IF_NOT(r == 0); + + http_state = f.alstate; + FAIL_IF(http_state == NULL); + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + + FAIL_IF(PacketAlertCheck(p1, 1)); + + r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http2_buf, http2_len); + FAIL_IF_NOT(r == 0); + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + + FAIL_IF(!PacketAlertCheck(p2, 1)); + + AppLayerParserThreadCtxFree(alp_tctx); + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + PASS; +} + +/** + * \test Trailing headers. + */ +static int DetectEngineHttpHeaderTest34(void) +{ + TcpSession ssn; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http1_buf[] = + "GET /index.html HTTP/1.0\r\n" + "host: boom\r\n" + "Dummy-Header1: blah\r\n" + "Transfer-Encoding: chunked\r\n" + "\r\n"; + uint8_t http2_buf[] = + "13\r\n" + "This is dummy body1\r\n" + "0\r\n"; + uint8_t http3_buf[] = + "Dummy-Header2: kaboom\r\n" + "\r\n"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 1; + uint32_t http3_len = sizeof(http3_buf) - 1; + + AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); + FAIL_IF_NULL(alp_tctx); + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + Packet *p3 = 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; + p1->pcap_cnt = 1; + p2->flow = &f; + p2->flowflags |= FLOW_PKT_TOSERVER; + p2->flowflags |= FLOW_PKT_ESTABLISHED; + p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; + p2->pcap_cnt = 2; + p3->flow = &f; + p3->flowflags |= FLOW_PKT_TOSERVER; + p3->flowflags |= FLOW_PKT_ESTABLISHED; + p3->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; + p3->pcap_cnt = 3; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + + de_ctx = DetectEngineCtxInit(); + FAIL_IF(de_ctx == NULL); + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(content:\"Dummy\"; http_header; content:\"Header2\"; http_header; within:8; " + "sid:1;)"); + FAIL_IF(de_ctx->sig_list == NULL); + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http1_buf, http1_len); + FAIL_IF_NOT(r == 0); + + http_state = f.alstate; + FAIL_IF(http_state == NULL); + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + FAIL_IF(PacketAlertCheck(p1, 1)); + + r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http2_buf, http2_len); + FAIL_IF_NOT(r == 0); + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + FAIL_IF(PacketAlertCheck(p2, 1)); + + r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http3_buf, http3_len); + FAIL_IF_NOT(r == 0); + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p3); + FAIL_IF(!PacketAlertCheck(p3, 1)); /* should match in trailer */ + + AppLayerParserThreadCtxFree(alp_tctx); + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + UTHFreePackets(&p3, 1); + PASS; +} + +/** + * \test Trailing headers. + */ +static int DetectEngineHttpHeaderTest35(void) +{ + TcpSession ssn; + ThreadVars th_v; + DetectEngineCtx *de_ctx = NULL; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + Flow f; + uint8_t http1_buf[] = + "GET /index.html HTTP/1.0\r\n" + "host: boom\r\n" + "Dummy-Header1: blah\r\n" + "Transfer-Encoding: chunked\r\n" + "\r\n"; + uint8_t http2_buf[] = + "13\r\n" + "This is dummy body1\r\n" + "0\r\n"; + uint8_t http3_buf[] = + "Dummy-Header2: kaboom\r\n" + "\r\n"; + uint32_t http1_len = sizeof(http1_buf) - 1; + uint32_t http2_len = sizeof(http2_buf) - 1; + uint32_t http3_len = sizeof(http3_buf) - 1; + + AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc(); + FAIL_IF_NULL(alp_tctx); + + memset(&th_v, 0, sizeof(th_v)); + memset(&f, 0, sizeof(f)); + memset(&ssn, 0, sizeof(ssn)); + + Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP); + Packet *p3 = 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; + p1->pcap_cnt = 1; + p2->flow = &f; + p2->flowflags |= FLOW_PKT_TOSERVER; + p2->flowflags |= FLOW_PKT_ESTABLISHED; + p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; + p2->pcap_cnt = 2; + p3->flow = &f; + p3->flowflags |= FLOW_PKT_TOSERVER; + p3->flowflags |= FLOW_PKT_ESTABLISHED; + p3->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; + p3->pcap_cnt = 3; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + + de_ctx = DetectEngineCtxInit(); + FAIL_IF(de_ctx == NULL); + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(content:\"Dummy\"; http_header; fast_pattern; content:\"Header2\"; http_header; within:8; " + "sid:1;)"); + FAIL_IF(de_ctx->sig_list == NULL); + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + + int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http1_buf, http1_len); + FAIL_IF_NOT(r == 0); + + http_state = f.alstate; + FAIL_IF(http_state == NULL); + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); + FAIL_IF(PacketAlertCheck(p1, 1)); + + r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http2_buf, http2_len); + FAIL_IF_NOT(r == 0); + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p2); + FAIL_IF(PacketAlertCheck(p2, 1)); + + r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOSERVER, http3_buf, http3_len); + FAIL_IF_NOT(r == 0); + + /* do detect */ + SigMatchSignatures(&th_v, de_ctx, det_ctx, p3); + FAIL_IF(!PacketAlertCheck(p3, 1)); /* should match in trailer */ + + AppLayerParserThreadCtxFree(alp_tctx); + DetectEngineCtxFree(de_ctx); + + StreamTcpFreeConfig(TRUE); + FLOW_DESTROY(&f); + UTHFreePackets(&p1, 1); + UTHFreePackets(&p2, 1); + UTHFreePackets(&p3, 1); + PASS; +} + +void DetectHttpHeaderRegisterTests(void) +{ + UtRegisterTest("DetectHttpHeaderTest01", DetectHttpHeaderTest01); + UtRegisterTest("DetectHttpHeaderTest02", DetectHttpHeaderTest02); + UtRegisterTest("DetectHttpHeaderTest03", DetectHttpHeaderTest03); + UtRegisterTest("DetectHttpHeaderTest04", DetectHttpHeaderTest04); + UtRegisterTest("DetectHttpHeaderTest05", DetectHttpHeaderTest05); + UtRegisterTest("DetectHttpHeaderTest06", DetectHttpHeaderTest06); + UtRegisterTest("DetectHttpHeaderTest07", DetectHttpHeaderTest07); + UtRegisterTest("DetectHttpHeaderTest08", DetectHttpHeaderTest08); + UtRegisterTest("DetectHttpHeaderTest09", DetectHttpHeaderTest09); + UtRegisterTest("DetectHttpHeaderTest10", DetectHttpHeaderTest10); + UtRegisterTest("DetectHttpHeaderTest11", DetectHttpHeaderTest11); + UtRegisterTest("DetectHttpHeaderTest12", DetectHttpHeaderTest12); + UtRegisterTest("DetectHttpHeaderTest13", DetectHttpHeaderTest13); + UtRegisterTest("DetectHttpHeaderTest20", DetectHttpHeaderTest20); + UtRegisterTest("DetectHttpHeaderTest21", DetectHttpHeaderTest21); + UtRegisterTest("DetectHttpHeaderTest22", DetectHttpHeaderTest22); + UtRegisterTest("DetectHttpHeaderTest23", DetectHttpHeaderTest23); + UtRegisterTest("DetectHttpHeaderTest24", DetectHttpHeaderTest24); + UtRegisterTest("DetectHttpHeaderTest25", DetectHttpHeaderTest25); + UtRegisterTest("DetectHttpHeaderTest26", DetectHttpHeaderTest26); + UtRegisterTest("DetectHttpHeaderTest27", DetectHttpHeaderTest27); + UtRegisterTest("DetectHttpHeaderTest28", DetectHttpHeaderTest28); + UtRegisterTest("DetectHttpHeaderTest29", DetectHttpHeaderTest29); + UtRegisterTest("DetectHttpHeaderTest30", DetectHttpHeaderTest30); + + UtRegisterTest("DetectHttpHeaderIsdataatParseTest", + DetectHttpHeaderIsdataatParseTest); + + UtRegisterTest("DetectEngineHttpHeaderTest01", + DetectEngineHttpHeaderTest01); + UtRegisterTest("DetectEngineHttpHeaderTest02", + DetectEngineHttpHeaderTest02); + UtRegisterTest("DetectEngineHttpHeaderTest03", + DetectEngineHttpHeaderTest03); + UtRegisterTest("DetectEngineHttpHeaderTest04", + DetectEngineHttpHeaderTest04); + UtRegisterTest("DetectEngineHttpHeaderTest05", + DetectEngineHttpHeaderTest05); + UtRegisterTest("DetectEngineHttpHeaderTest06", + DetectEngineHttpHeaderTest06); + UtRegisterTest("DetectEngineHttpHeaderTest07", + DetectEngineHttpHeaderTest07); + UtRegisterTest("DetectEngineHttpHeaderTest08", + DetectEngineHttpHeaderTest08); + UtRegisterTest("DetectEngineHttpHeaderTest09", + DetectEngineHttpHeaderTest09); + UtRegisterTest("DetectEngineHttpHeaderTest10", + DetectEngineHttpHeaderTest10); + UtRegisterTest("DetectEngineHttpHeaderTest11", + DetectEngineHttpHeaderTest11); + UtRegisterTest("DetectEngineHttpHeaderTest12", + DetectEngineHttpHeaderTest12); + UtRegisterTest("DetectEngineHttpHeaderTest13", + DetectEngineHttpHeaderTest13); + UtRegisterTest("DetectEngineHttpHeaderTest14", + DetectEngineHttpHeaderTest14); + UtRegisterTest("DetectEngineHttpHeaderTest15", + DetectEngineHttpHeaderTest15); + UtRegisterTest("DetectEngineHttpHeaderTest16", + DetectEngineHttpHeaderTest16); + UtRegisterTest("DetectEngineHttpHeaderTest17", + DetectEngineHttpHeaderTest17); + UtRegisterTest("DetectEngineHttpHeaderTest20", + DetectEngineHttpHeaderTest20); + UtRegisterTest("DetectEngineHttpHeaderTest21", + DetectEngineHttpHeaderTest21); + UtRegisterTest("DetectEngineHttpHeaderTest22", + DetectEngineHttpHeaderTest22); + UtRegisterTest("DetectEngineHttpHeaderTest23", + DetectEngineHttpHeaderTest23); + UtRegisterTest("DetectEngineHttpHeaderTest24", + DetectEngineHttpHeaderTest24); + UtRegisterTest("DetectEngineHttpHeaderTest25", + DetectEngineHttpHeaderTest25); + UtRegisterTest("DetectEngineHttpHeaderTest26", + DetectEngineHttpHeaderTest26); + UtRegisterTest("DetectEngineHttpHeaderTest27", + DetectEngineHttpHeaderTest27); + UtRegisterTest("DetectEngineHttpHeaderTest28", + DetectEngineHttpHeaderTest28); + UtRegisterTest("DetectEngineHttpHeaderTest29", + DetectEngineHttpHeaderTest29); + UtRegisterTest("DetectEngineHttpHeaderTest30", + DetectEngineHttpHeaderTest30); + UtRegisterTest("DetectEngineHttpHeaderTest31", + DetectEngineHttpHeaderTest31); +#if 0 + UtRegisterTest("DetectEngineHttpHeaderTest30", + DetectEngineHttpHeaderTest30, 1); +#endif + UtRegisterTest("DetectEngineHttpHeaderTest32", + DetectEngineHttpHeaderTest32); + UtRegisterTest("DetectEngineHttpHeaderTest33 -- Trailer", + DetectEngineHttpHeaderTest33); + UtRegisterTest("DetectEngineHttpHeaderTest34 -- Trailer", + DetectEngineHttpHeaderTest34); + UtRegisterTest("DetectEngineHttpHeaderTest35 -- Trailer", + DetectEngineHttpHeaderTest35); +} + +/** + * @} + */