summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2005-05-05 22:02:11 +0000
committerHavoc Pennington <hp@redhat.com>2005-05-05 22:02:11 +0000
commit4db285c800a68245ad7593e606ca8cb2c21a1329 (patch)
tree4d10264c98f39ca3d048b97755983fd2feb794ce
parentb4b85685f139f1bbf64a557dee2b7c803e5e550b (diff)
2005-05-05 Havoc Pennington <hp@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
-rw-r--r--ChangeLog17
-rw-r--r--configure.in14
-rw-r--r--dbus/dbus-auth.c96
-rw-r--r--dbus/dbus-auth.h1
-rw-r--r--dbus/dbus-transport-protected.h4
-rw-r--r--dbus/dbus-transport.c57
-rw-r--r--doc/TODO7
-rw-r--r--doc/dbus-specification.xml18
-rw-r--r--test/data/auth/fallback.auth-script2
9 files changed, 187 insertions, 29 deletions
diff --git a/ChangeLog b/ChangeLog
index 408a4e3f..1fbbf859 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2005-05-05 Havoc Pennington <hp@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
+
2005-05-05 John (J5) Palmieri <johnp@redhat.com>
* Fix my name in previous changelog ;)
diff --git a/configure.in b/configure.in
index cc918e74..111ef6c8 100644
--- a/configure.in
+++ b/configure.in
@@ -17,13 +17,23 @@ AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE",[The name of the gettext d
## must come before we use the $USE_MAINTAINER_MODE variable later
AM_MAINTAINER_MODE
-# libtool versioning - this applies to libhal and libhal-storage
+# libtool versioning - this applies to libdbus
#
# See http://sources.redhat.com/autobook/autobook/autobook_91.html#SEC91 for details
#
-LT_CURRENT=1
+
+## increment if the interface has additions, changes, removals.
+LT_CURRENT=2
+
+## increment any time the source changes; set to
+## 0 if you increment CURRENT
LT_REVISION=0
+
+## increment if any interfaces have been added; set to 0
+## if any interfaces have been changed or removed. removal has
+## precedence over adding, so set to 0 if both happened.
LT_AGE=0
+
AC_SUBST(LT_CURRENT)
AC_SUBST(LT_REVISION)
AC_SUBST(LT_AGE)
diff --git a/dbus/dbus-auth.c b/dbus/dbus-auth.c
index 2a1bbd4c..ced93303 100644
--- a/dbus/dbus-auth.c
+++ b/dbus/dbus-auth.c
@@ -199,6 +199,8 @@ typedef struct
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_rejected (DBusAuth *auth);
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 @@ send_error (DBusAuth *auth, const char *message)
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 @@ send_cancel (DBusAuth *auth)
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 @@ handle_client_state_waiting_for_data (DBusAuth *auth,
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 @@ handle_client_state_waiting_for_ok (DBusAuth *auth,
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 @@ DBusAuth*
_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 @@ _dbus_auth_unref (DBusAuth *auth)
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 @@ _dbus_auth_get_identity (DBusAuth *auth,
}
/**
+ * 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.
*
diff --git a/dbus/dbus-auth.h b/dbus/dbus-auth.h
index 6ed5040e..9cff8b56 100644
--- a/dbus/dbus-auth.h
+++ b/dbus/dbus-auth.h
@@ -74,6 +74,7 @@ void _dbus_auth_get_identity (DBusAuth *auth,
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
diff --git a/dbus/dbus-transport-protected.h b/dbus/dbus-transport-protected.h
index 879c3db8..f3ad3370 100644
--- a/dbus/dbus-transport-protected.h
+++ b/dbus/dbus-transport-protected.h
@@ -96,7 +96,9 @@ struct DBusTransport
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 */
diff --git a/dbus/dbus-transport.c b/dbus/dbus-transport.c
index b271d944..cfc86e4a 100644
--- a/dbus/dbus-transport.c
+++ b/dbus/dbus-transport.c
@@ -153,6 +153,8 @@ _dbus_transport_init_base (DBusTransport *transport,
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 @@ _dbus_transport_finalize_base (DBusTransport *transport)
0, NULL, NULL);
_dbus_counter_unref (transport->live_messages_size);
dbus_free (transport->address);
+ dbus_free (transport->expected_guid);
}
/**
@@ -213,7 +216,9 @@ _dbus_transport_open (DBusAddressEntry *entry,
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 @@ _dbus_transport_open (DBusAddressEntry *entry,
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 @@ _dbus_transport_open (DBusAddressEntry *entry,
}
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 @@ _dbus_transport_get_is_authenticated (DBusTransport *transport)
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 @@ _dbus_transport_get_is_authenticated (DBusTransport *transport)
}
}
}
-
+
transport->authenticated = maybe_authenticated;
_dbus_connection_unref_unlocked (transport->connection);
diff --git a/doc/TODO b/doc/TODO
index f25eac05..0c126c11 100644
--- a/doc/TODO
+++ b/doc/TODO
@@ -31,10 +31,6 @@ Important for 1.0
- dbus-pending-call.c has some API and thread safety issues to review
- - transmit GUID from server to client in the auth protocol, so
- connections can be shared even if the address used to connect
- to them didn't have a GUID in it.
-
- Add test harness for selinux allow/deny cf. this message
http://lists.freedesktop.org/archives/dbus/2005-April/002506.html
@@ -63,6 +59,9 @@ Might as Well for 1.0
Can Be Post 1.0
===
+ - if the GUID is obtained only during authentication, not in the address,
+ we could still share the connection
+
- Allow a dbus_g_proxy_to_string()/g_object_to_string() that
would convert the proxy to an "IOR" and dbus_g_proxy_from_string()
that would decode; using these, dbus-glib users could avoid
diff --git a/doc/dbus-specification.xml b/doc/dbus-specification.xml
index ff625447..0ea43a87 100644
--- a/doc/dbus-specification.xml
+++ b/doc/dbus-specification.xml
@@ -1337,7 +1337,7 @@
<itemizedlist>
<listitem><para>REJECTED &lt;space-separated list of mechanism names&gt;</para></listitem>
- <listitem><para>OK</para></listitem>
+ <listitem><para>OK &lt;GUID in hex&gt;</para></listitem>
<listitem><para>DATA &lt;data in hex encoding&gt;</para></listitem>
<listitem><para>ERROR</para></listitem>
</itemizedlist>
@@ -1478,6 +1478,10 @@
The server must not accept additional commands using this protocol
after the OK command has been sent.
</para>
+ <para>
+ The OK command has one argument, which is the GUID of the server.
+ See <xref linkend="addresses"/> for more on server GUIDs.
+ </para>
</sect2>
<sect2 id="auth-command-error">
<title>ERROR Command</title>
@@ -1516,7 +1520,7 @@
(MAGIC_COOKIE is a made up mechanism)
C: AUTH MAGIC_COOKIE 3138363935333137393635383634
- S: OK
+ S: OK 1234deadbeef
C: BEGIN
</programlisting>
</figure>
@@ -1528,7 +1532,7 @@
C: AUTH SKEY 7ab83f32ee
S: DATA 8799cabb2ea93e
C: DATA 8ac876e8f68ee9809bfa876e6f9876g8fa8e76e98f
- S: OK
+ S: OK 1234deadbeef
C: BEGIN
</programlisting>
</figure>
@@ -1538,7 +1542,7 @@
C: FOOBAR
S: ERROR
C: AUTH MAGIC_COOKIE 3736343435313230333039
- S: OK
+ S: OK 1234deadbeef
C: BEGIN
</programlisting>
</figure>
@@ -1550,7 +1554,7 @@
C: AUTH SKEY 7ab83f32ee
S: DATA 8799cabb2ea93e
C: DATA 8ac876e8f68ee9809bfa876e6f9876g8fa8e76e98f
- S: OK
+ S: OK 1234deadbeef
C: BEGIN
</programlisting>
</figure>
@@ -1566,7 +1570,7 @@
C: AUTH SKEY 7ab83f32ee
S: DATA 8799cabb2ea93e
C: DATA 8ac876e8f68ee9809bfa876e6f9876g8fa8e76e98f
- S: OK
+ S: OK 1234deadbeef
C: BEGIN
</programlisting>
</figure>
@@ -1582,7 +1586,7 @@
C: AUTH SKEY 7ab83f32ee
S: DATA 8799cabb2ea93e
C: DATA 8ac876e8f68ee9809bfa876e6f9876g8fa8e76e98f
- S: OK
+ S: OK 1234deadbeef
C: BEGIN
</programlisting>
</figure>
diff --git a/test/data/auth/fallback.auth-script b/test/data/auth/fallback.auth-script
index ebe7ae28..f598b77e 100644
--- a/test/data/auth/fallback.auth-script
+++ b/test/data/auth/fallback.auth-script
@@ -16,7 +16,7 @@ SEND 'REJECTED EXTERNAL DBUS_COOKIE_SHA1 DBUS_TEST_NONEXISTENT_MECH'
EXPECT_COMMAND AUTH
## of course real DBUS_COOKIE_SHA1 would not send this here...
-SEND 'OK'
+SEND 'OK 1234deadbeef'
EXPECT_COMMAND BEGIN
EXPECT_STATE AUTHENTICATED