async def tls(q, where, timeout=None, port=853, source=None, source_port=0, one_rr_per_rrset=False, ignore_trailing=False, sock=None, backend=None, ssl_context=None, server_hostname=None): """Return the response obtained after sending a query via TLS. *sock*, an ``asyncbackend.StreamSocket``, or ``None``, the socket to use for the query. If ``None``, the default, a socket is created. Note that if a socket is provided, it must be a connected SSL stream socket, and *where*, *port*, *source*, *source_port*, *backend*, *ssl_context*, and *server_hostname* are ignored. *backend*, a ``dns.asyncbackend.Backend``, or ``None``. If ``None``, the default, then dnspython will use the default backend. See :py:func:`dns.query.tls()` for the documentation of the other parameters, exceptions, and return type of this method. """ # After 3.6 is no longer supported, this can use an AsyncExitStack. (begin_time, expiration) = _compute_times(timeout) if not sock: if ssl_context is None: ssl_context = ssl.create_default_context() if server_hostname is None: ssl_context.check_hostname = False else: ssl_context = None server_hostname = None af = dns.inet.af_for_address(where) stuple = _source_tuple(af, source, source_port) dtuple = (where, port) if not backend: backend = dns.asyncbackend.get_default_backend() s = await backend.make_socket(af, socket.SOCK_STREAM, 0, stuple, dtuple, timeout, ssl_context, server_hostname) else: s = sock try: timeout = _timeout(expiration) response = await tcp(q, where, timeout, port, source, source_port, one_rr_per_rrset, ignore_trailing, s, backend) end_time = time.time() response.time = end_time - begin_time return response finally: if not sock and s: await s.close()
async def run(): ssl_context = ssl.create_default_context() ssl_context.check_hostname = False async with await self.backend.make_socket( dns.inet.af_for_address(address), socket.SOCK_STREAM, 0, None, (address, 853), None, ssl_context, None) as s: # for basic coverage await s.getsockname() q = dns.message.make_query(qname, dns.rdatatype.A) return await dns.asyncquery.tls(q, '8.8.8.8', sock=s)
import time import unittest import dns.asyncbackend import dns.asyncquery import dns.asyncresolver import dns.message import dns.name import dns.rdataclass import dns.rdatatype import dns.resolver # Some tests require TLS so skip those if it's not there. from dns.query import ssl try: ssl.create_default_context() _ssl_available = True except Exception: _ssl_available = False # Some tests require the internet to be available to run, so let's # skip those if it's not there. _network_available = True try: socket.gethostbyname('dnspython.org') except socket.gaierror: _network_available = False # Look for systemd-resolved, as it does dangling CNAME responses incorrectly. # # Currently we simply check if the nameserver is 127.0.0.53.
async def tls(q, where, timeout=None, port=853, source=None, source_port=0, one_rr_per_rrset=False, ignore_trailing=False, sock=None, backend=None, ssl_context=None, server_hostname=None): """Return the response obtained after sending a query via TLS. *q*, a ``dns.message.Message``, the query to send *where*, a ``str`` containing an IPv4 or IPv6 address, where to send the message. *timeout*, a ``float`` or ``None``, the number of seconds to wait before the query times out. If ``None``, the default, wait forever. *port*, an ``int``, the port send the message to. The default is 853. *source*, a ``str`` containing an IPv4 or IPv6 address, specifying the source address. The default is the wildcard address. *source_port*, an ``int``, the port from which to send the message. The default is 0. *one_rr_per_rrset*, a ``bool``. If ``True``, put each RR into its own RRset. *ignore_trailing*, a ``bool``. If ``True``, ignore trailing junk at end of the received message. *sock*, an ``asyncbackend.StreamSocket``, or ``None``, the socket to use for the query. If ``None``, the default, a socket is created. Note that if a socket is provided, it must be a connected SSL stream socket, and *where*, *port*, *source*, *source_port*, *backend*, *ssl_context*, and *server_hostname* are ignored. *backend*, a ``dns.asyncbackend.Backend``, or ``None``. If ``None``, the default, then dnspython will use the default backend. *ssl_context*, an ``ssl.SSLContext``, the context to use when establishing a TLS connection. If ``None``, the default, creates one with the default configuration. *server_hostname*, a ``str`` containing the server's hostname. The default is ``None``, which means that no hostname is known, and if an SSL context is created, hostname checking will be disabled. Returns a ``dns.message.Message``. """ # After 3.6 is no longer supported, this can use an AsyncExitStack. (begin_time, expiration) = _compute_times(timeout) if not sock: if ssl_context is None: ssl_context = ssl.create_default_context() if server_hostname is None: ssl_context.check_hostname = False else: ssl_context = None server_hostname = None af = dns.inet.af_for_address(where) stuple = _source_tuple(af, source, source_port) dtuple = (where, port) if not backend: backend = dns.asyncbackend.get_default_backend() s = await backend.make_socket(af, socket.SOCK_STREAM, 0, stuple, dtuple, timeout, ssl_context, server_hostname) else: s = sock try: timeout = _timeout(expiration) response = await tcp(q, where, timeout, port, source, source_port, one_rr_per_rrset, ignore_trailing, s, backend) end_time = time.time() response.time = end_time - begin_time return response finally: if not sock and s: await s.close()
async def tls( q: dns.message.Message, where: str, timeout: Optional[float] = None, port: int = 853, source: Optional[str] = None, source_port: int = 0, one_rr_per_rrset: bool = False, ignore_trailing: bool = False, sock: Optional[dns.asyncbackend.StreamSocket] = None, backend: Optional[dns.asyncbackend.Backend] = None, ssl_context: Optional[ssl.SSLContext] = None, server_hostname: Optional[str] = None, ) -> dns.message.Message: """Return the response obtained after sending a query via TLS. *sock*, an ``asyncbackend.StreamSocket``, or ``None``, the socket to use for the query. If ``None``, the default, a socket is created. Note that if a socket is provided, it must be a connected SSL stream socket, and *where*, *port*, *source*, *source_port*, *backend*, *ssl_context*, and *server_hostname* are ignored. *backend*, a ``dns.asyncbackend.Backend``, or ``None``. If ``None``, the default, then dnspython will use the default backend. See :py:func:`dns.query.tls()` for the documentation of the other parameters, exceptions, and return type of this method. """ (begin_time, expiration) = _compute_times(timeout) if sock: cm: contextlib.AbstractAsyncContextManager = NullContext(sock) else: if ssl_context is None: # See the comment about ssl.create_default_context() in query.py ssl_context = ssl.create_default_context( ) # lgtm[py/insecure-protocol] ssl_context.minimum_version = ssl.TLSVersion.TLSv1_2 if server_hostname is None: ssl_context.check_hostname = False else: ssl_context = None server_hostname = None af = dns.inet.af_for_address(where) stuple = _source_tuple(af, source, source_port) dtuple = (where, port) if not backend: backend = dns.asyncbackend.get_default_backend() cm = await backend.make_socket( af, socket.SOCK_STREAM, 0, stuple, dtuple, timeout, ssl_context, server_hostname, ) async with cm as s: timeout = _timeout(expiration) response = await tcp( q, where, timeout, port, source, source_port, one_rr_per_rrset, ignore_trailing, s, backend, ) end_time = time.time() response.time = end_time - begin_time return response
async def stream(q, where, tls=False, port=None, source=None, source_port=0, one_rr_per_rrset=False, ignore_trailing=False, ssl_context=None, server_hostname=None): """Return the response obtained after sending a query using TCP or TLS. *q*, a ``dns.message.Message``, the query to send. *where*, a ``str`` containing an IPv4 or IPv6 address, where to send the message. *tls*, a ``bool``. If ``False``, the default, the query will be sent using TCP and *port* will default to 53. If ``True``, the query is sent using TLS, and *port* will default to 853. *port*, an ``int``, the port send the message to. The default is as specified in the description for *tls*. *source*, a ``str`` containing an IPv4 or IPv6 address, specifying the source address. The default is the wildcard address. *source_port*, an ``int``, the port from which to send the message. The default is 0. *one_rr_per_rrset*, a ``bool``. If ``True``, put each RR into its own RRset. *ignore_trailing*, a ``bool``. If ``True``, ignore trailing junk at end of the received message. *ssl_context*, an ``ssl.SSLContext``, the context to use when establishing a TLS connection. If ``None``, the default, creates one with the default configuration. If this value is not ``None``, then the *tls* parameter is treated as if it were ``True`` regardless of its value. *server_hostname*, a ``str`` containing the server's hostname. The default is ``None``, which means that no hostname is known, and if an SSL context is created, hostname checking will be disabled. Returns a ``dns.message.Message``. """ if ssl_context is not None: tls = True if port is None: if tls: port = 853 else: port = 53 wire = q.to_wire() (af, destination, source) = \ dns.query._destination_and_source(None, where, port, source, source_port) with socket_factory(af, socket.SOCK_STREAM, 0) as s: begin_time = time.time() if source is not None: await s.bind(source) await s.connect(destination) stream = trio.SocketStream(s) if tls and ssl_context is None: ssl_context = ssl.create_default_context() if server_hostname is None: ssl_context.check_hostname = False if ssl_context: stream = trio.SSLStream(stream, ssl_context, server_hostname=server_hostname) async with stream: await send_stream(stream, wire) (r, received_time) = await receive_stream(stream, one_rr_per_rrset, q.keyring, q.mac, ignore_trailing) if not q.is_response(r): raise BadResponse r.time = received_time - begin_time return r