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  return;
80 }
81 
83 {
84  if (de_ctx->class_conf_regex != NULL) {
85  pcre2_code_free(de_ctx->class_conf_regex);
86  de_ctx->class_conf_regex = NULL;
87  }
88  if (de_ctx->class_conf_regex_match != NULL) {
89  pcre2_match_data_free(de_ctx->class_conf_regex_match);
91  }
92 }
93 
94 
95 /**
96  * \brief Inits the context to be used by the Classification Config parsing API.
97  *
98  * This function initializes the hash table to be used by the Detection
99  * Engine Context to hold the data from the classification.config file,
100  * obtains the file desc to parse the classification.config file, and
101  * inits the regex used to parse the lines from classification.config
102  * file.
103  *
104  * \param de_ctx Pointer to the Detection Engine Context.
105  * \param fd Pointer to already opened file
106  *
107  * \note even if the file open fails we will keep the de_ctx->class_conf_ht
108  * initialized.
109  *
110  * \retval fp NULL on error
111  */
112 static FILE *SCClassConfInitContextAndLocalResources(DetectEngineCtx *de_ctx, FILE *fd)
113 {
114  /* init the hash table to be used by the classification config Classtypes */
118  if (de_ctx->class_conf_ht == NULL) {
119  SCLogError("Error initializing the hash "
120  "table");
121  return NULL;
122  }
123 
124  /* if it is not NULL, use the file descriptor. The hack so that we can
125  * avoid using a dummy classification file for testing purposes and
126  * instead use an input stream against a buffer containing the
127  * classification strings */
128  if (fd == NULL) {
129  const char *filename = SCClassConfGetConfFilename(de_ctx);
130  if ( (fd = fopen(filename, "r")) == NULL) {
131 #ifdef UNITTESTS
132  if (RunmodeIsUnittests())
133  return NULL; // silently fail
134 #endif
135  SCLogWarning("could not open: \"%s\": %s", filename, strerror(errno));
136  return NULL;
137  }
138  }
139 
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 (ConfGet(config_value, &log_filename) != 1) {
165  if (ConfGet("classification-file", &log_filename) != 1) {
166  log_filename = (char *)SC_CLASS_CONF_DEF_CONF_FILEPATH;
167  }
168  }
169  } else {
170  if (ConfGet("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(DetectEngineCtx *de_ctx, 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  return;
199 }
200 
201 /**
202  * \brief Converts a string to lowercase.
203  *
204  * \param str Pointer to the string to be converted.
205  */
206 static char *SCClassConfStringToLowercase(const char *str)
207 {
208  char *new_str = NULL;
209  char *temp_str = NULL;
210 
211  if ( (new_str = SCStrdup(str)) == NULL) {
212  SCLogError("Error allocating memory");
213  return NULL;
214  }
215 
216  temp_str = new_str;
217  while (*temp_str != '\0') {
218  *temp_str = u8_tolower((unsigned char)*temp_str);
219  temp_str++;
220  }
221 
222  return new_str;
223 }
224 
225 /**
226  * \brief Parses a line from the classification file and adds it to Classtype
227  * hash table in DetectEngineCtx, i.e. DetectEngineCtx->class_conf_ht.
228  *
229  * \param rawstr Pointer to the string to be parsed.
230  * \param index Relative index of the string to be parsed.
231  * \param de_ctx Pointer to the Detection Engine Context.
232  *
233  * \retval 0 On success.
234  * \retval -1 On failure.
235  */
236 int SCClassConfAddClasstype(DetectEngineCtx *de_ctx, char *rawstr, uint16_t index)
237 {
238  char ct_name[CLASSTYPE_NAME_MAX_LEN];
239  char ct_desc[CLASSTYPE_DESC_MAX_LEN];
240  char ct_priority_str[16];
241  uint32_t ct_priority = 0;
242  uint16_t ct_id = index;
243 
244  SCClassConfClasstype *ct_new = NULL;
245  SCClassConfClasstype *ct_lookup = NULL;
246 
247  int ret = 0;
248 
249  ret = pcre2_match(de_ctx->class_conf_regex, (PCRE2_SPTR8)rawstr, strlen(rawstr), 0, 0,
251  if (ret < 0) {
252  SCLogError("Invalid Classtype in "
253  "classification.config file %s: \"%s\"",
254  SCClassConfGetConfFilename(de_ctx), rawstr);
255  goto error;
256  }
257 
258  size_t copylen = sizeof(ct_name);
259  /* retrieve the classtype name */
260  ret = pcre2_substring_copy_bynumber(
261  de_ctx->class_conf_regex_match, 1, (PCRE2_UCHAR8 *)ct_name, &copylen);
262  if (ret < 0) {
263  SCLogInfo("pcre2_substring_copy_bynumber() failed");
264  goto error;
265  }
266 
267  /* retrieve the classtype description */
268  copylen = sizeof(ct_desc);
269  ret = pcre2_substring_copy_bynumber(
270  de_ctx->class_conf_regex_match, 2, (PCRE2_UCHAR8 *)ct_desc, &copylen);
271  if (ret < 0) {
272  SCLogInfo("pcre2_substring_copy_bynumber() failed");
273  goto error;
274  }
275 
276  /* retrieve the classtype priority */
277  copylen = sizeof(ct_priority_str);
278  ret = pcre2_substring_copy_bynumber(
279  de_ctx->class_conf_regex_match, 3, (PCRE2_UCHAR8 *)ct_priority_str, &copylen);
280  if (ret < 0) {
281  SCLogInfo("pcre2_substring_copy_bynumber() failed");
282  goto error;
283  }
284  if (StringParseUint32(&ct_priority, 10, 0, (const char *)ct_priority_str) < 0) {
285  goto error;
286  }
287 
288  /* Create a new instance of the parsed Classtype string */
289  ct_new = SCClassConfAllocClasstype(ct_id, ct_name, ct_desc, ct_priority);
290  if (ct_new == NULL)
291  goto error;
292 
293  /* Check if the Classtype is present in the HashTable. In case it's present
294  * ignore it, as it is a duplicate. If not present, add it to the table */
295  ct_lookup = HashTableLookup(de_ctx->class_conf_ht, ct_new, 0);
296  if (ct_lookup == NULL) {
297  if (HashTableAdd(de_ctx->class_conf_ht, ct_new, 0) < 0)
298  SCLogDebug("HashTable Add failed");
299  } else {
300  SCLogDebug("Duplicate classtype found inside classification.config");
301  if (ct_new->classtype_desc) SCFree(ct_new->classtype_desc);
302  if (ct_new->classtype) SCFree(ct_new->classtype);
303  SCFree(ct_new);
304  }
305 
306  return 0;
307 
308  error:
309  return -1;
310 }
311 
312 /**
313  * \brief Checks if a string is a comment or a blank line.
314  *
315  * Comments lines are lines of the following format -
316  * "# This is a comment string" or
317  * " # This is a comment string".
318  *
319  * \param line String that has to be checked
320  *
321  * \retval 1 On the argument string being a comment or blank line
322  * \retval 0 Otherwise
323  */
324 static int SCClassConfIsLineBlankOrComment(char *line)
325 {
326  while (*line != '\0') {
327  /* we have a comment */
328  if (*line == '#')
329  return 1;
330 
331  /* this line is neither a comment line, nor a blank line */
332  if (!isspace((unsigned char)*line))
333  return 0;
334 
335  line++;
336  }
337 
338  /* we have a blank line */
339  return 1;
340 }
341 
342 /**
343  * \brief Parses the Classification Config file and updates the
344  * DetectionEngineCtx->class_conf_ht with the Classtype information.
345  *
346  * \param de_ctx Pointer to the Detection Engine Context.
347  */
348 static bool SCClassConfParseFile(DetectEngineCtx *de_ctx, FILE *fd)
349 {
350  char line[1024];
351  uint16_t i = 1;
352  int errors = 0;
353 
354  while (fgets(line, sizeof(line), fd) != NULL) {
355  if (SCClassConfIsLineBlankOrComment(line))
356  continue;
357 
358  if (SCClassConfAddClasstype(de_ctx, line, i) == -1) {
359  errors++;
360  } else {
361  i++;
362  }
363  }
364 
365 #ifdef UNITTESTS
366  if (de_ctx != NULL && strlen(de_ctx->config_prefix) > 0)
367  SCLogInfo("tenant id %d: Added \"%d\" classification types from the classification file",
369  else
370  SCLogInfo("Added \"%d\" classification types from the classification file",
372 #endif
373 
374  return errors == 0;
375 }
376 
377 /**
378  * \internal
379  * \brief Returns a new SCClassConfClasstype instance. The classtype string
380  * is converted into lowercase, before being assigned to the instance.
381  *
382  * \param classtype Pointer to the classification type.
383  * \param classtype_desc Pointer to the classification type description.
384  * \param priority Holds the priority for the classification type.
385  *
386  * \retval ct Pointer to the new instance of SCClassConfClasstype on success;
387  * NULL on failure.
388  */
389 static SCClassConfClasstype *SCClassConfAllocClasstype(uint16_t classtype_id,
390  const char *classtype,
391  const char *classtype_desc,
392  int priority)
393 {
394  SCClassConfClasstype *ct = NULL;
395 
396  if (classtype == NULL)
397  return NULL;
398 
399  if ((ct = SCCalloc(1, sizeof(SCClassConfClasstype))) == NULL)
400  return NULL;
401 
402  if ((ct->classtype = SCClassConfStringToLowercase(classtype)) == NULL) {
403  SCClassConfDeAllocClasstype(ct);
404  return NULL;
405  }
406 
407  if (classtype_desc != NULL &&
408  (ct->classtype_desc = SCStrdup(classtype_desc)) == NULL) {
409  SCLogError("Error allocating memory");
410 
411  SCClassConfDeAllocClasstype(ct);
412  return NULL;
413  }
414 
415  ct->classtype_id = classtype_id;
416  ct->priority = priority;
417 
418  return ct;
419 }
420 
421 /**
422  * \internal
423  * \brief Frees a SCClassConfClasstype instance
424  *
425  * \param Pointer to the SCClassConfClasstype instance that has to be freed
426  */
427 static void SCClassConfDeAllocClasstype(SCClassConfClasstype *ct)
428 {
429  if (ct != NULL) {
430  if (ct->classtype != NULL)
431  SCFree(ct->classtype);
432 
433  if (ct->classtype_desc != NULL)
434  SCFree(ct->classtype_desc);
435 
436  SCFree(ct);
437  }
438 
439  return;
440 }
441 
442 /**
443  * \brief Hashing function to be used to hash the Classtype name. Would be
444  * supplied as an argument to the HashTableInit function for
445  * DetectEngineCtx->class_conf_ht.
446  *
447  * \param ht Pointer to the HashTable.
448  * \param data Pointer to the data to be hashed. In this case, the data
449  * would be a pointer to a SCClassConfClasstype instance.
450  * \param datalen Not used by this function.
451  */
452 uint32_t SCClassConfClasstypeHashFunc(HashTable *ht, void *data, uint16_t datalen)
453 {
455  uint32_t hash = 0;
456  int i = 0;
457 
458  int len = strlen(ct->classtype);
459 
460  for (i = 0; i < len; i++)
461  hash += u8_tolower((unsigned char)(ct->classtype)[i]);
462 
463  hash = hash % ht->array_size;
464 
465  return hash;
466 }
467 
468 /**
469  * \brief Used to compare two Classtypes that have been stored in the HashTable.
470  * This function is supplied as an argument to the HashTableInit function
471  * for DetectionEngineCtx->class_conf_ct.
472  *
473  * \param data1 Pointer to the first SCClassConfClasstype to be compared.
474  * \param len1 Not used by this function.
475  * \param data2 Pointer to the second SCClassConfClasstype to be compared.
476  * \param len2 Not used by this function.
477  *
478  * \retval 1 On data1 and data2 being equal.
479  * \retval 0 On data1 and data2 not being equal.
480  */
481 char SCClassConfClasstypeHashCompareFunc(void *data1, uint16_t datalen1,
482  void *data2, uint16_t datalen2)
483 {
486  int len1 = 0;
487  int len2 = 0;
488 
489  if (ct1 == NULL || ct2 == NULL)
490  return 0;
491 
492  if (ct1->classtype == NULL || ct2->classtype == NULL)
493  return 0;
494 
495  len1 = strlen(ct1->classtype);
496  len2 = strlen(ct2->classtype);
497 
498  if (len1 == len2 && memcmp(ct1->classtype, ct2->classtype, len1) == 0) {
499  SCLogDebug("Match found inside Classification-Config hash function");
500  return 1;
501  }
502 
503  return 0;
504 }
505 
506 /**
507  * \brief Used to free the Classification Config Hash Data that was stored in
508  * DetectEngineCtx->class_conf_ht Hashtable.
509  *
510  * \param ch Pointer to the data that has to be freed.
511  */
513 {
514  SCClassConfDeAllocClasstype(ch);
515 
516  return;
517 }
518 
519 /**
520  * \brief Loads the Classtype info from the classification.config file.
521  *
522  * The classification.config file contains the different classtypes,
523  * that can be used to label Signatures. Each line of the file should
524  * have the following format -
525  * classtype_name, classtype_description, priority
526  * None of the above parameters should hold a quote inside the file.
527  *
528  * \param de_ctx Pointer to the Detection Engine Context that should be updated
529  * with Classtype information.
530  */
532 {
533  fd = SCClassConfInitContextAndLocalResources(de_ctx, fd);
534  if (fd == NULL) {
535 #ifdef UNITTESTS
536  if (RunmodeIsUnittests()) {
537  return false;
538  }
539 #endif
540  SCLogError("please check the \"classification-file\" "
541  "option in your suricata.yaml file");
542  return false;
543  }
544 
545  bool ret = true;
546  if (!SCClassConfParseFile(de_ctx, fd)) {
547  SCLogWarning("Error loading classification configuration from %s",
548  SCClassConfGetConfFilename(de_ctx));
549  ret = false;
550  }
551 
552  SCClassConfDeInitLocalResources(de_ctx, fd);
553 
554  return ret;
555 }
556 
557 /**
558  * \brief Gets the classtype from the corresponding hash table stored
559  * in the Detection Engine Context's class conf ht, given the
560  * classtype name.
561  *
562  * \param ct_name Pointer to the classtype name that has to be looked up.
563  * \param de_ctx Pointer to the Detection Engine Context.
564  *
565  * \retval lookup_ct_info Pointer to the SCClassConfClasstype instance from
566  * the hash table on success; NULL on failure.
567  */
570 {
571  char name[strlen(ct_name) + 1];
572  size_t s;
573  for (s = 0; s < strlen(ct_name); s++)
574  name[s] = u8_tolower((unsigned char)ct_name[s]);
575  name[s] = '\0';
576 
577  SCClassConfClasstype ct_lookup = {0, 0, name, NULL };
579  &ct_lookup, 0);
580  return lookup_ct_info;
581 }
582 
583 /*----------------------------------Unittests---------------------------------*/
584 
585 
586 #ifdef UNITTESTS
587 
588 /**
589  * \brief Creates a dummy classification file, with all valid Classtypes, for
590  * testing purposes.
591  *
592  * \file_path Pointer to the file_path for the dummy classification file.
593  */
595 {
596  const char *buffer =
597  "config classification: nothing-wrong,Nothing Wrong With Us,3\n"
598  "config classification: unknown,Unknown are we,3\n"
599  "config classification: bad-unknown,We think it's bad, 2\n";
600 
601  FILE *fd = SCFmemopen((void *)buffer, strlen(buffer), "r");
602  if (fd == NULL)
603  SCLogDebug("Error with SCFmemopen() called by Classification Config test code");
604 
605  return fd;
606 }
607 
608 /**
609  * \brief Creates a dummy classification file, with some valid Classtypes and a
610  * couple of invalid Classtypes, for testing purposes.
611  *
612  * \file_path Pointer to the file_path for the dummy classification file.
613  */
615 {
616  const char *buffer =
617  "config classification: not-suspicious,Not Suspicious Traffic,3\n"
618  "onfig classification: unknown,Unknown Traffic,3\n"
619  "config classification: _badunknown,Potentially Bad Traffic, 2\n"
620  "config classification: bamboola1,Unknown Traffic,3\n"
621  "config classification: misc-activity,Misc activity,-1\n"
622  "config classification: policy-violation,Potential Corporate "
623  "config classification: bamboola,Unknown Traffic,3\n";
624 
625  FILE *fd = SCFmemopen((void *)buffer, strlen(buffer), "r");
626  if (fd == NULL)
627  SCLogDebug("Error with SCFmemopen() called by Classification Config test code");
628 
629  return fd;
630 }
631 
632 /**
633  * \brief Creates a dummy classification file, with all invalid Classtypes, for
634  * testing purposes.
635  *
636  * \file_path Pointer to the file_path for the dummy classification file.
637  */
639 {
640  const char *buffer =
641  "conig classification: not-suspicious,Not Suspicious Traffic,3\n"
642  "onfig classification: unknown,Unknown Traffic,3\n"
643  "config classification: _badunknown,Potentially Bad Traffic, 2\n"
644  "config classification: misc-activity,Misc activity,-1\n";
645 
646  FILE *fd = SCFmemopen((void *)buffer, strlen(buffer), "r");
647  if (fd == NULL)
648  SCLogDebug("Error with SCFmemopen() called by Classification Config test code");
649 
650  return fd;
651 }
652 
653 /**
654  * \test Check that the classification file is loaded and the detection engine
655  * content class_conf_hash_table loaded with the classtype data.
656  */
657 static int SCClassConfTest01(void)
658 {
660  int result = 0;
661 
662  if (de_ctx == NULL)
663  return result;
664 
667 
668  if (de_ctx->class_conf_ht == NULL)
669  return result;
670 
671  result = (de_ctx->class_conf_ht->count == 3);
672  if (result == 0) printf("de_ctx->class_conf_ht->count %u: ", de_ctx->class_conf_ht->count);
673 
675 
676  return result;
677 }
678 
679 /**
680  * \test Check that invalid classtypes present in the classification config file
681  * aren't loaded.
682  */
683 static int SCClassConfTest02(void)
684 {
686  int result = 0;
687 
688  if (de_ctx == NULL)
689  return result;
690 
693 
694  if (de_ctx->class_conf_ht == NULL)
695  return result;
696 
697  result = (de_ctx->class_conf_ht->count == 0);
698 
700 
701  return result;
702 }
703 
704 /**
705  * \test Check that only valid classtypes are loaded into the hash table from
706  * the classification.config file.
707  */
708 static int SCClassConfTest03(void)
709 {
711 
713 
716 
718 
719  PASS;
720 }
721 
722 /**
723  * \test Check if the classtype info from the classification.config file have
724  * been loaded into the hash table.
725  */
726 static int SCClassConfTest04(void)
727 {
729  int result = 1;
730 
731  if (de_ctx == NULL)
732  return 0;
733 
736 
737  if (de_ctx->class_conf_ht == NULL)
738  return 0;
739 
740  result = (de_ctx->class_conf_ht->count == 3);
741 
742  result &= (SCClassConfGetClasstype("unknown", de_ctx) != NULL);
743  result &= (SCClassConfGetClasstype("unKnoWn", de_ctx) != NULL);
744  result &= (SCClassConfGetClasstype("bamboo", de_ctx) == NULL);
745  result &= (SCClassConfGetClasstype("bad-unknown", de_ctx) != NULL);
746  result &= (SCClassConfGetClasstype("BAD-UNKnOWN", de_ctx) != NULL);
747  result &= (SCClassConfGetClasstype("bed-unknown", de_ctx) == NULL);
748 
750 
751  return result;
752 }
753 
754 /**
755  * \test Check if the classtype info from the invalid classification.config file
756  * have not been loaded into the hash table, and cross verify to check
757  * that the hash table contains no classtype data.
758  */
759 static int SCClassConfTest05(void)
760 {
762  int result = 1;
763 
764  if (de_ctx == NULL)
765  return 0;
766 
769 
770  if (de_ctx->class_conf_ht == NULL)
771  return 0;
772 
773  result = (de_ctx->class_conf_ht->count == 0);
774 
775  result &= (SCClassConfGetClasstype("unknown", de_ctx) == NULL);
776  result &= (SCClassConfGetClasstype("unKnoWn", de_ctx) == NULL);
777  result &= (SCClassConfGetClasstype("bamboo", de_ctx) == NULL);
778  result &= (SCClassConfGetClasstype("bad-unknown", de_ctx) == NULL);
779  result &= (SCClassConfGetClasstype("BAD-UNKnOWN", de_ctx) == NULL);
780  result &= (SCClassConfGetClasstype("bed-unknown", de_ctx) == NULL);
781 
783 
784  return result;
785 }
786 
787 /**
788  * \brief This function registers unit tests for Classification Config API.
789  */
791 {
792  UtRegisterTest("SCClassConfTest01", SCClassConfTest01);
793  UtRegisterTest("SCClassConfTest02", SCClassConfTest02);
794  UtRegisterTest("SCClassConfTest03", SCClassConfTest03);
795  UtRegisterTest("SCClassConfTest04", SCClassConfTest04);
796  UtRegisterTest("SCClassConfTest05", SCClassConfTest05);
797 }
798 #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:1028
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
SCLogDebug
#define SCLogDebug(...)
Definition: util-debug.h:269
util-hash.h
DetectEngineCtx_
main detection engine ctx
Definition: detect.h:839
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:452
DetectEngineCtxFree
void DetectEngineCtxFree(DetectEngineCtx *)
Free a DetectEngineCtx::
Definition: detect-engine.c:2533
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:512
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:436
DetectEngineCtx_::class_conf_regex
pcre2_code * class_conf_regex
Definition: detect.h:1029
SCFmemopen
#define SCFmemopen
Definition: util-fmemopen.h:52
util-unittest.h
HashTableFree
void HashTableFree(HashTable *ht)
Definition: util-hash.c:78
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:614
ConfGet
int ConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
Definition: conf.c:335
DetectEngineCtx_::class_conf_regex_match
pcre2_match_data * class_conf_regex_match
Definition: detect.h:1030
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:17
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:183
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:236
SCClassConfDeinit
void SCClassConfDeinit(DetectEngineCtx *de_ctx)
Definition: util-classification-config.c:82
StringParseUint32
int StringParseUint32(uint32_t *res, int base, size_t len, const char *str)
Definition: util-byte.c:313
SCLogWarning
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition: util-debug.h:249
HashTableAdd
int HashTableAdd(HashTable *ht, void *data, uint16_t datalen)
Definition: util-hash.c:104
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:568
conf.h
RunmodeIsUnittests
int RunmodeIsUnittests(void)
Definition: suricata.c:257
SCLogInfo
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:224
SCClassConfGenerateInvalidDummyClassConfigFD03
FILE * SCClassConfGenerateInvalidDummyClassConfigFD03(void)
Creates a dummy classification file, with all invalid Classtypes, for testing purposes.
Definition: util-classification-config.c:638
DetectEngineCtx_::config_prefix
char config_prefix[64]
Definition: detect.h:962
FAIL_IF
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Definition: util-unittest.h:71
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:39
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:790
str
#define str(s)
Definition: suricata-common.h:291
SCLogError
#define SCLogError(...)
Macro used to log ERROR messages.
Definition: util-debug.h:261
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:2494
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:481
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:594
SCClassConfInit
void SCClassConfInit(DetectEngineCtx *de_ctx)
Definition: util-classification-config.c:61
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53
DetectEngineCtx_::tenant_id
uint32_t tenant_id
Definition: detect.h:845
SCClassConfLoadClassificationConfigFile
bool SCClassConfLoadClassificationConfigFile(DetectEngineCtx *de_ctx, FILE *fd)
Loads the Classtype info from the classification.config file.
Definition: util-classification-config.c:531
SCClassConfDeInitContext
void SCClassConfDeInitContext(DetectEngineCtx *de_ctx)
Releases resources used by the Classification Config API.
Definition: util-classification-config.c:191