I'm trying to set up remote access to D-Bus, and I don't understand how authentication and authorization are (not) working.
I have a D-Bus server listening on an abstract socket.
$ echo $DBUS_SESSION_BUS_ADDRESS unix:abstract=/tmp/dbus-g5sxxvDlmz,guid=49bd93b893fe40d83604952155190c31
dbus-monitor to watch what's going on. My test case is
notify-send hello, which works when executed from the local machine.
From another account on the same machine, I can't connect to that bus.
otheraccount$ DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-g5sxxvDlmz,guid=49bd93b893fe40d83604952155190c31 dbus-monitor Failed to open connection to session bus: Did not receive a reply. Possible causes include: the remote application did not send a reply, the message bus security policy blocked the reply, the reply timeout expired, or the network connection was broken. otheraccount$ DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-g5sxxvDlmz,guid=49bd93b893fe40d83604952155190c31 notify-send hello
After browsing the D-Bus specification, I copied
~/.dbus-keyrings/org_freedesktop_general to the other account, but it doesn't help.
socat TCP-LISTEN:8004,reuseaddr,fork,range=127.0.0.1/32 ABSTRACT-CONNECT:/tmp/dbus-g5sxxvDlmz
I can connect to the TCP socket from my account.
DBUS_SESSION_BUS_ADDRESS=tcp:host=127.0.0.1,port=8004 notify-send hello
But not from the other account, neither with
dbus-monitor nor with
notify-send. Same error message for
dbus-monitor as above with the abstract socket;
notify-send now emits a trace:
otheraccount$ DBUS_SESSION_BUS_ADDRESS=tcp:host=127.0.0.1,port=8004 notify-send hello ** (notify-send:2952): WARNING **: The connection is closed
Stracing reveals that this version of
notify-send doesn't try to read the cookie file, so I understand why it wouldn't be able to connect.
I also tried SSHing into another machine and forwarding the TCP connection.
ssh -R 8004:localhost:8004 remotehost
dbus-monitor works without a cookie file! I can watch the D-Bus traffic from the remote host. I see a notice about eavesdropping in my local
remotehost$ DBUS_SESSION_BUS_ADDRESS=tcp:host=127.0.0.1,port=8004 dbus-monitor signal sender=org.freedesktop.DBus -> dest=:1.58 serial=2 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=NameAcquired string ":1.58" method call sender=:1.58 -> dest=org.freedesktop.DBus serial=2 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch string "eavesdrop=true"
If I run
notify-send on the local machine,
dbus-monitor on the remote host sees the notification. It's definitely reached a level of access that should require authentication.
notify-send complained about not finding a cookie. After copying the cookie file,
notify-send works from the remote machine.
The local machine runs Debian wheezy. The remote machine runs FreeBSD 10.1.
I don't understand how D-Bus authentication and authorization work.
- Why can I eavesdrop, as far as I can tell, with no credentials from the remote machine? What am I exposing when I forward D-Bus to a TCP connection? Why are authorizations for
- Why can I not eavesdrop from another account on the same machine, whether over the abstract socket or over the TCP connection?
- I noticed that the cookie file changes every few minutes (I haven't figured out if it's at regular intervals or not). Why?
(I know I can launch a D-Bus daemon that listens on TCP. That's not the purpose of my question, I want to understand why what I did did and did not work.)