From 505e2b55276a61821a61c43e22ddf108df3080c7 Mon Sep 17 00:00:00 2001 From: Alvaro Leiva Geisse Date: Tue, 19 Oct 2021 16:25:44 -0700 Subject: [PATCH] add interactive_authorization options for buses Summary: Pystemd is menat to be used as a library, so it never really implemented the interactive auth that systemd uses, but recently people really want to use it, and since its already there, lets just add it. see examples/start_transient_unit.py on how to setup interactive auth. Reviewed By: davide125 Differential Revision: D31773957 fbshipit-source-id: 2cae24cadd3945693515613850c345f9b0d33d83 --- CHANGES.md | 4 ++++ examples/start_transient_unit.py | 34 +++++++++++++++++--------------- pystemd/__version__.py | 2 +- pystemd/dbusc.pxd | 3 +++ pystemd/dbuslib.pyi | 2 ++ pystemd/dbuslib.pyx | 14 ++++++++++++- 6 files changed, 41 insertions(+), 18 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 5d0e1ca..0b358f8 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,10 @@ Changelog We annotate all changes here, keep in mind that the high version may not be the one you find pypi, but its the one in development. +0.10.0 +===== +* support for interactive auth. + 0.9.0 ===== * add initial support for Python 3.9 diff --git a/examples/start_transient_unit.py b/examples/start_transient_unit.py index f065229..51d94b8 100644 --- a/examples/start_transient_unit.py +++ b/examples/start_transient_unit.py @@ -11,6 +11,7 @@ import shlex import time +from pystemd.dbuslib import DBus from pystemd.systemd1 import Manager, Unit @@ -25,23 +26,24 @@ def start_transient_unit(cmd="/bin/sleep 15"): b"ExecStart": [(a_cmd[0], a_cmd, False)], b"RemainAfterExit": True, } - - with Manager() as manager: + # if we need interactive prompts for passwords, we can create our own DBus object. + # if we dont need interactive, we would just do `with Manager() as manager:`. + with DBus(interactive=True) as bus, Manager(bus=bus) as manager: manager.Manager.StartTransientUnit(random_unit_name, b"fail", unit) - with Unit(random_unit_name) as unit: - while True: - print( - "service `{cmd}` (name={random_unit_name}) has MainPID " - "{unit.Service.MainPID}".format(**locals()) - ) - if unit.Service.MainPID == 0: + with Unit(random_unit_name, bus=bus) as unit: + while True: print( - "service finished with " - "{unit.Service.ExecMainStatus}/{unit.Service.Result} " - "will stop it and then... bye".format(**locals()) + "service `{cmd}` (name={random_unit_name}) has MainPID " + "{unit.Service.MainPID}".format(**locals()) ) - unit.Unit.Stop(b"replace") - break - print("service still runing, sleeping by 5 seconds") - time.sleep(5) + if unit.Service.MainPID == 0: + print( + "service finished with " + "{unit.Service.ExecMainStatus}/{unit.Service.Result} " + "will stop it and then... bye".format(**locals()) + ) + unit.Unit.Stop(b"replace") + break + print("service still runing, sleeping by 5 seconds") + time.sleep(5) diff --git a/pystemd/__version__.py b/pystemd/__version__.py index 96a81b0..23bd127 100644 --- a/pystemd/__version__.py +++ b/pystemd/__version__.py @@ -11,7 +11,7 @@ import sys -__version__ = "0.9" +__version__ = "0.10" _endstr = ".dev" diff --git a/pystemd/dbusc.pxd b/pystemd/dbusc.pxd index 494ff84..958b687 100644 --- a/pystemd/dbusc.pxd +++ b/pystemd/dbusc.pxd @@ -156,6 +156,9 @@ cdef extern from "systemd/sd-bus.h": int sd_bus_path_encode(char* prefix, char* external_id, char **ret_path) int sd_bus_path_decode(char* path, char* prefix, char **ret_external_id) + int sd_bus_set_allow_interactive_authorization(sd_bus *bus, int b); + int sd_bus_get_allow_interactive_authorization(sd_bus *bus); + cdef extern from "systemd/sd-bus-protocol.h": diff --git a/pystemd/dbuslib.pyi b/pystemd/dbuslib.pyi index e73628c..0e84341 100644 --- a/pystemd/dbuslib.pyi +++ b/pystemd/dbuslib.pyi @@ -42,6 +42,8 @@ class DBus: ) -> None: ... def wait(self, timeout: int) -> None: ... def get_fd(self) -> int: ... + def get_allow_interactive_authorization(self) -> bool: ... + def set_allow_interactive_authorization(self, interactive: bool) -> None: ... class DBusMachine(DBus): def __init__(self, machine: bytes) -> None: ... diff --git a/pystemd/dbuslib.pyx b/pystemd/dbuslib.pyx index 7301d83..b97b25d 100644 --- a/pystemd/dbuslib.pyx +++ b/pystemd/dbuslib.pyx @@ -277,9 +277,11 @@ cdef class DbusMessage: cdef class DBus: cdef dbusc.sd_bus *bus cdef bool user_mode + cdef int interactive - def __init__(self, user_mode=False): + def __init__(self, user_mode=False, interactive=None): self.user_mode = user_mode + self.interactive = -1 if interactive is None else int(interactive) def __enter__(self): self.open() @@ -301,6 +303,8 @@ cdef class DBus: rets = self.open_dbus_bus() if (rets < 0): raise DBusError(rets, None, "Could not open a bus to DBus") + if self.interactive >= 0: + self.set_allow_interactive_authorization(self.interactive) def close(self): dbusc.sd_bus_close(self.bus) @@ -541,6 +545,14 @@ cdef class DBus: cpdef int get_fd(self): return dbusc.sd_bus_get_fd(self.bus) + cpdef bool get_allow_interactive_authorization(self): + return dbusc.sd_bus_get_allow_interactive_authorization(self.bus) + + cpdef set_allow_interactive_authorization(self, bool interactive): + r = dbusc.sd_bus_set_allow_interactive_authorization(self.bus, interactive) + if r < 0: + raise DBusError(r, None, "Failed to set interactive authorization") + cdef class DBusMachine(DBus): "DBus class that connects to machine"