summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHavoc Pennington <hp@redhat.com>2007-06-12 18:36:19 +0000
committerHavoc Pennington <hp@redhat.com>2007-06-12 18:36:19 +0000
commit94125e89b6be74cb20100d5321a98aa6529187a9 (patch)
tree7ec1aab41bad3448155c07e1a8328e9d0168a0a3
parenta789b7b38cb4f4540a41444cbd64bf7ada2d60d2 (diff)
2007-06-12 Havoc Pennington <hp@redhat.com>
* dbus/dbus-auth.c (sha1_handle_second_client_response) (handle_server_data_anonymous_mech): add the process ID from socket credentials, if available, even if not using EXTERNAL * dbus/dbus-transport.c (auth_via_default_rules): support allow_anonymous flag * dbus/dbus-connection.c (dbus_connection_get_is_anonymous) (dbus_connection_set_allow_anonymous): new API for controlling anonymous access
-rw-r--r--dbus/dbus-auth-script.c4
-rw-r--r--dbus/dbus-auth.c21
-rw-r--r--dbus/dbus-connection.c72
-rw-r--r--dbus/dbus-connection.h3
-rw-r--r--dbus/dbus-credentials-util.c2
-rw-r--r--dbus/dbus-credentials.c14
-rw-r--r--dbus/dbus-credentials.h1
-rw-r--r--dbus/dbus-transport-protected.h1
-rw-r--r--dbus/dbus-transport.c43
-rw-r--r--dbus/dbus-transport.h5
10 files changed, 153 insertions, 13 deletions
diff --git a/dbus/dbus-auth-script.c b/dbus/dbus-auth-script.c
index dd864ca5..eb145e49 100644
--- a/dbus/dbus-auth-script.c
+++ b/dbus/dbus-auth-script.c
@@ -665,7 +665,7 @@ _dbus_auth_script_run (const DBusString *filename)
DBusCredentials *authorized_identity;
authorized_identity = _dbus_auth_get_identity (auth);
- if (!_dbus_credentials_are_empty (authorized_identity))
+ if (!_dbus_credentials_are_anonymous (authorized_identity))
{
_dbus_warn ("Expected anonymous login or failed login, but some credentials were authorized\n");
goto out;
@@ -677,7 +677,7 @@ _dbus_auth_script_run (const DBusString *filename)
DBusCredentials *authorized_identity;
authorized_identity = _dbus_auth_get_identity (auth);
- if (_dbus_credentials_are_empty (authorized_identity))
+ if (_dbus_credentials_are_anonymous (authorized_identity))
{
_dbus_warn ("Expected to have some credentials, but we don't\n");
goto out;
diff --git a/dbus/dbus-auth.c b/dbus/dbus-auth.c
index 657f8d3d..e47f6e36 100644
--- a/dbus/dbus-auth.c
+++ b/dbus/dbus-auth.c
@@ -731,6 +731,13 @@ sha1_handle_second_client_response (DBusAuth *auth,
if (!_dbus_credentials_add_credentials (auth->authorized_identity,
auth->desired_identity))
goto out_3;
+
+ /* Copy process ID from the socket credentials if it's there
+ */
+ if (!_dbus_credentials_add_credential (auth->authorized_identity,
+ DBUS_CREDENTIAL_UNIX_PROCESS_ID,
+ auth->credentials))
+ goto out_3;
if (!send_ok (auth))
goto out_3;
@@ -994,7 +1001,7 @@ static dbus_bool_t
handle_server_data_external_mech (DBusAuth *auth,
const DBusString *data)
{
- if (_dbus_credentials_are_empty (auth->credentials))
+ if (_dbus_credentials_are_anonymous (auth->credentials))
{
_dbus_verbose ("%s: no credentials, mechanism EXTERNAL can't authenticate\n",
DBUS_AUTH_NAME (auth));
@@ -1059,7 +1066,7 @@ handle_server_data_external_mech (DBusAuth *auth,
}
}
- if (_dbus_credentials_are_empty (auth->desired_identity))
+ if (_dbus_credentials_are_anonymous (auth->desired_identity))
{
_dbus_verbose ("%s: desired user %s is no good\n",
DBUS_AUTH_NAME (auth),
@@ -1075,8 +1082,7 @@ handle_server_data_external_mech (DBusAuth *auth,
auth->desired_identity))
return FALSE;
- /* also copy process ID from the socket credentials - FIXME this
- * should be done even if auth EXTERNAL not used
+ /* also copy process ID from the socket credentials
*/
if (!_dbus_credentials_add_credential (auth->authorized_identity,
DBUS_CREDENTIAL_UNIX_PROCESS_ID,
@@ -1192,6 +1198,13 @@ handle_server_data_anonymous_mech (DBusAuth *auth,
/* We want to be anonymous (clear in case some other protocol got midway through I guess) */
_dbus_credentials_clear (auth->desired_identity);
+ /* Copy process ID from the socket credentials
+ */
+ if (!_dbus_credentials_add_credential (auth->authorized_identity,
+ DBUS_CREDENTIAL_UNIX_PROCESS_ID,
+ auth->credentials))
+ return FALSE;
+
/* Anonymous is always allowed */
if (!send_ok (auth))
return FALSE;
diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c
index 1cd3d05d..656f7502 100644
--- a/dbus/dbus-connection.c
+++ b/dbus/dbus-connection.c
@@ -2811,6 +2811,40 @@ dbus_connection_get_is_authenticated (DBusConnection *connection)
}
/**
+ * Gets whether the connection is not authenticated as a specific
+ * user. If the connection is not authenticated, this function
+ * returns #TRUE, and if it is authenticated but as an anonymous user,
+ * it returns #TRUE. If it is authenticated as a specific user, then
+ * this returns #FALSE. (Note that if the connection was authenticated
+ * as anonymous then disconnected, this function still returns #TRUE.)
+ *
+ * If the connection is not anonymous, you can use
+ * dbus_connection_get_unix_user() and
+ * dbus_connection_get_windows_user() to see who it's authorized as.
+ *
+ * If you want to prevent non-anonymous authorization, use
+ * dbus_server_set_auth_mechanisms() to remove the mechanisms that
+ * allow proving user identity (i.e. only allow the ANONYMOUS
+ * mechanism).
+ *
+ * @param connection the connection
+ * @returns #TRUE if not authenticated or authenticated as anonymous
+ */
+dbus_bool_t
+dbus_connection_get_is_anonymous (DBusConnection *connection)
+{
+ dbus_bool_t res;
+
+ _dbus_return_val_if_fail (connection != NULL, FALSE);
+
+ CONNECTION_LOCK (connection);
+ res = _dbus_transport_get_is_anonymous (connection->transport);
+ CONNECTION_UNLOCK (connection);
+
+ return res;
+}
+
+/**
* Set whether _exit() should be called when the connection receives a
* disconnect signal. The call to _exit() comes after any handlers for
* the disconnect signal run; handlers can cancel the exit by calling
@@ -4987,6 +5021,43 @@ dbus_connection_set_windows_user_function (DBusConnection *connecti
}
/**
+ * This function must be called on the server side of a connection when the
+ * connection is first seen in the #DBusNewConnectionFunction. If set to
+ * #TRUE (the default is #FALSE), then the connection can proceed even if
+ * the client does not authenticate as some user identity, i.e. clients
+ * can connect anonymously.
+ *
+ * This setting interacts with the available authorization mechanisms
+ * (see dbus_server_set_auth_mechanisms()). Namely, an auth mechanism
+ * such as ANONYMOUS that supports anonymous auth must be included in
+ * the list of available mechanisms for anonymous login to work.
+ *
+ * This setting also changes the default rule for connections
+ * authorized as a user; normally, if a connection authorizes as
+ * a user identity, it is permitted if the user identity is
+ * root or the user identity matches the user identity of the server
+ * process. If anonymous connections are allowed, however,
+ * then any user identity is allowed.
+ *
+ * You can override the rules for connections authorized as a
+ * user identity with dbus_connection_set_unix_user_function()
+ * and dbus_connection_set_windows_user_function().
+ *
+ * @param connection the connection
+ * @param value whether to allow authentication as an anonymous user
+ */
+void
+dbus_connection_set_allow_anonymous (DBusConnection *connection,
+ dbus_bool_t value)
+{
+ _dbus_return_if_fail (connection != NULL);
+
+ CONNECTION_LOCK (connection);
+ _dbus_transport_set_allow_anonymous (connection->transport, value);
+ CONNECTION_UNLOCK (connection);
+}
+
+/**
*
* Normally #DBusConnection automatically handles all messages to the
* org.freedesktop.DBus.Peer interface. However, the message bus wants
@@ -4997,7 +5068,6 @@ dbus_connection_set_windows_user_function (DBusConnection *connecti
* handled by the #DBusConnection and instead will be dispatched
* normally to the application.
*
- *
* If a normal application sets this flag, it can break things badly.
* So don't set this unless you are the message bus.
*
diff --git a/dbus/dbus-connection.h b/dbus/dbus-connection.h
index 2b673fda..533ac98d 100644
--- a/dbus/dbus-connection.h
+++ b/dbus/dbus-connection.h
@@ -178,6 +178,7 @@ void dbus_connection_unref (DBusConnection
void dbus_connection_close (DBusConnection *connection);
dbus_bool_t dbus_connection_get_is_connected (DBusConnection *connection);
dbus_bool_t dbus_connection_get_is_authenticated (DBusConnection *connection);
+dbus_bool_t dbus_connection_get_is_anonymous (DBusConnection *connection);
void dbus_connection_set_exit_on_disconnect (DBusConnection *connection,
dbus_bool_t exit_on_disconnect);
void dbus_connection_flush (DBusConnection *connection);
@@ -239,6 +240,8 @@ void dbus_connection_set_windows_user_function (DBusConnection
DBusAllowWindowsUserFunction function,
void *data,
DBusFreeFunction free_data_function);
+void dbus_connection_set_allow_anonymous (DBusConnection *connection,
+ dbus_bool_t value);
void dbus_connection_set_route_peer_messages (DBusConnection *connection,
dbus_bool_t value);
diff --git a/dbus/dbus-credentials-util.c b/dbus/dbus-credentials-util.c
index 9b81aca4..a76ad093 100644
--- a/dbus/dbus-credentials-util.c
+++ b/dbus/dbus-credentials-util.c
@@ -104,6 +104,7 @@ _dbus_credentials_test (const char *test_data_dir)
_dbus_assert (strcmp (_dbus_credentials_get_windows_sid (creds), SAMPLE_SID) == 0);
_dbus_assert (!_dbus_credentials_are_empty (creds));
+ _dbus_assert (!_dbus_credentials_are_anonymous (creds));
/* Test copy */
creds2 = _dbus_credentials_copy (creds);
@@ -193,6 +194,7 @@ _dbus_credentials_test (const char *test_data_dir)
_dbus_assert (_dbus_credentials_get_windows_sid (creds) == NULL);
_dbus_assert (_dbus_credentials_are_empty (creds));
+ _dbus_assert (_dbus_credentials_are_anonymous (creds));
_dbus_credentials_unref (creds);
diff --git a/dbus/dbus-credentials.c b/dbus/dbus-credentials.c
index dde69281..2023c170 100644
--- a/dbus/dbus-credentials.c
+++ b/dbus/dbus-credentials.c
@@ -289,6 +289,20 @@ _dbus_credentials_are_empty (DBusCredentials *credentials)
}
/**
+ * Checks whether a credentials object contains a user identity.
+ *
+ * @param credentials the object
+ * @returns #TRUE if there are no user identities in the object
+ */
+dbus_bool_t
+_dbus_credentials_are_anonymous (DBusCredentials *credentials)
+{
+ return
+ credentials->unix_uid == DBUS_UID_UNSET &&
+ credentials->windows_sid == NULL;
+}
+
+/**
* Merge all credentials found in the second object into the first object,
* overwriting the first object if there are any overlaps.
*
diff --git a/dbus/dbus-credentials.h b/dbus/dbus-credentials.h
index b47c9c47..f728b375 100644
--- a/dbus/dbus-credentials.h
+++ b/dbus/dbus-credentials.h
@@ -54,6 +54,7 @@ const char* _dbus_credentials_get_windows_sid (DBusCredentials
dbus_bool_t _dbus_credentials_are_superset (DBusCredentials *credentials,
DBusCredentials *possible_subset);
dbus_bool_t _dbus_credentials_are_empty (DBusCredentials *credentials);
+dbus_bool_t _dbus_credentials_are_anonymous (DBusCredentials *credentials);
dbus_bool_t _dbus_credentials_add_credentials (DBusCredentials *credentials,
DBusCredentials *other_credentials);
/* must silently allow 'which' to not exist */
diff --git a/dbus/dbus-transport-protected.h b/dbus/dbus-transport-protected.h
index 6d3f1f3c..76a17cf2 100644
--- a/dbus/dbus-transport-protected.h
+++ b/dbus/dbus-transport-protected.h
@@ -116,6 +116,7 @@ struct DBusTransport
unsigned int receive_credentials_pending : 1; /**< #TRUE if we need to receive credentials */
unsigned int is_server : 1; /**< #TRUE if on the server side */
unsigned int unused_bytes_recovered : 1; /**< #TRUE if we've recovered unused bytes from auth */
+ unsigned int allow_anonymous : 1; /**< #TRUE if an anonymous client can connect */
};
dbus_bool_t _dbus_transport_init_base (DBusTransport *transport,
diff --git a/dbus/dbus-transport.c b/dbus/dbus-transport.c
index 029cc6cf..d738cc0c 100644
--- a/dbus/dbus-transport.c
+++ b/dbus/dbus-transport.c
@@ -603,10 +603,10 @@ auth_via_default_rules (DBusTransport *transport)
auth_identity = _dbus_auth_get_identity (transport->auth);
_dbus_assert (auth_identity != NULL);
- /* By default, connection is allowed if the client is
- * 1) root or 2) has the same UID as us
+ /* By default, connection is allowed if the client is 1) root or 2)
+ * has the same UID as us or 3) anonymous is allowed.
*/
-
+
our_identity = _dbus_credentials_new_from_current_process ();
if (our_identity == NULL)
{
@@ -614,7 +614,8 @@ auth_via_default_rules (DBusTransport *transport)
return FALSE;
}
- if (_dbus_credentials_get_unix_uid (auth_identity) == 0 ||
+ if (transport->allow_anonymous ||
+ _dbus_credentials_get_unix_uid (auth_identity) == 0 ||
_dbus_credentials_same_user (our_identity,
auth_identity))
{
@@ -756,6 +757,28 @@ _dbus_transport_get_is_authenticated (DBusTransport *transport)
}
/**
+ * See dbus_connection_get_is_anonymous().
+ *
+ * @param transport the transport
+ * @returns #TRUE if not authenticated or authenticated as anonymous
+ */
+dbus_bool_t
+_dbus_transport_get_is_anonymous (DBusTransport *transport)
+{
+ DBusCredentials *auth_identity;
+
+ if (!transport->authenticated)
+ return TRUE;
+
+ auth_identity = _dbus_auth_get_identity (transport->auth);
+
+ if (_dbus_credentials_are_anonymous (auth_identity))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/**
* Gets the address of a transport. It will be
* #NULL for a server-side transport.
*
@@ -1298,5 +1321,17 @@ _dbus_transport_set_auth_mechanisms (DBusTransport *transport,
return _dbus_auth_set_mechanisms (transport->auth, mechanisms);
}
+/**
+ * See dbus_connection_set_allow_anonymous()
+ *
+ * @param transport the transport
+ * @param value #TRUE to allow anonymous connection
+ */
+void
+_dbus_transport_set_allow_anonymous (DBusTransport *transport,
+ dbus_bool_t value)
+{
+ transport->allow_anonymous = value != FALSE;
+}
/** @} */
diff --git a/dbus/dbus-transport.h b/dbus/dbus-transport.h
index 9e952a1e..3335c46b 100644
--- a/dbus/dbus-transport.h
+++ b/dbus/dbus-transport.h
@@ -39,6 +39,7 @@ void _dbus_transport_unref (DBusTransport
void _dbus_transport_disconnect (DBusTransport *transport);
dbus_bool_t _dbus_transport_get_is_connected (DBusTransport *transport);
dbus_bool_t _dbus_transport_get_is_authenticated (DBusTransport *transport);
+dbus_bool_t _dbus_transport_get_is_anonymous (DBusTransport *transport);
const char* _dbus_transport_get_address (DBusTransport *transport);
dbus_bool_t _dbus_transport_handle_watch (DBusTransport *transport,
DBusWatch *watch,
@@ -78,8 +79,8 @@ void _dbus_transport_set_windows_user_function (DBusTransport
DBusFreeFunction *old_free_data_function);
dbus_bool_t _dbus_transport_set_auth_mechanisms (DBusTransport *transport,
const char **mechanisms);
-
-
+void _dbus_transport_set_allow_anonymous (DBusTransport *transport,
+ dbus_bool_t value);
DBUS_END_DECLS