From 47b1a4c41004bf494b87370987b222c934b19016 Mon Sep 17 00:00:00 2001
From: Simon McVittie <smcv@collabora.com>
Date: Thu, 30 May 2019 12:53:03 +0100
Subject: [PATCH] auth: Reject DBUS_COOKIE_SHA1 for users other than the server
 owner

The DBUS_COOKIE_SHA1 authentication mechanism aims to prove ownership
of a shared home directory by having the server write a secret "cookie"
into a .dbus-keyrings subdirectory of the desired identity's home
directory with 0700 permissions, and having the client prove that it can
read the cookie. This never actually worked for non-malicious clients in
the case where server uid != client uid (unless the server and client
both have privileges, such as Linux CAP_DAC_OVERRIDE or traditional
Unix uid 0) because an unprivileged server would fail to write out the
cookie, and an unprivileged client would be unable to read the resulting
file owned by the server.

Additionally, since dbus 1.7.10 we have checked that ~/.dbus-keyrings
is owned by the uid of the server (a side-effect of a check added to
harden our use of XDG_RUNTIME_DIR), further ruling out successful use
by a non-malicious client with a uid differing from the server's.

Joe Vennix of Apple Information Security discovered that the
implementation of DBUS_COOKIE_SHA1 was susceptible to a symbolic link
attack: a malicious client with write access to its own home directory
could manipulate a ~/.dbus-keyrings symlink to cause the DBusServer to
read and write in unintended locations. In the worst case this could
result in the DBusServer reusing a cookie that is known to the
malicious client, and treating that cookie as evidence that a subsequent
client connection came from an attacker-chosen uid, allowing
authentication bypass.

This is mitigated by the fact that by default, the well-known system
dbus-daemon (since 2003) and the well-known session dbus-daemon (in
stable releases since dbus 1.10.0 in 2015) only accept the EXTERNAL
authentication mechanism, and as a result will reject DBUS_COOKIE_SHA1
at an early stage, before manipulating cookies. As a result, this
vulnerability only applies to:

* system or session dbus-daemons with non-standard configuration
* third-party dbus-daemon invocations such as at-spi2-core (although
  in practice at-spi2-core also only accepts EXTERNAL by default)
* third-party uses of DBusServer such as the one in Upstart

Avoiding symlink attacks in a portable way is difficult, because APIs
like openat() and Linux /proc/self/fd are not universally available.
However, because DBUS_COOKIE_SHA1 already doesn't work in practice for
a non-matching uid, we can solve this vulnerability in an easier way
without regressions, by rejecting it early (before looking at
~/.dbus-keyrings) whenever the requested identity doesn't match the
identity of the process hosting the DBusServer.

Signed-off-by: Simon McVittie <smcv@collabora.com>
Closes: https://gitlab.freedesktop.org/dbus/dbus/issues/269
Closes: CVE-2019-12749
---
 dbus/dbus-auth.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

Index: dbus-1.8.22/dbus/dbus-auth.c
===================================================================
--- dbus-1.8.22.orig/dbus/dbus-auth.c
+++ dbus-1.8.22/dbus/dbus-auth.c
@@ -4,7 +4,7 @@
  * Copyright (C) 2002, 2003, 2004 Red Hat Inc.
  *
  * Licensed under the Academic Free License version 2.1
- * 
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -14,7 +14,7 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
@@ -50,7 +50,7 @@
  *
  * @todo the cookie keyring needs to be cached globally not just
  * per-auth (which raises threadsafety issues too)
- * 
+ *
  * @todo grep FIXME in dbus-auth.c
  */
 
@@ -157,7 +157,7 @@ struct DBusAuth
 
   DBusString incoming;    /**< Incoming data buffer */
   DBusString outgoing;    /**< Outgoing data buffer */
-  
+
   const DBusAuthStateData *state;         /**< Current protocol state */
 
   const DBusAuthMechanismHandler *mech;   /**< Current auth mechanism */
@@ -165,14 +165,14 @@ struct DBusAuth
   DBusString identity;                   /**< Current identity we're authorizing
                                           *   as.
                                           */
-  
+
   DBusCredentials *credentials;          /**< Credentials read from socket
                                           */
 
   DBusCredentials *authorized_identity; /**< Credentials that are authorized */
 
   DBusCredentials *desired_identity;    /**< Identity client has requested */
-  
+
   DBusString context;               /**< Cookie scope */
   DBusKeyring *keyring;             /**< Keyring for cookie mechanism. */
   int cookie_id;                    /**< ID of cookie to use */
@@ -181,7 +181,7 @@ struct DBusAuth
   char **allowed_mechs;             /**< Mechanisms we're allowed to use,
                                      * or #NULL if we can use any
                                      */
-  
+
   unsigned int needed_memory : 1;   /**< We needed memory to continue since last
                                      * successful getting something done
                                      */
@@ -203,7 +203,7 @@ typedef struct
   DBusList *mechs_to_try; /**< Mechanisms we got from the server that we're going to try using */
 
   DBusString guid_from_server; /**< GUID received from server */
-  
+
 } DBusAuthClient;
 
 /**
@@ -217,7 +217,7 @@ typedef struct
   int max_failures; /**< Number of times we reject before disconnect */
 
   DBusString guid;  /**< Our globally unique ID in hex encoding */
-  
+
 } DBusAuthServer;
 
 static void        goto_state                (DBusAuth                       *auth,
@@ -238,7 +238,7 @@ static dbus_bool_t send_agree_unix_fd
 /**
  * Client states
  */
- 
+
 static dbus_bool_t handle_server_state_waiting_for_auth  (DBusAuth         *auth,
                                                           DBusAuthCommand   command,
                                                           const DBusString *args);
@@ -248,7 +248,7 @@ static dbus_bool_t handle_server_state_w
 static dbus_bool_t handle_server_state_waiting_for_begin (DBusAuth         *auth,
                                                           DBusAuthCommand   command,
                                                           const DBusString *args);
-  
+
 static const DBusAuthStateData server_state_waiting_for_auth = {
   "WaitingForAuth", handle_server_state_waiting_for_auth
 };
@@ -258,11 +258,11 @@ static const DBusAuthStateData server_st
 static const DBusAuthStateData server_state_waiting_for_begin = {
   "WaitingForBegin", handle_server_state_waiting_for_begin
 };
-  
+
 /**
  * Client states
  */
- 
+
 static dbus_bool_t handle_client_state_waiting_for_data   (DBusAuth         *auth,
                                                            DBusAuthCommand   command,
                                                            const DBusString *args);
@@ -338,16 +338,16 @@ static DBusAuth*
 _dbus_auth_new (int size)
 {
   DBusAuth *auth;
-  
+
   auth = dbus_malloc0 (size);
   if (auth == NULL)
     return NULL;
-  
+
   auth->refcount = 1;
-  
+
   auth->keyring = NULL;
   auth->cookie_id = -1;
-  
+
   /* note that we don't use the max string length feature,
    * because you can't use that feature if you're going to
    * try to recover from out-of-memory (it creates
@@ -355,13 +355,13 @@ _dbus_auth_new (int size)
    * more space in the string). But we do handle
    * overlong buffers in _dbus_auth_do_work().
    */
-  
+
   if (!_dbus_string_init (&auth->incoming))
     goto enomem_0;
 
   if (!_dbus_string_init (&auth->outgoing))
     goto enomem_1;
-    
+
   if (!_dbus_string_init (&auth->identity))
     goto enomem_2;
 
@@ -378,7 +378,7 @@ _dbus_auth_new (int size)
   auth->credentials = _dbus_credentials_new ();
   if (auth->credentials == NULL)
     goto enomem_6;
-  
+
   auth->authorized_identity = _dbus_credentials_new ();
   if (auth->authorized_identity == NULL)
     goto enomem_7;
@@ -386,7 +386,7 @@ _dbus_auth_new (int size)
   auth->desired_identity = _dbus_credentials_new ();
   if (auth->desired_identity == NULL)
     goto enomem_8;
-  
+
   return auth;
 
 #if 0
@@ -423,17 +423,17 @@ shutdown_mech (DBusAuth *auth)
 
   _dbus_credentials_clear (auth->authorized_identity);
   _dbus_credentials_clear (auth->desired_identity);
-  
+
   if (auth->mech != NULL)
     {
       _dbus_verbose ("%s: Shutting down mechanism %s\n",
                      DBUS_AUTH_NAME (auth), auth->mech->mechanism);
-      
+
       if (DBUS_AUTH_IS_CLIENT (auth))
         (* auth->mech->client_shutdown_func) (auth);
       else
         (* auth->mech->server_shutdown_func) (auth);
-      
+
       auth->mech = NULL;
     }
 }
@@ -456,11 +456,11 @@ sha1_compute_hash (DBusAuth         *aut
   DBusString cookie;
   DBusString to_hash;
   dbus_bool_t retval;
-  
+
   _dbus_assert (auth->keyring != NULL);
 
   retval = FALSE;
-  
+
   if (!_dbus_string_init (&cookie))
     return FALSE;
 
@@ -476,14 +476,14 @@ sha1_compute_hash (DBusAuth         *aut
 
   if (!_dbus_string_init (&to_hash))
     goto out_0;
-  
+
   if (!_dbus_string_copy (server_challenge, 0,
                           &to_hash, _dbus_string_get_length (&to_hash)))
     goto out_1;
 
   if (!_dbus_string_append (&to_hash, ":"))
     goto out_1;
-  
+
   if (!_dbus_string_copy (client_challenge, 0,
                           &to_hash, _dbus_string_get_length (&to_hash)))
     goto out_1;
@@ -497,7 +497,7 @@ sha1_compute_hash (DBusAuth         *aut
 
   if (!_dbus_sha_compute (&to_hash, hash))
     goto out_1;
-  
+
   retval = TRUE;
 
  out_1:
@@ -526,11 +526,11 @@ sha1_handle_first_client_response (DBusA
   DBusString tmp2;
   dbus_bool_t retval;
   DBusError error;
-  
+  DBusCredentials *myself = NULL;
   retval = FALSE;
 
   _dbus_string_set_length (&auth->challenge, 0);
-  
+
   if (_dbus_string_get_length (data) > 0)
     {
       if (_dbus_string_get_length (&auth->identity) > 0)
@@ -547,14 +547,14 @@ sha1_handle_first_client_response (DBusA
             return FALSE;
         }
     }
-      
+
   if (!_dbus_credentials_add_from_user (auth->desired_identity, data))
     {
       _dbus_verbose ("%s: Did not get a valid username from client\n",
                      DBUS_AUTH_NAME (auth));
       return send_rejected (auth);
     }
-      
+
   if (!_dbus_string_init (&tmp))
     return FALSE;
 
@@ -564,6 +564,34 @@ sha1_handle_first_client_response (DBusA
       return FALSE;
     }
 
+  myself = _dbus_credentials_new_from_current_process ();
+
+  if (myself == NULL)
+    goto out;
+
+  if (!_dbus_credentials_same_user (myself, auth->desired_identity))
+    {
+      /*
+       * DBUS_COOKIE_SHA1 is not suitable for authenticating that the
+       * client is anyone other than the user owning the process
+       * containing the DBusServer: we probably aren't allowed to write
+       * to other users' home directories. Even if we can (for example
+       * uid 0 on traditional Unix or CAP_DAC_OVERRIDE on Linux), we
+       * must not, because the other user controls their home directory,
+       * and could carry out symlink attacks to make us read from or
+       * write to unintended locations. It's difficult to avoid symlink
+       * attacks in a portable way, so we just don't try. This isn't a
+       * regression, because DBUS_COOKIE_SHA1 never worked for other
+       * users anyway.
+       */
+      _dbus_verbose ("%s: client tried to authenticate as \"%s\", "
+                     "but that doesn't match this process",
+                     DBUS_AUTH_NAME (auth),
+                     _dbus_string_get_const_data (data));
+      retval = send_rejected (auth);
+      goto out;
+    }
+
   /* we cache the keyring for speed, so here we drop it if it's the
    * wrong one. FIXME caching the keyring here is useless since we use
    * a different DBusAuth for every connection.
@@ -575,7 +603,7 @@ sha1_handle_first_client_response (DBusA
       _dbus_keyring_unref (auth->keyring);
       auth->keyring = NULL;
     }
-  
+
   if (auth->keyring == NULL)
     {
       dbus_error_init (&error);
@@ -638,31 +666,34 @@ sha1_handle_first_client_response (DBusA
     goto out;
 
   if (!_dbus_string_append (&tmp2, " "))
-    goto out;  
-  
+    goto out;
+
   if (!_dbus_generate_random_bytes (&tmp, N_CHALLENGE_BYTES))
     goto out;
 
   _dbus_string_set_length (&auth->challenge, 0);
   if (!_dbus_string_hex_encode (&tmp, 0, &auth->challenge, 0))
     goto out;
-  
+
   if (!_dbus_string_hex_encode (&tmp, 0, &tmp2,
                                 _dbus_string_get_length (&tmp2)))
     goto out;
 
   if (!send_data (auth, &tmp2))
     goto out;
-      
+
   goto_state (auth, &server_state_waiting_for_data);
   retval = TRUE;
-  
+
  out:
   _dbus_string_zero (&tmp);
   _dbus_string_free (&tmp);
   _dbus_string_zero (&tmp2);
   _dbus_string_free (&tmp2);
 
+  if (myself != NULL)
+    _dbus_credentials_unref (myself);
+
   return retval;
 }
 
@@ -680,28 +711,28 @@ sha1_handle_second_client_response (DBus
   DBusString client_hash;
   dbus_bool_t retval;
   DBusString correct_hash;
-  
+
   retval = FALSE;
-  
+
   if (!_dbus_string_find_blank (data, 0, &i))
     {
       _dbus_verbose ("%s: no space separator in client response\n",
                      DBUS_AUTH_NAME (auth));
       return send_rejected (auth);
     }
-  
+
   if (!_dbus_string_init (&client_challenge))
     goto out_0;
 
   if (!_dbus_string_init (&client_hash))
-    goto out_1;  
+    goto out_1;
 
   if (!_dbus_string_copy_len (data, 0, i, &client_challenge,
                               0))
     goto out_2;
 
   _dbus_string_skip_blank (data, i, &i);
-  
+
   if (!_dbus_string_copy_len (data, i,
                               _dbus_string_get_length (data) - i,
                               &client_hash,
@@ -722,7 +753,7 @@ sha1_handle_second_client_response (DBus
     goto out_2;
 
   if (!sha1_compute_hash (auth, auth->cookie_id,
-                          &auth->challenge, 
+                          &auth->challenge,
                           &client_challenge,
                           &correct_hash))
     goto out_3;
@@ -734,7 +765,7 @@ sha1_handle_second_client_response (DBus
         retval = TRUE;
       goto out_3;
     }
-  
+
   if (!_dbus_string_equal (&client_hash, &correct_hash))
     {
       if (send_rejected (auth))
@@ -752,15 +783,15 @@ sha1_handle_second_client_response (DBus
                                          DBUS_CREDENTIAL_UNIX_PROCESS_ID,
                                          auth->credentials))
     goto out_3;
-  
+
   if (!send_ok (auth))
     goto out_3;
 
   _dbus_verbose ("%s: authenticated client using DBUS_COOKIE_SHA1\n",
                  DBUS_AUTH_NAME (auth));
-  
+
   retval = TRUE;
-  
+
  out_3:
   _dbus_string_zero (&correct_hash);
   _dbus_string_free (&correct_hash);
@@ -786,7 +817,7 @@ handle_server_data_cookie_sha1_mech (DBu
 static void
 handle_server_shutdown_cookie_sha1_mech (DBusAuth *auth)
 {
-  auth->cookie_id = -1;  
+  auth->cookie_id = -1;
   _dbus_string_set_length (&auth->challenge, 0);
 }
 
@@ -801,7 +832,7 @@ handle_client_initial_response_cookie_sh
 
   if (!_dbus_string_init (&username))
     return FALSE;
-  
+
   if (!_dbus_append_user_from_current_process (&username))
     goto out_0;
 
@@ -811,10 +842,10 @@ handle_client_initial_response_cookie_sh
     goto out_0;
 
   retval = TRUE;
-  
+
  out_0:
   _dbus_string_free (&username);
-  
+
   return retval;
 }
 
@@ -835,9 +866,9 @@ handle_client_data_cookie_sha1_mech (DBu
   DBusString tmp;
   int i, j;
   long val;
-  
-  retval = FALSE;                 
-  
+
+  retval = FALSE;
+
   if (!_dbus_string_find_blank (data, 0, &i))
     {
       if (send_error (auth,
@@ -852,7 +883,7 @@ handle_client_data_cookie_sha1_mech (DBu
   if (!_dbus_string_copy_len (data, 0, i,
                               &context, 0))
     goto out_1;
-  
+
   _dbus_string_skip_blank (data, i, &i);
   if (!_dbus_string_find_blank (data, i, &j))
     {
@@ -864,10 +895,10 @@ handle_client_data_cookie_sha1_mech (DBu
 
   if (!_dbus_string_init (&cookie_id_str))
     goto out_1;
-  
+
   if (!_dbus_string_copy_len (data, i, j - i,
                               &cookie_id_str, 0))
-    goto out_2;  
+    goto out_2;
 
   if (!_dbus_string_init (&server_challenge))
     goto out_2;
@@ -924,10 +955,10 @@ handle_client_data_cookie_sha1_mech (DBu
 
               _dbus_verbose ("%s: Error loading keyring: %s\n",
                              DBUS_AUTH_NAME (auth), error.message);
-              
+
               if (send_error (auth, "Could not load cookie file"))
                 retval = TRUE; /* retval is only about mem */
-              
+
               dbus_error_free (&error);
               goto out_3;
             }
@@ -937,12 +968,12 @@ handle_client_data_cookie_sha1_mech (DBu
           _dbus_assert (!dbus_error_is_set (&error));
         }
     }
-  
+
   _dbus_assert (auth->keyring != NULL);
-  
+
   if (!_dbus_string_init (&tmp))
     goto out_3;
-  
+
   if (!_dbus_generate_random_bytes (&tmp, N_CHALLENGE_BYTES))
     goto out_4;
 
@@ -954,7 +985,7 @@ handle_client_data_cookie_sha1_mech (DBu
 
   if (!_dbus_string_init (&correct_hash))
     goto out_5;
-  
+
   if (!sha1_compute_hash (auth, val,
                           &server_challenge,
                           &client_challenge,
@@ -968,9 +999,9 @@ handle_client_data_cookie_sha1_mech (DBu
         retval = TRUE;
       goto out_6;
     }
-  
+
   _dbus_string_set_length (&tmp, 0);
-  
+
   if (!_dbus_string_copy (&client_challenge, 0, &tmp,
                           _dbus_string_get_length (&tmp)))
     goto out_6;
@@ -1008,7 +1039,7 @@ handle_client_data_cookie_sha1_mech (DBu
 static void
 handle_client_shutdown_cookie_sha1_mech (DBusAuth *auth)
 {
-  auth->cookie_id = -1;  
+  auth->cookie_id = -1;
   _dbus_string_set_length (&auth->challenge, 0);
 }
 
@@ -1026,7 +1057,7 @@ handle_server_data_external_mech (DBusAu
                      DBUS_AUTH_NAME (auth));
       return send_rejected (auth);
     }
-  
+
   if (_dbus_string_get_length (data) > 0)
     {
       if (_dbus_string_get_length (&auth->identity) > 0)
@@ -1061,7 +1092,7 @@ handle_server_data_external_mech (DBusAu
     }
 
   _dbus_credentials_clear (auth->desired_identity);
-  
+
   /* If auth->identity is still empty here, then client
    * responded with an empty string after we poked it for
    * an initial response. This means to try to auth the
@@ -1093,7 +1124,7 @@ handle_server_data_external_mech (DBusAu
                      _dbus_string_get_const_data (&auth->identity));
       return send_rejected (auth);
     }
-  
+
   if (_dbus_credentials_are_superset (auth->credentials,
                                       auth->desired_identity))
     {
@@ -1115,7 +1146,7 @@ handle_server_data_external_mech (DBusAu
                                              DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID,
                                              auth->credentials))
         return FALSE;
-      
+
       if (!send_ok (auth))
         return FALSE;
 
@@ -1161,19 +1192,19 @@ handle_client_initial_response_external_
     goto failed;
 
   _dbus_string_free (&plaintext);
-  
+
   return TRUE;
 
  failed:
   _dbus_string_free (&plaintext);
-  return FALSE;  
+  return FALSE;
 }
 
 static dbus_bool_t
 handle_client_data_external_mech (DBusAuth         *auth,
                                   const DBusString *data)
 {
-  
+
   return TRUE;
 }
 
@@ -1190,7 +1221,7 @@ handle_client_shutdown_external_mech (DB
 static dbus_bool_t
 handle_server_data_anonymous_mech (DBusAuth         *auth,
                                    const DBusString *data)
-{  
+{
   if (_dbus_string_get_length (data) > 0)
     {
       /* Client is allowed to send "trace" data, the only defined
@@ -1204,7 +1235,7 @@ handle_server_data_anonymous_mech (DBusA
                          DBUS_AUTH_NAME (auth));
           return send_rejected (auth);
         }
-      
+
       _dbus_verbose ("%s: ANONYMOUS client sent trace string: '%s'\n",
                      DBUS_AUTH_NAME (auth),
                      _dbus_string_get_const_data (data));
@@ -1219,7 +1250,7 @@ handle_server_data_anonymous_mech (DBusA
                                          DBUS_CREDENTIAL_UNIX_PROCESS_ID,
                                          auth->credentials))
     return FALSE;
-  
+
   /* Anonymous is always allowed */
   if (!send_ok (auth))
     return FALSE;
@@ -1233,7 +1264,7 @@ handle_server_data_anonymous_mech (DBusA
 static void
 handle_server_shutdown_anonymous_mech (DBusAuth *auth)
 {
-  
+
 }
 
 static dbus_bool_t
@@ -1261,26 +1292,26 @@ handle_client_initial_response_anonymous
     goto failed;
 
   _dbus_string_free (&plaintext);
-  
+
   return TRUE;
 
  failed:
   _dbus_string_free (&plaintext);
-  return FALSE;  
+  return FALSE;
 }
 
 static dbus_bool_t
 handle_client_data_anonymous_mech (DBusAuth         *auth,
                                   const DBusString *data)
 {
-  
+
   return TRUE;
 }
 
 static void
 handle_client_shutdown_anonymous_mech (DBusAuth *auth)
 {
-  
+
 }
 
 /* Put mechanisms here in order of preference.
@@ -1292,7 +1323,7 @@ handle_client_shutdown_anonymous_mech (D
  *
  * We might ideally add a mechanism to chain to Cyrus SASL so we can
  * use its mechanisms as well.
- * 
+ *
  */
 static const DBusAuthMechanismHandler
 all_mechanisms[] = {
@@ -1319,7 +1350,7 @@ all_mechanisms[] = {
     handle_client_initial_response_anonymous_mech,
     handle_client_data_anonymous_mech,
     NULL, NULL,
-    handle_client_shutdown_anonymous_mech },  
+    handle_client_shutdown_anonymous_mech },
   { NULL, NULL }
 };
 
@@ -1328,23 +1359,23 @@ find_mech (const DBusString  *name,
            char             **allowed_mechs)
 {
   int i;
-  
+
   if (allowed_mechs != NULL &&
       !_dbus_string_array_contains ((const char**) allowed_mechs,
                                     _dbus_string_get_const_data (name)))
     return NULL;
-  
+
   i = 0;
   while (all_mechanisms[i].mechanism != NULL)
-    {      
+    {
       if (_dbus_string_equal_c_str (name,
                                     all_mechanisms[i].mechanism))
 
         return &all_mechanisms[i];
-      
+
       ++i;
     }
-  
+
   return NULL;
 }
 
@@ -1355,14 +1386,14 @@ send_auth (DBusAuth *auth, const DBusAut
 
   if (!_dbus_string_init (&auth_command))
     return FALSE;
-      
+
   if (!_dbus_string_append (&auth_command,
                             "AUTH "))
     {
       _dbus_string_free (&auth_command);
       return FALSE;
-    }  
-  
+    }
+
   if (!_dbus_string_append (&auth_command,
                             mech->mechanism))
     {
@@ -1377,14 +1408,14 @@ send_auth (DBusAuth *auth, const DBusAut
           _dbus_string_free (&auth_command);
           return FALSE;
         }
-      
+
       if (!(* mech->client_initial_response_func) (auth, &auth_command))
         {
           _dbus_string_free (&auth_command);
           return FALSE;
         }
     }
-  
+
   if (!_dbus_string_append (&auth_command,
                             "\r\n"))
     {
@@ -1402,7 +1433,7 @@ send_auth (DBusAuth *auth, const DBusAut
 
   _dbus_string_free (&auth_command);
   shutdown_mech (auth);
-  auth->mech = mech;      
+  auth->mech = mech;
   goto_state (auth, &client_state_waiting_for_data);
 
   return TRUE;
@@ -1443,10 +1474,10 @@ send_rejected (DBusAuth *auth)
   DBusString command;
   DBusAuthServer *server_auth;
   int i;
-  
+
   if (!_dbus_string_init (&command))
     return FALSE;
-  
+
   if (!_dbus_string_append (&command,
                             "REJECTED"))
     goto nomem;
@@ -1461,10 +1492,10 @@ send_rejected (DBusAuth *auth)
       if (!_dbus_string_append (&command,
                                 all_mechanisms[i].mechanism))
         goto nomem;
-      
+
       ++i;
     }
-  
+
   if (!_dbus_string_append (&command, "\r\n"))
     goto nomem;
 
@@ -1473,7 +1504,7 @@ send_rejected (DBusAuth *auth)
     goto nomem;
 
   shutdown_mech (auth);
-  
+
   _dbus_assert (DBUS_AUTH_IS_SERVER (auth));
   server_auth = DBUS_AUTH_SERVER (auth);
   server_auth->failures += 1;
@@ -1484,7 +1515,7 @@ send_rejected (DBusAuth *auth)
     goto_state (auth, &server_state_waiting_for_auth);
 
   _dbus_string_free (&command);
-  
+
   return TRUE;
 
  nomem:
@@ -1505,7 +1536,7 @@ send_ok (DBusAuth *auth)
   int orig_len;
 
   orig_len = _dbus_string_get_length (&auth->outgoing);
-  
+
   if (_dbus_string_append (&auth->outgoing, "OK ") &&
       _dbus_string_copy (& DBUS_AUTH_SERVER (auth)->guid,
                          0,
@@ -1540,12 +1571,12 @@ process_ok(DBusAuth *auth,
           const DBusString *args_from_ok) {
 
   int end_of_hex;
-  
+
   /* "args_from_ok" should be the GUID, whitespace already pulled off the front */
   _dbus_assert (_dbus_string_get_length (& DBUS_AUTH_CLIENT (auth)->guid_from_server) == 0);
 
   /* We decode the hex string to binary, using guid_from_server as scratch... */
-  
+
   end_of_hex = 0;
   if (!_dbus_string_hex_decode (args_from_ok, 0, &end_of_hex,
                                 & DBUS_AUTH_CLIENT (auth)->guid_from_server, 0))
@@ -1553,7 +1584,7 @@ process_ok(DBusAuth *auth,
 
   /* now clear out the scratch */
   _dbus_string_set_length (& DBUS_AUTH_CLIENT (auth)->guid_from_server, 0);
-  
+
   if (end_of_hex != _dbus_string_get_length (args_from_ok) ||
       end_of_hex == 0)
     {
@@ -1623,7 +1654,7 @@ process_data (DBusAuth             *auth
                    DBUS_AUTH_NAME (auth),
                    _dbus_string_get_const_data (&decoded));
 #endif
-      
+
   if (!(* data_func) (auth, &decoded))
     {
       _dbus_string_free (&decoded);
@@ -1677,7 +1708,7 @@ handle_auth (DBusAuth *auth, const DBusS
       int i;
       DBusString mech;
       DBusString hex_response;
-      
+
       _dbus_string_find_blank (args, 0, &i);
 
       if (!_dbus_string_init (&mech))
@@ -1688,21 +1719,21 @@ handle_auth (DBusAuth *auth, const DBusS
           _dbus_string_free (&mech);
           return FALSE;
         }
-      
+
       if (!_dbus_string_copy_len (args, 0, i, &mech, 0))
         goto failed;
 
       _dbus_string_skip_blank (args, i, &i);
       if (!_dbus_string_copy (args, i, &hex_response, 0))
         goto failed;
-     
+
       auth->mech = find_mech (&mech, auth->allowed_mechs);
       if (auth->mech != NULL)
         {
           _dbus_verbose ("%s: Trying mechanism %s\n",
                          DBUS_AUTH_NAME (auth),
                          auth->mech->mechanism);
-          
+
           if (!process_data (auth, &hex_response,
                              auth->mech->server_data_func))
             goto failed;
@@ -1713,16 +1744,16 @@ handle_auth (DBusAuth *auth, const DBusS
           _dbus_verbose ("%s: Unsupported mechanism %s\n",
                          DBUS_AUTH_NAME (auth),
                          _dbus_string_get_const_data (&mech));
-          
+
           if (!send_rejected (auth))
             goto failed;
         }
 
-      _dbus_string_free (&mech);      
+      _dbus_string_free (&mech);
       _dbus_string_free (&hex_response);
 
       return TRUE;
-      
+
     failed:
       auth->mech = NULL;
       _dbus_string_free (&mech);
@@ -1843,12 +1874,12 @@ get_word (const DBusString *str,
 
   _dbus_string_skip_blank (str, *start, start);
   _dbus_string_find_blank (str, *start, &i);
-  
+
   if (i > *start)
     {
       if (!_dbus_string_copy_len (str, *start, i - *start, word, 0))
         return FALSE;
-      
+
       *start = i;
     }
 
@@ -1864,18 +1895,18 @@ record_mechanisms (DBusAuth         *aut
 
   if (auth->already_got_mechanisms)
     return TRUE;
-  
+
   len = _dbus_string_get_length (args);
-  
+
   next = 0;
   while (next < len)
     {
       DBusString m;
       const DBusAuthMechanismHandler *mech;
-      
+
       if (!_dbus_string_init (&m))
         goto nomem;
-      
+
       if (!get_word (args, &next, &m))
         {
           _dbus_string_free (&m);
@@ -1899,7 +1930,7 @@ record_mechanisms (DBusAuth         *aut
             {
               _dbus_verbose ("%s: Adding mechanism %s to list we will try\n",
                              DBUS_AUTH_NAME (auth), mech->mechanism);
-          
+
               if (!_dbus_list_append (& DBUS_AUTH_CLIENT (auth)->mechs_to_try,
                                       (void*) mech))
                 {
@@ -1922,14 +1953,14 @@ record_mechanisms (DBusAuth         *aut
 
       _dbus_string_free (&m);
     }
-  
+
   auth->already_got_mechanisms = TRUE;
-  
+
   return TRUE;
 
  nomem:
   _dbus_list_clear (& DBUS_AUTH_CLIENT (auth)->mechs_to_try);
-  
+
   return FALSE;
 }
 
@@ -1946,7 +1977,7 @@ process_rejected (DBusAuth *auth, const
       if (!record_mechanisms (auth, args))
         return FALSE;
     }
-  
+
   if (DBUS_AUTH_CLIENT (auth)->mechs_to_try != NULL)
     {
       mech = client->mechs_to_try->data;
@@ -1967,7 +1998,7 @@ process_rejected (DBusAuth *auth, const
                      DBUS_AUTH_NAME (auth));
       goto_state (auth, &common_state_need_disconnect);
     }
-  
+
   return TRUE;
 }
 
@@ -1978,7 +2009,7 @@ handle_client_state_waiting_for_data (DB
                                       const DBusString *args)
 {
   _dbus_assert (auth->mech != NULL);
- 
+
   switch (command)
     {
     case DBUS_AUTH_COMMAND_DATA:
@@ -2041,7 +2072,7 @@ handle_client_state_waiting_for_reject (
     {
     case DBUS_AUTH_COMMAND_REJECTED:
       return process_rejected (auth, args);
-      
+
     case DBUS_AUTH_COMMAND_AUTH:
     case DBUS_AUTH_COMMAND_CANCEL:
     case DBUS_AUTH_COMMAND_DATA:
@@ -2148,13 +2179,13 @@ process_command (DBusAuth *auth)
   dbus_bool_t retval;
 
   /* _dbus_verbose ("%s:   trying process_command()\n"); */
-  
+
   retval = FALSE;
-  
+
   eol = 0;
   if (!_dbus_string_find (&auth->incoming, 0, "\r\n", &eol))
     return FALSE;
-  
+
   if (!_dbus_string_init (&line))
     {
       auth->needed_memory = TRUE;
@@ -2167,7 +2198,7 @@ process_command (DBusAuth *auth)
       auth->needed_memory = TRUE;
       return FALSE;
     }
-  
+
   if (!_dbus_string_copy_len (&auth->incoming, 0, eol, &line, 0))
     goto out;
 
@@ -2181,41 +2212,41 @@ process_command (DBusAuth *auth)
       else
         goto next_command;
     }
-  
+
   _dbus_verbose ("%s: got command \"%s\"\n",
                  DBUS_AUTH_NAME (auth),
                  _dbus_string_get_const_data (&line));
-  
+
   _dbus_string_find_blank (&line, 0, &i);
   _dbus_string_skip_blank (&line, i, &j);
 
   if (j > i)
     _dbus_string_delete (&line, i, j - i);
-  
+
   if (!_dbus_string_move (&line, i, &args, 0))
     goto out;
 
   /* FIXME 1.0 we should probably validate that only the allowed
    * chars are in the command name
    */
-  
+
   command = lookup_command_from_name (&line);
   if (!(* auth->state->handler) (auth, command, &args))
     goto out;
 
  next_command:
-  
+
   /* We've succeeded in processing the whole command so drop it out
    * of the incoming buffer and return TRUE to try another command.
    */
 
   _dbus_string_delete (&auth->incoming, 0, eol);
-  
+
   /* kill the \r\n */
   _dbus_string_delete (&auth->incoming, 0, 2);
 
   retval = TRUE;
-  
+
  out:
   _dbus_string_free (&args);
   _dbus_string_free (&line);
@@ -2224,7 +2255,7 @@ process_command (DBusAuth *auth)
     auth->needed_memory = TRUE;
   else
     auth->needed_memory = FALSE;
-  
+
   return retval;
 }
 
@@ -2265,20 +2296,20 @@ _dbus_auth_server_new (const DBusString
       _dbus_string_free (&guid_copy);
       return NULL;
     }
-  
+
   auth->side = auth_side_server;
   auth->state = &server_state_waiting_for_auth;
 
   server_auth = DBUS_AUTH_SERVER (auth);
 
   server_auth->guid = guid_copy;
-  
+
   /* perhaps this should be per-mechanism with a lower
    * max
    */
   server_auth->failures = 0;
   server_auth->max_failures = 6;
-  
+
   return auth;
 }
 
@@ -2317,7 +2348,7 @@ _dbus_auth_client_new (void)
       _dbus_auth_unref (auth);
       return NULL;
     }
-  
+
   return auth;
 }
 
@@ -2331,9 +2362,9 @@ DBusAuth *
 _dbus_auth_ref (DBusAuth *auth)
 {
   _dbus_assert (auth != NULL);
-  
+
   auth->refcount += 1;
-  
+
   return auth;
 }
 
@@ -2379,7 +2410,7 @@ _dbus_auth_unref (DBusAuth *auth)
       _dbus_credentials_unref (auth->credentials);
       _dbus_credentials_unref (auth->authorized_identity);
       _dbus_credentials_unref (auth->desired_identity);
-      
+
       dbus_free (auth);
     }
 }
@@ -2406,7 +2437,7 @@ _dbus_auth_set_mechanisms (DBusAuth    *
     }
   else
     copy = NULL;
-  
+
   dbus_free_string_array (auth->allowed_mechs);
 
   auth->allowed_mechs = copy;
@@ -2439,7 +2470,7 @@ _dbus_auth_do_work (DBusAuth *auth)
     {
       if (DBUS_AUTH_IN_END_STATE (auth))
         break;
-      
+
       if (_dbus_string_get_length (&auth->incoming) > MAX_BUFFER ||
           _dbus_string_get_length (&auth->outgoing) > MAX_BUFFER)
         {
@@ -2479,7 +2510,7 @@ _dbus_auth_get_bytes_to_send (DBusAuth
   _dbus_assert (str != NULL);
 
   *str = NULL;
-  
+
   if (_dbus_string_get_length (&auth->outgoing) == 0)
     return FALSE;
 
@@ -2504,7 +2535,7 @@ _dbus_auth_bytes_sent (DBusAuth *auth,
                  DBUS_AUTH_NAME (auth),
                  bytes_sent,
                  _dbus_string_get_const_data (&auth->outgoing));
-  
+
   _dbus_string_delete (&auth->outgoing,
                        0, bytes_sent);
 }
@@ -2522,7 +2553,7 @@ _dbus_auth_get_buffer (DBusAuth     *aut
 {
   _dbus_assert (auth != NULL);
   _dbus_assert (!auth->buffer_outstanding);
-  
+
   *buffer = &auth->incoming;
 
   auth->buffer_outstanding = TRUE;
@@ -2592,7 +2623,7 @@ _dbus_auth_needs_encoding (DBusAuth *aut
 {
   if (auth->state != &common_state_authenticated)
     return FALSE;
-  
+
   if (auth->mech != NULL)
     {
       if (DBUS_AUTH_IS_CLIENT (auth))
@@ -2620,10 +2651,10 @@ _dbus_auth_encode_data (DBusAuth
                         DBusString       *encoded)
 {
   _dbus_assert (plaintext != encoded);
-  
+
   if (auth->state != &common_state_authenticated)
     return FALSE;
-  
+
   if (_dbus_auth_needs_encoding (auth))
     {
       if (DBUS_AUTH_IS_CLIENT (auth))
@@ -2651,7 +2682,7 @@ _dbus_auth_needs_decoding (DBusAuth *aut
 {
   if (auth->state != &common_state_authenticated)
     return FALSE;
-    
+
   if (auth->mech != NULL)
     {
       if (DBUS_AUTH_IS_CLIENT (auth))
@@ -2683,10 +2714,10 @@ _dbus_auth_decode_data (DBusAuth
                         DBusString       *plaintext)
 {
   _dbus_assert (plaintext != encoded);
-  
+
   if (auth->state != &common_state_authenticated)
     return FALSE;
-  
+
   if (_dbus_auth_needs_decoding (auth))
     {
       if (DBUS_AUTH_IS_CLIENT (auth))
@@ -2755,7 +2786,7 @@ const char*
 _dbus_auth_get_guid_from_server (DBusAuth *auth)
 {
   _dbus_assert (DBUS_AUTH_IS_CLIENT (auth));
-  
+
   if (auth->state == &common_state_authenticated)
     return _dbus_string_get_const_data (& DBUS_AUTH_CLIENT (auth)->guid_from_server);
   else
