summaryrefslogtreecommitdiffstats
path: root/src/tests/detect-http-uri.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests/detect-http-uri.c')
-rw-r--r--src/tests/detect-http-uri.c6920
1 files changed, 6920 insertions, 0 deletions
diff --git a/src/tests/detect-http-uri.c b/src/tests/detect-http-uri.c
new file mode 100644
index 0000000..f167be4
--- /dev/null
+++ b/src/tests/detect-http-uri.c
@@ -0,0 +1,6920 @@
+/* Copyright (C) 2007-2018 Open Information Security Foundation
+ *
+ * You can copy, redistribute or modify this Program under the terms of
+ * the GNU General Public License version 2 as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/** \file
+ *
+ * \author Victor Julien <victor@inliniac.net>
+ * \author Pablo Rincon Crespo <pablo.rincon.crespo@gmail.com>
+ */
+
+#include "../suricata-common.h"
+#include "../app-layer.h"
+#include "../app-layer-parser.h"
+#include "../app-layer-htp.h"
+#include "../util-unittest.h"
+#include "../util-unittest-helper.h"
+
+#include "../flow.h"
+#include "../flow-util.h"
+
+#include "../detect-isdataat.h"
+#include "../detect-engine-build.h"
+#include "../detect-engine-alert.h"
+
+/** \test Test a simple uricontent option */
+static int UriTestSig01(void)
+{
+ int result = 0;
+ Flow f;
+ HtpState *http_state = NULL;
+ uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n"
+ "Cookie: hellocatch\r\n\r\n";
+ uint32_t http_buf1_len = sizeof(http_buf1) - 1;
+ uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n"
+ "Cookie: hellocatch\r\n\r\n";
+ uint32_t http_buf2_len = sizeof(http_buf2) - 1;
+ TcpSession ssn;
+ Packet *p = NULL;
+ Signature *s = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p->flow = &f;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f.alproto = ALPROTO_HTTP1;
+
+ 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 tcp any any -> any any "
+ "(msg:\"Test uricontent option\"; "
+ "uricontent:\"one\"; sid:1;)");
+ if (s == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_buf1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 alerted, but it should not: ");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf2, http_buf2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 alerted, but it should not: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+/** \test Test the pcre /U option */
+static int UriTestSig02(void)
+{
+ int result = 0;
+ Flow f;
+ HtpState *http_state = NULL;
+ uint8_t http_buf1[] = "POST /on HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n"
+ "Cookie: hellocatch\r\n\r\n";
+ uint32_t http_buf1_len = sizeof(http_buf1) - 1;
+ uint8_t http_buf2[] = "POST /one HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n"
+ "Cookie: hellocatch\r\n\r\n";
+ uint32_t http_buf2_len = sizeof(http_buf2) - 1;
+ TcpSession ssn;
+ Packet *p = NULL;
+ Signature *s = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p->flow = &f;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f.alproto = ALPROTO_HTTP1;
+
+ 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 tcp any any -> any any "
+ "(msg:\"Test pcre /U option\"; "
+ "pcre:/one/U; sid:1;)");
+ if (s == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_buf1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (PacketAlertCheck(p, 1)) {
+ printf("sig 1 alerted with payload2, but it should not: ");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf2, http_buf2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 didnt alert, but it should: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+/** \test Test the pcre /U option */
+static int UriTestSig03(void)
+{
+ int result = 0;
+ Flow f;
+ HtpState *http_state = NULL;
+ uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n"
+ "Cookie: hellocatch\r\n\r\n";
+ uint32_t http_buf1_len = sizeof(http_buf1) - 1;
+ uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n"
+ "Cookie: hellocatch\r\n\r\n";
+ uint32_t http_buf2_len = sizeof(http_buf2) - 1;
+ TcpSession ssn;
+ Packet *p = NULL;
+ Signature *s = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p->flow = &f;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f.alproto = ALPROTO_HTTP1;
+
+ 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 tcp any any -> any any "
+ "(msg:\"Test pcre /U option\"; "
+ "pcre:/blah/U; sid:1;)");
+ if (s == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_buf1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (PacketAlertCheck(p, 1)) {
+ printf("sig 1 alerted, but it should not: ");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf2, http_buf2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (PacketAlertCheck(p, 1)) {
+ printf("sig 1 alerted, but it should not: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+/** \test Test the urilen option */
+static int UriTestSig04(void)
+{
+ int result = 0;
+ Flow f;
+ HtpState *http_state = NULL;
+ uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n"
+ "Cookie: hellocatch\r\n\r\n";
+ uint32_t http_buf1_len = sizeof(http_buf1) - 1;
+ uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n"
+ "Cookie: hellocatch\r\n\r\n";
+ uint32_t http_buf2_len = sizeof(http_buf2) - 1;
+ TcpSession ssn;
+ Packet *p = NULL;
+ Signature *s = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p->flow = &f;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f.alproto = ALPROTO_HTTP1;
+
+ 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 tcp any any -> any any "
+ "(msg:\"Test urilen option\"; "
+ "urilen:>20; sid:1;)");
+ if (s == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_buf1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (PacketAlertCheck(p, 1)) {
+ printf("sig 1 alerted, but it should not: ");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf2, http_buf2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (PacketAlertCheck(p, 1)) {
+ printf("sig 1 alerted, but it should not: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+/** \test Test the urilen option */
+static int UriTestSig05(void)
+{
+ int result = 0;
+ Flow f;
+ HtpState *http_state = NULL;
+ uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n"
+ "Cookie: hellocatch\r\n\r\n";
+ uint32_t http_buf1_len = sizeof(http_buf1) - 1;
+ uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n"
+ "Cookie: hellocatch\r\n\r\n";
+ uint32_t http_buf2_len = sizeof(http_buf2) - 1;
+ TcpSession ssn;
+ Packet *p = NULL;
+ Signature *s = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p->flow = &f;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f.alproto = ALPROTO_HTTP1;
+
+ 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 tcp any any -> any any "
+ "(msg:\"Test urilen option\"; "
+ "urilen:>4; sid:1;)");
+ if (s == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_buf1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (PacketAlertCheck(p, 1)) {
+ printf("sig 1 alerted, but it should not: ");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf2, http_buf2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 didnt alert with payload2, but it should: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+/** \test Test the pcre /U option */
+static int UriTestSig06(void)
+{
+ int result = 0;
+ Flow f;
+ HtpState *http_state = NULL;
+ uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n"
+ "Cookie: hellocatch\r\n\r\n";
+ uint32_t http_buf1_len = sizeof(http_buf1) - 1;
+ uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n"
+ "Cookie: hellocatch\r\n\r\n";
+ uint32_t http_buf2_len = sizeof(http_buf2) - 1;
+ TcpSession ssn;
+ Packet *p = NULL;
+ Signature *s = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p->flow = &f;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f.alproto = ALPROTO_HTTP1;
+
+ 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 tcp any any -> any any "
+ "(msg:\"Test pcre /U option\"; "
+ "pcre:/(oneself)+/U; sid:1;)");
+ if (s == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_buf1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (PacketAlertCheck(p, 1)) {
+ printf("sig 1 alerted, but it should not: ");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf2, http_buf2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 didnt alert on payload2, but it should: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+/** \test Test the pcre /U option in combination with urilen */
+static int UriTestSig07(void)
+{
+ int result = 0;
+ Flow f;
+ HtpState *http_state = NULL;
+ uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n"
+ "Cookie: hellocatch\r\n\r\n";
+ uint32_t http_buf1_len = sizeof(http_buf1) - 1;
+ uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n"
+ "Cookie: hellocatch\r\n\r\n";
+ uint32_t http_buf2_len = sizeof(http_buf2) - 1;
+ TcpSession ssn;
+ Packet *p = NULL;
+ Signature *s = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p->flow = &f;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f.alproto = ALPROTO_HTTP1;
+
+ 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 tcp any any -> any any "
+ "(msg:\"Test pcre /U option with urilen \"; "
+ "pcre:/(one){2,}(self)?/U; urilen:3<>20; sid:1;)");
+ if (s == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_buf1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 didnt alert, but it should: ");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf2, http_buf2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 didnt alert with payload2, but it should: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+/** \test Test the pcre /U option in combination with urilen */
+static int UriTestSig08(void)
+{
+ int result = 0;
+ Flow f;
+ HtpState *http_state = NULL;
+ uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n"
+ "Cookie: hellocatch\r\n\r\n";
+ uint32_t http_buf1_len = sizeof(http_buf1) - 1;
+ uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n"
+ "Cookie: hellocatch\r\n\r\n";
+ uint32_t http_buf2_len = sizeof(http_buf2) - 1;
+ TcpSession ssn;
+ Packet *p = NULL;
+ Signature *s = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p->flow = &f;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f.alproto = ALPROTO_HTTP1;
+
+ 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 tcp any any -> any any "
+ "(msg:\"Test pcre /U option with urilen\"; "
+ "pcre:/(blabla){2,}(self)?/U; urilen:3<>20; sid:1;)");
+ if (s == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_buf1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (PacketAlertCheck(p, 1)) {
+ printf("sig 1 alerted, but it should not: ");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf2, http_buf2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (PacketAlertCheck(p, 1)) {
+ printf("sig 1 alerted, but it should not: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+/** \test Test the pcre /U option in combination with urilen */
+static int UriTestSig09(void)
+{
+ int result = 0;
+ Flow f;
+ HtpState *http_state = NULL;
+ uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n"
+ "Cookie: hellocatch\r\n\r\n";
+ uint32_t http_buf1_len = sizeof(http_buf1) - 1;
+ uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n"
+ "Cookie: hellocatch\r\n\r\n";
+ uint32_t http_buf2_len = sizeof(http_buf2) - 1;
+ TcpSession ssn;
+ Packet *p = NULL;
+ Signature *s = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p->flow = &f;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f.alproto = ALPROTO_HTTP1;
+
+ 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 tcp any any -> any any "
+ "(msg:\"Test pcre /U option with urilen \"; "
+ "pcre:/(one){2,}(self)?/U; urilen:<2; sid:1;)");
+ if (s == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_buf1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (PacketAlertCheck(p, 1)) {
+ printf("sig 1 alerted, but it should not: ");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf2, http_buf2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (PacketAlertCheck(p, 1)) {
+ printf("sig 1 alerted, but it should not: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+/** \test Test uricontent, urilen, pcre /U options */
+static int UriTestSig12(void)
+{
+ int result = 0;
+ Flow f;
+ HtpState *http_state = NULL;
+ uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n"
+ "Cookie: hellocatch\r\n\r\n";
+ uint32_t http_buf1_len = sizeof(http_buf1) - 1;
+ uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n"
+ "Cookie: hellocatch\r\n\r\n";
+ uint32_t http_buf2_len = sizeof(http_buf2) - 1;
+ TcpSession ssn;
+ Packet *p = NULL;
+ Signature *s = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p->flow = &f;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f.alproto = ALPROTO_HTTP1;
+
+ 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 tcp any any -> any any "
+ "(msg:\"Test pcre /U, uricontent and urilen option\"; "
+ "uricontent:\"one\"; "
+ "pcre:/(one)+self/U; urilen:>2; sid:1;)");
+ if (s == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_buf1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (PacketAlertCheck(p, 1)) {
+ printf("sig 1 alerted, but it should not: ");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf2, http_buf2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 didnt alert with payload2, but it should: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+/** \test Test uricontent, urilen */
+static int UriTestSig13(void)
+{
+ int result = 0;
+ Flow f;
+ HtpState *http_state = NULL;
+ uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n"
+ "Cookie: hellocatch\r\n\r\n";
+ uint32_t http_buf1_len = sizeof(http_buf1) - 1;
+ uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n"
+ "Cookie: hellocatch\r\n\r\n";
+ uint32_t http_buf2_len = sizeof(http_buf2) - 1;
+ TcpSession ssn;
+ Packet *p = NULL;
+ Signature *s = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p->flow = &f;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f.alproto = ALPROTO_HTTP1;
+
+ 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 tcp any any -> any any "
+ "(msg:\"Test urilen option\"; "
+ "urilen:>2; uricontent:\"one\"; sid:1;)");
+ if (s == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_buf1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 didnt alert with pkt, but it should: ");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf2, http_buf2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 didnt alert with payload2, but it should: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+/** \test Test uricontent, pcre /U */
+static int UriTestSig14(void)
+{
+ int result = 0;
+ Flow f;
+ HtpState *http_state = NULL;
+ uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n"
+ "Cookie: hellocatch\r\n\r\n";
+ uint32_t http_buf1_len = sizeof(http_buf1) - 1;
+ uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n"
+ "Cookie: hellocatch\r\n\r\n";
+ uint32_t http_buf2_len = sizeof(http_buf2) - 1;
+ TcpSession ssn;
+ Packet *p = NULL;
+ Signature *s = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p->flow = &f;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f.alproto = ALPROTO_HTTP1;
+
+ 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 tcp any any -> any any "
+ "(msg:\"Test uricontent option\"; "
+ "uricontent:\"one\"; pcre:/one(self)?/U;sid:1;)");
+ if (s == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_buf1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 didnt alert with pkt, but it should: ");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf2, http_buf2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 didnt alert with payload2, but it should: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+/** \test Test pcre /U with anchored regex (bug 155) */
+static int UriTestSig15(void)
+{
+ int result = 0;
+ Flow f;
+ HtpState *http_state = NULL;
+ uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n"
+ "Cookie: hellocatch\r\n\r\n";
+ uint32_t http_buf1_len = sizeof(http_buf1) - 1;
+ uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n"
+ "Cookie: hellocatch\r\n\r\n";
+ uint32_t http_buf2_len = sizeof(http_buf2) - 1;
+ TcpSession ssn;
+ Packet *p = NULL;
+ Signature *s = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p->flow = &f;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f.alproto = ALPROTO_HTTP1;
+
+ 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 tcp any any -> any any "
+ "(msg:\"Test uricontent option\"; "
+ "uricontent:\"one\"; pcre:/^\\/one(self)?$/U;sid:1;)");
+ if (s == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_buf1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 didnt alert with pkt, but it should: ");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf2, http_buf2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 didnt alert with payload2, but it should: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+/** \test Test pcre /U with anchored regex (bug 155) */
+static int UriTestSig16(void)
+{
+ HtpState *http_state = NULL;
+ uint8_t http_buf1[] = "POST /search?q=123&aq=7123abcee HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0/\r\n"
+ "Host: 1.2.3.4\r\n\r\n";
+ uint32_t http_buf1_len = sizeof(http_buf1) - 1;
+ uint8_t http_buf2[] = "POST /search?q=123&aq=7123abcee HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n"
+ "Cookie: hellocatch\r\n\r\n";
+ uint32_t http_buf2_len = sizeof(http_buf2) - 1;
+ TcpSession ssn;
+ Signature *s = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&ssn, 0, sizeof(TcpSession));
+ StreamTcpInitConfig(true);
+
+ Packet *p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
+ FAIL_IF_NULL(p);
+ p->tcph->th_seq = htonl(1000);
+ Flow *f = UTHBuildFlow(AF_INET, "192.168.1.5", "192.168.1.1", 41424, 80);
+ FAIL_IF_NULL(f);
+ f->proto = IPPROTO_TCP;
+
+ UTHAddSessionToFlow(f, 1000, 1000);
+ UTHAddStreamToFlow(f, 0, http_buf1, http_buf1_len);
+
+ p->flow = f;
+ p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST | PKT_DETECT_HAS_STREAMDATA;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f->alproto = ALPROTO_HTTP1;
+
+ DetectEngineCtx *de_ctx = DetectEngineCtxInit();
+ FAIL_IF_NULL(de_ctx);
+ de_ctx->flags |= DE_QUIET;
+
+ s = de_ctx->sig_list = SigInit(de_ctx, "drop tcp any any -> any any (flow:to_server,established; uricontent:\"/search?q=\"; pcre:\"/^\\/search\\?q=[0-9]{1,3}(&aq=7(\\?[0-9a-f]{8})?)?/U\"; pcre:\"/\\x0d\\x0aHost\\: \\d+\\.\\d+\\.\\d+\\.\\d+\\x0d\\x0a/\"; sid:2009024; rev:9;)");
+ FAIL_IF_NULL(s);
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ UTHAddStreamToFlow(f, 0, http_buf2, http_buf2_len);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_buf1_len);
+ FAIL_IF(r != 0);
+
+ http_state = f->alstate;
+ FAIL_IF_NULL(http_state);
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+ FAIL_IF(!PacketAlertCheck(p, 2009024));
+ p->alerts.cnt = 0;
+
+ p->payload = http_buf2;
+ p->payload_len = http_buf2_len;
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf2, http_buf2_len);
+ FAIL_IF(r != 0);
+
+ http_state = f->alstate;
+ FAIL_IF_NULL(http_state);
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+ FAIL_IF(PacketAlertCheck(p, 2009024));
+
+ AppLayerParserThreadCtxFree(alp_tctx);
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ DetectEngineCtxFree(de_ctx);
+
+ UTHRemoveSessionFromFlow(f);
+ UTHFreeFlow(f);
+
+ StreamTcpFreeConfig(true);
+ UTHFreePacket(p);
+ PASS;
+}
+
+/**
+ * \test Test multiple relative contents
+ */
+static int UriTestSig17(void)
+{
+ int result = 0;
+ uint8_t *http_buf = (uint8_t *)"POST /now_this_is_is_big_big_string_now HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n";
+ uint32_t http_buf_len = strlen((char *)http_buf);
+ Flow f;
+ TcpSession ssn;
+ HtpState *http_state = NULL;
+ Packet *p = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p->flow = &f;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f.alproto = ALPROTO_HTTP1;
+
+ StreamTcpInitConfig(true);
+
+ DetectEngineCtx *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:\"test multiple relative uricontents\"; "
+ "uricontent:\"this\"; uricontent:\"is\"; within:6; "
+ "uricontent:\"big\"; within:8; "
+ "uricontent:\"string\"; within:8; sid:1;)");
+ if (de_ctx->sig_list == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_buf_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 alerted, but it should not: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+/**
+ * \test Test multiple relative contents
+ */
+static int UriTestSig18(void)
+{
+ int result = 0;
+ uint8_t *http_buf = (uint8_t *)"POST /now_this_is_is_is_big_big_big_string_now HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n";
+ uint32_t http_buf_len = strlen((char *)http_buf);
+ Flow f;
+ TcpSession ssn;
+ HtpState *http_state = NULL;
+ Packet *p = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p->flow = &f;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f.alproto = ALPROTO_HTTP1;
+
+ StreamTcpInitConfig(true);
+
+ DetectEngineCtx *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:\"test multiple relative uricontents\"; "
+ "uricontent:\"this\"; uricontent:\"is\"; within:9; "
+ "uricontent:\"big\"; within:12; "
+ "uricontent:\"string\"; within:8; sid:1;)");
+ if (de_ctx->sig_list == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_buf_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 alerted, but it should not: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+/**
+ * \test Test multiple relative contents
+ */
+static int UriTestSig19(void)
+{
+ int result = 0;
+ uint8_t *http_buf = (uint8_t *)"POST /this_this_now_is_is_____big_string_now HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n";
+ uint32_t http_buf_len = strlen((char *)http_buf);
+ Flow f;
+ TcpSession ssn;
+ HtpState *http_state = NULL;
+ Packet *p = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p->flow = &f;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f.alproto = ALPROTO_HTTP1;
+
+ StreamTcpInitConfig(true);
+
+ DetectEngineCtx *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:\"test multiple relative uricontents\"; "
+ "uricontent:\"now\"; uricontent:\"this\"; "
+ "uricontent:\"is\"; within:12; "
+ "uricontent:\"big\"; within:8; "
+ "uricontent:\"string\"; within:8; sid:1;)");
+ if (de_ctx->sig_list == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_buf_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 alerted, but it should not: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+/**
+ * \test Test multiple relative contents with offset
+ */
+static int UriTestSig20(void)
+{
+ int result = 0;
+ uint8_t *http_buf = (uint8_t *)"POST /_________thus_thus_is_a_big HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n";
+ uint32_t http_buf_len = strlen((char *)http_buf);
+ Flow f;
+ TcpSession ssn;
+ HtpState *http_state = NULL;
+ Packet *p = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p->flow = &f;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f.alproto = ALPROTO_HTTP1;
+
+ StreamTcpInitConfig(true);
+
+ DetectEngineCtx *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:\"test multiple relative uricontents\"; "
+ "uricontent:\"thus\"; offset:8; "
+ "uricontent:\"is\"; within:6; "
+ "uricontent:\"big\"; within:8; sid:1;)");
+ if (de_ctx->sig_list == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_buf_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 alerted, but it should not: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+/**
+ * \test Test multiple relative contents with a negated content.
+ */
+static int UriTestSig21(void)
+{
+ int result = 0;
+ uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n";
+ uint32_t http_buf_len = strlen((char *)http_buf);
+ Flow f;
+ TcpSession ssn;
+ HtpState *http_state = NULL;
+ Packet *p = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p->flow = &f;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f.alproto = ALPROTO_HTTP1;
+
+ StreamTcpInitConfig(true);
+
+ DetectEngineCtx *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:\"test multiple relative uricontents\"; "
+ "uricontent:\"fix\"; uricontent:\"this\"; within:6; "
+ "uricontent:!\"and\"; distance:0; sid:1;)");
+ if (de_ctx->sig_list == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_buf_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 alerted, but it should not: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+/**
+ * \test Test relative pcre.
+ */
+static int UriTestSig22(void)
+{
+ int result = 0;
+ uint8_t *http_buf = (uint8_t *)"POST /this_is_a_super_duper_"
+ "nova_in_super_nova_now HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n";
+ uint32_t http_buf_len = strlen((char *)http_buf);
+ Flow f;
+ TcpSession ssn;
+ HtpState *http_state = NULL;
+ Packet *p = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p->flow = &f;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f.alproto = ALPROTO_HTTP1;
+
+ StreamTcpInitConfig(true);
+
+ DetectEngineCtx *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:\"test multiple relative uricontents\"; "
+ "pcre:/super/U; uricontent:\"nova\"; within:7; sid:1;)");
+ if (de_ctx->sig_list == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_buf_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 didn't alert, but it should have: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+/**
+ * \test Test multiple relative contents with a negated content.
+ */
+static int UriTestSig23(void)
+{
+ int result = 0;
+ uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n";
+ uint32_t http_buf_len = strlen((char *)http_buf);
+ Flow f;
+ TcpSession ssn;
+ HtpState *http_state = NULL;
+ Packet *p = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p->flow = &f;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f.alproto = ALPROTO_HTTP1;
+
+ StreamTcpInitConfig(true);
+
+ DetectEngineCtx *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:\"test multiple relative uricontents\"; "
+ "uricontent:!\"fix_this_now\"; sid:1;)");
+ if (de_ctx->sig_list == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_buf_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (PacketAlertCheck(p, 1)) {
+ printf("sig 1 alerted, but it should not: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+/**
+ * \test Test multiple relative contents with a negated content.
+ */
+static int UriTestSig24(void)
+{
+ int result = 0;
+ uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n";
+ uint32_t http_buf_len = strlen((char *)http_buf);
+ Flow f;
+ TcpSession ssn;
+ HtpState *http_state = NULL;
+ Packet *p = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p->flow = &f;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f.alproto = ALPROTO_HTTP1;
+
+ StreamTcpInitConfig(true);
+
+ DetectEngineCtx *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:\"test multiple relative uricontents\"; "
+ "uricontent:\"we_need_to\"; uricontent:!\"fix_this_now\"; sid:1;)");
+ if (de_ctx->sig_list == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_buf_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (PacketAlertCheck(p, 1)) {
+ printf("sig 1 alerted, but it should not: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+/**
+ * \test Test normalized uricontents.
+ */
+static int UriTestSig25(void)
+{
+ int result = 0;
+ uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri "
+ "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n";
+ uint32_t http_buf_len = strlen((char *)http_buf);
+ Flow f;
+ TcpSession ssn;
+ HtpState *http_state = NULL;
+ Packet *p = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf, http_buf_len, 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;
+ f.alproto = ALPROTO_HTTP1;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+
+ StreamTcpInitConfig(true);
+
+ DetectEngineCtx *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:\"test multiple relative uricontents\"; "
+ "pcre:/normalized/U; uricontent:\"normalized uri\"; sid:1;)");
+ if (de_ctx->sig_list == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_buf_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 didn't alert, but it should have: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+/**
+ * \test Test multiple relative contents with a negated content.
+ */
+static int UriTestSig26(void)
+{
+ int result = 0;
+ uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n";
+ uint32_t http_buf_len = strlen((char *)http_buf);
+ Flow f;
+ TcpSession ssn;
+ HtpState *http_state = NULL;
+ Packet *p = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p->flow = &f;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f.alproto = ALPROTO_HTTP1;
+
+ StreamTcpInitConfig(true);
+
+ DetectEngineCtx *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:\"test multiple relative uricontents\"; "
+ "uricontent:\"fix_this\"; isdataat:4,relative; sid:1;)");
+ if (de_ctx->sig_list == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_buf_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 didn't alert, but it should have: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+/**
+ * \test Test multiple relative contents with a negated content.
+ */
+static int UriTestSig27(void)
+{
+ int result = 0;
+ uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n";
+ uint32_t http_buf_len = strlen((char *)http_buf);
+ Flow f;
+ TcpSession ssn;
+ HtpState *http_state = NULL;
+ Packet *p = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p->flow = &f;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f.alproto = ALPROTO_HTTP1;
+
+ StreamTcpInitConfig(true);
+
+ DetectEngineCtx *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:\"test multiple relative uricontents\"; "
+ "uricontent:\"fix_this\"; isdataat:!10,relative; sid:1;)");
+ if (de_ctx->sig_list == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_buf_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 didn't alert, but it should have: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+static int UriTestSig28(void)
+{
+ int result = 0;
+ uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n";
+ uint32_t http_buf_len = strlen((char *)http_buf);
+ Flow f;
+ TcpSession ssn;
+ HtpState *http_state = NULL;
+ Packet *p = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p->flow = &f;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f.alproto = ALPROTO_HTTP1;
+
+ StreamTcpInitConfig(true);
+
+ DetectEngineCtx *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:\"dummy\"; "
+ "uricontent:\"this\"; "
+ "byte_extract:1,2,one,string,dec,relative; "
+ "uricontent:\"ring\"; distance:one; sid:1;)");
+ if (de_ctx->sig_list == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_buf_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 didn't alert, but should have: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+static int UriTestSig29(void)
+{
+ int result = 0;
+ uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n";
+ uint32_t http_buf_len = strlen((char *)http_buf);
+ Flow f;
+ TcpSession ssn;
+ HtpState *http_state = NULL;
+ Packet *p = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p->flow = &f;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f.alproto = ALPROTO_HTTP1;
+
+ StreamTcpInitConfig(true);
+
+ DetectEngineCtx *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:\"dummy\"; "
+ "uricontent:\"this\"; "
+ "byte_extract:1,2,one,string,dec,relative; "
+ "uricontent:\"ring\"; distance:one; sid:1;)");
+ if (de_ctx->sig_list == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_buf_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 didn't alert, but should have: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+static int UriTestSig30(void)
+{
+ int result = 0;
+ uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n";
+ uint32_t http_buf_len = strlen((char *)http_buf);
+ Flow f;
+ TcpSession ssn;
+ HtpState *http_state = NULL;
+ Packet *p = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p->flow = &f;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f.alproto = ALPROTO_HTTP1;
+
+ StreamTcpInitConfig(true);
+
+ DetectEngineCtx *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:\"dummy\"; "
+ "uricontent:\"this\"; "
+ "byte_extract:1,2,one,string,dec,relative; "
+ "uricontent:\"_b5ig\"; offset:one; sid:1;)");
+ if (de_ctx->sig_list == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_buf_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 didn't alert, but should have: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+static int UriTestSig31(void)
+{
+ int result = 0;
+ uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n";
+ uint32_t http_buf_len = strlen((char *)http_buf);
+ Flow f;
+ TcpSession ssn;
+ HtpState *http_state = NULL;
+ Packet *p = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p->flow = &f;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f.alproto = ALPROTO_HTTP1;
+
+ StreamTcpInitConfig(true);
+
+ DetectEngineCtx *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:\"dummy\"; "
+ "uricontent:\"this\"; "
+ "byte_extract:1,2,one,string,dec,relative; "
+ "uricontent:\"his\"; depth:one; sid:1;)");
+ if (de_ctx->sig_list == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_buf_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 didn't alert, but should have: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+static int UriTestSig32(void)
+{
+ int result = 0;
+ uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n";
+ uint32_t http_buf_len = strlen((char *)http_buf);
+ Flow f;
+ TcpSession ssn;
+ HtpState *http_state = NULL;
+ Packet *p = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p->flow = &f;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f.alproto = ALPROTO_HTTP1;
+
+ StreamTcpInitConfig(true);
+
+ DetectEngineCtx *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:\"dummy\"; "
+ "uricontent:\"this\"; "
+ "byte_extract:1,2,one,string,dec,relative; "
+ "uricontent:\"g_st\"; within:one; sid:1;)");
+ if (de_ctx->sig_list == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_buf_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 didn't alert, but should have: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+static int UriTestSig33(void)
+{
+ int result = 0;
+ uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri "
+ "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n";
+ uint32_t http_buf_len = strlen((char *)http_buf);
+ Flow f;
+ TcpSession ssn;
+ HtpState *http_state = NULL;
+ Packet *p = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf, http_buf_len, 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;
+ f.alproto = ALPROTO_HTTP1;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+
+ StreamTcpInitConfig(true);
+
+ DetectEngineCtx *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:\"test multiple relative uricontents\"; "
+ "urilen:15; sid:1;)");
+ if (de_ctx->sig_list == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_buf_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 didn't alert, but it should have: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+static int UriTestSig34(void)
+{
+ int result = 0;
+ uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri "
+ "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n";
+ uint32_t http_buf_len = strlen((char *)http_buf);
+ Flow f;
+ TcpSession ssn;
+ HtpState *http_state = NULL;
+ Packet *p = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf, http_buf_len, 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;
+ f.alproto = ALPROTO_HTTP1;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+
+ StreamTcpInitConfig(true);
+
+ DetectEngineCtx *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:\"test multiple relative uricontents\"; "
+ "urilen:15, norm; sid:1;)");
+ if (de_ctx->sig_list == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_buf_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 didn't alert, but it should have: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+static int UriTestSig35(void)
+{
+ int result = 0;
+ uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri "
+ "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n";
+ uint32_t http_buf_len = strlen((char *)http_buf);
+ Flow f;
+ TcpSession ssn;
+ HtpState *http_state = NULL;
+ Packet *p = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf, http_buf_len, 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;
+ f.alproto = ALPROTO_HTTP1;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+
+ StreamTcpInitConfig(true);
+
+ DetectEngineCtx *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:\"test multiple relative uricontents\"; "
+ "urilen:16; sid:1;)");
+ if (de_ctx->sig_list == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_buf_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (PacketAlertCheck(p, 1)) {
+ printf("sig 1 alerted, but it shouldn't have: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+static int UriTestSig36(void)
+{
+ int result = 0;
+ uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri "
+ "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n";
+ uint32_t http_buf_len = strlen((char *)http_buf);
+ Flow f;
+ TcpSession ssn;
+ HtpState *http_state = NULL;
+ Packet *p = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf, http_buf_len, 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;
+ f.alproto = ALPROTO_HTTP1;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+
+ StreamTcpInitConfig(true);
+
+ DetectEngineCtx *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:\"test multiple relative uricontents\"; "
+ "urilen:16, norm; sid:1;)");
+ if (de_ctx->sig_list == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_buf_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (PacketAlertCheck(p, 1)) {
+ printf("sig 1 alerted, but it shouldn't have: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+static int UriTestSig37(void)
+{
+ int result = 0;
+ uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri "
+ "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n";
+ uint32_t http_buf_len = strlen((char *)http_buf);
+ Flow f;
+ TcpSession ssn;
+ HtpState *http_state = NULL;
+ Packet *p = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf, http_buf_len, 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;
+ f.alproto = ALPROTO_HTTP1;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+
+ StreamTcpInitConfig(true);
+
+ DetectEngineCtx *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:\"test multiple relative uricontents\"; "
+ "urilen:17, raw; sid:1;)");
+ if (de_ctx->sig_list == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_buf_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 didn't alert, but it should have: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+static int UriTestSig38(void)
+{
+ int result = 0;
+ uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri "
+ "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n";
+ uint32_t http_buf_len = strlen((char *)http_buf);
+ Flow f;
+ TcpSession ssn;
+ HtpState *http_state = NULL;
+ Packet *p = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf, http_buf_len, 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;
+ f.alproto = ALPROTO_HTTP1;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+
+ StreamTcpInitConfig(true);
+
+ DetectEngineCtx *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:\"test multiple relative uricontents\"; "
+ "urilen:18, raw; sid:1;)");
+ if (de_ctx->sig_list == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_buf_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (PacketAlertCheck(p, 1)) {
+ printf("sig 1 alerted, but it shouldn't have: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+static int DetectHttpUriIsdataatParseTest(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 ("
+ "content:\"one\"; http_uri; "
+ "isdataat:!4,relative; sid:1;)");
+ FAIL_IF_NULL(s);
+
+ SigMatch *sm = DetectBufferGetLastSigMatch(s, g_http_uri_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;
+}
+
+static int DetectEngineHttpRawUriTest01(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 /../a/b/../c";
+ uint8_t http2_buf[] =
+ "/./d.html HTTP/1.1\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: 46\r\n"
+ "\r\n"
+ "This is dummy body1"
+ "This is dummy message body2";
+ 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_HTTP1;
+
+ 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 raw uri test\"; "
+ "content:\"../c/./d\"; http_raw_uri; "
+ "sid:1;)");
+ if (de_ctx->sig_list == NULL)
+ goto end;
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: \n");
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+
+ if ((PacketAlertCheck(p1, 1))) {
+ printf("sid 1 matched but shouldn't have\n");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (!(PacketAlertCheck(p2, 1))) {
+ printf("sid 1 didn't match but should have");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ SigCleanSignatures(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePackets(&p1, 1);
+ UTHFreePackets(&p2, 1);
+ return result;
+}
+
+static int DetectEngineHttpRawUriTest02(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 /../a/b/../c/./d.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: 19\r\n"
+ "\r\n"
+ "This is dummy body1";
+ uint32_t http1_len = sizeof(http1_buf) - 1;
+ int result = 0;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&th_v, 0, sizeof(th_v));
+ memset(&f, 0, sizeof(f));
+ memset(&ssn, 0, sizeof(ssn));
+
+ p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
+ 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_HTTP1;
+
+ 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 raw uri test\"; "
+ "content:\"/c/./d\"; http_raw_uri; offset:5; "
+ "sid:1;)");
+ if (de_ctx->sig_list == NULL)
+ goto end;
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: \n");
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+
+ if (!(PacketAlertCheck(p1, 1))) {
+ printf("sid 1 didn't match but should have\n");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ SigCleanSignatures(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePackets(&p1, 1);
+ UTHFreePackets(&p2, 1);
+ return result;
+}
+
+static int DetectEngineHttpRawUriTest03(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 /../a/b/../";
+ uint8_t http2_buf[] =
+ "c/./d.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: 46\r\n"
+ "\r\n"
+ "This is dummy body1"
+ "This is dummy message body2";
+ 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_HTTP1;
+
+ 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 raw uri test\"; "
+ "content:\"/a/b\"; http_raw_uri; offset:10; "
+ "sid:1;)");
+ if (de_ctx->sig_list == NULL)
+ goto end;
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: \n");
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+
+ if (PacketAlertCheck(p1, 1)) {
+ printf("sid 1 matched but shouldn't have\n");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (PacketAlertCheck(p2, 1)) {
+ printf("sid 1 didn't match but should have");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ SigCleanSignatures(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePackets(&p1, 1);
+ UTHFreePackets(&p2, 1);
+ return result;
+}
+
+static int DetectEngineHttpRawUriTest04(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 /../a/b/../";
+ uint8_t http2_buf[] =
+ "c/./d.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: 46\r\n"
+ "\r\n"
+ "This is dummy body1"
+ "This is dummy message body2";
+ 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_HTTP1;
+
+ 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 raw uri test\"; "
+ "content:!\"/a/b\"; http_raw_uri; offset:10; "
+ "sid:1;)");
+ if (de_ctx->sig_list == NULL)
+ goto end;
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: \n");
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+
+ if (PacketAlertCheck(p1, 1)) {
+ printf("sid 1 matched but shouldn't have\n");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (!PacketAlertCheck(p2, 1)) {
+ printf("sid 1 didn't match but should have");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ SigCleanSignatures(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePackets(&p1, 1);
+ UTHFreePackets(&p2, 1);
+ return result;
+}
+
+static int DetectEngineHttpRawUriTest05(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 /../a/b/";
+ uint8_t http2_buf[] =
+ "../c/./d.html HTTP/1.0\r\n"
+ "Host: www.openinfosecfoundation.org\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 46\r\n"
+ "\r\n"
+ "This is dummy body1"
+ "This is dummy message body2";
+ 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_HTTP1;
+
+ 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 raw uri test\"; "
+ "content:\"a/b\"; http_raw_uri; depth:10; "
+ "sid:1;)");
+ if (de_ctx->sig_list == NULL)
+ goto end;
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: \n");
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+
+ if (PacketAlertCheck(p1, 1)) {
+ printf("sid 1 matched but shouldn't have\n");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (!PacketAlertCheck(p2, 1)) {
+ printf("sid 1 didn't match but should have");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ SigCleanSignatures(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePackets(&p1, 1);
+ UTHFreePackets(&p2, 1);
+ return result;
+}
+
+static int DetectEngineHttpRawUriTest06(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 /../a/b/";
+ uint8_t http2_buf[] =
+ "../c/./d.html HTTP/1.0\r\n"
+ "Host: www.openinfosecfoundation.org\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 46\r\n"
+ "\r\n"
+ "This is dummy body1"
+ "This is dummy message body2";
+ 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_HTTP1;
+
+ 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 raw uri test\"; "
+ "content:!\"/a/b\"; http_raw_uri; depth:25; "
+ "sid:1;)");
+ if (de_ctx->sig_list == NULL)
+ goto end;
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: \n");
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+
+ if (PacketAlertCheck(p1, 1)) {
+ printf("sid 1 matched but shouldn't have\n");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (PacketAlertCheck(p2, 1)) {
+ printf("sid 1 matched but shouldn't have");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ SigCleanSignatures(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePackets(&p1, 1);
+ UTHFreePackets(&p2, 1);
+ return result;
+}
+
+static int DetectEngineHttpRawUriTest07(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 /../a/b/";
+ uint8_t http2_buf[] =
+ "../c/./d.html HTTP/1.0\r\n"
+ "Host: www.openinfosecfoundation.org\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 46\r\n"
+ "\r\n"
+ "This is dummy body1"
+ "This is dummy message body2";
+ 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_HTTP1;
+
+ 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 raw uri test\"; "
+ "content:!\"/c/./d\"; http_raw_uri; depth:12; "
+ "sid:1;)");
+ if (de_ctx->sig_list == NULL)
+ goto end;
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: \n");
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+
+ if (PacketAlertCheck(p1, 1)) {
+ printf("sid 1 matched but shouldn't have\n");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (!PacketAlertCheck(p2, 1)) {
+ printf("sid 1 didn't match but should have");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ SigCleanSignatures(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePackets(&p1, 1);
+ UTHFreePackets(&p2, 1);
+ return result;
+}
+
+static int DetectEngineHttpRawUriTest08(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 /../a/";
+ uint8_t http2_buf[] =
+ "b/../c/./d.html HTTP/1.0\r\n"
+ "Host: www.openinfosecfoundation.org\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 46\r\n"
+ "\r\n"
+ "This is dummy body1"
+ "This is dummy message body2";
+ 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_HTTP1;
+
+ 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 raw uri test\"; "
+ "content:!\"/c/./d\"; http_raw_uri; depth:18; "
+ "sid:1;)");
+ if (de_ctx->sig_list == NULL)
+ goto end;
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: \n");
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+
+ if (PacketAlertCheck(p1, 1)) {
+ printf("sid 1 matched but shouldn't have\n");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (PacketAlertCheck(p2, 1)) {
+ printf("sid 1 matched but shouldn't have");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ SigCleanSignatures(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePackets(&p1, 1);
+ UTHFreePackets(&p2, 1);
+ return result;
+}
+
+static int DetectEngineHttpRawUriTest09(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 /../a";
+ uint8_t http2_buf[] =
+ "/b/../c/./d.html HTTP/1.0\r\n"
+ "Host: www.openinfosecfoundation.org\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 46\r\n"
+ "\r\n"
+ "This is dummy body1"
+ "This is dummy message body2";
+ 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_HTTP1;
+
+ 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 raw uri test\"; "
+ "content:\"/a\"; http_raw_uri; "
+ "content:\"./c/.\"; http_raw_uri; within:9; "
+ "sid:1;)");
+ if (de_ctx->sig_list == NULL)
+ goto end;
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: \n");
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+
+ if (PacketAlertCheck(p1, 1)) {
+ printf("sid 1 matched but shouldn't have\n");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (!PacketAlertCheck(p2, 1)) {
+ printf("sid 1 didn't match but should have");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ SigCleanSignatures(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePackets(&p1, 1);
+ UTHFreePackets(&p2, 1);
+ return result;
+}
+
+static int DetectEngineHttpRawUriTest10(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 /../a";
+ uint8_t http2_buf[] =
+ "/b/../c/./d.html HTTP/1.0\r\n"
+ "Host: www.openinfosecfoundation.org\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 46\r\n"
+ "\r\n"
+ "This is dummy body1"
+ "This is dummy message body2";
+ 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_HTTP1;
+
+ 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 raw uri test\"; "
+ "content:\"/a\"; http_raw_uri; "
+ "content:!\"boom\"; http_raw_uri; within:5; "
+ "sid:1;)");
+ if (de_ctx->sig_list == NULL)
+ goto end;
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: \n");
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+
+ if (PacketAlertCheck(p1, 1)) {
+ printf("sid 1 matched but shouldn't have\n");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (!PacketAlertCheck(p2, 1)) {
+ printf("sid 1 didn't match but should have");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ SigCleanSignatures(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePackets(&p1, 1);
+ UTHFreePackets(&p2, 1);
+ return result;
+}
+
+static int DetectEngineHttpRawUriTest11(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 /../a";
+ uint8_t http2_buf[] =
+ "/b/../c/./d.html HTTP/1.0\r\n"
+ "Host: www.openinfosecfoundation.org\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 46\r\n"
+ "\r\n"
+ "This is dummy body1"
+ "This is dummy message body2";
+ 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_HTTP1;
+
+ 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 raw uri test\"; "
+ "content:\"./a\"; http_raw_uri; "
+ "content:\"boom\"; http_raw_uri; within:5; "
+ "sid:1;)");
+ if (de_ctx->sig_list == NULL)
+ goto end;
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: \n");
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+
+ if (PacketAlertCheck(p1, 1)) {
+ printf("sid 1 matched but shouldn't have\n");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (PacketAlertCheck(p2, 1)) {
+ printf("sid 1 matched but shouldn't have");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ SigCleanSignatures(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePackets(&p1, 1);
+ UTHFreePackets(&p2, 1);
+ return result;
+}
+
+static int DetectEngineHttpRawUriTest12(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 /../a";
+ uint8_t http2_buf[] =
+ "/b/../c/./d.html HTTP/1.0\r\n"
+ "Host: www.openinfosecfoundation.org\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 46\r\n"
+ "\r\n"
+ "This is dummy body1"
+ "This is dummy message body2";
+ 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_HTTP1;
+
+ 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 raw uri test\"; "
+ "content:\"./a\"; http_raw_uri; "
+ "content:!\"/b/..\"; http_raw_uri; within:5; "
+ "sid:1;)");
+ if (de_ctx->sig_list == NULL)
+ goto end;
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: \n");
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+
+ if (PacketAlertCheck(p1, 1)) {
+ printf("sid 1 matched but shouldn't have\n");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (PacketAlertCheck(p2, 1)) {
+ printf("sid 1 matched but shouldn't have");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ SigCleanSignatures(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePackets(&p1, 1);
+ UTHFreePackets(&p2, 1);
+ return result;
+}
+
+static int DetectEngineHttpRawUriTest13(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 /../a";
+ uint8_t http2_buf[] =
+ "/b/../c/./d.html HTTP/1.0\r\n"
+ "Host: www.openinfosecfoundation.org\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 46\r\n"
+ "\r\n"
+ "This is dummy body1"
+ "This is dummy message body2";
+ 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_HTTP1;
+
+ 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 raw uri test\"; "
+ "content:\"./a\"; http_raw_uri; "
+ "content:\"/c/.\"; http_raw_uri; distance:5; "
+ "sid:1;)");
+ if (de_ctx->sig_list == NULL)
+ goto end;
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: \n");
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+
+ if (PacketAlertCheck(p1, 1)) {
+ printf("sid 1 matched but shouldn't have\n");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (!PacketAlertCheck(p2, 1)) {
+ printf("sid 1 didn't match but should have");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ SigCleanSignatures(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePackets(&p1, 1);
+ UTHFreePackets(&p2, 1);
+ return result;
+}
+
+static int DetectEngineHttpRawUriTest14(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 /../a";
+ uint8_t http2_buf[] =
+ "/b/../c/./d.html HTTP/1.0\r\n"
+ "Host: www.openinfosecfoundation.org\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 46\r\n"
+ "\r\n"
+ "This is dummy body1"
+ "This is dummy message body2";
+ 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_HTTP1;
+
+ 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 raw uri test\"; "
+ "content:\"./a\"; http_raw_uri; "
+ "content:!\"b/..\"; http_raw_uri; distance:5; "
+ "sid:1;)");
+ if (de_ctx->sig_list == NULL)
+ goto end;
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: \n");
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+
+ if (PacketAlertCheck(p1, 1)) {
+ printf("sid 1 matched but shouldn't have\n");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (!PacketAlertCheck(p2, 1)) {
+ printf("sid 1 didn't match but should have");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ SigCleanSignatures(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePackets(&p1, 1);
+ UTHFreePackets(&p2, 1);
+ return result;
+}
+
+static int DetectEngineHttpRawUriTest15(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 /../a";
+ uint8_t http2_buf[] =
+ "/b/../c/./d.html HTTP/1.0\r\n"
+ "Host: www.openinfosecfoundation.org\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 46\r\n"
+ "\r\n"
+ "This is dummy body1"
+ "This is dummy message body2";
+ 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_HTTP1;
+
+ 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 raw uri test\"; "
+ "content:\"./a\"; http_raw_uri; "
+ "content:\"/c/\"; http_raw_uri; distance:7; "
+ "sid:1;)");
+ if (de_ctx->sig_list == NULL)
+ goto end;
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: \n");
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+
+ if (PacketAlertCheck(p1, 1)) {
+ printf("sid 1 matched but shouldn't have\n");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (PacketAlertCheck(p2, 1)) {
+ printf("sid 1 matched but shouldn't have");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ SigCleanSignatures(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePackets(&p1, 1);
+ UTHFreePackets(&p2, 1);
+ return result;
+}
+
+static int DetectEngineHttpRawUriTest16(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 /../a";
+ uint8_t http2_buf[] =
+ "/b/../c/./d.html HTTP/1.0\r\n"
+ "Host: www.openinfosecfoundation.org\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 46\r\n"
+ "\r\n"
+ "This is dummy body1"
+ "This is dummy message body2";
+ 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_HTTP1;
+
+ 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 raw uri test\"; "
+ "content:\"./a\"; http_raw_uri; "
+ "content:!\"/c/\"; http_raw_uri; distance:4; "
+ "sid:1;)");
+ if (de_ctx->sig_list == NULL)
+ goto end;
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: \n");
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+
+ if (PacketAlertCheck(p1, 1)) {
+ printf("sid 1 matched but shouldn't have\n");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (PacketAlertCheck(p2, 1)) {
+ printf("sid 1 matched but shouldn't have");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ SigCleanSignatures(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePackets(&p1, 1);
+ UTHFreePackets(&p2, 1);
+ return result;
+}
+
+static int DetectEngineHttpRawUriTest21(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 /../a";
+ uint8_t http2_buf[] =
+ "/b/../c/./d.html HTTP/1.0\r\n"
+ "Host: www.openinfosecfoundation.org\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 46\r\n"
+ "\r\n"
+ "This is dummy body1"
+ "This is dummy message body2";
+ 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_HTTP1;
+
+ 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 raw uri test\"; "
+ "pcre:/\\.\\/a/I; "
+ "content:!\"/c/\"; http_raw_uri; within:5; "
+ "sid:1;)");
+ if (de_ctx->sig_list == NULL)
+ goto end;
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: \n");
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+
+ if (PacketAlertCheck(p1, 1)) {
+ printf("sid 1 matched but shouldn't have\n");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (!PacketAlertCheck(p2, 1)) {
+ printf("sid 1 didn't match but shouldn't have");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ SigCleanSignatures(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePackets(&p1, 1);
+ UTHFreePackets(&p2, 1);
+ return result;
+}
+
+static int DetectEngineHttpRawUriTest22(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 /../a";
+ uint8_t http2_buf[] =
+ "/b/../c/./d.html HTTP/1.0\r\n"
+ "Host: www.openinfosecfoundation.org\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 46\r\n"
+ "\r\n"
+ "This is dummy body1"
+ "This is dummy message body2";
+ 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_HTTP1;
+
+ 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 raw uri test\"; "
+ "pcre:/\\.\\/a/I; "
+ "content:!\"/c/\"; within:5; http_raw_uri; "
+ "sid:1;)");
+ if (de_ctx->sig_list == NULL)
+ goto end;
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: \n");
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+
+ if (PacketAlertCheck(p1, 1)) {
+ printf("sid 1 matched but shouldn't have\n");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (!PacketAlertCheck(p2, 1)) {
+ printf("sid 1 didn't match but shouldn't have");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ SigCleanSignatures(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePackets(&p1, 1);
+ UTHFreePackets(&p2, 1);
+ return result;
+}
+
+static int DetectEngineHttpRawUriTest23(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 /../a";
+ uint8_t http2_buf[] =
+ "/b/../c/./d.html HTTP/1.0\r\n"
+ "Host: www.openinfosecfoundation.org\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 46\r\n"
+ "\r\n"
+ "This is dummy body1"
+ "This is dummy message body2";
+ 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_HTTP1;
+
+ 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 raw uri test\"; "
+ "pcre:/\\.\\/a/I; "
+ "content:!\"/c/\"; distance:3; http_raw_uri; "
+ "sid:1;)");
+ if (de_ctx->sig_list == NULL)
+ goto end;
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: \n");
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+
+ if (PacketAlertCheck(p1, 1)) {
+ printf("sid 1 matched but shouldn't have\n");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (PacketAlertCheck(p2, 1)) {
+ printf("sid 1 matched but shouldn't have");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ SigCleanSignatures(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePackets(&p1, 1);
+ UTHFreePackets(&p2, 1);
+ return result;
+}
+
+static int DetectEngineHttpRawUriTest24(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 /../a";
+ uint8_t http2_buf[] =
+ "/b/../c/./d.html HTTP/1.0\r\n"
+ "Host: www.openinfosecfoundation.org\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 46\r\n"
+ "\r\n"
+ "This is dummy body1"
+ "This is dummy message body2";
+ 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_HTTP1;
+
+ 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 raw uri test\"; "
+ "pcre:/\\.\\/a/I; "
+ "content:!\"/c/\"; distance:10; http_raw_uri; "
+ "sid:1;)");
+ if (de_ctx->sig_list == NULL)
+ goto end;
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: \n");
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+
+ if (PacketAlertCheck(p1, 1)) {
+ printf("sid 1 matched but shouldn't have\n");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (!PacketAlertCheck(p2, 1)) {
+ printf("sid 1 didn't match but should have");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ SigCleanSignatures(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePackets(&p1, 1);
+ UTHFreePackets(&p2, 1);
+ return result;
+}
+
+static int DetectEngineHttpRawUriTest25(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 /../a";
+ uint8_t http2_buf[] =
+ "/b/../c/./d.html HTTP/1.0\r\n"
+ "Host: www.openinfosecfoundation.org\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 46\r\n"
+ "\r\n"
+ "This is dummy body1"
+ "This is dummy message body2";
+ 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_HTTP1;
+
+ 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 raw uri test\"; "
+ "pcre:/\\.\\/a/I; "
+ "content:\"/c/\"; within:10; http_raw_uri; "
+ "sid:1;)");
+ if (de_ctx->sig_list == NULL)
+ goto end;
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: \n");
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+
+ if (PacketAlertCheck(p1, 1)) {
+ printf("sid 1 matched but shouldn't have\n");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (!PacketAlertCheck(p2, 1)) {
+ printf("sid 1 didn't match but should have");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ SigCleanSignatures(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePackets(&p1, 1);
+ UTHFreePackets(&p2, 1);
+ return result;
+}
+
+static int DetectEngineHttpRawUriTest26(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 /../a";
+ uint8_t http2_buf[] =
+ "/b/../c/./d.html HTTP/1.0\r\n"
+ "Host: www.openinfosecfoundation.org\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 46\r\n"
+ "\r\n"
+ "This is dummy body1"
+ "This is dummy message body2";
+ 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_HTTP1;
+
+ 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 raw uri test\"; "
+ "pcre:/\\.\\/a/I; "
+ "content:\"/c/\"; within:5; http_raw_uri; "
+ "sid:1;)");
+ if (de_ctx->sig_list == NULL)
+ goto end;
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: \n");
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+
+ if (PacketAlertCheck(p1, 1)) {
+ printf("sid 1 matched but shouldn't have\n");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (PacketAlertCheck(p2, 1)) {
+ printf("sid 1 matched but shouldn't have");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ SigCleanSignatures(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePackets(&p1, 1);
+ UTHFreePackets(&p2, 1);
+ return result;
+}
+
+static int DetectEngineHttpRawUriTest27(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 /../a";
+ uint8_t http2_buf[] =
+ "/b/../c/./d.html HTTP/1.0\r\n"
+ "Host: www.openinfosecfoundation.org\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 46\r\n"
+ "\r\n"
+ "This is dummy body1"
+ "This is dummy message body2";
+ 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_HTTP1;
+
+ 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 raw uri test\"; "
+ "pcre:/\\.\\/a/I; "
+ "content:\"/c/\"; distance:5; http_raw_uri; "
+ "sid:1;)");
+ if (de_ctx->sig_list == NULL)
+ goto end;
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: \n");
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+
+ if (PacketAlertCheck(p1, 1)) {
+ printf("sid 1 matched but shouldn't have\n");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (!PacketAlertCheck(p2, 1)) {
+ printf("sid 1 didn't match but should have");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ SigCleanSignatures(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePackets(&p1, 1);
+ UTHFreePackets(&p2, 1);
+ return result;
+}
+
+static int DetectEngineHttpRawUriTest28(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 /../a";
+ uint8_t http2_buf[] =
+ "/b/../c/./d.html HTTP/1.0\r\n"
+ "Host: www.openinfosecfoundation.org\r\n"
+ "Content-Type: text/html\r\n"
+ "Content-Length: 46\r\n"
+ "\r\n"
+ "This is dummy body1"
+ "This is dummy message body2";
+ 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_HTTP1;
+
+ 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 raw uri test\"; "
+ "pcre:/\\.\\/a/I; "
+ "content:\"/c/\"; distance:10; http_raw_uri; "
+ "sid:1;)");
+ if (de_ctx->sig_list == NULL)
+ goto end;
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ result = 0;
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: \n");
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
+
+ if (PacketAlertCheck(p1, 1)) {
+ printf("sid 1 matched but shouldn't have\n");
+ goto end;
+ }
+
+ r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
+ result = 0;
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
+
+ if (PacketAlertCheck(p2, 1)) {
+ printf("sid 1 matched but shouldn't have");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ SigCleanSignatures(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePackets(&p1, 1);
+ UTHFreePackets(&p2, 1);
+ return result;
+}
+
+/**
+ * \test Test multiple relative contents with a negated content.
+ */
+static int DetectEngineHttpRawUriTest29(void)
+{
+ int result = 0;
+ uint8_t *http_buf = (uint8_t *)"POST /../a/b/../c/./d.html HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n";
+ uint32_t http_buf_len = strlen((char *)http_buf);
+ Flow f;
+ TcpSession ssn;
+ HtpState *http_state = NULL;
+ Packet *p = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p->flow = &f;
+ p->flags |= PKT_HAS_FLOW | PKT_STREAM_EST;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f.alproto = ALPROTO_HTTP1;
+
+ StreamTcpInitConfig(true);
+
+ DetectEngineCtx *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:\"test multiple relative raw uri contents\"; "
+ "content:\"/c/\"; http_raw_uri; "
+ "isdataat:4,relative; sid:1;)");
+ if (de_ctx->sig_list == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_buf_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 didn't alert, but it should have: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+/**
+ * \test Test multiple relative contents with a negated content.
+ */
+static int DetectEngineHttpRawUriTest30(void)
+{
+ int result = 0;
+ uint8_t *http_buf = (uint8_t *)"POST /../a/b/../c/./d.html HTTP/1.0\r\n"
+ "User-Agent: Mozilla/1.0\r\n";
+ uint32_t http_buf_len = strlen((char *)http_buf);
+ Flow f;
+ TcpSession ssn;
+ HtpState *http_state = NULL;
+ Packet *p = NULL;
+ ThreadVars tv;
+ DetectEngineThreadCtx *det_ctx = NULL;
+ AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
+
+ memset(&tv, 0, sizeof(ThreadVars));
+ memset(&f, 0, sizeof(Flow));
+ memset(&ssn, 0, sizeof(TcpSession));
+
+ p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
+
+ FLOW_INITIALIZE(&f);
+ f.protoctx = (void *)&ssn;
+ f.proto = IPPROTO_TCP;
+ f.flags |= FLOW_IPV4;
+
+ p->flow = &f;
+ p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
+ p->flowflags |= FLOW_PKT_TOSERVER;
+ p->flowflags |= FLOW_PKT_ESTABLISHED;
+ f.alproto = ALPROTO_HTTP1;
+
+ StreamTcpInitConfig(true);
+
+ DetectEngineCtx *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:\"test multiple relative raw uri contents\"; "
+ "uricontent:\"/c/\"; isdataat:!10,relative; sid:1;)");
+ if (de_ctx->sig_list == NULL) {
+ goto end;
+ }
+
+ SigGroupBuild(de_ctx);
+ DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
+
+ int r = AppLayerParserParse(
+ NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_buf_len);
+ if (r != 0) {
+ printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
+ goto end;
+ }
+
+ http_state = f.alstate;
+ if (http_state == NULL) {
+ printf("no http state: ");
+ goto end;
+ }
+
+ /* do detect */
+ SigMatchSignatures(&tv, de_ctx, det_ctx, p);
+
+ if (!PacketAlertCheck(p, 1)) {
+ printf("sig 1 didn't alert, but it should have: ");
+ goto end;
+ }
+
+ result = 1;
+
+end:
+ if (alp_tctx != NULL)
+ AppLayerParserThreadCtxFree(alp_tctx);
+ if (det_ctx != NULL)
+ DetectEngineThreadCtxDeinit(&tv, det_ctx);
+ if (de_ctx != NULL)
+ SigGroupCleanup(de_ctx);
+ if (de_ctx != NULL)
+ DetectEngineCtxFree(de_ctx);
+
+ StreamTcpFreeConfig(true);
+ FLOW_DESTROY(&f);
+ UTHFreePacket(p);
+ return result;
+}
+
+/**
+ * \brief Register the UNITTESTS for the http_uri keyword
+ */
+static void DetectHttpUriRegisterTests (void)
+{
+ UtRegisterTest("UriTestSig01", UriTestSig01);
+ UtRegisterTest("UriTestSig02", UriTestSig02);
+ UtRegisterTest("UriTestSig03", UriTestSig03);
+ UtRegisterTest("UriTestSig04", UriTestSig04);
+ UtRegisterTest("UriTestSig05", UriTestSig05);
+ UtRegisterTest("UriTestSig06", UriTestSig06);
+ UtRegisterTest("UriTestSig07", UriTestSig07);
+ UtRegisterTest("UriTestSig08", UriTestSig08);
+ UtRegisterTest("UriTestSig09", UriTestSig09);
+ UtRegisterTest("UriTestSig12", UriTestSig12);
+ UtRegisterTest("UriTestSig13", UriTestSig13);
+ UtRegisterTest("UriTestSig14", UriTestSig14);
+ UtRegisterTest("UriTestSig15", UriTestSig15);
+ UtRegisterTest("UriTestSig16", UriTestSig16);
+ UtRegisterTest("UriTestSig17", UriTestSig17);
+ UtRegisterTest("UriTestSig18", UriTestSig18);
+ UtRegisterTest("UriTestSig19", UriTestSig19);
+ UtRegisterTest("UriTestSig20", UriTestSig20);
+ UtRegisterTest("UriTestSig21", UriTestSig21);
+ UtRegisterTest("UriTestSig22", UriTestSig22);
+ UtRegisterTest("UriTestSig23", UriTestSig23);
+ UtRegisterTest("UriTestSig24", UriTestSig24);
+ UtRegisterTest("UriTestSig25", UriTestSig25);
+ UtRegisterTest("UriTestSig26", UriTestSig26);
+ UtRegisterTest("UriTestSig27", UriTestSig27);
+
+ UtRegisterTest("UriTestSig28", UriTestSig28);
+ UtRegisterTest("UriTestSig29", UriTestSig29);
+ UtRegisterTest("UriTestSig30", UriTestSig30);
+ UtRegisterTest("UriTestSig31", UriTestSig31);
+ UtRegisterTest("UriTestSig32", UriTestSig32);
+ UtRegisterTest("UriTestSig33", UriTestSig33);
+ UtRegisterTest("UriTestSig34", UriTestSig34);
+ UtRegisterTest("UriTestSig35", UriTestSig35);
+ UtRegisterTest("UriTestSig36", UriTestSig36);
+ UtRegisterTest("UriTestSig37", UriTestSig37);
+ UtRegisterTest("UriTestSig38", UriTestSig38);
+
+ UtRegisterTest("DetectHttpUriIsdataatParseTest",
+ DetectHttpUriIsdataatParseTest);
+
+ UtRegisterTest("DetectEngineHttpRawUriTest01",
+ DetectEngineHttpRawUriTest01);
+ UtRegisterTest("DetectEngineHttpRawUriTest02",
+ DetectEngineHttpRawUriTest02);
+ UtRegisterTest("DetectEngineHttpRawUriTest03",
+ DetectEngineHttpRawUriTest03);
+ UtRegisterTest("DetectEngineHttpRawUriTest04",
+ DetectEngineHttpRawUriTest04);
+ UtRegisterTest("DetectEngineHttpRawUriTest05",
+ DetectEngineHttpRawUriTest05);
+ UtRegisterTest("DetectEngineHttpRawUriTest06",
+ DetectEngineHttpRawUriTest06);
+ UtRegisterTest("DetectEngineHttpRawUriTest07",
+ DetectEngineHttpRawUriTest07);
+ UtRegisterTest("DetectEngineHttpRawUriTest08",
+ DetectEngineHttpRawUriTest08);
+ UtRegisterTest("DetectEngineHttpRawUriTest09",
+ DetectEngineHttpRawUriTest09);
+ UtRegisterTest("DetectEngineHttpRawUriTest10",
+ DetectEngineHttpRawUriTest10);
+ UtRegisterTest("DetectEngineHttpRawUriTest11",
+ DetectEngineHttpRawUriTest11);
+ UtRegisterTest("DetectEngineHttpRawUriTest12",
+ DetectEngineHttpRawUriTest12);
+ UtRegisterTest("DetectEngineHttpRawUriTest13",
+ DetectEngineHttpRawUriTest13);
+ UtRegisterTest("DetectEngineHttpRawUriTest14",
+ DetectEngineHttpRawUriTest14);
+ UtRegisterTest("DetectEngineHttpRawUriTest15",
+ DetectEngineHttpRawUriTest15);
+ UtRegisterTest("DetectEngineHttpRawUriTest16",
+ DetectEngineHttpRawUriTest16);
+ UtRegisterTest("DetectEngineHttpRawUriTest21",
+ DetectEngineHttpRawUriTest21);
+ UtRegisterTest("DetectEngineHttpRawUriTest22",
+ DetectEngineHttpRawUriTest22);
+ UtRegisterTest("DetectEngineHttpRawUriTest23",
+ DetectEngineHttpRawUriTest23);
+ UtRegisterTest("DetectEngineHttpRawUriTest24",
+ DetectEngineHttpRawUriTest24);
+ UtRegisterTest("DetectEngineHttpRawUriTest25",
+ DetectEngineHttpRawUriTest25);
+ UtRegisterTest("DetectEngineHttpRawUriTest26",
+ DetectEngineHttpRawUriTest26);
+ UtRegisterTest("DetectEngineHttpRawUriTest27",
+ DetectEngineHttpRawUriTest27);
+ UtRegisterTest("DetectEngineHttpRawUriTest28",
+ DetectEngineHttpRawUriTest28);
+ UtRegisterTest("DetectEngineHttpRawUriTest29",
+ DetectEngineHttpRawUriTest29);
+ UtRegisterTest("DetectEngineHttpRawUriTest30",
+ DetectEngineHttpRawUriTest30);
+}