Search code examples
linuxsystemddbussambaazure-entra-id

Secure communication between a daemon and D-Bus on Linux


So I have a daemon which is used to authenticate users via Azure Entra Id (the daemon is Himmelblaud). I'm writing a session D-Bus service (the bare bones here) to provide SSO creds to various apps that are running (such as MS apps, browser plugins, gnome-online-accounts, etc). This D-Bus service will mimic the MS Intune D-Bus service. Essentially I'm providing a opensource drop-in replacement for MS's proprietary binaries.

So the question is, how do I securely transmit the appropriate credentials between the daemon (which runs under a systemd dynamic user) and the session D-Bus service (which runs as the authenticated user who needs the creds)? There is no way to access those creds outside of getting them somehow from that daemon.

I'm thinking along the lines of a unix socket, but validate that the connecting D-Bus session is from the user who is authorized to request those creds. Is this secure though?

The situation I want to avoid is a system with multiple authenticated users, and to have some user communicate with the daemon and ask for someone else's access token for Entra Id, etc.


Solution

  • You could design a custom Unix socket protocol between the session service and system service that uses either the SO_PEERCRED or SCM_CREDENTIALS features – I would not be surprised if Samba and Winbindd already had plenty of examples – but this seems like a waste of effort, since your project already involves D-Bus (which typically works over the same Unix sockets), it would be easiest to make the system daemon also a D-Bus service and make use of the existing code.

    There is a special D-Bus call to dbus-daemon itself which your system daemon may use to get the connection credentials of any entity on the bus – many D-Bus libraries provide specific bindings for these calls, e.g. get_connection_credentials() and get_connection_unix_user() in zbus, but it can also be called manually on the "bus object":

    • Destination: org.freedesktop.DBus
    • Object: /org/freedesktop/DBus
    • Method: org.freedesktop.DBus.GetConnectionCredentials(s bus_name)
    • Method: org.freedesktop.DBus.GetConnectionUnixUser(s bus_name)

    ...where the argument is the original caller's unique bus name (the :1.xyz string) that the D-Bus library provides to your service's method call implementations.

    Most if not all services on your system bus rely on this mechanism – some of them use bus policies (where dbus-daemon directly applies restrictions based on the Unix client UID/GID), while most others directly get caller credentials and make their own decisions.