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
This commit is contained in:
Goffi 2019-10-01 22:49:10 +02:00
commit 310ce2eb13
3 changed files with 24 additions and 32 deletions

View file

@ -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 @@ log = getLogger(__name__)
## 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 @@ def HybridClientFactory(jid, password, check_certificate=True):
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 @@ class XmlStream(xmlstream.XmlStream):
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 @@ class XmlStream(xmlstream.XmlStream):
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 internJID(jidstring):
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

View file

@ -26,6 +26,7 @@ from sat.core.i18n import _
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 @@ class SatXMPPClient(SatXMPPEntity, wokkel_client.XMPPClient):
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)

View file

@ -45,7 +45,7 @@ install_requires = [
'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',