Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow custom chunksizes in dns.rdata.to_text #617

Merged
merged 1 commit into from Jan 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions dns/rdata.py
Expand Up @@ -51,15 +51,15 @@ 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.
"""

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.
"""
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion dns/rdtypes/ANY/CERT.py
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion dns/rdtypes/ANY/OPENPGPKEY.py
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion dns/rdtypes/ANY/RRSIG.py
Expand Up @@ -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
Expand Down
5 changes: 4 additions & 1 deletion dns/rdtypes/ANY/SSHFP.py
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion dns/rdtypes/IN/DHCID.py
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion dns/rdtypes/IN/IPSECKEY.py
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion dns/rdtypes/dnskeybase.py
Expand Up @@ -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,
Expand Down
5 changes: 4 additions & 1 deletion dns/rdtypes/dsbase.py
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion dns/rdtypes/euibase.py
Expand Up @@ -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,
Expand Down
5 changes: 4 additions & 1 deletion dns/rdtypes/tlsabase.py
Expand Up @@ -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,
Expand Down
38 changes: 38 additions & 0 deletions tests/test_rdata.py
Expand Up @@ -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):

Expand Down