From: Eric Leblond Date: Mon, 18 Jan 2021 22:39:09 +0000 (+0100) Subject: datasets: add dataset-lookup command X-Git-Tag: suricata-7.0.0-rc1~471 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=843dba0a28ce5b1b4286e897c0f5fcec6bd41ca0;p=thirdparty%2Fsuricata.git datasets: add dataset-lookup command Ticket: #5184 --- diff --git a/src/datasets.c b/src/datasets.c index 15a5f6f36c..8d84affbf1 100644 --- a/src/datasets.c +++ b/src/datasets.c @@ -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) diff --git a/src/datasets.h b/src/datasets.h index bd22cb13c7..af5e49af8e 100644 --- a/src/datasets.h +++ b/src/datasets.h @@ -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__ */ diff --git a/src/runmode-unix-socket.c b/src/runmode-unix-socket.c index c4981e9323..9933cb3e66 100644 --- a/src/runmode-unix-socket.c +++ b/src/runmode-unix-socket.c @@ -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 * diff --git a/src/runmode-unix-socket.h b/src/runmode-unix-socket.h index 469dc771c9..c2fa84aa32 100644 --- a/src/runmode-unix-socket.h +++ b/src/runmode-unix-socket.h @@ -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); diff --git a/src/unix-manager.c b/src/unix-manager.c index 3fdcb73fe5..95a0a8c14c 100644 --- a/src/unix-manager.c +++ b/src/unix-manager.c @@ -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; }