@@ -126,9 +126,13 @@ def __init__(self, socket=None, host='', port=0, certfile=None,
126126 #:
127127 #: Most XMPP servers support TLSv1 or newer, however, if you really have to
128128 #: connect to systems with insecure SSLv3, you may set :attr:`ssl_version`
129- #: as ``ssl.PROTOCOL_SSLv3``. Other values are ignored by current implementation.
129+ #: as ``ssl.PROTOCOL_SSLv3``. Please note that many systems have removed,
130+ #: SSLv3, it is not possible to use it anymore, specifying SSLv3 on these
131+ #: system can trigger errors and exceptions. Other values are ignored by
132+ #: current implementation.
130133 #:
131134 #: import ssl
135+ #: # triggers AttributeError for systems that removed SSLv3
132136 #: xmpp.ssl_version = ssl.PROTOCOL_SSLv3
133137 self .ssl_version = ssl .PROTOCOL_SSLv23
134138
@@ -430,6 +434,9 @@ def _create_secure_socket(self):
430434 '!aNULL:!eNULL:!MD5:!3DES'
431435 )
432436
437+ # Some systems have disabled SSLv3 completely at build time.
438+ sslv3_available = hasattr (ssl , "PROTOCOL_SSLv3" )
439+
433440 log .info (
434441 "Using SSL/TLS version: %s" ,
435442 ssl .get_protocol_name (self .ssl_version ).replace ('PROTOCOL_' , '' , 1 )
@@ -440,6 +447,12 @@ def _create_secure_socket(self):
440447 "supported versions, actually TLSv1.0+, since SSLv2 and "
441448 "SSLv3 is disabled."
442449 )
450+ if not sslv3_available :
451+ log .info (
452+ "SSLv3 is removed by your system for good, because of its insecurity. "
453+ "If you have legacy systems and compatibility issues, upgrading "
454+ "them to TLS should be the right way to go."
455+ )
443456
444457 if self .ca_certs is None :
445458 cert_policy = ssl .CERT_NONE
@@ -459,7 +472,7 @@ def _create_secure_socket(self):
459472 # Good, create_default_context() is supported, which consists
460473 # recommended security settings by default.
461474 ctx = ssl .create_default_context ()
462- if self .ssl_version == ssl .PROTOCOL_SSLv3 :
475+ if sslv3_available and self .ssl_version == ssl .PROTOCOL_SSLv3 :
463476 # But if the user specifies insecure SSLv3, do a favor.
464477 ctx .options &= ~ ssl .OP_NO_SSLv3 # UNSET NO_SSLv3, or set SSLv3
465478 ctx .set_ciphers (_CIPHERS_SSL ) # _CIPHERS_SSL is weaker
@@ -473,7 +486,7 @@ def _create_secure_socket(self):
473486 ctx .load_verify_locations (cafile = self .ca_certs )
474487 else :
475488 # Oops, create_default_context() is not supported.
476- if self .ssl_version == ssl .PROTOCOL_SSLv3 :
489+ if sslv3_available and self .ssl_version == ssl .PROTOCOL_SSLv3 :
477490 # First, if the user specifies insecure SSLv3, do a favor.
478491 ctx = ssl .SSLContext (ssl .PROTOCOL_SSLv3 )
479492 ctx .set_ciphers (_CIPHERS_SSL )
@@ -497,7 +510,7 @@ def _create_secure_socket(self):
497510 elif sys .version_info >= (2 , 7 , 9 ):
498511 # Good, create_default_context() is supported, do the same as Python 3.4.
499512 ctx = ssl .create_default_context ()
500- if self .ssl_version == ssl .PROTOCOL_SSLv3 :
513+ if sslv3_available and self .ssl_version == ssl .PROTOCOL_SSLv3 :
501514 # If the user specifies insecure SSLv3, do a favor.
502515 ctx .options &= ~ ssl .OP_NO_SSLv3
503516 ctx .set_ciphers (_CIPHERS_SSL )
@@ -508,7 +521,7 @@ def _create_secure_socket(self):
508521 elif cert_policy == ssl .CERT_REQUIRED :
509522 ctx .load_verify_locations (cafile = self .ca_certs )
510523 else :
511- if self .ssl_version == ssl .PROTOCOL_SSLv3 :
524+ if sslv3_available and self .ssl_version == ssl .PROTOCOL_SSLv3 :
512525 ssl_args ['ssl_version' ] = ssl .PROTOCOL_SSLv3
513526 else :
514527 ssl_args ['ssl_version' ] = ssl .PROTOCOL_TLSv1
@@ -1892,4 +1905,4 @@ def exception(self, exception):
18921905XMLStream .sendRaw = XMLStream .send_raw
18931906XMLStream .getId = XMLStream .get_id
18941907XMLStream .getNewId = XMLStream .new_id
1895- XMLStream .sendXML = XMLStream .send_xml
1908+ XMLStream .sendXML = XMLStream .send_xml
0 commit comments