]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect: set events in inspection phase
authorGiuseppe Longo <glongo@stamus-networks.com>
Thu, 13 Jul 2017 22:22:13 +0000 (00:22 +0200)
committerVictor Julien <victor@inliniac.net>
Wed, 31 Jan 2018 13:31:00 +0000 (14:31 +0100)
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.

src/detect-app-layer-event.c
src/detect-app-layer-event.h
src/detect-engine.c
src/detect.h

index be2bb5aedc8c87400ad496405f344865d84b0ae4..107ee63ab212d0a9cf98f2f95673b4c72c701e66 100644 (file)
@@ -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;
index a3ed6088288db46d1aa2246c3ceae61b4830f7be..b7d6133dbe73e4ac21f55b2ddc5f0c270ce555b0 100644 (file)
@@ -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;
 
index 91822231a29d764ab4ab3452decdf7df0ee0cbf5..41861a883273d3572bed620b89990f00931c90ba 100644 (file)
@@ -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*********************************/
 
index e5e1f7c268890aec8b99c847db978bf6a5aab04c..89a6f0d527c65c010f83cd48776da35a7b8b9202 100644 (file)
@@ -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"