From acb688c708a4b8ac0ef348f3531e417badd61679 Mon Sep 17 00:00:00 2001 From: Julien Langlois Date: Wed, 5 Jun 2024 08:53:36 -0700 Subject: [PATCH] Custom revert of 3e72b44a to fix the SSLEOFError Could not "git revert" because the files have changed too much --- docs/reference.rst | 7 ++++ shotgun_api3/shotgun.py | 58 +++------------------------------ tests/test_api.py | 71 ----------------------------------------- 3 files changed, 11 insertions(+), 125 deletions(-) diff --git a/docs/reference.rst b/docs/reference.rst index 8c9e6af6..71f9e44b 100644 --- a/docs/reference.rst +++ b/docs/reference.rst @@ -949,6 +949,13 @@ Stores the number of milliseconds to wait between request retries. By default, In the case that both this environment variable and the config's ``rpc_attempt_interval`` property are set, the value in ``rpc_attempt_interal`` will be used. + +SHOTGUN_DISABLE_SSL_VALIDATION +============================== + +TODO + + ************ Localization ************ diff --git a/shotgun_api3/shotgun.py b/shotgun_api3/shotgun.py index 3adacb92..166d36c6 100644 --- a/shotgun_api3/shotgun.py +++ b/shotgun_api3/shotgun.py @@ -42,6 +42,7 @@ import os import re import copy +import ssl import stat # used for attachment upload import sys import time @@ -111,13 +112,7 @@ def _is_mimetypes_broken(): have a self-signed internal certificate that isn't included in our certificate bundle, you may not require the added security provided by enforcing this. """ -try: - import ssl -except ImportError as e: - if "SHOTGUN_FORCE_CERTIFICATE_VALIDATION" in os.environ: - raise ImportError("%s. SHOTGUN_FORCE_CERTIFICATE_VALIDATION environment variable prevents " - "disabling SSL certificate validation." % e) - LOG.debug("ssl not found, disabling certificate validation") +if os.environ.get("SHOTGUN_DISABLE_SSL_VALIDATION", False): NO_SSL_VALIDATION = True # ---------------------------------------------------------------------------- @@ -374,12 +369,11 @@ def __init__(self): self.py_version = ".".join(str(x) for x in sys.version_info[:2]) - # extract the OpenSSL version if we can. The version is only available in Python 2.7 and - # only if we successfully imported ssl + # extract the OpenSSL version if we can. self.ssl_version = "unknown" try: self.ssl_version = ssl.OPENSSL_VERSION - except (AttributeError, NameError): + except AttributeError: pass def __str__(self): @@ -3381,18 +3375,6 @@ def _get_certs_file(cls, ca_certs): cert_file = os.path.join(cur_dir, "lib", "certifi", "cacert.pem") return cert_file - def _turn_off_ssl_validation(self): - """ - Turn off SSL certificate validation. - """ - global NO_SSL_VALIDATION - self.config.no_ssl_validation = True - NO_SSL_VALIDATION = True - # reset ssl-validation in user-agents - self._user_agents = ["ssl %s (no-validate)" % self.client_caps.ssl_version - if ua.startswith("ssl ") else ua - for ua in self._user_agents] - # Deprecated methods from old wrapper def schema(self, entity_type): """ @@ -3594,38 +3576,6 @@ def _make_call(self, verb, path, body, headers): attempt += 1 try: return self._http_request(verb, path, body, req_headers) - except ssl_error_classes as e: - # Test whether the exception is due to the fact that this is an older version of - # Python that cannot validate certificates encrypted with SHA-2. If it is, then - # fall back on disabling the certificate validation and try again - unless the - # SHOTGUN_FORCE_CERTIFICATE_VALIDATION environment variable has been set by the - # user. In that case we simply raise the exception. Any other exceptions simply - # get raised as well. - # - # For more info see: - # https://www.shotgridsoftware.com/blog/important-ssl-certificate-renewal-and-sha-2/ - # - # SHA-2 errors look like this: - # [Errno 1] _ssl.c:480: error:0D0C50A1:asn1 encoding routines:ASN1_item_verify: - # unknown message digest algorithm - # - # Any other exceptions simply get raised. - if "unknown message digest algorithm" not in str(e) or \ - "SHOTGUN_FORCE_CERTIFICATE_VALIDATION" in os.environ: - raise - - if self.config.no_ssl_validation is False: - LOG.warning("SSL Error: this Python installation is incompatible with " - "certificates signed with SHA-2. Disabling certificate validation. " - "For more information, see https://www.shotgridsoftware.com/blog/" - "important-ssl-certificate-renewal-and-sha-2/") - self._turn_off_ssl_validation() - # reload user agent to reflect that we have turned off ssl validation - req_headers["user-agent"] = "; ".join(self._user_agents) - - self._close_connection() - if attempt == max_rpc_attempts: - raise except Exception: self._close_connection() if attempt == max_rpc_attempts: diff --git a/tests/test_api.py b/tests/test_api.py index 4fdaab03..2c4ab92d 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1839,77 +1839,6 @@ def test_status_not_200(self, mock_request): mock_request.return_value = (response, {}) self.assertRaises(shotgun_api3.ProtocolError, self.sg.find_one, 'Shot', []) - @patch('shotgun_api3.shotgun.Http.request') - def test_sha2_error(self, mock_request): - # Simulate the exception raised with SHA-2 errors - mock_request.side_effect = ShotgunSSLError( - "[Errno 1] _ssl.c:480: error:0D0C50A1:asn1 " - "encoding routines:ASN1_item_verify: unknown message digest " - "algorithm" - ) - - # save the original state - original_env_val = os.environ.pop("SHOTGUN_FORCE_CERTIFICATE_VALIDATION", None) - - # ensure we're starting with the right values - self.sg.reset_user_agent() - - # ensure the initial settings are correct. These will be different depending on whether - # the ssl module imported successfully or not. - if "ssl" in sys.modules: - self.assertFalse(self.sg.config.no_ssl_validation) - self.assertFalse(shotgun_api3.shotgun.NO_SSL_VALIDATION) - self.assertTrue("(validate)" in " ".join(self.sg._user_agents)) - self.assertFalse("(no-validate)" in " ".join(self.sg._user_agents)) - else: - self.assertTrue(self.sg.config.no_ssl_validation) - self.assertTrue(shotgun_api3.shotgun.NO_SSL_VALIDATION) - self.assertFalse("(validate)" in " ".join(self.sg._user_agents)) - self.assertTrue("(no-validate)" in " ".join(self.sg._user_agents)) - - try: - self.sg.info() - except ShotgunSSLError: - # ensure the api has reset the values in the correct fallback behavior - self.assertTrue(self.sg.config.no_ssl_validation) - self.assertTrue(shotgun_api3.shotgun.NO_SSL_VALIDATION) - self.assertFalse("(validate)" in " ".join(self.sg._user_agents)) - self.assertTrue("(no-validate)" in " ".join(self.sg._user_agents)) - - if original_env_val is not None: - os.environ["SHOTGUN_FORCE_CERTIFICATE_VALIDATION"] = original_env_val - - @patch('shotgun_api3.shotgun.Http.request') - def test_sha2_error_with_strict(self, mock_request): - # Simulate the exception raised with SHA-2 errors - mock_request.side_effect = ShotgunSSLError( - "[Errno 1] _ssl.c:480: error:0D0C50A1:asn1 " - "encoding routines:ASN1_item_verify: unknown message digest " - "algorithm" - ) - - # save the original state - original_env_val = os.environ.pop("SHOTGUN_FORCE_CERTIFICATE_VALIDATION", None) - os.environ["SHOTGUN_FORCE_CERTIFICATE_VALIDATION"] = "1" - - # ensure we're starting with the right values - self.sg.config.no_ssl_validation = False - shotgun_api3.shotgun.NO_SSL_VALIDATION = False - self.sg.reset_user_agent() - - try: - self.sg.info() - except ShotgunSSLError: - # ensure the api has NOT reset the values in the fallback behavior because we have - # set the env variable to force validation - self.assertFalse(self.sg.config.no_ssl_validation) - self.assertFalse(shotgun_api3.shotgun.NO_SSL_VALIDATION) - self.assertFalse("(no-validate)" in " ".join(self.sg._user_agents)) - self.assertTrue("(validate)" in " ".join(self.sg._user_agents)) - - if original_env_val is not None: - os.environ["SHOTGUN_FORCE_CERTIFICATE_VALIDATION"] = original_env_val - @patch.object(urllib.request.OpenerDirector, 'open') def test_sanitized_auth_params(self, mock_open): # Simulate the server blowing up and giving us a 500 error