changeset 3044:691283719bb2

core (patches): updated TLS patches: - updated patches to handle TLS after implementation in Twisted 19.7.0. A patch is still needed for Wokkel. - minimum required version of Twisted is now 19.7.0
author Goffi <goffi@goffi.org>
date Tue, 01 Oct 2019 22:49:10 +0200
parents 3df611adb598
children 6af44ca3beac
files sat/core/patches.py sat/core/xmpp.py setup.py
diffstat 3 files changed, 24 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/sat/core/patches.py	Tue Oct 01 22:49:10 2019 +0200
+++ b/sat/core/patches.py	Tue Oct 01 22:49:10 2019 +0200
@@ -1,13 +1,12 @@
 import copy
 from twisted.words.protocols.jabber import xmlstream, sasl, client as tclient, jid
-from twisted.internet import ssl
 from wokkel import client
 from sat.core.constants import Const as C
 from sat.core.log import getLogger
 
 log = getLogger(__name__)
 
-"""This module apply monkey patches to Twisted and Wokkel
+"""This module applies monkey patches to Twisted and Wokkel
    First part handle certificate validation during XMPP connectionand are temporary
    (until merged upstream).
    Second part add a trigger point to send and onElement method of XmlStream
@@ -16,36 +15,25 @@
 
 ## certificate validation patches
 
-class TLSInitiatingInitializer(xmlstream.TLSInitiatingInitializer):
-    check_certificate = True
-
-    def onProceed(self, obj):
-        self.xmlstream.removeObserver('/failure', self.onFailure)
-        trustRoot = ssl.platformTrust() if self.check_certificate else None
-        ctx = ssl.CertificateOptions(trustRoot=trustRoot)
-        self.xmlstream.transport.startTLS(ctx)
-        self.xmlstream.reset()
-        self.xmlstream.sendHeader()
-        self._deferred.callback(xmlstream.Reset)
-
 
 class XMPPClient(client.XMPPClient):
 
     def __init__(self, jid, password, host=None, port=5222,
-                 check_certificate=True):
+                 tls_required=True, configurationForTLS=None):
         self.jid = jid
         self.domain = jid.host.encode('idna')
         self.host = host
         self.port = port
 
         factory = HybridClientFactory(
-            jid, password, check_certificate=check_certificate)
+            jid, password, tls_required=tls_required,
+            configurationForTLS=configurationForTLS)
 
         client.StreamManager.__init__(self, factory)
 
 
-def HybridClientFactory(jid, password, check_certificate=True):
-    a = HybridAuthenticator(jid, password, check_certificate)
+def HybridClientFactory(jid, password, tls_required=True, configurationForTLS=None):
+    a = HybridAuthenticator(jid, password, tls_required, configurationForTLS)
 
     return xmlstream.XmlStreamFactory(a)
 
@@ -53,17 +41,18 @@
 class HybridAuthenticator(client.HybridAuthenticator):
     res_binding = True
 
-    def __init__(self, jid, password, check_certificate):
+    def __init__(self, jid, password, tls_required=True, configurationForTLS=None):
         xmlstream.ConnectAuthenticator.__init__(self, jid.host)
         self.jid = jid
         self.password = password
-        self.check_certificate = check_certificate
+        self.tls_required = tls_required
+        self.configurationForTLS = configurationForTLS
 
     def associateWithStream(self, xs):
         xmlstream.ConnectAuthenticator.associateWithStream(self, xs)
 
-        tlsInit = xmlstream.TLSInitiatingInitializer(xs)
-        tlsInit.check_certificate = self.check_certificate
+        tlsInit = xmlstream.TLSInitiatingInitializer(
+            xs, required=self.tls_required, configurationForTLS=self.configurationForTLS)
         xs.initializers = [client.client.CheckVersionInitializer(xs),
                            tlsInit,
                            CheckAuthInitializer(xs, self.res_binding)]
@@ -84,8 +73,7 @@
 
     def addHook(self, hook_type, callback):
         """Add a send or receive hook"""
-        conflict_msg = ("Hook conflict: can't add {hook_type} hook {callback}"
-            .format(hook_type=hook_type, callback=callback))
+        conflict_msg = f"Hook conflict: can't add {hook_type} hook {callback}"
         if hook_type == C.STREAM_HOOK_RECEIVE:
             if callback not in self._onElementHooks:
                 self._onElementHooks.append(callback)
@@ -97,8 +85,7 @@
             else:
                 log.warning(conflict_msg)
         else:
-            raise ValueError("Invalid hook type: {hook_type}"
-                .format(hook_type=hook_type))
+            raise ValueError(f"Invalid hook type: {hook_type}")
 
     def onElement(self, element):
         for hook in self._onElementHooks:
@@ -161,10 +148,8 @@
 
 
 def apply():
-    # FIXME: certificate validation is now implemented in Twisted trunk, to be removed
-    # # certificate validation
-    # xmlstream.TLSInitiatingInitializer = TLSInitiatingInitializer
-    # client.XMPPClient = XMPPClient
+    # certificate validation
+    client.XMPPClient = XMPPClient
     # XmlStream triggers
     xmlstream.XmlStreamFactory.protocol = XmlStream
     # jid fix
--- a/sat/core/xmpp.py	Tue Oct 01 22:49:10 2019 +0200
+++ b/sat/core/xmpp.py	Tue Oct 01 22:49:10 2019 +0200
@@ -26,6 +26,7 @@
 from sat.core.constants import Const as C
 from sat.memory import cache
 from twisted.internet import defer, error as internet_error
+from twisted.internet import ssl
 from twisted.words.protocols.jabber.xmlstream import XMPPHandler
 from twisted.words.protocols.jabber import xmlstream
 from twisted.words.protocols.jabber import error
@@ -715,9 +716,15 @@
         self.check_certificate = host_app.memory.getParamA(
             "check_certificate", "Connection", profile_key=profile)
 
+        if self.check_certificate:
+            tls_required, configurationForTLS = True, None
+        else:
+            tls_required = False
+            configurationForTLS = ssl.CertificateOptions(trustRoot=None)
+
         wokkel_client.XMPPClient.__init__(
             self, user_jid, password, host or None, port or C.XMPP_C2S_PORT,
-            # check_certificate = self.check_certificate  # FIXME: currently disabled with Python 3 port
+            tls_required=tls_required, configurationForTLS=configurationForTLS
         )
         SatXMPPEntity.__init__(self, host_app, profile, max_retries)
 
--- a/setup.py	Tue Oct 01 22:49:10 2019 +0200
+++ b/setup.py	Tue Oct 01 22:49:10 2019 +0200
@@ -45,7 +45,7 @@
     'pyxdg',
     'sat_tmp >= 0.7.0a4',
     'shortuuid',
-    'twisted[tls] >= 15.2.0',
+    'twisted[tls] >= 19.7.0',
     'urwid >= 1.2.0',
     'urwid-satext >= 0.7.0a2',
     'wokkel >= 0.7.1',