
EXTERNAL authentication changes to make it work across UID namespaces

Copyright (C) Espial Limited 2015 Company Confidential - All Rights Reserved 

The dbus-daemon examines the credentials on the UNIX domain socket, in order to find
out the peer's PID and UID.  If the peer is in a different PID and/or UID namespace,
the kernel will have remapped the credentials into the dbus-daemon's namespace.  The
client, however, will still try to authenticate by passing its UID in the SASL setup
for the connection by sending "AUTH EXTERNAL <UID>", where <UID> is a hex version of
the stringification of the effective UID of the client in *its* namespace.  e.g. the
UID 789 would be encoded as 373839!  Thus when the dbus-daemon receives this UID and
compares it to the credentials it found on the socket, it finds the UIDs don't match
and thus it refuses to permit the connection.

The first part of this patch removes the UID from the AUTH EXTERNAL message, leaving
no so-called "initial response" data in the message.  The server notices the absence
of the UID and asks us to supply it.  The second part of this patch sends the answer
back as an empty DATA message.  When the server receives this empty message, it just
decides to trust the socket credentials that it started with and carries on happily.
Previously, the code relied on the server not asking for more data ever.

diff -Nbru dbus-1.8.16/dbus/dbus-auth.c dbus-1.8.16-new/dbus/dbus-auth.c
--- dbus-1.8.16/dbus/dbus-auth.c	2015-02-03 15:47:02.000000000 +0000
+++ dbus-1.8.16-new/dbus/dbus-auth.c	2015-05-27 17:00:11.978193996 +0100
@@ -1152,8 +1152,10 @@
   if (!_dbus_string_init (&plaintext))
     return FALSE;
 
+  /* Espial change: the socket credentials will be sufficient, this is the wrong UID:
   if (!_dbus_append_user_from_current_process (&plaintext))
     goto failed;
+  */
 
   if (!_dbus_string_hex_encode (&plaintext, 0,
 				response,
@@ -1173,6 +1175,7 @@
 handle_client_data_external_mech (DBusAuth         *auth,
                                   const DBusString *data)
 {
+  return send_data(auth, NULL); /* Espial change: yes, really I did mean no initial response */
   
   return TRUE;
 }
