From 565ecf5d8bd9c89db3f5e32cf5fa5e6fb506c4bc Mon Sep 17 00:00:00 2001 From: Sven Sager Date: Mon, 27 Jul 2026 10:34:53 +0200 Subject: [PATCH] feat: Add unix group support for XML-RPC server socket permissions - Introduced `unixgroup` configuration for XML-RPC in `revpipyload.conf`. - Updated `UnixStreamXMLRPCServer` to set socket group ownership and permissions. Signed-off-by: Sven Sager --- data/etc/revpipyload/revpipyload.conf | 9 ++--- src/revpipyload/revpipyload.py | 3 +- src/revpipyload/xrpcserver.py | 50 +++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 5 deletions(-) diff --git a/data/etc/revpipyload/revpipyload.conf b/data/etc/revpipyload/revpipyload.conf index 37e1eaa..e38ce76 100644 --- a/data/etc/revpipyload/revpipyload.conf +++ b/data/etc/revpipyload/revpipyload.conf @@ -7,7 +7,7 @@ plcworkdir_set_uid = 1 plcprogram = program.py plcprogram_stop_timeout = 5 plcprogram_watchdog = 0 -plcarguments = +plcarguments = plcuid = 1000 plcgid = 1000 pythonversion = 3 @@ -28,6 +28,7 @@ watchdog = 1 xmlrpc = 1 aclfile = /etc/revpipyload/aclxmlrpc.conf bindip = socket +unixgroup = picontrol [MQTT] mqtt = 0 @@ -38,6 +39,6 @@ write_outputs = 0 broker_address = localhost port = 1883 tls_set = 0 -username = -password = -client_id = +username = +password = +client_id = diff --git a/src/revpipyload/revpipyload.py b/src/revpipyload/revpipyload.py index ff762de..175a551 100644 --- a/src/revpipyload/revpipyload.py +++ b/src/revpipyload/revpipyload.py @@ -331,6 +331,7 @@ class RevPiPyLoad: self.xmlrpcbindip = "127.0.0.1" self.xmlrpcport = self.globalconfig.getint("XMLRPC", "port", fallback=55123) + self.xmlrpcunixgroup = self.globalconfig.get("XMLRPC", "unixgroup", fallback="picontrol") # Workdirectory wechseln if not os.access(self.plcworkdir, os.R_OK | os.W_OK | os.X_OK): @@ -414,9 +415,9 @@ class RevPiPyLoad: self.xsrv = UnixStreamXMLRPCServer( self.xmlrpcbindip, - requestHandler=UnixStreamXMLRPCRequestHandler, logRequests=False, allow_none=True, + unixgroup=self.xmlrpcunixgroup ) else: diff --git a/src/revpipyload/xrpcserver.py b/src/revpipyload/xrpcserver.py index 583ad64..7d51ce7 100644 --- a/src/revpipyload/xrpcserver.py +++ b/src/revpipyload/xrpcserver.py @@ -4,6 +4,8 @@ __author__ = "Sven Sager" __copyright__ = "Copyright (C) 2023 Sven Sager" __license__ = "GPLv2" +import grp +import os import socket from xmlrpc.server import SimpleXMLRPCRequestHandler, SimpleXMLRPCServer @@ -127,6 +129,54 @@ class UnixStreamXMLRPCServer(SimpleXMLRPCServer): """XML-RPC Server fuer Unix Domain Sockets.""" address_family = socket.AF_UNIX + def __init__( + self, addr, logRequests=True, allow_none=False, unixgroup="picontrol"): + """Init UnixStreamXMLRPCServer class.""" + proginit.logger.debug("enter UnixStreamXMLRPCServer.__init__()") + + self.timeout = 0.5 + self.unixgroup = unixgroup + + # Create subdirectories for Unix Domain Socket + socket_dir = os.path.dirname(addr) + if socket_dir: + os.makedirs(socket_dir, exist_ok=True) + + super().__init__( + addr=addr, + requestHandler=UnixStreamXMLRPCRequestHandler, + logRequests=logRequests, + allow_none=allow_none, + encoding="utf-8", + bind_and_activate=False, + ) + + proginit.logger.debug("leave UnixStreamXMLRPCServer.__init__()") + + def server_bind(self): + """Ueberschreibt server_bind um Berechtigungen zu setzen.""" + super().server_bind() + + # Gruppe setzen + try: + gid = grp.getgrnam(self.unixgroup).gr_gid + # -1 will leave the owner unchanged + os.chown(self.server_address, -1, gid) + except (KeyError, PermissionError): + proginit.logger.warning( + "can not set group of socket {0} to '{1}'" + "".format(self.server_address, self.unixgroup) + ) + + # Berechtigungen fuer restliche Benutzer entziehen + try: + os.chmod(self.server_address, 0o660) + except PermissionError: + proginit.logger.warning( + "can not set permissions of socket {0}" + "".format(self.server_address) + ) + def _dispatch(self, method, params): """Prueft ACL Level fuer angeforderte Methode.