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 if (val == 0 && (endptr == in)) {
81 static int ParseJsonLine(
const char *in,
size_t ins,
DataJsonType *rep_out)
84 SCLogError(
"dataset: json string too long: %s", in);
89 json_t *msg = json_loads(in, 0, &jerror);
93 if (!IsFloat(in, ins) && !((in[0] ==
'"') && (in[ins - 1] ==
'"'))) {
94 SCLogError(
"dataset: Invalid json: %s: '%s'", jerror.text, in);
100 rep_out->
len = (uint16_t)ins;
102 if (rep_out->
value == NULL) {
108 static json_t *GetSubObjectByKey(json_t *json,
const char *key)
110 if (!json || !key || !json_is_object(json)) {
118 const char *current_key = key;
119 json_t *current = json;
120 while (current_key) {
121 const char *dot = strchr(current_key,
'.');
123 size_t key_len = dot ? (size_t)(dot - current_key) : strlen(current_key);
124 char key_buffer[key_len + 1];
125 strlcpy(key_buffer, current_key, key_len + 1);
127 if (json_is_object(current) ==
false) {
130 current = json_object_get(current, key_buffer);
131 if (current == NULL) {
134 current_key = dot ? dot + 1 : NULL;
139 static int ParseJsonFile(
const char *file, json_t **array,
char *key)
144 json = json_load_file(file, 0, &error);
146 FatalErrorOnInit(
"can't load JSON, error on line %d: %s", error.line, error.text);
150 if (key == NULL || strlen(key) == 0) {
153 *array = GetSubObjectByKey(json, key);
154 if (*array == NULL) {
155 SCLogError(
"dataset: %s failed to get key '%s'", file, key);
162 if (!json_is_array(*array)) {
170 static int DatajsonSetValue(
171 Dataset *set,
const uint8_t *val, uint16_t val_len, json_t *value,
const char *json_key)
175 json_object_del(value, json_key);
178 elt.
value = json_dumps(value, JSON_COMPACT);
179 if (elt.
value == NULL) {
189 elt.
len = (uint16_t)strlen(elt.
value);
191 int add_ret = DatajsonAdd(set, val, val_len, &elt);
204 static int DatajsonAddString(
207 StringType lookup = { .
ptr = (uint8_t *)data, .
len = data_len, .json = *json };
210 DatajsonUnlockData(res.
data);
211 return res.
is_new ? 1 : 0;
216 static int DatajsonAddMd5(
226 DatajsonUnlockData(res.
data);
227 return res.
is_new ? 1 : 0;
232 static int DatajsonAddSha256(
242 DatajsonUnlockData(res.
data);
243 return res.
is_new ? 1 : 0;
248 static int DatajsonAddIPv4(
258 DatajsonUnlockData(res.
data);
259 return res.
is_new ? 1 : 0;
264 static int DatajsonAddIPv6(
274 DatajsonUnlockData(res.
data);
275 return res.
is_new ? 1 : 0;
295 static int DatajsonAdd(
300 if (json->
value == NULL)
304 if (json->
value != NULL) {
314 add_ret = DatajsonAddString(set,
data, data_len, json);
317 add_ret = DatajsonAddMd5(set,
data, data_len, json);
320 add_ret = DatajsonAddSha256(set,
data, data_len, json);
323 add_ret = DatajsonAddIPv4(set,
data, data_len, json);
326 add_ret = DatajsonAddIPv6(set,
data, data_len, json);
339 static int DatajsonLoadTypeFromJSON(
Dataset *set,
char *json_key,
char *array_key,
340 uint32_t (*DatajsonAddTypeElement)(
Dataset *, json_t *,
char *,
bool *))
342 if (strlen(set->
load) == 0)
350 SCLogDebug(
"dataset: array_key '%s' %p", array_key, array_key);
351 if (ParseJsonFile(set->
load, &json, array_key) == -1) {
358 json_array_foreach (json, index, value) {
359 cnt += DatajsonAddTypeElement(set, value, json_key, &found);
363 if (found ==
false) {
365 "No valid entries for key '%s' found in the file '%s'", json_key, set->
load);
374 static uint32_t DatajsonLoadTypeFromJsonline(
Dataset *set,
char *json_key,
375 uint32_t (*DatajsonAddTypeElement)(
Dataset *, json_t *,
char *,
bool *))
378 FILE *fp = fopen(set->
load,
"r");
387 while (fgets(line,
sizeof(line), fp) != NULL) {
388 json_t *json = json_loads(line, 0, NULL);
390 SCLogError(
"dataset: %s failed to parse line '%s'", set->
name, line);
393 cnt += DatajsonAddTypeElement(set, json, json_key, &found);
396 int close_op = fclose(fp);
402 if (found ==
false) {
404 "No valid entries for key '%s' found in the file '%s'", json_key, set->
load);
409 close_op = fclose(fp);
416 static uint32_t DatajsonAddStringElement(
Dataset *set, json_t *value,
char *json_key,
bool *found)
418 json_t *key = GetSubObjectByKey(value, json_key);
427 const char *val_key = json_string_value(key);
428 if (val_key == NULL) {
432 size_t val_len = strlen(val_key);
435 int ret = DatajsonSetValue(set, (
const uint8_t *)val_key, (uint16_t)val_len, value, json_key);
446 if (strlen(set->
load) == 0)
453 cnt = DatajsonLoadTypeFromJSON(set, json_key, array_key, DatajsonAddStringElement);
455 cnt = DatajsonLoadTypeFromJsonline(set, json_key, DatajsonAddStringElement);
463 static uint32_t DatajsonAddMd5Element(
Dataset *set, json_t *value,
char *json_key,
bool *found)
465 json_t *key = GetSubObjectByKey(value, json_key);
474 const char *hash_string = json_string_value(key);
475 if (strlen(hash_string) != SC_MD5_HEX_LEN) {
481 if (
HexToRaw((
const uint8_t *)hash_string, SC_MD5_HEX_LEN, hash,
sizeof(hash)) < 0) {
485 return DatajsonSetValue(set, hash,
SC_MD5_LEN, value, json_key);
490 if (strlen(set->
load) == 0)
497 cnt = DatajsonLoadTypeFromJSON(set, json_key, array_key, DatajsonAddMd5Element);
499 cnt = DatajsonLoadTypeFromJsonline(set, json_key, DatajsonAddMd5Element);
507 static uint32_t DatajsonAddSha256Element(
Dataset *set, json_t *value,
char *json_key,
bool *found)
509 json_t *key = GetSubObjectByKey(value, json_key);
518 const char *hash_string = json_string_value(key);
519 if (strlen(hash_string) != SC_SHA256_HEX_LEN) {
525 if (
HexToRaw((
const uint8_t *)hash_string, SC_SHA256_HEX_LEN, hash,
sizeof(hash)) < 0) {
530 return DatajsonSetValue(set, hash,
SC_SHA256_LEN, value, json_key);
535 if (strlen(set->
load) == 0)
542 cnt = DatajsonLoadTypeFromJSON(set, json_key, array_key, DatajsonAddSha256Element);
544 cnt = DatajsonLoadTypeFromJsonline(set, json_key, DatajsonAddSha256Element);
552 static uint32_t DatajsonAddIpv4Element(
Dataset *set, json_t *value,
char *json_key,
bool *found)
554 json_t *key = GetSubObjectByKey(value, json_key);
563 const char *ip_string = json_string_value(key);
565 if (inet_pton(AF_INET, ip_string, &in) != 1) {
570 return DatajsonSetValue(set, (
const uint8_t *)&in.s_addr,
SC_IPV4_LEN, value, json_key);
575 if (strlen(set->
load) == 0)
582 cnt = DatajsonLoadTypeFromJSON(set, json_key, array_key, DatajsonAddIpv4Element);
584 cnt = DatajsonLoadTypeFromJsonline(set, json_key, DatajsonAddIpv4Element);
592 static uint32_t DatajsonAddIPv6Element(
Dataset *set, json_t *value,
char *json_key,
bool *found)
594 json_t *key = GetSubObjectByKey(value, json_key);
603 const char *ip_string = json_string_value(key);
611 return DatajsonSetValue(set, (
const uint8_t *)&in6.s6_addr,
SC_IPV6_LEN, value, json_key);
616 if (strlen(set->
load) == 0)
624 cnt = DatajsonLoadTypeFromJSON(set, json_key, array_key, DatajsonAddIPv6Element);
626 cnt = DatajsonLoadTypeFromJsonline(set, json_key, DatajsonAddIPv6Element);
663 snprintf(cnf_name,
sizeof(cnf_name),
"datasets.%s.hash",
name);
669 if (set->
hash == NULL)
671 if (DatajsonLoadMd5(set, json_key_value, json_array_key, format) < 0)
678 if (set->
hash == NULL)
680 if (DatajsonLoadString(set, json_key_value, json_array_key, format) < 0) {
688 load != NULL ? 1 : 0, memcap,
hashsize);
689 if (set->
hash == NULL)
691 if (DatajsonLoadSha256(set, json_key_value, json_array_key, format) < 0)
697 if (set->
hash == NULL)
699 if (DatajsonLoadIPv4(set, json_key_value, json_array_key, format) < 0)
705 if (set->
hash == NULL)
707 if (DatajsonLoadIPv6(set, json_key_value, json_array_key, format) < 0)
713 "set %p/%s type %u save %s load %s", set, set->
name, set->
type, set->
save, set->
load);
732 Dataset *set,
const uint8_t *data,
const uint32_t data_len)
740 .ptr = (uint8_t *)data, .
len = data_len, .json.value = NULL, .json.len = 0
754 Dataset *set,
const uint8_t *data,
const uint32_t data_len)
765 memcpy(lookup.
md5, data, data_len);
778 Dataset *set,
const uint8_t *data,
const uint32_t data_len)
789 memcpy(lookup.
sha256, data, data_len);
802 Dataset *set,
const uint8_t *data,
const uint32_t data_len)
813 memcpy(lookup.
ipv4, data, data_len);
826 Dataset *set,
const uint8_t *data,
const uint32_t data_len)
838 memcpy(lookup.
ipv6, data, data_len);
858 return DatajsonLookupString(set, data, data_len);
860 return DatajsonLookupMd5(set, data, data_len);
862 return DatajsonLookupSha256(set, data, data_len);
864 return DatajsonLookupIPv4(set, data, data_len);
866 return DatajsonLookupIPv6(set, data, data_len);
884 if (strlen(value) == 0)
889 if (ParseJsonLine(json, strlen(json), &jvalue) < 0) {
898 uint32_t decoded_size = SCBase64DecodeBufferSize((uint32_t)strlen(value));
899 uint8_t decoded[decoded_size];
900 uint32_t num_decoded = SCBase64Decode(
901 (
const uint8_t *)value, strlen(value), SCBase64ModeStrict, decoded);
902 if (num_decoded == 0)
904 ret = DatajsonAdd(set, decoded, num_decoded, &jvalue);
908 if (strlen(value) != SC_MD5_HEX_LEN)
911 if (
HexToRaw((
const uint8_t *)value, SC_MD5_HEX_LEN, hash,
sizeof(hash)) < 0)
913 ret = DatajsonAdd(set, hash,
SC_MD5_LEN, &jvalue);
917 if (strlen(value) != SC_SHA256_HEX_LEN)
920 if (
HexToRaw((
const uint8_t *)value, SC_SHA256_HEX_LEN, hash,
sizeof(hash)) < 0)
927 if (inet_pton(AF_INET, value, &in) != 1)
929 ret = DatajsonAdd(set, (uint8_t *)&in.s_addr,
SC_IPV4_LEN, &jvalue);
935 SCLogError(
"Dataset failed to import %s as IPv6", value);
938 ret = DatajsonAdd(set, (uint8_t *)&in6.s6_addr,
SC_IPV6_LEN, &jvalue);