Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP1:GA
python-dnspython.34852
CVE-2023-29483-pre1.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File CVE-2023-29483-pre1.patch of Package python-dnspython.34852
Index: dnspython-1.12.0/dns/query.py =================================================================== --- dnspython-1.12.0.orig/dns/query.py +++ dnspython-1.12.0/dns/query.py @@ -187,6 +187,72 @@ def _destination_and_source(af, where, p return (af, destination, source) +def send_udp(sock, what, destination, expiration=None): + """Send a DNS message to the specified UDP socket. + + @param sock: the socket + @type sock: socket.socket + @param what: the message to send + @type what: wire format bytes or a dns.message.Message + @param destination: where to send the query + @type destination: tuple appropriate for the address family of the socket + @param expiration: The absolute time at which a timeout exception should + be raised. + @type expiration: float + @rtype: (int, double) tuple of bytes sent and the sent time. + """ + if isinstance(what, dns.message.Message): + what = what.to_wire() + _wait_for_writable(sock, expiration) + sent_time = time.time() + n = sock.sendto(what, destination) + return (n, sent_time) + + +def receive_udp(sock, destination, expiration=None, af=None, + ignore_unexpected=False, one_rr_per_rrset=False, + keyring=None, request_mac=b''): + """Read a DNS message from a UDP socket. + + @param sock: the socket + @type sock: socket.socket + @param af: the address family to use. The default is None, which + causes the address family to use to be inferred from the form of + destination. If the inference attempt fails, AF_INET is used. + @type af: int + @param ignore_unexpected: If True, ignore responses from unexpected + sources. The default is False. + @type ignore_unexpected: bool + @param one_rr_per_rrset: Put each RR into its own RRset + @type one_rr_per_rrset: bool + @param keyring: the keyring to use for TSIG + @type keyring: keyring dict + @param request_mac: the MAC of the request (for TSIG) + @type request_mac: bytes + @rtype: dns.message.Message object + """ + if af is None: + try: + af = dns.inet.af_for_address(destination[0]) + except Exception: + af = dns.inet.AF_INET + wire = b'' + while 1: + _wait_for_readable(sock, expiration) + (wire, from_address) = sock.recvfrom(65535) + if _addresses_equal(af, from_address, destination) or \ + (dns.inet.is_multicast(destination[0]) and + from_address[1:] == destination[1:]): + break + if not ignore_unexpected: + raise UnexpectedSource('got a response from ' + '%s instead of %s' % (from_address, + destination)) + received_time = time.time() + r = dns.message.from_wire(wire, keyring=keyring, request_mac=request_mac, + one_rr_per_rrset=one_rr_per_rrset) + return (r, received_time) + def udp(q, where, timeout=None, port=53, af=None, source=None, source_port=0, ignore_unexpected=False, one_rr_per_rrset=False): """Return the response obtained after sending a query via UDP. @@ -204,7 +270,6 @@ def udp(q, where, timeout=None, port=53, causes the address family to use to be inferred from the form of of where. If the inference attempt fails, AF_INET is used. @type af: int - @rtype: dns.message.Message object @param source: source address. The default is the wildcard address. @type source: string @param source_port: The port from which to send the message. @@ -215,34 +280,27 @@ def udp(q, where, timeout=None, port=53, @type ignore_unexpected: bool @param one_rr_per_rrset: Put each RR into its own RRset @type one_rr_per_rrset: bool + @rtype: dns.message.Message object """ wire = q.to_wire() (af, destination, source) = _destination_and_source(af, where, port, source, source_port) s = socket.socket(af, socket.SOCK_DGRAM, 0) + received_time = None + sent_time = None try: expiration = _compute_expiration(timeout) s.setblocking(0) if source is not None: s.bind(source) - _wait_for_writable(s, expiration) - s.sendto(wire, destination) - while 1: - _wait_for_readable(s, expiration) - (wire, from_address) = s.recvfrom(65535) - if _addresses_equal(af, from_address, destination) or \ - (dns.inet.is_multicast(where) and - from_address[1:] == destination[1:]): - break - if not ignore_unexpected: - raise UnexpectedSource('got a response from ' - '%s instead of %s' % (from_address, - destination)) + + (_, sent_time) = send_udp(s, wire, destination, expiration) + (r, received_time) = receive_udp(s, destination, expiration, af, + ignore_unexpected, one_rr_per_rrset, + q.keyring, q.request_mac) finally: s.close() - r = dns.message.from_wire(wire, keyring=q.keyring, request_mac=q.mac, - one_rr_per_rrset=one_rr_per_rrset) if not q.is_response(r): raise BadResponse return r @@ -277,6 +335,52 @@ def _net_write(sock, data, expiration): current += sock.send(data[current:]) +def send_tcp(sock, what, expiration=None): + """Send a DNS message to the specified TCP socket. + + @param sock: the socket + @type sock: socket.socket + @param what: the message to send + @type what: wire format bytes or a dns.message.Message + @param expiration: The absolute time at which a timeout exception should + be raised. + @type expiration: float + @rtype: (int, double) tuple of bytes sent and the sent time. + """ + if isinstance(what, dns.message.Message): + what = what.to_wire() + l = len(what) + # copying the wire into tcpmsg is inefficient, but lets us + # avoid writev() or doing a short write that would get pushed + # onto the net + tcpmsg = struct.pack("!H", l) + what + _wait_for_writable(sock, expiration) + sent_time = time.time() + _net_write(sock, tcpmsg, expiration) + return (len(tcpmsg), sent_time) + +def receive_tcp(sock, expiration=None, one_rr_per_rrset=False, + keyring=None, request_mac=b''): + """Read a DNS message from a TCP socket. + + @param sock: the socket + @type sock: socket.socket + @param one_rr_per_rrset: Put each RR into its own RRset + @type one_rr_per_rrset: bool + @param keyring: the keyring to use for TSIG + @type keyring: keyring dict + @param request_mac: the MAC of the request (for TSIG) + @type request_mac: bytes + @rtype: dns.message.Message object + """ + ldata = _net_read(sock, 2, expiration) + (l,) = struct.unpack("!H", ldata) + wire = _net_read(sock, l, expiration) + received_time = time.time() + r = dns.message.from_wire(wire, keyring=keyring, request_mac=request_mac, + one_rr_per_rrset=one_rr_per_rrset) + return (r, received_time) + def _connect(s, address): try: s.connect(address) @@ -326,20 +430,11 @@ def tcp(q, where, timeout=None, port=53, s.bind(source) _connect(s, destination) - l = len(wire) - - # copying the wire into tcpmsg is inefficient, but lets us - # avoid writev() or doing a short write that would get pushed - # onto the net - tcpmsg = struct.pack("!H", l) + wire - _net_write(s, tcpmsg, expiration) - ldata = _net_read(s, 2, expiration) - (l,) = struct.unpack("!H", ldata) - wire = _net_read(s, l, expiration) + send_tcp(s, wire, expiration) + (r, received_time) = receive_tcp(s, expiration, one_rr_per_rrset, + q.keyring, q.request_mac) finally: s.close() - r = dns.message.from_wire(wire, keyring=q.keyring, request_mac=q.mac, - one_rr_per_rrset=one_rr_per_rrset) if not q.is_response(r): raise BadResponse return r
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor