+Overview of changes in GLib 2.60.5
+==================================
+
+* Fix implicit use of the `GKeyfileSettingsBackend` (#1822)
+
+* Fix opening a URI using the ‘Open URI’ portal (!968)
+
+* Bugs fixed:
+ - !910 Backport !909 “D-Bus auth mechanism improvements” to glib-2-60
+ - !949 Backport !945 “Avoid overrunning stack at the end of the varargs.” to glib-2-60
+ - !956 Backport !954 “Fix the ISO 15924 code for Manichaean” to glib-2-60
+ - !958 gthread: fix minor errno problem in GCond
+ - !969 Backport !968 ”Fix typo in request handle” to glib-2-60
+ - !977 Backport !974 “Ensure that the keyfile settings backend exists” to glib-2-60
+
+
Overview of changes in GLib 2.60.4
==================================
* 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
GCredentials *credentials,
gpointer user_data)
{
- gboolean authorized = TRUE;
+ gboolean authorized = FALSE;
if (credentials != NULL)
{
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;
}
*
* 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.
*/
/**
* 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.
*
/* 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
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);
* 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() /
* 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.
*
* 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.
*
/* ---------------------------------------------------------------------------------------------------- */
+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[])
{
if (opt_server)
{
+ GDBusAuthObserver *observer;
GDBusServer *server;
gchar *guid;
GMainLoop *loop;
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)
g_assert_not_reached ();
}
- type = va_arg (ap, GMarkupCollectType);
- attr = va_arg (ap, const char *);
written++;
+ type = va_arg (ap, GMarkupCollectType);
+ if (type != G_MARKUP_COLLECT_INVALID)
+ attr = va_arg (ap, const char *);
}
va_end (ap);
}
type = va_arg (ap, GMarkupCollectType);
- attr = va_arg (ap, const char *);
+ if (type != G_MARKUP_COLLECT_INVALID)
+ attr = va_arg (ap, const char *);
}
va_end (ap);
struct timespec span;
guint sampled;
int res;
+ gboolean success;
if (end_time < 0)
return FALSE;
sampled = cond->i[0];
g_mutex_unlock (mutex);
res = syscall (__NR_futex, &cond->i[0], (gsize) FUTEX_WAIT_PRIVATE, (gsize) sampled, &span);
+ success = (res < 0 && errno == ETIMEDOUT) ? FALSE : TRUE;
g_mutex_lock (mutex);
- return (res < 0 && errno == ETIMEDOUT) ? FALSE : TRUE;
+ return success;
}
#endif
G_UNICODE_SCRIPT_KHUDAWADI, /* Sind */
G_UNICODE_SCRIPT_LINEAR_A, /* Lina */
G_UNICODE_SCRIPT_MAHAJANI, /* Mahj */
- G_UNICODE_SCRIPT_MANICHAEAN, /* Manu */
+ G_UNICODE_SCRIPT_MANICHAEAN, /* Mani */
G_UNICODE_SCRIPT_MENDE_KIKAKUI, /* Mend */
G_UNICODE_SCRIPT_MODI, /* Modi */
G_UNICODE_SCRIPT_MRO, /* Mroo */
PACK ('S','i','n','d'), /* G_UNICODE_SCRIPT_KHUDAWADI */
PACK ('L','i','n','a'), /* G_UNICODE_SCRIPT_LINEAR_A */
PACK ('M','a','h','j'), /* G_UNICODE_SCRIPT_MAHAJANI */
- PACK ('M','a','n','u'), /* G_UNICODE_SCRIPT_MANICHAEAN */
+ PACK ('M','a','n','i'), /* G_UNICODE_SCRIPT_MANICHAEAN */
PACK ('M','e','n','d'), /* G_UNICODE_SCRIPT_MENDE_KIKAKUI */
PACK ('M','o','d','i'), /* G_UNICODE_SCRIPT_MODI */
PACK ('M','r','o','o'), /* G_UNICODE_SCRIPT_MRO */
{ G_UNICODE_SCRIPT_KHUDAWADI, "Sind" },
{ G_UNICODE_SCRIPT_LINEAR_A, "Lina" },
{ G_UNICODE_SCRIPT_MAHAJANI, "Mahj" },
- { G_UNICODE_SCRIPT_MANICHAEAN, "Manu" },
+ { G_UNICODE_SCRIPT_MANICHAEAN, "Mani" },
{ G_UNICODE_SCRIPT_MENDE_KIKAKUI, "Mend" },
{ G_UNICODE_SCRIPT_MODI, "Modi" },
{ G_UNICODE_SCRIPT_MRO, "Mroo" },
project('glib', 'c', 'cpp',
- version : '2.60.4',
+ version : '2.60.5',
meson_version : '>= 0.48.0',
default_options : [
'buildtype=debugoptimized',