Go to the documentation of this file.
47 #define DETECT_DATASET_CMD_SET 0
48 #define DETECT_DATASET_CMD_UNSET 1
49 #define DETECT_DATASET_CMD_ISNOTSET 2
50 #define DETECT_DATASET_CMD_ISSET 3
52 #define DATASET_SUBDOMAIN_MAX_LOOKUPS 126
69 Dataset *set,
const uint8_t *data,
const uint32_t data_len)
72 .
found =
false, .json = { .value = NULL, .len = 0 }, .hashdata = NULL
75 for (uint32_t i = 1; i < data_len; i++) {
76 if (data[i] ==
'.' && data[i - 1] !=
'.') {
92 const uint8_t *data,
const uint32_t data_len)
94 if (data == NULL || data_len == 0)
103 r = DatajsonLookupSubdomain(sd->
set, data, data_len);
131 r = DatajsonLookupSubdomain(sd->
set, data, data_len);
146 static int DatasetLookupSubdomain(
Dataset *set,
const uint8_t *data,
const uint32_t data_len)
149 for (uint32_t i = 1; i < data_len; i++) {
150 if (data[i] ==
'.' && data[i - 1] !=
'.') {
167 const uint8_t *data,
const uint32_t data_len)
169 if (data == NULL || data_len == 0)
173 return DetectDatajsonBufferMatch(det_ctx, sd, data, data_len);
181 r = DatasetLookupSubdomain(sd->
set, data, data_len);
192 r = DatasetLookupSubdomain(sd->
set, data, data_len);
218 static int DetectDatasetParse(
const char *
str,
char *cmd,
int cmd_len,
char *
name,
int name_len,
219 enum DatasetTypes *
type,
char *load,
size_t load_size,
char *save,
size_t save_size,
221 size_t value_key_size,
char *array_key,
size_t array_key_size,
char *enrichment_key,
222 size_t enrichment_key_size,
bool *remove_key,
bool *match_subdomain)
224 bool cmd_set =
false;
225 bool name_set =
false;
226 bool load_set =
false;
227 bool save_set =
false;
228 bool state_set =
false;
229 bool format_set =
false;
231 char copy[strlen(
str)+1];
233 char *xsaveptr = NULL;
234 char *key = strtok_r(copy,
",", &xsaveptr);
236 while (key != NULL) {
237 while (*key !=
'\0' && isblank(*key)) {
240 char *val = strchr(key,
' ');
243 while (*val !=
'\0' && isblank(*val)) {
251 if (strlen(key) == 0) {
256 if (val && strlen(val) != 0) {
261 }
else if (!name_set) {
262 if (val && strlen(val) != 0) {
270 if (strcmp(key,
"remove_key") == 0) {
274 }
else if (strcmp(key,
"match") == 0) {
275 if (strcmp(val,
"subdomain") == 0) {
276 *match_subdomain =
true;
281 }
else if (strcmp(key,
"type") == 0) {
284 if (strcmp(val,
"md5") == 0) {
286 }
else if (strcmp(val,
"sha256") == 0) {
288 }
else if (strcmp(val,
"string") == 0) {
290 }
else if (strcmp(val,
"ipv4") == 0) {
292 }
else if (strcmp(val,
"ipv6") == 0) {
294 }
else if (strcmp(val,
"ip") == 0) {
301 }
else if (strcmp(key,
"save") == 0) {
309 }
else if (strcmp(key,
"load") == 0) {
317 }
else if (strcmp(key,
"state") == 0) {
326 }
else if (strcmp(key,
"format") == 0) {
332 if (strcmp(val,
"csv") == 0) {
334 }
else if (strcmp(val,
"ndjson") == 0) {
336 }
else if (strcmp(val,
"json") == 0) {
343 }
else if (strcmp(key,
"value_key") == 0) {
344 if (strlen(val) > value_key_size) {
345 SCLogError(
"'key' value too long (limit is %zu)", value_key_size);
348 strlcpy(value_key, val, value_key_size);
349 }
else if (strcmp(key,
"array_key") == 0) {
350 if (strlen(val) > array_key_size) {
351 SCLogError(
"'key' value too long (limit is %zu)", array_key_size);
354 strlcpy(array_key, val, array_key_size);
355 }
else if (strcmp(key,
"context_key") == 0) {
356 for (
size_t i = 0; i < strlen(val); i++) {
357 if (!isalnum(val[i]) && val[i] !=
'_') {
358 SCLogError(
"context_key can only contain alphanumeric characters and "
363 if (strlen(val) > enrichment_key_size) {
364 SCLogError(
"'key' value too long (limit is %zu)", enrichment_key_size);
367 strlcpy(enrichment_key, val, enrichment_key_size);
370 if (strcmp(key,
"memcap") == 0) {
373 " resetting to default",
378 if (strcmp(key,
"hashsize") == 0) {
381 " resetting to default",
391 key = strtok_r(NULL,
",", &xsaveptr);
394 if ((load_set || save_set) && state_set) {
395 SCLogError(
"'state' can not be mixed with 'load' and 'save'");
400 while (strlen(
name) > 0 && isblank(
name[strlen(
name) - 1])) {
405 for (
size_t i = 0; i < strlen(
name); i++) {
406 if (isblank(
name[i])) {
407 SCLogError(
"spaces not allowed in dataset names");
416 static void GetDirName(
const char *in,
char *out,
size_t outs)
418 if (strlen(in) == 0) {
422 size_t size = strlen(in) + 1;
426 char *dir = dirname(tmp);
432 char *load,
size_t load_size)
444 char dir[PATH_MAX] =
"";
449 if (
PathMerge(path,
sizeof(path), dir, load) < 0)
454 strlcpy(load, path, load_size);
455 SCLogDebug(
"using path '%s' (HAVE_LIBGEN_H)", load);
466 strlcpy(load, loadp, load_size);
467 SCLogDebug(
"using path '%s' (non-HAVE_LIBGEN_H)", load);
475 char *save,
size_t save_size)
480 if (
SCConfGetBool(
"datasets.rules.allow-write", &allow_save)) {
482 SCLogError(
"Rules containing save/state datasets have been disabled");
487 int allow_absolute = 0;
488 (void)
SCConfGetBool(
"datasets.rules.allow-absolute-filenames", &allow_absolute);
489 if (allow_absolute) {
490 SCLogNotice(
"Allowing absolute filename for dataset rule: %s", save);
493 SCLogError(
"Absolute paths not allowed: %s", save);
498 SCLogError(
"Directory traversals not allowed: %s", save);
508 if (
PathMerge(path,
sizeof(path), dir, save) < 0)
513 strlcpy(save, path, save_size);
527 char load[PATH_MAX] =
"";
528 char save[PATH_MAX] =
"";
533 bool remove_key =
false;
534 bool match_subdomain =
false;
537 SCLogError(
"datasets are only supported for sticky buffers");
543 SCLogError(
"datasets are only supported for sticky buffers");
547 if (!DetectDatasetParse(rawstr, cmd_str,
sizeof(cmd_str),
name,
sizeof(
name), &
type, load,
548 sizeof(load), save,
sizeof(save), &memcap, &
hashsize, &format, value_key,
549 sizeof(value_key), array_key,
sizeof(array_key), enrichment_key,
550 sizeof(enrichment_key), &remove_key, &match_subdomain)) {
554 if (strcmp(cmd_str,
"isset") == 0) {
556 }
else if (strcmp(cmd_str,
"isnotset") == 0) {
558 }
else if (strcmp(cmd_str,
"set") == 0) {
560 SCLogError(
"json format is not supported for 'set' command");
564 }
else if (strcmp(cmd_str,
"unset") == 0) {
566 SCLogError(
"json format is not supported for 'unset' command");
571 SCLogError(
"dataset action \"%s\" is not supported.", cmd_str);
575 if (match_subdomain) {
577 SCLogError(
"'match subdomain' only supports isset/isnotset commands");
581 SCLogError(
"'match subdomain' only supports type string");
587 if (strlen(save) != 0) {
588 SCLogError(
"json format is not supported with 'save' or 'state' option");
591 if (strlen(enrichment_key) == 0) {
592 SCLogError(
"json format needs a 'context_key' parameter");
595 if (strlen(value_key) == 0) {
596 SCLogError(
"json format needs a 'value_key' parameter");
603 if (strlen(save) == 0 && strlen(load) != 0) {
604 if (SetupLoadPath(
de_ctx, load,
sizeof(load)) != 0)
608 }
else if (strlen(save) != 0 && strlen(load) == 0) {
609 if (SetupSavePath(
de_ctx, save,
sizeof(save)) != 0)
613 }
else if (strlen(save) != 0 && strlen(load) != 0 &&
614 strcmp(save, load) == 0) {
615 if (SetupSavePath(
de_ctx, save,
sizeof(save)) != 0)
617 strlcpy(load, save,
sizeof(load));
618 }
else if (strlen(save) != 0 && strlen(load) != 0) {
621 if (SetupSavePath(
de_ctx, save,
sizeof(save)) != 0)
623 if (SetupLoadPath(
de_ctx, load,
sizeof(load)) != 0)
658 cmd_str, strlen(
name) ?
name :
"(none)");
DataJsonResultType DatajsonLookup(Dataset *set, const uint8_t *data, const uint32_t data_len)
SigTableElmt * sigmatch_table
void(* Free)(DetectEngineCtx *, void *)
#define DETECT_DATASET_CMD_SET
int PathMerge(char *out_buf, size_t buf_size, const char *const dir, const char *const fname)
int ParseSizeStringU64(const char *size, uint64_t *res)
struct HtpBodyChunk_ * next
main detection engine ctx
int SCConfGetBool(const char *name, int *val)
Retrieve a configuration value as a boolean.
const char * ConfigGetDataDirectory(void)
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
#define SIG_JSON_CONTENT_ITEM_LEN
void DatajsonUnlockElt(DataJsonResultType *r)
#define DETECT_DATASET_CMD_ISSET
size_t strlcpy(char *dst, const char *src, size_t siz)
Dataset * DatasetGet(const char *name, enum DatasetTypes type, const char *save, const char *load, uint64_t memcap, uint32_t hashsize)
bool SCPathContainsTraversal(const char *path)
Check for directory traversal.
int DatasetRemove(Dataset *set, const uint8_t *data, const uint32_t data_len)
#define SIG_JSON_CONTENT_KEY_LEN
void DetectDatasetFree(DetectEngineCtx *, void *)
#define DATASET_TYPE_NOTSET
SigMatch * SCSigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
#define SCLogWarning(...)
Macro used to log WARNING messages.
uint8_t json_content_capacity
void DetectDatasetRegister(void)
int SCDatasetAdd(Dataset *set, const uint8_t *data, const uint32_t data_len)
SignatureInitData * init_data
int DatasetLookup(Dataset *set, const uint8_t *data, const uint32_t data_len)
see if data is part of the set
Data structures and function prototypes for keeping state for the detection engine.
int DetectEngineThreadCtxGetJsonContext(DetectEngineThreadCtx *det_ctx)
char json_key[SIG_JSON_CONTENT_KEY_LEN]
#define DATASET_SUBDOMAIN_MAX_LOOKUPS
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
#define DETECT_SM_LIST_NOTSET
bool SCPathExists(const char *path)
Check if a path exists.
int DetectDatasetBufferMatch(DetectEngineThreadCtx *det_ctx, const DetectDatasetData *sd, const uint8_t *data, const uint32_t data_len)
#define DATASET_NAME_MAX_LEN
#define DETECT_DATASET_CMD_UNSET
int PathIsAbsolute(const char *path)
Check if a path is absolute.
int ParseSizeStringU32(const char *size, uint32_t *res)
SigJsonContent * json_content
#define SCLogError(...)
Macro used to log ERROR messages.
Dataset * DatajsonGet(const char *name, enum DatasetTypes type, const char *load, uint64_t memcap, uint32_t hashsize, char *json_key_value, char *json_array_key, DatasetFormats format, bool remove_key)
#define DETECT_DATASET_CMD_ISNOTSET
#define SIGMATCH_SUPPORT_FIREWALL
char * DetectLoadCompleteSigPath(const DetectEngineCtx *de_ctx, const char *sig_file)
Create the path if default-rule-path was specified.
#define SCLogNotice(...)
Macro used to log NOTICE messages.
int DetectBufferGetActiveList(DetectEngineCtx *de_ctx, Signature *s)
#define DEBUG_VALIDATE_BUG_ON(exp)
char json_content[SIG_JSON_CONTENT_ITEM_LEN]