[glib/glib-2-60: 5/7] gdbus-example-peer: Provide an example GDBusAuthObserver



commit d2ae55fafad634ad577b25a03d5aaa8d7881a919
Author: Simon McVittie <smcv collabora com>
Date:   Wed Jun 5 13:53:25 2019 +0100

    gdbus-example-peer: Provide an example GDBusAuthObserver
    
    It's somewhat unrealistic to use a GDBusServer without a
    GDBusAuthObserver, because most D-Bus servers want to be like the
    standard session bus (the owning user can connect) rather than being
    like the standard system bus (all users can connect, the server is a
    security boundary, and many bugs are security vulnerabilities).
    
    Signed-off-by: Simon McVittie <smcv collabora com>

 gio/tests/gdbus-example-peer.c | 77 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 76 insertions(+), 1 deletion(-)
---
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)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]