[glib] GDBusAuthObserver: Add a way to control what authentication mechanisms to use



commit ce81bd87c5fdd54126ceb81c17fea7c914833c3e
Author: David Zeuthen <davidz redhat com>
Date:   Wed Apr 11 23:30:48 2012 -0400

    GDBusAuthObserver: Add a way to control what authentication mechanisms to use
    
    This is related to https://bugzilla.gnome.org/show_bug.cgi?id=673943
    but also useful in a lot of other contexts.

 docs/reference/gio/gio-sections.txt |    1 +
 gio/gdbusauth.c                     |   40 ++++++++++++++++-------
 gio/gdbusauth.h                     |    1 +
 gio/gdbusauthobserver.c             |   62 +++++++++++++++++++++++++++++++++++
 gio/gdbusauthobserver.h             |    3 ++
 gio/gdbusconnection.c               |    1 +
 gio/gio.symbols                     |    1 +
 7 files changed, 97 insertions(+), 12 deletions(-)
---
diff --git a/docs/reference/gio/gio-sections.txt b/docs/reference/gio/gio-sections.txt
index 5d08b46..eee39bb 100644
--- a/docs/reference/gio/gio-sections.txt
+++ b/docs/reference/gio/gio-sections.txt
@@ -2493,6 +2493,7 @@ g_dbus_gvariant_to_gvalue
 GDBusAuthObserver
 g_dbus_auth_observer_new
 g_dbus_auth_observer_authorize_authenticated_peer
+g_dbus_auth_observer_allow_mechanism
 <SUBSECTION Standard>
 G_DBUS_AUTH_OBSERVER
 G_IS_DBUS_AUTH_OBSERVER
diff --git a/gio/gdbusauth.c b/gio/gdbusauth.c
index 768635b..8d4723c 100644
--- a/gio/gdbusauth.c
+++ b/gio/gdbusauth.c
@@ -194,17 +194,22 @@ mechanism_free (Mechanism *m)
 }
 
 static void
-add_mechanism (GDBusAuth *auth,
-               GType      mechanism_type)
+add_mechanism (GDBusAuth         *auth,
+               GDBusAuthObserver *observer,
+               GType              mechanism_type)
 {
-  Mechanism *m;
-
-  m = g_new0 (Mechanism, 1);
-  m->name = _g_dbus_auth_mechanism_get_name (mechanism_type);
-  m->priority = _g_dbus_auth_mechanism_get_priority (mechanism_type);
-  m->gtype = mechanism_type;
+  const gchar *name;
 
-  auth->priv->available_mechanisms = g_list_prepend (auth->priv->available_mechanisms, m);
+  name = _g_dbus_auth_mechanism_get_name (mechanism_type);
+  if (g_dbus_auth_observer_allow_mechanism (observer, name))
+    {
+      Mechanism *m;
+      m = g_new0 (Mechanism, 1);
+      m->name = name;
+      m->priority = _g_dbus_auth_mechanism_get_priority (mechanism_type);
+      m->gtype = mechanism_type;
+      auth->priv->available_mechanisms = g_list_prepend (auth->priv->available_mechanisms, m);
+    }
 }
 
 static gint
@@ -223,10 +228,16 @@ _g_dbus_auth_init (GDBusAuth *auth)
 {
   auth->priv = G_TYPE_INSTANCE_GET_PRIVATE (auth, G_TYPE_DBUS_AUTH, GDBusAuthPrivate);
 
+}
+
+static void
+_g_dbus_auth_add_mechs (GDBusAuth         *auth,
+                        GDBusAuthObserver *observer)
+{
   /* TODO: trawl extension points */
-  add_mechanism (auth, G_TYPE_DBUS_AUTH_MECHANISM_ANON);
-  add_mechanism (auth, G_TYPE_DBUS_AUTH_MECHANISM_SHA1);
-  add_mechanism (auth, G_TYPE_DBUS_AUTH_MECHANISM_EXTERNAL);
+  add_mechanism (auth, observer, G_TYPE_DBUS_AUTH_MECHANISM_ANON);
+  add_mechanism (auth, observer, G_TYPE_DBUS_AUTH_MECHANISM_SHA1);
+  add_mechanism (auth, observer, G_TYPE_DBUS_AUTH_MECHANISM_EXTERNAL);
 
   auth->priv->available_mechanisms = g_list_sort (auth->priv->available_mechanisms,
                                                   (GCompareFunc) mech_compare_func);
@@ -576,6 +587,7 @@ typedef enum
 
 gchar *
 _g_dbus_auth_run_client (GDBusAuth     *auth,
+                         GDBusAuthObserver     *observer,
                          GDBusCapabilityFlags offered_capabilities,
                          GDBusCapabilityFlags *out_negotiated_capabilities,
                          GCancellable  *cancellable,
@@ -596,6 +608,8 @@ _g_dbus_auth_run_client (GDBusAuth     *auth,
 
   debug_print ("CLIENT: initiating");
 
+  _g_dbus_auth_add_mechs (auth, observer);
+
   ret_guid = NULL;
   supported_auth_mechs = NULL;
   attempted_auth_mechs = g_ptr_array_new ();
@@ -962,6 +976,8 @@ _g_dbus_auth_run_server (GDBusAuth              *auth,
 
   debug_print ("SERVER: initiating");
 
+  _g_dbus_auth_add_mechs (auth, observer);
+
   ret = FALSE;
   dis = NULL;
   dos = NULL;
diff --git a/gio/gdbusauth.h b/gio/gdbusauth.h
index 0395659..1ee3ec4 100644
--- a/gio/gdbusauth.h
+++ b/gio/gdbusauth.h
@@ -76,6 +76,7 @@ gboolean    _g_dbus_auth_run_server (GDBusAuth             *auth,
                                      GError               **error);
 
 gchar      *_g_dbus_auth_run_client (GDBusAuth     *auth,
+                                     GDBusAuthObserver     *observer,
                                      GDBusCapabilityFlags offered_capabilities,
                                      GDBusCapabilityFlags *out_negotiated_capabilities,
                                      GCancellable  *cancellable,
diff --git a/gio/gdbusauthobserver.c b/gio/gdbusauthobserver.c
index a55e13d..0140c52 100644
--- a/gio/gdbusauthobserver.c
+++ b/gio/gdbusauthobserver.c
@@ -89,6 +89,9 @@ struct _GDBusAuthObserverClass
   gboolean (*authorize_authenticated_peer) (GDBusAuthObserver  *observer,
                                             GIOStream          *stream,
                                             GCredentials       *credentials);
+
+  gboolean (*allow_mechanism) (GDBusAuthObserver  *observer,
+                               const gchar        *mechanism);
 };
 
 /**
@@ -107,6 +110,7 @@ struct _GDBusAuthObserver
 enum
 {
   AUTHORIZE_AUTHENTICATED_PEER_SIGNAL,
+  ALLOW_MECHANISM_SIGNAL,
   LAST_SIGNAL,
 };
 
@@ -130,6 +134,13 @@ g_dbus_auth_observer_authorize_authenticated_peer_real (GDBusAuthObserver  *obse
   return TRUE;
 }
 
+static gboolean
+g_dbus_auth_observer_allow_mechanism_real (GDBusAuthObserver  *observer,
+                                           const gchar        *mechanism)
+{
+  return TRUE;
+}
+
 static void
 g_dbus_auth_observer_class_init (GDBusAuthObserverClass *klass)
 {
@@ -138,6 +149,7 @@ g_dbus_auth_observer_class_init (GDBusAuthObserverClass *klass)
   gobject_class->finalize = g_dbus_auth_observer_finalize;
 
   klass->authorize_authenticated_peer = g_dbus_auth_observer_authorize_authenticated_peer_real;
+  klass->allow_mechanism = g_dbus_auth_observer_allow_mechanism_real;
 
   /**
    * GDBusAuthObserver::authorize-authenticated-peer:
@@ -164,6 +176,29 @@ g_dbus_auth_observer_class_init (GDBusAuthObserverClass *klass)
                   2,
                   G_TYPE_IO_STREAM,
                   G_TYPE_CREDENTIALS);
+
+  /**
+   * GDBusAuthObserver::allow-mechanism:
+   * @observer: The #GDBusAuthObserver emitting the signal.
+   * @mechanism: The name of the mechanism, e.g. <literal>DBUS_COOKIE_SHA1</literal>.
+   *
+   * Emitted to check if @mechanism is allowed to be used.
+   *
+   * Returns: %TRUE if @mechanism can be used to authenticate the other peer, %FALSE if not.
+   *
+   * Since: 2.34
+   */
+  signals[ALLOW_MECHANISM_SIGNAL] =
+    g_signal_new ("allow-mechanism",
+                  G_TYPE_DBUS_AUTH_OBSERVER,
+                  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (GDBusAuthObserverClass, allow_mechanism),
+                  _g_signal_accumulator_false_handled,
+                  NULL, /* accu_data */
+                  NULL,
+                  G_TYPE_BOOLEAN,
+                  1,
+                  G_TYPE_STRING);
 }
 
 static void
@@ -216,3 +251,30 @@ g_dbus_auth_observer_authorize_authenticated_peer (GDBusAuthObserver  *observer,
                  &denied);
   return denied;
 }
+
+/**
+ * g_dbus_auth_observer_allow_mechanism:
+ * @observer: A #GDBusAuthObserver.
+ * @mechanism: The name of the mechanism, e.g. <literal>DBUS_COOKIE_SHA1</literal>.
+ *
+ * Emits the #GDBusAuthObserver::allow-mechanism signal on @observer.
+ *
+ * Returns: %TRUE if @mechanism can be used to authenticate the other peer, %FALSE if not.
+ *
+ * Since: 2.34
+ */
+gboolean
+g_dbus_auth_observer_allow_mechanism (GDBusAuthObserver  *observer,
+                                      const gchar        *mechanism)
+{
+  gboolean ret;
+
+  ret = FALSE;
+  g_signal_emit (observer,
+                 signals[ALLOW_MECHANISM_SIGNAL],
+                 0,
+                 mechanism,
+                 &ret);
+  return ret;
+}
+
diff --git a/gio/gdbusauthobserver.h b/gio/gdbusauthobserver.h
index fb709cd..5bb1dac 100644
--- a/gio/gdbusauthobserver.h
+++ b/gio/gdbusauthobserver.h
@@ -41,6 +41,9 @@ gboolean           g_dbus_auth_observer_authorize_authenticated_peer (GDBusAuthO
                                                                       GIOStream          *stream,
                                                                       GCredentials       *credentials);
 
+gboolean           g_dbus_auth_observer_allow_mechanism (GDBusAuthObserver  *observer,
+                                                         const gchar        *mechanism);
+
 G_END_DECLS
 
 #endif /* _G_DBUS_AUTH_OBSERVER_H__ */
diff --git a/gio/gdbusconnection.c b/gio/gdbusconnection.c
index 2a1f090..8bf0dc3 100644
--- a/gio/gdbusconnection.c
+++ b/gio/gdbusconnection.c
@@ -2553,6 +2553,7 @@ initable_init (GInitable     *initable,
       g_assert (connection->guid == NULL);
       connection->auth = _g_dbus_auth_new (connection->stream);
       connection->guid = _g_dbus_auth_run_client (connection->auth,
+                                                  connection->authentication_observer,
                                                   get_offered_capabilities_max (connection),
                                                   &connection->capabilities,
                                                   cancellable,
diff --git a/gio/gio.symbols b/gio/gio.symbols
index d632d49..96b6875 100644
--- a/gio/gio.symbols
+++ b/gio/gio.symbols
@@ -1203,6 +1203,7 @@ g_dbus_address_get_stream_sync
 g_dbus_auth_observer_get_type
 g_dbus_auth_observer_new
 g_dbus_auth_observer_authorize_authenticated_peer
+g_dbus_auth_observer_allow_mechanism
 g_dbus_connection_get_type
 g_bus_get
 g_bus_get_finish



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