Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tls: add custom_ssl_context parameter #1161

Draft
wants to merge 5 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 39 additions & 3 deletions ldap3/core/tls.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,32 @@ def __init__(self,
local_private_key_password=None,
ciphers=None,
sni=None,
peer_certificate=None):
peer_certificate=None,
custom_ssl_context=None):
if custom_ssl_context is not None:
if not use_ssl_context:
if log_enabled(ERROR):
log(ERROR, 'cannot use custom_ssl_context, SSLContext not available')
raise LDAPSSLNotSupportedError('cannot use custom_ssl_context, SSLContext not available')
if not isinstance(custom_ssl_context, ssl.SSLContext):
if log_enabled(ERROR):
log(ERROR, 'custom_ssl_context must be an ssl.SSLContext object')
raise LDAPSSLNotSupportedError('custom_ssl_context must be an ssl.SSLContext object')
if not (local_private_key_file is None and
local_certificate_file is None and
validate == ssl.CERT_NONE and
version is None and
ssl_options is None and
ca_certs_file is None and
ca_certs_path is None and
ca_certs_data is None and
local_private_key_password is None and
ciphers is None and
peer_certificate is None):
if log_enabled(ERROR):
log(ERROR, 'cannot specify other parameters when using custom_ssl_context (except for sni and valid_names)')
raise LDAPSSLConfigurationError('cannot specify other parameters when using custom_ssl_context (except for sni and valid_names)')
self.custom_ssl_context = custom_ssl_context
if ssl_options is None:
ssl_options = []
self.ssl_options = ssl_options
Expand Down Expand Up @@ -152,7 +177,8 @@ def __str__(self):
'verify mode: ' + str(self.validate),
'valid names: ' + str(self.valid_names),
'ciphers: ' + str(self.ciphers),
'sni: ' + str(self.sni)
'sni: ' + str(self.sni),
'custom_ssl_context: ' + ('present ' if self.custom_ssl_context else 'not present')
]
return ' - '.join(s)

Expand All @@ -166,14 +192,24 @@ def __repr__(self):
r += '' if self.ca_certs_data is None else ', ca_certs_data={0.ca_certs_data!r}'.format(self)
r += '' if self.ciphers is None else ', ciphers={0.ciphers!r}'.format(self)
r += '' if self.sni is None else ', sni={0.sni!r}'.format(self)
r += '' if self.custom_ssl_context is None else ', custom_ssl_context={0.custom_ssl_context!r}'.format(self)
r = 'Tls(' + r[2:] + ')'
return r

def wrap_socket(self, connection, do_handshake=False):
"""
Adds TLS to the connection socket
"""
if use_ssl_context:
if self.custom_ssl_context is not None:
ssl_context = self.custom_ssl_context
if self.sni:
wrapped_socket = ssl_context.wrap_socket(connection.socket, server_side=False, do_handshake_on_connect=do_handshake, server_hostname=self.sni)
else:
wrapped_socket = ssl_context.wrap_socket(connection.socket, server_side=False, do_handshake_on_connect=do_handshake)
self.validate = ssl_context.verify_mode
if log_enabled(NETWORK):
log(NETWORK, 'socket wrapped with SSL using custom SSLContext for <%s>', connection)
elif use_ssl_context:
if self.version is None: # uses the default ssl context for reasonable security
ssl_context = create_default_context(purpose=Purpose.SERVER_AUTH,
cafile=self.ca_certs_file,
Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pyasn1>=0.4.6
pycryptodomex
winkerberos
winkerberos; platform_system=='Windows'
gssapi; platform_system!='Windows'