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