From f3d61ae5be1d7bda26f46506172187ede5e42f31 Mon Sep 17 00:00:00 2001 From: Sergei Maertens Date: Wed, 10 Jul 2024 14:41:46 +0200 Subject: [PATCH] :sparkles: [#403] Support cafile and capath parameters When retrieving the IDP metadata, you can now optionally specify the the capath or cafile to use for certificate verification, rather than just enabling/disabling it. This allows TLS verification of server certificates that are not in the system root store (such as when using private CAs). --- src/onelogin/saml2/idp_metadata_parser.py | 33 ++++++++++++++--------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/onelogin/saml2/idp_metadata_parser.py b/src/onelogin/saml2/idp_metadata_parser.py index 6710ff1f..b3b3d9be 100644 --- a/src/onelogin/saml2/idp_metadata_parser.py +++ b/src/onelogin/saml2/idp_metadata_parser.py @@ -6,11 +6,7 @@ from copy import deepcopy - -try: - import urllib.request as urllib2 -except ImportError: - import urllib2 +from urllib.request import Request, urlopen import ssl @@ -27,7 +23,15 @@ class OneLogin_Saml2_IdPMetadataParser(object): """ @classmethod - def get_metadata(cls, url, validate_cert=True, timeout=None, headers=None): + def get_metadata( + cls, + url, + validate_cert=True, + cafile=None, + capath=None, + timeout=None, + headers=None, + ): """ Gets the metadata XML from the provided URL :param url: Url where the XML of the Identity Provider Metadata is published. @@ -46,15 +50,20 @@ def get_metadata(cls, url, validate_cert=True, timeout=None, headers=None): """ valid = False - request = urllib2.Request(url, headers=headers or {}) - - if validate_cert: - response = urllib2.urlopen(request, timeout=timeout) - else: + # Respect the no-TLS-certificate validation option + ctx = None + if not validate_cert: + if cafile or capath: + raise ValueError( + "Specifying 'cafile' or 'capath' while disabling certificate " + "validation is contradictory." + ) ctx = ssl.create_default_context() ctx.check_hostname = False ctx.verify_mode = ssl.CERT_NONE - response = urllib2.urlopen(request, context=ctx, timeout=timeout) + + request = Request(url, headers=headers or {}) + response = urlopen(request, timeout=timeout, cafile=cafile, capath=capath, context=ctx) xml = response.read() if xml: