detect: set events in inspection phase

During the inspection phase actually is not possible to catch
an error if it occurs.
This patch permits to store events in the detection engine
such that we can match on events and catch them.
pull/3209/head
Giuseppe Longo 8 years ago committed by Victor Julien
parent d0f92e2a56
commit 822faa08f8

@ -194,8 +194,13 @@ static int DetectAppLayerEventParseAppP2(DetectAppLayerEventData *data,
return -1; return -1;
} }
r = AppLayerParserGetEventInfo(ipproto, data->alproto, if (!data->needs_detctx) {
p_idx + 1, &event_id, event_type); 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 (r < 0) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "app-layer-event keyword's " SCLogError(SC_ERR_INVALID_SIGNATURE, "app-layer-event keyword's "
"protocol \"%s\" doesn't have event \"%s\" registered", "protocol \"%s\" doesn't have event \"%s\" registered",
@ -214,6 +219,7 @@ static DetectAppLayerEventData *DetectAppLayerEventParseAppP1(const char *arg)
AppProto alproto; AppProto alproto;
const char *p_idx; const char *p_idx;
char alproto_name[MAX_ALPROTO_NAME]; char alproto_name[MAX_ALPROTO_NAME];
int needs_detctx = FALSE;
p_idx = strchr(arg, '.'); p_idx = strchr(arg, '.');
if (strlen(arg) > MAX_ALPROTO_NAME) { if (strlen(arg) > MAX_ALPROTO_NAME) {
@ -225,10 +231,14 @@ static DetectAppLayerEventData *DetectAppLayerEventParseAppP1(const char *arg)
alproto = AppLayerGetProtoByName(alproto_name); alproto = AppLayerGetProtoByName(alproto_name);
if (alproto == ALPROTO_UNKNOWN) { if (alproto == ALPROTO_UNKNOWN) {
SCLogError(SC_ERR_INVALID_SIGNATURE, "app-layer-event keyword " if (!strcmp(alproto_name, "file")) {
"supplied with unknown protocol \"%s\"", needs_detctx = TRUE;
alproto_name); } else {
return NULL; SCLogError(SC_ERR_INVALID_SIGNATURE, "app-layer-event keyword "
"supplied with unknown protocol \"%s\"",
alproto_name);
return NULL;
}
} }
aled = SCMalloc(sizeof(*aled)); aled = SCMalloc(sizeof(*aled));
@ -237,6 +247,7 @@ static DetectAppLayerEventData *DetectAppLayerEventParseAppP1(const char *arg)
memset(aled, 0x00, sizeof(*aled)); memset(aled, 0x00, sizeof(*aled));
aled->alproto = alproto; aled->alproto = alproto;
aled->arg = SCStrdup(arg); aled->arg = SCStrdup(arg);
aled->needs_detctx = needs_detctx;
if (aled->arg == NULL) { if (aled->arg == NULL) {
SCFree(aled); SCFree(aled);
return NULL; return NULL;
@ -791,6 +802,31 @@ static int DetectAppLayerEventTest05(void)
PASS; 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);
if (DetectAppLayerEventParseAppP2(aled, ipproto_bitarray, &event_type) < 0)
goto error;
if (aled->alproto != ALPROTO_UNKNOWN || aled->event_id != DET_CTX_EVENT_TEST)
goto error;
DetectAppLayerEventFree(aled);
PASS;
error:
DetectAppLayerEventFree(aled);
FAIL;
}
#endif /* UNITTESTS */ #endif /* UNITTESTS */
/** /**
@ -804,6 +840,7 @@ void DetectAppLayerEventRegisterTests(void)
UtRegisterTest("DetectAppLayerEventTest03", DetectAppLayerEventTest03); UtRegisterTest("DetectAppLayerEventTest03", DetectAppLayerEventTest03);
UtRegisterTest("DetectAppLayerEventTest04", DetectAppLayerEventTest04); UtRegisterTest("DetectAppLayerEventTest04", DetectAppLayerEventTest04);
UtRegisterTest("DetectAppLayerEventTest05", DetectAppLayerEventTest05); UtRegisterTest("DetectAppLayerEventTest05", DetectAppLayerEventTest05);
UtRegisterTest("DetectAppLayerEventTest06", DetectAppLayerEventTest06);
#endif /* UNITTESTS */ #endif /* UNITTESTS */
return; return;

@ -28,6 +28,9 @@ typedef struct DetectAppLayerEventData_ {
AppProto alproto; AppProto alproto;
int event_id; int event_id;
/* it's used to check if there are event set into the detect engine */
bool needs_detctx;
char *arg; char *arg;
} DetectAppLayerEventData; } DetectAppLayerEventData;

@ -100,6 +100,27 @@ static uint32_t DetectEngineTentantGetIdFromPcap(const void *ctx, const Packet *
static DetectEngineAppInspectionEngine *g_app_inspect_engines = NULL; static DetectEngineAppInspectionEngine *g_app_inspect_engines = NULL;
SCEnumCharMap det_ctx_event_table[ ] = {
#ifdef UNITTESTS
{ "TEST", DET_CTX_EVENT_TEST },
#endif
{ "NO_MEMORY", FILE_DECODER_EVENT_NO_MEM },
{ "INVALID_SWF_LENGTH", FILE_DECODER_EVENT_INVALID_SWF_LENGTH },
{ "INVALID_SWF_VERSION", FILE_DECODER_EVENT_INVALID_SWF_VERSION },
{ "Z_DATA_ERROR", FILE_DECODER_EVENT_Z_DATA_ERROR },
{ "Z_STREAM_ERROR", FILE_DECODER_EVENT_Z_STREAM_ERROR },
{ "Z_BUF_ERROR", FILE_DECODER_EVENT_Z_BUF_ERROR },
{ "Z_UNKNOWN_ERROR", FILE_DECODER_EVENT_Z_UNKNOWN_ERROR },
{ "LZMA_DECODER_ERROR", FILE_DECODER_EVENT_LZMA_DECODER_ERROR },
{ "LZMA_MEMLIMIT_ERROR", FILE_DECODER_EVENT_LZMA_MEMLIMIT_ERROR },
{ "LZMA_OPTIONS_ERROR", FILE_DECODER_EVENT_LZMA_OPTIONS_ERROR },
{ "LZMA_FORMAT_ERROR", FILE_DECODER_EVENT_LZMA_FORMAT_ERROR },
{ "LZMA_DATA_ERROR", FILE_DECODER_EVENT_LZMA_DATA_ERROR },
{ "LZMA_BUF_ERROR", FILE_DECODER_EVENT_LZMA_BUF_ERROR },
{ "LZMA_UNKNOWN_ERROR", FILE_DECODER_EVENT_LZMA_UNKNOWN_ERROR },
{ NULL, -1 },
};
void DetectAppLayerInspectEngineRegister(const char *name, void DetectAppLayerInspectEngineRegister(const char *name,
AppProto alproto, uint32_t dir, AppProto alproto, uint32_t dir,
int progress, InspectEngineFuncPtr Callback) int progress, InspectEngineFuncPtr Callback)
@ -3102,6 +3123,32 @@ const char *DetectSigmatchListEnumToString(enum DetectSigmatchListEnum type)
return "error"; return "error";
} }
/* events api */
void DetectEngineSetEvent(DetectEngineThreadCtx *det_ctx, uint8_t e)
{
AppLayerDecoderEventsSetEventRaw(&det_ctx->decoder_events, e);
det_ctx->events++;
}
AppLayerDecoderEvents *DetectEngineGetEvents(DetectEngineThreadCtx *det_ctx)
{
return det_ctx->decoder_events;
}
int DetectEngineGetEventInfo(const char *event_name, int *event_id,
AppLayerEventType *event_type)
{
*event_id = SCMapEnumNameToValue(event_name, det_ctx_event_table);
if (*event_id == -1) {
SCLogError(SC_ERR_INVALID_ENUM_MAP, "event \"%s\" not present in "
"det_ctx's enum map table.", event_name);
/* this should be treated as fatal */
return -1;
}
*event_type = APP_LAYER_EVENT_TYPE_TRANSACTION;
return 0;
}
/*************************************Unittest*********************************/ /*************************************Unittest*********************************/

@ -50,6 +50,8 @@
#include "util-var-name.h" #include "util-var-name.h"
#include "app-layer-events.h"
#define DETECT_MAX_RULE_SIZE 8192 #define DETECT_MAX_RULE_SIZE 8192
/* forward declarations for the structures from detect-engine-sigorder.h */ /* forward declarations for the structures from detect-engine-sigorder.h */
@ -959,6 +961,9 @@ typedef struct DetectEngineThreadCtx_ {
int base64_decoded_len; int base64_decoded_len;
int base64_decoded_len_max; int base64_decoded_len_max;
AppLayerDecoderEvents *decoder_events;
uint16_t events;
#ifdef DEBUG #ifdef DEBUG
uint64_t pkt_stream_add_cnt; uint64_t pkt_stream_add_cnt;
uint64_t payload_mpm_cnt; uint64_t payload_mpm_cnt;
@ -1018,6 +1023,27 @@ typedef struct SigTableElmt_ {
} SigTableElmt; } SigTableElmt;
/* event code */
enum {
#ifdef UNITTESTS
DET_CTX_EVENT_TEST,
#endif
FILE_DECODER_EVENT_NO_MEM,
FILE_DECODER_EVENT_INVALID_SWF_LENGTH,
FILE_DECODER_EVENT_INVALID_SWF_VERSION,
FILE_DECODER_EVENT_Z_DATA_ERROR,
FILE_DECODER_EVENT_Z_STREAM_ERROR,
FILE_DECODER_EVENT_Z_BUF_ERROR,
FILE_DECODER_EVENT_Z_UNKNOWN_ERROR,
FILE_DECODER_EVENT_LZMA_DECODER_ERROR,
FILE_DECODER_EVENT_LZMA_MEMLIMIT_ERROR,
FILE_DECODER_EVENT_LZMA_OPTIONS_ERROR,
FILE_DECODER_EVENT_LZMA_FORMAT_ERROR,
FILE_DECODER_EVENT_LZMA_DATA_ERROR,
FILE_DECODER_EVENT_LZMA_BUF_ERROR,
FILE_DECODER_EVENT_LZMA_UNKNOWN_ERROR,
};
#define SIG_GROUP_HEAD_HAVERAWSTREAM (1 << 0) #define SIG_GROUP_HEAD_HAVERAWSTREAM (1 << 0)
#ifdef HAVE_MAGIC #ifdef HAVE_MAGIC
#define SIG_GROUP_HEAD_HAVEFILEMAGIC (1 << 20) #define SIG_GROUP_HEAD_HAVEFILEMAGIC (1 << 20)
@ -1265,6 +1291,12 @@ void DetectFlowbitsAnalyze(DetectEngineCtx *de_ctx);
int DetectMetadataHashInit(DetectEngineCtx *de_ctx); int DetectMetadataHashInit(DetectEngineCtx *de_ctx);
void DetectMetadataHashFree(DetectEngineCtx *de_ctx); void DetectMetadataHashFree(DetectEngineCtx *de_ctx);
/* events */
void DetectEngineSetEvent(DetectEngineThreadCtx *det_ctx, uint8_t e);
AppLayerDecoderEvents *DetectEngineGetEvents(DetectEngineThreadCtx *det_ctx);
int DetectEngineGetEventInfo(const char *event_name, int *event_id,
AppLayerEventType *event_type);
#include "detect-engine-build.h" #include "detect-engine-build.h"
#include "detect-engine-register.h" #include "detect-engine-register.h"

Loading…
Cancel
Save