From a82f3110ea6c47a9d9c1da5114bb538e09db8dba Mon Sep 17 00:00:00 2001 From: William Grant Date: Fri, 3 Jun 2011 22:07:42 +1000 Subject: [PATCH] Split out DNS utilities into their own module. --- dkim/__init__.py | 33 ++--------------------------- dkim/dns.py | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 31 deletions(-) create mode 100644 dkim/dns.py diff --git a/dkim/__init__.py b/dkim/__init__.py index 3533444..518a6c0 100644 --- a/dkim/__init__.py +++ b/dkim/__init__.py @@ -34,6 +34,7 @@ from dkim.crypto import ( RSASSA_PKCS1_v1_5_verify, UnparsableKeyError, ) +from dkim.dns import get_txt from dkim.util import ( get_default_logger, InvalidTagValueList, @@ -180,36 +181,6 @@ def rfc822_parse(message): -def dnstxt_dnspython(name): - """Return a TXT record associated with a DNS name.""" - a = dns.resolver.query(name, dns.rdatatype.TXT) - for r in a.response.answer: - if r.rdtype == dns.rdatatype.TXT: - return b"".join(r.items[0].strings) - return None - - -def dnstxt_pydns(name): - """Return a TXT record associated with a DNS name.""" - # Older pydns releases don't like a trailing dot. - if name.endswith('.'): - name = name[:-1] - DNS.ParseResolvConf() - response = DNS.DnsRequest(name, qtype='txt').req() - if not response.answers: - return None - return response.answers[0]['data'][0] - - -# Prefer dnspython if it's there, otherwise use pydns. -try: - import dns.resolver - dnstxt = dnstxt_dnspython -except ImportError: - import DNS - dnstxt = dnstxt_pydns - - def fold(header): """Fold a header line into multiple crlf-separated lines at column 72.""" i = header.rfind(b"\r\n ") @@ -315,7 +286,7 @@ def sign(message, selector, domain, privkey, identity=None, return b'DKIM-Signature: ' + sig_value + b"\r\n" -def verify(message, logger=None, dnsfunc=dnstxt): +def verify(message, logger=None, dnsfunc=get_txt): """Verify a DKIM signature on an RFC822 formatted message. @param message: an RFC822 formatted message (with either \\n or \\r\\n line endings) diff --git a/dkim/dns.py b/dkim/dns.py new file mode 100644 index 0000000..c158f2b --- /dev/null +++ b/dkim/dns.py @@ -0,0 +1,55 @@ +# This software is provided 'as-is', without any express or implied +# warranty. In no event will the author be held liable for any damages +# arising from the use of this software. +# +# Permission is granted to anyone to use this software for any purpose, +# including commercial applications, and to alter it and redistribute it +# freely, subject to the following restrictions: +# +# 1. The origin of this software must not be misrepresented; you must not +# claim that you wrote the original software. If you use this software +# in a product, an acknowledgment in the product documentation would be +# appreciated but is not required. +# 2. Altered source versions must be plainly marked as such, and must not be +# misrepresented as being the original software. +# 3. This notice may not be removed or altered from any source distribution. +# +# Copyright (c) 2008 Greg Hewgill http://hewgill.com +# +# This has been modified from the original software. +# Copyright (c) 2011 William Grant + + +__all__ = [ + 'get_txt' + ] + + +def get_txt_dnspython(name): + """Return a TXT record associated with a DNS name.""" + a = dns.resolver.query(name, dns.rdatatype.TXT) + for r in a.response.answer: + if r.rdtype == dns.rdatatype.TXT: + return b"".join(r.items[0].strings) + return None + + +def get_txt_pydns(name): + """Return a TXT record associated with a DNS name.""" + # Older pydns releases don't like a trailing dot. + if name.endswith('.'): + name = name[:-1] + DNS.ParseResolvConf() + response = DNS.DnsRequest(name, qtype='txt').req() + if not response.answers: + return None + return response.answers[0]['data'][0] + + +# Prefer dnspython if it's there, otherwise use pydns. +try: + import dns.resolver + get_txt = get_txt_dnspython +except ImportError: + import DNS + get_txt = get_txt_pydns