# HG changeset patch # User Goffi # Date 1551637125 -3600 # Node ID 8018cf9aa55bbff99170ee79304e6110d34efb2a # Parent e2005dd39c9265ffa7209579d877561733f98df6 plugin XEP-0077: correctly report invalid certificate + errback on unexpected stream close diff -r e2005dd39c92 -r 8018cf9aa55b sat/plugins/plugin_xep_0077.py --- a/sat/plugins/plugin_xep_0077.py Sun Mar 03 17:17:07 2019 +0100 +++ b/sat/plugins/plugin_xep_0077.py Sun Mar 03 19:18:45 2019 +0100 @@ -23,7 +23,7 @@ from sat.core.log import getLogger log = getLogger(__name__) -from twisted.words.protocols.jabber import jid, xmlstream, client +from twisted.words.protocols.jabber import jid, xmlstream, client, error as jabber_error from twisted.internet import defer, reactor from sat.tools import xml_tools @@ -50,12 +50,13 @@ # FIXME: doesn't handle data form or oob namespace = 'jabber:client' - def __init__(self, jid_, password, email=None): + def __init__(self, jid_, password, email=None, check_certificate=True): log.debug(_(u"Registration asked for {jid}").format(jid=jid_)) xmlstream.ConnectAuthenticator.__init__(self, jid_.host) self.jid = jid_ self.password = password self.email = email + self.check_certificate = check_certificate self.registered = defer.Deferred() def associateWithStream(self, xs): @@ -63,13 +64,10 @@ xs.addObserver(xmlstream.STREAM_AUTHD_EVENT, self.register) xs.initializers = [client.CheckVersionInitializer(xs)] - inits = [ (xmlstream.TLSInitiatingInitializer, False), - ] - - for initClass, required in inits: - init = initClass(xs) - init.required = required - xs.initializers.append(init) + tls_init = xmlstream.TLSInitiatingInitializer(xs) + tls_init.required = False + tls_init.check_certificate = self.check_certificate + xs.initializers.append(tls_init) def register(self, xmlstream): log.debug(_(u"Stream started with {server}, now registering" @@ -88,6 +86,26 @@ raise failure_ +class ServerRegister(xmlstream.XmlStreamFactory): + + def __init__(self, *args, **kwargs): + xmlstream.XmlStreamFactory.__init__(self, *args, **kwargs) + self.addBootstrap(xmlstream.STREAM_END_EVENT, self._disconnected) + + def clientConnectionLost(self, connector, reason): + connector.disconnect() + + def _disconnected(self, reason): + if not self.authenticator.registered.called: + err = jabber_error.StreamError(u"Server unexpectedly closed the connection") + try: + if reason.value.args[0][0][2] == "certificate verify failed": + err = exceptions.InvalidCertificate() + except (IndexError, TypeError): + pass + self.authenticator.registered.errback(err) + + class XEP_0077(object): def __init__(self, host): log.info(_("Plugin XEP_0077 initialization")) @@ -237,11 +255,12 @@ @param host(unicode): host of the server to register to @param port(int): port of the server to register to """ - authenticator = RegisteringAuthenticator(jid_, password, email) + check_certificate = host != u"127.0.0.1" + authenticator = RegisteringAuthenticator( + jid_, password, email, check_certificate=check_certificate) registered_d = authenticator.registered - serverRegistrer = xmlstream.XmlStreamFactory(authenticator) - connector = reactor.connectTCP(host, port, serverRegistrer) - serverRegistrer.clientConnectionLost = lambda conn, reason: connector.disconnect() + server_register = ServerRegister(authenticator) + reactor.connectTCP(host, port, server_register) return registered_d def _changePassword(self, new_password, profile_key):