changeset 2a705299d7e7 in /home/hg/repos/python-nbxmpp
details:http://hg.gajim.org/python-nbxmpp?cmd=changeset;node=2a705299d7e7 description: ability to configure cipher list. see #7
diffstat:
doc/examples/xsend.py | 4 +++- nbxmpp/bosh.py | 8 ++++---- nbxmpp/client_nb.py | 27 ++++++++++++++++----------- nbxmpp/tls_nb.py | 20 ++++++++++---------- nbxmpp/transports_nb.py | 29 ++++++++++++++++------------- 5 files changed, 49 insertions(+), 39 deletions(-)
diffs (232 lines):
diff -r 8b9b9ea9a20d -r 2a705299d7e7 doc/examples/xsend.py --- a/doc/examples/xsend.py Sun Nov 03 13:47:50 2013 +0100 +++ b/doc/examples/xsend.py Sun Nov 03 17:55:20 2013 +0100 @@ -35,6 +35,8 @@ def __init__(self): self.jid = nbxmpp.protocol.JID(jidparams['jid']) self.password = jidparams['password'] + self.sm = nbxmpp.Smacks(self) # Stream Management + self.client_cert = None
def on_auth(self, con, auth): if not auth: @@ -59,7 +61,7 @@ def connect(self): idle_queue = nbxmpp.idlequeue.get_idlequeue() self.client = nbxmpp.NonBlockingClient(self.jid.getDomain(), idle_queue, caller=self) - self.con = self.client.connect(self.on_connected, self.on_connection_failed, secure_tuple=('tls', '', '')) + self.con = self.client.connect(self.on_connected, self.on_connection_failed, secure_tuple=('tls', '', '', None))
def send_message(self, to_jid, text): id_ = self.client.send(nbxmpp.protocol.Message(to_jid, text, typ='chat')) diff -r 8b9b9ea9a20d -r 2a705299d7e7 nbxmpp/bosh.py --- a/nbxmpp/bosh.py Sun Nov 03 13:47:50 2013 +0100 +++ b/nbxmpp/bosh.py Sun Nov 03 17:55:20 2013 +0100 @@ -37,10 +37,10 @@
class NonBlockingBOSH(NonBlockingTransport): - def __init__(self, raise_event, on_disconnect, idlequeue, estabilish_tls, certs, - xmpp_server, domain, bosh_dict, proxy_creds): - NonBlockingTransport.__init__(self, raise_event, on_disconnect, idlequeue, - estabilish_tls, certs) + def __init__(self, raise_event, on_disconnect, idlequeue, estabilish_tls, + certs, cipher_list, xmpp_server, domain, bosh_dict, proxy_creds): + NonBlockingTransport.__init__(self, raise_event, on_disconnect, + idlequeue, estabilish_tls, certs, cipher_list)
self.bosh_sid = None if locale.getdefaultlocale()[0]: diff -r 8b9b9ea9a20d -r 2a705299d7e7 nbxmpp/client_nb.py --- a/nbxmpp/client_nb.py Sun Nov 03 13:47:50 2013 +0100 +++ b/nbxmpp/client_nb.py Sun Nov 03 17:55:20 2013 +0100 @@ -149,7 +149,7 @@
def connect(self, on_connect, on_connect_failure, hostname=None, port=5222, on_proxy_failure=None, on_stream_error_cb=None, proxy=None, - secure_tuple=('plain', None, None)): + secure_tuple=('tls', None, None, None)): """ Open XMPP connection (open XML streams in both directions)
@@ -157,22 +157,25 @@ :param on_connect_failure: called when error occures during connection :param hostname: hostname of XMPP server from SRV request :param port: port number of XMPP server - :param on_proxy_failure: called if error occurres during TCP connection to - proxy server or during proxy connecting process + :param on_proxy_failure: called if error occurres during TCP connection + to proxy server or during proxy connecting process :param proxy: dictionary with proxy data. It should contain at least - 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) - connection type can be 'ssl' - TLS established after TCP connection, - 'tls' - TLS established after negotiation with starttls, or 'plain'. - cacerts, mycerts - see tls_nb.NonBlockingTLS constructor for more - details + 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) + 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 + 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 = secure_tuple + self.desired_security, self.cacerts, self.mycerts, self.cipher_list = \ + secure_tuple self.Connection = None self.Port = port self.proxy = proxy @@ -209,6 +212,7 @@ idlequeue=self.idlequeue, estabilish_tls=establish_tls, certs=certs, + cipher_list = self.cipher_list, proxy_creds=(proxy_user, proxy_pass), xmpp_server=(self.xmpp_hostname, self.Port), domain=self.Server, @@ -230,6 +234,7 @@ idlequeue=self.idlequeue, estabilish_tls=establish_tls, certs=certs, + cipher_list = self.cipher_list, proxy_dict=proxy_dict)
# plug transport into client as self.Connection diff -r 8b9b9ea9a20d -r 2a705299d7e7 nbxmpp/tls_nb.py --- a/nbxmpp/tls_nb.py Sun Nov 03 13:47:50 2013 +0100 +++ b/nbxmpp/tls_nb.py Sun Nov 03 17:55:20 2013 +0100 @@ -250,21 +250,21 @@ PyOpenSSLWrapper. """
- def __init__(self, cacerts, mycerts): + def __init__(self, cacerts, mycerts, 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 mycerts: path to pem file with certificates of user trusted + servers + :param cipher_list: list of ciphers to use when connection to server. If + None is provided, a default list is used: HIGH:!aNULL:!eNULL:RC4-SHA """ PlugIn.__init__(self) self.cacerts = cacerts self.mycerts = mycerts - - # from ssl.h (partial extract) - ssl_h_bits = { "SSL_ST_CONNECT": 0x1000, "SSL_ST_ACCEPT": 0x2000, - "SSL_CB_LOOP": 0x01, "SSL_CB_EXIT": 0x02, - "SSL_CB_READ": 0x04, "SSL_CB_WRITE": 0x08, - "SSL_CB_ALERT": 0x4000, - "SSL_CB_HANDSHAKE_START": 0x10, "SSL_CB_HANDSHAKE_DONE": 0x20} + if cipher_list is None: + self.cipher_list = 'HIGH:!aNULL:!eNULL:RC4-SHA' + else: + self.cipher_list = cipher_list
def plugin(self, owner): """ @@ -403,7 +403,7 @@ tcpsock.ssl_errnum = [] tcpsock._sslContext.set_verify(OpenSSL.SSL.VERIFY_PEER, self._ssl_verify_callback) - tcpsock._sslContext.set_cipher_list('HIGH:!aNULL:!eNULL:RC4-SHA') + tcpsock._sslContext.set_cipher_list(self.cipher_list) store = tcpsock._sslContext.get_cert_store() self._load_cert_file(self.cacerts, store) self._load_cert_file(self.mycerts, store) diff -r 8b9b9ea9a20d -r 2a705299d7e7 nbxmpp/transports_nb.py --- a/nbxmpp/transports_nb.py Sun Nov 03 13:47:50 2013 +0100 +++ b/nbxmpp/transports_nb.py Sun Nov 03 17:55:20 2013 +0100 @@ -109,7 +109,7 @@ """
def __init__(self, raise_event, on_disconnect, idlequeue, estabilish_tls, - certs): + certs, cipher_list): """ Each trasport class can have different constructor but it has to have at least all the arguments of NonBlockingTransport constructor @@ -117,10 +117,11 @@ :param raise_event: callback for monitoring of sent and received data :param on_disconnect: callback called on disconnection during runtime :param idlequeue: processing idlequeue - :param estabilish_tls: boolean whether to estabilish TLS connection after - TCP connection is done - :param certs: tuple of (cacerts, mycerts) see constructor of - tls_nb.NonBlockingTLS for more details + :param estabilish_tls: boolean whether to estabilish TLS connection + after TCP connection is done + :param certs: tuple of (cacerts, mycerts) see constructor + of tls_nb.NonBlockingTLS for more details + :param cipher_list: list of ciphers used to connect to server """ PlugIn.__init__(self) self.raise_event = raise_event @@ -135,6 +136,7 @@ self.set_state(DISCONNECTED) self.estabilish_tls = estabilish_tls self.certs = certs + self.cipher_list = cipher_list # type of used ssl lib (if any) will be assigned to this member var self.ssl_lib = None self._exported_methods=[self.onreceive, self.set_send_timeout, @@ -293,12 +295,12 @@ estabilish TLS connection. """ def __init__(self, raise_event, on_disconnect, idlequeue, estabilish_tls, - certs, proxy_dict=None): + certs, 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) + NonBlockingTransport.__init__(self, raise_event, on_disconnect, + idlequeue, estabilish_tls, certs, cipher_list) IdleObject.__init__(self)
# queue with messages to be send @@ -409,7 +411,8 @@ NonBlockingTLS module """ cacerts, mycerts = self.certs - result = tls_nb.NonBlockingTLS.get_instance(cacerts, mycerts).PlugIn(self) + result = tls_nb.NonBlockingTLS.get_instance(cacerts, mycerts, + self.cipher_list).PlugIn(self) if result: on_succ() else: @@ -663,8 +666,8 @@ """
def __init__(self, raise_event, on_disconnect, idlequeue, estabilish_tls, - certs, on_http_request_possible, on_persistent_fallback, http_dict, - proxy_dict=None): + certs, 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 socket owned by transport is possible. @@ -673,10 +676,10 @@ :param http_dict: dictionary with data for HTTP request and headers """ NonBlockingTCP.__init__(self, raise_event, on_disconnect, idlequeue, - estabilish_tls, certs, proxy_dict) + estabilish_tls, certs, cipher_list, proxy_dict)
self.http_protocol, self.http_host, self.http_port, self.http_path = \ - urisplit(http_dict['http_uri']) + urisplit(http_dict['http_uri']) self.http_protocol = self.http_protocol or 'http' self.http_path = self.http_path or '/' self.http_version = http_dict['http_version']