From 40ab38b66011d32eb2e9c01bf26b6f4879599169 Mon Sep 17 00:00:00 2001 From: coletdjnz Date: Sun, 8 Sep 2024 17:00:12 +1200 Subject: [PATCH] add legacy_ssl_support tests --- test/test_http_proxy.py | 58 +++++++++++++++++++++++++++++++++++++ yt_dlp/networking/common.py | 8 ++--- 2 files changed, 62 insertions(+), 4 deletions(-) diff --git a/test/test_http_proxy.py b/test/test_http_proxy.py index b290eb9a28..1dbeed7e2d 100644 --- a/test/test_http_proxy.py +++ b/test/test_http_proxy.py @@ -152,6 +152,20 @@ class MTLSHTTPSProxyHandler(HTTPProxyHandler): 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): protocol_version = 'HTTP/1.1' default_request_version = 'HTTP/1.1' @@ -212,6 +226,22 @@ class MTLSHTTPSConnectProxyHandler(HTTPConnectProxyHandler): 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 def proxy_server(proxy_server_class, request_handler, bind_ip=None, **proxy_server_kwargs): server = server_thread = None @@ -333,6 +363,20 @@ class TestHTTPProxy: 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('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.parametrize('proxy_client_cert', [ {'client_certificate': os.path.join(MTLS_CERT_DIR, 'clientwithkey.crt')}, @@ -488,3 +532,17 @@ class TestHTTPConnectProxy: ) as rh: with pytest.raises((ProxyError, SSLError)): 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) diff --git a/yt_dlp/networking/common.py b/yt_dlp/networking/common.py index f77838090f..d5e05325e9 100644 --- a/yt_dlp/networking/common.py +++ b/yt_dlp/networking/common.py @@ -194,7 +194,7 @@ class RequestHandler(abc.ABC): @param verify: Verify SSL certificates @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_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, either the Request configuration option takes precedence or they are merged. @@ -238,7 +238,7 @@ class RequestHandler(abc.ABC): verify: bool = True, proxy_verify: bool = True, 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.proxy_verify = proxy_verify 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__() 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): return make_ssl_context( 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, **self._proxy_client_cert, )