]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
datasets: unix socket dataset-add command
authorVictor Julien <victor@inliniac.net>
Sun, 14 Jul 2019 05:09:12 +0000 (07:09 +0200)
committerVictor Julien <victor@inliniac.net>
Tue, 3 Sep 2019 13:17:55 +0000 (15:17 +0200)
src/datasets.c
src/datasets.h
src/runmode-unix-socket.c
src/runmode-unix-socket.h
src/unix-manager.c

index d6d625fee610bc8c304f5b941369322f7b64b272..0b94dd1ec524a9a0ba7ee5ef8ef4118cfd3c574e 100644 (file)
@@ -40,6 +40,17 @@ static uint32_t set_ids = 0;
 static int DatasetAddwRep(Dataset *set, const uint8_t *data, const uint32_t data_len,
         DataRepType *rep);
 
+enum DatasetTypes DatasetGetTypeFromString(const char *s)
+{
+    if (strcasecmp("md5", s) == 0)
+        return DATASET_TYPE_MD5;
+    if (strcasecmp("sha256", s) == 0)
+        return DATASET_TYPE_SHA256;
+    if (strcasecmp("string", s) == 0)
+        return DATASET_TYPE_STRING;
+    return DATASET_TYPE_NOTSET;
+}
+
 static Dataset *DatasetAlloc(const char *name)
 {
     Dataset *set = SCCalloc(1, sizeof(*set));
@@ -61,16 +72,6 @@ static Dataset *DatasetSearchByName(const char *name)
     return NULL;
 }
 
-Dataset *DatasetGetByName(const char *name)
-{
-    Dataset *set = DatasetSearchByName(name);
-    if (set)
-        return set;
-
-    return DatasetAlloc(name);
-}
-
-
 static int HexToRaw(const uint8_t *in, size_t ins, uint8_t *out, size_t outs)
 {
     if (ins % 2 != 0)
@@ -360,6 +361,21 @@ static void DatasetGetPath(const char *in_path,
     SCLogNotice("in_path \'%s\' => \'%s\'", in_path, out_path);
 }
 
+/** \brief look for set by name without creating it */
+Dataset *DatasetFind(const char *name, enum DatasetTypes type)
+{
+    SCMutexLock(&sets_lock);
+    Dataset *set = DatasetSearchByName(name);
+    if (set) {
+        if (set->type != type) {
+            SCMutexUnlock(&sets_lock);
+            return NULL;
+        }
+    }
+    SCMutexUnlock(&sets_lock);
+    return set;
+}
+
 Dataset *DatasetGet(const char *name, enum DatasetTypes type,
         const char *save, const char *load)
 {
@@ -936,3 +952,39 @@ static int DatasetAddwRep(Dataset *set, const uint8_t *data, const uint32_t data
     }
     return -1;
 }
+
+/** \brief add serialized data to set */
+int DatasetAddSerialized(Dataset *set, const char *string)
+{
+    if (set == NULL)
+        return -1;
+
+    switch (set->type) {
+        case DATASET_TYPE_STRING: {
+            uint8_t decoded[strlen(string)];
+            uint32_t len = DecodeBase64(decoded, (const uint8_t *)string, strlen(string), 1);
+            if (len == 0) {
+                return -1;
+            }
+
+            return DatasetAddString(set, decoded, len);
+        }
+        case DATASET_TYPE_MD5: {
+            if (strlen(string) != 32)
+                return -1;
+            uint8_t hash[16];
+            if (HexToRaw((const uint8_t *)string, 32, hash, sizeof(hash)) < 0)
+                return -1;
+            return DatasetAddMd5(set, hash, 16);
+        }
+        case DATASET_TYPE_SHA256: {
+            if (strlen(string) != 64)
+                return -1;
+            uint8_t hash[32];
+            if (HexToRaw((const uint8_t *)string, 64, hash, sizeof(hash)) < 0)
+                return -1;
+            return DatasetAddSha256(set, hash, 32);
+        }
+    }
+    return -1;
+}
index 15d1445930a931b642457b4f57beb8e7710ef60c..514340b46fb0d1744571a61b2202b720d62cfdfa 100644 (file)
@@ -45,12 +45,14 @@ typedef struct Dataset {
     struct Dataset *next;
 } Dataset;
 
-Dataset *DatasetGetByName(const char *name);
+enum DatasetTypes DatasetGetTypeFromString(const char *s);
+Dataset *DatasetFind(const char *name, enum DatasetTypes type);
 Dataset *DatasetGet(const char *name, enum DatasetTypes type,
         const char *save, const char *load);
 int DatasetAdd(Dataset *set, const uint8_t *data, const uint32_t data_len);
 int DatasetLookup(Dataset *set, const uint8_t *data, const uint32_t data_len);
 DataRepResultType DatasetLookupwRep(Dataset *set, const uint8_t *data, const uint32_t data_len,
         const DataRepType *rep);
+int DatasetAddSerialized(Dataset *set, const char *string);
 
 #endif /* __DATASETS_H__ */
index 04257b44084b411e87c13baed87b4185c08ab3c7..72a9ed04d0082f1f6f9d5fe8921ebe3f1c465f42 100644 (file)
@@ -49,6 +49,8 @@
 
 #include "conf-yaml-loader.h"
 
+#include "datasets.h"
+
 int unix_socket_mode_is_running = 0;
 
 typedef struct PcapFiles_ {
@@ -629,6 +631,62 @@ TmEcode UnixSocketPcapFile(TmEcode tm, struct timespec *last_processed)
 }
 
 #ifdef BUILD_UNIX_SOCKET
+/**
+ * \brief Command to add data to a dataset
+ *
+ * \param cmd the content of command Arguments as a json_t object
+ * \param answer the json_t object that has to be used to answer
+ * \param data pointer to data defining the context here a PcapCommand::
+ */
+TmEcode UnixSocketDatasetAdd(json_t *cmd, json_t* answer, void *data)
+{
+    /* 1 get dataset name */
+    json_t *narg = json_object_get(cmd, "setname");
+    if (!json_is_string(narg)) {
+        json_object_set_new(answer, "message", json_string("setname is not a string"));
+        return TM_ECODE_FAILED;
+    }
+    const char *set_name = json_string_value(narg);
+
+    /* 2 get the data type */
+    json_t *targ = json_object_get(cmd, "settype");
+    if (!json_is_string(targ)) {
+        json_object_set_new(answer, "message", json_string("settype is not a string"));
+        return TM_ECODE_FAILED;
+    }
+    const char *type = json_string_value(targ);
+
+    /* 3 get value */
+    json_t *varg = json_object_get(cmd, "datavalue");
+    if (!json_is_string(varg)) {
+        json_object_set_new(answer, "message", json_string("datavalue is not string"));
+        return TM_ECODE_FAILED;
+    }
+    const char *value = json_string_value(varg);
+
+    SCLogNotice("dataset-add: %s type %s value %s", set_name, type, value);
+
+    enum DatasetTypes t = DatasetGetTypeFromString(type);
+
+    Dataset *set = DatasetFind(set_name, t);
+    if (set == NULL) {
+        json_object_set_new(answer, "message", json_string("set not found or wrong type"));
+        return TM_ECODE_FAILED;
+    }
+
+    int r = DatasetAddSerialized(set, value);
+    if (r == 1) {
+        json_object_set_new(answer, "message", json_string("data added"));
+        return TM_ECODE_OK;
+    } else if (r == 0) {
+        json_object_set_new(answer, "message", json_string("data already in set"));
+        return TM_ECODE_OK;
+    } else {
+        json_object_set_new(answer, "message", json_string("failed to add data"));
+        return TM_ECODE_FAILED;
+    }
+}
+
 /**
  * \brief Command to add a tenant handler
  *
index c8a06e06bf26d326fe9d267b4354606d63f99c5c..630246996c69f900598dfdc6f2672d69a2fcaf09 100644 (file)
@@ -31,6 +31,7 @@ int RunModeUnixSocketIsActive(void);
 TmEcode UnixSocketPcapFile(TmEcode tm, struct timespec *last_processed);
 
 #ifdef BUILD_UNIX_SOCKET
+TmEcode UnixSocketDatasetAdd(json_t *cmd, json_t* answer, void *data);
 TmEcode UnixSocketRegisterTenantHandler(json_t *cmd, json_t* answer, void *data);
 TmEcode UnixSocketUnregisterTenantHandler(json_t *cmd, json_t* answer, void *data);
 TmEcode UnixSocketRegisterTenant(json_t *cmd, json_t* answer, void *data);
index 105648087a1a0072fc6cd593a1b8d74b8f80b140..11f452cf1579116494463783835154a92526ba51 100644 (file)
@@ -1089,6 +1089,8 @@ int UnixManagerInit(void)
     UnixManagerRegisterCommand("memcap-show", UnixSocketShowMemcap, &command, UNIX_CMD_TAKE_ARGS);
     UnixManagerRegisterCommand("memcap-list", UnixSocketShowAllMemcap, NULL, 0);
 
+    UnixManagerRegisterCommand("dataset-add", UnixSocketDatasetAdd, &command, UNIX_CMD_TAKE_ARGS);
+
     return 0;
 }