Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

DBus: connecting without DBUS_SESSION_BUS_ADDRESS environment variable #394

Closed
kwshi opened this issue Dec 25, 2020 · 8 comments
Closed

Comments

@kwshi
Copy link

kwshi commented Dec 25, 2020

It appears, per #258, that the DBUS_SESSION_BUS_ADDRESS environment variable needs to be set in order for signal-cli to be able to detect and connect to a running DBus user session bus. Yet many other DBus-interacting programs, e.g. the dbus-send CLI tool, Python's pydbus library, etc., are capable of detecting and establishing a session bus connection even in the absence of the DBUS_SESSION_BUS_ADDRESS environment variable. Why is that?

I don't know very much about DBus, so this is more of a question than an actual issue--how do those other things succeed at connecting to DBus even though the environment variable is unset? And if those things can do it, shouldn't it be nice for signal-cli to be able to do that as well?

Relevant information: my OS is Void Linux, signal-cli version 0.7.1 (downloaded via GH release binary tar).

@exquo
Copy link
Contributor

exquo commented Dec 25, 2020

Just linking here the same issue that had been reported by some BSD users: #363.

dbus-send CLI tool, Python's pydbus library, etc., are capable of detecting and establishing a session bus connection even in the absence of the DBUS_SESSION_BUS_ADDRESS environment variable. Why is that?

My guess (and it's not an educated one): those tools connect to the running dbus services, whereas signal-cli needs to register its (new) dbus service.

Here is a SO question that gives an example of registering a basic "hello world" dbus service. If running that code also requires setting the env variable on your system, then we know it's not just a signal-cli issue.

@kwshi
Copy link
Author

kwshi commented Dec 25, 2020

Thanks for linking that! The code example given in the SO question was written for dbus-python, which I couldn't install for some reason, so instead I found this equivalent (I think) example from pydbus, which registers a new service named net.lew21.pydbus.ClientServerExample.

Running that script raises no errors for me, even in the absence of the DBUS_SESSION_BUS_ADDRESS variable, and I could confirm the service was running and working by the following commands:

  • Introspecting the interface XML:

    [kshi@(none) ~]$ dbus-send --session --print-reply \
      --dest=net.lew21.pydbus.ClientServerExample \
      /net/lew21/pydbus/ClientServerExample \
      org.freedesktop.DBus.Introspectable.Introspect
    

    output, too long to paste here

  • Calling the Hello method:

    [kshi@(none) ~]$ dbus-send --session --print-reply \
      --dest=net.lew21.pydbus.ClientServerExample \
      /net/lew21/pydbus/ClientServerExample \
      net.lew21.pydbus.ClientServerExample.Hello
    
    method return time=1608928484.888991 sender=:1.154 -> destination=:1.156 serial=5 reply_serial=2
       string "Hello, World!"
    
  • Calling the EchoString method:

    [kshi@(none) ~]$ dbus-send --session --print-reply \
      --dest=net.lew21.pydbus.ClientServerExample \
      /net/lew21/pydbus/ClientServerExample \
      net.lew21.pydbus.ClientServerExample.EchoString \
      'string:pingpong'
    
    method return time=1608928853.030217 sender=:1.154 -> destination=:1.162 serial=10 reply_serial=2
       string "pingpong"
    

So it appears to me that registering vs. connecting doesn't appear to be the source of the issue.

@kwshi
Copy link
Author

kwshi commented Dec 25, 2020

An aside: the error message I receive is "Cannot Resolve Session Bus Address", which differs from the one described by #363, which is "Failed to connect to bus: No such file or directory". Perhaps they are the same underlying error (with different messages because of the differing OS platform), and it seems likely that they share the same cause, but I'm going to hold off on closing this issue as a duplicate of that one just in case there happen to be other differences.

I propose, since the specific issue of running the dbus daemon without DBUS_SESSION_BUS_ADDRESS set appears not actually specific to FreeBSD, that discussion about that remain on this thread, while #363 be used for discussing whether the solutions found here also solve the corresponding problem specifically on FreeBSD.

@exquo
Copy link
Contributor

exquo commented Dec 26, 2020

👍 for testing the code!

I vaguely remember the DBUS_SESSION_BUS_ADDRESS being discussed in some other contexts as a fix of some other issue. I think one thing in common there was not running an X11 session (e.g. SSH). A cursory search dug up this man page that might be relevant (I haven't really read it, but skimming it seems to be mentioning the dbus address a lot):
https://linux.die.net/man/1/dbus-launch

the error message I receive is "Cannot Resolve Session Bus Address", which differs from the one described by #363, which is "Failed to connect to bus: No such file or directory"

Yes, I've noticed that too (only after posting). They just have the fix in common - setting the environment variable seems to work for both.

@johnfreed
Copy link
Contributor

I've done quite a bit of searching through the dbus code, and among other things I discovered that for the MacOSX, at least, the dbus helper programs (like dbus-send) actually spawn a subprocess to query launchctl to determine the value of DBUS_LAUNCHD_SESSION_BUS_SOCKET (which is stashed in the launchd server upon startup by dbus-daemon).

DBUS_SESSION_BUS_ADDRESS can be trivially determined from DBUS_LAUNCHD_SESSION_BUS_SOCKET:

export DBUS_SESSION_BUS_ADDRESS=unix:path=$DBUS_LAUNCHD_SESSION_BUS_SOCKET

Importantly, these environment variables are NOT available to SSH sessions (I have documented some workarounds on the wiki).

On the Mac, dbus-send first looks to see if DBUS_SESSION_BUS_ADDRESS is set, and if not it issues the query.

@johnfreed
Copy link
Contributor

I'm not sure how DBus works on Free BSD (and thus issue #363) but it appears that the authors of DBus (freedesktop.org) assume that there is a well-known location for the system and session bus sockets (respectively, /var/run/system_bus_socket and /run/user/$UID/bus, where $UID is the user ID obtainable from the id -u command).

All this happens behind the scenes on standard Linux desktop startups, but on other systems, you may need to rely on dbus-daemon. In that case you can specify the --address= option, and set DBUS_SESSION_BUS_ADDRESS to match. So for instance you could have:

export DBUS_SESSION_BUS_ADDRESS=unix:path=/home/myname/bus
dbus-daemon --session --nofork --address=$DBUS_SESSION_BUS_ADDRESS 

This is essentially the reverse of the process described in this blog post

@AsamK
Copy link
Owner

AsamK commented Nov 14, 2021

I've updated signal-cli to use the hypfview dbus-java 4.0 beta, which uses native java unix sockets, that should resolve at least some dbus issues.
If you still have issues with dbus, please open an issue on the dbus-java project
If there are some known workarounds or additional steps, feel free to add it to the wiki: https://github.com/AsamK/signal-cli/wiki/DBus-service

@AsamK AsamK closed this as completed Nov 14, 2021
@dsernst
Copy link

dsernst commented Mar 28, 2023

After quite a lot of struggle, I finally managed to get signal-cli to find DBus from within an Alpine Linux Docker container.

In case it's helpful for anyone else, here's what it took...

  1. In my Dockerfile, I needed to install dbus:
RUN apk add --no-cache dbus-x11

Needs to be dbus-x11, not dbus, or else would get org.freedesktop.dbus.exceptions.AddressResolvingException: Cannot Resolve Session Bus Address: DISPLAY variable not set errors

  1. Then, I needed to start dbus. The only way I could get this to work was by merging it into my CMD with &&, to then start the rest of my app too (which starts up signal-cli and all the logic around it):
CMD sh -c 'dbus-launch && yarn start'
  1. The final step was getting the DBUS_SESSION_BUS_ADDRESS set. dbus-launch would print it to the console whenever it launched, like:

DBUS_SESSION_BUS_ADDRESS=unix:path=/tmp/dbus-jB9U5EdNU4,guid=c9adf5328b82c38ad510b97164232a0c
DBUS_SESSION_BUS_PID=11

But the values weren't being set (leading to a java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 error from org.freedesktop.dbus.utils.AddressBuilder.getSessionConnection(AddressBuilder.java:66))

And the values would change every time (I believe because the Docker Container ID changed), so I couldn't hardcode them in. Instead, by modifying the launch command from above, this would set the environment variables on launch:

CMD sh -c 'eval $(dbus-launch --sh-syntax) && yarn start'

Now signal-cli would use DBus from within the container!

INFO DaemonCommand - DBus daemon running on SESSION bus: org.asamk.Signal

Signal messages successfully received and sent!

🎉🎉

# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

No branches or pull requests

5 participants