From: Jason Ish Date: Thu, 21 Jun 2018 16:18:18 +0000 (-0600) Subject: sid matchers: allow command separated sids X-Git-Tag: 1.0.0rc1~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d12b3127c76e2f58b83ef4ebbbe4e3d6261458c6;p=thirdparty%2Fsuricata-update.git sid matchers: allow command separated sids Inspired by patch from Russel Fulton. --- diff --git a/suricata/update/main.py b/suricata/update/main.py index e10824b..e4c64ba 100644 --- a/suricata/update/main.py +++ b/suricata/update/main.py @@ -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 diff --git a/tests/test_matchers.py b/tests/test_matchers.py index e567a3f..c0df407 100644 --- a/tests/test_matchers.py +++ b/tests/test_matchers.py @@ -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)