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)) {
114 const char *current_key = key;
115 json_t *current = json;
116 while (current_key) {
117 const char *dot = strchr(current_key,
'.');
119 size_t key_len = dot ? (size_t)(dot - current_key) : strlen(current_key);
120 char key_buffer[key_len + 1];
121 strlcpy(key_buffer, current_key, key_len + 1);
123 if (json_is_object(current) ==
false) {
126 current = json_object_get(current, key_buffer);
127 if (current == NULL) {
130 current_key = dot ? dot + 1 : NULL;
135 static int ParseJsonFile(
const char *file, json_t **array,
char *key)
140 json = json_load_file(file, 0, &error);
142 FatalErrorOnInit(
"can't load JSON, error on line %d: %s", error.line, error.text);
146 if (key == NULL || strlen(key) == 0) {
149 *array = GetSubObjectByKey(json, key);
150 if (*array == NULL) {
151 SCLogError(
"dataset: %s failed to get key '%s'", file, key);
158 if (!json_is_array(*array)) {
166 static int DatajsonSetValue(
167 Dataset *set,
const uint8_t *val, uint16_t val_len, json_t *value,
const char *json_key)
171 json_object_del(value, json_key);
174 elt.
value = json_dumps(value, JSON_COMPACT);
175 if (elt.
value == NULL) {
185 elt.
len = (uint16_t)strlen(elt.
value);
187 int add_ret = DatajsonAdd(set, val, val_len, &elt);
200 static int DatajsonAddString(
203 StringType lookup = { .
ptr = (uint8_t *)data, .
len = data_len, .json = *json };
206 DatajsonUnlockData(res.
data);
207 return res.
is_new ? 1 : 0;
212 static int DatajsonAddMd5(
222 DatajsonUnlockData(res.
data);
223 return res.
is_new ? 1 : 0;
228 static int DatajsonAddSha256(
238 DatajsonUnlockData(res.
data);
239 return res.
is_new ? 1 : 0;
244 static int DatajsonAddIPv4(
254 DatajsonUnlockData(res.
data);
255 return res.
is_new ? 1 : 0;
260 static int DatajsonAddIPv6(
270 DatajsonUnlockData(res.
data);
271 return res.
is_new ? 1 : 0;
291 static int DatajsonAdd(
296 if (json->
value == NULL)
300 if (json->
value != NULL) {
310 add_ret = DatajsonAddString(set,
data, data_len, json);
313 add_ret = DatajsonAddMd5(set,
data, data_len, json);
316 add_ret = DatajsonAddSha256(set,
data, data_len, json);
319 add_ret = DatajsonAddIPv4(set,
data, data_len, json);
322 add_ret = DatajsonAddIPv6(set,
data, data_len, json);
335 static int DatajsonLoadTypeFromJSON(
Dataset *set,
char *json_key,
char *array_key,
336 uint32_t (*DatajsonAddTypeElement)(
Dataset *, json_t *,
char *,
bool *))
338 if (strlen(set->
load) == 0)
346 SCLogDebug(
"dataset: array_key '%s' %p", array_key, array_key);
347 if (ParseJsonFile(set->
load, &json, array_key) == -1) {
354 json_array_foreach (json, index, value) {
355 cnt += DatajsonAddTypeElement(set, value, json_key, &found);
359 if (found ==
false) {
361 "No valid entries for key '%s' found in the file '%s'", json_key, set->
load);
370 static uint32_t DatajsonLoadTypeFromJsonline(
Dataset *set,
char *json_key,
371 uint32_t (*DatajsonAddTypeElement)(
Dataset *, json_t *,
char *,
bool *))
374 FILE *fp = fopen(set->
load,
"r");
383 while (fgets(line,
sizeof(line), fp) != NULL) {
384 json_t *json = json_loads(line, 0, NULL);
386 SCLogError(
"dataset: %s failed to parse line '%s'", set->
name, line);
389 cnt += DatajsonAddTypeElement(set, json, json_key, &found);
392 int close_op = fclose(fp);
398 if (found ==
false) {
400 "No valid entries for key '%s' found in the file '%s'", json_key, set->
load);
405 close_op = fclose(fp);
412 static uint32_t DatajsonAddStringElement(
Dataset *set, json_t *value,
char *json_key,
bool *found)
414 json_t *key = GetSubObjectByKey(value, json_key);
423 const char *val_key = json_string_value(key);
424 if (val_key == NULL) {
428 size_t val_len = strlen(val_key);
431 int ret = DatajsonSetValue(set, (
const uint8_t *)val_key, (uint16_t)val_len, value, json_key);
442 if (strlen(set->
load) == 0)
449 cnt = DatajsonLoadTypeFromJSON(set, json_key, array_key, DatajsonAddStringElement);
451 cnt = DatajsonLoadTypeFromJsonline(set, json_key, DatajsonAddStringElement);
459 static uint32_t DatajsonAddMd5Element(
Dataset *set, json_t *value,
char *json_key,
bool *found)
461 json_t *key = GetSubObjectByKey(value, json_key);
470 const char *hash_string = json_string_value(key);
471 if (strlen(hash_string) != SC_MD5_HEX_LEN) {
477 if (
HexToRaw((
const uint8_t *)hash_string, SC_MD5_HEX_LEN, hash,
sizeof(hash)) < 0) {
481 return DatajsonSetValue(set, hash,
SC_MD5_LEN, value, json_key);
486 if (strlen(set->
load) == 0)
493 cnt = DatajsonLoadTypeFromJSON(set, json_key, array_key, DatajsonAddMd5Element);
495 cnt = DatajsonLoadTypeFromJsonline(set, json_key, DatajsonAddMd5Element);
503 static uint32_t DatajsonAddSha256Element(
Dataset *set, json_t *value,
char *json_key,
bool *found)
505 json_t *key = GetSubObjectByKey(value, json_key);
514 const char *hash_string = json_string_value(key);
515 if (strlen(hash_string) != SC_SHA256_HEX_LEN) {
521 if (
HexToRaw((
const uint8_t *)hash_string, SC_SHA256_HEX_LEN, hash,
sizeof(hash)) < 0) {
526 return DatajsonSetValue(set, hash,
SC_SHA256_LEN, value, json_key);
531 if (strlen(set->
load) == 0)
538 cnt = DatajsonLoadTypeFromJSON(set, json_key, array_key, DatajsonAddSha256Element);
540 cnt = DatajsonLoadTypeFromJsonline(set, json_key, DatajsonAddSha256Element);
548 static uint32_t DatajsonAddIpv4Element(
Dataset *set, json_t *value,
char *json_key,
bool *found)
550 json_t *key = GetSubObjectByKey(value, json_key);
559 const char *ip_string = json_string_value(key);
561 if (inet_pton(AF_INET, ip_string, &in) != 1) {
566 return DatajsonSetValue(set, (
const uint8_t *)&in.s_addr,
SC_IPV4_LEN, value, json_key);
571 if (strlen(set->
load) == 0)
578 cnt = DatajsonLoadTypeFromJSON(set, json_key, array_key, DatajsonAddIpv4Element);
580 cnt = DatajsonLoadTypeFromJsonline(set, json_key, DatajsonAddIpv4Element);
588 static uint32_t DatajsonAddIPv6Element(
Dataset *set, json_t *value,
char *json_key,
bool *found)
590 json_t *key = GetSubObjectByKey(value, json_key);
599 const char *ip_string = json_string_value(key);
607 return DatajsonSetValue(set, (
const uint8_t *)&in6.s6_addr,
SC_IPV6_LEN, value, json_key);
612 if (strlen(set->
load) == 0)
620 cnt = DatajsonLoadTypeFromJSON(set, json_key, array_key, DatajsonAddIPv6Element);
622 cnt = DatajsonLoadTypeFromJsonline(set, json_key, DatajsonAddIPv6Element);
659 snprintf(cnf_name,
sizeof(cnf_name),
"datasets.%s.hash",
name);
665 if (set->
hash == NULL)
667 if (DatajsonLoadMd5(set, json_key_value, json_array_key, format) < 0)
674 if (set->
hash == NULL)
676 if (DatajsonLoadString(set, json_key_value, json_array_key, format) < 0) {
684 load != NULL ? 1 : 0, memcap,
hashsize);
685 if (set->
hash == NULL)
687 if (DatajsonLoadSha256(set, json_key_value, json_array_key, format) < 0)
693 if (set->
hash == NULL)
695 if (DatajsonLoadIPv4(set, json_key_value, json_array_key, format) < 0)
701 if (set->
hash == NULL)
703 if (DatajsonLoadIPv6(set, json_key_value, json_array_key, format) < 0)
709 "set %p/%s type %u save %s load %s", set, set->
name, set->
type, set->
save, set->
load);
728 Dataset *set,
const uint8_t *data,
const uint32_t data_len)
736 .ptr = (uint8_t *)data, .
len = data_len, .json.value = NULL, .json.len = 0
750 Dataset *set,
const uint8_t *data,
const uint32_t data_len)
761 memcpy(lookup.
md5, data, data_len);
774 Dataset *set,
const uint8_t *data,
const uint32_t data_len)
785 memcpy(lookup.
sha256, data, data_len);
798 Dataset *set,
const uint8_t *data,
const uint32_t data_len)
809 memcpy(lookup.
ipv4, data, data_len);
822 Dataset *set,
const uint8_t *data,
const uint32_t data_len)
834 memcpy(lookup.
ipv6, data, data_len);
854 return DatajsonLookupString(set, data, data_len);
856 return DatajsonLookupMd5(set, data, data_len);
858 return DatajsonLookupSha256(set, data, data_len);
860 return DatajsonLookupIPv4(set, data, data_len);
862 return DatajsonLookupIPv6(set, data, data_len);
880 if (strlen(value) == 0)
885 if (ParseJsonLine(json, strlen(json), &jvalue) < 0) {
894 uint32_t decoded_size = SCBase64DecodeBufferSize((uint32_t)strlen(value));
895 uint8_t decoded[decoded_size];
896 uint32_t num_decoded = SCBase64Decode(
897 (
const uint8_t *)value, strlen(value), SCBase64ModeStrict, decoded);
898 if (num_decoded == 0)
900 ret = DatajsonAdd(set, decoded, num_decoded, &jvalue);
904 if (strlen(value) != SC_MD5_HEX_LEN)
907 if (
HexToRaw((
const uint8_t *)value, SC_MD5_HEX_LEN, hash,
sizeof(hash)) < 0)
909 ret = DatajsonAdd(set, hash,
SC_MD5_LEN, &jvalue);
913 if (strlen(value) != SC_SHA256_HEX_LEN)
916 if (
HexToRaw((
const uint8_t *)value, SC_SHA256_HEX_LEN, hash,
sizeof(hash)) < 0)
923 if (inet_pton(AF_INET, value, &in) != 1)
925 ret = DatajsonAdd(set, (uint8_t *)&in.s_addr,
SC_IPV4_LEN, &jvalue);
931 SCLogError(
"Dataset failed to import %s as IPv6", value);
934 ret = DatajsonAdd(set, (uint8_t *)&in6.s6_addr,
SC_IPV6_LEN, &jvalue);