From: Bob Halley Date: Sat, 14 Sep 2024 15:51:39 +0000 (-0700) Subject: Check SAN for IP if using an address URL in https() [#1125]. X-Git-Tag: v2.7.0rc1~13 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b0be65568e36921475954949b954b1e35b6fa453;p=thirdparty%2Fdnspython.git Check SAN for IP if using an address URL in https() [#1125]. Httpx needs us to set the "sni_hostname" extension if the server in the URL is an IP address, as otherwise it will not check the certificate. With this change, it will look for a SAN with the IP address. --- diff --git a/dns/asyncquery.py b/dns/asyncquery.py index eac10de3..ce885a4c 100644 --- a/dns/asyncquery.py +++ b/dns/asyncquery.py @@ -39,9 +39,9 @@ import dns.transaction from dns._asyncbackend import NullContext from dns.query import ( BadResponse, + HTTPVersion, NoDOH, NoDOQ, - HTTPVersion, UDPMode, _check_status, _compute_times, @@ -560,12 +560,14 @@ async def https( else: url = where + extensions = {} if bootstrap_address is None: parsed = urllib.parse.urlparse(url) if parsed.hostname is None: raise ValueError("no hostname in URL") if dns.inet.is_address(parsed.hostname): bootstrap_address = parsed.hostname + extensions["sni_hostname"] = parsed.hostname if parsed.port is not None: port = parsed.port @@ -638,13 +640,25 @@ async def https( } ) response = await backend.wait_for( - the_client.post(url, headers=headers, content=wire), timeout + the_client.post( + url, + headers=headers, + content=wire, + extensions=extensions, + ), + timeout, ) else: wire = base64.urlsafe_b64encode(wire).rstrip(b"=") twire = wire.decode() # httpx does a repr() if we give it bytes response = await backend.wait_for( - the_client.get(url, headers=headers, params={"dns": twire}), timeout + the_client.get( + url, + headers=headers, + params={"dns": twire}, + extensions=extensions, + ), + timeout, ) # see https://tools.ietf.org/html/rfc8484#section-4.2.1 for info about DoH diff --git a/dns/query.py b/dns/query.py index 1b0703b2..9060012c 100644 --- a/dns/query.py +++ b/dns/query.py @@ -449,12 +449,14 @@ def https( else: url = where + extensions = {} if bootstrap_address is None: parsed = urllib.parse.urlparse(url) if parsed.hostname is None: raise ValueError("no hostname in URL") if dns.inet.is_address(parsed.hostname): bootstrap_address = parsed.hostname + extensions["sni_hostname"] = parsed.hostname if parsed.port is not None: port = parsed.port @@ -525,12 +527,22 @@ def https( "content-length": str(len(wire)), } ) - response = session.post(url, headers=headers, content=wire, timeout=timeout) + response = session.post( + url, + headers=headers, + content=wire, + timeout=timeout, + extensions=extensions, + ) else: wire = base64.urlsafe_b64encode(wire).rstrip(b"=") twire = wire.decode() # httpx does a repr() if we give it bytes response = session.get( - url, headers=headers, timeout=timeout, params={"dns": twire} + url, + headers=headers, + timeout=timeout, + params={"dns": twire}, + extensions=extensions, ) # see https://tools.ietf.org/html/rfc8484#section-4.2.1 for info about DoH