diff options
author | Ray Strode <rstrode@redhat.com> | 2017-07-14 16:05:46 -0400 |
---|---|---|
committer | Ray Strode <rstrode@redhat.com> | 2017-10-20 14:14:16 -0400 |
commit | d5280a38761a558c32c32e1e277ebd26f63af5c7 (patch) | |
tree | 626b7cdf75ac50a4b787bf85f8a897c34e6f414a /daemon/gdm-session.c | |
parent | 5683e5d5a6bc37c7a1b52a633cc79c70b60defb3 (diff) | |
download | gdm-d5280a38761a558c32c32e1e277ebd26f63af5c7.tar.gz |
daemon: introduce pam extension mechanism
This abuses PAM_BINARY_PROMPT for our own nefarious purposes.
The way it works is GDM advertises what "extensions" it supports
with the environment variable, GDM_SUPPORTED_PAM_EXTENSIONS (a space
separated list of reverse dns notation names). PAM services that
support this protocol, will read the environment variable, and
check for extension strings they support. They then know that sending
PAM_BINARY_PROMPT won't blow up, and know what format to use for the
binary data. The type field of the structure is the index of the
string from the environment variable.
This commit is just foundation work. It doesn't actually add any
extensions.
https://bugzilla.gnome.org/show_bug.cgi?id=788851
Diffstat (limited to 'daemon/gdm-session.c')
-rw-r--r-- | daemon/gdm-session.c | 49 |
1 files changed, 47 insertions, 2 deletions
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c index 812c7be0..aa437e56 100644 --- a/daemon/gdm-session.c +++ b/daemon/gdm-session.c @@ -101,6 +101,7 @@ struct _GdmSessionPrivate char **conversation_environment; GdmDBusUserVerifier *user_verifier_interface; + GHashTable *user_verifier_extensions; GdmDBusGreeter *greeter_interface; GdmDBusRemoteGreeter *remote_greeter_interface; GdmDBusChooser *chooser_interface; @@ -1219,6 +1220,20 @@ begin_verification_conversation (GdmSession *self, } 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"); + + g_hash_table_remove_all (self->priv->user_verifier_extensions); + + gdm_dbus_user_verifier_complete_enable_extensions (user_verifier_interface, invocation); + + return TRUE; +} +static gboolean gdm_session_handle_client_begin_verification (GdmDBusUserVerifier *user_verifier_interface, GDBusMethodInvocation *invocation, const char *service_name, @@ -1372,6 +1387,13 @@ export_user_verifier_interface (GdmSession *self, { GdmDBusUserVerifier *user_verifier_interface; user_verifier_interface = GDM_DBUS_USER_VERIFIER (gdm_dbus_user_verifier_skeleton_new ()); + + g_object_set_data (G_OBJECT (connection), "gdm-session", self); + + g_signal_connect (user_verifier_interface, + "handle-enable-extensions", + G_CALLBACK (gdm_session_handle_client_enable_extensions), + connection); g_signal_connect (user_verifier_interface, "handle-begin-verification", G_CALLBACK (gdm_session_handle_client_begin_verification), @@ -1811,6 +1833,15 @@ next_line: } static void +unexport_and_free_user_verifier_extension (GDBusInterfaceSkeleton *interface) +{ + g_dbus_interface_skeleton_unexport (interface); + + g_object_run_dispose (G_OBJECT (interface)); + g_object_unref (interface); +} + +static void gdm_session_init (GdmSession *self) { self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, @@ -1826,6 +1857,11 @@ gdm_session_init (GdmSession *self) g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) g_free); + self->priv->user_verifier_extensions = g_hash_table_new_full (g_str_hash, + g_str_equal, + NULL, + (GDestroyNotify) + unexport_and_free_user_verifier_extension); load_lang_config_file (self); setup_worker_server (self); @@ -2099,14 +2135,19 @@ initialize (GdmSession *self, const char *username, const char *log_file) { - GVariantBuilder details; - GdmSessionConversation *conversation; + GVariantBuilder details; + const char **extensions; + GdmSessionConversation *conversation; g_assert (service_name != NULL); g_variant_builder_init (&details, G_VARIANT_TYPE ("a{sv}")); g_variant_builder_add_parsed (&details, "{'service', <%s>}", service_name); + extensions = (const char **) g_hash_table_get_keys_as_array (self->priv->user_verifier_extensions, NULL); + + g_variant_builder_add_parsed (&details, "{'extensions', <%^as>}", extensions); + if (username != NULL) g_variant_builder_add_parsed (&details, "{'username', <%s>}", username); @@ -2148,6 +2189,8 @@ initialize (GdmSession *self, (GAsyncReadyCallback) on_initialization_complete_cb, conversation); } + + g_free (extensions); } void @@ -3294,6 +3337,8 @@ gdm_session_dispose (GObject *object) g_hash_table_unref); g_clear_object (&self->priv->user_verifier_interface); + g_clear_pointer (&self->priv->user_verifier_extensions, + g_hash_table_unref); g_clear_object (&self->priv->greeter_interface); g_clear_object (&self->priv->chooser_interface); |