XDG-DBUS-PROXY(1)

๐Ÿ’… NAME

xdg-dbus-proxy โ€” it's a D-Bus proxy, bestie. That's the whole vibe.


โœจ SYNOPSIS

xdg-dbus-proxy [OPTION...] [ADDRESS PATH [OPTION...]...]

๐ŸŒธ DESCRIPTION

So xdg-dbus-proxy is literally a filtering proxy for D-Bus connections. Iconic behavior honestly.

The way you talk to it is: you hand it one or more ADDRESS-PATH pairs telling it which buses to proxy, plus options saying what filtering to apply. Simple as that.

๐Ÿงš Basic Operation

The proxy sits and listens on the unix domain socket at PATH. Every time a client connects to that socket, it opens up a brand new connection to the D-Bus ADDRESS you gave it (usually the session bus, real talk) and forwards data back and forth between the two like a little messenger.

During the authentication phase, everything gets forwarded exactly as it's received. And also โ€” for the first 1 byte zero โ€” we additionally send the proxy credentials to the bus. Yep, exactly that.

Once the connection is all authenticated, there's two modes: filtered and unfiltered.

  • In the unfiltered mode, all messages are sent on as they are received. No notes, no gatekeeping.
  • In the filtering mode, policy gets applied to figure out which messages to allow and which to drop. ๐Ÿ’€

Filtering only applies to outgoing signals and method calls, and incoming broadcast signals. All replies (errors or method returns) are allowed once for an outstanding method call, and never otherwise. That's the rule, periodt.

If a client ever receives a message from another peer on the bus, that sender's unique name gets made visible, so the client can track caller lifetimes via NameOwnerChanged signals. And if a client calls a method on, or receives a broadcast signal from, a name โ€” even if it's filtered down to some subset of paths or interfaces โ€” then that name's basic policy is considered to be (at least) TALK, from then on. Sticky situation, but make it fashion. โœจ

๐Ÿ‘‘ Policy

The policy for filtering is a mapping from well-known names to a policy that's either SEE, TALK or OWN.

The default initial policy: the user is only allowed to TALK to the bus itself (org.freedesktop.DBus, or no destination specified at all), and TALK to its own unique ID. All other clients are invisible. Not ghosting you, they literally don't exist to you.

Here's the policy levels, each one implying the ones before it:

SEE

  • The name/ID is visible in the ListNames reply
  • The name/ID is visible in the ListActivatableNames reply
  • You can call GetNameOwner on the name
  • You can call NameHasOwner on the name
  • You see NameOwnerChanged signals on the name
  • You see NameOwnerChanged signals on the ID when the client disconnects
  • You can call the GetXXX methods on the name/ID to get e.g. the peer pid
  • You get AccessDenied rather than NameHasNoOwner when sending messages to the name/ID

TALK

  • You can send any method calls and signals to the name/ID
  • You will receive broadcast signals from the name/ID (if you have a match rule for them)
  • You can call StartServiceByName on the name

OWN

  • You are allowed to call RequestName/ReleaseName/ListQueuedOwners on the name

Policy gets specified with the --see, --talk and --own options. The well-known names in these options can have a .* suffix. So a name of "org.foo.*" matches "org.foo", "org.foo.bar", and "org.foo.bar.gazonk" โ€” but not "org.foobar". Respect the boundary, bestie. ๐Ÿšง

Policies are specified for well-known names, but they also affect the owner of that name, so the policy for a unique ID is the union of the policies for all the names it owns. For technical reasons (iykyk), the policy for a unique name is "sticky" โ€” the highest policy ever granted by a once-owned name is kept, even when the client releases that name. This is impossible to avoid in a race-free way in a proxy. But it's rarely a problem in practice, since few clients release names and stay on the bus.

On top of the basic SEE/TALK/OWN policy, you can also specify way more complicated rules about what method calls can be made on, and what broadcast signals can be received from, well-known names. A rule can restrict the allowed calls/signals to a specific object path or a subtree of object paths, and it can restrict the allowed interface down to an individual method or signal name.

Rules get specified with the --call and --broadcast options. The RULE in these options decides what interfaces, methods and object paths are allowed. It must be of the form:

[METHOD][@PATH]

where METHOD can be either '*' or a D-Bus interface (possibly with a '.*' suffix), or a fully-qualified method name, and PATH is a D-Bus object path (possibly with a '/*' suffix).


๐ŸŽ€ OPTIONS

Heads up: when options are used multiple times, the last option wins, unless otherwise specified. Last one standing, always.

๐ŸŒˆ General options:

  • --help โ€” Print help and exit. Your classic "what does anything mean" button.
  • --version โ€” Print version. Number reveal, slay.
  • --fd=FD โ€” Write to FD when the proxies are ready, and stop when it is closed.
  • --args=FD โ€” Parse nul-separated arguments from the given file descriptor. This option can be used multiple times to parse options from multiple sources. Multitasking queen.

๐Ÿฆ‹ Proxy Options:

These options can only be used after an ADDRESS, and they apply to the proxy for that address. Order matters, bestie.
  • --filter โ€” Enable filtering.
  • --log โ€” Turn on logging.
  • --sloppy-names โ€” Make all unique names visible.
  • --see=NAME โ€” Set the SEE policy for the given name.
  • --talk=NAME โ€” Set the TALK policy for the given name.
  • --own=NAME โ€” Set the OWN policy for the given name.
  • --call=NAME=RULE โ€” Set a rule for calls on the given name.
  • --broadcast=NAME=RULE โ€” Set a rule for broadcast signals from the given name.

๐Ÿซถ EXAMPLES

Look at her go:

$ xdg-dbus-proxy --fd=26 unix:path=/run/usr/1000/bus
/run/usr/1000/.dbus-proxy/session-bus-proxy --filter
--own=org.gnome.ghex.* --talk=ca.desrt.dconf
--call=org.freedesktop.portal.*=*
--broadcast=org.freedesktop.portal.*=@/org/freedesktop/portal/*

aaaand that's the whole page, you ate it up fr fr ๐Ÿ“

this lil manual page lives in the flatpak family โ€” that's the source it came from and the name it rides under (XDG-DBUS-PROXY(1)). mwah, go proxy something responsibly ๐Ÿ’–

๐Ÿ“ฆ where this page comes from