Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 44d7b9f

Browse files
author
ddraganov
committed
Python 3.12 compatibility - closes #1057
There are two Python 3.12 changes that affect the pyVmomi client - Python 3.12 removes ssl.wrap_socket(), deprecated in Python 3.7. ssl.SSLContext.wrap_socket() should be used instead. Ref. https://docs.python.org/3/whatsnew/3.12.html#ssl - key_file, cert_file are removed from http.client.HTTPSConnection. Ref. https://docs.python.org/3/whatsnew/3.12.html#others This change: - The connection logic is refactored to comply with the new Python rules. Python now forces users to generate the SSL context on their own. However, the SoapStubAdapter still has to accept the cert and key pair and SSL context at the same time to keep backwards compatibility for all existing tests and clients. To do that, instead of relying on the http module to generate the SSL context if none is provided, the SoapStubAdapter now handles that generation by mirroring the http module code before the Python 3.12 changes. Because the SSL context generation is pulled to be executed as early as possible there is no need to figure out what parameters are acceptable to pass to the Python http module because the context is already generated. Therefore, the HTTP connection wrappers can be removed - _HTTPConnection and _HTTPSConnection. - ssl.create_default_context() is replaced with SSL._create_default_https_context() to mirror the HTTP module logic. This change is propagated to the sso.py module to keep the behavior consistent. Additional changes: Breaking change: - SSLTunnelConnection is trimmed down to handle only tunnel connections. The code that handles remote proxy doubles the HTTPProxyConnection logic and therefore is removed. This is a breaking change for consumers that wrongly set "sslProxyPath" instead of "httpProxyHost" when they want to go through a remote proxy but I consider this a necessary change because allowing this behavior is a bug and shouldn't have been available at first place. Non-breaking changes: - SSLTunnelConnection now inherits HTTPProxyConnection and overwrites the call method because the constructor is the same. Keep in mind that it's deprecated. Hopefully it will be removed sooner rather than later. - _CheckIPv4(), _CheckIPv6() and _CheckHostname() are removed because it's not necessary to make those verifications when SSLTunnelConnection does not support remote proxies. - Small changes to variable names and imports
1 parent c248b32 commit 44d7b9f

2 files changed

Lines changed: 90 additions & 252 deletions

File tree

pyVim/sso.py

Lines changed: 21 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
#############################################################
2-
# Copyright (c) 2012-2024 VMware, Inc.
2+
# Copyright (c) 2012-2024 Broadcom. All Rights Reserved.
3+
# The term "Broadcom" refers to Broadcom Inc.
4+
# and/or its subsidiaries.
35
# A python helper module to do SSO related operations.
46
#############################################################
57
__author__ = 'VMware, Inc.'
68

79
#Standard library imports.
8-
import six.moves.http_client
10+
from six.moves.http_client import HTTPConnection, HTTPSConnection
911
import re
1012
from six import PY3
1113
if PY3:
@@ -101,30 +103,11 @@ def __str__(self):
101103
"faultxml: %(_soap_msg)s" % self.__dict__)
102104

103105

104-
class SSOHTTPConnection(six.moves.http_client.HTTPConnection):
105-
"""
106-
A class that establishes HTTP Connection.
107-
Only intened to be used for calls routing through
108-
a local sidecar proxy (localhost:1080).
109-
"""
110-
def __init__(self, *args, **kwargs):
111-
"""
112-
Initializer. See httplib.HTTPConnection for other arguments
113-
"""
114-
tmpKwargs = {}
115-
httpConn = six.moves.http_client.HTTPConnection
116-
for key in httpConn.__init__.__code__.co_varnames:
117-
if key in kwargs and key != 'self':
118-
tmpKwargs[key] = kwargs[key]
119-
self.host = kwargs.pop('host')
120-
six.moves.http_client.HTTPConnection.__init__(self, *args, **tmpKwargs)
121-
122-
123-
class SSOHTTPSConnection(six.moves.http_client.HTTPSConnection):
106+
class _SSOHTTPSConnection(HTTPSConnection):
124107
"""
125108
An HTTPS class that verifies server's certificate on connect.
126109
"""
127-
def __init__(self, *args, **kwargs):
110+
def __init__(self, host, context, thumbprint=None, server_cert=None):
128111
"""
129112
Initializer. See httplib.HTTPSConnection for other arguments
130113
than thumbprint and server_cert.
@@ -140,18 +123,18 @@ def __init__(self, *args, **kwargs):
140123
@param server_cert: File with expected server certificate.
141124
May be None.
142125
"""
143-
self.server_thumbprint = kwargs.pop('thumbprint')
126+
self.server_thumbprint = thumbprint
144127
if self.server_thumbprint is not None:
145128
self.server_thumbprint = re.sub(':', '',
146129
self.server_thumbprint.lower())
147-
server_cert_path = kwargs.pop('server_cert')
130+
server_cert_path = server_cert
148131
if server_cert_path is not None:
149132
with open(server_cert_path, 'rb') as f:
150133
server_cert = f.read().decode(UTF_8)
151134
self.server_cert = _extract_certificate(server_cert)
152135
else:
153136
self.server_cert = None
154-
six.moves.http_client.HTTPSConnection.__init__(self, *args, **kwargs)
137+
HTTPSConnection.__init__(self, host=host, context=context)
155138

156139
def _check_cert(self, peerCert):
157140
"""
@@ -182,7 +165,7 @@ def connect(self):
182165
Throws an exception when something is wrong. See
183166
httplib.HTTPSConnection.connect() for details.
184167
"""
185-
six.moves.http_client.HTTPSConnection.connect(self)
168+
HTTPSConnection.connect(self)
186169

187170
self._check_cert(self.sock.getpeercert(True))
188171

@@ -240,7 +223,6 @@ def perform_request(self,
240223
user registered with SSO, in PEM format.
241224
@type ssl_context: C{ssl.SSLContext}
242225
@param ssl_context: SSL context describing the various SSL options.
243-
It is only supported in Python 2.7.9 or higher.
244226
@rtype: C{str}
245227
@return: Response received from the STS after the HoK request.
246228
"""
@@ -249,29 +231,25 @@ def perform_request(self,
249231
scheme = parsed.scheme
250232
encoded_message = soap_message.encode(UTF_8)
251233

234+
if ssl_context is not None:
235+
sslContext = ssl_context
236+
else:
237+
sslContext = ssl._create_default_https_context()
238+
if public_key and private_key:
239+
sslContext.load_cert_chain(public_key, private_key)
240+
252241
"""
253242
Allow creation of HTTPConnection, only for calls routing
254243
through local sidecar (localhost:1080)
255244
"""
256245
if is_sidecar_request(scheme, host):
257-
webservice = SSOHTTPConnection(host=host)
258-
elif hasattr(ssl, '_create_unverified_context'):
259-
# Python 2.7.9 has stronger SSL certificate validation, so we need
260-
# to pass in a context when dealing with self-signed certificates.
261-
webservice = SSOHTTPSConnection(host=host,
262-
key_file=private_key,
263-
cert_file=public_key,
246+
webservice = HTTPConnection(host=host)
247+
else:
248+
webservice = _SSOHTTPSConnection(host=host,
264249
server_cert=self._sts_cert,
265250
thumbprint=self._sts_thumbprint,
266251
context=ssl_context)
267-
else:
268-
# Versions of Python before 2.7.9 don't support
269-
# the context parameter, so don't pass it on.
270-
webservice = SSOHTTPSConnection(host=host,
271-
key_file=private_key,
272-
cert_file=public_key,
273-
server_cert=self._sts_cert,
274-
thumbprint=self._sts_thumbprint)
252+
275253

276254
webservice.putrequest("POST", parsed.path, skip_host=True) # pylint: disable=E1101
277255
webservice.putheader("Host", host)
@@ -342,7 +320,6 @@ def get_bearer_saml_assertion(self,
342320
The default value is False
343321
@type ssl_context: C{ssl.SSLContext}
344322
@param ssl_context: SSL context describing the various SSL options.
345-
It is only supported in Python 2.7.9 or higher.
346323
@rtype: C{str}
347324
@return: The SAML assertion in Unicode.
348325
"""
@@ -398,7 +375,6 @@ def get_hok_saml_assertion(self,
398375
The default value is False
399376
@type ssl_context: C{ssl.SSLContext}
400377
@param ssl_context: SSL context describing the various SSL options.
401-
It is only supported in Python 2.7.9 or higher.
402378
@rtype: C{str}
403379
@return: The SAML assertion in Unicode.
404380
"""
@@ -449,7 +425,6 @@ def get_token_by_token(self,
449425
The default value is False
450426
@type ssl_context: C{ssl.SSLContext}
451427
@param ssl_context: SSL context describing the various SSL options.
452-
It is only supported in Python 2.7.9 or higher.
453428
@rtype: C{str}
454429
@return: The Hok SAML assertion in Unicode.
455430
"""

0 commit comments

Comments
 (0)