dnspython 2.9.0__tar.gz → 2.9.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dnspython-2.9.2/LICENSE +35 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/PKG-INFO +4 -2
- {dnspython-2.9.0 → dnspython-2.9.2}/README.md +1 -1
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/asyncquery.py +10 -6
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/asyncresolver.py +1 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/btreezone.py +53 -30
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/dnssec.py +11 -9
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/dnssecalgs/cryptography.py +3 -3
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/dnssecalgs/dsa.py +6 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/dnssecalgs/ecdsa.py +5 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/dnssecalgs/eddsa.py +1 -1
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/dnssecalgs/mldsa.py +1 -1
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/edns.py +21 -5
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/entropy.py +19 -3
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/message.py +72 -9
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/name.py +59 -9
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/namedict.py +2 -1
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/query.py +9 -5
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdata.py +6 -3
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/AFSDB.py +2 -2
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/CAA.py +1 -1
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/CERT.py +1 -1
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/HIP.py +1 -1
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/KEY.py +1 -1
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/LOC.py +7 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/NSEC3.py +23 -6
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/OPENPGPKEY.py +1 -1
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/RP.py +2 -2
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/RT.py +1 -1
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/SIG.py +7 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/SOA.py +2 -2
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/SSHFP.py +10 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/TKEY.py +3 -3
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/TSIG.py +4 -3
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/IN/APL.py +2 -1
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/IN/DHCID.py +1 -1
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/IN/IPSECKEY.py +1 -1
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/IN/NAPTR.py +1 -1
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/IN/PX.py +2 -2
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/IN/SRV.py +1 -1
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/IN/WKS.py +7 -2
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/base64base.py +1 -1
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/dnskeybase.py +1 -1
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/mxbase.py +31 -2
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/nsbase.py +8 -3
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/rrsigbase.py +11 -5
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/svcbbase.py +7 -7
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/tlsabase.py +13 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/util.py +7 -4
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/renderer.py +2 -2
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/resolver.py +1 -3
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/reversename.py +2 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/set.py +4 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/tokenizer.py +14 -1
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/ttl.py +1 -1
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/version.py +1 -1
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/versioned.py +4 -3
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/wire.py +4 -2
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/wirebase.py +7 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/zone.py +16 -3
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/zonefile.py +80 -74
- {dnspython-2.9.0 → dnspython-2.9.2}/pyproject.toml +4 -2
- {dnspython-2.9.0 → dnspython-2.9.2}/pyproject.toml.orig +4 -2
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_btreezone.py +20 -0
- dnspython-2.9.2/tests/test_btreezone_delegations.py +217 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_bugs.py +46 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_dnssec.py +69 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_dnssecalgs.py +41 -0
- dnspython-2.9.2/tests/test_doq.py +142 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_edns.py +18 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_entropy.py +9 -4
- dnspython-2.9.2/tests/test_gateway_text.py +38 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_generate.py +63 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_message.py +75 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_name.py +47 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_namedict.py +20 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_nsec3.py +35 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_query.py +3 -3
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_rdata.py +222 -1
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_renderer.py +9 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_resolver.py +56 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_reversename.py +37 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_set.py +33 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_tokenizer.py +29 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_transaction.py +64 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_tsig.py +41 -0
- dnspython-2.9.2/tests/test_tsig_doh_doq.py +144 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_ttl.py +5 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_wire.py +61 -2
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_xfr.py +195 -26
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_zone.py +40 -0
- dnspython-2.9.0/tests/test_doq.py +0 -76
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/__init__.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/_asyncbackend.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/_asyncio_backend.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/_ddr.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/_features.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/_file_util.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/_immutable_ctx.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/_no_ssl.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/_render_util.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/_text_util.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/_tls_util.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/_trio_backend.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/asyncbackend.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/btree.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/dnssecalgs/__init__.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/dnssecalgs/base.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/dnssecalgs/rsa.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/dnssectypes.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/e164.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/enum.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/exception.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/flags.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/grange.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/immutable.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/inet.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/ipv4.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/ipv6.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/nameserver.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/node.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/opcode.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/py.typed +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/quic/__init__.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/quic/_asyncio.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/quic/_common.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/quic/_sync.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/quic/_trio.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rcode.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdataclass.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdataset.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdatatype.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/AMTRELAY.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/AVC.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/BRID.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/CDNSKEY.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/CDS.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/CNAME.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/CSYNC.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/DLV.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/DNAME.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/DNSKEY.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/DS.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/DSYNC.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/EUI48.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/EUI64.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/GPOS.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/HHIT.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/HINFO.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/ISDN.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/L32.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/L64.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/LP.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/MX.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/NID.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/NINFO.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/NS.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/NSEC.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/NSEC3PARAM.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/OPT.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/PTR.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/RESINFO.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/RRSIG.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/SMIMEA.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/SPF.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/TLSA.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/TXT.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/URI.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/WALLET.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/X25.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/ZONEMD.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/ANY/__init__.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/CH/A.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/CH/__init__.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/IN/A.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/IN/AAAA.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/IN/HTTPS.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/IN/KX.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/IN/NSAP.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/IN/NSAP_PTR.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/IN/SVCB.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/IN/__init__.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/__init__.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/dsbase.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/euibase.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rdtypes/txtbase.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/rrset.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/serial.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/style.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/transaction.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/tsig.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/tsigkeyring.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/update.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/win32util.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/xfr.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/dns/zonetypes.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/examples/async_dns.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/examples/ddns_client.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/examples/ddns_server.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/examples/ddr.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/examples/doh-json.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/examples/doh.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/examples/doq.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/examples/dot.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/examples/e164.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/examples/ecs.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/examples/edns.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/examples/edns_resolver.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/examples/mx-typed.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/examples/mx.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/examples/name.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/examples/query_specific.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/examples/receive_notify.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/examples/reverse.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/examples/reverse_name.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/examples/send_notify.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/examples/server.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/examples/tsig.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/examples/wire_read_tcp.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/examples/xfr.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/examples/zonediff.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/__init__.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/doh.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/doq.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/example +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/example1.good +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/example2.good +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/example3.good +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/example4.good +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/keys.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/md_module.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/mx-2-0.pickle +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/nanonameserver.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/query +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/resolv.conf +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/stxt_module.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/svcb_test_vectors.generic +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/svcb_test_vectors.text +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_address.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_ascii_digits.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_async.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_btree.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_constants.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_ddr.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_doh.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_exceptions.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_features.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_flags.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_grange.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_immutable.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_nsec3_hash.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_ntoaaton.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_processing_order.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_rdataset.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_rdtypeandclass.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_rdtypeanydnskey.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_rdtypeanyeui.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_rdtypeanykey.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_rdtypeanyloc.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_rdtypeanytkey.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_resolution.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_resolver_override.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_rrset.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_rrset_reader.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_serial.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_svcb.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_tls_util.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_tsigkeyring.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_update.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/test_zonedigest.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/tls/ca.crt +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/tls/private.pem +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/tls/public.crt +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/tsigkeys/1.key +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/tsigkeys/2.key +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/tsigkeys/3.key +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/tsigkeys/4.key +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/tsigkeys/5.key +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/ttl_include.text +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/ttxt_module.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/utest.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/tests/util.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/util/constants-tool +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/util/generate-features +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/util/generate-mx-pickle.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/util/generate-rdatatype-doc.py +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/util/make-test-project +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/util/update-version +0 -0
- {dnspython-2.9.0 → dnspython-2.9.2}/util/uv-dev-setup +0 -0
dnspython-2.9.2/LICENSE
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (C) Dnspython Contributors
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for
|
|
6
|
+
any purpose with or without fee is hereby granted, provided that the
|
|
7
|
+
above copyright notice and this permission notice appear in all
|
|
8
|
+
copies.
|
|
9
|
+
|
|
10
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
|
11
|
+
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
|
12
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
|
13
|
+
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
|
14
|
+
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
|
15
|
+
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
|
16
|
+
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
17
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
Copyright (C) 2001-2017 Nominum, Inc.
|
|
22
|
+
Copyright (C) Google Inc.
|
|
23
|
+
|
|
24
|
+
Permission to use, copy, modify, and distribute this software and its
|
|
25
|
+
documentation for any purpose with or without fee is hereby granted,
|
|
26
|
+
provided that the above copyright notice and this permission notice
|
|
27
|
+
appear in all copies.
|
|
28
|
+
|
|
29
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
|
|
30
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
31
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
|
|
32
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
33
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
34
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
|
35
|
+
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dnspython
|
|
3
|
-
Version: 2.9.
|
|
3
|
+
Version: 2.9.2
|
|
4
4
|
Summary: DNS toolkit
|
|
5
5
|
Author: Bob Halley
|
|
6
6
|
Author-email: Bob Halley <halley@dnspython.org>
|
|
7
7
|
License-Expression: ISC
|
|
8
|
+
License-File: LICENSE
|
|
8
9
|
Classifier: Development Status :: 5 - Production/Stable
|
|
9
10
|
Classifier: Intended Audience :: Developers
|
|
10
11
|
Classifier: Intended Audience :: System Administrators
|
|
@@ -18,6 +19,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
18
19
|
Classifier: Programming Language :: Python :: 3.12
|
|
19
20
|
Classifier: Programming Language :: Python :: 3.13
|
|
20
21
|
Classifier: Programming Language :: Python :: 3.14
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
21
23
|
Requires-Dist: black>=26.5 ; extra == 'dev'
|
|
22
24
|
Requires-Dist: coverage>=7.15 ; extra == 'dev'
|
|
23
25
|
Requires-Dist: hypercorn>=0.18.0 ; extra == 'dev'
|
|
@@ -83,7 +85,7 @@ testing of DNS software.
|
|
|
83
85
|
|
|
84
86
|
## ABOUT THIS RELEASE
|
|
85
87
|
|
|
86
|
-
This is `dnspython` 2.9.
|
|
88
|
+
This is `dnspython` 2.9.2.
|
|
87
89
|
Please read
|
|
88
90
|
[What's New](https://dnspython.readthedocs.io/en/stable/whatsnew.html) for
|
|
89
91
|
information about the changes in this release.
|
|
@@ -698,7 +698,7 @@ async def https(
|
|
|
698
698
|
r = dns.message.from_wire(
|
|
699
699
|
response.content,
|
|
700
700
|
keyring=q.keyring,
|
|
701
|
-
request_mac=q.
|
|
701
|
+
request_mac=q.mac,
|
|
702
702
|
one_rr_per_rrset=one_rr_per_rrset,
|
|
703
703
|
ignore_trailing=ignore_trailing,
|
|
704
704
|
)
|
|
@@ -732,7 +732,7 @@ async def _http3(
|
|
|
732
732
|
if url_parts.port is not None:
|
|
733
733
|
port = url_parts.port
|
|
734
734
|
|
|
735
|
-
q.
|
|
735
|
+
q.set_id(0)
|
|
736
736
|
wire = q.to_wire()
|
|
737
737
|
the_connection: dns.quic.AsyncQuicConnection
|
|
738
738
|
if connection:
|
|
@@ -762,7 +762,7 @@ async def _http3(
|
|
|
762
762
|
r = dns.message.from_wire(
|
|
763
763
|
wire,
|
|
764
764
|
keyring=q.keyring,
|
|
765
|
-
request_mac=q.
|
|
765
|
+
request_mac=q.mac,
|
|
766
766
|
one_rr_per_rrset=one_rr_per_rrset,
|
|
767
767
|
ignore_trailing=ignore_trailing,
|
|
768
768
|
)
|
|
@@ -804,7 +804,7 @@ async def quic(
|
|
|
804
804
|
if server_hostname is not None and hostname is None:
|
|
805
805
|
hostname = server_hostname
|
|
806
806
|
|
|
807
|
-
q.
|
|
807
|
+
q.set_id(0)
|
|
808
808
|
wire = q.to_wire()
|
|
809
809
|
the_connection: dns.quic.AsyncQuicConnection
|
|
810
810
|
if connection:
|
|
@@ -818,7 +818,7 @@ async def quic(
|
|
|
818
818
|
async with mfactory(
|
|
819
819
|
context,
|
|
820
820
|
verify_mode=verify,
|
|
821
|
-
server_name=
|
|
821
|
+
server_name=hostname,
|
|
822
822
|
) as the_manager:
|
|
823
823
|
if not connection:
|
|
824
824
|
the_connection = the_manager.connect( # pyright: ignore
|
|
@@ -833,7 +833,7 @@ async def quic(
|
|
|
833
833
|
r = dns.message.from_wire(
|
|
834
834
|
wire,
|
|
835
835
|
keyring=q.keyring,
|
|
836
|
-
request_mac=q.
|
|
836
|
+
request_mac=q.mac,
|
|
837
837
|
one_rr_per_rrset=one_rr_per_rrset,
|
|
838
838
|
ignore_trailing=ignore_trailing,
|
|
839
839
|
)
|
|
@@ -869,6 +869,7 @@ async def _inbound_xfr(
|
|
|
869
869
|
txn_manager, rdtype, serial, is_udp, raise_on_serial_went_backwards
|
|
870
870
|
) as inbound:
|
|
871
871
|
done = False
|
|
872
|
+
first = True
|
|
872
873
|
tsig_ctx = None
|
|
873
874
|
while not done:
|
|
874
875
|
_, mexpiration = _compute_times(timeout)
|
|
@@ -893,6 +894,9 @@ async def _inbound_xfr(
|
|
|
893
894
|
multi=(not is_udp),
|
|
894
895
|
one_rr_per_rrset=is_ixfr,
|
|
895
896
|
)
|
|
897
|
+
if not query.is_response(r, xfr_continuation=not first):
|
|
898
|
+
raise BadResponse
|
|
899
|
+
first = False
|
|
896
900
|
done = inbound.process_message(r)
|
|
897
901
|
yield r
|
|
898
902
|
tsig_ctx = r.tsig_ctx
|
|
@@ -89,6 +89,7 @@ class Resolver(dns.resolver.BaseResolver):
|
|
|
89
89
|
nameserver, tcp, backoff = resolution.next_nameserver()
|
|
90
90
|
if backoff:
|
|
91
91
|
await backend.sleep(backoff)
|
|
92
|
+
request.set_random_id()
|
|
92
93
|
timeout = self._compute_timeout(start, lifetime, resolution.errors)
|
|
93
94
|
try:
|
|
94
95
|
response = await nameserver.async_query(
|
|
@@ -225,7 +225,7 @@ class WritableVersion(dns.zone.WritableVersion):
|
|
|
225
225
|
if self.zone.relativize:
|
|
226
226
|
return name == dns.name.empty
|
|
227
227
|
else:
|
|
228
|
-
return name == self.
|
|
228
|
+
return name == self.origin
|
|
229
229
|
|
|
230
230
|
def _maybe_cow_with_name(
|
|
231
231
|
self, name: dns.name.Name
|
|
@@ -236,20 +236,25 @@ class WritableVersion(dns.zone.WritableVersion):
|
|
|
236
236
|
node.flags |= NodeFlags.ORIGIN
|
|
237
237
|
elif self.delegations.is_glue(name):
|
|
238
238
|
node.flags |= NodeFlags.GLUE
|
|
239
|
+
elif name in self.delegations:
|
|
240
|
+
node.flags |= NodeFlags.DELEGATION
|
|
239
241
|
return (node, name)
|
|
240
242
|
|
|
241
243
|
def update_glue_flag(self, name: dns.name.Name, is_glue: bool) -> None:
|
|
242
|
-
"""
|
|
243
|
-
|
|
244
|
+
"""Update the delegation and glue flags on proper subdomains of *name*.
|
|
245
|
+
|
|
246
|
+
An added delegation obscures any descendant delegations. Removing
|
|
247
|
+
one exposes the first NS rdataset on each branch of its subtree.
|
|
244
248
|
|
|
245
249
|
:param name: The delegation-point name whose subtree should be updated.
|
|
246
250
|
:type name: :py:class:`dns.name.Name`
|
|
247
|
-
:param is_glue: ``True`` to
|
|
251
|
+
:param is_glue: ``True`` to obscure the subtree; ``False`` to expose it.
|
|
248
252
|
:type is_glue: bool
|
|
249
253
|
"""
|
|
250
254
|
cursor = self.nodes.cursor() # pyright: ignore
|
|
251
255
|
cursor.seek(name, False)
|
|
252
256
|
updates = []
|
|
257
|
+
cut = name if is_glue else None
|
|
253
258
|
while True:
|
|
254
259
|
elt = cursor.next()
|
|
255
260
|
if elt is None:
|
|
@@ -257,18 +262,27 @@ class WritableVersion(dns.zone.WritableVersion):
|
|
|
257
262
|
ename = elt.key()
|
|
258
263
|
if not ename.is_subdomain(name):
|
|
259
264
|
break
|
|
260
|
-
node =
|
|
265
|
+
node = elt.value()
|
|
266
|
+
self.delegations.discard(ename)
|
|
267
|
+
if cut is not None and not ename.is_subdomain(cut):
|
|
268
|
+
cut = None
|
|
269
|
+
if cut is not None:
|
|
270
|
+
flags = NodeFlags.GLUE
|
|
271
|
+
elif node.get_rdataset(self.zone.rdclass, dns.rdatatype.NS) is not None:
|
|
272
|
+
flags = NodeFlags.DELEGATION
|
|
273
|
+
cut = ename
|
|
274
|
+
self.delegations.add(ename)
|
|
275
|
+
else:
|
|
276
|
+
flags = NodeFlags(0)
|
|
277
|
+
if node.flags == flags:
|
|
278
|
+
continue
|
|
261
279
|
if ename not in self.changed:
|
|
262
|
-
new_node = self.zone.node_factory()
|
|
263
|
-
new_node.id = self.id
|
|
280
|
+
new_node = cast(Node, self.zone.node_factory())
|
|
281
|
+
new_node.id = self.id
|
|
264
282
|
new_node.rdatasets.extend(node.rdatasets)
|
|
265
283
|
self.changed.add(ename)
|
|
266
284
|
node = new_node
|
|
267
|
-
|
|
268
|
-
if is_glue:
|
|
269
|
-
node.flags |= NodeFlags.GLUE
|
|
270
|
-
else:
|
|
271
|
-
node.flags &= ~NodeFlags.GLUE
|
|
285
|
+
node.flags = flags
|
|
272
286
|
# We don't update node here as any insertion could disturb the
|
|
273
287
|
# btree and invalidate our cursor. We could use the cursor in a
|
|
274
288
|
# with block and avoid this, but it would do a lot of parking and
|
|
@@ -277,12 +291,28 @@ class WritableVersion(dns.zone.WritableVersion):
|
|
|
277
291
|
for ename, node in updates:
|
|
278
292
|
self.nodes[ename] = node
|
|
279
293
|
|
|
294
|
+
def _update_delegation(self, name: dns.name.Name, node: Node) -> None:
|
|
295
|
+
is_delegation = (
|
|
296
|
+
not node.is_origin_or_glue()
|
|
297
|
+
and node.get_rdataset(self.zone.rdclass, dns.rdatatype.NS) is not None
|
|
298
|
+
)
|
|
299
|
+
if is_delegation:
|
|
300
|
+
node.flags |= NodeFlags.DELEGATION
|
|
301
|
+
if name not in self.delegations:
|
|
302
|
+
self.delegations.add(name)
|
|
303
|
+
self.update_glue_flag(name, True)
|
|
304
|
+
elif name in self.delegations:
|
|
305
|
+
node.flags &= ~NodeFlags.DELEGATION
|
|
306
|
+
self.delegations.discard(name)
|
|
307
|
+
self.update_glue_flag(name, False)
|
|
308
|
+
|
|
280
309
|
def delete_node(self, name: dns.name.Name) -> None:
|
|
281
310
|
"""Delete the node at *name*, updating delegation tracking as needed.
|
|
282
311
|
|
|
283
312
|
If *name* is a delegation point, it is removed from the delegations
|
|
284
|
-
index and
|
|
285
|
-
|
|
313
|
+
index and any exposed descendant NS nodes become delegation points.
|
|
314
|
+
Nodes beneath those delegations remain glue. If *name* does not
|
|
315
|
+
exist in the zone, this method is a no-op.
|
|
286
316
|
|
|
287
317
|
:param name: The name of the node to delete.
|
|
288
318
|
:type name: :py:class:`dns.name.Name`
|
|
@@ -290,7 +320,7 @@ class WritableVersion(dns.zone.WritableVersion):
|
|
|
290
320
|
name = self._validate_name(name)
|
|
291
321
|
node = self.nodes.get(name)
|
|
292
322
|
if node is not None:
|
|
293
|
-
if
|
|
323
|
+
if name in self.delegations:
|
|
294
324
|
self.delegations.discard(name)
|
|
295
325
|
self.update_glue_flag(name, False)
|
|
296
326
|
del self.nodes[name]
|
|
@@ -303,7 +333,9 @@ class WritableVersion(dns.zone.WritableVersion):
|
|
|
303
333
|
|
|
304
334
|
If *rdataset* is an NS rdataset and *name* is not the origin or beneath
|
|
305
335
|
an existing delegation, the ``DELEGATION`` flag is set on the node and
|
|
306
|
-
the ``GLUE`` flag is set on all nodes in *name*'s subtree
|
|
336
|
+
the ``GLUE`` flag is set on all nodes in *name*'s subtree, obscuring
|
|
337
|
+
any descendant delegations. Replacing an NS rdataset with a CNAME
|
|
338
|
+
removes the delegation and exposes descendant delegations.
|
|
307
339
|
|
|
308
340
|
:param name: The owner name.
|
|
309
341
|
:type name: :py:class:`dns.name.Name`
|
|
@@ -311,15 +343,8 @@ class WritableVersion(dns.zone.WritableVersion):
|
|
|
311
343
|
:type rdataset: :py:class:`dns.rdataset.Rdataset`
|
|
312
344
|
"""
|
|
313
345
|
node, name = self._maybe_cow_with_name(name)
|
|
314
|
-
if (
|
|
315
|
-
rdataset.rdtype == dns.rdatatype.NS
|
|
316
|
-
and not node.is_origin_or_glue() # type: ignore
|
|
317
|
-
):
|
|
318
|
-
node.flags |= NodeFlags.DELEGATION # type: ignore
|
|
319
|
-
if name not in self.delegations:
|
|
320
|
-
self.delegations.add(name)
|
|
321
|
-
self.update_glue_flag(name, True)
|
|
322
346
|
node.replace_rdataset(rdataset)
|
|
347
|
+
self._update_delegation(name, cast(Node, node))
|
|
323
348
|
|
|
324
349
|
def delete_rdataset(
|
|
325
350
|
self,
|
|
@@ -330,8 +355,9 @@ class WritableVersion(dns.zone.WritableVersion):
|
|
|
330
355
|
"""Delete the rdataset with *rdtype* and *covers* at *name*.
|
|
331
356
|
|
|
332
357
|
If the deleted rdataset was the NS rdataset at a delegation point,
|
|
333
|
-
the ``DELEGATION`` flag is cleared from that node and
|
|
334
|
-
|
|
358
|
+
the ``DELEGATION`` flag is cleared from that node and any exposed
|
|
359
|
+
descendant NS nodes become delegation points. Nodes beneath those
|
|
360
|
+
delegations remain glue.
|
|
335
361
|
|
|
336
362
|
:param name: The owner name.
|
|
337
363
|
:type name: :py:class:`dns.name.Name`
|
|
@@ -341,11 +367,8 @@ class WritableVersion(dns.zone.WritableVersion):
|
|
|
341
367
|
:type covers: :py:class:`dns.rdatatype.RdataType`
|
|
342
368
|
"""
|
|
343
369
|
node, name = self._maybe_cow_with_name(name)
|
|
344
|
-
if rdtype == dns.rdatatype.NS and name in self.delegations: # pyright: ignore
|
|
345
|
-
node.flags &= ~NodeFlags.DELEGATION # type: ignore
|
|
346
|
-
self.delegations.discard(name) # pyright: ignore
|
|
347
|
-
self.update_glue_flag(name, False)
|
|
348
370
|
node.delete_rdataset(self.zone.rdclass, rdtype, covers)
|
|
371
|
+
self._update_delegation(name, cast(Node, node))
|
|
349
372
|
if len(node) == 0:
|
|
350
373
|
del self.nodes[name]
|
|
351
374
|
|
|
@@ -296,6 +296,10 @@ def _find_candidate_keys(
|
|
|
296
296
|
and key_id(rd) == rrsig.key_tag
|
|
297
297
|
and (rd.flags & Flag.ZONE) == Flag.ZONE # RFC 4034 2.1.1
|
|
298
298
|
and rd.protocol == 3 # RFC 4034 2.1.2
|
|
299
|
+
# A revoked key may only validate the DNSKEY RRset (RFC 5011 2.1)
|
|
300
|
+
and (
|
|
301
|
+
(rd.flags & Flag.REVOKE) == 0 or rrsig.type_covered == dns.rdatatype.DNSKEY
|
|
302
|
+
)
|
|
299
303
|
]
|
|
300
304
|
|
|
301
305
|
|
|
@@ -354,6 +358,11 @@ def _validate_rrsig(
|
|
|
354
358
|
if policy is None:
|
|
355
359
|
policy = default_policy
|
|
356
360
|
|
|
361
|
+
# RFC 4035 section 5.3.1: the RRSIG must cover the RRset's type and class.
|
|
362
|
+
_, rdataset = _get_rrname_rdataset(rrset)
|
|
363
|
+
if rrsig.type_covered != rdataset.rdtype or rrsig.rdclass != rdataset.rdclass:
|
|
364
|
+
raise ValidationFailure("RRSIG does not cover the RRset")
|
|
365
|
+
|
|
357
366
|
candidate_keys = _find_candidate_keys(keys, rrsig)
|
|
358
367
|
if candidate_keys is None:
|
|
359
368
|
raise ValidationFailure("unknown key")
|
|
@@ -715,10 +724,6 @@ def nsec3_hash(
|
|
|
715
724
|
:rtype: str
|
|
716
725
|
"""
|
|
717
726
|
|
|
718
|
-
b32_conversion = str.maketrans(
|
|
719
|
-
"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567", "0123456789ABCDEFGHIJKLMNOPQRSTUV"
|
|
720
|
-
)
|
|
721
|
-
|
|
722
727
|
try:
|
|
723
728
|
if isinstance(algorithm, str):
|
|
724
729
|
algorithm = NSEC3Hash[algorithm.upper()]
|
|
@@ -747,10 +752,7 @@ def nsec3_hash(
|
|
|
747
752
|
for _ in range(iterations):
|
|
748
753
|
digest = hashlib.sha1(digest + salt_encoded).digest()
|
|
749
754
|
|
|
750
|
-
|
|
751
|
-
output = output.translate(b32_conversion)
|
|
752
|
-
|
|
753
|
-
return output
|
|
755
|
+
return base64.b32hexencode(digest).decode("utf-8")
|
|
754
756
|
|
|
755
757
|
|
|
756
758
|
def make_ds_rdataset(
|
|
@@ -1117,7 +1119,7 @@ def _sign_zone_nsec(
|
|
|
1117
1119
|
_txn_add_nsec(txn, last_secure, name, zone.rdclass, rrsig_ttl, rrset_signer)
|
|
1118
1120
|
last_secure = name
|
|
1119
1121
|
|
|
1120
|
-
if last_secure:
|
|
1122
|
+
if last_secure is not None:
|
|
1121
1123
|
_txn_add_nsec(
|
|
1122
1124
|
txn, last_secure, zone.origin, zone.rdclass, rrsig_ttl, rrset_signer
|
|
1123
1125
|
)
|
|
@@ -20,7 +20,7 @@ class CryptographyPublicKey(GenericPublicKey):
|
|
|
20
20
|
self.key = key
|
|
21
21
|
|
|
22
22
|
@classmethod
|
|
23
|
-
def from_pem(cls, public_pem: bytes) ->
|
|
23
|
+
def from_pem(cls, public_pem: bytes) -> GenericPublicKey:
|
|
24
24
|
key = serialization.load_pem_public_key(public_pem)
|
|
25
25
|
return cls(key=key)
|
|
26
26
|
|
|
@@ -34,7 +34,7 @@ class CryptographyPublicKey(GenericPublicKey):
|
|
|
34
34
|
class CryptographyPrivateKey(GenericPrivateKey):
|
|
35
35
|
key: Any = None
|
|
36
36
|
key_cls: Any = None
|
|
37
|
-
public_cls: type[CryptographyPublicKey] #
|
|
37
|
+
public_cls: type[CryptographyPublicKey] # type: ignore
|
|
38
38
|
|
|
39
39
|
def __init__(self, key: Any) -> None: # pylint: disable=super-init-not-called
|
|
40
40
|
if self.key_cls is None:
|
|
@@ -51,7 +51,7 @@ class CryptographyPrivateKey(GenericPrivateKey):
|
|
|
51
51
|
@classmethod
|
|
52
52
|
def from_pem(
|
|
53
53
|
cls, private_pem: bytes, password: bytes | None = None
|
|
54
|
-
) ->
|
|
54
|
+
) -> GenericPrivateKey:
|
|
55
55
|
key = serialization.load_pem_private_key(private_pem, password=password)
|
|
56
56
|
return cls(key=key)
|
|
57
57
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import struct
|
|
2
2
|
|
|
3
|
+
from cryptography.exceptions import InvalidSignature
|
|
3
4
|
from cryptography.hazmat.backends import default_backend
|
|
4
5
|
from cryptography.hazmat.primitives import hashes
|
|
5
6
|
from cryptography.hazmat.primitives.asymmetric import dsa, utils
|
|
@@ -16,6 +17,11 @@ class PublicDSA(CryptographyPublicKey):
|
|
|
16
17
|
chosen_hash = hashes.SHA1()
|
|
17
18
|
|
|
18
19
|
def verify(self, signature: bytes, data: bytes) -> None:
|
|
20
|
+
# RFC 2536 section 3: the signature is T, R, and S (41 octets), where T
|
|
21
|
+
# is the same as the key's T.
|
|
22
|
+
dsa_t = (self.key.key_size // 8 - 64) // 8
|
|
23
|
+
if len(signature) != 41 or signature[0] != dsa_t:
|
|
24
|
+
raise InvalidSignature
|
|
19
25
|
sig_r = signature[1:21]
|
|
20
26
|
sig_s = signature[21:]
|
|
21
27
|
sig = utils.encode_dss_signature(
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from cryptography.exceptions import InvalidSignature
|
|
1
2
|
from cryptography.hazmat.backends import default_backend
|
|
2
3
|
from cryptography.hazmat.primitives import hashes
|
|
3
4
|
from cryptography.hazmat.primitives.asymmetric import ec, utils
|
|
@@ -16,6 +17,10 @@ class PublicECDSA(CryptographyPublicKey):
|
|
|
16
17
|
octets: int
|
|
17
18
|
|
|
18
19
|
def verify(self, signature: bytes, data: bytes) -> None:
|
|
20
|
+
# RFC 6605 section 4: the signature is r and s, each exactly
|
|
21
|
+
# self.octets long.
|
|
22
|
+
if len(signature) != self.octets * 2:
|
|
23
|
+
raise InvalidSignature
|
|
19
24
|
sig_r = signature[0 : self.octets]
|
|
20
25
|
sig_s = signature[self.octets :]
|
|
21
26
|
sig = utils.encode_dss_signature(
|
|
@@ -73,6 +73,22 @@ class OptionType(dns.enum.IntEnum):
|
|
|
73
73
|
return 65535
|
|
74
74
|
|
|
75
75
|
|
|
76
|
+
def _escapify_text(text: str) -> str:
|
|
77
|
+
"""Escape backslash and control characters in option text so that text
|
|
78
|
+
taken from the wire cannot add lines to, or otherwise alter, the output
|
|
79
|
+
of ``to_text()``."""
|
|
80
|
+
|
|
81
|
+
escaped = ""
|
|
82
|
+
for c in text:
|
|
83
|
+
if c == "\\":
|
|
84
|
+
escaped += "\\\\"
|
|
85
|
+
elif ord(c) < 0x20 or 0x7F <= ord(c) <= 0x9F:
|
|
86
|
+
escaped += f"\\{ord(c):03d}"
|
|
87
|
+
else:
|
|
88
|
+
escaped += c
|
|
89
|
+
return escaped
|
|
90
|
+
|
|
91
|
+
|
|
76
92
|
class Option:
|
|
77
93
|
"""Base class for all EDNS option types."""
|
|
78
94
|
|
|
@@ -432,7 +448,7 @@ class EDEOption(Option): # lgtm[py/missing-equals]
|
|
|
432
448
|
)
|
|
433
449
|
output += f" ({desc})"
|
|
434
450
|
if self.text is not None:
|
|
435
|
-
output += f": {self.text}"
|
|
451
|
+
output += f": {_escapify_text(self.text)}"
|
|
436
452
|
return output
|
|
437
453
|
|
|
438
454
|
def to_wire(self, file: Any | None = None) -> bytes | None:
|
|
@@ -564,7 +580,7 @@ class EDEExtraTextLanguageOption(Option):
|
|
|
564
580
|
return self.language.encode()
|
|
565
581
|
|
|
566
582
|
def to_text(self) -> str:
|
|
567
|
-
return f"EDE-EXTRA-TEXT-LANGUAGE {self.language}"
|
|
583
|
+
return f"EDE-EXTRA-TEXT-LANGUAGE {_escapify_text(self.language)}"
|
|
568
584
|
|
|
569
585
|
@classmethod
|
|
570
586
|
def from_wire_parser(
|
|
@@ -594,7 +610,7 @@ class FilteringContactOption(Option):
|
|
|
594
610
|
return self.contact.encode()
|
|
595
611
|
|
|
596
612
|
def to_text(self) -> str:
|
|
597
|
-
return f"FILTERING-CONTACT {self.contact}"
|
|
613
|
+
return f"FILTERING-CONTACT {_escapify_text(self.contact)}"
|
|
598
614
|
|
|
599
615
|
@classmethod
|
|
600
616
|
def from_wire_parser(
|
|
@@ -624,7 +640,7 @@ class FilteringOrganizationOption(Option):
|
|
|
624
640
|
return self.organization.encode()
|
|
625
641
|
|
|
626
642
|
def to_text(self) -> str:
|
|
627
|
-
return f"FILTERING-ORGANIZATION {self.organization}"
|
|
643
|
+
return f"FILTERING-ORGANIZATION {_escapify_text(self.organization)}"
|
|
628
644
|
|
|
629
645
|
@classmethod
|
|
630
646
|
def from_wire_parser(
|
|
@@ -658,7 +674,7 @@ class FilteringDBOption(Option):
|
|
|
658
674
|
return self.db.encode()
|
|
659
675
|
|
|
660
676
|
def to_text(self) -> str:
|
|
661
|
-
return f"FILTERING-DB {self.db}"
|
|
677
|
+
return f"FILTERING-DB {_escapify_text(self.db)}"
|
|
662
678
|
|
|
663
679
|
@classmethod
|
|
664
680
|
def from_wire_parser(
|
|
@@ -34,9 +34,9 @@ class EntropyPool:
|
|
|
34
34
|
self.digest: bytearray | None = None
|
|
35
35
|
self.next_byte = 0
|
|
36
36
|
self.lock = threading.Lock()
|
|
37
|
-
self.hash =
|
|
38
|
-
self.hash_len =
|
|
39
|
-
self.pool = bytearray(
|
|
37
|
+
self.hash = None
|
|
38
|
+
self.hash_len = 0
|
|
39
|
+
self.pool = bytearray()
|
|
40
40
|
if seed is not None:
|
|
41
41
|
self._stir(seed)
|
|
42
42
|
self.seeded = True
|
|
@@ -45,7 +45,19 @@ class EntropyPool:
|
|
|
45
45
|
self.seeded = False
|
|
46
46
|
self.seed_pid = 0
|
|
47
47
|
|
|
48
|
+
def _new_hash(self):
|
|
49
|
+
try:
|
|
50
|
+
self.hash = hashlib.sha256()
|
|
51
|
+
self.hash_len = 32
|
|
52
|
+
except AttributeError:
|
|
53
|
+
self.hash = hashlib.sha1()
|
|
54
|
+
self.hash_len = 20
|
|
55
|
+
if len(self.pool) != self.hash_len:
|
|
56
|
+
self.pool = bytearray(b"\0" * self.hash_len)
|
|
57
|
+
|
|
48
58
|
def _stir(self, entropy: bytes | bytearray) -> None:
|
|
59
|
+
if self.hash is None:
|
|
60
|
+
self._new_hash()
|
|
49
61
|
for c in entropy:
|
|
50
62
|
if self.pool_index == self.hash_len:
|
|
51
63
|
self.pool_index = 0
|
|
@@ -77,8 +89,12 @@ class EntropyPool:
|
|
|
77
89
|
with self.lock:
|
|
78
90
|
self._maybe_seed()
|
|
79
91
|
if self.digest is None or self.next_byte == self.hash_len:
|
|
92
|
+
assert self.hash is not None
|
|
80
93
|
self.hash.update(bytes(self.pool))
|
|
81
94
|
self.digest = bytearray(self.hash.digest())
|
|
95
|
+
# We make a new hash because on MicroPython you can't update
|
|
96
|
+
# and digest more than once.
|
|
97
|
+
self._new_hash()
|
|
82
98
|
self._stir(self.digest)
|
|
83
99
|
self.next_byte = 0
|
|
84
100
|
value = self.digest[self.next_byte]
|