Improve tests and add support for tagged decoding

This commit is contained in:
Istvan Ruzman
2020-09-04 21:14:26 +02:00
parent 47d75ab686
commit 1665bfef47
5 changed files with 185 additions and 64 deletions

View File

@@ -16,6 +16,105 @@ from pyrad3 import dictionary, utils
SECRET = b"secret"
def num_tlv(num_type, num, length, expected=None):
exp = num if expected is None else expected
return (num_type + num.to_bytes(length, "big"), exp)
TEST_ATTRIBUTES = [
(b"\x01\x07ABCDE", "ABCDE"), # rfc string
(b"\x02\x07ABCDE", b"ABCDE"), # rfc octets
(b"\x03\x06\0\0\0\0", 0), # rfc date
# TODO: ABINARY
(b"\x05\x03\x00", 0), # rfc byte
num_tlv(b"\x06\x04", 0, 2), # rfc short
num_tlv(b"\x06\x04", 0xFF, 2), # rfc short
num_tlv(b"\x06\x04", 0x100, 2), # rfc short
num_tlv(b"\x06\x04", 0xFFFF, 2), # rfc short
num_tlv(b"\x07\x06", 0, 4), # rfc integer
num_tlv(b"\x07\x06", 0xFF, 4), # rfc integer
num_tlv(b"\x07\x06", 0x100, 4), # rfc integer
num_tlv(b"\x07\x06", 0xFFFF, 4), # rfc integer
num_tlv(b"\x07\x06", 0x10000, 4), # rfc integer
num_tlv(b"\x07\x06", 0xFFFFFFFF, 4), # rfc integer
num_tlv(b"\x08\x06", 0, 4), # rfc signed
num_tlv(b"\x08\x06", 0xFF, 4), # rfc signed
num_tlv(b"\x08\x06", 0x1000, 4), # rfc signed
num_tlv(b"\x08\x06", 0xFFFF, 4), # rfc signed
num_tlv(b"\x08\x06", 0x10000, 4), # rfc signed
num_tlv(b"\x08\x06", 0xFFFFFFFF, 4, -1), # rfc signed
num_tlv(b"\x08\x06", 0x80000000, 4, -2147483648), # rfc signed
num_tlv(b"\x08\x06", 0x7FFFFFFF, 4, 2147483647), # rfc signed
num_tlv(b"\x09\x0A", 0, 8), # rfc integer64
num_tlv(b"\x09\x0A", 0xFF, 8), # rfc integer64
num_tlv(b"\x09\x0A", 0x100, 8), # rfc integer64
num_tlv(b"\x09\x0A", 0xFFFF, 8), # rfc integer64
num_tlv(b"\x09\x0A", 0x10000, 8), # rfc integer64
num_tlv(b"\x09\x0A", 0xFFFFFFFF, 8), # rfc integer64
num_tlv(b"\x09\x0A", 0x100000000, 8), # rfc integer64
num_tlv(b"\x09\x0A", 0xFFFFFFFFFFFFFFFF, 8), # rfc integer64
(b"\x0a\x06\xc0\xa8\x01\x08", IPv4Address("192.168.1.8")),
(b"\x0b\x07\x10\xc0\xa8\x00\x00", IPv4Network("192.168.0.0/16")),
(
b"\x0c\x12\x20\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01",
IPv6Address("2003::1"),
),
(
b"\x0d\x14\x00\x40\x20\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
IPv6Network("2003::0/64"),
),
(b"\x0c\x04\x20\x03", IPv6Address("2003::0")),
(b"\x0d\x06\x00\x40\x20\x03", IPv6Network("2003::0/64")),
]
TAGGED_ATTRIBUTES = [
(b"\x65\x08\x01ABCDE", "ABCDE"), # rfc string
(b"\x66\x08\x01ABCDE", b"ABCDE"), # rfc octets
(b"\x67\x07\x01\0\0\0\0", 0), # rfc date
# TODO: ABINARY
(b"\x69\x04\x01\x00", 0), # rfc byte
num_tlv(b"\x6a\x05\x01", 0, 2), # rfc short
num_tlv(b"\x6a\x05\x01", 0xFF, 2), # rfc short
num_tlv(b"\x6a\x05\x01", 0x100, 2), # rfc short
num_tlv(b"\x6a\x05\x01", 0xFFFF, 2), # rfc short
num_tlv(b"\x6b\x06\x01", 0, 3), # rfc integer
num_tlv(b"\x6b\x06\x01", 0xFF, 3), # rfc integer
num_tlv(b"\x6b\x06\x01", 0x100, 3), # rfc integer
num_tlv(b"\x6b\x06\x01", 0xFFFF, 3), # rfc integer
num_tlv(b"\x6b\x06\x01", 0x10000, 3), # rfc integer
# integer with tag is only 3 bytes
# num_tlv(b"\x70\x06\x01", 0xFFFFFFFF, 4), # rfc integer
num_tlv(b"\x6c\x07\x01", 0, 4), # rfc signed
num_tlv(b"\x6c\x07\x01", 0xFF, 4), # rfc signed
num_tlv(b"\x6c\x07\x01", 0x1000, 4), # rfc signed
num_tlv(b"\x6c\x07\x01", 0xFFFF, 4), # rfc signed
num_tlv(b"\x6c\x07\x01", 0x10000, 4), # rfc signed
num_tlv(b"\x6c\x07\x01", 0xFFFFFFFF, 4, -1), # rfc signed
num_tlv(b"\x6c\x07\x01", 0x80000000, 4, -2147483648), # rfc signed
num_tlv(b"\x6c\x07\x01", 0x7FFFFFFF, 4, 2147483647), # rfc signed
num_tlv(b"\x6d\x0B\x01", 0, 8), # rfc integer64
num_tlv(b"\x6d\x0B\x01", 0xFF, 8), # rfc integer64
num_tlv(b"\x6d\x0B\x01", 0x100, 8), # rfc integer64
num_tlv(b"\x6d\x0B\x01", 0xFFFF, 8), # rfc integer64
num_tlv(b"\x6d\x0B\x01", 0x10000, 8), # rfc integer64
num_tlv(b"\x6d\x0B\x01", 0xFFFFFFFF, 8), # rfc integer64
num_tlv(b"\x6d\x0B\x01", 0x100000000, 8), # rfc integer64
num_tlv(b"\x6d\x0B\x01", 0xFFFFFFFFFFFFFFFF, 8), # rfc integer64
(b"\x6e\x07\x01\xc0\xa8\x01\x08", IPv4Address("192.168.1.8")),
(b"\x6f\x08\x01\x10\xc0\xa8\x00\x00", IPv4Network("192.168.0.0/16")),
(
b"\x70\x13\x01\x20\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01",
IPv6Address("2003::1"),
),
(
b"\x71\x15\x01\x00\x40\x20\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
IPv6Network("2003::0/64"),
),
(b"\x70\x05\x01\x20\x03", IPv6Address("2003::0")),
(b"\x71\x07\x01\x00\x40\x20\x03", IPv6Network("2003::0/64")),
]
@pytest.fixture
def radius_dictionary():
return dictionary.Dictionary("tests/dictionaries/dict")
@@ -35,65 +134,17 @@ def test_invalid_header(header):
utils.parse_header(header)
def num_tlv(num_type, num, length, expected=None):
exp = num if expected is None else expected
return (num_type + num.to_bytes(length, "big"), exp)
@pytest.mark.parametrize(
"attr_bytes, expected",
[
(b"\x01\x07ABCDE", "ABCDE"), # rfc string
(b"\x02\x07ABCDE", b"ABCDE"), # rfc octets
(b"\x03\x06\0\0\0\0", 0), # rfc date
# TODO: ABINARY
(b"\x05\x03\x00", 0), # rfc byte
num_tlv(b"\x06\x04", 0, 2), # rfc short
num_tlv(b"\x06\x04", 0xFF, 2), # rfc short
num_tlv(b"\x06\x04", 0x100, 2), # rfc short
num_tlv(b"\x06\x04", 0xFFFF, 2), # rfc short
num_tlv(b"\x07\x06", 0, 4), # rfc integer
num_tlv(b"\x07\x06", 0xFF, 4), # rfc integer
num_tlv(b"\x07\x06", 0x100, 4), # rfc integer
num_tlv(b"\x07\x06", 0xFFFF, 4), # rfc integer
num_tlv(b"\x07\x06", 0x10000, 4), # rfc integer
num_tlv(b"\x07\x06", 0xFFFFFFFF, 4), # rfc integer
num_tlv(b"\x08\x06", 0, 4), # rfc signed
num_tlv(b"\x08\x06", 0xFF, 4), # rfc signed
num_tlv(b"\x08\x06", 0x1000, 4), # rfc signed
num_tlv(b"\x08\x06", 0xFFFF, 4), # rfc signed
num_tlv(b"\x08\x06", 0x10000, 4), # rfc signed
num_tlv(b"\x08\x06", 0xFFFFFFFF, 4, -1), # rfc signed
num_tlv(b"\x08\x06", 0x80000000, 4, -2147483648), # rfc signed
num_tlv(b"\x08\x06", 0x7FFFFFFF, 4, 2147483647), # rfc signed
num_tlv(b"\x09\x0A", 0, 8), # rfc integer64
num_tlv(b"\x09\x0A", 0xFF, 8), # rfc integer64
num_tlv(b"\x09\x0A", 0x100, 8), # rfc integer64
num_tlv(b"\x09\x0A", 0xFFFF, 8), # rfc integer64
num_tlv(b"\x09\x0A", 0x10000, 8), # rfc integer64
num_tlv(b"\x09\x0A", 0xFFFFFFFF, 8), # rfc integer64
num_tlv(b"\x09\x0A", 0x100000000, 8), # rfc integer64
num_tlv(b"\x09\x0A", 0xFFFFFFFFFFFFFFFF, 8), # rfc integer64
(b"\x0a\x06\xc0\xa8\x01\x08", IPv4Address("192.168.1.8")),
(b"\x0b\x07\x10\xc0\xa8\x00\x00", IPv4Network("192.168.0.0/16")),
(
b"\x0c\x12\x20\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01",
IPv6Address("2003::1"),
),
(
b"\x0d\x14\x00\x40\x20\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
IPv6Network("2003::0/64"),
),
(b"\x0c\x04\x20\x03", IPv6Address("2003::0")),
(b"\x0d\x06\x00\x40\x20\x03", IPv6Network("2003::0/64")),
],
)
def test_parse_attribute_rfc_and_vsa(radius_dictionary, attr_bytes, expected):
@pytest.mark.parametrize("attr_bytes, expected", TEST_ATTRIBUTES)
def test_parse_attribute_rfc(radius_dictionary, attr_bytes, expected):
raw_packet = bytes(20) + attr_bytes
attrs = utils.parse_attributes(radius_dictionary, raw_packet)
assert len(attrs) == 1
assert attrs[0].value == expected
assert attrs[0].tag == 0
@pytest.mark.parametrize("attr_bytes, expected", TEST_ATTRIBUTES)
def test_parse_attribute_vsa(radius_dictionary, attr_bytes, expected):
vsa_length = (6 + len(attr_bytes)).to_bytes(1, "big")
raw_packet = (
bytes(20) + b"\x1a" + vsa_length + b"\x00\x00\x04\xd2" + attr_bytes
@@ -101,6 +152,28 @@ def test_parse_attribute_rfc_and_vsa(radius_dictionary, attr_bytes, expected):
attrs = utils.parse_attributes(radius_dictionary, raw_packet)
assert len(attrs) == 1
assert attrs[0].value == expected
assert attrs[0].tag == 0
@pytest.mark.parametrize("attr_bytes, expected", TAGGED_ATTRIBUTES)
def test_parse_attribute_rfc_tagged(radius_dictionary, attr_bytes, expected):
raw_packet = bytes(20) + attr_bytes
attrs = utils.parse_attributes(radius_dictionary, raw_packet)
assert len(attrs) == 1
assert attrs[0].value == expected
assert attrs[0].tag == 1
@pytest.mark.parametrize("attr_bytes, expected", TAGGED_ATTRIBUTES)
def test_parse_attribute_vsa_tagged(radius_dictionary, attr_bytes, expected):
vsa_length = (6 + len(attr_bytes)).to_bytes(1, "big")
raw_packet = (
bytes(20) + b"\x1a" + vsa_length + b"\x00\x00\x04\xd2" + attr_bytes
)
attrs = utils.parse_attributes(radius_dictionary, raw_packet)
assert len(attrs) == 1
assert attrs[0].value == expected
assert attrs[0].tag == 1
@pytest.mark.parametrize(