diff options
author | Ray Strode <rstrode@redhat.com> | 2017-07-26 13:28:50 -0400 |
---|---|---|
committer | Ray Strode <rstrode@redhat.com> | 2017-10-20 14:14:17 -0400 |
commit | d39ed7b722761e5110e26c8e937782ecb24b7315 (patch) | |
tree | 3fe23217bbe7f8af8c83535bb8866e0397ef52c9 /daemon/gdm-session.c | |
parent | d5280a38761a558c32c32e1e277ebd26f63af5c7 (diff) | |
download | gdm-d39ed7b722761e5110e26c8e937782ecb24b7315.tar.gz |
daemon: add ChoiceList PAM extension
This commit adds one PAM extension, a "Choice List" using the
new PAM_BINARY_PROMPT protocol added in the previous commit. The
PAM module sends a list of (key, row text) pairs, and GDM ferries
the request to gnome-shell using a new user verifier sub-interface.
gnome-shell should present the list to the user and pass back the
corresponding key, which GDM ferries back to the PAM module.
Note this commit is only the daemon side. A subsequent commit will
add the libgdm API needed for gnome-shell to actually deal with
this new PAM extension.
https://bugzilla.gnome.org/show_bug.cgi?id=788851
Diffstat (limited to 'daemon/gdm-session.c')
-rw-r--r-- | daemon/gdm-session.c | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c index aa437e56..19d26c92 100644 --- a/daemon/gdm-session.c +++ b/daemon/gdm-session.c @@ -681,6 +681,44 @@ set_pending_query (GdmSessionConversation *conversation, } static gboolean +gdm_session_handle_choice_list_query (GdmDBusWorkerManager *worker_manager_interface, + GDBusMethodInvocation *invocation, + const char *service_name, + const char *prompt_message, + GVariant *query, + GdmSession *self) +{ + GdmSessionConversation *conversation; + GdmDBusUserVerifierChoiceList *choice_list_interface = NULL; + + g_debug ("GdmSession: choice query for service '%s'", service_name); + + if (self->priv->user_verifier_extensions != NULL) + choice_list_interface = g_hash_table_lookup (self->priv->user_verifier_extensions, + gdm_dbus_user_verifier_choice_list_interface_info ()->name); + + if (choice_list_interface == NULL) { + g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, + G_DBUS_ERROR_NOT_SUPPORTED, + "ChoiceList interface not supported by client"); + return TRUE; + } + + conversation = find_conversation_by_name (self, service_name); + if (conversation != NULL) { + set_pending_query (conversation, invocation); + + g_debug ("GdmSession: emitting choice query '%s'", prompt_message); + gdm_dbus_user_verifier_choice_list_emit_choice_query (choice_list_interface, + service_name, + prompt_message, + query); + } + + return TRUE; +} + +static gboolean gdm_session_handle_info_query (GdmDBusWorkerManager *worker_manager_interface, GDBusMethodInvocation *invocation, const char *service_name, @@ -1137,6 +1175,10 @@ export_worker_manager_interface (GdmSession *self, "handle-problem", G_CALLBACK (gdm_session_handle_problem), self); + g_signal_connect (worker_manager_interface, + "handle-choice-list-query", + G_CALLBACK (gdm_session_handle_choice_list_query), + self); g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (worker_manager_interface), connection, @@ -1166,6 +1208,9 @@ unexport_worker_manager_interface (GdmSession *self, g_signal_handlers_disconnect_by_func (worker_manager_interface, G_CALLBACK (gdm_session_handle_problem), self); + g_signal_handlers_disconnect_by_func (worker_manager_interface, + G_CALLBACK (gdm_session_handle_choice_list_query), + self); } static gboolean @@ -1220,15 +1265,62 @@ begin_verification_conversation (GdmSession *self, } static gboolean +gdm_session_handle_client_select_choice (GdmDBusUserVerifierChoiceList *choice_list_interface, + GDBusMethodInvocation *invocation, + const char *service_name, + const char *answer, + GdmSession *self) +{ + g_debug ("GdmSession: user selected choice '%s'", answer); + gdm_dbus_user_verifier_choice_list_complete_select_choice (choice_list_interface, invocation); + gdm_session_answer_query (self, service_name, answer); + return TRUE; +} + +static void +export_user_verifier_choice_list_interface (GdmSession *self, + GDBusConnection *connection) +{ + GdmDBusUserVerifierChoiceList *interface; + + interface = GDM_DBUS_USER_VERIFIER_CHOICE_LIST (gdm_dbus_user_verifier_choice_list_skeleton_new ()); + + g_signal_connect (interface, + "handle-select-choice", + G_CALLBACK (gdm_session_handle_client_select_choice), + self); + + g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (interface), + connection, + GDM_SESSION_DBUS_OBJECT_PATH, + NULL); + + g_hash_table_insert (self->priv->user_verifier_extensions, + gdm_dbus_user_verifier_choice_list_interface_info ()->name, + interface); +} + +static gboolean gdm_session_handle_client_enable_extensions (GdmDBusUserVerifier *user_verifier_interface, GDBusMethodInvocation *invocation, const char * const * extensions, GDBusConnection *connection) { GdmSession *self = g_object_get_data (G_OBJECT (connection), "gdm-session"); + size_t i; g_hash_table_remove_all (self->priv->user_verifier_extensions); + for (i = 0; extensions[i] != NULL; i++) { + if (g_hash_table_lookup (self->priv->user_verifier_extensions, extensions[i]) != NULL) + continue; + + if (strcmp (extensions[i], + gdm_dbus_user_verifier_choice_list_interface_info ()->name) == 0) + export_user_verifier_choice_list_interface (self, connection); + + } + gdm_dbus_user_verifier_complete_enable_extensions (user_verifier_interface, invocation); return TRUE; |