]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect/parse: add --strict-rule-keywords option
authorVictor Julien <victor@inliniac.net>
Thu, 3 Oct 2019 08:32:42 +0000 (10:32 +0200)
committerVictor Julien <victor@inliniac.net>
Wed, 9 Oct 2019 13:26:59 +0000 (15:26 +0200)
Add --strict-rule-keywords commandline option to enable strict rule
parsing.

It can be used without options or with a comma separated list:
--strict-rule-keywords
--strict-rule-keywords=all
--strict-rule-keywords=classtype,reference

Parsing implementations can use SigMatchStrictEnabled to check
if strict parsing is enabled for them and act accordingly.

src/detect-parse.c
src/detect-parse.h
src/detect.h
src/suricata.c
src/suricata.h

index 8c1f6bf194ac80fef851453a353c47ca1e70da07..65e3b3564a798ba4167d9775318e6d9d844e6b87 100644 (file)
@@ -278,6 +278,50 @@ static SigTableElmt *SigTableGet(char *name)
     return NULL;
 }
 
+bool SigMatchStrictEnabled(const enum DetectKeywordId id)
+{
+    if (id < DETECT_TBLSIZE) {
+        return ((sigmatch_table[id].flags & SIGMATCH_STRICT_PARSING) != 0);
+    }
+    return false;
+}
+
+void SigTableApplyStrictCommandlineOption(const char *str)
+{
+    if (str == NULL) {
+        /* nothing to be done */
+        return;
+    }
+
+    /* "all" just sets the flag for each keyword */
+    if (strcmp(str, "all") == 0) {
+        for (int i = 0; i < DETECT_TBLSIZE; i++) {
+            SigTableElmt *st = &sigmatch_table[i];
+            st->flags |= SIGMATCH_STRICT_PARSING;
+        }
+        return;
+    }
+
+    char *copy = SCStrdup(str);
+    if (copy == NULL)
+        FatalError(SC_ERR_MEM_ALLOC, "could not duplicate opt string");
+
+    char *xsaveptr = NULL;
+    char *key = strtok_r(copy, ",", &xsaveptr);
+    while (key != NULL) {
+        SigTableElmt *st = SigTableGet(key);
+        if (st != NULL) {
+            st->flags |= SIGMATCH_STRICT_PARSING;
+        } else {
+            SCLogWarning(SC_ERR_CMD_LINE, "'strict' command line "
+                    "argument '%s' not found", key);
+        }
+        key = strtok_r(NULL, ",", &xsaveptr);
+    }
+
+    SCFree(copy);
+}
+
 /**
  * \brief Append a SigMatch to the list type.
  *
index c50c1792dba0a279dd90bb0a5aa5b727bb027ace..a390abbe58d603c1ef5e20404c431d0ad1ecd644 100644 (file)
@@ -59,9 +59,13 @@ int DetectEngineContentModifierBufferSetup(DetectEngineCtx *de_ctx,
         Signature *s, const char *arg, int sm_type, int sm_list,
         AppProto alproto);
 
+bool SigMatchStrictEnabled(const enum DetectKeywordId id);
+
 const char *DetectListToHumanString(int list);
 const char *DetectListToString(int list);
 
+void SigTableApplyStrictCommandlineOption(const char *str);
+
 SigMatch *DetectGetLastSM(const Signature *);
 SigMatch *DetectGetLastSMFromMpmLists(const DetectEngineCtx *de_ctx, const Signature *s);
 SigMatch *DetectGetLastSMFromLists(const Signature *s, ...);
index ae936040b9c3a69d1184f7ced15876d73280effb..35d17f43a011b2174cf0adf87b7584706ee85ebf 100644 (file)
@@ -1391,6 +1391,8 @@ typedef struct SigGroupHead_ {
 #define SIGMATCH_INFO_STICKY_BUFFER     BIT_U16(9)
 /** keyword is deprecated: used to suggest an alternative */
 #define SIGMATCH_INFO_DEPRECATED        BIT_U16(10)
+/** strict parsing is enabled */
+#define SIGMATCH_STRICT_PARSING         BIT_U16(11)
 
 enum DetectEngineTenantSelectors
 {
index 54621ff84aa2f2bd896af756e20e78048675c6c3..03865afe8cf9ecff22788e375136028021b58e98 100644 (file)
@@ -1467,6 +1467,7 @@ static TmEcode ParseCommandLine(int argc, char** argv, SCInstance *suri)
         {"pcap-file-delete", 0, 0, 0},
         {"simulate-ips", 0, 0 , 0},
         {"no-random", 0, &g_disable_randomness, 1},
+        {"strict-rule-keywords", optional_argument, 0, 0},
 
         /* AFL app-layer options. */
         {"afl-http-request", required_argument, 0 , 0},
@@ -1887,6 +1888,15 @@ static TmEcode ParseCommandLine(int argc, char** argv, SCInstance *suri)
                     return TM_ECODE_FAILED;
                 }
                 suri->set_datadir = true;
+            } else if (strcmp((long_opts[option_index]).name , "strict-rule-keywords") == 0){
+                if (optarg == NULL) {
+                    suri->strict_rule_parsing_string = SCStrdup("all");
+                } else {
+                    suri->strict_rule_parsing_string = SCStrdup(optarg);
+                }
+                if (suri->strict_rule_parsing_string == NULL) {
+                    FatalError(SC_ERR_MEM_ALLOC, "failed to duplicate 'strict' string");
+                }
             }
             break;
         case 'c':
@@ -2799,6 +2809,7 @@ static int PostConfLoadedSetup(SCInstance *suri)
 
     /* hardcoded initialization code */
     SigTableSetup(); /* load the rule keywords */
+    SigTableApplyStrictCommandlineOption(suri->strict_rule_parsing_string);
     TmqhSetup();
 
     CIDRInit();
index 6ddc5a92a89cacab77f71a2313e1766e680b9348..0ffba2cb6d765b5fb688f930345dd3a0157f92fc 100644 (file)
@@ -167,6 +167,7 @@ typedef struct SCInstance_ {
     const char *log_dir;
     const char *progname; /**< pointer to argv[0] */
     const char *conf_filename;
+    char *strict_rule_parsing_string;
 } SCInstance;