diff options
| author | Havoc Pennington <hp@redhat.com> | 2005-05-05 22:02:11 +0000 | 
|---|---|---|
| committer | Havoc Pennington <hp@redhat.com> | 2005-05-05 22:02:11 +0000 | 
| commit | 4db285c800a68245ad7593e606ca8cb2c21a1329 (patch) | |
| tree | 4d10264c98f39ca3d048b97755983fd2feb794ce | |
| parent | b4b85685f139f1bbf64a557dee2b7c803e5e550b (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-- | ChangeLog | 17 | ||||
| -rw-r--r-- | configure.in | 14 | ||||
| -rw-r--r-- | dbus/dbus-auth.c | 96 | ||||
| -rw-r--r-- | dbus/dbus-auth.h | 1 | ||||
| -rw-r--r-- | dbus/dbus-transport-protected.h | 4 | ||||
| -rw-r--r-- | dbus/dbus-transport.c | 57 | ||||
| -rw-r--r-- | doc/TODO | 7 | ||||
| -rw-r--r-- | doc/dbus-specification.xml | 18 | ||||
| -rw-r--r-- | test/data/auth/fallback.auth-script | 2 | 
9 files changed, 187 insertions, 29 deletions
| @@ -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); @@ -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 <space-separated list of mechanism names></para></listitem> -	  <listitem><para>OK</para></listitem> +	  <listitem><para>OK <GUID in hex></para></listitem>  	  <listitem><para>DATA <data in hex encoding></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 | 
