mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-08-14 02:26:58 -07:00
Bump dnspython from 2.2.1 to 2.3.0 (#1975)
* Bump dnspython from 2.2.1 to 2.3.0 Bumps [dnspython](https://github.com/rthalley/dnspython) from 2.2.1 to 2.3.0. - [Release notes](https://github.com/rthalley/dnspython/releases) - [Changelog](https://github.com/rthalley/dnspython/blob/master/doc/whatsnew.rst) - [Commits](https://github.com/rthalley/dnspython/compare/v2.2.1...v2.3.0) --- updated-dependencies: - dependency-name: dnspython dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Update dnspython==2.3.0 --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com> [skip ci]
This commit is contained in:
parent
6910079330
commit
32c06a8b72
137 changed files with 7699 additions and 4277 deletions
124
lib/dns/xfr.py
124
lib/dns/xfr.py
|
@ -15,12 +15,17 @@
|
|||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
from typing import Any, List, Optional, Tuple, Union
|
||||
|
||||
import dns.exception
|
||||
import dns.message
|
||||
import dns.name
|
||||
import dns.rcode
|
||||
import dns.serial
|
||||
import dns.rdataset
|
||||
import dns.rdatatype
|
||||
import dns.transaction
|
||||
import dns.tsig
|
||||
import dns.zone
|
||||
|
||||
|
||||
|
@ -28,7 +33,7 @@ class TransferError(dns.exception.DNSException):
|
|||
"""A zone transfer response got a non-zero rcode."""
|
||||
|
||||
def __init__(self, rcode):
|
||||
message = 'Zone transfer error: %s' % dns.rcode.to_text(rcode)
|
||||
message = "Zone transfer error: %s" % dns.rcode.to_text(rcode)
|
||||
super().__init__(message)
|
||||
self.rcode = rcode
|
||||
|
||||
|
@ -46,8 +51,13 @@ class Inbound:
|
|||
State machine for zone transfers.
|
||||
"""
|
||||
|
||||
def __init__(self, txn_manager, rdtype=dns.rdatatype.AXFR,
|
||||
serial=None, is_udp=False):
|
||||
def __init__(
|
||||
self,
|
||||
txn_manager: dns.transaction.TransactionManager,
|
||||
rdtype: dns.rdatatype.RdataType = dns.rdatatype.AXFR,
|
||||
serial: Optional[int] = None,
|
||||
is_udp: bool = False,
|
||||
):
|
||||
"""Initialize an inbound zone transfer.
|
||||
|
||||
*txn_manager* is a :py:class:`dns.transaction.TransactionManager`.
|
||||
|
@ -61,22 +71,22 @@ class Inbound:
|
|||
XFR.
|
||||
"""
|
||||
self.txn_manager = txn_manager
|
||||
self.txn = None
|
||||
self.txn: Optional[dns.transaction.Transaction] = None
|
||||
self.rdtype = rdtype
|
||||
if rdtype == dns.rdatatype.IXFR:
|
||||
if serial is None:
|
||||
raise ValueError('a starting serial must be supplied for IXFRs')
|
||||
raise ValueError("a starting serial must be supplied for IXFRs")
|
||||
elif is_udp:
|
||||
raise ValueError('is_udp specified for AXFR')
|
||||
raise ValueError("is_udp specified for AXFR")
|
||||
self.serial = serial
|
||||
self.is_udp = is_udp
|
||||
(_, _, self.origin) = txn_manager.origin_information()
|
||||
self.soa_rdataset = None
|
||||
self.soa_rdataset: Optional[dns.rdataset.Rdataset] = None
|
||||
self.done = False
|
||||
self.expecting_SOA = False
|
||||
self.delete_mode = False
|
||||
|
||||
def process_message(self, message):
|
||||
def process_message(self, message: dns.message.Message) -> bool:
|
||||
"""Process one message in the transfer.
|
||||
|
||||
The message should have the same relativization as was specified when
|
||||
|
@ -107,10 +117,8 @@ class Inbound:
|
|||
# the origin.
|
||||
#
|
||||
if not message.answer or message.answer[0].name != self.origin:
|
||||
raise dns.exception.FormError("No answer or RRset not "
|
||||
"for zone origin")
|
||||
raise dns.exception.FormError("No answer or RRset not for zone origin")
|
||||
rrset = message.answer[0]
|
||||
name = rrset.name
|
||||
rdataset = rrset
|
||||
if rdataset.rdtype != dns.rdatatype.SOA:
|
||||
raise dns.exception.FormError("first RRset is not an SOA")
|
||||
|
@ -122,8 +130,7 @@ class Inbound:
|
|||
# We're already up-to-date.
|
||||
#
|
||||
self.done = True
|
||||
elif dns.serial.Serial(self.soa_rdataset[0].serial) < \
|
||||
self.serial:
|
||||
elif dns.serial.Serial(self.soa_rdataset[0].serial) < self.serial:
|
||||
# It went backwards!
|
||||
raise SerialWentBackwards
|
||||
else:
|
||||
|
@ -147,8 +154,8 @@ class Inbound:
|
|||
rdataset = rrset
|
||||
if self.done:
|
||||
raise dns.exception.FormError("answers after final SOA")
|
||||
if rdataset.rdtype == dns.rdatatype.SOA and \
|
||||
name == self.origin:
|
||||
assert self.txn is not None # for mypy
|
||||
if rdataset.rdtype == dns.rdatatype.SOA and name == self.origin:
|
||||
#
|
||||
# Every time we see an origin SOA delete_mode inverts
|
||||
#
|
||||
|
@ -160,20 +167,21 @@ class Inbound:
|
|||
# check that we're seeing the record in the expected
|
||||
# part of the response.
|
||||
#
|
||||
if rdataset == self.soa_rdataset and \
|
||||
(self.rdtype == dns.rdatatype.AXFR or
|
||||
(self.rdtype == dns.rdatatype.IXFR and
|
||||
self.delete_mode)):
|
||||
if rdataset == self.soa_rdataset and (
|
||||
self.rdtype == dns.rdatatype.AXFR
|
||||
or (self.rdtype == dns.rdatatype.IXFR and self.delete_mode)
|
||||
):
|
||||
#
|
||||
# This is the final SOA
|
||||
#
|
||||
if self.expecting_SOA:
|
||||
# We got an empty IXFR sequence!
|
||||
raise dns.exception.FormError('empty IXFR sequence')
|
||||
if self.rdtype == dns.rdatatype.IXFR \
|
||||
and self.serial != rdataset[0].serial:
|
||||
raise dns.exception.FormError('unexpected end of IXFR '
|
||||
'sequence')
|
||||
raise dns.exception.FormError("empty IXFR sequence")
|
||||
if (
|
||||
self.rdtype == dns.rdatatype.IXFR
|
||||
and self.serial != rdataset[0].serial
|
||||
):
|
||||
raise dns.exception.FormError("unexpected end of IXFR sequence")
|
||||
self.txn.replace(name, rdataset)
|
||||
self.txn.commit()
|
||||
self.txn = None
|
||||
|
@ -188,15 +196,15 @@ class Inbound:
|
|||
# This is the start of an IXFR deletion set
|
||||
if rdataset[0].serial != self.serial:
|
||||
raise dns.exception.FormError(
|
||||
"IXFR base serial mismatch")
|
||||
"IXFR base serial mismatch"
|
||||
)
|
||||
else:
|
||||
# This is the start of an IXFR addition set
|
||||
self.serial = rdataset[0].serial
|
||||
self.txn.replace(name, rdataset)
|
||||
else:
|
||||
# We saw a non-final SOA for the origin in an AXFR.
|
||||
raise dns.exception.FormError('unexpected origin SOA '
|
||||
'in AXFR')
|
||||
raise dns.exception.FormError("unexpected origin SOA in AXFR")
|
||||
continue
|
||||
if self.expecting_SOA:
|
||||
#
|
||||
|
@ -223,7 +231,7 @@ class Inbound:
|
|||
# This is a UDP IXFR and we didn't get to done, and we didn't
|
||||
# get the proper "truncated" response
|
||||
#
|
||||
raise dns.exception.FormError('unexpected end of UDP IXFR')
|
||||
raise dns.exception.FormError("unexpected end of UDP IXFR")
|
||||
return self.done
|
||||
|
||||
#
|
||||
|
@ -239,11 +247,18 @@ class Inbound:
|
|||
return False
|
||||
|
||||
|
||||
def make_query(txn_manager, serial=0,
|
||||
use_edns=None, ednsflags=None, payload=None,
|
||||
request_payload=None, options=None,
|
||||
keyring=None, keyname=None,
|
||||
keyalgorithm=dns.tsig.default_algorithm):
|
||||
def make_query(
|
||||
txn_manager: dns.transaction.TransactionManager,
|
||||
serial: Optional[int] = 0,
|
||||
use_edns: Optional[Union[int, bool]] = None,
|
||||
ednsflags: Optional[int] = None,
|
||||
payload: Optional[int] = None,
|
||||
request_payload: Optional[int] = None,
|
||||
options: Optional[List[dns.edns.Option]] = None,
|
||||
keyring: Any = None,
|
||||
keyname: Optional[dns.name.Name] = None,
|
||||
keyalgorithm: Union[dns.name.Name, str] = dns.tsig.default_algorithm,
|
||||
) -> Tuple[dns.message.QueryMessage, Optional[int]]:
|
||||
"""Make an AXFR or IXFR query.
|
||||
|
||||
*txn_manager* is a ``dns.transaction.TransactionManager``, typically a
|
||||
|
@ -264,13 +279,15 @@ def make_query(txn_manager, serial=0,
|
|||
Returns a `(query, serial)` tuple.
|
||||
"""
|
||||
(zone_origin, _, origin) = txn_manager.origin_information()
|
||||
if zone_origin is None:
|
||||
raise ValueError("no zone origin")
|
||||
if serial is None:
|
||||
rdtype = dns.rdatatype.AXFR
|
||||
elif not isinstance(serial, int):
|
||||
raise ValueError('serial is not an integer')
|
||||
raise ValueError("serial is not an integer")
|
||||
elif serial == 0:
|
||||
with txn_manager.reader() as txn:
|
||||
rdataset = txn.get(origin, 'SOA')
|
||||
rdataset = txn.get(origin, "SOA")
|
||||
if rdataset:
|
||||
serial = rdataset[0].serial
|
||||
rdtype = dns.rdatatype.IXFR
|
||||
|
@ -280,34 +297,47 @@ def make_query(txn_manager, serial=0,
|
|||
elif serial > 0 and serial < 4294967296:
|
||||
rdtype = dns.rdatatype.IXFR
|
||||
else:
|
||||
raise ValueError('serial out-of-range')
|
||||
raise ValueError("serial out-of-range")
|
||||
rdclass = txn_manager.get_class()
|
||||
q = dns.message.make_query(zone_origin, rdtype, rdclass,
|
||||
use_edns, False, ednsflags, payload,
|
||||
request_payload, options)
|
||||
q = dns.message.make_query(
|
||||
zone_origin,
|
||||
rdtype,
|
||||
rdclass,
|
||||
use_edns,
|
||||
False,
|
||||
ednsflags,
|
||||
payload,
|
||||
request_payload,
|
||||
options,
|
||||
)
|
||||
if serial is not None:
|
||||
rdata = dns.rdata.from_text(rdclass, 'SOA', f'. . {serial} 0 0 0 0')
|
||||
rrset = q.find_rrset(q.authority, zone_origin, rdclass,
|
||||
dns.rdatatype.SOA, create=True)
|
||||
rdata = dns.rdata.from_text(rdclass, "SOA", f". . {serial} 0 0 0 0")
|
||||
rrset = q.find_rrset(
|
||||
q.authority, zone_origin, rdclass, dns.rdatatype.SOA, create=True
|
||||
)
|
||||
rrset.add(rdata, 0)
|
||||
if keyring is not None:
|
||||
q.use_tsig(keyring, keyname, algorithm=keyalgorithm)
|
||||
return (q, serial)
|
||||
|
||||
def extract_serial_from_query(query):
|
||||
|
||||
def extract_serial_from_query(query: dns.message.Message) -> Optional[int]:
|
||||
"""Extract the SOA serial number from query if it is an IXFR and return
|
||||
it, otherwise return None.
|
||||
|
||||
*query* is a dns.message.QueryMessage that is an IXFR or AXFR request.
|
||||
|
||||
Raises if the query is not an IXFR or AXFR, or if an IXFR doesn't have
|
||||
an appropriate SOA RRset in the authority section."""
|
||||
|
||||
an appropriate SOA RRset in the authority section.
|
||||
"""
|
||||
if not isinstance(query, dns.message.QueryMessage):
|
||||
raise ValueError("query not a QueryMessage")
|
||||
question = query.question[0]
|
||||
if question.rdtype == dns.rdatatype.AXFR:
|
||||
return None
|
||||
elif question.rdtype != dns.rdatatype.IXFR:
|
||||
raise ValueError("query is not an AXFR or IXFR")
|
||||
soa = query.find_rrset(query.authority, question.name, question.rdclass,
|
||||
dns.rdatatype.SOA)
|
||||
soa = query.find_rrset(
|
||||
query.authority, question.name, question.rdclass, dns.rdatatype.SOA
|
||||
)
|
||||
return soa[0].serial
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue