# HG changeset patch # User Edouard Tisserant # Date 1515506888 -3600 # Node ID 971de876b1af5d7ec289c5e40fa25a6e93cfc490 # Parent daf40a1e7607a387aed86d205ae6a64bfabf2b8e WAMP runtime : changes from dporopat and agregorcic, adding CRA (-s) and changed way to load WAMP conf (-c) - added Challenge Response Authentication, - use -s commandline switch to give the shared secret. - WAMP configuration now either given as -c commandline switch or taken as default wampconf.json in project files. diff -r daf40a1e7607 -r 971de876b1af Beremiz_service.py --- a/Beremiz_service.py Tue Jan 09 14:52:56 2018 +0100 +++ b/Beremiz_service.py Tue Jan 09 15:08:08 2018 +0100 @@ -52,6 +52,7 @@ -t - enable/disable Twisted web interface (0:disable 1:enable) (default:1) -w - web server port or "off" (default:8009) -c - WAMP client config file or "off" (default:wampconf.json) + -s - WAMP client secret, given as a file or "off" -e - python extension (absolute path .py) working_dir - directory where are stored PLC files @@ -70,7 +71,8 @@ given_ip = None port = 3000 webport = 8009 -wampconf = "wampconf.json" +wampsecret = None +wampconf = None servicename = None autostart = False enablewx = True @@ -105,6 +107,8 @@ webport = None if a == "off" else int(a) elif o == "-c": wampconf = None if a == "off" else a + elif o == "-s": + wampsecret = None if a == "off" else a elif o == "-e": extensions.append(a) else: @@ -596,9 +600,21 @@ if wampconf is not None: try: - WC.RegisterWampClient(wampconf) - pyruntimevars["wampsession"] = WC.GetSession - WC.SetServer(pyroserver) + wampconf_project = os.path.join(WorkingDir, "wampconf.json") + _wampconf = WC.LoadWampClientConf(wampconf_project) # if project WAMP config is added + + if not _wampconf: + # loaded wamp config file path forced parameter -c + _wampconf = WC.LoadWampClientConf(wampconf) + else: + wampconf = wampconf_project + + if _wampconf and _wampconf["url"]: + WC.RegisterWampClient(wampconf, wampsecret) + pyruntimevars["wampsession"] = WC.GetSession + WC.SetServer(pyroserver) + else: + print(_("WAMP config is not defined.")) except Exception, e: print(_("WAMP client startup failed. "), e) diff -r daf40a1e7607 -r 971de876b1af runtime/WampClient.py --- a/runtime/WampClient.py Tue Jan 09 14:52:56 2018 +0100 +++ b/runtime/WampClient.py Tue Jan 09 15:08:08 2018 +0100 @@ -26,10 +26,13 @@ from __future__ import print_function import json +import os +import json 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.serializer import MsgPackSerializer +from autobahn.wamp.exception import ApplicationError from twisted.internet.defer import inlineCallbacks from twisted.internet.protocol import ReconnectingClientFactory @@ -66,6 +69,21 @@ class WampSession(wamp.ApplicationSession): + def onConnect(self): + secret = self.config.extra["secret"] + if secret: + user = self.config.extra["ID"].encode('utf8') + self.join(u"Automation", [u"wampcra"], user) + else: + self.join(u"Automation") + + def onChallenge(self, challenge): + if challenge.method == u"wampcra": + secret = self.config.extra["secret"].encode('utf8') + signature = auth.compute_wcs(secret, challenge.extra['challenge'].encode('utf8')) + return signature.decode("ascii") + else: + raise Exception("don't know how to handle authmethod {}".format(challenge.method)) @inlineCallbacks def onJoin(self, details): @@ -100,22 +118,40 @@ def LoadWampClientConf(wampconf): + try: + WSClientConf = json.load(open(wampconf)) + return WSClientConf + except ValueError, ve: + print(_("WAMP load error: "), ve) + return None + except Exception: + return None - WSClientConf = json.load(open(wampconf)) - return WSClientConf +def LoadWampSecret(secretfname): + try: + WSClientWampSecret = open(secretfname, 'rb').read() + return WSClientWampSecret + except ValueError, ve: + print(_("Wamp secret load error:"), ve) + return None + except Exception: + return None -def RegisterWampClient(wampconf): +def RegisterWampClient(wampconf, secretfname): WSClientConf = LoadWampClientConf(wampconf) - # start logging to console - # log.startLogging(sys.stdout) + if not WSClientConf: + print _("WAMP client connection not established!") + return + + WampSecret = LoadWampSecret(secretfname) # create a WAMP application session factory component_config = types.ComponentConfig( realm=WSClientConf["realm"], - extra={"ID": WSClientConf["ID"]}) + extra=WSClientConf) session_factory = wamp.ApplicationSessionFactory( config=component_config) session_factory.session = WampSession @@ -124,9 +160,7 @@ transport_factory = ReconnectingWampWebSocketClientFactory( session_factory, url=WSClientConf["url"], - serializers=[MsgPackSerializer()], - debug=False, - debug_wamp=False) + serializers=[MsgPackSerializer()]) # start the client from a Twisted endpoint conn = connectWS(transport_factory)