38 static int DatajsonAdd(
41 static inline void DatajsonUnlockData(
THashData *d)
58 if (
dst->value == NULL)
61 dst->value[
dst->len] =
'\0';
66 static bool IsFloat(
const char *in,
size_t ins)
69 float val = strtof(in, &endptr);
70 const char *end_ins = in + ins - 1;
71 if (val != 0 && (endptr == end_ins)) {
75 return val != 0 || endptr != in;
78 static int ParseJsonLine(
const char *in,
size_t ins,
DataJsonType *rep_out)
81 SCLogError(
"dataset: json string too long: %s", in);
86 json_t *msg = json_loads(in, 0, &jerror);
90 if (!IsFloat(in, ins) && !((in[0] ==
'"') && (in[ins - 1] ==
'"'))) {
91 SCLogError(
"dataset: Invalid json: %s: '%s'", jerror.text, in);
97 rep_out->
len = (uint16_t)ins;
99 if (rep_out->
value == NULL) {
105 static json_t *GetSubObjectByKey(json_t *json,
const char *key)
107 if (!json || !key || !json_is_object(json)) {
115 const char *current_key = key;
116 json_t *current = json;
117 while (current_key) {
118 const char *dot = strchr(current_key,
'.');
120 size_t key_len = dot ? (size_t)(dot - current_key) : strlen(current_key);
121 char key_buffer[key_len + 1];
122 strlcpy(key_buffer, current_key, key_len + 1);
124 if (json_is_object(current) ==
false) {
127 current = json_object_get(current, key_buffer);
128 if (current == NULL) {
131 current_key = dot ? dot + 1 : NULL;
136 static int ParseJsonFile(
const char *file, json_t **array,
char *key)
141 json = json_load_file(file, 0, &error);
143 FatalErrorOnInit(
"can't load JSON, error on line %d: %s", error.line, error.text);
147 if (key == NULL || strlen(key) == 0) {
150 *array = GetSubObjectByKey(json, key);
151 if (*array == NULL) {
152 SCLogError(
"dataset: %s failed to get key '%s'", file, key);
159 if (!json_is_array(*array)) {
167 static int DatajsonSetValue(
168 Dataset *set,
const uint8_t *val, uint16_t val_len, json_t *value,
const char *json_key)
172 json_object_del(value, json_key);
175 elt.
value = json_dumps(value, JSON_COMPACT);
176 if (elt.
value == NULL) {
186 elt.
len = (uint16_t)strlen(elt.
value);
188 int add_ret = DatajsonAdd(set, val, val_len, &elt);
201 static int DatajsonAddString(
204 StringType lookup = { .
ptr = (uint8_t *)data, .
len = data_len, .json = *json };
207 DatajsonUnlockData(res.
data);
208 return res.
is_new ? 1 : 0;
213 static int DatajsonAddMd5(
223 DatajsonUnlockData(res.
data);
224 return res.
is_new ? 1 : 0;
229 static int DatajsonAddSha256(
239 DatajsonUnlockData(res.
data);
240 return res.
is_new ? 1 : 0;
245 static int DatajsonAddIPv4(
255 DatajsonUnlockData(res.
data);
256 return res.
is_new ? 1 : 0;
261 static int DatajsonAddIPv6(
271 DatajsonUnlockData(res.
data);
272 return res.
is_new ? 1 : 0;
292 static int DatajsonAdd(
297 if (json->
value == NULL)
301 if (json->
value != NULL) {
311 add_ret = DatajsonAddString(set,
data, data_len, json);
314 add_ret = DatajsonAddMd5(set,
data, data_len, json);
317 add_ret = DatajsonAddSha256(set,
data, data_len, json);
320 add_ret = DatajsonAddIPv4(set,
data, data_len, json);
323 add_ret = DatajsonAddIPv6(set,
data, data_len, json);
336 static int DatajsonLoadTypeFromJSON(
Dataset *set,
char *json_key,
char *array_key,
337 uint32_t (*DatajsonAddTypeElement)(
Dataset *, json_t *,
char *,
bool *))
339 if (strlen(set->
load) == 0)
347 SCLogDebug(
"dataset: array_key '%s' %p", array_key, array_key);
348 if (ParseJsonFile(set->
load, &json, array_key) == -1) {
355 json_array_foreach (json, index, value) {
356 cnt += DatajsonAddTypeElement(set, value, json_key, &found);
360 if (found ==
false) {
362 "No valid entries for key '%s' found in the file '%s'", json_key, set->
load);
371 static uint32_t DatajsonLoadTypeFromJsonline(
Dataset *set,
char *json_key,
372 uint32_t (*DatajsonAddTypeElement)(
Dataset *, json_t *,
char *,
bool *))
375 FILE *fp = fopen(set->
load,
"r");
384 while (fgets(line,
sizeof(line), fp) != NULL) {
385 json_t *json = json_loads(line, 0, NULL);
387 SCLogError(
"dataset: %s failed to parse line '%s'", set->
name, line);
390 cnt += DatajsonAddTypeElement(set, json, json_key, &found);
393 int close_op = fclose(fp);
399 if (found ==
false) {
401 "No valid entries for key '%s' found in the file '%s'", json_key, set->
load);
406 close_op = fclose(fp);
413 static uint32_t DatajsonAddStringElement(
Dataset *set, json_t *value,
char *json_key,
bool *found)
415 json_t *key = GetSubObjectByKey(value, json_key);
423 if (!json_is_string(key)) {
428 const char *val_key = json_string_value(key);
429 if (val_key == NULL) {
433 size_t val_len = strlen(val_key);
436 int ret = DatajsonSetValue(set, (
const uint8_t *)val_key, (uint16_t)val_len, value, json_key);
447 if (strlen(set->
load) == 0)
454 cnt = DatajsonLoadTypeFromJSON(set, json_key, array_key, DatajsonAddStringElement);
456 cnt = DatajsonLoadTypeFromJsonline(set, json_key, DatajsonAddStringElement);
464 static uint32_t DatajsonAddMd5Element(
Dataset *set, json_t *value,
char *json_key,
bool *found)
466 json_t *key = GetSubObjectByKey(value, json_key);
475 if (!json_is_string(key)) {
479 const char *hash_string = json_string_value(key);
480 if (strlen(hash_string) != SC_MD5_HEX_LEN) {
486 if (
HexToRaw((
const uint8_t *)hash_string, SC_MD5_HEX_LEN, hash,
sizeof(hash)) < 0) {
490 return DatajsonSetValue(set, hash,
SC_MD5_LEN, value, json_key);
495 if (strlen(set->
load) == 0)
502 cnt = DatajsonLoadTypeFromJSON(set, json_key, array_key, DatajsonAddMd5Element);
504 cnt = DatajsonLoadTypeFromJsonline(set, json_key, DatajsonAddMd5Element);
512 static uint32_t DatajsonAddSha256Element(
Dataset *set, json_t *value,
char *json_key,
bool *found)
514 json_t *key = GetSubObjectByKey(value, json_key);
523 if (!json_is_string(key)) {
527 const char *hash_string = json_string_value(key);
528 if (strlen(hash_string) != SC_SHA256_HEX_LEN) {
534 if (
HexToRaw((
const uint8_t *)hash_string, SC_SHA256_HEX_LEN, hash,
sizeof(hash)) < 0) {
539 return DatajsonSetValue(set, hash,
SC_SHA256_LEN, value, json_key);
544 if (strlen(set->
load) == 0)
551 cnt = DatajsonLoadTypeFromJSON(set, json_key, array_key, DatajsonAddSha256Element);
553 cnt = DatajsonLoadTypeFromJsonline(set, json_key, DatajsonAddSha256Element);
561 static uint32_t DatajsonAddIpv4Element(
Dataset *set, json_t *value,
char *json_key,
bool *found)
563 json_t *key = GetSubObjectByKey(value, json_key);
572 if (!json_is_string(key)) {
576 const char *ip_string = json_string_value(key);
578 if (inet_pton(AF_INET, ip_string, &in) != 1) {
583 return DatajsonSetValue(set, (
const uint8_t *)&in.s_addr,
SC_IPV4_LEN, value, json_key);
588 if (strlen(set->
load) == 0)
595 cnt = DatajsonLoadTypeFromJSON(set, json_key, array_key, DatajsonAddIpv4Element);
597 cnt = DatajsonLoadTypeFromJsonline(set, json_key, DatajsonAddIpv4Element);
605 static uint32_t DatajsonAddIPv6Element(
Dataset *set, json_t *value,
char *json_key,
bool *found)
607 json_t *key = GetSubObjectByKey(value, json_key);
616 if (!json_is_string(key)) {
620 const char *ip_string = json_string_value(key);
628 return DatajsonSetValue(set, (
const uint8_t *)&in6.s6_addr,
SC_IPV6_LEN, value, json_key);
633 if (strlen(set->
load) == 0)
641 cnt = DatajsonLoadTypeFromJSON(set, json_key, array_key, DatajsonAddIPv6Element);
643 cnt = DatajsonLoadTypeFromJsonline(set, json_key, DatajsonAddIPv6Element);
680 snprintf(cnf_name,
sizeof(cnf_name),
"datasets.%s.hash",
name);
686 if (set->
hash == NULL)
688 if (DatajsonLoadMd5(set, json_key_value, json_array_key, format) < 0)
695 if (set->
hash == NULL)
697 if (DatajsonLoadString(set, json_key_value, json_array_key, format) < 0) {
705 load != NULL ? 1 : 0, memcap,
hashsize);
706 if (set->
hash == NULL)
708 if (DatajsonLoadSha256(set, json_key_value, json_array_key, format) < 0)
714 if (set->
hash == NULL)
716 if (DatajsonLoadIPv4(set, json_key_value, json_array_key, format) < 0)
722 if (set->
hash == NULL)
724 if (DatajsonLoadIPv6(set, json_key_value, json_array_key, format) < 0)
730 "set %p/%s type %u save %s load %s", set, set->
name, set->
type, set->
save, set->
load);
749 Dataset *set,
const uint8_t *data,
const uint32_t data_len)
757 .ptr = (uint8_t *)data, .
len = data_len, .json.value = NULL, .json.len = 0
771 Dataset *set,
const uint8_t *data,
const uint32_t data_len)
782 memcpy(lookup.
md5, data, data_len);
795 Dataset *set,
const uint8_t *data,
const uint32_t data_len)
806 memcpy(lookup.
sha256, data, data_len);
819 Dataset *set,
const uint8_t *data,
const uint32_t data_len)
830 memcpy(lookup.
ipv4, data, data_len);
843 Dataset *set,
const uint8_t *data,
const uint32_t data_len)
855 memcpy(lookup.
ipv6, data, data_len);
875 return DatajsonLookupString(set, data, data_len);
877 return DatajsonLookupMd5(set, data, data_len);
879 return DatajsonLookupSha256(set, data, data_len);
881 return DatajsonLookupIPv4(set, data, data_len);
883 return DatajsonLookupIPv6(set, data, data_len);
901 if (strlen(value) == 0)
906 if (ParseJsonLine(json, strlen(json), &jvalue) < 0) {
915 if (strlen(value) > UINT16_MAX) {
921 uint32_t decoded_size = SCBase64DecodeBufferSize((uint32_t)strlen(value));
922 uint8_t decoded[decoded_size];
923 uint32_t num_decoded = SCBase64Decode(
924 (
const uint8_t *)value, strlen(value), SCBase64ModeStrict, decoded);
925 if (num_decoded == 0)
927 ret = DatajsonAdd(set, decoded, num_decoded, &jvalue);
931 if (strlen(value) != SC_MD5_HEX_LEN)
934 if (
HexToRaw((
const uint8_t *)value, SC_MD5_HEX_LEN, hash,
sizeof(hash)) < 0)
936 ret = DatajsonAdd(set, hash,
SC_MD5_LEN, &jvalue);
940 if (strlen(value) != SC_SHA256_HEX_LEN)
943 if (
HexToRaw((
const uint8_t *)value, SC_SHA256_HEX_LEN, hash,
sizeof(hash)) < 0)
950 if (inet_pton(AF_INET, value, &in) != 1)
952 ret = DatajsonAdd(set, (uint8_t *)&in.s_addr,
SC_IPV4_LEN, &jvalue);
958 SCLogError(
"Dataset failed to import %s as IPv6", value);
961 ret = DatajsonAdd(set, (uint8_t *)&in6.s6_addr,
SC_IPV6_LEN, &jvalue);