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-worker.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-worker.c')
-rw-r--r-- | daemon/gdm-session-worker.c | 82 |
1 files changed, 80 insertions, 2 deletions
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c index aafc8880..a1e46366 100644 --- a/daemon/gdm-session-worker.c +++ b/daemon/gdm-session-worker.c @@ -188,6 +188,7 @@ static char gdm_pam_extension_environment_block[_POSIX_ARG_MAX]; static const char * const gdm_supported_pam_extensions[] = { + GDM_PAM_EXTENSION_CHOICE_LIST, NULL }; #endif @@ -536,6 +537,61 @@ gdm_session_worker_report_problem (GdmSessionWorker *worker, #ifdef SUPPORTS_PAM_EXTENSIONS static gboolean +gdm_session_worker_ask_list_of_choices (GdmSessionWorker *worker, + const char *prompt_message, + GdmChoiceList *list, + char **answerp) +{ + GVariantBuilder builder; + GVariant *choices_as_variant; + GError *error = NULL; + gboolean res; + size_t i; + + g_debug ("GdmSessionWorker: presenting user with list of choices:"); + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}")); + + for (i = 0; i < list->number_of_items; i++) { + if (list->items[i].key == NULL) { + g_warning ("choice list contains item with NULL key"); + g_variant_builder_clear (&builder); + return FALSE; + } + g_debug ("GdmSessionWorker: choices['%s'] = \"%s\"", list->items[i].key, list->items[i].text); + g_variant_builder_add (&builder, "{ss}", list->items[i].key, list->items[i].text); + } + g_debug ("GdmSessionWorker: (and waiting for reply)"); + + choices_as_variant = g_variant_builder_end (&builder); + + res = gdm_dbus_worker_manager_call_choice_list_query_sync (worker->priv->manager, + worker->priv->service, + prompt_message, + choices_as_variant, + answerp, + NULL, + &error); + + if (! res) { + g_debug ("GdmSessionWorker: list request failed: %s", error->message); + g_clear_error (&error); + } else { + g_debug ("GdmSessionWorker: user selected '%s'", *answerp); + } + + return res; +} + +static gboolean +gdm_session_worker_process_choice_list_request (GdmSessionWorker *worker, + GdmPamExtensionChoiceListRequest *request, + GdmPamExtensionChoiceListResponse *response) +{ + return gdm_session_worker_ask_list_of_choices (worker, request->prompt_message, &request->list, &response->key); +} + +static gboolean gdm_session_worker_process_extended_pam_message (GdmSessionWorker *worker, const struct pam_message *query, char **response) @@ -555,8 +611,30 @@ gdm_session_worker_process_extended_pam_message (GdmSessionWorker *work return FALSE; } - g_debug ("GdmSessionWorker: received extended pam message of unknown type %u", (unsigned int) extended_message->type); - return FALSE; + if (GDM_PAM_EXTENSION_MESSAGE_MATCH (extended_message, worker->priv->extensions, GDM_PAM_EXTENSION_CHOICE_LIST)) { + GdmPamExtensionChoiceListRequest *list_request = (GdmPamExtensionChoiceListRequest *) extended_message; + GdmPamExtensionChoiceListResponse *list_response = malloc (GDM_PAM_EXTENSION_CHOICE_LIST_RESPONSE_SIZE); + + g_debug ("GdmSessionWorker: received extended pam message '%s'", GDM_PAM_EXTENSION_CHOICE_LIST); + + GDM_PAM_EXTENSION_CHOICE_LIST_RESPONSE_INIT (list_response); + + res = gdm_session_worker_process_choice_list_request (worker, list_request, list_response); + + if (! res) { + g_free (list_response); + return FALSE; + } + + *response = GDM_PAM_EXTENSION_MESSAGE_TO_PAM_REPLY (list_response); + return TRUE; + } else { + g_debug ("GdmSessionWorker: received extended pam message of unknown type %u", (unsigned int) extended_message->type); + return FALSE; + + } + + return TRUE; } #endif |