aabe760838
https://fedoraproject.org/wiki/Features/MultiplePAMStacksInGDM) - Drop 10 second delay in start up because of broken autostart file
18867 lines
739 KiB
Diff
18867 lines
739 KiB
Diff
From 0b295480d3f0955d7133c39c0c4b2ec3bd2f3084 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Fri, 16 Jan 2009 11:00:08 -0500
|
|
Subject: [PATCH 01/65] Drop session "Open" in favor of "StartConversation"
|
|
|
|
We want to eventually support having multiple
|
|
simultaneous PAM conversations in one login
|
|
screen (so, e.g., username/password, smart card, and
|
|
fingerprint all work at the same time).
|
|
|
|
This commit refactors the session code to be in terms
|
|
of a conversation object. With this change, it should
|
|
be easier later to have multiple conversation objects.
|
|
|
|
The conversation is named by the pam service the login
|
|
screen is talking to.
|
|
---
|
|
daemon/gdm-factory-slave.c | 13 +-
|
|
daemon/gdm-product-slave.c | 47 ++++++---
|
|
daemon/gdm-session-direct.c | 250 ++++++++++++++++++++++++++----------------
|
|
daemon/gdm-session-private.h | 3 +-
|
|
daemon/gdm-session-relay.c | 29 +++--
|
|
daemon/gdm-session.c | 20 ++--
|
|
daemon/gdm-session.h | 9 +-
|
|
daemon/gdm-simple-slave.c | 3 -
|
|
daemon/test-session.c | 13 +-
|
|
9 files changed, 240 insertions(+), 147 deletions(-)
|
|
|
|
diff --git a/daemon/gdm-factory-slave.c b/daemon/gdm-factory-slave.c
|
|
index d09c913..6497293 100644
|
|
--- a/daemon/gdm-factory-slave.c
|
|
+++ b/daemon/gdm-factory-slave.c
|
|
@@ -180,10 +180,11 @@ on_session_secret_info_query (GdmSession *session,
|
|
}
|
|
|
|
static void
|
|
-on_session_opened (GdmSession *session,
|
|
- GdmFactorySlave *slave)
|
|
+on_session_conversation_started (GdmSession *session,
|
|
+ GdmFactorySlave *slave,
|
|
+ const char *service_name)
|
|
{
|
|
- g_debug ("GdmFactorySlave: session opened");
|
|
+ g_debug ("GdmFactorySlave: session conversation started");
|
|
|
|
gdm_greeter_server_ready (slave->priv->greeter_server);
|
|
}
|
|
@@ -367,7 +368,7 @@ on_session_relay_connected (GdmSessionRelay *session,
|
|
{
|
|
g_debug ("GdmFactorySlave: Relay Connected");
|
|
|
|
- gdm_session_open (GDM_SESSION (slave->priv->session));
|
|
+ gdm_session_start_conversation (GDM_SESSION (slave->priv->session), "gdm");
|
|
}
|
|
|
|
static void
|
|
@@ -694,8 +695,8 @@ gdm_factory_slave_start (GdmSlave *slave)
|
|
|
|
GDM_FACTORY_SLAVE (slave)->priv->session = gdm_session_relay_new ();
|
|
g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
|
|
- "opened",
|
|
- G_CALLBACK (on_session_opened),
|
|
+ "conversation-started",
|
|
+ G_CALLBACK (on_session_conversation_started),
|
|
slave);
|
|
g_signal_connect (GDM_FACTORY_SLAVE (slave)->priv->session,
|
|
"setup-complete",
|
|
diff --git a/daemon/gdm-product-slave.c b/daemon/gdm-product-slave.c
|
|
index 9adcb09..15a2820 100644
|
|
--- a/daemon/gdm-product-slave.c
|
|
+++ b/daemon/gdm-product-slave.c
|
|
@@ -246,19 +246,21 @@ relay_session_started (GdmProductSlave *slave,
|
|
}
|
|
|
|
static void
|
|
-relay_session_opened (GdmProductSlave *slave)
|
|
+relay_session_conversation_started (GdmProductSlave *slave,
|
|
+ const char *service_name)
|
|
{
|
|
- send_dbus_void_method (slave->priv->session_relay_connection,
|
|
- "Opened");
|
|
+ send_dbus_string_method (slave->priv->session_relay_connection,
|
|
+ "ConversationStarted", service_name);
|
|
}
|
|
|
|
static void
|
|
-on_session_opened (GdmSession *session,
|
|
- GdmProductSlave *slave)
|
|
+on_session_conversation_started (GdmSession *session,
|
|
+ const char *service_name,
|
|
+ GdmProductSlave *slave)
|
|
{
|
|
- g_debug ("GdmProductSlave: session opened");
|
|
+ g_debug ("GdmProductSlave: session conversation started");
|
|
|
|
- relay_session_opened (slave);
|
|
+ relay_session_conversation_started (slave, service_name);
|
|
}
|
|
|
|
static void
|
|
@@ -784,10 +786,27 @@ on_relay_user_selected (GdmProductSlave *slave,
|
|
}
|
|
|
|
static void
|
|
-on_relay_open (GdmProductSlave *slave,
|
|
- DBusMessage *message)
|
|
+on_relay_start_conversation (GdmProductSlave *slave,
|
|
+ DBusMessage *message)
|
|
{
|
|
- gdm_session_open (GDM_SESSION (slave->priv->session));
|
|
+ DBusError error;
|
|
+ char *service_name;
|
|
+ dbus_bool_t res;
|
|
+
|
|
+ dbus_error_init (&error);
|
|
+ res = dbus_message_get_args (message,
|
|
+ &error,
|
|
+ DBUS_TYPE_STRING, &service_name,
|
|
+ DBUS_TYPE_INVALID);
|
|
+ if (res) {
|
|
+ g_debug ("GdmProductSlave: Started conversation with %s service", service_name);
|
|
+ gdm_session_start_conversation (GDM_SESSION (slave->priv->session),
|
|
+ service_name);
|
|
+ } else {
|
|
+ g_warning ("Unable to get arguments: %s", error.message);
|
|
+ }
|
|
+
|
|
+ dbus_error_free (&error);
|
|
}
|
|
|
|
static void
|
|
@@ -832,8 +851,8 @@ create_new_session (GdmProductSlave *slave)
|
|
g_free (display_device);
|
|
|
|
g_signal_connect (slave->priv->session,
|
|
- "opened",
|
|
- G_CALLBACK (on_session_opened),
|
|
+ "conversation-started",
|
|
+ G_CALLBACK (on_session_conversation_started),
|
|
slave);
|
|
g_signal_connect (slave->priv->session,
|
|
"setup-complete",
|
|
@@ -991,8 +1010,8 @@ relay_dbus_handle_message (DBusConnection *connection,
|
|
on_relay_user_selected (slave, message);
|
|
} else if (dbus_message_is_signal (message, RELAY_SERVER_DBUS_INTERFACE, "StartSession")) {
|
|
on_relay_start_session (slave, message);
|
|
- } else if (dbus_message_is_signal (message, RELAY_SERVER_DBUS_INTERFACE, "Open")) {
|
|
- on_relay_open (slave, message);
|
|
+ } else if (dbus_message_is_signal (message, RELAY_SERVER_DBUS_INTERFACE, "StartConversation")) {
|
|
+ on_relay_start_conversation (slave, message);
|
|
} else if (dbus_message_is_signal (message, RELAY_SERVER_DBUS_INTERFACE, "Cancelled")) {
|
|
on_relay_cancelled (slave, message);
|
|
} else {
|
|
diff --git a/daemon/gdm-session-direct.c b/daemon/gdm-session-direct.c
|
|
index 34a126f..a76051b 100644
|
|
--- a/daemon/gdm-session-direct.c
|
|
+++ b/daemon/gdm-session-direct.c
|
|
@@ -61,6 +61,15 @@
|
|
#define GDM_SESSION_DEFAULT_PATH "/usr/local/bin:/usr/bin:/bin"
|
|
#endif
|
|
|
|
+typedef struct
|
|
+{
|
|
+ GdmSessionDirect *session;
|
|
+ GdmSessionWorkerJob *job;
|
|
+ GPid worker_pid;
|
|
+ char *service_name;
|
|
+ DBusConnection *worker_connection;
|
|
+} GdmSessionConversation;
|
|
+
|
|
struct _GdmSessionDirectPrivate
|
|
{
|
|
/* per open scope */
|
|
@@ -74,10 +83,9 @@ struct _GdmSessionDirectPrivate
|
|
char *user_x11_authority_file;
|
|
|
|
DBusMessage *message_pending_reply;
|
|
- DBusConnection *worker_connection;
|
|
|
|
- GdmSessionWorkerJob *job;
|
|
- GPid session_pid;
|
|
+ GdmSessionConversation *conversation;
|
|
+
|
|
guint32 is_authenticated : 1;
|
|
guint32 is_running : 1;
|
|
|
|
@@ -147,6 +155,7 @@ send_dbus_string_signal (GdmSessionDirect *session,
|
|
{
|
|
DBusMessage *message;
|
|
DBusMessageIter iter;
|
|
+ GdmSessionConversation *conversation;
|
|
|
|
g_return_if_fail (session != NULL);
|
|
|
|
@@ -157,7 +166,8 @@ send_dbus_string_signal (GdmSessionDirect *session,
|
|
dbus_message_iter_init_append (message, &iter);
|
|
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &text);
|
|
|
|
- if (! send_dbus_message (session->priv->worker_connection, message)) {
|
|
+ conversation = session->priv->conversation;
|
|
+ if (! send_dbus_message (conversation->worker_connection, message)) {
|
|
g_debug ("GdmSessionDirect: Could not send %s signal", name);
|
|
}
|
|
|
|
@@ -169,6 +179,7 @@ send_dbus_void_signal (GdmSessionDirect *session,
|
|
const char *name)
|
|
{
|
|
DBusMessage *message;
|
|
+ GdmSessionConversation *conversation;
|
|
|
|
g_return_if_fail (session != NULL);
|
|
|
|
@@ -176,7 +187,8 @@ send_dbus_void_signal (GdmSessionDirect *session,
|
|
GDM_SESSION_DBUS_INTERFACE,
|
|
name);
|
|
|
|
- if (! send_dbus_message (session->priv->worker_connection, message)) {
|
|
+ conversation = session->priv->conversation;
|
|
+ if (! send_dbus_message (conversation->worker_connection, message)) {
|
|
g_debug ("GdmSessionDirect: Could not send %s signal", name);
|
|
}
|
|
|
|
@@ -188,22 +200,32 @@ on_authentication_failed (GdmSession *session,
|
|
const char *message)
|
|
{
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
- gdm_session_record_failed (impl->priv->session_pid,
|
|
- impl->priv->selected_user,
|
|
- impl->priv->display_hostname,
|
|
- impl->priv->display_name,
|
|
- impl->priv->display_device);
|
|
+ GdmSessionConversation *conversation;
|
|
+
|
|
+ conversation = impl->priv->conversation;
|
|
+ if (conversation != NULL) {
|
|
+ gdm_session_record_failed (conversation->worker_pid,
|
|
+ impl->priv->selected_user,
|
|
+ impl->priv->display_hostname,
|
|
+ impl->priv->display_name,
|
|
+ impl->priv->display_device);
|
|
+ }
|
|
}
|
|
|
|
static void
|
|
on_session_started (GdmSession *session)
|
|
{
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
- gdm_session_record_login (impl->priv->session_pid,
|
|
- impl->priv->selected_user,
|
|
- impl->priv->display_hostname,
|
|
- impl->priv->display_name,
|
|
- impl->priv->display_device);
|
|
+ GdmSessionConversation *conversation;
|
|
+
|
|
+ conversation = impl->priv->conversation;
|
|
+ if (conversation != NULL) {
|
|
+ gdm_session_record_login (conversation->worker_pid,
|
|
+ impl->priv->selected_user,
|
|
+ impl->priv->display_hostname,
|
|
+ impl->priv->display_name,
|
|
+ impl->priv->display_device);
|
|
+ }
|
|
}
|
|
|
|
static void
|
|
@@ -211,11 +233,16 @@ on_session_start_failed (GdmSession *session,
|
|
const char *message)
|
|
{
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
- gdm_session_record_login (impl->priv->session_pid,
|
|
- impl->priv->selected_user,
|
|
- impl->priv->display_hostname,
|
|
- impl->priv->display_name,
|
|
- impl->priv->display_device);
|
|
+ GdmSessionConversation *conversation;
|
|
+
|
|
+ conversation = impl->priv->conversation;
|
|
+ if (conversation != NULL) {
|
|
+ gdm_session_record_login (conversation->worker_pid,
|
|
+ impl->priv->selected_user,
|
|
+ impl->priv->display_hostname,
|
|
+ impl->priv->display_name,
|
|
+ impl->priv->display_device);
|
|
+ }
|
|
}
|
|
|
|
static void
|
|
@@ -223,11 +250,16 @@ on_session_exited (GdmSession *session,
|
|
int exit_code)
|
|
{
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
- gdm_session_record_logout (impl->priv->session_pid,
|
|
- impl->priv->selected_user,
|
|
- impl->priv->display_hostname,
|
|
- impl->priv->display_name,
|
|
- impl->priv->display_device);
|
|
+ GdmSessionConversation *conversation;
|
|
+
|
|
+ conversation = impl->priv->conversation;
|
|
+ if (conversation != NULL) {
|
|
+ gdm_session_record_logout (conversation->worker_pid,
|
|
+ impl->priv->selected_user,
|
|
+ impl->priv->display_hostname,
|
|
+ impl->priv->display_name,
|
|
+ impl->priv->display_device);
|
|
+ }
|
|
}
|
|
|
|
static DBusHandlerResult
|
|
@@ -734,6 +766,7 @@ static void
|
|
cancel_pending_query (GdmSessionDirect *session)
|
|
{
|
|
DBusMessage *reply;
|
|
+ GdmSessionConversation *conversation;
|
|
|
|
if (session->priv->message_pending_reply == NULL) {
|
|
return;
|
|
@@ -744,8 +777,9 @@ cancel_pending_query (GdmSessionDirect *session)
|
|
reply = dbus_message_new_error (session->priv->message_pending_reply,
|
|
GDM_SESSION_DBUS_ERROR_CANCEL,
|
|
"Operation cancelled");
|
|
- dbus_connection_send (session->priv->worker_connection, reply, NULL);
|
|
- dbus_connection_flush (session->priv->worker_connection);
|
|
+ conversation = session->priv->conversation;
|
|
+ dbus_connection_send (conversation->worker_connection, reply, NULL);
|
|
+ dbus_connection_flush (conversation->worker_connection);
|
|
|
|
dbus_message_unref (reply);
|
|
dbus_message_unref (session->priv->message_pending_reply);
|
|
@@ -758,6 +792,7 @@ answer_pending_query (GdmSessionDirect *session,
|
|
{
|
|
DBusMessage *reply;
|
|
DBusMessageIter iter;
|
|
+ GdmSessionConversation *conversation;
|
|
|
|
g_assert (session->priv->message_pending_reply != NULL);
|
|
|
|
@@ -765,7 +800,8 @@ answer_pending_query (GdmSessionDirect *session,
|
|
dbus_message_iter_init_append (reply, &iter);
|
|
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &answer);
|
|
|
|
- dbus_connection_send (session->priv->worker_connection, reply, NULL);
|
|
+ conversation = session->priv->conversation;
|
|
+ dbus_connection_send (conversation->worker_connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
dbus_message_unref (session->priv->message_pending_reply);
|
|
@@ -923,7 +959,7 @@ gdm_session_direct_handle_session_started (GdmSessionDirect *session,
|
|
g_debug ("GdmSessionDirect: Emitting 'session-started' signal with pid '%d'",
|
|
pid);
|
|
|
|
- session->priv->session_pid = pid;
|
|
+ session->priv->conversation->worker_pid = pid;
|
|
session->priv->is_running = TRUE;
|
|
|
|
_gdm_session_session_started (GDM_SESSION (session), pid);
|
|
@@ -1439,16 +1475,18 @@ handle_connection (DBusServer *server,
|
|
void *user_data)
|
|
{
|
|
GdmSessionDirect *session = GDM_SESSION_DIRECT (user_data);
|
|
+ GdmSessionConversation *conversation;
|
|
|
|
g_debug ("GdmSessionDirect: Handing new connection");
|
|
|
|
- if (session->priv->worker_connection == NULL) {
|
|
+ conversation = session->priv->conversation;
|
|
+ if (conversation->worker_connection == NULL) {
|
|
DBusObjectPathVTable vtable = { &session_unregister_handler,
|
|
&session_message_handler,
|
|
NULL, NULL, NULL, NULL
|
|
};
|
|
|
|
- session->priv->worker_connection = new_connection;
|
|
+ conversation->worker_connection = new_connection;
|
|
dbus_connection_ref (new_connection);
|
|
dbus_connection_setup_with_g_main (new_connection, NULL);
|
|
|
|
@@ -1465,8 +1503,9 @@ handle_connection (DBusServer *server,
|
|
&vtable,
|
|
session);
|
|
|
|
- g_debug ("GdmSessionDirect: Emitting opened signal");
|
|
- _gdm_session_opened (GDM_SESSION (session));
|
|
+ g_debug ("GdmSessionDirect: Emitting conversation-started signal");
|
|
+ _gdm_session_conversation_started (GDM_SESSION (session),
|
|
+ conversation->service_name);
|
|
}
|
|
}
|
|
|
|
@@ -1536,8 +1575,6 @@ gdm_session_direct_init (GdmSessionDirect *session)
|
|
G_CALLBACK (on_session_exited),
|
|
NULL);
|
|
|
|
- session->priv->session_pid = -1;
|
|
-
|
|
session->priv->environment = g_hash_table_new_full (g_str_hash,
|
|
g_str_equal,
|
|
(GDestroyNotify) g_free,
|
|
@@ -1548,15 +1585,15 @@ gdm_session_direct_init (GdmSessionDirect *session)
|
|
}
|
|
|
|
static void
|
|
-worker_stopped (GdmSessionWorkerJob *job,
|
|
- GdmSessionDirect *session)
|
|
+worker_stopped (GdmSessionWorkerJob *job,
|
|
+ GdmSessionConversation *conversation)
|
|
{
|
|
g_debug ("GdmSessionDirect: Worker job stopped");
|
|
}
|
|
|
|
static void
|
|
worker_started (GdmSessionWorkerJob *job,
|
|
- GdmSessionDirect *session)
|
|
+ GdmSessionConversation *conversation)
|
|
{
|
|
g_debug ("GdmSessionDirect: Worker job started");
|
|
}
|
|
@@ -1564,106 +1601,118 @@ worker_started (GdmSessionWorkerJob *job,
|
|
static void
|
|
worker_exited (GdmSessionWorkerJob *job,
|
|
int code,
|
|
- GdmSessionDirect *session)
|
|
+ GdmSessionConversation *conversation)
|
|
{
|
|
g_debug ("GdmSessionDirect: Worker job exited: %d", code);
|
|
|
|
- if (!session->priv->is_authenticated) {
|
|
+ if (!conversation->session->priv->is_authenticated) {
|
|
char *msg;
|
|
|
|
msg = g_strdup_printf (_("worker exited with status %d"), code);
|
|
- _gdm_session_authentication_failed (GDM_SESSION (session), msg);
|
|
+ _gdm_session_authentication_failed (GDM_SESSION (conversation->session), msg);
|
|
g_free (msg);
|
|
- } else if (session->priv->is_running) {
|
|
- _gdm_session_session_exited (GDM_SESSION (session), code);
|
|
+ } else if (conversation->session->priv->is_running) {
|
|
+ _gdm_session_session_exited (GDM_SESSION (conversation->session), code);
|
|
}
|
|
}
|
|
|
|
static void
|
|
worker_died (GdmSessionWorkerJob *job,
|
|
int signum,
|
|
- GdmSessionDirect *session)
|
|
+ GdmSessionConversation *conversation)
|
|
{
|
|
g_debug ("GdmSessionDirect: Worker job died: %d", signum);
|
|
|
|
- if (!session->priv->is_authenticated) {
|
|
+ if (!conversation->session->priv->is_authenticated) {
|
|
char *msg;
|
|
|
|
msg = g_strdup_printf (_("worker exited with status %d"), signum);
|
|
- _gdm_session_authentication_failed (GDM_SESSION (session), msg);
|
|
+ _gdm_session_authentication_failed (GDM_SESSION (conversation->session), msg);
|
|
g_free (msg);
|
|
- } else if (session->priv->is_running) {
|
|
- _gdm_session_session_died (GDM_SESSION (session), signum);
|
|
+ } else if (conversation->session->priv->is_running) {
|
|
+ _gdm_session_session_died (GDM_SESSION (conversation->session), signum);
|
|
}
|
|
}
|
|
|
|
-static gboolean
|
|
-start_worker (GdmSessionDirect *session)
|
|
+static GdmSessionConversation *
|
|
+start_conversation (GdmSessionDirect *session,
|
|
+ const char *service_name)
|
|
{
|
|
- gboolean res;
|
|
+ GdmSessionConversation *conversation;
|
|
|
|
- session->priv->job = gdm_session_worker_job_new ();
|
|
- gdm_session_worker_job_set_server_address (session->priv->job, session->priv->server_address);
|
|
- g_signal_connect (session->priv->job,
|
|
+ conversation = g_new0 (GdmSessionConversation, 1);
|
|
+ conversation->session = session;
|
|
+ conversation->service_name = g_strdup (service_name);
|
|
+ conversation->worker_pid = -1;
|
|
+ conversation->job = gdm_session_worker_job_new ();
|
|
+ gdm_session_worker_job_set_server_address (conversation->job, session->priv->server_address);
|
|
+ g_signal_connect (conversation->job,
|
|
"stopped",
|
|
G_CALLBACK (worker_stopped),
|
|
- session);
|
|
- g_signal_connect (session->priv->job,
|
|
+ conversation);
|
|
+ g_signal_connect (conversation->job,
|
|
"started",
|
|
G_CALLBACK (worker_started),
|
|
- session);
|
|
- g_signal_connect (session->priv->job,
|
|
+ conversation);
|
|
+ g_signal_connect (conversation->job,
|
|
"exited",
|
|
G_CALLBACK (worker_exited),
|
|
- session);
|
|
- g_signal_connect (session->priv->job,
|
|
+ conversation);
|
|
+ g_signal_connect (conversation->job,
|
|
"died",
|
|
G_CALLBACK (worker_died),
|
|
- session);
|
|
+ conversation);
|
|
|
|
- res = gdm_session_worker_job_start (session->priv->job);
|
|
+ if (!gdm_session_worker_job_start (conversation->job)) {
|
|
+ g_object_unref (conversation->job);
|
|
+ g_free (conversation->service_name);
|
|
+ g_free (conversation);
|
|
+ return NULL;
|
|
+ }
|
|
|
|
- return res;
|
|
+ return conversation;
|
|
}
|
|
|
|
static void
|
|
-stop_worker (GdmSessionDirect *session)
|
|
+stop_conversation (GdmSessionConversation *conversation)
|
|
{
|
|
- g_signal_handlers_disconnect_by_func (session->priv->job,
|
|
+ g_signal_handlers_disconnect_by_func (conversation->job,
|
|
G_CALLBACK (worker_stopped),
|
|
- session);
|
|
- g_signal_handlers_disconnect_by_func (session->priv->job,
|
|
+ conversation);
|
|
+ g_signal_handlers_disconnect_by_func (conversation->job,
|
|
G_CALLBACK (worker_started),
|
|
- session);
|
|
- g_signal_handlers_disconnect_by_func (session->priv->job,
|
|
+ conversation);
|
|
+ g_signal_handlers_disconnect_by_func (conversation->job,
|
|
G_CALLBACK (worker_exited),
|
|
- session);
|
|
- g_signal_handlers_disconnect_by_func (session->priv->job,
|
|
+ conversation);
|
|
+ g_signal_handlers_disconnect_by_func (conversation->job,
|
|
G_CALLBACK (worker_died),
|
|
- session);
|
|
+ conversation);
|
|
|
|
- cancel_pending_query (session);
|
|
+ cancel_pending_query (conversation->session);
|
|
|
|
- if (session->priv->worker_connection != NULL) {
|
|
- dbus_connection_close (session->priv->worker_connection);
|
|
- session->priv->worker_connection = NULL;
|
|
+ if (conversation->worker_connection != NULL) {
|
|
+ dbus_connection_close (conversation->worker_connection);
|
|
+ conversation->worker_connection = NULL;
|
|
}
|
|
|
|
- gdm_session_worker_job_stop (session->priv->job);
|
|
- g_object_unref (session->priv->job);
|
|
- session->priv->job = NULL;
|
|
+ gdm_session_worker_job_stop (conversation->job);
|
|
+ g_object_unref (conversation->job);
|
|
+ g_free (conversation->service_name);
|
|
+ g_free (conversation);
|
|
}
|
|
|
|
static void
|
|
-gdm_session_direct_open (GdmSession *session)
|
|
+gdm_session_direct_start_conversation (GdmSession *session,
|
|
+ const char *service_name)
|
|
{
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
|
|
g_return_if_fail (session != NULL);
|
|
|
|
- g_debug ("GdmSessionDirect: Opening session");
|
|
+ g_debug ("GdmSessionDirect: starting conversation");
|
|
|
|
- start_worker (impl);
|
|
+ impl->priv->conversation = start_conversation (impl, service_name);
|
|
}
|
|
|
|
static void
|
|
@@ -1676,6 +1725,7 @@ send_setup (GdmSessionDirect *session,
|
|
const char *display_device;
|
|
const char *display_hostname;
|
|
const char *display_x11_authority_file;
|
|
+ GdmSessionConversation *conversation;
|
|
|
|
g_assert (service_name != NULL);
|
|
|
|
@@ -1713,7 +1763,8 @@ send_setup (GdmSessionDirect *session,
|
|
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_hostname);
|
|
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_x11_authority_file);
|
|
|
|
- if (! send_dbus_message (session->priv->worker_connection, message)) {
|
|
+ conversation = session->priv->conversation;
|
|
+ if (! send_dbus_message (conversation->worker_connection, message)) {
|
|
g_debug ("GdmSessionDirect: Could not send %s signal", "Setup");
|
|
}
|
|
|
|
@@ -1731,6 +1782,7 @@ send_setup_for_user (GdmSessionDirect *session,
|
|
const char *display_hostname;
|
|
const char *display_x11_authority_file;
|
|
const char *selected_user;
|
|
+ GdmSessionConversation *conversation;
|
|
|
|
g_assert (service_name != NULL);
|
|
|
|
@@ -1774,7 +1826,8 @@ send_setup_for_user (GdmSessionDirect *session,
|
|
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_x11_authority_file);
|
|
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &selected_user);
|
|
|
|
- if (! send_dbus_message (session->priv->worker_connection, message)) {
|
|
+ conversation = session->priv->conversation;
|
|
+ if (! send_dbus_message (conversation->worker_connection, message)) {
|
|
g_debug ("GdmSessionDirect: Could not send %s signal", "SetupForUser");
|
|
}
|
|
|
|
@@ -1788,7 +1841,8 @@ gdm_session_direct_setup (GdmSession *session,
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
|
|
g_return_if_fail (session != NULL);
|
|
- g_return_if_fail (dbus_connection_get_is_connected (impl->priv->worker_connection));
|
|
+ g_return_if_fail (impl->priv->conversation != NULL);
|
|
+ g_return_if_fail (dbus_connection_get_is_connected (impl->priv->conversation->worker_connection));
|
|
|
|
send_setup (impl, service_name);
|
|
gdm_session_direct_defaults_changed (impl);
|
|
@@ -1802,7 +1856,8 @@ gdm_session_direct_setup_for_user (GdmSession *session,
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
|
|
g_return_if_fail (session != NULL);
|
|
- g_return_if_fail (dbus_connection_get_is_connected (impl->priv->worker_connection));
|
|
+ g_return_if_fail (impl->priv->conversation != NULL);
|
|
+ g_return_if_fail (dbus_connection_get_is_connected (impl->priv->conversation->worker_connection));
|
|
g_return_if_fail (username != NULL);
|
|
|
|
gdm_session_direct_select_user (session, username);
|
|
@@ -1817,7 +1872,8 @@ gdm_session_direct_authenticate (GdmSession *session)
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
|
|
g_return_if_fail (session != NULL);
|
|
- g_return_if_fail (dbus_connection_get_is_connected (impl->priv->worker_connection));
|
|
+ g_return_if_fail (impl->priv->conversation != NULL);
|
|
+ g_return_if_fail (dbus_connection_get_is_connected (impl->priv->conversation->worker_connection));
|
|
|
|
send_dbus_void_signal (impl, "Authenticate");
|
|
}
|
|
@@ -1828,7 +1884,8 @@ gdm_session_direct_authorize (GdmSession *session)
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
|
|
g_return_if_fail (session != NULL);
|
|
- g_return_if_fail (dbus_connection_get_is_connected (impl->priv->worker_connection));
|
|
+ g_return_if_fail (impl->priv->conversation != NULL);
|
|
+ g_return_if_fail (dbus_connection_get_is_connected (impl->priv->conversation->worker_connection));
|
|
|
|
send_dbus_void_signal (impl, "Authorize");
|
|
}
|
|
@@ -1840,7 +1897,8 @@ gdm_session_direct_accredit (GdmSession *session,
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
|
|
g_return_if_fail (session != NULL);
|
|
- g_return_if_fail (dbus_connection_get_is_connected (impl->priv->worker_connection));
|
|
+ g_return_if_fail (impl->priv->conversation != NULL);
|
|
+ g_return_if_fail (dbus_connection_get_is_connected (impl->priv->conversation->worker_connection));
|
|
|
|
switch (cred_flag) {
|
|
case GDM_SESSION_CRED_ESTABLISH:
|
|
@@ -1861,6 +1919,7 @@ send_environment_variable (const char *key,
|
|
{
|
|
DBusMessage *message;
|
|
DBusMessageIter iter;
|
|
+ GdmSessionConversation *conversation;
|
|
|
|
message = dbus_message_new_signal (GDM_SESSION_DBUS_PATH,
|
|
GDM_SESSION_DBUS_INTERFACE,
|
|
@@ -1870,7 +1929,8 @@ send_environment_variable (const char *key,
|
|
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
|
|
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value);
|
|
|
|
- if (! send_dbus_message (session->priv->worker_connection, message)) {
|
|
+ conversation = session->priv->conversation;
|
|
+ if (! send_dbus_message (conversation->worker_connection, message)) {
|
|
g_debug ("GdmSessionDirect: Could not send %s signal", "SetEnvironmentVariable");
|
|
}
|
|
|
|
@@ -2026,16 +2086,17 @@ gdm_session_direct_close (GdmSession *session)
|
|
|
|
g_debug ("GdmSessionDirect: Closing session");
|
|
|
|
- if (impl->priv->job != NULL) {
|
|
+ if (impl->priv->conversation != NULL) {
|
|
if (impl->priv->is_running) {
|
|
- gdm_session_record_logout (impl->priv->session_pid,
|
|
+ gdm_session_record_logout (impl->priv->conversation->worker_pid,
|
|
impl->priv->selected_user,
|
|
impl->priv->display_hostname,
|
|
impl->priv->display_name,
|
|
impl->priv->display_device);
|
|
}
|
|
|
|
- stop_worker (impl);
|
|
+ stop_conversation (impl->priv->conversation);
|
|
+ impl->priv->conversation = NULL;
|
|
}
|
|
|
|
g_free (impl->priv->selected_user);
|
|
@@ -2064,7 +2125,6 @@ gdm_session_direct_close (GdmSession *session)
|
|
|
|
g_hash_table_remove_all (impl->priv->environment);
|
|
|
|
- impl->priv->session_pid = -1;
|
|
impl->priv->is_authenticated = FALSE;
|
|
impl->priv->is_running = FALSE;
|
|
}
|
|
@@ -2408,7 +2468,7 @@ gdm_session_direct_constructor (GType type,
|
|
static void
|
|
gdm_session_iface_init (GdmSessionIface *iface)
|
|
{
|
|
- iface->open = gdm_session_direct_open;
|
|
+ iface->start_conversation = gdm_session_direct_start_conversation;
|
|
iface->setup = gdm_session_direct_setup;
|
|
iface->setup_for_user = gdm_session_direct_setup_for_user;
|
|
iface->authenticate = gdm_session_direct_authenticate;
|
|
diff --git a/daemon/gdm-session-private.h b/daemon/gdm-session-private.h
|
|
index 6a6fcfc..074aa6f 100644
|
|
--- a/daemon/gdm-session-private.h
|
|
+++ b/daemon/gdm-session-private.h
|
|
@@ -27,7 +27,8 @@
|
|
G_BEGIN_DECLS
|
|
|
|
/* state changes */
|
|
-void _gdm_session_opened (GdmSession *session);
|
|
+void _gdm_session_conversation_started (GdmSession *session,
|
|
+ const char *service_name);
|
|
void _gdm_session_setup_complete (GdmSession *session);
|
|
void _gdm_session_setup_failed (GdmSession *session,
|
|
const char *message);
|
|
diff --git a/daemon/gdm-session-relay.c b/daemon/gdm-session-relay.c
|
|
index b57bf89..35b4738 100644
|
|
--- a/daemon/gdm-session-relay.c
|
|
+++ b/daemon/gdm-session-relay.c
|
|
@@ -180,10 +180,11 @@ send_dbus_void_signal (GdmSessionRelay *session_relay,
|
|
}
|
|
|
|
static void
|
|
-gdm_session_relay_open (GdmSession *session)
|
|
+gdm_session_relay_start_conversation (GdmSession *session,
|
|
+ const char *service_name)
|
|
{
|
|
GdmSessionRelay *impl = GDM_SESSION_RELAY (session);
|
|
- send_dbus_void_signal (impl, "Open");
|
|
+ send_dbus_string_signal (impl, "StartConversation", service_name);
|
|
}
|
|
|
|
static void
|
|
@@ -664,22 +665,28 @@ handle_session_stopped (GdmSessionRelay *session_relay,
|
|
}
|
|
|
|
static DBusHandlerResult
|
|
-handle_opened (GdmSessionRelay *session_relay,
|
|
+handle_conversation_started (GdmSessionRelay *session_relay,
|
|
DBusConnection *connection,
|
|
DBusMessage *message)
|
|
{
|
|
DBusMessage *reply;
|
|
DBusError error;
|
|
+ char *service_name;
|
|
|
|
dbus_error_init (&error);
|
|
+ if (! dbus_message_get_args (message, &error,
|
|
+ DBUS_TYPE_STRING, &service_name,
|
|
+ DBUS_TYPE_INVALID)) {
|
|
+ g_warning ("ERROR: %s", error.message);
|
|
+ }
|
|
|
|
- g_debug ("GdmSessionRelay: Opened");
|
|
+ g_debug ("GdmSessionRelay: Conversation Started");
|
|
|
|
reply = dbus_message_new_method_return (message);
|
|
dbus_connection_send (connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
- _gdm_session_opened (GDM_SESSION (session_relay));
|
|
+ _gdm_session_conversation_started (GDM_SESSION (session_relay), service_name);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
@@ -719,8 +726,8 @@ session_handle_child_message (DBusConnection *connection,
|
|
return handle_session_started (session_relay, connection, message);
|
|
} else if (dbus_message_is_method_call (message, GDM_SESSION_RELAY_DBUS_INTERFACE, "SessionStopped")) {
|
|
return handle_session_stopped (session_relay, connection, message);
|
|
- } else if (dbus_message_is_method_call (message, GDM_SESSION_RELAY_DBUS_INTERFACE, "Opened")) {
|
|
- return handle_opened (session_relay, connection, message);
|
|
+ } else if (dbus_message_is_method_call (message, GDM_SESSION_RELAY_DBUS_INTERFACE, "ConversationStarted")) {
|
|
+ return handle_conversation_started (session_relay, connection, message);
|
|
}
|
|
|
|
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
|
@@ -749,7 +756,8 @@ do_introspect (DBusConnection *connection,
|
|
/* interface */
|
|
xml = g_string_append (xml,
|
|
" <interface name=\"org.gnome.DisplayManager.SessionRelay\">\n"
|
|
- " <method name=\"Opened\">\n"
|
|
+ " <method name=\"ConversationStarted\">\n"
|
|
+ " <arg name=\"service_name\" direction=\"in\" type=\"s\"/>\n"
|
|
" </method>\n"
|
|
" <method name=\"SetupComplete\">\n"
|
|
" </method>\n"
|
|
@@ -810,7 +818,8 @@ do_introspect (DBusConnection *connection,
|
|
" <signal name=\"RefreshCredentials\">\n"
|
|
" </signal>\n"
|
|
|
|
- " <signal name=\"Open\">\n"
|
|
+ " <signal name=\"StartConversation\">\n"
|
|
+ " <arg name=\"service_name\" type=\"s\"/>\n"
|
|
" </signal>\n"
|
|
" <signal name=\"Close\">\n"
|
|
" </signal>\n"
|
|
@@ -1106,7 +1115,7 @@ static void
|
|
gdm_session_iface_init (GdmSessionIface *iface)
|
|
{
|
|
|
|
- iface->open = gdm_session_relay_open;
|
|
+ iface->start_conversation = gdm_session_relay_start_conversation;
|
|
iface->setup = gdm_session_relay_setup;
|
|
iface->setup_for_user = gdm_session_relay_setup_for_user;
|
|
iface->authenticate = gdm_session_relay_authenticate;
|
|
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
|
|
index feb7938..0073294 100644
|
|
--- a/daemon/gdm-session.c
|
|
+++ b/daemon/gdm-session.c
|
|
@@ -28,7 +28,7 @@
|
|
#include "gdm-session-private.h"
|
|
|
|
enum {
|
|
- OPENED = 0,
|
|
+ CONVERSATION_STARTED = 0,
|
|
SETUP_COMPLETE,
|
|
SETUP_FAILED,
|
|
RESET_COMPLETE,
|
|
@@ -78,11 +78,12 @@ gdm_session_get_type (void)
|
|
}
|
|
|
|
void
|
|
-gdm_session_open (GdmSession *session)
|
|
+gdm_session_start_conversation (GdmSession *session,
|
|
+ const char *service_name)
|
|
{
|
|
g_return_if_fail (GDM_IS_SESSION (session));
|
|
|
|
- GDM_SESSION_GET_IFACE (session)->open (session);
|
|
+ GDM_SESSION_GET_IFACE (session)->start_conversation (session, service_name);
|
|
}
|
|
|
|
void
|
|
@@ -203,14 +204,14 @@ gdm_session_class_init (gpointer g_iface)
|
|
{
|
|
GType iface_type = G_TYPE_FROM_INTERFACE (g_iface);
|
|
|
|
- signals [OPENED] =
|
|
- g_signal_new ("opened",
|
|
+ signals [CONVERSATION_STARTED] =
|
|
+ g_signal_new ("conversation-started",
|
|
iface_type,
|
|
G_SIGNAL_RUN_FIRST,
|
|
- G_STRUCT_OFFSET (GdmSessionIface, opened),
|
|
+ G_STRUCT_OFFSET (GdmSessionIface, conversation_started),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__VOID,
|
|
+ g_cclosure_marshal_VOID__STRING,
|
|
G_TYPE_NONE,
|
|
0);
|
|
signals [SETUP_COMPLETE] =
|
|
@@ -608,10 +609,11 @@ _gdm_session_session_died (GdmSession *session,
|
|
}
|
|
|
|
void
|
|
-_gdm_session_opened (GdmSession *session)
|
|
+_gdm_session_conversation_started (GdmSession *session,
|
|
+ const char *service_name)
|
|
{
|
|
g_return_if_fail (GDM_IS_SESSION (session));
|
|
- g_signal_emit (session, signals [OPENED], 0);
|
|
+ g_signal_emit (session, signals [CONVERSATION_STARTED], 0, service_name);
|
|
}
|
|
|
|
void
|
|
diff --git a/daemon/gdm-session.h b/daemon/gdm-session.h
|
|
index dfb7e27..77e0cf6 100644
|
|
--- a/daemon/gdm-session.h
|
|
+++ b/daemon/gdm-session.h
|
|
@@ -45,7 +45,8 @@ struct _GdmSessionIface
|
|
GTypeInterface base_iface;
|
|
|
|
/* Methods */
|
|
- void (* open) (GdmSession *session);
|
|
+ void (* start_conversation) (GdmSession *session,
|
|
+ const char *service_name);
|
|
void (* setup) (GdmSession *session,
|
|
const char *service_name);
|
|
void (* setup_for_user) (GdmSession *session,
|
|
@@ -103,7 +104,8 @@ struct _GdmSessionIface
|
|
int exit_code);
|
|
void (* session_died) (GdmSession *session,
|
|
int signal_number);
|
|
- void (* opened) (GdmSession *session);
|
|
+ void (* conversation_started) (GdmSession *session,
|
|
+ const char *service_name);
|
|
void (* closed) (GdmSession *session);
|
|
void (* selected_user_changed) (GdmSession *session,
|
|
const char *text);
|
|
@@ -118,7 +120,8 @@ struct _GdmSessionIface
|
|
|
|
GType gdm_session_get_type (void) G_GNUC_CONST;
|
|
|
|
-void gdm_session_open (GdmSession *session);
|
|
+void gdm_session_start_conversation (GdmSession *session,
|
|
+ const char *service_name);
|
|
void gdm_session_setup (GdmSession *session,
|
|
const char *service_name);
|
|
void gdm_session_setup_for_user (GdmSession *session,
|
|
diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c
|
|
index 6a00931..111d4cf 100644
|
|
--- a/daemon/gdm-simple-slave.c
|
|
+++ b/daemon/gdm-simple-slave.c
|
|
@@ -171,7 +171,6 @@ reset_session (GdmSimpleSlave *slave)
|
|
{
|
|
destroy_session (slave);
|
|
create_new_session (slave);
|
|
- gdm_session_open (GDM_SESSION (slave->priv->session));
|
|
}
|
|
|
|
static gboolean
|
|
@@ -813,8 +812,6 @@ on_greeter_connected (GdmGreeterServer *greeter_server,
|
|
|
|
g_debug ("GdmSimpleSlave: Greeter connected");
|
|
|
|
- gdm_session_open (GDM_SESSION (slave->priv->session));
|
|
-
|
|
g_object_get (slave,
|
|
"display-is-local", &display_is_local,
|
|
NULL);
|
|
diff --git a/daemon/test-session.c b/daemon/test-session.c
|
|
index c6a158c..d9fa26e 100644
|
|
--- a/daemon/test-session.c
|
|
+++ b/daemon/test-session.c
|
|
@@ -33,12 +33,13 @@
|
|
static GMainLoop *loop;
|
|
|
|
static void
|
|
-on_open (GdmSession *session,
|
|
- const char *username)
|
|
+on_conversation_started (GdmSession *session,
|
|
+ const char *service_name,
|
|
+ const char *username)
|
|
{
|
|
g_debug ("Got opened: calling setup...");
|
|
|
|
- gdm_session_setup (session, "gdm");
|
|
+ gdm_session_setup (session, service_name);
|
|
}
|
|
|
|
static void
|
|
@@ -256,11 +257,11 @@ main (int argc,
|
|
username = argv[1];
|
|
}
|
|
|
|
- gdm_session_open (GDM_SESSION (session));
|
|
+ gdm_session_start_conversation (GDM_SESSION (session), "gdm");
|
|
|
|
g_signal_connect (session,
|
|
- "opened",
|
|
- G_CALLBACK (on_open),
|
|
+ "conversation-started",
|
|
+ G_CALLBACK (on_conversation_started),
|
|
username);
|
|
g_signal_connect (session,
|
|
"setup-complete",
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 6a9f8abd1dfc0a2995935652669c32dd8e598ed2 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Fri, 16 Jan 2009 13:01:48 -0500
|
|
Subject: [PATCH 02/65] Make greeter explicitly request PAM conversation
|
|
|
|
Now the greeter has to say what PAM stack it wants the slave to
|
|
run. When that stack is ready, we emit the Ready signal as
|
|
before, but now the Ready signal carries a string argument
|
|
saying which service is ready to converse.
|
|
|
|
When we support multiple PAM stacks, the greeter will call
|
|
StartConversation for each stack, and will keep the UI
|
|
associated with each stack disabled until the Ready signals
|
|
come back one-by-one.
|
|
---
|
|
daemon/gdm-factory-slave.c | 3 +-
|
|
daemon/gdm-greeter-server.c | 53 ++++++++++++++++++++++++++++--
|
|
daemon/gdm-greeter-server.h | 5 ++-
|
|
daemon/gdm-simple-slave.c | 30 +++++++++++++---
|
|
gui/simple-greeter/gdm-greeter-client.c | 18 ++++++----
|
|
gui/simple-greeter/gdm-greeter-client.h | 4 ++-
|
|
gui/simple-greeter/gdm-greeter-session.c | 3 ++
|
|
7 files changed, 97 insertions(+), 19 deletions(-)
|
|
|
|
diff --git a/daemon/gdm-factory-slave.c b/daemon/gdm-factory-slave.c
|
|
index 6497293..d1bb5dd 100644
|
|
--- a/daemon/gdm-factory-slave.c
|
|
+++ b/daemon/gdm-factory-slave.c
|
|
@@ -186,7 +186,8 @@ on_session_conversation_started (GdmSession *session,
|
|
{
|
|
g_debug ("GdmFactorySlave: session conversation started");
|
|
|
|
- gdm_greeter_server_ready (slave->priv->greeter_server);
|
|
+ gdm_greeter_server_ready (slave->priv->greeter_server,
|
|
+ service_name);
|
|
}
|
|
|
|
static void
|
|
diff --git a/daemon/gdm-greeter-server.c b/daemon/gdm-greeter-server.c
|
|
index 2e01d33..06c80a0 100644
|
|
--- a/daemon/gdm-greeter-server.c
|
|
+++ b/daemon/gdm-greeter-server.c
|
|
@@ -69,6 +69,7 @@ enum {
|
|
};
|
|
|
|
enum {
|
|
+ START_CONVERSATION,
|
|
BEGIN_AUTO_LOGIN,
|
|
BEGIN_VERIFICATION,
|
|
BEGIN_VERIFICATION_FOR_USER,
|
|
@@ -246,9 +247,10 @@ gdm_greeter_server_reset (GdmGreeterServer *greeter_server)
|
|
}
|
|
|
|
gboolean
|
|
-gdm_greeter_server_ready (GdmGreeterServer *greeter_server)
|
|
+gdm_greeter_server_ready (GdmGreeterServer *greeter_server,
|
|
+ const char *service_name)
|
|
{
|
|
- send_dbus_void_signal (greeter_server, "Ready");
|
|
+ send_dbus_string_signal (greeter_server, "Ready", service_name);
|
|
return TRUE;
|
|
}
|
|
|
|
@@ -323,6 +325,34 @@ generate_address (void)
|
|
}
|
|
|
|
static DBusHandlerResult
|
|
+handle_start_conversation (GdmGreeterServer *greeter_server,
|
|
+ DBusConnection *connection,
|
|
+ DBusMessage *message)
|
|
+{
|
|
+ DBusMessage *reply;
|
|
+ DBusError error;
|
|
+ const char *service_name;
|
|
+
|
|
+ dbus_error_init (&error);
|
|
+ if (! dbus_message_get_args (message, &error,
|
|
+ DBUS_TYPE_STRING, &service_name,
|
|
+ DBUS_TYPE_INVALID)) {
|
|
+ g_warning ("ERROR: %s", error.message);
|
|
+ }
|
|
+ dbus_error_free (&error);
|
|
+
|
|
+ g_debug ("GreeterServer: StartConversation");
|
|
+
|
|
+ reply = dbus_message_new_method_return (message);
|
|
+ dbus_connection_send (connection, reply, NULL);
|
|
+ dbus_message_unref (reply);
|
|
+
|
|
+ g_signal_emit (greeter_server, signals [START_CONVERSATION], 0, service_name);
|
|
+
|
|
+ return DBUS_HANDLER_RESULT_HANDLED;
|
|
+}
|
|
+
|
|
+static DBusHandlerResult
|
|
handle_begin_verification (GdmGreeterServer *greeter_server,
|
|
DBusConnection *connection,
|
|
DBusMessage *message)
|
|
@@ -645,7 +675,9 @@ greeter_handle_child_message (DBusConnection *connection,
|
|
{
|
|
GdmGreeterServer *greeter_server = GDM_GREETER_SERVER (user_data);
|
|
|
|
- if (dbus_message_is_method_call (message, GDM_GREETER_SERVER_DBUS_INTERFACE, "BeginVerification")) {
|
|
+ if (dbus_message_is_method_call (message, GDM_GREETER_SERVER_DBUS_INTERFACE, "StartConversation")) {
|
|
+ return handle_start_conversation (greeter_server, connection, message);
|
|
+ } else if (dbus_message_is_method_call (message, GDM_GREETER_SERVER_DBUS_INTERFACE, "BeginVerification")) {
|
|
return handle_begin_verification (greeter_server, connection, message);
|
|
} else if (dbus_message_is_method_call (message, GDM_GREETER_SERVER_DBUS_INTERFACE, "BeginVerificationForUser")) {
|
|
return handle_begin_verification_for_user (greeter_server, connection, message);
|
|
@@ -699,7 +731,11 @@ do_introspect (DBusConnection *connection,
|
|
/* interface */
|
|
xml = g_string_append (xml,
|
|
" <interface name=\"org.gnome.DisplayManager.GreeterServer\">\n"
|
|
+ " <method name=\"StartConversation\">\n"
|
|
+ " <arg name=\"service_name\" direction=\"in\" type=\"s\"/>\n"
|
|
+ " </method>\n"
|
|
" <method name=\"BeginVerification\">\n"
|
|
+ " </method>\n"
|
|
" <method name=\"BeginTimedLogin\">\n"
|
|
" </method>\n"
|
|
" <method name=\"BeginVerificationForUser\">\n"
|
|
@@ -760,6 +796,7 @@ do_introspect (DBusConnection *connection,
|
|
" <arg name=\"delay\" type=\"i\"/>\n"
|
|
" </signal>\n"
|
|
" <signal name=\"Ready\">\n"
|
|
+ " <arg name=\"service-name\" type=\"s\"/>\n"
|
|
" </signal>\n"
|
|
" <signal name=\"Reset\">\n"
|
|
" </signal>\n"
|
|
@@ -1122,6 +1159,16 @@ gdm_greeter_server_class_init (GdmGreeterServerClass *klass)
|
|
"group name",
|
|
GDM_GROUPNAME,
|
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
|
|
+ signals [START_CONVERSATION] =
|
|
+ g_signal_new ("start-conversation",
|
|
+ G_OBJECT_CLASS_TYPE (object_class),
|
|
+ G_SIGNAL_RUN_FIRST,
|
|
+ G_STRUCT_OFFSET (GdmGreeterServerClass, start_conversation),
|
|
+ NULL,
|
|
+ NULL,
|
|
+ g_cclosure_marshal_VOID__STRING,
|
|
+ G_TYPE_NONE,
|
|
+ 1, G_TYPE_STRING);
|
|
signals [BEGIN_VERIFICATION] =
|
|
g_signal_new ("begin-verification",
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
diff --git a/daemon/gdm-greeter-server.h b/daemon/gdm-greeter-server.h
|
|
index 6e92100..7333db1 100644
|
|
--- a/daemon/gdm-greeter-server.h
|
|
+++ b/daemon/gdm-greeter-server.h
|
|
@@ -45,6 +45,8 @@ typedef struct
|
|
{
|
|
GObjectClass parent_class;
|
|
|
|
+ void (* start_conversation) (GdmGreeterServer *greeter_server,
|
|
+ const char *service_name);
|
|
void (* begin_auto_login) (GdmGreeterServer *greeter_server);
|
|
void (* begin_verification) (GdmGreeterServer *greeter_server);
|
|
void (* begin_verification_for_user)(GdmGreeterServer *greeter_server,
|
|
@@ -85,7 +87,8 @@ gboolean gdm_greeter_server_info (GdmGreeterServer *
|
|
gboolean gdm_greeter_server_problem (GdmGreeterServer *greeter_server,
|
|
const char *text);
|
|
gboolean gdm_greeter_server_reset (GdmGreeterServer *greeter_server);
|
|
-gboolean gdm_greeter_server_ready (GdmGreeterServer *greeter_server);
|
|
+gboolean gdm_greeter_server_ready (GdmGreeterServer *greeter_server,
|
|
+ const char *service_name);
|
|
void gdm_greeter_server_selected_user_changed (GdmGreeterServer *greeter_server,
|
|
const char *text);
|
|
void gdm_greeter_server_default_language_name_changed (GdmGreeterServer *greeter_server,
|
|
diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c
|
|
index 111d4cf..eab5c8d 100644
|
|
--- a/daemon/gdm-simple-slave.c
|
|
+++ b/daemon/gdm-simple-slave.c
|
|
@@ -475,8 +475,9 @@ on_session_secret_info_query (GdmSession *session,
|
|
}
|
|
|
|
static void
|
|
-on_session_opened (GdmSession *session,
|
|
- GdmSimpleSlave *slave)
|
|
+on_session_conversation_started (GdmSession *session,
|
|
+ const char *service_name,
|
|
+ GdmSimpleSlave *slave)
|
|
{
|
|
gboolean res;
|
|
gboolean enabled;
|
|
@@ -485,7 +486,8 @@ on_session_opened (GdmSession *session,
|
|
|
|
g_debug ("GdmSimpleSlave: session opened");
|
|
if (slave->priv->greeter_server != NULL) {
|
|
- res = gdm_greeter_server_ready (slave->priv->greeter_server);
|
|
+ res = gdm_greeter_server_ready (slave->priv->greeter_server,
|
|
+ service_name);
|
|
if (! res) {
|
|
g_warning ("Unable to send ready");
|
|
}
|
|
@@ -501,8 +503,10 @@ on_session_opened (GdmSession *session,
|
|
gdm_greeter_server_request_timed_login (slave->priv->greeter_server, username, delay);
|
|
} else {
|
|
g_debug ("GdmSimpleSlave: begin auto login for user '%s'", username);
|
|
+ /* service_name will be "gdm-autologin"
|
|
+ */
|
|
gdm_session_setup_for_user (GDM_SESSION (slave->priv->session),
|
|
- "gdm-autologin",
|
|
+ service_name,
|
|
username);
|
|
}
|
|
|
|
@@ -594,8 +598,8 @@ create_new_session (GdmSimpleSlave *slave)
|
|
g_free (display_hostname);
|
|
|
|
g_signal_connect (slave->priv->session,
|
|
- "opened",
|
|
- G_CALLBACK (on_session_opened),
|
|
+ "conversation-started",
|
|
+ G_CALLBACK (on_session_conversation_started),
|
|
slave);
|
|
g_signal_connect (slave->priv->session,
|
|
"setup-complete",
|
|
@@ -726,6 +730,16 @@ on_greeter_session_died (GdmGreeterSession *greeter,
|
|
}
|
|
|
|
static void
|
|
+on_greeter_start_conversation (GdmGreeterServer *greeter_server,
|
|
+ const char *service_name,
|
|
+ GdmSimpleSlave *slave)
|
|
+{
|
|
+ g_debug ("GdmSimpleSlave: starting conversation with '%s' pam service'", service_name);
|
|
+ gdm_session_start_conversation (GDM_SESSION (slave->priv->session),
|
|
+ service_name);
|
|
+}
|
|
+
|
|
+static void
|
|
on_greeter_begin_verification (GdmGreeterServer *greeter_server,
|
|
GdmSimpleSlave *slave)
|
|
{
|
|
@@ -895,6 +909,10 @@ start_greeter (GdmSimpleSlave *slave)
|
|
|
|
slave->priv->greeter_server = gdm_greeter_server_new (display_id);
|
|
g_signal_connect (slave->priv->greeter_server,
|
|
+ "start-conversation",
|
|
+ G_CALLBACK (on_greeter_start_conversation),
|
|
+ slave);
|
|
+ g_signal_connect (slave->priv->greeter_server,
|
|
"begin-auto-login",
|
|
G_CALLBACK (on_greeter_begin_auto_login),
|
|
slave);
|
|
diff --git a/gui/simple-greeter/gdm-greeter-client.c b/gui/simple-greeter/gdm-greeter-client.c
|
|
index 461b85c..1e2c55d 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-client.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-client.c
|
|
@@ -237,11 +237,7 @@ static void
|
|
on_ready (GdmGreeterClient *client,
|
|
DBusMessage *message)
|
|
{
|
|
- g_debug ("GdmGreeterClient: Ready");
|
|
-
|
|
- g_signal_emit (client,
|
|
- gdm_greeter_client_signals[READY],
|
|
- 0);
|
|
+ emit_string_signal_for_message (client, "Ready", message, READY);
|
|
}
|
|
|
|
static void
|
|
@@ -400,6 +396,14 @@ send_dbus_void_method (DBusConnection *connection,
|
|
}
|
|
|
|
void
|
|
+gdm_greeter_client_call_start_conversation (GdmGreeterClient *client,
|
|
+ const char *service_name)
|
|
+{
|
|
+ send_dbus_string_method (client->priv->connection,
|
|
+ "StartConversation", service_name);
|
|
+}
|
|
+
|
|
+void
|
|
gdm_greeter_client_call_begin_auto_login (GdmGreeterClient *client,
|
|
const char *username)
|
|
{
|
|
@@ -879,9 +883,9 @@ gdm_greeter_client_class_init (GdmGreeterClientClass *klass)
|
|
G_STRUCT_OFFSET (GdmGreeterClientClass, ready),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__VOID,
|
|
+ g_cclosure_marshal_VOID__STRING,
|
|
G_TYPE_NONE,
|
|
- 0);
|
|
+ 1, G_TYPE_STRING);
|
|
|
|
gdm_greeter_client_signals[RESET] =
|
|
g_signal_new ("reset",
|
|
diff --git a/gui/simple-greeter/gdm-greeter-client.h b/gui/simple-greeter/gdm-greeter-client.h
|
|
index 08deabd..88b0281 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-client.h
|
|
+++ b/gui/simple-greeter/gdm-greeter-client.h
|
|
@@ -84,13 +84,15 @@ GQuark gdm_greeter_client_error_quark (void);
|
|
GdmGreeterClient * gdm_greeter_client_new (void);
|
|
|
|
gboolean gdm_greeter_client_start (GdmGreeterClient *client,
|
|
- GError **error);
|
|
+ GError **error);
|
|
void gdm_greeter_client_stop (GdmGreeterClient *client);
|
|
|
|
gboolean gdm_greeter_client_get_display_is_local (GdmGreeterClient *client);
|
|
|
|
char * gdm_greeter_client_call_get_display_id (GdmGreeterClient *client);
|
|
|
|
+void gdm_greeter_client_call_start_conversation (GdmGreeterClient *client,
|
|
+ const char *service_name);
|
|
void gdm_greeter_client_call_begin_auto_login (GdmGreeterClient *client,
|
|
const char *username);
|
|
void gdm_greeter_client_call_begin_verification (GdmGreeterClient *client);
|
|
diff --git a/gui/simple-greeter/gdm-greeter-session.c b/gui/simple-greeter/gdm-greeter-session.c
|
|
index 83375b2..8681828 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-session.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-session.c
|
|
@@ -84,6 +84,7 @@ on_problem (GdmGreeterClient *client,
|
|
|
|
static void
|
|
on_ready (GdmGreeterClient *client,
|
|
+ const char *service_name,
|
|
GdmGreeterSession *session)
|
|
{
|
|
g_debug ("GdmGreeterSession: Ready");
|
|
@@ -377,6 +378,8 @@ gdm_greeter_session_start (GdmGreeterSession *session,
|
|
toggle_panel (session, TRUE);
|
|
toggle_login_window (session, TRUE);
|
|
|
|
+ gdm_greeter_client_call_start_conversation (session->priv->client, "gdm");
|
|
+
|
|
gdm_profile_end (NULL);
|
|
|
|
return res;
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From ed43a24257accc3996fab4cdf7d1bc99a03ea219 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Fri, 16 Jan 2009 13:55:48 -0500
|
|
Subject: [PATCH 03/65] Refactor send_dbus_ functions in session-direct
|
|
|
|
Previously they were in terms of the session or
|
|
dbus connection, but we really want them in terms
|
|
of the conversation.
|
|
---
|
|
daemon/gdm-session-direct.c | 64 +++++++++++++++++++++++++------------------
|
|
1 files changed, 37 insertions(+), 27 deletions(-)
|
|
|
|
diff --git a/daemon/gdm-session-direct.c b/daemon/gdm-session-direct.c
|
|
index a76051b..c392ae6 100644
|
|
--- a/daemon/gdm-session-direct.c
|
|
+++ b/daemon/gdm-session-direct.c
|
|
@@ -124,40 +124,39 @@ G_DEFINE_TYPE_WITH_CODE (GdmSessionDirect,
|
|
gdm_session_iface_init))
|
|
|
|
static gboolean
|
|
-send_dbus_message (DBusConnection *connection,
|
|
- DBusMessage *message)
|
|
+send_dbus_message (GdmSessionConversation *conversation,
|
|
+ DBusMessage *message)
|
|
{
|
|
gboolean is_connected;
|
|
gboolean sent;
|
|
|
|
g_return_val_if_fail (message != NULL, FALSE);
|
|
|
|
- if (connection == NULL) {
|
|
+ if (conversation->worker_connection == NULL) {
|
|
g_warning ("There is no valid connection");
|
|
return FALSE;
|
|
}
|
|
|
|
- is_connected = dbus_connection_get_is_connected (connection);
|
|
+ is_connected = dbus_connection_get_is_connected (conversation->worker_connection);
|
|
if (! is_connected) {
|
|
g_warning ("Not connected!");
|
|
return FALSE;
|
|
}
|
|
|
|
- sent = dbus_connection_send (connection, message, NULL);
|
|
+ sent = dbus_connection_send (conversation->worker_connection, message, NULL);
|
|
|
|
return sent;
|
|
}
|
|
|
|
static void
|
|
-send_dbus_string_signal (GdmSessionDirect *session,
|
|
+send_dbus_string_signal (GdmSessionConversation *conversation,
|
|
const char *name,
|
|
const char *text)
|
|
{
|
|
DBusMessage *message;
|
|
DBusMessageIter iter;
|
|
- GdmSessionConversation *conversation;
|
|
|
|
- g_return_if_fail (session != NULL);
|
|
+ g_return_if_fail (conversation != NULL);
|
|
|
|
message = dbus_message_new_signal (GDM_SESSION_DBUS_PATH,
|
|
GDM_SESSION_DBUS_INTERFACE,
|
|
@@ -166,8 +165,7 @@ send_dbus_string_signal (GdmSessionDirect *session,
|
|
dbus_message_iter_init_append (message, &iter);
|
|
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &text);
|
|
|
|
- conversation = session->priv->conversation;
|
|
- if (! send_dbus_message (conversation->worker_connection, message)) {
|
|
+ if (! send_dbus_message (conversation, message)) {
|
|
g_debug ("GdmSessionDirect: Could not send %s signal", name);
|
|
}
|
|
|
|
@@ -175,20 +173,18 @@ send_dbus_string_signal (GdmSessionDirect *session,
|
|
}
|
|
|
|
static void
|
|
-send_dbus_void_signal (GdmSessionDirect *session,
|
|
- const char *name)
|
|
+send_dbus_void_signal (GdmSessionConversation *conversation,
|
|
+ const char *name)
|
|
{
|
|
DBusMessage *message;
|
|
- GdmSessionConversation *conversation;
|
|
|
|
- g_return_if_fail (session != NULL);
|
|
+ g_return_if_fail (conversation != NULL);
|
|
|
|
message = dbus_message_new_signal (GDM_SESSION_DBUS_PATH,
|
|
GDM_SESSION_DBUS_INTERFACE,
|
|
name);
|
|
|
|
- conversation = session->priv->conversation;
|
|
- if (! send_dbus_message (conversation->worker_connection, message)) {
|
|
+ if (! send_dbus_message (conversation, message)) {
|
|
g_debug ("GdmSessionDirect: Could not send %s signal", name);
|
|
}
|
|
|
|
@@ -1764,7 +1760,7 @@ send_setup (GdmSessionDirect *session,
|
|
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_x11_authority_file);
|
|
|
|
conversation = session->priv->conversation;
|
|
- if (! send_dbus_message (conversation->worker_connection, message)) {
|
|
+ if (! send_dbus_message (conversation, message)) {
|
|
g_debug ("GdmSessionDirect: Could not send %s signal", "Setup");
|
|
}
|
|
|
|
@@ -1827,7 +1823,7 @@ send_setup_for_user (GdmSessionDirect *session,
|
|
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &selected_user);
|
|
|
|
conversation = session->priv->conversation;
|
|
- if (! send_dbus_message (conversation->worker_connection, message)) {
|
|
+ if (! send_dbus_message (conversation, message)) {
|
|
g_debug ("GdmSessionDirect: Could not send %s signal", "SetupForUser");
|
|
}
|
|
|
|
@@ -1870,24 +1866,28 @@ static void
|
|
gdm_session_direct_authenticate (GdmSession *session)
|
|
{
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
+ GdmSessionConversation *conversation;
|
|
|
|
g_return_if_fail (session != NULL);
|
|
g_return_if_fail (impl->priv->conversation != NULL);
|
|
g_return_if_fail (dbus_connection_get_is_connected (impl->priv->conversation->worker_connection));
|
|
|
|
- send_dbus_void_signal (impl, "Authenticate");
|
|
+ conversation = impl->priv->conversation;
|
|
+ send_dbus_void_signal (conversation, "Authenticate");
|
|
}
|
|
|
|
static void
|
|
gdm_session_direct_authorize (GdmSession *session)
|
|
{
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
+ GdmSessionConversation *conversation;
|
|
|
|
g_return_if_fail (session != NULL);
|
|
g_return_if_fail (impl->priv->conversation != NULL);
|
|
g_return_if_fail (dbus_connection_get_is_connected (impl->priv->conversation->worker_connection));
|
|
|
|
- send_dbus_void_signal (impl, "Authorize");
|
|
+ conversation = impl->priv->conversation;
|
|
+ send_dbus_void_signal (conversation, "Authorize");
|
|
}
|
|
|
|
static void
|
|
@@ -1895,17 +1895,19 @@ gdm_session_direct_accredit (GdmSession *session,
|
|
int cred_flag)
|
|
{
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
+ GdmSessionConversation *conversation;
|
|
|
|
g_return_if_fail (session != NULL);
|
|
g_return_if_fail (impl->priv->conversation != NULL);
|
|
g_return_if_fail (dbus_connection_get_is_connected (impl->priv->conversation->worker_connection));
|
|
|
|
+ conversation = impl->priv->conversation;
|
|
switch (cred_flag) {
|
|
case GDM_SESSION_CRED_ESTABLISH:
|
|
- send_dbus_void_signal (impl, "EstablishCredentials");
|
|
+ send_dbus_void_signal (conversation, "EstablishCredentials");
|
|
break;
|
|
case GDM_SESSION_CRED_REFRESH:
|
|
- send_dbus_void_signal (impl, "RefreshCredentials");
|
|
+ send_dbus_void_signal (conversation, "RefreshCredentials");
|
|
break;
|
|
default:
|
|
g_assert_not_reached ();
|
|
@@ -1930,7 +1932,7 @@ send_environment_variable (const char *key,
|
|
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value);
|
|
|
|
conversation = session->priv->conversation;
|
|
- if (! send_dbus_message (conversation->worker_connection, message)) {
|
|
+ if (! send_dbus_message (conversation, message)) {
|
|
g_debug ("GdmSessionDirect: Could not send %s signal", "SetEnvironmentVariable");
|
|
}
|
|
|
|
@@ -2060,6 +2062,7 @@ static void
|
|
gdm_session_direct_start_session (GdmSession *session)
|
|
{
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
+ GdmSessionConversation *conversation;
|
|
char *command;
|
|
char *program;
|
|
|
|
@@ -2073,7 +2076,8 @@ gdm_session_direct_start_session (GdmSession *session)
|
|
setup_session_environment (impl);
|
|
send_environment (impl);
|
|
|
|
- send_dbus_string_signal (impl, "StartProgram", program);
|
|
+ conversation = impl->priv->conversation;
|
|
+ send_dbus_string_signal (conversation, "StartProgram", program);
|
|
g_free (program);
|
|
}
|
|
|
|
@@ -2163,6 +2167,7 @@ gdm_session_direct_select_session (GdmSession *session,
|
|
const char *text)
|
|
{
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
+ GdmSessionConversation *conversation;
|
|
|
|
g_free (impl->priv->selected_session);
|
|
|
|
@@ -2172,7 +2177,8 @@ gdm_session_direct_select_session (GdmSession *session,
|
|
impl->priv->selected_session = g_strdup (text);
|
|
}
|
|
|
|
- send_dbus_string_signal (impl, "SetSessionName",
|
|
+ conversation = impl->priv->conversation;
|
|
+ send_dbus_string_signal (conversation, "SetSessionName",
|
|
get_session_name (impl));
|
|
}
|
|
|
|
@@ -2181,6 +2187,7 @@ gdm_session_direct_select_language (GdmSession *session,
|
|
const char *text)
|
|
{
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
+ GdmSessionConversation *conversation;
|
|
|
|
g_free (impl->priv->selected_language);
|
|
|
|
@@ -2190,7 +2197,8 @@ gdm_session_direct_select_language (GdmSession *session,
|
|
impl->priv->selected_language = g_strdup (text);
|
|
}
|
|
|
|
- send_dbus_string_signal (impl, "SetLanguageName",
|
|
+ conversation = impl->priv->conversation;
|
|
+ send_dbus_string_signal (conversation, "SetLanguageName",
|
|
get_language_name (impl));
|
|
}
|
|
|
|
@@ -2199,6 +2207,7 @@ gdm_session_direct_select_layout (GdmSession *session,
|
|
const char *text)
|
|
{
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
+ GdmSessionConversation *conversation;
|
|
|
|
g_free (impl->priv->selected_layout);
|
|
|
|
@@ -2208,7 +2217,8 @@ gdm_session_direct_select_layout (GdmSession *session,
|
|
impl->priv->selected_layout = g_strdup (text);
|
|
}
|
|
|
|
- send_dbus_string_signal (impl, "SetLayoutName",
|
|
+ conversation = impl->priv->conversation;
|
|
+ send_dbus_string_signal (conversation, "SetLayoutName",
|
|
get_layout_name (impl));
|
|
}
|
|
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From dd908a665638a10a6df281eee764ca9a131ab95b Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Fri, 16 Jan 2009 13:57:04 -0500
|
|
Subject: [PATCH 04/65] Clean up stop_conversation
|
|
|
|
We now keep a pointer to the session object around
|
|
separate from the conversation. This is so we
|
|
can free it but still get at the session.
|
|
---
|
|
daemon/gdm-session-direct.c | 6 +++++-
|
|
1 files changed, 5 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/daemon/gdm-session-direct.c b/daemon/gdm-session-direct.c
|
|
index c392ae6..59f3fd6 100644
|
|
--- a/daemon/gdm-session-direct.c
|
|
+++ b/daemon/gdm-session-direct.c
|
|
@@ -1672,6 +1672,10 @@ start_conversation (GdmSessionDirect *session,
|
|
static void
|
|
stop_conversation (GdmSessionConversation *conversation)
|
|
{
|
|
+ GdmSessionDirect *session;
|
|
+
|
|
+ session = conversation->session;
|
|
+
|
|
g_signal_handlers_disconnect_by_func (conversation->job,
|
|
G_CALLBACK (worker_stopped),
|
|
conversation);
|
|
@@ -1685,7 +1689,7 @@ stop_conversation (GdmSessionConversation *conversation)
|
|
G_CALLBACK (worker_died),
|
|
conversation);
|
|
|
|
- cancel_pending_query (conversation->session);
|
|
+ cancel_pending_query (session);
|
|
|
|
if (conversation->worker_connection != NULL) {
|
|
dbus_connection_close (conversation->worker_connection);
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From d17f2ffa75d51a0bcec99ebce110a15a3c792ec3 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Fri, 16 Jan 2009 14:28:58 -0500
|
|
Subject: [PATCH 05/65] Properly record worker pid when starting job
|
|
|
|
We had the variable but we weren't initializing
|
|
it and we need it.
|
|
---
|
|
daemon/gdm-session-direct.c | 2 ++
|
|
daemon/gdm-session-worker-job.c | 7 +++++++
|
|
daemon/gdm-session-worker-job.h | 2 ++
|
|
3 files changed, 11 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/daemon/gdm-session-direct.c b/daemon/gdm-session-direct.c
|
|
index 59f3fd6..1ddef8c 100644
|
|
--- a/daemon/gdm-session-direct.c
|
|
+++ b/daemon/gdm-session-direct.c
|
|
@@ -1666,6 +1666,8 @@ start_conversation (GdmSessionDirect *session,
|
|
return NULL;
|
|
}
|
|
|
|
+ conversation->worker_pid = gdm_session_worker_job_get_pid (conversation->job);
|
|
+
|
|
return conversation;
|
|
}
|
|
|
|
diff --git a/daemon/gdm-session-worker-job.c b/daemon/gdm-session-worker-job.c
|
|
index bb30245..1a7cf36 100644
|
|
--- a/daemon/gdm-session-worker-job.c
|
|
+++ b/daemon/gdm-session-worker-job.c
|
|
@@ -270,6 +270,13 @@ gdm_session_worker_job_stop (GdmSessionWorkerJob *session_worker_job)
|
|
return TRUE;
|
|
}
|
|
|
|
+GPid
|
|
+gdm_session_worker_job_get_pid (GdmSessionWorkerJob *session_worker_job)
|
|
+{
|
|
+ g_return_if_fail (GDM_IS_SESSION_WORKER_JOB (session_worker_job));
|
|
+ return session_worker_job->priv->pid;
|
|
+}
|
|
+
|
|
void
|
|
gdm_session_worker_job_set_server_address (GdmSessionWorkerJob *session_worker_job,
|
|
const char *address)
|
|
diff --git a/daemon/gdm-session-worker-job.h b/daemon/gdm-session-worker-job.h
|
|
index d42eb37..9cb08ce 100644
|
|
--- a/daemon/gdm-session-worker-job.h
|
|
+++ b/daemon/gdm-session-worker-job.h
|
|
@@ -61,6 +61,8 @@ void gdm_session_worker_job_set_server_address (GdmSessionWor
|
|
gboolean gdm_session_worker_job_start (GdmSessionWorkerJob *session_worker_job);
|
|
gboolean gdm_session_worker_job_stop (GdmSessionWorkerJob *session_worker_job);
|
|
|
|
+GPid gdm_session_worker_job_get_pid (GdmSessionWorkerJob *session_worker_job);
|
|
+
|
|
G_END_DECLS
|
|
|
|
#endif /* __GDM_SESSION_WORKER_JOB_H */
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From e816e596e049420602d68655099255fca20d623c Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Fri, 16 Jan 2009 14:30:40 -0500
|
|
Subject: [PATCH 06/65] When starting session record its pid
|
|
|
|
When writing out logout records we need the
|
|
pid of the running session. We store that
|
|
on the session object when the session gets
|
|
started and write out the logout record when
|
|
the session ends.
|
|
---
|
|
daemon/gdm-session-direct.c | 34 +++++++++++++---------------------
|
|
1 files changed, 13 insertions(+), 21 deletions(-)
|
|
|
|
diff --git a/daemon/gdm-session-direct.c b/daemon/gdm-session-direct.c
|
|
index 1ddef8c..1d4ab63 100644
|
|
--- a/daemon/gdm-session-direct.c
|
|
+++ b/daemon/gdm-session-direct.c
|
|
@@ -88,6 +88,7 @@ struct _GdmSessionDirectPrivate
|
|
|
|
guint32 is_authenticated : 1;
|
|
guint32 is_running : 1;
|
|
+ GPid session_pid;
|
|
|
|
/* object lifetime scope */
|
|
char *id;
|
|
@@ -246,16 +247,12 @@ on_session_exited (GdmSession *session,
|
|
int exit_code)
|
|
{
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
- GdmSessionConversation *conversation;
|
|
|
|
- conversation = impl->priv->conversation;
|
|
- if (conversation != NULL) {
|
|
- gdm_session_record_logout (conversation->worker_pid,
|
|
- impl->priv->selected_user,
|
|
- impl->priv->display_hostname,
|
|
- impl->priv->display_name,
|
|
- impl->priv->display_device);
|
|
- }
|
|
+ gdm_session_record_logout (impl->priv->session_pid,
|
|
+ impl->priv->selected_user,
|
|
+ impl->priv->display_hostname,
|
|
+ impl->priv->display_name,
|
|
+ impl->priv->display_device);
|
|
}
|
|
|
|
static DBusHandlerResult
|
|
@@ -955,7 +952,7 @@ gdm_session_direct_handle_session_started (GdmSessionDirect *session,
|
|
g_debug ("GdmSessionDirect: Emitting 'session-started' signal with pid '%d'",
|
|
pid);
|
|
|
|
- session->priv->conversation->worker_pid = pid;
|
|
+ session->priv->session_pid = pid;
|
|
session->priv->is_running = TRUE;
|
|
|
|
_gdm_session_session_started (GDM_SESSION (session), pid);
|
|
@@ -2096,17 +2093,12 @@ gdm_session_direct_close (GdmSession *session)
|
|
|
|
g_debug ("GdmSessionDirect: Closing session");
|
|
|
|
- if (impl->priv->conversation != NULL) {
|
|
- if (impl->priv->is_running) {
|
|
- gdm_session_record_logout (impl->priv->conversation->worker_pid,
|
|
- impl->priv->selected_user,
|
|
- impl->priv->display_hostname,
|
|
- impl->priv->display_name,
|
|
- impl->priv->display_device);
|
|
- }
|
|
-
|
|
- stop_conversation (impl->priv->conversation);
|
|
- impl->priv->conversation = NULL;
|
|
+ if (impl->priv->is_running) {
|
|
+ gdm_session_record_logout (impl->priv->session_pid,
|
|
+ impl->priv->selected_user,
|
|
+ impl->priv->display_hostname,
|
|
+ impl->priv->display_name,
|
|
+ impl->priv->display_device);
|
|
}
|
|
|
|
g_free (impl->priv->selected_user);
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 1f60a95dc2d40f5f0ed9350cb5440ebd95b7654d Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Fri, 16 Jan 2009 15:18:31 -0500
|
|
Subject: [PATCH 07/65] Store multiple conversations in the session
|
|
|
|
We keep multiple conversations in the session now, keyed off of
|
|
PAM service is at the other end. Much of the guts still
|
|
only operate on the first conversation added though.
|
|
---
|
|
daemon/gdm-session-direct.c | 99 ++++++++++++++++++++++++++++++++++++++----
|
|
1 files changed, 89 insertions(+), 10 deletions(-)
|
|
|
|
diff --git a/daemon/gdm-session-direct.c b/daemon/gdm-session-direct.c
|
|
index 1d4ab63..5a93103 100644
|
|
--- a/daemon/gdm-session-direct.c
|
|
+++ b/daemon/gdm-session-direct.c
|
|
@@ -85,6 +85,7 @@ struct _GdmSessionDirectPrivate
|
|
DBusMessage *message_pending_reply;
|
|
|
|
GdmSessionConversation *conversation;
|
|
+ GHashTable *conversations;
|
|
|
|
guint32 is_authenticated : 1;
|
|
guint32 is_running : 1;
|
|
@@ -1462,6 +1463,42 @@ allow_user_function (DBusConnection *connection,
|
|
return FALSE;
|
|
}
|
|
|
|
+static GdmSessionConversation *
|
|
+find_conversation_by_name (GdmSessionDirect *session,
|
|
+ const char *service_name)
|
|
+{
|
|
+ GdmSessionConversation *conversation;
|
|
+
|
|
+ conversation = g_hash_table_lookup (session->priv->conversations, service_name);
|
|
+
|
|
+ if (conversation == NULL) {
|
|
+ g_warning ("Tried to look up non-existant conversation");
|
|
+ }
|
|
+
|
|
+ return conversation;
|
|
+}
|
|
+
|
|
+static GdmSessionConversation *
|
|
+find_conversation_by_pid (GdmSessionDirect *session,
|
|
+ GPid pid)
|
|
+{
|
|
+ GHashTableIter iter;
|
|
+ gpointer key, value;
|
|
+
|
|
+ g_hash_table_iter_init (&iter, session->priv->conversations);
|
|
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
|
|
+ GdmSessionConversation *conversation;
|
|
+
|
|
+ conversation = (GdmSessionConversation *) value;
|
|
+
|
|
+ if (conversation->worker_pid == pid) {
|
|
+ return conversation;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
static void
|
|
handle_connection (DBusServer *server,
|
|
DBusConnection *new_connection,
|
|
@@ -1469,10 +1506,22 @@ handle_connection (DBusServer *server,
|
|
{
|
|
GdmSessionDirect *session = GDM_SESSION_DIRECT (user_data);
|
|
GdmSessionConversation *conversation;
|
|
+ gulong pid;
|
|
|
|
g_debug ("GdmSessionDirect: Handing new connection");
|
|
|
|
- conversation = session->priv->conversation;
|
|
+ if (!dbus_connection_get_unix_process_id (new_connection, &pid)) {
|
|
+ g_warning ("Unable to read pid on new worker connection");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ conversation = find_conversation_by_pid (session, (GPid) pid);
|
|
+
|
|
+ if (conversation == NULL) {
|
|
+ g_warning ("New worker connection is from unknown source");
|
|
+ return;
|
|
+ }
|
|
+
|
|
if (conversation->worker_connection == NULL) {
|
|
DBusObjectPathVTable vtable = { &session_unregister_handler,
|
|
&session_message_handler,
|
|
@@ -1568,6 +1617,10 @@ gdm_session_direct_init (GdmSessionDirect *session)
|
|
G_CALLBACK (on_session_exited),
|
|
NULL);
|
|
|
|
+ session->priv->conversations = g_hash_table_new_full (g_str_hash,
|
|
+ g_str_equal,
|
|
+ (GDestroyNotify) g_free,
|
|
+ NULL);
|
|
session->priv->environment = g_hash_table_new_full (g_str_hash,
|
|
g_str_equal,
|
|
(GDestroyNotify) g_free,
|
|
@@ -1696,6 +1749,8 @@ stop_conversation (GdmSessionConversation *conversation)
|
|
}
|
|
|
|
gdm_session_worker_job_stop (conversation->job);
|
|
+ g_hash_table_remove (session->priv->conversations, conversation);
|
|
+
|
|
g_object_unref (conversation->job);
|
|
g_free (conversation->service_name);
|
|
g_free (conversation);
|
|
@@ -1706,12 +1761,20 @@ gdm_session_direct_start_conversation (GdmSession *session,
|
|
const char *service_name)
|
|
{
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
+ GdmSessionConversation *conversation;
|
|
|
|
g_return_if_fail (session != NULL);
|
|
|
|
g_debug ("GdmSessionDirect: starting conversation");
|
|
|
|
- impl->priv->conversation = start_conversation (impl, service_name);
|
|
+ conversation = start_conversation (impl, service_name);
|
|
+
|
|
+ g_hash_table_insert (impl->priv->conversations,
|
|
+ g_strdup (service_name), conversation);
|
|
+
|
|
+ if (impl->priv->conversation != NULL) {
|
|
+ impl->priv->conversation = conversation;
|
|
+ }
|
|
}
|
|
|
|
static void
|
|
@@ -1762,8 +1825,8 @@ send_setup (GdmSessionDirect *session,
|
|
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_hostname);
|
|
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_x11_authority_file);
|
|
|
|
- conversation = session->priv->conversation;
|
|
- if (! send_dbus_message (conversation, message)) {
|
|
+ conversation = find_conversation_by_name (session, service_name);
|
|
+ if (conversation != NULL && ! send_dbus_message (conversation, message)) {
|
|
g_debug ("GdmSessionDirect: Could not send %s signal", "Setup");
|
|
}
|
|
|
|
@@ -1825,8 +1888,8 @@ send_setup_for_user (GdmSessionDirect *session,
|
|
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &display_x11_authority_file);
|
|
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &selected_user);
|
|
|
|
- conversation = session->priv->conversation;
|
|
- if (! send_dbus_message (conversation, message)) {
|
|
+ conversation = find_conversation_by_name (session, service_name);
|
|
+ if (conversation != NULL && ! send_dbus_message (conversation, message)) {
|
|
g_debug ("GdmSessionDirect: Could not send %s signal", "SetupForUser");
|
|
}
|
|
|
|
@@ -1840,8 +1903,6 @@ gdm_session_direct_setup (GdmSession *session,
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
|
|
g_return_if_fail (session != NULL);
|
|
- g_return_if_fail (impl->priv->conversation != NULL);
|
|
- g_return_if_fail (dbus_connection_get_is_connected (impl->priv->conversation->worker_connection));
|
|
|
|
send_setup (impl, service_name);
|
|
gdm_session_direct_defaults_changed (impl);
|
|
@@ -1855,8 +1916,6 @@ gdm_session_direct_setup_for_user (GdmSession *session,
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
|
|
g_return_if_fail (session != NULL);
|
|
- g_return_if_fail (impl->priv->conversation != NULL);
|
|
- g_return_if_fail (dbus_connection_get_is_connected (impl->priv->conversation->worker_connection));
|
|
g_return_if_fail (username != NULL);
|
|
|
|
gdm_session_direct_select_user (session, username);
|
|
@@ -2085,6 +2144,24 @@ gdm_session_direct_start_session (GdmSession *session)
|
|
}
|
|
|
|
static void
|
|
+stop_all_conversations (GdmSessionDirect *session)
|
|
+{
|
|
+ GHashTableIter iter;
|
|
+ gpointer key, value;
|
|
+
|
|
+ g_hash_table_iter_init (&iter, session->priv->conversations);
|
|
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
|
|
+ GdmSessionConversation *conversation;
|
|
+
|
|
+ conversation = (GdmSessionConversation *) value;
|
|
+
|
|
+ stop_conversation (conversation);
|
|
+ }
|
|
+
|
|
+ g_hash_table_remove_all (session->priv->conversations);
|
|
+}
|
|
+
|
|
+static void
|
|
gdm_session_direct_close (GdmSession *session)
|
|
{
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
@@ -2101,6 +2178,8 @@ gdm_session_direct_close (GdmSession *session)
|
|
impl->priv->display_device);
|
|
}
|
|
|
|
+ stop_all_conversations (impl);
|
|
+
|
|
g_free (impl->priv->selected_user);
|
|
impl->priv->selected_user = NULL;
|
|
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 9b5d9c73cd1b53f674825b8b5595b1e92630a8e5 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Thu, 22 Jan 2009 08:52:01 -0500
|
|
Subject: [PATCH 08/65] Propagate service name to more layers
|
|
|
|
This is more prep work to get multiple concurrent
|
|
PAM stacks going.
|
|
---
|
|
daemon/gdm-factory-slave.c | 49 ++-
|
|
daemon/gdm-greeter-server.c | 120 ++++++--
|
|
daemon/gdm-greeter-server.h | 17 +-
|
|
daemon/gdm-product-slave.c | 233 ++++++++++++---
|
|
daemon/gdm-session-direct.c | 481 ++++++++++++++++++------------
|
|
daemon/gdm-session-private.h | 22 ++-
|
|
daemon/gdm-session-relay.c | 117 ++++++--
|
|
daemon/gdm-session-worker.c | 27 ++
|
|
daemon/gdm-session.c | 151 ++++++----
|
|
daemon/gdm-session.h | 44 ++-
|
|
daemon/gdm-simple-slave.c | 75 ++++--
|
|
daemon/test-session.c | 22 +-
|
|
gui/simple-greeter/gdm-greeter-client.c | 183 +++++++++---
|
|
gui/simple-greeter/gdm-greeter-client.h | 16 +-
|
|
gui/simple-greeter/gdm-greeter-session.c | 11 +-
|
|
15 files changed, 1122 insertions(+), 446 deletions(-)
|
|
|
|
diff --git a/daemon/gdm-factory-slave.c b/daemon/gdm-factory-slave.c
|
|
index d1bb5dd..3251ec2 100644
|
|
--- a/daemon/gdm-factory-slave.c
|
|
+++ b/daemon/gdm-factory-slave.c
|
|
@@ -144,45 +144,49 @@ on_greeter_session_died (GdmGreeterSession *greeter,
|
|
|
|
static void
|
|
on_session_info (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text,
|
|
GdmFactorySlave *slave)
|
|
{
|
|
g_debug ("GdmFactorySlave: Info: %s", text);
|
|
- gdm_greeter_server_info (slave->priv->greeter_server, text);
|
|
+ gdm_greeter_server_info (slave->priv->greeter_server, service_name, text);
|
|
}
|
|
|
|
static void
|
|
on_session_problem (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text,
|
|
GdmFactorySlave *slave)
|
|
{
|
|
g_debug ("GdmFactorySlave: Problem: %s", text);
|
|
- gdm_greeter_server_problem (slave->priv->greeter_server, text);
|
|
+ gdm_greeter_server_problem (slave->priv->greeter_server, service_name, text);
|
|
}
|
|
|
|
static void
|
|
on_session_info_query (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text,
|
|
GdmFactorySlave *slave)
|
|
{
|
|
|
|
g_debug ("GdmFactorySlave: Info query: %s", text);
|
|
- gdm_greeter_server_info_query (slave->priv->greeter_server, text);
|
|
+ gdm_greeter_server_info_query (slave->priv->greeter_server, service_name, text);
|
|
}
|
|
|
|
static void
|
|
on_session_secret_info_query (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text,
|
|
GdmFactorySlave *slave)
|
|
{
|
|
g_debug ("GdmFactorySlave: Secret info query: %s", text);
|
|
- gdm_greeter_server_secret_info_query (slave->priv->greeter_server, text);
|
|
+ gdm_greeter_server_secret_info_query (slave->priv->greeter_server, service_name, text);
|
|
}
|
|
|
|
static void
|
|
on_session_conversation_started (GdmSession *session,
|
|
- GdmFactorySlave *slave,
|
|
- const char *service_name)
|
|
+ const char *service_name,
|
|
+ GdmFactorySlave *slave)
|
|
{
|
|
g_debug ("GdmFactorySlave: session conversation started");
|
|
|
|
@@ -192,17 +196,19 @@ on_session_conversation_started (GdmSession *session,
|
|
|
|
static void
|
|
on_session_setup_complete (GdmSession *session,
|
|
+ const char *service_name,
|
|
GdmFactorySlave *slave)
|
|
{
|
|
- gdm_session_authenticate (session);
|
|
+ gdm_session_authenticate (session, service_name);
|
|
}
|
|
|
|
static void
|
|
on_session_setup_failed (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *message,
|
|
GdmFactorySlave *slave)
|
|
{
|
|
- gdm_greeter_server_problem (slave->priv->greeter_server, _("Unable to initialize login system"));
|
|
+ gdm_greeter_server_problem (slave->priv->greeter_server, service_name, _("Unable to initialize login system"));
|
|
|
|
queue_greeter_reset (slave);
|
|
}
|
|
@@ -224,23 +230,26 @@ on_session_reset_failed (GdmSession *session,
|
|
|
|
static void
|
|
on_session_authenticated (GdmSession *session,
|
|
+ const char *service_name,
|
|
GdmFactorySlave *slave)
|
|
{
|
|
- gdm_session_authorize (session);
|
|
+ gdm_session_authorize (session, service_name);
|
|
}
|
|
|
|
static void
|
|
on_session_authentication_failed (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *message,
|
|
GdmFactorySlave *slave)
|
|
{
|
|
- gdm_greeter_server_problem (slave->priv->greeter_server, _("Unable to authenticate user"));
|
|
+ gdm_greeter_server_problem (slave->priv->greeter_server, service_name, _("Unable to authenticate user"));
|
|
|
|
queue_greeter_reset (slave);
|
|
}
|
|
|
|
static void
|
|
on_session_authorized (GdmSession *session,
|
|
+ const char *service_name,
|
|
GdmFactorySlave *slave)
|
|
{
|
|
int flag;
|
|
@@ -248,39 +257,42 @@ on_session_authorized (GdmSession *session,
|
|
/* FIXME: check for migration? */
|
|
flag = GDM_SESSION_CRED_ESTABLISH;
|
|
|
|
- gdm_session_accredit (session, flag);
|
|
+ gdm_session_accredit (session, service_name, flag);
|
|
}
|
|
|
|
static void
|
|
on_session_authorization_failed (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *message,
|
|
GdmFactorySlave *slave)
|
|
{
|
|
- gdm_greeter_server_problem (slave->priv->greeter_server, _("Unable to authorize user"));
|
|
+ gdm_greeter_server_problem (slave->priv->greeter_server, service_name, _("Unable to authorize user"));
|
|
|
|
queue_greeter_reset (slave);
|
|
}
|
|
|
|
static void
|
|
on_session_accredited (GdmSession *session,
|
|
+ const char *service_name,
|
|
GdmFactorySlave *slave)
|
|
{
|
|
g_debug ("GdmFactorySlave: session user verified");
|
|
|
|
- gdm_session_start_session (session);
|
|
+ gdm_session_start_session (session, service_name);
|
|
|
|
gdm_greeter_server_reset (slave->priv->greeter_server);
|
|
}
|
|
|
|
static void
|
|
on_session_accreditation_failed (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *message,
|
|
GdmFactorySlave *slave)
|
|
{
|
|
g_debug ("GdmFactorySlave: could not successfully authenticate user: %s",
|
|
message);
|
|
|
|
- gdm_greeter_server_problem (slave->priv->greeter_server, _("Unable to establish credentials"));
|
|
+ gdm_greeter_server_problem (slave->priv->greeter_server, service_name, _("Unable to establish credentials"));
|
|
|
|
queue_greeter_reset (slave);
|
|
}
|
|
@@ -374,31 +386,34 @@ on_session_relay_connected (GdmSessionRelay *session,
|
|
|
|
static void
|
|
on_greeter_begin_verification (GdmGreeterServer *greeter_server,
|
|
+ const char *service_name,
|
|
GdmFactorySlave *slave)
|
|
{
|
|
g_debug ("GdmFactorySlave: begin verification");
|
|
gdm_session_setup (GDM_SESSION (slave->priv->session),
|
|
- "gdm");
|
|
+ service_name);
|
|
}
|
|
|
|
static void
|
|
on_greeter_begin_verification_for_user (GdmGreeterServer *greeter_server,
|
|
+ const char *service_name,
|
|
const char *username,
|
|
GdmFactorySlave *slave)
|
|
{
|
|
g_debug ("GdmFactorySlave: begin verification for user");
|
|
gdm_session_setup_for_user (GDM_SESSION (slave->priv->session),
|
|
- "gdm",
|
|
+ service_name,
|
|
username);
|
|
}
|
|
|
|
static void
|
|
on_greeter_answer (GdmGreeterServer *greeter_server,
|
|
+ const char *service_name,
|
|
const char *text,
|
|
GdmFactorySlave *slave)
|
|
{
|
|
g_debug ("GdmFactorySlave: Greeter answer");
|
|
- gdm_session_answer_query (GDM_SESSION (slave->priv->session), text);
|
|
+ gdm_session_answer_query (GDM_SESSION (slave->priv->session), service_name, text);
|
|
}
|
|
|
|
static void
|
|
diff --git a/daemon/gdm-greeter-server.c b/daemon/gdm-greeter-server.c
|
|
index 06c80a0..0ac0a09 100644
|
|
--- a/daemon/gdm-greeter-server.c
|
|
+++ b/daemon/gdm-greeter-server.c
|
|
@@ -43,6 +43,7 @@
|
|
#include <dbus/dbus-glib.h>
|
|
#include <dbus/dbus-glib-lowlevel.h>
|
|
|
|
+#include "gdm-marshal.h"
|
|
#include "gdm-greeter-server.h"
|
|
|
|
#define GDM_GREETER_SERVER_DBUS_PATH "/org/gnome/DisplayManager/GreeterServer"
|
|
@@ -156,6 +157,46 @@ send_dbus_string_and_int_signal (GdmGreeterServer *greeter_server,
|
|
}
|
|
|
|
static void
|
|
+send_dbus_string_string_signal (GdmGreeterServer *greeter_server,
|
|
+ const char *name,
|
|
+ const char *text1,
|
|
+ const char *text2)
|
|
+{
|
|
+ DBusMessage *message;
|
|
+ DBusMessageIter iter;
|
|
+ const char *str;
|
|
+
|
|
+ g_return_if_fail (greeter_server != NULL);
|
|
+
|
|
+ message = dbus_message_new_signal (GDM_GREETER_SERVER_DBUS_PATH,
|
|
+ GDM_GREETER_SERVER_DBUS_INTERFACE,
|
|
+ name);
|
|
+
|
|
+ dbus_message_iter_init_append (message, &iter);
|
|
+
|
|
+ if (text1 != NULL) {
|
|
+ str = text1;
|
|
+ } else {
|
|
+ str = "";
|
|
+ }
|
|
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &str);
|
|
+
|
|
+ if (text2 != NULL) {
|
|
+ str = text2;
|
|
+ } else {
|
|
+ str = "";
|
|
+ }
|
|
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &str);
|
|
+
|
|
+ g_debug ("GreeterServer: Sending %s (%s)", name, str);
|
|
+ if (! send_dbus_message (greeter_server->priv->greeter_connection, message)) {
|
|
+ g_debug ("GreeterServer: Could not send %s signal", name);
|
|
+ }
|
|
+
|
|
+ dbus_message_unref (message);
|
|
+}
|
|
+
|
|
+static void
|
|
send_dbus_string_signal (GdmGreeterServer *greeter_server,
|
|
const char *name,
|
|
const char *text)
|
|
@@ -208,34 +249,38 @@ send_dbus_void_signal (GdmGreeterServer *greeter_server,
|
|
|
|
gboolean
|
|
gdm_greeter_server_info_query (GdmGreeterServer *greeter_server,
|
|
+ const char *service_name,
|
|
const char *text)
|
|
{
|
|
- send_dbus_string_signal (greeter_server, "InfoQuery", text);
|
|
+ send_dbus_string_string_signal (greeter_server, "InfoQuery", service_name, text);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
gboolean
|
|
gdm_greeter_server_secret_info_query (GdmGreeterServer *greeter_server,
|
|
+ const char *service_name,
|
|
const char *text)
|
|
{
|
|
- send_dbus_string_signal (greeter_server, "SecretInfoQuery", text);
|
|
+ send_dbus_string_string_signal (greeter_server, "SecretInfoQuery", service_name, text);
|
|
return TRUE;
|
|
}
|
|
|
|
gboolean
|
|
gdm_greeter_server_info (GdmGreeterServer *greeter_server,
|
|
+ const char *service_name,
|
|
const char *text)
|
|
{
|
|
- send_dbus_string_signal (greeter_server, "Info", text);
|
|
+ send_dbus_string_string_signal (greeter_server, "Info", service_name, text);
|
|
return TRUE;
|
|
}
|
|
|
|
gboolean
|
|
gdm_greeter_server_problem (GdmGreeterServer *greeter_server,
|
|
+ const char *service_name,
|
|
const char *text)
|
|
{
|
|
- send_dbus_string_signal (greeter_server, "Problem", text);
|
|
+ send_dbus_string_string_signal (greeter_server, "Problem", service_name, text);
|
|
return TRUE;
|
|
}
|
|
|
|
@@ -291,9 +336,10 @@ gdm_greeter_server_request_timed_login (GdmGreeterServer *greeter_server,
|
|
}
|
|
|
|
void
|
|
-gdm_greeter_server_user_authorized (GdmGreeterServer *greeter_server)
|
|
+gdm_greeter_server_user_authorized (GdmGreeterServer *greeter_server,
|
|
+ const char *service_name)
|
|
{
|
|
- send_dbus_void_signal (greeter_server, "UserAuthorized");
|
|
+ send_dbus_string_signal (greeter_server, "UserAuthorized", service_name);
|
|
}
|
|
|
|
/* Note: Use abstract sockets like dbus does by default on Linux. Abstract
|
|
@@ -358,6 +404,16 @@ handle_begin_verification (GdmGreeterServer *greeter_server,
|
|
DBusMessage *message)
|
|
{
|
|
DBusMessage *reply;
|
|
+ DBusError error;
|
|
+ const char *service_name;
|
|
+
|
|
+ dbus_error_init (&error);
|
|
+ if (! dbus_message_get_args (message, &error,
|
|
+ DBUS_TYPE_STRING, &service_name,
|
|
+ DBUS_TYPE_INVALID)) {
|
|
+ g_warning ("ERROR: %s", error.message);
|
|
+ }
|
|
+ dbus_error_free (&error);
|
|
|
|
g_debug ("GreeterServer: BeginVerification");
|
|
|
|
@@ -365,7 +421,7 @@ handle_begin_verification (GdmGreeterServer *greeter_server,
|
|
dbus_connection_send (connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
- g_signal_emit (greeter_server, signals [BEGIN_VERIFICATION], 0);
|
|
+ g_signal_emit (greeter_server, signals [BEGIN_VERIFICATION], 0, service_name);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
@@ -379,7 +435,6 @@ handle_begin_auto_login (GdmGreeterServer *greeter_server,
|
|
DBusError error;
|
|
const char *text;
|
|
|
|
-
|
|
dbus_error_init (&error);
|
|
if (! dbus_message_get_args (message, &error,
|
|
DBUS_TYPE_STRING, &text,
|
|
@@ -406,13 +461,16 @@ handle_begin_verification_for_user (GdmGreeterServer *greeter_server,
|
|
DBusMessage *reply;
|
|
DBusError error;
|
|
const char *text;
|
|
+ const char *service_name;
|
|
|
|
dbus_error_init (&error);
|
|
if (! dbus_message_get_args (message, &error,
|
|
+ DBUS_TYPE_STRING, &service_name,
|
|
DBUS_TYPE_STRING, &text,
|
|
DBUS_TYPE_INVALID)) {
|
|
g_warning ("ERROR: %s", error.message);
|
|
}
|
|
+ dbus_error_free (&error);
|
|
|
|
g_debug ("GreeterServer: BeginVerificationForUser for '%s'", text);
|
|
|
|
@@ -420,7 +478,7 @@ handle_begin_verification_for_user (GdmGreeterServer *greeter_server,
|
|
dbus_connection_send (connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
- g_signal_emit (greeter_server, signals [BEGIN_VERIFICATION_FOR_USER], 0, text);
|
|
+ g_signal_emit (greeter_server, signals [BEGIN_VERIFICATION_FOR_USER], 0, service_name, text);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
@@ -433,13 +491,16 @@ handle_answer_query (GdmGreeterServer *greeter_server,
|
|
DBusMessage *reply;
|
|
DBusError error;
|
|
const char *text;
|
|
+ const char *service_name;
|
|
|
|
dbus_error_init (&error);
|
|
if (! dbus_message_get_args (message, &error,
|
|
+ DBUS_TYPE_STRING, &service_name,
|
|
DBUS_TYPE_STRING, &text,
|
|
DBUS_TYPE_INVALID)) {
|
|
g_warning ("ERROR: %s", error.message);
|
|
}
|
|
+ dbus_error_free (&error);
|
|
|
|
g_debug ("GreeterServer: AnswerQuery");
|
|
|
|
@@ -447,7 +508,7 @@ handle_answer_query (GdmGreeterServer *greeter_server,
|
|
dbus_connection_send (connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
- g_signal_emit (greeter_server, signals [QUERY_ANSWER], 0, text);
|
|
+ g_signal_emit (greeter_server, signals [QUERY_ANSWER], 0, service_name, text);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
@@ -644,9 +705,11 @@ handle_start_session_when_ready (GdmGreeterServer *greeter_server,
|
|
DBusMessage *reply;
|
|
DBusError error;
|
|
gboolean should_start_session;
|
|
+ char *service_name;
|
|
|
|
dbus_error_init (&error);
|
|
if (! dbus_message_get_args (message, &error,
|
|
+ DBUS_TYPE_STRING, &service_name,
|
|
DBUS_TYPE_BOOLEAN, &should_start_session,
|
|
DBUS_TYPE_INVALID)) {
|
|
g_warning ("ERROR: %s", error.message);
|
|
@@ -660,9 +723,9 @@ handle_start_session_when_ready (GdmGreeterServer *greeter_server,
|
|
dbus_message_unref (reply);
|
|
|
|
if (should_start_session) {
|
|
- g_signal_emit (greeter_server, signals [START_SESSION_WHEN_READY], 0);
|
|
+ g_signal_emit (greeter_server, signals [START_SESSION_WHEN_READY], 0, service_name);
|
|
} else {
|
|
- g_signal_emit (greeter_server, signals [START_SESSION_LATER] ,0);
|
|
+ g_signal_emit (greeter_server, signals [START_SESSION_LATER] ,0, service_name);
|
|
}
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
@@ -735,13 +798,16 @@ do_introspect (DBusConnection *connection,
|
|
" <arg name=\"service_name\" direction=\"in\" type=\"s\"/>\n"
|
|
" </method>\n"
|
|
" <method name=\"BeginVerification\">\n"
|
|
+ " <arg name=\"service_name\" direction=\"in\" type=\"s\"/>\n"
|
|
" </method>\n"
|
|
" <method name=\"BeginTimedLogin\">\n"
|
|
" </method>\n"
|
|
" <method name=\"BeginVerificationForUser\">\n"
|
|
+ " <arg name=\"service_name\" direction=\"in\" type=\"s\"/>\n"
|
|
" <arg name=\"username\" direction=\"in\" type=\"s\"/>\n"
|
|
" </method>\n"
|
|
" <method name=\"AnswerQuery\">\n"
|
|
+ " <arg name=\"service_name\" direction=\"in\" type=\"s\"/>\n"
|
|
" <arg name=\"text\" direction=\"in\" type=\"s\"/>\n"
|
|
" </method>\n"
|
|
" <method name=\"SelectSession\">\n"
|
|
@@ -764,18 +830,23 @@ do_introspect (DBusConnection *connection,
|
|
" <arg name=\"id\" direction=\"out\" type=\"o\"/>\n"
|
|
" </method>\n"
|
|
" <method name=\"StartSessionWhenReady\">\n"
|
|
+ " <arg name=\"service_name\" direction=\"in\" type=\"s\"/>\n"
|
|
" <arg name=\"should_start_session\" type=\"b\"/>\n"
|
|
" </method>\n"
|
|
" <signal name=\"Info\">\n"
|
|
+ " <arg name=\"service_name\" direction=\"in\" type=\"s\"/>\n"
|
|
" <arg name=\"text\" type=\"s\"/>\n"
|
|
" </signal>\n"
|
|
" <signal name=\"Problem\">\n"
|
|
+ " <arg name=\"service_name\" direction=\"in\" type=\"s\"/>\n"
|
|
" <arg name=\"text\" type=\"s\"/>\n"
|
|
" </signal>\n"
|
|
" <signal name=\"InfoQuery\">\n"
|
|
+ " <arg name=\"service_name\" direction=\"in\" type=\"s\"/>\n"
|
|
" <arg name=\"text\" type=\"s\"/>\n"
|
|
" </signal>\n"
|
|
" <signal name=\"SecretInfoQuery\">\n"
|
|
+ " <arg name=\"service_name\" direction=\"in\" type=\"s\"/>\n"
|
|
" <arg name=\"text\" type=\"s\"/>\n"
|
|
" </signal>\n"
|
|
" <signal name=\"SelectedUserChanged\">\n"
|
|
@@ -801,6 +872,7 @@ do_introspect (DBusConnection *connection,
|
|
" <signal name=\"Reset\">\n"
|
|
" </signal>\n"
|
|
" <signal name=\"UserAuthorized\">\n"
|
|
+ " <arg name=\"service_name\" direction=\"in\" type=\"s\"/>\n"
|
|
" </signal>\n"
|
|
" </interface>\n");
|
|
|
|
@@ -1176,9 +1248,9 @@ gdm_greeter_server_class_init (GdmGreeterServerClass *klass)
|
|
G_STRUCT_OFFSET (GdmGreeterServerClass, begin_verification),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__VOID,
|
|
+ g_cclosure_marshal_VOID__STRING,
|
|
G_TYPE_NONE,
|
|
- 0);
|
|
+ 1, G_TYPE_STRING);
|
|
signals [BEGIN_AUTO_LOGIN] =
|
|
g_signal_new ("begin-auto-login",
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
@@ -1197,10 +1269,10 @@ gdm_greeter_server_class_init (GdmGreeterServerClass *klass)
|
|
G_STRUCT_OFFSET (GdmGreeterServerClass, begin_verification_for_user),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__STRING,
|
|
+ gdm_marshal_VOID__STRING_STRING,
|
|
G_TYPE_NONE,
|
|
- 1,
|
|
- G_TYPE_STRING);
|
|
+ 2,
|
|
+ G_TYPE_STRING, G_TYPE_STRING);
|
|
signals [QUERY_ANSWER] =
|
|
g_signal_new ("query-answer",
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
@@ -1208,10 +1280,10 @@ gdm_greeter_server_class_init (GdmGreeterServerClass *klass)
|
|
G_STRUCT_OFFSET (GdmGreeterServerClass, query_answer),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__STRING,
|
|
+ gdm_marshal_VOID__STRING_STRING,
|
|
G_TYPE_NONE,
|
|
- 1,
|
|
- G_TYPE_STRING);
|
|
+ 2,
|
|
+ G_TYPE_STRING, G_TYPE_STRING);
|
|
signals [SESSION_SELECTED] =
|
|
g_signal_new ("session-selected",
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
@@ -1305,9 +1377,9 @@ gdm_greeter_server_class_init (GdmGreeterServerClass *klass)
|
|
G_STRUCT_OFFSET (GdmGreeterServerClass, start_session_when_ready),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__VOID,
|
|
+ g_cclosure_marshal_VOID__STRING,
|
|
G_TYPE_NONE,
|
|
- 0);
|
|
+ 1, G_TYPE_STRING);
|
|
|
|
signals [START_SESSION_LATER] =
|
|
g_signal_new ("start-session-later",
|
|
@@ -1316,9 +1388,9 @@ gdm_greeter_server_class_init (GdmGreeterServerClass *klass)
|
|
G_STRUCT_OFFSET (GdmGreeterServerClass, start_session_later),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__VOID,
|
|
+ g_cclosure_marshal_VOID__STRING,
|
|
G_TYPE_NONE,
|
|
- 0);
|
|
+ 1, G_TYPE_STRING);
|
|
}
|
|
|
|
static void
|
|
diff --git a/daemon/gdm-greeter-server.h b/daemon/gdm-greeter-server.h
|
|
index 7333db1..6d0dd87 100644
|
|
--- a/daemon/gdm-greeter-server.h
|
|
+++ b/daemon/gdm-greeter-server.h
|
|
@@ -48,10 +48,13 @@ typedef struct
|
|
void (* start_conversation) (GdmGreeterServer *greeter_server,
|
|
const char *service_name);
|
|
void (* begin_auto_login) (GdmGreeterServer *greeter_server);
|
|
- void (* begin_verification) (GdmGreeterServer *greeter_server);
|
|
+ void (* begin_verification) (GdmGreeterServer *greeter_server,
|
|
+ const char *service_name);
|
|
void (* begin_verification_for_user)(GdmGreeterServer *greeter_server,
|
|
+ const char *service_name,
|
|
const char *username);
|
|
void (* query_answer) (GdmGreeterServer *greeter_server,
|
|
+ const char *service_name,
|
|
const char *text);
|
|
void (* session_selected) (GdmGreeterServer *greeter_server,
|
|
const char *name);
|
|
@@ -66,7 +69,8 @@ typedef struct
|
|
void (* cancelled) (GdmGreeterServer *greeter_server);
|
|
void (* connected) (GdmGreeterServer *greeter_server);
|
|
void (* disconnected) (GdmGreeterServer *greeter_server);
|
|
- void (* start_session_when_ready) (GdmGreeterServer *greeter_server);
|
|
+ void (* start_session_when_ready) (GdmGreeterServer *greeter_server,
|
|
+ const char *service_name);
|
|
void (* start_session_later) (GdmGreeterServer *greeter_server);
|
|
} GdmGreeterServerClass;
|
|
|
|
@@ -77,14 +81,17 @@ gboolean gdm_greeter_server_start (GdmGreeterServer *
|
|
gboolean gdm_greeter_server_stop (GdmGreeterServer *greeter_server);
|
|
char * gdm_greeter_server_get_address (GdmGreeterServer *greeter_server);
|
|
|
|
-
|
|
gboolean gdm_greeter_server_info_query (GdmGreeterServer *greeter_server,
|
|
+ const char *service_name,
|
|
const char *text);
|
|
gboolean gdm_greeter_server_secret_info_query (GdmGreeterServer *greeter_server,
|
|
+ const char *service_name,
|
|
const char *text);
|
|
gboolean gdm_greeter_server_info (GdmGreeterServer *greeter_server,
|
|
+ const char *service_name,
|
|
const char *text);
|
|
gboolean gdm_greeter_server_problem (GdmGreeterServer *greeter_server,
|
|
+ const char *service_name,
|
|
const char *text);
|
|
gboolean gdm_greeter_server_reset (GdmGreeterServer *greeter_server);
|
|
gboolean gdm_greeter_server_ready (GdmGreeterServer *greeter_server,
|
|
@@ -101,8 +108,8 @@ void gdm_greeter_server_default_session_name_changed (GdmGreeterS
|
|
void gdm_greeter_server_request_timed_login (GdmGreeterServer *greeter_server,
|
|
const char *username,
|
|
int delay);
|
|
-void gdm_greeter_server_user_authorized (GdmGreeterServer *greeter_server);
|
|
-
|
|
+void gdm_greeter_server_user_authorized (GdmGreeterServer *greeter_server,
|
|
+ const char *service_name);
|
|
|
|
G_END_DECLS
|
|
|
|
diff --git a/daemon/gdm-product-slave.c b/daemon/gdm-product-slave.c
|
|
index 15a2820..dd2e1bc 100644
|
|
--- a/daemon/gdm-product-slave.c
|
|
+++ b/daemon/gdm-product-slave.c
|
|
@@ -79,6 +79,8 @@ struct GdmProductSlavePrivate
|
|
|
|
DBusGProxy *product_display_proxy;
|
|
DBusGConnection *connection;
|
|
+
|
|
+ char *start_session_service_name;
|
|
};
|
|
|
|
enum {
|
|
@@ -93,6 +95,68 @@ static void gdm_product_slave_finalize (GObject *object);
|
|
G_DEFINE_TYPE (GdmProductSlave, gdm_product_slave, GDM_TYPE_SLAVE)
|
|
|
|
static gboolean
|
|
+send_dbus_string_string_method (DBusConnection *connection,
|
|
+ const char *method,
|
|
+ const char *payload1,
|
|
+ const char *payload2)
|
|
+{
|
|
+ DBusError error;
|
|
+ DBusMessage *message;
|
|
+ DBusMessage *reply;
|
|
+ DBusMessageIter iter;
|
|
+ const char *str;
|
|
+
|
|
+ g_debug ("GdmProductSlave: Calling %s", method);
|
|
+ message = dbus_message_new_method_call (NULL,
|
|
+ RELAY_SERVER_DBUS_PATH,
|
|
+ RELAY_SERVER_DBUS_INTERFACE,
|
|
+ method);
|
|
+ if (message == NULL) {
|
|
+ g_warning ("Couldn't allocate the D-Bus message");
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ dbus_message_iter_init_append (message, &iter);
|
|
+
|
|
+ if (payload1 != NULL) {
|
|
+ str = payload1;
|
|
+ } else {
|
|
+ str = "";
|
|
+ }
|
|
+ dbus_message_iter_append_basic (&iter,
|
|
+ DBUS_TYPE_STRING,
|
|
+ &str);
|
|
+ if (payload2 != NULL) {
|
|
+ str = payload2;
|
|
+ } else {
|
|
+ str = "";
|
|
+ }
|
|
+ dbus_message_iter_append_basic (&iter,
|
|
+ DBUS_TYPE_STRING,
|
|
+ &str);
|
|
+ dbus_error_init (&error);
|
|
+ reply = dbus_connection_send_with_reply_and_block (connection,
|
|
+ message,
|
|
+ -1,
|
|
+ &error);
|
|
+
|
|
+ dbus_message_unref (message);
|
|
+
|
|
+ if (dbus_error_is_set (&error)) {
|
|
+ g_warning ("%s %s raised: %s\n",
|
|
+ method,
|
|
+ error.name,
|
|
+ error.message);
|
|
+ return FALSE;
|
|
+ }
|
|
+ if (reply != NULL) {
|
|
+ dbus_message_unref (reply);
|
|
+ }
|
|
+ dbus_connection_flush (connection);
|
|
+
|
|
+ return TRUE;
|
|
+}
|
|
+static gboolean
|
|
send_dbus_string_method (DBusConnection *connection,
|
|
const char *method,
|
|
const char *payload)
|
|
@@ -356,7 +420,8 @@ setup_session (GdmProductSlave *slave)
|
|
g_free (display_device);
|
|
g_free (auth_file);
|
|
|
|
- gdm_session_start_session (GDM_SESSION (slave->priv->session));
|
|
+ gdm_session_start_session (GDM_SESSION (slave->priv->session),
|
|
+ slave->priv->start_session_service_name);
|
|
|
|
return TRUE;
|
|
}
|
|
@@ -508,96 +573,112 @@ on_session_reset_failed (GdmSession *session,
|
|
|
|
static void
|
|
on_session_authenticated (GdmSession *session,
|
|
+ const char *service_name,
|
|
GdmProductSlave *slave)
|
|
{
|
|
- send_dbus_void_method (slave->priv->session_relay_connection,
|
|
- "Authenticated");
|
|
+ send_dbus_string_method (slave->priv->session_relay_connection,
|
|
+ "Authenticated", service_name);
|
|
}
|
|
|
|
static void
|
|
on_session_authentication_failed (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *message,
|
|
GdmProductSlave *slave)
|
|
{
|
|
- send_dbus_string_method (slave->priv->session_relay_connection,
|
|
- "AuthenticationFailed",
|
|
- message);
|
|
+ send_dbus_string_string_method (slave->priv->session_relay_connection,
|
|
+ "AuthenticationFailed",
|
|
+ service_name,
|
|
+ message);
|
|
}
|
|
|
|
static void
|
|
on_session_authorized (GdmSession *session,
|
|
+ const char *service_name,
|
|
GdmProductSlave *slave)
|
|
{
|
|
- send_dbus_void_method (slave->priv->session_relay_connection,
|
|
- "Authorized");
|
|
+ send_dbus_string_method (slave->priv->session_relay_connection,
|
|
+ "Authorized", service_name);
|
|
}
|
|
|
|
static void
|
|
on_session_authorization_failed (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *message,
|
|
GdmProductSlave *slave)
|
|
{
|
|
- send_dbus_string_method (slave->priv->session_relay_connection,
|
|
- "AuthorizationFailed",
|
|
- message);
|
|
+ send_dbus_string_string_method (slave->priv->session_relay_connection,
|
|
+ "AuthorizationFailed",
|
|
+ service_name,
|
|
+ message);
|
|
}
|
|
|
|
static void
|
|
on_session_accredited (GdmSession *session,
|
|
+ const char *service_name,
|
|
GdmProductSlave *slave)
|
|
{
|
|
- send_dbus_void_method (slave->priv->session_relay_connection,
|
|
- "Accredited");
|
|
+ send_dbus_string_method (slave->priv->session_relay_connection,
|
|
+ "Accredited", service_name);
|
|
}
|
|
|
|
static void
|
|
on_session_accreditation_failed (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *message,
|
|
GdmProductSlave *slave)
|
|
{
|
|
- send_dbus_string_method (slave->priv->session_relay_connection,
|
|
- "AccreditationFailed",
|
|
- message);
|
|
+ send_dbus_string_string_method (slave->priv->session_relay_connection,
|
|
+ "AccreditationFailed",
|
|
+ service_name,
|
|
+ message);
|
|
}
|
|
|
|
static void
|
|
on_session_info (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text,
|
|
GdmProductSlave *slave)
|
|
{
|
|
- send_dbus_string_method (slave->priv->session_relay_connection,
|
|
- "Info",
|
|
- text);
|
|
+ send_dbus_string_string_method (slave->priv->session_relay_connection,
|
|
+ "Info",
|
|
+ service_name,
|
|
+ text);
|
|
}
|
|
|
|
static void
|
|
on_session_problem (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text,
|
|
GdmProductSlave *slave)
|
|
{
|
|
- send_dbus_string_method (slave->priv->session_relay_connection,
|
|
- "Problem",
|
|
- text);
|
|
+ send_dbus_string_string_method (slave->priv->session_relay_connection,
|
|
+ "Problem",
|
|
+ service_name,
|
|
+ text);
|
|
}
|
|
|
|
static void
|
|
on_session_info_query (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text,
|
|
GdmProductSlave *slave)
|
|
{
|
|
- send_dbus_string_method (slave->priv->session_relay_connection,
|
|
- "InfoQuery",
|
|
- text);
|
|
+ send_dbus_string_string_method (slave->priv->session_relay_connection,
|
|
+ "InfoQuery",
|
|
+ service_name, text);
|
|
}
|
|
|
|
static void
|
|
on_session_secret_info_query (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text,
|
|
GdmProductSlave *slave)
|
|
{
|
|
- send_dbus_string_method (slave->priv->session_relay_connection,
|
|
- "SecretInfoQuery",
|
|
- text);
|
|
+ send_dbus_string_string_method (slave->priv->session_relay_connection,
|
|
+ "SecretInfoQuery",
|
|
+ service_name,
|
|
+ text);
|
|
}
|
|
|
|
static void
|
|
@@ -658,36 +739,92 @@ static void
|
|
on_relay_authenticate (GdmProductSlave *slave,
|
|
DBusMessage *message)
|
|
{
|
|
- g_debug ("GdmProductSlave: Relay Authenticate");
|
|
+ DBusError error;
|
|
+ char *service_name;
|
|
+ dbus_bool_t res;
|
|
|
|
- gdm_session_authenticate (GDM_SESSION (slave->priv->session));
|
|
+ dbus_error_init (&error);
|
|
+ res = dbus_message_get_args (message,
|
|
+ &error,
|
|
+ DBUS_TYPE_STRING, &service_name,
|
|
+ DBUS_TYPE_INVALID);
|
|
+ if (res) {
|
|
+ g_debug ("GdmProductSlave: Relay Authenticate");
|
|
+ gdm_session_authenticate (GDM_SESSION (slave->priv->session), service_name);
|
|
+ } else {
|
|
+ g_warning ("Unable to get arguments: %s", error.message);
|
|
+ dbus_error_free (&error);
|
|
+ }
|
|
+ dbus_error_free (&error);
|
|
}
|
|
|
|
static void
|
|
on_relay_authorize (GdmProductSlave *slave,
|
|
DBusMessage *message)
|
|
{
|
|
- g_debug ("GdmProductSlave: Relay Authorize");
|
|
+ DBusError error;
|
|
+ char *service_name;
|
|
+ dbus_bool_t res;
|
|
|
|
- gdm_session_authorize (GDM_SESSION (slave->priv->session));
|
|
+ dbus_error_init (&error);
|
|
+ res = dbus_message_get_args (message,
|
|
+ &error,
|
|
+ DBUS_TYPE_STRING, &service_name,
|
|
+ DBUS_TYPE_INVALID);
|
|
+ if (res) {
|
|
+ g_debug ("GdmProductSlave: Relay Authorize");
|
|
+ gdm_session_authorize (GDM_SESSION (slave->priv->session), service_name);
|
|
+ } else {
|
|
+ g_warning ("Unable to get arguments: %s", error.message);
|
|
+ dbus_error_free (&error);
|
|
+ }
|
|
+ dbus_error_free (&error);
|
|
}
|
|
|
|
static void
|
|
on_relay_establish_credentials (GdmProductSlave *slave,
|
|
DBusMessage *message)
|
|
{
|
|
- g_debug ("GdmProductSlave: Relay EstablishCredentials");
|
|
+ DBusError error;
|
|
+ char *service_name;
|
|
+ dbus_bool_t res;
|
|
|
|
- gdm_session_accredit (GDM_SESSION (slave->priv->session), GDM_SESSION_CRED_ESTABLISH);
|
|
+ dbus_error_init (&error);
|
|
+ res = dbus_message_get_args (message,
|
|
+ &error,
|
|
+ DBUS_TYPE_STRING, &service_name,
|
|
+ DBUS_TYPE_INVALID);
|
|
+ if (res) {
|
|
+ g_debug ("GdmProductSlave: Relay EstablishCredentials");
|
|
+ gdm_session_accredit (GDM_SESSION (slave->priv->session), service_name, GDM_SESSION_CRED_ESTABLISH);
|
|
+ } else {
|
|
+ g_warning ("Unable to get arguments: %s", error.message);
|
|
+ dbus_error_free (&error);
|
|
+ }
|
|
+ dbus_error_free (&error);
|
|
}
|
|
|
|
static void
|
|
on_relay_refresh_credentials (GdmProductSlave *slave,
|
|
DBusMessage *message)
|
|
{
|
|
- g_debug ("GdmProductSlave: Relay RefreshCredentials");
|
|
+ DBusError error;
|
|
+ char *service_name;
|
|
+ dbus_bool_t res;
|
|
|
|
- gdm_session_accredit (GDM_SESSION (slave->priv->session), GDM_SESSION_CRED_REFRESH);
|
|
+ dbus_error_init (&error);
|
|
+ res = dbus_message_get_args (message,
|
|
+ &error,
|
|
+ DBUS_TYPE_STRING, &service_name,
|
|
+ DBUS_TYPE_INVALID);
|
|
+ if (res) {
|
|
+ g_debug ("GdmProductSlave: Relay RefreshCredentials");
|
|
+ gdm_session_accredit (GDM_SESSION (slave->priv->session), service_name, GDM_SESSION_CRED_REFRESH);
|
|
+ } else {
|
|
+ g_warning ("Unable to get arguments: %s", error.message);
|
|
+ dbus_error_free (&error);
|
|
+ }
|
|
+ dbus_error_free (&error);
|
|
}
|
|
|
|
static void
|
|
@@ -696,16 +833,18 @@ on_relay_answer_query (GdmProductSlave *slave,
|
|
{
|
|
DBusError error;
|
|
const char *text;
|
|
+ const char *service_name;
|
|
dbus_bool_t res;
|
|
|
|
dbus_error_init (&error);
|
|
res = dbus_message_get_args (message,
|
|
&error,
|
|
+ DBUS_TYPE_STRING, &service_name,
|
|
DBUS_TYPE_STRING, &text,
|
|
DBUS_TYPE_INVALID);
|
|
if (res) {
|
|
g_debug ("GdmProductSlave: Relay AnswerQuery");
|
|
- gdm_session_answer_query (GDM_SESSION (slave->priv->session), text);
|
|
+ gdm_session_answer_query (GDM_SESSION (slave->priv->session), service_name, text);
|
|
} else {
|
|
g_warning ("Unable to get arguments: %s", error.message);
|
|
dbus_error_free (&error);
|
|
@@ -813,7 +952,25 @@ static void
|
|
on_relay_start_session (GdmProductSlave *slave,
|
|
DBusMessage *message)
|
|
{
|
|
- gdm_product_slave_create_server (slave);
|
|
+ DBusError error;
|
|
+ const char *service_name;
|
|
+ dbus_bool_t res;
|
|
+
|
|
+ dbus_error_init (&error);
|
|
+
|
|
+ res = dbus_message_get_args (message,
|
|
+ &error,
|
|
+ DBUS_TYPE_STRING, &service_name,
|
|
+ DBUS_TYPE_INVALID);
|
|
+ if (res) {
|
|
+ g_debug ("GdmProductSlave: Relay StartSession");
|
|
+ g_free (slave->priv->start_session_service_name);
|
|
+ slave->priv->start_session_service_name = g_strdup (service_name);
|
|
+ gdm_product_slave_create_server (slave);
|
|
+ } else {
|
|
+ g_warning ("Unable to get arguments: %s", error.message);
|
|
+ dbus_error_free (&error);
|
|
+ }
|
|
}
|
|
|
|
static void
|
|
diff --git a/daemon/gdm-session-direct.c b/daemon/gdm-session-direct.c
|
|
index 5a93103..a12e333 100644
|
|
--- a/daemon/gdm-session-direct.c
|
|
+++ b/daemon/gdm-session-direct.c
|
|
@@ -84,9 +84,10 @@ struct _GdmSessionDirectPrivate
|
|
|
|
DBusMessage *message_pending_reply;
|
|
|
|
- GdmSessionConversation *conversation;
|
|
GHashTable *conversations;
|
|
|
|
+ GList *pending_connections;
|
|
+
|
|
guint32 is_authenticated : 1;
|
|
guint32 is_running : 1;
|
|
GPid session_pid;
|
|
@@ -193,14 +194,30 @@ send_dbus_void_signal (GdmSessionConversation *conversation,
|
|
dbus_message_unref (message);
|
|
}
|
|
|
|
+static GdmSessionConversation *
|
|
+find_conversation_by_name (GdmSessionDirect *session,
|
|
+ const char *service_name)
|
|
+{
|
|
+ GdmSessionConversation *conversation;
|
|
+
|
|
+ conversation = g_hash_table_lookup (session->priv->conversations, service_name);
|
|
+
|
|
+ if (conversation == NULL) {
|
|
+ g_warning ("Tried to look up non-existant conversation");
|
|
+ }
|
|
+
|
|
+ return conversation;
|
|
+}
|
|
+
|
|
static void
|
|
on_authentication_failed (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *message)
|
|
{
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
GdmSessionConversation *conversation;
|
|
|
|
- conversation = impl->priv->conversation;
|
|
+ conversation = find_conversation_by_name (impl, service_name);
|
|
if (conversation != NULL) {
|
|
gdm_session_record_failed (conversation->worker_pid,
|
|
impl->priv->selected_user,
|
|
@@ -211,12 +228,13 @@ on_authentication_failed (GdmSession *session,
|
|
}
|
|
|
|
static void
|
|
-on_session_started (GdmSession *session)
|
|
+on_session_started (GdmSession *session,
|
|
+ const char *service_name)
|
|
{
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
GdmSessionConversation *conversation;
|
|
|
|
- conversation = impl->priv->conversation;
|
|
+ conversation = find_conversation_by_name (impl, service_name);
|
|
if (conversation != NULL) {
|
|
gdm_session_record_login (conversation->worker_pid,
|
|
impl->priv->selected_user,
|
|
@@ -228,12 +246,13 @@ on_session_started (GdmSession *session)
|
|
|
|
static void
|
|
on_session_start_failed (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *message)
|
|
{
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
GdmSessionConversation *conversation;
|
|
|
|
- conversation = impl->priv->conversation;
|
|
+ conversation = find_conversation_by_name (impl, service_name);
|
|
if (conversation != NULL) {
|
|
gdm_session_record_login (conversation->worker_pid,
|
|
impl->priv->selected_user,
|
|
@@ -258,7 +277,7 @@ on_session_exited (GdmSession *session,
|
|
|
|
static DBusHandlerResult
|
|
gdm_session_direct_handle_setup_complete (GdmSessionDirect *session,
|
|
- DBusConnection *connection,
|
|
+ GdmSessionConversation *conversation,
|
|
DBusMessage *message)
|
|
{
|
|
DBusMessage *reply;
|
|
@@ -266,17 +285,17 @@ gdm_session_direct_handle_setup_complete (GdmSessionDirect *session,
|
|
g_debug ("GdmSessionDirect: Emitting 'setup-complete' signal");
|
|
|
|
reply = dbus_message_new_method_return (message);
|
|
- dbus_connection_send (connection, reply, NULL);
|
|
+ dbus_connection_send (conversation->worker_connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
- _gdm_session_setup_complete (GDM_SESSION (session));
|
|
+ _gdm_session_setup_complete (GDM_SESSION (session), conversation->service_name);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
|
|
static DBusHandlerResult
|
|
gdm_session_direct_handle_setup_failed (GdmSessionDirect *session,
|
|
- DBusConnection *connection,
|
|
+ GdmSessionConversation *conversation,
|
|
DBusMessage *message)
|
|
{
|
|
DBusMessage *reply;
|
|
@@ -291,12 +310,12 @@ gdm_session_direct_handle_setup_failed (GdmSessionDirect *session,
|
|
}
|
|
|
|
reply = dbus_message_new_method_return (message);
|
|
- dbus_connection_send (connection, reply, NULL);
|
|
+ dbus_connection_send (conversation->worker_connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
g_debug ("GdmSessionDirect: Emitting 'setup-failed' signal");
|
|
|
|
- _gdm_session_setup_failed (GDM_SESSION (session), NULL);
|
|
+ _gdm_session_setup_failed (GDM_SESSION (session), conversation->service_name, NULL);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
@@ -304,7 +323,7 @@ gdm_session_direct_handle_setup_failed (GdmSessionDirect *session,
|
|
|
|
static DBusHandlerResult
|
|
gdm_session_direct_handle_reset_complete (GdmSessionDirect *session,
|
|
- DBusConnection *connection,
|
|
+ GdmSessionConversation *conversation,
|
|
DBusMessage *message)
|
|
{
|
|
DBusMessage *reply;
|
|
@@ -312,7 +331,7 @@ gdm_session_direct_handle_reset_complete (GdmSessionDirect *session,
|
|
g_debug ("GdmSessionDirect: Emitting 'reset-complete' signal");
|
|
|
|
reply = dbus_message_new_method_return (message);
|
|
- dbus_connection_send (connection, reply, NULL);
|
|
+ dbus_connection_send (conversation->worker_connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
_gdm_session_reset_complete (GDM_SESSION (session));
|
|
@@ -322,7 +341,7 @@ gdm_session_direct_handle_reset_complete (GdmSessionDirect *session,
|
|
|
|
static DBusHandlerResult
|
|
gdm_session_direct_handle_reset_failed (GdmSessionDirect *session,
|
|
- DBusConnection *connection,
|
|
+ GdmSessionConversation *conversation,
|
|
DBusMessage *message)
|
|
{
|
|
DBusMessage *reply;
|
|
@@ -337,7 +356,7 @@ gdm_session_direct_handle_reset_failed (GdmSessionDirect *session,
|
|
}
|
|
|
|
reply = dbus_message_new_method_return (message);
|
|
- dbus_connection_send (connection, reply, NULL);
|
|
+ dbus_connection_send (conversation->worker_connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
g_debug ("GdmSessionDirect: Emitting 'reset-failed' signal");
|
|
@@ -349,7 +368,7 @@ gdm_session_direct_handle_reset_failed (GdmSessionDirect *session,
|
|
|
|
static DBusHandlerResult
|
|
gdm_session_direct_handle_authenticated (GdmSessionDirect *session,
|
|
- DBusConnection *connection,
|
|
+ GdmSessionConversation *conversation,
|
|
DBusMessage *message)
|
|
{
|
|
DBusMessage *reply;
|
|
@@ -357,17 +376,17 @@ gdm_session_direct_handle_authenticated (GdmSessionDirect *session,
|
|
g_debug ("GdmSessionDirect: Emitting 'authenticated' signal");
|
|
|
|
reply = dbus_message_new_method_return (message);
|
|
- dbus_connection_send (connection, reply, NULL);
|
|
+ dbus_connection_send (conversation->worker_connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
- _gdm_session_authenticated (GDM_SESSION (session));
|
|
+ _gdm_session_authenticated (GDM_SESSION (session), conversation->service_name);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
|
|
static DBusHandlerResult
|
|
gdm_session_direct_handle_authentication_failed (GdmSessionDirect *session,
|
|
- DBusConnection *connection,
|
|
+ GdmSessionConversation *conversation,
|
|
DBusMessage *message)
|
|
{
|
|
DBusMessage *reply;
|
|
@@ -382,19 +401,19 @@ gdm_session_direct_handle_authentication_failed (GdmSessionDirect *session,
|
|
}
|
|
|
|
reply = dbus_message_new_method_return (message);
|
|
- dbus_connection_send (connection, reply, NULL);
|
|
+ dbus_connection_send (conversation->worker_connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
g_debug ("GdmSessionDirect: Emitting 'authentication-failed' signal");
|
|
|
|
- _gdm_session_authentication_failed (GDM_SESSION (session), NULL);
|
|
+ _gdm_session_authentication_failed (GDM_SESSION (session), conversation->service_name, NULL);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
|
|
static DBusHandlerResult
|
|
gdm_session_direct_handle_authorized (GdmSessionDirect *session,
|
|
- DBusConnection *connection,
|
|
+ GdmSessionConversation *conversation,
|
|
DBusMessage *message)
|
|
{
|
|
DBusMessage *reply;
|
|
@@ -402,17 +421,17 @@ gdm_session_direct_handle_authorized (GdmSessionDirect *session,
|
|
g_debug ("GdmSessionDirect: Emitting 'authorized' signal");
|
|
|
|
reply = dbus_message_new_method_return (message);
|
|
- dbus_connection_send (connection, reply, NULL);
|
|
+ dbus_connection_send (conversation->worker_connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
- _gdm_session_authorized (GDM_SESSION (session));
|
|
+ _gdm_session_authorized (GDM_SESSION (session), conversation->service_name);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
|
|
static DBusHandlerResult
|
|
gdm_session_direct_handle_authorization_failed (GdmSessionDirect *session,
|
|
- DBusConnection *connection,
|
|
+ GdmSessionConversation *conversation,
|
|
DBusMessage *message)
|
|
{
|
|
DBusMessage *reply;
|
|
@@ -427,19 +446,19 @@ gdm_session_direct_handle_authorization_failed (GdmSessionDirect *session,
|
|
}
|
|
|
|
reply = dbus_message_new_method_return (message);
|
|
- dbus_connection_send (connection, reply, NULL);
|
|
+ dbus_connection_send (conversation->worker_connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
g_debug ("GdmSessionDirect: Emitting 'authorization-failed' signal");
|
|
|
|
- _gdm_session_authorization_failed (GDM_SESSION (session), NULL);
|
|
+ _gdm_session_authorization_failed (GDM_SESSION (session), conversation->service_name, NULL);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
|
|
static DBusHandlerResult
|
|
gdm_session_direct_handle_accredited (GdmSessionDirect *session,
|
|
- DBusConnection *connection,
|
|
+ GdmSessionConversation *conversation,
|
|
DBusMessage *message)
|
|
{
|
|
DBusMessage *reply;
|
|
@@ -447,17 +466,17 @@ gdm_session_direct_handle_accredited (GdmSessionDirect *session,
|
|
g_debug ("GdmSessionDirect: Emitting 'accredited' signal");
|
|
|
|
reply = dbus_message_new_method_return (message);
|
|
- dbus_connection_send (connection, reply, NULL);
|
|
+ dbus_connection_send (conversation->worker_connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
- _gdm_session_accredited (GDM_SESSION (session));
|
|
+ _gdm_session_accredited (GDM_SESSION (session), conversation->service_name);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
|
|
static DBusHandlerResult
|
|
gdm_session_direct_handle_accreditation_failed (GdmSessionDirect *session,
|
|
- DBusConnection *connection,
|
|
+ GdmSessionConversation *conversation,
|
|
DBusMessage *message)
|
|
{
|
|
DBusMessage *reply;
|
|
@@ -472,12 +491,12 @@ gdm_session_direct_handle_accreditation_failed (GdmSessionDirect *session,
|
|
}
|
|
|
|
reply = dbus_message_new_method_return (message);
|
|
- dbus_connection_send (connection, reply, NULL);
|
|
+ dbus_connection_send (conversation->worker_connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
g_debug ("GdmSessionDirect: Emitting 'accreditation-failed' signal");
|
|
|
|
- _gdm_session_accreditation_failed (GDM_SESSION (session), NULL);
|
|
+ _gdm_session_accreditation_failed (GDM_SESSION (session), conversation->service_name, text);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
@@ -725,7 +744,7 @@ gdm_session_direct_select_user (GdmSession *session,
|
|
|
|
static DBusHandlerResult
|
|
gdm_session_direct_handle_username_changed (GdmSessionDirect *session,
|
|
- DBusConnection *connection,
|
|
+ GdmSessionConversation *conversation,
|
|
DBusMessage *message)
|
|
{
|
|
DBusMessage *reply;
|
|
@@ -740,7 +759,7 @@ gdm_session_direct_handle_username_changed (GdmSessionDirect *session,
|
|
}
|
|
|
|
reply = dbus_message_new_method_return (message);
|
|
- dbus_connection_send (connection, reply, NULL);
|
|
+ dbus_connection_send (conversation->worker_connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
g_debug ("GdmSessionDirect: changing username from '%s' to '%s'",
|
|
@@ -771,7 +790,7 @@ cancel_pending_query (GdmSessionDirect *session)
|
|
reply = dbus_message_new_error (session->priv->message_pending_reply,
|
|
GDM_SESSION_DBUS_ERROR_CANCEL,
|
|
"Operation cancelled");
|
|
- conversation = session->priv->conversation;
|
|
+ conversation = NULL;
|
|
dbus_connection_send (conversation->worker_connection, reply, NULL);
|
|
dbus_connection_flush (conversation->worker_connection);
|
|
|
|
@@ -782,6 +801,7 @@ cancel_pending_query (GdmSessionDirect *session)
|
|
|
|
static void
|
|
answer_pending_query (GdmSessionDirect *session,
|
|
+ const char *service_name,
|
|
const char *answer)
|
|
{
|
|
DBusMessage *reply;
|
|
@@ -794,7 +814,7 @@ answer_pending_query (GdmSessionDirect *session,
|
|
dbus_message_iter_init_append (reply, &iter);
|
|
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &answer);
|
|
|
|
- conversation = session->priv->conversation;
|
|
+ conversation = find_conversation_by_name (session, service_name);
|
|
dbus_connection_send (conversation->worker_connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
@@ -813,7 +833,7 @@ set_pending_query (GdmSessionDirect *session,
|
|
|
|
static DBusHandlerResult
|
|
gdm_session_direct_handle_info_query (GdmSessionDirect *session,
|
|
- DBusConnection *connection,
|
|
+ GdmSessionConversation *conversation,
|
|
DBusMessage *message)
|
|
{
|
|
DBusError error;
|
|
@@ -829,14 +849,14 @@ gdm_session_direct_handle_info_query (GdmSessionDirect *session,
|
|
set_pending_query (session, message);
|
|
|
|
g_debug ("GdmSessionDirect: Emitting 'info-query' signal");
|
|
- _gdm_session_info_query (GDM_SESSION (session), text);
|
|
+ _gdm_session_info_query (GDM_SESSION (session), conversation->service_name, text);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
|
|
static DBusHandlerResult
|
|
gdm_session_direct_handle_secret_info_query (GdmSessionDirect *session,
|
|
- DBusConnection *connection,
|
|
+ GdmSessionConversation *conversation,
|
|
DBusMessage *message)
|
|
{
|
|
DBusError error;
|
|
@@ -852,14 +872,14 @@ gdm_session_direct_handle_secret_info_query (GdmSessionDirect *session,
|
|
set_pending_query (session, message);
|
|
|
|
g_debug ("GdmSessionDirect: Emitting 'secret-info-query' signal");
|
|
- _gdm_session_secret_info_query (GDM_SESSION (session), text);
|
|
+ _gdm_session_secret_info_query (GDM_SESSION (session), conversation->service_name, text);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
|
|
static DBusHandlerResult
|
|
gdm_session_direct_handle_info (GdmSessionDirect *session,
|
|
- DBusConnection *connection,
|
|
+ GdmSessionConversation *conversation,
|
|
DBusMessage *message)
|
|
{
|
|
DBusMessage *reply;
|
|
@@ -874,18 +894,18 @@ gdm_session_direct_handle_info (GdmSessionDirect *session,
|
|
}
|
|
|
|
reply = dbus_message_new_method_return (message);
|
|
- dbus_connection_send (connection, reply, NULL);
|
|
+ dbus_connection_send (conversation->worker_connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
g_debug ("GdmSessionDirect: Emitting 'info' signal");
|
|
- _gdm_session_info (GDM_SESSION (session), text);
|
|
+ _gdm_session_info (GDM_SESSION (session), conversation->service_name, text);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
|
|
static DBusHandlerResult
|
|
gdm_session_direct_handle_cancel_pending_query (GdmSessionDirect *session,
|
|
- DBusConnection *connection,
|
|
+ GdmSessionConversation *conversation,
|
|
DBusMessage *message)
|
|
{
|
|
DBusMessage *reply;
|
|
@@ -894,7 +914,7 @@ gdm_session_direct_handle_cancel_pending_query (GdmSessionDirect *session,
|
|
cancel_pending_query (session);
|
|
|
|
reply = dbus_message_new_method_return (message);
|
|
- dbus_connection_send (connection, reply, NULL);
|
|
+ dbus_connection_send (conversation->worker_connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
@@ -902,7 +922,7 @@ gdm_session_direct_handle_cancel_pending_query (GdmSessionDirect *session,
|
|
|
|
static DBusHandlerResult
|
|
gdm_session_direct_handle_problem (GdmSessionDirect *session,
|
|
- DBusConnection *connection,
|
|
+ GdmSessionConversation *conversation,
|
|
DBusMessage *message)
|
|
{
|
|
DBusMessage *reply;
|
|
@@ -917,18 +937,18 @@ gdm_session_direct_handle_problem (GdmSessionDirect *session,
|
|
}
|
|
|
|
reply = dbus_message_new_method_return (message);
|
|
- dbus_connection_send (connection, reply, NULL);
|
|
+ dbus_connection_send (conversation->worker_connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
g_debug ("GdmSessionDirect: Emitting 'problem' signal");
|
|
- _gdm_session_problem (GDM_SESSION (session), text);
|
|
+ _gdm_session_problem (GDM_SESSION (session), conversation->service_name, text);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
|
|
static DBusHandlerResult
|
|
gdm_session_direct_handle_session_started (GdmSessionDirect *session,
|
|
- DBusConnection *connection,
|
|
+ GdmSessionConversation *conversation,
|
|
DBusMessage *message)
|
|
{
|
|
DBusMessage *reply;
|
|
@@ -947,7 +967,7 @@ gdm_session_direct_handle_session_started (GdmSessionDirect *session,
|
|
}
|
|
|
|
reply = dbus_message_new_method_return (message);
|
|
- dbus_connection_send (connection, reply, NULL);
|
|
+ dbus_connection_send (conversation->worker_connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
g_debug ("GdmSessionDirect: Emitting 'session-started' signal with pid '%d'",
|
|
@@ -956,14 +976,14 @@ gdm_session_direct_handle_session_started (GdmSessionDirect *session,
|
|
session->priv->session_pid = pid;
|
|
session->priv->is_running = TRUE;
|
|
|
|
- _gdm_session_session_started (GDM_SESSION (session), pid);
|
|
+ _gdm_session_session_started (GDM_SESSION (session), conversation->service_name, pid);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
|
|
static DBusHandlerResult
|
|
gdm_session_direct_handle_start_failed (GdmSessionDirect *session,
|
|
- DBusConnection *connection,
|
|
+ GdmSessionConversation *conversation,
|
|
DBusMessage *message)
|
|
{
|
|
DBusMessage *reply;
|
|
@@ -978,18 +998,18 @@ gdm_session_direct_handle_start_failed (GdmSessionDirect *session,
|
|
}
|
|
|
|
reply = dbus_message_new_method_return (message);
|
|
- dbus_connection_send (connection, reply, NULL);
|
|
+ dbus_connection_send (conversation->worker_connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
g_debug ("GdmSessionDirect: Emitting 'session-start-failed' signal");
|
|
- _gdm_session_session_start_failed (GDM_SESSION (session), text);
|
|
+ _gdm_session_session_start_failed (GDM_SESSION (session), conversation->service_name, text);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
|
|
static DBusHandlerResult
|
|
gdm_session_direct_handle_session_exited (GdmSessionDirect *session,
|
|
- DBusConnection *connection,
|
|
+ GdmSessionConversation *conversation,
|
|
DBusMessage *message)
|
|
{
|
|
DBusMessage *reply;
|
|
@@ -1004,7 +1024,7 @@ gdm_session_direct_handle_session_exited (GdmSessionDirect *session,
|
|
}
|
|
|
|
reply = dbus_message_new_method_return (message);
|
|
- dbus_connection_send (connection, reply, NULL);
|
|
+ dbus_connection_send (conversation->worker_connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
g_debug ("GdmSessionDirect: Emitting 'session-exited' signal with exit code '%d'",
|
|
@@ -1018,7 +1038,7 @@ gdm_session_direct_handle_session_exited (GdmSessionDirect *session,
|
|
|
|
static DBusHandlerResult
|
|
gdm_session_direct_handle_session_died (GdmSessionDirect *session,
|
|
- DBusConnection *connection,
|
|
+ GdmSessionConversation *conversation,
|
|
DBusMessage *message)
|
|
{
|
|
DBusMessage *reply;
|
|
@@ -1033,7 +1053,7 @@ gdm_session_direct_handle_session_died (GdmSessionDirect *session,
|
|
}
|
|
|
|
reply = dbus_message_new_method_return (message);
|
|
- dbus_connection_send (connection, reply, NULL);
|
|
+ dbus_connection_send (conversation->worker_connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
g_debug ("GdmSessionDirect: Emitting 'session-died' signal with signal number '%d'",
|
|
@@ -1047,7 +1067,7 @@ gdm_session_direct_handle_session_died (GdmSessionDirect *session,
|
|
|
|
static DBusHandlerResult
|
|
gdm_session_direct_handle_saved_language_name_read (GdmSessionDirect *session,
|
|
- DBusConnection *connection,
|
|
+ GdmSessionConversation *conversation,
|
|
DBusMessage *message)
|
|
{
|
|
DBusMessage *reply;
|
|
@@ -1062,7 +1082,7 @@ gdm_session_direct_handle_saved_language_name_read (GdmSessionDirect *session,
|
|
}
|
|
|
|
reply = dbus_message_new_method_return (message);
|
|
- dbus_connection_send (connection, reply, NULL);
|
|
+ dbus_connection_send (conversation->worker_connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
if (strcmp (language_name,
|
|
@@ -1080,7 +1100,7 @@ gdm_session_direct_handle_saved_language_name_read (GdmSessionDirect *session,
|
|
|
|
static DBusHandlerResult
|
|
gdm_session_direct_handle_saved_layout_name_read (GdmSessionDirect *session,
|
|
- DBusConnection *connection,
|
|
+ GdmSessionConversation *conversation,
|
|
DBusMessage *message)
|
|
{
|
|
DBusMessage *reply;
|
|
@@ -1095,7 +1115,7 @@ gdm_session_direct_handle_saved_layout_name_read (GdmSessionDirect *session,
|
|
}
|
|
|
|
reply = dbus_message_new_method_return (message);
|
|
- dbus_connection_send (connection, reply, NULL);
|
|
+ dbus_connection_send (conversation->worker_connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
if (strcmp (layout_name,
|
|
@@ -1113,7 +1133,7 @@ gdm_session_direct_handle_saved_layout_name_read (GdmSessionDirect *session,
|
|
|
|
static DBusHandlerResult
|
|
gdm_session_direct_handle_saved_session_name_read (GdmSessionDirect *session,
|
|
- DBusConnection *connection,
|
|
+ GdmSessionConversation *conversation,
|
|
DBusMessage *message)
|
|
{
|
|
DBusMessage *reply;
|
|
@@ -1128,7 +1148,7 @@ gdm_session_direct_handle_saved_session_name_read (GdmSessionDirect *session,
|
|
}
|
|
|
|
reply = dbus_message_new_method_return (message);
|
|
- dbus_connection_send (connection, reply, NULL);
|
|
+ dbus_connection_send (conversation->worker_connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
if (! get_session_command_for_name (session_name, NULL)) {
|
|
@@ -1156,66 +1176,69 @@ session_worker_message (DBusConnection *connection,
|
|
DBusMessage *message,
|
|
void *user_data)
|
|
{
|
|
- GdmSessionDirect *session = GDM_SESSION_DIRECT (user_data);
|
|
+ GdmSessionConversation *conversation = user_data;
|
|
+ GdmSessionDirect *session;
|
|
+
|
|
+ session = conversation->session;
|
|
|
|
if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "InfoQuery")) {
|
|
- return gdm_session_direct_handle_info_query (session, connection, message);
|
|
+ return gdm_session_direct_handle_info_query (session, conversation, message);
|
|
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SecretInfoQuery")) {
|
|
- return gdm_session_direct_handle_secret_info_query (session, connection, message);
|
|
+ return gdm_session_direct_handle_secret_info_query (session, conversation, message);
|
|
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "Info")) {
|
|
- return gdm_session_direct_handle_info (session, connection, message);
|
|
+ return gdm_session_direct_handle_info (session, conversation, message);
|
|
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "Problem")) {
|
|
- return gdm_session_direct_handle_problem (session, connection, message);
|
|
+ return gdm_session_direct_handle_problem (session, conversation, message);
|
|
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "CancelPendingQuery")) {
|
|
- return gdm_session_direct_handle_cancel_pending_query (session, connection, message);
|
|
+ return gdm_session_direct_handle_cancel_pending_query (session, conversation, message);
|
|
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SetupComplete")) {
|
|
- return gdm_session_direct_handle_setup_complete (session, connection, message);
|
|
+ return gdm_session_direct_handle_setup_complete (session, conversation, message);
|
|
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SetupFailed")) {
|
|
- return gdm_session_direct_handle_setup_failed (session, connection, message);
|
|
+ return gdm_session_direct_handle_setup_failed (session, conversation, message);
|
|
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "ResetComplete")) {
|
|
- return gdm_session_direct_handle_reset_complete (session, connection, message);
|
|
+ return gdm_session_direct_handle_reset_complete (session, conversation, message);
|
|
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "ResetFailed")) {
|
|
- return gdm_session_direct_handle_reset_failed (session, connection, message);
|
|
+ return gdm_session_direct_handle_reset_failed (session, conversation, message);
|
|
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "Authenticated")) {
|
|
- return gdm_session_direct_handle_authenticated (session, connection, message);
|
|
+ return gdm_session_direct_handle_authenticated (session, conversation, message);
|
|
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "AuthenticationFailed")) {
|
|
- return gdm_session_direct_handle_authentication_failed (session, connection, message);
|
|
+ return gdm_session_direct_handle_authentication_failed (session, conversation, message);
|
|
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "Authorized")) {
|
|
- return gdm_session_direct_handle_authorized (session, connection, message);
|
|
+ return gdm_session_direct_handle_authorized (session, conversation, message);
|
|
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "AuthorizationFailed")) {
|
|
- return gdm_session_direct_handle_authorization_failed (session, connection, message);
|
|
+ return gdm_session_direct_handle_authorization_failed (session, conversation, message);
|
|
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "Accredited")) {
|
|
- return gdm_session_direct_handle_accredited (session, connection, message);
|
|
+ return gdm_session_direct_handle_accredited (session, conversation, message);
|
|
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "AccreditationFailed")) {
|
|
- return gdm_session_direct_handle_accreditation_failed (session, connection, message);
|
|
+ return gdm_session_direct_handle_accreditation_failed (session, conversation, message);
|
|
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "Authenticated")) {
|
|
- return gdm_session_direct_handle_authenticated (session, connection, message);
|
|
+ return gdm_session_direct_handle_authenticated (session, conversation, message);
|
|
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "AuthenticationFailed")) {
|
|
- return gdm_session_direct_handle_authentication_failed (session, connection, message);
|
|
+ return gdm_session_direct_handle_authentication_failed (session, conversation, message);
|
|
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "Authorized")) {
|
|
- return gdm_session_direct_handle_authorized (session, connection, message);
|
|
+ return gdm_session_direct_handle_authorized (session, conversation, message);
|
|
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "AuthorizationFailed")) {
|
|
- return gdm_session_direct_handle_authorization_failed (session, connection, message);
|
|
+ return gdm_session_direct_handle_authorization_failed (session, conversation, message);
|
|
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "Accredited")) {
|
|
- return gdm_session_direct_handle_accredited (session, connection, message);
|
|
+ return gdm_session_direct_handle_accredited (session, conversation, message);
|
|
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "AccreditationFailed")) {
|
|
- return gdm_session_direct_handle_accreditation_failed (session, connection, message);
|
|
+ return gdm_session_direct_handle_accreditation_failed (session, conversation, message);
|
|
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "UsernameChanged")) {
|
|
- return gdm_session_direct_handle_username_changed (session, connection, message);
|
|
+ return gdm_session_direct_handle_username_changed (session, conversation, message);
|
|
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SessionStarted")) {
|
|
- return gdm_session_direct_handle_session_started (session, connection, message);
|
|
+ return gdm_session_direct_handle_session_started (session, conversation, message);
|
|
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "StartFailed")) {
|
|
- return gdm_session_direct_handle_start_failed (session, connection, message);
|
|
+ return gdm_session_direct_handle_start_failed (session, conversation, message);
|
|
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SessionExited")) {
|
|
- return gdm_session_direct_handle_session_exited (session, connection, message);
|
|
+ return gdm_session_direct_handle_session_exited (session, conversation, message);
|
|
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SessionDied")) {
|
|
- return gdm_session_direct_handle_session_died (session, connection, message);
|
|
+ return gdm_session_direct_handle_session_died (session, conversation, message);
|
|
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SavedLanguageNameRead")) {
|
|
- return gdm_session_direct_handle_saved_language_name_read (session, connection, message);
|
|
+ return gdm_session_direct_handle_saved_language_name_read (session, conversation, message);
|
|
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SavedLayoutNameRead")) {
|
|
- return gdm_session_direct_handle_saved_layout_name_read (session, connection, message);
|
|
+ return gdm_session_direct_handle_saved_layout_name_read (session, conversation, message);
|
|
} else if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "SavedSessionNameRead")) {
|
|
- return gdm_session_direct_handle_saved_session_name_read (session, connection, message);
|
|
+ return gdm_session_direct_handle_saved_session_name_read (session, conversation, message);
|
|
}
|
|
|
|
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
|
@@ -1449,6 +1472,27 @@ session_unregister_handler (DBusConnection *connection,
|
|
g_debug ("session_unregister_handler");
|
|
}
|
|
|
|
+static GdmSessionConversation *
|
|
+find_conversation_by_pid (GdmSessionDirect *session,
|
|
+ GPid pid)
|
|
+{
|
|
+ GHashTableIter iter;
|
|
+ gpointer key, value;
|
|
+
|
|
+ g_hash_table_iter_init (&iter, session->priv->conversations);
|
|
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
|
|
+ GdmSessionConversation *conversation;
|
|
+
|
|
+ conversation = (GdmSessionConversation *) value;
|
|
+
|
|
+ if (conversation->worker_pid == pid) {
|
|
+ return conversation;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
static dbus_bool_t
|
|
allow_user_function (DBusConnection *connection,
|
|
unsigned long uid,
|
|
@@ -1463,40 +1507,83 @@ allow_user_function (DBusConnection *connection,
|
|
return FALSE;
|
|
}
|
|
|
|
-static GdmSessionConversation *
|
|
-find_conversation_by_name (GdmSessionDirect *session,
|
|
- const char *service_name)
|
|
+static gboolean
|
|
+register_worker (GdmSessionDirect *session,
|
|
+ DBusConnection *connection)
|
|
{
|
|
GdmSessionConversation *conversation;
|
|
+ DBusObjectPathVTable vtable = { &session_unregister_handler,
|
|
+ &session_message_handler,
|
|
+ NULL, NULL, NULL, NULL };
|
|
+ GList *connection_node;
|
|
+ gulong pid;
|
|
|
|
- conversation = g_hash_table_lookup (session->priv->conversations, service_name);
|
|
+ g_debug ("GdmSessionDirect: Authenticating new connection");
|
|
+
|
|
+ connection_node = g_list_find (session->priv->pending_connections, connection);
|
|
+
|
|
+ if (connection_node == NULL) {
|
|
+ g_debug ("GdmSessionDirect: Ignoring connection that we aren't tracking");
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ session->priv->pending_connections =
|
|
+ g_list_delete_link (session->priv->pending_connections,
|
|
+ connection_node);
|
|
+
|
|
+ if (!dbus_connection_get_unix_process_id (connection, &pid)) {
|
|
+ g_warning ("GdmSessionDirect: Unable to read pid on new worker connection");
|
|
+ dbus_connection_unref (connection);
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ conversation = find_conversation_by_pid (session, (GPid) pid);
|
|
|
|
if (conversation == NULL) {
|
|
- g_warning ("Tried to look up non-existant conversation");
|
|
+ g_warning ("GdmSessionDirect: New worker connection is from unknown source");
|
|
+ dbus_connection_unref (connection);
|
|
+ return FALSE;
|
|
}
|
|
|
|
- return conversation;
|
|
+ conversation->worker_connection = connection;
|
|
+
|
|
+ g_debug ("GdmSessionDirect: worker connection is %p", connection);
|
|
+
|
|
+ dbus_connection_register_object_path (connection,
|
|
+ GDM_SESSION_DBUS_PATH,
|
|
+ &vtable,
|
|
+ conversation);
|
|
+
|
|
+ g_debug ("GdmSessionDirect: Emitting conversation-started signal");
|
|
+ _gdm_session_conversation_started (GDM_SESSION (session),
|
|
+ conversation->service_name);
|
|
+
|
|
+ g_debug ("GdmSessionDirect: Conversation started");
|
|
+
|
|
+ return TRUE;
|
|
}
|
|
|
|
-static GdmSessionConversation *
|
|
-find_conversation_by_pid (GdmSessionDirect *session,
|
|
- GPid pid)
|
|
+static DBusHandlerResult
|
|
+on_message (DBusConnection *connection, DBusMessage *message, void *user_data)
|
|
{
|
|
- GHashTableIter iter;
|
|
- gpointer key, value;
|
|
+ GdmSessionDirect *session = GDM_SESSION_DIRECT (user_data);
|
|
|
|
- g_hash_table_iter_init (&iter, session->priv->conversations);
|
|
- while (g_hash_table_iter_next (&iter, &key, &value)) {
|
|
- GdmSessionConversation *conversation;
|
|
+ g_debug ("GdmSessionDirect: got message");
|
|
|
|
- conversation = (GdmSessionConversation *) value;
|
|
+ if (dbus_message_is_method_call (message, GDM_SESSION_DBUS_INTERFACE, "Hello")) {
|
|
+ DBusMessage *reply;
|
|
|
|
- if (conversation->worker_pid == pid) {
|
|
- return conversation;
|
|
+ if (register_worker (session, connection)) {
|
|
+ reply = dbus_message_new_method_return (message);
|
|
+ } else {
|
|
+ reply = dbus_message_new_error (message, DBUS_ERROR_FAILED, "");
|
|
}
|
|
+
|
|
+ dbus_connection_send (connection, reply, NULL);
|
|
+ return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
|
|
- return NULL;
|
|
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
|
}
|
|
|
|
static void
|
|
@@ -1505,50 +1592,23 @@ handle_connection (DBusServer *server,
|
|
void *user_data)
|
|
{
|
|
GdmSessionDirect *session = GDM_SESSION_DIRECT (user_data);
|
|
- GdmSessionConversation *conversation;
|
|
- gulong pid;
|
|
-
|
|
g_debug ("GdmSessionDirect: Handing new connection");
|
|
|
|
- if (!dbus_connection_get_unix_process_id (new_connection, &pid)) {
|
|
- g_warning ("Unable to read pid on new worker connection");
|
|
- return;
|
|
- }
|
|
-
|
|
- conversation = find_conversation_by_pid (session, (GPid) pid);
|
|
-
|
|
- if (conversation == NULL) {
|
|
- g_warning ("New worker connection is from unknown source");
|
|
- return;
|
|
- }
|
|
-
|
|
- if (conversation->worker_connection == NULL) {
|
|
- DBusObjectPathVTable vtable = { &session_unregister_handler,
|
|
- &session_message_handler,
|
|
- NULL, NULL, NULL, NULL
|
|
- };
|
|
-
|
|
- conversation->worker_connection = new_connection;
|
|
- dbus_connection_ref (new_connection);
|
|
- dbus_connection_setup_with_g_main (new_connection, NULL);
|
|
-
|
|
- g_debug ("GdmSessionDirect: worker connection is %p", new_connection);
|
|
- dbus_connection_set_exit_on_disconnect (new_connection, FALSE);
|
|
-
|
|
- dbus_connection_set_unix_user_function (new_connection,
|
|
- allow_user_function,
|
|
- session,
|
|
- NULL);
|
|
-
|
|
- dbus_connection_register_object_path (new_connection,
|
|
- GDM_SESSION_DBUS_PATH,
|
|
- &vtable,
|
|
- session);
|
|
+ /* add to the list of pending connections. We won't be able to
|
|
+ * associate it with a specific worker conversation until we have
|
|
+ * authenticated the connection (from the Hello handler).
|
|
+ */
|
|
+ session->priv->pending_connections =
|
|
+ g_list_prepend (session->priv->pending_connections,
|
|
+ dbus_connection_ref (new_connection));
|
|
+ dbus_connection_setup_with_g_main (new_connection, NULL);
|
|
+ dbus_connection_set_exit_on_disconnect (new_connection, FALSE);
|
|
|
|
- g_debug ("GdmSessionDirect: Emitting conversation-started signal");
|
|
- _gdm_session_conversation_started (GDM_SESSION (session),
|
|
- conversation->service_name);
|
|
- }
|
|
+ dbus_connection_set_unix_user_function (new_connection,
|
|
+ allow_user_function,
|
|
+ session,
|
|
+ NULL);
|
|
+ dbus_connection_add_filter (new_connection, on_message, session, NULL);
|
|
}
|
|
|
|
static gboolean
|
|
@@ -1655,7 +1715,7 @@ worker_exited (GdmSessionWorkerJob *job,
|
|
char *msg;
|
|
|
|
msg = g_strdup_printf (_("worker exited with status %d"), code);
|
|
- _gdm_session_authentication_failed (GDM_SESSION (conversation->session), msg);
|
|
+ _gdm_session_authentication_failed (GDM_SESSION (conversation->session), conversation->service_name, msg);
|
|
g_free (msg);
|
|
} else if (conversation->session->priv->is_running) {
|
|
_gdm_session_session_exited (GDM_SESSION (conversation->session), code);
|
|
@@ -1673,7 +1733,7 @@ worker_died (GdmSessionWorkerJob *job,
|
|
char *msg;
|
|
|
|
msg = g_strdup_printf (_("worker exited with status %d"), signum);
|
|
- _gdm_session_authentication_failed (GDM_SESSION (conversation->session), msg);
|
|
+ _gdm_session_authentication_failed (GDM_SESSION (conversation->session), conversation->service_name, msg);
|
|
g_free (msg);
|
|
} else if (conversation->session->priv->is_running) {
|
|
_gdm_session_session_died (GDM_SESSION (conversation->session), signum);
|
|
@@ -1771,10 +1831,6 @@ gdm_session_direct_start_conversation (GdmSession *session,
|
|
|
|
g_hash_table_insert (impl->priv->conversations,
|
|
g_strdup (service_name), conversation);
|
|
-
|
|
- if (impl->priv->conversation != NULL) {
|
|
- impl->priv->conversation = conversation;
|
|
- }
|
|
}
|
|
|
|
static void
|
|
@@ -1925,45 +1981,50 @@ gdm_session_direct_setup_for_user (GdmSession *session,
|
|
}
|
|
|
|
static void
|
|
-gdm_session_direct_authenticate (GdmSession *session)
|
|
+gdm_session_direct_authenticate (GdmSession *session,
|
|
+ const char *service_name)
|
|
{
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
GdmSessionConversation *conversation;
|
|
|
|
g_return_if_fail (session != NULL);
|
|
- g_return_if_fail (impl->priv->conversation != NULL);
|
|
- g_return_if_fail (dbus_connection_get_is_connected (impl->priv->conversation->worker_connection));
|
|
|
|
- conversation = impl->priv->conversation;
|
|
- send_dbus_void_signal (conversation, "Authenticate");
|
|
+ conversation = find_conversation_by_name (impl, service_name);
|
|
+ if (conversation != NULL) {
|
|
+ send_dbus_void_signal (conversation, "Authenticate");
|
|
+ }
|
|
}
|
|
|
|
static void
|
|
-gdm_session_direct_authorize (GdmSession *session)
|
|
+gdm_session_direct_authorize (GdmSession *session,
|
|
+ const char *service_name)
|
|
{
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
GdmSessionConversation *conversation;
|
|
|
|
g_return_if_fail (session != NULL);
|
|
- g_return_if_fail (impl->priv->conversation != NULL);
|
|
- g_return_if_fail (dbus_connection_get_is_connected (impl->priv->conversation->worker_connection));
|
|
|
|
- conversation = impl->priv->conversation;
|
|
- send_dbus_void_signal (conversation, "Authorize");
|
|
+ conversation = find_conversation_by_name (impl, service_name);
|
|
+ if (conversation != NULL) {
|
|
+ send_dbus_void_signal (conversation, "Authorize");
|
|
+ }
|
|
}
|
|
|
|
static void
|
|
gdm_session_direct_accredit (GdmSession *session,
|
|
+ const char *service_name,
|
|
int cred_flag)
|
|
{
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
GdmSessionConversation *conversation;
|
|
|
|
g_return_if_fail (session != NULL);
|
|
- g_return_if_fail (impl->priv->conversation != NULL);
|
|
- g_return_if_fail (dbus_connection_get_is_connected (impl->priv->conversation->worker_connection));
|
|
|
|
- conversation = impl->priv->conversation;
|
|
+ conversation = find_conversation_by_name (impl, service_name);
|
|
+ if (conversation == NULL) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
switch (cred_flag) {
|
|
case GDM_SESSION_CRED_ESTABLISH:
|
|
send_dbus_void_signal (conversation, "EstablishCredentials");
|
|
@@ -1977,13 +2038,12 @@ gdm_session_direct_accredit (GdmSession *session,
|
|
}
|
|
|
|
static void
|
|
-send_environment_variable (const char *key,
|
|
- const char *value,
|
|
- GdmSessionDirect *session)
|
|
+send_environment_variable (const char *key,
|
|
+ const char *value,
|
|
+ GdmSessionConversation *conversation)
|
|
{
|
|
DBusMessage *message;
|
|
DBusMessageIter iter;
|
|
- GdmSessionConversation *conversation;
|
|
|
|
message = dbus_message_new_signal (GDM_SESSION_DBUS_PATH,
|
|
GDM_SESSION_DBUS_INTERFACE,
|
|
@@ -1993,7 +2053,6 @@ send_environment_variable (const char *key,
|
|
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &key);
|
|
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &value);
|
|
|
|
- conversation = session->priv->conversation;
|
|
if (! send_dbus_message (conversation, message)) {
|
|
g_debug ("GdmSessionDirect: Could not send %s signal", "SetEnvironmentVariable");
|
|
}
|
|
@@ -2002,12 +2061,13 @@ send_environment_variable (const char *key,
|
|
}
|
|
|
|
static void
|
|
-send_environment (GdmSessionDirect *session)
|
|
+send_environment (GdmSessionDirect *session,
|
|
+ GdmSessionConversation *conversation)
|
|
{
|
|
|
|
g_hash_table_foreach (session->priv->environment,
|
|
(GHFunc) send_environment_variable,
|
|
- session);
|
|
+ conversation);
|
|
}
|
|
|
|
static const char *
|
|
@@ -2121,7 +2181,8 @@ setup_session_environment (GdmSessionDirect *session)
|
|
}
|
|
|
|
static void
|
|
-gdm_session_direct_start_session (GdmSession *session)
|
|
+gdm_session_direct_start_session (GdmSession *session,
|
|
+ const char *service_name)
|
|
{
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
GdmSessionConversation *conversation;
|
|
@@ -2135,10 +2196,11 @@ gdm_session_direct_start_session (GdmSession *session)
|
|
program = g_strdup_printf (GDMCONFDIR "/Xsession \"%s\"", command);
|
|
g_free (command);
|
|
|
|
+ conversation = find_conversation_by_name (impl, service_name);
|
|
+
|
|
setup_session_environment (impl);
|
|
- send_environment (impl);
|
|
+ send_environment (impl, conversation);
|
|
|
|
- conversation = impl->priv->conversation;
|
|
send_dbus_string_signal (conversation, "StartProgram", program);
|
|
g_free (program);
|
|
}
|
|
@@ -2180,6 +2242,11 @@ gdm_session_direct_close (GdmSession *session)
|
|
|
|
stop_all_conversations (impl);
|
|
|
|
+ g_list_foreach (impl->priv->pending_connections,
|
|
+ (GFunc) dbus_connection_unref, NULL);
|
|
+ g_list_free (impl->priv->pending_connections);
|
|
+ impl->priv->pending_connections = NULL;
|
|
+
|
|
g_free (impl->priv->selected_user);
|
|
impl->priv->selected_user = NULL;
|
|
|
|
@@ -2212,13 +2279,14 @@ gdm_session_direct_close (GdmSession *session)
|
|
|
|
static void
|
|
gdm_session_direct_answer_query (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text)
|
|
{
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
|
|
g_return_if_fail (session != NULL);
|
|
|
|
- answer_pending_query (impl, text);
|
|
+ answer_pending_query (impl, service_name, text);
|
|
}
|
|
|
|
static void
|
|
@@ -2244,7 +2312,8 @@ gdm_session_direct_select_session (GdmSession *session,
|
|
const char *text)
|
|
{
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
- GdmSessionConversation *conversation;
|
|
+ GHashTableIter iter;
|
|
+ gpointer key, value;
|
|
|
|
g_free (impl->priv->selected_session);
|
|
|
|
@@ -2254,9 +2323,15 @@ gdm_session_direct_select_session (GdmSession *session,
|
|
impl->priv->selected_session = g_strdup (text);
|
|
}
|
|
|
|
- conversation = impl->priv->conversation;
|
|
- send_dbus_string_signal (conversation, "SetSessionName",
|
|
- get_session_name (impl));
|
|
+ g_hash_table_iter_init (&iter, impl->priv->conversations);
|
|
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
|
|
+ GdmSessionConversation *conversation;
|
|
+
|
|
+ conversation = (GdmSessionConversation *) value;
|
|
+
|
|
+ send_dbus_string_signal (conversation, "SetSessionName",
|
|
+ get_session_name (impl));
|
|
+ }
|
|
}
|
|
|
|
static void
|
|
@@ -2264,7 +2339,8 @@ gdm_session_direct_select_language (GdmSession *session,
|
|
const char *text)
|
|
{
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
- GdmSessionConversation *conversation;
|
|
+ GHashTableIter iter;
|
|
+ gpointer key, value;
|
|
|
|
g_free (impl->priv->selected_language);
|
|
|
|
@@ -2274,9 +2350,15 @@ gdm_session_direct_select_language (GdmSession *session,
|
|
impl->priv->selected_language = g_strdup (text);
|
|
}
|
|
|
|
- conversation = impl->priv->conversation;
|
|
- send_dbus_string_signal (conversation, "SetLanguageName",
|
|
- get_language_name (impl));
|
|
+ g_hash_table_iter_init (&iter, impl->priv->conversations);
|
|
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
|
|
+ GdmSessionConversation *conversation;
|
|
+
|
|
+ conversation = (GdmSessionConversation *) value;
|
|
+
|
|
+ send_dbus_string_signal (conversation, "SetLanguageName",
|
|
+ get_language_name (impl));
|
|
+ }
|
|
}
|
|
|
|
static void
|
|
@@ -2284,7 +2366,8 @@ gdm_session_direct_select_layout (GdmSession *session,
|
|
const char *text)
|
|
{
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
- GdmSessionConversation *conversation;
|
|
+ GHashTableIter iter;
|
|
+ gpointer key, value;
|
|
|
|
g_free (impl->priv->selected_layout);
|
|
|
|
@@ -2294,9 +2377,15 @@ gdm_session_direct_select_layout (GdmSession *session,
|
|
impl->priv->selected_layout = g_strdup (text);
|
|
}
|
|
|
|
- conversation = impl->priv->conversation;
|
|
- send_dbus_string_signal (conversation, "SetLayoutName",
|
|
- get_layout_name (impl));
|
|
+ g_hash_table_iter_init (&iter, impl->priv->conversations);
|
|
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
|
|
+ GdmSessionConversation *conversation;
|
|
+
|
|
+ conversation = (GdmSessionConversation *) value;
|
|
+
|
|
+ send_dbus_string_signal (conversation, "SetLayoutName",
|
|
+ get_language_name (impl));
|
|
+ }
|
|
}
|
|
|
|
static void
|
|
diff --git a/daemon/gdm-session-private.h b/daemon/gdm-session-private.h
|
|
index 074aa6f..de6e54a 100644
|
|
--- a/daemon/gdm-session-private.h
|
|
+++ b/daemon/gdm-session-private.h
|
|
@@ -29,24 +29,34 @@ G_BEGIN_DECLS
|
|
/* state changes */
|
|
void _gdm_session_conversation_started (GdmSession *session,
|
|
const char *service_name);
|
|
-void _gdm_session_setup_complete (GdmSession *session);
|
|
+void _gdm_session_setup_complete (GdmSession *session,
|
|
+ const char *service_name);
|
|
void _gdm_session_setup_failed (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *message);
|
|
void _gdm_session_reset_complete (GdmSession *session);
|
|
void _gdm_session_reset_failed (GdmSession *session,
|
|
const char *message);
|
|
-void _gdm_session_authenticated (GdmSession *session);
|
|
+void _gdm_session_authenticated (GdmSession *session,
|
|
+ const char *service_name);
|
|
void _gdm_session_authentication_failed (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text);
|
|
-void _gdm_session_authorized (GdmSession *session);
|
|
+void _gdm_session_authorized (GdmSession *session,
|
|
+ const char *service_name);
|
|
void _gdm_session_authorization_failed (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text);
|
|
-void _gdm_session_accredited (GdmSession *session);
|
|
+void _gdm_session_accredited (GdmSession *session,
|
|
+ const char *service_name);
|
|
void _gdm_session_accreditation_failed (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text);
|
|
void _gdm_session_session_started (GdmSession *session,
|
|
+ const char *service_name,
|
|
int pid);
|
|
void _gdm_session_session_start_failed (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *message);
|
|
void _gdm_session_session_exited (GdmSession *session,
|
|
int exit_code);
|
|
@@ -67,12 +77,16 @@ void _gdm_session_selected_user_changed (GdmSession *sessio
|
|
|
|
/* call and response stuff */
|
|
void _gdm_session_info_query (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text);
|
|
void _gdm_session_secret_info_query (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text);
|
|
void _gdm_session_info (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text);
|
|
void _gdm_session_problem (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text);
|
|
|
|
G_END_DECLS
|
|
diff --git a/daemon/gdm-session-relay.c b/daemon/gdm-session-relay.c
|
|
index 35b4738..36e86b5 100644
|
|
--- a/daemon/gdm-session-relay.c
|
|
+++ b/daemon/gdm-session-relay.c
|
|
@@ -212,31 +212,34 @@ gdm_session_relay_setup_for_user (GdmSession *session,
|
|
}
|
|
|
|
static void
|
|
-gdm_session_relay_authenticate (GdmSession *session)
|
|
+gdm_session_relay_authenticate (GdmSession *session,
|
|
+ const char *service_name)
|
|
{
|
|
GdmSessionRelay *impl = GDM_SESSION_RELAY (session);
|
|
- send_dbus_void_signal (impl, "Authenticate");
|
|
+ send_dbus_string_signal (impl, "Authenticate", service_name);
|
|
}
|
|
|
|
static void
|
|
-gdm_session_relay_authorize (GdmSession *session)
|
|
+gdm_session_relay_authorize (GdmSession *session,
|
|
+ const char *service_name)
|
|
{
|
|
GdmSessionRelay *impl = GDM_SESSION_RELAY (session);
|
|
- send_dbus_void_signal (impl, "Authorize");
|
|
+ send_dbus_string_signal (impl, "Authorize", service_name);
|
|
}
|
|
|
|
static void
|
|
gdm_session_relay_accredit (GdmSession *session,
|
|
+ const char *service_name,
|
|
int cred_flag)
|
|
{
|
|
GdmSessionRelay *impl = GDM_SESSION_RELAY (session);
|
|
|
|
switch (cred_flag) {
|
|
case GDM_SESSION_CRED_ESTABLISH:
|
|
- send_dbus_void_signal (impl, "EstablishCredentials");
|
|
+ send_dbus_string_signal (impl, "EstablishCredentials", service_name);
|
|
break;
|
|
case GDM_SESSION_CRED_REFRESH:
|
|
- send_dbus_void_signal (impl, "RefreshCredentials");
|
|
+ send_dbus_string_signal (impl, "RefreshCredentials", service_name);
|
|
break;
|
|
default:
|
|
g_assert_not_reached ();
|
|
@@ -245,10 +248,11 @@ gdm_session_relay_accredit (GdmSession *session,
|
|
|
|
static void
|
|
gdm_session_relay_answer_query (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text)
|
|
{
|
|
GdmSessionRelay *impl = GDM_SESSION_RELAY (session);
|
|
- send_dbus_string_signal (impl, "AnswerQuery", text);
|
|
+ send_dbus_string_string_signal (impl, "AnswerQuery", service_name, text);
|
|
}
|
|
|
|
static void
|
|
@@ -334,10 +338,12 @@ handle_info_query (GdmSessionRelay *session_relay,
|
|
{
|
|
DBusMessage *reply;
|
|
DBusError error;
|
|
- const char *text;
|
|
+ char *service_name;
|
|
+ char *text;
|
|
|
|
dbus_error_init (&error);
|
|
if (! dbus_message_get_args (message, &error,
|
|
+ DBUS_TYPE_STRING, &service_name,
|
|
DBUS_TYPE_STRING, &text,
|
|
DBUS_TYPE_INVALID)) {
|
|
g_warning ("ERROR: %s", error.message);
|
|
@@ -349,7 +355,7 @@ handle_info_query (GdmSessionRelay *session_relay,
|
|
dbus_connection_send (connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
- _gdm_session_info_query (GDM_SESSION (session_relay), text);
|
|
+ _gdm_session_info_query (GDM_SESSION (session_relay), service_name, text);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
@@ -361,12 +367,14 @@ handle_secret_info_query (GdmSessionRelay *session_relay,
|
|
{
|
|
DBusMessage *reply;
|
|
DBusError error;
|
|
- const char *text;
|
|
+ char *service_name;
|
|
+ char *text;
|
|
|
|
text = NULL;
|
|
|
|
dbus_error_init (&error);
|
|
if (! dbus_message_get_args (message, &error,
|
|
+ DBUS_TYPE_STRING, &service_name,
|
|
DBUS_TYPE_STRING, &text,
|
|
DBUS_TYPE_INVALID)) {
|
|
g_warning ("ERROR: %s", error.message);
|
|
@@ -378,7 +386,7 @@ handle_secret_info_query (GdmSessionRelay *session_relay,
|
|
dbus_connection_send (connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
- _gdm_session_secret_info_query (GDM_SESSION (session_relay), text);
|
|
+ _gdm_session_secret_info_query (GDM_SESSION (session_relay), service_name, text);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
@@ -390,12 +398,14 @@ handle_info (GdmSessionRelay *session_relay,
|
|
{
|
|
DBusMessage *reply;
|
|
DBusError error;
|
|
- const char *text;
|
|
+ char *service_name;
|
|
+ char *text;
|
|
|
|
text = NULL;
|
|
|
|
dbus_error_init (&error);
|
|
if (! dbus_message_get_args (message, &error,
|
|
+ DBUS_TYPE_STRING, &service_name,
|
|
DBUS_TYPE_STRING, &text,
|
|
DBUS_TYPE_INVALID)) {
|
|
g_warning ("ERROR: %s", error.message);
|
|
@@ -407,7 +417,7 @@ handle_info (GdmSessionRelay *session_relay,
|
|
dbus_connection_send (connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
- _gdm_session_info (GDM_SESSION (session_relay), text);
|
|
+ _gdm_session_info (GDM_SESSION (session_relay), service_name, text);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
@@ -419,12 +429,14 @@ handle_problem (GdmSessionRelay *session_relay,
|
|
{
|
|
DBusMessage *reply;
|
|
DBusError error;
|
|
- const char *text;
|
|
+ char *service_name;
|
|
+ char *text;
|
|
|
|
text = NULL;
|
|
|
|
dbus_error_init (&error);
|
|
if (! dbus_message_get_args (message, &error,
|
|
+ DBUS_TYPE_STRING, &service_name,
|
|
DBUS_TYPE_STRING, &text,
|
|
DBUS_TYPE_INVALID)) {
|
|
g_warning ("ERROR: %s", error.message);
|
|
@@ -436,7 +448,7 @@ handle_problem (GdmSessionRelay *session_relay,
|
|
dbus_connection_send (connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
- _gdm_session_problem (GDM_SESSION (session_relay), text);
|
|
+ _gdm_session_problem (GDM_SESSION (session_relay), service_name, text);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
@@ -448,8 +460,15 @@ handle_setup_complete (GdmSessionRelay *session_relay,
|
|
{
|
|
DBusMessage *reply;
|
|
DBusError error;
|
|
+ char *service_name;
|
|
|
|
dbus_error_init (&error);
|
|
+ if (! dbus_message_get_args (message, &error,
|
|
+ DBUS_TYPE_STRING, &service_name,
|
|
+ DBUS_TYPE_INVALID)) {
|
|
+ g_warning ("ERROR: %s", error.message);
|
|
+ }
|
|
+ dbus_error_free (&error);
|
|
|
|
g_debug ("GdmSessionRelay: SetupComplete");
|
|
|
|
@@ -457,7 +476,7 @@ handle_setup_complete (GdmSessionRelay *session_relay,
|
|
dbus_connection_send (connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
- _gdm_session_setup_complete (GDM_SESSION (session_relay));
|
|
+ _gdm_session_setup_complete (GDM_SESSION (session_relay), service_name);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
@@ -469,8 +488,15 @@ handle_setup_failed (GdmSessionRelay *session_relay,
|
|
{
|
|
DBusMessage *reply;
|
|
DBusError error;
|
|
+ char *service_name;
|
|
|
|
dbus_error_init (&error);
|
|
+ if (! dbus_message_get_args (message, &error,
|
|
+ DBUS_TYPE_STRING, &service_name,
|
|
+ DBUS_TYPE_INVALID)) {
|
|
+ g_warning ("ERROR: %s", error.message);
|
|
+ }
|
|
+ dbus_error_free (&error);
|
|
|
|
g_debug ("GdmSessionRelay: SetupFailed");
|
|
|
|
@@ -478,7 +504,7 @@ handle_setup_failed (GdmSessionRelay *session_relay,
|
|
dbus_connection_send (connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
- _gdm_session_setup_failed (GDM_SESSION (session_relay), NULL);
|
|
+ _gdm_session_setup_failed (GDM_SESSION (session_relay), service_name, NULL);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
@@ -491,8 +517,15 @@ handle_authenticated (GdmSessionRelay *session_relay,
|
|
{
|
|
DBusMessage *reply;
|
|
DBusError error;
|
|
+ char *service_name;
|
|
|
|
dbus_error_init (&error);
|
|
+ if (! dbus_message_get_args (message, &error,
|
|
+ DBUS_TYPE_STRING, &service_name,
|
|
+ DBUS_TYPE_INVALID)) {
|
|
+ g_warning ("ERROR: %s", error.message);
|
|
+ }
|
|
+ dbus_error_free (&error);
|
|
|
|
g_debug ("GdmSessionRelay: Authenticated");
|
|
|
|
@@ -500,7 +533,7 @@ handle_authenticated (GdmSessionRelay *session_relay,
|
|
dbus_connection_send (connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
- _gdm_session_authenticated (GDM_SESSION (session_relay));
|
|
+ _gdm_session_authenticated (GDM_SESSION (session_relay), service_name);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
@@ -512,8 +545,15 @@ handle_authentication_failed (GdmSessionRelay *session_relay,
|
|
{
|
|
DBusMessage *reply;
|
|
DBusError error;
|
|
+ char *service_name;
|
|
|
|
dbus_error_init (&error);
|
|
+ if (! dbus_message_get_args (message, &error,
|
|
+ DBUS_TYPE_STRING, &service_name,
|
|
+ DBUS_TYPE_INVALID)) {
|
|
+ g_warning ("ERROR: %s", error.message);
|
|
+ }
|
|
+ dbus_error_free (&error);
|
|
|
|
g_debug ("GdmSessionRelay: AuthenticationFailed");
|
|
|
|
@@ -521,7 +561,7 @@ handle_authentication_failed (GdmSessionRelay *session_relay,
|
|
dbus_connection_send (connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
- _gdm_session_authentication_failed (GDM_SESSION (session_relay), NULL);
|
|
+ _gdm_session_authentication_failed (GDM_SESSION (session_relay), service_name, NULL);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
@@ -533,8 +573,15 @@ handle_authorized (GdmSessionRelay *session_relay,
|
|
{
|
|
DBusMessage *reply;
|
|
DBusError error;
|
|
+ char *service_name;
|
|
|
|
dbus_error_init (&error);
|
|
+ if (! dbus_message_get_args (message, &error,
|
|
+ DBUS_TYPE_STRING, &service_name,
|
|
+ DBUS_TYPE_INVALID)) {
|
|
+ g_warning ("ERROR: %s", error.message);
|
|
+ }
|
|
+ dbus_error_free (&error);
|
|
|
|
g_debug ("GdmSessionRelay: Authorized");
|
|
|
|
@@ -542,7 +589,7 @@ handle_authorized (GdmSessionRelay *session_relay,
|
|
dbus_connection_send (connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
- _gdm_session_authorized (GDM_SESSION (session_relay));
|
|
+ _gdm_session_authorized (GDM_SESSION (session_relay), service_name);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
@@ -554,8 +601,15 @@ handle_authorization_failed (GdmSessionRelay *session_relay,
|
|
{
|
|
DBusMessage *reply;
|
|
DBusError error;
|
|
+ char *service_name;
|
|
|
|
dbus_error_init (&error);
|
|
+ if (! dbus_message_get_args (message, &error,
|
|
+ DBUS_TYPE_STRING, &service_name,
|
|
+ DBUS_TYPE_INVALID)) {
|
|
+ g_warning ("ERROR: %s", error.message);
|
|
+ }
|
|
+ dbus_error_free (&error);
|
|
|
|
g_debug ("GdmSessionRelay: AuthorizationFailed");
|
|
|
|
@@ -563,7 +617,7 @@ handle_authorization_failed (GdmSessionRelay *session_relay,
|
|
dbus_connection_send (connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
- _gdm_session_authorization_failed (GDM_SESSION (session_relay), NULL);
|
|
+ _gdm_session_authorization_failed (GDM_SESSION (session_relay), service_name, NULL);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
@@ -575,8 +629,15 @@ handle_accredited (GdmSessionRelay *session_relay,
|
|
{
|
|
DBusMessage *reply;
|
|
DBusError error;
|
|
+ char *service_name;
|
|
|
|
dbus_error_init (&error);
|
|
+ if (! dbus_message_get_args (message, &error,
|
|
+ DBUS_TYPE_STRING, &service_name,
|
|
+ DBUS_TYPE_INVALID)) {
|
|
+ g_warning ("ERROR: %s", error.message);
|
|
+ }
|
|
+ dbus_error_free (&error);
|
|
|
|
g_debug ("GdmSessionRelay: Accredited");
|
|
|
|
@@ -584,7 +645,7 @@ handle_accredited (GdmSessionRelay *session_relay,
|
|
dbus_connection_send (connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
- _gdm_session_accredited (GDM_SESSION (session_relay));
|
|
+ _gdm_session_accredited (GDM_SESSION (session_relay), service_name);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
@@ -596,8 +657,15 @@ handle_accreditation_failed (GdmSessionRelay *session_relay,
|
|
{
|
|
DBusMessage *reply;
|
|
DBusError error;
|
|
+ char *service_name;
|
|
|
|
dbus_error_init (&error);
|
|
+ if (! dbus_message_get_args (message, &error,
|
|
+ DBUS_TYPE_STRING, &service_name,
|
|
+ DBUS_TYPE_INVALID)) {
|
|
+ g_warning ("ERROR: %s", error.message);
|
|
+ }
|
|
+ dbus_error_free (&error);
|
|
|
|
g_debug ("GdmSessionRelay: AccreditationFailed");
|
|
|
|
@@ -605,7 +673,7 @@ handle_accreditation_failed (GdmSessionRelay *session_relay,
|
|
dbus_connection_send (connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
- _gdm_session_accreditation_failed (GDM_SESSION (session_relay), NULL);
|
|
+ _gdm_session_accreditation_failed (GDM_SESSION (session_relay), service_name, NULL);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
@@ -617,6 +685,7 @@ handle_session_started (GdmSessionRelay *session_relay,
|
|
{
|
|
DBusMessage *reply;
|
|
DBusError error;
|
|
+ char *service_name;
|
|
int pid;
|
|
|
|
dbus_error_init (&error);
|
|
@@ -624,6 +693,7 @@ handle_session_started (GdmSessionRelay *session_relay,
|
|
pid = 0;
|
|
if (! dbus_message_get_args (message,
|
|
&error,
|
|
+ DBUS_TYPE_STRING, &service_name,
|
|
DBUS_TYPE_INT32, &pid,
|
|
DBUS_TYPE_INVALID)) {
|
|
g_warning ("ERROR: %s", error.message);
|
|
@@ -636,6 +706,7 @@ handle_session_started (GdmSessionRelay *session_relay,
|
|
dbus_message_unref (reply);
|
|
|
|
_gdm_session_session_started (GDM_SESSION (session_relay),
|
|
+ service_name,
|
|
pid);
|
|
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
|
|
index 565420a..27fce28 100644
|
|
--- a/daemon/gdm-session-worker.c
|
|
+++ b/daemon/gdm-session-worker.c
|
|
@@ -2568,6 +2568,28 @@ worker_dbus_filter_function (DBusConnection *connection,
|
|
return DBUS_HANDLER_RESULT_HANDLED;
|
|
}
|
|
|
|
+static void
|
|
+send_hello (GdmSessionWorker *worker)
|
|
+{
|
|
+ DBusMessage *message, *reply;
|
|
+ DBusError error;
|
|
+
|
|
+ message = dbus_message_new_method_call (NULL,
|
|
+ GDM_SESSION_DBUS_PATH,
|
|
+ GDM_SESSION_DBUS_INTERFACE,
|
|
+ "Hello");
|
|
+
|
|
+ dbus_error_init (&error);
|
|
+ reply = dbus_connection_send_with_reply_and_block (worker->priv->connection,
|
|
+ message, -1, &error);
|
|
+ dbus_message_unref (message);
|
|
+ dbus_error_free (&error);
|
|
+
|
|
+ if (reply != NULL) {
|
|
+ dbus_message_unref (reply);
|
|
+ }
|
|
+}
|
|
+
|
|
static GObject *
|
|
gdm_session_worker_constructor (GType type,
|
|
guint n_construct_properties,
|
|
@@ -2594,6 +2616,11 @@ gdm_session_worker_constructor (GType type,
|
|
exit (1);
|
|
}
|
|
|
|
+ /* Send an initial Hello message so that the session can associate
|
|
+ * the conversation we manage with our pid.
|
|
+ */
|
|
+ send_hello (worker);
|
|
+
|
|
dbus_connection_setup_with_g_main (worker->priv->connection, NULL);
|
|
dbus_connection_set_exit_on_disconnect (worker->priv->connection, TRUE);
|
|
|
|
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
|
|
index 0073294..5f6ff5d 100644
|
|
--- a/daemon/gdm-session.c
|
|
+++ b/daemon/gdm-session.c
|
|
@@ -24,6 +24,7 @@
|
|
#include <glib/gi18n.h>
|
|
#include <glib-object.h>
|
|
|
|
+#include "gdm-marshal.h"
|
|
#include "gdm-session.h"
|
|
#include "gdm-session-private.h"
|
|
|
|
@@ -114,37 +115,41 @@ gdm_session_setup_for_user (GdmSession *session,
|
|
}
|
|
|
|
void
|
|
-gdm_session_authenticate (GdmSession *session)
|
|
+gdm_session_authenticate (GdmSession *session,
|
|
+ const char *service_name)
|
|
{
|
|
g_return_if_fail (GDM_IS_SESSION (session));
|
|
|
|
- GDM_SESSION_GET_IFACE (session)->authenticate (session);
|
|
+ GDM_SESSION_GET_IFACE (session)->authenticate (session, service_name);
|
|
}
|
|
|
|
void
|
|
-gdm_session_authorize (GdmSession *session)
|
|
+gdm_session_authorize (GdmSession *session,
|
|
+ const char *service_name)
|
|
{
|
|
g_return_if_fail (GDM_IS_SESSION (session));
|
|
|
|
- GDM_SESSION_GET_IFACE (session)->authorize (session);
|
|
+ GDM_SESSION_GET_IFACE (session)->authorize (session, service_name);
|
|
}
|
|
|
|
void
|
|
gdm_session_accredit (GdmSession *session,
|
|
+ const char *service_name,
|
|
int flag)
|
|
{
|
|
g_return_if_fail (GDM_IS_SESSION (session));
|
|
|
|
- GDM_SESSION_GET_IFACE (session)->accredit (session, flag);
|
|
+ GDM_SESSION_GET_IFACE (session)->accredit (session, service_name, flag);
|
|
}
|
|
|
|
void
|
|
gdm_session_answer_query (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text)
|
|
{
|
|
g_return_if_fail (GDM_IS_SESSION (session));
|
|
|
|
- GDM_SESSION_GET_IFACE (session)->answer_query (session, text);
|
|
+ GDM_SESSION_GET_IFACE (session)->answer_query (session, service_name, text);
|
|
}
|
|
|
|
void
|
|
@@ -192,11 +197,12 @@ gdm_session_cancel (GdmSession *session)
|
|
}
|
|
|
|
void
|
|
-gdm_session_start_session (GdmSession *session)
|
|
+gdm_session_start_session (GdmSession *session,
|
|
+ const char *service_name)
|
|
{
|
|
g_return_if_fail (GDM_IS_SESSION (session));
|
|
|
|
- GDM_SESSION_GET_IFACE (session)->start_session (session);
|
|
+ GDM_SESSION_GET_IFACE (session)->start_session (session, service_name);
|
|
}
|
|
|
|
static void
|
|
@@ -213,7 +219,7 @@ gdm_session_class_init (gpointer g_iface)
|
|
NULL,
|
|
g_cclosure_marshal_VOID__STRING,
|
|
G_TYPE_NONE,
|
|
- 0);
|
|
+ 1, G_TYPE_STRING);
|
|
signals [SETUP_COMPLETE] =
|
|
g_signal_new ("setup-complete",
|
|
iface_type,
|
|
@@ -221,9 +227,10 @@ gdm_session_class_init (gpointer g_iface)
|
|
G_STRUCT_OFFSET (GdmSessionIface, setup_complete),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__VOID,
|
|
+ g_cclosure_marshal_VOID__STRING,
|
|
G_TYPE_NONE,
|
|
- 0);
|
|
+ 1,
|
|
+ G_TYPE_STRING);
|
|
signals [SETUP_FAILED] =
|
|
g_signal_new ("setup-failed",
|
|
iface_type,
|
|
@@ -231,10 +238,10 @@ gdm_session_class_init (gpointer g_iface)
|
|
G_STRUCT_OFFSET (GdmSessionIface, setup_failed),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__STRING,
|
|
+ gdm_marshal_VOID__STRING_STRING,
|
|
G_TYPE_NONE,
|
|
- 1,
|
|
- G_TYPE_STRING);
|
|
+ 2,
|
|
+ G_TYPE_STRING, G_TYPE_STRING);
|
|
signals [RESET_COMPLETE] =
|
|
g_signal_new ("reset-complete",
|
|
iface_type,
|
|
@@ -263,9 +270,9 @@ gdm_session_class_init (gpointer g_iface)
|
|
G_STRUCT_OFFSET (GdmSessionIface, authenticated),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__VOID,
|
|
+ g_cclosure_marshal_VOID__STRING,
|
|
G_TYPE_NONE,
|
|
- 0);
|
|
+ 1, G_TYPE_STRING);
|
|
signals [AUTHENTICATION_FAILED] =
|
|
g_signal_new ("authentication-failed",
|
|
iface_type,
|
|
@@ -273,10 +280,10 @@ gdm_session_class_init (gpointer g_iface)
|
|
G_STRUCT_OFFSET (GdmSessionIface, authentication_failed),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__STRING,
|
|
+ gdm_marshal_VOID__STRING_STRING,
|
|
G_TYPE_NONE,
|
|
- 1,
|
|
- G_TYPE_STRING);
|
|
+ 2,
|
|
+ G_TYPE_STRING, G_TYPE_STRING);
|
|
signals [AUTHORIZED] =
|
|
g_signal_new ("authorized",
|
|
iface_type,
|
|
@@ -284,9 +291,9 @@ gdm_session_class_init (gpointer g_iface)
|
|
G_STRUCT_OFFSET (GdmSessionIface, authorized),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__VOID,
|
|
+ g_cclosure_marshal_VOID__STRING,
|
|
G_TYPE_NONE,
|
|
- 0);
|
|
+ 1, G_TYPE_STRING);
|
|
signals [AUTHORIZATION_FAILED] =
|
|
g_signal_new ("authorization-failed",
|
|
iface_type,
|
|
@@ -294,10 +301,10 @@ gdm_session_class_init (gpointer g_iface)
|
|
G_STRUCT_OFFSET (GdmSessionIface, authorization_failed),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__STRING,
|
|
+ gdm_marshal_VOID__STRING_STRING,
|
|
G_TYPE_NONE,
|
|
- 1,
|
|
- G_TYPE_STRING);
|
|
+ 2,
|
|
+ G_TYPE_STRING, G_TYPE_STRING);
|
|
signals [ACCREDITED] =
|
|
g_signal_new ("accredited",
|
|
iface_type,
|
|
@@ -305,9 +312,9 @@ gdm_session_class_init (gpointer g_iface)
|
|
G_STRUCT_OFFSET (GdmSessionIface, accredited),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__VOID,
|
|
+ g_cclosure_marshal_VOID__STRING,
|
|
G_TYPE_NONE,
|
|
- 0);
|
|
+ 1, G_TYPE_STRING);
|
|
signals [ACCREDITATION_FAILED] =
|
|
g_signal_new ("accreditation-failed",
|
|
iface_type,
|
|
@@ -315,10 +322,10 @@ gdm_session_class_init (gpointer g_iface)
|
|
G_STRUCT_OFFSET (GdmSessionIface, accreditation_failed),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__STRING,
|
|
+ gdm_marshal_VOID__STRING_STRING,
|
|
G_TYPE_NONE,
|
|
- 1,
|
|
- G_TYPE_STRING);
|
|
+ 2,
|
|
+ G_TYPE_STRING, G_TYPE_STRING);
|
|
|
|
signals [INFO_QUERY] =
|
|
g_signal_new ("info-query",
|
|
@@ -327,10 +334,10 @@ gdm_session_class_init (gpointer g_iface)
|
|
G_STRUCT_OFFSET (GdmSessionIface, info_query),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__STRING,
|
|
+ gdm_marshal_VOID__STRING_STRING,
|
|
G_TYPE_NONE,
|
|
- 1,
|
|
- G_TYPE_STRING);
|
|
+ 2,
|
|
+ G_TYPE_STRING, G_TYPE_STRING);
|
|
signals [SECRET_INFO_QUERY] =
|
|
g_signal_new ("secret-info-query",
|
|
iface_type,
|
|
@@ -338,10 +345,10 @@ gdm_session_class_init (gpointer g_iface)
|
|
G_STRUCT_OFFSET (GdmSessionIface, secret_info_query),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__STRING,
|
|
+ gdm_marshal_VOID__STRING_STRING,
|
|
G_TYPE_NONE,
|
|
- 1,
|
|
- G_TYPE_STRING);
|
|
+ 2,
|
|
+ G_TYPE_STRING, G_TYPE_STRING);
|
|
signals [INFO] =
|
|
g_signal_new ("info",
|
|
iface_type,
|
|
@@ -349,10 +356,10 @@ gdm_session_class_init (gpointer g_iface)
|
|
G_STRUCT_OFFSET (GdmSessionIface, info),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__STRING,
|
|
+ gdm_marshal_VOID__STRING_STRING,
|
|
G_TYPE_NONE,
|
|
- 1,
|
|
- G_TYPE_STRING);
|
|
+ 2,
|
|
+ G_TYPE_STRING, G_TYPE_STRING);
|
|
signals [PROBLEM] =
|
|
g_signal_new ("problem",
|
|
iface_type,
|
|
@@ -360,10 +367,10 @@ gdm_session_class_init (gpointer g_iface)
|
|
G_STRUCT_OFFSET (GdmSessionIface, problem),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__STRING,
|
|
+ gdm_marshal_VOID__STRING_STRING,
|
|
G_TYPE_NONE,
|
|
- 1,
|
|
- G_TYPE_STRING);
|
|
+ 2,
|
|
+ G_TYPE_STRING, G_TYPE_STRING);
|
|
signals [SESSION_STARTED] =
|
|
g_signal_new ("session-started",
|
|
iface_type,
|
|
@@ -371,10 +378,10 @@ gdm_session_class_init (gpointer g_iface)
|
|
G_STRUCT_OFFSET (GdmSessionIface, session_started),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__INT,
|
|
+ gdm_marshal_VOID__STRING_INT,
|
|
G_TYPE_NONE,
|
|
- 1,
|
|
- G_TYPE_INT);
|
|
+ 2,
|
|
+ G_TYPE_STRING, G_TYPE_INT);
|
|
signals [SESSION_START_FAILED] =
|
|
g_signal_new ("session-start-failed",
|
|
iface_type,
|
|
@@ -382,10 +389,10 @@ gdm_session_class_init (gpointer g_iface)
|
|
G_STRUCT_OFFSET (GdmSessionIface, session_start_failed),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__STRING,
|
|
+ gdm_marshal_VOID__STRING_STRING,
|
|
G_TYPE_NONE,
|
|
- 1,
|
|
- G_TYPE_STRING);
|
|
+ 2,
|
|
+ G_TYPE_STRING, G_TYPE_STRING);
|
|
signals [SESSION_EXITED] =
|
|
g_signal_new ("session-exited",
|
|
iface_type,
|
|
@@ -465,19 +472,21 @@ gdm_session_class_init (gpointer g_iface)
|
|
}
|
|
|
|
void
|
|
-_gdm_session_setup_complete (GdmSession *session)
|
|
+_gdm_session_setup_complete (GdmSession *session,
|
|
+ const char *service_name)
|
|
{
|
|
g_return_if_fail (GDM_IS_SESSION (session));
|
|
|
|
- g_signal_emit (session, signals [SETUP_COMPLETE], 0);
|
|
+ g_signal_emit (session, signals [SETUP_COMPLETE], 0, service_name);
|
|
}
|
|
|
|
void
|
|
_gdm_session_setup_failed (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text)
|
|
{
|
|
g_return_if_fail (GDM_IS_SESSION (session));
|
|
- g_signal_emit (session, signals [SETUP_FAILED], 0, text);
|
|
+ g_signal_emit (session, signals [SETUP_FAILED], 0, service_name, text);
|
|
}
|
|
|
|
void
|
|
@@ -497,99 +506,111 @@ _gdm_session_reset_failed (GdmSession *session,
|
|
}
|
|
|
|
void
|
|
-_gdm_session_authenticated (GdmSession *session)
|
|
+_gdm_session_authenticated (GdmSession *session,
|
|
+ const char *service_name)
|
|
{
|
|
g_return_if_fail (GDM_IS_SESSION (session));
|
|
|
|
- g_signal_emit (session, signals [AUTHENTICATED], 0);
|
|
+ g_signal_emit (session, signals [AUTHENTICATED], 0, service_name);
|
|
}
|
|
|
|
void
|
|
_gdm_session_authentication_failed (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text)
|
|
{
|
|
g_return_if_fail (GDM_IS_SESSION (session));
|
|
- g_signal_emit (session, signals [AUTHENTICATION_FAILED], 0, text);
|
|
+ g_signal_emit (session, signals [AUTHENTICATION_FAILED], 0, service_name, text);
|
|
}
|
|
|
|
void
|
|
-_gdm_session_authorized (GdmSession *session)
|
|
+_gdm_session_authorized (GdmSession *session,
|
|
+ const char *service_name)
|
|
{
|
|
g_return_if_fail (GDM_IS_SESSION (session));
|
|
|
|
- g_signal_emit (session, signals [AUTHORIZED], 0);
|
|
+ g_signal_emit (session, signals [AUTHORIZED], 0, service_name);
|
|
}
|
|
|
|
void
|
|
_gdm_session_authorization_failed (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text)
|
|
{
|
|
g_return_if_fail (GDM_IS_SESSION (session));
|
|
- g_signal_emit (session, signals [AUTHORIZATION_FAILED], 0, text);
|
|
+ g_signal_emit (session, signals [AUTHORIZATION_FAILED], 0, service_name, text);
|
|
}
|
|
|
|
void
|
|
-_gdm_session_accredited (GdmSession *session)
|
|
+_gdm_session_accredited (GdmSession *session,
|
|
+ const char *service_name)
|
|
{
|
|
g_return_if_fail (GDM_IS_SESSION (session));
|
|
|
|
- g_signal_emit (session, signals [ACCREDITED], 0);
|
|
+ g_signal_emit (session, signals [ACCREDITED], 0, service_name);
|
|
}
|
|
|
|
void
|
|
_gdm_session_accreditation_failed (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text)
|
|
{
|
|
g_return_if_fail (GDM_IS_SESSION (session));
|
|
- g_signal_emit (session, signals [ACCREDITATION_FAILED], 0, text);
|
|
+ g_signal_emit (session, signals [ACCREDITATION_FAILED], 0, service_name, text);
|
|
}
|
|
|
|
void
|
|
_gdm_session_info_query (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text)
|
|
{
|
|
g_return_if_fail (GDM_IS_SESSION (session));
|
|
- g_signal_emit (session, signals [INFO_QUERY], 0, text);
|
|
+ g_signal_emit (session, signals [INFO_QUERY], 0, service_name, text);
|
|
}
|
|
|
|
void
|
|
_gdm_session_secret_info_query (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text)
|
|
{
|
|
g_return_if_fail (GDM_IS_SESSION (session));
|
|
- g_signal_emit (session, signals [SECRET_INFO_QUERY], 0, text);
|
|
+ g_signal_emit (session, signals [SECRET_INFO_QUERY], 0, service_name, text);
|
|
}
|
|
|
|
void
|
|
_gdm_session_info (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text)
|
|
{
|
|
g_return_if_fail (GDM_IS_SESSION (session));
|
|
- g_signal_emit (session, signals [INFO], 0, text);
|
|
+ g_signal_emit (session, signals [INFO], 0, service_name, text);
|
|
}
|
|
|
|
void
|
|
_gdm_session_problem (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text)
|
|
{
|
|
g_return_if_fail (GDM_IS_SESSION (session));
|
|
- g_signal_emit (session, signals [PROBLEM], 0, text);
|
|
+ g_signal_emit (session, signals [PROBLEM], 0, service_name, text);
|
|
}
|
|
|
|
void
|
|
_gdm_session_session_started (GdmSession *session,
|
|
+ const char *service_name,
|
|
int pid)
|
|
{
|
|
g_return_if_fail (GDM_IS_SESSION (session));
|
|
- g_signal_emit (session, signals [SESSION_STARTED], 0, pid);
|
|
+ g_signal_emit (session, signals [SESSION_STARTED], 0, service_name, pid);
|
|
}
|
|
|
|
void
|
|
_gdm_session_session_start_failed (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text)
|
|
{
|
|
g_return_if_fail (GDM_IS_SESSION (session));
|
|
- g_signal_emit (session, signals [SESSION_START_FAILED], 0, text);
|
|
+ g_signal_emit (session, signals [SESSION_START_FAILED], 0, service_name, text);
|
|
}
|
|
|
|
void
|
|
diff --git a/daemon/gdm-session.h b/daemon/gdm-session.h
|
|
index 77e0cf6..db5fc4a 100644
|
|
--- a/daemon/gdm-session.h
|
|
+++ b/daemon/gdm-session.h
|
|
@@ -53,11 +53,15 @@ struct _GdmSessionIface
|
|
const char *service_name,
|
|
const char *username);
|
|
void (* reset) (GdmSession *session);
|
|
- void (* authenticate) (GdmSession *session);
|
|
- void (* authorize) (GdmSession *session);
|
|
+ void (* authenticate) (GdmSession *session,
|
|
+ const char *service_name);
|
|
+ void (* authorize) (GdmSession *session,
|
|
+ const char *service_name);
|
|
void (* accredit) (GdmSession *session,
|
|
+ const char *service_name,
|
|
int cred_flag);
|
|
void (* answer_query) (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text);
|
|
void (* select_language) (GdmSession *session,
|
|
const char *text);
|
|
@@ -67,38 +71,53 @@ struct _GdmSessionIface
|
|
const char *text);
|
|
void (* select_user) (GdmSession *session,
|
|
const char *text);
|
|
- void (* start_session) (GdmSession *session);
|
|
+ void (* start_session) (GdmSession *session,
|
|
+ const char *service_name);
|
|
void (* close) (GdmSession *session);
|
|
void (* cancel) (GdmSession *session);
|
|
|
|
/* Signals */
|
|
- void (* setup_complete) (GdmSession *session);
|
|
+ void (* setup_complete) (GdmSession *session,
|
|
+ const char *service_name);
|
|
void (* setup_failed) (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *message);
|
|
void (* reset_complete) (GdmSession *session);
|
|
void (* reset_failed) (GdmSession *session,
|
|
const char *message);
|
|
- void (* authenticated) (GdmSession *session);
|
|
+ void (* authenticated) (GdmSession *session,
|
|
+ const char *service_name);
|
|
void (* authentication_failed) (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *message);
|
|
- void (* authorized) (GdmSession *session);
|
|
+ void (* authorized) (GdmSession *session,
|
|
+ const char *service_name);
|
|
void (* authorization_failed) (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *message);
|
|
- void (* accredited) (GdmSession *session);
|
|
+ void (* accredited) (GdmSession *session,
|
|
+ const char *service_name);
|
|
void (* accreditation_failed) (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *message);
|
|
|
|
void (* info_query) (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *query_text);
|
|
void (* secret_info_query) (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *query_text);
|
|
void (* info) (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *info);
|
|
void (* problem) (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *problem);
|
|
void (* session_started) (GdmSession *session,
|
|
+ const char *service_name,
|
|
int pid);
|
|
void (* session_start_failed) (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *message);
|
|
void (* session_exited) (GdmSession *session,
|
|
int exit_code);
|
|
@@ -128,14 +147,19 @@ void gdm_session_setup_for_user (GdmSession *session,
|
|
const char *service_name,
|
|
const char *username);
|
|
void gdm_session_reset (GdmSession *session);
|
|
-void gdm_session_authenticate (GdmSession *session);
|
|
-void gdm_session_authorize (GdmSession *session);
|
|
+void gdm_session_authenticate (GdmSession *session,
|
|
+ const char *service_name);
|
|
+void gdm_session_authorize (GdmSession *session,
|
|
+ const char *service_name);
|
|
void gdm_session_accredit (GdmSession *session,
|
|
+ const char *service_name,
|
|
int cred_flag);
|
|
-void gdm_session_start_session (GdmSession *session);
|
|
+void gdm_session_start_session (GdmSession *session,
|
|
+ const char *service_name);
|
|
void gdm_session_close (GdmSession *session);
|
|
|
|
void gdm_session_answer_query (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text);
|
|
void gdm_session_select_session (GdmSession *session,
|
|
const char *session_name);
|
|
diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c
|
|
index eab5c8d..3a24d8d 100644
|
|
--- a/daemon/gdm-simple-slave.c
|
|
+++ b/daemon/gdm-simple-slave.c
|
|
@@ -68,6 +68,8 @@ struct GdmSimpleSlavePrivate
|
|
guint greeter_reset_id;
|
|
guint start_session_id;
|
|
|
|
+ char *start_session_service_name;
|
|
+
|
|
int ping_interval;
|
|
|
|
GPid server_pid;
|
|
@@ -98,6 +100,7 @@ static void start_greeter (GdmSimpleSlave *slave);
|
|
|
|
static void
|
|
on_session_started (GdmSession *session,
|
|
+ const char *service_name,
|
|
int pid,
|
|
GdmSimpleSlave *slave)
|
|
{
|
|
@@ -201,18 +204,21 @@ queue_greeter_reset (GdmSimpleSlave *slave)
|
|
|
|
static void
|
|
on_session_setup_complete (GdmSession *session,
|
|
+ const char *service_name,
|
|
GdmSimpleSlave *slave)
|
|
{
|
|
- gdm_session_authenticate (session);
|
|
+ gdm_session_authenticate (session, service_name);
|
|
}
|
|
|
|
static void
|
|
on_session_setup_failed (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *message,
|
|
GdmSimpleSlave *slave)
|
|
{
|
|
if (slave->priv->greeter_server != NULL) {
|
|
gdm_greeter_server_problem (slave->priv->greeter_server,
|
|
+ service_name,
|
|
_("Unable to initialize login system"));
|
|
}
|
|
|
|
@@ -237,18 +243,21 @@ on_session_reset_failed (GdmSession *session,
|
|
|
|
static void
|
|
on_session_authenticated (GdmSession *session,
|
|
+ const char *service_name,
|
|
GdmSimpleSlave *slave)
|
|
{
|
|
- gdm_session_authorize (session);
|
|
+ gdm_session_authorize (session, service_name);
|
|
}
|
|
|
|
static void
|
|
on_session_authentication_failed (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *message,
|
|
GdmSimpleSlave *slave)
|
|
{
|
|
if (slave->priv->greeter_server != NULL) {
|
|
gdm_greeter_server_problem (slave->priv->greeter_server,
|
|
+ service_name,
|
|
_("Unable to authenticate user"));
|
|
}
|
|
destroy_session (slave);
|
|
@@ -256,7 +265,8 @@ on_session_authentication_failed (GdmSession *session,
|
|
}
|
|
|
|
static void
|
|
-gdm_simple_slave_accredit_when_ready (GdmSimpleSlave *slave)
|
|
+gdm_simple_slave_accredit_when_ready (GdmSimpleSlave *slave,
|
|
+ const char *service_name)
|
|
{
|
|
if (slave->priv->start_session_when_ready) {
|
|
char *ssid;
|
|
@@ -277,7 +287,7 @@ gdm_simple_slave_accredit_when_ready (GdmSimpleSlave *slave)
|
|
g_free (ssid);
|
|
g_free (username);
|
|
|
|
- gdm_session_accredit (GDM_SESSION (slave->priv->session), cred_flag);
|
|
+ gdm_session_accredit (GDM_SESSION (slave->priv->session), service_name, cred_flag);
|
|
} else {
|
|
slave->priv->waiting_to_start_session = TRUE;
|
|
}
|
|
@@ -285,24 +295,27 @@ gdm_simple_slave_accredit_when_ready (GdmSimpleSlave *slave)
|
|
|
|
static void
|
|
on_session_authorized (GdmSession *session,
|
|
+ const char *service_name,
|
|
GdmSimpleSlave *slave)
|
|
{
|
|
if (slave->priv->greeter_server != NULL) {
|
|
- gdm_greeter_server_user_authorized (slave->priv->greeter_server);
|
|
- gdm_simple_slave_accredit_when_ready (slave);
|
|
+ gdm_greeter_server_user_authorized (slave->priv->greeter_server, service_name);
|
|
+ gdm_simple_slave_accredit_when_ready (slave, service_name);
|
|
} else {
|
|
slave->priv->start_session_when_ready = TRUE;
|
|
- gdm_simple_slave_accredit_when_ready (slave);
|
|
+ gdm_simple_slave_accredit_when_ready (slave, service_name);
|
|
}
|
|
}
|
|
|
|
static void
|
|
on_session_authorization_failed (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *message,
|
|
GdmSimpleSlave *slave)
|
|
{
|
|
if (slave->priv->greeter_server != NULL) {
|
|
gdm_greeter_server_problem (slave->priv->greeter_server,
|
|
+ service_name,
|
|
_("Unable to authorize user"));
|
|
}
|
|
|
|
@@ -383,31 +396,38 @@ start_session_timeout (GdmSimpleSlave *slave)
|
|
|
|
g_free (auth_file);
|
|
|
|
- gdm_session_start_session (GDM_SESSION (slave->priv->session));
|
|
+ gdm_session_start_session (GDM_SESSION (slave->priv->session),
|
|
+ slave->priv->start_session_service_name);
|
|
out:
|
|
slave->priv->start_session_id = 0;
|
|
+ g_free (slave->priv->start_session_service_name);
|
|
+ slave->priv->start_session_service_name = NULL;
|
|
return FALSE;
|
|
}
|
|
|
|
static void
|
|
-queue_start_session (GdmSimpleSlave *slave)
|
|
+queue_start_session (GdmSimpleSlave *slave,
|
|
+ const char *service_name)
|
|
{
|
|
if (slave->priv->start_session_id > 0) {
|
|
return;
|
|
}
|
|
|
|
slave->priv->start_session_id = g_idle_add ((GSourceFunc)start_session_timeout, slave);
|
|
+ slave->priv->start_session_service_name = g_strdup (service_name);
|
|
}
|
|
|
|
static void
|
|
on_session_accredited (GdmSession *session,
|
|
+ const char *service_name,
|
|
GdmSimpleSlave *slave)
|
|
{
|
|
- queue_start_session (slave);
|
|
+ queue_start_session (slave, service_name);
|
|
}
|
|
|
|
static void
|
|
on_session_accreditation_failed (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *message,
|
|
GdmSimpleSlave *slave)
|
|
{
|
|
@@ -422,6 +442,7 @@ on_session_accreditation_failed (GdmSession *session,
|
|
if (! migrated) {
|
|
if (slave->priv->greeter_server != NULL) {
|
|
gdm_greeter_server_problem (slave->priv->greeter_server,
|
|
+ service_name,
|
|
_("Unable establish credentials"));
|
|
}
|
|
}
|
|
@@ -437,41 +458,45 @@ on_session_accreditation_failed (GdmSession *session,
|
|
|
|
static void
|
|
on_session_info (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text,
|
|
GdmSimpleSlave *slave)
|
|
{
|
|
g_debug ("GdmSimpleSlave: Info: %s", text);
|
|
if (slave->priv->greeter_server != NULL) {
|
|
- gdm_greeter_server_info (slave->priv->greeter_server, text);
|
|
+ gdm_greeter_server_info (slave->priv->greeter_server, service_name, text);
|
|
}
|
|
}
|
|
|
|
static void
|
|
on_session_problem (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text,
|
|
GdmSimpleSlave *slave)
|
|
{
|
|
g_debug ("GdmSimpleSlave: Problem: %s", text);
|
|
- gdm_greeter_server_problem (slave->priv->greeter_server, text);
|
|
+ gdm_greeter_server_problem (slave->priv->greeter_server, service_name, text);
|
|
}
|
|
|
|
static void
|
|
on_session_info_query (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text,
|
|
GdmSimpleSlave *slave)
|
|
{
|
|
|
|
g_debug ("GdmSimpleSlave: Info query: %s", text);
|
|
- gdm_greeter_server_info_query (slave->priv->greeter_server, text);
|
|
+ gdm_greeter_server_info_query (slave->priv->greeter_server, service_name, text);
|
|
}
|
|
|
|
static void
|
|
on_session_secret_info_query (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *text,
|
|
GdmSimpleSlave *slave)
|
|
{
|
|
g_debug ("GdmSimpleSlave: Secret info query: %s", text);
|
|
- gdm_greeter_server_secret_info_query (slave->priv->greeter_server, text);
|
|
+ gdm_greeter_server_secret_info_query (slave->priv->greeter_server, service_name, text);
|
|
}
|
|
|
|
static void
|
|
@@ -741,11 +766,12 @@ on_greeter_start_conversation (GdmGreeterServer *greeter_server,
|
|
|
|
static void
|
|
on_greeter_begin_verification (GdmGreeterServer *greeter_server,
|
|
+ const char *service_name,
|
|
GdmSimpleSlave *slave)
|
|
{
|
|
g_debug ("GdmSimpleSlave: begin verification");
|
|
gdm_session_setup (GDM_SESSION (slave->priv->session),
|
|
- "gdm");
|
|
+ service_name);
|
|
}
|
|
|
|
static void
|
|
@@ -761,21 +787,23 @@ on_greeter_begin_auto_login (GdmGreeterServer *greeter_server,
|
|
|
|
static void
|
|
on_greeter_begin_verification_for_user (GdmGreeterServer *greeter_server,
|
|
+ const char *service_name,
|
|
const char *username,
|
|
GdmSimpleSlave *slave)
|
|
{
|
|
g_debug ("GdmSimpleSlave: begin verification");
|
|
gdm_session_setup_for_user (GDM_SESSION (slave->priv->session),
|
|
- "gdm",
|
|
+ service_name,
|
|
username);
|
|
}
|
|
|
|
static void
|
|
on_greeter_answer (GdmGreeterServer *greeter_server,
|
|
+ const char *service_name,
|
|
const char *text,
|
|
GdmSimpleSlave *slave)
|
|
{
|
|
- gdm_session_answer_query (GDM_SESSION (slave->priv->session), text);
|
|
+ gdm_session_answer_query (GDM_SESSION (slave->priv->session), service_name, text);
|
|
}
|
|
|
|
static void
|
|
@@ -838,18 +866,20 @@ on_greeter_connected (GdmGreeterServer *greeter_server,
|
|
|
|
static void
|
|
on_start_session_when_ready (GdmGreeterServer *session,
|
|
+ const char *service_name,
|
|
GdmSimpleSlave *slave)
|
|
{
|
|
g_debug ("GdmSimpleSlave: Will start session when ready");
|
|
slave->priv->start_session_when_ready = TRUE;
|
|
|
|
if (slave->priv->waiting_to_start_session) {
|
|
- gdm_simple_slave_accredit_when_ready (slave);
|
|
+ gdm_simple_slave_accredit_when_ready (slave, service_name);
|
|
}
|
|
}
|
|
|
|
static void
|
|
on_start_session_later (GdmGreeterServer *session,
|
|
+ const char *service_name,
|
|
GdmSimpleSlave *slave)
|
|
{
|
|
g_debug ("GdmSimpleSlave: Will start session when ready and told");
|
|
@@ -861,6 +891,15 @@ setup_server (GdmSimpleSlave *slave)
|
|
{
|
|
/* Set the busy cursor */
|
|
gdm_slave_set_busy_cursor (GDM_SLAVE (slave));
|
|
+
|
|
+ /* The root window has a background that may be useful
|
|
+ * to cross fade or transition from when setting the
|
|
+ * login screen background. We read it here, and stuff
|
|
+ * it into the standard _XROOTPMAP_ID root window property,
|
|
+ * so gnome-settings-daemon can get at it.
|
|
+ */
|
|
+ gdm_slave_save_root_windows (GDM_SLAVE (slave));
|
|
+
|
|
}
|
|
|
|
static void
|
|
diff --git a/daemon/test-session.c b/daemon/test-session.c
|
|
index d9fa26e..3cf8483 100644
|
|
--- a/daemon/test-session.c
|
|
+++ b/daemon/test-session.c
|
|
@@ -44,10 +44,11 @@ on_conversation_started (GdmSession *session,
|
|
|
|
static void
|
|
on_session_setup_complete (GdmSession *session,
|
|
+ const char *service_name,
|
|
gpointer data)
|
|
{
|
|
g_debug ("Session setup complete");
|
|
- gdm_session_authenticate (session);
|
|
+ gdm_session_authenticate (session, service_name);
|
|
}
|
|
|
|
static void
|
|
@@ -79,10 +80,11 @@ on_session_reset_failed (GdmSession *session,
|
|
|
|
static void
|
|
on_session_authenticated (GdmSession *session,
|
|
+ const char *service_name,
|
|
gpointer data)
|
|
{
|
|
g_debug ("Session authenticated");
|
|
- gdm_session_authorize (session);
|
|
+ gdm_session_authorize (session, service_name);
|
|
}
|
|
|
|
static void
|
|
@@ -97,14 +99,16 @@ on_session_authentication_failed (GdmSession *session,
|
|
|
|
static void
|
|
on_session_authorized (GdmSession *session,
|
|
+ const char *service_name,
|
|
gpointer data)
|
|
{
|
|
g_debug ("Session authorized");
|
|
- gdm_session_accredit (session, GDM_SESSION_CRED_ESTABLISH);
|
|
+ gdm_session_accredit (session, service_name, GDM_SESSION_CRED_ESTABLISH);
|
|
}
|
|
|
|
static void
|
|
on_session_authorization_failed (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *message,
|
|
gpointer data)
|
|
{
|
|
@@ -115,6 +119,7 @@ on_session_authorization_failed (GdmSession *session,
|
|
|
|
static void
|
|
on_session_accredited (GdmSession *session,
|
|
+ const char *service_name,
|
|
gpointer data)
|
|
{
|
|
char *username;
|
|
@@ -125,12 +130,13 @@ on_session_accredited (GdmSession *session,
|
|
username ? username : "", username ? " " : "");
|
|
g_free (username);
|
|
|
|
- gdm_session_start_session (session);
|
|
+ gdm_session_start_session (session, service_name);
|
|
|
|
}
|
|
|
|
static void
|
|
on_session_accreditation_failed (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *message,
|
|
gpointer data)
|
|
{
|
|
@@ -165,6 +171,7 @@ on_session_died (GdmSession *session,
|
|
|
|
static void
|
|
on_info_query (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *query_text)
|
|
{
|
|
char answer[1024];
|
|
@@ -178,12 +185,13 @@ on_info_query (GdmSession *session,
|
|
gdm_session_close (session);
|
|
g_main_loop_quit (loop);
|
|
} else {
|
|
- gdm_session_answer_query (session, answer);
|
|
+ gdm_session_answer_query (session, service_name, answer);
|
|
}
|
|
}
|
|
|
|
static void
|
|
on_info (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *info)
|
|
{
|
|
g_print ("\n** NOTE: %s\n", info);
|
|
@@ -191,6 +199,7 @@ on_info (GdmSession *session,
|
|
|
|
static void
|
|
on_problem (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *problem)
|
|
{
|
|
g_print ("\n** WARNING: %s\n", problem);
|
|
@@ -198,6 +207,7 @@ on_problem (GdmSession *session,
|
|
|
|
static void
|
|
on_secret_info_query (GdmSession *session,
|
|
+ const char *service_name,
|
|
const char *query_text)
|
|
{
|
|
char answer[1024];
|
|
@@ -222,7 +232,7 @@ on_secret_info_query (GdmSession *session,
|
|
|
|
g_print ("\n");
|
|
|
|
- gdm_session_answer_query (session, answer);
|
|
+ gdm_session_answer_query (session, service_name, answer);
|
|
}
|
|
|
|
static void
|
|
diff --git a/gui/simple-greeter/gdm-greeter-client.c b/gui/simple-greeter/gdm-greeter-client.c
|
|
index 1e2c55d..ee7019d 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-client.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-client.c
|
|
@@ -134,6 +134,37 @@ emit_string_and_int_signal_for_message (GdmGreeterClient *client,
|
|
}
|
|
|
|
static void
|
|
+emit_string_and_string_signal_for_message (GdmGreeterClient *client,
|
|
+ const char *name,
|
|
+ DBusMessage *message,
|
|
+ int signal)
|
|
+{
|
|
+ DBusError error;
|
|
+ char *text1;
|
|
+ char *text2;
|
|
+ dbus_bool_t res;
|
|
+
|
|
+ dbus_error_init (&error);
|
|
+ res = dbus_message_get_args (message,
|
|
+ &error,
|
|
+ DBUS_TYPE_STRING, &text1,
|
|
+ DBUS_TYPE_STRING, &text2,
|
|
+ DBUS_TYPE_INVALID);
|
|
+ if (res) {
|
|
+
|
|
+ g_debug ("GdmGreeterClient: Received %s (%s, %s)", name, text1, text2);
|
|
+
|
|
+ g_signal_emit (client,
|
|
+ gdm_greeter_client_signals[signal],
|
|
+ 0, text1, text2);
|
|
+ } else {
|
|
+ g_warning ("Unable to get arguments: %s", error.message);
|
|
+ dbus_error_free (&error);
|
|
+ }
|
|
+ dbus_error_free (&error);
|
|
+}
|
|
+
|
|
+static void
|
|
emit_string_signal_for_message (GdmGreeterClient *client,
|
|
const char *name,
|
|
DBusMessage *message,
|
|
@@ -200,37 +231,35 @@ static void
|
|
on_user_authorized (GdmGreeterClient *client,
|
|
DBusMessage *message)
|
|
{
|
|
- g_signal_emit (client,
|
|
- gdm_greeter_client_signals[USER_AUTHORIZED],
|
|
- 0);
|
|
+ emit_string_signal_for_message (client, "UserAuthorized", message, USER_AUTHORIZED);
|
|
}
|
|
|
|
static void
|
|
on_info_query (GdmGreeterClient *client,
|
|
DBusMessage *message)
|
|
{
|
|
- emit_string_signal_for_message (client, "InfoQuery", message, INFO_QUERY);
|
|
+ emit_string_and_string_signal_for_message (client, "InfoQuery", message, INFO_QUERY);
|
|
}
|
|
|
|
static void
|
|
on_secret_info_query (GdmGreeterClient *client,
|
|
DBusMessage *message)
|
|
{
|
|
- emit_string_signal_for_message (client, "SecretInfoQuery", message, SECRET_INFO_QUERY);
|
|
+ emit_string_and_string_signal_for_message (client, "SecretInfoQuery", message, SECRET_INFO_QUERY);
|
|
}
|
|
|
|
static void
|
|
on_info (GdmGreeterClient *client,
|
|
DBusMessage *message)
|
|
{
|
|
- emit_string_signal_for_message (client, "Info", message, INFO);
|
|
+ emit_string_and_string_signal_for_message (client, "Info", message, INFO);
|
|
}
|
|
|
|
static void
|
|
on_problem (GdmGreeterClient *client,
|
|
DBusMessage *message)
|
|
{
|
|
- emit_string_signal_for_message (client, "Problem", message, PROBLEM);
|
|
+ emit_string_and_string_signal_for_message (client, "Problem", message, PROBLEM);
|
|
}
|
|
|
|
static void
|
|
@@ -307,14 +336,22 @@ send_dbus_string_method (DBusConnection *connection,
|
|
}
|
|
|
|
static gboolean
|
|
-send_dbus_bool_method (DBusConnection *connection,
|
|
- const char *method,
|
|
- gboolean payload)
|
|
+send_dbus_string_and_bool_method (DBusConnection *connection,
|
|
+ const char *method,
|
|
+ const char *string_payload,
|
|
+ gboolean bool_payload)
|
|
{
|
|
DBusError error;
|
|
DBusMessage *message;
|
|
DBusMessage *reply;
|
|
DBusMessageIter iter;
|
|
+ const char *str;
|
|
+
|
|
+ if (string_payload != NULL) {
|
|
+ str = string_payload;
|
|
+ } else {
|
|
+ str = "";
|
|
+ }
|
|
|
|
g_debug ("GdmGreeterClient: Calling %s", method);
|
|
message = dbus_message_new_method_call (NULL,
|
|
@@ -328,8 +365,77 @@ send_dbus_bool_method (DBusConnection *connection,
|
|
|
|
dbus_message_iter_init_append (message, &iter);
|
|
dbus_message_iter_append_basic (&iter,
|
|
+ DBUS_TYPE_STRING,
|
|
+ &str);
|
|
+
|
|
+ dbus_message_iter_append_basic (&iter,
|
|
DBUS_TYPE_BOOLEAN,
|
|
- &payload);
|
|
+ &bool_payload);
|
|
+
|
|
+ dbus_error_init (&error);
|
|
+ reply = dbus_connection_send_with_reply_and_block (connection,
|
|
+ message,
|
|
+ -1,
|
|
+ &error);
|
|
+
|
|
+ dbus_message_unref (message);
|
|
+
|
|
+ if (dbus_error_is_set (&error)) {
|
|
+ g_warning ("%s %s raised: %s\n",
|
|
+ method,
|
|
+ error.name,
|
|
+ error.message);
|
|
+ return FALSE;
|
|
+ }
|
|
+ if (reply != NULL) {
|
|
+ dbus_message_unref (reply);
|
|
+ }
|
|
+ dbus_connection_flush (connection);
|
|
+
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+send_dbus_string_and_string_method (DBusConnection *connection,
|
|
+ const char *method,
|
|
+ const char *payload1,
|
|
+ const char *payload2)
|
|
+{
|
|
+ DBusError error;
|
|
+ DBusMessage *message;
|
|
+ DBusMessage *reply;
|
|
+ DBusMessageIter iter;
|
|
+ const char *str;
|
|
+
|
|
+ g_debug ("GdmGreeterClient: Calling %s", method);
|
|
+ message = dbus_message_new_method_call (NULL,
|
|
+ GREETER_SERVER_DBUS_PATH,
|
|
+ GREETER_SERVER_DBUS_INTERFACE,
|
|
+ method);
|
|
+ if (message == NULL) {
|
|
+ g_warning ("Couldn't allocate the D-Bus message");
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ dbus_message_iter_init_append (message, &iter);
|
|
+
|
|
+ if (payload1 != NULL) {
|
|
+ str = payload1;
|
|
+ } else {
|
|
+ str = "";
|
|
+ }
|
|
+ dbus_message_iter_append_basic (&iter,
|
|
+ DBUS_TYPE_STRING,
|
|
+ &str);
|
|
+
|
|
+ if (payload2 != NULL) {
|
|
+ str = payload2;
|
|
+ } else {
|
|
+ str = "";
|
|
+ }
|
|
+ dbus_message_iter_append_basic (&iter,
|
|
+ DBUS_TYPE_STRING,
|
|
+ &str);
|
|
|
|
dbus_error_init (&error);
|
|
reply = dbus_connection_send_with_reply_and_block (connection,
|
|
@@ -412,37 +518,44 @@ gdm_greeter_client_call_begin_auto_login (GdmGreeterClient *client,
|
|
}
|
|
|
|
void
|
|
-gdm_greeter_client_call_begin_verification (GdmGreeterClient *client)
|
|
+gdm_greeter_client_call_begin_verification (GdmGreeterClient *client,
|
|
+ const char *service_name)
|
|
{
|
|
- send_dbus_void_method (client->priv->connection,
|
|
- "BeginVerification");
|
|
+ send_dbus_string_method (client->priv->connection,
|
|
+ "BeginVerification", service_name);
|
|
}
|
|
|
|
void
|
|
gdm_greeter_client_call_begin_verification_for_user (GdmGreeterClient *client,
|
|
+ const char *service_name,
|
|
const char *username)
|
|
{
|
|
- send_dbus_string_method (client->priv->connection,
|
|
- "BeginVerificationForUser",
|
|
- username);
|
|
+ send_dbus_string_and_string_method (client->priv->connection,
|
|
+ "BeginVerificationForUser",
|
|
+ service_name,
|
|
+ username);
|
|
}
|
|
|
|
void
|
|
gdm_greeter_client_call_answer_query (GdmGreeterClient *client,
|
|
+ const char *service_name,
|
|
const char *text)
|
|
{
|
|
- send_dbus_string_method (client->priv->connection,
|
|
- "AnswerQuery",
|
|
- text);
|
|
+ send_dbus_string_and_string_method (client->priv->connection,
|
|
+ "AnswerQuery",
|
|
+ service_name,
|
|
+ text);
|
|
}
|
|
|
|
void
|
|
gdm_greeter_client_call_start_session_when_ready (GdmGreeterClient *client,
|
|
+ const char *service_name,
|
|
gboolean should_start_session)
|
|
{
|
|
- send_dbus_bool_method (client->priv->connection,
|
|
- "StartSessionWhenReady",
|
|
- should_start_session);
|
|
+ send_dbus_string_and_bool_method (client->priv->connection,
|
|
+ "StartSessionWhenReady",
|
|
+ service_name,
|
|
+ should_start_session);
|
|
}
|
|
|
|
void
|
|
@@ -835,10 +948,10 @@ gdm_greeter_client_class_init (GdmGreeterClientClass *klass)
|
|
G_STRUCT_OFFSET (GdmGreeterClientClass, info_query),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__STRING,
|
|
+ gdm_marshal_VOID__STRING_STRING,
|
|
G_TYPE_NONE,
|
|
- 1,
|
|
- G_TYPE_STRING);
|
|
+ 2,
|
|
+ G_TYPE_STRING, G_TYPE_STRING);
|
|
|
|
gdm_greeter_client_signals[SECRET_INFO_QUERY] =
|
|
g_signal_new ("secret-info-query",
|
|
@@ -847,10 +960,10 @@ gdm_greeter_client_class_init (GdmGreeterClientClass *klass)
|
|
G_STRUCT_OFFSET (GdmGreeterClientClass, secret_info_query),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__STRING,
|
|
+ gdm_marshal_VOID__STRING_STRING,
|
|
G_TYPE_NONE,
|
|
- 1,
|
|
- G_TYPE_STRING);
|
|
+ 2,
|
|
+ G_TYPE_STRING, G_TYPE_STRING);
|
|
|
|
gdm_greeter_client_signals[INFO] =
|
|
g_signal_new ("info",
|
|
@@ -859,10 +972,10 @@ gdm_greeter_client_class_init (GdmGreeterClientClass *klass)
|
|
G_STRUCT_OFFSET (GdmGreeterClientClass, info),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__STRING,
|
|
+ gdm_marshal_VOID__STRING_STRING,
|
|
G_TYPE_NONE,
|
|
- 1,
|
|
- G_TYPE_STRING);
|
|
+ 2,
|
|
+ G_TYPE_STRING, G_TYPE_STRING);
|
|
|
|
gdm_greeter_client_signals[PROBLEM] =
|
|
g_signal_new ("problem",
|
|
@@ -871,10 +984,10 @@ gdm_greeter_client_class_init (GdmGreeterClientClass *klass)
|
|
G_STRUCT_OFFSET (GdmGreeterClientClass, problem),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__STRING,
|
|
+ gdm_marshal_VOID__STRING_STRING,
|
|
G_TYPE_NONE,
|
|
- 1,
|
|
- G_TYPE_STRING);
|
|
+ 2,
|
|
+ G_TYPE_STRING, G_TYPE_STRING);
|
|
|
|
gdm_greeter_client_signals[READY] =
|
|
g_signal_new ("ready",
|
|
diff --git a/gui/simple-greeter/gdm-greeter-client.h b/gui/simple-greeter/gdm-greeter-client.h
|
|
index 88b0281..2f857dc 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-client.h
|
|
+++ b/gui/simple-greeter/gdm-greeter-client.h
|
|
@@ -45,17 +45,22 @@ typedef struct
|
|
GObjectClass parent_class;
|
|
|
|
void (* info_query) (GdmGreeterClient *client,
|
|
+ const char *service_name,
|
|
const char *query_text);
|
|
|
|
void (* secret_info_query) (GdmGreeterClient *client,
|
|
+ const char *service_name,
|
|
const char *query_text);
|
|
|
|
void (* info) (GdmGreeterClient *client,
|
|
+ const char *service_name,
|
|
const char *info);
|
|
|
|
void (* problem) (GdmGreeterClient *client,
|
|
+ const char *service_name,
|
|
const char *problem);
|
|
- void (* ready) (GdmGreeterClient *client);
|
|
+ void (* ready) (GdmGreeterClient *client,
|
|
+ const char *service_name);
|
|
void (* reset) (GdmGreeterClient *client);
|
|
void (* selected_user_changed) (GdmGreeterClient *client,
|
|
const char *username);
|
|
@@ -69,7 +74,8 @@ typedef struct
|
|
void (* timed_login_requested) (GdmGreeterClient *client,
|
|
const char *username,
|
|
int delay);
|
|
- void (* user_authorized) (GdmGreeterClient *client);
|
|
+ void (* user_authorized) (GdmGreeterClient *client,
|
|
+ const char *service_name);
|
|
} GdmGreeterClientClass;
|
|
|
|
#define GDM_GREETER_CLIENT_ERROR (gdm_greeter_client_error_quark ())
|
|
@@ -95,8 +101,10 @@ void gdm_greeter_client_call_start_conversation (GdmGreeter
|
|
const char *service_name);
|
|
void gdm_greeter_client_call_begin_auto_login (GdmGreeterClient *client,
|
|
const char *username);
|
|
-void gdm_greeter_client_call_begin_verification (GdmGreeterClient *client);
|
|
+void gdm_greeter_client_call_begin_verification (GdmGreeterClient *client,
|
|
+ const char *service_name);
|
|
void gdm_greeter_client_call_begin_verification_for_user (GdmGreeterClient *client,
|
|
+ const char *service_name,
|
|
const char *username);
|
|
void gdm_greeter_client_call_cancel (GdmGreeterClient *client);
|
|
void gdm_greeter_client_call_disconnect (GdmGreeterClient *client);
|
|
@@ -111,9 +119,11 @@ void gdm_greeter_client_call_select_layout (GdmGreeter
|
|
void gdm_greeter_client_call_select_session (GdmGreeterClient *client,
|
|
const char *text);
|
|
void gdm_greeter_client_call_answer_query (GdmGreeterClient *client,
|
|
+ const char *service_name,
|
|
const char *text);
|
|
|
|
void gdm_greeter_client_call_start_session_when_ready (GdmGreeterClient *client,
|
|
+ const char *service_name,
|
|
gboolean should_start_session);
|
|
|
|
|
|
diff --git a/gui/simple-greeter/gdm-greeter-session.c b/gui/simple-greeter/gdm-greeter-session.c
|
|
index 8681828..e625c24 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-session.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-session.c
|
|
@@ -64,6 +64,7 @@ static gpointer session_object = NULL;
|
|
|
|
static void
|
|
on_info (GdmGreeterClient *client,
|
|
+ const char *service_name,
|
|
const char *text,
|
|
GdmGreeterSession *session)
|
|
{
|
|
@@ -74,6 +75,7 @@ on_info (GdmGreeterClient *client,
|
|
|
|
static void
|
|
on_problem (GdmGreeterClient *client,
|
|
+ const char *service_name,
|
|
const char *text,
|
|
GdmGreeterSession *session)
|
|
{
|
|
@@ -160,6 +162,7 @@ on_user_authorized (GdmGreeterClient *client,
|
|
|
|
static void
|
|
on_info_query (GdmGreeterClient *client,
|
|
+ const char *service_name,
|
|
const char *text,
|
|
GdmGreeterSession *session)
|
|
{
|
|
@@ -170,6 +173,7 @@ on_info_query (GdmGreeterClient *client,
|
|
|
|
static void
|
|
on_secret_info_query (GdmGreeterClient *client,
|
|
+ const char *service_name,
|
|
const char *text,
|
|
GdmGreeterSession *session)
|
|
{
|
|
@@ -191,7 +195,8 @@ static void
|
|
on_begin_verification (GdmGreeterLoginWindow *login_window,
|
|
GdmGreeterSession *session)
|
|
{
|
|
- gdm_greeter_client_call_begin_verification (session->priv->client);
|
|
+ gdm_greeter_client_call_begin_verification (session->priv->client,
|
|
+ "gdm");
|
|
}
|
|
|
|
static void
|
|
@@ -200,6 +205,7 @@ on_begin_verification_for_user (GdmGreeterLoginWindow *login_window,
|
|
GdmGreeterSession *session)
|
|
{
|
|
gdm_greeter_client_call_begin_verification_for_user (session->priv->client,
|
|
+ "gdm",
|
|
username);
|
|
}
|
|
|
|
@@ -209,6 +215,7 @@ on_query_answer (GdmGreeterLoginWindow *login_window,
|
|
GdmGreeterSession *session)
|
|
{
|
|
gdm_greeter_client_call_answer_query (session->priv->client,
|
|
+ "gdm",
|
|
text);
|
|
}
|
|
|
|
@@ -265,7 +272,7 @@ static void
|
|
on_start_session (GdmGreeterLoginWindow *login_window,
|
|
GdmGreeterSession *session)
|
|
{
|
|
- gdm_greeter_client_call_start_session_when_ready (session->priv->client, TRUE);
|
|
+ gdm_greeter_client_call_start_session_when_ready (session->priv->client, "gdm", TRUE);
|
|
}
|
|
|
|
static void
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 37c3657589bc1d29ac7af31b4dbaff74aa07f5a5 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Wed, 28 Jan 2009 15:12:04 -0500
|
|
Subject: [PATCH 09/65] Move messages pending replies to conversations
|
|
|
|
---
|
|
daemon/gdm-session-direct.c | 40 ++++++++++++++++++----------------------
|
|
1 files changed, 18 insertions(+), 22 deletions(-)
|
|
|
|
diff --git a/daemon/gdm-session-direct.c b/daemon/gdm-session-direct.c
|
|
index a12e333..b15b727 100644
|
|
--- a/daemon/gdm-session-direct.c
|
|
+++ b/daemon/gdm-session-direct.c
|
|
@@ -68,6 +68,7 @@ typedef struct
|
|
GPid worker_pid;
|
|
char *service_name;
|
|
DBusConnection *worker_connection;
|
|
+ DBusMessage *message_pending_reply;
|
|
} GdmSessionConversation;
|
|
|
|
struct _GdmSessionDirectPrivate
|
|
@@ -82,8 +83,6 @@ struct _GdmSessionDirectPrivate
|
|
char *selected_user;
|
|
char *user_x11_authority_file;
|
|
|
|
- DBusMessage *message_pending_reply;
|
|
-
|
|
GHashTable *conversations;
|
|
|
|
GList *pending_connections;
|
|
@@ -776,27 +775,25 @@ gdm_session_direct_handle_username_changed (GdmSessionDirect *session,
|
|
}
|
|
|
|
static void
|
|
-cancel_pending_query (GdmSessionDirect *session)
|
|
+cancel_pending_query (GdmSessionConversation *conversation)
|
|
{
|
|
DBusMessage *reply;
|
|
- GdmSessionConversation *conversation;
|
|
|
|
- if (session->priv->message_pending_reply == NULL) {
|
|
+ if (conversation->message_pending_reply == NULL) {
|
|
return;
|
|
}
|
|
|
|
g_debug ("GdmSessionDirect: Cancelling pending query");
|
|
|
|
- reply = dbus_message_new_error (session->priv->message_pending_reply,
|
|
+ reply = dbus_message_new_error (conversation->message_pending_reply,
|
|
GDM_SESSION_DBUS_ERROR_CANCEL,
|
|
"Operation cancelled");
|
|
- conversation = NULL;
|
|
dbus_connection_send (conversation->worker_connection, reply, NULL);
|
|
dbus_connection_flush (conversation->worker_connection);
|
|
|
|
dbus_message_unref (reply);
|
|
- dbus_message_unref (session->priv->message_pending_reply);
|
|
- session->priv->message_pending_reply = NULL;
|
|
+ dbus_message_unref (conversation->message_pending_reply);
|
|
+ conversation->message_pending_reply = NULL;
|
|
}
|
|
|
|
static void
|
|
@@ -808,27 +805,26 @@ answer_pending_query (GdmSessionDirect *session,
|
|
DBusMessageIter iter;
|
|
GdmSessionConversation *conversation;
|
|
|
|
- g_assert (session->priv->message_pending_reply != NULL);
|
|
+ conversation = find_conversation_by_name (session, service_name);
|
|
|
|
- reply = dbus_message_new_method_return (session->priv->message_pending_reply);
|
|
+ reply = dbus_message_new_method_return (conversation->message_pending_reply);
|
|
dbus_message_iter_init_append (reply, &iter);
|
|
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &answer);
|
|
|
|
- conversation = find_conversation_by_name (session, service_name);
|
|
dbus_connection_send (conversation->worker_connection, reply, NULL);
|
|
dbus_message_unref (reply);
|
|
|
|
- dbus_message_unref (session->priv->message_pending_reply);
|
|
- session->priv->message_pending_reply = NULL;
|
|
+ dbus_message_unref (conversation->message_pending_reply);
|
|
+ conversation->message_pending_reply = NULL;
|
|
}
|
|
|
|
static void
|
|
-set_pending_query (GdmSessionDirect *session,
|
|
- DBusMessage *message)
|
|
+set_pending_query (GdmSessionConversation *conversation,
|
|
+ DBusMessage *message)
|
|
{
|
|
- g_assert (session->priv->message_pending_reply == NULL);
|
|
+ g_assert (conversation->message_pending_reply == NULL);
|
|
|
|
- session->priv->message_pending_reply = dbus_message_ref (message);
|
|
+ conversation->message_pending_reply = dbus_message_ref (message);
|
|
}
|
|
|
|
static DBusHandlerResult
|
|
@@ -846,7 +842,7 @@ gdm_session_direct_handle_info_query (GdmSessionDirect *session,
|
|
g_warning ("ERROR: %s", error.message);
|
|
}
|
|
|
|
- set_pending_query (session, message);
|
|
+ set_pending_query (conversation, message);
|
|
|
|
g_debug ("GdmSessionDirect: Emitting 'info-query' signal");
|
|
_gdm_session_info_query (GDM_SESSION (session), conversation->service_name, text);
|
|
@@ -869,7 +865,7 @@ gdm_session_direct_handle_secret_info_query (GdmSessionDirect *session,
|
|
g_warning ("ERROR: %s", error.message);
|
|
}
|
|
|
|
- set_pending_query (session, message);
|
|
+ set_pending_query (conversation, message);
|
|
|
|
g_debug ("GdmSessionDirect: Emitting 'secret-info-query' signal");
|
|
_gdm_session_secret_info_query (GDM_SESSION (session), conversation->service_name, text);
|
|
@@ -911,7 +907,7 @@ gdm_session_direct_handle_cancel_pending_query (GdmSessionDirect *session,
|
|
DBusMessage *reply;
|
|
|
|
g_debug ("GdmSessionDirect: worker cancelling pending query");
|
|
- cancel_pending_query (session);
|
|
+ cancel_pending_query (conversation);
|
|
|
|
reply = dbus_message_new_method_return (message);
|
|
dbus_connection_send (conversation->worker_connection, reply, NULL);
|
|
@@ -1801,7 +1797,7 @@ stop_conversation (GdmSessionConversation *conversation)
|
|
G_CALLBACK (worker_died),
|
|
conversation);
|
|
|
|
- cancel_pending_query (session);
|
|
+ cancel_pending_query (conversation);
|
|
|
|
if (conversation->worker_connection != NULL) {
|
|
dbus_connection_close (conversation->worker_connection);
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From d693910b078cc8077ee504fe39bde63e74c891f1 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Wed, 28 Jan 2009 15:15:10 -0500
|
|
Subject: [PATCH 10/65] Remove filter on worker connection at end of conv
|
|
|
|
---
|
|
daemon/gdm-session-direct.c | 2 ++
|
|
1 files changed, 2 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/daemon/gdm-session-direct.c b/daemon/gdm-session-direct.c
|
|
index b15b727..a243ead 100644
|
|
--- a/daemon/gdm-session-direct.c
|
|
+++ b/daemon/gdm-session-direct.c
|
|
@@ -1800,6 +1800,8 @@ stop_conversation (GdmSessionConversation *conversation)
|
|
cancel_pending_query (conversation);
|
|
|
|
if (conversation->worker_connection != NULL) {
|
|
+ dbus_connection_remove_filter (conversation->worker_connection, on_message, session);
|
|
+
|
|
dbus_connection_close (conversation->worker_connection);
|
|
conversation->worker_connection = NULL;
|
|
}
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 6fa05c7cd02e5db1d2df056197bbd41cd237c6b9 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Wed, 28 Jan 2009 15:16:02 -0500
|
|
Subject: [PATCH 11/65] Pass service name to StartSession in relay session
|
|
|
|
---
|
|
daemon/gdm-session-relay.c | 5 +++--
|
|
1 files changed, 3 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/daemon/gdm-session-relay.c b/daemon/gdm-session-relay.c
|
|
index 36e86b5..6e15f75 100644
|
|
--- a/daemon/gdm-session-relay.c
|
|
+++ b/daemon/gdm-session-relay.c
|
|
@@ -296,11 +296,12 @@ gdm_session_relay_cancel (GdmSession *session)
|
|
}
|
|
|
|
static void
|
|
-gdm_session_relay_start_session (GdmSession *session)
|
|
+gdm_session_relay_start_session (GdmSession *session,
|
|
+ const char *service_name)
|
|
{
|
|
GdmSessionRelay *impl = GDM_SESSION_RELAY (session);
|
|
|
|
- send_dbus_void_signal (impl, "StartSession");
|
|
+ send_dbus_string_signal (impl, "StartSession", service_name);
|
|
}
|
|
|
|
/* Note: Use abstract sockets like dbus does by default on Linux. Abstract
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From ccc1a816780e0e42ae124d471d6eb365c3c35e01 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Wed, 28 Jan 2009 15:16:30 -0500
|
|
Subject: [PATCH 12/65] change g_return_if_fail to g_return_val_if_fail
|
|
|
|
---
|
|
daemon/gdm-session-worker-job.c | 2 +-
|
|
1 files changed, 1 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/daemon/gdm-session-worker-job.c b/daemon/gdm-session-worker-job.c
|
|
index 1a7cf36..7328c0e 100644
|
|
--- a/daemon/gdm-session-worker-job.c
|
|
+++ b/daemon/gdm-session-worker-job.c
|
|
@@ -273,7 +273,7 @@ gdm_session_worker_job_stop (GdmSessionWorkerJob *session_worker_job)
|
|
GPid
|
|
gdm_session_worker_job_get_pid (GdmSessionWorkerJob *session_worker_job)
|
|
{
|
|
- g_return_if_fail (GDM_IS_SESSION_WORKER_JOB (session_worker_job));
|
|
+ g_return_val_if_fail (GDM_IS_SESSION_WORKER_JOB (session_worker_job), 0);
|
|
return session_worker_job->priv->pid;
|
|
}
|
|
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 5d4aebec04b11866e9fdaf02fe59e271d3d762cb Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Wed, 28 Jan 2009 15:16:51 -0500
|
|
Subject: [PATCH 13/65] Fix cancel operation
|
|
|
|
---
|
|
daemon/gdm-session-direct.c | 11 ++++++++++-
|
|
gui/simple-greeter/gdm-greeter-session.c | 1 +
|
|
2 files changed, 11 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/daemon/gdm-session-direct.c b/daemon/gdm-session-direct.c
|
|
index a243ead..55ea4ee 100644
|
|
--- a/daemon/gdm-session-direct.c
|
|
+++ b/daemon/gdm-session-direct.c
|
|
@@ -2291,10 +2291,19 @@ static void
|
|
gdm_session_direct_cancel (GdmSession *session)
|
|
{
|
|
GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
+ GHashTableIter iter;
|
|
+ gpointer key, value;
|
|
|
|
g_return_if_fail (session != NULL);
|
|
|
|
- cancel_pending_query (impl);
|
|
+ g_hash_table_iter_init (&iter, impl->priv->conversations);
|
|
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
|
|
+ GdmSessionConversation *conversation;
|
|
+
|
|
+ conversation = (GdmSessionConversation *) value;
|
|
+
|
|
+ cancel_pending_query (conversation);
|
|
+ }
|
|
}
|
|
|
|
char *
|
|
diff --git a/gui/simple-greeter/gdm-greeter-session.c b/gui/simple-greeter/gdm-greeter-session.c
|
|
index e625c24..ea9e6d1 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-session.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-session.c
|
|
@@ -259,6 +259,7 @@ on_cancelled (GdmGreeterLoginWindow *login_window,
|
|
{
|
|
gdm_greeter_panel_hide_user_options (GDM_GREETER_PANEL (session->priv->panel));
|
|
gdm_greeter_client_call_cancel (session->priv->client);
|
|
+ gdm_greeter_client_call_start_conversation (session->priv->client, "gdm");
|
|
}
|
|
|
|
static void
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From f60c338339301925e35eabb327346cc35213c37e Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Wed, 28 Jan 2009 18:01:53 -0500
|
|
Subject: [PATCH 14/65] Handle Start Conversation for relay session
|
|
|
|
---
|
|
daemon/gdm-factory-slave.c | 14 +++++++++++++-
|
|
1 files changed, 13 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/daemon/gdm-factory-slave.c b/daemon/gdm-factory-slave.c
|
|
index 3251ec2..826612e 100644
|
|
--- a/daemon/gdm-factory-slave.c
|
|
+++ b/daemon/gdm-factory-slave.c
|
|
@@ -380,8 +380,16 @@ on_session_relay_connected (GdmSessionRelay *session,
|
|
GdmFactorySlave *slave)
|
|
{
|
|
g_debug ("GdmFactorySlave: Relay Connected");
|
|
+}
|
|
+
|
|
+static void
|
|
+on_greeter_start_conversation (GdmGreeterServer *greeter_server,
|
|
+ const char *service_name,
|
|
+ GdmFactorySlave *slave)
|
|
+{
|
|
+ g_debug ("GdmFactorySlave: start conversation");
|
|
|
|
- gdm_session_start_conversation (GDM_SESSION (slave->priv->session), "gdm");
|
|
+ gdm_session_start_conversation (GDM_SESSION (slave->priv->session), service_name);
|
|
}
|
|
|
|
static void
|
|
@@ -510,6 +518,10 @@ run_greeter (GdmFactorySlave *slave)
|
|
|
|
slave->priv->greeter_server = gdm_greeter_server_new (display_id);
|
|
g_signal_connect (slave->priv->greeter_server,
|
|
+ "start-conversation",
|
|
+ G_CALLBACK (on_greeter_start_conversation),
|
|
+ slave);
|
|
+ g_signal_connect (slave->priv->greeter_server,
|
|
"begin-verification",
|
|
G_CALLBACK (on_greeter_begin_verification),
|
|
slave);
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From d55500e9fa9c88a917b263f7477fb29ac4f727e2 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Fri, 30 Jan 2009 23:57:31 -0500
|
|
Subject: [PATCH 15/65] Add limited support for multiple pam stacks
|
|
|
|
This hard codes 3 pam stacks and doesn't handle
|
|
switching between them very well yet.
|
|
---
|
|
gui/simple-greeter/Makefile.am | 4 +
|
|
gui/simple-greeter/gdm-greeter-login-window.c | 84 ++++++++--
|
|
gui/simple-greeter/gdm-greeter-login-window.glade | 39 ++++-
|
|
gui/simple-greeter/gdm-greeter-login-window.h | 11 +-
|
|
gui/simple-greeter/gdm-greeter-session.c | 30 +++-
|
|
gui/simple-greeter/gdm-task-list.c | 201 +++++++++++++++++++++
|
|
gui/simple-greeter/gdm-task-list.h | 61 +++++++
|
|
7 files changed, 402 insertions(+), 28 deletions(-)
|
|
create mode 100644 gui/simple-greeter/gdm-task-list.c
|
|
create mode 100644 gui/simple-greeter/gdm-task-list.h
|
|
|
|
diff --git a/gui/simple-greeter/Makefile.am b/gui/simple-greeter/Makefile.am
|
|
index 9b5834d..e2d3996 100644
|
|
--- a/gui/simple-greeter/Makefile.am
|
|
+++ b/gui/simple-greeter/Makefile.am
|
|
@@ -83,6 +83,8 @@ test_greeter_login_window_SOURCES = \
|
|
gdm-user-chooser-widget.c \
|
|
gdm-user-chooser-dialog.h \
|
|
gdm-user-chooser-dialog.c \
|
|
+ gdm-task-list.h \
|
|
+ gdm-task-list.c \
|
|
$(NULL)
|
|
|
|
test_greeter_login_window_LDADD = \
|
|
@@ -316,6 +318,8 @@ gdm_simple_greeter_SOURCES = \
|
|
gdm-session-option-widget.c \
|
|
gdm-user-chooser-widget.h \
|
|
gdm-user-chooser-widget.c \
|
|
+ gdm-task-list.h \
|
|
+ gdm-task-list.c \
|
|
$(NULL)
|
|
|
|
gdm_simple_greeter_LDADD = \
|
|
diff --git a/gui/simple-greeter/gdm-greeter-login-window.c b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
index a3e1411..f3daccb 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-login-window.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
@@ -60,12 +60,16 @@
|
|
#include <polkit-gnome/polkit-gnome.h>
|
|
#endif
|
|
|
|
+#include "gdm-marshal.h"
|
|
+
|
|
#include "gdm-settings-client.h"
|
|
#include "gdm-settings-keys.h"
|
|
#include "gdm-profile.h"
|
|
|
|
+#include "gdm-greeter-client.h"
|
|
#include "gdm-greeter-login-window.h"
|
|
#include "gdm-user-chooser-widget.h"
|
|
+#include "gdm-task-list.h"
|
|
|
|
#ifdef HAVE_PAM
|
|
#include <security/pam_appl.h>
|
|
@@ -111,6 +115,7 @@ struct GdmGreeterLoginWindowPrivate
|
|
{
|
|
GladeXML *xml;
|
|
GtkWidget *user_chooser;
|
|
+ GtkWidget *conversation_list;
|
|
GtkWidget *auth_banner_label;
|
|
guint display_is_local : 1;
|
|
guint is_interactive : 1;
|
|
@@ -139,6 +144,7 @@ enum {
|
|
};
|
|
|
|
enum {
|
|
+ START_CONVERSATION,
|
|
BEGIN_AUTO_LOGIN,
|
|
BEGIN_VERIFICATION,
|
|
BEGIN_VERIFICATION_FOR_USER,
|
|
@@ -395,7 +401,7 @@ on_login_button_clicked_answer_query (GtkButton *button,
|
|
text = gtk_entry_get_text (GTK_ENTRY (entry));
|
|
|
|
_gdm_greeter_login_window_set_interactive (login_window, TRUE);
|
|
- g_signal_emit (login_window, signals[QUERY_ANSWER], 0, text);
|
|
+ g_signal_emit (login_window, signals[QUERY_ANSWER], 0, "gdm", text);
|
|
}
|
|
|
|
static void
|
|
@@ -751,26 +757,32 @@ gdm_greeter_login_window_reset (GdmGreeterLoginWindow *login_window)
|
|
|
|
gboolean
|
|
gdm_greeter_login_window_info (GdmGreeterLoginWindow *login_window,
|
|
+ const char *service_name,
|
|
const char *text)
|
|
{
|
|
g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE);
|
|
|
|
g_debug ("GdmGreeterLoginWindow: info: %s", text);
|
|
|
|
- set_message (GDM_GREETER_LOGIN_WINDOW (login_window), text);
|
|
+ if (strcmp (service_name, gdm_task_list_get_active_task (login_window->priv->conversation_list)) == 0) {
|
|
+ set_message (GDM_GREETER_LOGIN_WINDOW (login_window), text);
|
|
+ }
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
gboolean
|
|
gdm_greeter_login_window_problem (GdmGreeterLoginWindow *login_window,
|
|
+ const char *service_name,
|
|
const char *text)
|
|
{
|
|
g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE);
|
|
|
|
g_debug ("GdmGreeterLoginWindow: problem: %s", text);
|
|
|
|
- set_message (GDM_GREETER_LOGIN_WINDOW (login_window), text);
|
|
+ if (strcmp (service_name, gdm_task_list_get_active_task (login_window->priv->conversation_list)) == 0) {
|
|
+ set_message (GDM_GREETER_LOGIN_WINDOW (login_window), text);
|
|
+ }
|
|
gdk_window_beep (GTK_WIDGET (login_window)->window);
|
|
|
|
return TRUE;
|
|
@@ -846,6 +858,7 @@ gdm_greeter_login_window_start_session_when_ready (GdmGreeterLoginWindow *login_
|
|
|
|
gboolean
|
|
gdm_greeter_login_window_info_query (GdmGreeterLoginWindow *login_window,
|
|
+ const char *service_name,
|
|
const char *text)
|
|
{
|
|
GtkWidget *entry;
|
|
@@ -853,6 +866,10 @@ gdm_greeter_login_window_info_query (GdmGreeterLoginWindow *login_window,
|
|
|
|
g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE);
|
|
|
|
+ if (strcmp (service_name, gdm_task_list_get_active_task (login_window->priv->conversation_list)) != 0) {
|
|
+ return TRUE;
|
|
+ }
|
|
+
|
|
g_debug ("GdmGreeterLoginWindow: info query: %s", text);
|
|
|
|
entry = glade_xml_get_widget (GDM_GREETER_LOGIN_WINDOW (login_window)->priv->xml, "auth-prompt-entry");
|
|
@@ -875,6 +892,7 @@ gdm_greeter_login_window_info_query (GdmGreeterLoginWindow *login_window,
|
|
|
|
gboolean
|
|
gdm_greeter_login_window_secret_info_query (GdmGreeterLoginWindow *login_window,
|
|
+ const char *service_name,
|
|
const char *text)
|
|
{
|
|
GtkWidget *entry;
|
|
@@ -1347,7 +1365,10 @@ on_user_chosen (GdmUserChooserWidget *user_chooser,
|
|
0, user_name);
|
|
|
|
if (strcmp (user_name, GDM_USER_CHOOSER_USER_OTHER) == 0) {
|
|
- g_signal_emit (login_window, signals[BEGIN_VERIFICATION], 0);
|
|
+ const char *service_name;
|
|
+
|
|
+ service_name = gdm_task_list_get_active_task (GDM_TASK_LIST (login_window->priv->conversation_list));
|
|
+ g_signal_emit (login_window, signals[BEGIN_VERIFICATION], 0, service_name);
|
|
} else if (strcmp (user_name, GDM_USER_CHOOSER_USER_GUEST) == 0) {
|
|
/* FIXME: handle guest account stuff */
|
|
} else if (strcmp (user_name, GDM_USER_CHOOSER_USER_AUTO) == 0) {
|
|
@@ -1361,7 +1382,10 @@ on_user_chosen (GdmUserChooserWidget *user_chooser,
|
|
set_log_in_button_mode (login_window, LOGIN_BUTTON_TIMED_LOGIN);
|
|
set_message (login_window, _("Select language and click Log In"));
|
|
} else {
|
|
- g_signal_emit (login_window, signals[BEGIN_VERIFICATION_FOR_USER], 0, user_name);
|
|
+ const char *service_name;
|
|
+
|
|
+ service_name = gdm_task_list_get_active_task (GDM_TASK_LIST (login_window->priv->conversation_list));
|
|
+ g_signal_emit (login_window, signals[BEGIN_VERIFICATION_FOR_USER], 0, service_name, user_name);
|
|
}
|
|
|
|
switch_mode (login_window, MODE_AUTHENTICATION);
|
|
@@ -1505,6 +1529,21 @@ create_computer_info (GdmGreeterLoginWindow *login_window)
|
|
#define INVISIBLE_CHAR_BULLET 0x2022
|
|
#define INVISIBLE_CHAR_NONE 0
|
|
|
|
+static void
|
|
+on_task_activated (GdmGreeterLoginWindow *login_window,
|
|
+ const char *name)
|
|
+{
|
|
+ g_debug ("GdmGreeterLoginWindow: starting conversation with '%s'", name);
|
|
+ g_signal_emit (login_window, signals[START_CONVERSATION], 0, name);
|
|
+}
|
|
+
|
|
+static void
|
|
+on_task_deactivated (GdmGreeterLoginWindow *login_window,
|
|
+ const char *name)
|
|
+{
|
|
+ g_debug ("GdmGreeterLoginWindow: conversation '%s' now in background", name);
|
|
+}
|
|
+
|
|
static GtkWidget *
|
|
custom_widget_constructor (GladeXML *xml,
|
|
char *func_name,
|
|
@@ -1527,6 +1566,8 @@ custom_widget_constructor (GladeXML *xml,
|
|
|
|
if (strcmp (name, "user-chooser") == 0) {
|
|
widget = gdm_user_chooser_widget_new ();
|
|
+ } else if (strcmp (name, "conversation-list") == 0) {
|
|
+ widget = gdm_task_list_new ();
|
|
}
|
|
|
|
gdm_profile_end (NULL);
|
|
@@ -1600,6 +1641,18 @@ load_theme (GdmGreeterLoginWindow *login_window)
|
|
|
|
gtk_widget_show (login_window->priv->user_chooser);
|
|
|
|
+ login_window->priv->conversation_list = glade_xml_get_widget (login_window->priv->xml,
|
|
+ "conversation-list");
|
|
+ g_signal_connect_swapped (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
+ "activated",
|
|
+ G_CALLBACK (on_task_activated),
|
|
+ login_window);
|
|
+ g_signal_connect_swapped (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
+ "deactivated",
|
|
+ G_CALLBACK (on_task_deactivated),
|
|
+ login_window);
|
|
+ gtk_widget_show (login_window->priv->conversation_list);
|
|
+
|
|
login_window->priv->auth_banner_label = glade_xml_get_widget (login_window->priv->xml, "auth-banner-label");
|
|
/*make_label_small_italic (login_window->priv->auth_banner_label);*/
|
|
|
|
@@ -1757,6 +1810,15 @@ gdm_greeter_login_window_class_init (GdmGreeterLoginWindowClass *klass)
|
|
widget_class->key_press_event = gdm_greeter_login_window_key_press_event;
|
|
widget_class->size_request = gdm_greeter_login_window_size_request;
|
|
|
|
+ signals [START_CONVERSATION] =
|
|
+ g_signal_new ("start-conversation",
|
|
+ G_TYPE_FROM_CLASS (object_class),
|
|
+ G_SIGNAL_RUN_LAST,
|
|
+ G_STRUCT_OFFSET (GdmGreeterLoginWindowClass, start_conversation),
|
|
+ NULL,
|
|
+ NULL,
|
|
+ g_cclosure_marshal_VOID__STRING,
|
|
+ G_TYPE_NONE, 1, G_TYPE_STRING);
|
|
signals [BEGIN_AUTO_LOGIN] =
|
|
g_signal_new ("begin-auto-login",
|
|
G_TYPE_FROM_CLASS (object_class),
|
|
@@ -1773,9 +1835,9 @@ gdm_greeter_login_window_class_init (GdmGreeterLoginWindowClass *klass)
|
|
G_STRUCT_OFFSET (GdmGreeterLoginWindowClass, begin_verification),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__VOID,
|
|
+ g_cclosure_marshal_VOID__STRING,
|
|
G_TYPE_NONE,
|
|
- 0);
|
|
+ 1, G_TYPE_STRING);
|
|
signals [BEGIN_VERIFICATION_FOR_USER] =
|
|
g_signal_new ("begin-verification-for-user",
|
|
G_TYPE_FROM_CLASS (object_class),
|
|
@@ -1783,9 +1845,9 @@ gdm_greeter_login_window_class_init (GdmGreeterLoginWindowClass *klass)
|
|
G_STRUCT_OFFSET (GdmGreeterLoginWindowClass, begin_verification_for_user),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__STRING,
|
|
+ gdm_marshal_VOID__STRING_STRING,
|
|
G_TYPE_NONE,
|
|
- 1, G_TYPE_STRING);
|
|
+ 2, G_TYPE_STRING, G_TYPE_STRING);
|
|
signals [QUERY_ANSWER] =
|
|
g_signal_new ("query-answer",
|
|
G_TYPE_FROM_CLASS (object_class),
|
|
@@ -1793,9 +1855,9 @@ gdm_greeter_login_window_class_init (GdmGreeterLoginWindowClass *klass)
|
|
G_STRUCT_OFFSET (GdmGreeterLoginWindowClass, query_answer),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__STRING,
|
|
+ gdm_marshal_VOID__STRING_STRING,
|
|
G_TYPE_NONE,
|
|
- 1, G_TYPE_STRING);
|
|
+ 2, G_TYPE_STRING, G_TYPE_STRING);
|
|
signals [USER_SELECTED] =
|
|
g_signal_new ("user-selected",
|
|
G_TYPE_FROM_CLASS (object_class),
|
|
diff --git a/gui/simple-greeter/gdm-greeter-login-window.glade b/gui/simple-greeter/gdm-greeter-login-window.glade
|
|
index 0fb0ad8..a3ae5ba 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-login-window.glade
|
|
+++ b/gui/simple-greeter/gdm-greeter-login-window.glade
|
|
@@ -654,11 +654,38 @@
|
|
<property name="spacing">10</property>
|
|
|
|
<child>
|
|
- <widget class="Custom" id="user-chooser">
|
|
+ <widget class="GtkVBox" id="vbox6">
|
|
<property name="visible">True</property>
|
|
- <property name="int1">0</property>
|
|
- <property name="int2">0</property>
|
|
- <property name="last_modification_time">Tue, 18 Nov 2008 21:55:38 GMT</property>
|
|
+ <property name="homogeneous">False</property>
|
|
+ <property name="spacing">0</property>
|
|
+
|
|
+ <child>
|
|
+ <widget class="Custom" id="user-chooser">
|
|
+ <property name="visible">True</property>
|
|
+ <property name="int1">0</property>
|
|
+ <property name="int2">0</property>
|
|
+ <property name="last_modification_time">Tue, 18 Nov 2008 21:55:38 GMT</property>
|
|
+ </widget>
|
|
+ <packing>
|
|
+ <property name="padding">0</property>
|
|
+ <property name="expand">True</property>
|
|
+ <property name="fill">True</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+
|
|
+ <child>
|
|
+ <widget class="Custom" id="conversation-list">
|
|
+ <property name="visible">True</property>
|
|
+ <property name="int1">0</property>
|
|
+ <property name="int2">0</property>
|
|
+ <property name="last_modification_time">Fri, 30 Jan 2009 16:03:30 GMT</property>
|
|
+ </widget>
|
|
+ <packing>
|
|
+ <property name="padding">0</property>
|
|
+ <property name="expand">False</property>
|
|
+ <property name="fill">False</property>
|
|
+ </packing>
|
|
+ </child>
|
|
</widget>
|
|
<packing>
|
|
<property name="padding">0</property>
|
|
@@ -779,10 +806,6 @@
|
|
</child>
|
|
</widget>
|
|
</child>
|
|
-
|
|
- <child>
|
|
- <placeholder/>
|
|
- </child>
|
|
</widget>
|
|
</child>
|
|
</widget>
|
|
diff --git a/gui/simple-greeter/gdm-greeter-login-window.h b/gui/simple-greeter/gdm-greeter-login-window.h
|
|
index 817d0a2..559b26b 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-login-window.h
|
|
+++ b/gui/simple-greeter/gdm-greeter-login-window.h
|
|
@@ -46,12 +46,17 @@ typedef struct
|
|
GtkWindowClass parent_class;
|
|
|
|
/* signals */
|
|
+ void (* start_conversation) (GdmGreeterLoginWindow *login_window,
|
|
+ const char *service_name);
|
|
void (* begin_auto_login) (GdmGreeterLoginWindow *login_window,
|
|
const char *username);
|
|
- void (* begin_verification) (GdmGreeterLoginWindow *login_window);
|
|
+ void (* begin_verification) (GdmGreeterLoginWindow *login_window,
|
|
+ const char *service_name);
|
|
void (* begin_verification_for_user) (GdmGreeterLoginWindow *login_window,
|
|
+ const char *service_name,
|
|
const char *username);
|
|
void (* query_answer) (GdmGreeterLoginWindow *login_window,
|
|
+ const char *service_name,
|
|
const char *text);
|
|
void (* user_selected) (GdmGreeterLoginWindow *login_window,
|
|
const char *text);
|
|
@@ -68,12 +73,16 @@ GtkWidget * gdm_greeter_login_window_new (gboolean displa
|
|
gboolean gdm_greeter_login_window_reset (GdmGreeterLoginWindow *login_window);
|
|
gboolean gdm_greeter_login_window_ready (GdmGreeterLoginWindow *login_window);
|
|
gboolean gdm_greeter_login_window_info_query (GdmGreeterLoginWindow *login_window,
|
|
+ const char *service_name,
|
|
const char *text);
|
|
gboolean gdm_greeter_login_window_secret_info_query (GdmGreeterLoginWindow *login_window,
|
|
+ const char *service_name,
|
|
const char *text);
|
|
gboolean gdm_greeter_login_window_info (GdmGreeterLoginWindow *login_window,
|
|
+ const char *service_name,
|
|
const char *text);
|
|
gboolean gdm_greeter_login_window_problem (GdmGreeterLoginWindow *login_window,
|
|
+ const char *service_name,
|
|
const char *text);
|
|
|
|
void gdm_greeter_login_window_request_timed_login (GdmGreeterLoginWindow *login_window,
|
|
diff --git a/gui/simple-greeter/gdm-greeter-session.c b/gui/simple-greeter/gdm-greeter-session.c
|
|
index ea9e6d1..79f367c 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-session.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-session.c
|
|
@@ -70,7 +70,7 @@ on_info (GdmGreeterClient *client,
|
|
{
|
|
g_debug ("GdmGreeterSession: Info: %s", text);
|
|
|
|
- gdm_greeter_login_window_info (GDM_GREETER_LOGIN_WINDOW (session->priv->login_window), text);
|
|
+ gdm_greeter_login_window_info (GDM_GREETER_LOGIN_WINDOW (session->priv->login_window), service_name, text);
|
|
}
|
|
|
|
static void
|
|
@@ -81,7 +81,7 @@ on_problem (GdmGreeterClient *client,
|
|
{
|
|
g_debug ("GdmGreeterSession: Problem: %s", text);
|
|
|
|
- gdm_greeter_login_window_problem (GDM_GREETER_LOGIN_WINDOW (session->priv->login_window), text);
|
|
+ gdm_greeter_login_window_problem (GDM_GREETER_LOGIN_WINDOW (session->priv->login_window), service_name, text);
|
|
}
|
|
|
|
static void
|
|
@@ -168,7 +168,7 @@ on_info_query (GdmGreeterClient *client,
|
|
{
|
|
g_debug ("GdmGreeterSession: Info query: %s", text);
|
|
|
|
- gdm_greeter_login_window_info_query (GDM_GREETER_LOGIN_WINDOW (session->priv->login_window), text);
|
|
+ gdm_greeter_login_window_info_query (GDM_GREETER_LOGIN_WINDOW (session->priv->login_window), service_name, text);
|
|
}
|
|
|
|
static void
|
|
@@ -179,10 +179,18 @@ on_secret_info_query (GdmGreeterClient *client,
|
|
{
|
|
g_debug ("GdmGreeterSession: Secret info query: %s", text);
|
|
|
|
- gdm_greeter_login_window_secret_info_query (GDM_GREETER_LOGIN_WINDOW (session->priv->login_window), text);
|
|
+ gdm_greeter_login_window_secret_info_query (GDM_GREETER_LOGIN_WINDOW (session->priv->login_window), service_name, text);
|
|
}
|
|
|
|
static void
|
|
+on_start_conversation (GdmGreeterLoginWindow *login_window,
|
|
+ const char *service_name,
|
|
+ GdmGreeterSession *session)
|
|
+{
|
|
+ gdm_greeter_client_call_start_conversation (session->priv->client,
|
|
+ service_name);
|
|
+}
|
|
+static void
|
|
on_begin_auto_login (GdmGreeterLoginWindow *login_window,
|
|
const char *username,
|
|
GdmGreeterSession *session)
|
|
@@ -193,29 +201,32 @@ on_begin_auto_login (GdmGreeterLoginWindow *login_window,
|
|
|
|
static void
|
|
on_begin_verification (GdmGreeterLoginWindow *login_window,
|
|
+ const char *service_name,
|
|
GdmGreeterSession *session)
|
|
{
|
|
gdm_greeter_client_call_begin_verification (session->priv->client,
|
|
- "gdm");
|
|
+ service_name);
|
|
}
|
|
|
|
static void
|
|
on_begin_verification_for_user (GdmGreeterLoginWindow *login_window,
|
|
+ const char *service_name,
|
|
const char *username,
|
|
GdmGreeterSession *session)
|
|
{
|
|
gdm_greeter_client_call_begin_verification_for_user (session->priv->client,
|
|
- "gdm",
|
|
+ service_name,
|
|
username);
|
|
}
|
|
|
|
static void
|
|
on_query_answer (GdmGreeterLoginWindow *login_window,
|
|
+ const char *service_name,
|
|
const char *text,
|
|
GdmGreeterSession *session)
|
|
{
|
|
gdm_greeter_client_call_answer_query (session->priv->client,
|
|
- "gdm",
|
|
+ service_name,
|
|
text);
|
|
}
|
|
|
|
@@ -330,7 +341,10 @@ toggle_login_window (GdmGreeterSession *session,
|
|
is_local = gdm_greeter_client_get_display_is_local (session->priv->client);
|
|
g_debug ("GdmGreeterSession: Starting a login window local:%d", is_local);
|
|
session->priv->login_window = gdm_greeter_login_window_new (is_local);
|
|
-
|
|
+ g_signal_connect (session->priv->login_window,
|
|
+ "start-conversation",
|
|
+ G_CALLBACK (on_start_conversation),
|
|
+ session);
|
|
g_signal_connect (session->priv->login_window,
|
|
"begin-auto-login",
|
|
G_CALLBACK (on_begin_auto_login),
|
|
diff --git a/gui/simple-greeter/gdm-task-list.c b/gui/simple-greeter/gdm-task-list.c
|
|
new file mode 100644
|
|
index 0000000..d522858
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/gdm-task-list.c
|
|
@@ -0,0 +1,201 @@
|
|
+/*
|
|
+ * Copyright (C) 2009 Red Hat, Inc.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
+ *
|
|
+ * Written by: Ray Strode <rstrode@redhat.com>
|
|
+ */
|
|
+
|
|
+#include "config.h"
|
|
+
|
|
+#include <stdlib.h>
|
|
+#include <stdio.h>
|
|
+#include <unistd.h>
|
|
+#include <string.h>
|
|
+#include <errno.h>
|
|
+#include <dirent.h>
|
|
+#include <sys/stat.h>
|
|
+
|
|
+#include <glib.h>
|
|
+#include <glib/gi18n.h>
|
|
+#include <glib/gstdio.h>
|
|
+#include <gtk/gtk.h>
|
|
+
|
|
+#include "gdm-task-list.h"
|
|
+
|
|
+#define GDM_TASK_LIST_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_TASK_LIST, GdmTaskListPrivate))
|
|
+
|
|
+typedef struct
|
|
+{
|
|
+ GtkWidget *radio_button;
|
|
+ char *name;
|
|
+} GdmTask;
|
|
+
|
|
+struct GdmTaskListPrivate
|
|
+{
|
|
+ GtkWidget *box;
|
|
+ GList *tasks;
|
|
+};
|
|
+
|
|
+enum {
|
|
+ ACTIVATED = 0,
|
|
+ DEACTIVATED,
|
|
+ NUMBER_OF_SIGNALS
|
|
+};
|
|
+
|
|
+static guint signals[NUMBER_OF_SIGNALS];
|
|
+
|
|
+static void gdm_task_list_class_init (GdmTaskListClass *klass);
|
|
+static void gdm_task_list_init (GdmTaskList *task_list);
|
|
+static void gdm_task_list_finalize (GObject *object);
|
|
+
|
|
+G_DEFINE_TYPE (GdmTaskList, gdm_task_list, GTK_TYPE_ALIGNMENT);
|
|
+
|
|
+static void
|
|
+on_task_toggled (GdmTaskList *widget,
|
|
+ GtkRadioButton *radio_button)
|
|
+{
|
|
+ GdmTask *task;
|
|
+
|
|
+ task = g_object_get_data (G_OBJECT (radio_button), "gdm-task");
|
|
+
|
|
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radio_button))) {
|
|
+ g_signal_emit (widget, signals[ACTIVATED], 0, task->name);
|
|
+ } else {
|
|
+ g_signal_emit (widget, signals[DEACTIVATED], 0, task->name);
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
+add_task (GdmTaskList *task_list,
|
|
+ const char *name,
|
|
+ const char *icon_name)
|
|
+{
|
|
+ GdmTask *task;
|
|
+ GtkWidget *image;
|
|
+
|
|
+ task = g_slice_new0 (GdmTask);
|
|
+
|
|
+ task->name = g_strdup (name);
|
|
+ if (task_list->priv->tasks == NULL) {
|
|
+ task->radio_button = gtk_radio_button_new (NULL);
|
|
+ } else {
|
|
+ task->radio_button = gtk_radio_button_new_from_widget (GTK_RADIO_BUTTON (((GdmTask *) task_list->priv->tasks->data)->radio_button));
|
|
+ }
|
|
+
|
|
+ g_object_set (task->radio_button, "draw-indicator", FALSE, NULL);
|
|
+ g_object_set_data (G_OBJECT (task->radio_button), "gdm-task", task);
|
|
+ g_signal_connect_swapped (task->radio_button,
|
|
+ "toggled", G_CALLBACK (on_task_toggled), task_list);
|
|
+ image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_DND);
|
|
+ gtk_widget_show (image);
|
|
+ gtk_container_add (GTK_CONTAINER (task->radio_button), image);
|
|
+ gtk_widget_show (task->radio_button);
|
|
+ gtk_container_add (GTK_CONTAINER (task->radio_button), task_list->priv->box);
|
|
+
|
|
+ gtk_container_add (GTK_CONTAINER (task_list->priv->box), task->radio_button);
|
|
+ task_list->priv->tasks = g_list_append (task_list->priv->tasks, task);
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_task_list_class_init (GdmTaskListClass *klass)
|
|
+{
|
|
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
+
|
|
+ object_class->finalize = gdm_task_list_finalize;
|
|
+
|
|
+ signals [ACTIVATED] = g_signal_new ("activated",
|
|
+ G_TYPE_FROM_CLASS (object_class),
|
|
+ G_SIGNAL_RUN_FIRST,
|
|
+ G_STRUCT_OFFSET (GdmTaskListClass, activated),
|
|
+ NULL,
|
|
+ NULL,
|
|
+ g_cclosure_marshal_VOID__STRING,
|
|
+ G_TYPE_NONE,
|
|
+ 1, G_TYPE_STRING);
|
|
+
|
|
+ signals [DEACTIVATED] = g_signal_new ("deactivated",
|
|
+ G_TYPE_FROM_CLASS (object_class),
|
|
+ G_SIGNAL_RUN_FIRST,
|
|
+ G_STRUCT_OFFSET (GdmTaskListClass, deactivated),
|
|
+ NULL,
|
|
+ NULL,
|
|
+ g_cclosure_marshal_VOID__STRING,
|
|
+ G_TYPE_NONE,
|
|
+ 1, G_TYPE_STRING);
|
|
+
|
|
+ g_type_class_add_private (klass, sizeof (GdmTaskListPrivate));
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_task_list_init (GdmTaskList *widget)
|
|
+{
|
|
+ widget->priv = GDM_TASK_LIST_GET_PRIVATE (widget);
|
|
+
|
|
+ gtk_alignment_set_padding (GTK_ALIGNMENT (widget), 0, 0, 0, 0);
|
|
+ gtk_alignment_set (GTK_ALIGNMENT (widget), 0.0, 0.0, 0, 0);
|
|
+
|
|
+ widget->priv->box = gtk_hbox_new (FALSE, 2);
|
|
+ gtk_widget_show (widget->priv->box);
|
|
+ gtk_container_add (GTK_CONTAINER (widget),
|
|
+ widget->priv->box);
|
|
+
|
|
+ add_task (widget, "password-auth", "dialog-password");
|
|
+ add_task (widget, "fingerprint-auth", "stock_allow-effects");
|
|
+ add_task (widget, "smartcard-auth", "badge-small");
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_task_list_finalize (GObject *object)
|
|
+{
|
|
+ GdmTaskList *widget;
|
|
+
|
|
+ g_return_if_fail (object != NULL);
|
|
+ g_return_if_fail (GDM_IS_TASK_LIST (object));
|
|
+
|
|
+ widget = GDM_TASK_LIST (object);
|
|
+
|
|
+ g_return_if_fail (widget->priv != NULL);
|
|
+
|
|
+ G_OBJECT_CLASS (gdm_task_list_parent_class)->finalize (object);
|
|
+}
|
|
+
|
|
+GtkWidget *
|
|
+gdm_task_list_new (void)
|
|
+{
|
|
+ GObject *object;
|
|
+
|
|
+ object = g_object_new (GDM_TYPE_TASK_LIST, NULL);
|
|
+
|
|
+ return GTK_WIDGET (object);
|
|
+}
|
|
+
|
|
+const char *
|
|
+gdm_task_list_get_active_task (GdmTaskList *widget)
|
|
+{
|
|
+ GList *node;
|
|
+
|
|
+ for (node = widget->priv->tasks; node != NULL; node = node->next) {
|
|
+ GdmTask *task;
|
|
+
|
|
+ task = node->data;
|
|
+
|
|
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (task->radio_button)) ) {
|
|
+ return task->name;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return NULL;
|
|
+}
|
|
diff --git a/gui/simple-greeter/gdm-task-list.h b/gui/simple-greeter/gdm-task-list.h
|
|
new file mode 100644
|
|
index 0000000..90c31cf
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/gdm-task-list.h
|
|
@@ -0,0 +1,61 @@
|
|
+/*
|
|
+ * Copyright (C) 2009 Red Hat, Inc.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
+ *
|
|
+ * Written by: Ray Strode <rstrode@redhat.com>
|
|
+ */
|
|
+
|
|
+#ifndef __GDM_TASK_LIST_H
|
|
+#define __GDM_TASK_LIST_H
|
|
+
|
|
+#include <glib-object.h>
|
|
+#include <gtk/gtkalignment.h>
|
|
+
|
|
+G_BEGIN_DECLS
|
|
+
|
|
+#define GDM_TYPE_TASK_LIST (gdm_task_list_get_type ())
|
|
+#define GDM_TASK_LIST(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_TASK_LIST, GdmTaskList))
|
|
+#define GDM_TASK_LIST_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_TASK_LIST, GdmTaskListClass))
|
|
+#define GDM_IS_TASK_LIST(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_TASK_LIST))
|
|
+#define GDM_IS_TASK_LIST_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_TASK_LIST))
|
|
+#define GDM_TASK_LIST_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_TASK_LIST, GdmTaskListClass))
|
|
+
|
|
+typedef struct GdmTaskListPrivate GdmTaskListPrivate;
|
|
+
|
|
+typedef struct
|
|
+{
|
|
+ GtkAlignment parent;
|
|
+ GdmTaskListPrivate *priv;
|
|
+} GdmTaskList;
|
|
+
|
|
+typedef struct
|
|
+{
|
|
+ GtkAlignmentClass parent_class;
|
|
+
|
|
+ void (* deactivated) (GdmTaskList *widget,
|
|
+ const char *name);
|
|
+ void (* activated) (GdmTaskList *widget,
|
|
+ const char *name);
|
|
+} GdmTaskListClass;
|
|
+
|
|
+
|
|
+GType gdm_task_list_get_type (void);
|
|
+GtkWidget * gdm_task_list_new (void);
|
|
+
|
|
+const char * gdm_task_list_get_active_task (GdmTaskList *widget);
|
|
+G_END_DECLS
|
|
+
|
|
+#endif /* __GDM_TASK_LIST_H */
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 0389551de0b71716cb47f337431648f5e9702bd7 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Sun, 1 Feb 2009 12:33:52 -0500
|
|
Subject: [PATCH 16/65] Add some casts to drop some warnings
|
|
|
|
---
|
|
gui/simple-greeter/gdm-greeter-login-window.c | 6 +++---
|
|
1 files changed, 3 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-greeter-login-window.c b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
index f3daccb..fe186e7 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-login-window.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
@@ -764,7 +764,7 @@ gdm_greeter_login_window_info (GdmGreeterLoginWindow *login_window,
|
|
|
|
g_debug ("GdmGreeterLoginWindow: info: %s", text);
|
|
|
|
- if (strcmp (service_name, gdm_task_list_get_active_task (login_window->priv->conversation_list)) == 0) {
|
|
+ if (strcmp (service_name, gdm_task_list_get_active_task (GDM_TASK_LIST (login_window->priv->conversation_list))) == 0) {
|
|
set_message (GDM_GREETER_LOGIN_WINDOW (login_window), text);
|
|
}
|
|
|
|
@@ -780,7 +780,7 @@ gdm_greeter_login_window_problem (GdmGreeterLoginWindow *login_window,
|
|
|
|
g_debug ("GdmGreeterLoginWindow: problem: %s", text);
|
|
|
|
- if (strcmp (service_name, gdm_task_list_get_active_task (login_window->priv->conversation_list)) == 0) {
|
|
+ if (strcmp (service_name, gdm_task_list_get_active_task (GDM_TASK_LIST (login_window->priv->conversation_list))) == 0) {
|
|
set_message (GDM_GREETER_LOGIN_WINDOW (login_window), text);
|
|
}
|
|
gdk_window_beep (GTK_WIDGET (login_window)->window);
|
|
@@ -866,7 +866,7 @@ gdm_greeter_login_window_info_query (GdmGreeterLoginWindow *login_window,
|
|
|
|
g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE);
|
|
|
|
- if (strcmp (service_name, gdm_task_list_get_active_task (login_window->priv->conversation_list)) != 0) {
|
|
+ if (strcmp (service_name, gdm_task_list_get_active_task (GDM_TASK_LIST (login_window->priv->conversation_list))) != 0) {
|
|
return TRUE;
|
|
}
|
|
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 97853e0ace98a3aec0eafbf875739dfc1aee1ace Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Sun, 1 Feb 2009 12:35:30 -0500
|
|
Subject: [PATCH 17/65] Add tasks from login window instead of task list
|
|
|
|
This is just a refactoring to move it closer to
|
|
being able to be loaded dynamically, instead of
|
|
hard coded.
|
|
---
|
|
gui/simple-greeter/gdm-greeter-login-window.c | 7 +++++++
|
|
gui/simple-greeter/gdm-task-list.c | 12 ++++--------
|
|
gui/simple-greeter/gdm-task-list.h | 3 +++
|
|
3 files changed, 14 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-greeter-login-window.c b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
index fe186e7..a0d76a9 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-login-window.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
@@ -1653,6 +1653,13 @@ load_theme (GdmGreeterLoginWindow *login_window)
|
|
login_window);
|
|
gtk_widget_show (login_window->priv->conversation_list);
|
|
|
|
+ gdm_task_list_add_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
+ "password-auth", "dialog-password");
|
|
+ gdm_task_list_add_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
+ "fingerprint-auth", "stock_allow-effects");
|
|
+ gdm_task_list_add_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
+ "smartcard-auth", "badge-small");
|
|
+
|
|
login_window->priv->auth_banner_label = glade_xml_get_widget (login_window->priv->xml, "auth-banner-label");
|
|
/*make_label_small_italic (login_window->priv->auth_banner_label);*/
|
|
|
|
diff --git a/gui/simple-greeter/gdm-task-list.c b/gui/simple-greeter/gdm-task-list.c
|
|
index d522858..ef72f0c 100644
|
|
--- a/gui/simple-greeter/gdm-task-list.c
|
|
+++ b/gui/simple-greeter/gdm-task-list.c
|
|
@@ -78,10 +78,10 @@ on_task_toggled (GdmTaskList *widget,
|
|
}
|
|
}
|
|
|
|
-static void
|
|
-add_task (GdmTaskList *task_list,
|
|
- const char *name,
|
|
- const char *icon_name)
|
|
+void
|
|
+gdm_task_list_add_task (GdmTaskList *task_list,
|
|
+ const char *name,
|
|
+ const char *icon_name)
|
|
{
|
|
GdmTask *task;
|
|
GtkWidget *image;
|
|
@@ -151,10 +151,6 @@ gdm_task_list_init (GdmTaskList *widget)
|
|
gtk_widget_show (widget->priv->box);
|
|
gtk_container_add (GTK_CONTAINER (widget),
|
|
widget->priv->box);
|
|
-
|
|
- add_task (widget, "password-auth", "dialog-password");
|
|
- add_task (widget, "fingerprint-auth", "stock_allow-effects");
|
|
- add_task (widget, "smartcard-auth", "badge-small");
|
|
}
|
|
|
|
static void
|
|
diff --git a/gui/simple-greeter/gdm-task-list.h b/gui/simple-greeter/gdm-task-list.h
|
|
index 90c31cf..ade21b6 100644
|
|
--- a/gui/simple-greeter/gdm-task-list.h
|
|
+++ b/gui/simple-greeter/gdm-task-list.h
|
|
@@ -56,6 +56,9 @@ GType gdm_task_list_get_type (void);
|
|
GtkWidget * gdm_task_list_new (void);
|
|
|
|
const char * gdm_task_list_get_active_task (GdmTaskList *widget);
|
|
+void gdm_task_list_add_task (GdmTaskList *widget,
|
|
+ const char *name,
|
|
+ const char *icon_name);
|
|
G_END_DECLS
|
|
|
|
#endif /* __GDM_TASK_LIST_H */
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From a6769c7e07b3f76a331c9b0c8b69d679806c39bb Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Sun, 1 Feb 2009 12:36:17 -0500
|
|
Subject: [PATCH 18/65] Clean up list of tasks on task list finalization
|
|
|
|
---
|
|
gui/simple-greeter/gdm-task-list.c | 5 +++--
|
|
1 files changed, 3 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-task-list.c b/gui/simple-greeter/gdm-task-list.c
|
|
index ef72f0c..e0fd3d4 100644
|
|
--- a/gui/simple-greeter/gdm-task-list.c
|
|
+++ b/gui/simple-greeter/gdm-task-list.c
|
|
@@ -86,7 +86,7 @@ gdm_task_list_add_task (GdmTaskList *task_list,
|
|
GdmTask *task;
|
|
GtkWidget *image;
|
|
|
|
- task = g_slice_new0 (GdmTask);
|
|
+ task = g_new0 (GdmTask, 1);
|
|
|
|
task->name = g_strdup (name);
|
|
if (task_list->priv->tasks == NULL) {
|
|
@@ -163,7 +163,8 @@ gdm_task_list_finalize (GObject *object)
|
|
|
|
widget = GDM_TASK_LIST (object);
|
|
|
|
- g_return_if_fail (widget->priv != NULL);
|
|
+ g_list_foreach (widget->priv->tasks, (GFunc) g_free, NULL);
|
|
+ g_list_free (widget->priv->tasks);
|
|
|
|
G_OBJECT_CLASS (gdm_task_list_parent_class)->finalize (object);
|
|
}
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 2f2785b5a68a97e7bc774569f5f39a565b23b115 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Wed, 4 Feb 2009 10:55:03 -0500
|
|
Subject: [PATCH 19/65] Rename session worker to the service it's managing
|
|
|
|
This way if a pam module gets hung up and causes
|
|
GDM to stall, there's a chance the reporter will
|
|
bypass GDM when filing the report.
|
|
---
|
|
daemon/gdm-session-direct.c | 7 ++++-
|
|
daemon/gdm-session-worker-job.c | 63 ++++++++++++++++++++++++++++++--------
|
|
daemon/gdm-session-worker-job.h | 3 +-
|
|
3 files changed, 57 insertions(+), 16 deletions(-)
|
|
|
|
diff --git a/daemon/gdm-session-direct.c b/daemon/gdm-session-direct.c
|
|
index 55ea4ee..d25b988 100644
|
|
--- a/daemon/gdm-session-direct.c
|
|
+++ b/daemon/gdm-session-direct.c
|
|
@@ -1741,6 +1741,7 @@ start_conversation (GdmSessionDirect *session,
|
|
const char *service_name)
|
|
{
|
|
GdmSessionConversation *conversation;
|
|
+ char *job_name;
|
|
|
|
conversation = g_new0 (GdmSessionConversation, 1);
|
|
conversation->session = session;
|
|
@@ -1765,12 +1766,16 @@ start_conversation (GdmSessionDirect *session,
|
|
G_CALLBACK (worker_died),
|
|
conversation);
|
|
|
|
- if (!gdm_session_worker_job_start (conversation->job)) {
|
|
+ job_name = g_strdup_printf ("pam: %s", service_name);
|
|
+ if (!gdm_session_worker_job_start (conversation->job,
|
|
+ job_name)) {
|
|
g_object_unref (conversation->job);
|
|
g_free (conversation->service_name);
|
|
g_free (conversation);
|
|
+ g_free (job_name);
|
|
return NULL;
|
|
}
|
|
+ g_free (job_name);
|
|
|
|
conversation->worker_pid = gdm_session_worker_job_get_pid (conversation->job);
|
|
|
|
diff --git a/daemon/gdm-session-worker-job.c b/daemon/gdm-session-worker-job.c
|
|
index 7328c0e..c079762 100644
|
|
--- a/daemon/gdm-session-worker-job.c
|
|
+++ b/daemon/gdm-session-worker-job.c
|
|
@@ -124,6 +124,37 @@ listify_hash (const char *key,
|
|
}
|
|
|
|
static GPtrArray *
|
|
+get_job_arguments (GdmSessionWorkerJob *job,
|
|
+ const char *name)
|
|
+{
|
|
+ GPtrArray *args;
|
|
+ GError *error;
|
|
+ char **argv;
|
|
+ int i;
|
|
+
|
|
+ args = NULL;
|
|
+ argv = NULL;
|
|
+ error = NULL;
|
|
+ if (! g_shell_parse_argv (job->priv->command, NULL, &argv, &error)) {
|
|
+ g_warning ("Could not parse command: %s", error->message);
|
|
+ g_error_free (error);
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ args = g_ptr_array_new ();
|
|
+ g_ptr_array_add (args, g_strdup (argv[0]));
|
|
+ g_ptr_array_add (args, g_strdup (name));
|
|
+ for (i = 1; argv[i] != NULL; i++) {
|
|
+ g_ptr_array_add (args, g_strdup (argv[i]));
|
|
+ }
|
|
+ g_strfreev (argv);
|
|
+
|
|
+ g_ptr_array_add (args, NULL);
|
|
+out:
|
|
+ return args;
|
|
+}
|
|
+
|
|
+static GPtrArray *
|
|
get_job_environment (GdmSessionWorkerJob *job)
|
|
{
|
|
GPtrArray *env;
|
|
@@ -145,31 +176,31 @@ get_job_environment (GdmSessionWorkerJob *job)
|
|
}
|
|
|
|
static gboolean
|
|
-gdm_session_worker_job_spawn (GdmSessionWorkerJob *session_worker_job)
|
|
+gdm_session_worker_job_spawn (GdmSessionWorkerJob *session_worker_job,
|
|
+ const char *name)
|
|
{
|
|
- gchar **argv;
|
|
GError *error;
|
|
gboolean ret;
|
|
+ GPtrArray *args;
|
|
GPtrArray *env;
|
|
|
|
ret = FALSE;
|
|
|
|
- g_debug ("GdmSessionWorkerJob: Running session_worker_job process: %s", session_worker_job->priv->command);
|
|
+ g_debug ("GdmSessionWorkerJob: Running session_worker_job process: %s %s",
|
|
+ name != NULL? name : "", session_worker_job->priv->command);
|
|
|
|
- argv = NULL;
|
|
- if (! g_shell_parse_argv (session_worker_job->priv->command, NULL, &argv, &error)) {
|
|
- g_warning ("Could not parse command: %s", error->message);
|
|
- g_error_free (error);
|
|
- goto out;
|
|
- }
|
|
+ args = get_job_arguments (session_worker_job, name);
|
|
|
|
+ if (args == NULL) {
|
|
+ return FALSE;
|
|
+ }
|
|
env = get_job_environment (session_worker_job);
|
|
|
|
error = NULL;
|
|
ret = g_spawn_async_with_pipes (NULL,
|
|
- argv,
|
|
+ (char **) args->pdata,
|
|
(char **)env->pdata,
|
|
- G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
|
|
+ G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_FILE_AND_ARGV_ZERO,
|
|
(GSpawnChildSetupFunc)session_worker_job_child_setup,
|
|
session_worker_job,
|
|
&session_worker_job->priv->pid,
|
|
@@ -178,6 +209,9 @@ gdm_session_worker_job_spawn (GdmSessionWorkerJob *session_worker_job)
|
|
NULL,
|
|
&error);
|
|
|
|
+ g_ptr_array_foreach (args, (GFunc)g_free, NULL);
|
|
+ g_ptr_array_free (args, TRUE);
|
|
+
|
|
g_ptr_array_foreach (env, (GFunc)g_free, NULL);
|
|
g_ptr_array_free (env, TRUE);
|
|
|
|
@@ -194,7 +228,6 @@ gdm_session_worker_job_spawn (GdmSessionWorkerJob *session_worker_job)
|
|
(GChildWatchFunc)session_worker_job_child_watch,
|
|
session_worker_job);
|
|
|
|
- g_strfreev (argv);
|
|
out:
|
|
|
|
return ret;
|
|
@@ -207,13 +240,14 @@ gdm_session_worker_job_spawn (GdmSessionWorkerJob *session_worker_job)
|
|
* Starts a local X session_worker_job. Handles retries and fatal errors properly.
|
|
*/
|
|
gboolean
|
|
-gdm_session_worker_job_start (GdmSessionWorkerJob *session_worker_job)
|
|
+gdm_session_worker_job_start (GdmSessionWorkerJob *session_worker_job,
|
|
+ const char *name)
|
|
{
|
|
gboolean res;
|
|
|
|
g_debug ("GdmSessionWorkerJob: Starting worker...");
|
|
|
|
- res = gdm_session_worker_job_spawn (session_worker_job);
|
|
+ res = gdm_session_worker_job_spawn (session_worker_job, name);
|
|
|
|
if (res) {
|
|
|
|
@@ -261,6 +295,7 @@ gdm_session_worker_job_stop (GdmSessionWorkerJob *session_worker_job)
|
|
g_debug ("GdmSessionWorkerJob: Stopping job pid:%d", session_worker_job->priv->pid);
|
|
|
|
res = gdm_signal_pid (session_worker_job->priv->pid, SIGTERM);
|
|
+
|
|
if (res < 0) {
|
|
g_warning ("Unable to kill session worker process");
|
|
} else {
|
|
diff --git a/daemon/gdm-session-worker-job.h b/daemon/gdm-session-worker-job.h
|
|
index 9cb08ce..5b3be46 100644
|
|
--- a/daemon/gdm-session-worker-job.h
|
|
+++ b/daemon/gdm-session-worker-job.h
|
|
@@ -58,7 +58,8 @@ GType gdm_session_worker_job_get_type (void);
|
|
GdmSessionWorkerJob * gdm_session_worker_job_new (void);
|
|
void gdm_session_worker_job_set_server_address (GdmSessionWorkerJob *session_worker_job,
|
|
const char *server_address);
|
|
-gboolean gdm_session_worker_job_start (GdmSessionWorkerJob *session_worker_job);
|
|
+gboolean gdm_session_worker_job_start (GdmSessionWorkerJob *session_worker_job,
|
|
+ const char *name);
|
|
gboolean gdm_session_worker_job_stop (GdmSessionWorkerJob *session_worker_job);
|
|
|
|
GPid gdm_session_worker_job_get_pid (GdmSessionWorkerJob *session_worker_job);
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 34a4f90e837bdbb996d3b1dc8fd92753d1dd10b6 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Thu, 5 Feb 2009 15:20:25 -0500
|
|
Subject: [PATCH 20/65] Queue a greeter reset when the user clicks cancel
|
|
|
|
---
|
|
daemon/gdm-simple-slave.c | 37 +++++++++++++++++++++++++++++++++++++
|
|
1 files changed, 37 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c
|
|
index 3a24d8d..a6ae0ae 100644
|
|
--- a/daemon/gdm-simple-slave.c
|
|
+++ b/daemon/gdm-simple-slave.c
|
|
@@ -760,6 +760,9 @@ on_greeter_start_conversation (GdmGreeterServer *greeter_server,
|
|
GdmSimpleSlave *slave)
|
|
{
|
|
g_debug ("GdmSimpleSlave: starting conversation with '%s' pam service'", service_name);
|
|
+ if (slave->priv->greeter_reset_id > 0) {
|
|
+ return;
|
|
+ }
|
|
gdm_session_start_conversation (GDM_SESSION (slave->priv->session),
|
|
service_name);
|
|
}
|
|
@@ -770,6 +773,9 @@ on_greeter_begin_verification (GdmGreeterServer *greeter_server,
|
|
GdmSimpleSlave *slave)
|
|
{
|
|
g_debug ("GdmSimpleSlave: begin verification");
|
|
+ if (slave->priv->greeter_reset_id > 0) {
|
|
+ return;
|
|
+ }
|
|
gdm_session_setup (GDM_SESSION (slave->priv->session),
|
|
service_name);
|
|
}
|
|
@@ -780,6 +786,9 @@ on_greeter_begin_auto_login (GdmGreeterServer *greeter_server,
|
|
GdmSimpleSlave *slave)
|
|
{
|
|
g_debug ("GdmSimpleSlave: begin auto login for user '%s'", username);
|
|
+ if (slave->priv->greeter_reset_id > 0) {
|
|
+ return;
|
|
+ }
|
|
gdm_session_setup_for_user (GDM_SESSION (slave->priv->session),
|
|
"gdm-autologin",
|
|
username);
|
|
@@ -792,6 +801,9 @@ on_greeter_begin_verification_for_user (GdmGreeterServer *greeter_server,
|
|
GdmSimpleSlave *slave)
|
|
{
|
|
g_debug ("GdmSimpleSlave: begin verification");
|
|
+ if (slave->priv->greeter_reset_id > 0) {
|
|
+ return;
|
|
+ }
|
|
gdm_session_setup_for_user (GDM_SESSION (slave->priv->session),
|
|
service_name,
|
|
username);
|
|
@@ -803,6 +815,9 @@ on_greeter_answer (GdmGreeterServer *greeter_server,
|
|
const char *text,
|
|
GdmSimpleSlave *slave)
|
|
{
|
|
+ if (slave->priv->greeter_reset_id > 0) {
|
|
+ return;
|
|
+ }
|
|
gdm_session_answer_query (GDM_SESSION (slave->priv->session), service_name, text);
|
|
}
|
|
|
|
@@ -811,6 +826,9 @@ on_greeter_session_selected (GdmGreeterServer *greeter_server,
|
|
const char *text,
|
|
GdmSimpleSlave *slave)
|
|
{
|
|
+ if (slave->priv->greeter_reset_id > 0) {
|
|
+ return;
|
|
+ }
|
|
gdm_session_select_session (GDM_SESSION (slave->priv->session), text);
|
|
}
|
|
|
|
@@ -819,6 +837,9 @@ on_greeter_language_selected (GdmGreeterServer *greeter_server,
|
|
const char *text,
|
|
GdmSimpleSlave *slave)
|
|
{
|
|
+ if (slave->priv->greeter_reset_id > 0) {
|
|
+ return;
|
|
+ }
|
|
gdm_session_select_language (GDM_SESSION (slave->priv->session), text);
|
|
}
|
|
|
|
@@ -827,6 +848,9 @@ on_greeter_layout_selected (GdmGreeterServer *greeter_server,
|
|
const char *text,
|
|
GdmSimpleSlave *slave)
|
|
{
|
|
+ if (slave->priv->greeter_reset_id > 0) {
|
|
+ return;
|
|
+ }
|
|
gdm_session_select_layout (GDM_SESSION (slave->priv->session), text);
|
|
}
|
|
|
|
@@ -843,7 +867,11 @@ on_greeter_cancel (GdmGreeterServer *greeter_server,
|
|
GdmSimpleSlave *slave)
|
|
{
|
|
g_debug ("GdmSimpleSlave: Greeter cancelled");
|
|
+ if (slave->priv->greeter_reset_id > 0) {
|
|
+ return;
|
|
+ }
|
|
reset_session (slave);
|
|
+ queue_greeter_reset (slave);
|
|
}
|
|
|
|
static void
|
|
@@ -853,6 +881,9 @@ on_greeter_connected (GdmGreeterServer *greeter_server,
|
|
gboolean display_is_local;
|
|
|
|
g_debug ("GdmSimpleSlave: Greeter connected");
|
|
+ if (slave->priv->greeter_reset_id > 0) {
|
|
+ return;
|
|
+ }
|
|
|
|
g_object_get (slave,
|
|
"display-is-local", &display_is_local,
|
|
@@ -870,6 +901,9 @@ on_start_session_when_ready (GdmGreeterServer *session,
|
|
GdmSimpleSlave *slave)
|
|
{
|
|
g_debug ("GdmSimpleSlave: Will start session when ready");
|
|
+ if (slave->priv->greeter_reset_id > 0) {
|
|
+ return;
|
|
+ }
|
|
slave->priv->start_session_when_ready = TRUE;
|
|
|
|
if (slave->priv->waiting_to_start_session) {
|
|
@@ -883,6 +917,9 @@ on_start_session_later (GdmGreeterServer *session,
|
|
GdmSimpleSlave *slave)
|
|
{
|
|
g_debug ("GdmSimpleSlave: Will start session when ready and told");
|
|
+ if (slave->priv->greeter_reset_id > 0) {
|
|
+ return;
|
|
+ }
|
|
slave->priv->start_session_when_ready = FALSE;
|
|
}
|
|
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 48910d04a95487b38dc17c668cba5bfccba8fd10 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Thu, 5 Feb 2009 16:57:39 -0500
|
|
Subject: [PATCH 21/65] Don't bother cancelling worker through D-Bus when stopping
|
|
|
|
It's just going to get sent SIGTERM anyway.
|
|
---
|
|
daemon/gdm-session-direct.c | 19 +++++--------------
|
|
1 files changed, 5 insertions(+), 14 deletions(-)
|
|
|
|
diff --git a/daemon/gdm-session-direct.c b/daemon/gdm-session-direct.c
|
|
index d25b988..68e4084 100644
|
|
--- a/daemon/gdm-session-direct.c
|
|
+++ b/daemon/gdm-session-direct.c
|
|
@@ -1802,8 +1802,6 @@ stop_conversation (GdmSessionConversation *conversation)
|
|
G_CALLBACK (worker_died),
|
|
conversation);
|
|
|
|
- cancel_pending_query (conversation);
|
|
-
|
|
if (conversation->worker_connection != NULL) {
|
|
dbus_connection_remove_filter (conversation->worker_connection, on_message, session);
|
|
|
|
@@ -2214,6 +2212,10 @@ stop_all_conversations (GdmSessionDirect *session)
|
|
GHashTableIter iter;
|
|
gpointer key, value;
|
|
|
|
+ if (session->priv->conversations == NULL) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
g_hash_table_iter_init (&iter, session->priv->conversations);
|
|
while (g_hash_table_iter_next (&iter, &key, &value)) {
|
|
GdmSessionConversation *conversation;
|
|
@@ -2295,20 +2297,9 @@ gdm_session_direct_answer_query (GdmSession *session,
|
|
static void
|
|
gdm_session_direct_cancel (GdmSession *session)
|
|
{
|
|
- GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
- GHashTableIter iter;
|
|
- gpointer key, value;
|
|
-
|
|
g_return_if_fail (session != NULL);
|
|
|
|
- g_hash_table_iter_init (&iter, impl->priv->conversations);
|
|
- while (g_hash_table_iter_next (&iter, &key, &value)) {
|
|
- GdmSessionConversation *conversation;
|
|
-
|
|
- conversation = (GdmSessionConversation *) value;
|
|
-
|
|
- cancel_pending_query (conversation);
|
|
- }
|
|
+ stop_all_conversations (GDM_SESSION_DIRECT (session));
|
|
}
|
|
|
|
char *
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 69d70473c757ffa19e3827103e78c13b33ba14de Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Thu, 5 Feb 2009 17:16:55 -0500
|
|
Subject: [PATCH 22/65] Fix mistake in user authorized client signal marshaler
|
|
|
|
---
|
|
gui/simple-greeter/gdm-greeter-client.c | 5 +++--
|
|
1 files changed, 3 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-greeter-client.c b/gui/simple-greeter/gdm-greeter-client.c
|
|
index ee7019d..0bd27a9 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-client.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-client.c
|
|
@@ -1069,8 +1069,9 @@ gdm_greeter_client_class_init (GdmGreeterClientClass *klass)
|
|
G_STRUCT_OFFSET (GdmGreeterClientClass, user_authorized),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__VOID,
|
|
- G_TYPE_NONE, 0);
|
|
+ g_cclosure_marshal_VOID__STRING,
|
|
+ G_TYPE_NONE,
|
|
+ 1, G_TYPE_STRING);
|
|
}
|
|
|
|
static void
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 6f6a6f4ab7b28470417e52f33aa3baccf7e6dd79 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Fri, 6 Feb 2009 15:35:00 -0500
|
|
Subject: [PATCH 23/65] Drop "stopped" signal from worker-job class
|
|
|
|
It was unused, dead code.
|
|
---
|
|
daemon/gdm-session-direct.c | 14 --------------
|
|
daemon/gdm-session-worker-job.c | 11 -----------
|
|
daemon/gdm-session-worker-job.h | 1 -
|
|
3 files changed, 0 insertions(+), 26 deletions(-)
|
|
|
|
diff --git a/daemon/gdm-session-direct.c b/daemon/gdm-session-direct.c
|
|
index 68e4084..cbcc8d1 100644
|
|
--- a/daemon/gdm-session-direct.c
|
|
+++ b/daemon/gdm-session-direct.c
|
|
@@ -1687,13 +1687,6 @@ gdm_session_direct_init (GdmSessionDirect *session)
|
|
}
|
|
|
|
static void
|
|
-worker_stopped (GdmSessionWorkerJob *job,
|
|
- GdmSessionConversation *conversation)
|
|
-{
|
|
- g_debug ("GdmSessionDirect: Worker job stopped");
|
|
-}
|
|
-
|
|
-static void
|
|
worker_started (GdmSessionWorkerJob *job,
|
|
GdmSessionConversation *conversation)
|
|
{
|
|
@@ -1750,10 +1743,6 @@ start_conversation (GdmSessionDirect *session,
|
|
conversation->job = gdm_session_worker_job_new ();
|
|
gdm_session_worker_job_set_server_address (conversation->job, session->priv->server_address);
|
|
g_signal_connect (conversation->job,
|
|
- "stopped",
|
|
- G_CALLBACK (worker_stopped),
|
|
- conversation);
|
|
- g_signal_connect (conversation->job,
|
|
"started",
|
|
G_CALLBACK (worker_started),
|
|
conversation);
|
|
@@ -1790,9 +1779,6 @@ stop_conversation (GdmSessionConversation *conversation)
|
|
session = conversation->session;
|
|
|
|
g_signal_handlers_disconnect_by_func (conversation->job,
|
|
- G_CALLBACK (worker_stopped),
|
|
- conversation);
|
|
- g_signal_handlers_disconnect_by_func (conversation->job,
|
|
G_CALLBACK (worker_started),
|
|
conversation);
|
|
g_signal_handlers_disconnect_by_func (conversation->job,
|
|
diff --git a/daemon/gdm-session-worker-job.c b/daemon/gdm-session-worker-job.c
|
|
index c079762..ac2aa02 100644
|
|
--- a/daemon/gdm-session-worker-job.c
|
|
+++ b/daemon/gdm-session-worker-job.c
|
|
@@ -68,7 +68,6 @@ enum {
|
|
|
|
enum {
|
|
STARTED,
|
|
- STOPPED,
|
|
EXITED,
|
|
DIED,
|
|
LAST_SIGNAL
|
|
@@ -405,16 +404,6 @@ gdm_session_worker_job_class_init (GdmSessionWorkerJobClass *klass)
|
|
g_cclosure_marshal_VOID__VOID,
|
|
G_TYPE_NONE,
|
|
0);
|
|
- signals [STOPPED] =
|
|
- g_signal_new ("stopped",
|
|
- G_OBJECT_CLASS_TYPE (object_class),
|
|
- G_SIGNAL_RUN_FIRST,
|
|
- G_STRUCT_OFFSET (GdmSessionWorkerJobClass, stopped),
|
|
- NULL,
|
|
- NULL,
|
|
- g_cclosure_marshal_VOID__VOID,
|
|
- G_TYPE_NONE,
|
|
- 0);
|
|
signals [EXITED] =
|
|
g_signal_new ("exited",
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
diff --git a/daemon/gdm-session-worker-job.h b/daemon/gdm-session-worker-job.h
|
|
index 5b3be46..4833f23 100644
|
|
--- a/daemon/gdm-session-worker-job.h
|
|
+++ b/daemon/gdm-session-worker-job.h
|
|
@@ -46,7 +46,6 @@ typedef struct
|
|
GObjectClass parent_class;
|
|
|
|
void (* started) (GdmSessionWorkerJob *session_worker_job);
|
|
- void (* stopped) (GdmSessionWorkerJob *session_worker_job);
|
|
void (* exited) (GdmSessionWorkerJob *session_worker_job,
|
|
int exit_code);
|
|
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From aa5bd199dbb1274ef7acb155a4e8751ee4c68970 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Fri, 6 Feb 2009 16:23:48 -0500
|
|
Subject: [PATCH 24/65] Add a plugin based extension system to greeter
|
|
|
|
This allows plugins to drive which PAM conversations
|
|
get run. This commit just adds one plugin "password"
|
|
which does the one PAM conversation we've traditionally
|
|
run.
|
|
---
|
|
configure.ac | 36 ++
|
|
daemon/gdm-session-direct.c | 18 +-
|
|
gui/simple-greeter/Makefile.am | 15 +
|
|
gui/simple-greeter/gdm-greeter-login-window.c | 652 ++++++++++++++++----
|
|
gui/simple-greeter/gdm-greeter-login-window.glade | 144 +----
|
|
gui/simple-greeter/gdm-greeter-login-window.h | 19 +-
|
|
gui/simple-greeter/gdm-greeter-plugin.c | 251 ++++++++
|
|
gui/simple-greeter/gdm-greeter-plugin.h | 61 ++
|
|
gui/simple-greeter/gdm-greeter-session.c | 76 +++-
|
|
gui/simple-greeter/gdm-plugin-manager.c | 478 ++++++++++++++
|
|
gui/simple-greeter/gdm-plugin-manager.h | 66 ++
|
|
gui/simple-greeter/gdm-task-list.c | 166 ++++--
|
|
gui/simple-greeter/gdm-task-list.h | 34 +-
|
|
gui/simple-greeter/libgdmsimplegreeter/Makefile.am | 46 ++
|
|
.../libgdmsimplegreeter/gdm-conversation.c | 147 +++++
|
|
.../libgdmsimplegreeter/gdm-conversation.h | 87 +++
|
|
.../libgdmsimplegreeter/gdm-greeter-extension.c | 93 +++
|
|
.../libgdmsimplegreeter/gdm-greeter-extension.h | 55 ++
|
|
gui/simple-greeter/libgdmsimplegreeter/gdm-task.c | 117 ++++
|
|
gui/simple-greeter/libgdmsimplegreeter/gdm-task.h | 62 ++
|
|
.../libgdmsimplegreeter/gdmsimplegreeter.pc.in | 11 +
|
|
gui/simple-greeter/plugins/Makefile.am | 1 +
|
|
gui/simple-greeter/plugins/password/Makefile.am | 40 ++
|
|
.../plugins/password/gdm-password-extension.c | 316 ++++++++++
|
|
.../plugins/password/gdm-password-extension.h | 56 ++
|
|
gui/simple-greeter/plugins/password/page.ui | 56 ++
|
|
gui/simple-greeter/plugins/password/plugin.c | 40 ++
|
|
27 files changed, 2839 insertions(+), 304 deletions(-)
|
|
create mode 100644 gui/simple-greeter/gdm-greeter-plugin.c
|
|
create mode 100644 gui/simple-greeter/gdm-greeter-plugin.h
|
|
create mode 100644 gui/simple-greeter/gdm-plugin-manager.c
|
|
create mode 100644 gui/simple-greeter/gdm-plugin-manager.h
|
|
create mode 100644 gui/simple-greeter/libgdmsimplegreeter/Makefile.am
|
|
create mode 100644 gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.c
|
|
create mode 100644 gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.h
|
|
create mode 100644 gui/simple-greeter/libgdmsimplegreeter/gdm-greeter-extension.c
|
|
create mode 100644 gui/simple-greeter/libgdmsimplegreeter/gdm-greeter-extension.h
|
|
create mode 100644 gui/simple-greeter/libgdmsimplegreeter/gdm-task.c
|
|
create mode 100644 gui/simple-greeter/libgdmsimplegreeter/gdm-task.h
|
|
create mode 100644 gui/simple-greeter/libgdmsimplegreeter/gdmsimplegreeter.pc.in
|
|
create mode 100644 gui/simple-greeter/plugins/Makefile.am
|
|
create mode 100644 gui/simple-greeter/plugins/password/Makefile.am
|
|
create mode 100644 gui/simple-greeter/plugins/password/gdm-password-extension.c
|
|
create mode 100644 gui/simple-greeter/plugins/password/gdm-password-extension.h
|
|
create mode 100644 gui/simple-greeter/plugins/password/page.ui
|
|
create mode 100644 gui/simple-greeter/plugins/password/plugin.c
|
|
|
|
diff --git a/configure.ac b/configure.ac
|
|
index 2674271..cc2576f 100644
|
|
--- a/configure.ac
|
|
+++ b/configure.ac
|
|
@@ -18,6 +18,22 @@ AC_PROG_CXX
|
|
AM_PROG_CC_C_O
|
|
AC_PROG_LIBTOOL()
|
|
|
|
+## increment if the plugin interface has additions, changes, removals.
|
|
+LT_CURRENT=1
|
|
+
|
|
+## increment any time the source changes; set to
|
|
+## 0 if you increment CURRENT
|
|
+LT_REVISION=0
|
|
+
|
|
+## increment if any interfaces have been added; set to 0
|
|
+## if any interfaces have been changed or removed. removal has
|
|
+## precedence over adding, so set to 0 if both happened.
|
|
+LT_AGE=0
|
|
+
|
|
+AC_SUBST(LT_CURRENT)
|
|
+AC_SUBST(LT_REVISION)
|
|
+AC_SUBST(LT_AGE)
|
|
+
|
|
AC_HEADER_STDC
|
|
|
|
AC_SUBST(VERSION)
|
|
@@ -1274,6 +1290,22 @@ fi
|
|
AC_SUBST(GDM_XAUTH_DIR)
|
|
|
|
dnl ---------------------------------------------------------------------------
|
|
+dnl - Directory for simple greeter plugins
|
|
+dnl ---------------------------------------------------------------------------
|
|
+
|
|
+AC_ARG_WITH(simple-greeter-plugins-dir,
|
|
+ AS_HELP_STRING([--with-simple-greeter-plugins-dir=<dir>],
|
|
+ [simple greeter plugins directory]))
|
|
+
|
|
+if ! test -z "$with_simple_greeter_plugins_dir"; then
|
|
+ GDM_SIMPLE_GREETER_PLUGINS_DIR=$with_simple_greeter_plugins_dir
|
|
+else
|
|
+ GDM_SIMPLE_GREETER_PLUGINS_DIR=${libdir}/gdm/simple-greeter/plugins
|
|
+fi
|
|
+
|
|
+AC_SUBST(GDM_SIMPLE_GREETER_PLUGINS_DIR)
|
|
+
|
|
+dnl ---------------------------------------------------------------------------
|
|
dnl - Finish
|
|
dnl ---------------------------------------------------------------------------
|
|
|
|
@@ -1402,6 +1434,10 @@ docs/Makefile
|
|
gui/Makefile
|
|
gui/simple-greeter/Makefile
|
|
gui/simple-greeter/libnotificationarea/Makefile
|
|
+gui/simple-greeter/libgdmsimplegreeter/Makefile
|
|
+gui/simple-greeter/libgdmsimplegreeter/gdmsimplegreeter.pc
|
|
+gui/simple-greeter/plugins/Makefile
|
|
+gui/simple-greeter/plugins/password/Makefile
|
|
gui/simple-chooser/Makefile
|
|
gui/user-switch-applet/Makefile
|
|
utils/Makefile
|
|
diff --git a/daemon/gdm-session-direct.c b/daemon/gdm-session-direct.c
|
|
index cbcc8d1..099f884 100644
|
|
--- a/daemon/gdm-session-direct.c
|
|
+++ b/daemon/gdm-session-direct.c
|
|
@@ -1650,6 +1650,17 @@ setup_server (GdmSessionDirect *session)
|
|
}
|
|
|
|
static void
|
|
+free_conversation (GdmSessionConversation *conversation)
|
|
+{
|
|
+ if (conversation->job != NULL) {
|
|
+ g_warning ("Freeing conversation with active job");
|
|
+ }
|
|
+
|
|
+ g_free (conversation->service_name);
|
|
+ g_free (conversation);
|
|
+}
|
|
+
|
|
+static void
|
|
gdm_session_direct_init (GdmSessionDirect *session)
|
|
{
|
|
session->priv = G_TYPE_INSTANCE_GET_PRIVATE (session,
|
|
@@ -1676,7 +1687,8 @@ gdm_session_direct_init (GdmSessionDirect *session)
|
|
session->priv->conversations = g_hash_table_new_full (g_str_hash,
|
|
g_str_equal,
|
|
(GDestroyNotify) g_free,
|
|
- NULL);
|
|
+ (GDestroyNotify)
|
|
+ free_conversation);
|
|
session->priv->environment = g_hash_table_new_full (g_str_hash,
|
|
g_str_equal,
|
|
(GDestroyNotify) g_free,
|
|
@@ -1796,11 +1808,9 @@ stop_conversation (GdmSessionConversation *conversation)
|
|
}
|
|
|
|
gdm_session_worker_job_stop (conversation->job);
|
|
- g_hash_table_remove (session->priv->conversations, conversation);
|
|
|
|
g_object_unref (conversation->job);
|
|
- g_free (conversation->service_name);
|
|
- g_free (conversation);
|
|
+ conversation->job = NULL;
|
|
}
|
|
|
|
static void
|
|
diff --git a/gui/simple-greeter/Makefile.am b/gui/simple-greeter/Makefile.am
|
|
index e2d3996..a9e4d65 100644
|
|
--- a/gui/simple-greeter/Makefile.am
|
|
+++ b/gui/simple-greeter/Makefile.am
|
|
@@ -2,11 +2,14 @@ NULL =
|
|
|
|
SUBDIRS = \
|
|
libnotificationarea \
|
|
+ libgdmsimplegreeter \
|
|
+ plugins \
|
|
$(NULL)
|
|
|
|
AM_CPPFLAGS = \
|
|
-I$(top_srcdir)/common \
|
|
-I$(top_srcdir)/gui/simple-greeter/libnotificationarea \
|
|
+ -I$(top_srcdir)/gui/simple-greeter/libgdmsimplegreeter \
|
|
-DDMCONFDIR=\""$(dmconfdir)"\" \
|
|
-DGDMCONFDIR=\"$(gdmconfdir)\" \
|
|
-DDATADIR=\""$(datadir)"\" \
|
|
@@ -17,6 +20,7 @@ AM_CPPFLAGS = \
|
|
-DLIBEXECDIR=\""$(libexecdir)"\" \
|
|
-DSBINDIR=\""$(sbindir)"\" \
|
|
-DAT_SPI_REGISTRYD_DIR="\"$(AT_SPI_REGISTRYD_DIR)\"" \
|
|
+ -DGDM_SIMPLE_GREETER_PLUGINS_DIR="\"$(GDM_SIMPLE_GREETER_PLUGINS_DIR)\""\
|
|
$(DISABLE_DEPRECATED_CFLAGS) \
|
|
$(GTK_CFLAGS) \
|
|
$(SIMPLE_GREETER_CFLAGS) \
|
|
@@ -85,10 +89,15 @@ test_greeter_login_window_SOURCES = \
|
|
gdm-user-chooser-dialog.c \
|
|
gdm-task-list.h \
|
|
gdm-task-list.c \
|
|
+ gdm-plugin-manager.h \
|
|
+ gdm-plugin-manager.c \
|
|
+ gdm-greeter-plugin.h \
|
|
+ gdm-greeter-plugin.c \
|
|
$(NULL)
|
|
|
|
test_greeter_login_window_LDADD = \
|
|
$(top_builddir)/common/libgdmcommon.la \
|
|
+ $(top_builddir)/gui/simple-greeter/libgdmsimplegreeter/libgdmsimplegreeter.la \
|
|
libgdmuser.la \
|
|
$(COMMON_LIBS) \
|
|
$(SIMPLE_GREETER_LIBS) \
|
|
@@ -140,6 +149,7 @@ test_greeter_panel_SOURCES = \
|
|
test_greeter_panel_LDADD = \
|
|
$(top_builddir)/common/libgdmcommon.la \
|
|
$(top_builddir)/gui/simple-greeter/libnotificationarea/libnotificationarea.la \
|
|
+ $(top_builddir)/gui/simple-greeter/libgdmsimplegreeter/libgdmsimplegreeter.la \
|
|
$(SIMPLE_GREETER_LIBS) \
|
|
$(GTK_LIBS) \
|
|
$(GCONF_LIBS) \
|
|
@@ -312,10 +322,14 @@ gdm_simple_greeter_SOURCES = \
|
|
gdm-language-chooser-dialog.c \
|
|
gdm-language-option-widget.h \
|
|
gdm-language-option-widget.c \
|
|
+ gdm-plugin-manager.h \
|
|
+ gdm-plugin-manager.c \
|
|
gdm-sessions.h \
|
|
gdm-sessions.c \
|
|
gdm-session-option-widget.h \
|
|
gdm-session-option-widget.c \
|
|
+ gdm-greeter-plugin.h \
|
|
+ gdm-greeter-plugin.c \
|
|
gdm-user-chooser-widget.h \
|
|
gdm-user-chooser-widget.c \
|
|
gdm-task-list.h \
|
|
@@ -326,6 +340,7 @@ gdm_simple_greeter_LDADD = \
|
|
$(top_builddir)/common/libgdmcommon.la \
|
|
libgdmuser.la \
|
|
$(top_builddir)/gui/simple-greeter/libnotificationarea/libnotificationarea.la \
|
|
+ $(top_builddir)/gui/simple-greeter/libgdmsimplegreeter/libgdmsimplegreeter.la \
|
|
$(COMMON_LIBS) \
|
|
$(EXTRA_GREETER_LIBS) \
|
|
$(SIMPLE_GREETER_LIBS) \
|
|
diff --git a/gui/simple-greeter/gdm-greeter-login-window.c b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
index a0d76a9..ea96abc 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-login-window.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
@@ -1,7 +1,7 @@
|
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
|
|
*
|
|
* Copyright (C) 2007 William Jon McCann <mccann@jhu.edu>
|
|
- * Copyright (C) 2008 Red Hat, Inc.
|
|
+ * Copyright (C) 2008, 2009 Red Hat, Inc.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
@@ -17,6 +17,9 @@
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
+ * Written by: William Jon McCann <mccann@jhu.edu>
|
|
+ * Ray Strode <rstrode@redhat.com>
|
|
+ *
|
|
*/
|
|
|
|
#include "config.h"
|
|
@@ -117,6 +120,7 @@ struct GdmGreeterLoginWindowPrivate
|
|
GtkWidget *user_chooser;
|
|
GtkWidget *conversation_list;
|
|
GtkWidget *auth_banner_label;
|
|
+ GtkWidget *auth_page_box;
|
|
guint display_is_local : 1;
|
|
guint is_interactive : 1;
|
|
GConfClient *client;
|
|
@@ -166,6 +170,9 @@ static void restart_timed_login_timeout (GdmGreeterLoginWindow *login_window
|
|
static void on_user_unchosen (GdmUserChooserWidget *user_chooser,
|
|
GdmGreeterLoginWindow *login_window);
|
|
|
|
+static void gdm_greeter_login_window_start_session_when_ready (GdmGreeterLoginWindow *login_window,
|
|
+ const char *service_name);
|
|
+
|
|
G_DEFINE_TYPE (GdmGreeterLoginWindow, gdm_greeter_login_window, GTK_TYPE_WINDOW)
|
|
|
|
static void
|
|
@@ -190,9 +197,6 @@ set_sensitive (GdmGreeterLoginWindow *login_window,
|
|
{
|
|
GtkWidget *box;
|
|
|
|
- box = glade_xml_get_widget (login_window->priv->xml, "auth-input-box");
|
|
- gtk_widget_set_sensitive (box, sensitive);
|
|
-
|
|
box = glade_xml_get_widget (login_window->priv->xml, "buttonbox");
|
|
gtk_widget_set_sensitive (box, sensitive);
|
|
|
|
@@ -202,27 +206,43 @@ set_sensitive (GdmGreeterLoginWindow *login_window,
|
|
static void
|
|
set_focus (GdmGreeterLoginWindow *login_window)
|
|
{
|
|
- GtkWidget *entry;
|
|
-
|
|
- entry = glade_xml_get_widget (GDM_GREETER_LOGIN_WINDOW (login_window)->priv->xml, "auth-prompt-entry");
|
|
+ GdmTask *task;
|
|
|
|
gdk_window_focus (GTK_WIDGET (login_window)->window, GDK_CURRENT_TIME);
|
|
|
|
- if (GTK_WIDGET_REALIZED (entry) && ! GTK_WIDGET_HAS_FOCUS (entry)) {
|
|
- gtk_widget_grab_focus (entry);
|
|
+ task = gdm_task_list_get_active_task (GDM_TASK_LIST (login_window->priv->conversation_list));
|
|
+
|
|
+ if (gdm_conversation_focus (GDM_CONVERSATION (task))) {
|
|
+ char *name;
|
|
+ name = gdm_task_get_name (task);
|
|
+ g_debug ("GdmGreeterLoginWindow: focusing task %s", name);
|
|
+ g_free (name);
|
|
} else if (GTK_WIDGET_REALIZED (login_window->priv->user_chooser) && ! GTK_WIDGET_HAS_FOCUS (login_window->priv->user_chooser)) {
|
|
gtk_widget_grab_focus (login_window->priv->user_chooser);
|
|
}
|
|
+ g_object_unref (task);
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+set_task_conversation_message (GdmTaskList *task_list,
|
|
+ GdmTask *task,
|
|
+ const char *message)
|
|
+{
|
|
+
|
|
+ gdm_conversation_set_message (GDM_CONVERSATION (task), message);
|
|
+ return FALSE;
|
|
}
|
|
|
|
static void
|
|
set_message (GdmGreeterLoginWindow *login_window,
|
|
const char *text)
|
|
{
|
|
- GtkWidget *label;
|
|
+ g_return_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window));
|
|
|
|
- label = glade_xml_get_widget (login_window->priv->xml, "auth-message-label");
|
|
- gtk_label_set_text (GTK_LABEL (label), text);
|
|
+ gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
+ (GdmTaskListForeachFunc)
|
|
+ set_task_conversation_message,
|
|
+ (gpointer) text);
|
|
}
|
|
|
|
static void
|
|
@@ -388,30 +408,76 @@ get_show_restart_buttons (GdmGreeterLoginWindow *login_window)
|
|
}
|
|
|
|
static void
|
|
-on_login_button_clicked_answer_query (GtkButton *button,
|
|
- GdmGreeterLoginWindow *login_window)
|
|
+on_login_button_clicked_timed_login (GtkButton *button,
|
|
+ GdmGreeterLoginWindow *login_window)
|
|
{
|
|
- GtkWidget *entry;
|
|
- const char *text;
|
|
-
|
|
set_busy (login_window);
|
|
set_sensitive (login_window, FALSE);
|
|
|
|
- entry = glade_xml_get_widget (login_window->priv->xml, "auth-prompt-entry");
|
|
- text = gtk_entry_get_text (GTK_ENTRY (entry));
|
|
-
|
|
_gdm_greeter_login_window_set_interactive (login_window, TRUE);
|
|
- g_signal_emit (login_window, signals[QUERY_ANSWER], 0, "gdm", text);
|
|
}
|
|
|
|
static void
|
|
-on_login_button_clicked_timed_login (GtkButton *button,
|
|
- GdmGreeterLoginWindow *login_window)
|
|
+hide_task_actions (GdmTask *task)
|
|
{
|
|
- set_busy (login_window);
|
|
- set_sensitive (login_window, FALSE);
|
|
+ GtkActionGroup *actions;
|
|
|
|
- _gdm_greeter_login_window_set_interactive (login_window, TRUE);
|
|
+ actions = gdm_conversation_get_actions (GDM_CONVERSATION (task));
|
|
+
|
|
+ if (actions != NULL) {
|
|
+ gtk_action_group_set_visible (actions, FALSE);
|
|
+ gtk_action_group_set_sensitive (actions, FALSE);
|
|
+ g_object_unref (actions);
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
+grab_default_button_for_task (GdmTask *task)
|
|
+{
|
|
+ GtkActionGroup *actions;
|
|
+ GtkAction *action;
|
|
+ GSList *proxies, *node;
|
|
+
|
|
+ actions = gdm_conversation_get_actions (GDM_CONVERSATION (task));
|
|
+
|
|
+ if (actions == NULL) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ action = gtk_action_group_get_action (actions, GDM_CONVERSATION_DEFAULT_ACTION);
|
|
+ g_object_unref (actions);
|
|
+
|
|
+ if (action == NULL) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ proxies = gtk_action_get_proxies (action);
|
|
+ for (node = proxies; node != NULL; node = node->next) {
|
|
+ GtkWidget *widget;
|
|
+
|
|
+ widget = GTK_WIDGET (node->data);
|
|
+
|
|
+ if (GTK_WIDGET_CAN_DEFAULT (widget) &&
|
|
+ GTK_WIDGET_VISIBLE (widget)) {
|
|
+ gtk_widget_grab_default (widget);
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+}
|
|
+
|
|
+static void
|
|
+show_task_actions (GdmTask *task)
|
|
+{
|
|
+ GtkActionGroup *actions;
|
|
+
|
|
+ actions = gdm_conversation_get_actions (GDM_CONVERSATION (task));
|
|
+
|
|
+ if (actions != NULL) {
|
|
+ gtk_action_group_set_sensitive (actions, TRUE);
|
|
+ gtk_action_group_set_visible (actions, TRUE);
|
|
+ g_object_unref (actions);
|
|
+ }
|
|
}
|
|
|
|
static void
|
|
@@ -419,6 +485,7 @@ set_log_in_button_mode (GdmGreeterLoginWindow *login_window,
|
|
int mode)
|
|
{
|
|
GtkWidget *button;
|
|
+ GdmTask *task;
|
|
|
|
button = glade_xml_get_widget (login_window->priv->xml, "log-in-button");
|
|
gtk_widget_grab_default (button);
|
|
@@ -431,14 +498,27 @@ set_log_in_button_mode (GdmGreeterLoginWindow *login_window,
|
|
|
|
switch (mode) {
|
|
case LOGIN_BUTTON_HIDDEN:
|
|
+ task = gdm_task_list_get_active_task (GDM_TASK_LIST (login_window->priv->conversation_list));
|
|
+ if (task != NULL) {
|
|
+ hide_task_actions (task);
|
|
+ g_object_unref (task);
|
|
+ }
|
|
+
|
|
gtk_widget_hide (button);
|
|
break;
|
|
case LOGIN_BUTTON_ANSWER_QUERY:
|
|
- login_window->priv->login_button_handler_id = g_signal_connect (button, "clicked", G_CALLBACK (on_login_button_clicked_answer_query), login_window);
|
|
- gtk_widget_show (button);
|
|
+ task = gdm_task_list_get_active_task (GDM_TASK_LIST (login_window->priv->conversation_list));
|
|
+ if (task != NULL) {
|
|
+ show_task_actions (task);
|
|
+ grab_default_button_for_task (task);
|
|
+ g_object_unref (task);
|
|
+ }
|
|
+
|
|
+ gtk_widget_hide (button);
|
|
break;
|
|
case LOGIN_BUTTON_TIMED_LOGIN:
|
|
login_window->priv->login_button_handler_id = g_signal_connect (button, "clicked", G_CALLBACK (on_login_button_clicked_timed_login), login_window);
|
|
+
|
|
gtk_widget_show (button);
|
|
break;
|
|
default:
|
|
@@ -563,7 +643,7 @@ switch_mode (GdmGreeterLoginWindow *login_window,
|
|
show_widget (login_window, "disconnect-button",
|
|
! login_window->priv->display_is_local);
|
|
|
|
- show_widget (login_window, "auth-input-box", FALSE);
|
|
+ show_widget (login_window, "auth-page-box", FALSE);
|
|
|
|
add_sensitize_power_buttons_timeout (login_window);
|
|
sensitize_widget (login_window, "shutdown-button", FALSE);
|
|
@@ -582,6 +662,7 @@ switch_mode (GdmGreeterLoginWindow *login_window,
|
|
show_widget (login_window, "restart-button", FALSE);
|
|
show_widget (login_window, "suspend-button", FALSE);
|
|
show_widget (login_window, "disconnect-button", FALSE);
|
|
+ show_widget (login_window, "auth-page-box", TRUE);
|
|
default_name = "log-in-button";
|
|
break;
|
|
default:
|
|
@@ -661,25 +742,40 @@ do_suspend (GdmGreeterLoginWindow *login_window)
|
|
g_object_unref (proxy);
|
|
}
|
|
|
|
-static void
|
|
-delete_entry_text (GtkWidget *entry)
|
|
+static gboolean
|
|
+task_has_service_name (GdmTaskList *task_list,
|
|
+ GdmTask *task,
|
|
+ const char *service_name)
|
|
{
|
|
- const char *typed_text;
|
|
- char *null_text;
|
|
+ char *task_service_name;
|
|
+ gboolean has_service_name;
|
|
+
|
|
+ task_service_name = gdm_conversation_get_service_name (GDM_CONVERSATION (task));
|
|
+
|
|
+ has_service_name = strcmp (service_name, task_service_name) == 0;
|
|
+ g_free (task_service_name);
|
|
|
|
- /* try to scrub out any secret info */
|
|
- typed_text = gtk_entry_get_text (GTK_ENTRY (entry));
|
|
- null_text = g_strnfill (strlen (typed_text) + 1, '\b');
|
|
- gtk_entry_set_text (GTK_ENTRY (entry), null_text);
|
|
- gtk_entry_set_text (GTK_ENTRY (entry), "");
|
|
+ return has_service_name;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+reset_task (GdmTaskList *task_list,
|
|
+ GdmTask *task,
|
|
+ GdmGreeterLoginWindow *login_window)
|
|
+{
|
|
+ char *name;
|
|
+
|
|
+ name = gdm_task_get_name (task);
|
|
+ g_debug ("Resetting task '%s'", name);
|
|
+ g_free (name);
|
|
+
|
|
+ gdm_conversation_reset (GDM_CONVERSATION (task));
|
|
+ return FALSE;
|
|
}
|
|
|
|
static void
|
|
reset_dialog (GdmGreeterLoginWindow *login_window)
|
|
{
|
|
- GtkWidget *entry;
|
|
- GtkWidget *label;
|
|
-
|
|
g_debug ("GdmGreeterLoginWindow: Resetting dialog");
|
|
set_busy (login_window);
|
|
set_sensitive (login_window, FALSE);
|
|
@@ -703,16 +799,12 @@ reset_dialog (GdmGreeterLoginWindow *login_window)
|
|
login_window->priv->start_session_handler_id = 0;
|
|
}
|
|
|
|
- entry = glade_xml_get_widget (GDM_GREETER_LOGIN_WINDOW (login_window)->priv->xml, "auth-prompt-entry");
|
|
+ gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
+ (GdmTaskListForeachFunc)
|
|
+ reset_task,
|
|
+ login_window);
|
|
|
|
- delete_entry_text (entry);
|
|
-
|
|
- gtk_entry_set_visibility (GTK_ENTRY (entry), TRUE);
|
|
set_message (login_window, "");
|
|
-
|
|
- label = glade_xml_get_widget (GDM_GREETER_LOGIN_WINDOW (login_window)->priv->xml, "auth-prompt-label");
|
|
- gtk_label_set_text (GTK_LABEL (label), "");
|
|
-
|
|
switch_mode (login_window, MODE_SELECTION);
|
|
|
|
set_sensitive (login_window, TRUE);
|
|
@@ -732,11 +824,22 @@ do_cancel (GdmGreeterLoginWindow *login_window)
|
|
}
|
|
|
|
gboolean
|
|
-gdm_greeter_login_window_ready (GdmGreeterLoginWindow *login_window)
|
|
+gdm_greeter_login_window_ready (GdmGreeterLoginWindow *login_window,
|
|
+ const char *service_name)
|
|
{
|
|
+ GdmTask *task;
|
|
+
|
|
g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE);
|
|
|
|
- reset_dialog (login_window);
|
|
+ task = gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
+ (GdmTaskListForeachFunc)
|
|
+ task_has_service_name,
|
|
+ (gpointer) service_name);
|
|
+
|
|
+ if (task != NULL) {
|
|
+ gdm_conversation_set_ready (GDM_CONVERSATION (task));
|
|
+ g_object_unref (task);
|
|
+ }
|
|
|
|
set_sensitive (GDM_GREETER_LOGIN_WINDOW (login_window), TRUE);
|
|
set_ready (GDM_GREETER_LOGIN_WINDOW (login_window));
|
|
@@ -745,13 +848,41 @@ gdm_greeter_login_window_ready (GdmGreeterLoginWindow *login_window)
|
|
return TRUE;
|
|
}
|
|
|
|
+static gboolean
|
|
+restart_task_conversation (GdmTaskList *task_list,
|
|
+ GdmTask *task,
|
|
+ GdmGreeterLoginWindow *login_window)
|
|
+{
|
|
+ char *service_name;
|
|
+
|
|
+ service_name = gdm_conversation_get_service_name (GDM_CONVERSATION (task));
|
|
+ if (service_name != NULL) {
|
|
+ char *name;
|
|
+
|
|
+ name = gdm_task_get_name (task);
|
|
+ g_debug ("GdmGreeterLoginWindow: restarting '%s' conversation", name);
|
|
+ g_free (name);
|
|
+
|
|
+ g_signal_emit (login_window, signals[START_CONVERSATION], 0, service_name);
|
|
+ g_free (service_name);
|
|
+ }
|
|
+
|
|
+ return FALSE;
|
|
+}
|
|
+
|
|
gboolean
|
|
gdm_greeter_login_window_reset (GdmGreeterLoginWindow *login_window)
|
|
{
|
|
- g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE);
|
|
+ g_debug ("GdmGreeterLoginWindow: window reset");
|
|
|
|
+ g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE);
|
|
reset_dialog (GDM_GREETER_LOGIN_WINDOW (login_window));
|
|
|
|
+ gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
+ (GdmTaskListForeachFunc)
|
|
+ restart_task_conversation,
|
|
+ login_window);
|
|
+
|
|
return TRUE;
|
|
}
|
|
|
|
@@ -760,12 +891,20 @@ gdm_greeter_login_window_info (GdmGreeterLoginWindow *login_window,
|
|
const char *service_name,
|
|
const char *text)
|
|
{
|
|
- g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE);
|
|
+ GdmTask *task;
|
|
|
|
+ g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE);
|
|
g_debug ("GdmGreeterLoginWindow: info: %s", text);
|
|
|
|
- if (strcmp (service_name, gdm_task_list_get_active_task (GDM_TASK_LIST (login_window->priv->conversation_list))) == 0) {
|
|
- set_message (GDM_GREETER_LOGIN_WINDOW (login_window), text);
|
|
+ task = gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
+ (GdmTaskListForeachFunc)
|
|
+ task_has_service_name,
|
|
+ (gpointer) service_name);
|
|
+
|
|
+ if (task != NULL) {
|
|
+ gdm_conversation_set_message (GDM_CONVERSATION (task),
|
|
+ text);
|
|
+ g_object_unref (task);
|
|
}
|
|
|
|
return TRUE;
|
|
@@ -776,13 +915,22 @@ gdm_greeter_login_window_problem (GdmGreeterLoginWindow *login_window,
|
|
const char *service_name,
|
|
const char *text)
|
|
{
|
|
- g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE);
|
|
+ GdmTask *task;
|
|
|
|
+ g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE);
|
|
g_debug ("GdmGreeterLoginWindow: problem: %s", text);
|
|
|
|
- if (strcmp (service_name, gdm_task_list_get_active_task (GDM_TASK_LIST (login_window->priv->conversation_list))) == 0) {
|
|
- set_message (GDM_GREETER_LOGIN_WINDOW (login_window), text);
|
|
+ task = gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
+ (GdmTaskListForeachFunc)
|
|
+ task_has_service_name,
|
|
+ (gpointer) service_name);
|
|
+
|
|
+ if (task != NULL) {
|
|
+ gdm_conversation_set_message (GDM_CONVERSATION (task),
|
|
+ text);
|
|
+ g_object_unref (task);
|
|
}
|
|
+
|
|
gdk_window_beep (GTK_WIDGET (login_window)->window);
|
|
|
|
return TRUE;
|
|
@@ -820,11 +968,21 @@ gdm_greeter_login_window_request_timed_login (GdmGreeterLoginWindow *login_windo
|
|
}
|
|
|
|
static void
|
|
-gdm_greeter_login_window_start_session_when_ready (GdmGreeterLoginWindow *login_window)
|
|
+on_ready_to_start_session (GdmGreeterLoginWindow *login_window,
|
|
+ GParamSpec *param_spec,
|
|
+ char *service_name)
|
|
+{
|
|
+ gdm_greeter_login_window_start_session_when_ready (login_window, service_name);
|
|
+ g_free (service_name);
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_greeter_login_window_start_session_when_ready (GdmGreeterLoginWindow *login_window,
|
|
+ const char *service_name)
|
|
{
|
|
if (login_window->priv->is_interactive) {
|
|
g_debug ("GdmGreeterLoginWindow: starting session");
|
|
- g_signal_emit (login_window, signals[START_SESSION], 0);
|
|
+ g_signal_emit (login_window, signals[START_SESSION], 0, service_name);
|
|
} else {
|
|
g_debug ("GdmGreeterLoginWindow: not starting session since "
|
|
"user hasn't had an opportunity to pick language "
|
|
@@ -834,8 +992,8 @@ gdm_greeter_login_window_start_session_when_ready (GdmGreeterLoginWindow *login_
|
|
*/
|
|
login_window->priv->start_session_handler_id =
|
|
g_signal_connect (login_window, "notify::is-interactive",
|
|
- G_CALLBACK (gdm_greeter_login_window_start_session_when_ready),
|
|
- NULL);
|
|
+ G_CALLBACK (on_ready_to_start_session),
|
|
+ g_strdup (service_name));
|
|
|
|
/* FIXME: If the user wasn't asked any questions by pam but
|
|
* pam still authorized them (passwd -d, or the questions got
|
|
@@ -861,26 +1019,24 @@ gdm_greeter_login_window_info_query (GdmGreeterLoginWindow *login_window,
|
|
const char *service_name,
|
|
const char *text)
|
|
{
|
|
- GtkWidget *entry;
|
|
- GtkWidget *label;
|
|
+ GdmTask *task;
|
|
|
|
g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE);
|
|
|
|
- if (strcmp (service_name, gdm_task_list_get_active_task (GDM_TASK_LIST (login_window->priv->conversation_list))) != 0) {
|
|
- return TRUE;
|
|
- }
|
|
-
|
|
g_debug ("GdmGreeterLoginWindow: info query: %s", text);
|
|
|
|
- entry = glade_xml_get_widget (GDM_GREETER_LOGIN_WINDOW (login_window)->priv->xml, "auth-prompt-entry");
|
|
- delete_entry_text (entry);
|
|
- gtk_entry_set_visibility (GTK_ENTRY (entry), TRUE);
|
|
- set_log_in_button_mode (login_window, LOGIN_BUTTON_ANSWER_QUERY);
|
|
+ task = gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
+ (GdmTaskListForeachFunc)
|
|
+ task_has_service_name,
|
|
+ (gpointer) service_name);
|
|
|
|
- label = glade_xml_get_widget (GDM_GREETER_LOGIN_WINDOW (login_window)->priv->xml, "auth-prompt-label");
|
|
- gtk_label_set_text (GTK_LABEL (label), text);
|
|
+ if (task != NULL) {
|
|
+ gdm_conversation_ask_question (GDM_CONVERSATION (task),
|
|
+ text);
|
|
+ g_object_unref (task);
|
|
+ }
|
|
|
|
- show_widget (login_window, "auth-input-box", TRUE);
|
|
+ set_log_in_button_mode (login_window, LOGIN_BUTTON_ANSWER_QUERY);
|
|
set_sensitive (GDM_GREETER_LOGIN_WINDOW (login_window), TRUE);
|
|
set_ready (GDM_GREETER_LOGIN_WINDOW (login_window));
|
|
set_focus (GDM_GREETER_LOGIN_WINDOW (login_window));
|
|
@@ -895,20 +1051,23 @@ gdm_greeter_login_window_secret_info_query (GdmGreeterLoginWindow *login_window,
|
|
const char *service_name,
|
|
const char *text)
|
|
{
|
|
- GtkWidget *entry;
|
|
- GtkWidget *label;
|
|
+
|
|
+ GdmTask *task;
|
|
|
|
g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE);
|
|
|
|
- entry = glade_xml_get_widget (GDM_GREETER_LOGIN_WINDOW (login_window)->priv->xml, "auth-prompt-entry");
|
|
- delete_entry_text (entry);
|
|
- gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE);
|
|
- set_log_in_button_mode (login_window, LOGIN_BUTTON_ANSWER_QUERY);
|
|
+ task = gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
+ (GdmTaskListForeachFunc)
|
|
+ task_has_service_name,
|
|
+ (gpointer) service_name);
|
|
|
|
- label = glade_xml_get_widget (GDM_GREETER_LOGIN_WINDOW (login_window)->priv->xml, "auth-prompt-label");
|
|
- gtk_label_set_text (GTK_LABEL (label), text);
|
|
+ if (task != NULL) {
|
|
+ gdm_conversation_ask_secret (GDM_CONVERSATION (task),
|
|
+ text);
|
|
+ g_object_unref (task);
|
|
+ }
|
|
|
|
- show_widget (login_window, "auth-input-box", TRUE);
|
|
+ set_log_in_button_mode (login_window, LOGIN_BUTTON_ANSWER_QUERY);
|
|
set_sensitive (GDM_GREETER_LOGIN_WINDOW (login_window), TRUE);
|
|
set_ready (GDM_GREETER_LOGIN_WINDOW (login_window));
|
|
set_focus (GDM_GREETER_LOGIN_WINDOW (login_window));
|
|
@@ -919,13 +1078,16 @@ gdm_greeter_login_window_secret_info_query (GdmGreeterLoginWindow *login_window,
|
|
}
|
|
|
|
void
|
|
-gdm_greeter_login_window_user_authorized (GdmGreeterLoginWindow *login_window)
|
|
+gdm_greeter_login_window_user_authorized (GdmGreeterLoginWindow *login_window,
|
|
+ const char *service_name)
|
|
{
|
|
g_return_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window));
|
|
|
|
- g_debug ("GdmGreeterLoginWindow: user now authorized");
|
|
+ g_debug ("GdmGreeterLoginWindow: user now authorized via service %s",
|
|
+ service_name);
|
|
|
|
- gdm_greeter_login_window_start_session_when_ready (login_window);
|
|
+ gdm_greeter_login_window_start_session_when_ready (login_window,
|
|
+ service_name);
|
|
}
|
|
|
|
static void
|
|
@@ -1348,6 +1510,46 @@ on_users_loaded (GdmUserChooserWidget *user_chooser,
|
|
gdm_chooser_widget_activate_if_one_item (GDM_CHOOSER_WIDGET (login_window->priv->user_chooser));
|
|
}
|
|
|
|
+static gboolean
|
|
+begin_task_verification (GdmTaskList *task_list,
|
|
+ GdmTask *task,
|
|
+ GdmGreeterLoginWindow *login_window)
|
|
+{
|
|
+ char *service_name;
|
|
+
|
|
+ service_name = gdm_conversation_get_service_name (GDM_CONVERSATION (task));
|
|
+ if (service_name != NULL) {
|
|
+ g_signal_emit (login_window, signals[BEGIN_VERIFICATION], 0, service_name);
|
|
+ g_free (service_name);
|
|
+ }
|
|
+
|
|
+ return FALSE;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+begin_task_verification_for_selected_user (GdmTaskList *task_list,
|
|
+ GdmTask *task,
|
|
+ GdmGreeterLoginWindow *login_window)
|
|
+{
|
|
+ char *user_name;
|
|
+ char *service_name;
|
|
+
|
|
+ user_name = gdm_user_chooser_widget_get_chosen_user_name (GDM_USER_CHOOSER_WIDGET (login_window->priv->user_chooser));
|
|
+
|
|
+ if (user_name == NULL) {
|
|
+ return TRUE;
|
|
+ }
|
|
+
|
|
+ service_name = gdm_conversation_get_service_name (GDM_CONVERSATION (task));
|
|
+ if (service_name != NULL) {
|
|
+ g_signal_emit (login_window, signals[BEGIN_VERIFICATION_FOR_USER], 0, service_name, user_name);
|
|
+ g_free (service_name);
|
|
+ }
|
|
+
|
|
+ g_free (user_name);
|
|
+ return FALSE;
|
|
+}
|
|
+
|
|
static void
|
|
on_user_chosen (GdmUserChooserWidget *user_chooser,
|
|
GdmGreeterLoginWindow *login_window)
|
|
@@ -1365,10 +1567,10 @@ on_user_chosen (GdmUserChooserWidget *user_chooser,
|
|
0, user_name);
|
|
|
|
if (strcmp (user_name, GDM_USER_CHOOSER_USER_OTHER) == 0) {
|
|
- const char *service_name;
|
|
-
|
|
- service_name = gdm_task_list_get_active_task (GDM_TASK_LIST (login_window->priv->conversation_list));
|
|
- g_signal_emit (login_window, signals[BEGIN_VERIFICATION], 0, service_name);
|
|
+ gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
+ (GdmTaskListForeachFunc)
|
|
+ begin_task_verification,
|
|
+ login_window);
|
|
} else if (strcmp (user_name, GDM_USER_CHOOSER_USER_GUEST) == 0) {
|
|
/* FIXME: handle guest account stuff */
|
|
} else if (strcmp (user_name, GDM_USER_CHOOSER_USER_AUTO) == 0) {
|
|
@@ -1382,10 +1584,10 @@ on_user_chosen (GdmUserChooserWidget *user_chooser,
|
|
set_log_in_button_mode (login_window, LOGIN_BUTTON_TIMED_LOGIN);
|
|
set_message (login_window, _("Select language and click Log In"));
|
|
} else {
|
|
- const char *service_name;
|
|
-
|
|
- service_name = gdm_task_list_get_active_task (GDM_TASK_LIST (login_window->priv->conversation_list));
|
|
- g_signal_emit (login_window, signals[BEGIN_VERIFICATION_FOR_USER], 0, service_name, user_name);
|
|
+ gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
+ (GdmTaskListForeachFunc)
|
|
+ begin_task_verification_for_selected_user,
|
|
+ login_window);
|
|
}
|
|
|
|
switch_mode (login_window, MODE_AUTHENTICATION);
|
|
@@ -1531,17 +1733,65 @@ create_computer_info (GdmGreeterLoginWindow *login_window)
|
|
|
|
static void
|
|
on_task_activated (GdmGreeterLoginWindow *login_window,
|
|
- const char *name)
|
|
+ GdmTask *task)
|
|
{
|
|
- g_debug ("GdmGreeterLoginWindow: starting conversation with '%s'", name);
|
|
- g_signal_emit (login_window, signals[START_CONVERSATION], 0, name);
|
|
+ GtkWidget *container;
|
|
+ char *name;
|
|
+
|
|
+ name = gdm_task_get_name (task);
|
|
+ g_debug ("GdmGreeterLoginWindow: task '%s' activated", name);
|
|
+ g_free (name);
|
|
+
|
|
+ container = g_object_get_data (G_OBJECT (task),
|
|
+ "gdm-greeter-login-window-page-container");
|
|
+
|
|
+ if (container == NULL) {
|
|
+ GtkWidget *page;
|
|
+
|
|
+ container = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
|
|
+ gtk_container_add (GTK_CONTAINER (login_window->priv->auth_page_box),
|
|
+ container);
|
|
+
|
|
+ page = gdm_conversation_get_page (GDM_CONVERSATION (task));
|
|
+ if (page != NULL) {
|
|
+ gtk_container_add (GTK_CONTAINER (container), page);
|
|
+ gtk_widget_show (page);
|
|
+ }
|
|
+ g_object_set_data (G_OBJECT (task),
|
|
+ "gdm-greeter-login-window-page-container",
|
|
+ container);
|
|
+ }
|
|
+
|
|
+ gtk_widget_show (container);
|
|
+ set_log_in_button_mode (login_window, login_window->priv->dialog_mode);
|
|
}
|
|
|
|
static void
|
|
on_task_deactivated (GdmGreeterLoginWindow *login_window,
|
|
- const char *name)
|
|
+ GdmTask *task)
|
|
{
|
|
- g_debug ("GdmGreeterLoginWindow: conversation '%s' now in background", name);
|
|
+ GtkWidget *container;
|
|
+ char *name;
|
|
+ GtkActionGroup *actions;
|
|
+
|
|
+ name = gdm_task_get_name (task);
|
|
+ g_debug ("GdmGreeterLoginWindow: task '%s' now in background", name);
|
|
+ g_free (name);
|
|
+
|
|
+ container = g_object_get_data (G_OBJECT (task),
|
|
+ "gdm-greeter-login-window-page-container");
|
|
+
|
|
+ if (container != NULL) {
|
|
+ gtk_widget_hide (container);
|
|
+ }
|
|
+
|
|
+ actions = gdm_conversation_get_actions (GDM_CONVERSATION (task));
|
|
+
|
|
+ if (actions != NULL) {
|
|
+ gtk_action_group_set_sensitive (actions, FALSE);
|
|
+ gtk_action_group_set_visible (actions, FALSE);
|
|
+ g_object_unref (actions);
|
|
+ }
|
|
}
|
|
|
|
static GtkWidget *
|
|
@@ -1578,7 +1828,6 @@ custom_widget_constructor (GladeXML *xml,
|
|
static void
|
|
load_theme (GdmGreeterLoginWindow *login_window)
|
|
{
|
|
- GtkWidget *entry;
|
|
GtkWidget *button;
|
|
GtkWidget *box;
|
|
GtkWidget *image;
|
|
@@ -1653,15 +1902,9 @@ load_theme (GdmGreeterLoginWindow *login_window)
|
|
login_window);
|
|
gtk_widget_show (login_window->priv->conversation_list);
|
|
|
|
- gdm_task_list_add_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
- "password-auth", "dialog-password");
|
|
- gdm_task_list_add_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
- "fingerprint-auth", "stock_allow-effects");
|
|
- gdm_task_list_add_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
- "smartcard-auth", "badge-small");
|
|
-
|
|
login_window->priv->auth_banner_label = glade_xml_get_widget (login_window->priv->xml, "auth-banner-label");
|
|
/*make_label_small_italic (login_window->priv->auth_banner_label);*/
|
|
+ login_window->priv->auth_page_box = glade_xml_get_widget (login_window->priv->xml, "auth-page-box");
|
|
|
|
button = glade_xml_get_widget (login_window->priv->xml, "suspend-button");
|
|
g_signal_connect (button, "clicked", G_CALLBACK (suspend_button_clicked), login_window);
|
|
@@ -1677,14 +1920,6 @@ load_theme (GdmGreeterLoginWindow *login_window)
|
|
button = glade_xml_get_widget (login_window->priv->xml, "shutdown-button");
|
|
g_signal_connect (button, "clicked", G_CALLBACK (shutdown_button_clicked), login_window);
|
|
|
|
- entry = glade_xml_get_widget (login_window->priv->xml, "auth-prompt-entry");
|
|
- /* Only change the invisible character if it '*' otherwise assume it is OK */
|
|
- if ('*' == gtk_entry_get_invisible_char (GTK_ENTRY (entry))) {
|
|
- gunichar invisible_char;
|
|
- invisible_char = INVISIBLE_CHAR_BLACK_CIRCLE;
|
|
- gtk_entry_set_invisible_char (GTK_ENTRY (entry), invisible_char);
|
|
- }
|
|
-
|
|
create_computer_info (login_window);
|
|
|
|
box = glade_xml_get_widget (login_window->priv->xml, "computer-info-event-box");
|
|
@@ -1902,9 +2137,9 @@ gdm_greeter_login_window_class_init (GdmGreeterLoginWindowClass *klass)
|
|
G_STRUCT_OFFSET (GdmGreeterLoginWindowClass, start_session),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__VOID,
|
|
+ g_cclosure_marshal_VOID__STRING,
|
|
G_TYPE_NONE,
|
|
- 0);
|
|
+ 1, G_TYPE_STRING);
|
|
|
|
g_object_class_install_property (object_class,
|
|
PROP_DISPLAY_IS_LOCAL,
|
|
@@ -1957,6 +2192,187 @@ on_gconf_key_changed (GConfClient *client,
|
|
}
|
|
}
|
|
|
|
+static void
|
|
+on_conversation_answer (GdmGreeterLoginWindow *login_window,
|
|
+ const char *text,
|
|
+ GdmConversation *conversation)
|
|
+{
|
|
+ if (text != NULL) {
|
|
+ char *service_name;
|
|
+
|
|
+ service_name = gdm_conversation_get_service_name (conversation);
|
|
+ if (service_name != NULL) {
|
|
+ g_signal_emit (login_window, signals[QUERY_ANSWER], 0, service_name, text);
|
|
+ g_free (service_name);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ set_sensitive (login_window, TRUE);
|
|
+ set_ready (login_window);
|
|
+}
|
|
+
|
|
+void
|
|
+gdm_greeter_login_window_remove_extension (GdmGreeterLoginWindow *login_window,
|
|
+ GdmGreeterExtension *extension)
|
|
+{
|
|
+ g_return_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window));
|
|
+ g_return_if_fail (GDM_IS_GREETER_LOGIN_WINDOW_EXTENSION (extension));
|
|
+
|
|
+ if (!GDM_IS_CONVERSATION (extension)) {
|
|
+ return;
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
+on_button_action_label_changed (GtkWidget *button)
|
|
+{
|
|
+ GtkAction *action;
|
|
+ char *text;
|
|
+
|
|
+ action = gtk_widget_get_action (button);
|
|
+
|
|
+ g_object_get (G_OBJECT (action), "label", &text, NULL);
|
|
+
|
|
+ gtk_button_set_label (GTK_BUTTON (button), text);
|
|
+ g_free (text);
|
|
+}
|
|
+
|
|
+static void
|
|
+on_button_action_icon_name_changed (GtkWidget *button)
|
|
+{
|
|
+ GtkAction *action;
|
|
+ GtkWidget *image;
|
|
+
|
|
+ action = gtk_widget_get_action (button);
|
|
+
|
|
+ image = gtk_action_create_icon (GTK_ACTION (action), GTK_ICON_SIZE_BUTTON);
|
|
+ gtk_button_set_image (GTK_BUTTON (button), image);
|
|
+}
|
|
+
|
|
+static void
|
|
+on_button_action_tooltip_changed (GtkWidget *button)
|
|
+{
|
|
+ GtkAction *action;
|
|
+ char *text;
|
|
+
|
|
+ action = gtk_widget_get_action (button);
|
|
+
|
|
+ g_object_get (G_OBJECT (action), "tooltip", &text, NULL);
|
|
+
|
|
+ gtk_widget_set_tooltip_text (button, text);
|
|
+ g_free (text);
|
|
+}
|
|
+
|
|
+GtkWidget *
|
|
+create_button_from_action (GtkAction *action)
|
|
+{
|
|
+ GtkWidget *button;
|
|
+
|
|
+ button = gtk_button_new ();
|
|
+
|
|
+ gtk_action_connect_proxy (GTK_ACTION (action), button);
|
|
+
|
|
+ g_signal_connect_swapped (action,
|
|
+ "notify::label",
|
|
+ G_CALLBACK (on_button_action_label_changed),
|
|
+ button);
|
|
+ g_signal_connect_swapped (action,
|
|
+ "notify::icon-name",
|
|
+ G_CALLBACK (on_button_action_icon_name_changed),
|
|
+ button);
|
|
+ g_signal_connect_swapped (action,
|
|
+ "notify::tooltip",
|
|
+ G_CALLBACK (on_button_action_tooltip_changed),
|
|
+ button);
|
|
+
|
|
+ on_button_action_label_changed (button);
|
|
+ on_button_action_icon_name_changed (button);
|
|
+ on_button_action_tooltip_changed (button);
|
|
+
|
|
+ if (strcmp (gtk_action_get_name (action),
|
|
+ GDM_CONVERSATION_DEFAULT_ACTION) == 0) {
|
|
+ GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
|
|
+ }
|
|
+
|
|
+ return button;
|
|
+}
|
|
+
|
|
+static void
|
|
+create_buttons_for_actions (GdmGreeterLoginWindow *login_window,
|
|
+ GtkActionGroup *actions)
|
|
+{
|
|
+ GList *action_list;
|
|
+ GList *node;
|
|
+ GtkWidget *box;
|
|
+
|
|
+ action_list = gtk_action_group_list_actions (actions);
|
|
+
|
|
+ box = glade_xml_get_widget (login_window->priv->xml, "buttonbox");
|
|
+ for (node = action_list; node != NULL; node = node->next) {
|
|
+ GtkAction *action;
|
|
+ GtkWidget *button;
|
|
+
|
|
+ action = node->data;
|
|
+
|
|
+ button = create_button_from_action (action);
|
|
+ gtk_container_add (GTK_CONTAINER (box), button);
|
|
+ }
|
|
+
|
|
+ g_list_free (action_list);
|
|
+}
|
|
+
|
|
+void
|
|
+gdm_greeter_login_window_add_extension (GdmGreeterLoginWindow *login_window,
|
|
+ GdmGreeterExtension *extension)
|
|
+{
|
|
+ char *name;
|
|
+ char *description;
|
|
+ char *service_name;
|
|
+ GtkActionGroup *actions;
|
|
+
|
|
+ g_return_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window));
|
|
+ g_return_if_fail (GDM_IS_GREETER_LOGIN_WINDOW_EXTENSION (extension));
|
|
+
|
|
+ if (!GDM_IS_CONVERSATION (extension)) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ actions = gdm_conversation_get_actions (GDM_CONVERSATION (extension));
|
|
+
|
|
+ create_buttons_for_actions (login_window, actions);
|
|
+ hide_task_actions (GDM_TASK (extension));
|
|
+
|
|
+ g_object_unref (actions);
|
|
+
|
|
+ g_signal_connect_swapped (GDM_CONVERSATION (extension),
|
|
+ "answer",
|
|
+ G_CALLBACK (on_conversation_answer),
|
|
+ login_window);
|
|
+
|
|
+ name = gdm_task_get_name (GDM_TASK (extension));
|
|
+ description = gdm_task_get_description (GDM_TASK (extension));
|
|
+
|
|
+ g_debug ("GdmGreeterLoginWindow: new extension '%s - %s' added",
|
|
+ name, description);
|
|
+
|
|
+ g_free (name);
|
|
+ g_free (description);
|
|
+
|
|
+ if (gdm_task_list_get_number_of_tasks (GDM_TASK_LIST (login_window->priv->conversation_list)) == 0) {
|
|
+ gtk_widget_hide (login_window->priv->conversation_list);
|
|
+ } else {
|
|
+ gtk_widget_show (login_window->priv->conversation_list);
|
|
+ }
|
|
+
|
|
+ gdm_task_list_add_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
+ GDM_TASK (extension));
|
|
+
|
|
+ service_name = gdm_conversation_get_service_name (GDM_CONVERSATION (extension));
|
|
+ g_debug ("GdmGreeterLoginWindow: starting conversation with '%s'", service_name);
|
|
+ g_signal_emit (login_window, signals[START_CONVERSATION], 0, service_name);
|
|
+ g_free (service_name);
|
|
+}
|
|
+
|
|
static gboolean
|
|
on_window_state_event (GtkWidget *widget,
|
|
GdkEventWindowState *event,
|
|
diff --git a/gui/simple-greeter/gdm-greeter-login-window.glade b/gui/simple-greeter/gdm-greeter-login-window.glade
|
|
index a3ae5ba..9933437 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-login-window.glade
|
|
+++ b/gui/simple-greeter/gdm-greeter-login-window.glade
|
|
@@ -611,30 +611,29 @@
|
|
</child>
|
|
|
|
<child>
|
|
- <widget class="GtkLabel" id="auth-banner-label">
|
|
- <property name="visible">True</property>
|
|
- <property name="label" translatable="yes"></property>
|
|
- <property name="use_underline">False</property>
|
|
- <property name="use_markup">False</property>
|
|
- <property name="justify">GTK_JUSTIFY_CENTER</property>
|
|
- <property name="wrap">True</property>
|
|
- <property name="selectable">False</property>
|
|
- <property name="xalign">0.5</property>
|
|
- <property name="yalign">0.5</property>
|
|
- <property name="xpad">0</property>
|
|
- <property name="ypad">0</property>
|
|
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
|
- <property name="width_chars">-1</property>
|
|
- <property name="single_line_mode">False</property>
|
|
- <property name="angle">0</property>
|
|
- </widget>
|
|
- <packing>
|
|
- <property name="padding">0</property>
|
|
- <property name="expand">True</property>
|
|
- <property name="fill">True</property>
|
|
- </packing>
|
|
+ <widget class="GtkLabel" id="auth-banner-label">
|
|
+ <property name="visible">True</property>
|
|
+ <property name="label" translatable="yes"></property>
|
|
+ <property name="use_underline">False</property>
|
|
+ <property name="use_markup">False</property>
|
|
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
|
|
+ <property name="wrap">True</property>
|
|
+ <property name="selectable">False</property>
|
|
+ <property name="xalign">0.5</property>
|
|
+ <property name="yalign">0.5</property>
|
|
+ <property name="xpad">0</property>
|
|
+ <property name="ypad">0</property>
|
|
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
|
+ <property name="width_chars">-1</property>
|
|
+ <property name="single_line_mode">False</property>
|
|
+ <property name="angle">0</property>
|
|
+ </widget>
|
|
+ <packing>
|
|
+ <property name="padding">0</property>
|
|
+ <property name="expand">False</property>
|
|
+ <property name="fill">False</property>
|
|
+ </packing>
|
|
</child>
|
|
-
|
|
<child>
|
|
<widget class="GtkAlignment" id="alignment2">
|
|
<property name="visible">True</property>
|
|
@@ -660,20 +659,6 @@
|
|
<property name="spacing">0</property>
|
|
|
|
<child>
|
|
- <widget class="Custom" id="user-chooser">
|
|
- <property name="visible">True</property>
|
|
- <property name="int1">0</property>
|
|
- <property name="int2">0</property>
|
|
- <property name="last_modification_time">Tue, 18 Nov 2008 21:55:38 GMT</property>
|
|
- </widget>
|
|
- <packing>
|
|
- <property name="padding">0</property>
|
|
- <property name="expand">True</property>
|
|
- <property name="fill">True</property>
|
|
- </packing>
|
|
- </child>
|
|
-
|
|
- <child>
|
|
<widget class="Custom" id="conversation-list">
|
|
<property name="visible">True</property>
|
|
<property name="int1">0</property>
|
|
@@ -686,57 +671,13 @@
|
|
<property name="fill">False</property>
|
|
</packing>
|
|
</child>
|
|
- </widget>
|
|
- <packing>
|
|
- <property name="padding">0</property>
|
|
- <property name="expand">True</property>
|
|
- <property name="fill">True</property>
|
|
- </packing>
|
|
- </child>
|
|
-
|
|
- <child>
|
|
- <widget class="GtkHBox" id="auth-input-box">
|
|
- <property name="visible">True</property>
|
|
- <property name="homogeneous">False</property>
|
|
- <property name="spacing">6</property>
|
|
|
|
<child>
|
|
- <widget class="GtkLabel" id="auth-prompt-label">
|
|
- <property name="visible">True</property>
|
|
- <property name="label" translatable="yes"></property>
|
|
- <property name="use_underline">False</property>
|
|
- <property name="use_markup">False</property>
|
|
- <property name="justify">GTK_JUSTIFY_LEFT</property>
|
|
- <property name="wrap">False</property>
|
|
- <property name="selectable">False</property>
|
|
- <property name="xalign">0.5</property>
|
|
- <property name="yalign">0.5</property>
|
|
- <property name="xpad">0</property>
|
|
- <property name="ypad">0</property>
|
|
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
|
- <property name="width_chars">-1</property>
|
|
- <property name="single_line_mode">False</property>
|
|
- <property name="angle">0</property>
|
|
- </widget>
|
|
- <packing>
|
|
- <property name="padding">0</property>
|
|
- <property name="expand">False</property>
|
|
- <property name="fill">False</property>
|
|
- </packing>
|
|
- </child>
|
|
-
|
|
- <child>
|
|
- <widget class="GtkEntry" id="auth-prompt-entry">
|
|
+ <widget class="Custom" id="user-chooser">
|
|
<property name="visible">True</property>
|
|
- <property name="can_focus">True</property>
|
|
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
|
- <property name="editable">True</property>
|
|
- <property name="visibility">True</property>
|
|
- <property name="max_length">0</property>
|
|
- <property name="text" translatable="yes"></property>
|
|
- <property name="has_frame">True</property>
|
|
- <property name="invisible_char">•</property>
|
|
- <property name="activates_default">True</property>
|
|
+ <property name="int1">0</property>
|
|
+ <property name="int2">0</property>
|
|
+ <property name="last_modification_time">Tue, 18 Nov 2008 21:55:38 GMT</property>
|
|
</widget>
|
|
<packing>
|
|
<property name="padding">0</property>
|
|
@@ -745,46 +686,21 @@
|
|
</packing>
|
|
</child>
|
|
|
|
- <child>
|
|
- <placeholder/>
|
|
- </child>
|
|
</widget>
|
|
<packing>
|
|
<property name="padding">0</property>
|
|
- <property name="expand">False</property>
|
|
- <property name="fill">False</property>
|
|
+ <property name="expand">True</property>
|
|
+ <property name="fill">True</property>
|
|
</packing>
|
|
</child>
|
|
|
|
<child>
|
|
- <widget class="GtkHBox" id="auth-message-box">
|
|
+ <widget class="GtkHBox" id="auth-page-box">
|
|
<property name="visible">True</property>
|
|
<property name="homogeneous">False</property>
|
|
<property name="spacing">0</property>
|
|
-
|
|
<child>
|
|
- <widget class="GtkLabel" id="auth-message-label">
|
|
- <property name="visible">True</property>
|
|
- <property name="label" translatable="yes"></property>
|
|
- <property name="use_underline">False</property>
|
|
- <property name="use_markup">False</property>
|
|
- <property name="justify">GTK_JUSTIFY_LEFT</property>
|
|
- <property name="wrap">False</property>
|
|
- <property name="selectable">False</property>
|
|
- <property name="xalign">0.5</property>
|
|
- <property name="yalign">0.5</property>
|
|
- <property name="xpad">0</property>
|
|
- <property name="ypad">0</property>
|
|
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
|
- <property name="width_chars">-1</property>
|
|
- <property name="single_line_mode">False</property>
|
|
- <property name="angle">0</property>
|
|
- </widget>
|
|
- <packing>
|
|
- <property name="padding">0</property>
|
|
- <property name="expand">True</property>
|
|
- <property name="fill">True</property>
|
|
- </packing>
|
|
+ <placeholder/>
|
|
</child>
|
|
</widget>
|
|
<packing>
|
|
diff --git a/gui/simple-greeter/gdm-greeter-login-window.h b/gui/simple-greeter/gdm-greeter-login-window.h
|
|
index 559b26b..eda7f89 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-login-window.h
|
|
+++ b/gui/simple-greeter/gdm-greeter-login-window.h
|
|
@@ -23,6 +23,9 @@
|
|
#define __GDM_GREETER_LOGIN_WINDOW_H
|
|
|
|
#include <glib-object.h>
|
|
+#include "gdm-conversation.h"
|
|
+#include "gdm-task.h"
|
|
+#include "gdm-greeter-extension.h"
|
|
|
|
G_BEGIN_DECLS
|
|
|
|
@@ -33,6 +36,8 @@ G_BEGIN_DECLS
|
|
#define GDM_IS_GREETER_LOGIN_WINDOW_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_GREETER_LOGIN_WINDOW))
|
|
#define GDM_GREETER_LOGIN_WINDOW_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_GREETER_LOGIN_WINDOW, GdmGreeterLoginWindowClass))
|
|
|
|
+#define GDM_IS_GREETER_LOGIN_WINDOW_EXTENSION(e) (GDM_IS_CONVERSATION(e) && GDM_IS_TASK(e))
|
|
+
|
|
typedef struct GdmGreeterLoginWindowPrivate GdmGreeterLoginWindowPrivate;
|
|
|
|
typedef struct
|
|
@@ -62,7 +67,8 @@ typedef struct
|
|
const char *text);
|
|
void (* cancelled) (GdmGreeterLoginWindow *login_window);
|
|
void (* disconnected) (GdmGreeterLoginWindow *login_window);
|
|
- void (* start_session) (GdmGreeterLoginWindow *login_window);
|
|
+ void (* start_session) (GdmGreeterLoginWindow *login_window,
|
|
+ const char *sevice_name);
|
|
|
|
} GdmGreeterLoginWindowClass;
|
|
|
|
@@ -71,7 +77,8 @@ GtkWidget * gdm_greeter_login_window_new (gboolean displa
|
|
|
|
|
|
gboolean gdm_greeter_login_window_reset (GdmGreeterLoginWindow *login_window);
|
|
-gboolean gdm_greeter_login_window_ready (GdmGreeterLoginWindow *login_window);
|
|
+gboolean gdm_greeter_login_window_ready (GdmGreeterLoginWindow *login_window,
|
|
+ const char *service_name);
|
|
gboolean gdm_greeter_login_window_info_query (GdmGreeterLoginWindow *login_window,
|
|
const char *service_name,
|
|
const char *text);
|
|
@@ -88,7 +95,13 @@ gboolean gdm_greeter_login_window_problem (GdmGreeterLogin
|
|
void gdm_greeter_login_window_request_timed_login (GdmGreeterLoginWindow *login_window,
|
|
const char *username,
|
|
int delay);
|
|
-void gdm_greeter_login_window_user_authorized (GdmGreeterLoginWindow *login_window);
|
|
+void gdm_greeter_login_window_user_authorized (GdmGreeterLoginWindow *login_window,
|
|
+ const char *service_name);
|
|
+
|
|
+void gdm_greeter_login_window_add_extension (GdmGreeterLoginWindow *login_window,
|
|
+ GdmGreeterExtension *extension);
|
|
+void gdm_greeter_login_window_remove_extension (GdmGreeterLoginWindow *login_window,
|
|
+ GdmGreeterExtension *extension);
|
|
|
|
G_END_DECLS
|
|
|
|
diff --git a/gui/simple-greeter/gdm-greeter-plugin.c b/gui/simple-greeter/gdm-greeter-plugin.c
|
|
new file mode 100644
|
|
index 0000000..821b679
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/gdm-greeter-plugin.c
|
|
@@ -0,0 +1,251 @@
|
|
+/*
|
|
+ * Copyright (C) 2009 Red Hat, Inc.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
+ *
|
|
+ * Written by: Ray Strode <rstrode@redhat.com>
|
|
+ */
|
|
+
|
|
+#include <config.h>
|
|
+
|
|
+#include <string.h>
|
|
+#include <sys/types.h>
|
|
+#include <sys/stat.h>
|
|
+#include <unistd.h>
|
|
+
|
|
+#include <glib/gi18n.h>
|
|
+#include <gio/gio.h>
|
|
+
|
|
+#include "gdm-greeter-extension.h"
|
|
+#include "gdm-greeter-plugin.h"
|
|
+
|
|
+#define GDM_GREETER_PLUGIN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_GREETER_PLUGIN, GdmGreeterPluginPrivate))
|
|
+
|
|
+enum {
|
|
+ PROP_0,
|
|
+ PROP_FILENAME,
|
|
+};
|
|
+
|
|
+enum {
|
|
+ LOADED,
|
|
+ LOAD_FAILED,
|
|
+ UNLOADED,
|
|
+ LAST_SIGNAL
|
|
+};
|
|
+
|
|
+struct _GdmGreeterPluginPrivate {
|
|
+ GObject parent;
|
|
+
|
|
+ GModule *module;
|
|
+ char *filename;
|
|
+
|
|
+ GdmGreeterExtension *extension;
|
|
+};
|
|
+
|
|
+static void gdm_greeter_plugin_finalize (GObject *object);
|
|
+
|
|
+static guint signals[LAST_SIGNAL] = { 0 };
|
|
+
|
|
+G_DEFINE_TYPE (GdmGreeterPlugin, gdm_greeter_plugin, G_TYPE_OBJECT)
|
|
+
|
|
+static void
|
|
+gdm_greeter_plugin_set_property (GObject *object,
|
|
+ guint param_id,
|
|
+ const GValue *value,
|
|
+ GParamSpec *pspec)
|
|
+{
|
|
+ GdmGreeterPlugin *plugin;
|
|
+
|
|
+ plugin = GDM_GREETER_PLUGIN (object);
|
|
+ switch (param_id) {
|
|
+ case PROP_FILENAME:
|
|
+ plugin->priv->filename = g_strdup (g_value_get_string (value));
|
|
+ break;
|
|
+ default:
|
|
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_greeter_plugin_get_property (GObject *object,
|
|
+ guint param_id,
|
|
+ GValue *value,
|
|
+ GParamSpec *pspec)
|
|
+{
|
|
+ GdmGreeterPlugin *plugin;
|
|
+
|
|
+ plugin = GDM_GREETER_PLUGIN (object);
|
|
+
|
|
+ switch (param_id) {
|
|
+ case PROP_FILENAME:
|
|
+ g_value_set_string (value, plugin->priv->filename);
|
|
+ break;
|
|
+ default:
|
|
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_greeter_plugin_class_init (GdmGreeterPluginClass *class)
|
|
+{
|
|
+ GObjectClass *gobject_class;
|
|
+
|
|
+ gobject_class = G_OBJECT_CLASS (class);
|
|
+
|
|
+ gobject_class->set_property = gdm_greeter_plugin_set_property;
|
|
+ gobject_class->get_property = gdm_greeter_plugin_get_property;
|
|
+ gobject_class->finalize = gdm_greeter_plugin_finalize;
|
|
+
|
|
+ g_object_class_install_property (gobject_class,
|
|
+ PROP_FILENAME,
|
|
+ g_param_spec_string ("filename",
|
|
+ "Filename",
|
|
+ "The full path to the plugin.",
|
|
+ NULL,
|
|
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
|
+
|
|
+ signals [LOADED] =
|
|
+ g_signal_new ("loaded",
|
|
+ G_TYPE_FROM_CLASS (class),
|
|
+ G_SIGNAL_RUN_LAST,
|
|
+ G_STRUCT_OFFSET (GdmGreeterPluginClass, loaded),
|
|
+ NULL, NULL,
|
|
+ g_cclosure_marshal_VOID__VOID,
|
|
+ G_TYPE_NONE, 0);
|
|
+ signals [LOAD_FAILED] =
|
|
+ g_signal_new ("load-failed",
|
|
+ G_TYPE_FROM_CLASS (class),
|
|
+ G_SIGNAL_RUN_LAST,
|
|
+ G_STRUCT_OFFSET (GdmGreeterPluginClass, load_failed),
|
|
+ NULL, NULL,
|
|
+ g_cclosure_marshal_VOID__VOID,
|
|
+ G_TYPE_NONE, 0);
|
|
+ signals [UNLOADED] =
|
|
+ g_signal_new ("unloaded",
|
|
+ G_TYPE_FROM_CLASS (class),
|
|
+ G_SIGNAL_RUN_LAST,
|
|
+ G_STRUCT_OFFSET (GdmGreeterPluginClass, unloaded),
|
|
+ NULL, NULL,
|
|
+ g_cclosure_marshal_VOID__VOID,
|
|
+ G_TYPE_NONE, 0);
|
|
+
|
|
+ g_type_class_add_private (class, sizeof (GdmGreeterPluginPrivate));
|
|
+}
|
|
+
|
|
+GdmGreeterPlugin *
|
|
+gdm_greeter_plugin_new (const char *filename)
|
|
+{
|
|
+ GObject *object;
|
|
+
|
|
+ object = g_object_new (GDM_TYPE_GREETER_PLUGIN,
|
|
+ "filename", filename, NULL);
|
|
+
|
|
+ return GDM_GREETER_PLUGIN (object);
|
|
+}
|
|
+
|
|
+void
|
|
+gdm_greeter_plugin_load (GdmGreeterPlugin *plugin)
|
|
+{
|
|
+ GModule *module;
|
|
+ GdmGreeterExtension *extension;
|
|
+ union {
|
|
+ gpointer symbol;
|
|
+ GdmGreeterPluginGetExtensionFunc invoke;
|
|
+ } get_extension;
|
|
+
|
|
+ module = g_module_open (plugin->priv->filename, G_MODULE_BIND_LOCAL);
|
|
+
|
|
+ if (module == NULL) {
|
|
+ g_signal_emit (plugin, signals [LOAD_FAILED], 0);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (!g_module_symbol (module,
|
|
+ "gdm_greeter_plugin_get_extension",
|
|
+ &get_extension.symbol) ||
|
|
+ !get_extension.symbol) {
|
|
+ g_warning ("plugin %s lacks gdm_greeter_plugin_get_extension()",
|
|
+ plugin->priv->filename);
|
|
+ g_module_close (module);
|
|
+ g_signal_emit (plugin, signals [LOAD_FAILED], 0);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ extension = get_extension.invoke ();
|
|
+
|
|
+ if (!extension) {
|
|
+ g_warning ("plugin %s didn't return extension when asked",
|
|
+ plugin->priv->filename);
|
|
+ g_module_close (module);
|
|
+ g_signal_emit (plugin, signals [LOAD_FAILED], 0);
|
|
+ }
|
|
+
|
|
+ if (!GDM_IS_GREETER_EXTENSION (extension)) {
|
|
+ g_warning ("plugin %s returned bogus extension when asked",
|
|
+ plugin->priv->filename);
|
|
+ g_module_close (module);
|
|
+ g_signal_emit (plugin, signals [LOAD_FAILED], 0);
|
|
+ }
|
|
+
|
|
+ plugin->priv->module = module;
|
|
+ plugin->priv->extension = extension;
|
|
+
|
|
+ g_signal_emit (plugin, signals [LOADED], 0);
|
|
+}
|
|
+
|
|
+void
|
|
+gdm_greeter_plugin_unload (GdmGreeterPlugin *plugin)
|
|
+{
|
|
+ if (plugin->priv->extension != NULL) {
|
|
+ g_object_unref (plugin->priv->extension);
|
|
+ plugin->priv->extension = NULL;
|
|
+ }
|
|
+
|
|
+ if (plugin->priv->module != NULL) {
|
|
+ g_module_close (plugin->priv->module);
|
|
+ plugin->priv->module = NULL;
|
|
+ }
|
|
+}
|
|
+
|
|
+const char *
|
|
+gdm_greeter_plugin_get_filename (GdmGreeterPlugin *plugin)
|
|
+{
|
|
+ return plugin->priv->filename;
|
|
+}
|
|
+
|
|
+GdmGreeterExtension *
|
|
+gdm_greeter_plugin_get_extension (GdmGreeterPlugin *plugin)
|
|
+{
|
|
+ return g_object_ref (plugin->priv->extension);
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_greeter_plugin_init (GdmGreeterPlugin *plugin)
|
|
+{
|
|
+ plugin->priv = GDM_GREETER_PLUGIN_GET_PRIVATE (plugin);
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_greeter_plugin_finalize (GObject *object)
|
|
+{
|
|
+ GdmGreeterPlugin *plugin;
|
|
+
|
|
+ plugin = GDM_GREETER_PLUGIN (object);
|
|
+
|
|
+ gdm_greeter_plugin_unload (plugin);
|
|
+}
|
|
+
|
|
diff --git a/gui/simple-greeter/gdm-greeter-plugin.h b/gui/simple-greeter/gdm-greeter-plugin.h
|
|
new file mode 100644
|
|
index 0000000..904c231
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/gdm-greeter-plugin.h
|
|
@@ -0,0 +1,61 @@
|
|
+/*
|
|
+ * Copyright (C) 2009 Red Hat, Inc.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
+ */
|
|
+
|
|
+#ifndef __GDM_GREETER_PLUGIN
|
|
+#define __GDM_GREETER_PLUGIN
|
|
+
|
|
+#include <glib-object.h>
|
|
+#include <gtk/gtk.h>
|
|
+
|
|
+#include "gdm-greeter-extension.h"
|
|
+
|
|
+G_BEGIN_DECLS
|
|
+
|
|
+#define GDM_TYPE_GREETER_PLUGIN (gdm_greeter_plugin_get_type ())
|
|
+#define GDM_GREETER_PLUGIN(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDM_TYPE_GREETER_PLUGIN, GdmGreeterPlugin))
|
|
+#define GDM_IS_GREETER_PLUGIN(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDM_TYPE_GREETER_PLUGIN))
|
|
+
|
|
+typedef struct _GdmGreeterPlugin GdmGreeterPlugin;
|
|
+typedef struct _GdmGreeterPluginPrivate GdmGreeterPluginPrivate;
|
|
+typedef struct _GdmGreeterPluginClass GdmGreeterPluginClass;
|
|
+
|
|
+struct _GdmGreeterPlugin
|
|
+{
|
|
+ GObject parent;
|
|
+ GdmGreeterPluginPrivate *priv;
|
|
+};
|
|
+
|
|
+struct _GdmGreeterPluginClass
|
|
+{
|
|
+ GObjectClass parent_class;
|
|
+
|
|
+ void (* loaded) (GdmGreeterPlugin *plugin);
|
|
+ void (* load_failed) (GdmGreeterPlugin *plugin);
|
|
+ void (* unloaded) (GdmGreeterPlugin *plugin);
|
|
+};
|
|
+
|
|
+GType gdm_greeter_plugin_get_type (void) G_GNUC_CONST;
|
|
+GdmGreeterPlugin *gdm_greeter_plugin_new (const char *filename);
|
|
+void gdm_greeter_plugin_load (GdmGreeterPlugin *plugin);
|
|
+void gdm_greeter_plugin_unload (GdmGreeterPlugin *plugin);
|
|
+const char *gdm_greeter_plugin_get_filename (GdmGreeterPlugin *plugin);
|
|
+GdmGreeterExtension *gdm_greeter_plugin_get_extension (GdmGreeterPlugin *plugin);
|
|
+
|
|
+G_END_DECLS
|
|
+
|
|
+#endif
|
|
diff --git a/gui/simple-greeter/gdm-greeter-session.c b/gui/simple-greeter/gdm-greeter-session.c
|
|
index 79f367c..d8fd861 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-session.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-session.c
|
|
@@ -38,6 +38,8 @@
|
|
#include "gdm-greeter-panel.h"
|
|
#include "gdm-greeter-login-window.h"
|
|
|
|
+#include "gdm-plugin-manager.h"
|
|
+
|
|
#include "gdm-profile.h"
|
|
|
|
#define GDM_GREETER_SESSION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_GREETER_SESSION, GdmGreeterSessionPrivate))
|
|
@@ -45,9 +47,11 @@
|
|
struct GdmGreeterSessionPrivate
|
|
{
|
|
GdmGreeterClient *client;
|
|
+ GdmPluginManager *plugin_manager;
|
|
|
|
GtkWidget *login_window;
|
|
GtkWidget *panel;
|
|
+
|
|
};
|
|
|
|
enum {
|
|
@@ -91,7 +95,8 @@ on_ready (GdmGreeterClient *client,
|
|
{
|
|
g_debug ("GdmGreeterSession: Ready");
|
|
|
|
- gdm_greeter_login_window_ready (GDM_GREETER_LOGIN_WINDOW (session->priv->login_window));
|
|
+ gdm_greeter_login_window_ready (GDM_GREETER_LOGIN_WINDOW (session->priv->login_window),
|
|
+ service_name);
|
|
}
|
|
|
|
static void
|
|
@@ -154,10 +159,11 @@ on_timed_login_requested (GdmGreeterClient *client,
|
|
|
|
static void
|
|
on_user_authorized (GdmGreeterClient *client,
|
|
+ const char *service_name,
|
|
GdmGreeterSession *session)
|
|
{
|
|
g_debug ("GdmGreeterSession: user authorized");
|
|
- gdm_greeter_login_window_user_authorized (GDM_GREETER_LOGIN_WINDOW (session->priv->login_window));
|
|
+ gdm_greeter_login_window_user_authorized (GDM_GREETER_LOGIN_WINDOW (session->priv->login_window), service_name);
|
|
}
|
|
|
|
static void
|
|
@@ -270,7 +276,6 @@ on_cancelled (GdmGreeterLoginWindow *login_window,
|
|
{
|
|
gdm_greeter_panel_hide_user_options (GDM_GREETER_PANEL (session->priv->panel));
|
|
gdm_greeter_client_call_cancel (session->priv->client);
|
|
- gdm_greeter_client_call_start_conversation (session->priv->client, "gdm");
|
|
}
|
|
|
|
static void
|
|
@@ -282,9 +287,10 @@ on_disconnected (GdmGreeterLoginWindow *login_window,
|
|
|
|
static void
|
|
on_start_session (GdmGreeterLoginWindow *login_window,
|
|
+ const char *service_name,
|
|
GdmGreeterSession *session)
|
|
{
|
|
- gdm_greeter_client_call_start_session_when_ready (session->priv->client, "gdm", TRUE);
|
|
+ gdm_greeter_client_call_start_session_when_ready (session->priv->client, service_name, TRUE);
|
|
}
|
|
|
|
static void
|
|
@@ -400,8 +406,6 @@ gdm_greeter_session_start (GdmGreeterSession *session,
|
|
toggle_panel (session, TRUE);
|
|
toggle_login_window (session, TRUE);
|
|
|
|
- gdm_greeter_client_call_start_conversation (session->priv->client, "gdm");
|
|
-
|
|
gdm_profile_end (NULL);
|
|
|
|
return res;
|
|
@@ -511,6 +515,64 @@ gdm_greeter_session_event_handler (GdkEvent *event,
|
|
}
|
|
|
|
static void
|
|
+on_plugins_loaded (GdmGreeterSession *session)
|
|
+{
|
|
+ g_debug ("GdmGreeterSession: done loading plugins");
|
|
+}
|
|
+
|
|
+static void
|
|
+on_plugin_removed (GdmGreeterSession *session,
|
|
+ GdmGreeterPlugin *plugin)
|
|
+{
|
|
+ GdmGreeterExtension *extension;
|
|
+
|
|
+ extension = gdm_greeter_plugin_get_extension (plugin);
|
|
+
|
|
+ if (GDM_IS_GREETER_LOGIN_WINDOW_EXTENSION (extension)) {
|
|
+ gdm_greeter_login_window_remove_extension (GDM_GREETER_LOGIN_WINDOW (session->priv->login_window), extension);
|
|
+ }
|
|
+ g_object_unref (extension);
|
|
+}
|
|
+
|
|
+static void
|
|
+on_plugin_added (GdmGreeterSession *session,
|
|
+ GdmGreeterPlugin *plugin)
|
|
+{
|
|
+ GdmGreeterExtension *extension;
|
|
+
|
|
+ extension = gdm_greeter_plugin_get_extension (plugin);
|
|
+
|
|
+ if (GDM_IS_GREETER_LOGIN_WINDOW_EXTENSION (extension)) {
|
|
+ gdm_greeter_login_window_add_extension (GDM_GREETER_LOGIN_WINDOW (session->priv->login_window), extension);
|
|
+ }
|
|
+ g_object_unref (extension);
|
|
+}
|
|
+
|
|
+static void
|
|
+load_plugins (GdmGreeterSession *session)
|
|
+{
|
|
+ g_debug ("GdmGreeterSession: loading plugins");
|
|
+
|
|
+ session->priv->plugin_manager = gdm_plugin_manager_ref_default ();
|
|
+
|
|
+ g_signal_connect_swapped (session->priv->plugin_manager,
|
|
+ "plugins-loaded",
|
|
+ G_CALLBACK (on_plugins_loaded),
|
|
+ session);
|
|
+
|
|
+ g_signal_connect_swapped (session->priv->plugin_manager,
|
|
+ "plugin-added",
|
|
+ G_CALLBACK (on_plugin_added),
|
|
+ session);
|
|
+
|
|
+ g_signal_connect_swapped (session->priv->plugin_manager,
|
|
+ "plugin-removed",
|
|
+ G_CALLBACK (on_plugin_removed),
|
|
+ session);
|
|
+
|
|
+}
|
|
+
|
|
+static void
|
|
gdm_greeter_session_init (GdmGreeterSession *session)
|
|
{
|
|
gdm_profile_start (NULL);
|
|
@@ -573,6 +635,8 @@ gdm_greeter_session_init (GdmGreeterSession *session)
|
|
gdk_event_handler_set ((GdkEventFunc) gdm_greeter_session_event_handler,
|
|
session, NULL);
|
|
|
|
+
|
|
+ load_plugins (session);
|
|
gdm_profile_end (NULL);
|
|
}
|
|
|
|
diff --git a/gui/simple-greeter/gdm-plugin-manager.c b/gui/simple-greeter/gdm-plugin-manager.c
|
|
new file mode 100644
|
|
index 0000000..49e442c
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/gdm-plugin-manager.c
|
|
@@ -0,0 +1,478 @@
|
|
+/*
|
|
+ * Copyright (C) 2009 Red Hat, Inc.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
+ *
|
|
+ * Written By: Ray Strode <rstrode@redhat.com>
|
|
+ */
|
|
+
|
|
+#include "config.h"
|
|
+
|
|
+#include <glib.h>
|
|
+#include <glib/gi18n.h>
|
|
+#include <glib/gstdio.h>
|
|
+#include <glib-object.h>
|
|
+#include <gio/gio.h>
|
|
+
|
|
+#include "gdm-plugin-manager.h"
|
|
+#include "gdm-greeter-extension.h"
|
|
+
|
|
+#define GDM_PLUGIN_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_PLUGIN_MANAGER, GdmPluginManagerPrivate))
|
|
+
|
|
+typedef struct
|
|
+{
|
|
+ GModule *module;
|
|
+ char *filename;
|
|
+ GdmGreeterExtension *extension;
|
|
+} GdmPluginManagerPlugin;
|
|
+
|
|
+typedef struct
|
|
+{
|
|
+ GdmPluginManager *manager;
|
|
+ GCancellable *cancellable;
|
|
+} GdmPluginManagerOperation;
|
|
+
|
|
+struct GdmPluginManagerPrivate
|
|
+{
|
|
+ GHashTable *plugins;
|
|
+
|
|
+ GFileMonitor *plugin_dir_monitor;
|
|
+ GList *pending_operations;
|
|
+};
|
|
+
|
|
+enum {
|
|
+ PLUGINS_LOADED,
|
|
+ PLUGIN_ADDED,
|
|
+ PLUGIN_REMOVED,
|
|
+ LAST_SIGNAL
|
|
+};
|
|
+
|
|
+static guint signals [LAST_SIGNAL] = { 0, };
|
|
+
|
|
+static void gdm_plugin_manager_class_init (GdmPluginManagerClass *klass);
|
|
+static void gdm_plugin_manager_init (GdmPluginManager *plugin_manager);
|
|
+static void gdm_plugin_manager_finalize (GObject *object);
|
|
+
|
|
+static GObject *plugin_manager_object = NULL;
|
|
+
|
|
+G_DEFINE_TYPE (GdmPluginManager, gdm_plugin_manager, G_TYPE_OBJECT)
|
|
+
|
|
+static GdmPluginManagerOperation *
|
|
+start_operation (GdmPluginManager *manager)
|
|
+{
|
|
+ GdmPluginManagerOperation *operation;
|
|
+
|
|
+ operation = g_new0 (GdmPluginManagerOperation, 1);
|
|
+ operation->cancellable = g_cancellable_new ();
|
|
+ operation->manager = manager;
|
|
+
|
|
+ return operation;
|
|
+}
|
|
+
|
|
+static void
|
|
+free_operation (GdmPluginManagerOperation *operation)
|
|
+{
|
|
+ if (operation->cancellable != NULL) {
|
|
+ g_object_unref (operation->cancellable);
|
|
+ operation->cancellable = NULL;
|
|
+ }
|
|
+ g_free (operation);
|
|
+}
|
|
+
|
|
+static void
|
|
+cancel_operation (GdmPluginManagerOperation *operation)
|
|
+{
|
|
+ if (operation->cancellable != NULL &&
|
|
+ !g_cancellable_is_cancelled (operation->cancellable)) {
|
|
+ g_cancellable_cancel (operation->cancellable);
|
|
+ }
|
|
+
|
|
+ free_operation (operation);
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_plugin_manager_track_operation (GdmPluginManager *manager,
|
|
+ GdmPluginManagerOperation *operation)
|
|
+{
|
|
+ manager->priv->pending_operations =
|
|
+ g_list_prepend (manager->priv->pending_operations, operation);
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_plugin_manager_untrack_operation (GdmPluginManager *manager,
|
|
+ GdmPluginManagerOperation *operation)
|
|
+{
|
|
+ manager->priv->pending_operations =
|
|
+ g_list_remove (manager->priv->pending_operations, operation);
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_plugin_manager_cancel_pending_operations (GdmPluginManager *manager)
|
|
+{
|
|
+ GList *node;
|
|
+
|
|
+ node = manager->priv->pending_operations;
|
|
+ while (node != NULL) {
|
|
+ GList *next_node;
|
|
+ GdmPluginManagerOperation *operation;
|
|
+
|
|
+ operation = node->data;
|
|
+ next_node = node->next;
|
|
+
|
|
+ cancel_operation (operation);
|
|
+ manager->priv->pending_operations =
|
|
+ g_list_delete_link (manager->priv->pending_operations,
|
|
+ node);
|
|
+
|
|
+ node = next_node;
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_plugin_manager_class_init (GdmPluginManagerClass *klass)
|
|
+{
|
|
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
+
|
|
+ object_class->finalize = gdm_plugin_manager_finalize;
|
|
+
|
|
+ signals [PLUGINS_LOADED] =
|
|
+ g_signal_new ("plugins-loaded",
|
|
+ G_TYPE_FROM_CLASS (klass),
|
|
+ G_SIGNAL_RUN_LAST,
|
|
+ G_STRUCT_OFFSET (GdmPluginManagerClass, plugins_loaded),
|
|
+ NULL, NULL,
|
|
+ g_cclosure_marshal_VOID__VOID,
|
|
+ G_TYPE_NONE, 0);
|
|
+ signals [PLUGIN_ADDED] =
|
|
+ g_signal_new ("plugin-added",
|
|
+ G_TYPE_FROM_CLASS (klass),
|
|
+ G_SIGNAL_RUN_LAST,
|
|
+ G_STRUCT_OFFSET (GdmPluginManagerClass, plugin_added),
|
|
+ NULL, NULL,
|
|
+ g_cclosure_marshal_VOID__OBJECT,
|
|
+ G_TYPE_NONE, 1, GDM_TYPE_GREETER_PLUGIN);
|
|
+ signals [PLUGIN_REMOVED] =
|
|
+ g_signal_new ("plugin-removed",
|
|
+ G_TYPE_FROM_CLASS (klass),
|
|
+ G_SIGNAL_RUN_LAST,
|
|
+ G_STRUCT_OFFSET (GdmPluginManagerClass, plugin_removed),
|
|
+ NULL, NULL,
|
|
+ g_cclosure_marshal_VOID__OBJECT,
|
|
+ G_TYPE_NONE, 1, GDM_TYPE_GREETER_PLUGIN);
|
|
+
|
|
+ g_type_class_add_private (klass, sizeof (GdmPluginManagerPrivate));
|
|
+}
|
|
+
|
|
+static void
|
|
+on_plugin_loaded (GdmPluginManager *manager,
|
|
+ GdmGreeterPlugin *plugin)
|
|
+{
|
|
+ g_debug ("GdmPluginManager: plugin '%s' loaded.",
|
|
+ gdm_greeter_plugin_get_filename (plugin));
|
|
+ g_signal_emit (manager, signals [PLUGIN_ADDED], 0, plugin);
|
|
+}
|
|
+
|
|
+static void
|
|
+on_plugin_load_failed (GdmPluginManager *manager,
|
|
+ GdmGreeterPlugin *plugin)
|
|
+{
|
|
+ const char *filename;
|
|
+
|
|
+ g_debug ("GdmPluginManager: plugin '%s' could not be loaded.",
|
|
+ gdm_greeter_plugin_get_filename (plugin));
|
|
+ filename = gdm_greeter_plugin_get_filename (plugin);
|
|
+ g_hash_table_remove (manager->priv->plugins, filename);
|
|
+}
|
|
+
|
|
+static void
|
|
+on_plugin_unloaded (GdmPluginManager *manager,
|
|
+ GdmGreeterPlugin *plugin)
|
|
+{
|
|
+ const char *filename;
|
|
+
|
|
+ filename = gdm_greeter_plugin_get_filename (plugin);
|
|
+ g_hash_table_remove (manager->priv->plugins, filename);
|
|
+}
|
|
+
|
|
+static void
|
|
+load_plugin (GdmPluginManager *manager,
|
|
+ const char *filename)
|
|
+{
|
|
+ GdmGreeterPlugin *plugin;
|
|
+
|
|
+ g_debug ("GdmPluginManager: loading plugin '%s'", filename);
|
|
+
|
|
+ plugin = gdm_greeter_plugin_new (filename);
|
|
+
|
|
+ g_signal_connect_swapped (plugin, "loaded",
|
|
+ G_CALLBACK (on_plugin_loaded),
|
|
+ manager);
|
|
+ g_signal_connect_swapped (plugin, "load-failed",
|
|
+ G_CALLBACK (on_plugin_load_failed),
|
|
+ manager);
|
|
+ g_signal_connect_swapped (plugin, "unloaded",
|
|
+ G_CALLBACK (on_plugin_unloaded),
|
|
+ manager);
|
|
+ g_hash_table_insert (manager->priv->plugins,
|
|
+ g_strdup (filename), plugin);
|
|
+
|
|
+ gdm_greeter_plugin_load (plugin);
|
|
+}
|
|
+
|
|
+static void
|
|
+on_plugin_info_read (GFileEnumerator *enumerator,
|
|
+ GAsyncResult *result,
|
|
+ GdmPluginManagerOperation *operation)
|
|
+{
|
|
+ GdmPluginManager *manager;
|
|
+ GFile *plugin_dir_file;
|
|
+ GList *file_list, *node;
|
|
+ GError *error;
|
|
+
|
|
+ manager = operation->manager;
|
|
+ error = NULL;
|
|
+ file_list = g_file_enumerator_next_files_finish (enumerator,
|
|
+ result, &error);
|
|
+ plugin_dir_file = g_file_enumerator_get_container (enumerator);
|
|
+ if (error != NULL) {
|
|
+ char *plugin_dir;
|
|
+
|
|
+ plugin_dir = g_file_get_parse_name (plugin_dir_file);
|
|
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
|
+ g_debug ("GdmPluginManager: Cancelled reading plugin directory %s",
|
|
+ plugin_dir);
|
|
+ } else {
|
|
+ g_warning ("GdmPluginManager: Unable to read plugin directory %s: %s",
|
|
+ plugin_dir, error->message);
|
|
+ }
|
|
+ g_free (plugin_dir);
|
|
+ g_error_free (error);
|
|
+ g_object_unref (plugin_dir_file);
|
|
+ gdm_plugin_manager_untrack_operation (manager, operation);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+#ifndef PLUGIN_ORDERING_FIGURED_OUT
|
|
+ node = file_list;
|
|
+ while (node != NULL) {
|
|
+ GFileInfo *info;
|
|
+ GFile *file;
|
|
+ char *path;
|
|
+ GList *next_node;
|
|
+
|
|
+ next_node = node->next;
|
|
+
|
|
+ info = (GFileInfo *) node->data;
|
|
+
|
|
+ file = g_file_get_child (plugin_dir_file,
|
|
+ g_file_info_get_name (info));
|
|
+ path = g_file_get_path (file);
|
|
+
|
|
+ if (g_str_has_suffix (path, "password.so")) {
|
|
+ file_list = g_list_delete_link (file_list, node);
|
|
+ file_list = g_list_prepend (file_list, info);
|
|
+ next_node = NULL;
|
|
+ }
|
|
+ g_free (path);
|
|
+ g_object_unref (file);
|
|
+
|
|
+ node = next_node;
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ node = file_list;
|
|
+ while (node != NULL) {
|
|
+ GFileInfo *info;
|
|
+ GFile *file;
|
|
+ char *path;
|
|
+
|
|
+ info = (GFileInfo *) node->data;
|
|
+
|
|
+ file = g_file_get_child (plugin_dir_file,
|
|
+ g_file_info_get_name (info));
|
|
+ path = g_file_get_path (file);
|
|
+
|
|
+ if (g_str_has_suffix (path, G_MODULE_SUFFIX)) {
|
|
+ load_plugin (manager, path);
|
|
+ }
|
|
+ g_free (path);
|
|
+ g_object_unref (file);
|
|
+
|
|
+ node = node->next;
|
|
+ }
|
|
+ g_object_unref (plugin_dir_file);
|
|
+
|
|
+ gdm_plugin_manager_untrack_operation (manager, operation);
|
|
+ g_signal_emit (manager, signals [PLUGINS_LOADED], 0);
|
|
+
|
|
+ g_list_free (file_list);
|
|
+}
|
|
+
|
|
+static void
|
|
+on_plugin_dir_opened (GFile *plugin_dir_file,
|
|
+ GAsyncResult *result,
|
|
+ GdmPluginManagerOperation *open_operation)
|
|
+{
|
|
+ GdmPluginManager *manager;
|
|
+ GFileEnumerator *enumerator;
|
|
+ GError *error;
|
|
+ GdmPluginManagerOperation *operation;
|
|
+
|
|
+ manager = open_operation->manager;
|
|
+ gdm_plugin_manager_untrack_operation (manager, open_operation);
|
|
+
|
|
+ error = NULL;
|
|
+ enumerator = g_file_enumerate_children_finish (plugin_dir_file,
|
|
+ result, &error);
|
|
+
|
|
+ if (enumerator == NULL) {
|
|
+ char *plugin_dir;
|
|
+
|
|
+ plugin_dir = g_file_get_parse_name (plugin_dir_file);
|
|
+
|
|
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
|
|
+ g_debug ("GdmPluginManager: Cancelled opening plugin directory %s",
|
|
+ plugin_dir);
|
|
+ } else {
|
|
+ g_warning ("GdmPluginManager: Unable to open plugin directory %s: %s",
|
|
+ plugin_dir, error->message);
|
|
+ }
|
|
+ g_free (plugin_dir);
|
|
+ g_error_free (error);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ operation = start_operation (manager);
|
|
+
|
|
+ g_file_enumerator_next_files_async (enumerator, G_MAXINT,
|
|
+ G_PRIORITY_DEFAULT,
|
|
+ operation->cancellable,
|
|
+ (GAsyncReadyCallback)
|
|
+ on_plugin_info_read,
|
|
+ operation);
|
|
+
|
|
+ gdm_plugin_manager_track_operation (manager, operation);
|
|
+}
|
|
+
|
|
+static void
|
|
+load_plugins_in_dir (GdmPluginManager *manager,
|
|
+ const char *plugin_dir)
|
|
+{
|
|
+ GFile *plugin_dir_file;
|
|
+ GdmPluginManagerOperation *operation;
|
|
+
|
|
+ g_debug ("GdmPluginManager: loading plugins in dir '%s'", plugin_dir);
|
|
+
|
|
+ operation = start_operation (manager);
|
|
+ plugin_dir_file = g_file_new_for_path (plugin_dir);
|
|
+ g_file_enumerate_children_async (plugin_dir_file, "standard::*",
|
|
+ G_FILE_QUERY_INFO_NONE,
|
|
+ G_PRIORITY_DEFAULT,
|
|
+ operation->cancellable,
|
|
+ (GAsyncReadyCallback)
|
|
+ on_plugin_dir_opened,
|
|
+ operation);
|
|
+ g_object_unref (plugin_dir_file);
|
|
+ gdm_plugin_manager_track_operation (manager, operation);
|
|
+}
|
|
+
|
|
+static void
|
|
+on_plugin_dir_changed (GFileMonitor *monitor,
|
|
+ GFile *file,
|
|
+ GFile *other_file,
|
|
+ GFileMonitorEvent event_type,
|
|
+ GdmPluginManagerOperation *operation)
|
|
+{
|
|
+}
|
|
+
|
|
+static void
|
|
+watch_plugin_dir (GdmPluginManager *manager,
|
|
+ const char *plugin_dir)
|
|
+{
|
|
+
|
|
+ GdmPluginManagerOperation *operation;
|
|
+ GFile *file;
|
|
+ GError *error;
|
|
+
|
|
+ operation = start_operation (manager);
|
|
+
|
|
+ file = g_file_new_for_path (plugin_dir);
|
|
+ manager->priv->plugin_dir_monitor = g_file_monitor_directory (file,
|
|
+ G_FILE_MONITOR_NONE,
|
|
+ operation->cancellable,
|
|
+ &error);
|
|
+ if (manager->priv->plugin_dir_monitor != NULL) {
|
|
+ g_signal_connect (manager->priv->plugin_dir_monitor,
|
|
+ "changed",
|
|
+ G_CALLBACK (on_plugin_dir_changed),
|
|
+ operation);
|
|
+ gdm_plugin_manager_track_operation (manager, operation);
|
|
+ } else {
|
|
+ g_warning ("Unable to monitor %s: %s",
|
|
+ plugin_dir, error->message);
|
|
+ g_error_free (error);
|
|
+ free_operation (operation);
|
|
+ }
|
|
+ g_object_unref (file);
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_plugin_manager_init (GdmPluginManager *manager)
|
|
+{
|
|
+ manager->priv = GDM_PLUGIN_MANAGER_GET_PRIVATE (manager);
|
|
+
|
|
+ manager->priv->plugins = g_hash_table_new_full (g_str_hash,
|
|
+ g_str_equal,
|
|
+ g_free,
|
|
+ g_object_unref);
|
|
+ watch_plugin_dir (manager, GDM_SIMPLE_GREETER_PLUGINS_DIR);
|
|
+ load_plugins_in_dir (manager, GDM_SIMPLE_GREETER_PLUGINS_DIR);
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_plugin_manager_finalize (GObject *object)
|
|
+{
|
|
+ GdmPluginManager *manager;
|
|
+
|
|
+ manager = GDM_PLUGIN_MANAGER (object);
|
|
+
|
|
+ g_hash_table_destroy (manager->priv->plugins);
|
|
+ g_file_monitor_cancel (manager->priv->plugin_dir_monitor);
|
|
+
|
|
+ gdm_plugin_manager_cancel_pending_operations (manager);
|
|
+
|
|
+ G_OBJECT_CLASS (gdm_plugin_manager_parent_class)->finalize (object);
|
|
+}
|
|
+
|
|
+GdmPluginManager *
|
|
+gdm_plugin_manager_ref_default (void)
|
|
+{
|
|
+ if (plugin_manager_object != NULL) {
|
|
+ g_object_ref (plugin_manager_object);
|
|
+ } else {
|
|
+ plugin_manager_object = g_object_new (GDM_TYPE_PLUGIN_MANAGER, NULL);
|
|
+ g_object_add_weak_pointer (plugin_manager_object,
|
|
+ (gpointer *) &plugin_manager_object);
|
|
+ }
|
|
+
|
|
+ return GDM_PLUGIN_MANAGER (plugin_manager_object);
|
|
+}
|
|
+
|
|
+GdmGreeterPlugin *
|
|
+gdm_plugin_manager_get_plugin (GdmPluginManager *manager,
|
|
+ const char *name)
|
|
+{
|
|
+ return g_hash_table_lookup (manager->priv->plugins, name);
|
|
+}
|
|
diff --git a/gui/simple-greeter/gdm-plugin-manager.h b/gui/simple-greeter/gdm-plugin-manager.h
|
|
new file mode 100644
|
|
index 0000000..f181140
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/gdm-plugin-manager.h
|
|
@@ -0,0 +1,66 @@
|
|
+/*
|
|
+ * Copyright (C) 2009 Red Hat, Inc.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
+ *
|
|
+ * Written by: Ray Strode <rstrode@redhat.com>
|
|
+ *
|
|
+ */
|
|
+
|
|
+#ifndef __GDM_PLUGIN_MANAGER_H
|
|
+#define __GDM_PLUGIN_MANAGER_H
|
|
+
|
|
+#include <glib-object.h>
|
|
+
|
|
+#include "gdm-greeter-plugin.h"
|
|
+
|
|
+G_BEGIN_DECLS
|
|
+
|
|
+#define GDM_TYPE_PLUGIN_MANAGER (gdm_plugin_manager_get_type ())
|
|
+#define GDM_PLUGIN_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_PLUGIN_MANAGER, GdmPluginManager))
|
|
+#define GDM_PLUGIN_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_PLUGIN_MANAGER, GdmPluginManagerClass))
|
|
+#define GDM_IS_PLUGIN_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_PLUGIN_MANAGER))
|
|
+#define GDM_IS_PLUGIN_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_PLUGIN_MANAGER))
|
|
+#define GDM_PLUGIN_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_PLUGIN_MANAGER, GdmPluginManagerClass))
|
|
+
|
|
+typedef struct GdmPluginManagerPrivate GdmPluginManagerPrivate;
|
|
+
|
|
+typedef struct
|
|
+{
|
|
+ GObject parent;
|
|
+ GdmPluginManagerPrivate *priv;
|
|
+} GdmPluginManager;
|
|
+
|
|
+typedef struct
|
|
+{
|
|
+ GObjectClass parent_class;
|
|
+
|
|
+ void (* plugins_loaded) (GdmPluginManager *plugin_manager);
|
|
+ void (* plugin_added) (GdmPluginManager *plugin_manager,
|
|
+ GdmGreeterPlugin *plugin);
|
|
+ void (* plugin_removed) (GdmPluginManager *plugin_manager,
|
|
+ GdmGreeterPlugin *plugin);
|
|
+} GdmPluginManagerClass;
|
|
+
|
|
+GType gdm_plugin_manager_get_type (void);
|
|
+
|
|
+GdmPluginManager *gdm_plugin_manager_ref_default (void);
|
|
+
|
|
+GdmGreeterPlugin *gdm_plugin_manager_get_plugin (GdmPluginManager *plugin,
|
|
+ const char *name);
|
|
+
|
|
+G_END_DECLS
|
|
+
|
|
+#endif /* __GDM_PLUGIN_MANAGER_H */
|
|
diff --git a/gui/simple-greeter/gdm-task-list.c b/gui/simple-greeter/gdm-task-list.c
|
|
index e0fd3d4..71e103e 100644
|
|
--- a/gui/simple-greeter/gdm-task-list.c
|
|
+++ b/gui/simple-greeter/gdm-task-list.c
|
|
@@ -37,12 +37,6 @@
|
|
|
|
#define GDM_TASK_LIST_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_TASK_LIST, GdmTaskListPrivate))
|
|
|
|
-typedef struct
|
|
-{
|
|
- GtkWidget *radio_button;
|
|
- char *name;
|
|
-} GdmTask;
|
|
-
|
|
struct GdmTaskListPrivate
|
|
{
|
|
GtkWidget *box;
|
|
@@ -59,54 +53,123 @@ static guint signals[NUMBER_OF_SIGNALS];
|
|
|
|
static void gdm_task_list_class_init (GdmTaskListClass *klass);
|
|
static void gdm_task_list_init (GdmTaskList *task_list);
|
|
-static void gdm_task_list_finalize (GObject *object);
|
|
+static void gdm_task_list_finalize (GObject *object);
|
|
|
|
G_DEFINE_TYPE (GdmTaskList, gdm_task_list, GTK_TYPE_ALIGNMENT);
|
|
|
|
static void
|
|
on_task_toggled (GdmTaskList *widget,
|
|
- GtkRadioButton *radio_button)
|
|
+ GtkRadioButton *button)
|
|
{
|
|
GdmTask *task;
|
|
|
|
- task = g_object_get_data (G_OBJECT (radio_button), "gdm-task");
|
|
+ task = g_object_get_data (G_OBJECT (button), "gdm-task");
|
|
|
|
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radio_button))) {
|
|
- g_signal_emit (widget, signals[ACTIVATED], 0, task->name);
|
|
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) {
|
|
+ g_signal_emit (widget, signals[ACTIVATED], 0, task);
|
|
} else {
|
|
- g_signal_emit (widget, signals[DEACTIVATED], 0, task->name);
|
|
+ g_signal_emit (widget, signals[DEACTIVATED], 0, task);
|
|
+ }
|
|
+}
|
|
+
|
|
+GdmTask *
|
|
+gdm_task_list_foreach_task (GdmTaskList *task_list,
|
|
+ GdmTaskListForeachFunc search_func,
|
|
+ gpointer data)
|
|
+{
|
|
+ GList *node;
|
|
+
|
|
+ for (node = task_list->priv->tasks; node != NULL; node = node->next) {
|
|
+ GdmTask *task;
|
|
+
|
|
+ task = node->data;
|
|
+
|
|
+ if (search_func (task_list, task, data)) {
|
|
+ return g_object_ref (task);
|
|
+ }
|
|
}
|
|
+
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+static void
|
|
+on_task_enabled (GdmTaskList *task_list,
|
|
+ GdmTask *task)
|
|
+{
|
|
+ GtkWidget *button;
|
|
+
|
|
+ button = g_object_get_data (G_OBJECT (task), "gdm-task-list-button");
|
|
+
|
|
+ gtk_widget_set_sensitive (button, TRUE);
|
|
+
|
|
+}
|
|
+
|
|
+static void
|
|
+on_task_disabled (GdmTaskList *task_list,
|
|
+ GdmTask *task)
|
|
+{
|
|
+ GtkWidget *button;
|
|
+
|
|
+ button = g_object_get_data (G_OBJECT (task), "gdm-task-list-button");
|
|
+
|
|
+ gtk_widget_set_sensitive (button, FALSE);
|
|
}
|
|
|
|
void
|
|
gdm_task_list_add_task (GdmTaskList *task_list,
|
|
- const char *name,
|
|
- const char *icon_name)
|
|
+ GdmTask *task)
|
|
{
|
|
- GdmTask *task;
|
|
GtkWidget *image;
|
|
+ GtkWidget *button;
|
|
+ GIcon *icon;
|
|
+ char *description;
|
|
|
|
- task = g_new0 (GdmTask, 1);
|
|
-
|
|
- task->name = g_strdup (name);
|
|
if (task_list->priv->tasks == NULL) {
|
|
- task->radio_button = gtk_radio_button_new (NULL);
|
|
+ button = gtk_radio_button_new (NULL);
|
|
} else {
|
|
- task->radio_button = gtk_radio_button_new_from_widget (GTK_RADIO_BUTTON (((GdmTask *) task_list->priv->tasks->data)->radio_button));
|
|
+ GdmTask *previous_task;
|
|
+ GtkRadioButton *previous_button;
|
|
+
|
|
+ previous_task = GDM_TASK (task_list->priv->tasks->data);
|
|
+ previous_button = GTK_RADIO_BUTTON (g_object_get_data (G_OBJECT (previous_task), "gdm-task-list-button"));
|
|
+ button = gtk_radio_button_new_from_widget (previous_button);
|
|
}
|
|
+ g_object_set_data (G_OBJECT (task), "gdm-task-list-button", button);
|
|
+
|
|
+ g_object_set (G_OBJECT (button), "draw-indicator", FALSE, NULL);
|
|
+ g_object_set_data (G_OBJECT (button), "gdm-task", task);
|
|
+ g_signal_connect_swapped (button, "toggled",
|
|
+ G_CALLBACK (on_task_toggled),
|
|
+ task_list);
|
|
+
|
|
+ gtk_button_set_focus_on_click (GTK_BUTTON (button), FALSE);
|
|
+ gtk_widget_set_sensitive (button, gdm_task_is_enabled (task));
|
|
+
|
|
+ g_signal_connect_swapped (G_OBJECT (task), "enabled",
|
|
+ G_CALLBACK (on_task_enabled),
|
|
+ task_list);
|
|
+
|
|
+ g_signal_connect_swapped (G_OBJECT (task), "disabled",
|
|
+ G_CALLBACK (on_task_disabled),
|
|
+ task_list);
|
|
+
|
|
+ icon = gdm_task_get_icon (task);
|
|
+ image = gtk_image_new_from_gicon (icon, GTK_ICON_SIZE_SMALL_TOOLBAR);
|
|
+ g_object_unref (icon);
|
|
|
|
- g_object_set (task->radio_button, "draw-indicator", FALSE, NULL);
|
|
- g_object_set_data (G_OBJECT (task->radio_button), "gdm-task", task);
|
|
- g_signal_connect_swapped (task->radio_button,
|
|
- "toggled", G_CALLBACK (on_task_toggled), task_list);
|
|
- image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_DND);
|
|
gtk_widget_show (image);
|
|
- gtk_container_add (GTK_CONTAINER (task->radio_button), image);
|
|
- gtk_widget_show (task->radio_button);
|
|
- gtk_container_add (GTK_CONTAINER (task->radio_button), task_list->priv->box);
|
|
+ gtk_container_add (GTK_CONTAINER (button), image);
|
|
+ description = gdm_task_get_description (task);
|
|
+ gtk_widget_set_tooltip_text (button, description);
|
|
+ g_free (description);
|
|
+ gtk_widget_show (button);
|
|
|
|
- gtk_container_add (GTK_CONTAINER (task_list->priv->box), task->radio_button);
|
|
+ gtk_container_add (GTK_CONTAINER (task_list->priv->box), button);
|
|
task_list->priv->tasks = g_list_append (task_list->priv->tasks, task);
|
|
+
|
|
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) {
|
|
+ g_signal_emit (task_list, signals[ACTIVATED], 0, task);
|
|
+ }
|
|
}
|
|
|
|
static void
|
|
@@ -122,9 +185,9 @@ gdm_task_list_class_init (GdmTaskListClass *klass)
|
|
G_STRUCT_OFFSET (GdmTaskListClass, activated),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__STRING,
|
|
+ g_cclosure_marshal_VOID__OBJECT,
|
|
G_TYPE_NONE,
|
|
- 1, G_TYPE_STRING);
|
|
+ 1, G_TYPE_OBJECT);
|
|
|
|
signals [DEACTIVATED] = g_signal_new ("deactivated",
|
|
G_TYPE_FROM_CLASS (object_class),
|
|
@@ -132,22 +195,19 @@ gdm_task_list_class_init (GdmTaskListClass *klass)
|
|
G_STRUCT_OFFSET (GdmTaskListClass, deactivated),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__STRING,
|
|
+ g_cclosure_marshal_VOID__OBJECT,
|
|
G_TYPE_NONE,
|
|
- 1, G_TYPE_STRING);
|
|
+ 1, G_TYPE_OBJECT);
|
|
|
|
g_type_class_add_private (klass, sizeof (GdmTaskListPrivate));
|
|
-}
|
|
-
|
|
-static void
|
|
-gdm_task_list_init (GdmTaskList *widget)
|
|
+} static void gdm_task_list_init (GdmTaskList *widget)
|
|
{
|
|
widget->priv = GDM_TASK_LIST_GET_PRIVATE (widget);
|
|
|
|
gtk_alignment_set_padding (GTK_ALIGNMENT (widget), 0, 0, 0, 0);
|
|
gtk_alignment_set (GTK_ALIGNMENT (widget), 0.0, 0.0, 0, 0);
|
|
|
|
- widget->priv->box = gtk_hbox_new (FALSE, 2);
|
|
+ widget->priv->box = gtk_hbox_new (TRUE, 2);
|
|
gtk_widget_show (widget->priv->box);
|
|
gtk_container_add (GTK_CONTAINER (widget),
|
|
widget->priv->box);
|
|
@@ -179,20 +239,28 @@ gdm_task_list_new (void)
|
|
return GTK_WIDGET (object);
|
|
}
|
|
|
|
-const char *
|
|
-gdm_task_list_get_active_task (GdmTaskList *widget)
|
|
+gboolean
|
|
+gdm_task_list_task_is_active (GdmTaskList *task_list,
|
|
+ GdmTask *task)
|
|
{
|
|
- GList *node;
|
|
+ GtkWidget *button;
|
|
|
|
- for (node = widget->priv->tasks; node != NULL; node = node->next) {
|
|
- GdmTask *task;
|
|
+ button = g_object_get_data (G_OBJECT (task), "gdm-task-list-button");
|
|
|
|
- task = node->data;
|
|
+ return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
|
|
+}
|
|
|
|
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (task->radio_button)) ) {
|
|
- return task->name;
|
|
- }
|
|
- }
|
|
+GdmTask *
|
|
+gdm_task_list_get_active_task (GdmTaskList *widget)
|
|
+{
|
|
+ return gdm_task_list_foreach_task (widget,
|
|
+ (GdmTaskListForeachFunc)
|
|
+ gdm_task_list_task_is_active,
|
|
+ NULL);
|
|
+}
|
|
|
|
- return NULL;
|
|
+int
|
|
+gdm_task_list_get_number_of_tasks (GdmTaskList *widget)
|
|
+{
|
|
+ return g_list_length (widget->priv->tasks);
|
|
}
|
|
diff --git a/gui/simple-greeter/gdm-task-list.h b/gui/simple-greeter/gdm-task-list.h
|
|
index ade21b6..e8cc2f4 100644
|
|
--- a/gui/simple-greeter/gdm-task-list.h
|
|
+++ b/gui/simple-greeter/gdm-task-list.h
|
|
@@ -22,8 +22,11 @@
|
|
#define __GDM_TASK_LIST_H
|
|
|
|
#include <glib-object.h>
|
|
+#include <gio/gio.h>
|
|
#include <gtk/gtkalignment.h>
|
|
|
|
+#include "gdm-task.h"
|
|
+
|
|
G_BEGIN_DECLS
|
|
|
|
#define GDM_TYPE_TASK_LIST (gdm_task_list_get_type ())
|
|
@@ -34,31 +37,42 @@ G_BEGIN_DECLS
|
|
#define GDM_TASK_LIST_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_TASK_LIST, GdmTaskListClass))
|
|
|
|
typedef struct GdmTaskListPrivate GdmTaskListPrivate;
|
|
+typedef struct _GdmTaskList GdmTaskList;
|
|
|
|
-typedef struct
|
|
+typedef gboolean (* GdmTaskListForeachFunc) (GdmTaskList *task_list,
|
|
+ GdmTask *task,
|
|
+ gpointer data);
|
|
+
|
|
+struct _GdmTaskList
|
|
{
|
|
GtkAlignment parent;
|
|
GdmTaskListPrivate *priv;
|
|
-} GdmTaskList;
|
|
+};
|
|
|
|
typedef struct
|
|
{
|
|
GtkAlignmentClass parent_class;
|
|
|
|
void (* deactivated) (GdmTaskList *widget,
|
|
- const char *name);
|
|
+ GdmTask *task);
|
|
void (* activated) (GdmTaskList *widget,
|
|
- const char *name);
|
|
+ GdmTask *task);
|
|
} GdmTaskListClass;
|
|
|
|
+GType gdm_task_list_get_type (void);
|
|
+GtkWidget * gdm_task_list_new (void);
|
|
+
|
|
|
|
-GType gdm_task_list_get_type (void);
|
|
-GtkWidget * gdm_task_list_new (void);
|
|
+gboolean gdm_task_list_task_is_active (GdmTaskList *task_list,
|
|
+ GdmTask *task);
|
|
+GdmTask * gdm_task_list_get_active_task (GdmTaskList *widget);
|
|
+GdmTask * gdm_task_list_foreach_task (GdmTaskList *widget,
|
|
+ GdmTaskListForeachFunc foreach_func,
|
|
+ gpointer data);
|
|
+void gdm_task_list_add_task (GdmTaskList *widget,
|
|
+ GdmTask *task);
|
|
|
|
-const char * gdm_task_list_get_active_task (GdmTaskList *widget);
|
|
-void gdm_task_list_add_task (GdmTaskList *widget,
|
|
- const char *name,
|
|
- const char *icon_name);
|
|
+int gdm_task_list_get_number_of_tasks (GdmTaskList *widget);
|
|
G_END_DECLS
|
|
|
|
#endif /* __GDM_TASK_LIST_H */
|
|
diff --git a/gui/simple-greeter/libgdmsimplegreeter/Makefile.am b/gui/simple-greeter/libgdmsimplegreeter/Makefile.am
|
|
new file mode 100644
|
|
index 0000000..1ef5725
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/libgdmsimplegreeter/Makefile.am
|
|
@@ -0,0 +1,46 @@
|
|
+NULL =
|
|
+
|
|
+AM_CPPFLAGS = \
|
|
+ -I. \
|
|
+ -I.. \
|
|
+ -DBINDIR=\"$(bindir)\" \
|
|
+ -DDATADIR=\"$(datadir)\" \
|
|
+ -DLIBDIR=\"$(libdir)\" \
|
|
+ -DLIBEXECDIR=\"$(libexecdir)\" \
|
|
+ -DLOGDIR=\"$(logdir)\" \
|
|
+ -DPIXMAPDIR=\"$(pixmapdir)\" \
|
|
+ -DSBINDIR=\"$(sbindir)\" \
|
|
+ $(GTK_CFLAGS) \
|
|
+ $(NULL)
|
|
+
|
|
+lib_LTLIBRARIES = \
|
|
+ libgdmsimplegreeter.la \
|
|
+ $(NULL)
|
|
+
|
|
+libgdmsimplegreeter_la_SOURCES = \
|
|
+ gdm-task.h \
|
|
+ gdm-task.c \
|
|
+ gdm-conversation.h \
|
|
+ gdm-conversation.c \
|
|
+ gdm-greeter-extension.h \
|
|
+ gdm-greeter-extension.c \
|
|
+ $(NULL)
|
|
+
|
|
+libgdmsimplegreeter_la_LIBADD = \
|
|
+ $(GTK_LIBS) \
|
|
+ $(NULL)
|
|
+
|
|
+libgdmsimplegreeter_la_LDFLAGS = \
|
|
+ -export-symbols-regex '^[^_].*' \
|
|
+ -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \
|
|
+ -no-undefined \
|
|
+ $(NULL)
|
|
+
|
|
+headersdir = $(includedir)/gdm/simple-greeter
|
|
+headers_HEADERS = gdm-greeter-extension.h
|
|
+
|
|
+pkgconfigdir = $(libdir)/pkgconfig
|
|
+pkgconfig_DATA = gdmsimplegreeter.pc
|
|
+
|
|
+EXTRA_DIST = gdmsimplegreeter.pc
|
|
+MAINTAINERCLEANFILES = Makefile.in
|
|
diff --git a/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.c b/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.c
|
|
new file mode 100644
|
|
index 0000000..e21c56b
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.c
|
|
@@ -0,0 +1,147 @@
|
|
+/*
|
|
+ * Copyright (C) 2009 Red Hat, Inc.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
+ *
|
|
+ * Written By: Ray Strode <rstrode@redhat.com>
|
|
+ *
|
|
+ */
|
|
+
|
|
+#include <glib.h>
|
|
+#include <glib-object.h>
|
|
+
|
|
+#include <gtk/gtk.h>
|
|
+
|
|
+#include "gdm-conversation.h"
|
|
+#include "gdm-task.h"
|
|
+
|
|
+
|
|
+enum {
|
|
+ ANSWER,
|
|
+ LAST_SIGNAL
|
|
+};
|
|
+
|
|
+static guint signals [LAST_SIGNAL] = { 0, };
|
|
+
|
|
+static void gdm_conversation_class_init (gpointer g_iface);
|
|
+
|
|
+GType
|
|
+gdm_conversation_get_type (void)
|
|
+{
|
|
+ static GType type = 0;
|
|
+
|
|
+ if (!type) {
|
|
+ type = g_type_register_static_simple (G_TYPE_INTERFACE,
|
|
+ "GdmConversation",
|
|
+ sizeof (GdmConversationIface),
|
|
+ (GClassInitFunc) gdm_conversation_class_init,
|
|
+ 0, NULL, 0);
|
|
+
|
|
+ g_type_interface_add_prerequisite (type, G_TYPE_OBJECT);
|
|
+ g_type_interface_add_prerequisite (type, GDM_TYPE_TASK);
|
|
+ }
|
|
+
|
|
+ return type;
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_conversation_class_init (gpointer g_iface)
|
|
+{
|
|
+ GType iface_type = G_TYPE_FROM_INTERFACE (g_iface);
|
|
+
|
|
+ signals [ANSWER] =
|
|
+ g_signal_new ("answer",
|
|
+ iface_type,
|
|
+ G_SIGNAL_RUN_FIRST,
|
|
+ G_STRUCT_OFFSET (GdmConversationIface, answer),
|
|
+ NULL,
|
|
+ NULL,
|
|
+ g_cclosure_marshal_VOID__STRING,
|
|
+ G_TYPE_NONE,
|
|
+ 1, G_TYPE_STRING);
|
|
+}
|
|
+
|
|
+void
|
|
+gdm_conversation_set_message (GdmConversation *conversation,
|
|
+ const char *message)
|
|
+{
|
|
+ GDM_CONVERSATION_GET_IFACE (conversation)->set_message (conversation, message);
|
|
+}
|
|
+
|
|
+void
|
|
+gdm_conversation_ask_question (GdmConversation *conversation,
|
|
+ const char *message)
|
|
+{
|
|
+ GDM_CONVERSATION_GET_IFACE (conversation)->ask_question (conversation, message);
|
|
+}
|
|
+
|
|
+void
|
|
+gdm_conversation_ask_secret (GdmConversation *conversation,
|
|
+ const char *message)
|
|
+{
|
|
+ GDM_CONVERSATION_GET_IFACE (conversation)->ask_secret (conversation, message);
|
|
+}
|
|
+
|
|
+void
|
|
+gdm_conversation_reset (GdmConversation *conversation)
|
|
+{
|
|
+ return GDM_CONVERSATION_GET_IFACE (conversation)->reset (conversation);
|
|
+}
|
|
+
|
|
+void
|
|
+gdm_conversation_set_ready (GdmConversation *conversation)
|
|
+{
|
|
+ return GDM_CONVERSATION_GET_IFACE (conversation)->set_ready (conversation);
|
|
+}
|
|
+
|
|
+char *
|
|
+gdm_conversation_get_service_name (GdmConversation *conversation)
|
|
+{
|
|
+ return GDM_CONVERSATION_GET_IFACE (conversation)->get_service_name (conversation);
|
|
+}
|
|
+
|
|
+GtkWidget *
|
|
+gdm_conversation_get_page (GdmConversation *conversation)
|
|
+{
|
|
+ return GDM_CONVERSATION_GET_IFACE (conversation)->get_page (conversation);
|
|
+}
|
|
+
|
|
+GtkActionGroup *
|
|
+gdm_conversation_get_actions (GdmConversation *conversation)
|
|
+{
|
|
+ return GDM_CONVERSATION_GET_IFACE (conversation)->get_actions (conversation);
|
|
+}
|
|
+
|
|
+gboolean
|
|
+gdm_conversation_focus (GdmConversation *conversation)
|
|
+{
|
|
+ return GDM_CONVERSATION_GET_IFACE (conversation)->focus (conversation);
|
|
+}
|
|
+
|
|
+void
|
|
+gdm_conversation_request_answer (GdmConversation *conversation)
|
|
+{
|
|
+ return GDM_CONVERSATION_GET_IFACE (conversation)->request_answer (conversation);
|
|
+}
|
|
+
|
|
+/* protected
|
|
+ */
|
|
+void
|
|
+gdm_conversation_answer (GdmConversation *conversation,
|
|
+ const char *answer)
|
|
+{
|
|
+ g_signal_emit (conversation, signals [ANSWER], 0, answer);
|
|
+}
|
|
+
|
|
diff --git a/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.h b/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.h
|
|
new file mode 100644
|
|
index 0000000..f1910cf
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.h
|
|
@@ -0,0 +1,87 @@
|
|
+/*
|
|
+ * Copyright (C) Red Hat, Inc.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
+ *
|
|
+ * Written by: Ray Strode <rstrode@redhat.com>
|
|
+ */
|
|
+
|
|
+
|
|
+#ifndef __GDM_CONVERSATION_H
|
|
+#define __GDM_CONVERSATION_H
|
|
+
|
|
+#include <glib-object.h>
|
|
+#include <gtk/gtk.h>
|
|
+
|
|
+G_BEGIN_DECLS
|
|
+
|
|
+#define GDM_TYPE_CONVERSATION (gdm_conversation_get_type ())
|
|
+#define GDM_CONVERSATION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_CONVERSATION, GdmConversation))
|
|
+#define GDM_CONVERSATION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_CONVERSATION, GdmConversationIface))
|
|
+#define GDM_IS_CONVERSATION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_CONVERSATION))
|
|
+#define GDM_CONVERSATION_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), GDM_TYPE_CONVERSATION, GdmConversationIface))
|
|
+
|
|
+#define GDM_CONVERSATION_DEFAULT_ACTION "default-action"
|
|
+
|
|
+typedef struct _GdmConversation GdmConversation;
|
|
+typedef struct _GdmConversationIface GdmConversationIface;
|
|
+
|
|
+struct _GdmConversationIface
|
|
+{
|
|
+ GTypeInterface base_iface;
|
|
+
|
|
+ /* methods */
|
|
+ void (* set_message) (GdmConversation *conversation,
|
|
+ const char *message);
|
|
+ void (* ask_question) (GdmConversation *conversation,
|
|
+ const char *message);
|
|
+ void (* ask_secret) (GdmConversation *conversation,
|
|
+ const char *message);
|
|
+ void (* reset) (GdmConversation *conversation);
|
|
+ void (* set_ready) (GdmConversation *conversation);
|
|
+ char * (* get_service_name) (GdmConversation *conversation);
|
|
+ GtkWidget * (* get_page) (GdmConversation *conversation);
|
|
+ GtkActionGroup * (* get_actions) (GdmConversation *conversation);
|
|
+ void (* request_answer) (GdmConversation *conversation);
|
|
+ gboolean (* focus) (GdmConversation *conversation);
|
|
+
|
|
+ /* signals */
|
|
+ char * (* answer) (GdmConversation *conversation);
|
|
+};
|
|
+
|
|
+GType gdm_conversation_get_type (void) G_GNUC_CONST;
|
|
+
|
|
+void gdm_conversation_set_message (GdmConversation *conversation,
|
|
+ const char *message);
|
|
+void gdm_conversation_ask_question (GdmConversation *conversation,
|
|
+ const char *message);
|
|
+void gdm_conversation_ask_secret (GdmConversation *conversation,
|
|
+ const char *message);
|
|
+void gdm_conversation_reset (GdmConversation *converastion);
|
|
+void gdm_conversation_set_ready (GdmConversation *converastion);
|
|
+char *gdm_conversation_get_service_name (GdmConversation *conversation);
|
|
+GtkWidget *gdm_conversation_get_page (GdmConversation *conversation);
|
|
+GtkActionGroup *gdm_conversation_get_actions (GdmConversation *conversation);
|
|
+void gdm_conversation_request_answer (GdmConversation *conversation);
|
|
+gboolean gdm_conversation_focus (GdmConversation *conversation);
|
|
+
|
|
+/* protected
|
|
+ */
|
|
+void gdm_conversation_answer (GdmConversation *conversation,
|
|
+ const char *answer);
|
|
+
|
|
+G_END_DECLS
|
|
+
|
|
+#endif /* __GDM_CONVERSATION_H */
|
|
diff --git a/gui/simple-greeter/libgdmsimplegreeter/gdm-greeter-extension.c b/gui/simple-greeter/libgdmsimplegreeter/gdm-greeter-extension.c
|
|
new file mode 100644
|
|
index 0000000..a71d3f7
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/libgdmsimplegreeter/gdm-greeter-extension.c
|
|
@@ -0,0 +1,93 @@
|
|
+/*
|
|
+ * Copyright (C) 2009 Red Hat, Inc.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
+ *
|
|
+ * Written By: Ray Strode <rstrode@redhat.com>
|
|
+ *
|
|
+ */
|
|
+
|
|
+#include <glib.h>
|
|
+#include <glib-object.h>
|
|
+
|
|
+#include "gdm-greeter-extension.h"
|
|
+
|
|
+enum {
|
|
+ LOADED,
|
|
+ LOAD_FAILED,
|
|
+ LAST_SIGNAL
|
|
+};
|
|
+
|
|
+static guint signals [LAST_SIGNAL] = { 0, };
|
|
+
|
|
+static void gdm_greeter_extension_class_init (gpointer g_iface);
|
|
+
|
|
+GType
|
|
+gdm_greeter_extension_get_type (void)
|
|
+{
|
|
+ static GType greeter_extension_type = 0;
|
|
+
|
|
+ if (!greeter_extension_type) {
|
|
+ greeter_extension_type = g_type_register_static_simple (G_TYPE_INTERFACE,
|
|
+ "GdmGreeterExtension",
|
|
+ sizeof (GdmGreeterExtensionIface),
|
|
+ (GClassInitFunc) gdm_greeter_extension_class_init,
|
|
+ 0, NULL, 0);
|
|
+
|
|
+ g_type_interface_add_prerequisite (greeter_extension_type, G_TYPE_OBJECT);
|
|
+ }
|
|
+
|
|
+ return greeter_extension_type;
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_greeter_extension_class_init (gpointer g_iface)
|
|
+{
|
|
+ GType iface_type = G_TYPE_FROM_INTERFACE (g_iface);
|
|
+
|
|
+ signals [LOADED] =
|
|
+ g_signal_new ("loaded",
|
|
+ iface_type,
|
|
+ G_SIGNAL_RUN_FIRST,
|
|
+ G_STRUCT_OFFSET (GdmGreeterExtensionIface, loaded),
|
|
+ NULL,
|
|
+ NULL,
|
|
+ g_cclosure_marshal_VOID__VOID,
|
|
+ G_TYPE_NONE, 0);
|
|
+
|
|
+ signals [LOADED] =
|
|
+ g_signal_new ("load_failed",
|
|
+ iface_type,
|
|
+ G_SIGNAL_RUN_FIRST,
|
|
+ G_STRUCT_OFFSET (GdmGreeterExtensionIface, load_failed),
|
|
+ NULL,
|
|
+ NULL,
|
|
+ g_cclosure_marshal_VOID__POINTER,
|
|
+ G_TYPE_NONE,
|
|
+ 1, G_TYPE_POINTER);
|
|
+}
|
|
+
|
|
+void
|
|
+gdm_greeter_extension_loaded (GdmGreeterExtension *extension)
|
|
+{
|
|
+ g_signal_emit (extension, signals [LOADED], 0);
|
|
+}
|
|
+
|
|
+void
|
|
+gdm_greeter_extension_load_failed (GdmGreeterExtension *extension,
|
|
+ GError *error)
|
|
+{
|
|
+ g_signal_emit (extension, signals [LOAD_FAILED], 0, error);
|
|
+}
|
|
diff --git a/gui/simple-greeter/libgdmsimplegreeter/gdm-greeter-extension.h b/gui/simple-greeter/libgdmsimplegreeter/gdm-greeter-extension.h
|
|
new file mode 100644
|
|
index 0000000..283ba0e
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/libgdmsimplegreeter/gdm-greeter-extension.h
|
|
@@ -0,0 +1,55 @@
|
|
+/*
|
|
+ * Copyright 2009 Red Hat, Inc. *
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
+ *
|
|
+ * Written by: Ray Strode
|
|
+ */
|
|
+
|
|
+#ifndef __GDM_GREETER_EXTENSION_H
|
|
+#define __GDM_GREETER_EXTENSION_H
|
|
+
|
|
+#include <glib-object.h>
|
|
+
|
|
+G_BEGIN_DECLS
|
|
+
|
|
+#define GDM_TYPE_GREETER_EXTENSION (gdm_greeter_extension_get_type ())
|
|
+#define GDM_GREETER_EXTENSION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_GREETER_EXTENSION, GdmGreeterExtension))
|
|
+#define GDM_GREETER_EXTENSION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_GREETER_EXTENSION, GdmGreeterExtensionClass))
|
|
+#define GDM_IS_GREETER_EXTENSION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_GREETER_EXTENSION))
|
|
+#define GDM_GREETER_EXTENSION_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), GDM_TYPE_GREETER_EXTENSION, GdmGreeterExtensionIface))
|
|
+
|
|
+typedef struct _GdmGreeterExtension GdmGreeterExtension;
|
|
+typedef struct _GdmGreeterExtensionIface GdmGreeterExtensionIface;
|
|
+
|
|
+struct _GdmGreeterExtensionIface
|
|
+{
|
|
+ GTypeInterface base_iface;
|
|
+
|
|
+ void (* loaded) (GdmGreeterExtension *extension);
|
|
+ void (* load_failed) (GdmGreeterExtension *extension,
|
|
+ GError *error);
|
|
+};
|
|
+
|
|
+GType gdm_greeter_extension_get_type (void) G_GNUC_CONST;
|
|
+
|
|
+void gdm_greeter_extension_loaded (GdmGreeterExtension *extension);
|
|
+void gdm_greeter_extension_load_failed (GdmGreeterExtension *extension,
|
|
+ GError *error);
|
|
+
|
|
+typedef GdmGreeterExtension * (* GdmGreeterPluginGetExtensionFunc) (void);
|
|
+
|
|
+G_END_DECLS
|
|
+#endif /* __GDM_GREETER_EXTENSION_H */
|
|
diff --git a/gui/simple-greeter/libgdmsimplegreeter/gdm-task.c b/gui/simple-greeter/libgdmsimplegreeter/gdm-task.c
|
|
new file mode 100644
|
|
index 0000000..f72fa78
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/libgdmsimplegreeter/gdm-task.c
|
|
@@ -0,0 +1,117 @@
|
|
+/*
|
|
+ * Copyright (C) 2009 Red Hat, Inc.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
+ *
|
|
+ * Written By: Ray Strode <rstrode@redhat.com>
|
|
+ *
|
|
+ */
|
|
+
|
|
+#include <glib.h>
|
|
+#include <glib-object.h>
|
|
+
|
|
+#include "gdm-task.h"
|
|
+
|
|
+enum {
|
|
+ ENABLED,
|
|
+ DISABLED,
|
|
+ LAST_SIGNAL
|
|
+};
|
|
+
|
|
+static guint signals [LAST_SIGNAL] = { 0, };
|
|
+static void gdm_task_class_init (gpointer g_iface);
|
|
+
|
|
+GType
|
|
+gdm_task_get_type (void)
|
|
+{
|
|
+ static GType task_type = 0;
|
|
+
|
|
+ if (!task_type) {
|
|
+ task_type = g_type_register_static_simple (G_TYPE_INTERFACE,
|
|
+ "GdmTask",
|
|
+ sizeof (GdmTaskIface),
|
|
+ (GClassInitFunc) gdm_task_class_init,
|
|
+ 0, NULL, 0);
|
|
+
|
|
+ g_type_interface_add_prerequisite (task_type, G_TYPE_OBJECT);
|
|
+ }
|
|
+
|
|
+ return task_type;
|
|
+}
|
|
+
|
|
+GIcon *
|
|
+gdm_task_get_icon (GdmTask *task)
|
|
+{
|
|
+ return GDM_TASK_GET_IFACE (task)->get_icon (task);
|
|
+}
|
|
+
|
|
+char *
|
|
+gdm_task_get_description (GdmTask *task)
|
|
+{
|
|
+ return GDM_TASK_GET_IFACE (task)->get_description (task);
|
|
+}
|
|
+
|
|
+char *
|
|
+gdm_task_get_name (GdmTask *task)
|
|
+{
|
|
+ return GDM_TASK_GET_IFACE (task)->get_name (task);
|
|
+}
|
|
+
|
|
+void
|
|
+gdm_task_set_enabled (GdmTask *task,
|
|
+ gboolean should_enable)
|
|
+{
|
|
+ g_object_set_data (G_OBJECT (task), "gdm-task-is-disabled", GINT_TO_POINTER (!should_enable));
|
|
+
|
|
+ if (should_enable) {
|
|
+ g_signal_emit (G_OBJECT (task), signals [ENABLED], 0);
|
|
+ } else {
|
|
+ g_signal_emit (G_OBJECT (task), signals [DISABLED], 0);
|
|
+ }
|
|
+}
|
|
+
|
|
+gboolean
|
|
+gdm_task_is_enabled (GdmTask *task)
|
|
+{
|
|
+ return !g_object_get_data (G_OBJECT (task), "gdm-task-is-disabled");
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_task_class_init (gpointer g_iface)
|
|
+{
|
|
+ GType iface_type = G_TYPE_FROM_INTERFACE (g_iface);
|
|
+
|
|
+ signals [ENABLED] =
|
|
+ g_signal_new ("enabled",
|
|
+ iface_type,
|
|
+ G_SIGNAL_RUN_FIRST,
|
|
+ G_STRUCT_OFFSET (GdmTaskIface, enabled),
|
|
+ NULL,
|
|
+ NULL,
|
|
+ g_cclosure_marshal_VOID__VOID,
|
|
+ G_TYPE_NONE,
|
|
+ 0);
|
|
+
|
|
+ signals [DISABLED] =
|
|
+ g_signal_new ("disabled",
|
|
+ iface_type,
|
|
+ G_SIGNAL_RUN_FIRST,
|
|
+ G_STRUCT_OFFSET (GdmTaskIface, disabled),
|
|
+ NULL,
|
|
+ NULL,
|
|
+ g_cclosure_marshal_VOID__VOID,
|
|
+ G_TYPE_NONE,
|
|
+ 0);
|
|
+}
|
|
diff --git a/gui/simple-greeter/libgdmsimplegreeter/gdm-task.h b/gui/simple-greeter/libgdmsimplegreeter/gdm-task.h
|
|
new file mode 100644
|
|
index 0000000..9894e65
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/libgdmsimplegreeter/gdm-task.h
|
|
@@ -0,0 +1,62 @@
|
|
+/*
|
|
+ * Copyright (C) Red Hat, Inc.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
+ *
|
|
+ * Written by: Ray Strode <rstrode@redhat.com>
|
|
+ */
|
|
+
|
|
+
|
|
+#ifndef __GDM_TASK_H
|
|
+#define __GDM_TASK_H
|
|
+
|
|
+#include <glib-object.h>
|
|
+#include <gio/gio.h>
|
|
+
|
|
+G_BEGIN_DECLS
|
|
+
|
|
+#define GDM_TYPE_TASK (gdm_task_get_type ())
|
|
+#define GDM_TASK(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_TASK, GdmTask))
|
|
+#define GDM_TASK_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_TASK, GdmTaskIface))
|
|
+#define GDM_IS_TASK(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_TASK))
|
|
+#define GDM_TASK_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), GDM_TYPE_TASK, GdmTaskIface))
|
|
+
|
|
+typedef struct _GdmTask GdmTask;
|
|
+typedef struct _GdmTaskIface GdmTaskIface;
|
|
+
|
|
+struct _GdmTaskIface
|
|
+{
|
|
+ GTypeInterface base_iface;
|
|
+
|
|
+ /* methods */
|
|
+ GIcon * (* get_icon) (GdmTask *task);
|
|
+ char * (* get_description) (GdmTask *task);
|
|
+ char * (* get_name) (GdmTask *task);
|
|
+ /* signals */
|
|
+ void (* enabled) (GdmTask *task);
|
|
+ void (* disabled) (GdmTask *task);
|
|
+};
|
|
+
|
|
+GType gdm_task_get_type (void) G_GNUC_CONST;
|
|
+
|
|
+GIcon *gdm_task_get_icon (GdmTask *task);
|
|
+char *gdm_task_get_description (GdmTask *task);
|
|
+char *gdm_task_get_name (GdmTask *task);
|
|
+void gdm_task_set_enabled (GdmTask *task,
|
|
+ gboolean should_enable);
|
|
+gboolean gdm_task_is_enabled (GdmTask *task);
|
|
+G_END_DECLS
|
|
+
|
|
+#endif /* __GDM_TASK_H */
|
|
diff --git a/gui/simple-greeter/libgdmsimplegreeter/gdmsimplegreeter.pc.in b/gui/simple-greeter/libgdmsimplegreeter/gdmsimplegreeter.pc.in
|
|
new file mode 100644
|
|
index 0000000..a429d99
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/libgdmsimplegreeter/gdmsimplegreeter.pc.in
|
|
@@ -0,0 +1,11 @@
|
|
+prefix=@prefix@
|
|
+exec_prefix=@exec_prefix@
|
|
+libdir=@libdir@
|
|
+includedir=@includedir@
|
|
+pluginsdir=@GDM_SIMPLE_GREETER_PLUGINS_DIR@
|
|
+
|
|
+Name: GDM Simple Greeter
|
|
+Description: Library for GDM Simple Greeter Plugins
|
|
+Version: @VERSION@
|
|
+Libs: -L${libdir} -lgdmsimplegreeter
|
|
+Cflags: -I${includedir}/gdm/simple-greeter
|
|
diff --git a/gui/simple-greeter/plugins/Makefile.am b/gui/simple-greeter/plugins/Makefile.am
|
|
new file mode 100644
|
|
index 0000000..c0390db
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/plugins/Makefile.am
|
|
@@ -0,0 +1 @@
|
|
+SUBDIRS = password
|
|
diff --git a/gui/simple-greeter/plugins/password/Makefile.am b/gui/simple-greeter/plugins/password/Makefile.am
|
|
new file mode 100644
|
|
index 0000000..18b9801
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/plugins/password/Makefile.am
|
|
@@ -0,0 +1,40 @@
|
|
+NULL =
|
|
+
|
|
+AM_CPPFLAGS = \
|
|
+ -I$(top_srcdir)/common \
|
|
+ -I$(top_srcdir)/gui/simple-greeter/libnotificationarea \
|
|
+ -I$(top_srcdir)/gui/simple-greeter/libgdmsimplegreeter \
|
|
+ -DDMCONFDIR=\""$(dmconfdir)"\" \
|
|
+ -DGDMCONFDIR=\"$(gdmconfdir)\" \
|
|
+ -DDATADIR=\""$(datadir)"\" \
|
|
+ -DSYSCONFDIR=\""$(sysconfdir)"\" \
|
|
+ -DLIBLOCALEDIR=\""$(prefix)/lib/locale"\" \
|
|
+ -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
|
|
+ -DLIBEXECDIR=\""$(libexecdir)"\" \
|
|
+ -DSBINDIR=\""$(sbindir)"\" \
|
|
+ $(DISABLE_DEPRECATED_CFLAGS) \
|
|
+ $(GTK_CFLAGS) \
|
|
+ $(SIMPLE_GREETER_CFLAGS) \
|
|
+ $(POLKIT_GNOME_CFLAGS) \
|
|
+ $(NULL)
|
|
+
|
|
+plugindir = $(GDM_SIMPLE_GREETER_PLUGINS_DIR)
|
|
+plugin_LTLIBRARIES = password.la
|
|
+
|
|
+password_la_CFLAGS = \
|
|
+ $(SIMPLE_GREETER_CFLAGS) \
|
|
+ $(NULL)
|
|
+
|
|
+password_la_LDFLAGS = -module -avoid-version -export-dynamic
|
|
+password_la_LIBADD = ../../../../common/libgdmcommon.la \
|
|
+ ../../libgdmsimplegreeter/libgdmsimplegreeter.la
|
|
+password_la_SOURCES = \
|
|
+ gdm-password-extension.h \
|
|
+ gdm-password-extension.c \
|
|
+ plugin.c
|
|
+
|
|
+EXTRA_DIST = gdm-password
|
|
+
|
|
+MAINTAINERCLEANFILES = \
|
|
+ *~ \
|
|
+ Makefile.in
|
|
diff --git a/gui/simple-greeter/plugins/password/gdm-password-extension.c b/gui/simple-greeter/plugins/password/gdm-password-extension.c
|
|
new file mode 100644
|
|
index 0000000..80c9ea7
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/plugins/password/gdm-password-extension.c
|
|
@@ -0,0 +1,316 @@
|
|
+/*
|
|
+ * Copyright (C) 2009 Red Hat, Inc.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
+ *
|
|
+ * Written By: Ray Strode <rstrode@redhat.com>
|
|
+ *
|
|
+ */
|
|
+
|
|
+#include <config.h>
|
|
+#include "gdm-password-extension.h"
|
|
+#include "gdm-conversation.h"
|
|
+#include "gdm-task.h"
|
|
+
|
|
+#include <glib/gi18n-lib.h>
|
|
+#include <gio/gio.h>
|
|
+#include <gtk/gtk.h>
|
|
+
|
|
+struct _GdmPasswordExtensionPrivate
|
|
+{
|
|
+ GIcon *icon;
|
|
+ GtkWidget *page;
|
|
+ GtkActionGroup *actions;
|
|
+
|
|
+ GtkWidget *message_label;
|
|
+ GtkWidget *prompt_label;
|
|
+ GtkWidget *prompt_entry;
|
|
+
|
|
+ guint answer_pending : 1;
|
|
+};
|
|
+
|
|
+static void gdm_password_extension_finalize (GObject *object);
|
|
+
|
|
+static void gdm_task_iface_init (GdmTaskIface *iface);
|
|
+static void gdm_conversation_iface_init (GdmConversationIface *iface);
|
|
+static void gdm_greeter_extension_iface_init (GdmGreeterExtensionIface *iface);
|
|
+
|
|
+G_DEFINE_TYPE_WITH_CODE (GdmPasswordExtension,
|
|
+ gdm_password_extension,
|
|
+ G_TYPE_OBJECT,
|
|
+ G_IMPLEMENT_INTERFACE (GDM_TYPE_GREETER_EXTENSION,
|
|
+ gdm_greeter_extension_iface_init)
|
|
+ G_IMPLEMENT_INTERFACE (GDM_TYPE_TASK,
|
|
+ gdm_task_iface_init)
|
|
+ G_IMPLEMENT_INTERFACE (GDM_TYPE_CONVERSATION,
|
|
+ gdm_conversation_iface_init));
|
|
+
|
|
+static void
|
|
+gdm_password_extension_set_message (GdmConversation *conversation,
|
|
+ const char *message)
|
|
+{
|
|
+ GdmPasswordExtension *extension = GDM_PASSWORD_EXTENSION (conversation);
|
|
+ gtk_widget_show (extension->priv->message_label);
|
|
+ gtk_label_set_text (GTK_LABEL (extension->priv->message_label), message);
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_password_extension_ask_question (GdmConversation *conversation,
|
|
+ const char *message)
|
|
+{
|
|
+ GdmPasswordExtension *extension = GDM_PASSWORD_EXTENSION (conversation);
|
|
+ gtk_widget_show (extension->priv->prompt_label);
|
|
+ gtk_label_set_text (GTK_LABEL (extension->priv->prompt_label), message);
|
|
+ gtk_entry_set_text (GTK_ENTRY (extension->priv->prompt_entry), "");
|
|
+ gtk_entry_set_visibility (GTK_ENTRY (extension->priv->prompt_entry), TRUE);
|
|
+ gtk_widget_show (extension->priv->prompt_entry);
|
|
+ gtk_widget_grab_focus (extension->priv->prompt_entry);
|
|
+ extension->priv->answer_pending = TRUE;
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_password_extension_ask_secret (GdmConversation *conversation,
|
|
+ const char *message)
|
|
+{
|
|
+ GdmPasswordExtension *extension = GDM_PASSWORD_EXTENSION (conversation);
|
|
+ gtk_widget_show (extension->priv->prompt_label);
|
|
+ gtk_label_set_text (GTK_LABEL (extension->priv->prompt_label), message);
|
|
+ gtk_entry_set_visibility (GTK_ENTRY (extension->priv->prompt_entry), FALSE);
|
|
+ gtk_entry_set_text (GTK_ENTRY (extension->priv->prompt_entry), "");
|
|
+ gtk_widget_show (extension->priv->prompt_entry);
|
|
+ gtk_widget_grab_focus (extension->priv->prompt_entry);
|
|
+ extension->priv->answer_pending = TRUE;
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_password_extension_reset (GdmConversation *conversation)
|
|
+{
|
|
+ GdmPasswordExtension *extension = GDM_PASSWORD_EXTENSION (conversation);
|
|
+ gtk_widget_hide (extension->priv->prompt_label);
|
|
+ gtk_label_set_text (GTK_LABEL (extension->priv->prompt_label), "");
|
|
+
|
|
+ gtk_widget_hide (extension->priv->prompt_entry);
|
|
+ gtk_entry_set_text (GTK_ENTRY (extension->priv->prompt_entry), "");
|
|
+ gtk_entry_set_visibility (GTK_ENTRY (extension->priv->prompt_entry), TRUE);
|
|
+ extension->priv->answer_pending = FALSE;
|
|
+
|
|
+ gdm_task_set_enabled (GDM_TASK (conversation), FALSE);
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_password_extension_set_ready (GdmConversation *conversation)
|
|
+{
|
|
+ gdm_task_set_enabled (GDM_TASK (conversation), TRUE);
|
|
+}
|
|
+
|
|
+char *
|
|
+gdm_password_extension_get_service_name (GdmConversation *conversation)
|
|
+{
|
|
+ return g_strdup ("gdm");
|
|
+}
|
|
+
|
|
+GtkWidget *
|
|
+gdm_password_extension_get_page (GdmConversation *conversation)
|
|
+{
|
|
+ GdmPasswordExtension *extension = GDM_PASSWORD_EXTENSION (conversation);
|
|
+ return extension->priv->page;
|
|
+}
|
|
+
|
|
+GtkActionGroup *
|
|
+gdm_password_extension_get_actions (GdmConversation *conversation)
|
|
+{
|
|
+ GdmPasswordExtension *extension = GDM_PASSWORD_EXTENSION (conversation);
|
|
+ return g_object_ref (extension->priv->actions);
|
|
+}
|
|
+
|
|
+void
|
|
+gdm_password_extension_request_answer (GdmConversation *conversation)
|
|
+{
|
|
+ GdmPasswordExtension *extension = GDM_PASSWORD_EXTENSION (conversation);
|
|
+ const char *text;
|
|
+
|
|
+ if (!extension->priv->answer_pending) {
|
|
+ gdm_conversation_answer (conversation, NULL);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ extension->priv->answer_pending = FALSE;
|
|
+ text = gtk_entry_get_text (GTK_ENTRY (extension->priv->prompt_entry));
|
|
+ gdm_conversation_answer (conversation, text);
|
|
+
|
|
+ gtk_widget_hide (extension->priv->prompt_entry);
|
|
+ gtk_widget_hide (extension->priv->prompt_label);
|
|
+ gtk_label_set_text (GTK_LABEL (extension->priv->prompt_label), "");
|
|
+ gtk_entry_set_text (GTK_ENTRY (extension->priv->prompt_entry), "");
|
|
+}
|
|
+
|
|
+gboolean
|
|
+gdm_password_extension_focus (GdmConversation *conversation)
|
|
+{
|
|
+ GdmPasswordExtension *extension = GDM_PASSWORD_EXTENSION (conversation);
|
|
+ if (!extension->priv->answer_pending) {
|
|
+ gdm_conversation_answer (conversation, NULL);
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ gtk_widget_grab_focus (extension->priv->prompt_entry);
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+GIcon *
|
|
+gdm_password_extension_get_icon (GdmTask *task)
|
|
+{
|
|
+ GdmPasswordExtension *extension = GDM_PASSWORD_EXTENSION (task);
|
|
+ return g_object_ref (extension->priv->icon);
|
|
+}
|
|
+
|
|
+char *
|
|
+gdm_password_extension_get_name (GdmTask *task)
|
|
+{
|
|
+ return g_strdup (_("Password Authentication"));
|
|
+}
|
|
+
|
|
+char *
|
|
+gdm_password_extension_get_description (GdmTask *task)
|
|
+{
|
|
+ return g_strdup (_("Log into session with username and password"));
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_task_iface_init (GdmTaskIface *iface)
|
|
+{
|
|
+ iface->get_icon = gdm_password_extension_get_icon;
|
|
+ iface->get_description = gdm_password_extension_get_description;
|
|
+ iface->get_name = gdm_password_extension_get_name;
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_conversation_iface_init (GdmConversationIface *iface)
|
|
+{
|
|
+ iface->set_message = gdm_password_extension_set_message;
|
|
+ iface->ask_question = gdm_password_extension_ask_question;
|
|
+ iface->ask_secret = gdm_password_extension_ask_secret;
|
|
+ iface->reset = gdm_password_extension_reset;
|
|
+ iface->set_ready = gdm_password_extension_set_ready;
|
|
+ iface->get_service_name = gdm_password_extension_get_service_name;
|
|
+ iface->get_page = gdm_password_extension_get_page;
|
|
+ iface->get_actions = gdm_password_extension_get_actions;
|
|
+ iface->request_answer = gdm_password_extension_request_answer;
|
|
+ iface->focus = gdm_password_extension_focus;
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_greeter_extension_iface_init (GdmGreeterExtensionIface *iface)
|
|
+{
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_password_extension_class_init (GdmPasswordExtensionClass *extension_class)
|
|
+{
|
|
+ GObjectClass *object_class;
|
|
+
|
|
+ object_class = G_OBJECT_CLASS (extension_class);
|
|
+
|
|
+ object_class->finalize = gdm_password_extension_finalize;
|
|
+
|
|
+ g_type_class_add_private (extension_class,
|
|
+ sizeof (GdmPasswordExtensionPrivate));
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_password_extension_finalize (GObject *object)
|
|
+{
|
|
+}
|
|
+
|
|
+static void
|
|
+on_activate_log_in (GdmPasswordExtension *extension)
|
|
+{
|
|
+ gdm_password_extension_request_answer (GDM_CONVERSATION (extension));
|
|
+}
|
|
+
|
|
+static void
|
|
+create_page (GdmPasswordExtension *extension)
|
|
+{
|
|
+ GtkBuilder *builder;
|
|
+ GObject *object;
|
|
+ GError *error;
|
|
+
|
|
+ builder = gtk_builder_new ();
|
|
+
|
|
+ error = NULL;
|
|
+ gtk_builder_add_from_file (builder,
|
|
+ "/usr/share/gdm/simple-greeter/extensions/password/page.ui",
|
|
+ &error);
|
|
+
|
|
+ if (error != NULL) {
|
|
+ g_warning ("Could not load UI file: %s", error->message);
|
|
+ g_error_free (error);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ object = gtk_builder_get_object (builder, "page");
|
|
+ g_object_ref (object);
|
|
+
|
|
+ extension->priv->page = GTK_WIDGET (object);
|
|
+
|
|
+ object = gtk_builder_get_object (builder, "auth-prompt-label");
|
|
+ g_object_ref (object);
|
|
+ extension->priv->prompt_label = GTK_WIDGET (object);
|
|
+ gtk_widget_hide (extension->priv->prompt_label);
|
|
+
|
|
+ object = gtk_builder_get_object (builder, "auth-prompt-entry");
|
|
+ g_object_ref (object);
|
|
+ extension->priv->prompt_entry = GTK_WIDGET (object);
|
|
+ gtk_widget_hide (extension->priv->prompt_entry);
|
|
+
|
|
+ object = gtk_builder_get_object (builder, "auth-message-label");
|
|
+ g_object_ref (object);
|
|
+ extension->priv->message_label = GTK_WIDGET (object);
|
|
+ gtk_widget_show (extension->priv->message_label);
|
|
+
|
|
+ g_object_unref (builder);
|
|
+}
|
|
+
|
|
+static void
|
|
+create_actions (GdmPasswordExtension *extension)
|
|
+{
|
|
+ GtkAction *action;
|
|
+
|
|
+ extension->priv->actions = gtk_action_group_new ("gdm-password-extension");
|
|
+
|
|
+ action = gtk_action_new (GDM_CONVERSATION_DEFAULT_ACTION,
|
|
+ _("Log In"),
|
|
+ _("Log into the currently selected sesson"),
|
|
+ NULL);
|
|
+ g_signal_connect_swapped (action, "activate",
|
|
+ G_CALLBACK (on_activate_log_in), extension);
|
|
+ g_object_set (G_OBJECT (action), "icon-name", "go-home", NULL);
|
|
+ gtk_action_group_add_action (extension->priv->actions,
|
|
+ action);
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_password_extension_init (GdmPasswordExtension *extension)
|
|
+{
|
|
+ extension->priv = G_TYPE_INSTANCE_GET_PRIVATE (extension,
|
|
+ GDM_TYPE_PASSWORD_EXTENSION,
|
|
+ GdmPasswordExtensionPrivate);
|
|
+
|
|
+ extension->priv->icon = g_themed_icon_new ("dialog-password");
|
|
+ create_page (extension);
|
|
+ create_actions (extension);
|
|
+
|
|
+ gdm_password_extension_reset (GDM_CONVERSATION (extension));
|
|
+}
|
|
diff --git a/gui/simple-greeter/plugins/password/gdm-password-extension.h b/gui/simple-greeter/plugins/password/gdm-password-extension.h
|
|
new file mode 100644
|
|
index 0000000..99fe17b
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/plugins/password/gdm-password-extension.h
|
|
@@ -0,0 +1,56 @@
|
|
+/*
|
|
+ * Copyright (C) 2009 Red Hat, Inc.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2, or (at your option)
|
|
+ * any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
+ * 02111-1307, USA.
|
|
+ *
|
|
+ * Written By: Ray Strode <rstrode@redhat.com>
|
|
+ */
|
|
+
|
|
+#ifndef __GDM_PASSWORD_EXTENSION_H
|
|
+#define __GDM_PASSWORD_EXTENSION_H
|
|
+
|
|
+#include <glib-object.h>
|
|
+#include "gdm-greeter-extension.h"
|
|
+
|
|
+G_BEGIN_DECLS
|
|
+
|
|
+#define GDM_TYPE_PASSWORD_EXTENSION (gdm_password_extension_get_type ())
|
|
+#define GDM_PASSWORD_EXTENSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDM_TYPE_PASSWORD_EXTENSION, GdmPasswordExtension))
|
|
+#define GDM_PASSWORD_EXTENSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDM_TYPE_PASSWORD_EXTENSION, GdmPasswordExtensionClass))
|
|
+#define GDM_IS_PASSWORD_EXTENSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDM_TYPE_PASSWORD_EXTENSION))
|
|
+#define GDM_IS_PASSWORD_EXTENSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDM_TYPE_PASSWORD_EXTENSION))
|
|
+#define GDM_PASSWORD_EXTENSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GDM_TYPE_PASSWORD_EXTENSION, GdmPasswordExtensionClass))
|
|
+
|
|
+typedef struct _GdmPasswordExtensionPrivate GdmPasswordExtensionPrivate;
|
|
+
|
|
+typedef struct
|
|
+{
|
|
+ GObject parent;
|
|
+ GdmPasswordExtensionPrivate *priv;
|
|
+} GdmPasswordExtension;
|
|
+
|
|
+typedef struct
|
|
+{
|
|
+ GObjectClass parent_class;
|
|
+} GdmPasswordExtensionClass;
|
|
+
|
|
+GType gdm_password_extension_get_type (void);
|
|
+
|
|
+GdmPasswordExtension *gdm_password_extension_new (void);
|
|
+
|
|
+G_END_DECLS
|
|
+
|
|
+#endif /* GDM_PASSWORD_EXTENSION_H */
|
|
diff --git a/gui/simple-greeter/plugins/password/page.ui b/gui/simple-greeter/plugins/password/page.ui
|
|
new file mode 100644
|
|
index 0000000..fe6da78
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/plugins/password/page.ui
|
|
@@ -0,0 +1,56 @@
|
|
+<?xml version="1.0"?>
|
|
+<interface>
|
|
+ <requires lib="gtk+" version="2.14"/>
|
|
+ <object class="GtkVBox" id="page">
|
|
+ <property name="visible">True</property>
|
|
+ <property name="orientation">vertical</property>
|
|
+ <child>
|
|
+ <object class="GtkHBox" id="auth-input-box">
|
|
+ <property name="visible">True</property>
|
|
+ <child>
|
|
+ <object class="GtkLabel" id="auth-prompt-label">
|
|
+ <property name="visible">True</property>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="expand">False</property>
|
|
+ <property name="fill">False</property>
|
|
+ <property name="position">0</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ <child>
|
|
+ <object class="GtkEntry" id="auth-prompt-entry">
|
|
+ <property name="visible">True</property>
|
|
+ <property name="can_focus">True</property>
|
|
+ <property name="activates_default">True</property>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="position">1</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="expand">True</property>
|
|
+ <property name="fill">True</property>
|
|
+ <property name="position">0</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ <child>
|
|
+ <object class="GtkHBox" id="auth-message-box">
|
|
+ <property name="visible">True</property>
|
|
+ <child>
|
|
+ <object class="GtkLabel" id="auth-message-label">
|
|
+ <property name="visible">True</property>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="position">0</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="expand">True</property>
|
|
+ <property name="fill">True</property>
|
|
+ <property name="position">1</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ </object>
|
|
+</interface>
|
|
diff --git a/gui/simple-greeter/plugins/password/plugin.c b/gui/simple-greeter/plugins/password/plugin.c
|
|
new file mode 100644
|
|
index 0000000..9b87c67
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/plugins/password/plugin.c
|
|
@@ -0,0 +1,40 @@
|
|
+/*
|
|
+ * Copyright (C) 2009 Red Hat, Inc.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
+ *
|
|
+ * Written By: Ray Strode <rstrode@redhat.com>
|
|
+ *
|
|
+ */
|
|
+
|
|
+#include "gdm-password-extension.h"
|
|
+
|
|
+#include <gio/gio.h>
|
|
+#include <gtk/gtk.h>
|
|
+
|
|
+GdmGreeterExtension *
|
|
+gdm_greeter_plugin_get_extension (void)
|
|
+{
|
|
+ static GObject *extension;
|
|
+
|
|
+ if (extension != NULL) {
|
|
+ g_object_ref (extension);
|
|
+ } else {
|
|
+ extension = g_object_new (GDM_TYPE_PASSWORD_EXTENSION, NULL);
|
|
+ g_object_add_weak_pointer (extension, (gpointer *) &extension);
|
|
+ }
|
|
+
|
|
+ return GDM_GREETER_EXTENSION (extension);
|
|
+}
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From d979b62871f4519423fbb451f0dd010a30d40464 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Fri, 6 Feb 2009 16:25:47 -0500
|
|
Subject: [PATCH 25/65] Add fingerprint plugin
|
|
|
|
This commit adds a plugin to initiate a conversation for
|
|
fingerprint scans.
|
|
---
|
|
configure.ac | 1 +
|
|
gui/simple-greeter/plugins/Makefile.am | 2 +-
|
|
gui/simple-greeter/plugins/fingerprint/Makefile.am | 40 +++
|
|
.../fingerprint/gdm-fingerprint-extension.c | 299 ++++++++++++++++++++
|
|
.../fingerprint/gdm-fingerprint-extension.h | 56 ++++
|
|
gui/simple-greeter/plugins/fingerprint/page.ui | 56 ++++
|
|
gui/simple-greeter/plugins/fingerprint/plugin.c | 40 +++
|
|
7 files changed, 493 insertions(+), 1 deletions(-)
|
|
create mode 100644 gui/simple-greeter/plugins/fingerprint/Makefile.am
|
|
create mode 100644 gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.c
|
|
create mode 100644 gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.h
|
|
create mode 100644 gui/simple-greeter/plugins/fingerprint/page.ui
|
|
create mode 100644 gui/simple-greeter/plugins/fingerprint/plugin.c
|
|
|
|
diff --git a/configure.ac b/configure.ac
|
|
index cc2576f..5b2519a 100644
|
|
--- a/configure.ac
|
|
+++ b/configure.ac
|
|
@@ -1438,6 +1438,7 @@ gui/simple-greeter/libgdmsimplegreeter/Makefile
|
|
gui/simple-greeter/libgdmsimplegreeter/gdmsimplegreeter.pc
|
|
gui/simple-greeter/plugins/Makefile
|
|
gui/simple-greeter/plugins/password/Makefile
|
|
+gui/simple-greeter/plugins/fingerprint/Makefile
|
|
gui/simple-chooser/Makefile
|
|
gui/user-switch-applet/Makefile
|
|
utils/Makefile
|
|
diff --git a/gui/simple-greeter/plugins/Makefile.am b/gui/simple-greeter/plugins/Makefile.am
|
|
index c0390db..9811a68 100644
|
|
--- a/gui/simple-greeter/plugins/Makefile.am
|
|
+++ b/gui/simple-greeter/plugins/Makefile.am
|
|
@@ -1 +1 @@
|
|
-SUBDIRS = password
|
|
+SUBDIRS = password fingerprint
|
|
diff --git a/gui/simple-greeter/plugins/fingerprint/Makefile.am b/gui/simple-greeter/plugins/fingerprint/Makefile.am
|
|
new file mode 100644
|
|
index 0000000..6f2d727
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/plugins/fingerprint/Makefile.am
|
|
@@ -0,0 +1,40 @@
|
|
+NULL =
|
|
+
|
|
+AM_CPPFLAGS = \
|
|
+ -I$(top_srcdir)/common \
|
|
+ -I$(top_srcdir)/gui/simple-greeter/libnotificationarea \
|
|
+ -I$(top_srcdir)/gui/simple-greeter/libgdmsimplegreeter \
|
|
+ -DDMCONFDIR=\""$(dmconfdir)"\" \
|
|
+ -DGDMCONFDIR=\"$(gdmconfdir)\" \
|
|
+ -DDATADIR=\""$(datadir)"\" \
|
|
+ -DSYSCONFDIR=\""$(sysconfdir)"\" \
|
|
+ -DLIBLOCALEDIR=\""$(prefix)/lib/locale"\" \
|
|
+ -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
|
|
+ -DLIBEXECDIR=\""$(libexecdir)"\" \
|
|
+ -DSBINDIR=\""$(sbindir)"\" \
|
|
+ $(DISABLE_DEPRECATED_CFLAGS) \
|
|
+ $(GTK_CFLAGS) \
|
|
+ $(SIMPLE_GREETER_CFLAGS) \
|
|
+ $(POLKIT_GNOME_CFLAGS) \
|
|
+ $(NULL)
|
|
+
|
|
+plugindir = $(GDM_SIMPLE_GREETER_PLUGINS_DIR)
|
|
+plugin_LTLIBRARIES = fingerprint.la
|
|
+
|
|
+fingerprint_la_CFLAGS = \
|
|
+ $(SIMPLE_GREETER_CFLAGS) \
|
|
+ $(NULL)
|
|
+
|
|
+fingerprint_la_LDFLAGS = -module -avoid-version -export-dynamic
|
|
+fingerprint_la_LIBADD = ../../../../common/libgdmcommon.la \
|
|
+ ../../libgdmsimplegreeter/libgdmsimplegreeter.la
|
|
+fingerprint_la_SOURCES = \
|
|
+ gdm-fingerprint-extension.h \
|
|
+ gdm-fingerprint-extension.c \
|
|
+ plugin.c
|
|
+
|
|
+EXTRA_DIST = gdm-fingerprint
|
|
+
|
|
+MAINTAINERCLEANFILES = \
|
|
+ *~ \
|
|
+ Makefile.in
|
|
diff --git a/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.c b/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.c
|
|
new file mode 100644
|
|
index 0000000..2a4027c
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.c
|
|
@@ -0,0 +1,299 @@
|
|
+/*
|
|
+ * Copyright (C) 2009 Red Hat, Inc.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
+ *
|
|
+ * Written By: Ray Strode <rstrode@redhat.com>
|
|
+ *
|
|
+ */
|
|
+
|
|
+#include <config.h>
|
|
+#include "gdm-fingerprint-extension.h"
|
|
+#include "gdm-conversation.h"
|
|
+#include "gdm-task.h"
|
|
+
|
|
+#include <glib/gi18n-lib.h>
|
|
+#include <gio/gio.h>
|
|
+#include <gtk/gtk.h>
|
|
+
|
|
+struct _GdmFingerprintExtensionPrivate
|
|
+{
|
|
+ GIcon *icon;
|
|
+ GtkWidget *page;
|
|
+ GtkActionGroup *actions;
|
|
+
|
|
+ GtkWidget *message_label;
|
|
+ GtkWidget *prompt_label;
|
|
+ GtkWidget *prompt_entry;
|
|
+
|
|
+ guint answer_pending : 1;
|
|
+};
|
|
+
|
|
+static void gdm_fingerprint_extension_finalize (GObject *object);
|
|
+
|
|
+static void gdm_task_iface_init (GdmTaskIface *iface);
|
|
+static void gdm_conversation_iface_init (GdmConversationIface *iface);
|
|
+static void gdm_greeter_extension_iface_init (GdmGreeterExtensionIface *iface);
|
|
+
|
|
+G_DEFINE_TYPE_WITH_CODE (GdmFingerprintExtension,
|
|
+ gdm_fingerprint_extension,
|
|
+ G_TYPE_OBJECT,
|
|
+ G_IMPLEMENT_INTERFACE (GDM_TYPE_GREETER_EXTENSION,
|
|
+ gdm_greeter_extension_iface_init)
|
|
+ G_IMPLEMENT_INTERFACE (GDM_TYPE_TASK,
|
|
+ gdm_task_iface_init)
|
|
+ G_IMPLEMENT_INTERFACE (GDM_TYPE_CONVERSATION,
|
|
+ gdm_conversation_iface_init));
|
|
+
|
|
+static void
|
|
+gdm_fingerprint_extension_set_message (GdmConversation *conversation,
|
|
+ const char *message)
|
|
+{
|
|
+ GdmFingerprintExtension *extension = GDM_FINGERPRINT_EXTENSION (conversation);
|
|
+ gtk_widget_show (extension->priv->message_label);
|
|
+ gtk_label_set_text (GTK_LABEL (extension->priv->message_label), message);
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_fingerprint_extension_ask_question (GdmConversation *conversation,
|
|
+ const char *message)
|
|
+{
|
|
+ GdmFingerprintExtension *extension = GDM_FINGERPRINT_EXTENSION (conversation);
|
|
+ gtk_widget_show (extension->priv->prompt_label);
|
|
+ gtk_label_set_text (GTK_LABEL (extension->priv->prompt_label), message);
|
|
+ gtk_entry_set_text (GTK_ENTRY (extension->priv->prompt_entry), "");
|
|
+ gtk_entry_set_visibility (GTK_ENTRY (extension->priv->prompt_entry), TRUE);
|
|
+ gtk_widget_show (extension->priv->prompt_entry);
|
|
+ gtk_widget_grab_focus (extension->priv->prompt_entry);
|
|
+ extension->priv->answer_pending = TRUE;
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_fingerprint_extension_ask_secret (GdmConversation *conversation,
|
|
+ const char *message)
|
|
+{
|
|
+ GdmFingerprintExtension *extension = GDM_FINGERPRINT_EXTENSION (conversation);
|
|
+ gtk_widget_show (extension->priv->prompt_label);
|
|
+ gtk_label_set_text (GTK_LABEL (extension->priv->prompt_label), message);
|
|
+ gtk_entry_set_visibility (GTK_ENTRY (extension->priv->prompt_entry), FALSE);
|
|
+ gtk_entry_set_text (GTK_ENTRY (extension->priv->prompt_entry), "");
|
|
+ gtk_widget_show (extension->priv->prompt_entry);
|
|
+ gtk_widget_grab_focus (extension->priv->prompt_entry);
|
|
+ extension->priv->answer_pending = TRUE;
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_fingerprint_extension_reset (GdmConversation *conversation)
|
|
+{
|
|
+ GdmFingerprintExtension *extension = GDM_FINGERPRINT_EXTENSION (conversation);
|
|
+ gtk_widget_hide (extension->priv->prompt_label);
|
|
+ gtk_label_set_text (GTK_LABEL (extension->priv->prompt_label), "");
|
|
+
|
|
+ gtk_widget_hide (extension->priv->prompt_entry);
|
|
+ gtk_entry_set_text (GTK_ENTRY (extension->priv->prompt_entry), "");
|
|
+ gtk_entry_set_visibility (GTK_ENTRY (extension->priv->prompt_entry), TRUE);
|
|
+ extension->priv->answer_pending = FALSE;
|
|
+
|
|
+ gdm_task_set_enabled (GDM_TASK (conversation), FALSE);
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_fingerprint_extension_set_ready (GdmConversation *conversation)
|
|
+{
|
|
+ gdm_task_set_enabled (GDM_TASK (conversation), TRUE);
|
|
+}
|
|
+
|
|
+char *
|
|
+gdm_fingerprint_extension_get_service_name (GdmConversation *conversation)
|
|
+{
|
|
+ return g_strdup ("fingerprint-auth");
|
|
+}
|
|
+
|
|
+GtkWidget *
|
|
+gdm_fingerprint_extension_get_page (GdmConversation *conversation)
|
|
+{
|
|
+ GdmFingerprintExtension *extension = GDM_FINGERPRINT_EXTENSION (conversation);
|
|
+ return extension->priv->page;
|
|
+}
|
|
+
|
|
+GtkActionGroup *
|
|
+gdm_fingerprint_extension_get_actions (GdmConversation *conversation)
|
|
+{
|
|
+ GdmFingerprintExtension *extension = GDM_FINGERPRINT_EXTENSION (conversation);
|
|
+
|
|
+ return g_object_ref (extension->priv->actions);
|
|
+}
|
|
+
|
|
+void
|
|
+gdm_fingerprint_extension_request_answer (GdmConversation *conversation)
|
|
+{
|
|
+ GdmFingerprintExtension *extension = GDM_FINGERPRINT_EXTENSION (conversation);
|
|
+ const char *text;
|
|
+
|
|
+ if (!extension->priv->answer_pending) {
|
|
+ gdm_conversation_answer (conversation, NULL);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ extension->priv->answer_pending = FALSE;
|
|
+ text = gtk_entry_get_text (GTK_ENTRY (extension->priv->prompt_entry));
|
|
+ gdm_conversation_answer (conversation, text);
|
|
+
|
|
+ gtk_widget_hide (extension->priv->prompt_entry);
|
|
+ gtk_label_set_text (GTK_LABEL (extension->priv->prompt_label), "");
|
|
+ gtk_entry_set_text (GTK_ENTRY (extension->priv->prompt_entry), "");
|
|
+}
|
|
+
|
|
+gboolean
|
|
+gdm_fingerprint_extension_focus (GdmConversation *conversation)
|
|
+{
|
|
+ GdmFingerprintExtension *extension = GDM_FINGERPRINT_EXTENSION (conversation);
|
|
+
|
|
+ if (!extension->priv->answer_pending) {
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ gtk_widget_grab_focus (extension->priv->prompt_entry);
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+GIcon *
|
|
+gdm_fingerprint_extension_get_icon (GdmTask *task)
|
|
+{
|
|
+ GdmFingerprintExtension *extension = GDM_FINGERPRINT_EXTENSION (task);
|
|
+ return g_object_ref (extension->priv->icon);
|
|
+}
|
|
+
|
|
+char *
|
|
+gdm_fingerprint_extension_get_name (GdmTask *task)
|
|
+{
|
|
+ return g_strdup (_("Fingerprint Authentication"));
|
|
+}
|
|
+
|
|
+char *
|
|
+gdm_fingerprint_extension_get_description (GdmTask *task)
|
|
+{
|
|
+ return g_strdup (_("Log into session with fingerprint"));
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_task_iface_init (GdmTaskIface *iface)
|
|
+{
|
|
+ iface->get_icon = gdm_fingerprint_extension_get_icon;
|
|
+ iface->get_description = gdm_fingerprint_extension_get_description;
|
|
+ iface->get_name = gdm_fingerprint_extension_get_name;
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_conversation_iface_init (GdmConversationIface *iface)
|
|
+{
|
|
+ iface->set_message = gdm_fingerprint_extension_set_message;
|
|
+ iface->ask_question = gdm_fingerprint_extension_ask_question;
|
|
+ iface->ask_secret = gdm_fingerprint_extension_ask_secret;
|
|
+ iface->reset = gdm_fingerprint_extension_reset;
|
|
+ iface->set_ready = gdm_fingerprint_extension_set_ready;
|
|
+ iface->get_service_name = gdm_fingerprint_extension_get_service_name;
|
|
+ iface->get_page = gdm_fingerprint_extension_get_page;
|
|
+ iface->get_actions = gdm_fingerprint_extension_get_actions;
|
|
+ iface->request_answer = gdm_fingerprint_extension_request_answer;
|
|
+ iface->focus = gdm_fingerprint_extension_focus;
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_greeter_extension_iface_init (GdmGreeterExtensionIface *iface)
|
|
+{
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_fingerprint_extension_class_init (GdmFingerprintExtensionClass *extension_class)
|
|
+{
|
|
+ GObjectClass *object_class;
|
|
+
|
|
+ object_class = G_OBJECT_CLASS (extension_class);
|
|
+
|
|
+ object_class->finalize = gdm_fingerprint_extension_finalize;
|
|
+
|
|
+ g_type_class_add_private (extension_class,
|
|
+ sizeof (GdmFingerprintExtensionPrivate));
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_fingerprint_extension_finalize (GObject *object)
|
|
+{
|
|
+}
|
|
+
|
|
+static void
|
|
+create_page (GdmFingerprintExtension *extension)
|
|
+{
|
|
+ GtkBuilder *builder;
|
|
+ GObject *object;
|
|
+ GError *error;
|
|
+
|
|
+ builder = gtk_builder_new ();
|
|
+
|
|
+ error = NULL;
|
|
+ gtk_builder_add_from_file (builder,
|
|
+ "/usr/share/gdm/simple-greeter/extensions/fingerprint/page.ui",
|
|
+ &error);
|
|
+
|
|
+ if (error != NULL) {
|
|
+ g_warning ("Could not load UI file: %s", error->message);
|
|
+ g_error_free (error);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ object = gtk_builder_get_object (builder, "page");
|
|
+ g_object_ref (object);
|
|
+
|
|
+ extension->priv->page = GTK_WIDGET (object);
|
|
+
|
|
+ object = gtk_builder_get_object (builder, "auth-prompt-label");
|
|
+ g_object_ref (object);
|
|
+ extension->priv->prompt_label = GTK_WIDGET (object);
|
|
+ gtk_widget_hide (extension->priv->prompt_label);
|
|
+
|
|
+ object = gtk_builder_get_object (builder, "auth-prompt-entry");
|
|
+ g_object_ref (object);
|
|
+ extension->priv->prompt_entry = GTK_WIDGET (object);
|
|
+ gtk_widget_hide (extension->priv->prompt_entry);
|
|
+
|
|
+ object = gtk_builder_get_object (builder, "auth-message-label");
|
|
+ g_object_ref (object);
|
|
+ extension->priv->message_label = GTK_WIDGET (object);
|
|
+ gtk_widget_show (extension->priv->message_label);
|
|
+
|
|
+ g_object_unref (builder);
|
|
+}
|
|
+
|
|
+static void
|
|
+create_actions (GdmFingerprintExtension *extension)
|
|
+{
|
|
+ GtkAction *action;
|
|
+
|
|
+ extension->priv->actions = gtk_action_group_new ("gdm-fingerprint-extension");
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_fingerprint_extension_init (GdmFingerprintExtension *extension)
|
|
+{
|
|
+ extension->priv = G_TYPE_INSTANCE_GET_PRIVATE (extension,
|
|
+ GDM_TYPE_FINGERPRINT_EXTENSION,
|
|
+ GdmFingerprintExtensionPrivate);
|
|
+
|
|
+ extension->priv->icon = g_themed_icon_new ("stock_allow-effects");
|
|
+ create_page (extension);
|
|
+ create_actions (extension);
|
|
+ gdm_fingerprint_extension_reset (GDM_CONVERSATION (extension));
|
|
+}
|
|
diff --git a/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.h b/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.h
|
|
new file mode 100644
|
|
index 0000000..5d34b21
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.h
|
|
@@ -0,0 +1,56 @@
|
|
+/*
|
|
+ * Copyright (C) 2009 Red Hat, Inc.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2, or (at your option)
|
|
+ * any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
+ * 02111-1307, USA.
|
|
+ *
|
|
+ * Written By: Ray Strode <rstrode@redhat.com>
|
|
+ */
|
|
+
|
|
+#ifndef __GDM_FINGERPRINT_EXTENSION_H
|
|
+#define __GDM_FINGERPRINT_EXTENSION_H
|
|
+
|
|
+#include <glib-object.h>
|
|
+#include "gdm-greeter-extension.h"
|
|
+
|
|
+G_BEGIN_DECLS
|
|
+
|
|
+#define GDM_TYPE_FINGERPRINT_EXTENSION (gdm_fingerprint_extension_get_type ())
|
|
+#define GDM_FINGERPRINT_EXTENSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDM_TYPE_FINGERPRINT_EXTENSION, GdmFingerprintExtension))
|
|
+#define GDM_FINGERPRINT_EXTENSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDM_TYPE_FINGERPRINT_EXTENSION, GdmFingerprintExtensionClass))
|
|
+#define GDM_IS_FINGERPRINT_EXTENSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDM_TYPE_FINGERPRINT_EXTENSION))
|
|
+#define GDM_IS_FINGERPRINT_EXTENSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDM_TYPE_FINGERPRINT_EXTENSION))
|
|
+#define GDM_FINGERPRINT_EXTENSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GDM_TYPE_FINGERPRINT_EXTENSION, GdmFingerprintExtensionClass))
|
|
+
|
|
+typedef struct _GdmFingerprintExtensionPrivate GdmFingerprintExtensionPrivate;
|
|
+
|
|
+typedef struct
|
|
+{
|
|
+ GObject parent;
|
|
+ GdmFingerprintExtensionPrivate *priv;
|
|
+} GdmFingerprintExtension;
|
|
+
|
|
+typedef struct
|
|
+{
|
|
+ GObjectClass parent_class;
|
|
+} GdmFingerprintExtensionClass;
|
|
+
|
|
+GType gdm_fingerprint_extension_get_type (void);
|
|
+
|
|
+GdmFingerprintExtension *gdm_fingerprint_extension_new (void);
|
|
+
|
|
+G_END_DECLS
|
|
+
|
|
+#endif /* GDM_FINGERPRINT_EXTENSION_H */
|
|
diff --git a/gui/simple-greeter/plugins/fingerprint/page.ui b/gui/simple-greeter/plugins/fingerprint/page.ui
|
|
new file mode 100644
|
|
index 0000000..fe6da78
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/plugins/fingerprint/page.ui
|
|
@@ -0,0 +1,56 @@
|
|
+<?xml version="1.0"?>
|
|
+<interface>
|
|
+ <requires lib="gtk+" version="2.14"/>
|
|
+ <object class="GtkVBox" id="page">
|
|
+ <property name="visible">True</property>
|
|
+ <property name="orientation">vertical</property>
|
|
+ <child>
|
|
+ <object class="GtkHBox" id="auth-input-box">
|
|
+ <property name="visible">True</property>
|
|
+ <child>
|
|
+ <object class="GtkLabel" id="auth-prompt-label">
|
|
+ <property name="visible">True</property>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="expand">False</property>
|
|
+ <property name="fill">False</property>
|
|
+ <property name="position">0</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ <child>
|
|
+ <object class="GtkEntry" id="auth-prompt-entry">
|
|
+ <property name="visible">True</property>
|
|
+ <property name="can_focus">True</property>
|
|
+ <property name="activates_default">True</property>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="position">1</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="expand">True</property>
|
|
+ <property name="fill">True</property>
|
|
+ <property name="position">0</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ <child>
|
|
+ <object class="GtkHBox" id="auth-message-box">
|
|
+ <property name="visible">True</property>
|
|
+ <child>
|
|
+ <object class="GtkLabel" id="auth-message-label">
|
|
+ <property name="visible">True</property>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="position">0</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="expand">True</property>
|
|
+ <property name="fill">True</property>
|
|
+ <property name="position">1</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ </object>
|
|
+</interface>
|
|
diff --git a/gui/simple-greeter/plugins/fingerprint/plugin.c b/gui/simple-greeter/plugins/fingerprint/plugin.c
|
|
new file mode 100644
|
|
index 0000000..5ea9925
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/plugins/fingerprint/plugin.c
|
|
@@ -0,0 +1,40 @@
|
|
+/*
|
|
+ * Copyright (C) 2009 Red Hat, Inc.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
+ *
|
|
+ * Written By: Ray Strode <rstrode@redhat.com>
|
|
+ *
|
|
+ */
|
|
+
|
|
+#include "gdm-fingerprint-extension.h"
|
|
+
|
|
+#include <gio/gio.h>
|
|
+#include <gtk/gtk.h>
|
|
+
|
|
+GdmGreeterExtension *
|
|
+gdm_greeter_plugin_get_extension (void)
|
|
+{
|
|
+ static GObject *extension;
|
|
+
|
|
+ if (extension != NULL) {
|
|
+ g_object_ref (extension);
|
|
+ } else {
|
|
+ extension = g_object_new (GDM_TYPE_FINGERPRINT_EXTENSION, NULL);
|
|
+ g_object_add_weak_pointer (extension, (gpointer *) &extension);
|
|
+ }
|
|
+
|
|
+ return GDM_GREETER_EXTENSION (extension);
|
|
+}
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 86391cb7067920b99d92a27e0de600b26b1ec027 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Fri, 6 Feb 2009 17:12:04 -0500
|
|
Subject: [PATCH 26/65] fix debug message
|
|
|
|
---
|
|
daemon/gdm-simple-slave.c | 2 +-
|
|
1 files changed, 1 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c
|
|
index a6ae0ae..1245bc9 100644
|
|
--- a/daemon/gdm-simple-slave.c
|
|
+++ b/daemon/gdm-simple-slave.c
|
|
@@ -509,7 +509,7 @@ on_session_conversation_started (GdmSession *session,
|
|
char *username;
|
|
int delay;
|
|
|
|
- g_debug ("GdmSimpleSlave: session opened");
|
|
+ g_debug ("GdmSimpleSlave: conversation started");
|
|
if (slave->priv->greeter_server != NULL) {
|
|
res = gdm_greeter_server_ready (slave->priv->greeter_server,
|
|
service_name);
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 6df2f0bc6b32b26eaa533976b1271d8933b1410a Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Fri, 6 Feb 2009 17:44:37 -0500
|
|
Subject: [PATCH 27/65] Drop duplicated entry introspection output
|
|
|
|
---
|
|
daemon/gdm-greeter-server.c | 1 -
|
|
1 files changed, 0 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/daemon/gdm-greeter-server.c b/daemon/gdm-greeter-server.c
|
|
index 0ac0a09..dae34c5 100644
|
|
--- a/daemon/gdm-greeter-server.c
|
|
+++ b/daemon/gdm-greeter-server.c
|
|
@@ -859,7 +859,6 @@ do_introspect (DBusConnection *connection,
|
|
" <arg name=\"layout_name\" type=\"s\"/>\n"
|
|
" </signal>\n"
|
|
" <signal name=\"DefaultSessionNameChanged\">\n"
|
|
- " <signal name=\"DefaultSessionNameChanged\">\n"
|
|
" <arg name=\"session_name\" type=\"s\"/>\n"
|
|
" </signal>\n"
|
|
" <signal name=\"TimedLoginRequested\">\n"
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 1258c6b7826b125d1825cfb48ef0378744da77a4 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Sat, 7 Feb 2009 11:36:40 -0500
|
|
Subject: [PATCH 28/65] emit "ConversationStopped" signal at end of conv
|
|
|
|
This will allow us to track when individual
|
|
PAM conversations fail, instead of doing one
|
|
giant reset. The reason this is useful is that
|
|
some PAM modules fail immediately for some users
|
|
(for instance the fingerprint PAM module fails if
|
|
a user hasn't enrolled their print).
|
|
---
|
|
daemon/gdm-greeter-server.c | 13 +++++++++++++
|
|
daemon/gdm-greeter-server.h | 2 ++
|
|
daemon/gdm-session-direct.c | 36 ++++++++++++++++++++++++++++++++++++
|
|
daemon/gdm-session-private.h | 2 ++
|
|
daemon/gdm-session.c | 28 ++++++++++++++++++++++++++++
|
|
daemon/gdm-session.h | 6 ++++++
|
|
daemon/gdm-simple-slave.c | 34 ++++++++++++++++++++++++++--------
|
|
7 files changed, 113 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/daemon/gdm-greeter-server.c b/daemon/gdm-greeter-server.c
|
|
index dae34c5..5bf1f8a 100644
|
|
--- a/daemon/gdm-greeter-server.c
|
|
+++ b/daemon/gdm-greeter-server.c
|
|
@@ -299,6 +299,13 @@ gdm_greeter_server_ready (GdmGreeterServer *greeter_server,
|
|
return TRUE;
|
|
}
|
|
|
|
+gboolean
|
|
+gdm_greeter_server_conversation_stopped (GdmGreeterServer *greeter_server,
|
|
+ const char *service_name)
|
|
+{
|
|
+ send_dbus_string_signal (greeter_server, "ConversationStopped", service_name);
|
|
+}
|
|
+
|
|
void
|
|
gdm_greeter_server_selected_user_changed (GdmGreeterServer *greeter_server,
|
|
const char *username)
|
|
@@ -797,6 +804,9 @@ do_introspect (DBusConnection *connection,
|
|
" <method name=\"StartConversation\">\n"
|
|
" <arg name=\"service_name\" direction=\"in\" type=\"s\"/>\n"
|
|
" </method>\n"
|
|
+ " <method name=\"StopConversation\">\n"
|
|
+ " <arg name=\"service_name\" direction=\"in\" type=\"s\"/>\n"
|
|
+ " </method>\n"
|
|
" <method name=\"BeginVerification\">\n"
|
|
" <arg name=\"service_name\" direction=\"in\" type=\"s\"/>\n"
|
|
" </method>\n"
|
|
@@ -868,6 +878,9 @@ do_introspect (DBusConnection *connection,
|
|
" <signal name=\"Ready\">\n"
|
|
" <arg name=\"service-name\" type=\"s\"/>\n"
|
|
" </signal>\n"
|
|
+ " <signal name=\"ConversationStopped\">\n"
|
|
+ " <arg name=\"service-name\" type=\"s\"/>\n"
|
|
+ " </signal>\n"
|
|
" <signal name=\"Reset\">\n"
|
|
" </signal>\n"
|
|
" <signal name=\"UserAuthorized\">\n"
|
|
diff --git a/daemon/gdm-greeter-server.h b/daemon/gdm-greeter-server.h
|
|
index 6d0dd87..976f0b7 100644
|
|
--- a/daemon/gdm-greeter-server.h
|
|
+++ b/daemon/gdm-greeter-server.h
|
|
@@ -96,6 +96,8 @@ gboolean gdm_greeter_server_problem (GdmGreeterServer *
|
|
gboolean gdm_greeter_server_reset (GdmGreeterServer *greeter_server);
|
|
gboolean gdm_greeter_server_ready (GdmGreeterServer *greeter_server,
|
|
const char *service_name);
|
|
+gboolean gdm_greeter_server_conversation_stopped (GdmGreeterServer *greeter_server,
|
|
+ const char *service_name);
|
|
void gdm_greeter_server_selected_user_changed (GdmGreeterServer *greeter_server,
|
|
const char *text);
|
|
void gdm_greeter_server_default_language_name_changed (GdmGreeterServer *greeter_server,
|
|
diff --git a/daemon/gdm-session-direct.c b/daemon/gdm-session-direct.c
|
|
index 099f884..2fc39f3 100644
|
|
--- a/daemon/gdm-session-direct.c
|
|
+++ b/daemon/gdm-session-direct.c
|
|
@@ -1712,6 +1712,7 @@ worker_exited (GdmSessionWorkerJob *job,
|
|
{
|
|
g_debug ("GdmSessionDirect: Worker job exited: %d", code);
|
|
|
|
+ g_object_ref (conversation);
|
|
if (!conversation->session->priv->is_authenticated) {
|
|
char *msg;
|
|
|
|
@@ -1721,6 +1722,11 @@ worker_exited (GdmSessionWorkerJob *job,
|
|
} else if (conversation->session->priv->is_running) {
|
|
_gdm_session_session_exited (GDM_SESSION (conversation->session), code);
|
|
}
|
|
+
|
|
+ g_debug ("GdmSessionDirect: Emitting conversation-stopped signal");
|
|
+ _gdm_session_conversation_stopped (GDM_SESSION (conversation->session),
|
|
+ conversation->service_name);
|
|
+ g_object_unref (conversation);
|
|
}
|
|
|
|
static void
|
|
@@ -1730,6 +1736,7 @@ worker_died (GdmSessionWorkerJob *job,
|
|
{
|
|
g_debug ("GdmSessionDirect: Worker job died: %d", signum);
|
|
|
|
+ g_object_ref (conversation);
|
|
if (!conversation->session->priv->is_authenticated) {
|
|
char *msg;
|
|
|
|
@@ -1739,6 +1746,11 @@ worker_died (GdmSessionWorkerJob *job,
|
|
} else if (conversation->session->priv->is_running) {
|
|
_gdm_session_session_died (GDM_SESSION (conversation->session), signum);
|
|
}
|
|
+
|
|
+ g_debug ("GdmSessionDirect: Emitting conversation-stopped signal");
|
|
+ _gdm_session_conversation_stopped (GDM_SESSION (conversation->session),
|
|
+ conversation->service_name);
|
|
+ g_object_unref (conversation);
|
|
}
|
|
|
|
static GdmSessionConversation *
|
|
@@ -1811,6 +1823,10 @@ stop_conversation (GdmSessionConversation *conversation)
|
|
|
|
g_object_unref (conversation->job);
|
|
conversation->job = NULL;
|
|
+
|
|
+ g_debug ("GdmSessionDirect: Emitting conversation-stopped signal");
|
|
+ _gdm_session_conversation_stopped (GDM_SESSION (session),
|
|
+ conversation->service_name);
|
|
}
|
|
|
|
static void
|
|
@@ -1831,6 +1847,25 @@ gdm_session_direct_start_conversation (GdmSession *session,
|
|
}
|
|
|
|
static void
|
|
+gdm_session_direct_stop_conversation (GdmSession *session,
|
|
+ const char *service_name)
|
|
+{
|
|
+ GdmSessionDirect *impl = GDM_SESSION_DIRECT (session);
|
|
+ GdmSessionConversation *conversation;
|
|
+
|
|
+ g_return_if_fail (session != NULL);
|
|
+
|
|
+ g_debug ("GdmSessionDirect: stopping conversation");
|
|
+
|
|
+ conversation = find_conversation_by_name (impl, service_name);
|
|
+
|
|
+ if (conversation != NULL) {
|
|
+ stop_conversation (conversation);
|
|
+ g_hash_table_remove (impl->priv->conversations, service_name);
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
send_setup (GdmSessionDirect *session,
|
|
const char *service_name)
|
|
{
|
|
@@ -2644,6 +2679,7 @@ static void
|
|
gdm_session_iface_init (GdmSessionIface *iface)
|
|
{
|
|
iface->start_conversation = gdm_session_direct_start_conversation;
|
|
+ iface->stop_conversation = gdm_session_direct_stop_conversation;
|
|
iface->setup = gdm_session_direct_setup;
|
|
iface->setup_for_user = gdm_session_direct_setup_for_user;
|
|
iface->authenticate = gdm_session_direct_authenticate;
|
|
diff --git a/daemon/gdm-session-private.h b/daemon/gdm-session-private.h
|
|
index de6e54a..860c09c 100644
|
|
--- a/daemon/gdm-session-private.h
|
|
+++ b/daemon/gdm-session-private.h
|
|
@@ -29,6 +29,8 @@ G_BEGIN_DECLS
|
|
/* state changes */
|
|
void _gdm_session_conversation_started (GdmSession *session,
|
|
const char *service_name);
|
|
+void _gdm_session_conversation_stopped (GdmSession *session,
|
|
+ const char *service_name);
|
|
void _gdm_session_setup_complete (GdmSession *session,
|
|
const char *service_name);
|
|
void _gdm_session_setup_failed (GdmSession *session,
|
|
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
|
|
index 5f6ff5d..9ee34af 100644
|
|
--- a/daemon/gdm-session.c
|
|
+++ b/daemon/gdm-session.c
|
|
@@ -30,6 +30,7 @@
|
|
|
|
enum {
|
|
CONVERSATION_STARTED = 0,
|
|
+ CONVERSATION_STOPPED,
|
|
SETUP_COMPLETE,
|
|
SETUP_FAILED,
|
|
RESET_COMPLETE,
|
|
@@ -88,6 +89,15 @@ gdm_session_start_conversation (GdmSession *session,
|
|
}
|
|
|
|
void
|
|
+gdm_session_stop_conversation (GdmSession *session,
|
|
+ const char *service_name)
|
|
+{
|
|
+ g_return_if_fail (GDM_IS_SESSION (session));
|
|
+
|
|
+ GDM_SESSION_GET_IFACE (session)->stop_conversation (session, service_name);
|
|
+}
|
|
+
|
|
+void
|
|
gdm_session_close (GdmSession *session)
|
|
{
|
|
g_return_if_fail (GDM_IS_SESSION (session));
|
|
@@ -220,6 +230,16 @@ gdm_session_class_init (gpointer g_iface)
|
|
g_cclosure_marshal_VOID__STRING,
|
|
G_TYPE_NONE,
|
|
1, G_TYPE_STRING);
|
|
+ signals [CONVERSATION_STOPPED] =
|
|
+ g_signal_new ("conversation-stopped",
|
|
+ iface_type,
|
|
+ G_SIGNAL_RUN_FIRST,
|
|
+ G_STRUCT_OFFSET (GdmSessionIface, conversation_stopped),
|
|
+ NULL,
|
|
+ NULL,
|
|
+ g_cclosure_marshal_VOID__STRING,
|
|
+ G_TYPE_NONE,
|
|
+ 1, G_TYPE_STRING);
|
|
signals [SETUP_COMPLETE] =
|
|
g_signal_new ("setup-complete",
|
|
iface_type,
|
|
@@ -638,6 +658,14 @@ _gdm_session_conversation_started (GdmSession *session,
|
|
}
|
|
|
|
void
|
|
+_gdm_session_conversation_stopped (GdmSession *session,
|
|
+ const char *service_name)
|
|
+{
|
|
+ g_return_if_fail (GDM_IS_SESSION (session));
|
|
+ g_signal_emit (session, signals [CONVERSATION_STOPPED], 0, service_name);
|
|
+}
|
|
+
|
|
+void
|
|
_gdm_session_closed (GdmSession *session)
|
|
{
|
|
g_return_if_fail (GDM_IS_SESSION (session));
|
|
diff --git a/daemon/gdm-session.h b/daemon/gdm-session.h
|
|
index db5fc4a..c45a770 100644
|
|
--- a/daemon/gdm-session.h
|
|
+++ b/daemon/gdm-session.h
|
|
@@ -47,6 +47,8 @@ struct _GdmSessionIface
|
|
/* Methods */
|
|
void (* start_conversation) (GdmSession *session,
|
|
const char *service_name);
|
|
+ void (* stop_conversation) (GdmSession *session,
|
|
+ const char *service_name);
|
|
void (* setup) (GdmSession *session,
|
|
const char *service_name);
|
|
void (* setup_for_user) (GdmSession *session,
|
|
@@ -125,6 +127,8 @@ struct _GdmSessionIface
|
|
int signal_number);
|
|
void (* conversation_started) (GdmSession *session,
|
|
const char *service_name);
|
|
+ void (* conversation_stopped) (GdmSession *session,
|
|
+ const char *service_name);
|
|
void (* closed) (GdmSession *session);
|
|
void (* selected_user_changed) (GdmSession *session,
|
|
const char *text);
|
|
@@ -141,6 +145,8 @@ GType gdm_session_get_type (void) G_GNUC_CONST;
|
|
|
|
void gdm_session_start_conversation (GdmSession *session,
|
|
const char *service_name);
|
|
+void gdm_session_stop_conversation (GdmSession *session,
|
|
+ const char *service_name);
|
|
void gdm_session_setup (GdmSession *session,
|
|
const char *service_name);
|
|
void gdm_session_setup_for_user (GdmSession *session,
|
|
diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c
|
|
index 1245bc9..fba26ab 100644
|
|
--- a/daemon/gdm-simple-slave.c
|
|
+++ b/daemon/gdm-simple-slave.c
|
|
@@ -222,8 +222,7 @@ on_session_setup_failed (GdmSession *session,
|
|
_("Unable to initialize login system"));
|
|
}
|
|
|
|
- destroy_session (slave);
|
|
- queue_greeter_reset (slave);
|
|
+ gdm_session_stop_conversation (session, service_name);
|
|
}
|
|
|
|
static void
|
|
@@ -260,8 +259,8 @@ on_session_authentication_failed (GdmSession *session,
|
|
service_name,
|
|
_("Unable to authenticate user"));
|
|
}
|
|
- destroy_session (slave);
|
|
- queue_greeter_reset (slave);
|
|
+
|
|
+ gdm_session_stop_conversation (session, service_name);
|
|
}
|
|
|
|
static void
|
|
@@ -319,8 +318,7 @@ on_session_authorization_failed (GdmSession *session,
|
|
_("Unable to authorize user"));
|
|
}
|
|
|
|
- destroy_session (slave);
|
|
- queue_greeter_reset (slave);
|
|
+ gdm_session_stop_conversation (session, service_name);
|
|
}
|
|
|
|
static gboolean
|
|
@@ -451,9 +449,8 @@ on_session_accreditation_failed (GdmSession *session,
|
|
when Xorg exits it switches to the VT it was
|
|
started from. That interferes with fast
|
|
user switching. */
|
|
- destroy_session (slave);
|
|
|
|
- queue_greeter_reset (slave);
|
|
+ gdm_session_stop_conversation (session, service_name);
|
|
}
|
|
|
|
static void
|
|
@@ -539,6 +536,23 @@ on_session_conversation_started (GdmSession *session,
|
|
}
|
|
|
|
static void
|
|
+on_session_conversation_stopped (GdmSession *session,
|
|
+ const char *service_name,
|
|
+ GdmSimpleSlave *slave)
|
|
+{
|
|
+ gboolean res;
|
|
+ g_debug ("GdmSimpleSlave: conversation stopped");
|
|
+
|
|
+ if (slave->priv->greeter_server != NULL) {
|
|
+ res = gdm_greeter_server_conversation_stopped (slave->priv->greeter_server,
|
|
+ service_name);
|
|
+ if (! res) {
|
|
+ g_warning ("Unable to send conversation stopped");
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
on_session_selected_user_changed (GdmSession *session,
|
|
const char *text,
|
|
GdmSimpleSlave *slave)
|
|
@@ -627,6 +641,10 @@ create_new_session (GdmSimpleSlave *slave)
|
|
G_CALLBACK (on_session_conversation_started),
|
|
slave);
|
|
g_signal_connect (slave->priv->session,
|
|
+ "conversation-stopped",
|
|
+ G_CALLBACK (on_session_conversation_stopped),
|
|
+ slave);
|
|
+ g_signal_connect (slave->priv->session,
|
|
"setup-complete",
|
|
G_CALLBACK (on_session_setup_complete),
|
|
slave);
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From eb7b50c09cea1c5730c6d1c03a721538c979addc Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Sat, 7 Feb 2009 13:54:24 -0500
|
|
Subject: [PATCH 29/65] Cancel login conversations if any fails
|
|
|
|
This gives us the same behavior we had before
|
|
the ConversationStopped signal was added.
|
|
|
|
We'll improve upon this to only disable the
|
|
conversations that fail as they fail in
|
|
subsequent commits.
|
|
---
|
|
gui/simple-greeter/gdm-greeter-client.c | 21 +++++++++++++++++++++
|
|
gui/simple-greeter/gdm-greeter-client.h | 2 ++
|
|
gui/simple-greeter/gdm-greeter-login-window.c | 11 +++++++++++
|
|
gui/simple-greeter/gdm-greeter-login-window.h | 2 ++
|
|
gui/simple-greeter/gdm-greeter-session.c | 15 +++++++++++++++
|
|
5 files changed, 51 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-greeter-client.c b/gui/simple-greeter/gdm-greeter-client.c
|
|
index 0bd27a9..a9321aa 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-client.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-client.c
|
|
@@ -64,6 +64,7 @@ enum {
|
|
INFO_QUERY,
|
|
SECRET_INFO_QUERY,
|
|
READY,
|
|
+ CONVERSATION_STOPPED,
|
|
RESET,
|
|
SELECTED_USER_CHANGED,
|
|
DEFAULT_LANGUAGE_NAME_CHANGED,
|
|
@@ -270,6 +271,13 @@ on_ready (GdmGreeterClient *client,
|
|
}
|
|
|
|
static void
|
|
+on_conversation_stopped (GdmGreeterClient *client,
|
|
+ DBusMessage *message)
|
|
+{
|
|
+ emit_string_signal_for_message (client, "ConversationStopped", message, CONVERSATION_STOPPED);
|
|
+}
|
|
+
|
|
+static void
|
|
on_reset (GdmGreeterClient *client,
|
|
DBusMessage *message)
|
|
{
|
|
@@ -760,6 +768,8 @@ client_dbus_handle_message (DBusConnection *connection,
|
|
on_problem (client, message);
|
|
} else if (dbus_message_is_signal (message, GREETER_SERVER_DBUS_INTERFACE, "Ready")) {
|
|
on_ready (client, message);
|
|
+ } else if (dbus_message_is_signal (message, GREETER_SERVER_DBUS_INTERFACE, "ConversationStopped")) {
|
|
+ on_conversation_stopped (client, message);
|
|
} else if (dbus_message_is_signal (message, GREETER_SERVER_DBUS_INTERFACE, "Reset")) {
|
|
on_reset (client, message);
|
|
} else if (dbus_message_is_signal (message, GREETER_SERVER_DBUS_INTERFACE, "SelectedUserChanged")) {
|
|
@@ -1000,6 +1010,17 @@ gdm_greeter_client_class_init (GdmGreeterClientClass *klass)
|
|
G_TYPE_NONE,
|
|
1, G_TYPE_STRING);
|
|
|
|
+ gdm_greeter_client_signals[CONVERSATION_STOPPED] =
|
|
+ g_signal_new ("conversation-stopped",
|
|
+ G_OBJECT_CLASS_TYPE (object_class),
|
|
+ G_SIGNAL_RUN_FIRST,
|
|
+ G_STRUCT_OFFSET (GdmGreeterClientClass, conversation_stopped),
|
|
+ NULL,
|
|
+ NULL,
|
|
+ g_cclosure_marshal_VOID__STRING,
|
|
+ G_TYPE_NONE,
|
|
+ 1, G_TYPE_STRING);
|
|
+
|
|
gdm_greeter_client_signals[RESET] =
|
|
g_signal_new ("reset",
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
diff --git a/gui/simple-greeter/gdm-greeter-client.h b/gui/simple-greeter/gdm-greeter-client.h
|
|
index 2f857dc..f879307 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-client.h
|
|
+++ b/gui/simple-greeter/gdm-greeter-client.h
|
|
@@ -61,6 +61,8 @@ typedef struct
|
|
const char *problem);
|
|
void (* ready) (GdmGreeterClient *client,
|
|
const char *service_name);
|
|
+ void (* conversation_stopped) (GdmGreeterClient *client,
|
|
+ const char *service_name);
|
|
void (* reset) (GdmGreeterClient *client);
|
|
void (* selected_user_changed) (GdmGreeterClient *client,
|
|
const char *username);
|
|
diff --git a/gui/simple-greeter/gdm-greeter-login-window.c b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
index ea96abc..4766a78 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-login-window.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
@@ -848,6 +848,17 @@ gdm_greeter_login_window_ready (GdmGreeterLoginWindow *login_window,
|
|
return TRUE;
|
|
}
|
|
|
|
+gboolean
|
|
+gdm_greeter_login_window_conversation_stopped (GdmGreeterLoginWindow *login_window,
|
|
+ const char *service_name)
|
|
+{
|
|
+ GdmTask *task;
|
|
+
|
|
+ g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE);
|
|
+ do_cancel (login_window);
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
static gboolean
|
|
restart_task_conversation (GdmTaskList *task_list,
|
|
GdmTask *task,
|
|
diff --git a/gui/simple-greeter/gdm-greeter-login-window.h b/gui/simple-greeter/gdm-greeter-login-window.h
|
|
index eda7f89..c312a47 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-login-window.h
|
|
+++ b/gui/simple-greeter/gdm-greeter-login-window.h
|
|
@@ -79,6 +79,8 @@ GtkWidget * gdm_greeter_login_window_new (gboolean displa
|
|
gboolean gdm_greeter_login_window_reset (GdmGreeterLoginWindow *login_window);
|
|
gboolean gdm_greeter_login_window_ready (GdmGreeterLoginWindow *login_window,
|
|
const char *service_name);
|
|
+gboolean gdm_greeter_login_window_conversation_stopped (GdmGreeterLoginWindow *login_window,
|
|
+ const char *service_name);
|
|
gboolean gdm_greeter_login_window_info_query (GdmGreeterLoginWindow *login_window,
|
|
const char *service_name,
|
|
const char *text);
|
|
diff --git a/gui/simple-greeter/gdm-greeter-session.c b/gui/simple-greeter/gdm-greeter-session.c
|
|
index d8fd861..7ce4adb 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-session.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-session.c
|
|
@@ -100,6 +100,17 @@ on_ready (GdmGreeterClient *client,
|
|
}
|
|
|
|
static void
|
|
+on_conversation_stopped (GdmGreeterClient *client,
|
|
+ const char *service_name,
|
|
+ GdmGreeterSession *session)
|
|
+{
|
|
+ g_debug ("GdmGreeterSession: Conversation '%s' stopped", service_name);
|
|
+
|
|
+ gdm_greeter_login_window_conversation_stopped (GDM_GREETER_LOGIN_WINDOW (session->priv->login_window),
|
|
+ service_name);
|
|
+}
|
|
+
|
|
+static void
|
|
on_reset (GdmGreeterClient *client,
|
|
GdmGreeterSession *session)
|
|
{
|
|
@@ -601,6 +612,10 @@ gdm_greeter_session_init (GdmGreeterSession *session)
|
|
G_CALLBACK (on_ready),
|
|
session);
|
|
g_signal_connect (session->priv->client,
|
|
+ "conversation-stopped",
|
|
+ G_CALLBACK (on_conversation_stopped),
|
|
+ session);
|
|
+ g_signal_connect (session->priv->client,
|
|
"reset",
|
|
G_CALLBACK (on_reset),
|
|
session);
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From bcf134e25c4c339aace68b04e48dca26c9567cb9 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Sat, 7 Feb 2009 13:57:41 -0500
|
|
Subject: [PATCH 30/65] If a conversation fails in the slave disable task
|
|
|
|
If a conversation fails (say because the user
|
|
hasn't enrolled their fingerprint) then just disable
|
|
that task and keep the other plugins available.
|
|
---
|
|
gui/simple-greeter/gdm-greeter-login-window.c | 12 +++++++++++-
|
|
1 files changed, 11 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-greeter-login-window.c b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
index 4766a78..d5f0253 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-login-window.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
@@ -855,7 +855,17 @@ gdm_greeter_login_window_conversation_stopped (GdmGreeterLoginWindow *login_wind
|
|
GdmTask *task;
|
|
|
|
g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE);
|
|
- do_cancel (login_window);
|
|
+
|
|
+ task = gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
+ (GdmTaskListForeachFunc)
|
|
+ task_has_service_name,
|
|
+ (gpointer) service_name);
|
|
+
|
|
+ if (task != NULL) {
|
|
+ gdm_conversation_reset (GDM_CONVERSATION (task));
|
|
+ g_object_unref (task);
|
|
+ }
|
|
+
|
|
return TRUE;
|
|
}
|
|
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 7dc4f58b55cef33de6d3a3f7d3efae4ca313ca5f Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Sat, 7 Feb 2009 14:11:19 -0500
|
|
Subject: [PATCH 31/65] If a task gets disabled, jump to first task
|
|
|
|
This way we don't show the user a page they
|
|
can't access.
|
|
---
|
|
gui/simple-greeter/gdm-task-list.c | 31 +++++++++++++++++++++++++++++++
|
|
1 files changed, 31 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-task-list.c b/gui/simple-greeter/gdm-task-list.c
|
|
index 71e103e..445b6cc 100644
|
|
--- a/gui/simple-greeter/gdm-task-list.c
|
|
+++ b/gui/simple-greeter/gdm-task-list.c
|
|
@@ -105,14 +105,45 @@ on_task_enabled (GdmTaskList *task_list,
|
|
}
|
|
|
|
static void
|
|
+activate_first_available_task (GdmTaskList *task_list)
|
|
+{
|
|
+ GList *node;
|
|
+
|
|
+ node = task_list->priv->tasks;
|
|
+ while (node != NULL) {
|
|
+ GdmTask *task;
|
|
+ GtkWidget *button;
|
|
+
|
|
+ task = GDM_TASK (node->data);
|
|
+
|
|
+ button = GTK_WIDGET (g_object_get_data (G_OBJECT (task),
|
|
+ "gdm-task-list-button"));
|
|
+
|
|
+ if (GTK_WIDGET_IS_SENSITIVE (button)) {
|
|
+ if (gtk_widget_activate (button)) {
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ node = node->next;
|
|
+ }
|
|
+
|
|
+}
|
|
+
|
|
+static void
|
|
on_task_disabled (GdmTaskList *task_list,
|
|
GdmTask *task)
|
|
{
|
|
GtkWidget *button;
|
|
+ gboolean was_active;
|
|
|
|
button = g_object_get_data (G_OBJECT (task), "gdm-task-list-button");
|
|
+ was_active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
|
|
|
|
gtk_widget_set_sensitive (button, FALSE);
|
|
+
|
|
+ if (was_active) {
|
|
+ activate_first_available_task (task_list);
|
|
+ }
|
|
}
|
|
|
|
void
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From f6a60e2b59c067e222b2254b520c4bbbfc370d3e Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Sat, 7 Feb 2009 14:19:35 -0500
|
|
Subject: [PATCH 32/65] When active task is disabled fall back to old task
|
|
|
|
Previously we would just fall back to the first task
|
|
in the list. Now we fall back to the last task the
|
|
user clicked on.
|
|
---
|
|
gui/simple-greeter/gdm-task-list.c | 12 ++++++++++++
|
|
1 files changed, 12 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-task-list.c b/gui/simple-greeter/gdm-task-list.c
|
|
index 445b6cc..bcf9072 100644
|
|
--- a/gui/simple-greeter/gdm-task-list.c
|
|
+++ b/gui/simple-greeter/gdm-task-list.c
|
|
@@ -97,11 +97,23 @@ on_task_enabled (GdmTaskList *task_list,
|
|
GdmTask *task)
|
|
{
|
|
GtkWidget *button;
|
|
+ GList *task_node;
|
|
|
|
button = g_object_get_data (G_OBJECT (task), "gdm-task-list-button");
|
|
|
|
gtk_widget_set_sensitive (button, TRUE);
|
|
|
|
+ /* Sort the list such that the tasks the user clicks last end
|
|
+ * up first. This doesn't change the order in which the tasks
|
|
+ * appear in the UI, but will affect which tasks we implicitly
|
|
+ * activate if the currently active task gets disabled.
|
|
+ */
|
|
+ task_node = g_list_find (task_list->priv->tasks, task);
|
|
+ if (task_node != NULL) {
|
|
+ task_list->priv->tasks = g_list_delete_link (task_list->priv->tasks, task_node);
|
|
+ task_list->priv->tasks = g_list_prepend (task_list->priv->tasks,
|
|
+ task);
|
|
+ }
|
|
}
|
|
|
|
static void
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 65c9af2e94a1b936ba45f650c45142bf656491ee Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Sat, 7 Feb 2009 21:17:49 -0500
|
|
Subject: [PATCH 33/65] Force session reset if all PAM conversations fail
|
|
|
|
---
|
|
gui/simple-greeter/gdm-greeter-login-window.c | 22 +++++++++++++++++++---
|
|
1 files changed, 19 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-greeter-login-window.c b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
index d5f0253..e65331f 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-login-window.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
@@ -814,15 +814,21 @@ reset_dialog (GdmGreeterLoginWindow *login_window)
|
|
}
|
|
|
|
static void
|
|
-do_cancel (GdmGreeterLoginWindow *login_window)
|
|
+restart_conversations (GdmGreeterLoginWindow *login_window)
|
|
{
|
|
- /* need to wait for response from backend */
|
|
- set_message (login_window, _("Cancelling..."));
|
|
set_busy (login_window);
|
|
set_sensitive (login_window, FALSE);
|
|
g_signal_emit (login_window, signals[CANCELLED], 0);
|
|
}
|
|
|
|
+static void
|
|
+do_cancel (GdmGreeterLoginWindow *login_window)
|
|
+{
|
|
+ /* need to wait for response from backend */
|
|
+ set_message (login_window, _("Cancelling..."));
|
|
+ restart_conversations (login_window);
|
|
+}
|
|
+
|
|
gboolean
|
|
gdm_greeter_login_window_ready (GdmGreeterLoginWindow *login_window,
|
|
const char *service_name)
|
|
@@ -866,6 +872,16 @@ gdm_greeter_login_window_conversation_stopped (GdmGreeterLoginWindow *login_wind
|
|
g_object_unref (task);
|
|
}
|
|
|
|
+ /* If every conversation has failed, then just start over.
|
|
+ */
|
|
+ task = gdm_task_list_get_active_task (GDM_TASK_LIST (login_window->priv->conversation_list));
|
|
+
|
|
+ if (gdm_task_is_enabled (task)) {
|
|
+ g_object_unref (task);
|
|
+ } else {
|
|
+ restart_conversations (login_window);
|
|
+ }
|
|
+
|
|
return TRUE;
|
|
}
|
|
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 35b3c07bf86d64c10f6704987a16d95e694b55f6 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Wed, 11 Feb 2009 08:47:52 -0500
|
|
Subject: [PATCH 34/65] Add bare bones start of a smartcard plugin
|
|
|
|
---
|
|
configure.ac | 1 +
|
|
gui/simple-greeter/plugins/Makefile.am | 2 +-
|
|
gui/simple-greeter/plugins/smartcard/Makefile.am | 40 +++
|
|
.../plugins/smartcard/gdm-smartcard-extension.c | 299 ++++++++++++++++++++
|
|
.../plugins/smartcard/gdm-smartcard-extension.h | 56 ++++
|
|
gui/simple-greeter/plugins/smartcard/page.ui | 56 ++++
|
|
gui/simple-greeter/plugins/smartcard/plugin.c | 40 +++
|
|
7 files changed, 493 insertions(+), 1 deletions(-)
|
|
create mode 100644 gui/simple-greeter/plugins/smartcard/Makefile.am
|
|
create mode 100644 gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c
|
|
create mode 100644 gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.h
|
|
create mode 100644 gui/simple-greeter/plugins/smartcard/page.ui
|
|
create mode 100644 gui/simple-greeter/plugins/smartcard/plugin.c
|
|
|
|
diff --git a/configure.ac b/configure.ac
|
|
index 5b2519a..cf23c0c 100644
|
|
--- a/configure.ac
|
|
+++ b/configure.ac
|
|
@@ -1439,6 +1439,7 @@ gui/simple-greeter/libgdmsimplegreeter/gdmsimplegreeter.pc
|
|
gui/simple-greeter/plugins/Makefile
|
|
gui/simple-greeter/plugins/password/Makefile
|
|
gui/simple-greeter/plugins/fingerprint/Makefile
|
|
+gui/simple-greeter/plugins/smartcard/Makefile
|
|
gui/simple-chooser/Makefile
|
|
gui/user-switch-applet/Makefile
|
|
utils/Makefile
|
|
diff --git a/gui/simple-greeter/plugins/Makefile.am b/gui/simple-greeter/plugins/Makefile.am
|
|
index 9811a68..3dd336f 100644
|
|
--- a/gui/simple-greeter/plugins/Makefile.am
|
|
+++ b/gui/simple-greeter/plugins/Makefile.am
|
|
@@ -1 +1 @@
|
|
-SUBDIRS = password fingerprint
|
|
+SUBDIRS = password fingerprint smartcard
|
|
diff --git a/gui/simple-greeter/plugins/smartcard/Makefile.am b/gui/simple-greeter/plugins/smartcard/Makefile.am
|
|
new file mode 100644
|
|
index 0000000..365d299
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/plugins/smartcard/Makefile.am
|
|
@@ -0,0 +1,40 @@
|
|
+NULL =
|
|
+
|
|
+AM_CPPFLAGS = \
|
|
+ -I$(top_srcdir)/common \
|
|
+ -I$(top_srcdir)/gui/simple-greeter/libnotificationarea \
|
|
+ -I$(top_srcdir)/gui/simple-greeter/libgdmsimplegreeter \
|
|
+ -DDMCONFDIR=\""$(dmconfdir)"\" \
|
|
+ -DGDMCONFDIR=\"$(gdmconfdir)\" \
|
|
+ -DDATADIR=\""$(datadir)"\" \
|
|
+ -DSYSCONFDIR=\""$(sysconfdir)"\" \
|
|
+ -DLIBLOCALEDIR=\""$(prefix)/lib/locale"\" \
|
|
+ -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
|
|
+ -DLIBEXECDIR=\""$(libexecdir)"\" \
|
|
+ -DSBINDIR=\""$(sbindir)"\" \
|
|
+ $(DISABLE_DEPRECATED_CFLAGS) \
|
|
+ $(GTK_CFLAGS) \
|
|
+ $(SIMPLE_GREETER_CFLAGS) \
|
|
+ $(POLKIT_GNOME_CFLAGS) \
|
|
+ $(NULL)
|
|
+
|
|
+plugindir = $(GDM_SIMPLE_GREETER_PLUGINS_DIR)
|
|
+plugin_LTLIBRARIES = smartcard.la
|
|
+
|
|
+smartcard_la_CFLAGS = \
|
|
+ $(SIMPLE_GREETER_CFLAGS) \
|
|
+ $(NULL)
|
|
+
|
|
+smartcard_la_LDFLAGS = -module -avoid-version -export-dynamic
|
|
+smartcard_la_LIBADD = ../../../../common/libgdmcommon.la \
|
|
+ ../../libgdmsimplegreeter/libgdmsimplegreeter.la
|
|
+smartcard_la_SOURCES = \
|
|
+ gdm-smartcard-extension.h \
|
|
+ gdm-smartcard-extension.c \
|
|
+ plugin.c
|
|
+
|
|
+EXTRA_DIST = gdm-smartcard
|
|
+
|
|
+MAINTAINERCLEANFILES = \
|
|
+ *~ \
|
|
+ Makefile.in
|
|
diff --git a/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c
|
|
new file mode 100644
|
|
index 0000000..ac4ab96
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c
|
|
@@ -0,0 +1,299 @@
|
|
+/*
|
|
+ * Copyright (C) 2009 Red Hat, Inc.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
+ *
|
|
+ * Written By: Ray Strode <rstrode@redhat.com>
|
|
+ *
|
|
+ */
|
|
+
|
|
+#include <config.h>
|
|
+#include "gdm-smartcard-extension.h"
|
|
+#include "gdm-conversation.h"
|
|
+#include "gdm-task.h"
|
|
+
|
|
+#include <glib/gi18n-lib.h>
|
|
+#include <gio/gio.h>
|
|
+#include <gtk/gtk.h>
|
|
+
|
|
+struct _GdmSmartcardExtensionPrivate
|
|
+{
|
|
+ GIcon *icon;
|
|
+ GtkWidget *page;
|
|
+ GtkActionGroup *actions;
|
|
+
|
|
+ GtkWidget *message_label;
|
|
+ GtkWidget *prompt_label;
|
|
+ GtkWidget *prompt_entry;
|
|
+
|
|
+ guint answer_pending : 1;
|
|
+};
|
|
+
|
|
+static void gdm_smartcard_extension_finalize (GObject *object);
|
|
+
|
|
+static void gdm_task_iface_init (GdmTaskIface *iface);
|
|
+static void gdm_conversation_iface_init (GdmConversationIface *iface);
|
|
+static void gdm_greeter_extension_iface_init (GdmGreeterExtensionIface *iface);
|
|
+
|
|
+G_DEFINE_TYPE_WITH_CODE (GdmSmartcardExtension,
|
|
+ gdm_smartcard_extension,
|
|
+ G_TYPE_OBJECT,
|
|
+ G_IMPLEMENT_INTERFACE (GDM_TYPE_GREETER_EXTENSION,
|
|
+ gdm_greeter_extension_iface_init)
|
|
+ G_IMPLEMENT_INTERFACE (GDM_TYPE_TASK,
|
|
+ gdm_task_iface_init)
|
|
+ G_IMPLEMENT_INTERFACE (GDM_TYPE_CONVERSATION,
|
|
+ gdm_conversation_iface_init));
|
|
+
|
|
+static void
|
|
+gdm_smartcard_extension_set_message (GdmConversation *conversation,
|
|
+ const char *message)
|
|
+{
|
|
+ GdmSmartcardExtension *extension = GDM_SMARTCARD_EXTENSION (conversation);
|
|
+ gtk_widget_show (extension->priv->message_label);
|
|
+ gtk_label_set_text (GTK_LABEL (extension->priv->message_label), message);
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_extension_ask_question (GdmConversation *conversation,
|
|
+ const char *message)
|
|
+{
|
|
+ GdmSmartcardExtension *extension = GDM_SMARTCARD_EXTENSION (conversation);
|
|
+ gtk_widget_show (extension->priv->prompt_label);
|
|
+ gtk_label_set_text (GTK_LABEL (extension->priv->prompt_label), message);
|
|
+ gtk_entry_set_text (GTK_ENTRY (extension->priv->prompt_entry), "");
|
|
+ gtk_entry_set_visibility (GTK_ENTRY (extension->priv->prompt_entry), TRUE);
|
|
+ gtk_widget_show (extension->priv->prompt_entry);
|
|
+ gtk_widget_grab_focus (extension->priv->prompt_entry);
|
|
+ extension->priv->answer_pending = TRUE;
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_extension_ask_secret (GdmConversation *conversation,
|
|
+ const char *message)
|
|
+{
|
|
+ GdmSmartcardExtension *extension = GDM_SMARTCARD_EXTENSION (conversation);
|
|
+ gtk_widget_show (extension->priv->prompt_label);
|
|
+ gtk_label_set_text (GTK_LABEL (extension->priv->prompt_label), message);
|
|
+ gtk_entry_set_visibility (GTK_ENTRY (extension->priv->prompt_entry), FALSE);
|
|
+ gtk_entry_set_text (GTK_ENTRY (extension->priv->prompt_entry), "");
|
|
+ gtk_widget_show (extension->priv->prompt_entry);
|
|
+ gtk_widget_grab_focus (extension->priv->prompt_entry);
|
|
+ extension->priv->answer_pending = TRUE;
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_extension_reset (GdmConversation *conversation)
|
|
+{
|
|
+ GdmSmartcardExtension *extension = GDM_SMARTCARD_EXTENSION (conversation);
|
|
+ gtk_widget_hide (extension->priv->prompt_label);
|
|
+ gtk_label_set_text (GTK_LABEL (extension->priv->prompt_label), "");
|
|
+
|
|
+ gtk_widget_hide (extension->priv->prompt_entry);
|
|
+ gtk_entry_set_text (GTK_ENTRY (extension->priv->prompt_entry), "");
|
|
+ gtk_entry_set_visibility (GTK_ENTRY (extension->priv->prompt_entry), TRUE);
|
|
+ extension->priv->answer_pending = FALSE;
|
|
+
|
|
+ gdm_task_set_enabled (GDM_TASK (conversation), FALSE);
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_extension_set_ready (GdmConversation *conversation)
|
|
+{
|
|
+ gdm_task_set_enabled (GDM_TASK (conversation), TRUE);
|
|
+}
|
|
+
|
|
+char *
|
|
+gdm_smartcard_extension_get_service_name (GdmConversation *conversation)
|
|
+{
|
|
+ return g_strdup ("smartcard-auth");
|
|
+}
|
|
+
|
|
+GtkWidget *
|
|
+gdm_smartcard_extension_get_page (GdmConversation *conversation)
|
|
+{
|
|
+ GdmSmartcardExtension *extension = GDM_SMARTCARD_EXTENSION (conversation);
|
|
+ return extension->priv->page;
|
|
+}
|
|
+
|
|
+GtkActionGroup *
|
|
+gdm_smartcard_extension_get_actions (GdmConversation *conversation)
|
|
+{
|
|
+ GdmSmartcardExtension *extension = GDM_SMARTCARD_EXTENSION (conversation);
|
|
+
|
|
+ return g_object_ref (extension->priv->actions);
|
|
+}
|
|
+
|
|
+void
|
|
+gdm_smartcard_extension_request_answer (GdmConversation *conversation)
|
|
+{
|
|
+ GdmSmartcardExtension *extension = GDM_SMARTCARD_EXTENSION (conversation);
|
|
+ const char *text;
|
|
+
|
|
+ if (!extension->priv->answer_pending) {
|
|
+ gdm_conversation_answer (conversation, NULL);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ extension->priv->answer_pending = FALSE;
|
|
+ text = gtk_entry_get_text (GTK_ENTRY (extension->priv->prompt_entry));
|
|
+ gdm_conversation_answer (conversation, text);
|
|
+
|
|
+ gtk_widget_hide (extension->priv->prompt_entry);
|
|
+ gtk_label_set_text (GTK_LABEL (extension->priv->prompt_label), "");
|
|
+ gtk_entry_set_text (GTK_ENTRY (extension->priv->prompt_entry), "");
|
|
+}
|
|
+
|
|
+gboolean
|
|
+gdm_smartcard_extension_focus (GdmConversation *conversation)
|
|
+{
|
|
+ GdmSmartcardExtension *extension = GDM_SMARTCARD_EXTENSION (conversation);
|
|
+
|
|
+ if (!extension->priv->answer_pending) {
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ gtk_widget_grab_focus (extension->priv->prompt_entry);
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+GIcon *
|
|
+gdm_smartcard_extension_get_icon (GdmTask *task)
|
|
+{
|
|
+ GdmSmartcardExtension *extension = GDM_SMARTCARD_EXTENSION (task);
|
|
+ return g_object_ref (extension->priv->icon);
|
|
+}
|
|
+
|
|
+char *
|
|
+gdm_smartcard_extension_get_name (GdmTask *task)
|
|
+{
|
|
+ return g_strdup (_("Smartcard Authentication"));
|
|
+}
|
|
+
|
|
+char *
|
|
+gdm_smartcard_extension_get_description (GdmTask *task)
|
|
+{
|
|
+ return g_strdup (_("Log into session with smartcard"));
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_task_iface_init (GdmTaskIface *iface)
|
|
+{
|
|
+ iface->get_icon = gdm_smartcard_extension_get_icon;
|
|
+ iface->get_description = gdm_smartcard_extension_get_description;
|
|
+ iface->get_name = gdm_smartcard_extension_get_name;
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_conversation_iface_init (GdmConversationIface *iface)
|
|
+{
|
|
+ iface->set_message = gdm_smartcard_extension_set_message;
|
|
+ iface->ask_question = gdm_smartcard_extension_ask_question;
|
|
+ iface->ask_secret = gdm_smartcard_extension_ask_secret;
|
|
+ iface->reset = gdm_smartcard_extension_reset;
|
|
+ iface->set_ready = gdm_smartcard_extension_set_ready;
|
|
+ iface->get_service_name = gdm_smartcard_extension_get_service_name;
|
|
+ iface->get_page = gdm_smartcard_extension_get_page;
|
|
+ iface->get_actions = gdm_smartcard_extension_get_actions;
|
|
+ iface->request_answer = gdm_smartcard_extension_request_answer;
|
|
+ iface->focus = gdm_smartcard_extension_focus;
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_greeter_extension_iface_init (GdmGreeterExtensionIface *iface)
|
|
+{
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_extension_class_init (GdmSmartcardExtensionClass *extension_class)
|
|
+{
|
|
+ GObjectClass *object_class;
|
|
+
|
|
+ object_class = G_OBJECT_CLASS (extension_class);
|
|
+
|
|
+ object_class->finalize = gdm_smartcard_extension_finalize;
|
|
+
|
|
+ g_type_class_add_private (extension_class,
|
|
+ sizeof (GdmSmartcardExtensionPrivate));
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_extension_finalize (GObject *object)
|
|
+{
|
|
+}
|
|
+
|
|
+static void
|
|
+create_page (GdmSmartcardExtension *extension)
|
|
+{
|
|
+ GtkBuilder *builder;
|
|
+ GObject *object;
|
|
+ GError *error;
|
|
+
|
|
+ builder = gtk_builder_new ();
|
|
+
|
|
+ error = NULL;
|
|
+ gtk_builder_add_from_file (builder,
|
|
+ "/usr/share/gdm/simple-greeter/extensions/smartcard/page.ui",
|
|
+ &error);
|
|
+
|
|
+ if (error != NULL) {
|
|
+ g_warning ("Could not load UI file: %s", error->message);
|
|
+ g_error_free (error);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ object = gtk_builder_get_object (builder, "page");
|
|
+ g_object_ref (object);
|
|
+
|
|
+ extension->priv->page = GTK_WIDGET (object);
|
|
+
|
|
+ object = gtk_builder_get_object (builder, "auth-prompt-label");
|
|
+ g_object_ref (object);
|
|
+ extension->priv->prompt_label = GTK_WIDGET (object);
|
|
+ gtk_widget_hide (extension->priv->prompt_label);
|
|
+
|
|
+ object = gtk_builder_get_object (builder, "auth-prompt-entry");
|
|
+ g_object_ref (object);
|
|
+ extension->priv->prompt_entry = GTK_WIDGET (object);
|
|
+ gtk_widget_hide (extension->priv->prompt_entry);
|
|
+
|
|
+ object = gtk_builder_get_object (builder, "auth-message-label");
|
|
+ g_object_ref (object);
|
|
+ extension->priv->message_label = GTK_WIDGET (object);
|
|
+ gtk_widget_show (extension->priv->message_label);
|
|
+
|
|
+ g_object_unref (builder);
|
|
+}
|
|
+
|
|
+static void
|
|
+create_actions (GdmSmartcardExtension *extension)
|
|
+{
|
|
+ GtkAction *action;
|
|
+
|
|
+ extension->priv->actions = gtk_action_group_new ("gdm-smartcard-extension");
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_extension_init (GdmSmartcardExtension *extension)
|
|
+{
|
|
+ extension->priv = G_TYPE_INSTANCE_GET_PRIVATE (extension,
|
|
+ GDM_TYPE_SMARTCARD_EXTENSION,
|
|
+ GdmSmartcardExtensionPrivate);
|
|
+
|
|
+ extension->priv->icon = g_themed_icon_new ("apple-green");
|
|
+ create_page (extension);
|
|
+ create_actions (extension);
|
|
+ gdm_smartcard_extension_reset (GDM_CONVERSATION (extension));
|
|
+}
|
|
diff --git a/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.h b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.h
|
|
new file mode 100644
|
|
index 0000000..285b51a
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.h
|
|
@@ -0,0 +1,56 @@
|
|
+/*
|
|
+ * Copyright (C) 2009 Red Hat, Inc.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2, or (at your option)
|
|
+ * any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
+ * 02111-1307, USA.
|
|
+ *
|
|
+ * Written By: Ray Strode <rstrode@redhat.com>
|
|
+ */
|
|
+
|
|
+#ifndef __GDM_SMARTCARD_EXTENSION_H
|
|
+#define __GDM_SMARTCARD_EXTENSION_H
|
|
+
|
|
+#include <glib-object.h>
|
|
+#include "gdm-greeter-extension.h"
|
|
+
|
|
+G_BEGIN_DECLS
|
|
+
|
|
+#define GDM_TYPE_SMARTCARD_EXTENSION (gdm_smartcard_extension_get_type ())
|
|
+#define GDM_SMARTCARD_EXTENSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDM_TYPE_SMARTCARD_EXTENSION, GdmSmartcardExtension))
|
|
+#define GDM_SMARTCARD_EXTENSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDM_TYPE_SMARTCARD_EXTENSION, GdmSmartcardExtensionClass))
|
|
+#define GDM_IS_SMARTCARD_EXTENSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDM_TYPE_SMARTCARD_EXTENSION))
|
|
+#define GDM_IS_SMARTCARD_EXTENSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDM_TYPE_SMARTCARD_EXTENSION))
|
|
+#define GDM_SMARTCARD_EXTENSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GDM_TYPE_SMARTCARD_EXTENSION, GdmSmartcardExtensionClass))
|
|
+
|
|
+typedef struct _GdmSmartcardExtensionPrivate GdmSmartcardExtensionPrivate;
|
|
+
|
|
+typedef struct
|
|
+{
|
|
+ GObject parent;
|
|
+ GdmSmartcardExtensionPrivate *priv;
|
|
+} GdmSmartcardExtension;
|
|
+
|
|
+typedef struct
|
|
+{
|
|
+ GObjectClass parent_class;
|
|
+} GdmSmartcardExtensionClass;
|
|
+
|
|
+GType gdm_smartcard_extension_get_type (void);
|
|
+
|
|
+GdmSmartcardExtension *gdm_smartcard_extension_new (void);
|
|
+
|
|
+G_END_DECLS
|
|
+
|
|
+#endif /* GDM_SMARTCARD_EXTENSION_H */
|
|
diff --git a/gui/simple-greeter/plugins/smartcard/page.ui b/gui/simple-greeter/plugins/smartcard/page.ui
|
|
new file mode 100644
|
|
index 0000000..fe6da78
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/plugins/smartcard/page.ui
|
|
@@ -0,0 +1,56 @@
|
|
+<?xml version="1.0"?>
|
|
+<interface>
|
|
+ <requires lib="gtk+" version="2.14"/>
|
|
+ <object class="GtkVBox" id="page">
|
|
+ <property name="visible">True</property>
|
|
+ <property name="orientation">vertical</property>
|
|
+ <child>
|
|
+ <object class="GtkHBox" id="auth-input-box">
|
|
+ <property name="visible">True</property>
|
|
+ <child>
|
|
+ <object class="GtkLabel" id="auth-prompt-label">
|
|
+ <property name="visible">True</property>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="expand">False</property>
|
|
+ <property name="fill">False</property>
|
|
+ <property name="position">0</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ <child>
|
|
+ <object class="GtkEntry" id="auth-prompt-entry">
|
|
+ <property name="visible">True</property>
|
|
+ <property name="can_focus">True</property>
|
|
+ <property name="activates_default">True</property>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="position">1</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="expand">True</property>
|
|
+ <property name="fill">True</property>
|
|
+ <property name="position">0</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ <child>
|
|
+ <object class="GtkHBox" id="auth-message-box">
|
|
+ <property name="visible">True</property>
|
|
+ <child>
|
|
+ <object class="GtkLabel" id="auth-message-label">
|
|
+ <property name="visible">True</property>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="position">0</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ </object>
|
|
+ <packing>
|
|
+ <property name="expand">True</property>
|
|
+ <property name="fill">True</property>
|
|
+ <property name="position">1</property>
|
|
+ </packing>
|
|
+ </child>
|
|
+ </object>
|
|
+</interface>
|
|
diff --git a/gui/simple-greeter/plugins/smartcard/plugin.c b/gui/simple-greeter/plugins/smartcard/plugin.c
|
|
new file mode 100644
|
|
index 0000000..fffbd50
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/plugins/smartcard/plugin.c
|
|
@@ -0,0 +1,40 @@
|
|
+/*
|
|
+ * Copyright (C) 2009 Red Hat, Inc.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2 of the License, or
|
|
+ * (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
+ *
|
|
+ * Written By: Ray Strode <rstrode@redhat.com>
|
|
+ *
|
|
+ */
|
|
+
|
|
+#include "gdm-smartcard-extension.h"
|
|
+
|
|
+#include <gio/gio.h>
|
|
+#include <gtk/gtk.h>
|
|
+
|
|
+GdmGreeterExtension *
|
|
+gdm_greeter_plugin_get_extension (void)
|
|
+{
|
|
+ static GObject *extension;
|
|
+
|
|
+ if (extension != NULL) {
|
|
+ g_object_ref (extension);
|
|
+ } else {
|
|
+ extension = g_object_new (GDM_TYPE_SMARTCARD_EXTENSION, NULL);
|
|
+ g_object_add_weak_pointer (extension, (gpointer *) &extension);
|
|
+ }
|
|
+
|
|
+ return GDM_GREETER_EXTENSION (extension);
|
|
+}
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 5c160d8feb0edf8523f5d75957ab8ba4bdea887f Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Tue, 17 Feb 2009 17:38:22 -0500
|
|
Subject: [PATCH 35/65] Add another message when plugin fails to load
|
|
|
|
---
|
|
gui/simple-greeter/gdm-greeter-plugin.c | 4 ++++
|
|
1 files changed, 4 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-greeter-plugin.c b/gui/simple-greeter/gdm-greeter-plugin.c
|
|
index 821b679..02814a2 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-plugin.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-plugin.c
|
|
@@ -167,9 +167,13 @@ gdm_greeter_plugin_load (GdmGreeterPlugin *plugin)
|
|
GdmGreeterPluginGetExtensionFunc invoke;
|
|
} get_extension;
|
|
|
|
+
|
|
module = g_module_open (plugin->priv->filename, G_MODULE_BIND_LOCAL);
|
|
|
|
if (module == NULL) {
|
|
+ g_warning ("plugin %s couldn't be opened: %s",
|
|
+ plugin->priv->filename,
|
|
+ g_module_error ());
|
|
g_signal_emit (plugin, signals [LOAD_FAILED], 0);
|
|
return;
|
|
}
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 7f73245875240390f985971cef7d6ba107f48fd6 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Tue, 17 Feb 2009 17:39:24 -0500
|
|
Subject: [PATCH 36/65] Add new gdm_task_list_set_active_task
|
|
|
|
It will be useful to be able to select
|
|
a task from the greeter programmatically.
|
|
---
|
|
gui/simple-greeter/gdm-task-list.c | 29 +++++++++++++++++++++--------
|
|
gui/simple-greeter/gdm-task-list.h | 2 ++
|
|
2 files changed, 23 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-task-list.c b/gui/simple-greeter/gdm-task-list.c
|
|
index bcf9072..25831a6 100644
|
|
--- a/gui/simple-greeter/gdm-task-list.c
|
|
+++ b/gui/simple-greeter/gdm-task-list.c
|
|
@@ -124,18 +124,13 @@ activate_first_available_task (GdmTaskList *task_list)
|
|
node = task_list->priv->tasks;
|
|
while (node != NULL) {
|
|
GdmTask *task;
|
|
- GtkWidget *button;
|
|
|
|
task = GDM_TASK (node->data);
|
|
|
|
- button = GTK_WIDGET (g_object_get_data (G_OBJECT (task),
|
|
- "gdm-task-list-button"));
|
|
-
|
|
- if (GTK_WIDGET_IS_SENSITIVE (button)) {
|
|
- if (gtk_widget_activate (button)) {
|
|
- break;
|
|
- }
|
|
+ if (gdm_task_list_set_active_task (task_list, task)) {
|
|
+ break;
|
|
}
|
|
+
|
|
node = node->next;
|
|
}
|
|
|
|
@@ -302,6 +297,24 @@ gdm_task_list_get_active_task (GdmTaskList *widget)
|
|
NULL);
|
|
}
|
|
|
|
+gboolean
|
|
+gdm_task_list_set_active_task (GdmTaskList *widget,
|
|
+ GdmTask *task)
|
|
+{
|
|
+ GtkWidget *button;
|
|
+
|
|
+ button = GTK_WIDGET (g_object_get_data (G_OBJECT (task),
|
|
+ "gdm-task-list-button"));
|
|
+
|
|
+ if (GTK_WIDGET_IS_SENSITIVE (button)) {
|
|
+ if (gtk_widget_activate (button)) {
|
|
+ return TRUE;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return FALSE;
|
|
+}
|
|
+
|
|
int
|
|
gdm_task_list_get_number_of_tasks (GdmTaskList *widget)
|
|
{
|
|
diff --git a/gui/simple-greeter/gdm-task-list.h b/gui/simple-greeter/gdm-task-list.h
|
|
index e8cc2f4..8bc0c0e 100644
|
|
--- a/gui/simple-greeter/gdm-task-list.h
|
|
+++ b/gui/simple-greeter/gdm-task-list.h
|
|
@@ -66,6 +66,8 @@ GtkWidget * gdm_task_list_new (void);
|
|
gboolean gdm_task_list_task_is_active (GdmTaskList *task_list,
|
|
GdmTask *task);
|
|
GdmTask * gdm_task_list_get_active_task (GdmTaskList *widget);
|
|
+gboolean gdm_task_list_set_active_task (GdmTaskList *widget,
|
|
+ GdmTask *task);
|
|
GdmTask * gdm_task_list_foreach_task (GdmTaskList *widget,
|
|
GdmTaskListForeachFunc foreach_func,
|
|
gpointer data);
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 62ce8e8321096be8b6842400e70a468e0824656c Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Wed, 18 Feb 2009 12:32:39 -0500
|
|
Subject: [PATCH 37/65] Add a way for plugins to start/stop pam
|
|
|
|
The smartcard plugin is going to want to
|
|
start the conversation as soon as the card
|
|
gets plugged in.
|
|
---
|
|
gui/simple-greeter/gdm-greeter-login-window.c | 27 ++++++++++++++++
|
|
.../libgdmsimplegreeter/gdm-conversation.c | 32 ++++++++++++++++++++
|
|
.../libgdmsimplegreeter/gdm-conversation.h | 6 ++++
|
|
3 files changed, 65 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-greeter-login-window.c b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
index e65331f..5f37d0c 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-login-window.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
@@ -2248,6 +2248,25 @@ on_conversation_answer (GdmGreeterLoginWindow *login_window,
|
|
set_ready (login_window);
|
|
}
|
|
|
|
+static void
|
|
+on_conversation_cancel (GdmGreeterLoginWindow *login_window,
|
|
+ GdmConversation *conversation)
|
|
+{
|
|
+ do_cancel (login_window);
|
|
+}
|
|
+
|
|
+static void
|
|
+on_conversation_chose_user (GdmGreeterLoginWindow *login_window,
|
|
+ const char *username,
|
|
+ GdmConversation *conversation)
|
|
+{
|
|
+ if (gdm_task_list_set_active_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
+ GDM_TASK (conversation))) {
|
|
+ gdm_user_chooser_widget_set_chosen_user_name (GDM_USER_CHOOSER_WIDGET (login_window->priv->user_chooser),
|
|
+ username);
|
|
+ }
|
|
+}
|
|
+
|
|
void
|
|
gdm_greeter_login_window_remove_extension (GdmGreeterLoginWindow *login_window,
|
|
GdmGreeterExtension *extension)
|
|
@@ -2385,6 +2404,14 @@ gdm_greeter_login_window_add_extension (GdmGreeterLoginWindow *login_window,
|
|
"answer",
|
|
G_CALLBACK (on_conversation_answer),
|
|
login_window);
|
|
+ g_signal_connect_swapped (GDM_CONVERSATION (extension),
|
|
+ "cancel",
|
|
+ G_CALLBACK (on_conversation_cancel),
|
|
+ login_window);
|
|
+ g_signal_connect_swapped (GDM_CONVERSATION (extension),
|
|
+ "user-chosen",
|
|
+ G_CALLBACK (on_conversation_chose_user),
|
|
+ login_window);
|
|
|
|
name = gdm_task_get_name (GDM_TASK (extension));
|
|
description = gdm_task_get_description (GDM_TASK (extension));
|
|
diff --git a/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.c b/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.c
|
|
index e21c56b..cef435c 100644
|
|
--- a/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.c
|
|
+++ b/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.c
|
|
@@ -30,6 +30,8 @@
|
|
|
|
enum {
|
|
ANSWER,
|
|
+ USER_CHOSEN,
|
|
+ CANCEL,
|
|
LAST_SIGNAL
|
|
};
|
|
|
|
@@ -71,6 +73,25 @@ gdm_conversation_class_init (gpointer g_iface)
|
|
g_cclosure_marshal_VOID__STRING,
|
|
G_TYPE_NONE,
|
|
1, G_TYPE_STRING);
|
|
+ signals [USER_CHOSEN] =
|
|
+ g_signal_new ("user-chosen",
|
|
+ iface_type,
|
|
+ G_SIGNAL_RUN_FIRST,
|
|
+ G_STRUCT_OFFSET (GdmConversationIface, user_chosen),
|
|
+ NULL,
|
|
+ NULL,
|
|
+ g_cclosure_marshal_VOID__STRING,
|
|
+ G_TYPE_NONE,
|
|
+ 1, G_TYPE_STRING);
|
|
+ signals [CANCEL] =
|
|
+ g_signal_new ("cancel",
|
|
+ iface_type,
|
|
+ G_SIGNAL_RUN_FIRST,
|
|
+ G_STRUCT_OFFSET (GdmConversationIface, cancel),
|
|
+ NULL,
|
|
+ NULL,
|
|
+ g_cclosure_marshal_VOID__VOID,
|
|
+ G_TYPE_NONE, 0);
|
|
}
|
|
|
|
void
|
|
@@ -145,3 +166,14 @@ gdm_conversation_answer (GdmConversation *conversation,
|
|
g_signal_emit (conversation, signals [ANSWER], 0, answer);
|
|
}
|
|
|
|
+void
|
|
+gdm_conversation_cancel (GdmConversation *conversation)
|
|
+{
|
|
+ g_signal_emit (conversation, signals [CANCEL], 0);
|
|
+}
|
|
+void
|
|
+gdm_conversation_choose_user (GdmConversation *conversation,
|
|
+ const char *username)
|
|
+{
|
|
+ g_signal_emit (conversation, signals [USER_CHOSEN], 0, username);
|
|
+}
|
|
diff --git a/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.h b/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.h
|
|
index f1910cf..fb4bf49 100644
|
|
--- a/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.h
|
|
+++ b/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.h
|
|
@@ -34,6 +34,7 @@ G_BEGIN_DECLS
|
|
#define GDM_CONVERSATION_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), GDM_TYPE_CONVERSATION, GdmConversationIface))
|
|
|
|
#define GDM_CONVERSATION_DEFAULT_ACTION "default-action"
|
|
+#define GDM_CONVERSATION_OTHER_USER "__other"
|
|
|
|
typedef struct _GdmConversation GdmConversation;
|
|
typedef struct _GdmConversationIface GdmConversationIface;
|
|
@@ -59,6 +60,8 @@ struct _GdmConversationIface
|
|
|
|
/* signals */
|
|
char * (* answer) (GdmConversation *conversation);
|
|
+ void (* cancel) (GdmConversation *conversation);
|
|
+ void (* user_chosen) (GdmConversation *conversation);
|
|
};
|
|
|
|
GType gdm_conversation_get_type (void) G_GNUC_CONST;
|
|
@@ -81,6 +84,9 @@ gboolean gdm_conversation_focus (GdmConversation *conversation);
|
|
*/
|
|
void gdm_conversation_answer (GdmConversation *conversation,
|
|
const char *answer);
|
|
+void gdm_conversation_cancel (GdmConversation *conversation);
|
|
+void gdm_conversation_choose_user (GdmConversation *conversation,
|
|
+ const char *username);
|
|
|
|
G_END_DECLS
|
|
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 3a3508b1fde4e244b10b16566cd171ad9557855e Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Wed, 18 Feb 2009 12:48:37 -0500
|
|
Subject: [PATCH 38/65] Add helper program to listen for smart card events
|
|
|
|
This is a copy and paste of an old RHEL patch I did
|
|
a few years ago.
|
|
---
|
|
configure.ac | 7 +
|
|
gui/simple-greeter/plugins/smartcard/Makefile.am | 22 +
|
|
.../plugins/smartcard/gdm-smartcard-extension.c | 91 ++
|
|
.../plugins/smartcard/gdm-smartcard-manager.c | 1394 ++++++++++++++++++++
|
|
.../plugins/smartcard/gdm-smartcard-manager.h | 86 ++
|
|
.../plugins/smartcard/gdm-smartcard-worker.c | 167 +++
|
|
.../plugins/smartcard/gdm-smartcard.c | 558 ++++++++
|
|
.../plugins/smartcard/gdm-smartcard.h | 94 ++
|
|
8 files changed, 2419 insertions(+), 0 deletions(-)
|
|
create mode 100644 gui/simple-greeter/plugins/smartcard/gdm-smartcard-manager.c
|
|
create mode 100644 gui/simple-greeter/plugins/smartcard/gdm-smartcard-manager.h
|
|
create mode 100644 gui/simple-greeter/plugins/smartcard/gdm-smartcard-worker.c
|
|
create mode 100644 gui/simple-greeter/plugins/smartcard/gdm-smartcard.c
|
|
create mode 100644 gui/simple-greeter/plugins/smartcard/gdm-smartcard.h
|
|
|
|
diff --git a/configure.ac b/configure.ac
|
|
index cf23c0c..8e99509 100644
|
|
--- a/configure.ac
|
|
+++ b/configure.ac
|
|
@@ -67,6 +67,7 @@ GNOME_PANEL_REQUIRED_VERSION=2.0.0
|
|
LIBXKLAVIER_REQUIRED_VERSION=3.5
|
|
#FONTCONFIG_REQUIRED_VERSION=2.6.0
|
|
FONTCONFIG_REQUIRED_VERSION=2.5.0
|
|
+NSS_REQUIRED_VERSION=3.11.1
|
|
|
|
EXTRA_COMPILE_WARNINGS(yes)
|
|
|
|
@@ -89,6 +90,12 @@ PKG_CHECK_MODULES(DAEMON,
|
|
AC_SUBST(DAEMON_CFLAGS)
|
|
AC_SUBST(DAEMON_LIBS)
|
|
|
|
+PKG_CHECK_MODULES(NSS,
|
|
+ nss >= $NSS_REQUIRED_VERSION
|
|
+)
|
|
+AC_SUBST(NSS_CFLAGS)
|
|
+AC_SUBST(NSS_LIBS)
|
|
+
|
|
PKG_CHECK_MODULES(XLIB, x11 xau, ,
|
|
[AC_PATH_XTRA
|
|
if test "x$no_x" = xyes; then
|
|
diff --git a/gui/simple-greeter/plugins/smartcard/Makefile.am b/gui/simple-greeter/plugins/smartcard/Makefile.am
|
|
index 365d299..2dfe226 100644
|
|
--- a/gui/simple-greeter/plugins/smartcard/Makefile.am
|
|
+++ b/gui/simple-greeter/plugins/smartcard/Makefile.am
|
|
@@ -11,6 +11,7 @@ AM_CPPFLAGS = \
|
|
-DLIBLOCALEDIR=\""$(prefix)/lib/locale"\" \
|
|
-DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
|
|
-DLIBEXECDIR=\""$(libexecdir)"\" \
|
|
+ -DLIBDIR=\""$(libdir)"\" \
|
|
-DSBINDIR=\""$(sbindir)"\" \
|
|
$(DISABLE_DEPRECATED_CFLAGS) \
|
|
$(GTK_CFLAGS) \
|
|
@@ -25,6 +26,11 @@ smartcard_la_CFLAGS = \
|
|
$(SIMPLE_GREETER_CFLAGS) \
|
|
$(NULL)
|
|
|
|
+libexec_PROGRAMS = \
|
|
+ gdm-smartcard-worker \
|
|
+ $(NULL)
|
|
+
|
|
+
|
|
smartcard_la_LDFLAGS = -module -avoid-version -export-dynamic
|
|
smartcard_la_LIBADD = ../../../../common/libgdmcommon.la \
|
|
../../libgdmsimplegreeter/libgdmsimplegreeter.la
|
|
@@ -33,6 +39,22 @@ smartcard_la_SOURCES = \
|
|
gdm-smartcard-extension.c \
|
|
plugin.c
|
|
|
|
+gdm_smartcard_worker_LDADD = ../../../../common/libgdmcommon.la \
|
|
+ $(DAEMON_LIBS) \
|
|
+ $(GTHREAD_LIBS) \
|
|
+ $(NSS_LIBS) \
|
|
+ $(NULL)
|
|
+gdm_smartcard_worker_CFLAGS = $(DAEMON_CFLAGS) \
|
|
+ $(NSS_CFLAGS) \
|
|
+ $(NULL)
|
|
+gdm_smartcard_worker_SOURCES = \
|
|
+ gdm-smartcard.h \
|
|
+ gdm-smartcard.c \
|
|
+ gdm-smartcard-manager.h \
|
|
+ gdm-smartcard-manager.c \
|
|
+ gdm-smartcard-worker.c \
|
|
+ $(NULL)
|
|
+
|
|
EXTRA_DIST = gdm-smartcard
|
|
|
|
MAINTAINERCLEANFILES = \
|
|
diff --git a/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c
|
|
index ac4ab96..efa0978 100644
|
|
--- a/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c
|
|
+++ b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c
|
|
@@ -24,10 +24,20 @@
|
|
#include "gdm-conversation.h"
|
|
#include "gdm-task.h"
|
|
|
|
+#include <errno.h>
|
|
+#include <fcntl.h>
|
|
+#include <stdio.h>
|
|
+#include <sys/types.h>
|
|
+#include <unistd.h>
|
|
+
|
|
#include <glib/gi18n-lib.h>
|
|
#include <gio/gio.h>
|
|
#include <gtk/gtk.h>
|
|
|
|
+#ifndef GDM_SMARTCARD_WORKER_COMMAND
|
|
+#define GDM_SMARTCARD_WORKER_COMMAND LIBEXECDIR "/gdm-smartcard-worker"
|
|
+#endif
|
|
+
|
|
struct _GdmSmartcardExtensionPrivate
|
|
{
|
|
GIcon *icon;
|
|
@@ -38,6 +48,9 @@ struct _GdmSmartcardExtensionPrivate
|
|
GtkWidget *prompt_label;
|
|
GtkWidget *prompt_entry;
|
|
|
|
+ GPid worker_pid;
|
|
+ int number_of_tokens;
|
|
+
|
|
guint answer_pending : 1;
|
|
};
|
|
|
|
@@ -284,6 +297,83 @@ create_actions (GdmSmartcardExtension *extension)
|
|
|
|
extension->priv->actions = gtk_action_group_new ("gdm-smartcard-extension");
|
|
}
|
|
+static gboolean
|
|
+on_smartcard_event (GIOChannel *io_channel,
|
|
+ GIOCondition condition,
|
|
+ gpointer data)
|
|
+{
|
|
+ GdmSmartcardExtension *extension;
|
|
+
|
|
+ extension = GDM_SMARTCARD_EXTENSION (data);
|
|
+
|
|
+ if (condition & G_IO_IN) {
|
|
+ char buffer[1024];
|
|
+ ssize_t num_bytes;
|
|
+
|
|
+ num_bytes = read (g_io_channel_unix_get_fd (io_channel),
|
|
+ buffer, sizeof (buffer));
|
|
+
|
|
+ if (num_bytes < 0 && errno != EINTR)
|
|
+ return FALSE;
|
|
+
|
|
+ if (num_bytes != 1) {
|
|
+ g_debug ("buffer: %s\n", buffer);
|
|
+ return TRUE;
|
|
+ }
|
|
+
|
|
+ if (buffer[0] == 'I') {
|
|
+ extension->priv->number_of_tokens++;
|
|
+ } else {
|
|
+ extension->priv->number_of_tokens--;
|
|
+ }
|
|
+
|
|
+ if (extension->priv->number_of_tokens == 1) {
|
|
+ gdm_conversation_choose_user (GDM_CONVERSATION (extension),
|
|
+ GDM_CONVERSATION_OTHER_USER);
|
|
+ } else if (extension->priv->number_of_tokens == 0) {
|
|
+ gdm_conversation_cancel (GDM_CONVERSATION (extension));
|
|
+ }
|
|
+
|
|
+ return TRUE;
|
|
+ }
|
|
+
|
|
+ if (condition & G_IO_HUP) {
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+static void
|
|
+watch_for_smartcards (GdmSmartcardExtension *extension)
|
|
+{
|
|
+ GError *error;
|
|
+ GIOChannel *io_channel;
|
|
+ char *args[] = { GDM_SMARTCARD_WORKER_COMMAND, NULL };
|
|
+ GPid pid;
|
|
+ int stdout_fd;
|
|
+
|
|
+ error = NULL;
|
|
+
|
|
+ if (!g_spawn_async_with_pipes (NULL, args, NULL, 0,
|
|
+ NULL, NULL, &pid, NULL,
|
|
+ &stdout_fd, NULL, &error)) {
|
|
+ g_debug ("could not start smart card manager: %s", error->message);
|
|
+ g_error_free (error);
|
|
+ return;
|
|
+ }
|
|
+ fcntl (stdout_fd, F_SETFD, FD_CLOEXEC);
|
|
+
|
|
+ io_channel = g_io_channel_unix_new (stdout_fd);
|
|
+ g_io_channel_set_flags (io_channel, G_IO_FLAG_NONBLOCK, NULL);
|
|
+ g_io_channel_set_encoding (io_channel, NULL, NULL);
|
|
+ g_io_channel_set_buffered (io_channel, FALSE);
|
|
+ g_io_add_watch (io_channel, G_IO_IN, on_smartcard_event, extension);
|
|
+ g_io_channel_set_close_on_unref (io_channel, TRUE);
|
|
+ g_io_channel_unref (io_channel);
|
|
+
|
|
+ extension->priv->worker_pid = pid;
|
|
+}
|
|
|
|
static void
|
|
gdm_smartcard_extension_init (GdmSmartcardExtension *extension)
|
|
@@ -293,6 +383,7 @@ gdm_smartcard_extension_init (GdmSmartcardExtension *extension)
|
|
GdmSmartcardExtensionPrivate);
|
|
|
|
extension->priv->icon = g_themed_icon_new ("apple-green");
|
|
+ watch_for_smartcards (extension);
|
|
create_page (extension);
|
|
create_actions (extension);
|
|
gdm_smartcard_extension_reset (GDM_CONVERSATION (extension));
|
|
diff --git a/gui/simple-greeter/plugins/smartcard/gdm-smartcard-manager.c b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-manager.c
|
|
new file mode 100644
|
|
index 0000000..e346a9c
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-manager.c
|
|
@@ -0,0 +1,1394 @@
|
|
+/* gdm-smartcard-manager.c - object for monitoring smartcard insertion and
|
|
+ * removal events
|
|
+ *
|
|
+ * Copyright (C) 2006, 2009 Red Hat, Inc.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2, or (at your option)
|
|
+ * any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
+ * 02111-1307, USA.
|
|
+ *
|
|
+ * Written By: Ray Strode
|
|
+ */
|
|
+#define _GNU_SOURCE
|
|
+#include "gdm-smartcard-manager.h"
|
|
+
|
|
+#define GDM_SMARTCARD_ENABLE_INTERNAL_API
|
|
+#include "gdm-smartcard.h"
|
|
+
|
|
+#include <dirent.h>
|
|
+#include <errno.h>
|
|
+#include <fcntl.h>
|
|
+#include <limits.h>
|
|
+#include <poll.h>
|
|
+#include <signal.h>
|
|
+#include <stdlib.h>
|
|
+#include <string.h>
|
|
+#include <sys/resource.h>
|
|
+#include <sys/time.h>
|
|
+#include <sys/wait.h>
|
|
+#include <unistd.h>
|
|
+
|
|
+#include <glib.h>
|
|
+#include <glib/gi18n.h>
|
|
+
|
|
+#include <prerror.h>
|
|
+#include <nss.h>
|
|
+#include <pk11func.h>
|
|
+#include <secmod.h>
|
|
+#include <secerr.h>
|
|
+
|
|
+#ifndef GDM_SMARTCARD_MANAGER_DRIVER
|
|
+#define GDM_SMARTCARD_MANAGER_DRIVER LIBDIR"/pkcs11/libcoolkeypk11.so"
|
|
+#endif
|
|
+
|
|
+#ifndef GDM_SMARTCARD_MANAGER_NSS_DB
|
|
+#define GDM_SMARTCARD_MANAGER_NSS_DB SYSCONFDIR"/pki/nssdb"
|
|
+#endif
|
|
+
|
|
+#ifndef GDM_MAX_OPEN_FILE_DESCRIPTORS
|
|
+#define GDM_MAX_OPEN_FILE_DESCRIPTORS 1024
|
|
+#endif
|
|
+
|
|
+#ifndef GDM_OPEN_FILE_DESCRIPTORS_DIR
|
|
+#define GDM_OPEN_FILE_DESCRIPTORS_DIR "/proc/self/fd"
|
|
+#endif
|
|
+
|
|
+typedef enum _GdmSmartcardManagerState GdmSmartcardManagerState;
|
|
+typedef struct _GdmSmartcardManagerWorker GdmSmartcardManagerWorker;
|
|
+
|
|
+enum _GdmSmartcardManagerState {
|
|
+ GDM_SMARTCARD_MANAGER_STATE_STOPPED = 0,
|
|
+ GDM_SMARTCARD_MANAGER_STATE_STARTING,
|
|
+ GDM_SMARTCARD_MANAGER_STATE_STARTED,
|
|
+ GDM_SMARTCARD_MANAGER_STATE_STOPPING,
|
|
+};
|
|
+
|
|
+struct _GdmSmartcardManagerPrivate {
|
|
+ GdmSmartcardManagerState state;
|
|
+ SECMODModule *module;
|
|
+ char *module_path;
|
|
+
|
|
+ GSource *smartcard_event_source;
|
|
+ GPid smartcard_event_watcher_pid;
|
|
+ GHashTable *smartcards;
|
|
+
|
|
+ GThread *worker_thread;
|
|
+
|
|
+ guint poll_timeout_id;
|
|
+
|
|
+ guint32 is_unstoppable : 1;
|
|
+ guint32 nss_is_loaded : 1;
|
|
+};
|
|
+
|
|
+struct _GdmSmartcardManagerWorker {
|
|
+ SECMODModule *module;
|
|
+ GHashTable *smartcards;
|
|
+ gint write_fd;
|
|
+
|
|
+ guint32 nss_is_loaded : 1;
|
|
+};
|
|
+
|
|
+static void gdm_smartcard_manager_finalize (GObject *object);
|
|
+static void gdm_smartcard_manager_class_install_signals (GdmSmartcardManagerClass *service_class);
|
|
+static void gdm_smartcard_manager_class_install_properties (GdmSmartcardManagerClass *service_class);
|
|
+static void gdm_smartcard_manager_set_property (GObject *object,
|
|
+ guint prop_id,
|
|
+ const GValue *value,
|
|
+ GParamSpec *pspec);
|
|
+static void gdm_smartcard_manager_get_property (GObject *object,
|
|
+ guint prop_id,
|
|
+ GValue *value,
|
|
+ GParamSpec *pspec);
|
|
+static void gdm_smartcard_manager_set_module_path (GdmSmartcardManager *manager,
|
|
+ const char *module_path);
|
|
+static void gdm_smartcard_manager_card_removed_handler (GdmSmartcardManager *manager,
|
|
+ GdmSmartcard *card);
|
|
+static void gdm_smartcard_manager_card_inserted_handler (GdmSmartcardManager *manager_class,
|
|
+ GdmSmartcard *card);
|
|
+static gboolean gdm_smartcard_manager_stop_now (GdmSmartcardManager *manager);
|
|
+static void gdm_smartcard_manager_queue_stop (GdmSmartcardManager *manager);
|
|
+
|
|
+static gboolean gdm_smartcard_manager_create_worker (GdmSmartcardManager *manager,
|
|
+ int *worker_fd, GThread **worker_thread);
|
|
+
|
|
+static GdmSmartcardManagerWorker * gdm_smartcard_manager_worker_new (gint write_fd);
|
|
+static void gdm_smartcard_manager_worker_free (GdmSmartcardManagerWorker *worker);
|
|
+static gboolean gdm_open_pipe (gint *write_fd, gint *read_fd);
|
|
+static gboolean sc_read_bytes (gint fd, gpointer bytes, gsize num_bytes);
|
|
+static gboolean sc_write_bytes (gint fd, gconstpointer bytes, gsize num_bytes);
|
|
+static GdmSmartcard *sc_read_smartcard (gint fd, SECMODModule *module);
|
|
+static gboolean sc_write_smartcard (gint fd, GdmSmartcard *card);
|
|
+
|
|
+enum {
|
|
+ PROP_0 = 0,
|
|
+ PROP_MODULE_PATH,
|
|
+ NUMBER_OF_PROPERTIES
|
|
+};
|
|
+
|
|
+enum {
|
|
+ SMARTCARD_INSERTED = 0,
|
|
+ SMARTCARD_REMOVED,
|
|
+ ERROR,
|
|
+ NUMBER_OF_SIGNALS
|
|
+};
|
|
+
|
|
+static guint gdm_smartcard_manager_signals[NUMBER_OF_SIGNALS];
|
|
+
|
|
+G_DEFINE_TYPE (GdmSmartcardManager,
|
|
+ gdm_smartcard_manager,
|
|
+ G_TYPE_OBJECT);
|
|
+
|
|
+static void
|
|
+gdm_smartcard_manager_class_init (GdmSmartcardManagerClass *manager_class)
|
|
+{
|
|
+ GObjectClass *gobject_class;
|
|
+
|
|
+ gobject_class = G_OBJECT_CLASS (manager_class);
|
|
+
|
|
+ gobject_class->finalize = gdm_smartcard_manager_finalize;
|
|
+
|
|
+ gdm_smartcard_manager_class_install_signals (manager_class);
|
|
+ gdm_smartcard_manager_class_install_properties (manager_class);
|
|
+
|
|
+ g_type_class_add_private (manager_class,
|
|
+ sizeof (GdmSmartcardManagerPrivate));
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_manager_class_install_properties (GdmSmartcardManagerClass *card_class)
|
|
+{
|
|
+ GObjectClass *object_class;
|
|
+ GParamSpec *param_spec;
|
|
+
|
|
+ object_class = G_OBJECT_CLASS (card_class);
|
|
+ object_class->set_property = gdm_smartcard_manager_set_property;
|
|
+ object_class->get_property = gdm_smartcard_manager_get_property;
|
|
+
|
|
+ param_spec = g_param_spec_string ("module-path", _("Module Path"),
|
|
+ _("path to smartcard PKCS #11 driver"),
|
|
+ NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
|
+ g_object_class_install_property (object_class, PROP_MODULE_PATH, param_spec);
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_manager_set_property (GObject *object,
|
|
+ guint prop_id,
|
|
+ const GValue *value,
|
|
+ GParamSpec *pspec)
|
|
+{
|
|
+ GdmSmartcardManager *manager = GDM_SMARTCARD_MANAGER (object);
|
|
+
|
|
+ switch (prop_id) {
|
|
+ case PROP_MODULE_PATH:
|
|
+ gdm_smartcard_manager_set_module_path (manager,
|
|
+ g_value_get_string (value));
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_manager_get_property (GObject *object,
|
|
+ guint prop_id,
|
|
+ GValue *value,
|
|
+ GParamSpec *pspec)
|
|
+{
|
|
+ GdmSmartcardManager *manager = GDM_SMARTCARD_MANAGER (object);
|
|
+ char *module_path;
|
|
+
|
|
+ switch (prop_id) {
|
|
+ case PROP_MODULE_PATH:
|
|
+ module_path = gdm_smartcard_manager_get_module_path (manager);
|
|
+ g_value_set_string (value, module_path);
|
|
+ g_free (module_path);
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
+ break;
|
|
+ }
|
|
+}
|
|
+
|
|
+char *
|
|
+gdm_smartcard_manager_get_module_path (GdmSmartcardManager *manager)
|
|
+{
|
|
+ return manager->priv->module_path;
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_manager_set_module_path (GdmSmartcardManager *manager,
|
|
+ const char *module_path)
|
|
+{
|
|
+ if ((manager->priv->module_path == NULL) && (module_path == NULL)) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (((manager->priv->module_path == NULL) ||
|
|
+ (module_path == NULL) ||
|
|
+ (strcmp (manager->priv->module_path, module_path) != 0))) {
|
|
+ g_free (manager->priv->module_path);
|
|
+ manager->priv->module_path = g_strdup (module_path);
|
|
+ g_object_notify (G_OBJECT (manager), "module-path");
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_manager_card_removed_handler (GdmSmartcardManager *manager,
|
|
+ GdmSmartcard *card)
|
|
+{
|
|
+ g_debug ("informing smartcard of its removal");
|
|
+ _gdm_smartcard_set_state (card, GDM_SMARTCARD_STATE_REMOVED);
|
|
+ g_debug ("done");
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_manager_card_inserted_handler (GdmSmartcardManager *manager,
|
|
+ GdmSmartcard *card)
|
|
+{
|
|
+ g_debug ("informing smartcard of its insertion");
|
|
+
|
|
+ _gdm_smartcard_set_state (card, GDM_SMARTCARD_STATE_INSERTED);
|
|
+ g_debug ("done");
|
|
+
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_manager_class_install_signals (GdmSmartcardManagerClass *manager_class)
|
|
+{
|
|
+ GObjectClass *object_class;
|
|
+
|
|
+ object_class = G_OBJECT_CLASS (manager_class);
|
|
+
|
|
+ gdm_smartcard_manager_signals[SMARTCARD_INSERTED] =
|
|
+ g_signal_new ("smartcard-inserted",
|
|
+ G_OBJECT_CLASS_TYPE (object_class),
|
|
+ G_SIGNAL_RUN_FIRST,
|
|
+ G_STRUCT_OFFSET (GdmSmartcardManagerClass,
|
|
+ smartcard_inserted),
|
|
+ NULL, NULL, g_cclosure_marshal_VOID__POINTER,
|
|
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
|
|
+ manager_class->smartcard_inserted = gdm_smartcard_manager_card_inserted_handler;
|
|
+
|
|
+ gdm_smartcard_manager_signals[SMARTCARD_REMOVED] =
|
|
+ g_signal_new ("smartcard-removed",
|
|
+ G_OBJECT_CLASS_TYPE (object_class),
|
|
+ G_SIGNAL_RUN_FIRST,
|
|
+ G_STRUCT_OFFSET (GdmSmartcardManagerClass,
|
|
+ smartcard_removed),
|
|
+ NULL, NULL, g_cclosure_marshal_VOID__POINTER,
|
|
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
|
|
+ manager_class->smartcard_removed = gdm_smartcard_manager_card_removed_handler;
|
|
+
|
|
+ gdm_smartcard_manager_signals[ERROR] =
|
|
+ g_signal_new ("error",
|
|
+ G_OBJECT_CLASS_TYPE (object_class),
|
|
+ G_SIGNAL_RUN_LAST,
|
|
+ G_STRUCT_OFFSET (GdmSmartcardManagerClass, error),
|
|
+ NULL, NULL, g_cclosure_marshal_VOID__POINTER,
|
|
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
|
|
+ manager_class->error = NULL;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+sc_slot_id_equal (CK_SLOT_ID *slot_id_1,
|
|
+ CK_SLOT_ID *slot_id_2)
|
|
+{
|
|
+ g_assert (slot_id_1 != NULL);
|
|
+ g_assert (slot_id_2 != NULL);
|
|
+
|
|
+ return *slot_id_1 == *slot_id_2;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+sc_slot_id_hash (CK_SLOT_ID *slot_id)
|
|
+{
|
|
+ guint32 upper_bits, lower_bits;
|
|
+ gint temp;
|
|
+
|
|
+ if (sizeof (CK_SLOT_ID) == sizeof (gint)) {
|
|
+ return g_int_hash (slot_id);
|
|
+ }
|
|
+
|
|
+ upper_bits = ((*slot_id) >> 31) - 1;
|
|
+ lower_bits = (*slot_id) & 0xffffffff;
|
|
+
|
|
+ /* The upper bits are almost certainly always zero,
|
|
+ * so let's degenerate to g_int_hash for the
|
|
+ * (very) common case
|
|
+ */
|
|
+ temp = lower_bits + upper_bits;
|
|
+ return upper_bits + g_int_hash (&temp);
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_manager_init (GdmSmartcardManager *manager)
|
|
+{
|
|
+ g_debug ("initializing smartcard manager");
|
|
+
|
|
+ manager->priv = G_TYPE_INSTANCE_GET_PRIVATE (manager,
|
|
+ GDM_TYPE_SMARTCARD_MANAGER,
|
|
+ GdmSmartcardManagerPrivate);
|
|
+ manager->priv->poll_timeout_id = 0;
|
|
+ manager->priv->is_unstoppable = FALSE;
|
|
+ manager->priv->module = NULL;
|
|
+
|
|
+ manager->priv->smartcards =
|
|
+ g_hash_table_new_full (g_str_hash,
|
|
+ g_str_equal,
|
|
+ (GDestroyNotify) g_free,
|
|
+ (GDestroyNotify) g_object_unref);
|
|
+
|
|
+ if (!g_thread_supported()) {
|
|
+ g_thread_init (NULL);
|
|
+ }
|
|
+
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_manager_finalize (GObject *object)
|
|
+{
|
|
+ GdmSmartcardManager *manager;
|
|
+ GObjectClass *gobject_class;
|
|
+
|
|
+ manager = GDM_SMARTCARD_MANAGER (object);
|
|
+ gobject_class =
|
|
+ G_OBJECT_CLASS (gdm_smartcard_manager_parent_class);
|
|
+
|
|
+ gdm_smartcard_manager_stop_now (manager);
|
|
+
|
|
+ g_hash_table_destroy (manager->priv->smartcards);
|
|
+ manager->priv->smartcards = NULL;
|
|
+
|
|
+ gobject_class->finalize (object);
|
|
+}
|
|
+
|
|
+GQuark
|
|
+gdm_smartcard_manager_error_quark (void)
|
|
+{
|
|
+ static GQuark error_quark = 0;
|
|
+
|
|
+ if (error_quark == 0) {
|
|
+ error_quark = g_quark_from_static_string ("gdm-smartcard-manager-error-quark");
|
|
+ }
|
|
+
|
|
+ return error_quark;
|
|
+}
|
|
+
|
|
+GdmSmartcardManager *
|
|
+gdm_smartcard_manager_new (const char *module_path)
|
|
+{
|
|
+ GdmSmartcardManager *instance;
|
|
+
|
|
+ instance = GDM_SMARTCARD_MANAGER (g_object_new (GDM_TYPE_SMARTCARD_MANAGER,
|
|
+ "module-path", module_path,
|
|
+ NULL));
|
|
+
|
|
+ return instance;
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_manager_emit_error (GdmSmartcardManager *manager,
|
|
+ GError *error)
|
|
+{
|
|
+ manager->priv->is_unstoppable = TRUE;
|
|
+ g_signal_emit (manager, gdm_smartcard_manager_signals[ERROR], 0,
|
|
+ error);
|
|
+ manager->priv->is_unstoppable = FALSE;
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_manager_emit_smartcard_inserted (GdmSmartcardManager *manager,
|
|
+ GdmSmartcard *card)
|
|
+{
|
|
+ manager->priv->is_unstoppable = TRUE;
|
|
+ g_signal_emit (manager, gdm_smartcard_manager_signals[SMARTCARD_INSERTED], 0,
|
|
+ card);
|
|
+ manager->priv->is_unstoppable = FALSE;
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_manager_emit_smartcard_removed (GdmSmartcardManager *manager,
|
|
+ GdmSmartcard *card)
|
|
+{
|
|
+ GdmSmartcardManagerState old_state;
|
|
+
|
|
+ old_state = manager->priv->state;
|
|
+ manager->priv->is_unstoppable = TRUE;
|
|
+ g_signal_emit (manager, gdm_smartcard_manager_signals[SMARTCARD_REMOVED], 0,
|
|
+ card);
|
|
+ manager->priv->is_unstoppable = FALSE;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+gdm_smartcard_manager_check_for_and_process_events (GIOChannel *io_channel,
|
|
+ GIOCondition condition,
|
|
+ GdmSmartcardManager *manager)
|
|
+{
|
|
+ GdmSmartcard *card;
|
|
+ gboolean should_stop;
|
|
+ guchar event_type;
|
|
+ char *card_name;
|
|
+ gint fd;
|
|
+
|
|
+ card = NULL;
|
|
+ should_stop = (condition & G_IO_HUP) || (condition & G_IO_ERR);
|
|
+
|
|
+ if (should_stop) {
|
|
+ g_debug ("received %s on event socket, stopping "
|
|
+ "manager...",
|
|
+ (condition & G_IO_HUP) && (condition & G_IO_ERR)?
|
|
+ "error and hangup" :
|
|
+ (condition & G_IO_HUP)?
|
|
+ "hangup" : "error");
|
|
+ }
|
|
+
|
|
+ if (!(condition & G_IO_IN)) {
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ fd = g_io_channel_unix_get_fd (io_channel);
|
|
+
|
|
+ event_type = '\0';
|
|
+ if (!sc_read_bytes (fd, &event_type, 1)) {
|
|
+ should_stop = TRUE;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ card = sc_read_smartcard (fd, manager->priv->module);
|
|
+
|
|
+ if (card == NULL) {
|
|
+ should_stop = TRUE;
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ card_name = gdm_smartcard_get_name (card);
|
|
+
|
|
+ switch (event_type) {
|
|
+ case 'I':
|
|
+ g_hash_table_replace (manager->priv->smartcards,
|
|
+ card_name, card);
|
|
+ card_name = NULL;
|
|
+
|
|
+ gdm_smartcard_manager_emit_smartcard_inserted (manager, card);
|
|
+ card = NULL;
|
|
+ break;
|
|
+
|
|
+ case 'R':
|
|
+ gdm_smartcard_manager_emit_smartcard_removed (manager, card);
|
|
+ if (!g_hash_table_remove (manager->priv->smartcards, card_name)) {
|
|
+ g_debug ("got removal event of unknown card!");
|
|
+ }
|
|
+ g_free (card_name);
|
|
+ card_name = NULL;
|
|
+ card = NULL;
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ g_free (card_name);
|
|
+ card_name = NULL;
|
|
+ g_object_unref (card);
|
|
+
|
|
+ should_stop = TRUE;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+out:
|
|
+ if (should_stop) {
|
|
+ GError *error;
|
|
+
|
|
+ error = g_error_new (GDM_SMARTCARD_MANAGER_ERROR,
|
|
+ GDM_SMARTCARD_MANAGER_ERROR_WATCHING_FOR_EVENTS,
|
|
+ "%s", (condition & G_IO_IN) ? g_strerror (errno) : _("received error or hang up from event source"));
|
|
+
|
|
+ gdm_smartcard_manager_emit_error (manager, error);
|
|
+ g_error_free (error);
|
|
+ gdm_smartcard_manager_stop_now (manager);
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_manager_event_processing_stopped_handler (GdmSmartcardManager *manager)
|
|
+{
|
|
+ manager->priv->smartcard_event_source = NULL;
|
|
+ gdm_smartcard_manager_stop_now (manager);
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+gdm_open_pipe (gint *write_fd,
|
|
+ gint *read_fd)
|
|
+{
|
|
+ gint pipe_fds[2] = { -1, -1 };
|
|
+
|
|
+ g_assert (write_fd != NULL);
|
|
+ g_assert (read_fd != NULL);
|
|
+
|
|
+ if (pipe (pipe_fds) < 0) {
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ if (fcntl (pipe_fds[0], F_SETFD, FD_CLOEXEC) < 0) {
|
|
+ close (pipe_fds[0]);
|
|
+ close (pipe_fds[1]);
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ if (fcntl (pipe_fds[1], F_SETFD, FD_CLOEXEC) < 0) {
|
|
+ close (pipe_fds[0]);
|
|
+ close (pipe_fds[1]);
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ *read_fd = pipe_fds[0];
|
|
+ *write_fd = pipe_fds[1];
|
|
+
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_manager_stop_watching_for_events (GdmSmartcardManager *manager)
|
|
+{
|
|
+ if (manager->priv->smartcard_event_source != NULL) {
|
|
+ g_source_destroy (manager->priv->smartcard_event_source);
|
|
+ manager->priv->smartcard_event_source = NULL;
|
|
+ }
|
|
+
|
|
+ if (manager->priv->worker_thread != NULL) {
|
|
+ SECMOD_CancelWait (manager->priv->module);
|
|
+ /* FIXME: The function above doesn't seem to
|
|
+ * always wake up WaitForAnyTokenEvent
|
|
+ */
|
|
+ exit (0);
|
|
+ g_thread_join (manager->priv->worker_thread);
|
|
+ manager->priv->worker_thread = NULL;
|
|
+ }
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+sc_load_nss (GError **error)
|
|
+{
|
|
+ SECStatus status = SECSuccess;
|
|
+ static const guint32 flags =
|
|
+ NSS_INIT_READONLY | NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB |
|
|
+ NSS_INIT_FORCEOPEN | NSS_INIT_NOROOTINIT |
|
|
+ NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD;
|
|
+
|
|
+ g_debug ("attempting to load NSS database '%s'",
|
|
+ GDM_SMARTCARD_MANAGER_NSS_DB);
|
|
+
|
|
+ status = NSS_Initialize (GDM_SMARTCARD_MANAGER_NSS_DB,
|
|
+ "", "", SECMOD_DB, flags);
|
|
+
|
|
+ if (status != SECSuccess) {
|
|
+ gsize error_message_size;
|
|
+ char *error_message;
|
|
+
|
|
+ error_message_size = PR_GetErrorTextLength ();
|
|
+
|
|
+ if (error_message_size == 0) {
|
|
+ g_debug ("NSS security system could not be initialized");
|
|
+ g_set_error (error,
|
|
+ GDM_SMARTCARD_MANAGER_ERROR,
|
|
+ GDM_SMARTCARD_MANAGER_ERROR_WITH_NSS,
|
|
+ _("NSS security system could not be initialized"));
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ error_message = g_slice_alloc0 (error_message_size);
|
|
+ PR_GetErrorText (error_message);
|
|
+
|
|
+ g_set_error (error,
|
|
+ GDM_SMARTCARD_MANAGER_ERROR,
|
|
+ GDM_SMARTCARD_MANAGER_ERROR_WITH_NSS,
|
|
+ "%s", error_message);
|
|
+ g_debug ("NSS security system could not be initialized - %s",
|
|
+ error_message);
|
|
+
|
|
+ g_slice_free1 (error_message_size, error_message);
|
|
+
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ g_debug ("NSS database sucessfully loaded");
|
|
+ return TRUE;
|
|
+
|
|
+out:
|
|
+ g_debug ("NSS database couldn't be sucessfully loaded");
|
|
+ return FALSE;
|
|
+}
|
|
+
|
|
+static SECMODModule *
|
|
+load_driver (char *module_path,
|
|
+ GError **error)
|
|
+{
|
|
+ SECMODModule *module;
|
|
+ char *module_spec;
|
|
+ gboolean module_explicitly_specified;
|
|
+
|
|
+ g_debug ("attempting to load driver...");
|
|
+
|
|
+ module = NULL;
|
|
+ module_explicitly_specified = module_path != NULL;
|
|
+ if (module_explicitly_specified) {
|
|
+ module_spec = g_strdup_printf ("library=\"%s\"", module_path);
|
|
+ g_debug ("loading smartcard driver using spec '%s'",
|
|
+ module_spec);
|
|
+
|
|
+ module = SECMOD_LoadUserModule (module_spec,
|
|
+ NULL /* parent */,
|
|
+ FALSE /* recurse */);
|
|
+ g_free (module_spec);
|
|
+ module_spec = NULL;
|
|
+
|
|
+ } else {
|
|
+ SECMODModuleList *modules, *tmp;
|
|
+
|
|
+ modules = SECMOD_GetDefaultModuleList ();
|
|
+
|
|
+ for (tmp = modules; tmp != NULL; tmp = tmp->next) {
|
|
+ if (!SECMOD_HasRemovableSlots (tmp->module) ||
|
|
+ !tmp->module->loaded)
|
|
+ continue;
|
|
+
|
|
+ module = SECMOD_ReferenceModule (tmp->module);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ /* fallback to compiled in driver path
|
|
+ */
|
|
+ if (module == NULL) {
|
|
+ module_path = GDM_SMARTCARD_MANAGER_DRIVER;
|
|
+ module_spec = g_strdup_printf ("library=\"%s\"", module_path);
|
|
+ g_debug ("loading smartcard driver using spec '%s'",
|
|
+ module_spec);
|
|
+
|
|
+ module = SECMOD_LoadUserModule (module_spec,
|
|
+ NULL /* parent */,
|
|
+ FALSE /* recurse */);
|
|
+ g_free (module_spec);
|
|
+ module_spec = NULL;
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ if (!module_explicitly_specified && module == NULL) {
|
|
+ g_set_error (error,
|
|
+ GDM_SMARTCARD_MANAGER_ERROR,
|
|
+ GDM_SMARTCARD_MANAGER_ERROR_LOADING_DRIVER,
|
|
+ _("no suitable smartcard driver could be found"));
|
|
+ } else if (module == NULL || !module->loaded) {
|
|
+
|
|
+ gsize error_message_size;
|
|
+ char *error_message;
|
|
+
|
|
+ if (module != NULL && !module->loaded) {
|
|
+ g_debug ("module found but not loaded?!");
|
|
+ SECMOD_DestroyModule (module);
|
|
+ module = NULL;
|
|
+ }
|
|
+
|
|
+ error_message_size = PR_GetErrorTextLength ();
|
|
+
|
|
+ if (error_message_size == 0) {
|
|
+ g_debug ("smartcard driver '%s' could not be loaded",
|
|
+ module_path);
|
|
+ g_set_error (error,
|
|
+ GDM_SMARTCARD_MANAGER_ERROR,
|
|
+ GDM_SMARTCARD_MANAGER_ERROR_LOADING_DRIVER,
|
|
+ _("smartcard driver '%s' could not be "
|
|
+ "loaded"), module_path);
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ error_message = g_slice_alloc0 (error_message_size);
|
|
+ PR_GetErrorText (error_message);
|
|
+
|
|
+ g_set_error (error,
|
|
+ GDM_SMARTCARD_MANAGER_ERROR,
|
|
+ GDM_SMARTCARD_MANAGER_ERROR_LOADING_DRIVER,
|
|
+ "%s", error_message);
|
|
+
|
|
+ g_debug ("smartcard driver '%s' could not be loaded - %s",
|
|
+ module_path, error_message);
|
|
+ g_slice_free1 (error_message_size, error_message);
|
|
+ }
|
|
+
|
|
+out:
|
|
+ return module;
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_manager_get_all_cards (GdmSmartcardManager *manager)
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ for (i = 0; i < manager->priv->module->slotCount; i++) {
|
|
+ GdmSmartcard *card;
|
|
+ CK_SLOT_ID slot_id;
|
|
+ gint slot_series;
|
|
+ char *card_name;
|
|
+
|
|
+ slot_id = PK11_GetSlotID (manager->priv->module->slots[i]);
|
|
+ slot_series = PK11_GetSlotSeries (manager->priv->module->slots[i]);
|
|
+
|
|
+ card = _gdm_smartcard_new (manager->priv->module,
|
|
+ slot_id, slot_series);
|
|
+
|
|
+ card_name = gdm_smartcard_get_name (card);
|
|
+
|
|
+ g_hash_table_replace (manager->priv->smartcards,
|
|
+ card_name, card);
|
|
+ }
|
|
+}
|
|
+
|
|
+gboolean
|
|
+gdm_smartcard_manager_start (GdmSmartcardManager *manager,
|
|
+ GError **error)
|
|
+{
|
|
+ GError *watching_error;
|
|
+ gint worker_fd;
|
|
+ GPid worker_pid;
|
|
+ GIOChannel *io_channel;
|
|
+ GSource *source;
|
|
+ GIOFlags channel_flags;
|
|
+ GError *nss_error;
|
|
+
|
|
+ if (manager->priv->state == GDM_SMARTCARD_MANAGER_STATE_STARTED) {
|
|
+ g_debug ("smartcard manager already started");
|
|
+ return TRUE;
|
|
+ }
|
|
+
|
|
+ manager->priv->state = GDM_SMARTCARD_MANAGER_STATE_STARTING;
|
|
+
|
|
+ worker_fd = -1;
|
|
+ worker_pid = 0;
|
|
+
|
|
+ nss_error = NULL;
|
|
+ if (!manager->priv->nss_is_loaded && !sc_load_nss (&nss_error)) {
|
|
+ g_propagate_error (error, nss_error);
|
|
+ goto out;
|
|
+ }
|
|
+ manager->priv->nss_is_loaded = TRUE;
|
|
+
|
|
+ if (manager->priv->module == NULL) {
|
|
+ manager->priv->module = load_driver (manager->priv->module_path, &nss_error);
|
|
+ }
|
|
+
|
|
+ if (manager->priv->module == NULL) {
|
|
+ g_propagate_error (error, nss_error);
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ if (!gdm_smartcard_manager_create_worker (manager, &worker_fd, &manager->priv->worker_thread)) {
|
|
+
|
|
+ g_set_error (error,
|
|
+ GDM_SMARTCARD_MANAGER_ERROR,
|
|
+ GDM_SMARTCARD_MANAGER_ERROR_WATCHING_FOR_EVENTS,
|
|
+ _("could not watch for incoming card events - %s"),
|
|
+ g_strerror (errno));
|
|
+
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ io_channel = g_io_channel_unix_new (worker_fd);
|
|
+
|
|
+ channel_flags = g_io_channel_get_flags (io_channel);
|
|
+ watching_error = NULL;
|
|
+
|
|
+ source = g_io_create_watch (io_channel, G_IO_IN | G_IO_HUP);
|
|
+ g_io_channel_unref (io_channel);
|
|
+ io_channel = NULL;
|
|
+
|
|
+ manager->priv->smartcard_event_source = source;
|
|
+
|
|
+ g_source_set_callback (manager->priv->smartcard_event_source,
|
|
+ (GSourceFunc) (GIOFunc)
|
|
+ gdm_smartcard_manager_check_for_and_process_events,
|
|
+ manager,
|
|
+ (GDestroyNotify)
|
|
+ gdm_smartcard_manager_event_processing_stopped_handler);
|
|
+ g_source_attach (manager->priv->smartcard_event_source, NULL);
|
|
+ g_source_unref (manager->priv->smartcard_event_source);
|
|
+
|
|
+ /* populate the hash with cards that are already inserted
|
|
+ */
|
|
+ gdm_smartcard_manager_get_all_cards (manager);
|
|
+
|
|
+ manager->priv->state = GDM_SMARTCARD_MANAGER_STATE_STARTED;
|
|
+
|
|
+out:
|
|
+ /* don't leave it in a half started state
|
|
+ */
|
|
+ if (manager->priv->state != GDM_SMARTCARD_MANAGER_STATE_STARTED) {
|
|
+ g_debug ("smartcard manager could not be completely started");
|
|
+ gdm_smartcard_manager_stop (manager);
|
|
+ } else {
|
|
+ g_debug ("smartcard manager started");
|
|
+ }
|
|
+
|
|
+ return manager->priv->state == GDM_SMARTCARD_MANAGER_STATE_STARTED;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+gdm_smartcard_manager_stop_now (GdmSmartcardManager *manager)
|
|
+{
|
|
+ if (manager->priv->state == GDM_SMARTCARD_MANAGER_STATE_STOPPED) {
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ manager->priv->state = GDM_SMARTCARD_MANAGER_STATE_STOPPED;
|
|
+ gdm_smartcard_manager_stop_watching_for_events (manager);
|
|
+
|
|
+ if (manager->priv->module != NULL) {
|
|
+ SECMOD_DestroyModule (manager->priv->module);
|
|
+ manager->priv->module = NULL;
|
|
+ }
|
|
+
|
|
+ if (manager->priv->nss_is_loaded) {
|
|
+ NSS_Shutdown ();
|
|
+ manager->priv->nss_is_loaded = FALSE;
|
|
+ }
|
|
+
|
|
+ g_debug ("smartcard manager stopped");
|
|
+
|
|
+ return FALSE;
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_manager_queue_stop (GdmSmartcardManager *manager)
|
|
+{
|
|
+
|
|
+ manager->priv->state = GDM_SMARTCARD_MANAGER_STATE_STOPPING;
|
|
+
|
|
+ g_idle_add ((GSourceFunc) gdm_smartcard_manager_stop_now, manager);
|
|
+}
|
|
+
|
|
+void
|
|
+gdm_smartcard_manager_stop (GdmSmartcardManager *manager)
|
|
+{
|
|
+ if (manager->priv->state == GDM_SMARTCARD_MANAGER_STATE_STOPPED) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (manager->priv->is_unstoppable) {
|
|
+ gdm_smartcard_manager_queue_stop (manager);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ gdm_smartcard_manager_stop_now (manager);
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_manager_check_for_login_card (CK_SLOT_ID slot_id,
|
|
+ GdmSmartcard *card,
|
|
+ gboolean *is_inserted)
|
|
+{
|
|
+ g_assert (is_inserted != NULL);
|
|
+
|
|
+ if (gdm_smartcard_is_login_card (card)) {
|
|
+ *is_inserted = TRUE;
|
|
+ }
|
|
+
|
|
+}
|
|
+
|
|
+gboolean
|
|
+gdm_smartcard_manager_login_card_is_inserted (GdmSmartcardManager *manager)
|
|
+
|
|
+{
|
|
+ gboolean is_inserted;
|
|
+
|
|
+ is_inserted = FALSE;
|
|
+ g_hash_table_foreach (manager->priv->smartcards,
|
|
+ (GHFunc)
|
|
+ gdm_smartcard_manager_check_for_login_card,
|
|
+ &is_inserted);
|
|
+ return is_inserted;
|
|
+}
|
|
+
|
|
+static GdmSmartcardManagerWorker *
|
|
+gdm_smartcard_manager_worker_new (gint write_fd)
|
|
+{
|
|
+ GdmSmartcardManagerWorker *worker;
|
|
+
|
|
+ worker = g_slice_new0 (GdmSmartcardManagerWorker);
|
|
+ worker->write_fd = write_fd;
|
|
+ worker->module = NULL;
|
|
+
|
|
+ worker->smartcards =
|
|
+ g_hash_table_new_full ((GHashFunc) sc_slot_id_hash,
|
|
+ (GEqualFunc) sc_slot_id_equal,
|
|
+ (GDestroyNotify) g_free,
|
|
+ (GDestroyNotify) g_object_unref);
|
|
+
|
|
+ return worker;
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_manager_worker_free (GdmSmartcardManagerWorker *worker)
|
|
+{
|
|
+ if (worker->smartcards != NULL) {
|
|
+ g_hash_table_destroy (worker->smartcards);
|
|
+ worker->smartcards = NULL;
|
|
+ }
|
|
+
|
|
+ g_slice_free (GdmSmartcardManagerWorker, worker);
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+sc_read_bytes (gint fd, gpointer bytes, gsize num_bytes)
|
|
+{
|
|
+ size_t bytes_left;
|
|
+ size_t total_bytes_read;
|
|
+ ssize_t bytes_read;
|
|
+
|
|
+ bytes_left = (size_t) num_bytes;
|
|
+ total_bytes_read = 0;
|
|
+
|
|
+ do {
|
|
+ bytes_read = read (fd, bytes + total_bytes_read, bytes_left);
|
|
+ g_assert (bytes_read <= (ssize_t) bytes_left);
|
|
+
|
|
+ if (bytes_read <= 0) {
|
|
+ if ((bytes_read < 0) && (errno == EINTR || errno == EAGAIN)) {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ bytes_left = 0;
|
|
+ } else {
|
|
+ bytes_left -= bytes_read;
|
|
+ total_bytes_read += bytes_read;
|
|
+ }
|
|
+ } while (bytes_left > 0);
|
|
+
|
|
+ if (total_bytes_read < (size_t) num_bytes) {
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+sc_write_bytes (gint fd, gconstpointer bytes, gsize num_bytes)
|
|
+{
|
|
+ size_t bytes_left;
|
|
+ size_t total_bytes_written;
|
|
+ ssize_t bytes_written;
|
|
+
|
|
+ bytes_left = (size_t) num_bytes;
|
|
+ total_bytes_written = 0;
|
|
+
|
|
+ do {
|
|
+ bytes_written = write (fd, bytes + total_bytes_written, bytes_left);
|
|
+ g_assert (bytes_written <= (ssize_t) bytes_left);
|
|
+
|
|
+ if (bytes_written <= 0) {
|
|
+ if ((bytes_written < 0) && (errno == EINTR || errno == EAGAIN)) {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ bytes_left = 0;
|
|
+ } else {
|
|
+ bytes_left -= bytes_written;
|
|
+ total_bytes_written += bytes_written;
|
|
+ }
|
|
+ } while (bytes_left > 0);
|
|
+
|
|
+ if (total_bytes_written < (size_t) num_bytes) {
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+static GdmSmartcard *
|
|
+sc_read_smartcard (gint fd,
|
|
+ SECMODModule *module)
|
|
+{
|
|
+ GdmSmartcard *card;
|
|
+ char *card_name;
|
|
+ gsize card_name_size;
|
|
+
|
|
+ card_name_size = 0;
|
|
+ if (!sc_read_bytes (fd, &card_name_size, sizeof (card_name_size))) {
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ card_name = g_slice_alloc0 (card_name_size);
|
|
+ if (!sc_read_bytes (fd, card_name, card_name_size)) {
|
|
+ g_slice_free1 (card_name_size, card_name);
|
|
+ return NULL;
|
|
+ }
|
|
+ card = _gdm_smartcard_new_from_name (module, card_name);
|
|
+ g_slice_free1 (card_name_size, card_name);
|
|
+
|
|
+ return card;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+sc_write_smartcard (gint fd,
|
|
+ GdmSmartcard *card)
|
|
+{
|
|
+ gsize card_name_size;
|
|
+ char *card_name;
|
|
+
|
|
+ card_name = gdm_smartcard_get_name (card);
|
|
+ card_name_size = strlen (card_name) + 1;
|
|
+
|
|
+ if (!sc_write_bytes (fd, &card_name_size, sizeof (card_name_size))) {
|
|
+ g_free (card_name);
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ if (!sc_write_bytes (fd, card_name, card_name_size)) {
|
|
+ g_free (card_name);
|
|
+ return FALSE;
|
|
+ }
|
|
+ g_free (card_name);
|
|
+
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+gdm_smartcard_manager_worker_emit_smartcard_removed (GdmSmartcardManagerWorker *worker,
|
|
+ GdmSmartcard *card,
|
|
+ GError **error)
|
|
+{
|
|
+ g_debug ("card '%s' removed!", gdm_smartcard_get_name (card));
|
|
+
|
|
+ if (!sc_write_bytes (worker->write_fd, "R", 1)) {
|
|
+ goto error_out;
|
|
+ }
|
|
+
|
|
+ if (!sc_write_smartcard (worker->write_fd, card)) {
|
|
+ goto error_out;
|
|
+ }
|
|
+
|
|
+ return TRUE;
|
|
+
|
|
+error_out:
|
|
+ g_set_error (error, GDM_SMARTCARD_MANAGER_ERROR,
|
|
+ GDM_SMARTCARD_MANAGER_ERROR_REPORTING_EVENTS,
|
|
+ "%s", g_strerror (errno));
|
|
+ return FALSE;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+gdm_smartcard_manager_worker_emit_smartcard_inserted (GdmSmartcardManagerWorker *worker,
|
|
+ GdmSmartcard *card,
|
|
+ GError **error)
|
|
+{
|
|
+ GError *write_error;
|
|
+
|
|
+ write_error = NULL;
|
|
+ g_debug ("card '%s' inserted!", gdm_smartcard_get_name (card));
|
|
+ if (!sc_write_bytes (worker->write_fd, "I", 1)) {
|
|
+ goto error_out;
|
|
+ }
|
|
+
|
|
+ if (!sc_write_smartcard (worker->write_fd, card)) {
|
|
+ goto error_out;
|
|
+ }
|
|
+
|
|
+ return TRUE;
|
|
+
|
|
+error_out:
|
|
+ g_set_error (error, GDM_SMARTCARD_MANAGER_ERROR,
|
|
+ GDM_SMARTCARD_MANAGER_ERROR_REPORTING_EVENTS,
|
|
+ "%s", g_strerror (errno));
|
|
+ return FALSE;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+gdm_smartcard_manager_worker_watch_for_and_process_event (GdmSmartcardManagerWorker *worker,
|
|
+ GError **error)
|
|
+{
|
|
+ PK11SlotInfo *slot;
|
|
+ CK_SLOT_ID slot_id, *key;
|
|
+ gint slot_series, card_slot_series;
|
|
+ GdmSmartcard *card;
|
|
+ GError *processing_error;
|
|
+
|
|
+ g_debug ("waiting for card event");
|
|
+
|
|
+ /* FIXME: we return FALSE quite a bit in this function without cleaning up
|
|
+ * resources. By returning FALSE we're going to ultimately exit anyway, but
|
|
+ * we should still be tidier about things.
|
|
+ */
|
|
+
|
|
+ slot = SECMOD_WaitForAnyTokenEvent (worker->module, 0, PR_SecondsToInterval (1));
|
|
+ processing_error = NULL;
|
|
+
|
|
+ if (slot == NULL) {
|
|
+ int error_code;
|
|
+
|
|
+ error_code = PORT_GetError ();
|
|
+ if ((error_code == 0) || (error_code == SEC_ERROR_NO_EVENT)) {
|
|
+ g_debug ("spurrious event occurred");
|
|
+ return TRUE;
|
|
+ }
|
|
+
|
|
+ /* FIXME: is there a function to convert from a PORT error
|
|
+ * code to a translated string?
|
|
+ */
|
|
+ g_set_error (error, GDM_SMARTCARD_MANAGER_ERROR,
|
|
+ GDM_SMARTCARD_MANAGER_ERROR_WITH_NSS,
|
|
+ _("encountered unexpected error while "
|
|
+ "waiting for smartcard events"));
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ /* the slot id and series together uniquely identify a card.
|
|
+ * You can never have two cards with the same slot id at the
|
|
+ * same time, however (I think), so we can key off of it.
|
|
+ */
|
|
+ slot_id = PK11_GetSlotID (slot);
|
|
+ slot_series = PK11_GetSlotSeries (slot);
|
|
+
|
|
+ /* First check to see if there is a card that we're currently
|
|
+ * tracking in the slot.
|
|
+ */
|
|
+ key = g_new (CK_SLOT_ID, 1);
|
|
+ *key = slot_id;
|
|
+ card = g_hash_table_lookup (worker->smartcards, key);
|
|
+
|
|
+ if (card != NULL) {
|
|
+ card_slot_series = gdm_smartcard_get_slot_series (card);
|
|
+ } else {
|
|
+ card_slot_series = -1;
|
|
+ }
|
|
+
|
|
+ if (PK11_IsPresent (slot)) {
|
|
+ /* Now, check to see if their is a new card in the slot.
|
|
+ * If there was a different card in the slot now than
|
|
+ * there was before, then we need to emit a removed signal
|
|
+ * for the old card (we don't want unpaired insertion events).
|
|
+ */
|
|
+ if ((card != NULL) &&
|
|
+ card_slot_series != slot_series) {
|
|
+ if (!gdm_smartcard_manager_worker_emit_smartcard_removed (worker, card, &processing_error)) {
|
|
+ g_propagate_error (error, processing_error);
|
|
+ return FALSE;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ card = _gdm_smartcard_new (worker->module,
|
|
+ slot_id, slot_series);
|
|
+
|
|
+ g_hash_table_replace (worker->smartcards,
|
|
+ key, card);
|
|
+ key = NULL;
|
|
+
|
|
+ if (!gdm_smartcard_manager_worker_emit_smartcard_inserted (worker, card, &processing_error)) {
|
|
+ g_propagate_error (error, processing_error);
|
|
+ return FALSE;
|
|
+ }
|
|
+ } else {
|
|
+ /* if we aren't tracking the card, just discard the event.
|
|
+ * We don't want unpaired remove events. Note on startup
|
|
+ * NSS will generate an "insertion" event if a card is
|
|
+ * already inserted in the slot.
|
|
+ */
|
|
+ if ((card != NULL)) {
|
|
+ /* FIXME: i'm not sure about this code. Maybe we
|
|
+ * shouldn't do this at all, or maybe we should do it
|
|
+ * n times (where n = slot_series - card_slot_series + 1)
|
|
+ *
|
|
+ * Right now, i'm just doing it once.
|
|
+ */
|
|
+ if ((slot_series - card_slot_series) > 1) {
|
|
+
|
|
+ if (!gdm_smartcard_manager_worker_emit_smartcard_removed (worker, card, &processing_error)) {
|
|
+ g_propagate_error (error, processing_error);
|
|
+ return FALSE;
|
|
+ }
|
|
+ g_hash_table_remove (worker->smartcards, key);
|
|
+
|
|
+ card = _gdm_smartcard_new (worker->module,
|
|
+ slot_id, slot_series);
|
|
+ g_hash_table_replace (worker->smartcards,
|
|
+ key, card);
|
|
+ key = NULL;
|
|
+ if (!gdm_smartcard_manager_worker_emit_smartcard_inserted (worker, card, &processing_error)) {
|
|
+ g_propagate_error (error, processing_error);
|
|
+ return FALSE;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (!gdm_smartcard_manager_worker_emit_smartcard_removed (worker, card, &processing_error)) {
|
|
+ g_propagate_error (error, processing_error);
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ g_hash_table_remove (worker->smartcards, key);
|
|
+ card = NULL;
|
|
+ } else {
|
|
+ g_debug ("got spurious remove event");
|
|
+ }
|
|
+ }
|
|
+
|
|
+ g_free (key);
|
|
+ PK11_FreeSlot (slot);
|
|
+
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_manager_worker_run (GdmSmartcardManagerWorker *worker)
|
|
+{
|
|
+ GError *error;
|
|
+
|
|
+
|
|
+ error = NULL;
|
|
+
|
|
+ while (gdm_smartcard_manager_worker_watch_for_and_process_event (worker, &error));
|
|
+
|
|
+ if (error != NULL) {
|
|
+ g_debug ("could not process card event - %s", error->message);
|
|
+ g_error_free (error);
|
|
+ }
|
|
+
|
|
+ gdm_smartcard_manager_worker_free (worker);
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+gdm_smartcard_manager_create_worker (GdmSmartcardManager *manager,
|
|
+ gint *worker_fd,
|
|
+ GThread **worker_thread)
|
|
+{
|
|
+ GdmSmartcardManagerWorker *worker;
|
|
+ gint write_fd, read_fd;
|
|
+
|
|
+ write_fd = -1;
|
|
+ read_fd = -1;
|
|
+ if (!gdm_open_pipe (&write_fd, &read_fd)) {
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ worker = gdm_smartcard_manager_worker_new (write_fd);
|
|
+ worker->module = manager->priv->module;
|
|
+
|
|
+ *worker_thread = g_thread_create ((GThreadFunc)
|
|
+ gdm_smartcard_manager_worker_run,
|
|
+ worker, TRUE, NULL);
|
|
+
|
|
+ if (*worker_thread == NULL) {
|
|
+ gdm_smartcard_manager_worker_free (worker);
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ if (worker_fd) {
|
|
+ *worker_fd = read_fd;
|
|
+ }
|
|
+
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+#ifdef GDM_SMARTCARD_MANAGER_ENABLE_TEST
|
|
+#include <glib.h>
|
|
+
|
|
+static GMainLoop *event_loop;
|
|
+static gboolean should_exit_on_next_remove = FALSE;
|
|
+
|
|
+static gboolean
|
|
+on_timeout (GdmSmartcardManager *manager)
|
|
+{
|
|
+ GError *error;
|
|
+ g_print ("Re-enabling manager.\n");
|
|
+
|
|
+ if (!gdm_smartcard_manager_start (manager, &error)) {
|
|
+ g_warning ("could not start smartcard manager - %s",
|
|
+ error->message);
|
|
+ g_error_free (error);
|
|
+ return 1;
|
|
+ }
|
|
+ g_print ("Please re-insert smartcard\n");
|
|
+
|
|
+ should_exit_on_next_remove = TRUE;
|
|
+
|
|
+ return FALSE;
|
|
+}
|
|
+
|
|
+static void
|
|
+on_device_inserted (GdmSmartcardManager *manager,
|
|
+ GdmSmartcard *card)
|
|
+{
|
|
+ g_print ("smartcard inserted!\n");
|
|
+ g_print ("Please remove it.\n");
|
|
+}
|
|
+
|
|
+static void
|
|
+on_device_removed (GdmSmartcardManager *manager,
|
|
+ GdmSmartcard *card)
|
|
+{
|
|
+ g_print ("smartcard removed!\n");
|
|
+
|
|
+ if (should_exit_on_next_remove) {
|
|
+ g_main_loop_quit (event_loop);
|
|
+ } else {
|
|
+ g_print ("disabling manager for 2 seconds\n");
|
|
+ gdm_smartcard_manager_stop (manager);
|
|
+ g_timeout_add (2000, (GSourceFunc) on_timeout, manager);
|
|
+ }
|
|
+}
|
|
+
|
|
+int
|
|
+main (int argc,
|
|
+ char *argv[])
|
|
+{
|
|
+ GdmSmartcardManager *manager;
|
|
+ GError *error;
|
|
+
|
|
+ g_log_set_always_fatal (G_LOG_LEVEL_ERROR
|
|
+ | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING);
|
|
+
|
|
+ g_type_init ();
|
|
+
|
|
+ g_message ("creating instance of 'smartcard manager' object...");
|
|
+ manager = gdm_smartcard_manager_new (NULL);
|
|
+ g_message ("'smartcard manager' object created successfully");
|
|
+
|
|
+ g_signal_connect (manager, "smartcard-inserted",
|
|
+ G_CALLBACK (on_device_inserted), NULL);
|
|
+
|
|
+ g_signal_connect (manager, "smartcard-removed",
|
|
+ G_CALLBACK (on_device_removed), NULL);
|
|
+
|
|
+ g_message ("starting listener...");
|
|
+
|
|
+ error = NULL;
|
|
+ if (!gdm_smartcard_manager_start (manager, &error)) {
|
|
+ g_warning ("could not start smartcard manager - %s",
|
|
+ error->message);
|
|
+ g_error_free (error);
|
|
+ return 1;
|
|
+ }
|
|
+
|
|
+ event_loop = g_main_loop_new (NULL, FALSE);
|
|
+ g_main_loop_run (event_loop);
|
|
+ g_main_loop_unref (event_loop);
|
|
+ event_loop = NULL;
|
|
+
|
|
+ g_message ("destroying previously created 'smartcard manager' object...");
|
|
+ g_object_unref (manager);
|
|
+ manager = NULL;
|
|
+ g_message ("'smartcard manager' object destroyed successfully");
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+#endif
|
|
diff --git a/gui/simple-greeter/plugins/smartcard/gdm-smartcard-manager.h b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-manager.h
|
|
new file mode 100644
|
|
index 0000000..932a703
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-manager.h
|
|
@@ -0,0 +1,86 @@
|
|
+/* gdm-smartcard-manager.h - object for monitoring smartcard insertion and
|
|
+ * removal events
|
|
+ *
|
|
+ * Copyright (C) 2006, 2009 Red Hat, Inc.
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2, or (at your option)
|
|
+ * any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
+ * 02111-1307, USA.
|
|
+ *
|
|
+ * Written by: Ray Strode
|
|
+ */
|
|
+#ifndef GDM_SMARTCARD_MANAGER_H
|
|
+#define GDM_SMARTCARD_MANAGER_H
|
|
+
|
|
+#define GDM_SMARTCARD_ENABLE_INTERNAL_API
|
|
+#include "gdm-smartcard.h"
|
|
+
|
|
+#include <glib.h>
|
|
+#include <glib-object.h>
|
|
+
|
|
+G_BEGIN_DECLS
|
|
+#define GDM_TYPE_SMARTCARD_MANAGER (gdm_smartcard_manager_get_type ())
|
|
+#define GDM_SMARTCARD_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDM_TYPE_SMARTCARD_MANAGER, GdmSmartcardManager))
|
|
+#define GDM_SMARTCARD_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDM_TYPE_SMARTCARD_MANAGER, GdmSmartcardManagerClass))
|
|
+#define GDM_IS_SMARTCARD_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SC_TYPE_SMARTCARD_MANAGER))
|
|
+#define GDM_IS_SMARTCARD_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SC_TYPE_SMARTCARD_MANAGER))
|
|
+#define GDM_SMARTCARD_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GDM_TYPE_SMARTCARD_MANAGER, GdmSmartcardManagerClass))
|
|
+#define GDM_SMARTCARD_MANAGER_ERROR (gdm_smartcard_manager_error_quark ())
|
|
+typedef struct _GdmSmartcardManager GdmSmartcardManager;
|
|
+typedef struct _GdmSmartcardManagerClass GdmSmartcardManagerClass;
|
|
+typedef struct _GdmSmartcardManagerPrivate GdmSmartcardManagerPrivate;
|
|
+typedef enum _GdmSmartcardManagerError GdmSmartcardManagerError;
|
|
+
|
|
+struct _GdmSmartcardManager {
|
|
+ GObject parent;
|
|
+
|
|
+ /*< private > */
|
|
+ GdmSmartcardManagerPrivate *priv;
|
|
+};
|
|
+
|
|
+struct _GdmSmartcardManagerClass {
|
|
+ GObjectClass parent_class;
|
|
+
|
|
+ /* Signals */
|
|
+ void (*smartcard_inserted) (GdmSmartcardManager *manager,
|
|
+ GdmSmartcard *token);
|
|
+ void (*smartcard_removed) (GdmSmartcardManager *manager,
|
|
+ GdmSmartcard *token);
|
|
+ void (*error) (GdmSmartcardManager *manager,
|
|
+ GError *error);
|
|
+};
|
|
+
|
|
+enum _GdmSmartcardManagerError {
|
|
+ GDM_SMARTCARD_MANAGER_ERROR_GENERIC = 0,
|
|
+ GDM_SMARTCARD_MANAGER_ERROR_WITH_NSS,
|
|
+ GDM_SMARTCARD_MANAGER_ERROR_LOADING_DRIVER,
|
|
+ GDM_SMARTCARD_MANAGER_ERROR_WATCHING_FOR_EVENTS,
|
|
+ GDM_SMARTCARD_MANAGER_ERROR_REPORTING_EVENTS
|
|
+};
|
|
+
|
|
+GType gdm_smartcard_manager_get_type (void) G_GNUC_CONST;
|
|
+GQuark gdm_smartcard_manager_error_quark (void) G_GNUC_CONST;
|
|
+
|
|
+GdmSmartcardManager *gdm_smartcard_manager_new (const char *module);
|
|
+
|
|
+gboolean gdm_smartcard_manager_start (GdmSmartcardManager *manager,
|
|
+ GError **error);
|
|
+
|
|
+void gdm_smartcard_manager_stop (GdmSmartcardManager *manager);
|
|
+
|
|
+char *gdm_smartcard_manager_get_module_path (GdmSmartcardManager *manager);
|
|
+gboolean gdm_smartcard_manager_login_token_is_inserted (GdmSmartcardManager *manager);
|
|
+
|
|
+G_END_DECLS
|
|
+#endif /* GDM_SMARTCARD_MANAGER_H */
|
|
diff --git a/gui/simple-greeter/plugins/smartcard/gdm-smartcard-worker.c b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-worker.c
|
|
new file mode 100644
|
|
index 0000000..7fe4cf4
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-worker.c
|
|
@@ -0,0 +1,167 @@
|
|
+#include "config.h"
|
|
+
|
|
+#include <fcntl.h>
|
|
+#include <locale.h>
|
|
+#include <stdlib.h>
|
|
+#include <unistd.h>
|
|
+
|
|
+#include <glib.h>
|
|
+
|
|
+#include "gdm-smartcard-manager.h"
|
|
+#include "gdm-smartcard.h"
|
|
+
|
|
+#ifndef GDM_SMARTCARDS_CONF
|
|
+#define GDM_SMARTCARDS_CONF GDMCONFDIR "/smartcards.conf"
|
|
+#endif
|
|
+
|
|
+#ifndef GDM_SMARTCARDS_GROUP
|
|
+#define GDM_SMARTCARDS_GROUP "Smartcards"
|
|
+#endif
|
|
+
|
|
+#ifndef GDM_SMARTCARDS_KEY_ENABLED
|
|
+#define GDM_SMARTCARDS_KEY_ENABLED "Enabled"
|
|
+#endif
|
|
+
|
|
+#ifndef GDM_SMARTCARDS_KEY_DRIVER
|
|
+#define GDM_SMARTCARDS_KEY_DRIVER "Driver"
|
|
+#endif
|
|
+
|
|
+static GMainLoop *event_loop;
|
|
+static GdmSmartcardManager *manager;
|
|
+static int signal_pipe_fds[2] = { -1, -1 };
|
|
+
|
|
+static void
|
|
+on_smartcard_event (const char *event_string)
|
|
+{
|
|
+ g_debug ("smartcard event '%s' happened", event_string);
|
|
+ g_print ("%s", event_string);
|
|
+ fflush (stdout);
|
|
+}
|
|
+
|
|
+static void
|
|
+watch_for_smartcards (void)
|
|
+{
|
|
+ GError *error;
|
|
+ char *driver;
|
|
+ GKeyFile *cfg;
|
|
+
|
|
+ cfg = g_key_file_new ();
|
|
+
|
|
+ error = NULL;
|
|
+ driver = NULL;
|
|
+ if (g_key_file_load_from_file (cfg, GDM_SMARTCARDS_CONF, G_KEY_FILE_NONE, &error)) {
|
|
+ if (!g_key_file_get_boolean (cfg, GDM_SMARTCARDS_GROUP, GDM_SMARTCARDS_KEY_ENABLED, &error)) {
|
|
+ g_debug ("smartcard support is not enabled");
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ driver = g_key_file_get_string (cfg, GDM_SMARTCARDS_GROUP, GDM_SMARTCARDS_KEY_DRIVER, NULL);
|
|
+ g_debug ("smartcards driver is set to '%s'",
|
|
+ driver == NULL || driver[0] == '\0'? "<automatic>" : driver);
|
|
+ }
|
|
+
|
|
+ g_debug ("watching for smartcard insertion and removal events");
|
|
+ manager = gdm_smartcard_manager_new (driver);
|
|
+ g_free (driver);
|
|
+
|
|
+ g_signal_connect_swapped (manager,
|
|
+ "smartcard-inserted",
|
|
+ G_CALLBACK (on_smartcard_event),
|
|
+ "I");
|
|
+
|
|
+ g_signal_connect_swapped (manager,
|
|
+ "smartcard-removed",
|
|
+ G_CALLBACK (on_smartcard_event),
|
|
+ "R");
|
|
+
|
|
+ error = NULL;
|
|
+ if (!gdm_smartcard_manager_start (manager, &error)) {
|
|
+ g_object_unref (manager);
|
|
+ manager = NULL;
|
|
+
|
|
+ if (error != NULL) {
|
|
+ g_debug ("%s", error->message);
|
|
+ g_error_free (error);
|
|
+ } else {
|
|
+ g_debug ("could not start smartcard manager");
|
|
+
|
|
+ }
|
|
+ goto out;
|
|
+ }
|
|
+out:
|
|
+ g_key_file_free (cfg);
|
|
+}
|
|
+
|
|
+static void
|
|
+stop_watching_for_smartcards (void)
|
|
+{
|
|
+ if (manager != NULL) {
|
|
+ gdm_smartcard_manager_stop (manager);
|
|
+ g_object_unref (manager);
|
|
+ manager = NULL;
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
+on_term_signal (int signal_number)
|
|
+{
|
|
+ close (signal_pipe_fds[1]);
|
|
+ signal_pipe_fds[1] = -1;
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+after_term_signal (GIOChannel *io_channel,
|
|
+ GIOCondition condition,
|
|
+ gpointer data)
|
|
+{
|
|
+ g_main_loop_quit (event_loop);
|
|
+ return FALSE;
|
|
+}
|
|
+
|
|
+static void
|
|
+on_debug_message (const char *log_domain,
|
|
+ GLogLevelFlags log_level,
|
|
+ const char *message,
|
|
+ gpointer user_data)
|
|
+{
|
|
+ g_printerr ("*** DEBUG: %s", message);
|
|
+}
|
|
+
|
|
+int
|
|
+main (int argc,
|
|
+ char **argv)
|
|
+{
|
|
+ GIOChannel *io_channel;
|
|
+
|
|
+ setlocale (LC_ALL, "");
|
|
+
|
|
+ g_type_init ();
|
|
+
|
|
+ g_log_set_handler (NULL, G_LOG_LEVEL_DEBUG, on_debug_message, NULL);
|
|
+
|
|
+ event_loop = g_main_loop_new (NULL, FALSE);
|
|
+
|
|
+ watch_for_smartcards ();
|
|
+
|
|
+ signal (SIGTERM, on_term_signal);
|
|
+ signal (SIGPIPE, on_term_signal);
|
|
+ if (pipe (signal_pipe_fds) != 0) {
|
|
+ return 1;
|
|
+ }
|
|
+ fcntl (signal_pipe_fds[0], F_SETFD, FD_CLOEXEC);
|
|
+ fcntl (signal_pipe_fds[1], F_SETFD, FD_CLOEXEC);
|
|
+
|
|
+ io_channel = g_io_channel_unix_new (signal_pipe_fds[0]);
|
|
+ g_io_channel_set_flags (io_channel, G_IO_FLAG_NONBLOCK, NULL);
|
|
+ g_io_channel_set_encoding (io_channel, NULL, NULL);
|
|
+ g_io_channel_set_buffered (io_channel, FALSE);
|
|
+ g_io_add_watch (io_channel, G_IO_HUP, after_term_signal, NULL);
|
|
+ g_io_channel_set_close_on_unref (io_channel, TRUE);
|
|
+ g_io_channel_unref (io_channel);
|
|
+
|
|
+ g_main_loop_run (event_loop);
|
|
+
|
|
+ stop_watching_for_smartcards ();
|
|
+
|
|
+ return 0;
|
|
+}
|
|
diff --git a/gui/simple-greeter/plugins/smartcard/gdm-smartcard.c b/gui/simple-greeter/plugins/smartcard/gdm-smartcard.c
|
|
new file mode 100644
|
|
index 0000000..c0e2739
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/plugins/smartcard/gdm-smartcard.c
|
|
@@ -0,0 +1,558 @@
|
|
+/* gdm-smartcard.c - smartcard object
|
|
+ *
|
|
+ * Copyright (C) 2006 Ray Strode <rstrode@redhat.com>
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2, or (at your option)
|
|
+ * any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
+ * 02111-1307, USA.
|
|
+ */
|
|
+#define GDM_SMARTCARD_ENABLE_INTERNAL_API
|
|
+#include "gdm-smartcard.h"
|
|
+
|
|
+#include <errno.h>
|
|
+#include <string.h>
|
|
+#include <unistd.h>
|
|
+
|
|
+#include <glib.h>
|
|
+#include <glib/gi18n.h>
|
|
+
|
|
+#include <cert.h>
|
|
+#include <nss.h>
|
|
+#include <pk11func.h>
|
|
+#include <prerror.h>
|
|
+#include <secmod.h>
|
|
+#include <secerr.h>
|
|
+
|
|
+struct _GdmSmartcardPrivate {
|
|
+ SECMODModule *module;
|
|
+ GdmSmartcardState state;
|
|
+
|
|
+ CK_SLOT_ID slot_id;
|
|
+ int slot_series;
|
|
+
|
|
+ PK11SlotInfo *slot;
|
|
+ char *name;
|
|
+
|
|
+ CERTCertificate *signing_certificate;
|
|
+ CERTCertificate *encryption_certificate;
|
|
+};
|
|
+
|
|
+static void gdm_smartcard_finalize (GObject *object);
|
|
+static void gdm_smartcard_class_install_signals (GdmSmartcardClass *card_class);
|
|
+static void gdm_smartcard_class_install_properties (GdmSmartcardClass *card_class);
|
|
+static void gdm_smartcard_set_property (GObject *object,
|
|
+ guint prop_id,
|
|
+ const GValue *value,
|
|
+ GParamSpec *pspec);
|
|
+static void gdm_smartcard_get_property (GObject *object,
|
|
+ guint prop_id,
|
|
+ GValue *value,
|
|
+ GParamSpec *pspec);
|
|
+static void gdm_smartcard_set_name (GdmSmartcard *card, const char *name);
|
|
+static void gdm_smartcard_set_slot_id (GdmSmartcard *card,
|
|
+ int slot_id);
|
|
+static void gdm_smartcard_set_slot_series (GdmSmartcard *card,
|
|
+ int slot_series);
|
|
+static void gdm_smartcard_set_module (GdmSmartcard *card,
|
|
+ SECMODModule *module);
|
|
+
|
|
+static PK11SlotInfo *gdm_smartcard_find_slot_from_id (GdmSmartcard *card,
|
|
+ int slot_id);
|
|
+
|
|
+static PK11SlotInfo *gdm_smartcard_find_slot_from_card_name (GdmSmartcard *card,
|
|
+ const char *card_name);
|
|
+static gboolean gdm_smartcard_fetch_certificates (GdmSmartcard *card);
|
|
+
|
|
+#ifndef GDM_SMARTCARD_DEFAULT_SLOT_ID
|
|
+#define GDM_SMARTCARD_DEFAULT_SLOT_ID ((gulong) -1)
|
|
+#endif
|
|
+
|
|
+#ifndef GDM_SMARTCARD_DEFAULT_SLOT_SERIES
|
|
+#define GDM_SMARTCARD_DEFAULT_SLOT_SERIES -1
|
|
+#endif
|
|
+
|
|
+enum {
|
|
+ PROP_0 = 0,
|
|
+ PROP_NAME,
|
|
+ PROP_SLOT_ID,
|
|
+ PROP_SLOT_SERIES,
|
|
+ PROP_MODULE,
|
|
+ NUMBER_OF_PROPERTIES
|
|
+};
|
|
+
|
|
+enum {
|
|
+ INSERTED,
|
|
+ REMOVED,
|
|
+ NUMBER_OF_SIGNALS
|
|
+};
|
|
+
|
|
+static guint gdm_smartcard_signals[NUMBER_OF_SIGNALS];
|
|
+
|
|
+G_DEFINE_TYPE (GdmSmartcard, gdm_smartcard, G_TYPE_OBJECT);
|
|
+
|
|
+static void
|
|
+gdm_smartcard_class_init (GdmSmartcardClass *card_class)
|
|
+{
|
|
+ GObjectClass *gobject_class;
|
|
+
|
|
+ gobject_class = G_OBJECT_CLASS (card_class);
|
|
+
|
|
+ gobject_class->finalize = gdm_smartcard_finalize;
|
|
+
|
|
+ gdm_smartcard_class_install_signals (card_class);
|
|
+ gdm_smartcard_class_install_properties (card_class);
|
|
+
|
|
+ g_type_class_add_private (card_class,
|
|
+ sizeof (GdmSmartcardPrivate));
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_class_install_signals (GdmSmartcardClass *card_class)
|
|
+{
|
|
+ GObjectClass *object_class;
|
|
+
|
|
+ object_class = G_OBJECT_CLASS (card_class);
|
|
+
|
|
+ gdm_smartcard_signals[INSERTED] =
|
|
+ g_signal_new ("inserted",
|
|
+ G_OBJECT_CLASS_TYPE (object_class),
|
|
+ G_SIGNAL_RUN_LAST,
|
|
+ G_STRUCT_OFFSET (GdmSmartcardClass,
|
|
+ inserted),
|
|
+ NULL, NULL, g_cclosure_marshal_VOID__VOID,
|
|
+ G_TYPE_NONE, 0);
|
|
+
|
|
+ gdm_smartcard_signals[REMOVED] =
|
|
+ g_signal_new ("removed",
|
|
+ G_OBJECT_CLASS_TYPE (object_class),
|
|
+ G_SIGNAL_RUN_LAST,
|
|
+ G_STRUCT_OFFSET (GdmSmartcardClass,
|
|
+ removed),
|
|
+ NULL, NULL, g_cclosure_marshal_VOID__VOID,
|
|
+ G_TYPE_NONE, 0);
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_class_install_properties (GdmSmartcardClass *card_class)
|
|
+{
|
|
+ GObjectClass *object_class;
|
|
+ GParamSpec *param_spec;
|
|
+
|
|
+ object_class = G_OBJECT_CLASS (card_class);
|
|
+ object_class->set_property = gdm_smartcard_set_property;
|
|
+ object_class->get_property = gdm_smartcard_get_property;
|
|
+
|
|
+ param_spec = g_param_spec_ulong ("slot-id", _("Slot ID"),
|
|
+ _("The slot the card is in"),
|
|
+ 1, G_MAXULONG,
|
|
+ GDM_SMARTCARD_DEFAULT_SLOT_ID,
|
|
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
|
+ g_object_class_install_property (object_class, PROP_SLOT_ID, param_spec);
|
|
+
|
|
+ param_spec = g_param_spec_int ("slot-series", _("Slot Series"),
|
|
+ _("per-slot card identifier"),
|
|
+ -1, G_MAXINT,
|
|
+ GDM_SMARTCARD_DEFAULT_SLOT_SERIES,
|
|
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
|
+ g_object_class_install_property (object_class, PROP_SLOT_SERIES, param_spec);
|
|
+
|
|
+ param_spec = g_param_spec_string ("name", _("name"),
|
|
+ _("name"), NULL,
|
|
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
|
+ g_object_class_install_property (object_class, PROP_NAME, param_spec);
|
|
+
|
|
+ param_spec = g_param_spec_pointer ("module", _("Module"),
|
|
+ _("smartcard driver"),
|
|
+ G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY);
|
|
+ g_object_class_install_property (object_class, PROP_MODULE, param_spec);
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_set_property (GObject *object,
|
|
+ guint prop_id,
|
|
+ const GValue *value,
|
|
+ GParamSpec *pspec)
|
|
+{
|
|
+ GdmSmartcard *card = GDM_SMARTCARD (object);
|
|
+
|
|
+ switch (prop_id) {
|
|
+ case PROP_NAME:
|
|
+ gdm_smartcard_set_name (card, g_value_get_string (value));
|
|
+ break;
|
|
+
|
|
+ case PROP_SLOT_ID:
|
|
+ gdm_smartcard_set_slot_id (card,
|
|
+ g_value_get_ulong (value));
|
|
+ break;
|
|
+
|
|
+ case PROP_SLOT_SERIES:
|
|
+ gdm_smartcard_set_slot_series (card,
|
|
+ g_value_get_int (value));
|
|
+ break;
|
|
+
|
|
+ case PROP_MODULE:
|
|
+ gdm_smartcard_set_module (card,
|
|
+ (SECMODModule *)
|
|
+ g_value_get_pointer (value));
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
+ }
|
|
+}
|
|
+
|
|
+CK_SLOT_ID
|
|
+gdm_smartcard_get_slot_id (GdmSmartcard *card)
|
|
+{
|
|
+ return card->priv->slot_id;
|
|
+}
|
|
+
|
|
+GdmSmartcardState
|
|
+gdm_smartcard_get_state (GdmSmartcard *card)
|
|
+{
|
|
+ return card->priv->state;
|
|
+}
|
|
+
|
|
+char *
|
|
+gdm_smartcard_get_name (GdmSmartcard *card)
|
|
+{
|
|
+ return g_strdup (card->priv->name);
|
|
+}
|
|
+
|
|
+gboolean
|
|
+gdm_smartcard_is_login_card (GdmSmartcard *card)
|
|
+{
|
|
+ const char *login_card_name;
|
|
+ login_card_name = g_getenv ("PKCS11_LOGIN_TOKEN_NAME");
|
|
+
|
|
+ if ((login_card_name == NULL) || (card->priv->name == NULL)) {
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ if (strcmp (card->priv->name, login_card_name) == 0) {
|
|
+ return TRUE;
|
|
+ }
|
|
+
|
|
+ return FALSE;
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_get_property (GObject *object,
|
|
+ guint prop_id,
|
|
+ GValue *value,
|
|
+ GParamSpec *pspec)
|
|
+{
|
|
+ GdmSmartcard *card = GDM_SMARTCARD (object);
|
|
+
|
|
+ switch (prop_id) {
|
|
+ case PROP_NAME:
|
|
+ g_value_take_string (value,
|
|
+ gdm_smartcard_get_name (card));
|
|
+ break;
|
|
+
|
|
+ case PROP_SLOT_ID:
|
|
+ g_value_set_ulong (value,
|
|
+ (gulong) gdm_smartcard_get_slot_id (card));
|
|
+ break;
|
|
+
|
|
+ case PROP_SLOT_SERIES:
|
|
+ g_value_set_int (value,
|
|
+ gdm_smartcard_get_slot_series (card));
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_set_name (GdmSmartcard *card,
|
|
+ const char *name)
|
|
+{
|
|
+ if (name == NULL) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if ((card->priv->name == NULL) ||
|
|
+ (strcmp (card->priv->name, name) != 0)) {
|
|
+ g_free (card->priv->name);
|
|
+ card->priv->name = g_strdup (name);
|
|
+
|
|
+ if (card->priv->slot == NULL) {
|
|
+ card->priv->slot = gdm_smartcard_find_slot_from_card_name (card,
|
|
+ card->priv->name);
|
|
+
|
|
+ if (card->priv->slot != NULL) {
|
|
+ int slot_id, slot_series;
|
|
+
|
|
+ slot_id = PK11_GetSlotID (card->priv->slot);
|
|
+ if (slot_id != card->priv->slot_id) {
|
|
+ gdm_smartcard_set_slot_id (card, slot_id);
|
|
+ }
|
|
+
|
|
+ slot_series = PK11_GetSlotSeries (card->priv->slot);
|
|
+ if (slot_series != card->priv->slot_series) {
|
|
+ gdm_smartcard_set_slot_series (card, slot_series);
|
|
+ }
|
|
+
|
|
+ _gdm_smartcard_set_state (card, GDM_SMARTCARD_STATE_INSERTED);
|
|
+ } else {
|
|
+ _gdm_smartcard_set_state (card, GDM_SMARTCARD_STATE_REMOVED);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ g_object_notify (G_OBJECT (card), "name");
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_set_slot_id (GdmSmartcard *card,
|
|
+ int slot_id)
|
|
+{
|
|
+ if (card->priv->slot_id != slot_id) {
|
|
+ card->priv->slot_id = slot_id;
|
|
+
|
|
+ if (card->priv->slot == NULL) {
|
|
+ card->priv->slot = gdm_smartcard_find_slot_from_id (card,
|
|
+ card->priv->slot_id);
|
|
+
|
|
+ if (card->priv->slot != NULL) {
|
|
+ const char *card_name;
|
|
+
|
|
+ card_name = PK11_GetTokenName (card->priv->slot);
|
|
+ if ((card->priv->name == NULL) ||
|
|
+ ((card_name != NULL) &&
|
|
+ (strcmp (card_name, card->priv->name) != 0))) {
|
|
+ gdm_smartcard_set_name (card, card_name);
|
|
+ }
|
|
+
|
|
+ _gdm_smartcard_set_state (card, GDM_SMARTCARD_STATE_INSERTED);
|
|
+ } else {
|
|
+ _gdm_smartcard_set_state (card, GDM_SMARTCARD_STATE_REMOVED);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ g_object_notify (G_OBJECT (card), "slot-id");
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_set_slot_series (GdmSmartcard *card,
|
|
+ int slot_series)
|
|
+{
|
|
+ if (card->priv->slot_series != slot_series) {
|
|
+ card->priv->slot_series = slot_series;
|
|
+ g_object_notify (G_OBJECT (card), "slot-series");
|
|
+ }
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_set_module (GdmSmartcard *card,
|
|
+ SECMODModule *module)
|
|
+{
|
|
+ gboolean should_notify;
|
|
+
|
|
+ if (card->priv->module != module) {
|
|
+ should_notify = TRUE;
|
|
+ } else {
|
|
+ should_notify = FALSE;
|
|
+ }
|
|
+
|
|
+ if (card->priv->module != NULL) {
|
|
+ SECMOD_DestroyModule (card->priv->module);
|
|
+ card->priv->module = NULL;
|
|
+ }
|
|
+
|
|
+ if (module != NULL) {
|
|
+ card->priv->module = SECMOD_ReferenceModule (module);
|
|
+ }
|
|
+
|
|
+ if (should_notify) {
|
|
+ g_object_notify (G_OBJECT (card), "module");
|
|
+ }
|
|
+}
|
|
+
|
|
+int
|
|
+gdm_smartcard_get_slot_series (GdmSmartcard *card)
|
|
+{
|
|
+ return card->priv->slot_series;
|
|
+}
|
|
+
|
|
+static void
|
|
+gdm_smartcard_init (GdmSmartcard *card)
|
|
+{
|
|
+
|
|
+ g_debug ("initializing smartcard ");
|
|
+
|
|
+ card->priv = G_TYPE_INSTANCE_GET_PRIVATE (card,
|
|
+ GDM_TYPE_SMARTCARD,
|
|
+ GdmSmartcardPrivate);
|
|
+
|
|
+ if (card->priv->slot != NULL) {
|
|
+ card->priv->name = g_strdup (PK11_GetTokenName (card->priv->slot));
|
|
+ }
|
|
+}
|
|
+
|
|
+static void gdm_smartcard_finalize (GObject *object)
|
|
+{
|
|
+ GdmSmartcard *card;
|
|
+ GObjectClass *gobject_class;
|
|
+
|
|
+ card = GDM_SMARTCARD (object);
|
|
+
|
|
+ g_free (card->priv->name);
|
|
+
|
|
+ gdm_smartcard_set_module (card, NULL);
|
|
+
|
|
+ gobject_class = G_OBJECT_CLASS (gdm_smartcard_parent_class);
|
|
+
|
|
+ gobject_class->finalize (object);
|
|
+}
|
|
+
|
|
+GQuark gdm_smartcard_error_quark (void)
|
|
+{
|
|
+ static GQuark error_quark = 0;
|
|
+
|
|
+ if (error_quark == 0) {
|
|
+ error_quark = g_quark_from_static_string ("gdm-smartcard-error-quark");
|
|
+ }
|
|
+
|
|
+ return error_quark;
|
|
+}
|
|
+
|
|
+GdmSmartcard *
|
|
+_gdm_smartcard_new (SECMODModule *module,
|
|
+ CK_SLOT_ID slot_id,
|
|
+ int slot_series)
|
|
+{
|
|
+ GdmSmartcard *card;
|
|
+
|
|
+ g_return_val_if_fail (module != NULL, NULL);
|
|
+ g_return_val_if_fail (slot_id >= 1, NULL);
|
|
+ g_return_val_if_fail (slot_series > 0, NULL);
|
|
+ g_return_val_if_fail (sizeof (gulong) == sizeof (slot_id), NULL);
|
|
+
|
|
+ card = GDM_SMARTCARD (g_object_new (GDM_TYPE_SMARTCARD,
|
|
+ "module", module,
|
|
+ "slot-id", (gulong) slot_id,
|
|
+ "slot-series", slot_series,
|
|
+ NULL));
|
|
+ return card;
|
|
+}
|
|
+
|
|
+GdmSmartcard *
|
|
+_gdm_smartcard_new_from_name (SECMODModule *module,
|
|
+ const char *name)
|
|
+{
|
|
+ GdmSmartcard *card;
|
|
+
|
|
+ g_return_val_if_fail (module != NULL, NULL);
|
|
+ g_return_val_if_fail (name != NULL, NULL);
|
|
+
|
|
+ card = GDM_SMARTCARD (g_object_new (GDM_TYPE_SMARTCARD,
|
|
+ "module", module,
|
|
+ "name", name,
|
|
+ NULL));
|
|
+ return card;
|
|
+}
|
|
+
|
|
+void
|
|
+_gdm_smartcard_set_state (GdmSmartcard *card,
|
|
+ GdmSmartcardState state)
|
|
+{
|
|
+ /* gdm_smartcard_fetch_certificates (card); */
|
|
+ if (card->priv->state != state) {
|
|
+ card->priv->state = state;
|
|
+
|
|
+ if (state == GDM_SMARTCARD_STATE_INSERTED) {
|
|
+ g_signal_emit (card, gdm_smartcard_signals[INSERTED], 0);
|
|
+ } else if (state == GDM_SMARTCARD_STATE_REMOVED) {
|
|
+ g_signal_emit (card, gdm_smartcard_signals[REMOVED], 0);
|
|
+ } else {
|
|
+ g_assert_not_reached ();
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+/* So we could conceivably make the closure data a pointer to the card
|
|
+ * or something similiar and then emit signals when we want passwords,
|
|
+ * but it's probably easier to just get the password up front and use
|
|
+ * it. So we just take the passed in g_malloc'd (well probably, who knows)
|
|
+ * and strdup it using NSPR's memory allocation routines.
|
|
+ */
|
|
+static char *
|
|
+gdm_smartcard_password_handler (PK11SlotInfo *slot,
|
|
+ PRBool is_retrying,
|
|
+ const char *password)
|
|
+{
|
|
+ if (is_retrying) {
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ return password != NULL? PL_strdup (password): NULL;
|
|
+}
|
|
+
|
|
+gboolean
|
|
+gdm_smartcard_unlock (GdmSmartcard *card,
|
|
+ const char *password)
|
|
+{
|
|
+ SECStatus status;
|
|
+
|
|
+ PK11_SetPasswordFunc ((PK11PasswordFunc) gdm_smartcard_password_handler);
|
|
+
|
|
+ /* we pass PR_TRUE to load certificates
|
|
+ */
|
|
+ status = PK11_Authenticate (card->priv->slot, PR_TRUE, (gpointer) password);
|
|
+
|
|
+ if (status != SECSuccess) {
|
|
+ g_debug ("could not unlock card - %d", status);
|
|
+ return FALSE;
|
|
+ }
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+static PK11SlotInfo *
|
|
+gdm_smartcard_find_slot_from_card_name (GdmSmartcard *card,
|
|
+ const char *card_name)
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ for (i = 0; i < card->priv->module->slotCount; i++) {
|
|
+ const char *slot_card_name;
|
|
+
|
|
+ slot_card_name = PK11_GetTokenName (card->priv->module->slots[i]);
|
|
+
|
|
+ if ((slot_card_name != NULL) &&
|
|
+ (strcmp (slot_card_name, card_name) == 0)) {
|
|
+ return card->priv->module->slots[i];
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+static PK11SlotInfo *
|
|
+gdm_smartcard_find_slot_from_id (GdmSmartcard *card,
|
|
+ int slot_id)
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ for (i = 0; i < card->priv->module->slotCount; i++) {
|
|
+ if (PK11_GetSlotID (card->priv->module->slots[i]) == slot_id) {
|
|
+ return card->priv->module->slots[i];
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return NULL;
|
|
+}
|
|
diff --git a/gui/simple-greeter/plugins/smartcard/gdm-smartcard.h b/gui/simple-greeter/plugins/smartcard/gdm-smartcard.h
|
|
new file mode 100644
|
|
index 0000000..20303bd
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/plugins/smartcard/gdm-smartcard.h
|
|
@@ -0,0 +1,94 @@
|
|
+/* securitycard.h - api for reading and writing data to a security card
|
|
+ *
|
|
+ * Copyright (C) 2006 Ray Strode
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or modify
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
+ * the Free Software Foundation; either version 2, or (at your option)
|
|
+ * any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
+ * 02111-1307, USA.
|
|
+ */
|
|
+#ifndef GDM_SMARTCARD_H
|
|
+#define GDM_SMARTCARD_H
|
|
+
|
|
+#include <glib.h>
|
|
+#include <glib-object.h>
|
|
+
|
|
+#include <secmod.h>
|
|
+
|
|
+G_BEGIN_DECLS
|
|
+#define GDM_TYPE_SMARTCARD (gdm_smartcard_get_type ())
|
|
+#define GDM_SMARTCARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDM_TYPE_SMARTCARD, GdmSmartcard))
|
|
+#define GDM_SMARTCARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDM_TYPE_SMARTCARD, GdmSmartcardClass))
|
|
+#define GDM_IS_SMARTCARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDM_TYPE_SMARTCARD))
|
|
+#define GDM_IS_SMARTCARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDM_TYPE_SMARTCARD))
|
|
+#define GDM_SMARTCARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GDM_TYPE_SMARTCARD, GdmSmartcardClass))
|
|
+#define GDM_SMARTCARD_ERROR (gdm_smartcard_error_quark ())
|
|
+typedef struct _GdmSmartcardClass GdmSmartcardClass;
|
|
+typedef struct _GdmSmartcard GdmSmartcard;
|
|
+typedef struct _GdmSmartcardPrivate GdmSmartcardPrivate;
|
|
+typedef enum _GdmSmartcardError GdmSmartcardError;
|
|
+typedef enum _GdmSmartcardState GdmSmartcardState;
|
|
+
|
|
+typedef struct _GdmSmartcardRequest GdmSmartcardRequest;
|
|
+
|
|
+struct _GdmSmartcard {
|
|
+ GObject parent;
|
|
+
|
|
+ /*< private > */
|
|
+ GdmSmartcardPrivate *priv;
|
|
+};
|
|
+
|
|
+struct _GdmSmartcardClass {
|
|
+ GObjectClass parent_class;
|
|
+
|
|
+ void (* inserted) (GdmSmartcard *card);
|
|
+ void (* removed) (GdmSmartcard *card);
|
|
+};
|
|
+
|
|
+enum _GdmSmartcardError {
|
|
+ GDM_SMARTCARD_ERROR_GENERIC = 0,
|
|
+};
|
|
+
|
|
+enum _GdmSmartcardState {
|
|
+ GDM_SMARTCARD_STATE_INSERTED = 0,
|
|
+ GDM_SMARTCARD_STATE_REMOVED,
|
|
+};
|
|
+
|
|
+GType gdm_smartcard_get_type (void) G_GNUC_CONST;
|
|
+GQuark gdm_smartcard_error_quark (void) G_GNUC_CONST;
|
|
+
|
|
+CK_SLOT_ID gdm_smartcard_get_slot_id (GdmSmartcard *card);
|
|
+gint gdm_smartcard_get_slot_series (GdmSmartcard *card);
|
|
+GdmSmartcardState gdm_smartcard_get_state (GdmSmartcard *card);
|
|
+
|
|
+char *gdm_smartcard_get_name (GdmSmartcard *card);
|
|
+gboolean gdm_smartcard_is_login_card (GdmSmartcard *card);
|
|
+
|
|
+gboolean gdm_smartcard_unlock (GdmSmartcard *card,
|
|
+ const char *password);
|
|
+
|
|
+/* don't under any circumstances call these functions */
|
|
+#ifdef GDM_SMARTCARD_ENABLE_INTERNAL_API
|
|
+
|
|
+GdmSmartcard *_gdm_smartcard_new (SECMODModule *module,
|
|
+ CK_SLOT_ID slot_id,
|
|
+ gint slot_series);
|
|
+GdmSmartcard *_gdm_smartcard_new_from_name (SECMODModule *module,
|
|
+ const char *name);
|
|
+
|
|
+void _gdm_smartcard_set_state (GdmSmartcard *card,
|
|
+ GdmSmartcardState state);
|
|
+#endif
|
|
+
|
|
+G_END_DECLS
|
|
+#endif /* GDM_SMARTCARD_H */
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 6015de6362cb3c62313ec62445dc422cf26af219 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Thu, 19 Feb 2009 15:27:11 -0500
|
|
Subject: [PATCH 39/65] Don't hard code locations of plugin data files
|
|
|
|
They were full path names on my local system
|
|
before for quick testing. This commit cleans
|
|
it up to pull the location from the autogoo.
|
|
---
|
|
configure.ac | 9 +++++++++
|
|
gui/simple-greeter/plugins/fingerprint/Makefile.am | 14 ++++++++++++--
|
|
.../plugins/fingerprint/gdm-fingerprint | 10 ++++++++++
|
|
.../fingerprint/gdm-fingerprint-extension.c | 4 ++--
|
|
gui/simple-greeter/plugins/password/Makefile.am | 13 +++++++++++--
|
|
gui/simple-greeter/plugins/password/gdm-password | 13 +++++++++++++
|
|
.../plugins/password/gdm-password-extension.c | 4 ++--
|
|
gui/simple-greeter/plugins/smartcard/Makefile.am | 13 +++++++++++--
|
|
gui/simple-greeter/plugins/smartcard/gdm-smartcard | 11 +++++++++++
|
|
.../plugins/smartcard/gdm-smartcard-extension.c | 4 ++--
|
|
10 files changed, 83 insertions(+), 12 deletions(-)
|
|
create mode 100644 gui/simple-greeter/plugins/fingerprint/gdm-fingerprint
|
|
create mode 100644 gui/simple-greeter/plugins/password/gdm-password
|
|
create mode 100644 gui/simple-greeter/plugins/smartcard/gdm-smartcard
|
|
|
|
diff --git a/configure.ac b/configure.ac
|
|
index 8e99509..1b109d5 100644
|
|
--- a/configure.ac
|
|
+++ b/configure.ac
|
|
@@ -222,6 +222,15 @@ AC_ARG_WITH(dmconfdir,
|
|
AC_SUBST(dmconfdir)
|
|
|
|
dnl ---------------------------------------------------------------------------
|
|
+dnl - Configuration file stuff
|
|
+dnl ---------------------------------------------------------------------------
|
|
+AC_ARG_WITH(extensionsdatadir,
|
|
+ AS_HELP_STRING([--with-extensions-datadir],
|
|
+ [directory where extensions store data, default=DATADIR/gdm/simple-greeter/extensions]),
|
|
+ extensionsdatadir=${withval}, extensionsdatadir=${datadir}/gdm/simple-greeter/extensions)
|
|
+AC_SUBST(extensionsdatadir)
|
|
+
|
|
+dnl ---------------------------------------------------------------------------
|
|
dnl - Configure arguments
|
|
dnl ---------------------------------------------------------------------------
|
|
|
|
diff --git a/gui/simple-greeter/plugins/fingerprint/Makefile.am b/gui/simple-greeter/plugins/fingerprint/Makefile.am
|
|
index 6f2d727..6a5620f 100644
|
|
--- a/gui/simple-greeter/plugins/fingerprint/Makefile.am
|
|
+++ b/gui/simple-greeter/plugins/fingerprint/Makefile.am
|
|
@@ -1,12 +1,18 @@
|
|
NULL =
|
|
|
|
+extensiondir = $(extensionsdatadir)/fingerprint
|
|
+extension_DATA = page.ui
|
|
+
|
|
+pamservicename = gdm-fingerprint
|
|
+
|
|
AM_CPPFLAGS = \
|
|
-I$(top_srcdir)/common \
|
|
-I$(top_srcdir)/gui/simple-greeter/libnotificationarea \
|
|
-I$(top_srcdir)/gui/simple-greeter/libgdmsimplegreeter \
|
|
-DDMCONFDIR=\""$(dmconfdir)"\" \
|
|
-DGDMCONFDIR=\"$(gdmconfdir)\" \
|
|
- -DDATADIR=\""$(datadir)"\" \
|
|
+ -DPLUGINDATADIR=\""$(extensiondir)"\" \
|
|
+ -DPAMSERVICENAME=\""$(pamservicename)"\" \
|
|
-DSYSCONFDIR=\""$(sysconfdir)"\" \
|
|
-DLIBLOCALEDIR=\""$(prefix)/lib/locale"\" \
|
|
-DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
|
|
@@ -18,6 +24,7 @@ AM_CPPFLAGS = \
|
|
$(POLKIT_GNOME_CFLAGS) \
|
|
$(NULL)
|
|
|
|
+
|
|
plugindir = $(GDM_SIMPLE_GREETER_PLUGINS_DIR)
|
|
plugin_LTLIBRARIES = fingerprint.la
|
|
|
|
@@ -33,7 +40,10 @@ fingerprint_la_SOURCES = \
|
|
gdm-fingerprint-extension.c \
|
|
plugin.c
|
|
|
|
-EXTRA_DIST = gdm-fingerprint
|
|
+pamdir = $(PAM_PREFIX)/pam.d
|
|
+pam_DATA = $(pamservicename)
|
|
+
|
|
+EXTRA_DIST = $(extension_DATA) $(pam_DATA)
|
|
|
|
MAINTAINERCLEANFILES = \
|
|
*~ \
|
|
diff --git a/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint b/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint
|
|
new file mode 100644
|
|
index 0000000..e8316b0
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint
|
|
@@ -0,0 +1,10 @@
|
|
+#%PAM-1.0
|
|
+auth required pam_fprintd.so
|
|
+account required pam_nologin.so
|
|
+account include system-auth
|
|
+password include system-auth
|
|
+session required pam_loginuid.so
|
|
+session optional pam_console.so
|
|
+session optional pam_keyinit.so force revoke
|
|
+session required pam_namespace.so
|
|
+session include system-auth
|
|
diff --git a/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.c b/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.c
|
|
index 2a4027c..7f5eb1c 100644
|
|
--- a/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.c
|
|
+++ b/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.c
|
|
@@ -118,7 +118,7 @@ gdm_fingerprint_extension_set_ready (GdmConversation *conversation)
|
|
char *
|
|
gdm_fingerprint_extension_get_service_name (GdmConversation *conversation)
|
|
{
|
|
- return g_strdup ("fingerprint-auth");
|
|
+ return g_strdup (PAMSERVICENAME);
|
|
}
|
|
|
|
GtkWidget *
|
|
@@ -245,7 +245,7 @@ create_page (GdmFingerprintExtension *extension)
|
|
|
|
error = NULL;
|
|
gtk_builder_add_from_file (builder,
|
|
- "/usr/share/gdm/simple-greeter/extensions/fingerprint/page.ui",
|
|
+ PLUGINDATADIR "/page.ui",
|
|
&error);
|
|
|
|
if (error != NULL) {
|
|
diff --git a/gui/simple-greeter/plugins/password/Makefile.am b/gui/simple-greeter/plugins/password/Makefile.am
|
|
index 18b9801..e832c4d 100644
|
|
--- a/gui/simple-greeter/plugins/password/Makefile.am
|
|
+++ b/gui/simple-greeter/plugins/password/Makefile.am
|
|
@@ -1,12 +1,18 @@
|
|
NULL =
|
|
|
|
+extensiondir = $(extensionsdatadir)/password
|
|
+extension_DATA = page.ui
|
|
+
|
|
+pamservicename = gdm-password
|
|
+
|
|
AM_CPPFLAGS = \
|
|
-I$(top_srcdir)/common \
|
|
-I$(top_srcdir)/gui/simple-greeter/libnotificationarea \
|
|
-I$(top_srcdir)/gui/simple-greeter/libgdmsimplegreeter \
|
|
-DDMCONFDIR=\""$(dmconfdir)"\" \
|
|
-DGDMCONFDIR=\"$(gdmconfdir)\" \
|
|
- -DDATADIR=\""$(datadir)"\" \
|
|
+ -DPLUGINDATADIR=\""$(extensiondir)"\" \
|
|
+ -DPAMSERVICENAME=\""$(pamservicename)"\" \
|
|
-DSYSCONFDIR=\""$(sysconfdir)"\" \
|
|
-DLIBLOCALEDIR=\""$(prefix)/lib/locale"\" \
|
|
-DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
|
|
@@ -33,7 +39,10 @@ password_la_SOURCES = \
|
|
gdm-password-extension.c \
|
|
plugin.c
|
|
|
|
-EXTRA_DIST = gdm-password
|
|
+pamdir = $(PAM_PREFIX)/pam.d
|
|
+pam_DATA = $(pamservicename)
|
|
+
|
|
+EXTRA_DIST = $(extension_DATA) $(pam_DATA)
|
|
|
|
MAINTAINERCLEANFILES = \
|
|
*~ \
|
|
diff --git a/gui/simple-greeter/plugins/password/gdm-password b/gui/simple-greeter/plugins/password/gdm-password
|
|
new file mode 100644
|
|
index 0000000..d17f7b1
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/plugins/password/gdm-password
|
|
@@ -0,0 +1,13 @@
|
|
+#%PAM-1.0
|
|
+auth required pam_env.so
|
|
+auth substack system-auth
|
|
+auth optional pam_gnome_keyring.so
|
|
+account required pam_nologin.so
|
|
+account include system-auth
|
|
+password include system-auth
|
|
+session required pam_loginuid.so
|
|
+session optional pam_console.so
|
|
+session optional pam_keyinit.so force revoke
|
|
+session required pam_namespace.so
|
|
+session optional pam_gnome_keyring.so auto_start
|
|
+session include system-auth
|
|
diff --git a/gui/simple-greeter/plugins/password/gdm-password-extension.c b/gui/simple-greeter/plugins/password/gdm-password-extension.c
|
|
index 80c9ea7..fae73be 100644
|
|
--- a/gui/simple-greeter/plugins/password/gdm-password-extension.c
|
|
+++ b/gui/simple-greeter/plugins/password/gdm-password-extension.c
|
|
@@ -118,7 +118,7 @@ gdm_password_extension_set_ready (GdmConversation *conversation)
|
|
char *
|
|
gdm_password_extension_get_service_name (GdmConversation *conversation)
|
|
{
|
|
- return g_strdup ("gdm");
|
|
+ return g_strdup (PAMSERVICENAME);
|
|
}
|
|
|
|
GtkWidget *
|
|
@@ -251,7 +251,7 @@ create_page (GdmPasswordExtension *extension)
|
|
|
|
error = NULL;
|
|
gtk_builder_add_from_file (builder,
|
|
- "/usr/share/gdm/simple-greeter/extensions/password/page.ui",
|
|
+ PLUGINDATADIR "/page.ui",
|
|
&error);
|
|
|
|
if (error != NULL) {
|
|
diff --git a/gui/simple-greeter/plugins/smartcard/Makefile.am b/gui/simple-greeter/plugins/smartcard/Makefile.am
|
|
index 2dfe226..4897416 100644
|
|
--- a/gui/simple-greeter/plugins/smartcard/Makefile.am
|
|
+++ b/gui/simple-greeter/plugins/smartcard/Makefile.am
|
|
@@ -1,12 +1,18 @@
|
|
NULL =
|
|
|
|
+extensiondir = $(extensionsdatadir)/smartcard
|
|
+extension_DATA = page.ui
|
|
+
|
|
+pamservicename = gdm-smartcard
|
|
+
|
|
AM_CPPFLAGS = \
|
|
-I$(top_srcdir)/common \
|
|
-I$(top_srcdir)/gui/simple-greeter/libnotificationarea \
|
|
-I$(top_srcdir)/gui/simple-greeter/libgdmsimplegreeter \
|
|
-DDMCONFDIR=\""$(dmconfdir)"\" \
|
|
-DGDMCONFDIR=\"$(gdmconfdir)\" \
|
|
- -DDATADIR=\""$(datadir)"\" \
|
|
+ -DPLUGINDATADIR=\""$(extensiondir)"\" \
|
|
+ -DPAMSERVICENAME=\""$(pamservicename)"\" \
|
|
-DSYSCONFDIR=\""$(sysconfdir)"\" \
|
|
-DLIBLOCALEDIR=\""$(prefix)/lib/locale"\" \
|
|
-DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
|
|
@@ -55,7 +61,10 @@ gdm_smartcard_worker_SOURCES = \
|
|
gdm-smartcard-worker.c \
|
|
$(NULL)
|
|
|
|
-EXTRA_DIST = gdm-smartcard
|
|
+pamdir = $(PAM_PREFIX)/pam.d
|
|
+pam_DATA = $(pamservicename)
|
|
+
|
|
+EXTRA_DIST = $(extension_DATA) $(pam_DATA)
|
|
|
|
MAINTAINERCLEANFILES = \
|
|
*~ \
|
|
diff --git a/gui/simple-greeter/plugins/smartcard/gdm-smartcard b/gui/simple-greeter/plugins/smartcard/gdm-smartcard
|
|
new file mode 100644
|
|
index 0000000..a0d7492
|
|
--- /dev/null
|
|
+++ b/gui/simple-greeter/plugins/smartcard/gdm-smartcard
|
|
@@ -0,0 +1,11 @@
|
|
+#%PAM-1.0
|
|
+auth required pam_env.so
|
|
+auth required pam_pkcs11.so wait_for_card
|
|
+account required pam_nologin.so
|
|
+account include system-auth
|
|
+password include system-auth
|
|
+session required pam_loginuid.so
|
|
+session optional pam_console.so
|
|
+session optional pam_keyinit.so force revoke
|
|
+session required pam_namespace.so
|
|
+session include system-auth
|
|
diff --git a/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c
|
|
index efa0978..0ffea2c 100644
|
|
--- a/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c
|
|
+++ b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c
|
|
@@ -131,7 +131,7 @@ gdm_smartcard_extension_set_ready (GdmConversation *conversation)
|
|
char *
|
|
gdm_smartcard_extension_get_service_name (GdmConversation *conversation)
|
|
{
|
|
- return g_strdup ("smartcard-auth");
|
|
+ return g_strdup (PAMSERVICENAME);
|
|
}
|
|
|
|
GtkWidget *
|
|
@@ -258,7 +258,7 @@ create_page (GdmSmartcardExtension *extension)
|
|
|
|
error = NULL;
|
|
gtk_builder_add_from_file (builder,
|
|
- "/usr/share/gdm/simple-greeter/extensions/smartcard/page.ui",
|
|
+ PLUGINDATADIR "/page.ui",
|
|
&error);
|
|
|
|
if (error != NULL) {
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 1565a925432d212a8b11eeae00d384c2f023a49c Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Fri, 20 Feb 2009 13:52:19 -0500
|
|
Subject: [PATCH 40/65] Add a comment marking protected api in chooser
|
|
|
|
The chooser widget has methods that only its
|
|
subclasses are supposed to call. We should
|
|
mark them as such.
|
|
---
|
|
gui/simple-greeter/gdm-chooser-widget.h | 2 ++
|
|
1 files changed, 2 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-chooser-widget.h b/gui/simple-greeter/gdm-chooser-widget.h
|
|
index b73d1bb..216ea85 100644
|
|
--- a/gui/simple-greeter/gdm-chooser-widget.h
|
|
+++ b/gui/simple-greeter/gdm-chooser-widget.h
|
|
@@ -136,6 +136,8 @@ int gdm_chooser_widget_get_number_of_items (GdmChooserWidget
|
|
void gdm_chooser_widget_activate_if_one_item (GdmChooserWidget *widget);
|
|
void gdm_chooser_widget_propagate_pending_key_events (GdmChooserWidget *widget);
|
|
|
|
+/* Protected
|
|
+ */
|
|
void gdm_chooser_widget_loaded (GdmChooserWidget *widget);
|
|
|
|
G_END_DECLS
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 88e738b1aaa7785addea9fc4f8baba140e988e1c Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Fri, 20 Feb 2009 14:05:20 -0500
|
|
Subject: [PATCH 41/65] Add new api to ask when chooser widget is done loading items
|
|
|
|
---
|
|
gui/simple-greeter/gdm-chooser-widget.c | 9 +++++++++
|
|
gui/simple-greeter/gdm-chooser-widget.h | 2 ++
|
|
2 files changed, 11 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-chooser-widget.c b/gui/simple-greeter/gdm-chooser-widget.c
|
|
index f0298c6..e5ddf78 100644
|
|
--- a/gui/simple-greeter/gdm-chooser-widget.c
|
|
+++ b/gui/simple-greeter/gdm-chooser-widget.c
|
|
@@ -93,6 +93,7 @@ struct GdmChooserWidgetPrivate
|
|
guint32 should_hide_inactive_items : 1;
|
|
guint32 emit_activated_after_resize_animation : 1;
|
|
guint32 was_fully_grown : 1;
|
|
+ guint32 is_loaded : 1;
|
|
|
|
GdmChooserWidgetPosition separator_position;
|
|
GdmChooserWidgetState state;
|
|
@@ -2485,8 +2486,16 @@ gdm_chooser_widget_propagate_pending_key_events (GdmChooserWidget *widget)
|
|
gdm_scrollable_widget_replay_queued_key_events (GDM_SCROLLABLE_WIDGET (widget->priv->scrollable_widget));
|
|
}
|
|
|
|
+gboolean
|
|
+gdm_chooser_widget_is_loaded (GdmChooserWidget *widget)
|
|
+{
|
|
+ return widget->priv->is_loaded;
|
|
+}
|
|
+
|
|
void
|
|
gdm_chooser_widget_loaded (GdmChooserWidget *widget)
|
|
{
|
|
+ widget->priv->is_loaded = TRUE;
|
|
+
|
|
g_signal_emit (widget, signals[LOADED], 0);
|
|
}
|
|
diff --git a/gui/simple-greeter/gdm-chooser-widget.h b/gui/simple-greeter/gdm-chooser-widget.h
|
|
index 216ea85..38f889b 100644
|
|
--- a/gui/simple-greeter/gdm-chooser-widget.h
|
|
+++ b/gui/simple-greeter/gdm-chooser-widget.h
|
|
@@ -136,6 +136,8 @@ int gdm_chooser_widget_get_number_of_items (GdmChooserWidget
|
|
void gdm_chooser_widget_activate_if_one_item (GdmChooserWidget *widget);
|
|
void gdm_chooser_widget_propagate_pending_key_events (GdmChooserWidget *widget);
|
|
|
|
+gboolean gdm_chooser_widget_is_loaded (GdmChooserWidget *widget);
|
|
+
|
|
/* Protected
|
|
*/
|
|
void gdm_chooser_widget_loaded (GdmChooserWidget *widget);
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 0bf2cd04e08ad29371eed89cd03425cced4506f3 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Fri, 20 Feb 2009 14:31:27 -0500
|
|
Subject: [PATCH 42/65] Tell tasks they're ready only after user list loads
|
|
|
|
This way they won't try to access the list prematurely.
|
|
---
|
|
gui/simple-greeter/gdm-greeter-login-window.c | 10 +++++++++-
|
|
1 files changed, 9 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-greeter-login-window.c b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
index 5f37d0c..30989ad 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-login-window.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
@@ -843,7 +843,15 @@ gdm_greeter_login_window_ready (GdmGreeterLoginWindow *login_window,
|
|
(gpointer) service_name);
|
|
|
|
if (task != NULL) {
|
|
- gdm_conversation_set_ready (GDM_CONVERSATION (task));
|
|
+ if (gdm_chooser_widget_is_loaded (GDM_CHOOSER_WIDGET (login_window->priv->user_chooser))) {
|
|
+ gdm_conversation_set_ready (GDM_CONVERSATION (task));
|
|
+ } else {
|
|
+
|
|
+ g_signal_connect_swapped (login_window->priv->user_chooser,
|
|
+ "loaded",
|
|
+ G_CALLBACK (gdm_conversation_set_ready),
|
|
+ GDM_CONVERSATION (task));
|
|
+ }
|
|
g_object_unref (task);
|
|
}
|
|
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From b16790919e0d368d0119d9f5ada238e6ae8e59ab Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Fri, 20 Feb 2009 14:32:47 -0500
|
|
Subject: [PATCH 43/65] Start smartcard listener only after getting the go ahead
|
|
|
|
The greeter will tell us when it's ready for us. We
|
|
don't want to listen for events until that point.
|
|
---
|
|
.../plugins/smartcard/gdm-smartcard-extension.c | 162 ++++++++++----------
|
|
1 files changed, 84 insertions(+), 78 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c
|
|
index 0ffea2c..40ecd08 100644
|
|
--- a/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c
|
|
+++ b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c
|
|
@@ -70,6 +70,84 @@ G_DEFINE_TYPE_WITH_CODE (GdmSmartcardExtension,
|
|
G_IMPLEMENT_INTERFACE (GDM_TYPE_CONVERSATION,
|
|
gdm_conversation_iface_init));
|
|
|
|
+static gboolean
|
|
+on_smartcard_event (GIOChannel *io_channel,
|
|
+ GIOCondition condition,
|
|
+ gpointer data)
|
|
+{
|
|
+ GdmSmartcardExtension *extension;
|
|
+
|
|
+ extension = GDM_SMARTCARD_EXTENSION (data);
|
|
+
|
|
+ if (condition & G_IO_IN) {
|
|
+ char buffer[1024];
|
|
+ ssize_t num_bytes;
|
|
+
|
|
+ num_bytes = read (g_io_channel_unix_get_fd (io_channel),
|
|
+ buffer, sizeof (buffer));
|
|
+
|
|
+ if (num_bytes < 0 && errno != EINTR)
|
|
+ return FALSE;
|
|
+
|
|
+ if (num_bytes != 1) {
|
|
+ g_debug ("buffer: %s\n", buffer);
|
|
+ return TRUE;
|
|
+ }
|
|
+
|
|
+ if (buffer[0] == 'I') {
|
|
+ extension->priv->number_of_tokens++;
|
|
+ } else {
|
|
+ extension->priv->number_of_tokens--;
|
|
+ }
|
|
+
|
|
+ if (extension->priv->number_of_tokens == 1) {
|
|
+ gdm_conversation_choose_user (GDM_CONVERSATION (extension),
|
|
+ GDM_CONVERSATION_OTHER_USER);
|
|
+ } else if (extension->priv->number_of_tokens == 0) {
|
|
+ gdm_conversation_cancel (GDM_CONVERSATION (extension));
|
|
+ }
|
|
+
|
|
+ return TRUE;
|
|
+ }
|
|
+
|
|
+ if (condition & G_IO_HUP) {
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+static void
|
|
+watch_for_smartcards (GdmSmartcardExtension *extension)
|
|
+{
|
|
+ GError *error;
|
|
+ GIOChannel *io_channel;
|
|
+ char *args[] = { GDM_SMARTCARD_WORKER_COMMAND, NULL };
|
|
+ GPid pid;
|
|
+ int stdout_fd;
|
|
+
|
|
+ error = NULL;
|
|
+
|
|
+ if (!g_spawn_async_with_pipes (NULL, args, NULL, 0,
|
|
+ NULL, NULL, &pid, NULL,
|
|
+ &stdout_fd, NULL, &error)) {
|
|
+ g_debug ("could not start smart card manager: %s", error->message);
|
|
+ g_error_free (error);
|
|
+ return;
|
|
+ }
|
|
+ fcntl (stdout_fd, F_SETFD, FD_CLOEXEC);
|
|
+
|
|
+ io_channel = g_io_channel_unix_new (stdout_fd);
|
|
+ g_io_channel_set_flags (io_channel, G_IO_FLAG_NONBLOCK, NULL);
|
|
+ g_io_channel_set_encoding (io_channel, NULL, NULL);
|
|
+ g_io_channel_set_buffered (io_channel, FALSE);
|
|
+ g_io_add_watch (io_channel, G_IO_IN, on_smartcard_event, extension);
|
|
+ g_io_channel_set_close_on_unref (io_channel, TRUE);
|
|
+ g_io_channel_unref (io_channel);
|
|
+
|
|
+ extension->priv->worker_pid = pid;
|
|
+}
|
|
+
|
|
static void
|
|
gdm_smartcard_extension_set_message (GdmConversation *conversation,
|
|
const char *message)
|
|
@@ -125,7 +203,13 @@ gdm_smartcard_extension_reset (GdmConversation *conversation)
|
|
static void
|
|
gdm_smartcard_extension_set_ready (GdmConversation *conversation)
|
|
{
|
|
+ GdmSmartcardExtension *extension = GDM_SMARTCARD_EXTENSION (conversation);
|
|
gdm_task_set_enabled (GDM_TASK (conversation), TRUE);
|
|
+
|
|
+ if (extension->priv->worker_pid <= 0)
|
|
+ {
|
|
+ watch_for_smartcards (extension);
|
|
+ }
|
|
}
|
|
|
|
char *
|
|
@@ -297,83 +381,6 @@ create_actions (GdmSmartcardExtension *extension)
|
|
|
|
extension->priv->actions = gtk_action_group_new ("gdm-smartcard-extension");
|
|
}
|
|
-static gboolean
|
|
-on_smartcard_event (GIOChannel *io_channel,
|
|
- GIOCondition condition,
|
|
- gpointer data)
|
|
-{
|
|
- GdmSmartcardExtension *extension;
|
|
-
|
|
- extension = GDM_SMARTCARD_EXTENSION (data);
|
|
-
|
|
- if (condition & G_IO_IN) {
|
|
- char buffer[1024];
|
|
- ssize_t num_bytes;
|
|
-
|
|
- num_bytes = read (g_io_channel_unix_get_fd (io_channel),
|
|
- buffer, sizeof (buffer));
|
|
-
|
|
- if (num_bytes < 0 && errno != EINTR)
|
|
- return FALSE;
|
|
-
|
|
- if (num_bytes != 1) {
|
|
- g_debug ("buffer: %s\n", buffer);
|
|
- return TRUE;
|
|
- }
|
|
-
|
|
- if (buffer[0] == 'I') {
|
|
- extension->priv->number_of_tokens++;
|
|
- } else {
|
|
- extension->priv->number_of_tokens--;
|
|
- }
|
|
-
|
|
- if (extension->priv->number_of_tokens == 1) {
|
|
- gdm_conversation_choose_user (GDM_CONVERSATION (extension),
|
|
- GDM_CONVERSATION_OTHER_USER);
|
|
- } else if (extension->priv->number_of_tokens == 0) {
|
|
- gdm_conversation_cancel (GDM_CONVERSATION (extension));
|
|
- }
|
|
-
|
|
- return TRUE;
|
|
- }
|
|
-
|
|
- if (condition & G_IO_HUP) {
|
|
- return FALSE;
|
|
- }
|
|
-
|
|
- return TRUE;
|
|
-}
|
|
-
|
|
-static void
|
|
-watch_for_smartcards (GdmSmartcardExtension *extension)
|
|
-{
|
|
- GError *error;
|
|
- GIOChannel *io_channel;
|
|
- char *args[] = { GDM_SMARTCARD_WORKER_COMMAND, NULL };
|
|
- GPid pid;
|
|
- int stdout_fd;
|
|
-
|
|
- error = NULL;
|
|
-
|
|
- if (!g_spawn_async_with_pipes (NULL, args, NULL, 0,
|
|
- NULL, NULL, &pid, NULL,
|
|
- &stdout_fd, NULL, &error)) {
|
|
- g_debug ("could not start smart card manager: %s", error->message);
|
|
- g_error_free (error);
|
|
- return;
|
|
- }
|
|
- fcntl (stdout_fd, F_SETFD, FD_CLOEXEC);
|
|
-
|
|
- io_channel = g_io_channel_unix_new (stdout_fd);
|
|
- g_io_channel_set_flags (io_channel, G_IO_FLAG_NONBLOCK, NULL);
|
|
- g_io_channel_set_encoding (io_channel, NULL, NULL);
|
|
- g_io_channel_set_buffered (io_channel, FALSE);
|
|
- g_io_add_watch (io_channel, G_IO_IN, on_smartcard_event, extension);
|
|
- g_io_channel_set_close_on_unref (io_channel, TRUE);
|
|
- g_io_channel_unref (io_channel);
|
|
-
|
|
- extension->priv->worker_pid = pid;
|
|
-}
|
|
|
|
static void
|
|
gdm_smartcard_extension_init (GdmSmartcardExtension *extension)
|
|
@@ -383,7 +390,6 @@ gdm_smartcard_extension_init (GdmSmartcardExtension *extension)
|
|
GdmSmartcardExtensionPrivate);
|
|
|
|
extension->priv->icon = g_themed_icon_new ("apple-green");
|
|
- watch_for_smartcards (extension);
|
|
create_page (extension);
|
|
create_actions (extension);
|
|
gdm_smartcard_extension_reset (GDM_CONVERSATION (extension));
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 29bdaeeb5571914b2bff56c8ec39594712055f9c Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Fri, 20 Feb 2009 14:35:44 -0500
|
|
Subject: [PATCH 44/65] Add a sanity check against buggy plugins
|
|
|
|
We don't let them select items in the user list
|
|
before the user list is loaded.
|
|
---
|
|
gui/simple-greeter/gdm-greeter-login-window.c | 9 +++++++++
|
|
1 files changed, 9 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-greeter-login-window.c b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
index 30989ad..7739a7c 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-login-window.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
@@ -2268,6 +2268,15 @@ on_conversation_chose_user (GdmGreeterLoginWindow *login_window,
|
|
const char *username,
|
|
GdmConversation *conversation)
|
|
{
|
|
+ if (!gdm_chooser_widget_is_loaded (GDM_CHOOSER_WIDGET (login_window->priv->user_chooser))) {
|
|
+ char *name;
|
|
+
|
|
+ name = gdm_task_get_name (GDM_TASK (conversation));
|
|
+ g_warning ("Task %s is trying to choose user before list is loaded", name);
|
|
+ g_free (name);
|
|
+ return;
|
|
+ }
|
|
+
|
|
if (gdm_task_list_set_active_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
GDM_TASK (conversation))) {
|
|
gdm_user_chooser_widget_set_chosen_user_name (GDM_USER_CHOOSER_WIDGET (login_window->priv->user_chooser),
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From ec0b4c65adb8fcf9c4f2b3a52fec039afde0fbaf Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Mon, 23 Feb 2009 13:27:29 -0500
|
|
Subject: [PATCH 45/65] Fix smartcard plugin to accept a PIN code.
|
|
|
|
---
|
|
.../plugins/smartcard/gdm-smartcard-extension.c | 24 ++++++++++++++++++++
|
|
1 files changed, 24 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c
|
|
index 40ecd08..621d1ab 100644
|
|
--- a/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c
|
|
+++ b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c
|
|
@@ -43,6 +43,7 @@ struct _GdmSmartcardExtensionPrivate
|
|
GIcon *icon;
|
|
GtkWidget *page;
|
|
GtkActionGroup *actions;
|
|
+ GtkAction *login_action;
|
|
|
|
GtkWidget *message_label;
|
|
GtkWidget *prompt_label;
|
|
@@ -167,6 +168,7 @@ gdm_smartcard_extension_ask_question (GdmConversation *conversation,
|
|
gtk_entry_set_text (GTK_ENTRY (extension->priv->prompt_entry), "");
|
|
gtk_entry_set_visibility (GTK_ENTRY (extension->priv->prompt_entry), TRUE);
|
|
gtk_widget_show (extension->priv->prompt_entry);
|
|
+ gtk_action_set_visible (extension->priv->login_action, TRUE);
|
|
gtk_widget_grab_focus (extension->priv->prompt_entry);
|
|
extension->priv->answer_pending = TRUE;
|
|
}
|
|
@@ -182,6 +184,7 @@ gdm_smartcard_extension_ask_secret (GdmConversation *conversation,
|
|
gtk_entry_set_text (GTK_ENTRY (extension->priv->prompt_entry), "");
|
|
gtk_widget_show (extension->priv->prompt_entry);
|
|
gtk_widget_grab_focus (extension->priv->prompt_entry);
|
|
+ gtk_action_set_visible (extension->priv->login_action, TRUE);
|
|
extension->priv->answer_pending = TRUE;
|
|
}
|
|
|
|
@@ -195,6 +198,7 @@ gdm_smartcard_extension_reset (GdmConversation *conversation)
|
|
gtk_widget_hide (extension->priv->prompt_entry);
|
|
gtk_entry_set_text (GTK_ENTRY (extension->priv->prompt_entry), "");
|
|
gtk_entry_set_visibility (GTK_ENTRY (extension->priv->prompt_entry), TRUE);
|
|
+ gtk_action_set_visible (extension->priv->login_action, FALSE);
|
|
extension->priv->answer_pending = FALSE;
|
|
|
|
gdm_task_set_enabled (GDM_TASK (conversation), FALSE);
|
|
@@ -251,6 +255,7 @@ gdm_smartcard_extension_request_answer (GdmConversation *conversation)
|
|
gtk_widget_hide (extension->priv->prompt_entry);
|
|
gtk_label_set_text (GTK_LABEL (extension->priv->prompt_label), "");
|
|
gtk_entry_set_text (GTK_ENTRY (extension->priv->prompt_entry), "");
|
|
+ gtk_action_set_visible (extension->priv->login_action, FALSE);
|
|
}
|
|
|
|
gboolean
|
|
@@ -375,11 +380,30 @@ create_page (GdmSmartcardExtension *extension)
|
|
}
|
|
|
|
static void
|
|
+on_activate_log_in (GdmSmartcardExtension *extension)
|
|
+{
|
|
+ gdm_smartcard_extension_request_answer (GDM_CONVERSATION (extension));
|
|
+}
|
|
+
|
|
+static void
|
|
create_actions (GdmSmartcardExtension *extension)
|
|
{
|
|
GtkAction *action;
|
|
|
|
extension->priv->actions = gtk_action_group_new ("gdm-smartcard-extension");
|
|
+
|
|
+ action = gtk_action_new (GDM_CONVERSATION_DEFAULT_ACTION,
|
|
+ _("Log In"),
|
|
+ _("Log into the currently selected sesson"),
|
|
+ NULL);
|
|
+ g_signal_connect_swapped (action, "activate",
|
|
+ G_CALLBACK (on_activate_log_in), extension);
|
|
+ g_object_set (G_OBJECT (action), "icon-name", "go-home", NULL);
|
|
+ gtk_action_group_add_action (extension->priv->actions,
|
|
+ action);
|
|
+
|
|
+ gtk_action_set_visible (action, FALSE);
|
|
+ extension->priv->login_action = action;
|
|
}
|
|
|
|
static void
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From ecdb7ca6d5a3942352617b1cfea4a89ae06d1ae3 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Mon, 23 Feb 2009 17:57:06 -0500
|
|
Subject: [PATCH 46/65] Add a new "choosable" property to show tasks in user list
|
|
|
|
Useful for Smartcard and some future "Guest" account plugin
|
|
---
|
|
gui/simple-greeter/gdm-greeter-login-window.c | 13 ++++++++++---
|
|
gui/simple-greeter/libgdmsimplegreeter/gdm-task.c | 6 ++++++
|
|
gui/simple-greeter/libgdmsimplegreeter/gdm-task.h | 2 ++
|
|
.../fingerprint/gdm-fingerprint-extension.c | 7 +++++++
|
|
.../plugins/password/gdm-password-extension.c | 7 +++++++
|
|
.../plugins/smartcard/gdm-smartcard-extension.c | 7 +++++++
|
|
6 files changed, 39 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-greeter-login-window.c b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
index 7739a7c..9f10cb3 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-login-window.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
@@ -2436,9 +2436,6 @@ gdm_greeter_login_window_add_extension (GdmGreeterLoginWindow *login_window,
|
|
g_debug ("GdmGreeterLoginWindow: new extension '%s - %s' added",
|
|
name, description);
|
|
|
|
- g_free (name);
|
|
- g_free (description);
|
|
-
|
|
if (gdm_task_list_get_number_of_tasks (GDM_TASK_LIST (login_window->priv->conversation_list)) == 0) {
|
|
gtk_widget_hide (login_window->priv->conversation_list);
|
|
} else {
|
|
@@ -2449,6 +2446,16 @@ gdm_greeter_login_window_add_extension (GdmGreeterLoginWindow *login_window,
|
|
GDM_TASK (extension));
|
|
|
|
service_name = gdm_conversation_get_service_name (GDM_CONVERSATION (extension));
|
|
+
|
|
+ if (gdm_task_is_choosable (GDM_TASK (extension))) {
|
|
+ gdm_chooser_widget_add_item (GDM_CHOOSER_WIDGET (login_window->priv->user_chooser),
|
|
+ service_name, NULL, name, description, ~0,
|
|
+ FALSE, TRUE);
|
|
+ }
|
|
+
|
|
+ g_free (name);
|
|
+ g_free (description);
|
|
+
|
|
g_debug ("GdmGreeterLoginWindow: starting conversation with '%s'", service_name);
|
|
g_signal_emit (login_window, signals[START_CONVERSATION], 0, service_name);
|
|
g_free (service_name);
|
|
diff --git a/gui/simple-greeter/libgdmsimplegreeter/gdm-task.c b/gui/simple-greeter/libgdmsimplegreeter/gdm-task.c
|
|
index f72fa78..05fd75c 100644
|
|
--- a/gui/simple-greeter/libgdmsimplegreeter/gdm-task.c
|
|
+++ b/gui/simple-greeter/libgdmsimplegreeter/gdm-task.c
|
|
@@ -88,6 +88,12 @@ gdm_task_is_enabled (GdmTask *task)
|
|
return !g_object_get_data (G_OBJECT (task), "gdm-task-is-disabled");
|
|
}
|
|
|
|
+gboolean
|
|
+gdm_task_is_choosable (GdmTask *task)
|
|
+{
|
|
+ return GDM_TASK_GET_IFACE (task)->is_choosable (task);
|
|
+}
|
|
+
|
|
static void
|
|
gdm_task_class_init (gpointer g_iface)
|
|
{
|
|
diff --git a/gui/simple-greeter/libgdmsimplegreeter/gdm-task.h b/gui/simple-greeter/libgdmsimplegreeter/gdm-task.h
|
|
index 9894e65..c75bf29 100644
|
|
--- a/gui/simple-greeter/libgdmsimplegreeter/gdm-task.h
|
|
+++ b/gui/simple-greeter/libgdmsimplegreeter/gdm-task.h
|
|
@@ -44,6 +44,7 @@ struct _GdmTaskIface
|
|
GIcon * (* get_icon) (GdmTask *task);
|
|
char * (* get_description) (GdmTask *task);
|
|
char * (* get_name) (GdmTask *task);
|
|
+ gboolean (* is_choosable) (GdmTask *task);
|
|
/* signals */
|
|
void (* enabled) (GdmTask *task);
|
|
void (* disabled) (GdmTask *task);
|
|
@@ -57,6 +58,7 @@ char *gdm_task_get_name (GdmTask *task);
|
|
void gdm_task_set_enabled (GdmTask *task,
|
|
gboolean should_enable);
|
|
gboolean gdm_task_is_enabled (GdmTask *task);
|
|
+gboolean gdm_task_is_choosable (GdmTask *task);
|
|
G_END_DECLS
|
|
|
|
#endif /* __GDM_TASK_H */
|
|
diff --git a/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.c b/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.c
|
|
index 7f5eb1c..7c74ecf 100644
|
|
--- a/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.c
|
|
+++ b/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.c
|
|
@@ -188,12 +188,19 @@ gdm_fingerprint_extension_get_description (GdmTask *task)
|
|
return g_strdup (_("Log into session with fingerprint"));
|
|
}
|
|
|
|
+gboolean
|
|
+gdm_fingerprint_extension_is_choosable (GdmTask *task)
|
|
+{
|
|
+ return FALSE;
|
|
+}
|
|
+
|
|
static void
|
|
gdm_task_iface_init (GdmTaskIface *iface)
|
|
{
|
|
iface->get_icon = gdm_fingerprint_extension_get_icon;
|
|
iface->get_description = gdm_fingerprint_extension_get_description;
|
|
iface->get_name = gdm_fingerprint_extension_get_name;
|
|
+ iface->is_choosable = gdm_fingerprint_extension_is_choosable;
|
|
}
|
|
|
|
static void
|
|
diff --git a/gui/simple-greeter/plugins/password/gdm-password-extension.c b/gui/simple-greeter/plugins/password/gdm-password-extension.c
|
|
index fae73be..e6c608a 100644
|
|
--- a/gui/simple-greeter/plugins/password/gdm-password-extension.c
|
|
+++ b/gui/simple-greeter/plugins/password/gdm-password-extension.c
|
|
@@ -188,12 +188,19 @@ gdm_password_extension_get_description (GdmTask *task)
|
|
return g_strdup (_("Log into session with username and password"));
|
|
}
|
|
|
|
+gboolean
|
|
+gdm_password_extension_is_choosable (GdmTask *task)
|
|
+{
|
|
+ return FALSE;
|
|
+}
|
|
+
|
|
static void
|
|
gdm_task_iface_init (GdmTaskIface *iface)
|
|
{
|
|
iface->get_icon = gdm_password_extension_get_icon;
|
|
iface->get_description = gdm_password_extension_get_description;
|
|
iface->get_name = gdm_password_extension_get_name;
|
|
+ iface->is_choosable = gdm_password_extension_is_choosable;
|
|
}
|
|
|
|
static void
|
|
diff --git a/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c
|
|
index 621d1ab..f09b4e4 100644
|
|
--- a/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c
|
|
+++ b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c
|
|
@@ -290,12 +290,19 @@ gdm_smartcard_extension_get_description (GdmTask *task)
|
|
return g_strdup (_("Log into session with smartcard"));
|
|
}
|
|
|
|
+gboolean
|
|
+gdm_smartcard_extension_is_choosable (GdmTask *task)
|
|
+{
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
static void
|
|
gdm_task_iface_init (GdmTaskIface *iface)
|
|
{
|
|
iface->get_icon = gdm_smartcard_extension_get_icon;
|
|
iface->get_description = gdm_smartcard_extension_get_description;
|
|
iface->get_name = gdm_smartcard_extension_get_name;
|
|
+ iface->is_choosable = gdm_smartcard_extension_is_choosable;
|
|
}
|
|
|
|
static void
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From e25c0b355484745edf2f21f823bd78eb27570e0d Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Tue, 24 Feb 2009 15:12:35 -0500
|
|
Subject: [PATCH 47/65] Separate handling of non-users in user list from users
|
|
|
|
Now get_chosen_user returns NULL if the activated item
|
|
wasn't a user. We also separate the handling of on item
|
|
activation in two functions depending on the item type.
|
|
|
|
This will be useful for adding custom handling for plugin
|
|
added items.
|
|
---
|
|
gui/simple-greeter/gdm-greeter-login-window.c | 47 ++++++++++++--------
|
|
gui/simple-greeter/gdm-user-chooser-widget.c | 19 ++++++++-
|
|
.../fingerprint/gdm-fingerprint-extension.c | 2 -
|
|
3 files changed, 47 insertions(+), 21 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-greeter-login-window.c b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
index 9f10cb3..f46ec78 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-login-window.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
@@ -1596,29 +1596,46 @@ begin_task_verification_for_selected_user (GdmTaskList *task_list,
|
|
}
|
|
|
|
static void
|
|
-on_user_chosen (GdmUserChooserWidget *user_chooser,
|
|
- GdmGreeterLoginWindow *login_window)
|
|
+on_user_chosen (GdmGreeterLoginWindow *login_window,
|
|
+ const char *user_name)
|
|
{
|
|
- char *user_name;
|
|
+ g_debug ("GdmGreeterLoginWindow: user chosen '%s'", user_name);
|
|
+
|
|
+ g_signal_emit (G_OBJECT (login_window), signals[USER_SELECTED],
|
|
+ 0, user_name);
|
|
+
|
|
+ gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
+ (GdmTaskListForeachFunc)
|
|
+ begin_task_verification_for_selected_user,
|
|
+ login_window);
|
|
+
|
|
+ switch_mode (login_window, MODE_AUTHENTICATION);
|
|
+}
|
|
+
|
|
+static void
|
|
+on_user_chooser_activated (GdmUserChooserWidget *user_chooser,
|
|
+ GdmGreeterLoginWindow *login_window)
|
|
+{
|
|
+ char *item_id;
|
|
|
|
user_name = gdm_user_chooser_widget_get_chosen_user_name (GDM_USER_CHOOSER_WIDGET (login_window->priv->user_chooser));
|
|
g_debug ("GdmGreeterLoginWindow: user chosen '%s'", user_name);
|
|
|
|
- if (user_name == NULL) {
|
|
+ if (user_name != NULL) {
|
|
+ on_user_chosen (login_window, user_name);
|
|
+ g_free (user_name);
|
|
return;
|
|
}
|
|
|
|
- g_signal_emit (G_OBJECT (login_window), signals[USER_SELECTED],
|
|
- 0, user_name);
|
|
+ item_id = gdm_chooser_widget_get_active_item (GDM_CHOOSER_WIDGET (user_chooser));
|
|
|
|
- if (strcmp (user_name, GDM_USER_CHOOSER_USER_OTHER) == 0) {
|
|
+ if (strcmp (item_id, GDM_USER_CHOOSER_USER_OTHER) == 0) {
|
|
gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
(GdmTaskListForeachFunc)
|
|
begin_task_verification,
|
|
login_window);
|
|
- } else if (strcmp (user_name, GDM_USER_CHOOSER_USER_GUEST) == 0) {
|
|
- /* FIXME: handle guest account stuff */
|
|
- } else if (strcmp (user_name, GDM_USER_CHOOSER_USER_AUTO) == 0) {
|
|
+ g_free (item_id);
|
|
+ } else if (strcmp (item_id, GDM_USER_CHOOSER_USER_AUTO) == 0) {
|
|
g_signal_emit (login_window, signals[BEGIN_AUTO_LOGIN], 0,
|
|
login_window->priv->timed_login_username);
|
|
|
|
@@ -1628,16 +1645,10 @@ on_user_chosen (GdmUserChooserWidget *user_chooser,
|
|
/* just wait for the user to select language and stuff */
|
|
set_log_in_button_mode (login_window, LOGIN_BUTTON_TIMED_LOGIN);
|
|
set_message (login_window, _("Select language and click Log In"));
|
|
- } else {
|
|
- gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
- (GdmTaskListForeachFunc)
|
|
- begin_task_verification_for_selected_user,
|
|
- login_window);
|
|
+ g_free (item_id);
|
|
}
|
|
|
|
switch_mode (login_window, MODE_AUTHENTICATION);
|
|
-
|
|
- g_free (user_name);
|
|
}
|
|
|
|
static void
|
|
@@ -1926,7 +1937,7 @@ load_theme (GdmGreeterLoginWindow *login_window)
|
|
login_window);
|
|
g_signal_connect (login_window->priv->user_chooser,
|
|
"activated",
|
|
- G_CALLBACK (on_user_chosen),
|
|
+ G_CALLBACK (on_user_chooser_activated),
|
|
login_window);
|
|
g_signal_connect (login_window->priv->user_chooser,
|
|
"deactivated",
|
|
diff --git a/gui/simple-greeter/gdm-user-chooser-widget.c b/gui/simple-greeter/gdm-user-chooser-widget.c
|
|
index 08420b8..e569b7b 100644
|
|
--- a/gui/simple-greeter/gdm-user-chooser-widget.c
|
|
+++ b/gui/simple-greeter/gdm-user-chooser-widget.c
|
|
@@ -233,9 +233,26 @@ gdm_user_chooser_widget_set_show_user_auto (GdmUserChooserWidget *widget,
|
|
char *
|
|
gdm_user_chooser_widget_get_chosen_user_name (GdmUserChooserWidget *widget)
|
|
{
|
|
+ char *active_item_id;
|
|
+ gboolean isnt_user;
|
|
+
|
|
g_return_val_if_fail (GDM_IS_USER_CHOOSER_WIDGET (widget), NULL);
|
|
+ active_item_id = gdm_chooser_widget_get_active_item (GDM_CHOOSER_WIDGET (widget));
|
|
+
|
|
+ if (active_item_id == NULL) {
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ gdm_chooser_widget_lookup_item (GDM_CHOOSER_WIDGET (widget), active_item_id,
|
|
+ NULL, NULL, NULL, NULL, NULL,
|
|
+ &isnt_user);
|
|
+
|
|
+ if (isnt_user) {
|
|
+ g_free (active_item_id);
|
|
+ return NULL;
|
|
+ }
|
|
|
|
- return gdm_chooser_widget_get_active_item (GDM_CHOOSER_WIDGET (widget));
|
|
+ return active_item_id;
|
|
}
|
|
|
|
void
|
|
diff --git a/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.c b/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.c
|
|
index 7c74ecf..63f6ef3 100644
|
|
--- a/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.c
|
|
+++ b/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.c
|
|
@@ -287,8 +287,6 @@ create_page (GdmFingerprintExtension *extension)
|
|
static void
|
|
create_actions (GdmFingerprintExtension *extension)
|
|
{
|
|
- GtkAction *action;
|
|
-
|
|
extension->priv->actions = gtk_action_group_new ("gdm-fingerprint-extension");
|
|
}
|
|
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From bd66c8fb770fff47761521509e78f7a320a96957 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Tue, 24 Feb 2009 16:54:34 -0500
|
|
Subject: [PATCH 48/65] Fix compile warning
|
|
|
|
---
|
|
daemon/gdm-greeter-server.c | 1 +
|
|
1 files changed, 1 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/daemon/gdm-greeter-server.c b/daemon/gdm-greeter-server.c
|
|
index 5bf1f8a..ecb2ad6 100644
|
|
--- a/daemon/gdm-greeter-server.c
|
|
+++ b/daemon/gdm-greeter-server.c
|
|
@@ -304,6 +304,7 @@ gdm_greeter_server_conversation_stopped (GdmGreeterServer *greeter_server,
|
|
const char *service_name)
|
|
{
|
|
send_dbus_string_signal (greeter_server, "ConversationStopped", service_name);
|
|
+ return TRUE;
|
|
}
|
|
|
|
void
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 06d075066911d897c2577628ec1049519e608796 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Wed, 25 Feb 2009 10:56:43 -0500
|
|
Subject: [PATCH 49/65] Add some casts to fix compile warnings
|
|
|
|
---
|
|
gui/simple-greeter/gdm-user-chooser-widget.c | 6 +++---
|
|
1 files changed, 3 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-user-chooser-widget.c b/gui/simple-greeter/gdm-user-chooser-widget.c
|
|
index e569b7b..f8d5109 100644
|
|
--- a/gui/simple-greeter/gdm-user-chooser-widget.c
|
|
+++ b/gui/simple-greeter/gdm-user-chooser-widget.c
|
|
@@ -357,7 +357,7 @@ add_user (GdmUserChooserWidget *widget,
|
|
return;
|
|
}
|
|
|
|
- size = get_icon_height_for_widget (widget);
|
|
+ size = get_icon_height_for_widget (GTK_WIDGET (widget));
|
|
pixbuf = gdm_user_render_icon (user, size);
|
|
if (pixbuf == NULL && widget->priv->stock_person_pixbuf != NULL) {
|
|
pixbuf = g_object_ref (widget->priv->stock_person_pixbuf);
|
|
@@ -597,7 +597,7 @@ get_stock_person_pixbuf (GdmUserChooserWidget *widget)
|
|
GdkPixbuf *pixbuf;
|
|
int size;
|
|
|
|
- size = get_icon_height_for_widget (widget);
|
|
+ size = get_icon_height_for_widget (GTK_WIDGET (widget));
|
|
|
|
pixbuf = gtk_icon_theme_load_icon (widget->priv->icon_theme,
|
|
DEFAULT_USER_ICON,
|
|
@@ -614,7 +614,7 @@ get_logged_in_pixbuf (GdmUserChooserWidget *widget)
|
|
GdkPixbuf *pixbuf;
|
|
int size;
|
|
|
|
- size = get_icon_height_for_widget (widget);
|
|
+ size = get_icon_height_for_widget (GTK_WIDGET (widget));
|
|
|
|
pixbuf = gtk_icon_theme_load_icon (widget->priv->icon_theme,
|
|
"emblem-default",
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 36cbbb0bcda778c0da65980a38193d77de65057f Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Fri, 27 Feb 2009 15:34:04 -0500
|
|
Subject: [PATCH 50/65] Add newline on debug messages in sc helper
|
|
|
|
---
|
|
.../plugins/smartcard/gdm-smartcard-worker.c | 2 +-
|
|
1 files changed, 1 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/plugins/smartcard/gdm-smartcard-worker.c b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-worker.c
|
|
index 7fe4cf4..75e4f33 100644
|
|
--- a/gui/simple-greeter/plugins/smartcard/gdm-smartcard-worker.c
|
|
+++ b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-worker.c
|
|
@@ -124,7 +124,7 @@ on_debug_message (const char *log_domain,
|
|
const char *message,
|
|
gpointer user_data)
|
|
{
|
|
- g_printerr ("*** DEBUG: %s", message);
|
|
+ g_printerr ("*** DEBUG: %s\n", message);
|
|
}
|
|
|
|
int
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 86ab5470d491c686d1ad50acea58f3504bf3f981 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Fri, 27 Feb 2009 15:43:00 -0500
|
|
Subject: [PATCH 51/65] Make password auth strictly password based
|
|
|
|
---
|
|
gui/simple-greeter/plugins/password/gdm-password | 2 +-
|
|
1 files changed, 1 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/plugins/password/gdm-password b/gui/simple-greeter/plugins/password/gdm-password
|
|
index d17f7b1..5d4fb3a 100644
|
|
--- a/gui/simple-greeter/plugins/password/gdm-password
|
|
+++ b/gui/simple-greeter/plugins/password/gdm-password
|
|
@@ -1,6 +1,6 @@
|
|
#%PAM-1.0
|
|
auth required pam_env.so
|
|
-auth substack system-auth
|
|
+auth required pam_unix.so
|
|
auth optional pam_gnome_keyring.so
|
|
account required pam_nologin.so
|
|
account include system-auth
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 58199fdcb04deddb0438558326e86954fe81c056 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Fri, 27 Feb 2009 15:44:13 -0500
|
|
Subject: [PATCH 52/65] Initiate smart card auth when clicking on it in list
|
|
|
|
---
|
|
gui/simple-greeter/gdm-greeter-login-window.c | 21 ++++++++++++++++++++
|
|
.../plugins/smartcard/gdm-smartcard-extension.c | 2 +-
|
|
2 files changed, 22 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-greeter-login-window.c b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
index f46ec78..fcb5267 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-login-window.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
@@ -807,6 +807,7 @@ reset_dialog (GdmGreeterLoginWindow *login_window)
|
|
set_message (login_window, "");
|
|
switch_mode (login_window, MODE_SELECTION);
|
|
|
|
+ gtk_widget_set_sensitive (login_window->priv->conversation_list, TRUE);
|
|
set_sensitive (login_window, TRUE);
|
|
set_ready (login_window);
|
|
set_focus (GDM_GREETER_LOGIN_WINDOW (login_window));
|
|
@@ -1616,6 +1617,7 @@ static void
|
|
on_user_chooser_activated (GdmUserChooserWidget *user_chooser,
|
|
GdmGreeterLoginWindow *login_window)
|
|
{
|
|
+ char *user_name;
|
|
char *item_id;
|
|
|
|
user_name = gdm_user_chooser_widget_get_chosen_user_name (GDM_USER_CHOOSER_WIDGET (login_window->priv->user_chooser));
|
|
@@ -1646,6 +1648,25 @@ on_user_chooser_activated (GdmUserChooserWidget *user_chooser,
|
|
set_log_in_button_mode (login_window, LOGIN_BUTTON_TIMED_LOGIN);
|
|
set_message (login_window, _("Select language and click Log In"));
|
|
g_free (item_id);
|
|
+ } else {
|
|
+ GdmTask *task;
|
|
+
|
|
+ task = gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
+ (GdmTaskListForeachFunc)
|
|
+ task_has_service_name,
|
|
+ (gpointer) item_id);
|
|
+
|
|
+ if (task == NULL) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ /* FIXME: we should probably give the plugin more say for
|
|
+ * what happens here.
|
|
+ */
|
|
+ g_signal_emit (login_window, signals[BEGIN_VERIFICATION], 0, item_id);
|
|
+ g_free (item_id);
|
|
+
|
|
+ gtk_widget_set_sensitive (login_window->priv->conversation_list, FALSE);
|
|
}
|
|
|
|
switch_mode (login_window, MODE_AUTHENTICATION);
|
|
diff --git a/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c
|
|
index f09b4e4..8e87db6 100644
|
|
--- a/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c
|
|
+++ b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c
|
|
@@ -103,7 +103,7 @@ on_smartcard_event (GIOChannel *io_channel,
|
|
|
|
if (extension->priv->number_of_tokens == 1) {
|
|
gdm_conversation_choose_user (GDM_CONVERSATION (extension),
|
|
- GDM_CONVERSATION_OTHER_USER);
|
|
+ PAMSERVICENAME);
|
|
} else if (extension->priv->number_of_tokens == 0) {
|
|
gdm_conversation_cancel (GDM_CONVERSATION (extension));
|
|
}
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From a0142a0ae53b5931ba219d5c47c2a547967522dc Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Mon, 2 Mar 2009 09:37:26 -0500
|
|
Subject: [PATCH 53/65] Add some debug spew
|
|
|
|
---
|
|
gui/simple-greeter/gdm-greeter-login-window.c | 9 ++++++++-
|
|
1 files changed, 8 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-greeter-login-window.c b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
index fcb5267..b0c3ae1 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-login-window.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
@@ -1621,23 +1621,26 @@ on_user_chooser_activated (GdmUserChooserWidget *user_chooser,
|
|
char *item_id;
|
|
|
|
user_name = gdm_user_chooser_widget_get_chosen_user_name (GDM_USER_CHOOSER_WIDGET (login_window->priv->user_chooser));
|
|
- g_debug ("GdmGreeterLoginWindow: user chosen '%s'", user_name);
|
|
|
|
if (user_name != NULL) {
|
|
+ g_debug ("GdmGreeterLoginWindow: user chosen '%s'", user_name);
|
|
on_user_chosen (login_window, user_name);
|
|
g_free (user_name);
|
|
return;
|
|
}
|
|
|
|
item_id = gdm_chooser_widget_get_active_item (GDM_CHOOSER_WIDGET (user_chooser));
|
|
+ g_debug ("GdmGreeterLoginWindow: item chosen '%s'", item_id);
|
|
|
|
if (strcmp (item_id, GDM_USER_CHOOSER_USER_OTHER) == 0) {
|
|
+ g_debug ("GdmGreeterLoginWindow: Starting all auth conversations");
|
|
gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
(GdmTaskListForeachFunc)
|
|
begin_task_verification,
|
|
login_window);
|
|
g_free (item_id);
|
|
} else if (strcmp (item_id, GDM_USER_CHOOSER_USER_AUTO) == 0) {
|
|
+ g_debug ("GdmGreeterLoginWindow: Starting auto login");
|
|
g_signal_emit (login_window, signals[BEGIN_AUTO_LOGIN], 0,
|
|
login_window->priv->timed_login_username);
|
|
|
|
@@ -1657,8 +1660,11 @@ on_user_chooser_activated (GdmUserChooserWidget *user_chooser,
|
|
(gpointer) item_id);
|
|
|
|
if (task == NULL) {
|
|
+ g_debug ("GdmGreeterLoginWindow: %s has no task associated with it", item_id);
|
|
+ g_free (item_id);
|
|
return;
|
|
}
|
|
+ g_debug ("GdmGreeterLoginWindow: Beginning auth conversation for item %s", item_id);
|
|
|
|
/* FIXME: we should probably give the plugin more say for
|
|
* what happens here.
|
|
@@ -1669,6 +1675,7 @@ on_user_chooser_activated (GdmUserChooserWidget *user_chooser,
|
|
gtk_widget_set_sensitive (login_window->priv->conversation_list, FALSE);
|
|
}
|
|
|
|
+ g_debug ("GdmGreeterLoginWindow: Switching to shrunken authentication mode");
|
|
switch_mode (login_window, MODE_AUTHENTICATION);
|
|
}
|
|
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 99a6c0de0e439b29cb4e2f19ecd9a0b059d83906 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Mon, 2 Mar 2009 10:07:03 -0500
|
|
Subject: [PATCH 54/65] Work around g_warning
|
|
|
|
---
|
|
gui/simple-greeter/gdm-chooser-widget.c | 31 ++++++++++++++++++++++++-------
|
|
1 files changed, 24 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-chooser-widget.c b/gui/simple-greeter/gdm-chooser-widget.c
|
|
index e5ddf78..a7dbba5 100644
|
|
--- a/gui/simple-greeter/gdm-chooser-widget.c
|
|
+++ b/gui/simple-greeter/gdm-chooser-widget.c
|
|
@@ -2133,13 +2133,30 @@ gdm_chooser_widget_lookup_item (GdmChooserWidget *widget,
|
|
}
|
|
g_free (active_item_id);
|
|
|
|
- gtk_tree_model_get (GTK_TREE_MODEL (widget->priv->list_store), &iter,
|
|
- CHOOSER_IMAGE_COLUMN, image,
|
|
- CHOOSER_NAME_COLUMN, name,
|
|
- CHOOSER_PRIORITY_COLUMN, priority,
|
|
- CHOOSER_ITEM_IS_IN_USE_COLUMN, is_in_use,
|
|
- CHOOSER_ITEM_IS_SEPARATED_COLUMN, is_separate,
|
|
- -1);
|
|
+ if (image != NULL) {
|
|
+ gtk_tree_model_get (GTK_TREE_MODEL (widget->priv->list_store), &iter,
|
|
+ CHOOSER_IMAGE_COLUMN, image, -1);
|
|
+ }
|
|
+
|
|
+ if (name != NULL) {
|
|
+ gtk_tree_model_get (GTK_TREE_MODEL (widget->priv->list_store), &iter,
|
|
+ CHOOSER_NAME_COLUMN, name, -1);
|
|
+ }
|
|
+
|
|
+ if (priority != NULL) {
|
|
+ gtk_tree_model_get (GTK_TREE_MODEL (widget->priv->list_store), &iter,
|
|
+ CHOOSER_PRIORITY_COLUMN, priority, -1);
|
|
+ }
|
|
+
|
|
+ if (is_in_use != NULL) {
|
|
+ gtk_tree_model_get (GTK_TREE_MODEL (widget->priv->list_store), &iter,
|
|
+ CHOOSER_ITEM_IS_IN_USE_COLUMN, is_in_use, -1);
|
|
+ }
|
|
+
|
|
+ if (is_separate != NULL) {
|
|
+ gtk_tree_model_get (GTK_TREE_MODEL (widget->priv->list_store), &iter,
|
|
+ CHOOSER_ITEM_IS_SEPARATED_COLUMN, is_separate, -1);
|
|
+ }
|
|
|
|
return TRUE;
|
|
}
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 80c19c24a14976ad2b574ea7c504ddf359bacb0e Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Mon, 2 Mar 2009 11:09:27 -0500
|
|
Subject: [PATCH 55/65] add debug spew
|
|
|
|
---
|
|
gui/simple-greeter/gdm-user-chooser-widget.c | 6 +++++-
|
|
1 files changed, 5 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-user-chooser-widget.c b/gui/simple-greeter/gdm-user-chooser-widget.c
|
|
index f8d5109..bc83f39 100644
|
|
--- a/gui/simple-greeter/gdm-user-chooser-widget.c
|
|
+++ b/gui/simple-greeter/gdm-user-chooser-widget.c
|
|
@@ -237,9 +237,10 @@ gdm_user_chooser_widget_get_chosen_user_name (GdmUserChooserWidget *widget)
|
|
gboolean isnt_user;
|
|
|
|
g_return_val_if_fail (GDM_IS_USER_CHOOSER_WIDGET (widget), NULL);
|
|
- active_item_id = gdm_chooser_widget_get_active_item (GDM_CHOOSER_WIDGET (widget));
|
|
|
|
+ active_item_id = gdm_chooser_widget_get_active_item (GDM_CHOOSER_WIDGET (widget));
|
|
if (active_item_id == NULL) {
|
|
+ g_debug ("GdmUserChooserWidget: no active item in list");
|
|
return NULL;
|
|
}
|
|
|
|
@@ -248,10 +249,13 @@ gdm_user_chooser_widget_get_chosen_user_name (GdmUserChooserWidget *widget)
|
|
&isnt_user);
|
|
|
|
if (isnt_user) {
|
|
+ g_debug ("GdmUserChooserWidget: active item '%s' isn't a user", active_item_id);
|
|
g_free (active_item_id);
|
|
return NULL;
|
|
}
|
|
|
|
+ g_debug ("GdmUserChooserWidget: active item '%s' is a user", active_item_id);
|
|
+
|
|
return active_item_id;
|
|
}
|
|
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 46ce0e98d3e9c27bad63c15374e54eafe7b87151 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Mon, 2 Mar 2009 11:10:28 -0500
|
|
Subject: [PATCH 56/65] Only show task list if user is selected
|
|
|
|
---
|
|
gui/simple-greeter/gdm-greeter-login-window.c | 49 ++++++++++++++++---------
|
|
gui/simple-greeter/gdm-task-list.c | 11 +++++-
|
|
2 files changed, 41 insertions(+), 19 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-greeter-login-window.c b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
index b0c3ae1..a81cd09 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-login-window.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
@@ -105,7 +105,8 @@
|
|
|
|
enum {
|
|
MODE_SELECTION = 0,
|
|
- MODE_AUTHENTICATION
|
|
+ MODE_SINGLE_AUTHENTICATION,
|
|
+ MODE_MULTIPLE_AUTHENTICATION,
|
|
};
|
|
|
|
enum {
|
|
@@ -586,7 +587,8 @@ sensitize_power_buttons_timeout (GdmGreeterLoginWindow *login_window)
|
|
sensitize_widget (login_window, "suspend-button", TRUE);
|
|
sensitize_widget (login_window, "disconnect-button", TRUE);
|
|
break;
|
|
- case MODE_AUTHENTICATION:
|
|
+ case MODE_SINGLE_AUTHENTICATION:
|
|
+ case MODE_MULTIPLE_AUTHENTICATION:
|
|
break;
|
|
default:
|
|
g_assert_not_reached ();
|
|
@@ -614,6 +616,7 @@ switch_mode (GdmGreeterLoginWindow *login_window,
|
|
GtkWidget *box;
|
|
gboolean show_restart_buttons;
|
|
gboolean show_suspend_button;
|
|
+ int number_of_tasks;
|
|
|
|
show_restart_buttons = get_show_restart_buttons (login_window);
|
|
show_suspend_button = can_suspend (login_window);
|
|
@@ -644,6 +647,8 @@ switch_mode (GdmGreeterLoginWindow *login_window,
|
|
! login_window->priv->display_is_local);
|
|
|
|
show_widget (login_window, "auth-page-box", FALSE);
|
|
+ show_widget (login_window, "conversation-list", FALSE);
|
|
+ gtk_widget_set_sensitive (login_window->priv->conversation_list, TRUE);
|
|
|
|
add_sensitize_power_buttons_timeout (login_window);
|
|
sensitize_widget (login_window, "shutdown-button", FALSE);
|
|
@@ -653,7 +658,8 @@ switch_mode (GdmGreeterLoginWindow *login_window,
|
|
|
|
default_name = NULL;
|
|
break;
|
|
- case MODE_AUTHENTICATION:
|
|
+ case MODE_SINGLE_AUTHENTICATION:
|
|
+ case MODE_MULTIPLE_AUTHENTICATION:
|
|
gtk_widget_set_size_request (GTK_WIDGET (login_window),
|
|
GTK_WIDGET (login_window)->allocation.width,
|
|
-1);
|
|
@@ -663,6 +669,18 @@ switch_mode (GdmGreeterLoginWindow *login_window,
|
|
show_widget (login_window, "suspend-button", FALSE);
|
|
show_widget (login_window, "disconnect-button", FALSE);
|
|
show_widget (login_window, "auth-page-box", TRUE);
|
|
+
|
|
+ number_of_tasks = gdm_task_list_get_number_of_tasks (GDM_TASK_LIST (login_window->priv->conversation_list));
|
|
+ show_widget (login_window, "conversation-list", number_of_tasks > 1);
|
|
+
|
|
+ if (number == MODE_SINGLE_AUTHENTICATION) {
|
|
+ g_debug ("GdmGreeterLoginWindow: Single authentication, 1 task");
|
|
+ gtk_widget_set_sensitive (login_window->priv->conversation_list, FALSE);
|
|
+ } else {
|
|
+ g_debug ("GdmGreeterLoginWindow: Multiple authentication, %d tasks", number_of_tasks);
|
|
+ gtk_widget_set_sensitive (login_window->priv->conversation_list, TRUE);
|
|
+ }
|
|
+
|
|
default_name = "log-in-button";
|
|
break;
|
|
default:
|
|
@@ -1610,7 +1628,7 @@ on_user_chosen (GdmGreeterLoginWindow *login_window,
|
|
begin_task_verification_for_selected_user,
|
|
login_window);
|
|
|
|
- switch_mode (login_window, MODE_AUTHENTICATION);
|
|
+ switch_mode (login_window, MODE_MULTIPLE_AUTHENTICATION);
|
|
}
|
|
|
|
static void
|
|
@@ -1639,6 +1657,8 @@ on_user_chooser_activated (GdmUserChooserWidget *user_chooser,
|
|
begin_task_verification,
|
|
login_window);
|
|
g_free (item_id);
|
|
+
|
|
+ switch_mode (login_window, MODE_MULTIPLE_AUTHENTICATION);
|
|
} else if (strcmp (item_id, GDM_USER_CHOOSER_USER_AUTO) == 0) {
|
|
g_debug ("GdmGreeterLoginWindow: Starting auto login");
|
|
g_signal_emit (login_window, signals[BEGIN_AUTO_LOGIN], 0,
|
|
@@ -1651,6 +1671,8 @@ on_user_chooser_activated (GdmUserChooserWidget *user_chooser,
|
|
set_log_in_button_mode (login_window, LOGIN_BUTTON_TIMED_LOGIN);
|
|
set_message (login_window, _("Select language and click Log In"));
|
|
g_free (item_id);
|
|
+
|
|
+ switch_mode (login_window, MODE_SINGLE_AUTHENTICATION);
|
|
} else {
|
|
GdmTask *task;
|
|
|
|
@@ -1665,18 +1687,17 @@ on_user_chooser_activated (GdmUserChooserWidget *user_chooser,
|
|
return;
|
|
}
|
|
g_debug ("GdmGreeterLoginWindow: Beginning auth conversation for item %s", item_id);
|
|
-
|
|
/* FIXME: we should probably give the plugin more say for
|
|
* what happens here.
|
|
*/
|
|
g_signal_emit (login_window, signals[BEGIN_VERIFICATION], 0, item_id);
|
|
g_free (item_id);
|
|
|
|
- gtk_widget_set_sensitive (login_window->priv->conversation_list, FALSE);
|
|
- }
|
|
+ switch_mode (login_window, MODE_SINGLE_AUTHENTICATION);
|
|
+ gdm_task_list_set_active_task (GDM_TASK_LIST (login_window->priv->conversation_list), task);
|
|
|
|
- g_debug ("GdmGreeterLoginWindow: Switching to shrunken authentication mode");
|
|
- switch_mode (login_window, MODE_AUTHENTICATION);
|
|
+ g_object_unref (task);
|
|
+ }
|
|
}
|
|
|
|
static void
|
|
@@ -1984,7 +2005,6 @@ load_theme (GdmGreeterLoginWindow *login_window)
|
|
"deactivated",
|
|
G_CALLBACK (on_task_deactivated),
|
|
login_window);
|
|
- gtk_widget_show (login_window->priv->conversation_list);
|
|
|
|
login_window->priv->auth_banner_label = glade_xml_get_widget (login_window->priv->xml, "auth-banner-label");
|
|
/*make_label_small_italic (login_window->priv->auth_banner_label);*/
|
|
@@ -2023,7 +2043,8 @@ gdm_greeter_login_window_key_press_event (GtkWidget *widget,
|
|
login_window = GDM_GREETER_LOGIN_WINDOW (widget);
|
|
|
|
if (event->keyval == GDK_Escape) {
|
|
- if (login_window->priv->dialog_mode == MODE_AUTHENTICATION) {
|
|
+ if (login_window->priv->dialog_mode == MODE_SINGLE_AUTHENTICATION ||
|
|
+ login_window->priv->dialog_mode == MODE_MULTIPLE_AUTHENTICATION) {
|
|
do_cancel (GDM_GREETER_LOGIN_WINDOW (widget));
|
|
}
|
|
}
|
|
@@ -2475,12 +2496,6 @@ gdm_greeter_login_window_add_extension (GdmGreeterLoginWindow *login_window,
|
|
g_debug ("GdmGreeterLoginWindow: new extension '%s - %s' added",
|
|
name, description);
|
|
|
|
- if (gdm_task_list_get_number_of_tasks (GDM_TASK_LIST (login_window->priv->conversation_list)) == 0) {
|
|
- gtk_widget_hide (login_window->priv->conversation_list);
|
|
- } else {
|
|
- gtk_widget_show (login_window->priv->conversation_list);
|
|
- }
|
|
-
|
|
gdm_task_list_add_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
GDM_TASK (extension));
|
|
|
|
diff --git a/gui/simple-greeter/gdm-task-list.c b/gui/simple-greeter/gdm-task-list.c
|
|
index 25831a6..162b784 100644
|
|
--- a/gui/simple-greeter/gdm-task-list.c
|
|
+++ b/gui/simple-greeter/gdm-task-list.c
|
|
@@ -302,17 +302,24 @@ gdm_task_list_set_active_task (GdmTaskList *widget,
|
|
GdmTask *task)
|
|
{
|
|
GtkWidget *button;
|
|
+ gboolean was_sensitive;
|
|
+ gboolean was_activated;
|
|
+
|
|
+ was_sensitive = GTK_WIDGET_SENSITIVE (widget);
|
|
+ gtk_widget_set_sensitive (GTK_WIDGET (widget), TRUE);
|
|
|
|
button = GTK_WIDGET (g_object_get_data (G_OBJECT (task),
|
|
"gdm-task-list-button"));
|
|
|
|
+ was_activated = FALSE;
|
|
if (GTK_WIDGET_IS_SENSITIVE (button)) {
|
|
if (gtk_widget_activate (button)) {
|
|
- return TRUE;
|
|
+ was_activated = TRUE;
|
|
}
|
|
}
|
|
|
|
- return FALSE;
|
|
+ gtk_widget_set_sensitive (GTK_WIDGET (widget), was_sensitive);
|
|
+ return was_activated;
|
|
}
|
|
|
|
int
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 69e56ff36056bb0a58e5af91c2ab3c9c79110f6b Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Mon, 2 Mar 2009 13:30:03 -0500
|
|
Subject: [PATCH 57/65] Add debug statement
|
|
|
|
---
|
|
gui/simple-greeter/gdm-greeter-login-window.c | 2 ++
|
|
1 files changed, 2 insertions(+), 0 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-greeter-login-window.c b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
index a81cd09..45babd0 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-login-window.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
@@ -889,6 +889,8 @@ gdm_greeter_login_window_conversation_stopped (GdmGreeterLoginWindow *login_wind
|
|
|
|
g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE);
|
|
|
|
+ g_debug ("GdmGreeterLoginWindow: conversation '%s' has stopped", service_name);
|
|
+
|
|
task = gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
(GdmTaskListForeachFunc)
|
|
task_has_service_name,
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 09ef23cbc8b1303164f921365b197c5aac53697f Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Mon, 2 Mar 2009 13:31:31 -0500
|
|
Subject: [PATCH 58/65] Plug leak
|
|
|
|
---
|
|
gui/simple-greeter/gdm-greeter-login-window.c | 6 +++---
|
|
1 files changed, 3 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-greeter-login-window.c b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
index 45babd0..6bd2707 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-login-window.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
@@ -905,11 +905,11 @@ gdm_greeter_login_window_conversation_stopped (GdmGreeterLoginWindow *login_wind
|
|
*/
|
|
task = gdm_task_list_get_active_task (GDM_TASK_LIST (login_window->priv->conversation_list));
|
|
|
|
- if (gdm_task_is_enabled (task)) {
|
|
- g_object_unref (task);
|
|
- } else {
|
|
+ if (!gdm_task_is_enabled (task)) {
|
|
+ g_debug ("GdmGreeterLoginWindow: No conversations left, starting over");
|
|
restart_conversations (login_window);
|
|
}
|
|
+ g_object_unref (task);
|
|
|
|
return TRUE;
|
|
}
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From ac8977339e6684150b268128ed311937f5d4207f Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Mon, 2 Mar 2009 13:53:34 -0500
|
|
Subject: [PATCH 59/65] Pull verification functions out into their own subroutines
|
|
|
|
This makes the function smaller and easier to read
|
|
---
|
|
gui/simple-greeter/gdm-greeter-login-window.c | 107 +++++++++++++++---------
|
|
1 files changed, 67 insertions(+), 40 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-greeter-login-window.c b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
index 6bd2707..48e94ec 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-login-window.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
@@ -1592,6 +1592,17 @@ begin_task_verification (GdmTaskList *task_list,
|
|
return FALSE;
|
|
}
|
|
|
|
+static void
|
|
+begin_verification (GdmGreeterLoginWindow *login_window)
|
|
+{
|
|
+ gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
+ (GdmTaskListForeachFunc)
|
|
+ begin_task_verification,
|
|
+ login_window);
|
|
+
|
|
+ switch_mode (login_window, MODE_MULTIPLE_AUTHENTICATION);
|
|
+}
|
|
+
|
|
static gboolean
|
|
begin_task_verification_for_selected_user (GdmTaskList *task_list,
|
|
GdmTask *task,
|
|
@@ -1617,6 +1628,15 @@ begin_task_verification_for_selected_user (GdmTaskList *task_list,
|
|
}
|
|
|
|
static void
|
|
+begin_verification_for_selected_user (GdmGreeterLoginWindow *login_window)
|
|
+{
|
|
+ gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
+ (GdmTaskListForeachFunc)
|
|
+ begin_task_verification_for_selected_user,
|
|
+ login_window);
|
|
+}
|
|
+
|
|
+static void
|
|
on_user_chosen (GdmGreeterLoginWindow *login_window,
|
|
const char *user_name)
|
|
{
|
|
@@ -1625,15 +1645,55 @@ on_user_chosen (GdmGreeterLoginWindow *login_window,
|
|
g_signal_emit (G_OBJECT (login_window), signals[USER_SELECTED],
|
|
0, user_name);
|
|
|
|
- gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
- (GdmTaskListForeachFunc)
|
|
- begin_task_verification_for_selected_user,
|
|
- login_window);
|
|
+ begin_verification_for_selected_user (login_window);
|
|
|
|
switch_mode (login_window, MODE_MULTIPLE_AUTHENTICATION);
|
|
}
|
|
|
|
static void
|
|
+begin_auto_login (GdmGreeterLoginWindow *login_window)
|
|
+{
|
|
+ g_signal_emit (login_window, signals[BEGIN_AUTO_LOGIN], 0,
|
|
+ login_window->priv->timed_login_username);
|
|
+
|
|
+ login_window->priv->timed_login_enabled = TRUE;
|
|
+ restart_timed_login_timeout (login_window);
|
|
+
|
|
+ /* just wait for the user to select language and stuff */
|
|
+ set_log_in_button_mode (login_window, LOGIN_BUTTON_TIMED_LOGIN);
|
|
+ set_message (login_window, _("Select language and click Log In"));
|
|
+
|
|
+ switch_mode (login_window, MODE_SINGLE_AUTHENTICATION);
|
|
+}
|
|
+
|
|
+static void
|
|
+begin_single_service_verification (GdmGreeterLoginWindow *login_window,
|
|
+ const char *service_name)
|
|
+{
|
|
+ GdmTask *task;
|
|
+
|
|
+ task = gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
+ (GdmTaskListForeachFunc)
|
|
+ task_has_service_name,
|
|
+ (gpointer) service_name);
|
|
+
|
|
+ if (task == NULL) {
|
|
+ g_debug ("GdmGreeterLoginWindow: %s has no task associated with it", service_name);
|
|
+ return;
|
|
+ }
|
|
+ g_debug ("GdmGreeterLoginWindow: Beginning auth conversation for item %s", service_name);
|
|
+ /* FIXME: we should probably give the plugin more say for
|
|
+ * what happens here.
|
|
+ */
|
|
+ g_signal_emit (login_window, signals[BEGIN_VERIFICATION], 0, service_name);
|
|
+
|
|
+ switch_mode (login_window, MODE_SINGLE_AUTHENTICATION);
|
|
+ gdm_task_list_set_active_task (GDM_TASK_LIST (login_window->priv->conversation_list), task);
|
|
+
|
|
+ g_object_unref (task);
|
|
+}
|
|
+
|
|
+static void
|
|
on_user_chooser_activated (GdmUserChooserWidget *user_chooser,
|
|
GdmGreeterLoginWindow *login_window)
|
|
{
|
|
@@ -1654,51 +1714,18 @@ on_user_chooser_activated (GdmUserChooserWidget *user_chooser,
|
|
|
|
if (strcmp (item_id, GDM_USER_CHOOSER_USER_OTHER) == 0) {
|
|
g_debug ("GdmGreeterLoginWindow: Starting all auth conversations");
|
|
- gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
- (GdmTaskListForeachFunc)
|
|
- begin_task_verification,
|
|
- login_window);
|
|
g_free (item_id);
|
|
|
|
- switch_mode (login_window, MODE_MULTIPLE_AUTHENTICATION);
|
|
+ begin_verification (login_window);
|
|
} else if (strcmp (item_id, GDM_USER_CHOOSER_USER_AUTO) == 0) {
|
|
g_debug ("GdmGreeterLoginWindow: Starting auto login");
|
|
- g_signal_emit (login_window, signals[BEGIN_AUTO_LOGIN], 0,
|
|
- login_window->priv->timed_login_username);
|
|
-
|
|
- login_window->priv->timed_login_enabled = TRUE;
|
|
- restart_timed_login_timeout (login_window);
|
|
-
|
|
- /* just wait for the user to select language and stuff */
|
|
- set_log_in_button_mode (login_window, LOGIN_BUTTON_TIMED_LOGIN);
|
|
- set_message (login_window, _("Select language and click Log In"));
|
|
g_free (item_id);
|
|
|
|
- switch_mode (login_window, MODE_SINGLE_AUTHENTICATION);
|
|
+ begin_auto_login (login_window);
|
|
} else {
|
|
- GdmTask *task;
|
|
|
|
- task = gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
- (GdmTaskListForeachFunc)
|
|
- task_has_service_name,
|
|
- (gpointer) item_id);
|
|
-
|
|
- if (task == NULL) {
|
|
- g_debug ("GdmGreeterLoginWindow: %s has no task associated with it", item_id);
|
|
- g_free (item_id);
|
|
- return;
|
|
- }
|
|
- g_debug ("GdmGreeterLoginWindow: Beginning auth conversation for item %s", item_id);
|
|
- /* FIXME: we should probably give the plugin more say for
|
|
- * what happens here.
|
|
- */
|
|
- g_signal_emit (login_window, signals[BEGIN_VERIFICATION], 0, item_id);
|
|
+ begin_single_service_verification (login_window, item_id);
|
|
g_free (item_id);
|
|
-
|
|
- switch_mode (login_window, MODE_SINGLE_AUTHENTICATION);
|
|
- gdm_task_list_set_active_task (GDM_TASK_LIST (login_window->priv->conversation_list), task);
|
|
-
|
|
- g_object_unref (task);
|
|
}
|
|
}
|
|
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 5f6a57bff48ab174313966b05546a7b65dce6a69 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Mon, 2 Mar 2009 13:57:34 -0500
|
|
Subject: [PATCH 60/65] Add new function find_task_with_service_name
|
|
|
|
It hides a bunch of icky foreach calls.
|
|
---
|
|
gui/simple-greeter/gdm-greeter-login-window.c | 50 +++++++++++--------------
|
|
1 files changed, 22 insertions(+), 28 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-greeter-login-window.c b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
index 48e94ec..9a2f415 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-login-window.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
@@ -776,6 +776,20 @@ task_has_service_name (GdmTaskList *task_list,
|
|
return has_service_name;
|
|
}
|
|
|
|
+GdmTask *
|
|
+find_task_with_service_name (GdmGreeterLoginWindow *login_window,
|
|
+ const char *service_name)
|
|
+{
|
|
+ GdmTask *task;
|
|
+
|
|
+ task = gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
+ (GdmTaskListForeachFunc)
|
|
+ task_has_service_name,
|
|
+ (gpointer) service_name);
|
|
+
|
|
+ return task;
|
|
+}
|
|
+
|
|
static gboolean
|
|
reset_task (GdmTaskList *task_list,
|
|
GdmTask *task,
|
|
@@ -856,10 +870,7 @@ gdm_greeter_login_window_ready (GdmGreeterLoginWindow *login_window,
|
|
|
|
g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE);
|
|
|
|
- task = gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
- (GdmTaskListForeachFunc)
|
|
- task_has_service_name,
|
|
- (gpointer) service_name);
|
|
+ task = find_task_with_service_name (login_window, service_name);
|
|
|
|
if (task != NULL) {
|
|
if (gdm_chooser_widget_is_loaded (GDM_CHOOSER_WIDGET (login_window->priv->user_chooser))) {
|
|
@@ -891,10 +902,7 @@ gdm_greeter_login_window_conversation_stopped (GdmGreeterLoginWindow *login_wind
|
|
|
|
g_debug ("GdmGreeterLoginWindow: conversation '%s' has stopped", service_name);
|
|
|
|
- task = gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
- (GdmTaskListForeachFunc)
|
|
- task_has_service_name,
|
|
- (gpointer) service_name);
|
|
+ task = find_task_with_service_name (login_window, service_name);
|
|
|
|
if (task != NULL) {
|
|
gdm_conversation_reset (GDM_CONVERSATION (task));
|
|
@@ -962,10 +970,7 @@ gdm_greeter_login_window_info (GdmGreeterLoginWindow *login_window,
|
|
g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE);
|
|
g_debug ("GdmGreeterLoginWindow: info: %s", text);
|
|
|
|
- task = gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
- (GdmTaskListForeachFunc)
|
|
- task_has_service_name,
|
|
- (gpointer) service_name);
|
|
+ task = find_task_with_service_name (login_window, service_name);
|
|
|
|
if (task != NULL) {
|
|
gdm_conversation_set_message (GDM_CONVERSATION (task),
|
|
@@ -986,10 +991,7 @@ gdm_greeter_login_window_problem (GdmGreeterLoginWindow *login_window,
|
|
g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE);
|
|
g_debug ("GdmGreeterLoginWindow: problem: %s", text);
|
|
|
|
- task = gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
- (GdmTaskListForeachFunc)
|
|
- task_has_service_name,
|
|
- (gpointer) service_name);
|
|
+ task = find_task_with_service_name (login_window, service_name);
|
|
|
|
if (task != NULL) {
|
|
gdm_conversation_set_message (GDM_CONVERSATION (task),
|
|
@@ -1091,10 +1093,8 @@ gdm_greeter_login_window_info_query (GdmGreeterLoginWindow *login_window,
|
|
|
|
g_debug ("GdmGreeterLoginWindow: info query: %s", text);
|
|
|
|
- task = gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
- (GdmTaskListForeachFunc)
|
|
- task_has_service_name,
|
|
- (gpointer) service_name);
|
|
+
|
|
+ task = find_task_with_service_name (login_window, service_name);
|
|
|
|
if (task != NULL) {
|
|
gdm_conversation_ask_question (GDM_CONVERSATION (task),
|
|
@@ -1122,10 +1122,7 @@ gdm_greeter_login_window_secret_info_query (GdmGreeterLoginWindow *login_window,
|
|
|
|
g_return_val_if_fail (GDM_IS_GREETER_LOGIN_WINDOW (login_window), FALSE);
|
|
|
|
- task = gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
- (GdmTaskListForeachFunc)
|
|
- task_has_service_name,
|
|
- (gpointer) service_name);
|
|
+ task = find_task_with_service_name (login_window, service_name);
|
|
|
|
if (task != NULL) {
|
|
gdm_conversation_ask_secret (GDM_CONVERSATION (task),
|
|
@@ -1672,10 +1669,7 @@ begin_single_service_verification (GdmGreeterLoginWindow *login_window,
|
|
{
|
|
GdmTask *task;
|
|
|
|
- task = gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
- (GdmTaskListForeachFunc)
|
|
- task_has_service_name,
|
|
- (gpointer) service_name);
|
|
+ task = find_task_with_service_name (login_window, service_name);
|
|
|
|
if (task == NULL) {
|
|
g_debug ("GdmGreeterLoginWindow: %s has no task associated with it", service_name);
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 6472307e358cee4f47236ad0c38757ab10c892e3 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Mon, 2 Mar 2009 15:23:51 -0500
|
|
Subject: [PATCH 61/65] Drop the different auth modes in favor of calling reset manually
|
|
|
|
---
|
|
gui/simple-greeter/gdm-greeter-login-window.c | 57 +++++++++++++++----------
|
|
1 files changed, 35 insertions(+), 22 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-greeter-login-window.c b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
index 9a2f415..83f4057 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-login-window.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
@@ -105,8 +105,7 @@
|
|
|
|
enum {
|
|
MODE_SELECTION = 0,
|
|
- MODE_SINGLE_AUTHENTICATION,
|
|
- MODE_MULTIPLE_AUTHENTICATION,
|
|
+ MODE_AUTHENTICATION
|
|
};
|
|
|
|
enum {
|
|
@@ -587,8 +586,7 @@ sensitize_power_buttons_timeout (GdmGreeterLoginWindow *login_window)
|
|
sensitize_widget (login_window, "suspend-button", TRUE);
|
|
sensitize_widget (login_window, "disconnect-button", TRUE);
|
|
break;
|
|
- case MODE_SINGLE_AUTHENTICATION:
|
|
- case MODE_MULTIPLE_AUTHENTICATION:
|
|
+ case MODE_AUTHENTICATION:
|
|
break;
|
|
default:
|
|
g_assert_not_reached ();
|
|
@@ -648,7 +646,6 @@ switch_mode (GdmGreeterLoginWindow *login_window,
|
|
|
|
show_widget (login_window, "auth-page-box", FALSE);
|
|
show_widget (login_window, "conversation-list", FALSE);
|
|
- gtk_widget_set_sensitive (login_window->priv->conversation_list, TRUE);
|
|
|
|
add_sensitize_power_buttons_timeout (login_window);
|
|
sensitize_widget (login_window, "shutdown-button", FALSE);
|
|
@@ -658,8 +655,7 @@ switch_mode (GdmGreeterLoginWindow *login_window,
|
|
|
|
default_name = NULL;
|
|
break;
|
|
- case MODE_SINGLE_AUTHENTICATION:
|
|
- case MODE_MULTIPLE_AUTHENTICATION:
|
|
+ case MODE_AUTHENTICATION:
|
|
gtk_widget_set_size_request (GTK_WIDGET (login_window),
|
|
GTK_WIDGET (login_window)->allocation.width,
|
|
-1);
|
|
@@ -673,14 +669,6 @@ switch_mode (GdmGreeterLoginWindow *login_window,
|
|
number_of_tasks = gdm_task_list_get_number_of_tasks (GDM_TASK_LIST (login_window->priv->conversation_list));
|
|
show_widget (login_window, "conversation-list", number_of_tasks > 1);
|
|
|
|
- if (number == MODE_SINGLE_AUTHENTICATION) {
|
|
- g_debug ("GdmGreeterLoginWindow: Single authentication, 1 task");
|
|
- gtk_widget_set_sensitive (login_window->priv->conversation_list, FALSE);
|
|
- } else {
|
|
- g_debug ("GdmGreeterLoginWindow: Multiple authentication, %d tasks", number_of_tasks);
|
|
- gtk_widget_set_sensitive (login_window->priv->conversation_list, TRUE);
|
|
- }
|
|
-
|
|
default_name = "log-in-button";
|
|
break;
|
|
default:
|
|
@@ -1597,7 +1585,7 @@ begin_verification (GdmGreeterLoginWindow *login_window)
|
|
begin_task_verification,
|
|
login_window);
|
|
|
|
- switch_mode (login_window, MODE_MULTIPLE_AUTHENTICATION);
|
|
+ switch_mode (login_window, MODE_AUTHENTICATION);
|
|
}
|
|
|
|
static gboolean
|
|
@@ -1644,7 +1632,7 @@ on_user_chosen (GdmGreeterLoginWindow *login_window,
|
|
|
|
begin_verification_for_selected_user (login_window);
|
|
|
|
- switch_mode (login_window, MODE_MULTIPLE_AUTHENTICATION);
|
|
+ switch_mode (login_window, MODE_AUTHENTICATION);
|
|
}
|
|
|
|
static void
|
|
@@ -1660,7 +1648,30 @@ begin_auto_login (GdmGreeterLoginWindow *login_window)
|
|
set_log_in_button_mode (login_window, LOGIN_BUTTON_TIMED_LOGIN);
|
|
set_message (login_window, _("Select language and click Log In"));
|
|
|
|
- switch_mode (login_window, MODE_SINGLE_AUTHENTICATION);
|
|
+ switch_mode (login_window, MODE_AUTHENTICATION);
|
|
+}
|
|
+
|
|
+static gboolean
|
|
+reset_task_if_not_given (GdmTaskList *task_list,
|
|
+ GdmTask *task,
|
|
+ GdmTask *given_task)
|
|
+{
|
|
+ if (task == given_task) {
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ gdm_conversation_reset (GDM_CONVERSATION (task));
|
|
+ return FALSE;
|
|
+}
|
|
+
|
|
+static void
|
|
+reset_every_task_but_given_task (GdmGreeterLoginWindow *login_window,
|
|
+ GdmTask *task)
|
|
+{
|
|
+ gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
+ (GdmTaskListForeachFunc)
|
|
+ reset_task_if_not_given,
|
|
+ task);
|
|
}
|
|
|
|
static void
|
|
@@ -1675,15 +1686,18 @@ begin_single_service_verification (GdmGreeterLoginWindow *login_window,
|
|
g_debug ("GdmGreeterLoginWindow: %s has no task associated with it", service_name);
|
|
return;
|
|
}
|
|
- g_debug ("GdmGreeterLoginWindow: Beginning auth conversation for item %s", service_name);
|
|
+ g_debug ("GdmGreeterLoginWindow: Beginning %s auth conversation", service_name);
|
|
+
|
|
/* FIXME: we should probably give the plugin more say for
|
|
* what happens here.
|
|
*/
|
|
g_signal_emit (login_window, signals[BEGIN_VERIFICATION], 0, service_name);
|
|
|
|
- switch_mode (login_window, MODE_SINGLE_AUTHENTICATION);
|
|
+ switch_mode (login_window, MODE_AUTHENTICATION);
|
|
gdm_task_list_set_active_task (GDM_TASK_LIST (login_window->priv->conversation_list), task);
|
|
|
|
+ reset_every_task_but_given_task (login_window, task);
|
|
+
|
|
g_object_unref (task);
|
|
}
|
|
|
|
@@ -2066,8 +2080,7 @@ gdm_greeter_login_window_key_press_event (GtkWidget *widget,
|
|
login_window = GDM_GREETER_LOGIN_WINDOW (widget);
|
|
|
|
if (event->keyval == GDK_Escape) {
|
|
- if (login_window->priv->dialog_mode == MODE_SINGLE_AUTHENTICATION ||
|
|
- login_window->priv->dialog_mode == MODE_MULTIPLE_AUTHENTICATION) {
|
|
+ if (login_window->priv->dialog_mode == MODE_AUTHENTICATION) {
|
|
do_cancel (GDM_GREETER_LOGIN_WINDOW (widget));
|
|
}
|
|
}
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 4f14d44c0c3106bc45b2d1e72300944467fd7465 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Mon, 2 Mar 2009 15:50:47 -0500
|
|
Subject: [PATCH 62/65] Disconnect task "loaded" handler when loaded
|
|
|
|
---
|
|
gui/simple-greeter/gdm-greeter-login-window.c | 26 +++++++++++++++++++++---
|
|
1 files changed, 22 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/gdm-greeter-login-window.c b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
index 83f4057..d7f3cf3 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-login-window.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
@@ -850,6 +850,27 @@ do_cancel (GdmGreeterLoginWindow *login_window)
|
|
restart_conversations (login_window);
|
|
}
|
|
|
|
+static void
|
|
+on_can_set_task_ready (GtkWidget *user_chooser,
|
|
+ GdmTask *task)
|
|
+{
|
|
+ g_signal_handlers_disconnect_by_func (user_chooser,
|
|
+ on_can_set_task_ready,
|
|
+ task);
|
|
+ gdm_conversation_set_ready (GDM_CONVERSATION (task));
|
|
+ g_object_unref (task);
|
|
+}
|
|
+
|
|
+static void
|
|
+set_task_ready_when_loaded (GdmGreeterLoginWindow *login_window,
|
|
+ GdmTask *task)
|
|
+{
|
|
+ g_signal_connect (login_window->priv->user_chooser,
|
|
+ "loaded",
|
|
+ G_CALLBACK (on_can_set_task_ready),
|
|
+ g_object_ref (task));
|
|
+}
|
|
+
|
|
gboolean
|
|
gdm_greeter_login_window_ready (GdmGreeterLoginWindow *login_window,
|
|
const char *service_name)
|
|
@@ -865,10 +886,7 @@ gdm_greeter_login_window_ready (GdmGreeterLoginWindow *login_window,
|
|
gdm_conversation_set_ready (GDM_CONVERSATION (task));
|
|
} else {
|
|
|
|
- g_signal_connect_swapped (login_window->priv->user_chooser,
|
|
- "loaded",
|
|
- G_CALLBACK (gdm_conversation_set_ready),
|
|
- GDM_CONVERSATION (task));
|
|
+ set_task_ready_when_loaded (login_window, task);
|
|
}
|
|
g_object_unref (task);
|
|
}
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 2a877374cd32423b29de0d4ba42f449026446ea9 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Mon, 2 Mar 2009 17:09:16 -0500
|
|
Subject: [PATCH 63/65] Notify plugins if their user choose requests fail
|
|
|
|
This allows the smart card plugin to cancel pending
|
|
conversations when a card gets inserted.
|
|
|
|
This isn't perfect. We really want to only cancel
|
|
the conversations if they're for a user other
|
|
than the user the smartcard is for.
|
|
---
|
|
common/gdm-marshal.list | 1 +
|
|
gui/simple-greeter/gdm-greeter-login-window.c | 12 ++++++++-
|
|
gui/simple-greeter/libgdmsimplegreeter/Makefile.am | 2 +
|
|
.../libgdmsimplegreeter/gdm-conversation.c | 19 +++++++++++-----
|
|
.../libgdmsimplegreeter/gdm-conversation.h | 6 ++--
|
|
.../plugins/smartcard/gdm-smartcard-extension.c | 23 +++++++++++++++----
|
|
6 files changed, 47 insertions(+), 16 deletions(-)
|
|
|
|
diff --git a/common/gdm-marshal.list b/common/gdm-marshal.list
|
|
index d5455e1..d8a9e72 100644
|
|
--- a/common/gdm-marshal.list
|
|
+++ b/common/gdm-marshal.list
|
|
@@ -5,3 +5,4 @@ VOID:STRING,STRING
|
|
VOID:UINT,UINT
|
|
VOID:STRING,INT
|
|
VOID:DOUBLE
|
|
+BOOLEAN:STRING
|
|
diff --git a/gui/simple-greeter/gdm-greeter-login-window.c b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
index d7f3cf3..9797e67 100644
|
|
--- a/gui/simple-greeter/gdm-greeter-login-window.c
|
|
+++ b/gui/simple-greeter/gdm-greeter-login-window.c
|
|
@@ -2377,7 +2377,7 @@ on_conversation_cancel (GdmGreeterLoginWindow *login_window,
|
|
do_cancel (login_window);
|
|
}
|
|
|
|
-static void
|
|
+static gboolean
|
|
on_conversation_chose_user (GdmGreeterLoginWindow *login_window,
|
|
const char *username,
|
|
GdmConversation *conversation)
|
|
@@ -2388,7 +2388,13 @@ on_conversation_chose_user (GdmGreeterLoginWindow *login_window,
|
|
name = gdm_task_get_name (GDM_TASK (conversation));
|
|
g_warning ("Task %s is trying to choose user before list is loaded", name);
|
|
g_free (name);
|
|
- return;
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ /* If we're already authenticating then we can't pick a user
|
|
+ */
|
|
+ if (login_window->priv->dialog_mode == MODE_AUTHENTICATION) {
|
|
+ return FALSE;
|
|
}
|
|
|
|
if (gdm_task_list_set_active_task (GDM_TASK_LIST (login_window->priv->conversation_list),
|
|
@@ -2396,6 +2402,8 @@ on_conversation_chose_user (GdmGreeterLoginWindow *login_window,
|
|
gdm_user_chooser_widget_set_chosen_user_name (GDM_USER_CHOOSER_WIDGET (login_window->priv->user_chooser),
|
|
username);
|
|
}
|
|
+
|
|
+ return TRUE;
|
|
}
|
|
|
|
void
|
|
diff --git a/gui/simple-greeter/libgdmsimplegreeter/Makefile.am b/gui/simple-greeter/libgdmsimplegreeter/Makefile.am
|
|
index 1ef5725..0d7a0bd 100644
|
|
--- a/gui/simple-greeter/libgdmsimplegreeter/Makefile.am
|
|
+++ b/gui/simple-greeter/libgdmsimplegreeter/Makefile.am
|
|
@@ -3,6 +3,7 @@ NULL =
|
|
AM_CPPFLAGS = \
|
|
-I. \
|
|
-I.. \
|
|
+ -I$(top_srcdir)/common \
|
|
-DBINDIR=\"$(bindir)\" \
|
|
-DDATADIR=\"$(datadir)\" \
|
|
-DLIBDIR=\"$(libdir)\" \
|
|
@@ -28,6 +29,7 @@ libgdmsimplegreeter_la_SOURCES = \
|
|
|
|
libgdmsimplegreeter_la_LIBADD = \
|
|
$(GTK_LIBS) \
|
|
+ $(top_builddir)/common/libgdmcommon.la \
|
|
$(NULL)
|
|
|
|
libgdmsimplegreeter_la_LDFLAGS = \
|
|
diff --git a/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.c b/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.c
|
|
index cef435c..ee763ef 100644
|
|
--- a/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.c
|
|
+++ b/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.c
|
|
@@ -25,9 +25,9 @@
|
|
#include <gtk/gtk.h>
|
|
|
|
#include "gdm-conversation.h"
|
|
+#include "gdm-marshal.h"
|
|
#include "gdm-task.h"
|
|
|
|
-
|
|
enum {
|
|
ANSWER,
|
|
USER_CHOSEN,
|
|
@@ -76,12 +76,12 @@ gdm_conversation_class_init (gpointer g_iface)
|
|
signals [USER_CHOSEN] =
|
|
g_signal_new ("user-chosen",
|
|
iface_type,
|
|
- G_SIGNAL_RUN_FIRST,
|
|
+ G_SIGNAL_RUN_LAST,
|
|
G_STRUCT_OFFSET (GdmConversationIface, user_chosen),
|
|
NULL,
|
|
NULL,
|
|
- g_cclosure_marshal_VOID__STRING,
|
|
- G_TYPE_NONE,
|
|
+ gdm_marshal_BOOLEAN__STRING,
|
|
+ G_TYPE_BOOLEAN,
|
|
1, G_TYPE_STRING);
|
|
signals [CANCEL] =
|
|
g_signal_new ("cancel",
|
|
@@ -171,9 +171,16 @@ gdm_conversation_cancel (GdmConversation *conversation)
|
|
{
|
|
g_signal_emit (conversation, signals [CANCEL], 0);
|
|
}
|
|
-void
|
|
+
|
|
+gboolean
|
|
gdm_conversation_choose_user (GdmConversation *conversation,
|
|
const char *username)
|
|
{
|
|
- g_signal_emit (conversation, signals [USER_CHOSEN], 0, username);
|
|
+ gboolean was_chosen;
|
|
+
|
|
+ was_chosen = FALSE;
|
|
+
|
|
+ g_signal_emit (conversation, signals [USER_CHOSEN], 0, username, &was_chosen);
|
|
+
|
|
+ return was_chosen;
|
|
}
|
|
diff --git a/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.h b/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.h
|
|
index fb4bf49..b37b21e 100644
|
|
--- a/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.h
|
|
+++ b/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.h
|
|
@@ -61,7 +61,7 @@ struct _GdmConversationIface
|
|
/* signals */
|
|
char * (* answer) (GdmConversation *conversation);
|
|
void (* cancel) (GdmConversation *conversation);
|
|
- void (* user_chosen) (GdmConversation *conversation);
|
|
+ gboolean (* user_chosen) (GdmConversation *conversation);
|
|
};
|
|
|
|
GType gdm_conversation_get_type (void) G_GNUC_CONST;
|
|
@@ -85,8 +85,8 @@ gboolean gdm_conversation_focus (GdmConversation *conversation);
|
|
void gdm_conversation_answer (GdmConversation *conversation,
|
|
const char *answer);
|
|
void gdm_conversation_cancel (GdmConversation *conversation);
|
|
-void gdm_conversation_choose_user (GdmConversation *conversation,
|
|
- const char *username);
|
|
+gboolean gdm_conversation_choose_user (GdmConversation *conversation,
|
|
+ const char *username);
|
|
|
|
G_END_DECLS
|
|
|
|
diff --git a/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c
|
|
index 8e87db6..5a2c380 100644
|
|
--- a/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c
|
|
+++ b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c
|
|
@@ -53,6 +53,7 @@ struct _GdmSmartcardExtensionPrivate
|
|
int number_of_tokens;
|
|
|
|
guint answer_pending : 1;
|
|
+ guint select_when_ready : 1;
|
|
};
|
|
|
|
static void gdm_smartcard_extension_finalize (GObject *object);
|
|
@@ -102,8 +103,14 @@ on_smartcard_event (GIOChannel *io_channel,
|
|
}
|
|
|
|
if (extension->priv->number_of_tokens == 1) {
|
|
- gdm_conversation_choose_user (GDM_CONVERSATION (extension),
|
|
- PAMSERVICENAME);
|
|
+ if (!gdm_conversation_choose_user (GDM_CONVERSATION (extension),
|
|
+ PAMSERVICENAME)) {
|
|
+ g_debug ("could not choose smart card user, cancelling...");
|
|
+ gdm_conversation_cancel (GDM_CONVERSATION (extension));
|
|
+ extension->priv->select_when_ready = TRUE;
|
|
+ } else {
|
|
+ g_debug ("chose smart card user!");
|
|
+ }
|
|
} else if (extension->priv->number_of_tokens == 0) {
|
|
gdm_conversation_cancel (GDM_CONVERSATION (extension));
|
|
}
|
|
@@ -210,10 +217,16 @@ gdm_smartcard_extension_set_ready (GdmConversation *conversation)
|
|
GdmSmartcardExtension *extension = GDM_SMARTCARD_EXTENSION (conversation);
|
|
gdm_task_set_enabled (GDM_TASK (conversation), TRUE);
|
|
|
|
- if (extension->priv->worker_pid <= 0)
|
|
- {
|
|
+ if (extension->priv->worker_pid <= 0) {
|
|
watch_for_smartcards (extension);
|
|
- }
|
|
+ }
|
|
+
|
|
+ if (extension->priv->select_when_ready) {
|
|
+ if (gdm_conversation_choose_user (GDM_CONVERSATION (extension),
|
|
+ PAMSERVICENAME)) {
|
|
+ extension->priv->select_when_ready = FALSE;
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
char *
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From cdb57fbb1366ca4fe7314850d223cd0a79240fd9 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Tue, 3 Mar 2009 13:33:09 -0500
|
|
Subject: [PATCH 64/65] Don't build fingerprint and smartcard plugins
|
|
|
|
I'm staging a degenerate single stack case
|
|
for rawhide.
|
|
---
|
|
gui/simple-greeter/plugins/Makefile.am | 2 +-
|
|
1 files changed, 1 insertions(+), 1 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/plugins/Makefile.am b/gui/simple-greeter/plugins/Makefile.am
|
|
index 3dd336f..c0390db 100644
|
|
--- a/gui/simple-greeter/plugins/Makefile.am
|
|
+++ b/gui/simple-greeter/plugins/Makefile.am
|
|
@@ -1 +1 @@
|
|
-SUBDIRS = password fingerprint smartcard
|
|
+SUBDIRS = password
|
|
--
|
|
1.6.1
|
|
|
|
|
|
From 48c2237ff7efe68e116363ce51e0a4cdc42a5c78 Mon Sep 17 00:00:00 2001
|
|
From: Ray Strode <rstrode@redhat.com>
|
|
Date: Tue, 3 Mar 2009 17:15:10 -0500
|
|
Subject: [PATCH 65/65] Use "gdm" instead of "gdm-password"
|
|
|
|
This is so we hook into system configured auth policy
|
|
---
|
|
gui/simple-greeter/plugins/password/Makefile.am | 9 ++-------
|
|
1 files changed, 2 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/gui/simple-greeter/plugins/password/Makefile.am b/gui/simple-greeter/plugins/password/Makefile.am
|
|
index e832c4d..097b18e 100644
|
|
--- a/gui/simple-greeter/plugins/password/Makefile.am
|
|
+++ b/gui/simple-greeter/plugins/password/Makefile.am
|
|
@@ -3,8 +3,6 @@ NULL =
|
|
extensiondir = $(extensionsdatadir)/password
|
|
extension_DATA = page.ui
|
|
|
|
-pamservicename = gdm-password
|
|
-
|
|
AM_CPPFLAGS = \
|
|
-I$(top_srcdir)/common \
|
|
-I$(top_srcdir)/gui/simple-greeter/libnotificationarea \
|
|
@@ -12,7 +10,7 @@ AM_CPPFLAGS = \
|
|
-DDMCONFDIR=\""$(dmconfdir)"\" \
|
|
-DGDMCONFDIR=\"$(gdmconfdir)\" \
|
|
-DPLUGINDATADIR=\""$(extensiondir)"\" \
|
|
- -DPAMSERVICENAME=\""$(pamservicename)"\" \
|
|
+ -DPAMSERVICENAME=\""gdm"\" \
|
|
-DSYSCONFDIR=\""$(sysconfdir)"\" \
|
|
-DLIBLOCALEDIR=\""$(prefix)/lib/locale"\" \
|
|
-DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
|
|
@@ -39,10 +37,7 @@ password_la_SOURCES = \
|
|
gdm-password-extension.c \
|
|
plugin.c
|
|
|
|
-pamdir = $(PAM_PREFIX)/pam.d
|
|
-pam_DATA = $(pamservicename)
|
|
-
|
|
-EXTRA_DIST = $(extension_DATA) $(pam_DATA)
|
|
+EXTRA_DIST = $(extension_DATA)
|
|
|
|
MAINTAINERCLEANFILES = \
|
|
*~ \
|
|
--
|
|
1.6.1
|
|
|