add legacy_ssl_support tests

This commit is contained in:
coletdjnz 2024-09-08 17:00:12 +12:00
parent 4accb0befe
commit 40ab38b660
No known key found for this signature in database
GPG key ID: 91984263BB39894A
2 changed files with 62 additions and 4 deletions

View file

@ -152,6 +152,20 @@ class MTLSHTTPSProxyHandler(HTTPProxyHandler):
super().__init__(request, *args, **kwargs) super().__init__(request, *args, **kwargs)
class LegacyHTTPSProxyHandler(HTTPProxyHandler):
def __init__(self, request, *args, **kwargs):
certfn = os.path.join(TEST_DIR, 'testcert.pem')
sslctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
sslctx.maximum_version = ssl.TLSVersion.TLSv1_2
sslctx.set_ciphers('SHA1:AESCCM:aDSS:eNULL:aNULL')
sslctx.load_cert_chain(certfn, None)
if isinstance(request, ssl.SSLSocket):
request = SSLTransport(request, ssl_context=sslctx, server_side=True)
else:
request = sslctx.wrap_socket(request, server_side=True)
super().__init__(request, *args, **kwargs)
class HTTPConnectProxyHandler(BaseHTTPRequestHandler, HTTPProxyAuthMixin): class HTTPConnectProxyHandler(BaseHTTPRequestHandler, HTTPProxyAuthMixin):
protocol_version = 'HTTP/1.1' protocol_version = 'HTTP/1.1'
default_request_version = 'HTTP/1.1' default_request_version = 'HTTP/1.1'
@ -212,6 +226,22 @@ class MTLSHTTPSConnectProxyHandler(HTTPConnectProxyHandler):
self.server.close_request(self._original_request) self.server.close_request(self._original_request)
class LegacyHTTPSConnectProxyHandler(HTTPConnectProxyHandler):
def __init__(self, request, *args, **kwargs):
certfn = os.path.join(TEST_DIR, 'testcert.pem')
sslctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
sslctx.maximum_version = ssl.TLSVersion.TLSv1_2
sslctx.set_ciphers('SHA1:AESCCM:aDSS:eNULL:aNULL')
sslctx.load_cert_chain(certfn, None)
request = sslctx.wrap_socket(request, server_side=True)
self._original_request = request
super().__init__(request, *args, **kwargs)
def do_CONNECT(self):
super().do_CONNECT()
self.server.close_request(self._original_request)
@contextlib.contextmanager @contextlib.contextmanager
def proxy_server(proxy_server_class, request_handler, bind_ip=None, **proxy_server_kwargs): def proxy_server(proxy_server_class, request_handler, bind_ip=None, **proxy_server_kwargs):
server = server_thread = None server = server_thread = None
@ -333,6 +363,20 @@ class TestHTTPProxy:
with pytest.raises((ProxyError, SSLError)): with pytest.raises((ProxyError, SSLError)):
ctx.proxy_info_request(rh) ctx.proxy_info_request(rh)
@pytest.mark.skip_handler('Urllib', 'urllib does not support https proxies')
@pytest.mark.skip_handler('CurlCFFI', 'legacy_ssl ignored by CurlCFFI')
def test_https_legacy_ssl_support(self, handler, ctx):
with ctx.http_server(LegacyHTTPSProxyHandler) as server_address:
with handler(proxy_verify=False, verify=False, proxy_legacy_ssl_support=True, proxies={ctx.REQUEST_PROTO: f'https://{server_address}'}) as rh:
proxy_info = ctx.proxy_info_request(rh)
assert proxy_info['proxy'] == server_address
assert proxy_info['connect'] is False
assert 'Proxy-Authorization' not in proxy_info['headers']
with handler(proxy_verify=False, verify=False, proxy_legacy_ssl_support=False, proxies={ctx.REQUEST_PROTO: f'https://{server_address}'}) as rh:
with pytest.raises((ProxyError, SSLError)):
ctx.proxy_info_request(rh)
@pytest.mark.skip_handler('Urllib', 'urllib does not support https proxies') @pytest.mark.skip_handler('Urllib', 'urllib does not support https proxies')
@pytest.mark.parametrize('proxy_client_cert', [ @pytest.mark.parametrize('proxy_client_cert', [
{'client_certificate': os.path.join(MTLS_CERT_DIR, 'clientwithkey.crt')}, {'client_certificate': os.path.join(MTLS_CERT_DIR, 'clientwithkey.crt')},
@ -488,3 +532,17 @@ class TestHTTPConnectProxy:
) as rh: ) as rh:
with pytest.raises((ProxyError, SSLError)): with pytest.raises((ProxyError, SSLError)):
ctx.proxy_info_request(rh) ctx.proxy_info_request(rh)
@pytest.mark.skipif(urllib3 is None, reason='requires urllib3 to test')
@pytest.mark.skip_handler('CurlCFFI', 'legacy_ssl ignored by CurlCFFI')
def test_https_connect_legacy_ssl_support(self, handler, ctx):
with ctx.http_server(LegacyHTTPSConnectProxyHandler) as server_address:
with handler(proxy_verify=False, verify=False, proxy_legacy_ssl_support=True, proxies={ctx.REQUEST_PROTO: f'https://{server_address}'}) as rh:
proxy_info = ctx.proxy_info_request(rh)
assert proxy_info['proxy'] == server_address
assert proxy_info['connect'] is True
assert 'Proxy-Authorization' not in proxy_info['headers']
with handler(proxy_verify=False, verify=False, proxy_legacy_ssl_support=False, proxies={ctx.REQUEST_PROTO: f'https://{server_address}'}) as rh:
with pytest.raises((ProxyError, SSLError)):
ctx.proxy_info_request(rh)

View file

@ -194,7 +194,7 @@ class RequestHandler(abc.ABC):
@param verify: Verify SSL certificates @param verify: Verify SSL certificates
@param proxy_verify: Verify SSL certificates of proxy connections @param proxy_verify: Verify SSL certificates of proxy connections
@param legacy_ssl_support: Enable legacy SSL options such as legacy server connect and older cipher support. @param legacy_ssl_support: Enable legacy SSL options such as legacy server connect and older cipher support.
@param legacy_proxy_ssl_support: Enable legacy SSL options such as legacy server connect and older cipher support for proxy connections. @param proxy_legacy_ssl_support: Enable legacy SSL options such as legacy server connect and older cipher support for proxy connections.
Some configuration options may be available for individual Requests too. In this case, Some configuration options may be available for individual Requests too. In this case,
either the Request configuration option takes precedence or they are merged. either the Request configuration option takes precedence or they are merged.
@ -238,7 +238,7 @@ class RequestHandler(abc.ABC):
verify: bool = True, verify: bool = True,
proxy_verify: bool = True, proxy_verify: bool = True,
legacy_ssl_support: bool = False, legacy_ssl_support: bool = False,
legacy_proxy_ssl_support: bool = False, proxy_legacy_ssl_support: bool = False,
**_, **_,
): ):
@ -255,7 +255,7 @@ class RequestHandler(abc.ABC):
self.verify = verify self.verify = verify
self.proxy_verify = proxy_verify self.proxy_verify = proxy_verify
self.legacy_ssl_support = legacy_ssl_support self.legacy_ssl_support = legacy_ssl_support
self.legacy_proxy_ssl_support = legacy_proxy_ssl_support self.proxy_legacy_ssl_support = proxy_legacy_ssl_support
super().__init__() super().__init__()
def _make_sslcontext(self, legacy_ssl_support=None): def _make_sslcontext(self, legacy_ssl_support=None):
@ -269,7 +269,7 @@ class RequestHandler(abc.ABC):
def _make_proxy_sslcontext(self, legacy_ssl_support=None): def _make_proxy_sslcontext(self, legacy_ssl_support=None):
return make_ssl_context( return make_ssl_context(
verify=self.proxy_verify, verify=self.proxy_verify,
legacy_support=legacy_ssl_support if legacy_ssl_support is not None else self.legacy_proxy_ssl_support, legacy_support=legacy_ssl_support if legacy_ssl_support is not None else self.proxy_legacy_ssl_support,
use_certifi=not self.prefer_system_certs, use_certifi=not self.prefer_system_certs,
**self._proxy_client_cert, **self._proxy_client_cert,
) )