From 185210562d8e87576ce06a251c8d6f3d46c75332 Mon Sep 17 00:00:00 2001 From: Bryce Ferenczi Date: Tue, 15 Aug 2023 11:34:51 +1000 Subject: [PATCH] apply fix from stackof Signed-off-by: Bryce Ferenczi --- openconnect_sso/authenticator.py | 36 +++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/openconnect_sso/authenticator.py b/openconnect_sso/authenticator.py index ffbb383..12dc43a 100644 --- a/openconnect_sso/authenticator.py +++ b/openconnect_sso/authenticator.py @@ -1,6 +1,9 @@ +import ssl + import attr import requests import structlog +import urllib3 from lxml import etree, objectify from openconnect_sso.saml_authenticator import authenticate_in_browser @@ -9,6 +12,33 @@ logger = structlog.get_logger() +class CustomHttpAdapter(requests.adapters.HTTPAdapter): + """ + "Transport adapter" that allows us to use custom ssl_context. + Source: https://stackoverflow.com/questions/71603314/ssl-error-unsafe-legacy-renegotiation-disabled + """ + + def __init__(self, ssl_context=None, **kwargs): + self.ssl_context = ssl_context + super().__init__(**kwargs) + + def init_poolmanager(self, connections, maxsize, block=False): + self.poolmanager = urllib3.poolmanager.PoolManager( + num_pools=connections, + maxsize=maxsize, + block=block, + ssl_context=self.ssl_context, + ) + + +def get_legacy_session(): + ctx = ssl.create_default_context(ssl.Purpose.SERVER_AUTH) + ctx.options |= 0x4 # OP_LEGACY_SERVER_CONNECT + session = requests.Session() + session.mount("https://", CustomHttpAdapter(ctx)) + return session + + class Authenticator: def __init__(self, host, proxy=None, credentials=None, version=None): self.host = host @@ -55,7 +85,7 @@ async def authenticate(self, display_mode): def _detect_authentication_target_url(self): # Follow possible redirects in a GET request # Authentication will occcur using a POST request on the final URL - response = requests.get(self.host.vpn_url) + response = get_legacy_session().get(self.host.vpn_url) response.raise_for_status() self.host.address = response.url logger.debug("Auth target url", url=self.host.vpn_url) @@ -91,7 +121,7 @@ class AuthResponseError(AuthenticationError): def create_http_session(proxy, version): - session = requests.Session() + session = get_legacy_session() session.proxies = {"http": proxy, "https": proxy} session.headers.update( { @@ -158,7 +188,7 @@ def parse_auth_request_response(xml): token_cookie_name=xml.auth["sso-v2-token-cookie-name"], ) except AttributeError as exc: - raise AuthResponseError(exc) + raise AuthResponseError(exc) from exc logger.info( "Response received",