Skip to content

Commit

Permalink
add interactive_authorization options for buses
Browse files Browse the repository at this point in the history
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
  • Loading branch information
aleivag authored and facebook-github-bot committed Oct 19, 2021
1 parent 2d90700 commit 505e2b5
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 18 deletions.
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
34 changes: 18 additions & 16 deletions examples/start_transient_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import shlex
import time

from pystemd.dbuslib import DBus
from pystemd.systemd1 import Manager, Unit


Expand All @@ -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)
2 changes: 1 addition & 1 deletion pystemd/__version__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import sys


__version__ = "0.9"
__version__ = "0.10"

_endstr = ".dev"

Expand Down
3 changes: 3 additions & 0 deletions pystemd/dbusc.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -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":
Expand Down
2 changes: 2 additions & 0 deletions pystemd/dbuslib.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -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: ...
Expand Down
14 changes: 13 additions & 1 deletion pystemd/dbuslib.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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)
Expand Down Expand Up @@ -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"
Expand Down

0 comments on commit 505e2b5

Please sign in to comment.