mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-27 07:56:14 +01:00
Merge branch 'dbus-security-master' into 'master'
D-Bus auth mechanism improvements See merge request GNOME/glib!909
This commit is contained in:
commit
155d4c66c7
@ -39,11 +39,37 @@
|
||||
* signals you are interested in. Note that new signals may be added
|
||||
* in the future
|
||||
*
|
||||
* ## Controlling Authentication # {#auth-observer}
|
||||
* ## Controlling Authentication Mechanisms
|
||||
*
|
||||
* For example, if you only want to allow D-Bus connections from
|
||||
* processes owned by the same uid as the server, you would use a
|
||||
* signal handler like the following:
|
||||
* By default, a #GDBusServer or server-side #GDBusConnection will allow
|
||||
* any authentication mechanism to be used. If you only
|
||||
* want to allow D-Bus connections with the `EXTERNAL` mechanism,
|
||||
* which makes use of credentials passing and is the recommended
|
||||
* mechanism for modern Unix platforms such as Linux and the BSD family,
|
||||
* you would use a signal handler like this:
|
||||
*
|
||||
* |[<!-- language="C" -->
|
||||
* static gboolean
|
||||
* on_allow_mechanism (GDBusAuthObserver *observer,
|
||||
* const gchar *mechanism,
|
||||
* gpointer user_data)
|
||||
* {
|
||||
* if (g_strcmp0 (mechanism, "EXTERNAL") == 0)
|
||||
* {
|
||||
* return TRUE;
|
||||
* }
|
||||
*
|
||||
* return FALSE;
|
||||
* }
|
||||
* ]|
|
||||
*
|
||||
* ## Controlling Authorization # {#auth-observer}
|
||||
*
|
||||
* By default, a #GDBusServer or server-side #GDBusConnection will accept
|
||||
* connections from any successfully authenticated user (but not from
|
||||
* anonymous connections using the `ANONYMOUS` mechanism). If you only
|
||||
* want to allow D-Bus connections from processes owned by the same uid
|
||||
* as the server, you would use a signal handler like the following:
|
||||
*
|
||||
* |[<!-- language="C" -->
|
||||
* static gboolean
|
||||
|
@ -1539,7 +1539,7 @@ on_authorize_authenticated_peer (GDBusAuthObserver *observer,
|
||||
GCredentials *credentials,
|
||||
gpointer user_data)
|
||||
{
|
||||
gboolean authorized = TRUE;
|
||||
gboolean authorized = FALSE;
|
||||
|
||||
if (credentials != NULL)
|
||||
{
|
||||
@ -1549,6 +1549,14 @@ on_authorize_authenticated_peer (GDBusAuthObserver *observer,
|
||||
authorized = g_credentials_is_same_user (credentials, own_credentials, NULL);
|
||||
g_object_unref (own_credentials);
|
||||
}
|
||||
#ifdef G_OS_WIN32
|
||||
else
|
||||
{
|
||||
/* We allow ANONYMOUS authentication on Windows for now, in
|
||||
* combination with the nonce-tcp transport. */
|
||||
authorized = TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
return authorized;
|
||||
}
|
||||
|
@ -72,6 +72,11 @@
|
||||
*
|
||||
* An example of peer-to-peer communication with G-DBus can be found
|
||||
* in [gdbus-example-peer.c](https://git.gnome.org/browse/glib/tree/gio/tests/gdbus-example-peer.c).
|
||||
*
|
||||
* Note that a minimal #GDBusServer will accept connections from any
|
||||
* peer. In many use-cases it will be necessary to add a #GDBusAuthObserver
|
||||
* that only accepts connections that have successfully authenticated
|
||||
* as the same user that is running the #GDBusServer.
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -457,6 +462,10 @@ on_run (GSocketService *service,
|
||||
* Once constructed, you can use g_dbus_server_get_client_address() to
|
||||
* get a D-Bus address string that clients can use to connect.
|
||||
*
|
||||
* To have control over the available authentication mechanisms and
|
||||
* the users that are authorized to connect, it is strongly recommended
|
||||
* to provide a non-%NULL #GDBusAuthObserver.
|
||||
*
|
||||
* Connect to the #GDBusServer::new-connection signal to handle
|
||||
* incoming connections.
|
||||
*
|
||||
|
@ -5750,6 +5750,13 @@ g_socket_receive_message (GSocket *socket,
|
||||
* the %G_IO_ERROR_NOT_SUPPORTED error. On Linux this is implemented
|
||||
* by reading the %SO_PEERCRED option on the underlying socket.
|
||||
*
|
||||
* This method can be expected to be available on the following platforms:
|
||||
*
|
||||
* - Linux since GLib 2.26
|
||||
* - OpenBSD since GLib 2.30
|
||||
* - Solaris, Illumos and OpenSolaris since GLib 2.40
|
||||
* - NetBSD since GLib 2.42
|
||||
*
|
||||
* Other ways to obtain credentials from a foreign peer includes the
|
||||
* #GUnixCredentialsMessage type and
|
||||
* g_unix_connection_send_credentials() /
|
||||
|
@ -300,6 +300,14 @@ gboolean g_unix_connection_create_pair (GUnixCo
|
||||
* byte to the stream, as this is required for credentials passing to
|
||||
* work on some implementations.
|
||||
*
|
||||
* This method can be expected to be available on the following platforms:
|
||||
*
|
||||
* - Linux since GLib 2.26
|
||||
* - FreeBSD since GLib 2.26
|
||||
* - GNU/kFreeBSD since GLib 2.36
|
||||
* - Solaris, Illumos and OpenSolaris since GLib 2.40
|
||||
* - GNU/Hurd since GLib 2.40
|
||||
*
|
||||
* Other ways to exchange credentials with a foreign peer includes the
|
||||
* #GUnixCredentialsMessage type and g_socket_get_credentials() function.
|
||||
*
|
||||
@ -450,6 +458,14 @@ g_unix_connection_send_credentials_finish (GUnixConnection *connection,
|
||||
* single byte from the stream, as this is required for credentials
|
||||
* passing to work on some implementations.
|
||||
*
|
||||
* This method can be expected to be available on the following platforms:
|
||||
*
|
||||
* - Linux since GLib 2.26
|
||||
* - FreeBSD since GLib 2.26
|
||||
* - GNU/kFreeBSD since GLib 2.36
|
||||
* - Solaris, Illumos and OpenSolaris since GLib 2.40
|
||||
* - GNU/Hurd since GLib 2.40
|
||||
*
|
||||
* Other ways to exchange credentials with a foreign peer includes the
|
||||
* #GUnixCredentialsMessage type and g_socket_get_credentials() function.
|
||||
*
|
||||
|
@ -169,6 +169,74 @@ on_new_connection (GDBusServer *server,
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------------- */
|
||||
|
||||
static gboolean
|
||||
allow_mechanism_cb (GDBusAuthObserver *observer,
|
||||
const gchar *mechanism,
|
||||
G_GNUC_UNUSED gpointer user_data)
|
||||
{
|
||||
/*
|
||||
* In a production GDBusServer that only needs to work on modern Unix
|
||||
* platforms, consider requiring EXTERNAL (credentials-passing),
|
||||
* which is the recommended authentication mechanism for AF_UNIX
|
||||
* sockets:
|
||||
*
|
||||
* if (g_strcmp0 (mechanism, "EXTERNAL") == 0)
|
||||
* return TRUE;
|
||||
*
|
||||
* return FALSE;
|
||||
*
|
||||
* For this example we accept everything.
|
||||
*/
|
||||
|
||||
g_print ("Considering whether to accept %s authentication...\n", mechanism);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
authorize_authenticated_peer_cb (GDBusAuthObserver *observer,
|
||||
G_GNUC_UNUSED GIOStream *stream,
|
||||
GCredentials *credentials,
|
||||
G_GNUC_UNUSED gpointer user_data)
|
||||
{
|
||||
gboolean authorized = FALSE;
|
||||
|
||||
g_print ("Considering whether to authorize authenticated peer...\n");
|
||||
|
||||
if (credentials != NULL)
|
||||
{
|
||||
GCredentials *own_credentials;
|
||||
gchar *credentials_string = NULL;
|
||||
|
||||
credentials_string = g_credentials_to_string (credentials);
|
||||
g_print ("Peer's credentials: %s\n", credentials_string);
|
||||
g_free (credentials_string);
|
||||
|
||||
own_credentials = g_credentials_new ();
|
||||
|
||||
credentials_string = g_credentials_to_string (own_credentials);
|
||||
g_print ("Server's credentials: %s\n", credentials_string);
|
||||
g_free (credentials_string);
|
||||
|
||||
if (g_credentials_is_same_user (credentials, own_credentials, NULL))
|
||||
authorized = TRUE;
|
||||
|
||||
g_object_unref (own_credentials);
|
||||
}
|
||||
|
||||
if (!authorized)
|
||||
{
|
||||
/* In most servers you'd want to reject this, but for this example
|
||||
* we allow it. */
|
||||
g_print ("A server would often not want to authorize this identity\n");
|
||||
g_print ("Authorizing it anyway for demonstration purposes\n");
|
||||
authorized = TRUE;
|
||||
}
|
||||
|
||||
return authorized;
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------------------------------------- */
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
@ -221,6 +289,7 @@ main (int argc, char *argv[])
|
||||
|
||||
if (opt_server)
|
||||
{
|
||||
GDBusAuthObserver *observer;
|
||||
GDBusServer *server;
|
||||
gchar *guid;
|
||||
GMainLoop *loop;
|
||||
@ -232,14 +301,20 @@ main (int argc, char *argv[])
|
||||
if (opt_allow_anonymous)
|
||||
server_flags |= G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS;
|
||||
|
||||
observer = g_dbus_auth_observer_new ();
|
||||
g_signal_connect (observer, "allow-mechanism", G_CALLBACK (allow_mechanism_cb), NULL);
|
||||
g_signal_connect (observer, "authorize-authenticated-peer", G_CALLBACK (authorize_authenticated_peer_cb), NULL);
|
||||
|
||||
error = NULL;
|
||||
server = g_dbus_server_new_sync (opt_address,
|
||||
server_flags,
|
||||
guid,
|
||||
NULL, /* GDBusAuthObserver */
|
||||
observer,
|
||||
NULL, /* GCancellable */
|
||||
&error);
|
||||
g_dbus_server_start (server);
|
||||
|
||||
g_object_unref (observer);
|
||||
g_free (guid);
|
||||
|
||||
if (server == NULL)
|
||||
|
Loading…
Reference in New Issue
Block a user