diff options
-rwxr-xr-x | doc/examples/xsend.py | 4 | ||||
-rw-r--r-- | nbxmpp/bosh.py | 8 | ||||
-rw-r--r-- | nbxmpp/client_nb.py | 27 | ||||
-rw-r--r-- | nbxmpp/tls_nb.py | 20 | ||||
-rw-r--r-- | nbxmpp/transports_nb.py | 29 |
5 files changed, 49 insertions, 39 deletions
diff --git a/doc/examples/xsend.py b/doc/examples/xsend.py index 7b979c7..173dca3 100755 --- a/doc/examples/xsend.py +++ b/doc/examples/xsend.py @@ -35,6 +35,8 @@ class Connection: 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 @@ class Connection: 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 --git a/nbxmpp/bosh.py b/nbxmpp/bosh.py index fd2e7df..f84012e 100644 --- a/nbxmpp/bosh.py +++ b/nbxmpp/bosh.py @@ -37,10 +37,10 @@ FAKE_DESCRIPTOR = -1337 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 --git a/nbxmpp/client_nb.py b/nbxmpp/client_nb.py index 2ca12de..4306060 100644 --- a/nbxmpp/client_nb.py +++ b/nbxmpp/client_nb.py @@ -149,7 +149,7 @@ class NonBlockingClient: 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 @@ class NonBlockingClient: :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 @@ class NonBlockingClient: 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 @@ class NonBlockingClient: 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 --git a/nbxmpp/tls_nb.py b/nbxmpp/tls_nb.py index 057da57..430820b 100644 --- a/nbxmpp/tls_nb.py +++ b/nbxmpp/tls_nb.py @@ -247,21 +247,21 @@ class NonBlockingTLS(PlugIn): 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): """ @@ -399,7 +399,7 @@ class NonBlockingTLS(PlugIn): 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 --git a/nbxmpp/transports_nb.py b/nbxmpp/transports_nb.py index 89a99e0..b23b6c9 100644 --- a/nbxmpp/transports_nb.py +++ b/nbxmpp/transports_nb.py @@ -109,7 +109,7 @@ class NonBlockingTransport(PlugIn): """ 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 @@ class NonBlockingTransport(PlugIn): :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 @@ class NonBlockingTransport(PlugIn): 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 @@ class NonBlockingTCP(NonBlockingTransport, IdleObject): 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 @@ class NonBlockingTCP(NonBlockingTransport, IdleObject): 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: @@ -630,8 +633,8 @@ class NonBlockingHTTP(NonBlockingTCP): """ 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. @@ -640,10 +643,10 @@ class NonBlockingHTTP(NonBlockingTCP): :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'] |