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

dbus: check whether the client wanted interactive authentication #546

Merged
merged 1 commit into from
Nov 21, 2022

Conversation

muelli
Copy link
Contributor

@muelli muelli commented Apr 15, 2022

Some clients do not want to prompt for passwords, e.g. when authorising keyboards
when the screen is locked, prompting for a password doesn't make sense because
the user cannot enter anything.
This change extracts the flags and checks whether the client called with
G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION.

@muelli
Copy link
Contributor Author

muelli commented Apr 15, 2022

I'm coming from https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/issues/676 and I haven't been able to test this, yet. Sorry.

@muelli
Copy link
Contributor Author

muelli commented Apr 15, 2022

@hartwork may have an opinion here, too :)

Copy link
Contributor

@hartwork hartwork left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @muelli,

that's a nice idea, thanks for bringing this to my attention and for taking it upstream! 👍
Some notes:

What do you think?

Best, Sebastian

@muelli
Copy link
Contributor Author

muelli commented Apr 15, 2022

  • Flag G_DBUS_MESSAGE_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION seems to require glib >=2.46 according to https://libsoup.org/gio/GDBusMessage.html.
    configure.ac does not require a specific version of glib as of today and glib <2.46 may (or may not) be used on some to-be-supported environments.
    So we either need pre-processor if-else for glib <2.46 and >=2.46 or we need to make glib >=2.46 a known and checked-for build time dependency in configure.ac.
    @radosroka any thoughts on these options?

good catch.
I'd bump the dependency...

@muelli muelli force-pushed the polkit-interactive-authorisation branch from 0a86714 to 6d890cd Compare April 15, 2022 09:49
@hartwork
Copy link
Contributor

good catch. I'd bump the dependency...

@muelli alright, let's start with that approach then, I guess

@muelli
Copy link
Contributor Author

muelli commented Apr 15, 2022

that indeed addresses part of the problem. The other part is that we try to authorise keyboards when the screen is locked. We may or may not be able to do that currently. With this change we can detect whether the user is actually allowed to authorise the device. It would still be better if the user could actually perform the authorisation, but this change probably encodes the right behaviour, because it checks whether the caller is fine with asking for authorisation.

@hartwork
Copy link
Contributor

hartwork commented Apr 15, 2022

We should also should check with (say) d-feet if interactive auth still works with this patch in practice before merging, to be sure. I haven't done that, yet.

Copy link
Contributor

@hartwork hartwork left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@muelli I believe this is the place to insert >=2.46 (for gio):

PKG_CHECK_MODULES([dbus], [dbus-1 gio-2.0 polkit-gobject-1],

@benzea
Copy link

benzea commented Apr 15, 2022

Note that while this patch is correct, it causes a timeout error from the client (https://gitlab.gnome.org/GNOME/gnome-settings-daemon/-/issues/676#note_1430710). The problem is that in various places there is code like:

      if (! isAuthorizedByPolkit(invocation)) {
        return;
      }

Which is obviously wrong, as it means that no error is returned. Instead, the code needs to call

        g_dbus_method_invocation_return_error(invocation, G_DBUS_ERROR,
          G_DBUS_ERROR_ACCESS_DENIED, "Could not authenticate request"););

at some point.

Though, not sure if G_DBUS_ERROR_ACCESS_DENIED or G_DBUS_ERROR_AUTH_FAILED is right. I suppose isAuthorizedByPolkit could already return the error for the invocation, simplifying the code flow a bit and also allowing returning different values depending on what went wrong.

@muelli
Copy link
Contributor Author

muelli commented Apr 16, 2022

Which is obviously wrong, as it means that no error is returned. Instead, the code needs to call

uh.
thanks for pointing it out.
I know only little about dbus architecture and I am a bit surprised. I expected that kind of error to be produced by the broker, somehow.

But it feels like it would be easy to add.

reg. the type of error: The docs have this to say:

G_DBUS_ERROR_ACCESS_DENIED | Security restrictions don't allow doing what you're trying to do.
G_DBUS_ERROR_AUTH_FAILED | Authentication didn't work.

(from https://www.freedesktop.org/software/gstreamer-sdk/data/docs/latest/gio/gio-GDBusError.html - why does it show up under the gstreamer namespace? Rather than a more generic "dbus" namespace or something.)

@hartwork
Copy link
Contributor

hartwork commented Apr 16, 2022

@benzea thanks for your input, that's definitely helpful! 👍

@muelli how should we proceed with this pull request? Should I (a) cherry-pick your commit and make a new pull request applying the ideas of @benzea or (b) make commits for those, export using git format-patch and attach those files here for you to add here using git am or (c) … — what do you think? I should note that I have no permissions on branches or pull requests in USBGuard.

@benzea
Copy link

benzea commented Apr 16, 2022

I know only little about dbus architecture and I am a bit surprised. I expected that kind of error to be produced by the broker, somehow.

The broker isn't doing the access control, so it can't react anymore.

@hartwork
Copy link
Contributor

I know only little about dbus architecture and I am a bit surprised. I expected that kind of error to be produced by the broker, somehow.

The broker isn't doing the access control, so it can't react anymore.

Who is the broker in this picture?

@benzea
Copy link

benzea commented May 6, 2022

Who is the broker in this picture?

The server that forwards messages between clients. i.e. dbus-daemon or dbus-broker in almost all cases.

@hartwork
Copy link
Contributor

Regarding the missing reply aspect brought up by @benzea, there is pull request #548 ready fro review and testing now.

Regarding the allow-interactive-flag aspect brought up by @muelli:
Maybe it's okay that the dbus-send CLI never sends the flag with its calls (so that making calls with e.g. sudo is required) but GNOME D-Bus GUI tool d-feet also doesn't send the flag which means that requiring the flag in USBGuard would break use from d-feet, as of today. I have opened a ticket for clarification with d-feet upstream at https://gitlab.gnome.org/GNOME/d-feet/-/issues/26 now.

I'm looking forward to your feedback 🍻

@muelli
Copy link
Contributor Author

muelli commented Sep 27, 2022

GUI tool d-feet also doesn't send the flag which means that requiring the flag in USBGuard would break use from d-feet, as of today.

That's a problem of the tool, i.e. d-feet.
The correct behaviour is to check whether interactive authorisation was allowed by the caller. If the caller doesn't want popups to be spawned, then it'd be nice if usbguard respected that request.
Whether d-feet is capable of creating such a request is not relevant for encoding the correct behaviour.

@Cropi
Copy link
Member

Cropi commented Oct 24, 2022

Hello @muelli , may I ask you to bump the dependency for gio-2.0 >=2.26 as @hartwork suggested?

@hartwork
Copy link
Contributor

@muelli
Copy link
Contributor Author

muelli commented Oct 24, 2022

Hello @muelli , may I ask you to bump the dependency for gio-2.0 >=2.26 as @hartwork suggested?

I think I tried but couldn't add this new dependency to configure.ac since my autotools-fu is not very good. But I can try again.

@hartwork
Copy link
Contributor

@muelli I believe we need something like this:

   #
   # Check for required D-Bus modules
   #
-  PKG_CHECK_MODULES([dbus], [dbus-1 gio-2.0 polkit-gobject-1],
+  PKG_CHECK_MODULES([dbus], [dbus-1 gio-2.0 >= 2.46 polkit-gobject-1],
   [AC_DEFINE([HAVE_DBUS], [1], [Required GDBus API available])
   dbus_summary="system-wide; $dbus_CFLAGS $dbus_LIBS"],
   [AC_MSG_FAILURE([Required D-Bus modules (dbus-1, gio-2.0, polkit-gobject-1) not found!])]

You can try with a version that your system has no way of satisfying — e.g. 100.0 — to see if things fail as expected. Script ./autogen.sh can be used to regenerated configure from configure.ac sources.

Some clients do not want to prompt for passwords, e.g. when authorising
keyboards when the screen is locked, prompting for a password doesn't
make sense because the user cannot enter anything.
This change extracts the flags and checks whether the client called with
G_DBUS_CALL_FLAGS_ALLOW_INTERACTIVE_AUTHORIZATION.

The flag is available since 2.46:
https://libsoup.org/gio/GDBusMessage.html#GDBusMessageFlags
Hence, we update the dependency in configure.ac.
@muelli muelli force-pushed the polkit-interactive-authorisation branch from 6d890cd to e70d445 Compare November 4, 2022 12:09
@muelli
Copy link
Contributor Author

muelli commented Nov 5, 2022

I've added the check now.
It bails out when I put a fantasy value for the version, so I believe it's working as intended.

I haven't tested these changes, though.

@muelli
Copy link
Contributor Author

muelli commented Nov 7, 2022

okay, I've managed to test the change.
The flag is correctly received by USBGuard.
For some reason I don't yet understand, it allows me everything all the time. So there might be glitch in the code, but given that it looks so innocent, I guess it's my system's configuration.

Probably this is causing me getting unconditional access:

ubuntu@ubuntu-Standard-PC-Q35-ICH9-2009:~$ sudo cat /var/lib/polkit-1/localauthority/10-vendor.d/org.usbguard1.pkla
[Allow users in plugdev and sudo groups to run usbguard actions without authentication]
Identity=unix-group:plugdev;unix-group:sudo
Action=org.usbguard1.setParameter;org.usbguard.Policy1.appendRule
ResultActive=yes
ubuntu@ubuntu-Standard-PC-Q35-ICH9-2009:~$

@muelli
Copy link
Contributor Author

muelli commented Nov 7, 2022

I managed to get a proper test case, now.

ubuntu@ubuntu-Standard-PC-Q35-ICH9-2009:~$ busctl call --allow-interactive-authorization=yes --system org.usbguard1 /org/usbguard1/Policy   org.usbguard.Policy1 appendRule 'sub'  "allow label \"foo\"" 1 true
u 18
ubuntu@ubuntu-Standard-PC-Q35-ICH9-2009:~$ busctl call --allow-interactive-authorization=no --system org.usbguard1 /org/usbguard1/Policy   org.usbguard.Policy1 appendRule 'sub'  "allow label \"foo\"" 1 true
Call failed: Access denied
ubuntu@ubuntu-Standard-PC-Q35-ICH9-2009:~$ sudo cat /var/lib/polkit-1/localauthority/10-vendor.d/org.usbguard1.pkla
[Allow users in plugdev and sudo groups to run usbguard actions without authentication]
Identity=unix-group:pplugdev;unix-group:ssudo
Action=org.usbguard1.setParameter;org.usbguard.Policy1.appendRule
ResultActive=yes
ubuntu@ubuntu-Standard-PC-Q35-ICH9-2009:~$ 

So I conclude that the patch is working as intended.

@radosroka radosroka merged commit d003aa1 into USBGuard:master Nov 21, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants