diff options
author | Hyunjee Kim <hj0426.kim@samsung.com> | 2019-12-03 10:52:54 +0900 |
---|---|---|
committer | Hyunjee Kim <hj0426.kim@samsung.com> | 2019-12-03 10:52:54 +0900 |
commit | 2e6b92d87ed1e99f6b728de138debf83f1f08400 (patch) | |
tree | dd3c87b1cdd661dbc8e3295dc91105e11ca7a7cf /gio | |
parent | 93170c90c821cc42bad002ed8e0f2a2f9a6342b7 (diff) | |
download | glib-2e6b92d87ed1e99f6b728de138debf83f1f08400.tar.gz glib-2e6b92d87ed1e99f6b728de138debf83f1f08400.tar.bz2 glib-2e6b92d87ed1e99f6b728de138debf83f1f08400.zip |
Imported Upstream version 2.60.5
Diffstat (limited to 'gio')
-rw-r--r-- | gio/gdbusauthobserver.c | 34 | ||||
-rw-r--r-- | gio/gdbusdaemon.c | 10 | ||||
-rw-r--r-- | gio/gdbusserver.c | 9 | ||||
-rw-r--r-- | gio/giomodule.c | 1 | ||||
-rw-r--r-- | gio/gopenuriportal.c | 2 | ||||
-rw-r--r-- | gio/gsocket.c | 7 | ||||
-rw-r--r-- | gio/gunixconnection.c | 16 | ||||
-rwxr-xr-x | gio/tests/gdbus-example-peer.c | 77 |
8 files changed, 149 insertions, 7 deletions
diff --git a/gio/gdbusauthobserver.c b/gio/gdbusauthobserver.c index 34758aa20..4590ffcae 100644 --- a/gio/gdbusauthobserver.c +++ b/gio/gdbusauthobserver.c @@ -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 diff --git a/gio/gdbusdaemon.c b/gio/gdbusdaemon.c index e6b3c1af0..d893b930a 100644 --- a/gio/gdbusdaemon.c +++ b/gio/gdbusdaemon.c @@ -1534,7 +1534,7 @@ on_authorize_authenticated_peer (GDBusAuthObserver *observer, GCredentials *credentials, gpointer user_data) { - gboolean authorized = TRUE; + gboolean authorized = FALSE; if (credentials != NULL) { @@ -1544,6 +1544,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; } diff --git a/gio/gdbusserver.c b/gio/gdbusserver.c index 07757f40f..eb641a9bc 100644 --- a/gio/gdbusserver.c +++ b/gio/gdbusserver.c @@ -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. * diff --git a/gio/giomodule.c b/gio/giomodule.c index b92162dcc..b97e3a26b 100644 --- a/gio/giomodule.c +++ b/gio/giomodule.c @@ -1209,6 +1209,7 @@ _g_io_modules_ensure_loaded (void) /* Initialize types from built-in "modules" */ g_type_ensure (g_null_settings_backend_get_type ()); g_type_ensure (g_memory_settings_backend_get_type ()); + g_type_ensure (g_keyfile_settings_backend_get_type ()); #if defined(HAVE_INOTIFY_INIT1) g_type_ensure (g_inotify_file_monitor_get_type ()); #endif diff --git a/gio/gopenuriportal.c b/gio/gopenuriportal.c index b798d7cd1..be68569ed 100644 --- a/gio/gopenuriportal.c +++ b/gio/gopenuriportal.c @@ -279,7 +279,7 @@ g_openuri_portal_open_uri_async (const char *uri, if (sender[i] == '.') sender[i] = '_'; - handle = g_strdup_printf ("/org/fredesktop/portal/desktop/request/%s/%s", sender, token); + handle = g_strdup_printf ("/org/freedesktop/portal/desktop/request/%s/%s", sender, token); g_object_set_data_full (G_OBJECT (task), "handle", handle, g_free); g_free (sender); diff --git a/gio/gsocket.c b/gio/gsocket.c index d4372c544..fe869f5fb 100644 --- a/gio/gsocket.c +++ b/gio/gsocket.c @@ -5748,6 +5748,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() / diff --git a/gio/gunixconnection.c b/gio/gunixconnection.c index c85ac3650..e9e2f75f0 100644 --- a/gio/gunixconnection.c +++ b/gio/gunixconnection.c @@ -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. * diff --git a/gio/tests/gdbus-example-peer.c b/gio/tests/gdbus-example-peer.c index bf151cfcf..9d5de32a6 100755 --- a/gio/tests/gdbus-example-peer.c +++ b/gio/tests/gdbus-example-peer.c @@ -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) |