--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: bullseye
User: release.debian....@packages.debian.org
Usertags: pu
Security issue was evaluated as no-dsa, so following up as a regular
stable update:
https://security-tracker.debian.org/tracker/CVE-2022-22846
The dnslib package through 0.9.16 for Python does not verify that the ID value
in a DNS reply matches an ID value in a query.
The only change in the new upstream release is the fix for this issue,
so it seems better to bump to the new release. Package is ready for
upload. Both package and autopkgtest tests pass. There is a minor
change from how the tests were called bullseye to better match with how
it was done with this version in unstable.
Most of the change is documentation changes driven by tooling changes in
the upstream build system. The code changes are very minor.
bullseye debdiff attached.
Scott K
diff -Nru python-dnslib-0.9.16/debian/changelog
python-dnslib-0.9.18/debian/changelog
--- python-dnslib-0.9.16/debian/changelog 2021-12-05 15:05:46.000000000
-0500
+++ python-dnslib-0.9.18/debian/changelog 2022-01-12 10:19:36.000000000
-0500
@@ -1,3 +1,13 @@
+python-dnslib (0.9.18-1) unstable; urgency=medium
+
+ * Remove d/patches/0001-Only-run-tests-for-python3.patch and set test
+ versions in d/rules instead
+ * Iterate over supported python3 versions during build test
+ * Update dh_auto_test override to check DEB_BUILD_OPTIONS
+ * New upstream release
+
+ -- Scott Kitterman <sc...@kitterman.com> Wed, 12 Jan 2022 10:19:36 -0500
+
python-dnslib (0.9.16-1) unstable; urgency=medium
[ Ondřej Nový ]
diff -Nru
python-dnslib-0.9.16/debian/patches/0001-Only-run-tests-for-python3.patch
python-dnslib-0.9.18/debian/patches/0001-Only-run-tests-for-python3.patch
--- python-dnslib-0.9.16/debian/patches/0001-Only-run-tests-for-python3.patch
2021-12-05 14:52:29.000000000 -0500
+++ python-dnslib-0.9.18/debian/patches/0001-Only-run-tests-for-python3.patch
1969-12-31 19:00:00.000000000 -0500
@@ -1,21 +0,0 @@
-From: Scott Kitterman <sc...@kitterman.com>
-Date: Mon, 6 Jan 2020 02:40:47 -0500
-Subject: Only run tests for python3
-
----
- run_tests.sh | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/run_tests.sh b/run_tests.sh
-index 16bc398..3e22f06 100755
---- a/run_tests.sh
-+++ b/run_tests.sh
-@@ -2,7 +2,7 @@
-
- export PYTHONPATH=$(pwd)
-
--: ${VERSIONS:="python python3"}
-+: ${VERSIONS:="python3"}
-
- for src in __init__.py bimap.py bit.py buffer.py label.py dns.py lex.py
server.py digparser.py ranges.py test_decode.py
- do
diff -Nru python-dnslib-0.9.16/debian/patches/series
python-dnslib-0.9.18/debian/patches/series
--- python-dnslib-0.9.16/debian/patches/series 2021-12-05 14:52:29.000000000
-0500
+++ python-dnslib-0.9.18/debian/patches/series 1969-12-31 19:00:00.000000000
-0500
@@ -1 +0,0 @@
-0001-Only-run-tests-for-python3.patch
diff -Nru python-dnslib-0.9.16/debian/rules python-dnslib-0.9.18/debian/rules
--- python-dnslib-0.9.16/debian/rules 2021-12-05 14:45:18.000000000 -0500
+++ python-dnslib-0.9.18/debian/rules 2022-01-12 10:12:33.000000000 -0500
@@ -6,4 +6,6 @@
dh $@ --with python3 --buildsystem=pybuild
override_dh_auto_test:
- ./run_tests.sh
+ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
+ VERSIONS="$(shell py3versions -s)" ./run_tests.sh
+endif
diff -Nru python-dnslib-0.9.16/dnslib/client.py
python-dnslib-0.9.18/dnslib/client.py
--- python-dnslib-0.9.16/dnslib/client.py 2020-06-09 04:01:28.000000000
-0400
+++ python-dnslib-0.9.18/dnslib/client.py 2022-01-09 18:07:12.000000000
-0500
@@ -76,6 +76,9 @@
a_pkt = q.send(address,port,tcp=args.tcp)
a = DNSRecord.parse(a_pkt)
+ if q.header.id != a.header.id:
+ raise DNSError('Response transaction id does not match query
transaction id')
+
if a.header.tc and args.noretry == False:
# Truncated - retry in TCP mode
a_pkt = q.send(address,port,tcp=True)
diff -Nru python-dnslib-0.9.16/dnslib/__init__.py
python-dnslib-0.9.18/dnslib/__init__.py
--- python-dnslib-0.9.16/dnslib/__init__.py 2021-05-07 12:08:33.000000000
-0400
+++ python-dnslib-0.9.18/dnslib/__init__.py 2022-01-09 18:17:03.000000000
-0500
@@ -274,6 +274,14 @@
;; OPT PSEUDOSECTION
; EDNS: version: 0, flags: do; udp: 4096
+Note that when using the library you should always validate the received TXID
+
+ q = DNSRecord.question("abc.com")
+ a_pkt = q.send(address,port,tcp=args.tcp)
+ a = DNSRecord.parse(a_pkt)
+ if q.header.id != a.header.id:
+ raise DNSError('Response transaction id does not match query
transaction id')
+
The library also includes a simple framework for generating custom DNS
resolvers in dnslib.server (see module docs). In most cases this just
requires implementing a custom 'resolve' method which receives a question
@@ -359,6 +367,8 @@
Add support for all RR types to NSEC type bitmap
Merge pull request #17 from sunds/issue_16
Issue 16: uncaught exceptions leak open sockets
+ * 0.9.18 2022-01-09 Validate TXID in client.py (Issue #30 - thanks to
@daniel4x)
+
License:
--------
@@ -381,7 +391,7 @@
from dnslib.dns import *
-version = "0.9.16"
+version = "0.9.18"
if __name__ == '__main__':
import doctest,sys,textwrap
diff -Nru python-dnslib-0.9.16/dnslib/server.py
python-dnslib-0.9.18/dnslib/server.py
--- python-dnslib-0.9.16/dnslib/server.py 2021-05-07 11:20:19.000000000
-0400
+++ python-dnslib-0.9.18/dnslib/server.py 2022-01-09 18:05:47.000000000
-0500
@@ -302,7 +302,7 @@
print("\n",dnsobj.toZone(" "),"\n",sep="")
-class UDPServer(socketserver.UDPServer,socketserver.ThreadingMixIn,object):
+class UDPServer(socketserver.ThreadingMixIn,socketserver.UDPServer,object):
def __init__(self, server_address, handler):
self.allow_reuse_address = True
self.daemon_threads = True
@@ -310,7 +310,7 @@
self.address_family = socket.AF_INET6
super(UDPServer,self).__init__(server_address, handler)
-class TCPServer(socketserver.TCPServer,socketserver.ThreadingMixIn,object):
+class TCPServer(socketserver.ThreadingMixIn,socketserver.TCPServer,object):
def __init__(self, server_address, handler):
self.allow_reuse_address = True
self.daemon_threads = True
diff -Nru python-dnslib-0.9.16/dnslib.egg-info/PKG-INFO
python-dnslib-0.9.18/dnslib.egg-info/PKG-INFO
--- python-dnslib-0.9.16/dnslib.egg-info/PKG-INFO 2021-05-07
12:16:39.000000000 -0400
+++ python-dnslib-0.9.18/dnslib.egg-info/PKG-INFO 2022-01-09
18:18:36.000000000 -0500
@@ -1,389 +1,402 @@
Metadata-Version: 2.1
Name: dnslib
-Version: 0.9.16
+Version: 0.9.18
Summary: Simple library to encode/decode DNS wire-format packets
Home-page: https://github.com/paulc/dnslib
Author: PaulC
License: BSD
-Description:
-
- ## From Version 0.9.12 the master repository for _dnslib_ has been
moved to GitHub (https://github.com/paulc/dnslib). Please update any links to
the original BitBucket repository as this will no longer be maintained.
-
-
- dnslib
- ------
-
- A library to encode/decode DNS wire-format packets supporting both
- Python 2.7 and Python 3.2+.
-
- The library provides:
-
- * Support for encoding/decoding DNS packets between wire format,
- python objects, and Zone/DiG textual representation (dnslib.dns)
-
- * A server framework allowing the simple creation of custom DNS
- resolvers (dnslib.server) and a number of example servers
- created using this framework
-
- * A number of utilities for testing (dnslib.client, dnslib.proxy,
- dnslib.intercept)
-
- Python 3 support was added in Version 0.9.0 which represented a fairly
- major update to the library - the key changes include:
-
- * Python 2.7/3.2+ support (the last version supporting Python 2.6
- or earlier was version 0.8.3)
-
- * The 'Bimap' interface was changed significantly to explicitly
- split forward (value->text) lookups via __getitem__ and
- reverse (text->value) lookups via __getattr__. Applications
- using the old interface will need to be updated.
-
- * Hostnames are now returned with a trailing dot by default (in
- line with RFC)
-
- * Most object attributes are now typed in line with the record
- definitions to make it harder to generate invalid packets
-
- * Support for encoding/decoding resource records in 'Zone' (BIND)
- file format
-
- * Support for encoding/decoding packets in 'DiG' format
-
- * Server framework allowing (in most cases) custom resolvers to
- be created by just subclassing the DNSResolver class and
- overriding the 'resolve' method
-
- * A lot of fixes to error detection/handling which should make
- the library much more robust to invalid/unsupported data. The
- library should now either return a valid DNSRecord instance
- when parsing a packet or raise DNSError (tested via fuzzing)
-
- * Improved utilities (dnslib.client, dnslib.proxy, dnslib.intercept)
-
- * Improvements to encoding/decoding tests including the ability
- to generate test data automatically in test_decode.py (comparing
- outputs against DiG)
-
- * Ability to compare and diff DNSRecords
-
- Classes
- -------
-
- The key DNS packet handling classes are in dnslib.dns and map to the
- standard DNS packet sections:
-
- * DNSRecord - container for DNS packet. Contains:
- - DNSHeader
- - Question section containing zero or more DNSQuestion objects
- - Answer section containing zero or more RR objects
- - Authority section containing zero or more RR objects
- - Additional section containing zero or more RR objects
- * DNS RRs (resource records) contain an RR header and an RD object)
- * Specific RD types are implemented as subclasses of RD
- * DNS labels are represented by a DNSLabel class - in most cases
- this handles conversion to/from textual representation however
- does support arbitatry labels via a tuple of bytes objects
-
- Usage
- -----
-
- To decode a DNS packet:
-
- >>> packet =
binascii.unhexlify(b'd5ad818000010005000000000377777706676f6f676c6503636f6d0000010001c00c0005000100000005000803777777016cc010c02c0001000100000005000442f95b68c02c0001000100000005000442f95b63c02c0001000100000005000442f95b67c02c0001000100000005000442f95b93')
- >>> d = DNSRecord.parse(packet)
- >>> d
- <DNS Header: id=0xd5ad type=RESPONSE opcode=QUERY flags=RD,RA
rcode='NOERROR' q=1 a=5 ns=0 ar=0>
- <DNS Question: 'www.google.com.' qtype=A qclass=IN>
- <DNS RR: 'www.google.com.' rtype=CNAME rclass=IN ttl=5
rdata='www.l.google.com.'>
- <DNS RR: 'www.l.google.com.' rtype=A rclass=IN ttl=5
rdata='66.249.91.104'>
- <DNS RR: 'www.l.google.com.' rtype=A rclass=IN ttl=5
rdata='66.249.91.99'>
- <DNS RR: 'www.l.google.com.' rtype=A rclass=IN ttl=5
rdata='66.249.91.103'>
- <DNS RR: 'www.l.google.com.' rtype=A rclass=IN ttl=5
rdata='66.249.91.147'>
-
- The default text representation of the DNSRecord is in zone file
format:
-
- >>> print(d)
- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54701
- ;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 0
- ;; QUESTION SECTION:
- ;www.google.com. IN A
- ;; ANSWER SECTION:
- www.google.com. 5 IN CNAME www.l.google.com.
- www.l.google.com. 5 IN A 66.249.91.104
- www.l.google.com. 5 IN A 66.249.91.99
- www.l.google.com. 5 IN A 66.249.91.103
- www.l.google.com. 5 IN A 66.249.91.147
-
- To create a DNS Request Packet:
-
- >>> d = DNSRecord.question("google.com")
-
- (This is equivalent to: d = DNSRecord(q=DNSQuestion("google.com") )
-
- >>> d
- <DNS Header: id=... type=QUERY opcode=QUERY flags=RD
rcode='NOERROR' q=1 a=0 ns=0 ar=0>
- <DNS Question: 'google.com.' qtype=A qclass=IN>
-
- >>> str(DNSRecord.parse(d.pack())) == str(d)
- True
-
- >>> print(d)
- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
- ;; flags: rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
- ;; QUESTION SECTION:
- ;google.com. IN A
-
- >>> d = DNSRecord.question("google.com","MX")
-
- (This is equivalent to: d =
DNSRecord(q=DNSQuestion("google.com",QTYPE.MX) )
-
- >>> str(DNSRecord.parse(d.pack())) == str(d)
- True
-
- >>> print(d)
- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
- ;; flags: rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
- ;; QUESTION SECTION:
- ;google.com. IN MX
-
- To create a DNS Response Packet:
-
- >>> d = DNSRecord(DNSHeader(qr=1,aa=1,ra=1),
- ... q=DNSQuestion("abc.com"),
- ... a=RR("abc.com",rdata=A("1.2.3.4")))
- >>> d
- <DNS Header: id=... type=RESPONSE opcode=QUERY flags=AA,RD,RA
rcode='NOERROR' q=1 a=1 ns=0 ar=0>
- <DNS Question: 'abc.com.' qtype=A qclass=IN>
- <DNS RR: 'abc.com.' rtype=A rclass=IN ttl=0 rdata='1.2.3.4'>
- >>> str(DNSRecord.parse(d.pack())) == str(d)
- True
-
- >>> print(d)
- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
- ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0,
ADDITIONAL: 0
- ;; QUESTION SECTION:
- ;abc.com. IN A
- ;; ANSWER SECTION:
- abc.com. 0 IN A 1.2.3.4
-
- It is also possible to create RRs from a string in zone file format
-
- >>> RR.fromZone("abc.com IN A 1.2.3.4")
- [<DNS RR: 'abc.com.' rtype=A rclass=IN ttl=0 rdata='1.2.3.4'>]
-
- (Note: this produces a list of RRs which should be unpacked if
being
- passed to add_answer/add_auth/add_ar etc)
-
- >>> q = DNSRecord.question("abc.com")
- >>> a = q.reply()
- >>> a.add_answer(*RR.fromZone("abc.com 60 A 1.2.3.4"))
- >>> print(a)
- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
- ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0,
ADDITIONAL: 0
- ;; QUESTION SECTION:
- ;abc.com. IN A
- ;; ANSWER SECTION:
- abc.com. 60 IN A 1.2.3.4
-
- The zone file can contain multiple entries and supports most of the
normal
- format defined in RFC1035 (specifically not $INCLUDE)
-
- >>> z = '''
- ... $TTL 300
- ... $ORIGIN abc.com
- ...
- ... @ IN MX 10 mail.abc.com.
- ... www IN A 1.2.3.4
- ... IN TXT "Some Text"
- ... mail IN CNAME www.abc.com.
- ... '''
- >>> for rr in RR.fromZone(textwrap.dedent(z)):
- ... print(rr)
- abc.com. 300 IN MX 10 mail.abc.com.
- www.abc.com. 300 IN A 1.2.3.4
- www.abc.com. 300 IN TXT "Some Text"
- mail.abc.com. 300 IN CNAME www.abc.com.
-
- To create a skeleton reply to a DNS query:
-
- >>> q = DNSRecord(q=DNSQuestion("abc.com",QTYPE.ANY))
- >>> a = q.reply()
- >>> a.add_answer(RR("abc.com",QTYPE.A,rdata=A("1.2.3.4"),ttl=60))
- >>> str(DNSRecord.parse(a.pack())) == str(a)
- True
- >>> print(a)
- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
- ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0,
ADDITIONAL: 0
- ;; QUESTION SECTION:
- ;abc.com. IN ANY
- ;; ANSWER SECTION:
- abc.com. 60 IN A 1.2.3.4
-
- Add additional RRs:
-
- >>> a.add_answer(RR("xxx.abc.com",QTYPE.A,rdata=A("1.2.3.4")))
- >>>
a.add_answer(RR("xxx.abc.com",QTYPE.AAAA,rdata=AAAA("1234:5678::1")))
- >>> str(DNSRecord.parse(a.pack())) == str(a)
- True
- >>> print(a)
- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
- ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0,
ADDITIONAL: 0
- ;; QUESTION SECTION:
- ;abc.com. IN ANY
- ;; ANSWER SECTION:
- abc.com. 60 IN A 1.2.3.4
- xxx.abc.com. 0 IN A 1.2.3.4
- xxx.abc.com. 0 IN AAAA 1234:5678::1
-
-
- It is also possible to create a reply from a string in zone file
format:
-
- >>> q = DNSRecord(q=DNSQuestion("abc.com",QTYPE.ANY))
- >>> a = q.replyZone("abc.com 60 IN CNAME xxx.abc.com")
- >>> print(a)
- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
- ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0,
ADDITIONAL: 0
- ;; QUESTION SECTION:
- ;abc.com. IN ANY
- ;; ANSWER SECTION:
- abc.com. 60 IN CNAME xxx.abc.com.
-
- >>> str(DNSRecord.parse(a.pack())) == str(a)
- True
-
- >>> q = DNSRecord(q=DNSQuestion("abc.com",QTYPE.ANY))
- >>> a = q.replyZone(textwrap.dedent(z))
- >>> print(a)
- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
- ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0,
ADDITIONAL: 0
- ;; QUESTION SECTION:
- ;abc.com. IN ANY
- ;; ANSWER SECTION:
- abc.com. 300 IN MX 10 mail.abc.com.
- www.abc.com. 300 IN A 1.2.3.4
- www.abc.com. 300 IN TXT "Some Text"
- mail.abc.com. 300 IN CNAME www.abc.com.
-
- To send a DNSSEC request (EDNS OPT record with DO flag & header AD
flag):
-
- >>> q = DNSRecord(q=DNSQuestion("abc.com",QTYPE.A))
- >>> q.add_ar(EDNS0(flags="do",udp_len=4096))
- >>> q.header.ad = 1
- >>> print(q)
- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
- ;; flags: rd ad; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
- ;; QUESTION SECTION:
- ;abc.com. IN A
- ;; ADDITIONAL SECTION:
- ;; OPT PSEUDOSECTION
- ; EDNS: version: 0, flags: do; udp: 4096
-
- The library also includes a simple framework for generating custom DNS
- resolvers in dnslib.server (see module docs). In most cases this just
- requires implementing a custom 'resolve' method which receives a
question
- object and returns a response.
-
- A number of sample resolvers are provided as examples (see CLI --help):
-
- * dnslib.fixedresolver - Respond to all requests with fixed
response
- * dnslib.zoneresolver - Respond from Zone file
- * dnslib.shellresolver - Call shell script to generate response
-
- The library includes a number of client utilities:
-
- * DiG like client library
-
- # python -m dnslib.client --help
-
- * DNS Proxy Server
-
- # python -m dnslib.proxy --help
-
- * Intercepting DNS Proxy Server (replace proxy responses for
specified domains)
-
- # python -m dnslib.intercept --help
-
-
- Changelog:
- ----------
-
- * 0.1 2010-09-19 Initial Release
- * 0.2 2010-09-22 Minor fixes
- * 0.3 2010-10-02 Add DNSLabel class to support arbitrary
labels (embedded '.')
- * 0.4 2012-02-26 Merge with dbslib-circuits
- * 0.5 2012-09-13 Add support for RFC2136 DDNS updates
- Patch provided by Wesley Shields
<w...@freebsd.org> - thanks
- * 0.6 2012-10-20 Basic AAAA support
- * 0.7 2012-10-20 Add initial EDNS0 support (untested)
- * 0.8 2012-11-04 Add support for NAPTR, Authority RR and
additional RR
- Patch provided by Stefan Andersson
(https://bitbucket.org/norox) - thanks
- * 0.8.1 2012-11-05 Added NAPTR test case and fixed logic error
- Patch provided by Stefan Andersson
(https://bitbucket.org/norox) - thanks
- * 0.8.2 2012-11-11 Patch to fix IPv6 formatting
- Patch provided by Torbjorn Lonnemark
(https://bitbucket.org/tobbezz) - thanks
- * 0.8.3 2013-04-27 Don't parse rdata if rdlength is 0
- Patch provided by Wesley Shields
<w...@freebsd.org> - thanks
- * 0.9.0 2014-05-05 Major update including Py3 support (see docs)
- * 0.9.1 2014-05-05 Minor fixes
- * 0.9.2 2014-08-26 Fix Bimap handling of unknown mappings to
avoid exception in printing
- Add typed attributes to classes
- Misc fixes from James Mills - thanks
- * 0.9.3 2014-08-26 Workaround for argparse bug which raises
AssertionError if [] is
- present in option text (really?)
- * 0.9.4 2015-04-10 Fix to support multiple strings in TXT record
- Patch provided by James Cherry
(https://bitbucket.org/james_cherry) - thanks
- NOTE: For consistency this patch changes the
'repr' output for
- TXT records to always be quoted
- * 0.9.5 2015-10-27 Add threading & timeout handling to DNSServer
- * 0.9.6 2015-10-28 Replace strftime in RRSIG formatting to avoid
possible locale issues
- Identified by Bryan Everly - thanks
- * 0.9.7 2017-01-15 Sort out CAA/TYPE257 DiG parsing mismatch
- * 0.9.8 2019-02-25 Force DNSKEY key to be bytes object
- Catch Bimap __wrapped__ attr (used by inspect
module in 3.7)
- * 0.9.9 2019-03-19 Add support for DNSSEC flag getters/setters
(from <r...@dinosec.com> - thanks)
- Added --dnssec flags to dnslib.client &
dnslib.test_decode (sets EDNS0 DO flag)
- Added EDNS0 support to dnslib.digparser
- * 0.9.10 2019-03-24 Fixes to DNSSEC support
- Add NSEC RR support
- Add --dnssec flag to dnslib.client &
dnslib.test_decode
- Quote/unquote non-printable characters in DNS
labels
- Update test data
- (Thanks to <r...@dinosec.com> for help)
- * 0.9.11 2019-12-17 Encode NOTIFY Opcode (Issue #26)
- * 0.9.12 2019-12-17 Transition master repository to Github
(Bitbucket shutting down hg)
- * 0.9.13 2020-06-01 Handle truncated requests in server.py (Issue
#9)
- Replace thred.isAlive with thread.is_alive
(Deprecated in Py3.9)
- Merged Pull Request #4 (Extra options for
intercept.py) - thanks to @nolanl
- * 0.9.14 2020-06-09 Merged Pull Request #10 (Return doctest
status via exit code)
- Thanks to @mgorny
- * 0.9.15 2021-05-07 DNSServer fixes - support IPv6 (from Pull
Request #21) - thanks to @mikma
- - deamon threads (Pull
Request #19) - thanks to @wojons
- Add unsupported RR types (Issue #27)
- * 0.9.16 2021-05-07 Merge pull request #23 from Tugzrida/patch-1
- Add support for all RR types to NSEC type
bitmap
- Merge pull request #17 from sunds/issue_16
- Issue 16: uncaught exceptions leak open
sockets
-
- License:
- --------
-
- BSD
-
- Author:
- -------
-
- * PaulC
-
- Master Repository/Issues:
- -------------------------
-
- * https://github.com/paulc/dnslib
-
- (Note: https://bitbucket.org/paulc/dnslib has been deprecated and
will not be updated)
-
Platform: UNKNOWN
Classifier: Topic :: Internet :: Name Service (DNS)
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 3
Description-Content-Type: text/markdown
+License-File: LICENSE
+
+
+
+## From Version 0.9.12 the master repository for _dnslib_ has been moved to
GitHub (https://github.com/paulc/dnslib). Please update any links to the
original BitBucket repository as this will no longer be maintained.
+
+
+dnslib
+------
+
+A library to encode/decode DNS wire-format packets supporting both
+Python 2.7 and Python 3.2+.
+
+The library provides:
+
+ * Support for encoding/decoding DNS packets between wire format,
+ python objects, and Zone/DiG textual representation (dnslib.dns)
+
+ * A server framework allowing the simple creation of custom DNS
+ resolvers (dnslib.server) and a number of example servers
+ created using this framework
+
+ * A number of utilities for testing (dnslib.client, dnslib.proxy,
+ dnslib.intercept)
+
+Python 3 support was added in Version 0.9.0 which represented a fairly
+major update to the library - the key changes include:
+
+ * Python 2.7/3.2+ support (the last version supporting Python 2.6
+ or earlier was version 0.8.3)
+
+ * The 'Bimap' interface was changed significantly to explicitly
+ split forward (value->text) lookups via __getitem__ and
+ reverse (text->value) lookups via __getattr__. Applications
+ using the old interface will need to be updated.
+
+ * Hostnames are now returned with a trailing dot by default (in
+ line with RFC)
+
+ * Most object attributes are now typed in line with the record
+ definitions to make it harder to generate invalid packets
+
+ * Support for encoding/decoding resource records in 'Zone' (BIND)
+ file format
+
+ * Support for encoding/decoding packets in 'DiG' format
+
+ * Server framework allowing (in most cases) custom resolvers to
+ be created by just subclassing the DNSResolver class and
+ overriding the 'resolve' method
+
+ * A lot of fixes to error detection/handling which should make
+ the library much more robust to invalid/unsupported data. The
+ library should now either return a valid DNSRecord instance
+ when parsing a packet or raise DNSError (tested via fuzzing)
+
+ * Improved utilities (dnslib.client, dnslib.proxy, dnslib.intercept)
+
+ * Improvements to encoding/decoding tests including the ability
+ to generate test data automatically in test_decode.py (comparing
+ outputs against DiG)
+
+ * Ability to compare and diff DNSRecords
+
+Classes
+-------
+
+The key DNS packet handling classes are in dnslib.dns and map to the
+standard DNS packet sections:
+
+ * DNSRecord - container for DNS packet. Contains:
+ - DNSHeader
+ - Question section containing zero or more DNSQuestion objects
+ - Answer section containing zero or more RR objects
+ - Authority section containing zero or more RR objects
+ - Additional section containing zero or more RR objects
+ * DNS RRs (resource records) contain an RR header and an RD object)
+ * Specific RD types are implemented as subclasses of RD
+ * DNS labels are represented by a DNSLabel class - in most cases
+ this handles conversion to/from textual representation however
+ does support arbitatry labels via a tuple of bytes objects
+
+Usage
+-----
+
+To decode a DNS packet:
+
+ >>> packet =
binascii.unhexlify(b'd5ad818000010005000000000377777706676f6f676c6503636f6d0000010001c00c0005000100000005000803777777016cc010c02c0001000100000005000442f95b68c02c0001000100000005000442f95b63c02c0001000100000005000442f95b67c02c0001000100000005000442f95b93')
+ >>> d = DNSRecord.parse(packet)
+ >>> d
+ <DNS Header: id=0xd5ad type=RESPONSE opcode=QUERY flags=RD,RA
rcode='NOERROR' q=1 a=5 ns=0 ar=0>
+ <DNS Question: 'www.google.com.' qtype=A qclass=IN>
+ <DNS RR: 'www.google.com.' rtype=CNAME rclass=IN ttl=5
rdata='www.l.google.com.'>
+ <DNS RR: 'www.l.google.com.' rtype=A rclass=IN ttl=5 rdata='66.249.91.104'>
+ <DNS RR: 'www.l.google.com.' rtype=A rclass=IN ttl=5 rdata='66.249.91.99'>
+ <DNS RR: 'www.l.google.com.' rtype=A rclass=IN ttl=5 rdata='66.249.91.103'>
+ <DNS RR: 'www.l.google.com.' rtype=A rclass=IN ttl=5 rdata='66.249.91.147'>
+
+The default text representation of the DNSRecord is in zone file format:
+
+ >>> print(d)
+ ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54701
+ ;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 0
+ ;; QUESTION SECTION:
+ ;www.google.com. IN A
+ ;; ANSWER SECTION:
+ www.google.com. 5 IN CNAME www.l.google.com.
+ www.l.google.com. 5 IN A 66.249.91.104
+ www.l.google.com. 5 IN A 66.249.91.99
+ www.l.google.com. 5 IN A 66.249.91.103
+ www.l.google.com. 5 IN A 66.249.91.147
+
+To create a DNS Request Packet:
+
+ >>> d = DNSRecord.question("google.com")
+
+(This is equivalent to: d = DNSRecord(q=DNSQuestion("google.com") )
+
+ >>> d
+ <DNS Header: id=... type=QUERY opcode=QUERY flags=RD rcode='NOERROR' q=1
a=0 ns=0 ar=0>
+ <DNS Question: 'google.com.' qtype=A qclass=IN>
+
+ >>> str(DNSRecord.parse(d.pack())) == str(d)
+ True
+
+ >>> print(d)
+ ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
+ ;; flags: rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
+ ;; QUESTION SECTION:
+ ;google.com. IN A
+
+ >>> d = DNSRecord.question("google.com","MX")
+
+(This is equivalent to: d = DNSRecord(q=DNSQuestion("google.com",QTYPE.MX) )
+
+ >>> str(DNSRecord.parse(d.pack())) == str(d)
+ True
+
+ >>> print(d)
+ ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
+ ;; flags: rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
+ ;; QUESTION SECTION:
+ ;google.com. IN MX
+
+To create a DNS Response Packet:
+
+ >>> d = DNSRecord(DNSHeader(qr=1,aa=1,ra=1),
+ ... q=DNSQuestion("abc.com"),
+ ... a=RR("abc.com",rdata=A("1.2.3.4")))
+ >>> d
+ <DNS Header: id=... type=RESPONSE opcode=QUERY flags=AA,RD,RA
rcode='NOERROR' q=1 a=1 ns=0 ar=0>
+ <DNS Question: 'abc.com.' qtype=A qclass=IN>
+ <DNS RR: 'abc.com.' rtype=A rclass=IN ttl=0 rdata='1.2.3.4'>
+ >>> str(DNSRecord.parse(d.pack())) == str(d)
+ True
+
+ >>> print(d)
+ ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
+ ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
+ ;; QUESTION SECTION:
+ ;abc.com. IN A
+ ;; ANSWER SECTION:
+ abc.com. 0 IN A 1.2.3.4
+
+It is also possible to create RRs from a string in zone file format
+
+ >>> RR.fromZone("abc.com IN A 1.2.3.4")
+ [<DNS RR: 'abc.com.' rtype=A rclass=IN ttl=0 rdata='1.2.3.4'>]
+
+ (Note: this produces a list of RRs which should be unpacked if being
+ passed to add_answer/add_auth/add_ar etc)
+
+ >>> q = DNSRecord.question("abc.com")
+ >>> a = q.reply()
+ >>> a.add_answer(*RR.fromZone("abc.com 60 A 1.2.3.4"))
+ >>> print(a)
+ ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
+ ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
+ ;; QUESTION SECTION:
+ ;abc.com. IN A
+ ;; ANSWER SECTION:
+ abc.com. 60 IN A 1.2.3.4
+
+The zone file can contain multiple entries and supports most of the normal
+format defined in RFC1035 (specifically not $INCLUDE)
+
+ >>> z = '''
+ ... $TTL 300
+ ... $ORIGIN abc.com
+ ...
+ ... @ IN MX 10 mail.abc.com.
+ ... www IN A 1.2.3.4
+ ... IN TXT "Some Text"
+ ... mail IN CNAME www.abc.com.
+ ... '''
+ >>> for rr in RR.fromZone(textwrap.dedent(z)):
+ ... print(rr)
+ abc.com. 300 IN MX 10 mail.abc.com.
+ www.abc.com. 300 IN A 1.2.3.4
+ www.abc.com. 300 IN TXT "Some Text"
+ mail.abc.com. 300 IN CNAME www.abc.com.
+
+To create a skeleton reply to a DNS query:
+
+ >>> q = DNSRecord(q=DNSQuestion("abc.com",QTYPE.ANY))
+ >>> a = q.reply()
+ >>> a.add_answer(RR("abc.com",QTYPE.A,rdata=A("1.2.3.4"),ttl=60))
+ >>> str(DNSRecord.parse(a.pack())) == str(a)
+ True
+ >>> print(a)
+ ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
+ ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
+ ;; QUESTION SECTION:
+ ;abc.com. IN ANY
+ ;; ANSWER SECTION:
+ abc.com. 60 IN A 1.2.3.4
+
+Add additional RRs:
+
+ >>> a.add_answer(RR("xxx.abc.com",QTYPE.A,rdata=A("1.2.3.4")))
+ >>> a.add_answer(RR("xxx.abc.com",QTYPE.AAAA,rdata=AAAA("1234:5678::1")))
+ >>> str(DNSRecord.parse(a.pack())) == str(a)
+ True
+ >>> print(a)
+ ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
+ ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0
+ ;; QUESTION SECTION:
+ ;abc.com. IN ANY
+ ;; ANSWER SECTION:
+ abc.com. 60 IN A 1.2.3.4
+ xxx.abc.com. 0 IN A 1.2.3.4
+ xxx.abc.com. 0 IN AAAA 1234:5678::1
+
+
+It is also possible to create a reply from a string in zone file format:
+
+ >>> q = DNSRecord(q=DNSQuestion("abc.com",QTYPE.ANY))
+ >>> a = q.replyZone("abc.com 60 IN CNAME xxx.abc.com")
+ >>> print(a)
+ ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
+ ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
+ ;; QUESTION SECTION:
+ ;abc.com. IN ANY
+ ;; ANSWER SECTION:
+ abc.com. 60 IN CNAME xxx.abc.com.
+
+ >>> str(DNSRecord.parse(a.pack())) == str(a)
+ True
+
+ >>> q = DNSRecord(q=DNSQuestion("abc.com",QTYPE.ANY))
+ >>> a = q.replyZone(textwrap.dedent(z))
+ >>> print(a)
+ ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
+ ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 0
+ ;; QUESTION SECTION:
+ ;abc.com. IN ANY
+ ;; ANSWER SECTION:
+ abc.com. 300 IN MX 10 mail.abc.com.
+ www.abc.com. 300 IN A 1.2.3.4
+ www.abc.com. 300 IN TXT "Some Text"
+ mail.abc.com. 300 IN CNAME www.abc.com.
+
+To send a DNSSEC request (EDNS OPT record with DO flag & header AD flag):
+
+ >>> q = DNSRecord(q=DNSQuestion("abc.com",QTYPE.A))
+ >>> q.add_ar(EDNS0(flags="do",udp_len=4096))
+ >>> q.header.ad = 1
+ >>> print(q)
+ ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
+ ;; flags: rd ad; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
+ ;; QUESTION SECTION:
+ ;abc.com. IN A
+ ;; ADDITIONAL SECTION:
+ ;; OPT PSEUDOSECTION
+ ; EDNS: version: 0, flags: do; udp: 4096
+
+Note that when using the library you should always validate the received TXID
+
+ q = DNSRecord.question("abc.com")
+ a_pkt = q.send(address,port,tcp=args.tcp)
+ a = DNSRecord.parse(a_pkt)
+ if q.header.id != a.header.id:
+ raise DNSError('Response transaction id does not match query
transaction id')
+
+The library also includes a simple framework for generating custom DNS
+resolvers in dnslib.server (see module docs). In most cases this just
+requires implementing a custom 'resolve' method which receives a question
+object and returns a response.
+
+A number of sample resolvers are provided as examples (see CLI --help):
+
+ * dnslib.fixedresolver - Respond to all requests with fixed response
+ * dnslib.zoneresolver - Respond from Zone file
+ * dnslib.shellresolver - Call shell script to generate response
+
+The library includes a number of client utilities:
+
+ * DiG like client library
+
+ # python -m dnslib.client --help
+
+ * DNS Proxy Server
+
+ # python -m dnslib.proxy --help
+
+ * Intercepting DNS Proxy Server (replace proxy responses for specified
domains)
+
+ # python -m dnslib.intercept --help
+
+
+Changelog:
+----------
+
+ * 0.1 2010-09-19 Initial Release
+ * 0.2 2010-09-22 Minor fixes
+ * 0.3 2010-10-02 Add DNSLabel class to support arbitrary labels
(embedded '.')
+ * 0.4 2012-02-26 Merge with dbslib-circuits
+ * 0.5 2012-09-13 Add support for RFC2136 DDNS updates
+ Patch provided by Wesley Shields <w...@freebsd.org> -
thanks
+ * 0.6 2012-10-20 Basic AAAA support
+ * 0.7 2012-10-20 Add initial EDNS0 support (untested)
+ * 0.8 2012-11-04 Add support for NAPTR, Authority RR and additional RR
+ Patch provided by Stefan Andersson
(https://bitbucket.org/norox) - thanks
+ * 0.8.1 2012-11-05 Added NAPTR test case and fixed logic error
+ Patch provided by Stefan Andersson
(https://bitbucket.org/norox) - thanks
+ * 0.8.2 2012-11-11 Patch to fix IPv6 formatting
+ Patch provided by Torbjorn Lonnemark
(https://bitbucket.org/tobbezz) - thanks
+ * 0.8.3 2013-04-27 Don't parse rdata if rdlength is 0
+ Patch provided by Wesley Shields <w...@freebsd.org> -
thanks
+ * 0.9.0 2014-05-05 Major update including Py3 support (see docs)
+ * 0.9.1 2014-05-05 Minor fixes
+ * 0.9.2 2014-08-26 Fix Bimap handling of unknown mappings to avoid
exception in printing
+ Add typed attributes to classes
+ Misc fixes from James Mills - thanks
+ * 0.9.3 2014-08-26 Workaround for argparse bug which raises
AssertionError if [] is
+ present in option text (really?)
+ * 0.9.4 2015-04-10 Fix to support multiple strings in TXT record
+ Patch provided by James Cherry
(https://bitbucket.org/james_cherry) - thanks
+ NOTE: For consistency this patch changes the 'repr'
output for
+ TXT records to always be quoted
+ * 0.9.5 2015-10-27 Add threading & timeout handling to DNSServer
+ * 0.9.6 2015-10-28 Replace strftime in RRSIG formatting to avoid
possible locale issues
+ Identified by Bryan Everly - thanks
+ * 0.9.7 2017-01-15 Sort out CAA/TYPE257 DiG parsing mismatch
+ * 0.9.8 2019-02-25 Force DNSKEY key to be bytes object
+ Catch Bimap __wrapped__ attr (used by inspect module
in 3.7)
+ * 0.9.9 2019-03-19 Add support for DNSSEC flag getters/setters (from
<r...@dinosec.com> - thanks)
+ Added --dnssec flags to dnslib.client &
dnslib.test_decode (sets EDNS0 DO flag)
+ Added EDNS0 support to dnslib.digparser
+ * 0.9.10 2019-03-24 Fixes to DNSSEC support
+ Add NSEC RR support
+ Add --dnssec flag to dnslib.client &
dnslib.test_decode
+ Quote/unquote non-printable characters in DNS labels
+ Update test data
+ (Thanks to <r...@dinosec.com> for help)
+ * 0.9.11 2019-12-17 Encode NOTIFY Opcode (Issue #26)
+ * 0.9.12 2019-12-17 Transition master repository to Github (Bitbucket
shutting down hg)
+ * 0.9.13 2020-06-01 Handle truncated requests in server.py (Issue #9)
+ Replace thred.isAlive with thread.is_alive
(Deprecated in Py3.9)
+ Merged Pull Request #4 (Extra options for
intercept.py) - thanks to @nolanl
+ * 0.9.14 2020-06-09 Merged Pull Request #10 (Return doctest status via
exit code)
+ Thanks to @mgorny
+ * 0.9.15 2021-05-07 DNSServer fixes - support IPv6 (from Pull Request
#21) - thanks to @mikma
+ - deamon threads (Pull Request #19) -
thanks to @wojons
+ Add unsupported RR types (Issue #27)
+ * 0.9.16 2021-05-07 Merge pull request #23 from Tugzrida/patch-1
+ Add support for all RR types to NSEC type bitmap
+ Merge pull request #17 from sunds/issue_16
+ Issue 16: uncaught exceptions leak open sockets
+ * 0.9.18 2022-01-09 Validate TXID in client.py (Issue #30 - thanks to
@daniel4x)
+
+
+License:
+--------
+
+BSD
+
+Author:
+-------
+
+ * PaulC
+
+Master Repository/Issues:
+-------------------------
+
+ * https://github.com/paulc/dnslib
+
+ (Note: https://bitbucket.org/paulc/dnslib has been deprecated and will not be
updated)
+
+
diff -Nru python-dnslib-0.9.16/PKG-INFO python-dnslib-0.9.18/PKG-INFO
--- python-dnslib-0.9.16/PKG-INFO 2021-05-07 12:16:39.721066200 -0400
+++ python-dnslib-0.9.18/PKG-INFO 2022-01-09 18:18:36.210179600 -0500
@@ -1,389 +1,402 @@
Metadata-Version: 2.1
Name: dnslib
-Version: 0.9.16
+Version: 0.9.18
Summary: Simple library to encode/decode DNS wire-format packets
Home-page: https://github.com/paulc/dnslib
Author: PaulC
License: BSD
-Description:
-
- ## From Version 0.9.12 the master repository for _dnslib_ has been
moved to GitHub (https://github.com/paulc/dnslib). Please update any links to
the original BitBucket repository as this will no longer be maintained.
-
-
- dnslib
- ------
-
- A library to encode/decode DNS wire-format packets supporting both
- Python 2.7 and Python 3.2+.
-
- The library provides:
-
- * Support for encoding/decoding DNS packets between wire format,
- python objects, and Zone/DiG textual representation (dnslib.dns)
-
- * A server framework allowing the simple creation of custom DNS
- resolvers (dnslib.server) and a number of example servers
- created using this framework
-
- * A number of utilities for testing (dnslib.client, dnslib.proxy,
- dnslib.intercept)
-
- Python 3 support was added in Version 0.9.0 which represented a fairly
- major update to the library - the key changes include:
-
- * Python 2.7/3.2+ support (the last version supporting Python 2.6
- or earlier was version 0.8.3)
-
- * The 'Bimap' interface was changed significantly to explicitly
- split forward (value->text) lookups via __getitem__ and
- reverse (text->value) lookups via __getattr__. Applications
- using the old interface will need to be updated.
-
- * Hostnames are now returned with a trailing dot by default (in
- line with RFC)
-
- * Most object attributes are now typed in line with the record
- definitions to make it harder to generate invalid packets
-
- * Support for encoding/decoding resource records in 'Zone' (BIND)
- file format
-
- * Support for encoding/decoding packets in 'DiG' format
-
- * Server framework allowing (in most cases) custom resolvers to
- be created by just subclassing the DNSResolver class and
- overriding the 'resolve' method
-
- * A lot of fixes to error detection/handling which should make
- the library much more robust to invalid/unsupported data. The
- library should now either return a valid DNSRecord instance
- when parsing a packet or raise DNSError (tested via fuzzing)
-
- * Improved utilities (dnslib.client, dnslib.proxy, dnslib.intercept)
-
- * Improvements to encoding/decoding tests including the ability
- to generate test data automatically in test_decode.py (comparing
- outputs against DiG)
-
- * Ability to compare and diff DNSRecords
-
- Classes
- -------
-
- The key DNS packet handling classes are in dnslib.dns and map to the
- standard DNS packet sections:
-
- * DNSRecord - container for DNS packet. Contains:
- - DNSHeader
- - Question section containing zero or more DNSQuestion objects
- - Answer section containing zero or more RR objects
- - Authority section containing zero or more RR objects
- - Additional section containing zero or more RR objects
- * DNS RRs (resource records) contain an RR header and an RD object)
- * Specific RD types are implemented as subclasses of RD
- * DNS labels are represented by a DNSLabel class - in most cases
- this handles conversion to/from textual representation however
- does support arbitatry labels via a tuple of bytes objects
-
- Usage
- -----
-
- To decode a DNS packet:
-
- >>> packet =
binascii.unhexlify(b'd5ad818000010005000000000377777706676f6f676c6503636f6d0000010001c00c0005000100000005000803777777016cc010c02c0001000100000005000442f95b68c02c0001000100000005000442f95b63c02c0001000100000005000442f95b67c02c0001000100000005000442f95b93')
- >>> d = DNSRecord.parse(packet)
- >>> d
- <DNS Header: id=0xd5ad type=RESPONSE opcode=QUERY flags=RD,RA
rcode='NOERROR' q=1 a=5 ns=0 ar=0>
- <DNS Question: 'www.google.com.' qtype=A qclass=IN>
- <DNS RR: 'www.google.com.' rtype=CNAME rclass=IN ttl=5
rdata='www.l.google.com.'>
- <DNS RR: 'www.l.google.com.' rtype=A rclass=IN ttl=5
rdata='66.249.91.104'>
- <DNS RR: 'www.l.google.com.' rtype=A rclass=IN ttl=5
rdata='66.249.91.99'>
- <DNS RR: 'www.l.google.com.' rtype=A rclass=IN ttl=5
rdata='66.249.91.103'>
- <DNS RR: 'www.l.google.com.' rtype=A rclass=IN ttl=5
rdata='66.249.91.147'>
-
- The default text representation of the DNSRecord is in zone file
format:
-
- >>> print(d)
- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54701
- ;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 0
- ;; QUESTION SECTION:
- ;www.google.com. IN A
- ;; ANSWER SECTION:
- www.google.com. 5 IN CNAME www.l.google.com.
- www.l.google.com. 5 IN A 66.249.91.104
- www.l.google.com. 5 IN A 66.249.91.99
- www.l.google.com. 5 IN A 66.249.91.103
- www.l.google.com. 5 IN A 66.249.91.147
-
- To create a DNS Request Packet:
-
- >>> d = DNSRecord.question("google.com")
-
- (This is equivalent to: d = DNSRecord(q=DNSQuestion("google.com") )
-
- >>> d
- <DNS Header: id=... type=QUERY opcode=QUERY flags=RD
rcode='NOERROR' q=1 a=0 ns=0 ar=0>
- <DNS Question: 'google.com.' qtype=A qclass=IN>
-
- >>> str(DNSRecord.parse(d.pack())) == str(d)
- True
-
- >>> print(d)
- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
- ;; flags: rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
- ;; QUESTION SECTION:
- ;google.com. IN A
-
- >>> d = DNSRecord.question("google.com","MX")
-
- (This is equivalent to: d =
DNSRecord(q=DNSQuestion("google.com",QTYPE.MX) )
-
- >>> str(DNSRecord.parse(d.pack())) == str(d)
- True
-
- >>> print(d)
- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
- ;; flags: rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
- ;; QUESTION SECTION:
- ;google.com. IN MX
-
- To create a DNS Response Packet:
-
- >>> d = DNSRecord(DNSHeader(qr=1,aa=1,ra=1),
- ... q=DNSQuestion("abc.com"),
- ... a=RR("abc.com",rdata=A("1.2.3.4")))
- >>> d
- <DNS Header: id=... type=RESPONSE opcode=QUERY flags=AA,RD,RA
rcode='NOERROR' q=1 a=1 ns=0 ar=0>
- <DNS Question: 'abc.com.' qtype=A qclass=IN>
- <DNS RR: 'abc.com.' rtype=A rclass=IN ttl=0 rdata='1.2.3.4'>
- >>> str(DNSRecord.parse(d.pack())) == str(d)
- True
-
- >>> print(d)
- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
- ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0,
ADDITIONAL: 0
- ;; QUESTION SECTION:
- ;abc.com. IN A
- ;; ANSWER SECTION:
- abc.com. 0 IN A 1.2.3.4
-
- It is also possible to create RRs from a string in zone file format
-
- >>> RR.fromZone("abc.com IN A 1.2.3.4")
- [<DNS RR: 'abc.com.' rtype=A rclass=IN ttl=0 rdata='1.2.3.4'>]
-
- (Note: this produces a list of RRs which should be unpacked if
being
- passed to add_answer/add_auth/add_ar etc)
-
- >>> q = DNSRecord.question("abc.com")
- >>> a = q.reply()
- >>> a.add_answer(*RR.fromZone("abc.com 60 A 1.2.3.4"))
- >>> print(a)
- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
- ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0,
ADDITIONAL: 0
- ;; QUESTION SECTION:
- ;abc.com. IN A
- ;; ANSWER SECTION:
- abc.com. 60 IN A 1.2.3.4
-
- The zone file can contain multiple entries and supports most of the
normal
- format defined in RFC1035 (specifically not $INCLUDE)
-
- >>> z = '''
- ... $TTL 300
- ... $ORIGIN abc.com
- ...
- ... @ IN MX 10 mail.abc.com.
- ... www IN A 1.2.3.4
- ... IN TXT "Some Text"
- ... mail IN CNAME www.abc.com.
- ... '''
- >>> for rr in RR.fromZone(textwrap.dedent(z)):
- ... print(rr)
- abc.com. 300 IN MX 10 mail.abc.com.
- www.abc.com. 300 IN A 1.2.3.4
- www.abc.com. 300 IN TXT "Some Text"
- mail.abc.com. 300 IN CNAME www.abc.com.
-
- To create a skeleton reply to a DNS query:
-
- >>> q = DNSRecord(q=DNSQuestion("abc.com",QTYPE.ANY))
- >>> a = q.reply()
- >>> a.add_answer(RR("abc.com",QTYPE.A,rdata=A("1.2.3.4"),ttl=60))
- >>> str(DNSRecord.parse(a.pack())) == str(a)
- True
- >>> print(a)
- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
- ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0,
ADDITIONAL: 0
- ;; QUESTION SECTION:
- ;abc.com. IN ANY
- ;; ANSWER SECTION:
- abc.com. 60 IN A 1.2.3.4
-
- Add additional RRs:
-
- >>> a.add_answer(RR("xxx.abc.com",QTYPE.A,rdata=A("1.2.3.4")))
- >>>
a.add_answer(RR("xxx.abc.com",QTYPE.AAAA,rdata=AAAA("1234:5678::1")))
- >>> str(DNSRecord.parse(a.pack())) == str(a)
- True
- >>> print(a)
- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
- ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0,
ADDITIONAL: 0
- ;; QUESTION SECTION:
- ;abc.com. IN ANY
- ;; ANSWER SECTION:
- abc.com. 60 IN A 1.2.3.4
- xxx.abc.com. 0 IN A 1.2.3.4
- xxx.abc.com. 0 IN AAAA 1234:5678::1
-
-
- It is also possible to create a reply from a string in zone file
format:
-
- >>> q = DNSRecord(q=DNSQuestion("abc.com",QTYPE.ANY))
- >>> a = q.replyZone("abc.com 60 IN CNAME xxx.abc.com")
- >>> print(a)
- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
- ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0,
ADDITIONAL: 0
- ;; QUESTION SECTION:
- ;abc.com. IN ANY
- ;; ANSWER SECTION:
- abc.com. 60 IN CNAME xxx.abc.com.
-
- >>> str(DNSRecord.parse(a.pack())) == str(a)
- True
-
- >>> q = DNSRecord(q=DNSQuestion("abc.com",QTYPE.ANY))
- >>> a = q.replyZone(textwrap.dedent(z))
- >>> print(a)
- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
- ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0,
ADDITIONAL: 0
- ;; QUESTION SECTION:
- ;abc.com. IN ANY
- ;; ANSWER SECTION:
- abc.com. 300 IN MX 10 mail.abc.com.
- www.abc.com. 300 IN A 1.2.3.4
- www.abc.com. 300 IN TXT "Some Text"
- mail.abc.com. 300 IN CNAME www.abc.com.
-
- To send a DNSSEC request (EDNS OPT record with DO flag & header AD
flag):
-
- >>> q = DNSRecord(q=DNSQuestion("abc.com",QTYPE.A))
- >>> q.add_ar(EDNS0(flags="do",udp_len=4096))
- >>> q.header.ad = 1
- >>> print(q)
- ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
- ;; flags: rd ad; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
- ;; QUESTION SECTION:
- ;abc.com. IN A
- ;; ADDITIONAL SECTION:
- ;; OPT PSEUDOSECTION
- ; EDNS: version: 0, flags: do; udp: 4096
-
- The library also includes a simple framework for generating custom DNS
- resolvers in dnslib.server (see module docs). In most cases this just
- requires implementing a custom 'resolve' method which receives a
question
- object and returns a response.
-
- A number of sample resolvers are provided as examples (see CLI --help):
-
- * dnslib.fixedresolver - Respond to all requests with fixed
response
- * dnslib.zoneresolver - Respond from Zone file
- * dnslib.shellresolver - Call shell script to generate response
-
- The library includes a number of client utilities:
-
- * DiG like client library
-
- # python -m dnslib.client --help
-
- * DNS Proxy Server
-
- # python -m dnslib.proxy --help
-
- * Intercepting DNS Proxy Server (replace proxy responses for
specified domains)
-
- # python -m dnslib.intercept --help
-
-
- Changelog:
- ----------
-
- * 0.1 2010-09-19 Initial Release
- * 0.2 2010-09-22 Minor fixes
- * 0.3 2010-10-02 Add DNSLabel class to support arbitrary
labels (embedded '.')
- * 0.4 2012-02-26 Merge with dbslib-circuits
- * 0.5 2012-09-13 Add support for RFC2136 DDNS updates
- Patch provided by Wesley Shields
<w...@freebsd.org> - thanks
- * 0.6 2012-10-20 Basic AAAA support
- * 0.7 2012-10-20 Add initial EDNS0 support (untested)
- * 0.8 2012-11-04 Add support for NAPTR, Authority RR and
additional RR
- Patch provided by Stefan Andersson
(https://bitbucket.org/norox) - thanks
- * 0.8.1 2012-11-05 Added NAPTR test case and fixed logic error
- Patch provided by Stefan Andersson
(https://bitbucket.org/norox) - thanks
- * 0.8.2 2012-11-11 Patch to fix IPv6 formatting
- Patch provided by Torbjorn Lonnemark
(https://bitbucket.org/tobbezz) - thanks
- * 0.8.3 2013-04-27 Don't parse rdata if rdlength is 0
- Patch provided by Wesley Shields
<w...@freebsd.org> - thanks
- * 0.9.0 2014-05-05 Major update including Py3 support (see docs)
- * 0.9.1 2014-05-05 Minor fixes
- * 0.9.2 2014-08-26 Fix Bimap handling of unknown mappings to
avoid exception in printing
- Add typed attributes to classes
- Misc fixes from James Mills - thanks
- * 0.9.3 2014-08-26 Workaround for argparse bug which raises
AssertionError if [] is
- present in option text (really?)
- * 0.9.4 2015-04-10 Fix to support multiple strings in TXT record
- Patch provided by James Cherry
(https://bitbucket.org/james_cherry) - thanks
- NOTE: For consistency this patch changes the
'repr' output for
- TXT records to always be quoted
- * 0.9.5 2015-10-27 Add threading & timeout handling to DNSServer
- * 0.9.6 2015-10-28 Replace strftime in RRSIG formatting to avoid
possible locale issues
- Identified by Bryan Everly - thanks
- * 0.9.7 2017-01-15 Sort out CAA/TYPE257 DiG parsing mismatch
- * 0.9.8 2019-02-25 Force DNSKEY key to be bytes object
- Catch Bimap __wrapped__ attr (used by inspect
module in 3.7)
- * 0.9.9 2019-03-19 Add support for DNSSEC flag getters/setters
(from <r...@dinosec.com> - thanks)
- Added --dnssec flags to dnslib.client &
dnslib.test_decode (sets EDNS0 DO flag)
- Added EDNS0 support to dnslib.digparser
- * 0.9.10 2019-03-24 Fixes to DNSSEC support
- Add NSEC RR support
- Add --dnssec flag to dnslib.client &
dnslib.test_decode
- Quote/unquote non-printable characters in DNS
labels
- Update test data
- (Thanks to <r...@dinosec.com> for help)
- * 0.9.11 2019-12-17 Encode NOTIFY Opcode (Issue #26)
- * 0.9.12 2019-12-17 Transition master repository to Github
(Bitbucket shutting down hg)
- * 0.9.13 2020-06-01 Handle truncated requests in server.py (Issue
#9)
- Replace thred.isAlive with thread.is_alive
(Deprecated in Py3.9)
- Merged Pull Request #4 (Extra options for
intercept.py) - thanks to @nolanl
- * 0.9.14 2020-06-09 Merged Pull Request #10 (Return doctest
status via exit code)
- Thanks to @mgorny
- * 0.9.15 2021-05-07 DNSServer fixes - support IPv6 (from Pull
Request #21) - thanks to @mikma
- - deamon threads (Pull
Request #19) - thanks to @wojons
- Add unsupported RR types (Issue #27)
- * 0.9.16 2021-05-07 Merge pull request #23 from Tugzrida/patch-1
- Add support for all RR types to NSEC type
bitmap
- Merge pull request #17 from sunds/issue_16
- Issue 16: uncaught exceptions leak open
sockets
-
- License:
- --------
-
- BSD
-
- Author:
- -------
-
- * PaulC
-
- Master Repository/Issues:
- -------------------------
-
- * https://github.com/paulc/dnslib
-
- (Note: https://bitbucket.org/paulc/dnslib has been deprecated and
will not be updated)
-
Platform: UNKNOWN
Classifier: Topic :: Internet :: Name Service (DNS)
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 3
Description-Content-Type: text/markdown
+License-File: LICENSE
+
+
+
+## From Version 0.9.12 the master repository for _dnslib_ has been moved to
GitHub (https://github.com/paulc/dnslib). Please update any links to the
original BitBucket repository as this will no longer be maintained.
+
+
+dnslib
+------
+
+A library to encode/decode DNS wire-format packets supporting both
+Python 2.7 and Python 3.2+.
+
+The library provides:
+
+ * Support for encoding/decoding DNS packets between wire format,
+ python objects, and Zone/DiG textual representation (dnslib.dns)
+
+ * A server framework allowing the simple creation of custom DNS
+ resolvers (dnslib.server) and a number of example servers
+ created using this framework
+
+ * A number of utilities for testing (dnslib.client, dnslib.proxy,
+ dnslib.intercept)
+
+Python 3 support was added in Version 0.9.0 which represented a fairly
+major update to the library - the key changes include:
+
+ * Python 2.7/3.2+ support (the last version supporting Python 2.6
+ or earlier was version 0.8.3)
+
+ * The 'Bimap' interface was changed significantly to explicitly
+ split forward (value->text) lookups via __getitem__ and
+ reverse (text->value) lookups via __getattr__. Applications
+ using the old interface will need to be updated.
+
+ * Hostnames are now returned with a trailing dot by default (in
+ line with RFC)
+
+ * Most object attributes are now typed in line with the record
+ definitions to make it harder to generate invalid packets
+
+ * Support for encoding/decoding resource records in 'Zone' (BIND)
+ file format
+
+ * Support for encoding/decoding packets in 'DiG' format
+
+ * Server framework allowing (in most cases) custom resolvers to
+ be created by just subclassing the DNSResolver class and
+ overriding the 'resolve' method
+
+ * A lot of fixes to error detection/handling which should make
+ the library much more robust to invalid/unsupported data. The
+ library should now either return a valid DNSRecord instance
+ when parsing a packet or raise DNSError (tested via fuzzing)
+
+ * Improved utilities (dnslib.client, dnslib.proxy, dnslib.intercept)
+
+ * Improvements to encoding/decoding tests including the ability
+ to generate test data automatically in test_decode.py (comparing
+ outputs against DiG)
+
+ * Ability to compare and diff DNSRecords
+
+Classes
+-------
+
+The key DNS packet handling classes are in dnslib.dns and map to the
+standard DNS packet sections:
+
+ * DNSRecord - container for DNS packet. Contains:
+ - DNSHeader
+ - Question section containing zero or more DNSQuestion objects
+ - Answer section containing zero or more RR objects
+ - Authority section containing zero or more RR objects
+ - Additional section containing zero or more RR objects
+ * DNS RRs (resource records) contain an RR header and an RD object)
+ * Specific RD types are implemented as subclasses of RD
+ * DNS labels are represented by a DNSLabel class - in most cases
+ this handles conversion to/from textual representation however
+ does support arbitatry labels via a tuple of bytes objects
+
+Usage
+-----
+
+To decode a DNS packet:
+
+ >>> packet =
binascii.unhexlify(b'd5ad818000010005000000000377777706676f6f676c6503636f6d0000010001c00c0005000100000005000803777777016cc010c02c0001000100000005000442f95b68c02c0001000100000005000442f95b63c02c0001000100000005000442f95b67c02c0001000100000005000442f95b93')
+ >>> d = DNSRecord.parse(packet)
+ >>> d
+ <DNS Header: id=0xd5ad type=RESPONSE opcode=QUERY flags=RD,RA
rcode='NOERROR' q=1 a=5 ns=0 ar=0>
+ <DNS Question: 'www.google.com.' qtype=A qclass=IN>
+ <DNS RR: 'www.google.com.' rtype=CNAME rclass=IN ttl=5
rdata='www.l.google.com.'>
+ <DNS RR: 'www.l.google.com.' rtype=A rclass=IN ttl=5 rdata='66.249.91.104'>
+ <DNS RR: 'www.l.google.com.' rtype=A rclass=IN ttl=5 rdata='66.249.91.99'>
+ <DNS RR: 'www.l.google.com.' rtype=A rclass=IN ttl=5 rdata='66.249.91.103'>
+ <DNS RR: 'www.l.google.com.' rtype=A rclass=IN ttl=5 rdata='66.249.91.147'>
+
+The default text representation of the DNSRecord is in zone file format:
+
+ >>> print(d)
+ ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54701
+ ;; flags: qr rd ra; QUERY: 1, ANSWER: 5, AUTHORITY: 0, ADDITIONAL: 0
+ ;; QUESTION SECTION:
+ ;www.google.com. IN A
+ ;; ANSWER SECTION:
+ www.google.com. 5 IN CNAME www.l.google.com.
+ www.l.google.com. 5 IN A 66.249.91.104
+ www.l.google.com. 5 IN A 66.249.91.99
+ www.l.google.com. 5 IN A 66.249.91.103
+ www.l.google.com. 5 IN A 66.249.91.147
+
+To create a DNS Request Packet:
+
+ >>> d = DNSRecord.question("google.com")
+
+(This is equivalent to: d = DNSRecord(q=DNSQuestion("google.com") )
+
+ >>> d
+ <DNS Header: id=... type=QUERY opcode=QUERY flags=RD rcode='NOERROR' q=1
a=0 ns=0 ar=0>
+ <DNS Question: 'google.com.' qtype=A qclass=IN>
+
+ >>> str(DNSRecord.parse(d.pack())) == str(d)
+ True
+
+ >>> print(d)
+ ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
+ ;; flags: rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
+ ;; QUESTION SECTION:
+ ;google.com. IN A
+
+ >>> d = DNSRecord.question("google.com","MX")
+
+(This is equivalent to: d = DNSRecord(q=DNSQuestion("google.com",QTYPE.MX) )
+
+ >>> str(DNSRecord.parse(d.pack())) == str(d)
+ True
+
+ >>> print(d)
+ ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
+ ;; flags: rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
+ ;; QUESTION SECTION:
+ ;google.com. IN MX
+
+To create a DNS Response Packet:
+
+ >>> d = DNSRecord(DNSHeader(qr=1,aa=1,ra=1),
+ ... q=DNSQuestion("abc.com"),
+ ... a=RR("abc.com",rdata=A("1.2.3.4")))
+ >>> d
+ <DNS Header: id=... type=RESPONSE opcode=QUERY flags=AA,RD,RA
rcode='NOERROR' q=1 a=1 ns=0 ar=0>
+ <DNS Question: 'abc.com.' qtype=A qclass=IN>
+ <DNS RR: 'abc.com.' rtype=A rclass=IN ttl=0 rdata='1.2.3.4'>
+ >>> str(DNSRecord.parse(d.pack())) == str(d)
+ True
+
+ >>> print(d)
+ ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
+ ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
+ ;; QUESTION SECTION:
+ ;abc.com. IN A
+ ;; ANSWER SECTION:
+ abc.com. 0 IN A 1.2.3.4
+
+It is also possible to create RRs from a string in zone file format
+
+ >>> RR.fromZone("abc.com IN A 1.2.3.4")
+ [<DNS RR: 'abc.com.' rtype=A rclass=IN ttl=0 rdata='1.2.3.4'>]
+
+ (Note: this produces a list of RRs which should be unpacked if being
+ passed to add_answer/add_auth/add_ar etc)
+
+ >>> q = DNSRecord.question("abc.com")
+ >>> a = q.reply()
+ >>> a.add_answer(*RR.fromZone("abc.com 60 A 1.2.3.4"))
+ >>> print(a)
+ ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
+ ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
+ ;; QUESTION SECTION:
+ ;abc.com. IN A
+ ;; ANSWER SECTION:
+ abc.com. 60 IN A 1.2.3.4
+
+The zone file can contain multiple entries and supports most of the normal
+format defined in RFC1035 (specifically not $INCLUDE)
+
+ >>> z = '''
+ ... $TTL 300
+ ... $ORIGIN abc.com
+ ...
+ ... @ IN MX 10 mail.abc.com.
+ ... www IN A 1.2.3.4
+ ... IN TXT "Some Text"
+ ... mail IN CNAME www.abc.com.
+ ... '''
+ >>> for rr in RR.fromZone(textwrap.dedent(z)):
+ ... print(rr)
+ abc.com. 300 IN MX 10 mail.abc.com.
+ www.abc.com. 300 IN A 1.2.3.4
+ www.abc.com. 300 IN TXT "Some Text"
+ mail.abc.com. 300 IN CNAME www.abc.com.
+
+To create a skeleton reply to a DNS query:
+
+ >>> q = DNSRecord(q=DNSQuestion("abc.com",QTYPE.ANY))
+ >>> a = q.reply()
+ >>> a.add_answer(RR("abc.com",QTYPE.A,rdata=A("1.2.3.4"),ttl=60))
+ >>> str(DNSRecord.parse(a.pack())) == str(a)
+ True
+ >>> print(a)
+ ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
+ ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
+ ;; QUESTION SECTION:
+ ;abc.com. IN ANY
+ ;; ANSWER SECTION:
+ abc.com. 60 IN A 1.2.3.4
+
+Add additional RRs:
+
+ >>> a.add_answer(RR("xxx.abc.com",QTYPE.A,rdata=A("1.2.3.4")))
+ >>> a.add_answer(RR("xxx.abc.com",QTYPE.AAAA,rdata=AAAA("1234:5678::1")))
+ >>> str(DNSRecord.parse(a.pack())) == str(a)
+ True
+ >>> print(a)
+ ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
+ ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0
+ ;; QUESTION SECTION:
+ ;abc.com. IN ANY
+ ;; ANSWER SECTION:
+ abc.com. 60 IN A 1.2.3.4
+ xxx.abc.com. 0 IN A 1.2.3.4
+ xxx.abc.com. 0 IN AAAA 1234:5678::1
+
+
+It is also possible to create a reply from a string in zone file format:
+
+ >>> q = DNSRecord(q=DNSQuestion("abc.com",QTYPE.ANY))
+ >>> a = q.replyZone("abc.com 60 IN CNAME xxx.abc.com")
+ >>> print(a)
+ ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
+ ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
+ ;; QUESTION SECTION:
+ ;abc.com. IN ANY
+ ;; ANSWER SECTION:
+ abc.com. 60 IN CNAME xxx.abc.com.
+
+ >>> str(DNSRecord.parse(a.pack())) == str(a)
+ True
+
+ >>> q = DNSRecord(q=DNSQuestion("abc.com",QTYPE.ANY))
+ >>> a = q.replyZone(textwrap.dedent(z))
+ >>> print(a)
+ ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
+ ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 0
+ ;; QUESTION SECTION:
+ ;abc.com. IN ANY
+ ;; ANSWER SECTION:
+ abc.com. 300 IN MX 10 mail.abc.com.
+ www.abc.com. 300 IN A 1.2.3.4
+ www.abc.com. 300 IN TXT "Some Text"
+ mail.abc.com. 300 IN CNAME www.abc.com.
+
+To send a DNSSEC request (EDNS OPT record with DO flag & header AD flag):
+
+ >>> q = DNSRecord(q=DNSQuestion("abc.com",QTYPE.A))
+ >>> q.add_ar(EDNS0(flags="do",udp_len=4096))
+ >>> q.header.ad = 1
+ >>> print(q)
+ ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: ...
+ ;; flags: rd ad; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
+ ;; QUESTION SECTION:
+ ;abc.com. IN A
+ ;; ADDITIONAL SECTION:
+ ;; OPT PSEUDOSECTION
+ ; EDNS: version: 0, flags: do; udp: 4096
+
+Note that when using the library you should always validate the received TXID
+
+ q = DNSRecord.question("abc.com")
+ a_pkt = q.send(address,port,tcp=args.tcp)
+ a = DNSRecord.parse(a_pkt)
+ if q.header.id != a.header.id:
+ raise DNSError('Response transaction id does not match query
transaction id')
+
+The library also includes a simple framework for generating custom DNS
+resolvers in dnslib.server (see module docs). In most cases this just
+requires implementing a custom 'resolve' method which receives a question
+object and returns a response.
+
+A number of sample resolvers are provided as examples (see CLI --help):
+
+ * dnslib.fixedresolver - Respond to all requests with fixed response
+ * dnslib.zoneresolver - Respond from Zone file
+ * dnslib.shellresolver - Call shell script to generate response
+
+The library includes a number of client utilities:
+
+ * DiG like client library
+
+ # python -m dnslib.client --help
+
+ * DNS Proxy Server
+
+ # python -m dnslib.proxy --help
+
+ * Intercepting DNS Proxy Server (replace proxy responses for specified
domains)
+
+ # python -m dnslib.intercept --help
+
+
+Changelog:
+----------
+
+ * 0.1 2010-09-19 Initial Release
+ * 0.2 2010-09-22 Minor fixes
+ * 0.3 2010-10-02 Add DNSLabel class to support arbitrary labels
(embedded '.')
+ * 0.4 2012-02-26 Merge with dbslib-circuits
+ * 0.5 2012-09-13 Add support for RFC2136 DDNS updates
+ Patch provided by Wesley Shields <w...@freebsd.org> -
thanks
+ * 0.6 2012-10-20 Basic AAAA support
+ * 0.7 2012-10-20 Add initial EDNS0 support (untested)
+ * 0.8 2012-11-04 Add support for NAPTR, Authority RR and additional RR
+ Patch provided by Stefan Andersson
(https://bitbucket.org/norox) - thanks
+ * 0.8.1 2012-11-05 Added NAPTR test case and fixed logic error
+ Patch provided by Stefan Andersson
(https://bitbucket.org/norox) - thanks
+ * 0.8.2 2012-11-11 Patch to fix IPv6 formatting
+ Patch provided by Torbjorn Lonnemark
(https://bitbucket.org/tobbezz) - thanks
+ * 0.8.3 2013-04-27 Don't parse rdata if rdlength is 0
+ Patch provided by Wesley Shields <w...@freebsd.org> -
thanks
+ * 0.9.0 2014-05-05 Major update including Py3 support (see docs)
+ * 0.9.1 2014-05-05 Minor fixes
+ * 0.9.2 2014-08-26 Fix Bimap handling of unknown mappings to avoid
exception in printing
+ Add typed attributes to classes
+ Misc fixes from James Mills - thanks
+ * 0.9.3 2014-08-26 Workaround for argparse bug which raises
AssertionError if [] is
+ present in option text (really?)
+ * 0.9.4 2015-04-10 Fix to support multiple strings in TXT record
+ Patch provided by James Cherry
(https://bitbucket.org/james_cherry) - thanks
+ NOTE: For consistency this patch changes the 'repr'
output for
+ TXT records to always be quoted
+ * 0.9.5 2015-10-27 Add threading & timeout handling to DNSServer
+ * 0.9.6 2015-10-28 Replace strftime in RRSIG formatting to avoid
possible locale issues
+ Identified by Bryan Everly - thanks
+ * 0.9.7 2017-01-15 Sort out CAA/TYPE257 DiG parsing mismatch
+ * 0.9.8 2019-02-25 Force DNSKEY key to be bytes object
+ Catch Bimap __wrapped__ attr (used by inspect module
in 3.7)
+ * 0.9.9 2019-03-19 Add support for DNSSEC flag getters/setters (from
<r...@dinosec.com> - thanks)
+ Added --dnssec flags to dnslib.client &
dnslib.test_decode (sets EDNS0 DO flag)
+ Added EDNS0 support to dnslib.digparser
+ * 0.9.10 2019-03-24 Fixes to DNSSEC support
+ Add NSEC RR support
+ Add --dnssec flag to dnslib.client &
dnslib.test_decode
+ Quote/unquote non-printable characters in DNS labels
+ Update test data
+ (Thanks to <r...@dinosec.com> for help)
+ * 0.9.11 2019-12-17 Encode NOTIFY Opcode (Issue #26)
+ * 0.9.12 2019-12-17 Transition master repository to Github (Bitbucket
shutting down hg)
+ * 0.9.13 2020-06-01 Handle truncated requests in server.py (Issue #9)
+ Replace thred.isAlive with thread.is_alive
(Deprecated in Py3.9)
+ Merged Pull Request #4 (Extra options for
intercept.py) - thanks to @nolanl
+ * 0.9.14 2020-06-09 Merged Pull Request #10 (Return doctest status via
exit code)
+ Thanks to @mgorny
+ * 0.9.15 2021-05-07 DNSServer fixes - support IPv6 (from Pull Request
#21) - thanks to @mikma
+ - deamon threads (Pull Request #19) -
thanks to @wojons
+ Add unsupported RR types (Issue #27)
+ * 0.9.16 2021-05-07 Merge pull request #23 from Tugzrida/patch-1
+ Add support for all RR types to NSEC type bitmap
+ Merge pull request #17 from sunds/issue_16
+ Issue 16: uncaught exceptions leak open sockets
+ * 0.9.18 2022-01-09 Validate TXID in client.py (Issue #30 - thanks to
@daniel4x)
+
+
+License:
+--------
+
+BSD
+
+Author:
+-------
+
+ * PaulC
+
+Master Repository/Issues:
+-------------------------
+
+ * https://github.com/paulc/dnslib
+
+ (Note: https://bitbucket.org/paulc/dnslib has been deprecated and will not be
updated)
+
+
diff -Nru python-dnslib-0.9.16/README python-dnslib-0.9.18/README
--- python-dnslib-0.9.16/README 2021-05-07 12:08:47.000000000 -0400
+++ python-dnslib-0.9.18/README 2022-01-09 18:17:21.000000000 -0500
@@ -272,6 +272,14 @@
;; OPT PSEUDOSECTION
; EDNS: version: 0, flags: do; udp: 4096
+Note that when using the library you should always validate the received TXID
+
+ q = DNSRecord.question("abc.com")
+ a_pkt = q.send(address,port,tcp=args.tcp)
+ a = DNSRecord.parse(a_pkt)
+ if q.header.id != a.header.id:
+ raise DNSError('Response transaction id does not match query
transaction id')
+
The library also includes a simple framework for generating custom DNS
resolvers in dnslib.server (see module docs). In most cases this just
requires implementing a custom 'resolve' method which receives a question
@@ -357,6 +365,8 @@
Add support for all RR types to NSEC type bitmap
Merge pull request #17 from sunds/issue_16
Issue 16: uncaught exceptions leak open sockets
+ * 0.9.18 2022-01-09 Validate TXID in client.py (Issue #30 - thanks to
@daniel4x)
+
License:
--------
--- End Message ---