Esempio n. 1
0
    def test_with_args_positional_override(self):
        class Positional(Keyable):
            def __init__(self, *args, **kwargs):
                self.args = args
                self.kwargs = kwargs
                self.doc = kwargs.get("doc")

        # Leave the positional argument (list type) blank, but specify a category.
        GenericCategorizedList = ListOf.with_args(category="my category")
        # Get lists with different types (but the same category).
        categorized_string_list = GenericCategorizedList(String())
        categorized_cert_list = GenericCategorizedList(Positional())
        self.assertEqual("my category", categorized_string_list.category)
        self.assertEqual("my category", categorized_cert_list.category)

        # ListOf(...) takes only one positional arg, so StringList(Positional()) should raise.
        StringList = ListOf.with_args(String())
        self.assertRaises(Exception, lambda: StringList(Positional()))

        # ListOf(...) needs exactly one positional arg, so GenericCategorizedList() should also raise.
        self.assertRaises(Exception, lambda: CategorizedCertificateList())

        # Confirm that positional args are pulled from the proper location
        MyPositional = Positional.with_args("a", doc="default docs")
        p0 = MyPositional()
        p0doc = MyPositional(doc="some docs")
        # Passing positional args to the factory constructor and the contructor is not allowed
        self.assertRaises(Exception, lambda: MyPositional("b"))
        self.assertRaises(Exception, lambda: MyPositional("x, y"))
        self.assertEqual(("a", ), p0.args)
        self.assertEqual("default docs", p0.doc)
        self.assertEqual(("a", ), p0doc.args)
        self.assertEqual("some docs", p0doc.doc)
Esempio n. 2
0
    def setUp(self):
        self.maxDiff = 10000

        heartbleed = SubRecord(
            {  # with explicit proto field indices
                "heartbeat_support":
                Boolean(pr_index=11),
                "heartbleed_vulnerable":
                Boolean(category="Vulnerabilities", pr_ignore=True),
                "timestamp":
                DateTime(pr_index=10)
            },
            pr_index=77)
        self.host = Record({
            "ipstr":
            IPv4Address(required=True, examples=["8.8.8.8"], pr_index=1),
            "ip":
            Unsigned32BitInteger(doc="The IP Address of the host", pr_index=2),
            Port(443):
            SubRecord({
                "tls": String(pr_index=1),
                "heartbleed": heartbleed
            },
                      category="heartbleed",
                      pr_index=3),
            "tags":
            ListOf(String(), pr_index=47)
        })
Esempio n. 3
0
 def test_merge_unmergable_types(self):
     a = SubRecord({
         "a": String(),
     })
     b = SubRecord({
         "a": String(),
     })
     try:
         a.merge(b)
         raise Exception("validation did not fail")
     except MergeConflictException:
         pass
Esempio n. 4
0
    def test_ListOf_exclude(self):
        a = ListOf(String())
        self.assertFalse(a.exclude_bigquery)
        self.assertFalse(a.exclude_elasticsearch)

        b = ListOf(String(exclude=["bigquery"]))
        self.assertTrue(b.exclude_bigquery)
        self.assertFalse(b.exclude_elasticsearch)

        c = ListOf(String(), exclude=["elasticsearch"])
        self.assertFalse(c.exclude_bigquery)
        self.assertTrue(c.exclude_elasticsearch)

        d = ListOf(String(exclude=["bigquery"]), exclude=["elasticsearch"])
        self.assertTrue(d.exclude_bigquery)
        self.assertTrue(d.exclude_elasticsearch)
Esempio n. 5
0
 def setUp(self):
     self.host = Record({
         "ipstr": IPv4Address(required=True),
         "ip": Unsigned32BitInteger(),
     })
     self.domain = Record({
         "domain": String(required=True),
     })
Esempio n. 6
0
    def test_extends(self):
        host = Record({
            "host": IPv4Address(required=True),
            "time": DateTime(required=True),
            "data": SubRecord({}),
            "error": String()
        })
        banner_grab = Record({"data": SubRecord({"banner": String()})},
                             extends=host)
        tls_banner_grab = Record({"data": SubRecord({"tls": SubRecord({})})},
                                 extends=banner_grab)
        smtp_starttls = Record({"data": SubRecord({"ehlo": String()})},
                               extends=tls_banner_grab)

        valid = Record({
            "host":
            IPv4Address(required=True),
            "time":
            DateTime(required=True),
            "data":
            SubRecord({
                "banner": String(),
                "tls": SubRecord({}),
                "ehlo": String()
            }),
            "error":
            String()
        })
        self.assertEqual(smtp_starttls.to_dict(), valid.to_dict())
Esempio n. 7
0
    def test_subrecord_type_extends(self):
        S = SubRecordType({
            "provided": Boolean(),
        })

        extended_type = SubRecord(
            {
                "property": String(),
                "record": SubRecord({
                    "another": String(),
                }),
            },
            extends=S())

        base = S()
        extends = extended_type
        self.assertNotIsInstance(extends, S)
        self.assertFalse(base.definition['provided'].exclude)
        self.assertFalse(extended_type.definition['provided'].exclude)
        base.definition['provided'].exclude = ['bigquery']
        self.assertEqual(['bigquery'], base.definition['provided'].exclude)
        self.assertFalse(extended_type.definition['provided'].exclude)
Esempio n. 8
0
    def test_with_args(self):
        Certificate = SubRecord.with_args({}, doc="A parsed certificate.")
        CertificateChain = ListOf.with_args(Certificate())
        AlgorithmType = String.with_args(doc="An algorithm identifier",
                                         examples=["a", "b", "c"])
        OtherType = SubRecord({
            "ca":
            Certificate(doc="The CA certificate."),
            "host":
            Certificate(doc="The host certificate."),
            "chain":
            CertificateChain(doc="The certificate chain."),
            "host_alg":
            AlgorithmType(doc="The host algorithm", examples=["x", "y"]),
            "client_alg":
            AlgorithmType(doc="The client algorithm"),
            "sig_alg":
            AlgorithmType(examples=["p", "q"]),
        })
        # Check default
        self.assertEqual("A parsed certificate.", Certificate().doc)

        # Check overridden
        self.assertEqual("The CA certificate.", OtherType.definition["ca"].doc)
        self.assertEqual("The host certificate.",
                         OtherType.definition["host"].doc)

        # Check ListOf
        self.assertEqual("The certificate chain.",
                         OtherType.definition["chain"].doc)

        # Check that instance default is used in child
        self.assertEqual("A parsed certificate.",
                         OtherType.definition["chain"].object_.doc)

        # Check Leaf type doc overrides
        self.assertEqual("The host algorithm",
                         OtherType.definition["host_alg"].doc)
        self.assertEqual("The client algorithm",
                         OtherType.definition["client_alg"].doc)
        self.assertEqual("An algorithm identifier",
                         OtherType.definition["sig_alg"].doc)

        # Check that examples are inherited
        self.assertEqual(["a", "b", "c"],
                         OtherType.definition["client_alg"].examples)

        # Check that examples are overridden
        self.assertEqual(["x", "y"], OtherType.definition["host_alg"].examples)
        self.assertEqual(["p", "q"], OtherType.definition["sig_alg"].examples)
Esempio n. 9
0
    def test_multiple_subrecord_types(self):
        A = SubRecordType({
            "first": String(),
        }, type_name="A")
        B = SubRecordType({
            "second": Boolean(),
        }, type_name="B")

        a = A()
        self.assertIn("first", a.definition)
        b = B()
        self.assertIn("second", b.definition)
        a = A()
        self.assertIn("first", a.definition)
Esempio n. 10
0
 def test_parses_ipv4_records(self):
     ipv4_host_ssh = Record({
         Port(22):
         SubRecord({
             "ssh":
             SubRecord({
                 "banner":
                 SubRecord({
                     "comment": String(),
                     "timestamp": DateTime()
                 })
             })
         })
     })
     ipv4_host_ssh.validate(json_fixture('ipv4-ssh-record'))
Esempio n. 11
0
 def test_merge_recursive(self):
     a = SubRecord({"m": SubRecord({"a": String()})})
     b = SubRecord({"a": String(), "m": SubRecord({"b": String()})})
     c = SubRecord({
         "a": String(),
         "m": SubRecord({
             "a": String(),
             "b": String()
         })
     })
     self.assertEquals(a.merge(b).to_dict(), c.to_dict())
Esempio n. 12
0
 def test_merge_no_conflict(self):
     a = SubRecord({"a": String(), "b": SubRecord({"c": String()})})
     b = SubRecord({
         "d": String(),
     })
     valid = SubRecord({
         "a": String(),
         "b": SubRecord({"c": String()}),
         "d": String(),
     })
     self.assertEqual(a.merge(b).to_dict(), valid.to_dict())
Esempio n. 13
0
 def test_subrecord_type_override(self):
     SSH = SubRecordType(
         {
             "banner": SubRecord({
                 "comment": String(),
                 "timestamp": DateTime()
             })
         },
         doc="class doc",
         required=False)
     self.assertEqual(SSH.DOC, "class doc")
     self.assertEqual(SSH.REQUIRED, False)
     ssh = SSH(doc="instance doc", required=True)
     ipv4_host_ssh = Record({Port(22): SubRecord({"ssh": ssh})})
     self.assertEqual(ssh.doc, "instance doc")
     self.assertEqual(ssh.required, True)
     ipv4_host_ssh.validate(json_fixture('ipv4-ssh-record'))
     # class unchanged
     self.assertEqual(SSH.DOC, "class doc")
     self.assertEqual(SSH.REQUIRED, False)
Esempio n. 14
0
    def test_subrecord_type(self):
        A = SubRecordType({
            "string": String(),
            "boolean": Boolean(),
        })

        first = A()
        second = A()

        # The class returned by SubRecordType() should be constructable into
        # unique objects
        self.assertIsNot(first, second)
        self.assertTrue(issubclass(A, SubRecord))
        self.assertIsInstance(first, A)
        self.assertIsInstance(second, A)

        # Check the properties aren't shared
        self.assertIsNone(first.definition['string'].doc)
        self.assertIsNone(second.definition['string'].doc)
        first.definition['string'].doc = "hello"
        self.assertIsNone(second.definition['string'].doc)
Esempio n. 15
0
class PathLogUnitTests(unittest.TestCase):
    sub_type = SubRecord(
        {
            "sub1":
            String(),
            "sub2":
            SubRecord({
                "sub2sub1":
                Unsigned8BitInteger(),
                "sub2sub2":
                NestedListOf(String(), "sub2sub2.subrecord_name"),
            }),
            "sub3":
            Enum(values=["a", "b", "c"])
        },
        validation_policy="error")
    SCHEMA = Record(
        {
            "a":
            SubRecord({
                "a1": String(),
                "a2": ListOf(sub_type),
                "a3": Unsigned8BitInteger(),
            }),
            "b":
            String(),
        },
        validation_policy="error")

    def test_good(self):
        good = {
            "a": {
                "a1":
                "{a.a1}:good",
                "a2": [
                    {
                        "sub1": "{a.a2[0].sub1}:good",
                        "sub2": {
                            "sub2sub1":
                            1,
                            "sub2sub2": [
                                "{a.a2[0].sub2.sub2sub2[0]}:good",
                                "{a.a2[0].sub2.sub2sub2[1]}:good",
                            ],
                        },
                    },
                    {
                        "sub1": "{a.a2[1].sub1}:good",
                        "sub2": {
                            "sub2sub1": 1,
                            "sub2sub2": [],
                        },
                    },
                ],
                "a3":
                1,
            },
            "b": "{b}:good",
        }
        self.SCHEMA.validate(good, policy="error")

    def test_bad_root(self):
        bad1 = {
            "does_not_exist": "{does_not_exist}:bad1",
            "a": {
                "a1":
                "{a.a1}:bad1",
                "a2": [
                    {
                        "sub1": "{a.a2[0].sub1}:bad1",
                        "sub2": {
                            "sub2sub1":
                            1,
                            "sub2sub2": [
                                "{a.a2[0].sub2.sub2sub2[0]}:bad1",
                                "{a.a2[0].sub2.sub2sub2[1]}:bad1",
                            ],
                        },
                    },
                    {
                        "sub1": "{a.a2[1].sub1}:bad1",
                        "sub2": {
                            "sub2sub1": 1,
                            "sub2sub2": [],
                        },
                    },
                ],
                "a3":
                1,
            },
            "b": "{b}:bad1",
        }
        try:
            self.SCHEMA.validate(bad1, policy="error")
            self.assertTrue(False, "bad1 failed to fail")
        except DataValidationException as e:
            self.assertTrue(not e.path)

        del (bad1["does_not_exist"])
        bad1["b"] = 23

        try:
            self.SCHEMA.validate(bad1, policy="error")
            self.assertTrue(False, "bad1 failed to fail")
        except DataValidationException as e:
            self.assertEquals(e.path, ["b"])

    def test_bad_a_key(self):
        bad = {
            "a": {
                "does_not_exist":
                23,
                "a1":
                "{a.a1}:bad1",
                "a2": [
                    {
                        "sub1": "{a.a2[0].sub1}:bad1",
                        "sub2": {
                            "sub2sub1":
                            1,
                            "sub2sub2": [
                                "{a.a2[0].sub2.sub2sub2[0]}:bad1",
                                "{a.a2[0].sub2.sub2sub2[1]}:bad1",
                            ],
                        },
                    },
                    {
                        "sub1": "{a.a2[1].sub1}:bad1",
                        "sub2": {
                            "sub2sub1": 1,
                            "sub2sub2": [],
                        },
                    },
                ],
                "a3":
                1,
            },
            "b": "{b}:bad1",
        }
        try:
            self.SCHEMA.validate(bad, policy="error")
            self.assertTrue(False, "bad failed to fail")
        except DataValidationException as e:
            self.assertEqual(e.path, ["a"])
        del (bad["a"]["does_not_exist"])
        bad["a"]["a3"] = "not an int"
        try:
            ret = self.SCHEMA.validate(bad, policy="error")
            self.assertTrue(False, "bad failed to fail")
        except DataValidationException as e:
            self.assertEqual(e.path, ["a", "a3"])

    def test_bad_deep_key(self):
        bad = {
            "a": {
                "a1":
                "{a.a1}:bad",
                "a2": [
                    {
                        "sub1": "{a.a2[0].sub1}:bad",
                        "sub2": {
                            "sub2sub1":
                            1,
                            "sub2sub2": [
                                "{a.a2[0].sub2.sub2sub2[0]}:bad",
                                "{a.a2[0].sub2.sub2sub2[1]}:bad",
                            ],
                            "does_not_exist":
                            "fake",
                        },
                    },
                    {
                        "sub1": "{a.a2[1].sub1}:bad1",
                        "sub2": {
                            "sub2sub1": 1,
                            "sub2sub2": [],
                        },
                    },
                ],
                "a3":
                1,
            },
            "b": "{b}:bad1",
        }
        try:
            self.SCHEMA.validate(bad, policy="error")
            self.assertTrue(False, "failed to fail")
        except DataValidationException as e:
            self.assertEqual(e.path, [
                "a",
                "a2",
                0,
                "sub2",
            ])
        del (bad["a"]["a2"][0]["sub2"]["does_not_exist"])
        bad["a"]["a2"][0]["sub2"]["sub2sub2"][1] = {"wrong type": "bad type"}
        try:
            self.SCHEMA.validate(bad, policy="error")
            self.assertTrue(False, "bad failed to fail")
        except DataValidationException as e:
            self.assertEqual(e.path, ["a", "a2", 0, "sub2", "sub2sub2", 1])
Esempio n. 16
0
from zschema.keys import Port
from zschema.compounds import ListOf, Record, SubRecord
from zschema.leaves import Boolean, DateTime, IPv4Address, String, Unsigned32BitInteger

heartbleed = SubRecord({
    "heartbeat_support": Boolean(),
    "heartbleed_vulnerable": Boolean(),
    "timestamp": DateTime()
})

host = Record({
    "ipstr": IPv4Address(required=True),
    "ip": Unsigned32BitInteger(),
    Port(443): SubRecord({
        "tls": String(),
        "heartbleed": heartbleed
    }),
    "tags": ListOf(String())
})