From 76fd666cad09fb1a9b97e1c3a901b944fdc62fd5 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Tue, 11 Dec 2018 07:26:22 +0100 Subject: [PATCH] detect/http_raw_header: move tests into tests/ --- src/Makefile.am | 1 - src/detect-engine-file.c | 1 - src/detect-engine-hrhd.h | 29 - src/detect-engine-mpm.c | 1 - src/detect-engine-register.c | 1 - src/detect-engine.c | 1 - src/detect-http-raw-header.c | 1439 +-------------- src/runmode-unittests.c | 2 - .../detect-http-raw-header.c} | 1588 ++++++++++++++++- 9 files changed, 1501 insertions(+), 1562 deletions(-) delete mode 100644 src/detect-engine-hrhd.h rename src/{detect-engine-hrhd.c => tests/detect-http-raw-header.c} (67%) diff --git a/src/Makefile.am b/src/Makefile.am index b2ea5985fc..63a749e4f4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -132,7 +132,6 @@ detect-engine-event.c detect-engine-event.h \ detect-engine-file.c detect-engine-file.h \ detect-engine-filedata.c detect-engine-filedata.h \ detect-engine-hcbd.c detect-engine-hcbd.h \ -detect-engine-hrhd.c detect-engine-hrhd.h \ detect-engine-hsbd.c detect-engine-hsbd.h \ detect-engine-iponly.c detect-engine-iponly.h \ detect-engine-loader.c detect-engine-loader.h \ diff --git a/src/detect-engine-file.c b/src/detect-engine-file.c index e4072b69e5..c29cc25592 100644 --- a/src/detect-engine-file.c +++ b/src/detect-engine-file.c @@ -33,7 +33,6 @@ #include "detect-filestore.h" #include "detect-engine-hcbd.h" -#include "detect-engine-hrhd.h" #include "detect-engine-dcepayload.h" #include "detect-engine-file.h" diff --git a/src/detect-engine-hrhd.h b/src/detect-engine-hrhd.h deleted file mode 100644 index 1c4436fed9..0000000000 --- a/src/detect-engine-hrhd.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (C) 2007-2010 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. - */ - -/** \file - * - * \author Anoop Saldanha - */ - -#ifndef __DETECT_ENGINE_HRHD_H__ -#define __DETECT_ENGINE_HRHD_H__ - -void DetectEngineHttpRawHeaderRegisterTests(void); - -#endif /* __DETECT_ENGINE_HHD_H__ */ - diff --git a/src/detect-engine-mpm.c b/src/detect-engine-mpm.c index 7906c70ab8..77cdc6140f 100644 --- a/src/detect-engine-mpm.c +++ b/src/detect-engine-mpm.c @@ -50,7 +50,6 @@ #include "detect-content.h" #include "detect-engine-payload.h" -#include "detect-engine-hrhd.h" #include "detect-engine-hcbd.h" #include "detect-engine-hsbd.h" #include "detect-engine-dns.h" diff --git a/src/detect-engine-register.c b/src/detect-engine-register.c index 938bcf2a23..9bbdd5370e 100644 --- a/src/detect-engine-register.c +++ b/src/detect-engine-register.c @@ -155,7 +155,6 @@ #include "detect-http-response-line.h" #include "detect-engine-hcbd.h" #include "detect-engine-hsbd.h" -#include "detect-engine-hrhd.h" #include "detect-byte-extract.h" #include "detect-file-data.h" #include "detect-pkt-data.h" diff --git a/src/detect-engine.c b/src/detect-engine.c index 34c0b0884a..d2178fb90a 100644 --- a/src/detect-engine.c +++ b/src/detect-engine.c @@ -46,7 +46,6 @@ #include "detect-engine-iponly.h" #include "detect-engine-tag.h" -#include "detect-engine-hrhd.h" #include "detect-engine-file.h" #include "detect-engine.h" diff --git a/src/detect-http-raw-header.c b/src/detect-http-raw-header.c index bddab2406d..e6318668a1 100644 --- a/src/detect-http-raw-header.c +++ b/src/detect-http-raw-header.c @@ -40,28 +40,22 @@ #include "detect-engine-mpm.h" #include "detect-engine-prefilter.h" #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 "app-layer.h" #include "app-layer-parser.h" - #include "app-layer-htp.h" #include "detect-http-raw-header.h" -#include "detect-engine-hrhd.h" -#include "stream-tcp.h" static int DetectHttpRawHeaderSetup(DetectEngineCtx *, Signature *, const char *); +#ifdef UNITTESTS static void DetectHttpRawHeaderRegisterTests(void); +#endif static _Bool DetectHttpRawHeaderValidateCallback(const Signature *s, const char **sigerror); static int g_http_raw_header_buffer_id = 0; static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx, @@ -82,7 +76,9 @@ void DetectHttpRawHeaderRegister(void) { sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].name = "http_raw_header"; sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].Setup = DetectHttpRawHeaderSetup; +#ifdef UNITTESTS sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].RegisterTests = DetectHttpRawHeaderRegisterTests; +#endif sigmatch_table[DETECT_AL_HTTP_RAW_HEADER].flags |= SIGMATCH_NOOPT; DetectAppLayerInspectEngineRegister2("http_raw_header", ALPROTO_HTTP, @@ -319,1432 +315,9 @@ static int PrefilterMpmHttpHeaderRawResponseRegister(DetectEngineCtx *de_ctx, /************************************Unittests*********************************/ #ifdef UNITTESTS +#include "tests/detect-http-raw-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 DetectHttpRawHeaderTest01(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\"; flow:to_server; " - "content:\"one\"; http_raw_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_raw_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 DetectHttpRawHeaderTest02(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\"; flow:to_server; " - "content:\"one\"; http_raw_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 DetectHttpRawHeaderTest03(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\"; flow:to_server; " - "http_raw_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 DetectHttpRawHeaderTest04(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\"; flow:to_server; " - "content:\"one\"; rawbytes; http_raw_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 DetectHttpRawHeaderTest05(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\"; flow:to_server; " - "content:\"one\"; nocase; http_raw_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 DetectHttpRawHeaderTest06(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\"; flow:to_server; " - "content:\"Content-Type: text/html\"; http_raw_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 DetectHttpRawHeaderTest07(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: 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; - 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\"; flow:to_server; " - "content:\"Mozilla\"; http_raw_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 - * which holds the content. - */ -static int DetectHttpRawHeaderTest08(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\"; flow:to_server; " - "content:\"Gecko/20091221 Firefox/3.5.7\"; http_raw_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 DetectHttpRawHeaderTest09(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->sig_list = SigInit(de_ctx,"alert http any any -> any any " - "(msg:\"http header test\"; flow:to_server; " - "content:\"Firefox/3.5.7|0D 0A|Content\"; http_raw_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 - * against a case insensitive pattern. - */ -static int DetectHttpRawHeaderTest10(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\"; flow:to_server; " - "content:\"firefox/3.5.7|0D 0A|content\"; nocase; http_raw_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 DetectHttpRawHeaderTest11(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\"; flow:to_server; " - "content:!\"lalalalala\"; http_raw_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 DetectHttpRawHeaderTest12(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\"; flow:to_server; " - "content:!\"User-Agent: Mozilla/5.0 \"; http_raw_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 DetectHttpRawHeaderTest13(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\"; flow:to_server; " - "content:\"Host: www.openinfosecfoundation.org\"; http_raw_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 DetectHttpRawHeaderTest20(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 http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; " - "content:\"two\"; distance:0; http_raw_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_raw_header_buffer_id] == NULL) { - printf("de_ctx->sig_list->sm_lists[g_http_raw_header_buffer_id] == NULL\n"); - goto end; - } - - DetectContentData *hrhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev->ctx; - DetectContentData *hrhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->ctx; - if (hrhd1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(hrhd1->content, "one", hrhd1->content_len) != 0 || - hrhd2->flags != DETECT_CONTENT_DISTANCE || - memcmp(hrhd2->content, "two", hrhd1->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -static int DetectHttpRawHeaderTest21(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 http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_header; " - "content:\"two\"; within:5; http_raw_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_raw_header_buffer_id] == NULL) { - printf("de_ctx->sig_list->sm_lists[g_http_raw_header_buffer_id] == NULL\n"); - goto end; - } - - DetectContentData *hrhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev->ctx; - DetectContentData *hrhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->ctx; - if (hrhd1->flags != DETECT_CONTENT_RELATIVE_NEXT || - memcmp(hrhd1->content, "one", hrhd1->content_len) != 0 || - hrhd2->flags != DETECT_CONTENT_WITHIN || - memcmp(hrhd2->content, "two", hrhd1->content_len) != 0) { - goto end; - } - - result = 1; - - end: - SigCleanSignatures(de_ctx); - DetectEngineCtxFree(de_ctx); - return result; -} - -static int DetectHttpRawHeaderTest22(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 http any any -> any any " - "(flow:to_server; content:\"one\"; within:5; http_raw_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 DetectHttpRawHeaderTest23(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 http any any -> any any " - "(flow:to_server; content:\"one\"; http_raw_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 DetectHttpRawHeaderTest24(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 http any any -> any any " - "(flow:to_server; 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 DetectHttpRawHeaderTest25(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 http any any -> any any " - "(flow:to_server; pcre:/one/D; " - "content:\"two\"; within:5; http_raw_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_raw_header_buffer_id] == NULL) { - printf("de_ctx->sig_list->sm_lists[g_http_raw_header_buffer_id] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id] == NULL || - de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->type != DETECT_CONTENT || - de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev == NULL || - de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev->type != DETECT_PCRE) { - - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev->ctx; - DetectContentData *hhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_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 DetectHttpRawHeaderTest26(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 http any any -> any any " - "(flow:to_server; content:\"two\"; http_raw_header; " - "pcre:/one/DR; 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_raw_header_buffer_id] == NULL) { - printf("de_ctx->sig_list->sm_lists[g_http_raw_header_buffer_id] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id] == NULL || - de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->type != DETECT_PCRE || - de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev == NULL || - de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev->type != DETECT_CONTENT) { - - goto end; - } - - DetectContentData *hhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev->ctx; - DetectPcreData *pd2 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_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 DetectHttpRawHeaderTest27(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 http any any -> any any " - "(flow:to_server; pcre:/one/D; " - "content:\"two\"; distance:5; http_raw_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_raw_header_buffer_id] == NULL) { - printf("de_ctx->sig_list->sm_lists[g_http_raw_header_buffer_id] == NULL\n"); - goto end; - } - - if (de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id] == NULL || - de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->type != DETECT_CONTENT || - de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev == NULL || - de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev->type != DETECT_PCRE) { - - goto end; - } - - DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev->ctx; - DetectContentData *hhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_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; -} - -static int DetectHttpRawHeaderIsdataatParseTest(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_raw_header; " - "isdataat:!4,relative; sid:1;)"); - FAIL_IF_NULL(s); - - SigMatch *sm = s->init_data->smlists_tail[g_http_raw_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; -} - -#endif /* UNITTESTS */ - -void DetectHttpRawHeaderRegisterTests(void) -{ -#ifdef UNITTESTS - UtRegisterTest("DetectHttpRawHeaderTest01", DetectHttpRawHeaderTest01); - UtRegisterTest("DetectHttpRawHeaderTest02", DetectHttpRawHeaderTest02); - UtRegisterTest("DetectHttpRawHeaderTest03", DetectHttpRawHeaderTest03); - UtRegisterTest("DetectHttpRawHeaderTest04", DetectHttpRawHeaderTest04); - UtRegisterTest("DetectHttpRawHeaderTest05", DetectHttpRawHeaderTest05); - UtRegisterTest("DetectHttpRawHeaderTest06", DetectHttpRawHeaderTest06); - UtRegisterTest("DetectHttpRawHeaderTest07", DetectHttpRawHeaderTest07); - UtRegisterTest("DetectHttpRawHeaderTest08", DetectHttpRawHeaderTest08); - UtRegisterTest("DetectHttpRawHeaderTest09", DetectHttpRawHeaderTest09); - UtRegisterTest("DetectHttpRawHeaderTest10", DetectHttpRawHeaderTest10); - UtRegisterTest("DetectHttpRawHeaderTest11", DetectHttpRawHeaderTest11); - UtRegisterTest("DetectHttpRawHeaderTest12", DetectHttpRawHeaderTest12); - UtRegisterTest("DetectHttpRawHeaderTest13", DetectHttpRawHeaderTest13); - UtRegisterTest("DetectHttpRawHeaderTest20", DetectHttpRawHeaderTest20); - UtRegisterTest("DetectHttpRawHeaderTest21", DetectHttpRawHeaderTest21); - UtRegisterTest("DetectHttpRawHeaderTest22", DetectHttpRawHeaderTest22); - UtRegisterTest("DetectHttpRawHeaderTest23", DetectHttpRawHeaderTest23); - UtRegisterTest("DetectHttpRawHeaderTest24", DetectHttpRawHeaderTest24); - UtRegisterTest("DetectHttpRawHeaderTest25", DetectHttpRawHeaderTest25); - UtRegisterTest("DetectHttpRawHeaderTest26", DetectHttpRawHeaderTest26); - UtRegisterTest("DetectHttpRawHeaderTest27", DetectHttpRawHeaderTest27); - - UtRegisterTest("DetectHttpRawHeaderIsdataatParseTest", - DetectHttpRawHeaderIsdataatParseTest); -#endif /* UNITTESTS */ - - return; -} /** * @} */ diff --git a/src/runmode-unittests.c b/src/runmode-unittests.c index 24e04451ae..dc3b09f542 100644 --- a/src/runmode-unittests.c +++ b/src/runmode-unittests.c @@ -38,7 +38,6 @@ #include "detect-engine-dcepayload.h" #include "detect-engine-hcbd.h" #include "detect-engine-hsbd.h" -#include "detect-engine-hrhd.h" #include "detect-engine-state.h" #include "detect-engine-tag.h" #include "detect-engine-modbus.h" @@ -193,7 +192,6 @@ static void RegisterUnittests(void) MemcmpRegisterTests(); DetectEngineHttpClientBodyRegisterTests(); DetectEngineHttpServerBodyRegisterTests(); - DetectEngineHttpRawHeaderRegisterTests(); DetectEngineInspectModbusRegisterTests(); DetectEngineRegisterTests(); DetectEngineSMTPFiledataRegisterTests(); diff --git a/src/detect-engine-hrhd.c b/src/tests/detect-http-raw-header.c similarity index 67% rename from src/detect-engine-hrhd.c rename to src/tests/detect-http-raw-header.c index 67919fca2c..dee84cdc74 100644 --- a/src/detect-engine-hrhd.c +++ b/src/tests/detect-http-raw-header.c @@ -31,35 +31,24 @@ * */ -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" +#include "../suricata-common.h" +#include "../suricata.h" +#include "../decode.h" -#include "detect.h" -#include "detect-engine.h" -#include "detect-engine-hrhd.h" -#include "detect-engine-mpm.h" -#include "detect-parse.h" -#include "detect-engine-state.h" -#include "detect-engine-content-inspection.h" -#include "detect-engine-prefilter.h" +#include "../detect.h" +#include "../detect-engine.h" +#include "../detect-isdataat.h" +#include "../detect-pcre.h" -#include "flow-util.h" -#include "util-debug.h" -#include "util-print.h" -#include "flow.h" +#include "../stream-tcp.h" +#include "../app-layer.h" +#include "../app-layer-htp.h" +#include "../app-layer-protos.h" +#include "../app-layer-parser.h" -#include "stream-tcp.h" - -#include "app-layer-parser.h" - -#include "util-unittest.h" -#include "util-unittest-helper.h" -#include "app-layer.h" -#include "app-layer-htp.h" -#include "app-layer-protos.h" - -#include "util-validate.h" +#include "../util-unittest.h" +#include "../util-unittest-helper.h" +#include "../util-validate.h" /***********************************Unittests**********************************/ @@ -3100,78 +3089,1491 @@ end: return result; } -#endif /* UNITTESTS */ +/** + * \test Test that a signature containting a http_header is correctly parsed + * and the keyword is registered. + */ +static int DetectHttpRawHeaderTest01(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\"; flow:to_server; " + "content:\"one\"; http_raw_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_raw_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; +} -void DetectEngineHttpRawHeaderRegisterTests(void) +/** + * \test Test that a signature containing an valid http_header entry is + * parsed. + */ +static int DetectHttpRawHeaderTest02(void) { + DetectEngineCtx *de_ctx = NULL; + int result = 0; -#ifdef UNITTESTS - UtRegisterTest("DetectEngineHttpRawHeaderTest01", - DetectEngineHttpRawHeaderTest01); - UtRegisterTest("DetectEngineHttpRawHeaderTest02", - DetectEngineHttpRawHeaderTest02); - UtRegisterTest("DetectEngineHttpRawHeaderTest03", - DetectEngineHttpRawHeaderTest03); - UtRegisterTest("DetectEngineHttpRawHeaderTest04", - DetectEngineHttpRawHeaderTest04); - UtRegisterTest("DetectEngineHttpRawHeaderTest05", - DetectEngineHttpRawHeaderTest05); - UtRegisterTest("DetectEngineHttpRawHeaderTest06", - DetectEngineHttpRawHeaderTest06); - UtRegisterTest("DetectEngineHttpRawHeaderTest07", - DetectEngineHttpRawHeaderTest07); - UtRegisterTest("DetectEngineHttpRawHeaderTest08", - DetectEngineHttpRawHeaderTest08); - UtRegisterTest("DetectEngineHttpRawHeaderTest09", - DetectEngineHttpRawHeaderTest09); - UtRegisterTest("DetectEngineHttpRawHeaderTest10", - DetectEngineHttpRawHeaderTest10); - UtRegisterTest("DetectEngineHttpRawHeaderTest11", - DetectEngineHttpRawHeaderTest11); - UtRegisterTest("DetectEngineHttpRawHeaderTest12", - DetectEngineHttpRawHeaderTest12); - UtRegisterTest("DetectEngineHttpRawHeaderTest13", - DetectEngineHttpRawHeaderTest13); - UtRegisterTest("DetectEngineHttpRawHeaderTest14", - DetectEngineHttpRawHeaderTest14); - UtRegisterTest("DetectEngineHttpRawHeaderTest15", - DetectEngineHttpRawHeaderTest15); - UtRegisterTest("DetectEngineHttpRawHeaderTest16", - DetectEngineHttpRawHeaderTest16); - UtRegisterTest("DetectEngineHttpRawHeaderTest17", - DetectEngineHttpRawHeaderTest17); - UtRegisterTest("DetectEngineHttpRawHeaderTest20", - DetectEngineHttpRawHeaderTest20); - UtRegisterTest("DetectEngineHttpRawHeaderTest21", - DetectEngineHttpRawHeaderTest21); - UtRegisterTest("DetectEngineHttpRawHeaderTest22", - DetectEngineHttpRawHeaderTest22); - UtRegisterTest("DetectEngineHttpRawHeaderTest23", - DetectEngineHttpRawHeaderTest23); - UtRegisterTest("DetectEngineHttpRawHeaderTest24", - DetectEngineHttpRawHeaderTest24); - UtRegisterTest("DetectEngineHttpRawHeaderTest25", - DetectEngineHttpRawHeaderTest25); - UtRegisterTest("DetectEngineHttpRawHeaderTest26", - DetectEngineHttpRawHeaderTest26); - UtRegisterTest("DetectEngineHttpRawHeaderTest27", - DetectEngineHttpRawHeaderTest27); - UtRegisterTest("DetectEngineHttpRawHeaderTest28", - DetectEngineHttpRawHeaderTest28); - UtRegisterTest("DetectEngineHttpRawHeaderTest29", - DetectEngineHttpRawHeaderTest29); -#if 0 - UtRegisterTest("DetectEngineHttpRawHeaderTest30", - DetectEngineHttpRawHeaderTest30, 1); -#endif - UtRegisterTest("DetectEngineHttpRawHeaderTest31", - DetectEngineHttpRawHeaderTest31); - UtRegisterTest("DetectEngineHttpRawHeaderTest32", - DetectEngineHttpRawHeaderTest32); -#endif /* UNITTESTS */ + de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) + goto end; - return; + de_ctx->flags |= DE_QUIET; + de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " + "(msg:\"Testing http_header\"; flow:to_server; " + "content:\"one\"; http_raw_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 DetectHttpRawHeaderTest03(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\"; flow:to_server; " + "http_raw_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 DetectHttpRawHeaderTest04(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\"; flow:to_server; " + "content:\"one\"; rawbytes; http_raw_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 DetectHttpRawHeaderTest05(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\"; flow:to_server; " + "content:\"one\"; nocase; http_raw_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 DetectHttpRawHeaderTest06(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\"; flow:to_server; " + "content:\"Content-Type: text/html\"; http_raw_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 DetectHttpRawHeaderTest07(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: 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; + 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\"; flow:to_server; " + "content:\"Mozilla\"; http_raw_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 + * which holds the content. + */ +static int DetectHttpRawHeaderTest08(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\"; flow:to_server; " + "content:\"Gecko/20091221 Firefox/3.5.7\"; http_raw_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 DetectHttpRawHeaderTest09(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->sig_list = SigInit(de_ctx,"alert http any any -> any any " + "(msg:\"http header test\"; flow:to_server; " + "content:\"Firefox/3.5.7|0D 0A|Content\"; http_raw_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 + * against a case insensitive pattern. + */ +static int DetectHttpRawHeaderTest10(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\"; flow:to_server; " + "content:\"firefox/3.5.7|0D 0A|content\"; nocase; http_raw_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 DetectHttpRawHeaderTest11(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\"; flow:to_server; " + "content:!\"lalalalala\"; http_raw_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 DetectHttpRawHeaderTest12(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\"; flow:to_server; " + "content:!\"User-Agent: Mozilla/5.0 \"; http_raw_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 DetectHttpRawHeaderTest13(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\"; flow:to_server; " + "content:\"Host: www.openinfosecfoundation.org\"; http_raw_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 DetectHttpRawHeaderTest20(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 http any any -> any any " + "(flow:to_server; content:\"one\"; http_raw_header; " + "content:\"two\"; distance:0; http_raw_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_raw_header_buffer_id] == NULL) { + printf("de_ctx->sig_list->sm_lists[g_http_raw_header_buffer_id] == NULL\n"); + goto end; + } + + DetectContentData *hrhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev->ctx; + DetectContentData *hrhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->ctx; + if (hrhd1->flags != DETECT_CONTENT_RELATIVE_NEXT || + memcmp(hrhd1->content, "one", hrhd1->content_len) != 0 || + hrhd2->flags != DETECT_CONTENT_DISTANCE || + memcmp(hrhd2->content, "two", hrhd1->content_len) != 0) { + goto end; + } + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +static int DetectHttpRawHeaderTest21(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 http any any -> any any " + "(flow:to_server; content:\"one\"; http_raw_header; " + "content:\"two\"; within:5; http_raw_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_raw_header_buffer_id] == NULL) { + printf("de_ctx->sig_list->sm_lists[g_http_raw_header_buffer_id] == NULL\n"); + goto end; + } + + DetectContentData *hrhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev->ctx; + DetectContentData *hrhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->ctx; + if (hrhd1->flags != DETECT_CONTENT_RELATIVE_NEXT || + memcmp(hrhd1->content, "one", hrhd1->content_len) != 0 || + hrhd2->flags != DETECT_CONTENT_WITHIN || + memcmp(hrhd2->content, "two", hrhd1->content_len) != 0) { + goto end; + } + + result = 1; + + end: + SigCleanSignatures(de_ctx); + DetectEngineCtxFree(de_ctx); + return result; +} + +static int DetectHttpRawHeaderTest22(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 http any any -> any any " + "(flow:to_server; content:\"one\"; within:5; http_raw_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 DetectHttpRawHeaderTest23(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 http any any -> any any " + "(flow:to_server; content:\"one\"; http_raw_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 DetectHttpRawHeaderTest24(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 http any any -> any any " + "(flow:to_server; 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 DetectHttpRawHeaderTest25(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 http any any -> any any " + "(flow:to_server; pcre:/one/D; " + "content:\"two\"; within:5; http_raw_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_raw_header_buffer_id] == NULL) { + printf("de_ctx->sig_list->sm_lists[g_http_raw_header_buffer_id] == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id] == NULL || + de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->type != DETECT_CONTENT || + de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev == NULL || + de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev->type != DETECT_PCRE) { + + goto end; + } + + DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev->ctx; + DetectContentData *hhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_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 DetectHttpRawHeaderTest26(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 http any any -> any any " + "(flow:to_server; content:\"two\"; http_raw_header; " + "pcre:/one/DR; 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_raw_header_buffer_id] == NULL) { + printf("de_ctx->sig_list->sm_lists[g_http_raw_header_buffer_id] == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id] == NULL || + de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->type != DETECT_PCRE || + de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev == NULL || + de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev->type != DETECT_CONTENT) { + + goto end; + } + + DetectContentData *hhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev->ctx; + DetectPcreData *pd2 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_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 DetectHttpRawHeaderTest27(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 http any any -> any any " + "(flow:to_server; pcre:/one/D; " + "content:\"two\"; distance:5; http_raw_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_raw_header_buffer_id] == NULL) { + printf("de_ctx->sig_list->sm_lists[g_http_raw_header_buffer_id] == NULL\n"); + goto end; + } + + if (de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id] == NULL || + de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->type != DETECT_CONTENT || + de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev == NULL || + de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev->type != DETECT_PCRE) { + + goto end; + } + + DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev->ctx; + DetectContentData *hhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_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; +} + +static int DetectHttpRawHeaderIsdataatParseTest(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_raw_header; " + "isdataat:!4,relative; sid:1;)"); + FAIL_IF_NULL(s); + + SigMatch *sm = s->init_data->smlists_tail[g_http_raw_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; +} + +void DetectHttpRawHeaderRegisterTests(void) +{ + UtRegisterTest("DetectEngineHttpRawHeaderTest01", + DetectEngineHttpRawHeaderTest01); + UtRegisterTest("DetectEngineHttpRawHeaderTest02", + DetectEngineHttpRawHeaderTest02); + UtRegisterTest("DetectEngineHttpRawHeaderTest03", + DetectEngineHttpRawHeaderTest03); + UtRegisterTest("DetectEngineHttpRawHeaderTest04", + DetectEngineHttpRawHeaderTest04); + UtRegisterTest("DetectEngineHttpRawHeaderTest05", + DetectEngineHttpRawHeaderTest05); + UtRegisterTest("DetectEngineHttpRawHeaderTest06", + DetectEngineHttpRawHeaderTest06); + UtRegisterTest("DetectEngineHttpRawHeaderTest07", + DetectEngineHttpRawHeaderTest07); + UtRegisterTest("DetectEngineHttpRawHeaderTest08", + DetectEngineHttpRawHeaderTest08); + UtRegisterTest("DetectEngineHttpRawHeaderTest09", + DetectEngineHttpRawHeaderTest09); + UtRegisterTest("DetectEngineHttpRawHeaderTest10", + DetectEngineHttpRawHeaderTest10); + UtRegisterTest("DetectEngineHttpRawHeaderTest11", + DetectEngineHttpRawHeaderTest11); + UtRegisterTest("DetectEngineHttpRawHeaderTest12", + DetectEngineHttpRawHeaderTest12); + UtRegisterTest("DetectEngineHttpRawHeaderTest13", + DetectEngineHttpRawHeaderTest13); + UtRegisterTest("DetectEngineHttpRawHeaderTest14", + DetectEngineHttpRawHeaderTest14); + UtRegisterTest("DetectEngineHttpRawHeaderTest15", + DetectEngineHttpRawHeaderTest15); + UtRegisterTest("DetectEngineHttpRawHeaderTest16", + DetectEngineHttpRawHeaderTest16); + UtRegisterTest("DetectEngineHttpRawHeaderTest17", + DetectEngineHttpRawHeaderTest17); + UtRegisterTest("DetectEngineHttpRawHeaderTest20", + DetectEngineHttpRawHeaderTest20); + UtRegisterTest("DetectEngineHttpRawHeaderTest21", + DetectEngineHttpRawHeaderTest21); + UtRegisterTest("DetectEngineHttpRawHeaderTest22", + DetectEngineHttpRawHeaderTest22); + UtRegisterTest("DetectEngineHttpRawHeaderTest23", + DetectEngineHttpRawHeaderTest23); + UtRegisterTest("DetectEngineHttpRawHeaderTest24", + DetectEngineHttpRawHeaderTest24); + UtRegisterTest("DetectEngineHttpRawHeaderTest25", + DetectEngineHttpRawHeaderTest25); + UtRegisterTest("DetectEngineHttpRawHeaderTest26", + DetectEngineHttpRawHeaderTest26); + UtRegisterTest("DetectEngineHttpRawHeaderTest27", + DetectEngineHttpRawHeaderTest27); + UtRegisterTest("DetectEngineHttpRawHeaderTest28", + DetectEngineHttpRawHeaderTest28); + UtRegisterTest("DetectEngineHttpRawHeaderTest29", + DetectEngineHttpRawHeaderTest29); +#if 0 + UtRegisterTest("DetectEngineHttpRawHeaderTest30", + DetectEngineHttpRawHeaderTest30, 1); +#endif + UtRegisterTest("DetectEngineHttpRawHeaderTest31", + DetectEngineHttpRawHeaderTest31); + UtRegisterTest("DetectEngineHttpRawHeaderTest32", + DetectEngineHttpRawHeaderTest32); + + UtRegisterTest("DetectHttpRawHeaderTest01", DetectHttpRawHeaderTest01); + UtRegisterTest("DetectHttpRawHeaderTest02", DetectHttpRawHeaderTest02); + UtRegisterTest("DetectHttpRawHeaderTest03", DetectHttpRawHeaderTest03); + UtRegisterTest("DetectHttpRawHeaderTest04", DetectHttpRawHeaderTest04); + UtRegisterTest("DetectHttpRawHeaderTest05", DetectHttpRawHeaderTest05); + UtRegisterTest("DetectHttpRawHeaderTest06", DetectHttpRawHeaderTest06); + UtRegisterTest("DetectHttpRawHeaderTest07", DetectHttpRawHeaderTest07); + UtRegisterTest("DetectHttpRawHeaderTest08", DetectHttpRawHeaderTest08); + UtRegisterTest("DetectHttpRawHeaderTest09", DetectHttpRawHeaderTest09); + UtRegisterTest("DetectHttpRawHeaderTest10", DetectHttpRawHeaderTest10); + UtRegisterTest("DetectHttpRawHeaderTest11", DetectHttpRawHeaderTest11); + UtRegisterTest("DetectHttpRawHeaderTest12", DetectHttpRawHeaderTest12); + UtRegisterTest("DetectHttpRawHeaderTest13", DetectHttpRawHeaderTest13); + UtRegisterTest("DetectHttpRawHeaderTest20", DetectHttpRawHeaderTest20); + UtRegisterTest("DetectHttpRawHeaderTest21", DetectHttpRawHeaderTest21); + UtRegisterTest("DetectHttpRawHeaderTest22", DetectHttpRawHeaderTest22); + UtRegisterTest("DetectHttpRawHeaderTest23", DetectHttpRawHeaderTest23); + UtRegisterTest("DetectHttpRawHeaderTest24", DetectHttpRawHeaderTest24); + UtRegisterTest("DetectHttpRawHeaderTest25", DetectHttpRawHeaderTest25); + UtRegisterTest("DetectHttpRawHeaderTest26", DetectHttpRawHeaderTest26); + UtRegisterTest("DetectHttpRawHeaderTest27", DetectHttpRawHeaderTest27); + + UtRegisterTest("DetectHttpRawHeaderIsdataatParseTest", + DetectHttpRawHeaderIsdataatParseTest); + + + return; +} + +#endif /* UNITTESTS */ + /** * @} */ -- 2.47.2