Fix Pyro work with SSL wrapper (sslpsk)
authorAndrey Skvortsov <andrej.skvortzov@gmail.com>
Wed, 13 Mar 2019 15:43:45 +0300
changeset 2543 2befed4d6ca8
parent 2542 a3ec35ee94e7
child 2544 640d639d9bd8
Fix Pyro work with SSL wrapper (sslpsk)

Following error was shown in Beremiz console:
PYRO connecting to URI : PYROS://127.0.0.1:3001#beremiz
Exception while connecting to 'PYROS://127.0.0.1:3001#beremiz': non-zero flags not allowed in calls to recv() on <class 'ssl.SSLSocket'>
Connection failed to PYROS://127.0.0.1:3001#beremiz!

Reason is that Pyro calls socket recv() with MSGWAITALL flag, that causes ValueError exception.

https://docs.python.org/2/library/ssl.html
recv(), recv_into() (but passing a non-zero flags argument is not allowed)
connectors/PYRO/PSK_Adapter.py
connectors/PYRO/__init__.py
--- a/connectors/PYRO/PSK_Adapter.py	Wed Mar 13 14:27:24 2019 +0300
+++ b/connectors/PYRO/PSK_Adapter.py	Wed Mar 13 15:43:45 2019 +0300
@@ -70,9 +70,6 @@
     return _getProtocolAdapter(protocol)
 
 
-Pyro.protocol.getProtocolAdapter = getProtocolAdapter
-
-
 _processStringURI = Pyro.core.processStringURI
 
 
@@ -91,4 +88,13 @@
     return _processStringURI(URI)
 
 
-Pyro.core.processStringURI = processStringURI
+def setupPSKAdapter():
+    """
+    Add PyroAdapter to the list of available in
+    Pyro adapters and handle new supported protocols
+
+    This function should be called after
+    reimport of Pyro module to enable PYROS:// again.
+    """
+    Pyro.protocol.getProtocolAdapter = getProtocolAdapter
+    Pyro.core.processStringURI = processStringURI
--- a/connectors/PYRO/__init__.py	Wed Mar 13 14:27:24 2019 +0300
+++ b/connectors/PYRO/__init__.py	Wed Mar 13 15:43:45 2019 +0300
@@ -37,13 +37,19 @@
 from Pyro.errors import PyroError
 
 import PSKManagement as PSK
+import connectors.PYRO.PSK_Adapter
 from runtime import PlcStatus
 
-# this module attribute contains a list of DNS-SD (Zeroconf) service types
-# supported by this connector confnode.
-#
-# for connectors that do not support DNS-SD, this attribute can be omitted
-# or set to an empty list.
+
+def switch_pyro_adapter(use_ssl):
+    """
+    Reloads Pyro module with new settings.
+    This is workaround for Pyro, because it doesn't work with SSL wrapper.
+    """
+    # Pyro.config.PYRO_BROKEN_MSGWAITALL = use_ssl
+    reload(Pyro.protocol)
+    if use_ssl:
+        connectors.PYRO.PSK_Adapter.setupPSKAdapter()
 
 
 def PYRO_connector_factory(uri, confnodesroot):
@@ -53,8 +59,9 @@
     confnodesroot.logger.write(_("PYRO connecting to URI : %s\n") % uri)
 
     scheme, location = uri.split("://")
-    if scheme == "PYROS":
-        import connectors.PYRO.PSK_Adapter  # pylint: disable=wrong-import-order,unused-import,wrong-import-position
+    use_ssl = scheme == "PYROS"
+    switch_pyro_adapter(use_ssl)
+    if use_ssl:
         schemename = "PYROLOCPSK"
         url, ID = location.split('#')  # TODO fix exception when # not found
         # load PSK from project