Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
upstream pull request fritzy#470 (fritzy#470): avoid using SSLv3 on u…
…nsupported systems
  • Loading branch information
thusser committed Nov 10, 2017
1 parent 7075a3b commit 95f8cbe
Showing 1 changed file with 19 additions and 6 deletions.
25 changes: 19 additions & 6 deletions sleekxmpp/xmlstream/xmlstream.py
Expand Up @@ -126,9 +126,13 @@ def __init__(self, socket=None, host='', port=0, certfile=None,
#:
#: Most XMPP servers support TLSv1 or newer, however, if you really have to
#: connect to systems with insecure SSLv3, you may set :attr:`ssl_version`
#: as ``ssl.PROTOCOL_SSLv3``. Other values are ignored by current implementation.
#: as ``ssl.PROTOCOL_SSLv3``. Please note that many systems have removed,
#: SSLv3, it is not possible to use it anymore, specifying SSLv3 on these
#: system can trigger errors and exceptions. Other values are ignored by
#: current implementation.
#:
#: import ssl
#: # triggers AttributeError for systems that removed SSLv3
#: xmpp.ssl_version = ssl.PROTOCOL_SSLv3
self.ssl_version = ssl.PROTOCOL_SSLv23

Expand Down Expand Up @@ -430,6 +434,9 @@ def _create_secure_socket(self):
'!aNULL:!eNULL:!MD5:!3DES'
)

# Some systems have disabled SSLv3 completely at build time.
sslv3_available = hasattr(ssl, "PROTOCOL_SSLv3")

log.info(
"Using SSL/TLS version: %s",
ssl.get_protocol_name(self.ssl_version).replace('PROTOCOL_', '', 1)
Expand All @@ -440,6 +447,12 @@ def _create_secure_socket(self):
"supported versions, actually TLSv1.0+, since SSLv2 and "
"SSLv3 is disabled."
)
if not sslv3_available:
log.info(
"SSLv3 is removed by your system for good, because of its insecurity. "
"If you have legacy systems and compatibility issues, upgrading "
"them to TLS should be the right way to go."
)

if self.ca_certs is None:
cert_policy = ssl.CERT_NONE
Expand All @@ -459,7 +472,7 @@ def _create_secure_socket(self):
# Good, create_default_context() is supported, which consists
# recommended security settings by default.
ctx = ssl.create_default_context()
if self.ssl_version == ssl.PROTOCOL_SSLv3:
if sslv3_available and self.ssl_version == ssl.PROTOCOL_SSLv3:
# But if the user specifies insecure SSLv3, do a favor.
ctx.options &= ~ssl.OP_NO_SSLv3 # UNSET NO_SSLv3, or set SSLv3
ctx.set_ciphers(_CIPHERS_SSL) # _CIPHERS_SSL is weaker
Expand All @@ -473,7 +486,7 @@ def _create_secure_socket(self):
ctx.load_verify_locations(cafile=self.ca_certs)
else:
# Oops, create_default_context() is not supported.
if self.ssl_version == ssl.PROTOCOL_SSLv3:
if sslv3_available and self.ssl_version == ssl.PROTOCOL_SSLv3:
# First, if the user specifies insecure SSLv3, do a favor.
ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv3)
ctx.set_ciphers(_CIPHERS_SSL)
Expand All @@ -497,7 +510,7 @@ def _create_secure_socket(self):
elif sys.version_info >= (2, 7, 9):
# Good, create_default_context() is supported, do the same as Python 3.4.
ctx = ssl.create_default_context()
if self.ssl_version == ssl.PROTOCOL_SSLv3:
if sslv3_available and self.ssl_version == ssl.PROTOCOL_SSLv3:
# If the user specifies insecure SSLv3, do a favor.
ctx.options &= ~ssl.OP_NO_SSLv3
ctx.set_ciphers(_CIPHERS_SSL)
Expand All @@ -508,7 +521,7 @@ def _create_secure_socket(self):
elif cert_policy == ssl.CERT_REQUIRED:
ctx.load_verify_locations(cafile=self.ca_certs)
else:
if self.ssl_version == ssl.PROTOCOL_SSLv3:
if sslv3_available and self.ssl_version == ssl.PROTOCOL_SSLv3:
ssl_args['ssl_version'] = ssl.PROTOCOL_SSLv3
else:
ssl_args['ssl_version'] = ssl.PROTOCOL_TLSv1
Expand Down Expand Up @@ -1892,4 +1905,4 @@ def exception(self, exception):
XMLStream.sendRaw = XMLStream.send_raw
XMLStream.getId = XMLStream.get_id
XMLStream.getNewId = XMLStream.new_id
XMLStream.sendXML = XMLStream.send_xml
XMLStream.sendXML = XMLStream.send_xml

0 comments on commit 95f8cbe

Please sign in to comment.