summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2017-07-17 15:14:02 -0400
committerRay Strode <rstrode@redhat.com>2017-10-20 14:14:19 -0400
commit4e409d6626737f0e668d86dd233ed105fd2f44fa (patch)
tree00e2f69d2f48e6ab22a5635d2dddf4a0732f96ef
parentd39ed7b722761e5110e26c8e937782ecb24b7315 (diff)
downloadgdm-4e409d6626737f0e668d86dd233ed105fd2f44fa.tar.gz
libgdm: add api for getting at ChoiceList interface
This provides gnome-shell with a way to use the new interface. https://bugzilla.gnome.org/show_bug.cgi?id=788851
-rw-r--r--libgdm/gdm-client.c216
-rw-r--r--libgdm/gdm-client.h4
2 files changed, 218 insertions, 2 deletions
diff --git a/libgdm/gdm-client.c b/libgdm/gdm-client.c
index 1f428915..6fd55bd0 100644
--- a/libgdm/gdm-client.c
+++ b/libgdm/gdm-client.c
@@ -41,7 +41,10 @@
struct GdmClientPrivate
{
GdmManager *manager;
+
GdmUserVerifier *user_verifier;
+ GHashTable *user_verifier_extensions;
+
GdmGreeter *greeter;
GdmRemoteGreeter *remote_greeter;
GdmChooser *chooser;
@@ -49,6 +52,7 @@ struct GdmClientPrivate
char *address;
GList *pending_opens;
+ char **enabled_extensions;
};
static void gdm_client_class_init (GdmClientClass *klass);
@@ -143,11 +147,127 @@ get_manager (GdmClient *client,
}
static void
+complete_user_verifier_proxy_operation (GdmClient *client,
+ GSimpleAsyncResult *operation_result)
+{
+ g_simple_async_result_complete_in_idle (operation_result);
+ g_object_unref (operation_result);
+}
+
+static void
+maybe_complete_user_verifier_proxy_operation (GdmClient *client,
+ GSimpleAsyncResult *operation_result)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+
+ if (client->priv->user_verifier_extensions != NULL) {
+ g_hash_table_iter_init (&iter, client->priv->user_verifier_extensions);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ if (value == NULL)
+ return;
+ }
+ }
+
+ complete_user_verifier_proxy_operation (client, operation_result);
+}
+
+static void
+on_user_verifier_choice_list_proxy_created (GObject *source,
+ GAsyncResult *result,
+ GSimpleAsyncResult *operation_result)
+{
+ GdmClient *client;
+ GdmUserVerifierChoiceList *choice_list;
+ GError *error = NULL;
+
+ client = GDM_CLIENT (g_async_result_get_source_object (G_ASYNC_RESULT (operation_result)));
+
+ choice_list = gdm_user_verifier_choice_list_proxy_new_finish (result, &error);
+
+ if (choice_list == NULL) {
+ g_debug ("Couldn't create UserVerifier ChoiceList proxy: %s", error->message);
+ g_clear_error (&error);
+ g_hash_table_remove (client->priv->user_verifier_extensions, gdm_user_verifier_choice_list_interface_info ()->name);
+ } else {
+ g_hash_table_replace (client->priv->user_verifier_extensions, gdm_user_verifier_choice_list_interface_info ()->name, choice_list);
+ }
+
+ maybe_complete_user_verifier_proxy_operation (client, operation_result);
+}
+
+static void
+on_user_verifier_extensions_enabled (GdmUserVerifier *user_verifier,
+ GAsyncResult *result,
+ GSimpleAsyncResult *operation_result)
+{
+ GdmClient *client;
+ GCancellable *cancellable;
+ GDBusConnection *connection;
+ GError *error = NULL;
+ size_t i;
+
+ client = GDM_CLIENT (g_async_result_get_source_object (G_ASYNC_RESULT (operation_result)));
+ cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
+
+ gdm_user_verifier_call_enable_extensions_finish (user_verifier, result, &error);
+
+ if (error != NULL) {
+ g_debug ("Couldn't enable user verifier extensions: %s",
+ error->message);
+ g_clear_error (&error);
+ complete_user_verifier_proxy_operation (client, operation_result);
+ return;
+ }
+
+ connection = g_dbus_proxy_get_connection (G_DBUS_PROXY (user_verifier));
+
+ for (i = 0; client->priv->enabled_extensions[i] != NULL; i++) {
+ g_debug ("Enabled extensions[%lu] = %s", i, client->priv->enabled_extensions[i]);
+ g_hash_table_insert (client->priv->user_verifier_extensions, client->priv->enabled_extensions[i], NULL);
+
+ if (strcmp (client->priv->enabled_extensions[i],
+ gdm_user_verifier_choice_list_interface_info ()->name) == 0) {
+ g_hash_table_insert (client->priv->user_verifier_extensions, client->priv->enabled_extensions[i], NULL);
+ gdm_user_verifier_choice_list_proxy_new (connection,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ SESSION_DBUS_PATH,
+ cancellable,
+ (GAsyncReadyCallback)
+ on_user_verifier_choice_list_proxy_created,
+ operation_result);
+ } else {
+ g_debug ("User verifier extension %s is unsupported", client->priv->enabled_extensions[i]);
+ g_hash_table_remove (client->priv->user_verifier_extensions,
+ client->priv->enabled_extensions[i]);
+ }
+ }
+
+ if (g_hash_table_size (client->priv->user_verifier_extensions) == 0) {
+ g_debug ("No supported user verifier extensions");
+ complete_user_verifier_proxy_operation (client, operation_result);
+ }
+
+}
+
+static void
+free_interface_skeleton (GDBusInterfaceSkeleton *interface)
+{
+ if (interface == NULL)
+ return;
+
+ g_object_unref (interface);
+}
+
+static void
on_user_verifier_proxy_created (GObject *source,
GAsyncResult *result,
GSimpleAsyncResult *operation_result)
{
+ GdmClient *self;
GdmUserVerifier *user_verifier;
+ GCancellable *cancellable = NULL;
GError *error = NULL;
user_verifier = gdm_user_verifier_proxy_new_finish (result, &error);
@@ -164,8 +284,29 @@ on_user_verifier_proxy_created (GObject *source,
user_verifier,
(GDestroyNotify)
g_object_unref);
- g_simple_async_result_complete_in_idle (operation_result);
- g_object_unref (operation_result);
+
+ self = GDM_CLIENT (g_async_result_get_source_object (G_ASYNC_RESULT (operation_result)));
+ if (self->priv->enabled_extensions == NULL) {
+ g_debug ("no enabled extensions");
+ g_simple_async_result_complete_in_idle (operation_result);
+ g_object_unref (operation_result);
+ return;
+ }
+
+ self->priv->user_verifier_extensions = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ NULL,
+ (GDestroyNotify)
+ free_interface_skeleton);
+ cancellable = g_object_get_data (G_OBJECT (operation_result), "cancellable");
+ gdm_user_verifier_call_enable_extensions (user_verifier,
+ (const char * const *)
+ self->priv->enabled_extensions,
+ cancellable,
+ (GAsyncReadyCallback)
+ on_user_verifier_extensions_enabled,
+ operation_result);
+
}
static void
@@ -688,6 +829,39 @@ gdm_client_get_user_verifier_sync (GdmClient *client,
(GWeakNotify)
g_clear_object,
&client->priv->connection);
+
+ if (client->priv->enabled_extensions != NULL) {
+ gboolean res;
+
+ client->priv->user_verifier_extensions = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ NULL,
+ (GDestroyNotify)
+ free_interface_skeleton);
+ res = gdm_user_verifier_call_enable_extensions_sync (client->priv->user_verifier,
+ (const char * const *)
+ client->priv->enabled_extensions,
+ cancellable,
+ NULL);
+
+ if (res) {
+ size_t i;
+ for (i = 0; client->priv->enabled_extensions[i] != NULL; i++) {
+ if (strcmp (client->priv->enabled_extensions[i],
+ gdm_user_verifier_choice_list_interface_info ()->name) == 0) {
+ GdmUserVerifierChoiceList *choice_list_interface;
+ choice_list_interface = gdm_user_verifier_choice_list_proxy_new_sync (client->priv->connection,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ SESSION_DBUS_PATH,
+ cancellable,
+ NULL);
+ if (choice_list_interface != NULL)
+ g_hash_table_insert (client->priv->user_verifier_extensions, client->priv->enabled_extensions[i], choice_list_interface);
+ }
+ }
+ }
+ }
}
return client->priv->user_verifier;
@@ -815,6 +989,26 @@ gdm_client_get_user_verifier_finish (GdmClient *client,
return g_object_ref (user_verifier);
}
+/**
+ * gdm_client_get_user_verifier_choice_list:
+ * @client: a #GdmClient
+ *
+ * Gets a #GdmUserVerifierChoiceList object that can be used to
+ * verify a user's local account.
+ *
+ * Returns: (transfer none): #GdmUserVerifierChoiceList or %NULL if user
+ * verifier isn't yet fetched, or daemon doesn't support choice lists
+ */
+GdmUserVerifierChoiceList *
+gdm_client_get_user_verifier_choice_list (GdmClient *client)
+{
+ if (client->priv->user_verifier_extensions == NULL)
+ return NULL;
+
+ return g_hash_table_lookup (client->priv->user_verifier_extensions,
+ gdm_user_verifier_choice_list_interface_info ()->name);
+}
+
static void
on_timed_login_details_got (GdmGreeter *greeter,
GAsyncResult *result)
@@ -1483,6 +1677,7 @@ gdm_client_finalize (GObject *object)
g_clear_object (&client->priv->manager);
g_clear_object (&client->priv->connection);
+ g_strfreev (client->priv->enabled_extensions);
g_free (client->priv->address);
G_OBJECT_CLASS (gdm_client_parent_class)->finalize (object);
@@ -1501,3 +1696,20 @@ gdm_client_new (void)
return GDM_CLIENT (client_object);
}
+
+
+/**
+ * gdm_client_set_enabled_extensions:
+ * @client: a #GdmClient
+ * @extensions: (array zero-terminated=1) (element-type utf8): a list of extensions
+ *
+ * Enables GDM's pam extensions. Currently, only
+ * org.gnome.DisplayManager.UserVerifier.ChoiceList is supported.
+ */
+void
+gdm_client_set_enabled_extensions (GdmClient *client,
+ const char * const *extensions)
+{
+ client->priv->enabled_extensions = g_strdupv ((char **) extensions);
+
+}
diff --git a/libgdm/gdm-client.h b/libgdm/gdm-client.h
index cbe2b389..1ae3d39e 100644
--- a/libgdm/gdm-client.h
+++ b/libgdm/gdm-client.h
@@ -58,6 +58,8 @@ GType gdm_client_get_type (void);
GQuark gdm_client_error_quark (void);
GdmClient *gdm_client_new (void);
+void gdm_client_set_enabled_extensions (GdmClient *client,
+ const char * const * extensions);
void gdm_client_open_reauthentication_channel (GdmClient *client,
const char *username,
@@ -85,6 +87,8 @@ GdmUserVerifier *gdm_client_get_user_verifier_sync (GdmClient *client,
GCancellable *cancellable,
GError **error);
+GdmUserVerifierChoiceList *gdm_client_get_user_verifier_choice_list (GdmClient *client);
+
void gdm_client_get_greeter (GdmClient *client,
GCancellable *cancellable,
GAsyncReadyCallback callback,