dbus/dbus dbus-auth.c, 1.42, 1.43 dbus-auth.h, 1.12, 1.13 dbus-transport-protected.h, 1.16, 1.17 dbus-transport.c, 1.45, 1.46

Havoc Pennington hp at freedesktop.org
Thu May 5 15:02:13 PDT 2005


Update of /cvs/dbus/dbus/dbus
In directory gabe:/tmp/cvs-serv18237/dbus

Modified Files:
	dbus-auth.c dbus-auth.h dbus-transport-protected.h 
	dbus-transport.c 
Log Message:
2005-05-05  Havoc Pennington  <hp at redhat.com>

	* configure.in (LT_*): add notes on how the libtool versioning
	works to save thinking. Increment soname to indicate protocol
	breakage (though really the library interface hasn't changed I
	guess)

	* dbus/dbus-transport.c (_dbus_transport_get_is_authenticated):
	verify the GUID received from server matches what we were
	expecting, if we had an expectation

	* dbus/dbus-auth.c (send_ok): send GUID along with the OK command
	(_dbus_auth_get_guid_from_server): new function
	(send_begin): parse the OK args

	* doc/dbus-specification.xml: add GUID to the auth protocol



Index: dbus-auth.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-auth.c,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -d -r1.42 -r1.43
--- dbus-auth.c	26 Feb 2005 06:37:46 -0000	1.42
+++ dbus-auth.c	5 May 2005 22:02:11 -0000	1.43
@@ -199,6 +199,8 @@
   DBusAuth base;    /**< Parent class */
 
   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;
 
@@ -226,7 +228,8 @@
 static dbus_bool_t send_error                (DBusAuth *auth,
                                               const char *message);
 static dbus_bool_t send_ok                   (DBusAuth *auth);
-static dbus_bool_t send_begin                (DBusAuth *auth);
+static dbus_bool_t send_begin                (DBusAuth *auth,
+                                              const DBusString *args_from_ok);
 static dbus_bool_t send_cancel               (DBusAuth *auth);
 
 /**
@@ -1329,25 +1332,69 @@
 static dbus_bool_t
 send_ok (DBusAuth *auth)
 {
-  if (_dbus_string_append (&auth->outgoing, "OK\r\n"))
+  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,
+                         &auth->outgoing,
+                         _dbus_string_get_length (&auth->outgoing)) &&
+      _dbus_string_append (&auth->outgoing, "\r\n"))
     {
       goto_state (auth, &server_state_waiting_for_begin);
       return TRUE;
     }
   else
-    return FALSE;
+    {
+      _dbus_string_set_length (&auth->outgoing, orig_len);
+      return FALSE;
+    }
 }
 
 static dbus_bool_t
-send_begin (DBusAuth *auth)
+send_begin (DBusAuth         *auth,
+            const DBusString *args_from_ok)
 {
-  if (_dbus_string_append (&auth->outgoing, "BEGIN\r\n"))
+  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))
+    return FALSE;
+
+  /* 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)
+    {
+      _dbus_verbose ("Bad GUID from server, parsed %d bytes and had %d bytes from server\n",
+                     end_of_hex, _dbus_string_get_length (args_from_ok));
+      goto_state (auth, &common_state_need_disconnect);
+      return TRUE;
+    }
+
+  if (_dbus_string_copy (args_from_ok, 0, &DBUS_AUTH_CLIENT (auth)->guid_from_server, 0) &&
+      _dbus_string_append (&auth->outgoing, "BEGIN\r\n"))
     {
+      _dbus_verbose ("Got GUID '%s' from the server\n",
+                     _dbus_string_get_const_data (& DBUS_AUTH_CLIENT (auth)->guid_from_server));
+      
       goto_state (auth, &common_state_authenticated);
       return TRUE;
     }
   else
-    return FALSE;
+    {
+      _dbus_string_set_length (& DBUS_AUTH_CLIENT (auth)->guid_from_server, 0);
+      return FALSE;
+    }
 }
 
 static dbus_bool_t
@@ -1364,8 +1411,8 @@
 
 static dbus_bool_t
 process_data (DBusAuth             *auth,
-             const DBusString     *args,
-             DBusAuthDataFunction  data_func)
+              const DBusString     *args,
+              DBusAuthDataFunction  data_func)
 {
   int end;
   DBusString decoded;
@@ -1710,7 +1757,7 @@
       return process_rejected (auth, args);
 
     case DBUS_AUTH_COMMAND_OK:
-      return send_begin (auth);
+      return send_begin (auth, args);
 
     case DBUS_AUTH_COMMAND_ERROR:
       return send_cancel (auth);
@@ -1735,7 +1782,7 @@
       return process_rejected (auth, args);
 
     case DBUS_AUTH_COMMAND_OK:
-      return send_begin (auth);
+      return send_begin (auth, args);
 
     case DBUS_AUTH_COMMAND_DATA:
     case DBUS_AUTH_COMMAND_ERROR:
@@ -1974,10 +2021,19 @@
 _dbus_auth_client_new (void)
 {
   DBusAuth *auth;
+  DBusString guid_str;
+
+  if (!_dbus_string_init (&guid_str))
+    return NULL;
 
   auth = _dbus_auth_new (sizeof (DBusAuthClient));
   if (auth == NULL)
-    return NULL;
+    {
+      _dbus_string_free (&guid_str);
+      return NULL;
+    }
+
+  DBUS_AUTH_CLIENT (auth)->guid_from_server = guid_str;
 
   auth->side = auth_side_client;
   auth->state = &client_state_need_send_auth;
@@ -2027,6 +2083,7 @@
 
       if (DBUS_AUTH_IS_CLIENT (auth))
         {
+          _dbus_string_free (& DBUS_AUTH_CLIENT (auth)->guid_from_server);
           _dbus_list_clear (& DBUS_AUTH_CLIENT (auth)->mechs_to_try);
         }
       else
@@ -2402,6 +2459,23 @@
 }
 
 /**
+ * Gets the GUID from the server if we've authenticated; gets
+ * #NULL otherwise.
+ * @param auth the auth object
+ * @returns the GUID in ASCII hex format
+ */
+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
+    return NULL;
+}
+
+/**
  * Sets the "authentication context" which scopes cookies
  * with the DBUS_COOKIE_SHA1 auth mechanism for example.
  *

Index: dbus-auth.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-auth.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- dbus-auth.h	26 Feb 2005 06:37:46 -0000	1.12
+++ dbus-auth.h	5 May 2005 22:02:11 -0000	1.13
@@ -74,6 +74,7 @@
                                               DBusCredentials        *credentials);
 dbus_bool_t   _dbus_auth_set_context         (DBusAuth               *auth,
                                               const DBusString       *context);
+const char*   _dbus_auth_get_guid_from_server(DBusAuth               *auth);
 
 
 DBUS_END_DECLS

Index: dbus-transport-protected.h
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-transport-protected.h,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- dbus-transport-protected.h	26 Feb 2005 06:37:46 -0000	1.16
+++ dbus-transport-protected.h	5 May 2005 22:02:11 -0000	1.17
@@ -96,7 +96,9 @@
   DBusCounter *live_messages_size;            /**< Counter for size of all live messages. */
 
 
-  char *address;                              /**< Address of this server */
+  char *address;                              /**< Address of the server we are connecting to (#NULL for the server side of a transport) */
+
+  char *expected_guid;                        /**< GUID we expect the server to have, #NULL on server side or if we don't have an expectation */
   
   DBusAllowUnixUserFunction unix_user_function; /**< Function for checking whether a user is authorized. */
   void *unix_user_data;                         /**< Data for unix_user_function */

Index: dbus-transport.c
===================================================================
RCS file: /cvs/dbus/dbus/dbus/dbus-transport.c,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -d -r1.45 -r1.46
--- dbus-transport.c	26 Feb 2005 06:37:46 -0000	1.45
+++ dbus-transport.c	5 May 2005 22:02:11 -0000	1.46
@@ -153,6 +153,8 @@
   transport->unix_user_function = NULL;
   transport->unix_user_data = NULL;
   transport->free_unix_user_data = NULL;
+
+  transport->expected_guid = NULL;
   
   /* Try to default to something that won't totally hose the system,
    * but doesn't impose too much of a limitation.
@@ -195,6 +197,7 @@
                             0, NULL, NULL);
   _dbus_counter_unref (transport->live_messages_size);
   dbus_free (transport->address);
+  dbus_free (transport->expected_guid);
 }
 
 /**
@@ -213,7 +216,9 @@
   const char *address_problem_type;
   const char *address_problem_field;
   const char *address_problem_other;
-  const char *method;     
+  const char *method;
+  const char *expected_guid_orig;
+  char *expected_guid;
 
   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
   
@@ -221,6 +226,14 @@
   address_problem_type = NULL;
   address_problem_field = NULL;
   address_problem_other = NULL;
+  expected_guid_orig = dbus_address_entry_get_value (entry, "guid");
+  expected_guid = _dbus_strdup (expected_guid_orig);
+
+  if (expected_guid_orig != NULL && expected_guid == NULL)
+    {
+      _DBUS_SET_OOM (error);
+      return NULL;
+    }
   
   method = dbus_address_entry_get_method (entry);
   _dbus_assert (method != NULL);
@@ -306,11 +319,20 @@
     }
 
   if (transport == NULL)
-    _DBUS_ASSERT_ERROR_IS_SET (error);
+    {
+      _DBUS_ASSERT_ERROR_IS_SET (error);
+      dbus_free (expected_guid);
+    }
+  else
+    {
+      transport->expected_guid = expected_guid;
+    }
   
   return transport;
   
  bad_address:
+  dbus_free (expected_guid);
+  
   if (address_problem_type != NULL)
     dbus_set_error (error, DBUS_ERROR_BAD_ADDRESS,
                     "Address of type %s was missing argument %s",
@@ -442,6 +464,35 @@
               maybe_authenticated = FALSE;
             }
         }
+
+      if (maybe_authenticated && !transport->is_server)
+        {
+          const char *server_guid;
+
+          server_guid = _dbus_auth_get_guid_from_server (transport->auth);
+          _dbus_assert (server_guid != NULL);
+
+          if (transport->expected_guid &&
+              strcmp (transport->expected_guid, server_guid) != 0)
+            {
+              _dbus_verbose ("Client expected GUID '%s' and we got '%s' from the server\n",
+                             transport->expected_guid, server_guid);
+              _dbus_transport_disconnect (transport);
+              _dbus_connection_unref_unlocked (transport->connection);
+              return FALSE;
+            }
+
+          if (transport->expected_guid == NULL)
+            {
+              transport->expected_guid = _dbus_strdup (server_guid);
+
+              if (transport->expected_guid == NULL)
+                {
+                  _dbus_verbose ("No memory to complete auth in %s\n", _DBUS_FUNCTION_NAME);
+                  return FALSE;
+                }
+            }
+        }
       
       /* If we've authenticated as some identity, check that the auth
        * identity is the same as our own identity.  In the future, we
@@ -518,7 +569,7 @@
                 }
             }
         }
-
+      
       transport->authenticated = maybe_authenticated;
 
       _dbus_connection_unref_unlocked (transport->connection);



More information about the dbus-commit mailing list