You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
suricata/src/tests/detect-http-raw-header.c

4620 lines
130 KiB
C

/* Copyright (C) 2007-2016 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/**
* \ingroup httplayer
*
* @{
*/
/** \file
*
* \author Anoop Saldanha <anoopsaldanha@gmail.com>
* \author Victor Julien <victor@inliniac.net>
*
* \brief Handle HTTP raw header match.
*
*/
#include "../suricata-common.h"
#include "../suricata.h"
#include "../decode.h"
#include "../detect.h"
#include "../detect-engine.h"
#include "../detect-isdataat.h"
#include "../detect-pcre.h"
#include "../stream-tcp.h"
#include "../app-layer.h"
#include "../app-layer-htp.h"
#include "../app-layer-protos.h"
#include "../app-layer-parser.h"
#include "../util-unittest.h"
#include "../util-unittest-helper.h"
#include "../util-validate.h"
/***********************************Unittests**********************************/
#ifdef UNITTESTS
/**
* \test Test parser accepting valid rules and rejecting invalid rules
*/
static int DetectHttpRawHeaderParserTest01(void)
{
FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; content:\"abc\"; http_raw_header; sid:1;)", true));
FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; content:\"abc\"; nocase; http_raw_header; sid:1;)", true));
FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; content:\"abc\"; endswith; http_raw_header; sid:1;)", true));
FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; content:\"abc\"; startswith; http_raw_header; sid:1;)", true));
FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; content:\"abc\"; startswith; endswith; http_raw_header; sid:1;)", true));
FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; content:\"abc\"; rawbytes; http_raw_header; sid:1;)", false));
FAIL_IF_NOT(UTHParseSignature("alert tcp any any -> any any (flow:to_server; http_raw_header; sid:1;)", false));
FAIL_IF_NOT(UTHParseSignature("alert tls any any -> any any (flow:to_server; content:\"abc\"; http_raw_header; sid:1;)", false));
PASS;
}
/**
* \test Test parser accepting valid rules and rejecting invalid rules
*/
static int DetectHttpRawHeaderParserTest02(void)
{
FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; http.header.raw; content:\"abc\"; sid:1;)", true));
FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; http.header.raw; content:\"abc\"; nocase; sid:1;)", true));
FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; http.header.raw; content:\"abc\"; endswith; sid:1;)", true));
FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; http.header.raw; content:\"abc\"; startswith; sid:1;)", true));
FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; http.header.raw; content:\"abc\"; startswith; endswith; sid:1;)", true));
FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; http.header.raw; bsize:10; sid:1;)", true));
FAIL_IF_NOT(UTHParseSignature("alert http any any -> any any (flow:to_server; http.header.raw; content:\"abc\"; rawbytes; sid:1;)", false));
FAIL_IF_NOT(UTHParseSignature("alert tcp any any -> any any (flow:to_server; http.header.raw; sid:1;)", false));
FAIL_IF_NOT(UTHParseSignature("alert tls any any -> any any (flow:to_server; http.header.raw; content:\"abc\"; sid:1;)", false));
PASS;
}
/**
*\test Test that the http_header content matches against a http request
* which holds the content.
*/
static int DetectEngineHttpRawHeaderTest01(void)
{
TcpSession ssn;
Packet *p = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
uint32_t http_len = sizeof(http_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 header test\"; flow:to_server; "
"content:\"one\"; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: ");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (!(PacketAlertCheck(p, 1))) {
printf("sid 1 didn't match but should have: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p, 1);
return result;
}
/**
*\test Test that the http_header content matches against a http request
* which holds the content.
*/
static int DetectEngineHttpRawHeaderTest02(void)
{
TcpSession ssn;
Packet *p = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
uint32_t http_len = sizeof(http_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 header test\"; flow:to_server; "
"content:\"one\"; depth:15; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: ");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (!(PacketAlertCheck(p, 1))) {
printf("sid 1 didn't match but should have: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p, 1);
return result;
}
/**
*\test Test that the http_header content matches against a http request
* which holds the content.
*/
static int DetectEngineHttpRawHeaderTest03(void)
{
TcpSession ssn;
Packet *p = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
uint32_t http_len = sizeof(http_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 header test\"; flow:to_server; "
"content:!\"one\"; depth:5; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: ");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (!(PacketAlertCheck(p, 1))) {
printf("sid 1 didn't match but should have: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p, 1);
return result;
}
/**
*\test Test that the http_header content matches against a http request
* which holds the content.
*/
static int DetectEngineHttpRawHeaderTest04(void)
{
TcpSession ssn;
Packet *p = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
uint32_t http_len = sizeof(http_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 header test\"; flow:to_server; "
"content:\"one\"; depth:5; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: ");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (PacketAlertCheck(p, 1)) {
printf("sid 1 matched but shouldn't have: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p, 1);
return result;
}
/**
*\test Test that the http_header content matches against a http request
* which holds the content.
*/
static int DetectEngineHttpRawHeaderTest05(void)
{
TcpSession ssn;
Packet *p = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
uint32_t http_len = sizeof(http_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 header test\"; flow:to_server; "
"content:!\"one\"; depth:15; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: ");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (PacketAlertCheck(p, 1)) {
printf("sid 1 matched but shouldn't have: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p, 1);
return result;
}
/**
*\test Test that the http_header content matches against a http request
* which holds the content.
*/
static int DetectEngineHttpRawHeaderTest06(void)
{
TcpSession ssn;
Packet *p = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
uint32_t http_len = sizeof(http_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 header test\"; flow:to_server; "
"content:\"one\"; offset:10; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: ");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (!(PacketAlertCheck(p, 1))) {
printf("sid 1 didn't match but should have: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p, 1);
return result;
}
/**
*\test Test that the http_header content matches against a http request
* which holds the content.
*/
static int DetectEngineHttpRawHeaderTest07(void)
{
TcpSession ssn;
Packet *p = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
uint32_t http_len = sizeof(http_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 header test\"; flow:to_server; "
"content:!\"one\"; offset:15; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: ");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (!(PacketAlertCheck(p, 1))) {
printf("sid 1 didn't match but should have: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p, 1);
return result;
}
/**
*\test Test that the http_header content matches against a http request
* which holds the content.
*/
static int DetectEngineHttpRawHeaderTest08(void)
{
TcpSession ssn;
Packet *p = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
uint32_t http_len = sizeof(http_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 header test\"; flow:to_server; "
"content:\"one\"; offset:15; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: ");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (PacketAlertCheck(p, 1)) {
printf("sid 1 matched but shouldn't have: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p, 1);
return result;
}
/**
*\test Test that the http_header content matches against a http request
* which holds the content.
*/
static int DetectEngineHttpRawHeaderTest09(void)
{
TcpSession ssn;
Packet *p = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
uint32_t http_len = sizeof(http_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 header test\"; flow:to_server; "
"content:!\"one\"; offset:10; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: ");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (PacketAlertCheck(p, 1)) {
printf("sid 1 matched but shouldn't have: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p, 1);
return result;
}
/**
*\test Test that the http_header content matches against a http request
* which holds the content.
*/
static int DetectEngineHttpRawHeaderTest10(void)
{
TcpSession ssn;
Packet *p = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
uint32_t http_len = sizeof(http_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 header test\"; flow:to_server; "
"content:\"one\"; http_raw_header; content:\"three\"; http_raw_header; within:10; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: ");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (!(PacketAlertCheck(p, 1))) {
printf("sid 1 didn't match but should have: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p, 1);
return result;
}
/**
*\test Test that the http_header content matches against a http request
* which holds the content.
*/
static int DetectEngineHttpRawHeaderTest11(void)
{
TcpSession ssn;
Packet *p = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
uint32_t http_len = sizeof(http_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 header test\"; flow:to_server; "
"content:\"one\"; http_raw_header; content:!\"three\"; http_raw_header; within:5; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: ");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (!(PacketAlertCheck(p, 1))) {
printf("sid 1 didn't match but should have: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p, 1);
return result;
}
/**
*\test Test that the http_header content matches against a http request
* which holds the content.
*/
static int DetectEngineHttpRawHeaderTest12(void)
{
TcpSession ssn;
Packet *p = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
uint32_t http_len = sizeof(http_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 header test\"; flow:to_server; "
"content:\"one\"; http_raw_header; content:!\"three\"; http_raw_header; within:10; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: ");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (PacketAlertCheck(p, 1)) {
printf("sid 1 matched but shouldn't have: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p, 1);
return result;
}
/**
*\test Test that the http_header content matches against a http request
* which holds the content.
*/
static int DetectEngineHttpRawHeaderTest13(void)
{
TcpSession ssn;
Packet *p = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
uint32_t http_len = sizeof(http_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 header test\"; flow:to_server; "
"content:\"one\"; http_raw_header; content:\"three\"; http_raw_header; within:5; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: ");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (PacketAlertCheck(p, 1)) {
printf("sid 1 matched but shouldn't have: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p, 1);
return result;
}
/**
*\test Test that the http_header content matches against a http request
* which holds the content.
*/
static int DetectEngineHttpRawHeaderTest14(void)
{
TcpSession ssn;
Packet *p = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
uint32_t http_len = sizeof(http_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 header test\"; flow:to_server; "
"content:\"one\"; http_raw_header; content:\"five\"; http_raw_header; distance:7; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: ");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (!(PacketAlertCheck(p, 1))) {
printf("sid 1 didn't match but should have: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p, 1);
return result;
}
/**
*\test Test that the http_header content matches against a http request
* which holds the content.
*/
static int DetectEngineHttpRawHeaderTest15(void)
{
TcpSession ssn;
Packet *p = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
uint32_t http_len = sizeof(http_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 header test\"; flow:to_server; "
"content:\"one\"; http_raw_header; content:!\"five\"; http_raw_header; distance:15; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: ");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (!(PacketAlertCheck(p, 1))) {
printf("sid 1 didn't match but should have: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p, 1);
return result;
}
/**
*\test Test that the http_header content matches against a http request
* which holds the content.
*/
static int DetectEngineHttpRawHeaderTest16(void)
{
TcpSession ssn;
Packet *p = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
uint32_t http_len = sizeof(http_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 header test\"; flow:to_server; "
"content:\"one\"; http_raw_header; content:!\"five\"; http_raw_header; distance:7; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: ");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (PacketAlertCheck(p, 1)) {
printf("sid 1 matched but shouldn't have: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p, 1);
return result;
}
/**
*\test Test that the http_header content matches against a http request
* which holds the content.
*/
static int DetectEngineHttpRawHeaderTest17(void)
{
TcpSession ssn;
Packet *p = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
uint32_t http_len = sizeof(http_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 header test\"; flow:to_server; "
"content:\"one\"; http_raw_header; content:\"five\"; http_raw_header; distance:15; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: ");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (PacketAlertCheck(p, 1)) {
printf("sid 1 matched but shouldn't have: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p, 1);
return result;
}
static int DetectEngineHttpRawHeaderTest20(void)
{
TcpSession ssn;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx = NULL;
Flow f;
uint8_t http1_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: This_is_dummy_body1";
uint8_t http2_buf[] =
"This_is_dummy_message_body2\r\n"
"\r\n";
uint32_t http1_len = sizeof(http1_buf) - 1;
uint32_t http2_len = sizeof(http2_buf) - 1;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
FAIL_IF_NULL(alp_tctx);
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
Packet *p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FAIL_IF_NULL(p1);
Packet *p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FAIL_IF_NULL(p2);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p1->flow = &f;
p1->flowflags |= FLOW_PKT_TOSERVER;
p1->flowflags |= FLOW_PKT_ESTABLISHED;
p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
p2->flow = &f;
p2->flowflags |= FLOW_PKT_TOSERVER;
p2->flowflags |= FLOW_PKT_ESTABLISHED;
p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_HTTP1;
StreamTcpInitConfig(true);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
FAIL_IF_NULL(de_ctx);
de_ctx->flags |= DE_QUIET;
Signature *s = DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
"(flow:to_server; pcre:/body1/D; "
"content:!\"dummy\"; http_raw_header; within:7; "
"sid:1;)");
FAIL_IF_NULL(s);
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FAIL_IF_NULL(det_ctx);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
FAIL_IF_NOT(r == 0);
HtpState *http_state = f.alstate;
FAIL_IF_NULL(http_state);
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
FAIL_IF(PacketAlertCheck(p1, 1));
r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
FAIL_IF_NOT(r == 0);
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
FAIL_IF(!PacketAlertCheck(p2, 1));
AppLayerParserThreadCtxFree(alp_tctx);
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p1, 1);
UTHFreePackets(&p2, 1);
PASS;
}
static int DetectEngineHttpRawHeaderTest21(void)
{
TcpSession ssn;
Packet *p1 = NULL;
Packet *p2 = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http1_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: This_is_dummy_body1";
uint8_t http2_buf[] =
"This_is_dummy_message_body2\r\n"
"\r\n";
uint32_t http1_len = sizeof(http1_buf) - 1;
uint32_t http2_len = sizeof(http2_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p1->flow = &f;
p1->flowflags |= FLOW_PKT_TOSERVER;
p1->flowflags |= FLOW_PKT_ESTABLISHED;
p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
p2->flow = &f;
p2->flowflags |= FLOW_PKT_TOSERVER;
p2->flowflags |= FLOW_PKT_ESTABLISHED;
p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 client body test\"; flow:to_server; "
"pcre:/body1/D; "
"content:!\"dummy\"; within:7; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: \n");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
if (PacketAlertCheck(p1, 1)) {
printf("sid 1 matched but shouldn't have\n");
goto end;
}
FLOWLOCK_WRLOCK(&f);
r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
if (!PacketAlertCheck(p2, 1)) {
printf("sid 1 didn't match but shouldn't have");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p1, 1);
UTHFreePackets(&p2, 1);
return result;
}
static int DetectEngineHttpRawHeaderTest22(void)
{
TcpSession ssn;
Packet *p1 = NULL;
Packet *p2 = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http1_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: This_is_dummy_body1";
uint8_t http2_buf[] =
"This_is_dummy_message_body2\r\n"
"\r\n";
uint32_t http1_len = sizeof(http1_buf) - 1;
uint32_t http2_len = sizeof(http2_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p1->flow = &f;
p1->flowflags |= FLOW_PKT_TOSERVER;
p1->flowflags |= FLOW_PKT_ESTABLISHED;
p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
p2->flow = &f;
p2->flowflags |= FLOW_PKT_TOSERVER;
p2->flowflags |= FLOW_PKT_ESTABLISHED;
p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 client body test\"; flow:to_server; "
"pcre:/body1/D; "
"content:!\"dummy\"; distance:3; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: \n");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
if (PacketAlertCheck(p1, 1)) {
printf("sid 1 matched but shouldn't have\n");
goto end;
}
FLOWLOCK_WRLOCK(&f);
r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
if (PacketAlertCheck(p2, 1)) {
printf("sid 1 matched but shouldn't have");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p1, 1);
UTHFreePackets(&p2, 1);
return result;
}
static int DetectEngineHttpRawHeaderTest23(void)
{
TcpSession ssn;
Packet *p1 = NULL;
Packet *p2 = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http1_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: This_is_dummy_body1";
uint8_t http2_buf[] =
"This_is_dummy_message_body2\r\n"
"\r\n";
uint32_t http1_len = sizeof(http1_buf) - 1;
uint32_t http2_len = sizeof(http2_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p1->flow = &f;
p1->flowflags |= FLOW_PKT_TOSERVER;
p1->flowflags |= FLOW_PKT_ESTABLISHED;
p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
p2->flow = &f;
p2->flowflags |= FLOW_PKT_TOSERVER;
p2->flowflags |= FLOW_PKT_ESTABLISHED;
p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 client body test\"; flow:to_server; "
"pcre:/body1/D; "
"content:!\"dummy\"; distance:13; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: \n");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
if (PacketAlertCheck(p1, 1)) {
printf("sid 1 matched but shouldn't have\n");
goto end;
}
FLOWLOCK_WRLOCK(&f);
r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
if (!PacketAlertCheck(p2, 1)) {
printf("sid 1 didn't match but should have");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p1, 1);
UTHFreePackets(&p2, 1);
return result;
}
static int DetectEngineHttpRawHeaderTest24(void)
{
TcpSession ssn;
Packet *p1 = NULL;
Packet *p2 = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http1_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: This_is_dummy_body1";
uint8_t http2_buf[] =
"This_is_dummy_message_body2\r\n"
"\r\n";
uint32_t http1_len = sizeof(http1_buf) - 1;
uint32_t http2_len = sizeof(http2_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p1->flow = &f;
p1->flowflags |= FLOW_PKT_TOSERVER;
p1->flowflags |= FLOW_PKT_ESTABLISHED;
p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
p2->flow = &f;
p2->flowflags |= FLOW_PKT_TOSERVER;
p2->flowflags |= FLOW_PKT_ESTABLISHED;
p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 client body test\"; flow:to_server; "
"pcre:/body1/D; "
"content:\"dummy\"; within:15; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: \n");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
if (PacketAlertCheck(p1, 1)) {
printf("sid 1 matched but shouldn't have\n");
goto end;
}
FLOWLOCK_WRLOCK(&f);
r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
if (!PacketAlertCheck(p2, 1)) {
printf("sid 1 didn't match but should have");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p1, 1);
UTHFreePackets(&p2, 1);
return result;
}
static int DetectEngineHttpRawHeaderTest25(void)
{
TcpSession ssn;
Packet *p1 = NULL;
Packet *p2 = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http1_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: This_is_dummy_body1";
uint8_t http2_buf[] =
"This_is_dummy_message_body2\r\n"
"\r\n";
uint32_t http1_len = sizeof(http1_buf) - 1;
uint32_t http2_len = sizeof(http2_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p1->flow = &f;
p1->flowflags |= FLOW_PKT_TOSERVER;
p1->flowflags |= FLOW_PKT_ESTABLISHED;
p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
p2->flow = &f;
p2->flowflags |= FLOW_PKT_TOSERVER;
p2->flowflags |= FLOW_PKT_ESTABLISHED;
p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 client body test\"; flow:to_server; "
"pcre:/body1/D; "
"content:\"dummy\"; within:10; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: \n");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
if (PacketAlertCheck(p1, 1)) {
printf("sid 1 matched but shouldn't have\n");
goto end;
}
FLOWLOCK_WRLOCK(&f);
r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
if (PacketAlertCheck(p2, 1)) {
printf("sid 1 matched but shouldn't have");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p1, 1);
UTHFreePackets(&p2, 1);
return result;
}
static int DetectEngineHttpRawHeaderTest26(void)
{
TcpSession ssn;
Packet *p1 = NULL;
Packet *p2 = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http1_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: This_is_dummy_body1";
uint8_t http2_buf[] =
"This_is_dummy_message_body2\r\n"
"\r\n";
uint32_t http1_len = sizeof(http1_buf) - 1;
uint32_t http2_len = sizeof(http2_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p1->flow = &f;
p1->flowflags |= FLOW_PKT_TOSERVER;
p1->flowflags |= FLOW_PKT_ESTABLISHED;
p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
p2->flow = &f;
p2->flowflags |= FLOW_PKT_TOSERVER;
p2->flowflags |= FLOW_PKT_ESTABLISHED;
p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 client body test\"; flow:to_server; "
"pcre:/body1/D; "
"content:\"dummy\"; distance:8; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: \n");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
if (PacketAlertCheck(p1, 1)) {
printf("sid 1 matched but shouldn't have\n");
goto end;
}
FLOWLOCK_WRLOCK(&f);
r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
if (!PacketAlertCheck(p2, 1)) {
printf("sid 1 didn't match but should have");
goto end;
}
result = 1;
end:
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p1, 1);
UTHFreePackets(&p2, 1);
return result;
}
static int DetectEngineHttpRawHeaderTest27(void)
{
TcpSession ssn;
Packet *p1 = NULL;
Packet *p2 = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http1_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: This_is_dummy_body1";
uint8_t http2_buf[] =
"This_is_dummy_message_body2\r\n"
"\r\n";
uint32_t http1_len = sizeof(http1_buf) - 1;
uint32_t http2_len = sizeof(http2_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p1->flow = &f;
p1->flowflags |= FLOW_PKT_TOSERVER;
p1->flowflags |= FLOW_PKT_ESTABLISHED;
p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
p2->flow = &f;
p2->flowflags |= FLOW_PKT_TOSERVER;
p2->flowflags |= FLOW_PKT_ESTABLISHED;
p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 client body test\"; flow:to_server; "
"pcre:/body1/D; "
"content:\"dummy\"; distance:14; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: \n");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
if (PacketAlertCheck(p1, 1)) {
printf("sid 1 matched but shouldn't have\n");
goto end;
}
FLOWLOCK_WRLOCK(&f);
r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
if (PacketAlertCheck(p2, 1)) {
printf("sid 1 matched but shouldn't have");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p1, 1);
UTHFreePackets(&p2, 1);
return result;
}
static int DetectEngineHttpRawHeaderTest28(void)
{
TcpSession ssn;
Packet *p1 = NULL;
Packet *p2 = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http_buf1[] =
"GET /index.html HTTP/1.0\r\n"
"Host: www.openinfosecfoundation.org\r\n"
"User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
"\r\n";
uint32_t http_buf1_len = sizeof(http_buf1) - 1;
uint8_t http_buf2[] =
"HTTP/1.0 200 ok\r\n"
"Content-Type: text/html\r\n"
"Content-Length: 6\r\n"
"\r\n"
"abcdef";
uint32_t http_buf2_len = sizeof(http_buf2) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p1->flow = &f;
p1->flowflags |= FLOW_PKT_TOSERVER;
p1->flowflags |= FLOW_PKT_ESTABLISHED;
p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST;
p2->flow = &f;
p2->flowflags |= FLOW_PKT_TOCLIENT;
p2->flowflags |= FLOW_PKT_ESTABLISHED;
p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST;
f.alproto = ALPROTO_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 header test\"; flow:to_client; "
"content:\"Content-Length: 6\"; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_buf1_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: \n");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
if (PacketAlertCheck(p1, 1)) {
printf("sid 1 matched but shouldn't have\n");
goto end;
}
FLOWLOCK_WRLOCK(&f);
r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOCLIENT, http_buf2, http_buf2_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
if (!PacketAlertCheck(p2, 1)) {
printf("sid 1 didn't match but should have");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p1, 1);
UTHFreePackets(&p2, 1);
return result;
}
static int DetectEngineHttpRawHeaderTest29(void)
{
TcpSession ssn;
Packet *p1 = NULL;
Packet *p2 = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http_buf1[] =
"GET /index.html HTTP/1.0\r\n"
"Host: www.openinfosecfoundation.org\r\n"
"User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
"\r\n";
uint32_t http_buf1_len = sizeof(http_buf1) - 1;
uint8_t http_buf2[] =
"HTTP/1.0 200 ok\r\n"
"Content-Type: text/html\r\n"
"Content-Length: 6\r\n"
"\r\n"
"abcdef";
uint32_t http_buf2_len = sizeof(http_buf2) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p1->flow = &f;
p1->flowflags |= FLOW_PKT_TOSERVER;
p1->flowflags |= FLOW_PKT_ESTABLISHED;
p1->flags |= PKT_HAS_FLOW | PKT_STREAM_EST;
p2->flow = &f;
p2->flowflags |= FLOW_PKT_TOCLIENT;
p2->flowflags |= FLOW_PKT_ESTABLISHED;
p2->flags |= PKT_HAS_FLOW | PKT_STREAM_EST;
f.alproto = ALPROTO_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 header test\"; flow:to_client; "
"content:\"Content-Length: 7\"; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf1, http_buf1_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: \n");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
if (PacketAlertCheck(p1, 1)) {
printf("sid 1 matched but shouldn't have\n");
goto end;
}
FLOWLOCK_WRLOCK(&f);
r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOCLIENT, http_buf2, http_buf2_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
if (PacketAlertCheck(p2, 1)) {
printf("sid 1 matched but shouldn't have");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p1, 1);
UTHFreePackets(&p2, 1);
return result;
}
#if 0
static int DetectEngineHttpRawHeaderTest30(void)
{
int result = 0;
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any "
"(msg:\"http header test\"; "
"content:\"Content-Length: 6\"; http_raw_header; "
"content:\"User-Agent: Mozilla\"; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list != NULL) {
goto end;
}
result = 1;
end:
if (de_ctx != NULL)
SigCleanSignatures(de_ctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
return result;
}
#endif /* #if 0 */
/**
* \test Trailing headers.
*/
static int DetectEngineHttpRawHeaderTest31(void)
{
TcpSession ssn;
Packet *p1 = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http1_buf[] =
"GET /index.html HTTP/1.0\r\n"
"host: boom\r\n"
"Transfer-Encoding: chunked\r\n"
"\r\n"
"13\r\n"
"This is dummy body1\r\n"
"0\r\n"
"Dummy-Header: kaboom\r\n"
"\r\n";
uint32_t http1_len = sizeof(http1_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p1->flow = &f;
p1->flowflags |= FLOW_PKT_TOSERVER;
p1->flowflags |= FLOW_PKT_ESTABLISHED;
p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 "
"(flow:to_server; "
"content:\"Dummy\"; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: \n");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
if (!(PacketAlertCheck(p1, 1))) {
printf("sid 1 didn't match but should have: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p1, 1);
return result;
}
/**
* \test Trailing headers.
*/
static int DetectEngineHttpRawHeaderTest32(void)
{
TcpSession ssn;
Packet *p1 = NULL;
Packet *p2 = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http1_buf[] =
"GET /index.html HTTP/1.0\r\n"
"host: boom\r\n"
"Transfer-Encoding: chunked\r\n"
"\r\n"
"13\r\n"
"This is dummy body1\r\n"
"0\r\n";
uint8_t http2_buf[] =
"Dummy-Header: kaboom\r\n"
"\r\n";
uint32_t http1_len = sizeof(http1_buf) - 1;
uint32_t http2_len = sizeof(http2_buf) - 1;
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 "
"(flow:to_server; "
"content:\"Dummy\"; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: \n");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
if (PacketAlertCheck(p1, 1)) {
printf("sid 1 matched but shouldn't have\n");
goto end;
}
FLOWLOCK_WRLOCK(&f);
r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: \n", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
if (!PacketAlertCheck(p2, 1)) {
printf("sid 1 didn't match but should have\n");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p1, 1);
UTHFreePackets(&p2, 1);
return result;
}
/**
* \test Test that a signature containting a http_header is correctly parsed
* and the keyword is registered.
*/
static int DetectHttpRawHeaderTest01(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
SigMatch *sm = NULL;
de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing http_header\"; flow:to_server; "
"content:\"one\"; http_raw_header; sid:1;)");
if (de_ctx->sig_list != NULL) {
result = 1;
} else {
printf("Error parsing signature: ");
goto end;
}
sm = de_ctx->sig_list->sm_lists[g_http_raw_header_buffer_id];
if (sm != NULL) {
result &= (sm->type == DETECT_CONTENT);
result &= (sm->next == NULL);
} else {
result = 0;
printf("Error updating content pattern to http_header pattern: ");
}
end:
DetectEngineCtxFree(de_ctx);
return result;
}
/**
* \test Test that a signature containing an valid http_header entry is
* parsed.
*/
static int DetectHttpRawHeaderTest02(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing http_header\"; flow:to_server; "
"content:\"one\"; http_raw_header:; sid:1;)");
if (de_ctx->sig_list != NULL)
result = 1;
else
printf("Error parsing signature: ");
end:
DetectEngineCtxFree(de_ctx);
return result;
}
/**
* \test Test that an invalid signature containing no content but a http_header
* is invalidated.
*/
static int DetectHttpRawHeaderTest03(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing http_header\"; flow:to_server; "
"http_raw_header; sid:1;)");
if (de_ctx->sig_list == NULL)
result = 1;
else
printf("Error parsing signature: ");
end:
DetectEngineCtxFree(de_ctx);
return result;
}
/**
* \test Test that an invalid signature containing a rawbytes along with a
* http_header is invalidated.
*/
static int DetectHttpRawHeaderTest04(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing http_header\"; flow:to_server; "
"content:\"one\"; rawbytes; http_raw_header; sid:1;)");
if (de_ctx->sig_list == NULL)
result = 1;
else
printf("Error parsing signature: ");
end:
DetectEngineCtxFree(de_ctx);
return result;
}
/**
* \test Test that an invalid signature containing a rawbytes along with a
* http_header is invalidated.
*/
static int DetectHttpRawHeaderTest05(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
"(msg:\"Testing http_header\"; flow:to_server; "
"content:\"one\"; nocase; http_raw_header; sid:1;)");
if (de_ctx->sig_list != NULL)
result = 1;
else
printf("Error parsing signature: ");
end:
DetectEngineCtxFree(de_ctx);
return result;
}
/**
*\test Test that the http_header content matches against a http request
* which holds the content.
*/
static int DetectHttpRawHeaderTest06(void)
{
TcpSession ssn;
Packet *p = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: www.openinfosecfoundation.org\r\n"
"User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
"Content-Type: text/html\r\n"
"Content-Length: 26\r\n"
"\r\n"
"This is dummy message body\r\n";
uint32_t http_len = sizeof(http_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 header test\"; flow:to_server; "
"content:\"Content-Type: text/html\"; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: ");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (!(PacketAlertCheck(p, 1))) {
printf("sid 1 didn't match but should have: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p, 1);
return result;
}
/**
*\test Test that the http_header content matches against a http request
* which holds the content.
*/
static int DetectHttpRawHeaderTest07(void)
{
TcpSession ssn;
Packet *p1 = NULL;
Packet *p2 = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http1_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: www.openinfosecfoundation.org\r\n"
"User-Agent: Mozi";
uint8_t http2_buf[] =
"lla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\nContent-Type: text/html\r\n"
"Content-Length: 67\r\n"
"\r\n"
"This is dummy message body1";
uint32_t http1_len = sizeof(http1_buf) - 1;
uint32_t http2_len = sizeof(http2_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p1->flow = &f;
p1->flowflags |= FLOW_PKT_TOSERVER;
p1->flowflags |= FLOW_PKT_ESTABLISHED;
p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
p2->flow = &f;
p2->flowflags |= FLOW_PKT_TOSERVER;
p2->flowflags |= FLOW_PKT_ESTABLISHED;
p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 header test\"; flow:to_server; "
"content:\"Mozilla\"; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: ");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
if ( (PacketAlertCheck(p1, 1))) {
printf("sid 1 matched but shouldn't have: ");
goto end;
}
FLOWLOCK_WRLOCK(&f);
r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
if (!(PacketAlertCheck(p2, 1))) {
printf("sid 1 didn't match but should have: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p1, 1);
UTHFreePackets(&p2, 1);
return result;
}
/**
*\test Test that the http_header content matches against a http request
* which holds the content.
*/
static int DetectHttpRawHeaderTest08(void)
{
TcpSession ssn;
Packet *p1 = NULL;
Packet *p2 = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http1_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: www.openinfosecfoundation.org\r\n";
uint8_t http2_buf[] =
"User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
"Content-Type: text/html\r\n"
"Content-Length: 67\r\n"
"\r\n";
uint32_t http1_len = sizeof(http1_buf) - 1;
uint32_t http2_len = sizeof(http2_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p1->flow = &f;
p1->flowflags |= FLOW_PKT_TOSERVER;
p1->flowflags |= FLOW_PKT_ESTABLISHED;
p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
p2->flow = &f;
p2->flowflags |= FLOW_PKT_TOSERVER;
p2->flowflags |= FLOW_PKT_ESTABLISHED;
p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 header test\"; flow:to_server; "
"content:\"Gecko/20091221 Firefox/3.5.7\"; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: ");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
if ((PacketAlertCheck(p1, 1))) {
printf("sid 1 didn't match but should have: ");
goto end;
}
FLOWLOCK_WRLOCK(&f);
r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
if (!(PacketAlertCheck(p2, 1))) {
printf("sid 1 didn't match but should have: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p1, 1);
UTHFreePackets(&p2, 1);
return result;
}
/**
*\test Test that the http_header content matches against a http request
* which holds the content, against a cross boundary present pattern.
*/
static int DetectHttpRawHeaderTest09(void)
{
TcpSession ssn;
Packet *p1 = NULL;
Packet *p2 = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http1_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: www.openinfosecfoundation.org\r\n"
"User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n";
uint8_t http2_buf[] =
"Content-Type: text/html\r\n"
"Content-Length: 67\r\n"
"\r\n"
"This is dummy body\r\n";
uint32_t http1_len = sizeof(http1_buf) - 1;
uint32_t http2_len = sizeof(http2_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p1->flow = &f;
p1->flowflags |= FLOW_PKT_TOSERVER;
p1->flowflags |= FLOW_PKT_ESTABLISHED;
p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
p2->flow = &f;
p2->flowflags |= FLOW_PKT_TOSERVER;
p2->flowflags |= FLOW_PKT_ESTABLISHED;
p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 header test\"; flow:to_server; "
"content:\"Firefox/3.5.7|0D 0A|Content\"; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: ");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
if ((PacketAlertCheck(p1, 1))) {
printf("sid 1 didn't match but should have: ");
goto end;
}
FLOWLOCK_WRLOCK(&f);
r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
if (!(PacketAlertCheck(p2, 1))) {
printf("sid 1 didn't match but should have: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p1, 1);
UTHFreePackets(&p2, 1);
return result;
}
/**
*\test Test that the http_header content matches against a http request
* against a case insensitive pattern.
*/
static int DetectHttpRawHeaderTest10(void)
{
TcpSession ssn;
Packet *p1 = NULL;
Packet *p2 = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http1_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: www.openinfosecfoundation.org\r\n"
"User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n";
uint8_t http2_buf[] =
"Content-Type: text/html\r\n"
"Content-Length: 67\r\n"
"\r\n"
"This is dummy body";
uint32_t http1_len = sizeof(http1_buf) - 1;
uint32_t http2_len = sizeof(http2_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p1 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
p2 = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p1->flow = &f;
p1->flowflags |= FLOW_PKT_TOSERVER;
p1->flowflags |= FLOW_PKT_ESTABLISHED;
p1->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
p2->flow = &f;
p2->flowflags |= FLOW_PKT_TOSERVER;
p2->flowflags |= FLOW_PKT_ESTABLISHED;
p2->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 header test\"; flow:to_server; "
"content:\"firefox/3.5.7|0D 0A|content\"; nocase; http_raw_header;"
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http1_buf, http1_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: ");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
if ((PacketAlertCheck(p1, 1))) {
printf("sid 1 didn't match but should have: ");
goto end;
}
FLOWLOCK_WRLOCK(&f);
r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http2_buf, http2_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p2);
if (!(PacketAlertCheck(p2, 1))) {
printf("sid 1 didn't match but should have: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p1, 1);
UTHFreePackets(&p2, 1);
return result;
}
/**
*\test Test that the negated http_header content matches against a
* http request which doesn't hold the content.
*/
static int DetectHttpRawHeaderTest11(void)
{
TcpSession ssn;
Packet *p = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: www.openinfosecfoundation.org\r\n"
"User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
"Content-Type: text/html\r\n"
"Content-Length: 26\r\n"
"\r\n"
"This is dummy message body\r\n";
uint32_t http_len = sizeof(http_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 header test\"; flow:to_server; "
"content:!\"lalalalala\"; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: ");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (!(PacketAlertCheck(p, 1))) {
printf("sid 1 didn't match but should have: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p, 1);
return result;
}
/**
*\test Negative test that the negated http_header content matches against a
* http request which holds hold the content.
*/
static int DetectHttpRawHeaderTest12(void)
{
TcpSession ssn;
Packet *p = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: www.openinfosecfoundation.org\r\n"
"User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
"Content-Type: text/html\r\n"
"Content-Length: 26\r\n"
"\r\n"
"This is dummy message body\r\n";
uint32_t http_len = sizeof(http_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 header test\"; flow:to_server; "
"content:!\"User-Agent: Mozilla/5.0 \"; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: ");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if ((PacketAlertCheck(p, 1))) {
printf("sid 1 didn't match but should have: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p, 1);
return result;
}
/**
*\test Test that the http_header content matches against a http request
* which holds the content.
*/
static int DetectHttpRawHeaderTest13(void)
{
TcpSession ssn;
Packet *p = NULL;
ThreadVars th_v;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
Flow f;
uint8_t http_buf[] =
"GET /index.html HTTP/1.0\r\n"
"Host: www.openinfosecfoundation.org\r\n"
"User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7\r\n"
"Content-Type: text/html\r\n"
"Content-Length: 100\r\n"
"\r\n"
"longbufferabcdefghijklmnopqrstuvwxyz0123456789bufferend\r\n";
uint32_t http_len = sizeof(http_buf) - 1;
int result = 0;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_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 header test\"; flow:to_server; "
"content:\"Host: www.openinfosecfoundation.org\"; http_raw_header; "
"sid:1;)");
if (de_ctx->sig_list == NULL)
goto end;
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(
NULL, alp_tctx, &f, ALPROTO_HTTP1, STREAM_TOSERVER, http_buf, http_len);
if (r != 0) {
printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
result = 0;
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
printf("no http state: ");
result = 0;
goto end;
}
/* do detect */
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (!(PacketAlertCheck(p, 1))) {
printf("sid 1 didn't match but should have: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(true);
FLOW_DESTROY(&f);
UTHFreePackets(&p, 1);
return result;
}
static int DetectHttpRawHeaderTest20(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any "
"(flow:to_server; content:\"one\"; http_raw_header; "
"content:\"two\"; distance:0; http_raw_header; sid:1;)");
if (de_ctx->sig_list == NULL) {
printf("de_ctx->sig_list == NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists[g_http_raw_header_buffer_id] == NULL) {
printf("de_ctx->sig_list->sm_lists[g_http_raw_header_buffer_id] == NULL\n");
goto end;
}
DetectContentData *hrhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev->ctx;
DetectContentData *hrhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->ctx;
if (hrhd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
memcmp(hrhd1->content, "one", hrhd1->content_len) != 0 ||
hrhd2->flags != DETECT_CONTENT_DISTANCE ||
memcmp(hrhd2->content, "two", hrhd1->content_len) != 0) {
goto end;
}
result = 1;
end:
SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
return result;
}
static int DetectHttpRawHeaderTest21(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any "
"(flow:to_server; content:\"one\"; http_raw_header; "
"content:\"two\"; within:5; http_raw_header; sid:1;)");
if (de_ctx->sig_list == NULL) {
printf("de_ctx->sig_list == NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists[g_http_raw_header_buffer_id] == NULL) {
printf("de_ctx->sig_list->sm_lists[g_http_raw_header_buffer_id] == NULL\n");
goto end;
}
DetectContentData *hrhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev->ctx;
DetectContentData *hrhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->ctx;
if (hrhd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
memcmp(hrhd1->content, "one", hrhd1->content_len) != 0 ||
hrhd2->flags != DETECT_CONTENT_WITHIN ||
memcmp(hrhd2->content, "two", hrhd1->content_len) != 0) {
goto end;
}
result = 1;
end:
SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
return result;
}
static int DetectHttpRawHeaderTest22(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any "
"(flow:to_server; content:\"one\"; within:5; http_raw_header; sid:1;)");
if (de_ctx->sig_list == NULL) {
printf("de_ctx->sig_list == NULL\n");
goto end;
}
result = 1;
end:
SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
return result;
}
static int DetectHttpRawHeaderTest23(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any "
"(flow:to_server; content:\"one\"; http_raw_header; within:5; sid:1;)");
if (de_ctx->sig_list == NULL) {
printf("de_ctx->sig_list == NULL\n");
goto end;
}
result = 1;
end:
SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
return result;
}
static int DetectHttpRawHeaderTest24(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any "
"(flow:to_server; content:\"one\"; within:5; sid:1;)");
if (de_ctx->sig_list == NULL) {
printf("de_ctx->sig_list == NULL\n");
goto end;
}
result = 1;
end:
SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
return result;
}
static int DetectHttpRawHeaderTest25(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any "
"(flow:to_server; pcre:/one/D; "
"content:\"two\"; within:5; http_raw_header; sid:1;)");
if (de_ctx->sig_list == NULL) {
printf("de_ctx->sig_list == NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists[g_http_raw_header_buffer_id] == NULL) {
printf("de_ctx->sig_list->sm_lists[g_http_raw_header_buffer_id] == NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id] == NULL ||
de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->type != DETECT_CONTENT ||
de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev == NULL ||
de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev->type != DETECT_PCRE) {
goto end;
}
DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev->ctx;
DetectContentData *hhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->ctx;
if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
hhd2->flags != DETECT_CONTENT_WITHIN ||
memcmp(hhd2->content, "two", hhd2->content_len) != 0) {
goto end;
}
result = 1;
end:
SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
return result;
}
static int DetectHttpRawHeaderTest26(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any "
"(flow:to_server; content:\"two\"; http_raw_header; "
"pcre:/one/DR; sid:1;)");
if (de_ctx->sig_list == NULL) {
printf("de_ctx->sig_list == NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists[g_http_raw_header_buffer_id] == NULL) {
printf("de_ctx->sig_list->sm_lists[g_http_raw_header_buffer_id] == NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id] == NULL ||
de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->type != DETECT_PCRE ||
de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev == NULL ||
de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev->type != DETECT_CONTENT) {
goto end;
}
DetectContentData *hhd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev->ctx;
DetectPcreData *pd2 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->ctx;
if (pd2->flags != (DETECT_PCRE_RELATIVE) ||
hhd1->flags != DETECT_CONTENT_RELATIVE_NEXT ||
memcmp(hhd1->content, "two", hhd1->content_len) != 0) {
goto end;
}
result = 1;
end:
SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
return result;
}
static int DetectHttpRawHeaderTest27(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert http any any -> any any "
"(flow:to_server; pcre:/one/D; "
"content:\"two\"; distance:5; http_raw_header; sid:1;)");
if (de_ctx->sig_list == NULL) {
printf("de_ctx->sig_list == NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL) {
printf("de_ctx->sig_list->sm_lists[DETECT_SM_LIST_PMATCH] != NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists[g_http_raw_header_buffer_id] == NULL) {
printf("de_ctx->sig_list->sm_lists[g_http_raw_header_buffer_id] == NULL\n");
goto end;
}
if (de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id] == NULL ||
de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->type != DETECT_CONTENT ||
de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev == NULL ||
de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev->type != DETECT_PCRE) {
goto end;
}
DetectPcreData *pd1 = (DetectPcreData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->prev->ctx;
DetectContentData *hhd2 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_raw_header_buffer_id]->ctx;
if (pd1->flags != (DETECT_PCRE_RELATIVE_NEXT) ||
hhd2->flags != DETECT_CONTENT_DISTANCE ||
memcmp(hhd2->content, "two", hhd2->content_len) != 0) {
goto end;
}
result = 1;
end:
SigCleanSignatures(de_ctx);
DetectEngineCtxFree(de_ctx);
return result;
}
static int DetectHttpRawHeaderIsdataatParseTest(void)
{
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
FAIL_IF_NULL(de_ctx);
de_ctx->flags |= DE_QUIET;
Signature *s = DetectEngineAppendSig(de_ctx,
"alert tcp any any -> any any ("
"flow:to_server; "
"content:\"one\"; http_raw_header; "
"isdataat:!4,relative; sid:1;)");
FAIL_IF_NULL(s);
SigMatch *sm = s->init_data->smlists_tail[g_http_raw_header_buffer_id];
FAIL_IF_NULL(sm);
FAIL_IF_NOT(sm->type == DETECT_ISDATAAT);
DetectIsdataatData *data = (DetectIsdataatData *)sm->ctx;
FAIL_IF_NOT(data->flags & ISDATAAT_RELATIVE);
FAIL_IF_NOT(data->flags & ISDATAAT_NEGATED);
FAIL_IF(data->flags & ISDATAAT_RAWBYTES);
DetectEngineCtxFree(de_ctx);
PASS;
}
void DetectHttpRawHeaderRegisterTests(void)
{
UtRegisterTest("DetectHttpRawHeaderParserTest01",
DetectHttpRawHeaderParserTest01);
UtRegisterTest("DetectHttpRawHeaderParserTest02",
DetectHttpRawHeaderParserTest02);
UtRegisterTest("DetectEngineHttpRawHeaderTest01",
DetectEngineHttpRawHeaderTest01);
UtRegisterTest("DetectEngineHttpRawHeaderTest02",
DetectEngineHttpRawHeaderTest02);
UtRegisterTest("DetectEngineHttpRawHeaderTest03",
DetectEngineHttpRawHeaderTest03);
UtRegisterTest("DetectEngineHttpRawHeaderTest04",
DetectEngineHttpRawHeaderTest04);
UtRegisterTest("DetectEngineHttpRawHeaderTest05",
DetectEngineHttpRawHeaderTest05);
UtRegisterTest("DetectEngineHttpRawHeaderTest06",
DetectEngineHttpRawHeaderTest06);
UtRegisterTest("DetectEngineHttpRawHeaderTest07",
DetectEngineHttpRawHeaderTest07);
UtRegisterTest("DetectEngineHttpRawHeaderTest08",
DetectEngineHttpRawHeaderTest08);
UtRegisterTest("DetectEngineHttpRawHeaderTest09",
DetectEngineHttpRawHeaderTest09);
UtRegisterTest("DetectEngineHttpRawHeaderTest10",
DetectEngineHttpRawHeaderTest10);
UtRegisterTest("DetectEngineHttpRawHeaderTest11",
DetectEngineHttpRawHeaderTest11);
UtRegisterTest("DetectEngineHttpRawHeaderTest12",
DetectEngineHttpRawHeaderTest12);
UtRegisterTest("DetectEngineHttpRawHeaderTest13",
DetectEngineHttpRawHeaderTest13);
UtRegisterTest("DetectEngineHttpRawHeaderTest14",
DetectEngineHttpRawHeaderTest14);
UtRegisterTest("DetectEngineHttpRawHeaderTest15",
DetectEngineHttpRawHeaderTest15);
UtRegisterTest("DetectEngineHttpRawHeaderTest16",
DetectEngineHttpRawHeaderTest16);
UtRegisterTest("DetectEngineHttpRawHeaderTest17",
DetectEngineHttpRawHeaderTest17);
UtRegisterTest("DetectEngineHttpRawHeaderTest20",
DetectEngineHttpRawHeaderTest20);
UtRegisterTest("DetectEngineHttpRawHeaderTest21",
DetectEngineHttpRawHeaderTest21);
UtRegisterTest("DetectEngineHttpRawHeaderTest22",
DetectEngineHttpRawHeaderTest22);
UtRegisterTest("DetectEngineHttpRawHeaderTest23",
DetectEngineHttpRawHeaderTest23);
UtRegisterTest("DetectEngineHttpRawHeaderTest24",
DetectEngineHttpRawHeaderTest24);
UtRegisterTest("DetectEngineHttpRawHeaderTest25",
DetectEngineHttpRawHeaderTest25);
UtRegisterTest("DetectEngineHttpRawHeaderTest26",
DetectEngineHttpRawHeaderTest26);
UtRegisterTest("DetectEngineHttpRawHeaderTest27",
DetectEngineHttpRawHeaderTest27);
UtRegisterTest("DetectEngineHttpRawHeaderTest28",
DetectEngineHttpRawHeaderTest28);
UtRegisterTest("DetectEngineHttpRawHeaderTest29",
DetectEngineHttpRawHeaderTest29);
#if 0
UtRegisterTest("DetectEngineHttpRawHeaderTest30",
DetectEngineHttpRawHeaderTest30, 1);
#endif
UtRegisterTest("DetectEngineHttpRawHeaderTest31",
DetectEngineHttpRawHeaderTest31);
UtRegisterTest("DetectEngineHttpRawHeaderTest32",
DetectEngineHttpRawHeaderTest32);
UtRegisterTest("DetectHttpRawHeaderTest01", DetectHttpRawHeaderTest01);
UtRegisterTest("DetectHttpRawHeaderTest02", DetectHttpRawHeaderTest02);
UtRegisterTest("DetectHttpRawHeaderTest03", DetectHttpRawHeaderTest03);
UtRegisterTest("DetectHttpRawHeaderTest04", DetectHttpRawHeaderTest04);
UtRegisterTest("DetectHttpRawHeaderTest05", DetectHttpRawHeaderTest05);
UtRegisterTest("DetectHttpRawHeaderTest06", DetectHttpRawHeaderTest06);
UtRegisterTest("DetectHttpRawHeaderTest07", DetectHttpRawHeaderTest07);
UtRegisterTest("DetectHttpRawHeaderTest08", DetectHttpRawHeaderTest08);
UtRegisterTest("DetectHttpRawHeaderTest09", DetectHttpRawHeaderTest09);
UtRegisterTest("DetectHttpRawHeaderTest10", DetectHttpRawHeaderTest10);
UtRegisterTest("DetectHttpRawHeaderTest11", DetectHttpRawHeaderTest11);
UtRegisterTest("DetectHttpRawHeaderTest12", DetectHttpRawHeaderTest12);
UtRegisterTest("DetectHttpRawHeaderTest13", DetectHttpRawHeaderTest13);
UtRegisterTest("DetectHttpRawHeaderTest20", DetectHttpRawHeaderTest20);
UtRegisterTest("DetectHttpRawHeaderTest21", DetectHttpRawHeaderTest21);
UtRegisterTest("DetectHttpRawHeaderTest22", DetectHttpRawHeaderTest22);
UtRegisterTest("DetectHttpRawHeaderTest23", DetectHttpRawHeaderTest23);
UtRegisterTest("DetectHttpRawHeaderTest24", DetectHttpRawHeaderTest24);
UtRegisterTest("DetectHttpRawHeaderTest25", DetectHttpRawHeaderTest25);
UtRegisterTest("DetectHttpRawHeaderTest26", DetectHttpRawHeaderTest26);
UtRegisterTest("DetectHttpRawHeaderTest27", DetectHttpRawHeaderTest27);
UtRegisterTest("DetectHttpRawHeaderIsdataatParseTest",
DetectHttpRawHeaderIsdataatParseTest);
return;
}
#endif /* UNITTESTS */
/**
* @}
*/