예제 #1
0
    def filter(self, record):
        """
        Filter given record based on rule's condition

        @note If the rule's condition is empty, record is always matched.

        @return Boolean
        """
        # The message must be converted via idea module
        if not isinstance(record, lite.Idea):
            logger.info("Converting message to IDEA")
            record = lite.Idea(record)

        logger.debug(record)
        logger.debug(self.__condition)

        if self.__condition == None or self.__condition == True:
            # Rule condition is empty (tautology) - should always match the record
            res = True
        elif self.__condition == False:
            res = False
        else:
            # Match the record with non-empty rule's condition
            res = self.__filter.filter(self.__condition, record)

        logger.debug("RESULT: %s", res)

        return res
예제 #2
0
    def setUp(self):
        self.flt = DataObjectFilter()
        self.psr = PynspectFilterParser()
        self.psr.build()
        self.cpl = IDEAFilterCompiler()

        self.msg_idea = lite.Idea(self.test_msg1)
예제 #3
0
class TestJPath(unittest.TestCase):

    msg_dict = {
        "Format":
        "IDEA0",
        "ID":
        "MESSAGE_ID",
        "DetectTime":
        "2016-06-21 13:08:27Z",
        "Category": ["CATEGORY"],
        "ConnCount":
        633,
        "Description":
        "Ping scan",
        "Source": [{
            "IP4": ["192.168.1.1", "192.168.1.2"],
            "Proto": ["icmp"]
        }, {
            "IP4": ["192.168.2.1", "192.168.2.2"],
            "Proto": ["tcp"]
        }],
        "Target": [{
            "Proto": ["udp"],
            "IP4": ["192.168.3.1", "192.168.3.2"],
            "Anonymised": True
        }],
        "Node": [{
            "SW": ["KIPPO", "FAIL_TO_BAN"],
            "Name": "node.name"
        }]
    }

    msg_idea = lite.Idea(msg_dict)

    def test_01_jpath_parse(self):
        """
        Perform the basic JPath parsing tests.

        Make sure all possible JPath forms parse correctly.
        """
        self.maxDiff = None

        cache_clear()
        self.assertEqual(cache_size(), 0)

        self.assertEqual(jpath_parse("Test"), [{
            'm': 'Test',
            'n': 'Test',
            'p': 'Test'
        }])
        self.assertEqual(jpath_parse("Test.Path"), [{
            'm': 'Test',
            'n': 'Test',
            'p': 'Test'
        }, {
            'm': 'Path',
            'n': 'Path',
            'p': 'Test.Path'
        }])
        self.assertEqual(jpath_parse("Long.Test.Path"), [{
            'm': 'Long',
            'n': 'Long',
            'p': 'Long'
        }, {
            'm': 'Test',
            'n': 'Test',
            'p': 'Long.Test'
        }, {
            'm': 'Path',
            'n': 'Path',
            'p': 'Long.Test.Path'
        }])

        self.assertEqual(jpath_parse("Long[1].Test.Path"),
                         [{
                             'i': 0,
                             'm': 'Long[1]',
                             'n': 'Long',
                             'p': 'Long[1]'
                         }, {
                             'm': 'Test',
                             'n': 'Test',
                             'p': 'Long[1].Test'
                         }, {
                             'm': 'Path',
                             'n': 'Path',
                             'p': 'Long[1].Test.Path'
                         }])
        self.assertEqual(jpath_parse("Long.Test[2].Path"),
                         [{
                             'm': 'Long',
                             'n': 'Long',
                             'p': 'Long'
                         }, {
                             'i': 1,
                             'm': 'Test[2]',
                             'n': 'Test',
                             'p': 'Long.Test[2]'
                         }, {
                             'm': 'Path',
                             'n': 'Path',
                             'p': 'Long.Test[2].Path'
                         }])
        self.assertEqual(jpath_parse("Long.Test.Path[3]"),
                         [{
                             'm': 'Long',
                             'n': 'Long',
                             'p': 'Long'
                         }, {
                             'm': 'Test',
                             'n': 'Test',
                             'p': 'Long.Test'
                         }, {
                             'i': 2,
                             'm': 'Path[3]',
                             'n': 'Path',
                             'p': 'Long.Test.Path[3]'
                         }])
        self.assertEqual(jpath_parse("Long[1].Test[1].Path"),
                         [{
                             'i': 0,
                             'm': 'Long[1]',
                             'n': 'Long',
                             'p': 'Long[1]'
                         }, {
                             'i': 0,
                             'm': 'Test[1]',
                             'n': 'Test',
                             'p': 'Long[1].Test[1]'
                         }, {
                             'm': 'Path',
                             'n': 'Path',
                             'p': 'Long[1].Test[1].Path'
                         }])
        self.assertEqual(jpath_parse("Long.Test[2].Path[2]"),
                         [{
                             'm': 'Long',
                             'n': 'Long',
                             'p': 'Long'
                         }, {
                             'i': 1,
                             'm': 'Test[2]',
                             'n': 'Test',
                             'p': 'Long.Test[2]'
                         }, {
                             'i': 1,
                             'm': 'Path[2]',
                             'n': 'Path',
                             'p': 'Long.Test[2].Path[2]'
                         }])
        self.assertEqual(jpath_parse("Long[3].Test.Path[3]"),
                         [{
                             'i': 2,
                             'm': 'Long[3]',
                             'n': 'Long',
                             'p': 'Long[3]'
                         }, {
                             'm': 'Test',
                             'n': 'Test',
                             'p': 'Long[3].Test'
                         }, {
                             'i': 2,
                             'm': 'Path[3]',
                             'n': 'Path',
                             'p': 'Long[3].Test.Path[3]'
                         }])

        self.assertEqual(jpath_parse("Long[#].Test.Path"),
                         [{
                             'i': -1,
                             'm': 'Long[#]',
                             'n': 'Long',
                             'p': 'Long[#]'
                         }, {
                             'm': 'Test',
                             'n': 'Test',
                             'p': 'Long[#].Test'
                         }, {
                             'm': 'Path',
                             'n': 'Path',
                             'p': 'Long[#].Test.Path'
                         }])
        self.assertEqual(jpath_parse("Long.Test[#].Path"),
                         [{
                             'm': 'Long',
                             'n': 'Long',
                             'p': 'Long'
                         }, {
                             'i': -1,
                             'm': 'Test[#]',
                             'n': 'Test',
                             'p': 'Long.Test[#]'
                         }, {
                             'm': 'Path',
                             'n': 'Path',
                             'p': 'Long.Test[#].Path'
                         }])
        self.assertEqual(jpath_parse("Long.Test.Path[#]"),
                         [{
                             'm': 'Long',
                             'n': 'Long',
                             'p': 'Long'
                         }, {
                             'm': 'Test',
                             'n': 'Test',
                             'p': 'Long.Test'
                         }, {
                             'i': -1,
                             'm': 'Path[#]',
                             'n': 'Path',
                             'p': 'Long.Test.Path[#]'
                         }])
        self.assertEqual(jpath_parse("Long[#].Test[#].Path"),
                         [{
                             'i': -1,
                             'm': 'Long[#]',
                             'n': 'Long',
                             'p': 'Long[#]'
                         }, {
                             'i': -1,
                             'm': 'Test[#]',
                             'n': 'Test',
                             'p': 'Long[#].Test[#]'
                         }, {
                             'm': 'Path',
                             'n': 'Path',
                             'p': 'Long[#].Test[#].Path'
                         }])
        self.assertEqual(jpath_parse("Long.Test[#].Path[#]"),
                         [{
                             'm': 'Long',
                             'n': 'Long',
                             'p': 'Long'
                         }, {
                             'i': -1,
                             'm': 'Test[#]',
                             'n': 'Test',
                             'p': 'Long.Test[#]'
                         }, {
                             'i': -1,
                             'm': 'Path[#]',
                             'n': 'Path',
                             'p': 'Long.Test[#].Path[#]'
                         }])
        self.assertEqual(jpath_parse("Long[#].Test.Path[#]"),
                         [{
                             'i': -1,
                             'm': 'Long[#]',
                             'n': 'Long',
                             'p': 'Long[#]'
                         }, {
                             'm': 'Test',
                             'n': 'Test',
                             'p': 'Long[#].Test'
                         }, {
                             'i': -1,
                             'm': 'Path[#]',
                             'n': 'Path',
                             'p': 'Long[#].Test.Path[#]'
                         }])

        self.assertEqual(jpath_parse("Long[*].Test.Path"),
                         [{
                             'i': '*',
                             'm': 'Long[*]',
                             'n': 'Long',
                             'p': 'Long[*]'
                         }, {
                             'm': 'Test',
                             'n': 'Test',
                             'p': 'Long[*].Test'
                         }, {
                             'm': 'Path',
                             'n': 'Path',
                             'p': 'Long[*].Test.Path'
                         }])
        self.assertEqual(jpath_parse("Long.Test[*].Path"),
                         [{
                             'm': 'Long',
                             'n': 'Long',
                             'p': 'Long'
                         }, {
                             'i': '*',
                             'm': 'Test[*]',
                             'n': 'Test',
                             'p': 'Long.Test[*]'
                         }, {
                             'm': 'Path',
                             'n': 'Path',
                             'p': 'Long.Test[*].Path'
                         }])
        self.assertEqual(jpath_parse("Long.Test.Path[*]"),
                         [{
                             'm': 'Long',
                             'n': 'Long',
                             'p': 'Long'
                         }, {
                             'm': 'Test',
                             'n': 'Test',
                             'p': 'Long.Test'
                         }, {
                             'i': '*',
                             'm': 'Path[*]',
                             'n': 'Path',
                             'p': 'Long.Test.Path[*]'
                         }])
        self.assertEqual(jpath_parse("Long[*].Test[*].Path"),
                         [{
                             'i': '*',
                             'm': 'Long[*]',
                             'n': 'Long',
                             'p': 'Long[*]'
                         }, {
                             'i': '*',
                             'm': 'Test[*]',
                             'n': 'Test',
                             'p': 'Long[*].Test[*]'
                         }, {
                             'm': 'Path',
                             'n': 'Path',
                             'p': 'Long[*].Test[*].Path'
                         }])
        self.assertEqual(jpath_parse("Long.Test[*].Path[*]"),
                         [{
                             'm': 'Long',
                             'n': 'Long',
                             'p': 'Long'
                         }, {
                             'i': '*',
                             'm': 'Test[*]',
                             'n': 'Test',
                             'p': 'Long.Test[*]'
                         }, {
                             'i': '*',
                             'm': 'Path[*]',
                             'n': 'Path',
                             'p': 'Long.Test[*].Path[*]'
                         }])
        self.assertEqual(jpath_parse("Long[*].Test.Path[*]"),
                         [{
                             'i': '*',
                             'm': 'Long[*]',
                             'n': 'Long',
                             'p': 'Long[*]'
                         }, {
                             'm': 'Test',
                             'n': 'Test',
                             'p': 'Long[*].Test'
                         }, {
                             'i': '*',
                             'm': 'Path[*]',
                             'n': 'Path',
                             'p': 'Long[*].Test.Path[*]'
                         }])

        self.assertEqual(jpath_parse("Test"), [{
            'm': 'Test',
            'n': 'Test',
            'p': 'Test'
        }])
        self.assertEqual(jpath_parse("test"), [{
            'm': 'test',
            'n': 'test',
            'p': 'test'
        }])
        self.assertEqual(jpath_parse("TEST"), [{
            'm': 'TEST',
            'n': 'TEST',
            'p': 'TEST'
        }])
        self.assertEqual(jpath_parse("_test"), [{
            'm': '_test',
            'n': '_test',
            'p': '_test'
        }])

        self.assertRaisesRegex(JPathException, "Invalid JPath chunk",
                               jpath_parse, 'Test/Value')
        self.assertRaisesRegex(JPathException, "Invalid JPath chunk",
                               jpath_parse, 'Test|Value')
        self.assertRaisesRegex(JPathException, "Invalid JPath chunk",
                               jpath_parse, 'Test-Value')
        self.assertRaisesRegex(JPathException, "Invalid JPath chunk",
                               jpath_parse, 'Test-.Value')
        self.assertRaisesRegex(JPathException, "Invalid JPath chunk",
                               jpath_parse, 'Test[]Value')
        self.assertRaisesRegex(JPathException, "Invalid JPath chunk",
                               jpath_parse, 'TestValue[]')
        self.assertRaisesRegex(JPathException, "Invalid JPath chunk",
                               jpath_parse, 'Test[1]Value')
        self.assertRaisesRegex(JPathException, "Invalid JPath chunk",
                               jpath_parse, 'Test[].Value')
        self.assertRaisesRegex(JPathException, "Invalid JPath chunk",
                               jpath_parse, 'Test.Value[]')
        self.assertRaisesRegex(JPathException, "Invalid JPath chunk",
                               jpath_parse, 'Test[-1].Value')
        self.assertRaisesRegex(JPathException, "Invalid JPath chunk",
                               jpath_parse, 'Test.[1].Value')
        self.assertRaisesRegex(JPathException, "Invalid JPath chunk",
                               jpath_parse, 'Test.Value.[1]')

        self.assertEqual(jpath_parse_c("Test"), [{
            'm': 'Test',
            'n': 'Test',
            'p': 'Test'
        }])
        self.assertEqual(jpath_parse_c("Test.Path"), [{
            'm': 'Test',
            'n': 'Test',
            'p': 'Test'
        }, {
            'm': 'Path',
            'n': 'Path',
            'p': 'Test.Path'
        }])
        self.assertEqual(jpath_parse_c("Long.Test.Path"),
                         [{
                             'm': 'Long',
                             'n': 'Long',
                             'p': 'Long'
                         }, {
                             'm': 'Test',
                             'n': 'Test',
                             'p': 'Long.Test'
                         }, {
                             'm': 'Path',
                             'n': 'Path',
                             'p': 'Long.Test.Path'
                         }])
        self.assertEqual(jpath_parse_c("Test"), [{
            'm': 'Test',
            'n': 'Test',
            'p': 'Test'
        }])
        self.assertEqual(jpath_parse_c("Test.Path"), [{
            'm': 'Test',
            'n': 'Test',
            'p': 'Test'
        }, {
            'm': 'Path',
            'n': 'Path',
            'p': 'Test.Path'
        }])
        self.assertEqual(jpath_parse_c("Long.Test.Path"),
                         [{
                             'm': 'Long',
                             'n': 'Long',
                             'p': 'Long'
                         }, {
                             'm': 'Test',
                             'n': 'Test',
                             'p': 'Long.Test'
                         }, {
                             'm': 'Path',
                             'n': 'Path',
                             'p': 'Long.Test.Path'
                         }])

        self.assertEqual(cache_size(), 3)
        cache_clear()
        self.assertEqual(cache_size(), 0)

    def test_02_jpath_values(self):
        """
        Perform the basic JPath values retrieval tests.

        Make sure all possible JPath forms return expected results.
        """
        self.maxDiff = None

        self.assertEqual(jpath_values(self.msg_dict, 'Format'), ['IDEA0'])
        self.assertEqual(jpath_values(self.msg_dict, 'Format[1]'), [])
        self.assertEqual(jpath_values(self.msg_dict, 'Format[#]'), [])
        self.assertEqual(jpath_values(self.msg_dict, 'Format[*]'), [])

        self.assertEqual(jpath_values(self.msg_dict, 'Category'), ['CATEGORY'])
        self.assertEqual(jpath_values(self.msg_dict, 'Category[1]'),
                         ['CATEGORY'])
        self.assertEqual(jpath_values(self.msg_dict, 'Category[2]'), [])
        self.assertEqual(jpath_values(self.msg_dict, 'Category[#]'),
                         ['CATEGORY'])
        self.assertEqual(jpath_values(self.msg_dict, 'Category[*]'),
                         ['CATEGORY'])

        self.assertEqual(jpath_values(self.msg_dict, 'Node.SW'),
                         ['KIPPO', 'FAIL_TO_BAN'])
        self.assertEqual(jpath_values(self.msg_dict, 'Node[1].SW'),
                         ['KIPPO', 'FAIL_TO_BAN'])
        self.assertEqual(jpath_values(self.msg_dict, 'Node[#].SW'),
                         ['KIPPO', 'FAIL_TO_BAN'])
        self.assertEqual(jpath_values(self.msg_dict, 'Node[*].SW'),
                         ['KIPPO', 'FAIL_TO_BAN'])
        self.assertEqual(jpath_values(self.msg_dict, 'Node[#].SW[1]'),
                         ['KIPPO'])
        self.assertEqual(jpath_values(self.msg_dict, 'Node[#].SW[2]'),
                         ['FAIL_TO_BAN'])
        self.assertEqual(jpath_values(self.msg_dict, 'Node[#].SW[#]'),
                         ['FAIL_TO_BAN'])
        self.assertEqual(jpath_values(self.msg_dict, 'Node[#].SW[*]'),
                         ['KIPPO', 'FAIL_TO_BAN'])

        self.assertEqual(jpath_values(self.msg_dict, 'Node.Name'),
                         ['node.name'])
        self.assertEqual(jpath_values(self.msg_dict, 'Node[1].Name'),
                         ['node.name'])
        self.assertEqual(jpath_values(self.msg_dict, 'Node[#].Name'),
                         ['node.name'])
        self.assertEqual(jpath_values(self.msg_dict, 'Node[*].Name'),
                         ['node.name'])
        self.assertEqual(jpath_values(self.msg_dict, 'Node[1].Name[1]'), [])
        self.assertEqual(jpath_values(self.msg_dict, 'Node[#].Name[#]'), [])
        self.assertEqual(jpath_values(self.msg_dict, 'Node[*].Name[*]'), [])

        self.assertEqual(
            jpath_values(self.msg_dict, 'Source.IP4'),
            ['192.168.1.1', '192.168.1.2', '192.168.2.1', '192.168.2.2'])
        self.assertEqual(jpath_values(self.msg_dict, 'Source[1].IP4'),
                         ['192.168.1.1', '192.168.1.2'])
        self.assertEqual(jpath_values(self.msg_dict, 'Source[2].IP4'),
                         ['192.168.2.1', '192.168.2.2'])
        self.assertEqual(jpath_values(self.msg_dict, 'Source[#].IP4'),
                         ['192.168.2.1', '192.168.2.2'])
        self.assertEqual(
            jpath_values(self.msg_dict, 'Source[*].IP4'),
            ['192.168.1.1', '192.168.1.2', '192.168.2.1', '192.168.2.2'])
        self.assertEqual(jpath_values(self.msg_dict, 'Source.IP4[1]'),
                         ['192.168.1.1', '192.168.2.1'])
        self.assertEqual(jpath_values(self.msg_dict, 'Source.IP4[2]'),
                         ['192.168.1.2', '192.168.2.2'])
        self.assertEqual(jpath_values(self.msg_dict, 'Source.IP4[#]'),
                         ['192.168.1.2', '192.168.2.2'])
        self.assertEqual(
            jpath_values(self.msg_dict, 'Source.IP4[*]'),
            ['192.168.1.1', '192.168.1.2', '192.168.2.1', '192.168.2.2'])
        self.assertEqual(jpath_values(self.msg_dict, 'Source[1].IP4[1]'),
                         ['192.168.1.1'])
        self.assertEqual(jpath_values(self.msg_dict, 'Source[1].IP4[2]'),
                         ['192.168.1.2'])
        self.assertEqual(jpath_values(self.msg_dict, 'Source[1].IP4[#]'),
                         ['192.168.1.2'])
        self.assertEqual(jpath_values(self.msg_dict, 'Source[1].IP4[*]'),
                         ['192.168.1.1', '192.168.1.2'])
        self.assertEqual(jpath_values(self.msg_dict, 'Source[2].IP4[1]'),
                         ['192.168.2.1'])
        self.assertEqual(jpath_values(self.msg_dict, 'Source[2].IP4[2]'),
                         ['192.168.2.2'])
        self.assertEqual(jpath_values(self.msg_dict, 'Source[2].IP4[#]'),
                         ['192.168.2.2'])
        self.assertEqual(jpath_values(self.msg_dict, 'Source[2].IP4[*]'),
                         ['192.168.2.1', '192.168.2.2'])
        self.assertEqual(jpath_values(self.msg_dict, 'Source[#].IP4[1]'),
                         ['192.168.2.1'])
        self.assertEqual(jpath_values(self.msg_dict, 'Source[#].IP4[2]'),
                         ['192.168.2.2'])
        self.assertEqual(jpath_values(self.msg_dict, 'Source[#].IP4[#]'),
                         ['192.168.2.2'])
        self.assertEqual(jpath_values(self.msg_dict, 'Source[#].IP4[*]'),
                         ['192.168.2.1', '192.168.2.2'])
        self.assertEqual(jpath_values(self.msg_dict, 'Source[*].IP4[1]'),
                         ['192.168.1.1', '192.168.2.1'])
        self.assertEqual(jpath_values(self.msg_dict, 'Source[*].IP4[2]'),
                         ['192.168.1.2', '192.168.2.2'])
        self.assertEqual(jpath_values(self.msg_dict, 'Source[*].IP4[#]'),
                         ['192.168.1.2', '192.168.2.2'])
        self.assertEqual(
            jpath_values(self.msg_dict, 'Source[*].IP4[*]'),
            ['192.168.1.1', '192.168.1.2', '192.168.2.1', '192.168.2.2'])

        self.assertEqual(jpath_values(self.msg_idea, 'Format'), ['IDEA0'])
        self.assertEqual(jpath_values(self.msg_idea, 'Node.Name'),
                         ['node.name'])
        self.assertEqual(jpath_values(self.msg_idea, 'Node[1].Name'),
                         ['node.name'])
        self.assertEqual(jpath_values(self.msg_idea, 'Node[#].Name'),
                         ['node.name'])
        self.assertEqual(jpath_values(self.msg_idea, 'Node[*].Name'),
                         ['node.name'])
        self.assertEqual(jpath_values(self.msg_idea, 'Node[1].Name[1]'), [])
        self.assertEqual(jpath_values(self.msg_idea, 'Node[#].Name[#]'), [])
        self.assertEqual(jpath_values(self.msg_idea, 'Node[*].Name[*]'), [])
        self.assertEqual(jpath_values(self.msg_idea, 'Node.SW'),
                         ['KIPPO', 'FAIL_TO_BAN'])
        self.assertEqual(jpath_values(self.msg_idea, 'Node[1].SW'),
                         ['KIPPO', 'FAIL_TO_BAN'])
        self.assertEqual(jpath_values(self.msg_idea, 'Node[#].SW'),
                         ['KIPPO', 'FAIL_TO_BAN'])
        self.assertEqual(jpath_values(self.msg_idea, 'Node[*].SW'),
                         ['KIPPO', 'FAIL_TO_BAN'])
        self.assertEqual(jpath_values(self.msg_idea, 'Node[#].SW[1]'),
                         ['KIPPO'])
        self.assertEqual(jpath_values(self.msg_idea, 'Node[#].SW[2]'),
                         ['FAIL_TO_BAN'])
        self.assertEqual(jpath_values(self.msg_idea, 'Node[#].SW[#]'),
                         ['FAIL_TO_BAN'])
        self.assertEqual(jpath_values(self.msg_idea, 'Node[#].SW[*]'),
                         ['KIPPO', 'FAIL_TO_BAN'])

    def test_03_jpath_value(self):
        """
        Perform the basic JPath value retrieval tests.

        Make sure all possible JPath forms return expected results.
        """
        self.maxDiff = None

        self.assertEqual(jpath_value(self.msg_dict, 'Format'), 'IDEA0')
        self.assertEqual(jpath_value(self.msg_dict, 'Format[1]'), None)
        self.assertEqual(jpath_value(self.msg_dict, 'Format[#]'), None)
        self.assertEqual(jpath_value(self.msg_dict, 'Format[*]'), None)

        self.assertEqual(jpath_value(self.msg_dict, 'Category'), 'CATEGORY')
        self.assertEqual(jpath_value(self.msg_dict, 'Category[1]'), 'CATEGORY')
        self.assertEqual(jpath_value(self.msg_dict, 'Category[2]'), None)
        self.assertEqual(jpath_value(self.msg_dict, 'Category[#]'), 'CATEGORY')
        self.assertEqual(jpath_value(self.msg_dict, 'Category[*]'), 'CATEGORY')

        self.assertEqual(jpath_value(self.msg_dict, 'Node.SW'), 'KIPPO')
        self.assertEqual(jpath_value(self.msg_dict, 'Node[1].SW'), 'KIPPO')
        self.assertEqual(jpath_value(self.msg_dict, 'Node[#].SW'), 'KIPPO')
        self.assertEqual(jpath_value(self.msg_dict, 'Node[*].SW'), 'KIPPO')
        self.assertEqual(jpath_value(self.msg_dict, 'Node[#].SW[1]'), 'KIPPO')
        self.assertEqual(jpath_value(self.msg_dict, 'Node[#].SW[2]'),
                         'FAIL_TO_BAN')
        self.assertEqual(jpath_value(self.msg_dict, 'Node[#].SW[#]'),
                         'FAIL_TO_BAN')
        self.assertEqual(jpath_value(self.msg_dict, 'Node[#].SW[*]'), 'KIPPO')

        self.assertEqual(jpath_value(self.msg_dict, 'Node.Name'), 'node.name')
        self.assertEqual(jpath_value(self.msg_dict, 'Node[1].Name'),
                         'node.name')
        self.assertEqual(jpath_value(self.msg_dict, 'Node[#].Name'),
                         'node.name')
        self.assertEqual(jpath_value(self.msg_dict, 'Node[*].Name'),
                         'node.name')
        self.assertEqual(jpath_value(self.msg_dict, 'Node[1].Name[1]'), None)
        self.assertEqual(jpath_value(self.msg_dict, 'Node[#].Name[#]'), None)
        self.assertEqual(jpath_value(self.msg_dict, 'Node[*].Name[*]'), None)

        self.assertEqual(jpath_value(self.msg_dict, 'Source.IP4'),
                         '192.168.1.1')
        self.assertEqual(jpath_value(self.msg_dict, 'Source[1].IP4'),
                         '192.168.1.1')
        self.assertEqual(jpath_value(self.msg_dict, 'Source[2].IP4'),
                         '192.168.2.1')
        self.assertEqual(jpath_value(self.msg_dict, 'Source[#].IP4'),
                         '192.168.2.1')
        self.assertEqual(jpath_value(self.msg_dict, 'Source[*].IP4'),
                         '192.168.1.1')
        self.assertEqual(jpath_value(self.msg_dict, 'Source.IP4[1]'),
                         '192.168.1.1')
        self.assertEqual(jpath_value(self.msg_dict, 'Source.IP4[2]'),
                         '192.168.1.2')
        self.assertEqual(jpath_value(self.msg_dict, 'Source.IP4[#]'),
                         '192.168.1.2')
        self.assertEqual(jpath_value(self.msg_dict, 'Source.IP4[*]'),
                         '192.168.1.1')
        self.assertEqual(jpath_value(self.msg_dict, 'Source[1].IP4[1]'),
                         '192.168.1.1')
        self.assertEqual(jpath_value(self.msg_dict, 'Source[1].IP4[2]'),
                         '192.168.1.2')
        self.assertEqual(jpath_value(self.msg_dict, 'Source[1].IP4[#]'),
                         '192.168.1.2')
        self.assertEqual(jpath_value(self.msg_dict, 'Source[1].IP4[*]'),
                         '192.168.1.1')
        self.assertEqual(jpath_value(self.msg_dict, 'Source[2].IP4[1]'),
                         '192.168.2.1')
        self.assertEqual(jpath_value(self.msg_dict, 'Source[2].IP4[2]'),
                         '192.168.2.2')
        self.assertEqual(jpath_value(self.msg_dict, 'Source[2].IP4[#]'),
                         '192.168.2.2')
        self.assertEqual(jpath_value(self.msg_dict, 'Source[2].IP4[*]'),
                         '192.168.2.1')
        self.assertEqual(jpath_value(self.msg_dict, 'Source[#].IP4[1]'),
                         '192.168.2.1')
        self.assertEqual(jpath_value(self.msg_dict, 'Source[#].IP4[2]'),
                         '192.168.2.2')
        self.assertEqual(jpath_value(self.msg_dict, 'Source[#].IP4[#]'),
                         '192.168.2.2')
        self.assertEqual(jpath_value(self.msg_dict, 'Source[#].IP4[*]'),
                         '192.168.2.1')
        self.assertEqual(jpath_value(self.msg_dict, 'Source[*].IP4[1]'),
                         '192.168.1.1')
        self.assertEqual(jpath_value(self.msg_dict, 'Source[*].IP4[2]'),
                         '192.168.1.2')
        self.assertEqual(jpath_value(self.msg_dict, 'Source[*].IP4[#]'),
                         '192.168.1.2')
        self.assertEqual(jpath_value(self.msg_dict, 'Source[*].IP4[*]'),
                         '192.168.1.1')

        self.assertEqual(jpath_value(self.msg_idea, 'Format'), 'IDEA0')
        self.assertEqual(jpath_value(self.msg_idea, 'Node.Name'), 'node.name')
        self.assertEqual(jpath_value(self.msg_idea, 'Node[1].Name'),
                         'node.name')
        self.assertEqual(jpath_value(self.msg_idea, 'Node[#].Name'),
                         'node.name')
        self.assertEqual(jpath_value(self.msg_idea, 'Node[*].Name'),
                         'node.name')
        self.assertEqual(jpath_value(self.msg_idea, 'Node[1].Name[1]'), None)
        self.assertEqual(jpath_value(self.msg_idea, 'Node[#].Name[#]'), None)
        self.assertEqual(jpath_value(self.msg_idea, 'Node[*].Name[*]'), None)
        self.assertEqual(jpath_value(self.msg_idea, 'Node.SW'), 'KIPPO')
        self.assertEqual(jpath_value(self.msg_idea, 'Node[1].SW'), 'KIPPO')
        self.assertEqual(jpath_value(self.msg_idea, 'Node[#].SW'), 'KIPPO')
        self.assertEqual(jpath_value(self.msg_idea, 'Node[*].SW'), 'KIPPO')
        self.assertEqual(jpath_value(self.msg_idea, 'Node[#].SW[1]'), 'KIPPO')
        self.assertEqual(jpath_value(self.msg_idea, 'Node[#].SW[2]'),
                         'FAIL_TO_BAN')
        self.assertEqual(jpath_value(self.msg_idea, 'Node[#].SW[#]'),
                         'FAIL_TO_BAN')
        self.assertEqual(jpath_value(self.msg_idea, 'Node[#].SW[*]'), 'KIPPO')

    def test_04_jpath_exists(self):
        """
        Perform the basic JPath elements existence tests.

        Make sure all possible JPath forms return expected results.
        """
        self.maxDiff = None

        self.assertEqual(jpath_exists(self.msg_dict, 'Format'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Format[1]'), False)
        self.assertEqual(jpath_exists(self.msg_dict, 'Format[#]'), False)
        self.assertEqual(jpath_exists(self.msg_dict, 'Format[*]'), False)

        self.assertEqual(jpath_exists(self.msg_dict, 'Category'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Category[1]'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Category[2]'), False)
        self.assertEqual(jpath_exists(self.msg_dict, 'Category[#]'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Category[*]'), True)

        self.assertEqual(jpath_exists(self.msg_dict, 'Node.SW'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Node[1].SW'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Node[#].SW'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Node[*].SW'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Node[#].SW[1]'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Node[#].SW[2]'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Node[#].SW[#]'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Node[#].SW[*]'), True)

        self.assertEqual(jpath_exists(self.msg_dict, 'Node.Name'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Node[1].Name'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Node[#].Name'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Node[*].Name'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Node[1].Name[1]'), False)
        self.assertEqual(jpath_exists(self.msg_dict, 'Node[#].Name[#]'), False)
        self.assertEqual(jpath_exists(self.msg_dict, 'Node[*].Name[*]'), False)

        self.assertEqual(jpath_exists(self.msg_dict, 'Source.IP4'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Source[1].IP4'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Source[2].IP4'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Source[#].IP4'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Source[*].IP4'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Source.IP4[1]'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Source.IP4[2]'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Source.IP4[#]'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Source.IP4[*]'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Source[1].IP4[1]'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Source[1].IP4[2]'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Source[1].IP4[#]'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Source[1].IP4[*]'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Source[2].IP4[1]'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Source[2].IP4[2]'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Source[2].IP4[#]'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Source[2].IP4[*]'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Source[#].IP4[1]'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Source[#].IP4[2]'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Source[#].IP4[#]'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Source[#].IP4[*]'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Source[*].IP4[1]'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Source[*].IP4[2]'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Source[*].IP4[#]'), True)
        self.assertEqual(jpath_exists(self.msg_dict, 'Source[*].IP4[*]'), True)

        self.assertEqual(jpath_exists(self.msg_idea, 'Format'), True)
        self.assertEqual(jpath_exists(self.msg_idea, 'Node.Name'), True)
        self.assertEqual(jpath_exists(self.msg_idea, 'Node[1].Name'), True)
        self.assertEqual(jpath_exists(self.msg_idea, 'Node[#].Name'), True)
        self.assertEqual(jpath_exists(self.msg_idea, 'Node[*].Name'), True)
        self.assertEqual(jpath_exists(self.msg_idea, 'Node[1].Name[1]'), False)
        self.assertEqual(jpath_exists(self.msg_idea, 'Node[#].Name[#]'), False)
        self.assertEqual(jpath_exists(self.msg_idea, 'Node[*].Name[*]'), False)
        self.assertEqual(jpath_exists(self.msg_idea, 'Node.SW'), True)
        self.assertEqual(jpath_exists(self.msg_idea, 'Node[1].SW'), True)
        self.assertEqual(jpath_exists(self.msg_idea, 'Node[#].SW'), True)
        self.assertEqual(jpath_exists(self.msg_idea, 'Node[*].SW'), True)
        self.assertEqual(jpath_exists(self.msg_idea, 'Node[#].SW[1]'), True)
        self.assertEqual(jpath_exists(self.msg_idea, 'Node[#].SW[2]'), True)
        self.assertEqual(jpath_exists(self.msg_idea, 'Node[#].SW[#]'), True)
        self.assertEqual(jpath_exists(self.msg_idea, 'Node[#].SW[*]'), True)

    def test_05_jpath_set(self):
        """
        Perform the basic JPath value setting tests.
        """
        self.maxDiff = None

        msg = {}
        self.assertEqual(jpath_set(msg, 'TestA.ValueA1', 'A1'), RC_VALUE_SET)
        self.assertEqual(msg, {'TestA': {'ValueA1': 'A1'}})
        self.assertEqual(jpath_set(msg, 'TestA.ValueA2', 'A2'), RC_VALUE_SET)
        self.assertEqual(msg, {'TestA': {'ValueA1': 'A1', 'ValueA2': 'A2'}})
        self.assertEqual(jpath_set(msg, 'TestB[1].ValueB1', 'B1'),
                         RC_VALUE_SET)
        self.assertEqual(
            msg, {
                'TestA': {
                    'ValueA1': 'A1',
                    'ValueA2': 'A2'
                },
                'TestB': [{
                    'ValueB1': 'B1'
                }]
            })
        self.assertEqual(jpath_set(msg, 'TestB[#].ValueB2', 'B2'),
                         RC_VALUE_SET)
        self.assertEqual(
            msg, {
                'TestA': {
                    'ValueA1': 'A1',
                    'ValueA2': 'A2'
                },
                'TestB': [{
                    'ValueB1': 'B1',
                    'ValueB2': 'B2'
                }]
            })
        self.assertEqual(jpath_set(msg, 'TestB[*].ValueB3', 'B3'),
                         RC_VALUE_SET)
        self.assertEqual(
            msg, {
                'TestA': {
                    'ValueA1': 'A1',
                    'ValueA2': 'A2'
                },
                'TestB': [{
                    'ValueB1': 'B1',
                    'ValueB2': 'B2'
                }, {
                    'ValueB3': 'B3'
                }]
            })
        self.assertEqual(jpath_set(msg, 'TestB[#].ValueB4', 'B4'),
                         RC_VALUE_SET)
        self.assertEqual(
            msg, {
                'TestA': {
                    'ValueA1': 'A1',
                    'ValueA2': 'A2'
                },
                'TestB': [{
                    'ValueB1': 'B1',
                    'ValueB2': 'B2'
                }, {
                    'ValueB3': 'B3',
                    'ValueB4': 'B4'
                }]
            })
        self.assertEqual(jpath_set(msg, 'TestB[#]', 'DROP'), RC_VALUE_SET)
        self.assertEqual(
            msg, {
                'TestA': {
                    'ValueA1': 'A1',
                    'ValueA2': 'A2'
                },
                'TestB': [{
                    'ValueB1': 'B1',
                    'ValueB2': 'B2'
                }, "DROP"]
            })

        # This will fail, because "TestA" node is not a list
        self.assertRaisesRegex(
            JPathException, "Expected list-like object under structure key",
            jpath_set, msg, 'TestA[#].ValueC1', 'C1')

        # This will fail, because "TestA.ValueA1" node is not a dict
        self.assertRaisesRegex(
            JPathException, "Expected dict-like object under structure key",
            jpath_set, msg, 'TestA.ValueA1.ValueC1', 'C1')

        # This will fail, because we try to attach a node to scalar "TestB[#]"
        self.assertRaisesRegex(JPathException,
                               "Expected dict-like structure to attach node",
                               jpath_set, msg, 'TestB[#].ValueB5',
                               'RAISE EXCEPTION')

    def test_06_jpath_set_unique(self):
        """
        Perform JPath value setting tests with unique flag.
        """
        self.maxDiff = None

        msg = {}
        self.assertEqual(
            jpath_set(msg, 'TestC[#].ListVals1[*]', 'LV1', unique=True),
            RC_VALUE_SET)
        self.assertEqual(msg, {'TestC': [{'ListVals1': ['LV1']}]})
        self.assertEqual(
            jpath_set(msg, 'TestC[#].ListVals1[*]', 'LV2', unique=True),
            RC_VALUE_SET)
        self.assertEqual(msg, {'TestC': [{'ListVals1': ['LV1', 'LV2']}]})
        self.assertEqual(
            jpath_set(msg, 'TestC[#].ListVals1[*]', 'LV1', unique=True),
            RC_VALUE_DUPLICATE)
        self.assertEqual(msg, {'TestC': [{'ListVals1': ['LV1', 'LV2']}]})

    def test_07_jpath_set_overwrite(self):
        """
        Perform JPath value setting tests with overwrite flag.
        """
        self.maxDiff = None

        msg = {}

        #
        # Overwriting in lists.
        #
        self.assertEqual(
            jpath_set(msg, 'TestD[#].ListVals1[*]', 'LV1', overwrite=False),
            RC_VALUE_SET)
        self.assertEqual(msg, {'TestD': [{'ListVals1': ['LV1']}]})
        self.assertEqual(
            jpath_set(msg, 'TestD[#].ListVals1[*]', 'LV2', overwrite=False),
            RC_VALUE_SET)
        self.assertEqual(msg, {'TestD': [{'ListVals1': ['LV1', 'LV2']}]})
        self.assertEqual(
            jpath_set(msg, 'TestD[#].ListVals1[2]', 'LV3', overwrite=False),
            RC_VALUE_EXISTS)
        self.assertEqual(msg, {'TestD': [{'ListVals1': ['LV1', 'LV2']}]})
        self.assertEqual(
            jpath_set(msg, 'TestD[#].ListVals1[3]', 'LV3', overwrite=False),
            RC_VALUE_SET)
        self.assertEqual(msg,
                         {'TestD': [{
                             'ListVals1': ['LV1', 'LV2', 'LV3']
                         }]})

        #
        # Overwriting in dicts.
        #
        self.assertEqual(
            jpath_set(msg, 'TestD[#].DictVal', 'DV1', overwrite=False),
            RC_VALUE_SET)
        self.assertEqual(msg, {
            'TestD': [{
                'ListVals1': ['LV1', 'LV2', 'LV3'],
                'DictVal': 'DV1'
            }]
        })
        self.assertEqual(
            jpath_set(msg, 'TestD[#].DictVal', 'DV2', overwrite=False),
            RC_VALUE_EXISTS)
        self.assertEqual(msg, {
            'TestD': [{
                'ListVals1': ['LV1', 'LV2', 'LV3'],
                'DictVal': 'DV1'
            }]
        })
    def test_01_inspector_filters(self):
        """
        Perform tests of filters currently used in mentat-inspector.py.
        """
        self.maxDiff = None

        inspection_rules = [{
            "filter":
            "Category in ['Attempt.Login'] and Target.Port in [3389]",
            "str":
            '((Category OP_IN ["Attempt.Login"]) OP_AND (Target.Port OP_IN [3389]))',
            "tests": [[{
                "Format":
                "IDEA0",
                "ID":
                "e214d2d9-359b-443d-993d-3cc5637107a0",
                "Source": [{
                    "IP4": ["188.14.166.39"]
                }],
                "Target": [{
                    "IP4": ["195.113.165.128/25"],
                    "Port": ["3389"],
                    "Proto": ["tcp", "ssh"]
                }],
                "Note":
                "SSH login attempt",
                "DetectTime":
                "2016-06-21 13:08:27Z",
                "Node": [{
                    "Type": ["Connection", "Honeypot"],
                    "SW": ["Kippo"],
                    "Name": "cz.uhk.apate.cowrie"
                }],
                "Category": ["Attempt.Login"]
            }, True],
                      [{
                          "Format":
                          "IDEA0",
                          "ID":
                          "e214d2d9-359b-443d-993d-3cc5637107a0",
                          "Source": [{
                              "IP4": ["188.14.166.39"]
                          }],
                          "Target": [{
                              "IP4": ["195.113.165.128/25"],
                              "Port": ["338"],
                              "Proto": ["tcp", "ssh"]
                          }],
                          "Note":
                          "SSH login attempt",
                          "DetectTime":
                          "2016-06-21 13:08:27Z",
                          "Node": [{
                              "Type": ["Connection", "Honeypot"],
                              "SW": ["Kippo"],
                              "Name": "cz.uhk.apate.cowrie"
                          }],
                          "Category": ["Attempt.Login"]
                      }, False]],
        }, {
            "filter":
            "Category in ['Attempt.Login'] and (Target.Proto in ['telnet'] or Source.Proto in ['telnet'] or Target.Port in [23])",
            "str":
            '((Category OP_IN ["Attempt.Login"]) OP_AND ((Target.Proto OP_IN ["telnet"]) OP_OR ((Source.Proto OP_IN ["telnet"]) OP_OR (Target.Port OP_IN [23]))))'
        }, {
            "filter":
            "Category in ['Attempt.Login'] and (Target.Proto in ['ssh'] or Source.Proto in ['ssh'] or Target.Port in [22])",
            "str":
            '((Category OP_IN ["Attempt.Login"]) OP_AND ((Target.Proto OP_IN ["ssh"]) OP_OR ((Source.Proto OP_IN ["ssh"]) OP_OR (Target.Port OP_IN [22]))))'
        }, {
            "filter":
            "Category in ['Attempt.Login'] and (Target.Proto in ['sip', 'sip-tls'] or Source.Proto in ['sip', 'sip-tls'] or Target.Port in [5060])",
            "str":
            '((Category OP_IN ["Attempt.Login"]) OP_AND ((Target.Proto OP_IN ["sip", "sip-tls"]) OP_OR ((Source.Proto OP_IN ["sip", "sip-tls"]) OP_OR (Target.Port OP_IN [5060]))))'
        }, {
            "filter":
            "Category in ['Attempt.Exploit'] and (Target.Proto in ['sip', 'sip-tls'] or Source.Proto in ['sip', 'sip-tls'] or Target.Port in [5060])",
            "str":
            '((Category OP_IN ["Attempt.Exploit"]) OP_AND ((Target.Proto OP_IN ["sip", "sip-tls"]) OP_OR ((Source.Proto OP_IN ["sip", "sip-tls"]) OP_OR (Target.Port OP_IN [5060]))))'
        }, {
            "filter":
            "Category in ['Attempt.Exploit'] and Target.Port in [23]",
            "str":
            '((Category OP_IN ["Attempt.Exploit"]) OP_AND (Target.Port OP_IN [23]))'
        }, {
            "filter":
            "Category in ['Attempt.Exploit'] and (Target.Port in [80, 443] or Source.Proto in ['http', 'https', 'http-alt'] or Target.Proto in ['http', 'https', 'http-alt'])",
            "str":
            '((Category OP_IN ["Attempt.Exploit"]) OP_AND ((Target.Port OP_IN [80, 443]) OP_OR ((Source.Proto OP_IN ["http", "https", "http-alt"]) OP_OR (Target.Proto OP_IN ["http", "https", "http-alt"]))))'
        }, {
            "filter":
            "Category in ['Attempt.Exploit'] and (Target.Port in [3306] or Source.Proto in ['mysql'] or Target.Proto in ['mysql'])",
            "str":
            '((Category OP_IN ["Attempt.Exploit"]) OP_AND ((Target.Port OP_IN [3306]) OP_OR ((Source.Proto OP_IN ["mysql"]) OP_OR (Target.Proto OP_IN ["mysql"]))))'
        }, {
            "filter":
            "Category in ['Attempt.Exploit'] and (Target.Port in [445] or Source.Proto in ['microsoft-ds', 'smb'] or Target.Proto in ['microsoft-ds', 'smb'])",
            "str":
            '((Category OP_IN ["Attempt.Exploit"]) OP_AND ((Target.Port OP_IN [445]) OP_OR ((Source.Proto OP_IN ["microsoft-ds", "smb"]) OP_OR (Target.Proto OP_IN ["microsoft-ds", "smb"]))))'
        }, {
            "filter":
            "Category in ['Attempt.Exploit'] and (Target.Port in [135] or Source.Proto in ['loc-srv', 'epmap'] or Target.Proto in ['loc-srv', 'epmap'])",
            "str":
            '((Category OP_IN ["Attempt.Exploit"]) OP_AND ((Target.Port OP_IN [135]) OP_OR ((Source.Proto OP_IN ["loc-srv", "epmap"]) OP_OR (Target.Proto OP_IN ["loc-srv", "epmap"]))))'
        }, {
            "filter":
            "Category in ['Attempt.Exploit'] and (Target.Port in [1900] or Source.Proto in ['upnp', 'ssdp'] or Target.Proto in ['upnp', 'ssdp'])",
            "str":
            '((Category OP_IN ["Attempt.Exploit"]) OP_AND ((Target.Port OP_IN [1900]) OP_OR ((Source.Proto OP_IN ["upnp", "ssdp"]) OP_OR (Target.Proto OP_IN ["upnp", "ssdp"]))))'
        }, {
            "filter":
            "Category in ['Attempt.Exploit'] and (Target.Port in [20, 21, 989, 990] or Source.Proto in ['ftp', 'ftp-data', 'ftps', 'ftps-data'] or Target.Proto in ['ftp', 'ftp-data', 'ftps', 'ftps-data'])",
            "str":
            '((Category OP_IN ["Attempt.Exploit"]) OP_AND ((Target.Port OP_IN [20, 21, 989, 990]) OP_OR ((Source.Proto OP_IN ["ftp", "ftp-data", "ftps", "ftps-data"]) OP_OR (Target.Proto OP_IN ["ftp", "ftp-data", "ftps", "ftps-data"]))))'
        }, {
            "filter":
            "Category in ['Attempt.Exploit'] and (Target.Port in [1433, 1434] or Source.Proto in ['ms-sql-s', 'ms-sql-m'] or Target.Proto in ['ms-sql-s', 'ms-sql-m'])",
            "str":
            '((Category OP_IN ["Attempt.Exploit"]) OP_AND ((Target.Port OP_IN [1433, 1434]) OP_OR ((Source.Proto OP_IN ["ms-sql-s", "ms-sql-m"]) OP_OR (Target.Proto OP_IN ["ms-sql-s", "ms-sql-m"]))))'
        }, {
            "filter":
            "Category in ['Attempt.Exploit'] and (Target.Port in [42] or Source.Proto in ['nameserver'] or Target.Proto in ['nameserver'])",
            "str":
            '((Category OP_IN ["Attempt.Exploit"]) OP_AND ((Target.Port OP_IN [42]) OP_OR ((Source.Proto OP_IN ["nameserver"]) OP_OR (Target.Proto OP_IN ["nameserver"]))))'
        }, {
            "filter":
            "Category in ['Attempt.Exploit'] and Node.SW in ['Dionaea']",
            "str":
            '((Category OP_IN ["Attempt.Exploit"]) OP_AND (Node.SW OP_IN ["Dionaea"]))'
        }, {
            "filter":
            "Category in ['Availability.DoS', 'Availability.DDoS'] and (Target.Proto in ['dns', 'domain'] or Source.Proto in ['dns', 'domain'] or Target.Port in [53] or Source.Port in [53])",
            "str":
            '((Category OP_IN ["Availability.DoS", "Availability.DDoS"]) OP_AND ((Target.Proto OP_IN ["dns", "domain"]) OP_OR ((Source.Proto OP_IN ["dns", "domain"]) OP_OR ((Target.Port OP_IN [53]) OP_OR (Source.Port OP_IN [53])))))'
        }, {
            "filter":
            "Category in ['Availability.DDoS'] and Node.Type in ['Flow'] and Node.Type in ['Statistical']",
            "str":
            '((Category OP_IN ["Availability.DDoS"]) OP_AND ((Node.Type OP_IN ["Flow"]) OP_AND (Node.Type OP_IN ["Statistical"])))'
        }, {
            "filter":
            "Category in ['Abusive.Spam'] and Node.SW in ['UCEPROT']",
            "str":
            '((Category OP_IN ["Abusive.Spam"]) OP_AND (Node.SW OP_IN ["UCEPROT"]))'
        }, {
            "filter":
            "Category in ['Abusive.Spam'] and Node.SW in ['Fail2Ban', 'IntelMQ']",
            "str":
            '((Category OP_IN ["Abusive.Spam"]) OP_AND (Node.SW OP_IN ["Fail2Ban", "IntelMQ"]))'
        }, {
            "filter":
            "Category in ['Vulnerable.Config'] and (Source.Proto in ['qotd'] or Source.Port in [17])",
            "str":
            '((Category OP_IN ["Vulnerable.Config"]) OP_AND ((Source.Proto OP_IN ["qotd"]) OP_OR (Source.Port OP_IN [17])))'
        }, {
            "filter":
            "Category in ['Vulnerable.Config'] and Source.Proto in ['ssdp']",
            "str":
            '((Category OP_IN ["Vulnerable.Config"]) OP_AND (Source.Proto OP_IN ["ssdp"]))'
        }, {
            "filter":
            "Category in ['Vulnerable.Config'] and (Source.Proto in ['ntp'] or Source.Port in [123])",
            "str":
            '((Category OP_IN ["Vulnerable.Config"]) OP_AND ((Source.Proto OP_IN ["ntp"]) OP_OR (Source.Port OP_IN [123])))'
        }, {
            "filter":
            "Category in ['Vulnerable.Config'] and (Source.Proto in ['domain'] or Source.Port in [53])",
            "str":
            '((Category OP_IN ["Vulnerable.Config"]) OP_AND ((Source.Proto OP_IN ["domain"]) OP_OR (Source.Port OP_IN [53])))'
        }, {
            "filter":
            "Category in ['Vulnerable.Config'] and (Source.Proto in ['netbios-ns'] or Source.Port in [137])",
            "str":
            '((Category OP_IN ["Vulnerable.Config"]) OP_AND ((Source.Proto OP_IN ["netbios-ns"]) OP_OR (Source.Port OP_IN [137])))'
        }, {
            "filter":
            "Category in ['Vulnerable.Config'] and (Source.Proto in ['ipmi'] or Source.Port in [623])",
            "str":
            '((Category OP_IN ["Vulnerable.Config"]) OP_AND ((Source.Proto OP_IN ["ipmi"]) OP_OR (Source.Port OP_IN [623])))'
        }, {
            "filter":
            "Category in ['Vulnerable.Config'] and (Source.Proto in ['chargen'] or Source.Port in [19])",
            "str":
            '((Category OP_IN ["Vulnerable.Config"]) OP_AND ((Source.Proto OP_IN ["chargen"]) OP_OR (Source.Port OP_IN [19])))'
        }, {
            "filter": "Category in ['Anomaly.Traffic']",
            "str": '(Category OP_IN ["Anomaly.Traffic"])'
        }, {
            "filter":
            "Category in ['Anomaly.Connection'] and Source.Type in ['Booter']",
            "str":
            '((Category OP_IN ["Anomaly.Connection"]) OP_AND (Source.Type OP_IN ["Booter"]))'
        }, {
            "filter":
            "Category in ['Intrusion.Botnet'] and Source.Type in ['Botnet']",
            "str":
            '((Category OP_IN ["Intrusion.Botnet"]) OP_AND (Source.Type OP_IN ["Botnet"]))'
        }, {
            "filter": "Category in ['Recon.Scanning']",
            "str": '(Category OP_IN ["Recon.Scanning"])'
        }]

        for insr in inspection_rules:
            rule = self.build_rule(insr['filter'])
            self.assertEqual(str(rule), insr['str'])
            if 'tests' in insr:
                for itemt in insr['tests']:
                    msg_idea = lite.Idea(itemt[0])
                    self.assertEqual(
                        [insr['filter'],
                         self.flt.filter(rule, msg_idea)],
                        [insr['filter'], itemt[1]])