]> git.ipfire.org Git - thirdparty/suricata-update.git/commitdiff
sid matchers: allow command separated sids 38/head
authorJason Ish <ish@unx.ca>
Thu, 21 Jun 2018 16:18:18 +0000 (10:18 -0600)
committerJason Ish <ish@unx.ca>
Thu, 21 Jun 2018 16:18:18 +0000 (10:18 -0600)
Inspired by patch from Russel Fulton.

suricata/update/main.py
tests/test_matchers.py

index e10824b21730084ae5950749881059784bcba470..e4c64baee86da8b94792c186c87e365d65a10185 100644 (file)
@@ -112,29 +112,42 @@ class IdRuleMatcher(object):
     """Matcher object to match an idstools rule object by its signature
     ID."""
 
-    def __init__(self, generatorId, signatureId):
-        self.generatorId = generatorId
-        self.signatureId = signatureId
+    def __init__(self, generatorId=None, signatureId=None):
+        self.signatureIds = []
+        if generatorId and signatureId:
+            self.signatureIds.append((generatorId, signatureId))
 
     def match(self, rule):
-        return self.generatorId == rule.gid and self.signatureId == rule.sid
+        for (generatorId, signatureId) in self.signatureIds:
+            if generatorId == rule.gid and signatureId == rule.sid:
+                return True
+        return False
 
     @classmethod
     def parse(cls, buf):
-        logger.debug("Parsing ID matcher: %s" % (buf))
-        try:
-            signatureId = int(buf)
-            return cls(1, signatureId)
-        except:
-            pass
-        try:
-            generatorString, signatureString = buf.split(":")
-            generatorId = int(generatorString)
-            signatureId = int(signatureString)
-            return cls(generatorId, signatureId)
-        except:
-            pass
-        return None
+        matcher = cls()
+
+        for entry in buf.split(","):
+            entry = entry.strip()
+
+            parts = entry.split(":", 1)
+            if not parts:
+                return None
+            if len(parts) == 1:
+                try:
+                    signatureId = int(parts[0])
+                    matcher.signatureIds.append((1, signatureId))
+                except:
+                    return None
+            else:
+                try:
+                    generatorId = int(parts[0])
+                    signatureId = int(parts[1])
+                    matcher.signatureIds.append((generatorId, signatureId))
+                except:
+                    return None
+
+        return matcher
 
 class FilenameMatcher(object):
     """Matcher object to match a rule by its filename. This is similar to
index e567a3f14155c34e29f00ce36d38e00a595a9693..c0df407532c3c742f17ad999dedfe0adf1424d23 100644 (file)
@@ -66,3 +66,43 @@ re:.# This is a comment*
             matchers[1].__class__, suricata.update.main.ReRuleMatcher)
         self.assertEquals(
             matchers[2].__class__, suricata.update.main.IdRuleMatcher)
+
+class IdRuleMatcherTestCase(unittest.TestCase):
+
+    def test_parse_single_sid(self):
+        matcher = main.IdRuleMatcher.parse("123")
+        self.assertIsNotNone(matcher)
+        self.assertEquals(1, len(matcher.signatureIds))
+
+    def test_parse_single_gidsid(self):
+        matcher = main.IdRuleMatcher.parse("1:123")
+        self.assertIsNotNone(matcher)
+        self.assertEquals(1, len(matcher.signatureIds))
+
+    def test_parse_multi_sid(self):
+        matcher = main.IdRuleMatcher.parse("1,2,3")
+        self.assertIsNotNone(matcher)
+        self.assertEquals(3, len(matcher.signatureIds))
+
+    def test_parse_multi_gidsid(self):
+        matcher = main.IdRuleMatcher.parse("1:1000,2:2000,    3:3000, 4:4000")
+        self.assertIsNotNone(matcher)
+        self.assertEquals(4, len(matcher.signatureIds))
+
+    def test_parse_multi_mixed(self):
+        matcher = main.IdRuleMatcher.parse("1:1000, 2000, 3:3000, 4000")
+        self.assertIsNotNone(matcher)
+        self.assertEquals(4, len(matcher.signatureIds))
+
+    def test_parse_invalid(self):
+        matcher = main.IdRuleMatcher.parse("a")
+        self.assertIsNone(matcher)
+
+        matcher = main.IdRuleMatcher.parse("1, a")
+        self.assertIsNone(matcher)
+
+        matcher = main.IdRuleMatcher.parse("1a")
+        self.assertIsNone(matcher)
+
+        matcher = main.IdRuleMatcher.parse("1:a")
+        self.assertIsNone(matcher)