]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
datasets: add dataset-lookup command
authorEric Leblond <eric@regit.org>
Mon, 18 Jan 2021 22:39:09 +0000 (23:39 +0100)
committerVictor Julien <vjulien@oisf.net>
Thu, 27 Oct 2022 07:44:20 +0000 (09:44 +0200)
Ticket: #5184

src/datasets.c
src/datasets.h
src/runmode-unix-socket.c
src/runmode-unix-socket.h
src/unix-manager.c

index 15a5f6f36c3b8e5034ff100e8e446ba33e8ba93e..8d84affbf1eb33a38f7132f681d83a9c3efc1beb 100644 (file)
@@ -1178,6 +1178,48 @@ int DatasetAddSerialized(Dataset *set, const char *string)
     return -1;
 }
 
+/** \brief add serialized data to set
+ *  \retval int 1 added
+ *  \retval int 0 already in hash
+ *  \retval int -1 API error (not added)
+ *  \retval int -2 DATA error
+ */
+int DatasetLookupSerialized(Dataset *set, const char *string)
+{
+    if (set == NULL)
+        return -1;
+
+    switch (set->type) {
+        case DATASET_TYPE_STRING: {
+            // coverity[alloc_strlen : FALSE]
+            uint8_t decoded[strlen(string)];
+            uint32_t consumed = 0, num_decoded = 0;
+            Base64Ecode code = DecodeBase64(decoded, strlen(string), (const uint8_t *)string,
+                    strlen(string), &consumed, &num_decoded, BASE64_MODE_STRICT);
+            if (code == BASE64_ECODE_ERR)
+                FatalError(SC_ERR_FATAL, "bad base64 encoding %s/%s", set->name, set->load);
+            return DatasetLookup(set, decoded, num_decoded);
+        }
+        case DATASET_TYPE_MD5: {
+            if (strlen(string) != 32)
+                return -2;
+            uint8_t hash[16];
+            if (HexToRaw((const uint8_t *)string, 32, hash, sizeof(hash)) < 0)
+                return -2;
+            return DatasetLookup(set, hash, 16);
+        }
+        case DATASET_TYPE_SHA256: {
+            if (strlen(string) != 64)
+                return -2;
+            uint8_t hash[32];
+            if (HexToRaw((const uint8_t *)string, 64, hash, sizeof(hash)) < 0)
+                return -2;
+            return DatasetLookup(set, hash, 32);
+        }
+    }
+    return -1;
+}
+
 /**
  *  \retval 1 data was removed from the hash
  *  \retval 0 data not removed (busy)
index bd22cb13c797e439885b1e7c452bd76feb40851a..af5e49af8e48a4bdecbca5cb8db9d499874f3c2d 100644 (file)
@@ -60,5 +60,6 @@ DataRepResultType DatasetLookupwRep(Dataset *set, const uint8_t *data, const uin
 
 int DatasetAddSerialized(Dataset *set, const char *string);
 int DatasetRemoveSerialized(Dataset *set, const char *string);
+int DatasetLookupSerialized(Dataset *set, const char *string);
 
 #endif /* __DATASETS_H__ */
index c4981e93231e5be041348b5a9186a6bfd9f83b35..9933cb3e665aae9cd05c4ca357aa6443bc69b44c 100644 (file)
@@ -808,6 +808,55 @@ TmEcode UnixSocketDatasetClear(json_t *cmd, json_t *answer, void *data)
     return TM_ECODE_OK;
 }
 
+TmEcode UnixSocketDatasetLookup(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);
+
+    SCLogDebug("dataset-exist: %s type %s value %s", set_name, type, value);
+
+    enum DatasetTypes t = DatasetGetTypeFromString(type);
+    if (t == DATASET_TYPE_NOTSET) {
+        json_object_set_new(answer, "message", json_string("unknown settype"));
+        return TM_ECODE_FAILED;
+    }
+
+    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;
+    }
+
+    if (DatasetLookupSerialized(set, value) > 0) {
+        json_object_set_new(answer, "message", json_string("item found in set"));
+        return TM_ECODE_OK;
+    } else {
+        json_object_set_new(answer, "message", json_string("item not found in set"));
+        return TM_ECODE_FAILED;
+    }
+}
+
 /**
  * \brief Command to add a tenant handler
  *
index 469dc771c9de61c2ecc10c003c1fe757dcf9b555..c2fa84aa3235cb421fc0065db0a01357ce5e2af5 100644 (file)
@@ -37,6 +37,7 @@ TmEcode UnixSocketDatasetAdd(json_t *cmd, json_t* answer, void *data);
 TmEcode UnixSocketDatasetRemove(json_t *cmd, json_t* answer, void *data);
 TmEcode UnixSocketDatasetDump(json_t *cmd, json_t *answer, void *data);
 TmEcode UnixSocketDatasetClear(json_t *cmd, json_t *answer, void *data);
+TmEcode UnixSocketDatasetLookup(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 3fdcb73fe54fbc1e46aa339f51af3a1efb3ddb7a..95a0a8c14c2026b1f7be91929ca493e03a5d96c0 100644 (file)
@@ -1091,6 +1091,8 @@ int UnixManagerInit(void)
     UnixManagerRegisterCommand("dataset-dump", UnixSocketDatasetDump, NULL, 0);
     UnixManagerRegisterCommand(
             "dataset-clear", UnixSocketDatasetClear, &command, UNIX_CMD_TAKE_ARGS);
+    UnixManagerRegisterCommand(
+            "dataset-lookup", UnixSocketDatasetLookup, &command, UNIX_CMD_TAKE_ARGS);
 
     return 0;
 }