--- a/Beremiz_service.py Tue Oct 23 16:19:20 2018 +0200
+++ b/Beremiz_service.py Mon Oct 29 11:33:36 2018 +0100
@@ -78,7 +78,7 @@
@@ -120,7 +120,7 @@
wampconf = None if a == "off" else a
- pskpath = None if a == "off" else a
+ PSKpath = None if a == "off" else a fnameanddirname = list(os.path.split(os.path.realpath(a)))
fnameanddirname.reverse()
@@ -492,9 +492,9 @@
# Service name is used as an ID for stunnel's PSK
# Some extension may set 'servicename' to a computed ID or Serial Number
# instead of using commandline '-n'
-if servicename is not None and pskpath is not None:
- from runtime.Stunnel import ensurepsk
- ensurepsk(servicename, pskpath)
+if servicename is not None and PSKpath is not None: + from runtime.Stunnel import ensurePSK + ensurePSK(servicename, PSKpath) runtime.CreatePLCObjectSingleton(
WorkingDir, argv, statuschange, evaluator, pyruntimevars)
@@ -517,7 +517,7 @@
- WC.RegisterWampClient(wampconf, pskpath)
+ WC.RegisterWampClient(wampconf, PSKpath) WC.RegisterWebSettings(NS)
LogMessageAndException(_("WAMP client startup failed. "))
--- a/connectors/PYRO/__init__.py Tue Oct 23 16:19:20 2018 +0200
+++ b/connectors/PYRO/__init__.py Mon Oct 29 11:33:36 2018 +0100
@@ -36,6 +36,7 @@
from Pyro.errors import PyroError
zeroconf_service_type = '_PYRO._tcp.local.'
# this module attribute contains a list of DNS-SD (Zeroconf) service types
# supported by this connector confnode.
@@ -54,14 +55,15 @@
if servicetype == "PYROS":
import connectors.PYRO.PSK_Adapter
schemename = "PYROLOCPSK"
- url, ID = location.split('#')
+ url, ID = location.split('#') #TODO fix exception when # not found secpath = os.path.join(str(confnodesroot.ProjectPath), 'psk', ID+'.secret')
if not os.path.exists(secpath):
confnodesroot.logger.write_error(
'Error: Pre-Shared-Key Secret in %s is missing!\n' % secpath)
- Pyro.config.PYROPSK = (open(secpath).read(), ID)
+ secret = open(secpath).read().partition(':')[2].rstrip('\n\r') + Pyro.config.PYROPSK = (secret, ID) # strip ID from URL, so that pyro can understand it.
@@ -88,9 +90,9 @@
# Try to get the proxy object
RemotePLCObjectProxy = Pyro.core.getAttrProxyForURI(schemename + "://" + location + "/PLCObject")
- confnodesroot.logger.write_error(_("Connection to '%s' failed.\n") % location)
- confnodesroot.logger.write_error(traceback.format_exc())
+ confnodesroot.logger.write_error(_("Connection to '%s' failed with exception '%s'\n") % (location, str(e))) + #confnodesroot.logger.write_error(traceback.format_exc()) def PyroCatcher(func, default=None):
@@ -117,10 +119,17 @@
# Check connection is effective.
# lambda is for getattr of GetPLCstatus to happen inside catcher
- if PyroCatcher(RemotePLCObjectProxy.GetPLCstatus)() is None:
- confnodesroot.logger.write_error(_("Cannot get PLC status - connection failed.\n"))
+ IDPSK = PyroCatcher(RemotePLCObjectProxy.GetPLCID)() + confnodesroot.logger.write_error(_("Cannot get PLC ID - connection failed.\n")) + if servicetype != "PYROS": + secpath = os.path.join(str(confnodesroot.ProjectPath), 'psk', ID+'.secret') + with open(secpath, 'w') as f: _special_return_funcs = {
"GetTraceVariables": ("Broken", None),
--- a/runtime/PLCObject.py Tue Oct 23 16:19:20 2018 +0200
+++ b/runtime/PLCObject.py Mon Oct 29 11:33:36 2018 +0100
@@ -33,6 +33,7 @@
from runtime.typemapping import TypeTranslator
from runtime.loglevels import LogLevelsDefault, LogLevelsCount
+from runtime.Stunnel import getPSKID from runtime import MainWorker
if os.name in ("nt", "ce"):
@@ -438,6 +439,10 @@
return self.PLCStatus, map(self.GetLogCount, xrange(LogLevelsCount))
def NewPLC(self, md5sum, data, extrafiles):
if self.PLCStatus in ["Stopped", "Empty", "Broken"]:
NewFileName = md5sum + lib_ext
--- a/runtime/Stunnel.py Tue Oct 23 16:19:20 2018 +0200
+++ b/runtime/Stunnel.py Mon Oct 29 11:33:36 2018 +0100
@@ -4,11 +4,13 @@
restart_stunnel_cmdline = ["/etc/init.d/S50stunnel","restart"]
-# stunnel takes no encoding for psk, so we try to lose minimum entropy
+# stunnel takes no encoding for PSK, so we try to lose minimum entropy # by using all possible chars except '\0\n\r' (checked stunnel parser to be sure)
translator = ''.join([(lambda c: '#' if c in '\0\n\r' else c)(chr(i)) for i in xrange(256)])
-def pskgen(ID, pskpath):
+def PSKgen(ID, PSKpath): secret = os.urandom(256) # 2048 bits is still safe nowadays
# following makes 512 length string, rejected by stunnel
@@ -16,14 +18,27 @@
# secretstring = hexlify(secret)
secretstring = secret.translate(translator)
- pskstring = ID+":"+secretstring
- with open(pskpath, 'w') as f:
+ PSKstring = ID+":"+secretstring + with open(PSKpath, 'w') as f: call(restart_stunnel_cmdline)
-def ensurepsk(ID, pskpath):
+def ensurePSK(ID, PSKpath): - if not os.path.exists(pskpath):
+ if not os.path.exists(PSKpath):
+ if _PSKpath is not None : + if not os.path.exists(_PSKpath): + confnodesroot.logger.write_error( + 'Error: Pre-Shared-Key Secret in %s is missing!\n' % _PSKpath) + ID,_sep,PSK = open(_PSKpath).read().partition(':') + PSK = PSK.rstrip('\n\r')