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