Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Make D-Bus work for Linuxulator apps (using the FreeBSD-side session bus) #2

Open
probonopd opened this issue Dec 11, 2021 · 13 comments
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@probonopd
Copy link
Member

probonopd commented Dec 11, 2021

Make D-Bus work so that Linux applications can use, e.g., the Global Menu.

This means that if the Linux side wants to talk to D-Bus, it should be talking to the D-Bus on the FreeBSD side.

cc @trasz

Reference:
AppImage/AppImageKit#98 (comment)

@probonopd
Copy link
Member Author

On the FreeBSD side, D-Bus is running.

FreeBSD% env | grep DBUS_
DBUS_SESSION_BUS_ADDRESS=unix:path=/tmp/dbus-KOUuupXO4Y,guid=b32f4b68667e05c70f52a0a06358338b
DBUS_SESSION_BUS_PID=2482
DBUS_SESSION_BUS_WINDOWID=8388609
FreeBSD% sudo chroot /media/.debian /bin/bash

# /tmp is a nullfs mount from the FreeBSD side to the Linux side, so /tmp/dbus-KOUuupXO4Y is there...
root@FreeBSD:/# mount | grep ^/tmp
/tmp on /tmp type nullfs (rw,nosuid,noatime)
root@FreeBSD:/# ls -lh /tmp/dbus-KOUuupXO4Y 
srwxrwxrwx 1 1001 root 0 Oct 25 21:05 /tmp/dbus-KOUuupXO4Y

root@FreeBSD:/# env
SHELL=/bin/csh
COLORTERM=truecolor
SUDO_GID=1001
LANGUAGE=
SUDO_COMMAND=/usr/sbin/chroot /media/.debian /bin/bash
SUDO_USER=user
PWD=/
LOGNAME=root
XAUTHORITY=/home/user/.Xauthority
TZ=Europe/Berlin
HOME=/root
LANG=de_DE.UTF-8
TERM=xterm-256color
USER=root
DISPLAY=unix:0.0
SHLVL=1
PATH=/home/user/bin:/home/user/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/games:/usr/sbin:/usr/bin:/sbin:/bin
SUDO_UID=1001
MAIL=/var/mail/root
_=/usr/bin/env
            
root@FreeBSD:/# dbus-monitor 
Failed to open connection to session bus: /usr/bin/dbus-launch terminated abnormally without any error message

root@FreeBSD:/# export DBUS_SESSION_BUS_ADDRESS=unix:path=/tmp/dbus-KOUuupXO4Y,guid=b32f4b68667e05c70f52a0a06358338b

root@FreeBSD:/# 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.

root@FreeBSD:/# export DBUS_SESSION_BUS_PID=2482

root@FreeBSD:/# 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.

root@FreeBSD:/# export DBUS_SESSION_BUS_WINDOWID=8388609
root@FreeBSD:/# 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.

What else might be needed so that Linux applciations can use the D-Bus from the FreeBSD side?

@probonopd
Copy link
Member Author

Could it be that the socket /tmp/dbus-KOUuupXO4Y is the culprit? Do FreeBSD sockets not work when /tmp is nullfs mounted to the Linux side like this?

FreeBSD% mount | grep tmp
zroot/var/tmp on /var/tmp (zfs, local, noatime, nosuid, nfsv4acls)
zroot/tmp on /tmp (zfs, local, noatime, nosuid, nfsv4acls)
tmpfs on /media/.debian/dev/shm (tmpfs, local)
/tmp on /media/.debian/tmp (nullfs, local, noatime, nosuid, nfsv4acls)

@probonopd
Copy link
Member Author

Do we need something like https://github.com/flatpak/xdg-dbus-proxy?

xdg-dbus-proxy is a filtering proxy for D-Bus connections. It was originally part of the flatpak project, but it has been broken out as a standalone module to facilitate using it in other contexts.

@probonopd
Copy link
Member Author

Or maybe it is because we are running as root inside the chroot. Whereas D-Bus on FreeBSD runs as one particular user.

@probonopd
Copy link
Member Author

probonopd commented Oct 25, 2022

Or maybe we need to do on the Linux side:

root@FreeBSD:/# export DBUS_SESSION_BUS_ADDRESS=tcp:host=localhost,bind=*,port=55556,family=ipv4

root@FreeBSD:/# dbus-monitor 
Failed to open connection to session bus: Failed to connect to socket "localhost:55556" Connection refused

and on the FreeBSD side allow D-Bus connections over TCP:

FreeBSD% sudo cp /usr/local/share/dbus-1/session.conf /usr/local/share/dbus-1/sessionlocal.conf

Edit as described at https://stackoverflow.com/a/13275973
so that it contains

  <listen>tcp:host=localhost,bind=*,port=55556,family=ipv4</listen>

  <listen>unix:tmpdir=/tmp</listen>

  <auth>ANONYMOUS</auth>
  <allow_anonymous/>

Then restart the D-Bus daemon:

FreeBSD% sudo service dbus restart

But still, on the Linux side in the chroot:

root@FreeBSD:/# dbus-monitor 
Failed to open connection to session bus: Failed to connect to socket "localhost:55556" Connection refused

On the FreeBSD side - should this be working?

FreeBSD% telnet localhost 55556
Trying ::1...
telnet: connect to address ::1: Connection refused
Trying 127.0.0.1...
telnet: connect to address 127.0.0.1: Connection refused
telnet: Unable to connect to remote host

FreeBSD% telnet 127.0.0.1 55556
Trying 127.0.0.1...
telnet: connect to address 127.0.0.1: Connection refused
telnet: Unable to connect to remote host

@probonopd probonopd changed the title Make D-Bus work Make D-Bus work for Linuxulator apps (using the FreeBSD-side session bus) Oct 25, 2022
@probonopd
Copy link
Member Author

probonopd commented Oct 25, 2022

Creating /usr/local/share/dbus-1/public-tcp.conf with the content below and restarting D-Bus didn't make it work, either...

<!DOCTYPE busconfig PUBLIC
 "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
 "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
    <listen>tcp:host=localhost,bind=*,port=55556,family=ipv4</listen>
    <listen>unix:tmpdir=/tmp</listen>
    <auth>EXTERNAL</auth>
    <auth>ANONYMOUS</auth>
    <allow_anonymous/>
    <apparmor mode="disabled" />
    <policy context="default">
        <allow user="*" />
        <allow own="*" />
        <allow send_type="*" />
        <allow receive_type="*" />
        <allow send_destination="*"/>
    </policy>
</busconfig>

@probonopd probonopd added enhancement New feature or request help wanted Extra attention is needed labels Oct 25, 2022
@trasz
Copy link

trasz commented Oct 25, 2022

Assuming it’s the same problem I’ve seen last time and that I remember it correctly, it’s about the way FreeBSD dbus daemon is trying to authenticate Linux client - the client assumes it’s authenticated via creds over Unix domain socket, whereas FreeBSD server assumes something else. The way I’d approach it first is to see if we can make native FreeBSD dbus authenticate the same way it’s done on Linux, I believe we have the kernel support now.

@probonopd
Copy link
Member Author

Other things to check

  • Socket permissions
  • dbus wants all clients to have the same UID/PID as the bus itself? (Is this why root can't send stuff to a user's session bus, or can it?)

Note to self:

  • DBUS_VERBOSE=1 dbus-daemon --session --nofork --nosyslog

@ngortheone
Copy link

ngortheone commented Oct 26, 2022

The problem has nothing to do with Linuxulator or chroot. I can reproduce this with root trying to connect to user's bus.

➜ echo $DBUS_SESSION_BUS_ADDRESS
unix:path=/var/run/1000/dbus

➜  ls -la /var/run/1000/dbus
srwxrwxrwx  1 ngor  wheel  0 Oct 24 17:52 /var/run/1000/dbus=

➜  su -
Password:

# dbus-monitor --address unix:path=/var/run/1000/dbus
Failed to register connection to bus at unix:path=/var/run/1000/dbus: 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.

I think it just checks the uid/gid of the client

@probonopd
Copy link
Member Author

probonopd commented Oct 26, 2022

https://dbus.freedesktop.org/doc/dbus-daemon.1.html says

Rules with the user or group attribute are checked when a new connection to the message bus is established, and control whether the connection can continue. Each of these attributes cannot be combined with any other attribute. As a special case, both user="" and group="" match any connection. If there are no rules of this form, the default is to allow connections from the same user ID that owns the dbus-daemon process. The well-known session bus normally uses that default behaviour, while the well-known system bus normally allows any connection.

So, maybe we need to throw in

        <allow user="*" />
        <allow own="*" />

? Possibly this is also the key to allowing root to talk to a user's D-Bus session bus?

@ngortheone
Copy link

I think you found it. You need a custom configuration for you session bus. Take a look at system bus config, and copy rules from it into your config

@probonopd
Copy link
Member Author

probonopd commented Jul 24, 2023

The following allows applications running on the same machine as root to access the user's session bus.
The trick is to use TCP instead of Unix sockets, which seems to be less restrictive about which user accesses it.
https://stackoverflow.com/a/13275973

Maybe the same can be used to make it work for Linux applications using the Linuxulator.

Essentially, in /usr/local/share/dbus-1/session.conf above the line <listen>unix:tmpdir=/tmp</listen> add:

<!-- Allow e.g, root to communicate with the user's session bus so that global menus work;
for applications to use this, do:
export DBUS_SESSION_BUS_ADDRESS=tcp:host=localhost,bind=localhost,port=55556,family=ipv4
-->
<listen>tcp:host=localhost,bind=localhost,port=55556,family=ipv4</listen>
<auth>ANONYMOUS</auth>
<allow_anonymous/>

Note the use of bind=localhost. I assume this means that only users of the local machine are allowed to use this bus, not remote users.

Log out of the session, log in again, and applications running as root can e.g., use the global menu now.

image

Maybe something along those lines can be used for the Linuxulator as well.

@probonopd
Copy link
Member Author

probonopd commented Aug 26, 2023

Looks like we are getting somewhere.

What you are seeing is Inkscape (Gtk; extracted from its AppImage) running using the Linuxulator.

See those menus? 💯

image

To be honest, I am a bit surprised - I did nothing special and it "just worked" this time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants