mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-25 11:42:10 +01:00
Merge branch 'dbus-security-glib-2-60' into 'glib-2-60'
Backport !909 “D-Bus auth mechanism improvements” to glib-2-60 See merge request GNOME/glib!910
This commit is contained in:
commit
23a6173e4e
@ -39,11 +39,37 @@
|
|||||||
* signals you are interested in. Note that new signals may be added
|
* signals you are interested in. Note that new signals may be added
|
||||||
* in the future
|
* in the future
|
||||||
*
|
*
|
||||||
* ## Controlling Authentication # {#auth-observer}
|
* ## Controlling Authentication Mechanisms
|
||||||
*
|
*
|
||||||
* For example, if you only want to allow D-Bus connections from
|
* By default, a #GDBusServer or server-side #GDBusConnection will allow
|
||||||
* processes owned by the same uid as the server, you would use a
|
* any authentication mechanism to be used. If you only
|
||||||
* signal handler like the following:
|
* 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" -->
|
* |[<!-- language="C" -->
|
||||||
* static gboolean
|
* static gboolean
|
||||||
|
@ -1534,7 +1534,7 @@ on_authorize_authenticated_peer (GDBusAuthObserver *observer,
|
|||||||
GCredentials *credentials,
|
GCredentials *credentials,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
gboolean authorized = TRUE;
|
gboolean authorized = FALSE;
|
||||||
|
|
||||||
if (credentials != NULL)
|
if (credentials != NULL)
|
||||||
{
|
{
|
||||||
@ -1544,6 +1544,14 @@ on_authorize_authenticated_peer (GDBusAuthObserver *observer,
|
|||||||
authorized = g_credentials_is_same_user (credentials, own_credentials, NULL);
|
authorized = g_credentials_is_same_user (credentials, own_credentials, NULL);
|
||||||
g_object_unref (own_credentials);
|
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;
|
return authorized;
|
||||||
}
|
}
|
||||||
|
@ -72,6 +72,11 @@
|
|||||||
*
|
*
|
||||||
* An example of peer-to-peer communication with G-DBus can be found
|
* 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).
|
* 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
|
* Once constructed, you can use g_dbus_server_get_client_address() to
|
||||||
* get a D-Bus address string that clients can use to connect.
|
* 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
|
* Connect to the #GDBusServer::new-connection signal to handle
|
||||||
* incoming connections.
|
* incoming connections.
|
||||||
*
|
*
|
||||||
|
@ -5748,6 +5748,13 @@ g_socket_receive_message (GSocket *socket,
|
|||||||
* the %G_IO_ERROR_NOT_SUPPORTED error. On Linux this is implemented
|
* the %G_IO_ERROR_NOT_SUPPORTED error. On Linux this is implemented
|
||||||
* by reading the %SO_PEERCRED option on the underlying socket.
|
* 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
|
* Other ways to obtain credentials from a foreign peer includes the
|
||||||
* #GUnixCredentialsMessage type and
|
* #GUnixCredentialsMessage type and
|
||||||
* g_unix_connection_send_credentials() /
|
* 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
|
* byte to the stream, as this is required for credentials passing to
|
||||||
* work on some implementations.
|
* 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
|
* Other ways to exchange credentials with a foreign peer includes the
|
||||||
* #GUnixCredentialsMessage type and g_socket_get_credentials() function.
|
* #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
|
* single byte from the stream, as this is required for credentials
|
||||||
* passing to work on some implementations.
|
* 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
|
* Other ways to exchange credentials with a foreign peer includes the
|
||||||
* #GUnixCredentialsMessage type and g_socket_get_credentials() function.
|
* #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
|
int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@ -221,6 +289,7 @@ main (int argc, char *argv[])
|
|||||||
|
|
||||||
if (opt_server)
|
if (opt_server)
|
||||||
{
|
{
|
||||||
|
GDBusAuthObserver *observer;
|
||||||
GDBusServer *server;
|
GDBusServer *server;
|
||||||
gchar *guid;
|
gchar *guid;
|
||||||
GMainLoop *loop;
|
GMainLoop *loop;
|
||||||
@ -232,14 +301,20 @@ main (int argc, char *argv[])
|
|||||||
if (opt_allow_anonymous)
|
if (opt_allow_anonymous)
|
||||||
server_flags |= G_DBUS_SERVER_FLAGS_AUTHENTICATION_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;
|
error = NULL;
|
||||||
server = g_dbus_server_new_sync (opt_address,
|
server = g_dbus_server_new_sync (opt_address,
|
||||||
server_flags,
|
server_flags,
|
||||||
guid,
|
guid,
|
||||||
NULL, /* GDBusAuthObserver */
|
observer,
|
||||||
NULL, /* GCancellable */
|
NULL, /* GCancellable */
|
||||||
&error);
|
&error);
|
||||||
g_dbus_server_start (server);
|
g_dbus_server_start (server);
|
||||||
|
|
||||||
|
g_object_unref (observer);
|
||||||
g_free (guid);
|
g_free (guid);
|
||||||
|
|
||||||
if (server == NULL)
|
if (server == NULL)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user