Skip to content

GDBus: improve interoperability of SASL handshake

Simon McVittie requested to merge wip/smcv/gdbus-sasl into main
  • gdbusauth: empty DATA does not need a trailing space

    From: @giuseppe

    This is an interoperability fix. If the line is exactly "DATA\r\n", the reference implementation of D-Bus treats this as equivalent to "DATA \r\n", meaning the data block consists of zero hex-encoded bytes. In practice, D-Bus clients send empty data blocks as "DATA\r\n", and in fact sd-bus only accepts that, rejecting "DATA \r\n".

    [Originally part of a larger commit; commit message added by smcv]

  • GDBusServer: If no initial response for EXTERNAL, send a challenge

    From: @giuseppe

    Sending an "initial response" along with the AUTH command is meant to be an optional optimization, and clients are allowed to omit it. We must reply with our initial challenge, which in the case of EXTERNAL is an empty string: the client responds to that with the authorization identity.

    If we do not reply to the AUTH command, then the client will wait forever for our reply, while we wait forever for the reply that we expect the client to send, resulting in deadlock.

    D-Bus does not have a way to distinguish between an empty initial response and the absence of an initial response, so clients that want to use an empty authorization identity, such as systed's sd-bus, cannot use the initial-response optimization and will fail to connect to a GDBusServer that does not have this change.

    [Originally part of a larger commit; commit message added by smcv.]

  • GDBusServer: Accept empty authorization identity for EXTERNAL mechanism

    From: @giuseppe

    RFC 4422 appendix A defines the empty authorization identity to mean the identity that the server associated with its authentication credentials. In this case, this means whatever uid is in the GCredentials object.

    In particular, this means that clients in a different Linux user namespace can authenticate against our server and will be authorized as the version of their uid that is visible in the server's namespace, even if the corresponding numeric uid returned by geteuid() in the client's namespace was different. systemd's sd-bus has relied on this since commit https://github.com/systemd/systemd/commit/1ed4723d38cd0d1423c8fe650f90fa86007ddf55.

    [Originally part of a larger commit; commit message added by smcv]

  • gdbusauth: Represent empty data block as DATA\r\n, with no space

    From: @smcv

    This is an interoperability fix. The reference implementation of D-Bus treats "DATA\r\n" as equivalent to "DATA \r\n", but sd-bus does not, and only accepts the former.

  • tests: Add a test for GDBusServer with various simulated clients

    From: @smcv

    Instead of using a GDBusConnection, this does the handshake at a lower level using specific strings in the SASL handshake, to verify that we will interoperate with various clients including sd-bus, libdbus and older versions of GDBus.


This is basically the first commit of !1403 (closed) and a small part of the second, broken up into smaller commits as I requested during review of !1403 (closed), with an explanation of what specific interoperability issues are being fixed. The last two commits are new, and add an additional interop fix and a unit test.

This improves GDBus client and server interoperability, in particular making the server interoperate with sd-bus clients.

The second commit of !1403 (closed), which makes the GDBus client behave like sd-bus, is not included. This would be an interoperability break to include, unfortunately: it would fix connections across the boundary of a uid namespace, at the cost of breaking interop with older versions of GDBusServer.

I'd like to get these fixes into GLib before the rest of !1403 (closed), in the hope that when we do the rest of !1403 (closed), we can assume that fixed versions of GLib are widespread.

/cc @giuseppe @malureau

Edited by Simon McVittie

Merge request reports