diff --git a/src/detect-app-layer-event.c b/src/detect-app-layer-event.c index be2bb5aedc..107ee63ab2 100644 --- a/src/detect-app-layer-event.c +++ b/src/detect-app-layer-event.c @@ -194,8 +194,13 @@ static int DetectAppLayerEventParseAppP2(DetectAppLayerEventData *data, return -1; } - r = AppLayerParserGetEventInfo(ipproto, data->alproto, - p_idx + 1, &event_id, event_type); + 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) { SCLogError(SC_ERR_INVALID_SIGNATURE, "app-layer-event keyword's " "protocol \"%s\" doesn't have event \"%s\" registered", @@ -214,6 +219,7 @@ static DetectAppLayerEventData *DetectAppLayerEventParseAppP1(const char *arg) AppProto alproto; const char *p_idx; char alproto_name[MAX_ALPROTO_NAME]; + int needs_detctx = FALSE; p_idx = strchr(arg, '.'); if (strlen(arg) > MAX_ALPROTO_NAME) { @@ -225,10 +231,14 @@ static DetectAppLayerEventData *DetectAppLayerEventParseAppP1(const char *arg) alproto = AppLayerGetProtoByName(alproto_name); if (alproto == ALPROTO_UNKNOWN) { - SCLogError(SC_ERR_INVALID_SIGNATURE, "app-layer-event keyword " - "supplied with unknown protocol \"%s\"", - alproto_name); - return NULL; + if (!strcmp(alproto_name, "file")) { + needs_detctx = TRUE; + } else { + SCLogError(SC_ERR_INVALID_SIGNATURE, "app-layer-event keyword " + "supplied with unknown protocol \"%s\"", + alproto_name); + return NULL; + } } aled = SCMalloc(sizeof(*aled)); @@ -237,6 +247,7 @@ static DetectAppLayerEventData *DetectAppLayerEventParseAppP1(const char *arg) memset(aled, 0x00, sizeof(*aled)); aled->alproto = alproto; aled->arg = SCStrdup(arg); + aled->needs_detctx = needs_detctx; if (aled->arg == NULL) { SCFree(aled); return NULL; @@ -791,6 +802,31 @@ static int DetectAppLayerEventTest05(void) 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 */ /** @@ -804,6 +840,7 @@ void DetectAppLayerEventRegisterTests(void) UtRegisterTest("DetectAppLayerEventTest03", DetectAppLayerEventTest03); UtRegisterTest("DetectAppLayerEventTest04", DetectAppLayerEventTest04); UtRegisterTest("DetectAppLayerEventTest05", DetectAppLayerEventTest05); + UtRegisterTest("DetectAppLayerEventTest06", DetectAppLayerEventTest06); #endif /* UNITTESTS */ return; diff --git a/src/detect-app-layer-event.h b/src/detect-app-layer-event.h index a3ed608828..b7d6133dbe 100644 --- a/src/detect-app-layer-event.h +++ b/src/detect-app-layer-event.h @@ -28,6 +28,9 @@ typedef struct DetectAppLayerEventData_ { AppProto alproto; int event_id; + /* it's used to check if there are event set into the detect engine */ + bool needs_detctx; + char *arg; } DetectAppLayerEventData; diff --git a/src/detect-engine.c b/src/detect-engine.c index 91822231a2..41861a8832 100644 --- a/src/detect-engine.c +++ b/src/detect-engine.c @@ -100,6 +100,27 @@ static uint32_t DetectEngineTentantGetIdFromPcap(const void *ctx, const Packet * 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, AppProto alproto, uint32_t dir, int progress, InspectEngineFuncPtr Callback) @@ -3102,6 +3123,32 @@ const char *DetectSigmatchListEnumToString(enum DetectSigmatchListEnum type) 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*********************************/ diff --git a/src/detect.h b/src/detect.h index e5e1f7c268..89a6f0d527 100644 --- a/src/detect.h +++ b/src/detect.h @@ -50,6 +50,8 @@ #include "util-var-name.h" +#include "app-layer-events.h" + #define DETECT_MAX_RULE_SIZE 8192 /* 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_max; + AppLayerDecoderEvents *decoder_events; + uint16_t events; + #ifdef DEBUG uint64_t pkt_stream_add_cnt; uint64_t payload_mpm_cnt; @@ -1018,6 +1023,27 @@ typedef struct 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) #ifdef HAVE_MAGIC #define SIG_GROUP_HEAD_HAVEFILEMAGIC (1 << 20) @@ -1265,6 +1291,12 @@ void DetectFlowbitsAnalyze(DetectEngineCtx *de_ctx); int DetectMetadataHashInit(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-register.h"