detect/http_method: move all tests into tests/

pull/3632/head
Victor Julien 6 years ago
parent d00732175a
commit cb332b4cda

@ -134,7 +134,6 @@ detect-engine-filedata.c detect-engine-filedata.h \
detect-engine-hcbd.c detect-engine-hcbd.h \
detect-engine-hcd.c detect-engine-hcd.h \
detect-engine-hhhd.c detect-engine-hhhd.h \
detect-engine-hmd.c detect-engine-hmd.h \
detect-engine-hrhd.c detect-engine-hrhd.h \
detect-engine-hrhhd.c detect-engine-hrhhd.h \
detect-engine-hsbd.c detect-engine-hsbd.h \

@ -34,7 +34,6 @@
#include "detect-engine-hcbd.h"
#include "detect-engine-hrhd.h"
#include "detect-engine-hmd.h"
#include "detect-engine-hcd.h"
#include "detect-engine-dcepayload.h"
#include "detect-engine-file.h"

@ -1,38 +0,0 @@
/* Copyright (C) 2007-2010 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/** \file
*
* \author Anoop Saldanha <anoopsaldanha@gmail.com>
*/
#ifndef __DETECT_ENGINE_HMD_H__
#define __DETECT_ENGINE_HMD_H__
#include "app-layer-htp.h"
int DetectEngineInspectHttpMethod(ThreadVars *tv,
DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
const Signature *s, const SigMatchData *smd,
Flow *f, uint8_t flags, void *alstate, void *tx, uint64_t tx_id);
int PrefilterTxMethodRegister(DetectEngineCtx *de_ctx,
SigGroupHead *sgh, MpmCtx *mpm_ctx);
void DetectEngineHttpMethodRegisterTests(void);
#endif /* __DETECT_ENGINE_HMD_H__ */

@ -50,7 +50,6 @@
#include "detect-content.h"
#include "detect-engine-payload.h"
#include "detect-engine-hmd.h"
#include "detect-engine-hrhd.h"
#include "detect-engine-hcd.h"
#include "detect-engine-hhhd.h"

@ -157,7 +157,6 @@
#include "detect-engine-hcbd.h"
#include "detect-engine-hsbd.h"
#include "detect-engine-hrhd.h"
#include "detect-engine-hmd.h"
#include "detect-engine-hcd.h"
#include "detect-engine-hsmd.h"
#include "detect-engine-hscd.h"

@ -57,12 +57,13 @@
#include "app-layer-htp.h"
#include "detect-http-method.h"
#include "detect-engine-hmd.h"
#include "stream-tcp.h"
static int g_http_method_buffer_id = 0;
static int DetectHttpMethodSetup(DetectEngineCtx *, Signature *, const char *);
#ifdef UNITTESTS
void DetectHttpMethodRegisterTests(void);
#endif
void DetectHttpMethodFree(void *);
static _Bool DetectHttpMethodValidateCallback(const Signature *s, const char **sigerror);
static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx,
@ -79,7 +80,9 @@ void DetectHttpMethodRegister(void)
sigmatch_table[DETECT_AL_HTTP_METHOD].url = DOC_URL DOC_VERSION "/rules/http-keywords.html#http-method";
sigmatch_table[DETECT_AL_HTTP_METHOD].Match = NULL;
sigmatch_table[DETECT_AL_HTTP_METHOD].Setup = DetectHttpMethodSetup;
#ifdef UNITTESTS
sigmatch_table[DETECT_AL_HTTP_METHOD].RegisterTests = DetectHttpMethodRegisterTests;
#endif
sigmatch_table[DETECT_AL_HTTP_METHOD].flags |= SIGMATCH_NOOPT;
DetectAppLayerInspectEngineRegister2("http_method", ALPROTO_HTTP,
@ -175,726 +178,9 @@ static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx,
return buffer;
}
#ifdef UNITTESTS /* UNITTESTS */
#include "detect-isdataat.h"
#include "stream-tcp-reassemble.h"
/** \test Check a signature with content */
static int DetectHttpMethodTest01(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx,
"alert tcp any any -> any any "
"(msg:\"Testing http_method\"; "
"content:\"GET\"; "
"http_method; sid:1;)");
if (de_ctx->sig_list != NULL) {
result = 1;
} else {
printf("sig parse failed: ");
}
end:
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
return result;
}
/** \test Check a signature without content (fail) */
static int DetectHttpMethodTest02(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx,
"alert tcp any any -> any any "
"(msg:\"Testing http_method\"; "
"http_method; sid:1;)");
if (de_ctx->sig_list == NULL) {
result = 1;
}
end:
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
return result;
}
/** \test Check a signature with parameter (fail) */
static int DetectHttpMethodTest03(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx,
"alert tcp any any -> any any "
"(msg:\"Testing http_method\"; "
"content:\"foobar\"; "
"http_method:\"GET\"; sid:1;)");
if (de_ctx->sig_list == NULL) {
result = 1;
}
end:
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
return result;
}
/** \test Check a signature with fast_pattern (should work) */
static int DetectHttpMethodTest04(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx,
"alert tcp any any -> any any "
"(msg:\"Testing http_method\"; "
"content:\"GET\"; "
"fast_pattern; "
"http_method; sid:1;)");
if (de_ctx->sig_list != NULL) {
result = 1;
}
end:
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
return result;
}
/** \test Check a signature with rawbytes (fail) */
static int DetectHttpMethodTest05(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx,
"alert tcp any any -> any any "
"(msg:\"Testing http_method\"; "
"content:\"GET\"; "
"rawbytes; "
"http_method; sid:1;)");
if (de_ctx->sig_list == NULL) {
result = 1;
}
end:
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
return result;
}
/** \test setting the nocase flag */
static int DetectHttpMethodTest12(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
if (DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
"(content:\"one\"; http_method; nocase; sid:1;)") == NULL) {
printf("DetectEngineAppend == NULL: ");
goto end;
}
if (DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
"(content:\"one\"; nocase; http_method; sid:2;)") == NULL) {
printf("DetectEngineAppend == NULL: ");
goto end;
}
if (de_ctx->sig_list->sm_lists[g_http_method_buffer_id] == NULL) {
printf("de_ctx->sig_list->sm_lists[g_http_method_buffer_id] == NULL: ");
goto end;
}
DetectContentData *hmd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_method_buffer_id]->ctx;
DetectContentData *hmd2 = (DetectContentData *)de_ctx->sig_list->next->sm_lists_tail[g_http_method_buffer_id]->ctx;
if (!(hmd1->flags & DETECT_CONTENT_NOCASE)) {
printf("nocase flag not set on sig 1: ");
goto end;
}
if (!(hmd2->flags & DETECT_CONTENT_NOCASE)) {
printf("nocase flag not set on sig 2: ");
goto end;
}
result = 1;
end:
DetectEngineCtxFree(de_ctx);
return result;
}
/** \test Check a signature with method + within and pcre with /M (should work) */
static int DetectHttpMethodTest13(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx,
"alert tcp any any -> any any "
"(msg:\"Testing http_method\"; "
"pcre:\"/HE/M\"; "
"content:\"AD\"; "
"within:2; http_method; sid:1;)");
if (de_ctx->sig_list != NULL) {
result = 1;
}
end:
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
return result;
}
/** \test Check a signature with method + within and pcre without /M (should fail) */
static int DetectHttpMethodTest14(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx,
"alert tcp any any -> any any "
"(msg:\"Testing http_method\"; "
"pcre:\"/HE/\"; "
"content:\"AD\"; "
"http_method; within:2; sid:1;)");
if (de_ctx->sig_list != NULL) {
result = 1;
}
end:
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
return result;
}
/** \test Check a signature with method + within and pcre with /M (should work) */
static int DetectHttpMethodTest15(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx,
"alert tcp any any -> any any "
"(msg:\"Testing http_method\"; "
"pcre:\"/HE/M\"; "
"content:\"AD\"; "
"http_method; within:2; sid:1;)");
if (de_ctx->sig_list != NULL) {
result = 1;
}
end:
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
return result;
}
/** \test Check a signature with an known request method */
static int DetectHttpMethodSigTest01(void)
{
int result = 0;
Flow f;
uint8_t httpbuf1[] = "GET / HTTP/1.0\r\n"
"Host: foo.bar.tld\r\n"
"\r\n";
uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
TcpSession ssn;
Packet *p = NULL;
Signature *s = NULL;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx;
HtpState *http_state = NULL;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_HTTP;
StreamTcpInitConfig(TRUE);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->flags |= DE_QUIET;
s = de_ctx->sig_list = SigInit(de_ctx,
"alert tcp any any -> any any "
"(msg:\"Testing http_method\"; "
"content:\"GET\"; "
"http_method; sid:1;)");
if (s == NULL) {
goto end;
}
s = s->next = SigInit(de_ctx,
"alert tcp any any -> any any "
"(msg:\"Testing http_method\"; "
"content:\"POST\"; "
"http_method; sid:2;)");
if (s == NULL) {
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
STREAM_TOSERVER, httpbuf1, httplen1);
if (r != 0) {
SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
SCLogDebug("no http state: ");
goto end;
}
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (!(PacketAlertCheck(p, 1))) {
goto end;
}
if (PacketAlertCheck(p, 2)) {
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 Check a signature with an unknown request method */
static int DetectHttpMethodSigTest02(void)
{
int result = 0;
Flow f;
uint8_t httpbuf1[] = "FOO / HTTP/1.0\r\n"
"Host: foo.bar.tld\r\n"
"\r\n";
uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
TcpSession ssn;
Packet *p = NULL;
Signature *s = NULL;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_HTTP;
StreamTcpInitConfig(TRUE);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->flags |= DE_QUIET;
s = de_ctx->sig_list = SigInit(de_ctx,
"alert tcp any any -> any any "
"(msg:\"Testing http_method\"; "
"content:\"FOO\"; "
"http_method; sid:1;)");
if (s == NULL) {
goto end;
}
s = s->next = SigInit(de_ctx,
"alert tcp any any -> any any "
"(msg:\"Testing http_method\"; "
"content:\"BAR\"; "
"http_method; sid:2;)");
if (s == NULL) {
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
STREAM_TOSERVER, httpbuf1, httplen1);
if (r != 0) {
SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
SCLogDebug("no http state: ");
goto end;
}
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (!(PacketAlertCheck(p, 1))) {
goto end;
}
if (PacketAlertCheck(p, 2)) {
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (det_ctx != NULL)
DetectEngineThreadCtxDeinit(&th_v, (void *) det_ctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(TRUE);
FLOW_DESTROY(&f);
UTHFreePackets(&p, 1);
return result;
}
/** \test Check a signature against an unparsable request */
static int DetectHttpMethodSigTest03(void)
{
int result = 0;
Flow f;
uint8_t httpbuf1[] = " ";
uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
TcpSession ssn;
Packet *p = NULL;
Signature *s = NULL;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx;
HtpState *http_state = NULL;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_HTTP;
StreamTcpInitConfig(TRUE);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->flags |= DE_QUIET;
s = de_ctx->sig_list = SigInit(de_ctx,
"alert tcp any any -> any any "
"(msg:\"Testing http_method\"; "
"content:\"GET\"; "
"http_method; sid:1;)");
if (s == NULL) {
SCLogDebug("Bad signature");
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
STREAM_TOSERVER, httpbuf1, httplen1);
if (r != 0) {
SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
SCLogDebug("no http state: ");
goto end;
}
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (PacketAlertCheck(p, 1)) {
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 Check a signature with an request method and negation of the same */
static int DetectHttpMethodSigTest04(void)
{
int result = 0;
Flow f;
uint8_t httpbuf1[] = "GET / HTTP/1.0\r\n"
"Host: foo.bar.tld\r\n"
"\r\n";
uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
TcpSession ssn;
Packet *p = NULL;
Signature *s = NULL;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_HTTP;
StreamTcpInitConfig(TRUE);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->flags |= DE_QUIET;
s = de_ctx->sig_list = SigInit(de_ctx,
"alert tcp any any -> any any (msg:\"Testing http_method\"; "
"content:\"GET\"; http_method; sid:1;)");
if (s == NULL) {
goto end;
}
s = s->next = SigInit(de_ctx,
"alert tcp any any -> any any (msg:\"Testing http_method\"; "
"content:!\"GET\"; http_method; sid:2;)");
if (s == NULL) {
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
STREAM_TOSERVER, httpbuf1, httplen1);
if (r != 0) {
SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
SCLogDebug("no http state: ");
goto end;
}
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (!(PacketAlertCheck(p, 1))) {
printf("sid 1 didn't match but should have: ");
goto end;
}
if (PacketAlertCheck(p, 2)) {
printf("sid 2 matched but shouldn't have: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (det_ctx != NULL) {
DetectEngineThreadCtxDeinit(&th_v, (void *) det_ctx);
}
if (de_ctx != NULL) {
DetectEngineCtxFree(de_ctx);
}
StreamTcpFreeConfig(TRUE);
FLOW_DESTROY(&f);
UTHFreePackets(&p, 1);
return result;
}
static int DetectHttpMethodIsdataatParseTest(void)
{
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
FAIL_IF_NULL(de_ctx);
de_ctx->flags |= DE_QUIET;
Signature *s = DetectEngineAppendSig(de_ctx,
"alert tcp any any -> any any ("
"content:\"one\"; http_method; "
"isdataat:!4,relative; sid:1;)");
FAIL_IF_NULL(s);
SigMatch *sm = s->init_data->smlists_tail[g_http_method_buffer_id];
FAIL_IF_NULL(sm);
FAIL_IF_NOT(sm->type == DETECT_ISDATAAT);
DetectIsdataatData *data = (DetectIsdataatData *)sm->ctx;
FAIL_IF_NOT(data->flags & ISDATAAT_RELATIVE);
FAIL_IF_NOT(data->flags & ISDATAAT_NEGATED);
FAIL_IF(data->flags & ISDATAAT_RAWBYTES);
DetectEngineCtxFree(de_ctx);
PASS;
}
#endif /* UNITTESTS */
/**
* \brief this function registers unit tests for DetectHttpMethod
*/
void DetectHttpMethodRegisterTests(void)
{
#ifdef UNITTESTS /* UNITTESTS */
SCLogDebug("Registering tests for DetectHttpMethod...");
UtRegisterTest("DetectHttpMethodTest01", DetectHttpMethodTest01);
UtRegisterTest("DetectHttpMethodTest02", DetectHttpMethodTest02);
UtRegisterTest("DetectHttpMethodTest03", DetectHttpMethodTest03);
UtRegisterTest("DetectHttpMethodTest04", DetectHttpMethodTest04);
UtRegisterTest("DetectHttpMethodTest05", DetectHttpMethodTest05);
UtRegisterTest("DetectHttpMethodTest12 -- nocase flag",
DetectHttpMethodTest12);
UtRegisterTest("DetectHttpMethodTest13", DetectHttpMethodTest13);
UtRegisterTest("DetectHttpMethodTest14", DetectHttpMethodTest14);
UtRegisterTest("DetectHttpMethodTest15", DetectHttpMethodTest15);
UtRegisterTest("DetectHttpMethodSigTest01", DetectHttpMethodSigTest01);
UtRegisterTest("DetectHttpMethodSigTest02", DetectHttpMethodSigTest02);
UtRegisterTest("DetectHttpMethodSigTest03", DetectHttpMethodSigTest03);
UtRegisterTest("DetectHttpMethodSigTest04", DetectHttpMethodSigTest04);
UtRegisterTest("DetectHttpMethodIsdataatParseTest",
DetectHttpMethodIsdataatParseTest);
#endif /* UNITTESTS */
}
#ifdef UNITTESTS
#include "tests/detect-http-method.c"
#endif
/**
* @}

@ -39,7 +39,6 @@
#include "detect-engine-hcbd.h"
#include "detect-engine-hsbd.h"
#include "detect-engine-hrhd.h"
#include "detect-engine-hmd.h"
#include "detect-engine-hcd.h"
#include "detect-engine-hsmd.h"
#include "detect-engine-hscd.h"
@ -200,7 +199,6 @@ static void RegisterUnittests(void)
DetectEngineHttpClientBodyRegisterTests();
DetectEngineHttpServerBodyRegisterTests();
DetectEngineHttpRawHeaderRegisterTests();
DetectEngineHttpMethodRegisterTests();
DetectEngineHttpCookieRegisterTests();
DetectEngineHttpStatMsgRegisterTests();
DetectEngineHttpStatCodeRegisterTests();

@ -30,119 +30,18 @@
*
*/
#include "suricata-common.h"
#include "suricata.h"
#include "decode.h"
#include "detect.h"
#include "detect-engine.h"
#include "detect-engine-hmd.h"
#include "detect-engine-mpm.h"
#include "detect-parse.h"
#include "detect-engine-state.h"
#include "detect-engine-content-inspection.h"
#include "detect-engine-prefilter.h"
#include "flow-util.h"
#include "util-debug.h"
#include "util-print.h"
#include "flow.h"
#include "stream-tcp.h"
#include "app-layer-parser.h"
#include "util-unittest.h"
#include "util-unittest-helper.h"
#include "app-layer.h"
#include "app-layer-htp.h"
#include "app-layer-protos.h"
#include "util-validate.h"
/** \brief HTTP Method Mpm prefilter callback
*
* \param det_ctx detection engine thread ctx
* \param p packet to inspect
* \param f flow to inspect
* \param txv tx to inspect
* \param pectx inspection context
*
* \retval ret number of matches
*/
static void PrefilterTxMethod(DetectEngineThreadCtx *det_ctx,
const void *pectx,
Packet *p, Flow *f, void *txv,
const uint64_t idx, const uint8_t flags)
{
SCEnter();
const MpmCtx *mpm_ctx = (MpmCtx *)pectx;
htp_tx_t *tx = (htp_tx_t *)txv;
if (tx->request_method == NULL)
return;
const uint32_t buffer_len = bstr_len(tx->request_method);
const uint8_t *buffer = bstr_ptr(tx->request_method);
if (buffer_len >= mpm_ctx->minlen) {
(void)mpm_table[mpm_ctx->mpm_type].Search(mpm_ctx,
&det_ctx->mtcu, &det_ctx->pmq, buffer, buffer_len);
}
}
int PrefilterTxMethodRegister(DetectEngineCtx *de_ctx,
SigGroupHead *sgh, MpmCtx *mpm_ctx)
{
return PrefilterAppendTxEngine(de_ctx, sgh, PrefilterTxMethod,
ALPROTO_HTTP, HTP_REQUEST_LINE,
mpm_ctx, NULL, "http_method");
}
/**
* \brief Do the http_method content inspection for a signature.
*
* \param de_ctx Detection engine context.
* \param det_ctx Detection engine thread context.
* \param s Signature to inspect.
* \param f Flow.
* \param flags App layer flags.
* \param state App layer state.
*
* \retval 0 No match.
* \retval 1 Match.
*/
int DetectEngineInspectHttpMethod(ThreadVars *tv,
DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
const Signature *s, const SigMatchData *smd,
Flow *f, uint8_t flags, void *alstate, void *txv, uint64_t tx_id)
{
htp_tx_t *tx = (htp_tx_t *)txv;
if (tx->request_method == NULL) {
if (AppLayerParserGetStateProgress(IPPROTO_TCP, ALPROTO_HTTP, tx, flags) > HTP_REQUEST_LINE)
return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
else
return DETECT_ENGINE_INSPECT_SIG_NO_MATCH;
}
det_ctx->buffer_offset = 0;
det_ctx->discontinue_matching = 0;
det_ctx->inspection_recursion_counter = 0;
int r = DetectEngineContentInspection(de_ctx, det_ctx, s, smd,
f,
(uint8_t *)bstr_ptr(tx->request_method),
bstr_len(tx->request_method),
0, DETECT_CI_FLAGS_SINGLE,
DETECT_ENGINE_CONTENT_INSPECTION_MODE_STATE, NULL);
if (r == 1)
return DETECT_ENGINE_INSPECT_SIG_MATCH;
else
return DETECT_ENGINE_INSPECT_SIG_CANT_MATCH;
}
/***********************************Unittests**********************************/
#ifdef UNITTESTS
#include "../suricata-common.h"
#include "../suricata.h"
#include "../flow-util.h"
#include "../flow.h"
#include "../app-layer-parser.h"
#include "../util-unittest.h"
#include "../util-unittest-helper.h"
#include "../app-layer.h"
#include "../app-layer-htp.h"
#include "../app-layer-protos.h"
#include "../detect-isdataat.h"
/**
* \test Test that the http_method content matches against a http request
@ -1750,12 +1649,715 @@ end:
return result;
}
#endif /* UNITTESTS */
/** \test Check a signature with content */
static int DetectHttpMethodTest01(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx,
"alert tcp any any -> any any "
"(msg:\"Testing http_method\"; "
"content:\"GET\"; "
"http_method; sid:1;)");
if (de_ctx->sig_list != NULL) {
result = 1;
} else {
printf("sig parse failed: ");
}
end:
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
return result;
}
/** \test Check a signature without content (fail) */
static int DetectHttpMethodTest02(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx,
"alert tcp any any -> any any "
"(msg:\"Testing http_method\"; "
"http_method; sid:1;)");
if (de_ctx->sig_list == NULL) {
result = 1;
}
end:
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
return result;
}
/** \test Check a signature with parameter (fail) */
static int DetectHttpMethodTest03(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx,
"alert tcp any any -> any any "
"(msg:\"Testing http_method\"; "
"content:\"foobar\"; "
"http_method:\"GET\"; sid:1;)");
if (de_ctx->sig_list == NULL) {
result = 1;
}
end:
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
return result;
}
/** \test Check a signature with fast_pattern (should work) */
static int DetectHttpMethodTest04(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx,
"alert tcp any any -> any any "
"(msg:\"Testing http_method\"; "
"content:\"GET\"; "
"fast_pattern; "
"http_method; sid:1;)");
if (de_ctx->sig_list != NULL) {
result = 1;
}
end:
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
return result;
}
/** \test Check a signature with rawbytes (fail) */
static int DetectHttpMethodTest05(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx,
"alert tcp any any -> any any "
"(msg:\"Testing http_method\"; "
"content:\"GET\"; "
"rawbytes; "
"http_method; sid:1;)");
if (de_ctx->sig_list == NULL) {
result = 1;
}
end:
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
return result;
}
/** \test setting the nocase flag */
static int DetectHttpMethodTest12(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
if (DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
"(content:\"one\"; http_method; nocase; sid:1;)") == NULL) {
printf("DetectEngineAppend == NULL: ");
goto end;
}
if (DetectEngineAppendSig(de_ctx, "alert http any any -> any any "
"(content:\"one\"; nocase; http_method; sid:2;)") == NULL) {
printf("DetectEngineAppend == NULL: ");
goto end;
}
if (de_ctx->sig_list->sm_lists[g_http_method_buffer_id] == NULL) {
printf("de_ctx->sig_list->sm_lists[g_http_method_buffer_id] == NULL: ");
goto end;
}
DetectContentData *hmd1 = (DetectContentData *)de_ctx->sig_list->sm_lists_tail[g_http_method_buffer_id]->ctx;
DetectContentData *hmd2 = (DetectContentData *)de_ctx->sig_list->next->sm_lists_tail[g_http_method_buffer_id]->ctx;
if (!(hmd1->flags & DETECT_CONTENT_NOCASE)) {
printf("nocase flag not set on sig 1: ");
goto end;
}
if (!(hmd2->flags & DETECT_CONTENT_NOCASE)) {
printf("nocase flag not set on sig 2: ");
goto end;
}
result = 1;
end:
DetectEngineCtxFree(de_ctx);
return result;
}
/** \test Check a signature with method + within and pcre with /M (should work) */
static int DetectHttpMethodTest13(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx,
"alert tcp any any -> any any "
"(msg:\"Testing http_method\"; "
"pcre:\"/HE/M\"; "
"content:\"AD\"; "
"within:2; http_method; sid:1;)");
if (de_ctx->sig_list != NULL) {
result = 1;
}
end:
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
return result;
}
/** \test Check a signature with method + within and pcre without /M (should fail) */
static int DetectHttpMethodTest14(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx,
"alert tcp any any -> any any "
"(msg:\"Testing http_method\"; "
"pcre:\"/HE/\"; "
"content:\"AD\"; "
"http_method; within:2; sid:1;)");
if (de_ctx->sig_list != NULL) {
result = 1;
}
end:
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
return result;
}
/** \test Check a signature with method + within and pcre with /M (should work) */
static int DetectHttpMethodTest15(void)
{
DetectEngineCtx *de_ctx = NULL;
int result = 0;
if ( (de_ctx = DetectEngineCtxInit()) == NULL)
goto end;
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx,
"alert tcp any any -> any any "
"(msg:\"Testing http_method\"; "
"pcre:\"/HE/M\"; "
"content:\"AD\"; "
"http_method; within:2; sid:1;)");
if (de_ctx->sig_list != NULL) {
result = 1;
}
end:
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
return result;
}
/** \test Check a signature with an known request method */
static int DetectHttpMethodSigTest01(void)
{
int result = 0;
Flow f;
uint8_t httpbuf1[] = "GET / HTTP/1.0\r\n"
"Host: foo.bar.tld\r\n"
"\r\n";
uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
TcpSession ssn;
Packet *p = NULL;
Signature *s = NULL;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx;
HtpState *http_state = NULL;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_HTTP;
StreamTcpInitConfig(TRUE);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->flags |= DE_QUIET;
s = de_ctx->sig_list = SigInit(de_ctx,
"alert tcp any any -> any any "
"(msg:\"Testing http_method\"; "
"content:\"GET\"; "
"http_method; sid:1;)");
if (s == NULL) {
goto end;
}
s = s->next = SigInit(de_ctx,
"alert tcp any any -> any any "
"(msg:\"Testing http_method\"; "
"content:\"POST\"; "
"http_method; sid:2;)");
if (s == NULL) {
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
STREAM_TOSERVER, httpbuf1, httplen1);
if (r != 0) {
SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
SCLogDebug("no http state: ");
goto end;
}
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (!(PacketAlertCheck(p, 1))) {
goto end;
}
if (PacketAlertCheck(p, 2)) {
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 Check a signature with an unknown request method */
static int DetectHttpMethodSigTest02(void)
{
int result = 0;
Flow f;
uint8_t httpbuf1[] = "FOO / HTTP/1.0\r\n"
"Host: foo.bar.tld\r\n"
"\r\n";
uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
TcpSession ssn;
Packet *p = NULL;
Signature *s = NULL;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_HTTP;
StreamTcpInitConfig(TRUE);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->flags |= DE_QUIET;
s = de_ctx->sig_list = SigInit(de_ctx,
"alert tcp any any -> any any "
"(msg:\"Testing http_method\"; "
"content:\"FOO\"; "
"http_method; sid:1;)");
if (s == NULL) {
goto end;
}
s = s->next = SigInit(de_ctx,
"alert tcp any any -> any any "
"(msg:\"Testing http_method\"; "
"content:\"BAR\"; "
"http_method; sid:2;)");
if (s == NULL) {
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
STREAM_TOSERVER, httpbuf1, httplen1);
if (r != 0) {
SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
SCLogDebug("no http state: ");
goto end;
}
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (!(PacketAlertCheck(p, 1))) {
goto end;
}
if (PacketAlertCheck(p, 2)) {
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (det_ctx != NULL)
DetectEngineThreadCtxDeinit(&th_v, (void *) det_ctx);
if (de_ctx != NULL)
DetectEngineCtxFree(de_ctx);
StreamTcpFreeConfig(TRUE);
FLOW_DESTROY(&f);
UTHFreePackets(&p, 1);
return result;
}
/** \test Check a signature against an unparsable request */
static int DetectHttpMethodSigTest03(void)
{
int result = 0;
Flow f;
uint8_t httpbuf1[] = " ";
uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
TcpSession ssn;
Packet *p = NULL;
Signature *s = NULL;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx;
HtpState *http_state = NULL;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_HTTP;
StreamTcpInitConfig(TRUE);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->flags |= DE_QUIET;
void DetectEngineHttpMethodRegisterTests(void)
s = de_ctx->sig_list = SigInit(de_ctx,
"alert tcp any any -> any any "
"(msg:\"Testing http_method\"; "
"content:\"GET\"; "
"http_method; sid:1;)");
if (s == NULL) {
SCLogDebug("Bad signature");
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
STREAM_TOSERVER, httpbuf1, httplen1);
if (r != 0) {
SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
SCLogDebug("no http state: ");
goto end;
}
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (PacketAlertCheck(p, 1)) {
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 Check a signature with an request method and negation of the same */
static int DetectHttpMethodSigTest04(void)
{
int result = 0;
Flow f;
uint8_t httpbuf1[] = "GET / HTTP/1.0\r\n"
"Host: foo.bar.tld\r\n"
"\r\n";
uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */
TcpSession ssn;
Packet *p = NULL;
Signature *s = NULL;
ThreadVars th_v;
DetectEngineThreadCtx *det_ctx = NULL;
HtpState *http_state = NULL;
AppLayerParserThreadCtx *alp_tctx = AppLayerParserThreadCtxAlloc();
memset(&th_v, 0, sizeof(th_v));
memset(&f, 0, sizeof(f));
memset(&ssn, 0, sizeof(ssn));
p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
FLOW_INITIALIZE(&f);
f.protoctx = (void *)&ssn;
f.proto = IPPROTO_TCP;
f.flags |= FLOW_IPV4;
p->flow = &f;
p->flowflags |= FLOW_PKT_TOSERVER;
p->flowflags |= FLOW_PKT_ESTABLISHED;
p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
f.alproto = ALPROTO_HTTP;
StreamTcpInitConfig(TRUE);
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) {
goto end;
}
de_ctx->flags |= DE_QUIET;
#ifdef UNITTESTS
s = de_ctx->sig_list = SigInit(de_ctx,
"alert tcp any any -> any any (msg:\"Testing http_method\"; "
"content:\"GET\"; http_method; sid:1;)");
if (s == NULL) {
goto end;
}
s = s->next = SigInit(de_ctx,
"alert tcp any any -> any any (msg:\"Testing http_method\"; "
"content:!\"GET\"; http_method; sid:2;)");
if (s == NULL) {
goto end;
}
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
FLOWLOCK_WRLOCK(&f);
int r = AppLayerParserParse(NULL, alp_tctx, &f, ALPROTO_HTTP,
STREAM_TOSERVER, httpbuf1, httplen1);
if (r != 0) {
SCLogDebug("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
FLOWLOCK_UNLOCK(&f);
goto end;
}
FLOWLOCK_UNLOCK(&f);
http_state = f.alstate;
if (http_state == NULL) {
SCLogDebug("no http state: ");
goto end;
}
SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
if (!(PacketAlertCheck(p, 1))) {
printf("sid 1 didn't match but should have: ");
goto end;
}
if (PacketAlertCheck(p, 2)) {
printf("sid 2 matched but shouldn't have: ");
goto end;
}
result = 1;
end:
if (alp_tctx != NULL)
AppLayerParserThreadCtxFree(alp_tctx);
if (det_ctx != NULL) {
DetectEngineThreadCtxDeinit(&th_v, (void *) det_ctx);
}
if (de_ctx != NULL) {
DetectEngineCtxFree(de_ctx);
}
StreamTcpFreeConfig(TRUE);
FLOW_DESTROY(&f);
UTHFreePackets(&p, 1);
return result;
}
static int DetectHttpMethodIsdataatParseTest(void)
{
DetectEngineCtx *de_ctx = DetectEngineCtxInit();
FAIL_IF_NULL(de_ctx);
de_ctx->flags |= DE_QUIET;
Signature *s = DetectEngineAppendSig(de_ctx,
"alert tcp any any -> any any ("
"content:\"one\"; http_method; "
"isdataat:!4,relative; sid:1;)");
FAIL_IF_NULL(s);
SigMatch *sm = s->init_data->smlists_tail[g_http_method_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;
}
/**
* \brief this function registers unit tests for DetectHttpMethod
*/
void DetectHttpMethodRegisterTests(void)
{
UtRegisterTest("DetectHttpMethodTest01", DetectHttpMethodTest01);
UtRegisterTest("DetectHttpMethodTest02", DetectHttpMethodTest02);
UtRegisterTest("DetectHttpMethodTest03", DetectHttpMethodTest03);
UtRegisterTest("DetectHttpMethodTest04", DetectHttpMethodTest04);
UtRegisterTest("DetectHttpMethodTest05", DetectHttpMethodTest05);
UtRegisterTest("DetectHttpMethodTest12 -- nocase flag",
DetectHttpMethodTest12);
UtRegisterTest("DetectHttpMethodTest13", DetectHttpMethodTest13);
UtRegisterTest("DetectHttpMethodTest14", DetectHttpMethodTest14);
UtRegisterTest("DetectHttpMethodTest15", DetectHttpMethodTest15);
UtRegisterTest("DetectHttpMethodSigTest01", DetectHttpMethodSigTest01);
UtRegisterTest("DetectHttpMethodSigTest02", DetectHttpMethodSigTest02);
UtRegisterTest("DetectHttpMethodSigTest03", DetectHttpMethodSigTest03);
UtRegisterTest("DetectHttpMethodSigTest04", DetectHttpMethodSigTest04);
UtRegisterTest("DetectHttpMethodIsdataatParseTest",
DetectHttpMethodIsdataatParseTest);
UtRegisterTest("DetectEngineHttpMethodTest01",
DetectEngineHttpMethodTest01);
UtRegisterTest("DetectEngineHttpMethodTest02",
@ -1790,10 +2392,8 @@ void DetectEngineHttpMethodRegisterTests(void)
DetectEngineHttpMethodTest16);
UtRegisterTest("DetectEngineHttpMethodTest17",
DetectEngineHttpMethodTest17);
#endif /* UNITTESTS */
return;
}
/**
* @}
*/
Loading…
Cancel
Save