From: Victor Julien Date: Mon, 26 Nov 2018 11:06:55 +0000 (+0100) Subject: detect/http_stat_msg: move tests to tests/ X-Git-Tag: suricata-5.0.0-beta1~270 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5dfba01b2e43740e7ce982363d7bd54c78c5d7f3;p=thirdparty%2Fsuricata.git detect/http_stat_msg: move tests to tests/ --- diff --git a/src/Makefile.am b/src/Makefile.am index b6ec1973fd..05edb783aa 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -136,7 +136,6 @@ detect-engine-hcd.c detect-engine-hcd.h \ detect-engine-hrhd.c detect-engine-hrhd.h \ detect-engine-hsbd.c detect-engine-hsbd.h \ detect-engine-hscd.c detect-engine-hscd.h \ -detect-engine-hsmd.c detect-engine-hsmd.h \ detect-engine-iponly.c detect-engine-iponly.h \ detect-engine-loader.c detect-engine-loader.h \ detect-engine-mpm.c detect-engine-mpm.h \ diff --git a/src/detect-engine-hsmd.h b/src/detect-engine-hsmd.h deleted file mode 100644 index c56cd73f38..0000000000 --- a/src/detect-engine-hsmd.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright (C) 2007-2016 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_HSMD_H__ -#define __DETECT_ENGINE_HSMD_H__ - -void DetectEngineHttpStatMsgRegisterTests(void); - -#endif /* __DETECT_ENGINE_HSMD_H__ */ diff --git a/src/detect-engine-mpm.c b/src/detect-engine-mpm.c index 08bd1b210b..fea3ae9ed1 100644 --- a/src/detect-engine-mpm.c +++ b/src/detect-engine-mpm.c @@ -52,7 +52,6 @@ #include "detect-engine-payload.h" #include "detect-engine-hrhd.h" #include "detect-engine-hcd.h" -#include "detect-engine-hsmd.h" #include "detect-engine-hscd.h" #include "detect-engine-hcbd.h" #include "detect-engine-hsbd.h" diff --git a/src/detect-engine-register.c b/src/detect-engine-register.c index 207c33827f..57d52b85fe 100644 --- a/src/detect-engine-register.c +++ b/src/detect-engine-register.c @@ -157,7 +157,6 @@ #include "detect-engine-hsbd.h" #include "detect-engine-hrhd.h" #include "detect-engine-hcd.h" -#include "detect-engine-hsmd.h" #include "detect-engine-hscd.h" #include "detect-byte-extract.h" #include "detect-file-data.h" diff --git a/src/detect-http-stat-msg.c b/src/detect-http-stat-msg.c index aba7fe407f..d76e5bc215 100644 --- a/src/detect-http-stat-msg.c +++ b/src/detect-http-stat-msg.c @@ -64,7 +64,9 @@ #include "stream-tcp.h" static int DetectHttpStatMsgSetup(DetectEngineCtx *, Signature *, const char *); +#ifdef UNITTESTS static void DetectHttpStatMsgRegisterTests(void); +#endif static int g_http_stat_msg_buffer_id = 0; static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx, const DetectEngineTransforms *transforms, Flow *_f, @@ -141,459 +143,9 @@ static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx, } #ifdef UNITTESTS - -/** - * \test Checks if a http_stat_msg is registered in a Signature, if content is not - * specified in the signature or rawbyes is specified or fast_pattern is - * provided in the signature. - */ -static int DetectHttpStatMsgTest01(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 tcp any any -> any any " - "(msg:\"Testing http_stat_msg\"; http_stat_msg;sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_stat_msg\"; content:\"|FF F1|\";" - " rawbytes; http_stat_msg;sid:1;)"); - if (de_ctx->sig_list != NULL) - goto end; - - de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " - "(msg:\"Testing http_stat_msg\"; content:\"one\";" - "fast_pattern; http_stat_msg; sid:1;)"); - if (de_ctx->sig_list == NULL) - goto end; - if (!(((DetectContentData *)de_ctx->sig_list->sm_lists[g_http_stat_msg_buffer_id]->ctx)->flags & - DETECT_CONTENT_FAST_PATTERN)) - { - goto end; - } - - result = 1; -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** - * \test Checks if a http_stat_msg is registered in a Signature and also checks - * the nocase - */ -static int DetectHttpStatMsgTest02(void) -{ - SigMatch *sm = NULL; - 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 tcp any any -> any any " - "(msg:\"Testing http_stat_msg\"; content:\"one\"; " - "http_stat_msg; content:\"two\"; http_stat_msg; " - "content:\"two\"; nocase; http_stat_msg; " - "sid:1;)"); - if (de_ctx->sig_list == NULL) { - printf("sig parse failed: "); - goto end; - } - - result = 0; - sm = de_ctx->sig_list->sm_lists[g_http_stat_msg_buffer_id]; - if (sm == NULL) { - printf("no sigmatch(es): "); - goto end; - } - - SigMatch *prev = NULL; - while (sm != NULL) { - if (sm->type == DETECT_CONTENT) { - result = 1; - } else { - printf("expected DETECT_CONTENT for http_stat_msg, got %d: ", sm->type); - goto end; - } - prev = sm; - sm = sm->next; - } - - if (! (((DetectContentData *)prev->ctx)->flags & - DETECT_CONTENT_NOCASE)) - { - result = 0; - } -end: - if (de_ctx != NULL) - DetectEngineCtxFree(de_ctx); - return result; -} - -/** \test Check the signature working to alert when http_stat_msg is matched . */ -static int DetectHttpStatMsgSigTest01(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint8_t httpbuf2[] = "HTTP/1.0 200 OK\r\n\r\n"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - 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_TOCLIENT; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"HTTP status message\"; content:\"OK\"; " - "http_stat_msg; sid:1;)"); - if (s == NULL) { - goto end; - } - - s->next = SigInit(de_ctx,"alert http any any -> any any (msg:\"HTTP " - "Status message nocase\"; content:\"ok\"; nocase; " - "http_stat_msg; sid:2;)"); - if (s->next == 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, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOCLIENT, httpbuf2, httplen2); - if (r != 0) { - printf("toclient 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; - } - if (!(PacketAlertCheck(p, 2))) { - printf("sid 2 didn't match but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check the signature working to alert when http_stat_msg is not matched . */ -static int DetectHttpStatMsgSigTest02(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint8_t httpbuf2[] = "HTTP/1.0 200 OK\r\n\r\n"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - 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_TOCLIENT; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"HTTP status message\"; content:\"no\"; " - "http_stat_msg; sid:1;)"); - if (s == 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, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOCLIENT, httpbuf2, httplen2); - if (r != 0) { - printf("toclient 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: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(&p, 1); - return result; -} - -/** \test Check the signature working to alert when http_stat_msg is used with - * negated content . */ -static int DetectHttpStatMsgSigTest03(void) -{ - int result = 0; - Flow f; - uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n\r\n"; - uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ - uint8_t httpbuf2[] = "HTTP/1.0 200 OK\r\n\r\n"; - uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ - TcpSession ssn; - Packet *p = NULL; - Signature *s = NULL; - ThreadVars th_v; - DetectEngineThreadCtx *det_ctx = NULL; - HtpState *http_state = NULL; - 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_TOCLIENT; - p->flowflags |= FLOW_PKT_ESTABLISHED; - p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; - f.alproto = ALPROTO_HTTP; - - StreamTcpInitConfig(TRUE); - - DetectEngineCtx *de_ctx = DetectEngineCtxInit(); - if (de_ctx == NULL) { - goto end; - } - - de_ctx->flags |= DE_QUIET; - - s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" - "\"HTTP status message\"; content:\"ok\"; " - "nocase; http_stat_msg; sid:1;)"); - if (s == NULL) { - goto end; - } - - s->next = SigInit(de_ctx,"alert http any any -> any any (msg:\"HTTP " - "Status message nocase\"; content:!\"Not\"; " - "http_stat_msg; sid:2;)"); - if (s->next == 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, httpbuf1, httplen1); - if (r != 0) { - printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); - result = 0; - FLOWLOCK_UNLOCK(&f); - goto end; - } - - r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, - STREAM_TOCLIENT, httpbuf2, httplen2); - if (r != 0) { - printf("toclient 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 matched but should have: "); - goto end; - } - if (! PacketAlertCheck(p, 2)) { - printf("sid 2 didn't matched but should have: "); - goto end; - } - - result = 1; -end: - if (alp_tctx != NULL) - AppLayerParserThreadCtxFree(alp_tctx); - if (det_ctx != NULL) { - DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - } - if (de_ctx != NULL) { - DetectEngineCtxFree(de_ctx); - } - - StreamTcpFreeConfig(TRUE); - - UTHFreePackets(&p, 1); - return result; -} - +#include "tests/detect-http-stat-msg.c" #endif /* UNITTESTS */ -/** - * \brief Register the UNITTESTS for the http_stat_msg keyword - */ -void DetectHttpStatMsgRegisterTests (void) -{ -#ifdef UNITTESTS /* UNITTESTS */ - - UtRegisterTest("DetectHttpStatMsgTest01", DetectHttpStatMsgTest01); - UtRegisterTest("DetectHttpStatMsgTest02", DetectHttpStatMsgTest02); - UtRegisterTest("DetectHttpStatMsgSigTest01", DetectHttpStatMsgSigTest01); - UtRegisterTest("DetectHttpStatMsgSigTest02", DetectHttpStatMsgSigTest02); - UtRegisterTest("DetectHttpStatMsgSigTest03", DetectHttpStatMsgSigTest03); - -#endif /* UNITTESTS */ -} /** * @} */ diff --git a/src/runmode-unittests.c b/src/runmode-unittests.c index 18bce0bf45..81f5e85a74 100644 --- a/src/runmode-unittests.c +++ b/src/runmode-unittests.c @@ -40,7 +40,6 @@ #include "detect-engine-hsbd.h" #include "detect-engine-hrhd.h" #include "detect-engine-hcd.h" -#include "detect-engine-hsmd.h" #include "detect-engine-hscd.h" #include "detect-engine-state.h" #include "detect-engine-tag.h" @@ -198,7 +197,6 @@ static void RegisterUnittests(void) DetectEngineHttpServerBodyRegisterTests(); DetectEngineHttpRawHeaderRegisterTests(); DetectEngineHttpCookieRegisterTests(); - DetectEngineHttpStatMsgRegisterTests(); DetectEngineHttpStatCodeRegisterTests(); DetectEngineInspectModbusRegisterTests(); DetectEngineRegisterTests(); diff --git a/src/detect-engine-hsmd.c b/src/tests/detect-http-stat-msg.c similarity index 80% rename from src/detect-engine-hsmd.c rename to src/tests/detect-http-stat-msg.c index 62c98b14df..d0e27aaff5 100644 --- a/src/detect-engine-hsmd.c +++ b/src/tests/detect-http-stat-msg.c @@ -28,38 +28,16 @@ * \author Victor Julien */ -#include "suricata-common.h" -#include "suricata.h" -#include "decode.h" - -#include "detect.h" -#include "detect-engine.h" -#include "detect-engine-mpm.h" -#include "detect-engine-hsmd.h" -#include "detect-parse.h" -#include "detect-engine-state.h" -#include "detect-engine-content-inspection.h" -#include "detect-engine-prefilter.h" - -#include "flow-util.h" -#include "util-debug.h" -#include "util-print.h" -#include "flow.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" - -/***********************************Unittests**********************************/ - -#ifdef UNITTESTS +#include "../suricata-common.h" +#include "../suricata.h" +#include "../flow-util.h" +#include "../flow.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" static int DetectEngineHttpStatMsgTest01(void) { @@ -1957,12 +1935,452 @@ end: return result; } -#endif /* UNITTESTS */ +/** + * \test Checks if a http_stat_msg is registered in a Signature, if content is not + * specified in the signature or rawbyes is specified or fast_pattern is + * provided in the signature. + */ +static int DetectHttpStatMsgTest01(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 tcp any any -> any any " + "(msg:\"Testing http_stat_msg\"; http_stat_msg;sid:1;)"); + if (de_ctx->sig_list != NULL) + goto end; + + de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " + "(msg:\"Testing http_stat_msg\"; content:\"|FF F1|\";" + " rawbytes; http_stat_msg;sid:1;)"); + if (de_ctx->sig_list != NULL) + goto end; + + de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any " + "(msg:\"Testing http_stat_msg\"; content:\"one\";" + "fast_pattern; http_stat_msg; sid:1;)"); + if (de_ctx->sig_list == NULL) + goto end; + if (!(((DetectContentData *)de_ctx->sig_list->sm_lists[g_http_stat_msg_buffer_id]->ctx)->flags & + DETECT_CONTENT_FAST_PATTERN)) + { + goto end; + } + + result = 1; +end: + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + return result; +} + +/** + * \test Checks if a http_stat_msg is registered in a Signature and also checks + * the nocase + */ +static int DetectHttpStatMsgTest02(void) +{ + SigMatch *sm = NULL; + 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 tcp any any -> any any " + "(msg:\"Testing http_stat_msg\"; content:\"one\"; " + "http_stat_msg; content:\"two\"; http_stat_msg; " + "content:\"two\"; nocase; http_stat_msg; " + "sid:1;)"); + if (de_ctx->sig_list == NULL) { + printf("sig parse failed: "); + goto end; + } + + result = 0; + sm = de_ctx->sig_list->sm_lists[g_http_stat_msg_buffer_id]; + if (sm == NULL) { + printf("no sigmatch(es): "); + goto end; + } + + SigMatch *prev = NULL; + while (sm != NULL) { + if (sm->type == DETECT_CONTENT) { + result = 1; + } else { + printf("expected DETECT_CONTENT for http_stat_msg, got %d: ", sm->type); + goto end; + } + prev = sm; + sm = sm->next; + } + + if (! (((DetectContentData *)prev->ctx)->flags & + DETECT_CONTENT_NOCASE)) + { + result = 0; + } +end: + if (de_ctx != NULL) + DetectEngineCtxFree(de_ctx); + return result; +} + +/** \test Check the signature working to alert when http_stat_msg is matched . */ +static int DetectHttpStatMsgSigTest01(void) +{ + int result = 0; + Flow f; + uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n\r\n"; + uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ + uint8_t httpbuf2[] = "HTTP/1.0 200 OK\r\n\r\n"; + uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ + TcpSession ssn; + Packet *p = NULL; + Signature *s = NULL; + ThreadVars th_v; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + 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_TOCLIENT; + p->flowflags |= FLOW_PKT_ESTABLISHED; + p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + + DetectEngineCtx *de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) { + goto end; + } + + de_ctx->flags |= DE_QUIET; + + s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" + "\"HTTP status message\"; content:\"OK\"; " + "http_stat_msg; sid:1;)"); + if (s == NULL) { + goto end; + } + + s->next = SigInit(de_ctx,"alert http any any -> any any (msg:\"HTTP " + "Status message nocase\"; content:\"ok\"; nocase; " + "http_stat_msg; sid:2;)"); + if (s->next == 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, httpbuf1, httplen1); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + + r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOCLIENT, httpbuf2, httplen2); + if (r != 0) { + printf("toclient 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; + } + if (!(PacketAlertCheck(p, 2))) { + printf("sid 2 didn't match but should have: "); + goto end; + } + + result = 1; +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (det_ctx != NULL) { + DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); + } + if (de_ctx != NULL) { + DetectEngineCtxFree(de_ctx); + } + + StreamTcpFreeConfig(TRUE); + + UTHFreePackets(&p, 1); + return result; +} + +/** \test Check the signature working to alert when http_stat_msg is not matched . */ +static int DetectHttpStatMsgSigTest02(void) +{ + int result = 0; + Flow f; + uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n\r\n"; + uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ + uint8_t httpbuf2[] = "HTTP/1.0 200 OK\r\n\r\n"; + uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ + TcpSession ssn; + Packet *p = NULL; + Signature *s = NULL; + ThreadVars th_v; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + 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_TOCLIENT; + p->flowflags |= FLOW_PKT_ESTABLISHED; + p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + + DetectEngineCtx *de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) { + goto end; + } + + de_ctx->flags |= DE_QUIET; + + s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" + "\"HTTP status message\"; content:\"no\"; " + "http_stat_msg; sid:1;)"); + if (s == 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, httpbuf1, httplen1); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + + r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOCLIENT, httpbuf2, httplen2); + if (r != 0) { + printf("toclient 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: "); + goto end; + } + + result = 1; +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (det_ctx != NULL) { + DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); + } + if (de_ctx != NULL) { + DetectEngineCtxFree(de_ctx); + } + + StreamTcpFreeConfig(TRUE); + + UTHFreePackets(&p, 1); + return result; +} + +/** \test Check the signature working to alert when http_stat_msg is used with + * negated content . */ +static int DetectHttpStatMsgSigTest03(void) +{ + int result = 0; + Flow f; + uint8_t httpbuf1[] = "POST / HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n\r\n"; + uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ + uint8_t httpbuf2[] = "HTTP/1.0 200 OK\r\n\r\n"; + uint32_t httplen2 = sizeof(httpbuf2) - 1; /* minus the \0 */ + TcpSession ssn; + Packet *p = NULL; + Signature *s = NULL; + ThreadVars th_v; + DetectEngineThreadCtx *det_ctx = NULL; + HtpState *http_state = NULL; + 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_TOCLIENT; + p->flowflags |= FLOW_PKT_ESTABLISHED; + p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST; + f.alproto = ALPROTO_HTTP; + + StreamTcpInitConfig(TRUE); + + DetectEngineCtx *de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) { + goto end; + } + + de_ctx->flags |= DE_QUIET; + + s = de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any (msg:" + "\"HTTP status message\"; content:\"ok\"; " + "nocase; http_stat_msg; sid:1;)"); + if (s == NULL) { + goto end; + } + + s->next = SigInit(de_ctx,"alert http any any -> any any (msg:\"HTTP " + "Status message nocase\"; content:!\"Not\"; " + "http_stat_msg; sid:2;)"); + if (s->next == 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, httpbuf1, httplen1); + if (r != 0) { + printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + + r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP, + STREAM_TOCLIENT, httpbuf2, httplen2); + if (r != 0) { + printf("toclient chunk 1 returned %" PRId32 ", expected 0: ", r); + result = 0; + FLOWLOCK_UNLOCK(&f); + goto end; + } + FLOWLOCK_UNLOCK(&f); -void DetectEngineHttpStatMsgRegisterTests(void) + 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 matched but should have: "); + goto end; + } + if (! PacketAlertCheck(p, 2)) { + printf("sid 2 didn't matched but should have: "); + goto end; + } + + result = 1; +end: + if (alp_tctx != NULL) + AppLayerParserThreadCtxFree(alp_tctx); + if (det_ctx != NULL) { + DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); + } + if (de_ctx != NULL) { + DetectEngineCtxFree(de_ctx); + } + + StreamTcpFreeConfig(TRUE); + + UTHFreePackets(&p, 1); + return result; +} + +/** + * \brief Register the UNITTESTS for the http_stat_msg keyword + */ +void DetectHttpStatMsgRegisterTests (void) { + UtRegisterTest("DetectHttpStatMsgTest01", DetectHttpStatMsgTest01); + UtRegisterTest("DetectHttpStatMsgTest02", DetectHttpStatMsgTest02); + UtRegisterTest("DetectHttpStatMsgSigTest01", DetectHttpStatMsgSigTest01); + UtRegisterTest("DetectHttpStatMsgSigTest02", DetectHttpStatMsgSigTest02); + UtRegisterTest("DetectHttpStatMsgSigTest03", DetectHttpStatMsgSigTest03); -#ifdef UNITTESTS UtRegisterTest("DetectEngineHttpStatMsgTest01", DetectEngineHttpStatMsgTest01); UtRegisterTest("DetectEngineHttpStatMsgTest02", @@ -1993,9 +2411,6 @@ void DetectEngineHttpStatMsgRegisterTests(void) DetectEngineHttpStatMsgTest14); UtRegisterTest("DetectEngineHttpStatMsgTest15", DetectEngineHttpStatMsgTest15); -#endif /* UNITTESTS */ - - return; } /**