mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-05-04 23:28:05 +02:00
GetConnectionCredentials: add
The initial set of credentials is just UnixUserID and ProcessID. The rest can follow when someone is sufficiently interested to actually test them. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=54445 Reviewed-by: Ralf Habacker <ralf.habacker@freenet.de> [rename a function that Ralf found unclear -smcv] Signed-off-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
This commit is contained in:
parent
46af309cf5
commit
4b63567c02
3 changed files with 306 additions and 0 deletions
77
bus/driver.c
77
bus/driver.c
|
|
@ -33,6 +33,7 @@
|
|||
#include "stats.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <dbus/dbus-asv-util.h>
|
||||
#include <dbus/dbus-string.h>
|
||||
#include <dbus/dbus-internals.h>
|
||||
#include <dbus/dbus-message.h>
|
||||
|
|
@ -1523,6 +1524,80 @@ bus_driver_handle_get_connection_selinux_security_context (DBusConnection *conne
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static dbus_bool_t
|
||||
bus_driver_handle_get_connection_credentials (DBusConnection *connection,
|
||||
BusTransaction *transaction,
|
||||
DBusMessage *message,
|
||||
DBusError *error)
|
||||
{
|
||||
DBusConnection *conn;
|
||||
DBusMessage *reply;
|
||||
DBusMessageIter reply_iter;
|
||||
DBusMessageIter array_iter;
|
||||
unsigned long ulong_val;
|
||||
const char *service;
|
||||
|
||||
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
|
||||
|
||||
reply = NULL;
|
||||
|
||||
conn = bus_driver_get_conn_helper (connection, message, "credentials",
|
||||
&service, error);
|
||||
|
||||
if (conn == NULL)
|
||||
goto failed;
|
||||
|
||||
reply = _dbus_asv_new_method_return (message, &reply_iter, &array_iter);
|
||||
if (reply == NULL)
|
||||
goto oom;
|
||||
|
||||
/* we can't represent > 32-bit pids; if your system needs them, please
|
||||
* add ProcessID64 to the spec or something */
|
||||
if (dbus_connection_get_unix_process_id (conn, &ulong_val) &&
|
||||
ulong_val <= _DBUS_UINT32_MAX)
|
||||
{
|
||||
if (!_dbus_asv_add_uint32 (&array_iter, "ProcessID", ulong_val))
|
||||
goto oom;
|
||||
}
|
||||
|
||||
/* we can't represent > 32-bit uids; if your system needs them, please
|
||||
* add UnixUserID64 to the spec or something */
|
||||
if (dbus_connection_get_unix_user (conn, &ulong_val) &&
|
||||
ulong_val <= _DBUS_UINT32_MAX)
|
||||
{
|
||||
if (!_dbus_asv_add_uint32 (&array_iter, "UnixUserID", ulong_val))
|
||||
goto oom;
|
||||
}
|
||||
|
||||
if (!_dbus_asv_close (&reply_iter, &array_iter))
|
||||
goto oom;
|
||||
|
||||
if (! bus_transaction_send_from_driver (transaction, connection, reply))
|
||||
{
|
||||
/* this time we don't want to close the iterator again, so just
|
||||
* get rid of the message */
|
||||
dbus_message_unref (reply);
|
||||
reply = NULL;
|
||||
goto oom;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
oom:
|
||||
BUS_SET_OOM (error);
|
||||
|
||||
failed:
|
||||
_DBUS_ASSERT_ERROR_IS_SET (error);
|
||||
|
||||
if (reply)
|
||||
{
|
||||
_dbus_asv_abandon (&reply_iter, &array_iter);
|
||||
dbus_message_unref (reply);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static dbus_bool_t
|
||||
bus_driver_handle_reload_config (DBusConnection *connection,
|
||||
BusTransaction *transaction,
|
||||
|
|
@ -1703,6 +1778,8 @@ static const MessageHandler dbus_message_handlers[] = {
|
|||
"",
|
||||
DBUS_TYPE_STRING_AS_STRING,
|
||||
bus_driver_handle_get_id },
|
||||
{ "GetConnectionCredentials", "s", "a{sv}",
|
||||
bus_driver_handle_get_connection_credentials },
|
||||
{ NULL, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -5579,6 +5579,108 @@
|
|||
</para>
|
||||
</sect3>
|
||||
|
||||
<sect3 id="bus-messages-get-connection-credentials">
|
||||
<title><literal>org.freedesktop.DBus.GetConnectionCredentials</literal></title>
|
||||
<para>
|
||||
As a method:
|
||||
<programlisting>
|
||||
DICT<STRING,VARIANT> GetConnectionCredentials (in STRING bus_name)
|
||||
</programlisting>
|
||||
Message arguments:
|
||||
<informaltable>
|
||||
<tgroup cols="3">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Argument</entry>
|
||||
<entry>Type</entry>
|
||||
<entry>Description</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>0</entry>
|
||||
<entry>STRING</entry>
|
||||
<entry>Unique or well-known bus name of the connection to
|
||||
query, such as <literal>:12.34</literal> or
|
||||
<literal>com.example.tea</literal></entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</informaltable>
|
||||
Reply arguments:
|
||||
<informaltable>
|
||||
<tgroup cols="3">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Argument</entry>
|
||||
<entry>Type</entry>
|
||||
<entry>Description</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>0</entry>
|
||||
<entry>DICT<STRING,VARIANT></entry>
|
||||
<entry>Credentials</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</informaltable>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Returns as many credentials as possible for the process connected to
|
||||
the server. If unable to determine certain credentials (for instance,
|
||||
because the process is not on the same machine as the bus daemon,
|
||||
or because this version of the bus daemon does not support a
|
||||
particular security framework), or if the values of those credentials
|
||||
cannot be represented as documented here, then those credentials
|
||||
are omitted.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Keys in the returned dictionary not containing "." are defined
|
||||
by this specification. Bus daemon implementors supporting
|
||||
credentials frameworks not mentioned in this document should either
|
||||
contribute patches to this specification, or use keys containing
|
||||
"." and starting with a reversed domain name.
|
||||
<informaltable>
|
||||
<tgroup cols="3">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Key</entry>
|
||||
<entry>Value type</entry>
|
||||
<entry>Value</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>UnixUserID</entry>
|
||||
<entry>UINT32</entry>
|
||||
<entry>The numeric Unix user ID, as defined by POSIX</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>ProcessID</entry>
|
||||
<entry>UINT32</entry>
|
||||
<entry>The numeric process ID, on platforms that have
|
||||
this concept. On Unix, this is the process ID defined by
|
||||
POSIX.</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</informaltable>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This method was added in D-Bus 1.7 to reduce the round-trips
|
||||
required to list a process's credentials. In older versions, calling
|
||||
this method will fail: applications should recover by using the
|
||||
separate methods such as
|
||||
<xref linkend="bus-messages-get-connection-unix-user"/>
|
||||
instead.
|
||||
</para>
|
||||
</sect3>
|
||||
|
||||
<sect3 id="bus-messages-add-match">
|
||||
<title><literal>org.freedesktop.DBus.AddMatch</literal></title>
|
||||
<para>
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#else
|
||||
# include <signal.h>
|
||||
# include <unistd.h>
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -309,6 +310,131 @@ test_echo (Fixture *f,
|
|||
count, elapsed);
|
||||
}
|
||||
|
||||
static void
|
||||
pending_call_store_reply (DBusPendingCall *pc,
|
||||
void *data)
|
||||
{
|
||||
DBusMessage **message_p = data;
|
||||
|
||||
*message_p = dbus_pending_call_steal_reply (pc);
|
||||
g_assert (*message_p != NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
test_creds (Fixture *f,
|
||||
gconstpointer context)
|
||||
{
|
||||
const char *unique = dbus_bus_get_unique_name (f->left_conn);
|
||||
DBusMessage *m = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
|
||||
DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "GetConnectionCredentials");
|
||||
DBusPendingCall *pc;
|
||||
DBusMessageIter args_iter;
|
||||
DBusMessageIter arr_iter;
|
||||
DBusMessageIter pair_iter;
|
||||
DBusMessageIter var_iter;
|
||||
enum {
|
||||
SEEN_UNIX_USER = 1,
|
||||
SEEN_PID = 2,
|
||||
SEEN_WINDOWS_SID = 4
|
||||
} seen = 0;
|
||||
|
||||
if (m == NULL)
|
||||
g_error ("OOM");
|
||||
|
||||
if (!dbus_message_append_args (m,
|
||||
DBUS_TYPE_STRING, &unique,
|
||||
DBUS_TYPE_INVALID))
|
||||
g_error ("OOM");
|
||||
|
||||
if (!dbus_connection_send_with_reply (f->left_conn, m, &pc,
|
||||
DBUS_TIMEOUT_USE_DEFAULT) ||
|
||||
pc == NULL)
|
||||
g_error ("OOM");
|
||||
|
||||
dbus_message_unref (m);
|
||||
m = NULL;
|
||||
|
||||
if (dbus_pending_call_get_completed (pc))
|
||||
pending_call_store_reply (pc, &m);
|
||||
else if (!dbus_pending_call_set_notify (pc, pending_call_store_reply,
|
||||
&m, NULL))
|
||||
g_error ("OOM");
|
||||
|
||||
while (m == NULL)
|
||||
g_main_context_iteration (NULL, TRUE);
|
||||
|
||||
g_assert_cmpstr (dbus_message_get_signature (m), ==, "a{sv}");
|
||||
|
||||
dbus_message_iter_init (m, &args_iter);
|
||||
g_assert_cmpuint (dbus_message_iter_get_arg_type (&args_iter), ==,
|
||||
DBUS_TYPE_ARRAY);
|
||||
g_assert_cmpuint (dbus_message_iter_get_element_type (&args_iter), ==,
|
||||
DBUS_TYPE_DICT_ENTRY);
|
||||
dbus_message_iter_recurse (&args_iter, &arr_iter);
|
||||
|
||||
while (dbus_message_iter_get_arg_type (&arr_iter) != DBUS_TYPE_INVALID)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
dbus_message_iter_recurse (&arr_iter, &pair_iter);
|
||||
g_assert_cmpuint (dbus_message_iter_get_arg_type (&pair_iter), ==,
|
||||
DBUS_TYPE_STRING);
|
||||
dbus_message_iter_get_basic (&pair_iter, &name);
|
||||
dbus_message_iter_next (&pair_iter);
|
||||
g_assert_cmpuint (dbus_message_iter_get_arg_type (&pair_iter), ==,
|
||||
DBUS_TYPE_VARIANT);
|
||||
dbus_message_iter_recurse (&pair_iter, &var_iter);
|
||||
|
||||
if (g_strcmp0 (name, "UnixUserID") == 0)
|
||||
{
|
||||
#ifdef G_OS_UNIX
|
||||
guint32 u32;
|
||||
|
||||
g_assert (!(seen & SEEN_UNIX_USER));
|
||||
g_assert_cmpuint (dbus_message_iter_get_arg_type (&var_iter), ==,
|
||||
DBUS_TYPE_UINT32);
|
||||
dbus_message_iter_get_basic (&var_iter, &u32);
|
||||
g_message ("%s of this process is %u", name, u32);
|
||||
g_assert_cmpuint (u32, ==, geteuid ());
|
||||
seen |= SEEN_UNIX_USER;
|
||||
#else
|
||||
g_assert_not_reached ();
|
||||
#endif
|
||||
}
|
||||
else if (g_strcmp0 (name, "ProcessID") == 0)
|
||||
{
|
||||
guint32 u32;
|
||||
|
||||
g_assert (!(seen & SEEN_PID));
|
||||
g_assert_cmpuint (dbus_message_iter_get_arg_type (&var_iter), ==,
|
||||
DBUS_TYPE_UINT32);
|
||||
dbus_message_iter_get_basic (&var_iter, &u32);
|
||||
g_message ("%s of this process is %u", name, u32);
|
||||
#ifdef G_OS_UNIX
|
||||
g_assert_cmpuint (u32, ==, getpid ());
|
||||
#elif defined(G_OS_WIN32)
|
||||
g_assert_cmpuint (u32, ==, GetCurrentProcessId ());
|
||||
#else
|
||||
g_assert_not_reached ();
|
||||
#endif
|
||||
seen |= SEEN_PID;
|
||||
}
|
||||
|
||||
dbus_message_iter_next (&arr_iter);
|
||||
}
|
||||
|
||||
#ifdef G_OS_UNIX
|
||||
g_assert (seen & SEEN_UNIX_USER);
|
||||
g_assert (seen & SEEN_PID);
|
||||
#endif
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
/* FIXME: when implemented:
|
||||
g_assert (seen & SEEN_WINDOWS_SID);
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
teardown (Fixture *f,
|
||||
gconstpointer context G_GNUC_UNUSED)
|
||||
|
|
@ -363,6 +489,7 @@ main (int argc,
|
|||
g_test_add ("/echo/session", Fixture, NULL, setup, test_echo, teardown);
|
||||
g_test_add ("/echo/limited", Fixture, &limited_config,
|
||||
setup, test_echo, teardown);
|
||||
g_test_add ("/creds", Fixture, NULL, setup, test_creds, teardown);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue