Commit 4db285c8 authored by Havoc Pennington's avatar Havoc Pennington

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
parent b4b85685
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 ;)
......
......@@ -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)
......
......@@ -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
......@@ -2401,6 +2458,23 @@ _dbus_auth_get_identity (DBusAuth *auth,
_dbus_credentials_clear (credentials);
}
/**
* 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.
......
......@@ -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
......
......@@ -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 */
......
......@@ -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);
......
......@@ -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
......
......@@ -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>
......
......@@ -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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment