--- a/connectors/WAMP/__init__.py Fri Feb 28 16:48:28 2025 +0100
+++ b/connectors/WAMP/__init__.py Fri Feb 28 16:53:33 2025 +0100
@@ -29,12 +29,16 @@
from threading import Thread, Event
from twisted.internet import reactor, threads
+from twisted.internet._sslverify import OpenSSLCertificateAuthorities from autobahn.twisted import wamp
from autobahn.twisted.websocket import WampWebSocketClientFactory, connectWS
-from autobahn.wamp import types
+from autobahn.wamp import types, auth from autobahn.wamp.exception import TransportLost
from autobahn.wamp.serializer import MsgPackSerializer
+from ProjectController import ToDoBeforeQuit +from connectors.ConnectorBase import ConnectorBase +import PSKManagement as PSK @@ -42,6 +46,29 @@
class WampSession(wamp.ApplicationSession):
+ user = self.config.extra["ID"] + self.config.realm, user)) + self.join(self.config.realm, ["wampcra"], user) + def onChallenge(self, challenge): + if challenge.method == "wampcra": + secret = self.config.extra["secret"] + if 'salt' in challenge.extra: + key = auth.derive_key(secret, + challenge.extra['salt'], + challenge.extra['iterations'], + challenge.extra['keylen']) + # plain, unsalted secret + signature = auth.compute_wcs(key, challenge.extra['challenge']) + raise Exception("Invalid authmethod {}".format(challenge.method)) def onJoin(self, details):
@@ -54,6 +81,19 @@
print('WAMP session left')
+def MakeSecureContextFactory(verifyHostname, trust_store=None): + if not os.path.exists(trust_store): + raise Exception("Wamp trust store not found") + cert = crypto.load_certificate( + open(trust_store, 'rb').read() + trustRoot=OpenSSLCertificateAuthorities([cert]) + return optionsForClientTLS(_transportFactory.host, trustRoot=trustRoot) def _WAMP_connector_factory(cls, uri, confnodesroot):
@@ -66,6 +106,16 @@
url = urlprefix+"://"+urlpath
+ secret = PSK.GetSecret(confnodesroot.ProjectPath, ID) + # TODO: add x509 certificate management together with PSK management. + confnodesroot.logger.write_error( + _("Connection to {loc} failed with exception {ex}\n").format( def RegisterWampClient():
# start logging to console
@@ -74,7 +124,10 @@
# create a WAMP application session factory
component_config = types.ComponentConfig(
session_factory = wamp.ApplicationSessionFactory(
session_factory.session = cls
@@ -85,8 +138,14 @@
serializers=[MsgPackSerializer()])
+ if transport_factory.isSecure: + contextFactory = MakeSecureContextFactory( + trust_store=trust_store) # start the client from a Twisted endpoint
- conn = connectWS(transport_factory)
+ conn = connectWS(transport_factory, contextFactory) confnodesroot.logger.write(_("WAMP connecting to URL : %s\n") % url)
@@ -97,7 +156,7 @@
ToDoBeforeQuit.append(reactor.stop)
reactor.run(installSignalHandlers=False)
- class WampPLCObjectProxy(object):
+ class WampPLCObjectProxy(ConnectorBase):