suricata
util-classification-config.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2010 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 Anoop Saldanha <anoopsaldanha@gmail.com>
22  *
23  * Used for parsing a classification.config file
24  */
25 
26 #include "suricata-common.h"
27 #include "detect.h"
28 #include "detect-engine.h"
29 #include "util-hash.h"
30 
31 #include "conf.h"
33 #include "util-unittest.h"
34 #include "util-error.h"
35 #include "util-debug.h"
36 #include "util-fmemopen.h"
37 #include "util-byte.h"
38 
39 /* Regex to parse the classtype argument from a Signature. The first substring
40  * holds the classtype name, the second substring holds the classtype the
41  * classtype description, and the third argument holds the priority */
42 #define DETECT_CLASSCONFIG_REGEX "^\\s*config\\s*classification\\s*:\\s*([a-zA-Z][a-zA-Z0-9-_]*)\\s*,\\s*(.+)\\s*,\\s*(\\d+)\\s*$"
43 
44 /* Default path for the classification.config file */
45 #if defined OS_WIN32 || defined __CYGWIN__
46 #define SC_CLASS_CONF_DEF_CONF_FILEPATH CONFIG_DIR "\\\\classification.config"
47 #else
48 #define SC_CLASS_CONF_DEF_CONF_FILEPATH CONFIG_DIR "/classification.config"
49 #endif
50 
51 uint32_t SCClassConfClasstypeHashFunc(HashTable *ht, void *data, uint16_t datalen);
52 char SCClassConfClasstypeHashCompareFunc(void *data1, uint16_t datalen1,
53  void *data2, uint16_t datalen2);
54 void SCClassConfClasstypeHashFree(void *ch);
55 static const char *SCClassConfGetConfFilename(const DetectEngineCtx *de_ctx);
56 
57 static SCClassConfClasstype *SCClassConfAllocClasstype(uint16_t classtype_id,
58  const char *classtype, const char *classtype_desc, int priority);
59 static void SCClassConfDeAllocClasstype(SCClassConfClasstype *ct);
60 
62 {
63  int en;
64  PCRE2_SIZE eo;
65  int opts = 0;
66 
67  de_ctx->class_conf_regex = pcre2_compile(
68  (PCRE2_SPTR8)DETECT_CLASSCONFIG_REGEX, PCRE2_ZERO_TERMINATED, opts, &en, &eo, NULL);
69  if (de_ctx->class_conf_regex == NULL) {
70  PCRE2_UCHAR errbuffer[256];
71  pcre2_get_error_message(en, errbuffer, sizeof(errbuffer));
72  SCLogWarning("pcre2 compile of \"%s\" failed at "
73  "offset %d: %s",
74  DETECT_CLASSCONFIG_REGEX, (int)eo, errbuffer);
75  return;
76  }
78  pcre2_match_data_create_from_pattern(de_ctx->class_conf_regex, NULL);
79 }
80 
82 {
83  if (de_ctx->class_conf_regex != NULL) {
84  pcre2_code_free(de_ctx->class_conf_regex);
85  de_ctx->class_conf_regex = NULL;
86  }
87  if (de_ctx->class_conf_regex_match != NULL) {
88  pcre2_match_data_free(de_ctx->class_conf_regex_match);
90  }
91 }
92 
93 
94 /**
95  * \brief Inits the context to be used by the Classification Config parsing API.
96  *
97  * This function initializes the hash table to be used by the Detection
98  * Engine Context to hold the data from the classification.config file,
99  * obtains the file desc to parse the classification.config file, and
100  * inits the regex used to parse the lines from classification.config
101  * file.
102  *
103  * \param de_ctx Pointer to the Detection Engine Context.
104  * \param fd Pointer to already opened file
105  *
106  * \note even if the file open fails we will keep the de_ctx->class_conf_ht
107  * initialized.
108  *
109  * \retval fp NULL on error
110  */
111 static FILE *SCClassConfInitContextAndLocalResources(DetectEngineCtx *de_ctx, FILE *fd)
112 {
113  /* init the hash table to be used by the classification config Classtypes */
117  if (de_ctx->class_conf_ht == NULL) {
118  SCLogError("Error initializing the hash "
119  "table");
120  return NULL;
121  }
122 
123  /* if it is not NULL, use the file descriptor. The hack so that we can
124  * avoid using a dummy classification file for testing purposes and
125  * instead use an input stream against a buffer containing the
126  * classification strings */
127  if (fd == NULL) {
128  const char *filename = SCClassConfGetConfFilename(de_ctx);
129  if ( (fd = fopen(filename, "r")) == NULL) {
130 #ifdef UNITTESTS
131  if (RunmodeIsUnittests())
132  return NULL; // silently fail
133 #endif
134  SCLogWarning("could not open: \"%s\": %s", filename, strerror(errno));
135  return NULL;
136  }
137  }
138 
140  return fd;
141 }
142 
143 
144 /**
145  * \brief Returns the path for the Classification Config file. We check if we
146  * can retrieve the path from the yaml conf file. If it is not present,
147  * return the default path for the classification file which is
148  * "./classification.config".
149  *
150  * \retval log_filename Pointer to a string containing the path for the
151  * Classification Config file.
152  */
153 static const char *SCClassConfGetConfFilename(const DetectEngineCtx *de_ctx)
154 {
155  const char *log_filename = NULL;
156 
157  if (de_ctx != NULL && strlen(de_ctx->config_prefix) > 0) {
158  char config_value[256];
159  snprintf(config_value, sizeof(config_value),
160  "%s.classification-file", de_ctx->config_prefix);
161 
162  /* try loading prefix setting, fall back to global if that
163  * fails. */
164  if (SCConfGet(config_value, &log_filename) != 1) {
165  if (SCConfGet("classification-file", &log_filename) != 1) {
166  log_filename = (char *)SC_CLASS_CONF_DEF_CONF_FILEPATH;
167  }
168  }
169  } else {
170  if (SCConfGet("classification-file", &log_filename) != 1) {
171  log_filename = (char *)SC_CLASS_CONF_DEF_CONF_FILEPATH;
172  }
173  }
174 
175  return log_filename;
176 }
177 
178 /**
179  * \brief Releases resources used by the Classification Config API.
180  */
181 static void SCClassConfDeInitLocalResources(FILE *fd)
182 {
183  if (fd != NULL) {
184  fclose(fd);
185  }
186 }
187 
188 /**
189  * \brief Releases resources used by the Classification Config API.
190  */
192 {
193  if (de_ctx->class_conf_ht != NULL)
195 
196  de_ctx->class_conf_ht = NULL;
197 }
198 
199 /**
200  * \brief Converts a string to lowercase.
201  *
202  * \param str Pointer to the string to be converted.
203  */
204 static char *SCClassConfStringToLowercase(const char *str)
205 {
206  char *new_str = NULL;
207  char *temp_str = NULL;
208 
209  if ( (new_str = SCStrdup(str)) == NULL) {
210  SCLogError("Error allocating memory");
211  return NULL;
212  }
213 
214  temp_str = new_str;
215  while (*temp_str != '\0') {
216  *temp_str = u8_tolower((unsigned char)*temp_str);
217  temp_str++;
218  }
219 
220  return new_str;
221 }
222 
223 /**
224  * \brief Parses a line from the classification file and adds it to Classtype
225  * hash table in DetectEngineCtx, i.e. DetectEngineCtx->class_conf_ht.
226  *
227  * \param rawstr Pointer to the string to be parsed.
228  * \param index Relative index of the string to be parsed.
229  * \param de_ctx Pointer to the Detection Engine Context.
230  *
231  * \retval 0 On success.
232  * \retval -1 On failure.
233  */
234 int SCClassConfAddClasstype(DetectEngineCtx *de_ctx, char *rawstr, uint16_t index)
235 {
236  char ct_name[CLASSTYPE_NAME_MAX_LEN];
237  char ct_desc[CLASSTYPE_DESC_MAX_LEN];
238  char ct_priority_str[16];
239  uint32_t ct_priority = 0;
240  uint16_t ct_id = index;
241 
242  SCClassConfClasstype *ct_new = NULL;
243  SCClassConfClasstype *ct_lookup = NULL;
244 
245  int ret = 0;
246 
247  ret = pcre2_match(de_ctx->class_conf_regex, (PCRE2_SPTR8)rawstr, strlen(rawstr), 0, 0,
249  if (ret < 0) {
250  SCLogError("Invalid Classtype in "
251  "classification.config file %s: \"%s\"",
252  SCClassConfGetConfFilename(de_ctx), rawstr);
253  goto error;
254  }
255 
256  size_t copylen = sizeof(ct_name);
257  /* retrieve the classtype name */
258  ret = pcre2_substring_copy_bynumber(
259  de_ctx->class_conf_regex_match, 1, (PCRE2_UCHAR8 *)ct_name, &copylen);
260  if (ret < 0) {
261  SCLogInfo("pcre2_substring_copy_bynumber() failed");
262  goto error;
263  }
264 
265  /* retrieve the classtype description */
266  copylen = sizeof(ct_desc);
267  ret = pcre2_substring_copy_bynumber(
268  de_ctx->class_conf_regex_match, 2, (PCRE2_UCHAR8 *)ct_desc, &copylen);
269  if (ret < 0) {
270  SCLogInfo("pcre2_substring_copy_bynumber() failed");
271  goto error;
272  }
273 
274  /* retrieve the classtype priority */
275  copylen = sizeof(ct_priority_str);
276  ret = pcre2_substring_copy_bynumber(
277  de_ctx->class_conf_regex_match, 3, (PCRE2_UCHAR8 *)ct_priority_str, &copylen);
278  if (ret < 0) {
279  SCLogInfo("pcre2_substring_copy_bynumber() failed");
280  goto error;
281  }
282  if (StringParseUint32(&ct_priority, 10, 0, (const char *)ct_priority_str) < 0) {
283  goto error;
284  }
285 
286  /* Create a new instance of the parsed Classtype string */
287  ct_new = SCClassConfAllocClasstype(ct_id, ct_name, ct_desc, ct_priority);
288  if (ct_new == NULL)
289  goto error;
290 
291  /* Check if the Classtype is present in the HashTable. In case it's present
292  * ignore it, as it is a duplicate. If not present, add it to the table */
293  ct_lookup = HashTableLookup(de_ctx->class_conf_ht, ct_new, 0);
294  if (ct_lookup == NULL) {
295  if (HashTableAdd(de_ctx->class_conf_ht, ct_new, 0) < 0)
296  SCLogDebug("HashTable Add failed");
297  } else {
298  SCLogDebug("Duplicate classtype found inside classification.config");
299  if (ct_new->classtype_desc) SCFree(ct_new->classtype_desc);
300  if (ct_new->classtype) SCFree(ct_new->classtype);
301  SCFree(ct_new);
302  }
303 
304  return 0;
305 
306  error:
307  return -1;
308 }
309 
310 /**
311  * \brief Checks if a string is a comment or a blank line.
312  *
313  * Comments lines are lines of the following format -
314  * "# This is a comment string" or
315  * " # This is a comment string".
316  *
317  * \param line String that has to be checked
318  *
319  * \retval 1 On the argument string being a comment or blank line
320  * \retval 0 Otherwise
321  */
322 static int SCClassConfIsLineBlankOrComment(char *line)
323 {
324  while (*line != '\0') {
325  /* we have a comment */
326  if (*line == '#')
327  return 1;
328 
329  /* this line is neither a comment line, nor a blank line */
330  if (!isspace((unsigned char)*line))
331  return 0;
332 
333  line++;
334  }
335 
336  /* we have a blank line */
337  return 1;
338 }
339 
340 /**
341  * \brief Parses the Classification Config file and updates the
342  * DetectionEngineCtx->class_conf_ht with the Classtype information.
343  *
344  * \param de_ctx Pointer to the Detection Engine Context.
345  */
346 static bool SCClassConfParseFile(DetectEngineCtx *de_ctx, FILE *fd)
347 {
348  char line[1024];
349  uint16_t i = 1;
350  int errors = 0;
351 
352  while (fgets(line, sizeof(line), fd) != NULL) {
353  if (SCClassConfIsLineBlankOrComment(line))
354  continue;
355 
356  if (SCClassConfAddClasstype(de_ctx, line, i) == -1) {
357  errors++;
358  } else {
359  i++;
360  }
361  }
362 
363 #ifdef UNITTESTS
364  if (de_ctx != NULL && strlen(de_ctx->config_prefix) > 0)
365  SCLogInfo("tenant id %d: Added \"%d\" classification types from the classification file",
367  else
368  SCLogInfo("Added \"%d\" classification types from the classification file",
370 #endif
371 
372  return errors == 0;
373 }
374 
375 /**
376  * \internal
377  * \brief Returns a new SCClassConfClasstype instance. The classtype string
378  * is converted into lowercase, before being assigned to the instance.
379  *
380  * \param classtype Pointer to the classification type.
381  * \param classtype_desc Pointer to the classification type description.
382  * \param priority Holds the priority for the classification type.
383  *
384  * \retval ct Pointer to the new instance of SCClassConfClasstype on success;
385  * NULL on failure.
386  */
387 static SCClassConfClasstype *SCClassConfAllocClasstype(uint16_t classtype_id,
388  const char *classtype,
389  const char *classtype_desc,
390  int priority)
391 {
392  SCClassConfClasstype *ct = NULL;
393 
394  if (classtype == NULL)
395  return NULL;
396 
397  if ((ct = SCCalloc(1, sizeof(SCClassConfClasstype))) == NULL)
398  return NULL;
399 
400  if ((ct->classtype = SCClassConfStringToLowercase(classtype)) == NULL) {
401  SCClassConfDeAllocClasstype(ct);
402  return NULL;
403  }
404 
405  if (classtype_desc != NULL &&
406  (ct->classtype_desc = SCStrdup(classtype_desc)) == NULL) {
407  SCLogError("Error allocating memory");
408 
409  SCClassConfDeAllocClasstype(ct);
410  return NULL;
411  }
412 
413  ct->classtype_id = classtype_id;
414  ct->priority = priority;
415 
416  return ct;
417 }
418 
419 /**
420  * \internal
421  * \brief Frees a SCClassConfClasstype instance
422  *
423  * \param Pointer to the SCClassConfClasstype instance that has to be freed
424  */
425 static void SCClassConfDeAllocClasstype(SCClassConfClasstype *ct)
426 {
427  if (ct != NULL) {
428  if (ct->classtype != NULL)
429  SCFree(ct->classtype);
430 
431  if (ct->classtype_desc != NULL)
432  SCFree(ct->classtype_desc);
433 
434  SCFree(ct);
435  }
436 }
437 
438 /**
439  * \brief Hashing function to be used to hash the Classtype name. Would be
440  * supplied as an argument to the HashTableInit function for
441  * DetectEngineCtx->class_conf_ht.
442  *
443  * \param ht Pointer to the HashTable.
444  * \param data Pointer to the data to be hashed. In this case, the data
445  * would be a pointer to a SCClassConfClasstype instance.
446  * \param datalen Not used by this function.
447  */
448 uint32_t SCClassConfClasstypeHashFunc(HashTable *ht, void *data, uint16_t datalen)
449 {
451  uint32_t hash = 0;
452  size_t i = 0;
453 
454  size_t len = strlen(ct->classtype);
455 
456  for (i = 0; i < len; i++)
457  hash += u8_tolower((unsigned char)(ct->classtype)[i]);
458 
459  hash = hash % ht->array_size;
460 
461  return hash;
462 }
463 
464 /**
465  * \brief Used to compare two Classtypes that have been stored in the HashTable.
466  * This function is supplied as an argument to the HashTableInit function
467  * for DetectionEngineCtx->class_conf_ct.
468  *
469  * \param data1 Pointer to the first SCClassConfClasstype to be compared.
470  * \param len1 Not used by this function.
471  * \param data2 Pointer to the second SCClassConfClasstype to be compared.
472  * \param len2 Not used by this function.
473  *
474  * \retval 1 On data1 and data2 being equal.
475  * \retval 0 On data1 and data2 not being equal.
476  */
477 char SCClassConfClasstypeHashCompareFunc(void *data1, uint16_t datalen1,
478  void *data2, uint16_t datalen2)
479 {
482 
483  if (ct1 == NULL || ct2 == NULL)
484  return 0;
485 
486  if (ct1->classtype == NULL || ct2->classtype == NULL)
487  return 0;
488 
489  if (strcmp(ct1->classtype, ct2->classtype) == 0) {
490  SCLogDebug("Match found inside Classification-Config hash function");
491  return 1;
492  }
493 
494  return 0;
495 }
496 
497 /**
498  * \brief Used to free the Classification Config Hash Data that was stored in
499  * DetectEngineCtx->class_conf_ht Hashtable.
500  *
501  * \param ch Pointer to the data that has to be freed.
502  */
504 {
505  SCClassConfDeAllocClasstype(ch);
506 }
507 
508 /**
509  * \brief Loads the Classtype info from the classification.config file.
510  *
511  * The classification.config file contains the different classtypes,
512  * that can be used to label Signatures. Each line of the file should
513  * have the following format -
514  * classtype_name, classtype_description, priority
515  * None of the above parameters should hold a quote inside the file.
516  *
517  * \param de_ctx Pointer to the Detection Engine Context that should be updated
518  * with Classtype information.
519  */
521 {
522  fd = SCClassConfInitContextAndLocalResources(de_ctx, fd);
523  if (fd == NULL) {
524 #ifdef UNITTESTS
525  if (RunmodeIsUnittests()) {
526  return false;
527  }
528 #endif
529  SCLogError("please check the \"classification-file\" "
530  "option in your suricata.yaml file");
531  return false;
532  }
533 
534  bool ret = true;
535  if (!SCClassConfParseFile(de_ctx, fd)) {
536  SCLogWarning("Error loading classification configuration from %s",
537  SCClassConfGetConfFilename(de_ctx));
538  ret = false;
539  }
540 
541  SCClassConfDeInitLocalResources(fd);
542 
543  return ret;
544 }
545 
546 /**
547  * \brief Gets the classtype from the corresponding hash table stored
548  * in the Detection Engine Context's class conf ht, given the
549  * classtype name.
550  *
551  * \param ct_name Pointer to the classtype name that has to be looked up.
552  * \param de_ctx Pointer to the Detection Engine Context.
553  *
554  * \retval lookup_ct_info Pointer to the SCClassConfClasstype instance from
555  * the hash table on success; NULL on failure.
556  */
559 {
560  if (strlen(ct_name) > CLASSTYPE_NAME_MAX_LEN) {
562  return NULL;
563  }
564  char name[strlen(ct_name) + 1];
565  size_t s;
566  for (s = 0; s < strlen(ct_name); s++)
567  name[s] = u8_tolower((unsigned char)ct_name[s]);
568  name[s] = '\0';
569 
570  SCClassConfClasstype ct_lookup = {0, 0, name, NULL };
572  &ct_lookup, 0);
573  return lookup_ct_info;
574 }
575 
576 /*----------------------------------Unittests---------------------------------*/
577 
578 
579 #ifdef UNITTESTS
580 
581 /**
582  * \brief Creates a dummy classification file, with all valid Classtypes, for
583  * testing purposes.
584  *
585  * \file_path Pointer to the file_path for the dummy classification file.
586  */
588 {
589  const char *buffer =
590  "config classification: nothing-wrong,Nothing Wrong With Us,3\n"
591  "config classification: unknown,Unknown are we,3\n"
592  "config classification: bad-unknown,We think it's bad, 2\n";
593 
594  FILE *fd = SCFmemopen((void *)buffer, strlen(buffer), "r");
595  if (fd == NULL)
596  SCLogDebug("Error with SCFmemopen() called by Classification Config test code");
597 
598  return fd;
599 }
600 
601 /**
602  * \brief Creates a dummy classification file, with some valid Classtypes and a
603  * couple of invalid Classtypes, for testing purposes.
604  *
605  * \file_path Pointer to the file_path for the dummy classification file.
606  */
608 {
609  const char *buffer =
610  "config classification: not-suspicious,Not Suspicious Traffic,3\n"
611  "onfig classification: unknown,Unknown Traffic,3\n"
612  "config classification: _badunknown,Potentially Bad Traffic, 2\n"
613  "config classification: bamboola1,Unknown Traffic,3\n"
614  "config classification: misc-activity,Misc activity,-1\n"
615  "config classification: policy-violation,Potential Corporate "
616  "config classification: bamboola,Unknown Traffic,3\n";
617 
618  FILE *fd = SCFmemopen((void *)buffer, strlen(buffer), "r");
619  if (fd == NULL)
620  SCLogDebug("Error with SCFmemopen() called by Classification Config test code");
621 
622  return fd;
623 }
624 
625 /**
626  * \brief Creates a dummy classification file, with all invalid Classtypes, for
627  * testing purposes.
628  *
629  * \file_path Pointer to the file_path for the dummy classification file.
630  */
632 {
633  const char *buffer =
634  "conig classification: not-suspicious,Not Suspicious Traffic,3\n"
635  "onfig classification: unknown,Unknown Traffic,3\n"
636  "config classification: _badunknown,Potentially Bad Traffic, 2\n"
637  "config classification: misc-activity,Misc activity,-1\n";
638 
639  FILE *fd = SCFmemopen((void *)buffer, strlen(buffer), "r");
640  if (fd == NULL)
641  SCLogDebug("Error with SCFmemopen() called by Classification Config test code");
642 
643  return fd;
644 }
645 
646 /**
647  * \test Check that the classification file is loaded and the detection engine
648  * content class_conf_hash_table loaded with the classtype data.
649  */
650 static int SCClassConfTest01(void)
651 {
653  int result = 0;
654 
655  if (de_ctx == NULL)
656  return result;
657 
661 
662  if (de_ctx->class_conf_ht == NULL)
663  return result;
664 
665  result = (de_ctx->class_conf_ht->count == 3);
666  if (result == 0) printf("de_ctx->class_conf_ht->count %u: ", de_ctx->class_conf_ht->count);
667 
669 
670  return result;
671 }
672 
673 /**
674  * \test Check that invalid classtypes present in the classification config file
675  * aren't loaded.
676  */
677 static int SCClassConfTest02(void)
678 {
680  int result = 0;
681 
682  if (de_ctx == NULL)
683  return result;
684 
688 
689  if (de_ctx->class_conf_ht == NULL)
690  return result;
691 
692  result = (de_ctx->class_conf_ht->count == 0);
693 
695 
696  return result;
697 }
698 
699 /**
700  * \test Check that only valid classtypes are loaded into the hash table from
701  * the classification.config file.
702  */
703 static int SCClassConfTest03(void)
704 {
706 
708 
712 
714 
715  PASS;
716 }
717 
718 /**
719  * \test Check if the classtype info from the classification.config file have
720  * been loaded into the hash table.
721  */
722 static int SCClassConfTest04(void)
723 {
726 
730 
733 
734  FAIL_IF_NOT(SCClassConfGetClasstype("unknown", de_ctx) != NULL);
735  FAIL_IF_NOT(SCClassConfGetClasstype("unKnoWn", de_ctx) != NULL);
736  FAIL_IF_NOT(SCClassConfGetClasstype("bamboo", de_ctx) == NULL);
737  FAIL_IF_NOT(SCClassConfGetClasstype("bad-unknown", de_ctx) != NULL);
738  FAIL_IF_NOT(SCClassConfGetClasstype("BAD-UNKnOWN", de_ctx) != NULL);
739  FAIL_IF_NOT(SCClassConfGetClasstype("bed-unknown", de_ctx) == NULL);
740 
742  PASS;
743 }
744 
745 /**
746  * \test Check if the classtype info from the invalid classification.config file
747  * have not been loaded into the hash table, and cross verify to check
748  * that the hash table contains no classtype data.
749  */
750 static int SCClassConfTest05(void)
751 {
754 
758 
761 
762  FAIL_IF_NOT(SCClassConfGetClasstype("unknown", de_ctx) == NULL);
763  FAIL_IF_NOT(SCClassConfGetClasstype("unKnoWn", de_ctx) == NULL);
764  FAIL_IF_NOT(SCClassConfGetClasstype("bamboo", de_ctx) == NULL);
765  FAIL_IF_NOT(SCClassConfGetClasstype("bad-unknown", de_ctx) == NULL);
766  FAIL_IF_NOT(SCClassConfGetClasstype("BAD-UNKnOWN", de_ctx) == NULL);
767  FAIL_IF_NOT(SCClassConfGetClasstype("bed-unknown", de_ctx) == NULL);
768 
770  PASS;
771 }
772 
773 /**
774  * \brief This function registers unit tests for Classification Config API.
775  */
777 {
778  UtRegisterTest("SCClassConfTest01", SCClassConfTest01);
779  UtRegisterTest("SCClassConfTest02", SCClassConfTest02);
780  UtRegisterTest("SCClassConfTest03", SCClassConfTest03);
781  UtRegisterTest("SCClassConfTest04", SCClassConfTest04);
782  UtRegisterTest("SCClassConfTest05", SCClassConfTest05);
783 }
784 #endif /* UNITTESTS */
util-byte.h
len
uint8_t len
Definition: app-layer-dnp3.h:2
detect-engine.h
FAIL_IF_NULL
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
DetectEngineCtx_::class_conf_ht
HashTable * class_conf_ht
Definition: detect.h:1164
SCClassConfClasstype_::classtype
char * classtype
Definition: util-classification-config.h:41
util-fmemopen.h
UtRegisterTest
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
Definition: util-unittest.c:103
SCClassSCConfInit
void SCClassSCConfInit(DetectEngineCtx *de_ctx)
Definition: util-classification-config.c:61
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:282
name
const char * name
Definition: detect-engine-proto.c:48
util-hash.h
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:973
SCConfGet
int SCConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
Definition: conf.c:351
SCClassConfClasstypeHashFunc
uint32_t SCClassConfClasstypeHashFunc(HashTable *ht, void *data, uint16_t datalen)
Hashing function to be used to hash the Classtype name. Would be supplied as an argument to the HashT...
Definition: util-classification-config.c:448
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2715
SCClassConfClasstypeHashFree
void SCClassConfClasstypeHashFree(void *ch)
Used to free the Classification Config Hash Data that was stored in DetectEngineCtx->class_conf_ht Ha...
Definition: util-classification-config.c:503
DETECT_CLASSCONFIG_REGEX
#define DETECT_CLASSCONFIG_REGEX
Definition: util-classification-config.c:42
HashTable_
Definition: util-hash.h:35
u8_tolower
#define u8_tolower(c)
Definition: suricata-common.h:461
DetectEngineCtx_::class_conf_regex
pcre2_code * class_conf_regex
Definition: detect.h:1165
SCFmemopen
#define SCFmemopen
Definition: util-fmemopen.h:52
util-unittest.h
FAIL_IF_NOT
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:82
HashTableFree
void HashTableFree(HashTable *ht)
Free a HashTable and all its contents.
Definition: util-hash.c:112
HashTable_::array_size
uint32_t array_size
Definition: util-hash.h:37
SCClassConfGenerateInvalidDummyClassConfigFD02
FILE * SCClassConfGenerateInvalidDummyClassConfigFD02(void)
Creates a dummy classification file, with some valid Classtypes and a couple of invalid Classtypes,...
Definition: util-classification-config.c:607
DetectEngineCtx_::class_conf_regex_match
pcre2_match_data * class_conf_regex_match
Definition: detect.h:1166
util-debug.h
PASS
#define PASS
Pass the test.
Definition: util-unittest.h:105
util-error.h
de_ctx
DetectEngineCtx * de_ctx
Definition: fuzz_siginit.c:22
SCClassConfClasstype_
Container for a Classtype from the Classification.config file.
Definition: util-classification-config.h:33
SC_CLASS_CONF_DEF_CONF_FILEPATH
#define SC_CLASS_CONF_DEF_CONF_FILEPATH
Definition: util-classification-config.c:48
HashTableLookup
void * HashTableLookup(HashTable *ht, void *data, uint16_t datalen)
Definition: util-hash.c:194
detect.h
SCClassConfClasstype_::classtype_id
uint16_t classtype_id
Definition: util-classification-config.h:35
SCClassConfAddClasstype
int SCClassConfAddClasstype(DetectEngineCtx *de_ctx, char *rawstr, uint16_t index)
Parses a line from the classification file and adds it to Classtype hash table in DetectEngineCtx,...
Definition: util-classification-config.c:234
SCClassConfDeinit
void SCClassConfDeinit(DetectEngineCtx *de_ctx)
Definition: util-classification-config.c:81
StringParseUint32
int StringParseUint32(uint32_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:269
SCLogWarning
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition: util-debug.h:262
HashTableAdd
int HashTableAdd(HashTable *ht, void *data, uint16_t datalen)
Definition: util-hash.c:132
SCClassConfGetClasstype
SCClassConfClasstype * SCClassConfGetClasstype(const char *ct_name, DetectEngineCtx *de_ctx)
Gets the classtype from the corresponding hash table stored in the Detection Engine Context's class c...
Definition: util-classification-config.c:557
conf.h
RunmodeIsUnittests
int RunmodeIsUnittests(void)
Definition: suricata.c:292
SCLogInfo
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:232
SCClassConfGenerateInvalidDummyClassConfigFD03
FILE * SCClassConfGenerateInvalidDummyClassConfigFD03(void)
Creates a dummy classification file, with all invalid Classtypes, for testing purposes.
Definition: util-classification-config.c:631
DetectEngineCtx_::config_prefix
char config_prefix[64]
Definition: detect.h:1098
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
DEBUG_VALIDATE_MARK_SANITIZED
#define DEBUG_VALIDATE_MARK_SANITIZED(ptr)
Definition: util-validate.h:111
suricata-common.h
CLASSTYPE_DESC_MAX_LEN
#define CLASSTYPE_DESC_MAX_LEN
Definition: util-classification-config.h:28
HashTable_::count
uint32_t count
Definition: util-hash.h:40
util-classification-config.h
SCStrdup
#define SCStrdup(s)
Definition: util-mem.h:56
SCClassConfClasstype_::priority
int priority
Definition: util-classification-config.h:38
SCClassConfRegisterTests
void SCClassConfRegisterTests(void)
This function registers unit tests for Classification Config API.
Definition: util-classification-config.c:776
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
CLASSTYPE_NAME_MAX_LEN
#define CLASSTYPE_NAME_MAX_LEN
Definition: util-classification-config.h:27
HashTableInit
HashTable * HashTableInit(uint32_t size, uint32_t(*Hash)(struct HashTable_ *, void *, uint16_t), char(*Compare)(void *, uint16_t, void *, uint16_t), void(*Free)(void *))
Definition: util-hash.c:35
DetectEngineCtxInit
DetectEngineCtx * DetectEngineCtxInit(void)
Definition: detect-engine.c:2676
SCClassConfClasstypeHashCompareFunc
char SCClassConfClasstypeHashCompareFunc(void *data1, uint16_t datalen1, void *data2, uint16_t datalen2)
Used to compare two Classtypes that have been stored in the HashTable. This function is supplied as a...
Definition: util-classification-config.c:477
SCClassConfClasstype_::classtype_desc
char * classtype_desc
Definition: util-classification-config.h:45
SCClassConfGenerateValidDummyClassConfigFD01
FILE * SCClassConfGenerateValidDummyClassConfigFD01(void)
Creates a dummy classification file, with all valid Classtypes, for testing purposes.
Definition: util-classification-config.c:587
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
DetectEngineCtx_::tenant_id
uint32_t tenant_id
Definition: detect.h:980
DEBUG_VALIDATE_BUG_ON
#define DEBUG_VALIDATE_BUG_ON(exp)
Definition: util-validate.h:109
SCClassConfLoadClassificationConfigFile
bool SCClassConfLoadClassificationConfigFile(DetectEngineCtx *de_ctx, FILE *fd)
Loads the Classtype info from the classification.config file.
Definition: util-classification-config.c:520
SCClassConfDeInitContext
void SCClassConfDeInitContext(DetectEngineCtx *de_ctx)
Releases resources used by the Classification Config API.
Definition: util-classification-config.c:191