Broadcast to specific user?

Simon McVittie smcv at collabora.com
Wed Oct 28 14:29:42 UTC 2020


On Tue, 27 Oct 2020 at 14:30:37 -0400, Felipe Gasper wrote:
> Is it possible with D-Bus to broadcast a signal such that only clients
> logged in as a specific user or group will receive the message?

No. A D-Bus signal is either broadcast to everyone by not setting a
destination (this is most common), or unicast to a single connection by
setting a non-NULL destination that is the connection's unique name or
one of its well-known names (this is rare).

Technically signals with no destination are more like multicast than
broadcast, because when you send a signal like this, the dbus-daemon
selectively only forwards it to the recipients that subscribed to it; but
everyone is allowed to subscribe to any signal, so conceptually this is
just broadcast with a performance optimization.

If you want to send non-public information on the system bus, you can't
use broadcasts. If you want to emulate a more controlled multicast by
sending individual unicast signals to each recipient, you should
implement your own subscription mechanism to avoid waking up clients
that have the right user/group but don't care about this particular
message, for example:

    signal com.example.MyAPI1.PasswordChanged(s user, u length, u strength)
        Emitted as a unicast signal when @user changes their password.
        The new password is @length characters and has a complexity given
        by @strength.

        This signal is only sent to @user or to members of the 'admin'
        group, and only if they have subscribed via Subscribe().

    method com.example.MyAPI1.Subscribe(s user) -> nothing
        Ask to be notified when @user changes their password, or if
        @user is the empty string, when anyone changes their password.

        The service will send unicast com.example.MyAPI1.PasswordChanged
        signals to the connection that called this method.

The Subscribe() method would be a good place to check that the caller
has the necessary credentials, and send back an error if they don't.

The other pattern that is sometimes used for this sort of thing is the
"agent" pattern used by Geoclue, NetworkManager, polkit, etc., where
the *client* implements an interface:

    method com.example.MyAPI.Agent1.CheckPasswordPolicy(
        s user, u length, u strength
    ) -> nothing
        Called when @user changes their password.
        The new password is @length characters and has a complexity given
        by @strength.

        The agent may raise an error to tell the caller that this
        password is too weak. Otherwise, it must send an empty reply.

and the service exports an interface that lets the client ask to be
contacted on that interface:

    method com.example.MyAPI1.RegisterAgent(s user, o path) -> nothing
        Ask to be notified when @user changes their password, or if
        @user is the empty string, when anyone changes their password.

        The service will call com.example.MyAPI.Agent1.CheckPasswordPolicy
        on the object path given by @path, at the bus name of the connection
        that called this method.

Obviously these examples are a bit silly and you wouldn't really implement
a password complexity policy like this - it's just the first thing I
thought of where secrets are going over the bus.

    smcv


More information about the dbus mailing list