7878
7979SHOTGUN_API_DISABLE_ENTITY_OPTIMIZATION = False
8080
81- NO_SSL_VALIDATION = False
82- """
83- Turns off hostname matching validation for SSL certificates
84-
85- Sometimes there are cases where certificate validation should be disabled. For example, if you
86- have a self-signed internal certificate that isn't included in our certificate bundle, you may
87- not require the added security provided by enforcing this.
88- """
8981
9082# ----------------------------------------------------------------------------
9183# Version
@@ -327,9 +319,7 @@ class ClientCapabilities(object):
327319 :ivar str local_path_field: The PTR field used for local file paths. This is calculated using
328320 the value of ``platform``. Ex. ``local_path_mac``.
329321 :ivar str py_version: Simple version of Python executable as a string. Eg. ``3.9``.
330- :ivar str ssl_version: Version of OpenSSL installed. Eg. ``OpenSSL 1.0.2g 1 Mar 2016``. This
331- info is only available in Python 2.7+ if the ssl module was imported successfully.
332- Defaults to ``unknown``
322+ :ivar str ssl_version: Version of OpenSSL installed. Eg. ``OpenSSL 1.0.2g 1 Mar 2016``.
333323 """
334324
335325 def __init__ (self ):
@@ -350,14 +340,7 @@ def __init__(self):
350340 self .local_path_field = None
351341
352342 self .py_version = "." .join (str (x ) for x in sys .version_info [:2 ])
353-
354- # extract the OpenSSL version if we can. The version is only available in Python 2.7 and
355- # only if we successfully imported ssl
356- self .ssl_version = "unknown"
357- try :
358- self .ssl_version = ssl .OPENSSL_VERSION
359- except (AttributeError , NameError ):
360- pass
343+ self .ssl_version = ssl .OPENSSL_VERSION
361344
362345 def __str__ (self ):
363346 return (
@@ -425,7 +408,6 @@ def __init__(self, sg):
425408 self .proxy_pass = None
426409 self .session_token = None
427410 self .authorization = None
428- self .no_ssl_validation = False
429411 self .localized = False
430412
431413 def set_server_params (self , base_url ):
@@ -616,7 +598,6 @@ def __init__(
616598 self .config .session_token = session_token
617599 self .config .sudo_as_login = sudo_as_login
618600 self .config .convert_datetimes_to_utc = convert_datetimes_to_utc
619- self .config .no_ssl_validation = NO_SSL_VALIDATION
620601 self .config .raw_http_proxy = http_proxy
621602
622603 try :
@@ -2264,14 +2245,10 @@ def reset_user_agent(self):
22642245 ua_platform = self .client_caps .platform .capitalize ()
22652246
22662247 # create ssl validation string based on settings
2267- validation_str = "validate"
2268- if self .config .no_ssl_validation :
2269- validation_str = "no-validate"
2270-
22712248 self ._user_agents = [
22722249 "shotgun-json (%s)" % __version__ ,
22732250 "Python %s (%s)" % (self .client_caps .py_version , ua_platform ),
2274- "ssl %s (%s) " % (self .client_caps .ssl_version , validation_str ),
2251+ "ssl %s" % (self .client_caps .ssl_version ),
22752252 ]
22762253
22772254 def set_session_uuid (self , session_uuid ):
@@ -3543,8 +3520,14 @@ def _build_opener(self, handler):
35433520 Build urllib2 opener with appropriate proxy handler.
35443521 """
35453522 handlers = []
3546- if self .__ca_certs and not NO_SSL_VALIDATION :
3547- handlers .append (CACertsHTTPSHandler (self .__ca_certs ))
3523+ if self .__ca_certs :
3524+ handlers .append (
3525+ urllib .request .HTTPSHandler (
3526+ context = ssl .create_default_context (
3527+ cafile = self .__ca_certs ,
3528+ ),
3529+ ),
3530+ )
35483531
35493532 if self .config .proxy_handler :
35503533 handlers .append (self .config .proxy_handler )
@@ -3613,23 +3596,6 @@ def _get_certs_file(cls, ca_certs):
36133596 cert_file = os .path .join (cur_dir , "lib" , "certifi" , "cacert.pem" )
36143597 return cert_file
36153598
3616- def _turn_off_ssl_validation (self ):
3617- """
3618- Turn off SSL certificate validation.
3619- """
3620- global NO_SSL_VALIDATION
3621- self .config .no_ssl_validation = True
3622- NO_SSL_VALIDATION = True
3623- # reset ssl-validation in user-agents
3624- self ._user_agents = [
3625- (
3626- "ssl %s (no-validate)" % self .client_caps .ssl_version
3627- if ua .startswith ("ssl " )
3628- else ua
3629- )
3630- for ua in self ._user_agents
3631- ]
3632-
36333599 # Deprecated methods from old wrapper
36343600 def schema (self , entity_type ):
36353601 """
@@ -3843,44 +3809,7 @@ def _make_call(self, verb, path, body, headers):
38433809 if attempt == max_rpc_attempts :
38443810 LOG .debug ("Request failed. Giving up after %d attempts." % attempt )
38453811 raise
3846- # This is the exact same block as the "except Exception" bellow.
3847- # We need to do it here because the next except will match it
3848- # otherwise and will not re-attempt.
3849- # When we drop support of Python 2 and we will probably drop the
3850- # next except, we might want to remove this except too.
38513812 except (ssl .SSLError , ssl .CertificateError ) as e :
3852- # Test whether the exception is due to the fact that this is an older version of
3853- # Python that cannot validate certificates encrypted with SHA-2. If it is, then
3854- # fall back on disabling the certificate validation and try again - unless the
3855- # SHOTGUN_FORCE_CERTIFICATE_VALIDATION environment variable has been set by the
3856- # user. In that case we simply raise the exception. Any other exceptions simply
3857- # get raised as well.
3858- #
3859- # For more info see:
3860- # https://www.shotgridsoftware.com/blog/important-ssl-certificate-renewal-and-sha-2/
3861- #
3862- # SHA-2 errors look like this:
3863- # [Errno 1] _ssl.c:480: error:0D0C50A1:asn1 encoding routines:ASN1_item_verify:
3864- # unknown message digest algorithm
3865- #
3866- # Any other exceptions simply get raised.
3867- if (
3868- "unknown message digest algorithm" not in str (e )
3869- or "SHOTGUN_FORCE_CERTIFICATE_VALIDATION" in os .environ
3870- ):
3871- raise
3872-
3873- if self .config .no_ssl_validation is False :
3874- LOG .warning (
3875- "SSL Error: this Python installation is incompatible with "
3876- "certificates signed with SHA-2. Disabling certificate validation. "
3877- "For more information, see https://www.shotgridsoftware.com/blog/"
3878- "important-ssl-certificate-renewal-and-sha-2/"
3879- )
3880- self ._turn_off_ssl_validation ()
3881- # reload user agent to reflect that we have turned off ssl validation
3882- req_headers ["user-agent" ] = "; " .join (self ._user_agents )
3883-
38843813 self ._close_connection ()
38853814 if attempt == max_rpc_attempts :
38863815 LOG .debug ("Request failed. Giving up after %d attempts." % attempt )
@@ -4142,14 +4071,12 @@ def _get_connection(self):
41424071 timeout = self .config .timeout_secs ,
41434072 ca_certs = self .__ca_certs ,
41444073 proxy_info = pi ,
4145- disable_ssl_certificate_validation = self .config .no_ssl_validation ,
41464074 )
41474075 else :
41484076 self ._connection = Http (
41494077 timeout = self .config .timeout_secs ,
41504078 ca_certs = self .__ca_certs ,
41514079 proxy_info = None ,
4152- disable_ssl_certificate_validation = self .config .no_ssl_validation ,
41534080 )
41544081
41554082 return self ._connection
@@ -4613,22 +4540,6 @@ def connect(self):
46134540 )
46144541
46154542
4616- class CACertsHTTPSHandler (urllib .request .HTTPHandler ):
4617- """
4618- Handler that ensures https connections are created with the custom CA certs.
4619- """
4620-
4621- def __init__ (self , cacerts ):
4622- super ().__init__ (self )
4623- self .__ca_certs = cacerts
4624-
4625- def https_open (self , req ):
4626- return self .do_open (self .create_https_connection , req )
4627-
4628- def create_https_connection (self , * args , ** kwargs ):
4629- return CACertsHTTPSConnection (* args , ca_certs = self .__ca_certs , ** kwargs )
4630-
4631-
46324543# Helpers from the previous API, left as is.
46334544# Based on http://code.activestate.com/recipes/146306/
46344545class FormPostHandler (urllib .request .BaseHandler ):
0 commit comments