]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
unix-manager: print failed rules
authorGiuseppe Longo <glongo@stamus-networks.com>
Mon, 19 Oct 2015 13:06:17 +0000 (15:06 +0200)
committerVictor Julien <victor@inliniac.net>
Mon, 11 Dec 2017 08:21:32 +0000 (09:21 +0100)
This permits to print the invalid rules through
unix socket.

An example output is the following:

>>> show-failed-rules
Success:
[
    {
        "filename": "/home/eric/git/oisf/benches/tls-store.rules",
        "line": 2,
        "rule": "alert ts any any -> any 334 (msg:\"Store TLS\"; tls.store; sid:2; rev:1;)"
    },
    {
        "filename": "/home/eric/git/oisf/benches/tls-store.rules",
        "line": 3,
        "rule": "alert ls any any -> any 334 (msg:\"Store TLS\"; tls.store; sid:3; rev:1;)"
    }
]

The dump is limited to 20 entries to avoid to send a too big
message to the client that don't support it by default.

src/unix-manager.c

index f5c372716a0f25855260bca5a7dfbd2715ef4bdf..b6e843025414a2909d71ed203db08be634e195da 100644 (file)
@@ -57,6 +57,8 @@
 #define SOCKET_FILENAME "suricata-command.socket"
 #define SOCKET_TARGET SOCKET_PATH SOCKET_FILENAME
 
+#define MAX_FAILED_RULES   20
+
 typedef struct Command_ {
     char *name;
     TmEcode (*Func)(json_t *, json_t *, void *);
@@ -707,6 +709,63 @@ static TmEcode UnixManagerRulesetStatsCommand(json_t *cmd,
     SCReturnInt(retval);
 }
 
+static TmEcode UnixManagerShowFailedRules(json_t *cmd,
+                                          json_t *server_msg, void *data)
+{
+    SCEnter();
+    int rules_cnt = 0;
+    DetectEngineCtx *de_ctx = DetectEngineGetCurrent();
+    if (de_ctx == NULL) {
+        json_object_set_new(server_msg, "message", json_string("Unable to get info"));
+        SCReturnInt(TM_ECODE_OK);
+    }
+
+    /* Since we need to deference de_ctx, we don't want to lost it. */
+    DetectEngineCtx *list = de_ctx;
+    json_t *js_sigs_array = json_array();
+
+    if (js_sigs_array == NULL) {
+        json_object_set_new(server_msg, "message", json_string("Unable to get info"));
+        goto error;
+    }
+    while (list) {
+        SigString *sigs_str = NULL;
+        TAILQ_FOREACH(sigs_str, &list->sig_stat.failed_sigs, next) {
+            json_t *jdata = json_object();
+            if (jdata == NULL) {
+                json_object_set_new(server_msg, "message", json_string("Unable to get the sig"));
+                goto error;
+            }
+
+            json_object_set_new(jdata, "tenant_id", json_integer(list->tenant_id));
+            json_object_set_new(jdata, "rule", json_string(sigs_str->sig_str));
+            json_object_set_new(jdata, "filename", json_string(sigs_str->filename));
+            json_object_set_new(jdata, "line", json_integer(sigs_str->line));
+            if (sigs_str->sig_error) {
+                json_object_set_new(jdata, "error", json_string(sigs_str->sig_error));
+            }
+            json_array_append_new(js_sigs_array, jdata);
+            if (++rules_cnt > MAX_FAILED_RULES) {
+                break;
+            }
+        }
+        if (rules_cnt > MAX_FAILED_RULES) {
+            break;
+        }
+        list = list->next;
+    }
+
+    json_object_set_new(server_msg, "message", js_sigs_array);
+    DetectEngineDeReference(&de_ctx);
+    SCReturnInt(TM_ECODE_OK);
+
+error:
+    DetectEngineDeReference(&de_ctx);
+    json_object_clear(js_sigs_array);
+    json_decref(js_sigs_array);
+    SCReturnInt(TM_ECODE_FAILED);
+}
+
 static TmEcode UnixManagerConfGetCommand(json_t *cmd,
                                          json_t *server_msg, void *data)
 {
@@ -921,6 +980,7 @@ int UnixManagerInit(void)
     UnixManagerRegisterCommand("ruleset-reload-nonblocking", UnixManagerNonBlockingReloadRules, NULL, 0);
     UnixManagerRegisterCommand("ruleset-reload-time", UnixManagerReloadTimeCommand, NULL, 0);
     UnixManagerRegisterCommand("ruleset-stats", UnixManagerRulesetStatsCommand, NULL, 0);
+    UnixManagerRegisterCommand("ruleset-failed-rules", UnixManagerShowFailedRules, NULL, 0);
     UnixManagerRegisterCommand("register-tenant-handler", UnixSocketRegisterTenantHandler, &command, UNIX_CMD_TAKE_ARGS);
     UnixManagerRegisterCommand("unregister-tenant-handler", UnixSocketUnregisterTenantHandler, &command, UNIX_CMD_TAKE_ARGS);
     UnixManagerRegisterCommand("register-tenant", UnixSocketRegisterTenant, &command, UNIX_CMD_TAKE_ARGS);