From 1a8865312998453432f4ccbd12e1fe6bed34358b Mon Sep 17 00:00:00 2001 From: Peter Thomassen Date: Tue, 29 Dec 2020 18:25:22 +0100 Subject: [PATCH] Pass kw from dns.rdata.to_text to _hexify and _base64ify --- dns/rdata.py | 6 +++--- dns/rdtypes/ANY/CERT.py | 2 +- dns/rdtypes/ANY/OPENPGPKEY.py | 2 +- dns/rdtypes/ANY/RRSIG.py | 2 +- dns/rdtypes/ANY/SSHFP.py | 5 ++++- dns/rdtypes/IN/DHCID.py | 2 +- dns/rdtypes/IN/IPSECKEY.py | 2 +- dns/rdtypes/dnskeybase.py | 2 +- dns/rdtypes/dsbase.py | 5 ++++- dns/rdtypes/euibase.py | 2 +- dns/rdtypes/tlsabase.py | 5 ++++- tests/test_rdata.py | 38 +++++++++++++++++++++++++++++++++++ 12 files changed, 60 insertions(+), 13 deletions(-) diff --git a/dns/rdata.py b/dns/rdata.py index 78462051..12f3b6f3 100644 --- a/dns/rdata.py +++ b/dns/rdata.py @@ -51,7 +51,7 @@ def _wordbreak(data, chunksize=_chunksize): in range(0, len(data), chunksize)]).decode() -def _hexify(data, chunksize=_chunksize): +def _hexify(data, chunksize=_chunksize, **kw): """Convert a binary string into its hex encoding, broken up into chunks of chunksize characters separated by a space. """ @@ -59,7 +59,7 @@ def _hexify(data, chunksize=_chunksize): return _wordbreak(binascii.hexlify(data), chunksize) -def _base64ify(data, chunksize=_chunksize): +def _base64ify(data, chunksize=_chunksize, **kw): """Convert a binary string into its base64 encoding, broken up into chunks of chunksize characters separated by a space. """ @@ -484,7 +484,7 @@ def __init__(self, rdclass, rdtype, data): object.__setattr__(self, 'data', data) def to_text(self, origin=None, relativize=True, **kw): - return r'\# %d ' % len(self.data) + _hexify(self.data) + return r'\# %d ' % len(self.data) + _hexify(self.data, **kw) @classmethod def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True, diff --git a/dns/rdtypes/ANY/CERT.py b/dns/rdtypes/ANY/CERT.py index 6d663cc9..5f26dde7 100644 --- a/dns/rdtypes/ANY/CERT.py +++ b/dns/rdtypes/ANY/CERT.py @@ -76,7 +76,7 @@ def to_text(self, origin=None, relativize=True, **kw): certificate_type = _ctype_to_text(self.certificate_type) return "%s %d %s %s" % (certificate_type, self.key_tag, dns.dnssec.algorithm_to_text(self.algorithm), - dns.rdata._base64ify(self.certificate)) + dns.rdata._base64ify(self.certificate, **kw)) @classmethod def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True, diff --git a/dns/rdtypes/ANY/OPENPGPKEY.py b/dns/rdtypes/ANY/OPENPGPKEY.py index 4bed1b1b..dcfa028d 100644 --- a/dns/rdtypes/ANY/OPENPGPKEY.py +++ b/dns/rdtypes/ANY/OPENPGPKEY.py @@ -34,7 +34,7 @@ def __init__(self, rdclass, rdtype, key): self.key = self._as_bytes(key) def to_text(self, origin=None, relativize=True, **kw): - return dns.rdata._base64ify(self.key, None) + return dns.rdata._base64ify(self.key, chunksize=None, **kw) @classmethod def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True, diff --git a/dns/rdtypes/ANY/RRSIG.py b/dns/rdtypes/ANY/RRSIG.py index 93c7f105..d050ccc6 100644 --- a/dns/rdtypes/ANY/RRSIG.py +++ b/dns/rdtypes/ANY/RRSIG.py @@ -87,7 +87,7 @@ def to_text(self, origin=None, relativize=True, **kw): posixtime_to_sigtime(self.inception), self.key_tag, self.signer.choose_relativity(origin, relativize), - dns.rdata._base64ify(self.signature) + dns.rdata._base64ify(self.signature, **kw) ) @classmethod diff --git a/dns/rdtypes/ANY/SSHFP.py b/dns/rdtypes/ANY/SSHFP.py index 4fd917c3..cc035195 100644 --- a/dns/rdtypes/ANY/SSHFP.py +++ b/dns/rdtypes/ANY/SSHFP.py @@ -40,10 +40,13 @@ def __init__(self, rdclass, rdtype, algorithm, fp_type, self.fingerprint = self._as_bytes(fingerprint, True) def to_text(self, origin=None, relativize=True, **kw): + kw = kw.copy() + chunksize = kw.pop('chunksize', 128) return '%d %d %s' % (self.algorithm, self.fp_type, dns.rdata._hexify(self.fingerprint, - chunksize=128)) + chunksize=chunksize, + **kw)) @classmethod def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True, diff --git a/dns/rdtypes/IN/DHCID.py b/dns/rdtypes/IN/DHCID.py index 23f14931..a9185989 100644 --- a/dns/rdtypes/IN/DHCID.py +++ b/dns/rdtypes/IN/DHCID.py @@ -35,7 +35,7 @@ def __init__(self, rdclass, rdtype, data): self.data = self._as_bytes(data) def to_text(self, origin=None, relativize=True, **kw): - return dns.rdata._base64ify(self.data) + return dns.rdata._base64ify(self.data, **kw) @classmethod def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True, diff --git a/dns/rdtypes/IN/IPSECKEY.py b/dns/rdtypes/IN/IPSECKEY.py index ce899577..d1d39438 100644 --- a/dns/rdtypes/IN/IPSECKEY.py +++ b/dns/rdtypes/IN/IPSECKEY.py @@ -50,7 +50,7 @@ def to_text(self, origin=None, relativize=True, **kw): relativize) return '%d %d %d %s %s' % (self.precedence, self.gateway_type, self.algorithm, gateway, - dns.rdata._base64ify(self.key)) + dns.rdata._base64ify(self.key, **kw)) @classmethod def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True, diff --git a/dns/rdtypes/dnskeybase.py b/dns/rdtypes/dnskeybase.py index f0ebfcc4..788bb2bf 100644 --- a/dns/rdtypes/dnskeybase.py +++ b/dns/rdtypes/dnskeybase.py @@ -49,7 +49,7 @@ def __init__(self, rdclass, rdtype, flags, protocol, algorithm, key): def to_text(self, origin=None, relativize=True, **kw): return '%d %d %d %s' % (self.flags, self.protocol, self.algorithm, - dns.rdata._base64ify(self.key)) + dns.rdata._base64ify(self.key, **kw)) @classmethod def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True, diff --git a/dns/rdtypes/dsbase.py b/dns/rdtypes/dsbase.py index 19e087c8..38c95484 100644 --- a/dns/rdtypes/dsbase.py +++ b/dns/rdtypes/dsbase.py @@ -40,10 +40,13 @@ def __init__(self, rdclass, rdtype, key_tag, algorithm, digest_type, self.digest = self._as_bytes(digest) def to_text(self, origin=None, relativize=True, **kw): + kw = kw.copy() + chunksize = kw.pop('chunksize', 128) return '%d %d %d %s' % (self.key_tag, self.algorithm, self.digest_type, dns.rdata._hexify(self.digest, - chunksize=128)) + chunksize=chunksize, + **kw)) @classmethod def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True, diff --git a/dns/rdtypes/euibase.py b/dns/rdtypes/euibase.py index 42b923d3..60ab56db 100644 --- a/dns/rdtypes/euibase.py +++ b/dns/rdtypes/euibase.py @@ -40,7 +40,7 @@ def __init__(self, rdclass, rdtype, eui): % (self.byte_len * 8, self.byte_len)) def to_text(self, origin=None, relativize=True, **kw): - return dns.rdata._hexify(self.eui, chunksize=2).replace(' ', '-') + return dns.rdata._hexify(self.eui, chunksize=2, **kw).replace(' ', '-') @classmethod def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True, diff --git a/dns/rdtypes/tlsabase.py b/dns/rdtypes/tlsabase.py index a9563da9..786fca55 100644 --- a/dns/rdtypes/tlsabase.py +++ b/dns/rdtypes/tlsabase.py @@ -41,11 +41,14 @@ def __init__(self, rdclass, rdtype, usage, selector, self.cert = self._as_bytes(cert) def to_text(self, origin=None, relativize=True, **kw): + kw = kw.copy() + chunksize = kw.pop('chunksize', 128) return '%d %d %d %s' % (self.usage, self.selector, self.mtype, dns.rdata._hexify(self.cert, - chunksize=128)) + chunksize=chunksize, + **kw)) @classmethod def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True, diff --git a/tests/test_rdata.py b/tests/test_rdata.py index 248f7247..45ceb29b 100644 --- a/tests/test_rdata.py +++ b/tests/test_rdata.py @@ -651,6 +651,44 @@ def test_bad_SMIMEA(self): with self.assertRaises(dns.exception.SyntaxError): dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SMIMEA, '1 1 1 aGVsbG8gd29ybGQh') + def test_DNSKEY_chunking(self): + inputs = ( # each with chunking as given by dig, unusual chunking, and no chunking + # example 1 + ( + '257 3 13 aCoEWYBBVsP9Fek2oC8yqU8ocKmnS1iDSFZNORnQuHKtJ9Wpyz+kNryq uB78Pyk/NTEoai5bxoipVQQXzHlzyg==', + '257 3 13 aCoEWYBBVsP9Fek2oC8yqU8ocK mnS1iDSFZNORnQuHKtJ9Wpyz+kNryquB78Pyk/ NTEoai5bxoipVQQXzHlzyg==', + '257 3 13 aCoEWYBBVsP9Fek2oC8yqU8ocKmnS1iDSFZNORnQuHKtJ9Wpyz+kNryquB78Pyk/NTEoai5bxoipVQQXzHlzyg==', + ), + # example 2 + ( + '257 3 8 AwEAAcw5QLr0IjC0wKbGoBPQv4qmeqHy9mvL5qGQTuaG5TSrNqEAR6b/ qvxDx6my4JmEmjUPA1JeEI9YfTUieMr2UZflu7aIbZFLw0vqiYrywCGr CHXLalOrEOmrvAxLvq4vHtuTlH7JIszzYBSes8g1vle6KG7xXiP3U5Ll 96Qiu6bZ31rlMQSPB20xbqJJh6psNSrQs41QvdcXAej+K2Hl1Wd8kPri ec4AgiBEh8sk5Pp8W9ROLQ7PcbqqttFaW2m7N/Wy4qcFU13roWKDEAst bxH5CHPoBfZSbIwK4KM6BK/uDHpSPIbiOvOCW+lvu9TAiZPc0oysY6as lO7jXv16Gws=', + '257 3 8 AwEAAcw5QLr0IjC0wKbGoBPQv4qmeq Hy9mvL5qGQTuaG5TSrNqEA R6b/qvxDx6my4JmEmjUPA1JeEI9Y fTUieMr2UZflu7aIbZFLw0vqiYrywCGrC HXLalOrEOmrvAxLvq4vHtuTlH7JIszzYBSes8g1vle6KG7 xXiP3U5Ll 96Qiu6bZ31rlMQSPB20xbqJJh6psNSrQs41QvdcXAej+K2Hl1Wd8kPriec4AgiBEh8sk5Pp8W9ROLQ7PcbqqttFaW2m7N/Wy4qcFU13roWKDEAst bxH5CHPoBfZSbIwK4KM6BK/uDHpSPIbiOvOCW+lvu9TAiZPc0oysY6as lO7jXv16Gws=', + '257 3 8 AwEAAcw5QLr0IjC0wKbGoBPQv4qmeqHy9mvL5qGQTuaG5TSrNqEAR6b/qvxDx6my4JmEmjUPA1JeEI9YfTUieMr2UZflu7aIbZFLw0vqiYrywCGrCHXLalOrEOmrvAxLvq4vHtuTlH7JIszzYBSes8g1vle6KG7xXiP3U5Ll96Qiu6bZ31rlMQSPB20xbqJJh6psNSrQs41QvdcXAej+K2Hl1Wd8kPriec4AgiBEh8sk5Pp8W9ROLQ7PcbqqttFaW2m7N/Wy4qcFU13roWKDEAstbxH5CHPoBfZSbIwK4KM6BK/uDHpSPIbiOvOCW+lvu9TAiZPc0oysY6aslO7jXv16Gws=', + ), + # example 3 + ( + '256 3 8 AwEAAday3UX323uVzQqtOMQ7EHQYfD5Ofv4akjQGN2zY5AgB/2jmdR/+ 1PvXFqzKCAGJv4wjABEBNWLLFm7ew1hHMDZEKVL17aml0EBKI6Dsz6Mx t6n7ScvLtHaFRKaxT4i2JxiuVhKdQR9XGMiWAPQKrRM5SLG0P+2F+TLK l3D0L/cD', + '256 3 8 AwEAAday3UX323uVzQqtOMQ7EHQYfD5Ofv4akjQGN2zY5 AgB/2jmdR/+1PvXFqzKCAGJv4wjABEBNWLLFm7ew1hHMDZEKVL17aml0EBKI6Dsz6Mxt6n7ScvLtHaFRKaxT4i2JxiuVhKdQR9XGMiWAPQKrRM5SLG0P+2F+ TLKl3D0L/cD', + '256 3 8 AwEAAday3UX323uVzQqtOMQ7EHQYfD5Ofv4akjQGN2zY5AgB/2jmdR/+1PvXFqzKCAGJv4wjABEBNWLLFm7ew1hHMDZEKVL17aml0EBKI6Dsz6Mxt6n7ScvLtHaFRKaxT4i2JxiuVhKdQR9XGMiWAPQKrRM5SLG0P+2F+TLKl3D0L/cD', + ), + ) + output_map = { + 32: ( + '257 3 13 aCoEWYBBVsP9Fek2oC8yqU8ocKmnS1iD SFZNORnQuHKtJ9Wpyz+kNryquB78Pyk/ NTEoai5bxoipVQQXzHlzyg==', + '257 3 8 AwEAAcw5QLr0IjC0wKbGoBPQv4qmeqHy 9mvL5qGQTuaG5TSrNqEAR6b/qvxDx6my 4JmEmjUPA1JeEI9YfTUieMr2UZflu7aI bZFLw0vqiYrywCGrCHXLalOrEOmrvAxL vq4vHtuTlH7JIszzYBSes8g1vle6KG7x XiP3U5Ll96Qiu6bZ31rlMQSPB20xbqJJ h6psNSrQs41QvdcXAej+K2Hl1Wd8kPri ec4AgiBEh8sk5Pp8W9ROLQ7PcbqqttFa W2m7N/Wy4qcFU13roWKDEAstbxH5CHPo BfZSbIwK4KM6BK/uDHpSPIbiOvOCW+lv u9TAiZPc0oysY6aslO7jXv16Gws=', + '256 3 8 AwEAAday3UX323uVzQqtOMQ7EHQYfD5O fv4akjQGN2zY5AgB/2jmdR/+1PvXFqzK CAGJv4wjABEBNWLLFm7ew1hHMDZEKVL1 7aml0EBKI6Dsz6Mxt6n7ScvLtHaFRKax T4i2JxiuVhKdQR9XGMiWAPQKrRM5SLG0 P+2F+TLKl3D0L/cD', + ), + 56: (t[0] for t in inputs), + 0: (t[0][:12] + t[0][12:].replace(' ', '') for t in inputs) + } + + for chunksize, outputs in output_map.items(): + for input, output in zip(inputs, outputs): + for input_variation in input: + rr = dns.rdata.from_text('IN', 'DNSKEY', input_variation) + new_text = rr.to_text(chunksize=chunksize) + self.assertEqual(output, new_text) + class UtilTestCase(unittest.TestCase):