diff --git a/data/etc/revpipyload/aclplcslave.conf b/data/etc/revpipyload/aclplcslave.conf
new file mode 100644
index 0000000..403205c
--- /dev/null
+++ b/data/etc/revpipyload/aclplcslave.conf
@@ -0,0 +1,3 @@
+# PLC-SLAVE Access Control List (acl)
+# One entry per Line IPADRESS,LEVEL
+#
diff --git a/data/etc/revpipyload/aclxmlrpc.conf b/data/etc/revpipyload/aclxmlrpc.conf
new file mode 100644
index 0000000..04c35f9
--- /dev/null
+++ b/data/etc/revpipyload/aclxmlrpc.conf
@@ -0,0 +1,3 @@
+# XML-RPC Access Control List (acl)
+# One entry per Line IPADRESS,LEVEL
+#
diff --git a/data/etc/revpipyload/revpipyload.conf b/data/etc/revpipyload/revpipyload.conf
index 89ccd4d..8afb9c1 100644
--- a/data/etc/revpipyload/revpipyload.conf
+++ b/data/etc/revpipyload/revpipyload.conf
@@ -14,11 +14,11 @@ zeroonexit = 0
[PLCSLAVE]
plcslave = 0
-acl =
+aclfile = /etc/revpipyload/aclplcslave.conf
bindip = *
port = 55234
[XMLRPC]
xmlrpc = 0
-acl =
+aclfile = /etc/revpipyload/aclxmlrpc.conf
bindip = *
diff --git a/doc/helper.html b/doc/helper.html
index eb567fc..c6856f8 100644
--- a/doc/helper.html
+++ b/doc/helper.html
@@ -17,10 +17,7 @@ Global Attributes
Classes
-
-| IpAclManager |
-Verwaltung fuer IP Adressen und deren ACL Level. |
-
+| None |
Functions
@@ -37,138 +34,6 @@ Functions
-
-IpAclManager
-
-Verwaltung fuer IP Adressen und deren ACL Level.
-
-
-Derived from
-None
-
-Class Attributes
-
-
-Class Methods
-
-
-Methods
-
-
-| IpAclManager |
-Init IpAclManager class. |
-
-| __get_acl |
-Getter fuer den rohen ACL-String. |
-
-| __get_regex_acl |
-Gibt formatierten RegEx-String zurueck. |
-
-| __iter__ |
-Gibt einzelne ACLs als aus. |
-
-| __set_acl |
-Uebernimmt neue ACL-Liste fuer die Ausertung der Level. |
-
-| get_acllevel |
-Prueft IP gegen ACL List und gibt ACL-Wert aus. |
-
-| loadacl |
-Laed ACL String und gibt erfolg zurueck. |
-
-
-
-Static Methods
-
-
-
-IpAclManager (Constructor)
-IpAclManager(minlevel, maxlevel, acl=None)
-
-Init IpAclManager class.
-
-- minlevel
--
-Smallest access level (min. 0)
-
- maxlevel
--
-Biggest access level (max. 9)
-
- acl
--
-ACL Liste fuer Berechtigungen als
-
-
-
-IpAclManager.__get_acl
-__get_acl()
-
-Getter fuer den rohen ACL-String.
- return ACLs als
-
-
-IpAclManager.__get_regex_acl
-__get_regex_acl()
-
-Gibt formatierten RegEx-String zurueck.
- return RegEx Code als
-
-
-IpAclManager.__iter__
-__iter__()
-
-Gibt einzelne ACLs als aus.
-
-
-IpAclManager.__set_acl
-__set_acl(value)
-
-Uebernimmt neue ACL-Liste fuer die Ausertung der Level.
-
-- value
--
-Neue ACL-Liste als
-
-
-
-IpAclManager.get_acllevel
-get_acllevel(ipaddress)
-
-Prueft IP gegen ACL List und gibt ACL-Wert aus.
-
-- ipaddress
--
-zum pruefen
-
-
-- Returns:
--
- ACL Wert oder -1 wenn nicht gefunden
-
-
-
-IpAclManager.loadacl
-loadacl(str_acl)
-
-Laed ACL String und gibt erfolg zurueck.
-
-- str_acl
--
-ACL als
-
-
-- Returns:
--
-True, wenn erfolgreich uebernommen
-
-
-
-
_setuprt
_setuprt(pid, evt_exit)
diff --git a/doc/index-revpipyload.shared.html b/doc/index-revpipyload.shared.html
new file mode 100644
index 0000000..387c9b5
--- /dev/null
+++ b/doc/index-revpipyload.shared.html
@@ -0,0 +1,20 @@
+
+
+revpipyload.shared
+
+
+
+
+revpipyload.shared
+
+
+
+
+Modules
+
+
\ No newline at end of file
diff --git a/doc/index.html b/doc/index.html
index eb76236..b9be723 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -8,6 +8,14 @@
Table of contents
+
+Packages
+
Modules
diff --git a/doc/picontrolserver.html b/doc/picontrolserver.html
index 1cef53d..ac57eb0 100644
--- a/doc/picontrolserver.html
+++ b/doc/picontrolserver.html
@@ -85,9 +85,9 @@ RevPiSlave (Constructor)
Instantiiert RevPiSlave-Klasse.
-- acl
+- ipacl
-
-Stringliste mit Leerstellen getrennt
+AclManager
- port
-
Listen Port fuer plc Slaveserver
diff --git a/doc/procimgserver.html b/doc/procimgserver.html
index 9a77e8c..1c0f2b8 100644
--- a/doc/procimgserver.html
+++ b/doc/procimgserver.html
@@ -93,16 +93,13 @@ Static Methods
ProcimgServer (Constructor)
-ProcimgServer(xmlserver, aclmode)
+ProcimgServer(xmlserver)
Instantiiert RevPiCheckServer()-Klasse.
- xmlserver
-
XML-RPC Server
-
- aclmode
--
-Zugriffsrechte
diff --git a/doc/revpipyload.shared.ipaclmanager.html b/doc/revpipyload.shared.ipaclmanager.html
new file mode 100644
index 0000000..9fdebde
--- /dev/null
+++ b/doc/revpipyload.shared.ipaclmanager.html
@@ -0,0 +1,239 @@
+
+
+revpipyload.shared.ipaclmanager
+
+
+
+
+revpipyload.shared.ipaclmanager
+
+Verwaltet IP Adressen und deren ACLs.
+
+
+Global Attributes
+
+
+Classes
+
+
+| IpAclManager |
+Verwaltung fuer IP Adressen und deren ACL Level. |
+
+
+
+Functions
+
+
+| refullmatch |
+re.fullmatch wegen alter python version aus wheezy nachgebaut. |
+
+
+
+
+IpAclManager
+
+Verwaltung fuer IP Adressen und deren ACL Level.
+
+
+Derived from
+None
+
+Class Attributes
+
+
+Class Methods
+
+
+Methods
+
+
+Static Methods
+
+
+
+IpAclManager (Constructor)
+IpAclManager(minlevel, maxlevel, acl=None)
+
+Init IpAclManager class.
+
+- minlevel
+-
+Smallest access level (min. 0)
+
- maxlevel
+-
+Biggest access level (max. 9)
+
- acl
+-
+ACL Liste fuer Berechtigungen als
+
+
+
+IpAclManager.__get_acl
+__get_acl()
+
+Getter fuer den rohen ACL-String.
+ return ACLs als
+
+
+IpAclManager.__get_filename
+__get_filename()
+
+Getter fuer Dateinamen.
+
+- Returns:
+-
+Filename der ACL
+
+
+
+IpAclManager.__get_regex_acl
+__get_regex_acl()
+
+Gibt formatierten RegEx-String zurueck.
+ return RegEx Code als
+
+
+IpAclManager.__iter__
+__iter__()
+
+Gibt einzelne ACLs als aus.
+
+
+IpAclManager.__set_acl
+__set_acl(value)
+
+Uebernimmt neue ACL-Liste fuer die Ausertung der Level.
+
+- value
+-
+Neue ACL-Liste als
+
+
+
+IpAclManager.get_acllevel
+get_acllevel(ipaddress)
+
+Prueft IP gegen ACL List und gibt ACL-Wert aus.
+
+- ipaddress
+-
+zum pruefen
+
+
+- Returns:
+-
+ ACL Wert oder -1 wenn nicht gefunden
+
+
+
+IpAclManager.loadacl
+loadacl(str_acl)
+
+Laed ACL String und gibt erfolg zurueck.
+
+- str_acl
+-
+ACL als
+
+
+- Returns:
+-
+True, wenn erfolgreich uebernommen
+
+
+
+IpAclManager.loadaclfile
+loadaclfile(filename)
+
+Laed ACL Definitionen aus Datei.
+
+- filename
+-
+Dateiname fuer Definitionen
+
+
+- Returns:
+-
+True, wenn Laden erfolgreich war
+
+
+
+IpAclManager.writeaclfile
+writeaclfile(filename=None, aclname=None)
+
+Schreibt ACL Definitionen in Datei.
+
+- filename
+-
+Dateiname fuer Definitionen
+
+
+- Returns:
+-
+True, wenn Schreiben erfolgreich war
+
+
+
+
+
+refullmatch
+refullmatch(regex, string)
+
+re.fullmatch wegen alter python version aus wheezy nachgebaut.
+
+- regex
+-
+RegEx Statement
+
- string
+-
+Zeichenfolge gegen die getestet wird
+
+
+- Returns:
+-
+True, wenn komplett passt sonst False
+
+
+
+
+
\ No newline at end of file
diff --git a/doc/xrpcserver.html b/doc/xrpcserver.html
index 2b5fd14..9e66610 100644
--- a/doc/xrpcserver.html
+++ b/doc/xrpcserver.html
@@ -128,7 +128,12 @@ SaveXMLRPCServer (Constructor)
SaveXMLRPCServer(addr, logRequests=True, allow_none=False, use_builtin_types=False, ipacl=None)
Init SaveXMLRPCServer class.
-
+
+- ipacl
+-
+AclManager
+
+
SaveXMLRPCServer._dispatch
_dispatch(method, params)
diff --git a/eric-revpipyload.api b/eric-revpipyload.api
index 3d4c816..b654401 100644
--- a/eric-revpipyload.api
+++ b/eric-revpipyload.api
@@ -1,12 +1,3 @@
-helper.IpAclManager.__get_acl?6()
-helper.IpAclManager.__get_regex_acl?6()
-helper.IpAclManager.__iter__?6()
-helper.IpAclManager.__set_acl?6(value)
-helper.IpAclManager.acl?7
-helper.IpAclManager.get_acllevel?4(ipaddress)
-helper.IpAclManager.loadacl?4(str_acl)
-helper.IpAclManager.regex_acl?7
-helper.IpAclManager?1(minlevel, maxlevel, acl=None)
helper._setuprt?5(pid, evt_exit)
helper._zeroprocimg?5()
helper.refullmatch?4(regex, string)
@@ -42,7 +33,7 @@ procimgserver.ProcimgServer.setvalue?4(device, io, value)
procimgserver.ProcimgServer.start?4()
procimgserver.ProcimgServer.stop?4()
procimgserver.ProcimgServer.values?4()
-procimgserver.ProcimgServer?1(xmlserver, aclmode)
+procimgserver.ProcimgServer?1(xmlserver)
proginit.cleanup?4()
proginit.configure?4()
proginit.forked?7
@@ -85,6 +76,20 @@ revpipyload.RevPiPyLoad.xml_setconfig?4(dc, loadnow=False)
revpipyload.RevPiPyLoad.xml_setpictoryrsc?4(filebytes, reset=False)
revpipyload.RevPiPyLoad?1()
revpipyload.pyloadversion?7
+revpipyload.shared.ipaclmanager.IpAclManager.__get_acl?6()
+revpipyload.shared.ipaclmanager.IpAclManager.__get_filename?6()
+revpipyload.shared.ipaclmanager.IpAclManager.__get_regex_acl?6()
+revpipyload.shared.ipaclmanager.IpAclManager.__iter__?6()
+revpipyload.shared.ipaclmanager.IpAclManager.__set_acl?6(value)
+revpipyload.shared.ipaclmanager.IpAclManager.acl?7
+revpipyload.shared.ipaclmanager.IpAclManager.filename?7
+revpipyload.shared.ipaclmanager.IpAclManager.get_acllevel?4(ipaddress)
+revpipyload.shared.ipaclmanager.IpAclManager.loadacl?4(str_acl)
+revpipyload.shared.ipaclmanager.IpAclManager.loadaclfile?4(filename)
+revpipyload.shared.ipaclmanager.IpAclManager.regex_acl?7
+revpipyload.shared.ipaclmanager.IpAclManager.writeaclfile?4(filename=None, aclname=None)
+revpipyload.shared.ipaclmanager.IpAclManager?1(minlevel, maxlevel, acl=None)
+revpipyload.shared.ipaclmanager.refullmatch?4(regex, string)
xrpcserver.SaveXMLRPCRequestHandler.parse_request?4()
xrpcserver.SaveXMLRPCServer._dispatch?5(method, params)
xrpcserver.SaveXMLRPCServer.isAlive?4()
diff --git a/revpipyload.e4p b/revpipyload.e4p
index 930cc3d..e7f4e7a 100644
--- a/revpipyload.e4p
+++ b/revpipyload.e4p
@@ -1,7 +1,7 @@
-
+
en_US
@@ -9,7 +9,7 @@
Python3
Console
Dieser Loader wird über das Init-System geladen und führt das angegebene Pythonprogramm aus. Es ist für den RevolutionPi gedacht um automatisch das SPS-Programm zu starten.
- 0.6.1
+ 0.6.2
Sven Sager
akira@narux.de
diff --git a/revpipyload/helper.py b/revpipyload/helper.py
index e73c960..e40f4fd 100644
--- a/revpipyload/helper.py
+++ b/revpipyload/helper.py
@@ -12,110 +12,6 @@ from re import match as rematch
from subprocess import Popen, PIPE
-class IpAclManager():
-
- """Verwaltung fuer IP Adressen und deren ACL Level."""
-
- def __init__(self, minlevel, maxlevel, acl=None):
- """Init IpAclManager class.
-
- @param minlevel Smallest access level (min. 0)
- @param maxlevel Biggest access level (max. 9)
- @param acl ACL Liste fuer Berechtigungen als
-
- """
- if type(minlevel) != int:
- raise ValueError("parameter minlevel must be ")
- if type(maxlevel) != int:
- raise ValueError("parameter maxlevel must be ")
- if minlevel < 0:
- raise ValueError("minlevel must be 0 or more")
- if maxlevel > 9:
- raise ValueError("maxlevel maximum is 9")
- if minlevel > maxlevel:
- raise ValueError("minlevel is smaller than maxlevel")
-
- self.__dict_acl = {}
- self.__dict_regex = {}
- self.__dict_knownips = {}
- self.__re_ipacl = "(([\\d\\*]{1,3}\\.){3}[\\d\\*]{1,3},[" \
- + str(minlevel) + "-" + str(maxlevel) + "] ?)*"
-
- # Liste erstellen, wenn übergeben
- if acl is not None:
- self.__set_acl(acl)
-
- def __iter__(self):
- """Gibt einzelne ACLs als aus."""
- for aclip in sorted(self.__dict_acl):
- yield (aclip, self.__dict_acl[aclip])
-
- def __get_acl(self):
- """Getter fuer den rohen ACL-String.
- return ACLs als """
- str_acl = ""
- for aclip in sorted(self.__dict_acl):
- str_acl += "{},{} ".format(aclip, self.__dict_acl[aclip])
- return str_acl.strip()
-
- def __get_regex_acl(self):
- """Gibt formatierten RegEx-String zurueck.
- return RegEx Code als """
- return self.__re_ipacl
-
- def __set_acl(self, value):
- """Uebernimmt neue ACL-Liste fuer die Ausertung der Level.
- @param value Neue ACL-Liste als """
- if type(value) != str:
- raise ValueError("parameter acl must be ")
-
- value = value.strip()
- if not refullmatch(self.__re_ipacl, value):
- raise ValueError("acl format ist not okay - 1.2.3.4,0 5.6.7.8,1")
-
- # Klassenwerte übernehmen
- self.__dict_acl = {}
- self.__dict_regex = {}
- self.__dict_knownips = {}
-
- # Liste neu füllen mit regex Strings
- for ip_level in value.split():
- ip, level = ip_level.split(",", 1)
- self.__dict_acl[ip] = int(level)
- self.__dict_regex[ip] = \
- ip.replace(".", "\\.").replace("*", "\\d{1,3}")
-
- def get_acllevel(self, ipaddress):
- """Prueft IP gegen ACL List und gibt ACL-Wert aus.
- @param ipaddress zum pruefen
- @return ACL Wert oder -1 wenn nicht gefunden"""
- # Bei bereits aufgelösten IPs direkt ACL auswerten
- if ipaddress in self.__dict_knownips:
- return self.__dict_knownips[ipaddress]
-
- for aclip in sorted(self.__dict_acl, reverse=True):
- if refullmatch(self.__dict_regex[aclip], ipaddress):
- # IP und Level merken
- self.__dict_knownips[ipaddress] = self.__dict_acl[aclip]
-
- # Level zurückgeben
- return self.__dict_acl[aclip]
-
- return -1
-
- def loadacl(self, str_acl):
- """Laed ACL String und gibt erfolg zurueck.
- @param str_acl ACL als
- @return True, wenn erfolgreich uebernommen"""
- if not refullmatch(self.__re_ipacl, str_acl):
- return False
- self.__set_acl(str_acl)
- return True
-
- acl = property(__get_acl, __set_acl)
- regex_acl = property(__get_regex_acl)
-
-
def _setuprt(pid, evt_exit):
"""Konfiguriert Programm fuer den RT-Scheduler.
@param pid PID, der angehoben werden soll
diff --git a/revpipyload/picontrolserver.py b/revpipyload/picontrolserver.py
index f9d9551..bc207da 100644
--- a/revpipyload/picontrolserver.py
+++ b/revpipyload/picontrolserver.py
@@ -8,6 +8,7 @@
"""Modul fuer die Verwaltung der PLC-Slave Funktionen."""
import proginit
import socket
+from shared.ipaclmanager import IpAclManager
from threading import Event, Thread
from timeit import default_timer
@@ -26,8 +27,13 @@ class RevPiSlave(Thread):
def __init__(self, ipacl, port=55234):
"""Instantiiert RevPiSlave-Klasse.
- @param acl Stringliste mit Leerstellen getrennt
+ @param ipacl AclManager
@param port Listen Port fuer plc Slaveserver"""
+ if not type(ipacl) == IpAclManager:
+ raise ValueError("parameter ipacl must be ")
+ if not type(port) == int:
+ raise ValueError("parameter port must be ")
+
super().__init__()
self.__ipacl = ipacl
self._evt_exit = Event()
diff --git a/revpipyload/procimgserver.py b/revpipyload/procimgserver.py
index cf86d95..2b77a2c 100644
--- a/revpipyload/procimgserver.py
+++ b/revpipyload/procimgserver.py
@@ -28,17 +28,12 @@ class ProcimgServer():
"""
- def __init__(self, xmlserver, aclmode):
+ def __init__(self, xmlserver):
"""Instantiiert RevPiCheckServer()-Klasse.
-
- @param xmlserver XML-RPC Server
- @param aclmode Zugriffsrechte
-
- """
+ @param xmlserver XML-RPC Server"""
# Logger übernehmen
proginit.logger.debug("enter ProcimgServer.__init__()")
- self.acl = aclmode
self.rpi = None
# XML-Server übernehmen
@@ -121,13 +116,6 @@ class ProcimgServer():
@return list() [device, io, status, msg]
"""
- # Zugriffsrechte prüfen
- if self.acl < 3:
- return [
- device, io, False,
- "not allowed in XML-RPC permission mode {}".format(self.acl)
- ]
-
# Binary() in bytes() umwandeln
if type(value) == Binary:
value = value.data
@@ -192,9 +180,8 @@ class ProcimgServer():
for xmlfunc in self.xmlreadfuncs:
if xmlfunc in self.xmlsrv.funcs:
del self.xmlsrv.funcs[xmlfunc]
- if self.acl >= 3:
- for xmlfunc in self.xmlwritefuncs:
- if xmlfunc in self.xmlsrv.funcs:
- del self.xmlsrv.funcs[xmlfunc]
+ for xmlfunc in self.xmlwritefuncs:
+ if xmlfunc in self.xmlsrv.funcs:
+ del self.xmlsrv.funcs[xmlfunc]
proginit.logger.debug("leave ProcimgServer.stop()")
diff --git a/revpipyload/revpipyload.py b/revpipyload/revpipyload.py
index e665643..0ce57a4 100755
--- a/revpipyload/revpipyload.py
+++ b/revpipyload/revpipyload.py
@@ -40,8 +40,9 @@ import signal
import tarfile
import zipfile
from configparser import ConfigParser
-from helper import refullmatch, IpAclManager
+from helper import refullmatch
from json import loads as jloads
+from shared.ipaclmanager import IpAclManager
from shutil import rmtree
from tempfile import mkstemp
from threading import Event
@@ -49,7 +50,7 @@ from time import asctime
from xmlrpc.client import Binary
from xrpcserver import SaveXMLRPCServer
-pyloadversion = "0.6.1"
+pyloadversion = "0.6.2"
class RevPiPyLoad():
@@ -140,8 +141,8 @@ class RevPiPyLoad():
self.plcslave = \
int(self.globalconfig["PLCSLAVE"].get("plcslave", 0))
self.plcslaveacl = IpAclManager(minlevel=0, maxlevel=1)
- if not self.plcslaveacl.loadacl(
- self.globalconfig["PLCSLAVE"].get("acl", "")):
+ if not self.plcslaveacl.loadaclfile(
+ self.globalconfig["PLCSLAVE"].get("aclfile", "")):
proginit.logger.warning(
"can not load plcslave acl - wrong format"
)
@@ -163,8 +164,8 @@ class RevPiPyLoad():
self.xmlrpc = \
int(self.globalconfig["XMLRPC"].get("xmlrpc", 0))
self.xmlrpcacl = IpAclManager(minlevel=0, maxlevel=4)
- if not self.xmlrpcacl.loadacl(
- self.globalconfig["XMLRPC"].get("acl", "")):
+ if not self.xmlrpcacl.loadaclfile(
+ self.globalconfig["XMLRPC"].get("aclfile", "")):
proginit.logger.warning(
"can not load xmlrpc acl - wrong format"
)
@@ -228,9 +229,7 @@ class RevPiPyLoad():
# Erweiterte Funktionen anmelden
try:
import procimgserver
- self.xml_ps = procimgserver.ProcimgServer(
- self.xsrv, self.xmlrpc
- )
+ self.xml_ps = procimgserver.ProcimgServer(self.xsrv)
self.xsrv.register_function(1, self.xml_psstart, "psstart")
self.xsrv.register_function(1, self.xml_psstop, "psstop")
except:
@@ -719,11 +718,46 @@ class RevPiPyLoad():
)
)
return False
- self.globalconfig.set(
- sektion,
- key if localkey == "" else localkey,
- str(dc[key])
+ if localkey != "acl":
+ self.globalconfig.set(
+ sektion,
+ key if localkey == "" else localkey,
+ str(dc[key])
+ )
+
+ # ACLs sofort übernehmen und schreiben
+ str_acl = dc.get("plcslaveacl", None)
+ if str_acl is not None and self.plcslaveacl.acl != str_acl:
+ self.plcslaveacl.acl = str_acl
+ if not self.plcslaveacl.writeaclfile(aclname="PLC-SLAVE"):
+ proginit.logger.error(
+ "can not write acl file '{}' for PLC-SLAVE".format(
+ self.plcslaveacl.filename
)
+ )
+ return False
+ else:
+ proginit.logger.info(
+ "wrote new acl file '{}' for PLC-SLAVE".format(
+ self.plcslaveacl.filename
+ )
+ )
+ str_acl = dc.get("xmlrpcacl", None)
+ if str_acl is not None and self.xmlrpcacl.acl != str_acl:
+ self.xmlrpcacl.acl = str_acl
+ if not self.xmlrpcacl.writeaclfile(aclname="XML-RPC"):
+ proginit.logger.error(
+ "can not write acl file '{}' for XML-RPC".format(
+ self.xmlrpcacl.filename
+ )
+ )
+ return False
+ else:
+ proginit.logger.info(
+ "wrote new acl file '{}' for XML-RPC".format(
+ self.xmlrpcacl.filename
+ )
+ )
# conf-Datei schreiben
with open(proginit.globalconffile, "w") as fh:
diff --git a/revpipyload/shared/__init__.py b/revpipyload/shared/__init__.py
new file mode 100644
index 0000000..d059206
--- /dev/null
+++ b/revpipyload/shared/__init__.py
@@ -0,0 +1 @@
+"""Shared modules."""
diff --git a/revpipyload/shared/ipaclmanager.py b/revpipyload/shared/ipaclmanager.py
new file mode 100644
index 0000000..5bf9aea
--- /dev/null
+++ b/revpipyload/shared/ipaclmanager.py
@@ -0,0 +1,189 @@
+# -*- coding: utf-8 -*-
+#
+# IpAclManager
+#
+# (c) Sven Sager, License: LGPLv3
+# Version 0.1.0
+#
+"""Verwaltet IP Adressen und deren ACLs."""
+from os import access, R_OK, W_OK
+from re import match as rematch
+
+
+def refullmatch(regex, string):
+ """re.fullmatch wegen alter python version aus wheezy nachgebaut.
+
+ @param regex RegEx Statement
+ @param string Zeichenfolge gegen die getestet wird
+ @return True, wenn komplett passt sonst False
+
+ """
+ m = rematch(regex, string)
+ return m is not None and m.end() == len(string)
+
+
+class IpAclManager():
+
+ """Verwaltung fuer IP Adressen und deren ACL Level."""
+
+ def __init__(self, minlevel, maxlevel, acl=None):
+ """Init IpAclManager class.
+
+ @param minlevel Smallest access level (min. 0)
+ @param maxlevel Biggest access level (max. 9)
+ @param acl ACL Liste fuer Berechtigungen als
+
+ """
+ if type(minlevel) != int:
+ raise ValueError("parameter minlevel must be ")
+ if type(maxlevel) != int:
+ raise ValueError("parameter maxlevel must be ")
+ if minlevel < 0:
+ raise ValueError("minlevel must be 0 or more")
+ if maxlevel > 9:
+ raise ValueError("maxlevel maximum is 9")
+ if minlevel > maxlevel:
+ raise ValueError("minlevel is smaller than maxlevel")
+
+ self.__dict_acl = {}
+ self.__dict_regex = {}
+ self.__dict_knownips = {}
+ self.__filename = None
+ self.__re_ipacl = "(([\\d\\*]{1,3}\\.){3}[\\d\\*]{1,3},[" \
+ + str(minlevel) + "-" + str(maxlevel) + "] ?)*"
+
+ # Liste erstellen, wenn übergeben
+ if acl is not None:
+ self.__set_acl(acl)
+
+ def __iter__(self):
+ """Gibt einzelne ACLs als aus."""
+ for aclip in sorted(self.__dict_acl):
+ yield (aclip, self.__dict_acl[aclip])
+
+ def __get_acl(self):
+ """Getter fuer den rohen ACL-String.
+ return ACLs als """
+ str_acl = ""
+ for aclip in sorted(self.__dict_acl):
+ str_acl += "{},{} ".format(aclip, self.__dict_acl[aclip])
+ return str_acl.strip()
+
+ def __get_filename(self):
+ """Getter fuer Dateinamen.
+ @return Filename der ACL """
+ return "" if self.__filename is None else self.__filename
+
+ def __get_regex_acl(self):
+ """Gibt formatierten RegEx-String zurueck.
+ return RegEx Code als """
+ return self.__re_ipacl
+
+ def __set_acl(self, value):
+ """Uebernimmt neue ACL-Liste fuer die Ausertung der Level.
+ @param value Neue ACL-Liste als """
+ if type(value) != str:
+ raise ValueError("parameter acl must be ")
+
+ value = value.strip()
+ if not refullmatch(self.__re_ipacl, value):
+ raise ValueError("acl format ist not okay - 1.2.3.4,0 5.6.7.8,1")
+
+ # Klassenwerte übernehmen
+ self.__dict_acl = {}
+ self.__dict_regex = {}
+ self.__dict_knownips = {}
+
+ # Liste neu füllen mit regex Strings
+ for ip_level in value.split():
+ ip, level = ip_level.split(",", 1)
+ self.__dict_acl[ip] = int(level)
+ self.__dict_regex[ip] = \
+ ip.replace(".", "\\.").replace("*", "\\d{1,3}")
+
+ def get_acllevel(self, ipaddress):
+ """Prueft IP gegen ACL List und gibt ACL-Wert aus.
+ @param ipaddress zum pruefen
+ @return ACL Wert oder -1 wenn nicht gefunden"""
+ # Bei bereits aufgelösten IPs direkt ACL auswerten
+ if ipaddress in self.__dict_knownips:
+ return self.__dict_knownips[ipaddress]
+
+ for aclip in sorted(self.__dict_acl, reverse=True):
+ if refullmatch(self.__dict_regex[aclip], ipaddress):
+ # IP und Level merken
+ self.__dict_knownips[ipaddress] = self.__dict_acl[aclip]
+
+ # Level zurückgeben
+ return self.__dict_acl[aclip]
+
+ return -1
+
+ def loadacl(self, str_acl):
+ """Laed ACL String und gibt erfolg zurueck.
+ @param str_acl ACL als
+ @return True, wenn erfolgreich uebernommen"""
+ if not refullmatch(self.__re_ipacl, str_acl):
+ return False
+ self.__set_acl(str_acl)
+ return True
+
+ def loadaclfile(self, filename):
+ """Laed ACL Definitionen aus Datei.
+ @param filename Dateiname fuer Definitionen
+ @return True, wenn Laden erfolgreich war"""
+ if type(filename) != str:
+ raise ValueError("parameter filename must be ")
+
+ # Zugriffsrecht prüfen
+ if not access(filename, R_OK):
+ return False
+
+ str_acl = ""
+ with open(filename, "r") as fh:
+ while True:
+ buff = fh.readline()
+ if buff == "":
+ break
+ buff = buff.split("#")[0].strip()
+ if len(buff) > 0:
+ str_acl += buff + " "
+
+ acl_okay = self.loadacl(str_acl.strip())
+ if acl_okay:
+ # Dateinamen für Schreiben übernehmen
+ self.__filename = filename
+
+ return acl_okay
+
+ def writeaclfile(self, filename=None, aclname=None):
+ """Schreibt ACL Definitionen in Datei.
+ @param filename Dateiname fuer Definitionen
+ @return True, wenn Schreiben erfolgreich war"""
+ if filename is not None and type(filename) != str:
+ raise ValueError("parameter filename must be ")
+ if aclname is not None and type(aclname) != str:
+ raise ValueError("parameter aclname must be ")
+
+ # Dateinamen prüfen
+ if filename is None and self.__filename is not None:
+ filename = self.__filename
+
+ # Zugriffsrecht prüfen
+ if not access(filename, W_OK):
+ return False
+
+ header = "# {}Access Control List (acl)\n" \
+ "# One entry per Line IPADRESS,LEVEL\n" \
+ "#\n".format("" if aclname is None else aclname + " ")
+
+ with open(filename, "w") as fh:
+ fh.write(header)
+ for aclip in sorted(self.__dict_acl):
+ fh.write("{},{}\n".format(aclip, self.__dict_acl[aclip]))
+
+ return True
+
+ acl = property(__get_acl, __set_acl)
+ filename = property(__get_filename)
+ regex_acl = property(__get_regex_acl)
diff --git a/revpipyload/xrpcserver.py b/revpipyload/xrpcserver.py
index 3304bed..1f3d1df 100644
--- a/revpipyload/xrpcserver.py
+++ b/revpipyload/xrpcserver.py
@@ -7,7 +7,7 @@
#
"""XML-RPC Server anpassungen fuer Absicherung."""
import proginit
-from helper import IpAclManager
+from shared.ipaclmanager import IpAclManager
from concurrent import futures
from xmlrpc.server import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
@@ -19,9 +19,13 @@ class SaveXMLRPCServer(SimpleXMLRPCServer):
def __init__(
self, addr, logRequests=True, allow_none=False,
use_builtin_types=False, ipacl=None):
- """Init SaveXMLRPCServer class."""
+ """Init SaveXMLRPCServer class.
+ @param ipacl AclManager """
proginit.logger.debug("enter SaveXMLRPCServer.__init__()")
+ if ipacl is not None and type(ipacl) != IpAclManager:
+ raise ValueError("parameter ipacl must be ")
+
# Vererbte Klasse instantiieren
super().__init__(
addr=addr,
diff --git a/setup.py b/setup.py
index 8102a5c..079f00e 100644
--- a/setup.py
+++ b/setup.py
@@ -27,7 +27,7 @@ setup(
license="LGPLv3",
name="revpipyload",
- version="0.6.1",
+ version="0.6.2",
scripts=["data/revpipyload"],