changeset 900625d7869c in /home/hg/repos/python-nbxmpp
details:http://hg.gajim.org/python-nbxmpp?cmd=changeset;node=900625d7869c description: Add ability to configure TLS protocol version. Add support for tls_version parameter.
Fixes #17
diffstat:
nbxmpp/bosh.py | 6 ++++-- nbxmpp/client_nb.py | 10 ++++++---- nbxmpp/tls_nb.py | 22 +++++++++++++++++++++- nbxmpp/transports_nb.py | 14 ++++++++------ 4 files changed, 39 insertions(+), 13 deletions(-)
diffs (194 lines):
diff -r 1196b6ac3d82 -r 900625d7869c nbxmpp/bosh.py --- a/nbxmpp/bosh.py Tue Feb 18 09:27:16 2014 +0100 +++ b/nbxmpp/bosh.py Mon Jan 27 16:28:32 2014 +0100 @@ -40,9 +40,9 @@
class NonBlockingBOSH(NonBlockingTransport): def __init__(self, raise_event, on_disconnect, idlequeue, estabilish_tls, - certs, cipher_list, xmpp_server, domain, bosh_dict, proxy_creds): + certs, tls_version, cipher_list, xmpp_server, domain, bosh_dict, proxy_creds): NonBlockingTransport.__init__(self, raise_event, on_disconnect, - idlequeue, estabilish_tls, certs, cipher_list) + idlequeue, estabilish_tls, certs, tls_version, cipher_list)
self.bosh_sid = None if locale.getdefaultlocale()[0]: @@ -70,6 +70,7 @@ self.bosh_secure = 'true' else: self.bosh_secure = 'false' + self.tls_version = tls_version self.cipher_list = cipher_list self.use_proxy_auth = bosh_dict['useauth'] self.proxy_creds = proxy_creds @@ -451,6 +452,7 @@ on_disconnect=self.disconnect, idlequeue = self.idlequeue, estabilish_tls = self.estabilish_tls, + tls_version = self.tls_version, cipher_list = self.cipher_list, certs = self.certs, on_http_request_possible = self.on_http_request_possible, diff -r 1196b6ac3d82 -r 900625d7869c nbxmpp/client_nb.py --- a/nbxmpp/client_nb.py Tue Feb 18 09:27:16 2014 +0100 +++ b/nbxmpp/client_nb.py Mon Jan 27 16:28:32 2014 +0100 @@ -163,19 +163,19 @@ values for keys 'host' and 'port' - connection details for proxy serve and optionally keys 'user' and 'pass' as proxy credentials :param secure_tuple: tuple of (desired connection type, cacerts, - mycerts, cipher_list) + mycerts, tls_version, cipher_list) connection type can be 'ssl' - TLS established after TCP connection, 'tls' - TLS established after negotiation with starttls, or 'plain'. - cacerts, mycerts, cipher_list - see tls_nb.NonBlockingTLS + cacerts, mycerts, tls_version, cipher_list - see tls_nb.NonBlockingTLS constructor for more details """ self.on_connect = on_connect self.on_connect_failure=on_connect_failure self.on_proxy_failure = on_proxy_failure self.on_stream_error_cb = on_stream_error_cb - self.desired_security, self.cacerts, self.mycerts, self.cipher_list = \ - secure_tuple + self.desired_security, self.cacerts, self.mycerts, self.tls_version, \ + self.cipher_list = secure_tuple self.Connection = None self.Port = port self.proxy = proxy @@ -212,6 +212,7 @@ idlequeue=self.idlequeue, estabilish_tls=establish_tls, certs=certs, + tls_version = self.tls_version, cipher_list = self.cipher_list, proxy_creds=(proxy_user, proxy_pass), xmpp_server=(self.xmpp_hostname, self.Port), @@ -234,6 +235,7 @@ idlequeue=self.idlequeue, estabilish_tls=establish_tls, certs=certs, + tls_version = self.tls_version, cipher_list = self.cipher_list, proxy_dict=proxy_dict)
diff -r 1196b6ac3d82 -r 900625d7869c nbxmpp/tls_nb.py --- a/nbxmpp/tls_nb.py Tue Feb 18 09:27:16 2014 +0100 +++ b/nbxmpp/tls_nb.py Mon Jan 27 16:28:32 2014 +0100 @@ -250,11 +250,14 @@ PyOpenSSLWrapper. """
- def __init__(self, cacerts, mycerts, cipher_list): + def __init__(self, cacerts, mycerts, tls_version, cipher_list): """ :param cacerts: path to pem file with certificates of known XMPP servers :param mycerts: path to pem file with certificates of user trusted servers + :param tls_version: The lowest supported TLS version. If None is + provided, version 1.0 is used. For example setting to 1.1 will + enable TLS 1.1, TLS 1.2 and all further protocols :param cipher_list: list of ciphers to use when connection to server. If None is provided, a default list is used: HIGH:!aNULL:RC4-SHA """ @@ -265,6 +268,10 @@ self.cipher_list = 'HIGH:!aNULL:RC4-SHA' else: self.cipher_list = cipher_list + if tls_version is None: + self.tls_version = '1.0' + else: + self.tls_version = tls_version
def plugin(self, owner): """ @@ -366,6 +373,19 @@ except AttributeError as e: # py-OpenSSL < 0.9 or old OpenSSL flags |= 16384 + + # OpenSSL 1.0.1d supports TLS 1.1 and TLS 1.2 and + # fixes renegotiation in TLS 1.1, 1.2 by using the correct TLS version. + if OpenSSL.SSL.OPENSSL_VERSION_NUMBER >= 0x1000104f: + if self.tls_version != '1.0': + flags |= OpenSSL.SSL.OP_NO_TLSv1 + if self.tls_version not in ('1.0', '1.1'): + try: + flags |= OpenSSL.SSL.OP_NO_TLSv1_1 + except AttributeError, e: + # older py-OpenSSL + flags |= 0x10000000 + tcpsock._sslContext.set_options(flags)
# NonBlockingHTTPBOSH instance has no attribute _owner diff -r 1196b6ac3d82 -r 900625d7869c nbxmpp/transports_nb.py --- a/nbxmpp/transports_nb.py Tue Feb 18 09:27:16 2014 +0100 +++ b/nbxmpp/transports_nb.py Mon Jan 27 16:28:32 2014 +0100 @@ -109,7 +109,7 @@ """
def __init__(self, raise_event, on_disconnect, idlequeue, estabilish_tls, - certs, cipher_list): + certs, tls_version, cipher_list): """ Each trasport class can have different constructor but it has to have at least all the arguments of NonBlockingTransport constructor @@ -121,6 +121,7 @@ after TCP connection is done :param certs: tuple of (cacerts, mycerts) see constructor of tls_nb.NonBlockingTLS for more details + :param tls_version: The lowest supported TLS version. :param cipher_list: list of ciphers used to connect to server """ PlugIn.__init__(self) @@ -136,6 +137,7 @@ self.set_state(DISCONNECTED) self.estabilish_tls = estabilish_tls self.certs = certs + self.tls_version = tls_version self.cipher_list = cipher_list # type of used ssl lib (if any) will be assigned to this member var self.ssl_lib = None @@ -295,12 +297,12 @@ estabilish TLS connection. """ def __init__(self, raise_event, on_disconnect, idlequeue, estabilish_tls, - certs, cipher_list, proxy_dict=None): + certs, tls_version, cipher_list, proxy_dict=None): """ :param proxy_dict: dictionary with proxy data as loaded from config file """ NonBlockingTransport.__init__(self, raise_event, on_disconnect, - idlequeue, estabilish_tls, certs, cipher_list) + idlequeue, estabilish_tls, certs, tls_version, cipher_list) IdleObject.__init__(self)
# queue with messages to be send @@ -410,7 +412,7 @@ """ cacerts, mycerts = self.certs result = tls_nb.NonBlockingTLS.get_instance(cacerts, mycerts, - self.cipher_list).PlugIn(self) + self.tls_version, self.cipher_list).PlugIn(self) if result: on_succ() else: @@ -664,7 +666,7 @@ """
def __init__(self, raise_event, on_disconnect, idlequeue, estabilish_tls, - certs, cipher_list, on_http_request_possible, on_persistent_fallback, + certs, tls_version, cipher_list, on_http_request_possible, on_persistent_fallback, http_dict, proxy_dict=None): """ :param on_http_request_possible: method to call when HTTP request to @@ -674,7 +676,7 @@ :param http_dict: dictionary with data for HTTP request and headers """ NonBlockingTCP.__init__(self, raise_event, on_disconnect, idlequeue, - estabilish_tls, certs, cipher_list, proxy_dict) + estabilish_tls, certs, tls_version, cipher_list, proxy_dict)
self.http_protocol, self.http_host, self.http_port, self.http_path = \ urisplit(http_dict['http_uri'])