[gdm] manager: support just-in-time reauthentication for non-GDM sessions
- From: Ray Strode <halfline src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gdm] manager: support just-in-time reauthentication for non-GDM sessions
- Date: Wed, 19 Mar 2014 19:04:48 +0000 (UTC)
commit b994e9478eb301f9344f376ead56060586d20a03
Author: Ray Strode <rstrode redhat com>
Date: Tue Mar 11 15:25:29 2014 -0400
manager: support just-in-time reauthentication for non-GDM sessions
Right now, gnome-shell can't unlock screens running on an X server that
isn't managed by GDM (say Xvnc or startx). This is because GDM handles
the backend processing for unlocking, and it handles that backend
processing from the worker associated with the session. If there is no
worker associated with the session (as is the case with Xvnc and startx),
then there's no process to handle reauthentication.
This commit notices that case, and creates a transient worker on the fly
just to perform one off authentication for unlock of non-GDM managed
sessions.
https://bugzilla.gnome.org/show_bug.cgi?id=726283
daemon/gdm-manager.c | 205 +++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 188 insertions(+), 17 deletions(-)
---
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
index f75e473..f7c33c6 100644
--- a/daemon/gdm-manager.c
+++ b/daemon/gdm-manager.c
@@ -918,7 +918,8 @@ gdm_manager_handle_open_session (GdmDBusManager *manager,
GdmSession *session;
const char *address;
GPid pid = 0;
- uid_t uid = 0, allowed_user;
+ uid_t uid = (uid_t) -1;
+ uid_t allowed_user;
g_debug ("GdmManager: trying to open new session");
@@ -967,6 +968,169 @@ gdm_manager_handle_open_session (GdmDBusManager *manager,
return TRUE;
}
+static void
+on_reauthentication_client_connected (GdmSession *session,
+ GCredentials *credentials,
+ GPid pid_of_client,
+ GdmManager *self)
+{
+ g_debug ("GdmManager: client connected to reauthentication server");
+}
+
+static void
+on_reauthentication_client_disconnected (GdmSession *session,
+ GCredentials *credentials,
+ GPid pid_of_client,
+ GdmManager *self)
+{
+ g_debug ("GdmManger: client disconnected from reauthentication server");
+ gdm_session_close (session);
+ g_object_unref (session);
+}
+
+static void
+on_reauthentication_cancelled (GdmSession *session,
+ GdmManager *self)
+{
+ g_debug ("GdmManager: client cancelled reauthentication request");
+ gdm_session_close (session);
+ g_object_unref (session);
+}
+
+static void
+on_reauthentication_conversation_started (GdmSession *session,
+ const char *service_name,
+ GdmManager *self)
+{
+ g_debug ("GdmManager: reauthentication service '%s' started",
+ service_name);
+}
+
+static void
+on_reauthentication_conversation_stopped (GdmSession *session,
+ const char *service_name,
+ GdmManager *self)
+{
+ g_debug ("GdmManager: reauthentication service '%s' stopped",
+ service_name);
+}
+
+static void
+on_reauthentication_verification_complete (GdmSession *session,
+ const char *service_name,
+ GdmManager *self)
+{
+ const char *session_id;
+ session_id = g_object_get_data (G_OBJECT (session), "caller-session-id");
+ g_debug ("GdmManager: reauthenticated user in unmanaged session '%s' with service '%s'",
+ session_id, service_name);
+ session_unlock (self, session_id);
+ gdm_session_close (session);
+ g_object_unref (session);
+}
+
+static void
+remove_session_weak_refs (GdmManager *self,
+ GdmSession *session)
+{
+ g_object_weak_unref (G_OBJECT (self),
+ (GWeakNotify)
+ gdm_session_close,
+ session);
+ g_object_weak_unref (G_OBJECT (self),
+ (GWeakNotify)
+ g_object_unref,
+ session);
+}
+
+static void
+add_session_weak_refs (GdmManager *self,
+ GdmSession *session)
+{
+ g_object_weak_ref (G_OBJECT (self),
+ (GWeakNotify)
+ gdm_session_close,
+ session);
+ g_object_weak_ref (G_OBJECT (self),
+ (GWeakNotify)
+ g_object_unref,
+ session);
+ g_object_weak_ref (G_OBJECT (session),
+ (GWeakNotify)
+ remove_session_weak_refs,
+ self);
+}
+
+static char *
+open_temporary_reauthentication_channel (GdmManager *self,
+ char *seat_id,
+ char *session_id,
+ GPid pid,
+ uid_t uid,
+ gboolean is_remote)
+{
+ GdmSession *session;
+ char **environment;
+ const char *display, *auth_file;
+ const char *address;
+
+ /* Note we're just using a minimal environment here rather than the
+ * session's environment because the caller is unprivileged and the
+ * associated worker will be privileged */
+ environment = g_get_environ ();
+ display = "";
+ auth_file = "/dev/null";
+
+ session = gdm_session_new (GDM_SESSION_VERIFICATION_MODE_REAUTHENTICATE,
+ uid,
+ display,
+ NULL,
+ NULL,
+ seat_id,
+ auth_file,
+ is_remote == FALSE,
+ (const char * const *)
+ environment);
+ g_strfreev (environment);
+
+ g_object_set_data_full (G_OBJECT (session),
+ "caller-session-id",
+ g_strdup (session_id),
+ (GDestroyNotify)
+ g_free);
+
+ add_session_weak_refs (self, session);
+
+ g_signal_connect (session,
+ "client-connected",
+ G_CALLBACK (on_reauthentication_client_connected),
+ self);
+ g_signal_connect (session,
+ "client-disconnected",
+ G_CALLBACK (on_reauthentication_client_disconnected),
+ self);
+ g_signal_connect (session,
+ "cancelled",
+ G_CALLBACK (on_reauthentication_cancelled),
+ self);
+ g_signal_connect (session,
+ "conversation-started",
+ G_CALLBACK (on_reauthentication_conversation_started),
+ self);
+ g_signal_connect (session,
+ "conversation-stopped",
+ G_CALLBACK (on_reauthentication_conversation_stopped),
+ self);
+ g_signal_connect (session,
+ "verification-complete",
+ G_CALLBACK (on_reauthentication_verification_complete),
+ self);
+
+ address = gdm_session_get_server_address (session);
+
+ return g_strdup (address);
+}
+
static gboolean
gdm_manager_handle_open_reauthentication_channel (GdmDBusManager *manager,
GDBusMethodInvocation *invocation,
@@ -977,15 +1141,18 @@ gdm_manager_handle_open_reauthentication_channel (GdmDBusManager *manager
GdmDisplay *display = NULL;
GdmSession *session;
GDBusConnection *connection;
+ char *seat_id = NULL;
+ char *session_id = NULL;
GPid pid = 0;
- uid_t uid = 0;
+ uid_t uid = (uid_t) -1;
gboolean is_login_screen = FALSE;
+ gboolean is_remote = FALSE;
g_debug ("GdmManager: trying to open reauthentication channel for user %s", username);
sender = g_dbus_method_invocation_get_sender (invocation);
connection = g_dbus_method_invocation_get_connection (invocation);
- get_display_and_details_for_bus_sender (self, connection, sender, &display, NULL, NULL, &pid, &uid,
&is_login_screen, NULL);
+ get_display_and_details_for_bus_sender (self, connection, sender, &display, &seat_id, &session_id,
&pid, &uid, &is_login_screen, &is_remote);
if (is_login_screen) {
g_dbus_method_invocation_return_error_literal (invocation,
@@ -995,7 +1162,7 @@ gdm_manager_handle_open_reauthentication_channel (GdmDBusManager *manager
return TRUE;
}
- if (display == NULL) {
+ if (seat_id == NULL || session_id == NULL || pid == 0 || uid == (uid_t) -1) {
g_dbus_method_invocation_return_error_literal (invocation,
G_DBUS_ERROR,
G_DBUS_ERROR_ACCESS_DENIED,
@@ -1006,21 +1173,25 @@ gdm_manager_handle_open_reauthentication_channel (GdmDBusManager *manager
session = get_seed_session_for_display (display);
- if (!gdm_session_is_running (session)) {
- g_dbus_method_invocation_return_error_literal (invocation,
- G_DBUS_ERROR,
- G_DBUS_ERROR_ACCESS_DENIED,
- _("No session available"));
-
- return TRUE;
+ if (session != NULL && gdm_session_is_running (session)) {
+ gdm_session_start_reauthentication (session, pid, uid);
+ g_hash_table_insert (self->priv->open_reauthentication_requests,
+ GINT_TO_POINTER (pid),
+ invocation);
+ } else {
+ char *address;
+ address = open_temporary_reauthentication_channel (self,
+ seat_id,
+ session_id,
+ pid,
+ uid,
+ is_remote);
+ gdm_dbus_manager_complete_open_reauthentication_channel (GDM_DBUS_MANAGER (manager),
+ invocation,
+ address);
+ g_free (address);
}
- gdm_session_start_reauthentication (session, pid, uid);
-
- g_hash_table_insert (self->priv->open_reauthentication_requests,
- GINT_TO_POINTER (pid),
- invocation);
-
return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]