detect/app-layer-event: simplify parsing code

Simpler and fully local parsing code.

Remove unittests that relied on previous implementation. Code
is tested by SV tests.
pull/8587/head
Victor Julien 2 years ago
parent 0c8646959e
commit 1726bd643c

@ -1,4 +1,4 @@
/* Copyright (C) 2007-2022 Open Information Security Foundation
/* Copyright (C) 2007-2023 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
@ -54,19 +54,11 @@
typedef struct DetectAppLayerEventData_ {
AppProto alproto;
uint8_t event_id;
/* it's used to check if there are event set into the detect engine */
bool needs_detctx;
char *arg;
} DetectAppLayerEventData;
static int DetectAppLayerEventPktMatch(DetectEngineThreadCtx *det_ctx,
Packet *p, const Signature *s, const SigMatchCtx *ctx);
static int DetectAppLayerEventSetupP1(DetectEngineCtx *, Signature *, const char *);
#ifdef UNITTESTS
static void DetectAppLayerEventRegisterTests(void);
#endif
static int DetectAppLayerEventSetup(DetectEngineCtx *, Signature *, const char *);
static void DetectAppLayerEventFree(DetectEngineCtx *, void *);
static uint8_t DetectEngineAptEventInspect(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
const struct DetectEngineAppInspectionEngine_ *engine, const Signature *s, Flow *f,
@ -83,12 +75,8 @@ void DetectAppLayerEventRegister(void)
sigmatch_table[DETECT_AL_APP_LAYER_EVENT].url = "/rules/app-layer.html#app-layer-event";
sigmatch_table[DETECT_AL_APP_LAYER_EVENT].Match =
DetectAppLayerEventPktMatch;
sigmatch_table[DETECT_AL_APP_LAYER_EVENT].Setup = DetectAppLayerEventSetupP1;
sigmatch_table[DETECT_AL_APP_LAYER_EVENT].Setup = DetectAppLayerEventSetup;
sigmatch_table[DETECT_AL_APP_LAYER_EVENT].Free = DetectAppLayerEventFree;
#ifdef UNITTESTS
sigmatch_table[DETECT_AL_APP_LAYER_EVENT].RegisterTests =
DetectAppLayerEventRegisterTests;
#endif
DetectAppLayerInspectEngineRegister2("app-layer-events", ALPROTO_UNKNOWN, SIG_FLAG_TOSERVER, 0,
DetectEngineAptEventInspect, NULL);
@ -106,9 +94,9 @@ static uint8_t DetectEngineAptEventInspect(DetectEngineCtx *de_ctx, DetectEngine
const AppProto alproto = f->alproto;
AppLayerDecoderEvents *decoder_events =
AppLayerParserGetEventsByTx(f->proto, alproto, tx);
if (decoder_events == NULL)
if (decoder_events == NULL) {
goto end;
}
SigMatchData *smd = engine->smd;
while (1) {
DetectAppLayerEventData *aled = (DetectAppLayerEventData *)smd->ctx;
@ -185,73 +173,6 @@ static bool OutdatedEvent(const char *raw)
return false;
}
/** \retval int 0 ok
* \retval int -1 error
* \retval int -3 non-fatal error: sig will be rejected w/o raising error
*/
static int DetectAppLayerEventParseAppP2(DetectAppLayerEventData *data,
uint8_t *ipproto_bitarray,
AppLayerEventType *event_type)
{
int event_id = 0;
uint8_t ipproto;
char alproto_name[MAX_ALPROTO_NAME];
int r = 0;
if (OutdatedEvent(data->arg)) {
if (SigMatchStrictEnabled(DETECT_AL_APP_LAYER_EVENT)) {
SCLogError("app-layer-event keyword no longer supports event \"%s\"", data->arg);
return -1;
} else {
SCLogWarning("app-layer-event keyword no longer supports event \"%s\"", data->arg);
return -3;
}
}
const char *p_idx = strchr(data->arg, '.');
if (strlen(data->arg) > MAX_ALPROTO_NAME) {
SCLogError("app-layer-event keyword is too long or malformed");
return -1;
}
strlcpy(alproto_name, data->arg, p_idx - data->arg + 1);
if (ipproto_bitarray[IPPROTO_TCP / 8] & 1 << (IPPROTO_TCP % 8)) {
ipproto = IPPROTO_TCP;
} else if (ipproto_bitarray[IPPROTO_UDP / 8] & 1 << (IPPROTO_UDP % 8)) {
ipproto = IPPROTO_UDP;
} else {
SCLogError("protocol %s is disabled", alproto_name);
return -1;
}
if (!data->needs_detctx) {
r = AppLayerParserGetEventInfo(ipproto, data->alproto,
p_idx + 1, &event_id, event_type);
} else {
r = DetectEngineGetEventInfo(p_idx + 1, &event_id, event_type);
}
if (r < 0) {
if (SigMatchStrictEnabled(DETECT_AL_APP_LAYER_EVENT)) {
SCLogError("app-layer-event keyword's "
"protocol \"%s\" doesn't have event \"%s\" registered",
alproto_name, p_idx + 1);
return -1;
} else {
SCLogWarning("app-layer-event keyword's "
"protocol \"%s\" doesn't have event \"%s\" registered",
alproto_name, p_idx + 1);
return -3;
}
}
if (event_id > UINT8_MAX) {
SCLogWarning("app-layer-event keyword's id has invalid value");
return -4;
}
data->event_id = (uint8_t)event_id;
return 0;
}
static AppProto AppLayerEventGetProtoByName(char *alproto_name)
{
AppProto alproto = AppLayerGetProtoByName(alproto_name);
@ -262,96 +183,100 @@ static AppProto AppLayerEventGetProtoByName(char *alproto_name)
return alproto;
}
static DetectAppLayerEventData *DetectAppLayerEventParseAppP1(const char *arg)
static int DetectAppLayerEventSetup(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
{
/* period index */
char alproto_name[MAX_ALPROTO_NAME];
bool needs_detctx = false;
const char *p_idx = strchr(arg, '.');
if (strlen(arg) > MAX_ALPROTO_NAME) {
SCLogError("app-layer-event keyword is too long or malformed");
return NULL;
}
/* + 1 for trailing \0 */
strlcpy(alproto_name, arg, p_idx - arg + 1);
const AppProto alproto = AppLayerEventGetProtoByName(alproto_name);
if (alproto == ALPROTO_UNKNOWN) {
if (!strcmp(alproto_name, "file")) {
needs_detctx = true;
} else {
SCLogError("app-layer-event keyword "
"supplied with unknown protocol \"%s\"",
alproto_name);
return NULL;
}
}
DetectAppLayerEventData *aled = SCCalloc(1, sizeof(*aled));
if (unlikely(aled == NULL))
return NULL;
aled->alproto = alproto;
aled->arg = SCStrdup(arg);
if (aled->arg == NULL) {
SCFree(aled);
return NULL;
}
aled->needs_detctx = needs_detctx;
return aled;
}
static DetectAppLayerEventData *DetectAppLayerEventParse(const char *arg,
AppLayerEventType *event_type)
{
*event_type = 0;
if (arg == NULL) {
SCLogError("app-layer-event keyword supplied "
"with no arguments. This keyword needs an argument.");
return NULL;
return -1;
}
while (*arg != '\0' && isspace((unsigned char)*arg))
arg++;
AppLayerEventType event_type;
DetectAppLayerEventData *data = NULL;
if (strchr(arg, '.') == NULL) {
return DetectAppLayerEventParsePkt(arg, event_type);
data = DetectAppLayerEventParsePkt(arg, &event_type);
if (data == NULL)
return -1;
} else {
return DetectAppLayerEventParseAppP1(arg);
}
}
SCLogDebug("parsing %s", arg);
char alproto_name[MAX_ALPROTO_NAME];
bool needs_detctx = false;
static int DetectAppLayerEventSetupP2(DetectEngineCtx *de_ctx,
Signature *s,
SigMatch *sm)
{
AppLayerEventType event_type = 0;
const char *p_idx = strchr(arg, '.');
if (strlen(arg) > MAX_ALPROTO_NAME) {
SCLogError("app-layer-event keyword is too long or malformed");
return -1;
}
const char *event_name = p_idx + 1; // skip .
/* + 1 for trailing \0 */
strlcpy(alproto_name, arg, p_idx - arg + 1);
const AppProto alproto = AppLayerEventGetProtoByName(alproto_name);
if (alproto == ALPROTO_UNKNOWN) {
if (!strcmp(alproto_name, "file")) {
needs_detctx = true;
} else {
SCLogError("app-layer-event keyword "
"supplied with unknown protocol \"%s\"",
alproto_name);
return -1;
}
}
if (OutdatedEvent(arg)) {
if (SigMatchStrictEnabled(DETECT_AL_APP_LAYER_EVENT)) {
SCLogError("app-layer-event keyword no longer supports event \"%s\"", arg);
return -1;
} else {
SCLogWarning("app-layer-event keyword no longer supports event \"%s\"", arg);
return -3;
}
}
int ret = DetectAppLayerEventParseAppP2((DetectAppLayerEventData *)sm->ctx,
s->proto.proto, &event_type);
if (ret < 0) {
/* DetectAppLayerEventParseAppP2 prints errors */
uint8_t ipproto = 0;
if (s->proto.proto[IPPROTO_TCP / 8] & 1 << (IPPROTO_TCP % 8)) {
ipproto = IPPROTO_TCP;
} else if (s->proto.proto[IPPROTO_UDP / 8] & 1 << (IPPROTO_UDP % 8)) {
ipproto = IPPROTO_UDP;
} else {
SCLogError("protocol %s is disabled", alproto_name);
return -1;
}
/* sm has been removed from lists by DetectAppLayerEventPrepare */
SigMatchFree(de_ctx, sm);
return ret;
int r;
int event_id = 0;
if (!needs_detctx) {
r = AppLayerParserGetEventInfo(ipproto, alproto, event_name, &event_id, &event_type);
} else {
r = DetectEngineGetEventInfo(event_name, &event_id, &event_type);
}
if (r < 0) {
if (SigMatchStrictEnabled(DETECT_AL_APP_LAYER_EVENT)) {
SCLogError("app-layer-event keyword's "
"protocol \"%s\" doesn't have event \"%s\" registered",
alproto_name, event_name);
return -1;
} else {
SCLogWarning("app-layer-event keyword's "
"protocol \"%s\" doesn't have event \"%s\" registered",
alproto_name, event_name);
return -3;
}
}
if (event_id > UINT8_MAX) {
SCLogWarning("app-layer-event keyword's id has invalid value");
return -4;
}
data = SCCalloc(1, sizeof(*data));
if (unlikely(data == NULL))
return -1;
data->alproto = alproto;
data->event_id = (uint8_t)event_id;
}
SigMatchAppendSMToList(s, sm, g_applayer_events_list_id);
/* We should have set this flag already in SetupP1 */
s->flags |= SIG_FLAG_APPLAYER;
return 0;
}
static int DetectAppLayerEventSetupP1(DetectEngineCtx *de_ctx, Signature *s, const char *arg)
{
AppLayerEventType event_type;
DetectAppLayerEventData *data = DetectAppLayerEventParse(arg, &event_type);
if (data == NULL)
SCReturnInt(-1);
SCLogDebug("data->event_id %u", data->event_id);
SigMatch *sm = SigMatchAlloc();
if (sm == NULL)
@ -367,6 +292,7 @@ static int DetectAppLayerEventSetupP1(DetectEngineCtx *de_ctx, Signature *s, con
goto error;
SigMatchAppendSMToList(s, sm, g_applayer_events_list_id);
s->flags |= SIG_FLAG_APPLAYER;
}
return 0;
@ -384,488 +310,5 @@ error:
static void DetectAppLayerEventFree(DetectEngineCtx *de_ctx, void *ptr)
{
DetectAppLayerEventData *data = (DetectAppLayerEventData *)ptr;
if (data->arg != NULL)
SCFree(data->arg);
SCFree(ptr);
return;
}
int DetectAppLayerEventPrepare(DetectEngineCtx *de_ctx, Signature *s)
{
SigMatch *sm = s->init_data->smlists[g_applayer_events_list_id];
SigMatch *smn;
s->init_data->smlists[g_applayer_events_list_id] = NULL;
s->init_data->smlists_tail[g_applayer_events_list_id] = NULL;
while (sm != NULL) {
// save it for later use in loop
smn = sm->next;
/* these will be overwritten in SigMatchAppendSMToList
* called by DetectAppLayerEventSetupP2
*/
sm->next = sm->prev = NULL;
int ret = DetectAppLayerEventSetupP2(de_ctx, s, sm);
if (ret < 0) {
// current one was freed, let's free the next ones
sm = smn;
while(sm) {
smn = sm->next;
SigMatchFree(de_ctx, sm);
sm = smn;
}
return ret;
}
sm = smn;
}
return 0;
}
/**********************************Unittests***********************************/
#ifdef UNITTESTS /* UNITTESTS */
#include "stream-tcp-private.h"
#include "stream-tcp-reassemble.h"
#include "stream-tcp.h"
#include "detect-engine-alert.h"
#define APP_LAYER_EVENT_TEST_MAP_EVENT1 0
#define APP_LAYER_EVENT_TEST_MAP_EVENT2 1
#define APP_LAYER_EVENT_TEST_MAP_EVENT3 2
#define APP_LAYER_EVENT_TEST_MAP_EVENT4 3
#define APP_LAYER_EVENT_TEST_MAP_EVENT5 4
#define APP_LAYER_EVENT_TEST_MAP_EVENT6 5
SCEnumCharMap app_layer_event_test_map[ ] = {
{ "event1", APP_LAYER_EVENT_TEST_MAP_EVENT1 },
{ "event2", APP_LAYER_EVENT_TEST_MAP_EVENT2 },
{ "event3", APP_LAYER_EVENT_TEST_MAP_EVENT3 },
{ "event4", APP_LAYER_EVENT_TEST_MAP_EVENT4 },
{ "event5", APP_LAYER_EVENT_TEST_MAP_EVENT5 },
{ "event6", APP_LAYER_EVENT_TEST_MAP_EVENT6 },
};
static int DetectAppLayerEventTestGetEventInfo(const char *event_name,
int *event_id,
AppLayerEventType *event_type)
{
*event_id = SCMapEnumNameToValue(event_name, app_layer_event_test_map);
if (*event_id == -1) {
SCLogError("event \"%s\" not present in "
"app-layer-event's test enum map table.",
event_name);
/* this should be treated as fatal */
return -1;
}
*event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
return 0;
}
static int DetectAppLayerEventTest01(void)
{
AppLayerParserBackupParserTable();
AppLayerParserRegisterGetEventInfo(IPPROTO_TCP, ALPROTO_SMTP,
DetectAppLayerEventTestGetEventInfo);
AppLayerEventType event_type;
int result = 0;
uint8_t ipproto_bitarray[256 / 8];
memset(ipproto_bitarray, 0, sizeof(ipproto_bitarray));
ipproto_bitarray[IPPROTO_TCP / 8] |= 1 << (IPPROTO_TCP % 8);
DetectAppLayerEventData *aled = DetectAppLayerEventParse("smtp.event1",
&event_type);
if (aled == NULL)
goto end;
if (DetectAppLayerEventParseAppP2(aled, ipproto_bitarray, &event_type) < 0) {
printf("failure 1\n");
goto end;
}
if (aled->alproto != ALPROTO_SMTP ||
aled->event_id != APP_LAYER_EVENT_TEST_MAP_EVENT1) {
printf("test failure. Holding wrong state\n");
goto end;
}
result = 1;
end:
AppLayerParserRestoreParserTable();
if (aled != NULL)
DetectAppLayerEventFree(NULL, aled);
return result;
}
static int DetectAppLayerEventTest02(void)
{
AppLayerParserBackupParserTable();
AppLayerParserRegisterGetEventInfo(IPPROTO_TCP, ALPROTO_SMTP,
DetectAppLayerEventTestGetEventInfo);
AppLayerParserRegisterGetEventInfo(
IPPROTO_TCP, ALPROTO_HTTP1, DetectAppLayerEventTestGetEventInfo);
AppLayerParserRegisterGetEventInfo(IPPROTO_TCP, ALPROTO_SMB,
DetectAppLayerEventTestGetEventInfo);
AppLayerParserRegisterGetEventInfo(IPPROTO_TCP, ALPROTO_FTP,
DetectAppLayerEventTestGetEventInfo);
AppLayerEventType event_type;
uint8_t ipproto_bitarray[256 / 8];
memset(ipproto_bitarray, 0, sizeof(ipproto_bitarray));
ipproto_bitarray[IPPROTO_TCP / 8] |= 1 << (IPPROTO_TCP % 8);
DetectAppLayerEventData *aled = DetectAppLayerEventParse("smtp.event1",
&event_type);
FAIL_IF_NULL(aled);
FAIL_IF(DetectAppLayerEventParseAppP2(aled, ipproto_bitarray, &event_type) < 0);
FAIL_IF(aled->alproto != ALPROTO_SMTP);
FAIL_IF(aled->event_id != APP_LAYER_EVENT_TEST_MAP_EVENT1);
aled = DetectAppLayerEventParse("smtp.event4",
&event_type);
FAIL_IF_NULL(aled);
FAIL_IF(DetectAppLayerEventParseAppP2(aled, ipproto_bitarray, &event_type) < 0);
FAIL_IF(aled->alproto != ALPROTO_SMTP);
FAIL_IF(aled->event_id != APP_LAYER_EVENT_TEST_MAP_EVENT4);
aled = DetectAppLayerEventParse("http.event2",
&event_type);
FAIL_IF_NULL(aled);
FAIL_IF(DetectAppLayerEventParseAppP2(aled, ipproto_bitarray, &event_type) < 0);
FAIL_IF(aled->alproto != ALPROTO_HTTP1);
FAIL_IF(aled->event_id != APP_LAYER_EVENT_TEST_MAP_EVENT2);
aled = DetectAppLayerEventParse("smb.event3",
&event_type);
FAIL_IF_NULL(aled);
FAIL_IF(DetectAppLayerEventParseAppP2(aled, ipproto_bitarray, &event_type) < 0);
FAIL_IF(aled->alproto != ALPROTO_SMB);
FAIL_IF(aled->event_id != APP_LAYER_EVENT_TEST_MAP_EVENT3);
aled = DetectAppLayerEventParse("ftp.event5",
&event_type);
FAIL_IF_NULL(aled);
FAIL_IF(DetectAppLayerEventParseAppP2(aled, ipproto_bitarray, &event_type) < 0);
FAIL_IF(aled->alproto != ALPROTO_FTP);
FAIL_IF(aled->event_id != APP_LAYER_EVENT_TEST_MAP_EVENT5);
AppLayerParserRestoreParserTable();
DetectAppLayerEventFree(NULL, aled);
PASS;
}
static int DetectAppLayerEventTest03(void)
{
ThreadVars tv;
TcpReassemblyThreadCtx *ra_ctx = NULL;
Packet *p = NULL;
Flow *f = NULL;
TcpSession ssn;
TcpStream stream_ts, stream_tc;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
uint8_t buf_ts[] = "GET /index.html HTTP/1.1\r\n"
"Host: 127.0.0.1\r\n"
"User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.3) Gecko/20100402 Firefox/3.6.3\r\n"
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
"Accept-Language: en-us,en;q=0.5\r\n"
"Accept-Encoding: gzip,deflate\r\n"
"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"
"Keep-Alive: 115\r\n"
"Connection: keep-alive\r\n"
"\r\n";
uint8_t buf_tc[] = "HTTP/1.1 200 OK\r\n"
"Date: Fri, 22 Oct 2010 12:31:08 GMT\r\n"
"Server: Apache/2.2.15 (Unix) DAV/2\r\n"
"Last-Modified: Sat, 20 Nov 2004 20:16:24 GMT\r\n"
"ETag: \"ab8486-2c-3e9564c23b600\"\r\n"
"Accept-Ranges: bytes\r\n"
"Content-Length: 44\r\n"
"Keep-Alive: timeout=5, max=100\r\n"
"Connection: Keep-Alive\r\n"
"Content-Type: text/html\r\n"
"\r\n"
"<html><body><h1>It works!</h1></body></html>";
memset(&tv, 0, sizeof (ThreadVars));
memset(&ssn, 0, sizeof(TcpSession));
memset(&stream_ts, 0, sizeof(TcpStream));
memset(&stream_tc, 0, sizeof(TcpStream));
ssn.data_first_seen_dir = STREAM_TOSERVER;
de_ctx = DetectEngineCtxInit();
FAIL_IF(de_ctx == NULL);
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
"(app-layer-event: applayer_mismatch_protocol_both_directions; "
"sid:1;)");
FAIL_IF(de_ctx->sig_list == NULL);
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 200, 220);
FAIL_IF(f == NULL);
FLOW_INITIALIZE(f);
f->protoctx = &ssn;
f->proto = IPPROTO_TCP;
f->flags |= FLOW_IPV4;
p = PacketGetFromAlloc();
FAIL_IF(unlikely(p == NULL));
p->flow = f;
p->src.family = AF_INET;
p->dst.family = AF_INET;
p->proto = IPPROTO_TCP;
StreamTcpUTInit(&ra_ctx);
p->flowflags = FLOW_PKT_TOSERVER;
TcpStream *stream = &stream_ts;
FAIL_IF(AppLayerHandleTCPData(&tv, ra_ctx, p, f, &ssn, &stream, buf_ts,
sizeof(buf_ts), STREAM_TOSERVER | STREAM_START) < 0);
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
FAIL_IF (PacketAlertCheck(p, 1));
p->flowflags = FLOW_PKT_TOCLIENT;
stream = &stream_tc;
FAIL_IF (AppLayerHandleTCPData(&tv, ra_ctx, p, f, &ssn, &stream, buf_tc,
sizeof(buf_tc), STREAM_TOCLIENT | STREAM_START) < 0);
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
FAIL_IF(PacketAlertCheck(p, 1));
StreamTcpUTDeinit(ra_ctx);
PASS;
}
static int DetectAppLayerEventTest04(void)
{
ThreadVars tv;
TcpReassemblyThreadCtx *ra_ctx = NULL;
Packet *p = NULL;
Flow *f = NULL;
TcpSession ssn;
TcpStream stream_ts, stream_tc;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
uint8_t buf_ts[] = "GET /index.html HTTP/1.1\r\n"
"Host: 127.0.0.1\r\n"
"User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.3) Gecko/20100402 Firefox/3.6.3\r\n"
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
"Accept-Language: en-us,en;q=0.5\r\n"
"Accept-Encoding: gzip,deflate\r\n"
"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"
"Keep-Alive: 115\r\n"
"Connection: keep-alive\r\n"
"\r\n";
uint8_t buf_tc[] = "XTTP/1.1 200 OK\r\n"
"Date: Fri, 22 Oct 2010 12:31:08 GMT\r\n"
"Server: Apache/2.2.15 (Unix) DAV/2\r\n"
"Last-Modified: Sat, 20 Nov 2004 20:16:24 GMT\r\n"
"ETag: \"ab8486-2c-3e9564c23b600\"\r\n"
"Accept-Ranges: bytes\r\n"
"Content-Length: 44\r\n"
"Keep-Alive: timeout=5, max=100\r\n"
"Connection: Keep-Alive\r\n"
"Content-Type: text/html\r\n"
"\r\n"
"<html><body><h1>It works!</h1></body></html>";
memset(&tv, 0, sizeof (ThreadVars));
memset(&ssn, 0, sizeof(TcpSession));
memset(&stream_ts, 0, sizeof(TcpStream));
memset(&stream_tc, 0, sizeof(TcpStream));
ssn.data_first_seen_dir = STREAM_TOSERVER;
de_ctx = DetectEngineCtxInit();
FAIL_IF (de_ctx == NULL);
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
"(app-layer-event: applayer_detect_protocol_only_one_direction; "
"sid:1;)");
FAIL_IF(de_ctx->sig_list == NULL);
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 200, 220);
FAIL_IF (f == NULL);
FLOW_INITIALIZE(f);
f->protoctx = &ssn;
f->proto = IPPROTO_TCP;
f->flags |= FLOW_IPV4;
p = PacketGetFromAlloc();
FAIL_IF(unlikely(p == NULL));
p->flow = f;
p->src.family = AF_INET;
p->dst.family = AF_INET;
p->proto = IPPROTO_TCP;
StreamTcpUTInit(&ra_ctx);
p->flowflags = FLOW_PKT_TOSERVER;
TcpStream *stream = &stream_ts;
FAIL_IF(AppLayerHandleTCPData(&tv, ra_ctx, p, f, &ssn, &stream, buf_ts,
sizeof(buf_ts), STREAM_TOSERVER | STREAM_START) < 0);
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
FAIL_IF (PacketAlertCheck(p, 1));
p->flowflags = FLOW_PKT_TOCLIENT;
stream = &stream_tc;
FAIL_IF (AppLayerHandleTCPData(&tv, ra_ctx, p, f, &ssn, &stream, buf_tc,
sizeof(buf_tc), STREAM_TOCLIENT | STREAM_START) < 0);
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
FAIL_IF (!PacketAlertCheck(p, 1));
StreamTcpUTDeinit(ra_ctx);
PASS;
}
static int DetectAppLayerEventTest05(void)
{
ThreadVars tv;
TcpReassemblyThreadCtx *ra_ctx = NULL;
Packet *p = NULL;
Flow *f = NULL;
TcpSession ssn;
TcpStream stream_ts, stream_tc;
DetectEngineCtx *de_ctx = NULL;
DetectEngineThreadCtx *det_ctx = NULL;
uint8_t buf_ts[] = "GET /index.html HTTP/1.1\r\n"
"Host: 127.0.0.1\r\n"
"User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.3) Gecko/20100402 Firefox/3.6.3\r\n"
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n"
"Accept-Language: en-us,en;q=0.5\r\n"
"Accept-Encoding: gzip,deflate\r\n"
"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"
"Keep-Alive: 115\r\n"
"Connection: keep-alive\r\n"
"\r\n";
/* tls */
uint8_t buf_tc[] = {
0x16, 0x03, 0x01, 0x00, 0x86, 0x10, 0x00, 0x00,
0x82, 0x00, 0x80, 0xd3, 0x6f, 0x1f, 0x63, 0x82,
0x8d, 0x75, 0x77, 0x8c, 0x91, 0xbc, 0xa1, 0x3d,
0xbb, 0xe1, 0xb5, 0xd3, 0x31, 0x92, 0x59, 0x2b,
0x2c, 0x43, 0x96, 0xa3, 0xaa, 0x23, 0x92, 0xd0,
0x91, 0x2a, 0x5e, 0x10, 0x5b, 0xc8, 0xc1, 0xe2,
0xd3, 0x5c, 0x8b, 0x8c, 0x91, 0x9e, 0xc2, 0xf2,
0x9c, 0x3c, 0x4f, 0x37, 0x1e, 0x20, 0x5e, 0x33,
0xd5, 0xf0, 0xd6, 0xaf, 0x89, 0xf5, 0xcc, 0xb2,
0xcf, 0xc1, 0x60, 0x3a, 0x46, 0xd5, 0x4e, 0x2a,
0xb6, 0x6a, 0xb9, 0xfc, 0x32, 0x8b, 0xe0, 0x6e,
0xa0, 0xed, 0x25, 0xa0, 0xa4, 0x82, 0x81, 0x73,
0x90, 0xbf, 0xb5, 0xde, 0xeb, 0x51, 0x8d, 0xde,
0x5b, 0x6f, 0x94, 0xee, 0xba, 0xe5, 0x69, 0xfa,
0x1a, 0x80, 0x30, 0x54, 0xeb, 0x12, 0x01, 0xb9,
0xfe, 0xbf, 0x82, 0x95, 0x01, 0x7b, 0xb0, 0x97,
0x14, 0xc2, 0x06, 0x3c, 0x69, 0xfb, 0x1c, 0x66,
0x47, 0x17, 0xd9, 0x14, 0x03, 0x01, 0x00, 0x01,
0x01, 0x16, 0x03, 0x01, 0x00, 0x30, 0xf6, 0xbc,
0x0d, 0x6f, 0xe8, 0xbb, 0xaa, 0xbf, 0x14, 0xeb,
0x7b, 0xcc, 0x6c, 0x28, 0xb0, 0xfc, 0xa6, 0x01,
0x2a, 0x97, 0x96, 0x17, 0x5e, 0xe8, 0xb4, 0x4e,
0x78, 0xc9, 0x04, 0x65, 0x53, 0xb6, 0x93, 0x3d,
0xeb, 0x44, 0xee, 0x86, 0xf9, 0x80, 0x49, 0x45,
0x21, 0x34, 0xd1, 0xee, 0xc8, 0x9c,
};
memset(&tv, 0, sizeof (ThreadVars));
memset(&ssn, 0, sizeof(TcpSession));
memset(&stream_ts, 0, sizeof(TcpStream));
memset(&stream_tc, 0, sizeof(TcpStream));
ssn.data_first_seen_dir = STREAM_TOSERVER;
de_ctx = DetectEngineCtxInit();
FAIL_IF (de_ctx == NULL);
de_ctx->flags |= DE_QUIET;
de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
"(app-layer-event: applayer_mismatch_protocol_both_directions; "
"sid:1;)");
FAIL_IF (de_ctx->sig_list == NULL);
SigGroupBuild(de_ctx);
DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
f = UTHBuildFlow(AF_INET, "1.2.3.4", "1.2.3.5", 200, 220);
FAIL_IF (f == NULL);
FLOW_INITIALIZE(f);
f->protoctx = &ssn;
f->proto = IPPROTO_TCP;
f->flags |= FLOW_IPV4;
p = PacketGetFromAlloc();
FAIL_IF (unlikely(p == NULL));
p->flow = f;
p->src.family = AF_INET;
p->dst.family = AF_INET;
p->proto = IPPROTO_TCP;
StreamTcpUTInit(&ra_ctx);
p->flowflags = FLOW_PKT_TOSERVER;
TcpStream *stream = &stream_ts;
FAIL_IF (AppLayerHandleTCPData(&tv, ra_ctx, p, f, &ssn, &stream, buf_ts,
sizeof(buf_ts), STREAM_TOSERVER | STREAM_START) < 0);
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
FAIL_IF (PacketAlertCheck(p, 1));
p->flowflags = FLOW_PKT_TOCLIENT;
stream = &stream_tc;
FAIL_IF (AppLayerHandleTCPData(&tv, ra_ctx, p, f, &ssn, &stream, buf_tc,
sizeof(buf_tc), STREAM_TOCLIENT | STREAM_START) < 0);
SigMatchSignatures(&tv, de_ctx, det_ctx, p);
FAIL_IF (!PacketAlertCheck(p, 1));
StreamTcpUTDeinit(ra_ctx);
PASS;
}
static int DetectAppLayerEventTest06(void)
{
AppLayerEventType event_type;
uint8_t ipproto_bitarray[256 / 8];
memset(ipproto_bitarray, 0, sizeof(ipproto_bitarray));
ipproto_bitarray[IPPROTO_TCP / 8] |= 1 << (IPPROTO_TCP % 8);
DetectAppLayerEventData *aled = DetectAppLayerEventParse("file.test",
&event_type);
FAIL_IF_NULL(aled);
FAIL_IF(DetectAppLayerEventParseAppP2(aled, ipproto_bitarray, &event_type) < 0);
FAIL_IF(aled->alproto != ALPROTO_UNKNOWN);
FAIL_IF(aled->event_id != DET_CTX_EVENT_TEST);
DetectAppLayerEventFree(NULL, aled);
PASS;
}
/**
* \brief This function registers unit tests for "app-layer-event" keyword.
*/
static void DetectAppLayerEventRegisterTests(void)
{
UtRegisterTest("DetectAppLayerEventTest01", DetectAppLayerEventTest01);
UtRegisterTest("DetectAppLayerEventTest02", DetectAppLayerEventTest02);
UtRegisterTest("DetectAppLayerEventTest03", DetectAppLayerEventTest03);
UtRegisterTest("DetectAppLayerEventTest04", DetectAppLayerEventTest04);
UtRegisterTest("DetectAppLayerEventTest05", DetectAppLayerEventTest05);
UtRegisterTest("DetectAppLayerEventTest06", DetectAppLayerEventTest06);
}
#endif /* UNITTESTS */

@ -24,7 +24,6 @@
#ifndef __DETECT_APP_LAYER_EVENT_H__
#define __DETECT_APP_LAYER_EVENT_H__
int DetectAppLayerEventPrepare(DetectEngineCtx *de_ctx, Signature *s);
void DetectAppLayerEventRegister(void);
#endif /* __DETECT_APP_LAYER_EVENT_H__ */

@ -2012,19 +2012,6 @@ static Signature *SigInitHelper(DetectEngineCtx *de_ctx, const char *sigstr,
AppLayerProtoDetectSupportedIpprotos(sig->alproto, sig->proto.proto);
}
ret = DetectAppLayerEventPrepare(de_ctx, sig);
if (ret == -3) {
de_ctx->sigerror_silent = true;
de_ctx->sigerror_ok = true;
goto error;
}
else if (ret == -2) {
de_ctx->sigerror_silent = true;
goto error;
} else if (ret < 0) {
goto error;
}
/* set the packet and app layer flags, but only if the
* app layer flag wasn't already set in which case we
* only consider the app layer */

Loading…
Cancel
Save