suricata
detect-dataset.c
Go to the documentation of this file.
1 /* Copyright (C) 2018-2025 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Victor Julien <victor@inliniac.net>
22  *
23  * Implements the dataset keyword
24  */
25 
26 #include "suricata-common.h"
27 #include "decode.h"
28 #include "detect.h"
29 #include "threads.h"
30 #include "datasets.h"
31 #include "datasets-context-json.h"
32 #include "detect-dataset.h"
33 
34 #include "detect-parse.h"
35 #include "detect-engine.h"
36 #include "detect-engine-buffer.h"
37 #include "detect-engine-mpm.h"
38 #include "detect-engine-state.h"
39 
40 #include "util-debug.h"
41 #include "util-print.h"
42 #include "util-misc.h"
43 #include "util-path.h"
44 #include "util-conf.h"
45 #include "util-validate.h"
46 
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
51 
52 #define DATASET_SUBDOMAIN_MAX_LOOKUPS 126
53 
54 static int DetectDatasetSetup (DetectEngineCtx *, Signature *, const char *);
55 void DetectDatasetFree (DetectEngineCtx *, void *);
56 
58 {
59  sigmatch_table[DETECT_DATASET].name = "dataset";
60  sigmatch_table[DETECT_DATASET].desc = "match sticky buffer against datasets (experimental)";
61  sigmatch_table[DETECT_DATASET].url = "/rules/datasets.html#dataset";
62  sigmatch_table[DETECT_DATASET].Setup = DetectDatasetSetup;
65 }
66 
67 /** \brief walk up the domain hierarchy looking for a match in a JSON dataset */
68 static DataJsonResultType DatajsonLookupSubdomain(
69  Dataset *set, const uint8_t *data, const uint32_t data_len)
70 {
71  DataJsonResultType r = {
72  .found = false, .json = { .value = NULL, .len = 0 }, .hashdata = NULL
73  };
74  int lookups = 0;
75  for (uint32_t i = 1; i < data_len; i++) {
76  if (data[i] == '.' && data[i - 1] != '.') {
77  if (++lookups > DATASET_SUBDOMAIN_MAX_LOOKUPS)
78  break;
79  r = DatajsonLookup(set, data + i, data_len - i);
80  if (r.found)
81  return r;
82  }
83  }
84  return r;
85 }
86 
87 /*
88  1 match
89  0 no match
90  */
91 static int DetectDatajsonBufferMatch(DetectEngineThreadCtx *det_ctx, const DetectDatasetData *sd,
92  const uint8_t *data, const uint32_t data_len)
93 {
94  if (data == NULL || data_len == 0)
95  return 0;
96 
97  switch (sd->cmd) {
99  // PrintRawDataFp(stdout, data, data_len);
100  DataJsonResultType r = DatajsonLookup(sd->set, data, data_len);
101  SCLogDebug("r found: %d, len: %u", r.found, r.json.len);
102  if (!r.found && sd->match_subdomain) {
103  r = DatajsonLookupSubdomain(sd->set, data, data_len);
104  }
105  if (!r.found)
106  return 0;
107  if (r.json.len > 0) {
108  /* we need to add 3 on length check for the added quotes and colon when
109  building the json string */
110  if (r.json.len + strlen(sd->json_key) + 3 < SIG_JSON_CONTENT_ITEM_LEN) {
111  if (DetectEngineThreadCtxGetJsonContext(det_ctx) < 0) {
112  DatajsonUnlockElt(&r);
113  return 0;
114  }
115  snprintf(det_ctx->json_content[det_ctx->json_content_len].json_content,
116  SIG_JSON_CONTENT_ITEM_LEN, "\"%s\":%s", sd->json_key, r.json.value);
117  det_ctx->json_content[det_ctx->json_content_len].id = sd->id;
118  det_ctx->json_content_len++;
119  SCLogDebug("Added json content %u (alloc length %u)", det_ctx->json_content_len,
120  det_ctx->json_content_capacity);
121  }
122  }
123  DatajsonUnlockElt(&r);
124  return 1;
125  }
127  // PrintRawDataFp(stdout, data, data_len);
128  DataJsonResultType r = DatajsonLookup(sd->set, data, data_len);
129  SCLogDebug("r found: %d, len: %u", r.found, r.json.len);
130  if (!r.found && sd->match_subdomain) {
131  r = DatajsonLookupSubdomain(sd->set, data, data_len);
132  }
133  if (r.found) {
134  DatajsonUnlockElt(&r);
135  return 0;
136  }
137  return 1;
138  }
139  default:
140  DEBUG_VALIDATE_BUG_ON("unknown dataset with json command");
141  }
142  return 0;
143 }
144 
145 /** \brief walk up the domain hierarchy looking for a match in a dataset */
146 static int DatasetLookupSubdomain(Dataset *set, const uint8_t *data, const uint32_t data_len)
147 {
148  int lookups = 0;
149  for (uint32_t i = 1; i < data_len; i++) {
150  if (data[i] == '.' && data[i - 1] != '.') {
151  if (++lookups > DATASET_SUBDOMAIN_MAX_LOOKUPS)
152  break;
153  int r = DatasetLookup(set, data + i, data_len - i);
154  if (r == 1)
155  return 1;
156  }
157  }
158  return 0;
159 }
160 
161 /*
162  1 match
163  0 no match
164  */
166  const DetectDatasetData *sd,
167  const uint8_t *data, const uint32_t data_len)
168 {
169  if (data == NULL || data_len == 0)
170  return 0;
171 
172  if ((sd->format == DATASET_FORMAT_JSON) || (sd->format == DATASET_FORMAT_NDJSON)) {
173  return DetectDatajsonBufferMatch(det_ctx, sd, data, data_len);
174  }
175 
176  switch (sd->cmd) {
178  //PrintRawDataFp(stdout, data, data_len);
179  int r = DatasetLookup(sd->set, data, data_len);
180  if (r != 1 && sd->match_subdomain) {
181  r = DatasetLookupSubdomain(sd->set, data, data_len);
182  }
183  SCLogDebug("r %d", r);
184  if (r == 1)
185  return 1;
186  break;
187  }
189  //PrintRawDataFp(stdout, data, data_len);
190  int r = DatasetLookup(sd->set, data, data_len);
191  if (r != 1 && sd->match_subdomain) {
192  r = DatasetLookupSubdomain(sd->set, data, data_len);
193  }
194  SCLogDebug("r %d", r);
195  if (r < 1)
196  return 1;
197  break;
198  }
199  case DETECT_DATASET_CMD_SET: {
200  //PrintRawDataFp(stdout, data, data_len);
201  int r = SCDatasetAdd(sd->set, data, data_len);
202  if (r == 1)
203  return 1;
204  break;
205  }
207  int r = DatasetRemove(sd->set, data, data_len);
208  if (r == 1)
209  return 1;
210  break;
211  }
212  default:
213  DEBUG_VALIDATE_BUG_ON("unknown dataset command");
214  }
215  return 0;
216 }
217 
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,
220  uint64_t *memcap, uint32_t *hashsize, DatasetFormats *format, char *value_key,
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)
223 {
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;
230 
231  char copy[strlen(str)+1];
232  strlcpy(copy, str, sizeof(copy));
233  char *xsaveptr = NULL;
234  char *key = strtok_r(copy, ",", &xsaveptr);
235 
236  while (key != NULL) {
237  while (*key != '\0' && isblank(*key)) {
238  key++;
239  }
240  char *val = strchr(key, ' ');
241  if (val != NULL) {
242  *val++ = '\0';
243  while (*val != '\0' && isblank(*val)) {
244  val++;
245  SCLogDebug("cmd %s val %s", key, val);
246  }
247  } else {
248  SCLogDebug("cmd %s", key);
249  }
250 
251  if (strlen(key) == 0) {
252  goto next;
253  }
254 
255  if (!cmd_set) {
256  if (val && strlen(val) != 0) {
257  return -1;
258  }
259  strlcpy(cmd, key, cmd_len);
260  cmd_set = true;
261  } else if (!name_set) {
262  if (val && strlen(val) != 0) {
263  return -1;
264  }
265  strlcpy(name, key, name_len);
266  name_set = true;
267  } else {
268  if (val == NULL) {
269  /* only non fixed place option without value is remove_key */
270  if (strcmp(key, "remove_key") == 0) {
271  *remove_key = true;
272  } else
273  return -1;
274  } else if (strcmp(key, "match") == 0) {
275  if (strcmp(val, "subdomain") == 0) {
276  *match_subdomain = true;
277  } else {
278  SCLogError("unknown match mode '%s'", val);
279  return -1;
280  }
281  } else if (strcmp(key, "type") == 0) {
282  SCLogDebug("type %s", val);
283 
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) {
296  } else {
297  SCLogError("bad type %s", val);
298  return -1;
299  }
300 
301  } else if (strcmp(key, "save") == 0) {
302  if (save_set) {
303  SCLogError("'save' can only appear once");
304  return -1;
305  }
306  SCLogDebug("save %s", val);
307  strlcpy(save, val, save_size);
308  save_set = true;
309  } else if (strcmp(key, "load") == 0) {
310  if (load_set) {
311  SCLogError("'load' can only appear once");
312  return -1;
313  }
314  SCLogDebug("load %s", val);
315  strlcpy(load, val, load_size);
316  load_set = true;
317  } else if (strcmp(key, "state") == 0) {
318  if (state_set) {
319  SCLogError("'state' can only appear once");
320  return -1;
321  }
322  SCLogDebug("state %s", val);
323  strlcpy(load, val, load_size);
324  strlcpy(save, val, save_size);
325  state_set = true;
326  } else if (strcmp(key, "format") == 0) {
327  if (format_set) {
328  SCLogError("'format' can only appear once");
329  return -1;
330  }
331  SCLogDebug("format %s", val);
332  if (strcmp(val, "csv") == 0) {
333  *format = DATASET_FORMAT_CSV;
334  } else if (strcmp(val, "ndjson") == 0) {
335  *format = DATASET_FORMAT_NDJSON;
336  } else if (strcmp(val, "json") == 0) {
337  *format = DATASET_FORMAT_JSON;
338  } else {
339  SCLogError("unknown format %s", val);
340  return -1;
341  }
342  format_set = true;
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);
346  return -1;
347  }
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);
352  return -1;
353  }
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 "
359  "underscores");
360  return -1;
361  }
362  }
363  if (strlen(val) > enrichment_key_size) {
364  SCLogError("'key' value too long (limit is %zu)", enrichment_key_size);
365  return -1;
366  }
367  strlcpy(enrichment_key, val, enrichment_key_size);
368  }
369 
370  if (strcmp(key, "memcap") == 0) {
371  if (ParseSizeStringU64(val, memcap) < 0) {
372  SCLogWarning("invalid value for memcap: %s,"
373  " resetting to default",
374  val);
375  *memcap = 0;
376  }
377  }
378  if (strcmp(key, "hashsize") == 0) {
379  if (ParseSizeStringU32(val, hashsize) < 0) {
380  SCLogWarning("invalid value for hashsize: %s,"
381  " resetting to default",
382  val);
383  *hashsize = 0;
384  }
385  }
386  }
387 
388  SCLogDebug("key: %s, value: %s", key, val);
389 
390  next:
391  key = strtok_r(NULL, ",", &xsaveptr);
392  }
393 
394  if ((load_set || save_set) && state_set) {
395  SCLogError("'state' can not be mixed with 'load' and 'save'");
396  return -1;
397  }
398 
399  /* Trim trailing whitespace. */
400  while (strlen(name) > 0 && isblank(name[strlen(name) - 1])) {
401  name[strlen(name) - 1] = '\0';
402  }
403 
404  /* Validate name, spaces are not allowed. */
405  for (size_t i = 0; i < strlen(name); i++) {
406  if (isblank(name[i])) {
407  SCLogError("spaces not allowed in dataset names");
408  return 0;
409  }
410  }
411 
412  return 1;
413 }
414 
415 /** \brief wrapper around dirname that does leave input untouched */
416 static void GetDirName(const char *in, char *out, size_t outs)
417 {
418  if (strlen(in) == 0) {
419  return;
420  }
421 
422  size_t size = strlen(in) + 1;
423  char tmp[size];
424  strlcpy(tmp, in, size);
425 
426  char *dir = dirname(tmp);
427  BUG_ON(dir == NULL);
428  strlcpy(out, dir, outs);
429 }
430 
431 static int SetupLoadPath(const DetectEngineCtx *de_ctx,
432  char *load, size_t load_size)
433 {
434  SCLogDebug("load %s", load);
435 
436  if (PathIsAbsolute(load)) {
437  return 0;
438  }
439 
440  bool done = false;
441 #ifdef HAVE_LIBGEN_H
442  BUG_ON(de_ctx->rule_file == NULL);
443 
444  char dir[PATH_MAX] = "";
445  GetDirName(de_ctx->rule_file, dir, sizeof(dir));
446 
447  SCLogDebug("rule_file %s dir %s", de_ctx->rule_file, dir);
448  char path[PATH_MAX];
449  if (PathMerge(path, sizeof(path), dir, load) < 0)
450  return -1;
451 
452  if (SCPathExists(path)) {
453  done = true;
454  strlcpy(load, path, load_size);
455  SCLogDebug("using path '%s' (HAVE_LIBGEN_H)", load);
456  }
457 #endif
458  if (!done) {
459  char *loadp = DetectLoadCompleteSigPath(de_ctx, load);
460  if (loadp == NULL) {
461  return -1;
462  }
463  SCLogDebug("loadp %s", loadp);
464 
465  if (SCPathExists(loadp)) {
466  strlcpy(load, loadp, load_size);
467  SCLogDebug("using path '%s' (non-HAVE_LIBGEN_H)", load);
468  }
469  SCFree(loadp);
470  }
471  return 0;
472 }
473 
474 static int SetupSavePath(const DetectEngineCtx *de_ctx,
475  char *save, size_t save_size)
476 {
477  SCLogDebug("save %s", save);
478 
479  int allow_save = 1;
480  if (SCConfGetBool("datasets.rules.allow-write", &allow_save)) {
481  if (!allow_save) {
482  SCLogError("Rules containing save/state datasets have been disabled");
483  return -1;
484  }
485  }
486 
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);
491  } else {
492  if (PathIsAbsolute(save)) {
493  SCLogError("Absolute paths not allowed: %s", save);
494  return -1;
495  }
496 
497  if (SCPathContainsTraversal(save)) {
498  SCLogError("Directory traversals not allowed: %s", save);
499  return -1;
500  }
501  }
502 
503  // data dir
504  const char *dir = ConfigGetDataDirectory();
505  BUG_ON(dir == NULL); // should not be able to fail
506  if (!PathIsAbsolute(save)) {
507  char path[PATH_MAX];
508  if (PathMerge(path, sizeof(path), dir, save) < 0)
509  return -1;
510 
511  /* TODO check if location exists and is writable */
512 
513  strlcpy(save, path, save_size);
514  }
515 
516  return 0;
517 }
518 
519 int DetectDatasetSetup (DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
520 {
521  DetectDatasetData *cd = NULL;
522  uint8_t cmd = 0;
523  uint64_t memcap = 0;
524  uint32_t hashsize = 0;
525  char cmd_str[16] = "", name[DATASET_NAME_MAX_LEN + 1] = "";
527  char load[PATH_MAX] = "";
528  char save[PATH_MAX] = "";
530  char value_key[SIG_JSON_CONTENT_KEY_LEN] = "";
531  char array_key[SIG_JSON_CONTENT_KEY_LEN] = "";
532  char enrichment_key[SIG_JSON_CONTENT_KEY_LEN] = "";
533  bool remove_key = false;
534  bool match_subdomain = false;
535 
536  if (DetectBufferGetActiveList(de_ctx, s) == -1) {
537  SCLogError("datasets are only supported for sticky buffers");
538  SCReturnInt(-1);
539  }
540 
541  int list = s->init_data->list;
542  if (list == DETECT_SM_LIST_NOTSET) {
543  SCLogError("datasets are only supported for sticky buffers");
544  SCReturnInt(-1);
545  }
546 
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)) {
551  return -1;
552  }
553 
554  if (strcmp(cmd_str,"isset") == 0) {
556  } else if (strcmp(cmd_str,"isnotset") == 0) {
558  } else if (strcmp(cmd_str,"set") == 0) {
559  if ((format == DATASET_FORMAT_JSON) || (format == DATASET_FORMAT_NDJSON)) {
560  SCLogError("json format is not supported for 'set' command");
561  return -1;
562  }
564  } else if (strcmp(cmd_str,"unset") == 0) {
565  if ((format == DATASET_FORMAT_JSON) || (format == DATASET_FORMAT_NDJSON)) {
566  SCLogError("json format is not supported for 'unset' command");
567  return -1;
568  }
570  } else {
571  SCLogError("dataset action \"%s\" is not supported.", cmd_str);
572  return -1;
573  }
574 
575  if (match_subdomain) {
577  SCLogError("'match subdomain' only supports isset/isnotset commands");
578  return -1;
579  }
580  if (type != DATASET_TYPE_STRING) {
581  SCLogError("'match subdomain' only supports type string");
582  return -1;
583  }
584  }
585 
586  if ((format == DATASET_FORMAT_JSON) || (format == DATASET_FORMAT_NDJSON)) {
587  if (strlen(save) != 0) {
588  SCLogError("json format is not supported with 'save' or 'state' option");
589  return -1;
590  }
591  if (strlen(enrichment_key) == 0) {
592  SCLogError("json format needs a 'context_key' parameter");
593  return -1;
594  }
595  if (strlen(value_key) == 0) {
596  SCLogError("json format needs a 'value_key' parameter");
597  return -1;
598  }
599  }
600 
601  /* if just 'load' is set, we load data from the same dir as the
602  * rule file. If load+save is used, we use data dir */
603  if (strlen(save) == 0 && strlen(load) != 0) {
604  if (SetupLoadPath(de_ctx, load, sizeof(load)) != 0)
605  return -1;
606  /* if just 'save' is set, we use either full path or the
607  * data-dir */
608  } else if (strlen(save) != 0 && strlen(load) == 0) {
609  if (SetupSavePath(de_ctx, save, sizeof(save)) != 0)
610  return -1;
611  /* use 'save' logic for 'state', but put the resulting
612  * path into 'load' as well. */
613  } else if (strlen(save) != 0 && strlen(load) != 0 &&
614  strcmp(save, load) == 0) {
615  if (SetupSavePath(de_ctx, save, sizeof(save)) != 0)
616  return -1;
617  strlcpy(load, save, sizeof(load));
618  } else if (strlen(save) != 0 && strlen(load) != 0) {
619  /* both 'load' and 'save' set with different paths: resolve each
620  * independently. */
621  if (SetupSavePath(de_ctx, save, sizeof(save)) != 0)
622  return -1;
623  if (SetupLoadPath(de_ctx, load, sizeof(load)) != 0)
624  return -1;
625  }
626 
627  SCLogDebug("name '%s' load '%s' save '%s'", name, load, save);
628  Dataset *set = NULL;
629 
630  if (format == DATASET_FORMAT_JSON) {
631  set = DatajsonGet(name, type, load, memcap, hashsize, value_key, array_key,
632  DATASET_FORMAT_JSON, remove_key);
633  } else if (format == DATASET_FORMAT_NDJSON) {
634  set = DatajsonGet(name, type, load, memcap, hashsize, value_key, NULL,
635  DATASET_FORMAT_NDJSON, remove_key);
636  } else {
637  set = DatasetGet(name, type, save, load, memcap, hashsize);
638  }
639  if (set == NULL) {
640  SCLogError("failed to set up dataset '%s'.", name);
641  return -1;
642  }
643 
644  cd = SCCalloc(1, sizeof(DetectDatasetData));
645  if (unlikely(cd == NULL))
646  goto error;
647 
648  cd->set = set;
649  cd->cmd = cmd;
650  cd->format = format;
651  cd->match_subdomain = match_subdomain;
652  if ((format == DATASET_FORMAT_JSON) || (format == DATASET_FORMAT_NDJSON)) {
653  strlcpy(cd->json_key, enrichment_key, sizeof(cd->json_key));
654  }
655  cd->id = s;
656 
657  SCLogDebug("cmd %s, name %s",
658  cmd_str, strlen(name) ? name : "(none)");
659 
660  /* Okay so far so good, lets get this into a SigMatch
661  * and put it in the Signature. */
662 
663  if (SCSigMatchAppendSMToList(de_ctx, s, DETECT_DATASET, (SigMatchCtx *)cd, list) == NULL) {
664  goto error;
665  }
666  return 0;
667 
668 error:
669  if (cd != NULL)
670  SCFree(cd);
671  return -1;
672 }
673 
675 {
677  if (fd == NULL)
678  return;
679 
680  SCFree(fd);
681 }
DatajsonLookup
DataJsonResultType DatajsonLookup(Dataset *set, const uint8_t *data, const uint32_t data_len)
Definition: datasets-context-json.c:867
DataJsonType::len
uint16_t len
Definition: datasets-context-json.h:34
DetectDatasetData_::match_subdomain
bool match_subdomain
Definition: detect-dataset.h:33
DetectDatasetData_
Definition: detect-dataset.h:30
SigTableElmt_::url
const char * url
Definition: detect.h:1512
DetectDatasetData_::id
void * id
Definition: detect-dataset.h:37
detect-engine.h
DetectDatasetData_::cmd
uint8_t cmd
Definition: detect-dataset.h:32
SigTableElmt_::desc
const char * desc
Definition: detect.h:1511
sigmatch_table
SigTableElmt * sigmatch_table
Definition: detect-parse.c:79
SigTableElmt_::Free
void(* Free)(DetectEngineCtx *, void *)
Definition: detect.h:1496
SigTableElmt_::name
const char * name
Definition: detect.h:1509
unlikely
#define unlikely(expr)
Definition: util-optimize.h:35
SigTableElmt_::flags
uint32_t flags
Definition: detect.h:1500
DETECT_DATASET_CMD_SET
#define DETECT_DATASET_CMD_SET
Definition: detect-dataset.c:47
PathMerge
int PathMerge(char *out_buf, size_t buf_size, const char *const dir, const char *const fname)
Definition: util-path.c:74
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:282
ParseSizeStringU64
int ParseSizeStringU64(const char *size, uint64_t *res)
Definition: util-misc.c:191
next
struct HtpBodyChunk_ * next
Definition: app-layer-htp.h:0
name
const char * name
Definition: detect-engine-proto.c:48
type
uint8_t type
Definition: decode-sctp.h:0
threads.h
DatasetFormats
DatasetFormats
Definition: datasets.h:39
DetectDatasetData_::format
DatasetFormats format
Definition: detect-dataset.h:34
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:973
SCConfGetBool
int SCConfGetBool(const char *name, int *val)
Retrieve a configuration value as a boolean.
Definition: conf.c:524
DATASET_TYPE_SHA256
@ DATASET_TYPE_SHA256
Definition: datasets.h:49
DetectDatasetData_::set
Dataset * set
Definition: detect-dataset.h:31
ConfigGetDataDirectory
const char * ConfigGetDataDirectory(void)
Definition: util-conf.c:85
SigTableElmt_::Setup
int(* Setup)(DetectEngineCtx *, Signature *, const char *)
Definition: detect.h:1491
DataJsonResultType::found
bool found
Definition: datasets-context-json.h:38
DATASET_TYPE_IPV6
@ DATASET_TYPE_IPV6
Definition: datasets.h:51
SIG_JSON_CONTENT_ITEM_LEN
#define SIG_JSON_CONTENT_ITEM_LEN
Definition: detect.h:1279
DatajsonUnlockElt
void DatajsonUnlockElt(DataJsonResultType *r)
Definition: datasets-context-json.c:47
DETECT_DATASET_CMD_ISSET
#define DETECT_DATASET_CMD_ISSET
Definition: detect-dataset.c:50
strlcpy
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: util-strlcpyu.c:43
DatasetGet
Dataset * DatasetGet(const char *name, enum DatasetTypes type, const char *save, const char *load, uint64_t memcap, uint32_t hashsize)
Definition: datasets.c:451
SCPathContainsTraversal
bool SCPathContainsTraversal(const char *path)
Check for directory traversal.
Definition: util-path.c:268
DatasetRemove
int DatasetRemove(Dataset *set, const uint8_t *data, const uint32_t data_len)
Definition: datasets.c:1537
DataJsonResultType
Definition: datasets-context-json.h:37
datasets.h
decode.h
util-debug.h
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:22
DetectEngineThreadCtx_
Definition: detect.h:1291
SIG_JSON_CONTENT_KEY_LEN
#define SIG_JSON_CONTENT_KEY_LEN
Definition: detect.h:1280
DetectDatasetFree
void DetectDatasetFree(DetectEngineCtx *, void *)
Definition: detect-dataset.c:674
DATASET_TYPE_NOTSET
#define DATASET_TYPE_NOTSET
Definition: datasets.h:46
SignatureInitData_::list
int list
Definition: detect.h:632
util-print.h
detect-engine-mpm.h
SCSigMatchAppendSMToList
SigMatch * SCSigMatchAppendSMToList(DetectEngineCtx *de_ctx, Signature *s, uint16_t type, SigMatchCtx *ctx, const int list)
Append a SigMatch to the list type.
Definition: detect-parse.c:387
detect.h
DataJsonResultType::json
DataJsonType json
Definition: datasets-context-json.h:39
SCLogWarning
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition: util-debug.h:262
DetectEngineThreadCtx_::json_content_capacity
uint8_t json_content_capacity
Definition: detect.h:1329
BUG_ON
#define BUG_ON(x)
Definition: suricata-common.h:325
DetectDatasetRegister
void DetectDatasetRegister(void)
Definition: detect-dataset.c:57
SCDatasetAdd
int SCDatasetAdd(Dataset *set, const uint8_t *data, const uint32_t data_len)
Definition: datasets.c:1334
DATASET_FORMAT_CSV
@ DATASET_FORMAT_CSV
Definition: datasets.h:40
Signature_::init_data
SignatureInitData * init_data
Definition: detect.h:754
DatasetLookup
int DatasetLookup(Dataset *set, const uint8_t *data, const uint32_t data_len)
see if data is part of the set
Definition: datasets.c:1100
DATASET_TYPE_IPV4
@ DATASET_TYPE_IPV4
Definition: datasets.h:50
detect-engine-state.h
Data structures and function prototypes for keeping state for the detection engine.
DetectEngineThreadCtxGetJsonContext
int DetectEngineThreadCtxGetJsonContext(DetectEngineThreadCtx *det_ctx)
Definition: detect-engine.c:5263
DetectDatasetData_::json_key
char json_key[SIG_JSON_CONTENT_KEY_LEN]
Definition: detect-dataset.h:36
DATASET_SUBDOMAIN_MAX_LOOKUPS
#define DATASET_SUBDOMAIN_MAX_LOOKUPS
Definition: detect-dataset.c:52
SigMatchCtx_
Used to start a pointer to SigMatch context Should never be dereferenced without casting to something...
Definition: detect.h:351
DETECT_SM_LIST_NOTSET
#define DETECT_SM_LIST_NOTSET
Definition: detect.h:144
SCPathExists
bool SCPathExists(const char *path)
Check if a path exists.
Definition: util-path.c:183
DetectDatasetBufferMatch
int DetectDatasetBufferMatch(DetectEngineThreadCtx *det_ctx, const DetectDatasetData *sd, const uint8_t *data, const uint32_t data_len)
Definition: detect-dataset.c:165
DatasetTypes
DatasetTypes
Definition: datasets.h:45
util-conf.h
DetectEngineCtx_::rule_file
const char * rule_file
Definition: detect.h:1071
DATASET_FORMAT_NDJSON
@ DATASET_FORMAT_NDJSON
Definition: datasets.h:42
DATASET_FORMAT_JSON
@ DATASET_FORMAT_JSON
Definition: datasets.h:41
suricata-common.h
util-path.h
datasets-context-json.h
DATASET_NAME_MAX_LEN
#define DATASET_NAME_MAX_LEN
Definition: datasets.h:54
DETECT_DATASET_CMD_UNSET
#define DETECT_DATASET_CMD_UNSET
Definition: detect-dataset.c:48
PathIsAbsolute
int PathIsAbsolute(const char *path)
Check if a path is absolute.
Definition: util-path.c:44
detect-engine-buffer.h
detect-dataset.h
hashsize
#define hashsize(n)
Definition: util-hash-lookup3.h:40
ParseSizeStringU32
int ParseSizeStringU32(const char *size, uint32_t *res)
Definition: util-misc.c:174
util-validate.h
DetectEngineThreadCtx_::json_content
SigJsonContent * json_content
Definition: detect.h:1328
str
#define str(s)
Definition: suricata-common.h:316
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:274
SCFree
#define SCFree(p)
Definition: util-mem.h:61
DatajsonGet
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)
Definition: datasets-context-json.c:652
detect-parse.h
Signature_
Signature container.
Definition: detect.h:675
DataJsonType::value
char * value
Definition: datasets-context-json.h:33
DETECT_DATASET_CMD_ISNOTSET
#define DETECT_DATASET_CMD_ISNOTSET
Definition: detect-dataset.c:49
DATASET_TYPE_MD5
@ DATASET_TYPE_MD5
Definition: datasets.h:48
DATASET_TYPE_STRING
@ DATASET_TYPE_STRING
Definition: datasets.h:47
SIGMATCH_SUPPORT_FIREWALL
#define SIGMATCH_SUPPORT_FIREWALL
Definition: detect-engine-register.h:334
DetectLoadCompleteSigPath
char * DetectLoadCompleteSigPath(const DetectEngineCtx *de_ctx, const char *sig_file)
Create the path if default-rule-path was specified.
Definition: detect-engine-loader.c:108
DetectEngineThreadCtx_::json_content_len
uint8_t json_content_len
Definition: detect.h:1330
Dataset
Definition: datasets.h:55
util-misc.h
SCLogNotice
#define SCLogNotice(...)
Macro used to log NOTICE messages.
Definition: util-debug.h:250
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
SCReturnInt
#define SCReturnInt(x)
Definition: util-debug.h:288
DetectBufferGetActiveList
int DetectBufferGetActiveList(DetectEngineCtx *de_ctx, Signature *s)
Definition: detect-engine-buffer.c:109
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:109
DETECT_DATASET
@ DETECT_DATASET
Definition: detect-engine-register.h:93
SigJsonContent::json_content
char json_content[SIG_JSON_CONTENT_ITEM_LEN]
Definition: detect.h:1285
SigJsonContent::id
void * id
Definition: detect.h:1284