[gnome-keyring/dbus-api] Tons of bug fixes for the prompting.



commit bb151e8ebea668e7261e231b77d2e2a00405e071
Author: Stef Walter <stef memberwebs com>
Date:   Sun Nov 1 20:15:32 2009 +0000

    Tons of bug fixes for the prompting.

 daemon/data/Makefile.am                  |    1 +
 daemon/data/introspect-prompt.xml        |   23 +++++++++++++++++++++++
 daemon/dbus/gkd-secrets-prompt.c         |    3 +++
 daemon/dbus/gkd-secrets-service.c        |   16 +++++++++-------
 daemon/dbus/gkd-secrets-unlock.c         |   27 +++++++++++++++++++++++----
 daemon/dbus/gkd-secrets-unlock.h         |    5 +++--
 daemon/gkr-daemon.c                      |    2 --
 daemon/prompt/gkd-prompt.c               |   30 ++++++++++++++++++++----------
 daemon/prompt/test/test-data/prompt-full |   16 ++++++++++++++++
 9 files changed, 98 insertions(+), 25 deletions(-)
---
diff --git a/daemon/data/Makefile.am b/daemon/data/Makefile.am
index 1b5aa8c..65efe87 100644
--- a/daemon/data/Makefile.am
+++ b/daemon/data/Makefile.am
@@ -23,6 +23,7 @@ introspectdir = $(datadir)/gnome-keyring/introspect
 introspect_DATA = \
 	introspect-collection.xml \
 	introspect-item.xml \
+	introspect-prompt.xml \
 	introspect-service.xml \
 	introspect-session.xml
 
diff --git a/daemon/data/introspect-prompt.xml b/daemon/data/introspect-prompt.xml
new file mode 100644
index 0000000..50a6c2f
--- /dev/null
+++ b/daemon/data/introspect-prompt.xml
@@ -0,0 +1,23 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+	"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd";>
+<node>
+
+	<interface name="org.freedesktop.DBus.Introspectable">
+		<method name="Introspect">
+			<arg name="data" direction="out" type="s"/>
+		</method>
+	</interface>
+
+	<interface name="org.freedesktop.Secrets.Prompt">
+		<method name="Prompt">
+			<arg name="window-id" type="s" direction="in"/>
+		</method>
+		<method name="Dismiss">
+		</method>
+		<signal name="Completed">
+			<arg name="result" type="v"/>
+			<arg name="dismissed" type="b"/>
+		</signal>
+	</interface>
+
+</node>
diff --git a/daemon/dbus/gkd-secrets-prompt.c b/daemon/dbus/gkd-secrets-prompt.c
index ec4246b..7f0a382 100644
--- a/daemon/dbus/gkd-secrets-prompt.c
+++ b/daemon/dbus/gkd-secrets-prompt.c
@@ -337,6 +337,9 @@ gkd_secrets_prompt_dispatch (GkdSecretsPrompt *self, DBusMessage *message)
 	else if (dbus_message_is_method_call (message, SECRETS_PROMPT_INTERFACE, "Dismiss"))
 		reply = prompt_method_dismiss (self, message);
 
+	else if (dbus_message_has_interface (message, DBUS_INTERFACE_INTROSPECTABLE))
+		return gkd_dbus_introspect_handle (message, "prompt");
+
 	return reply;
 }
 
diff --git a/daemon/dbus/gkd-secrets-service.c b/daemon/dbus/gkd-secrets-service.c
index 68871fa..59872cd 100644
--- a/daemon/dbus/gkd-secrets-service.c
+++ b/daemon/dbus/gkd-secrets-service.c
@@ -372,22 +372,23 @@ service_method_open_session (GkdSecretsService *self, DBusMessage *message)
 static DBusMessage*
 service_method_unlock (GkdSecretsService *self, DBusMessage *message)
 {
-	char **objpaths, **o;
 	GkdSecretsUnlock *unlock;
 	ServiceClient *client;
 	DBusMessage *reply;
 	const char *caller;
 	const gchar *path;
+	int n_objpaths, i;
+	char **objpaths;
 
 	if (!dbus_message_get_args (message, NULL,
-	                            DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &objpaths,
+	                            DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &objpaths, &n_objpaths,
 	                            DBUS_TYPE_INVALID))
 		return NULL;
 
 	caller = dbus_message_get_sender (message);
 	unlock = gkd_secrets_unlock_new (self, caller);
-	for (o = objpaths; o && *o; ++o)
-		gkd_secrets_unlock_queue (unlock, *o);
+	for (i = 0; i < n_objpaths; ++i)
+		gkd_secrets_unlock_queue (unlock, objpaths[i]);
 	dbus_free_string_array (objpaths);
 
 	/* So do we need to prompt? */
@@ -395,7 +396,7 @@ service_method_unlock (GkdSecretsService *self, DBusMessage *message)
 		client = g_hash_table_lookup (self->clients, caller);
 		g_return_val_if_fail (client, NULL);
 		path = gkd_secrets_prompt_get_object_path (GKD_SECRETS_PROMPT (unlock));
-		g_hash_table_replace (client->sessions, (gpointer)path, g_object_ref (unlock));
+		g_hash_table_replace (client->prompts, (gpointer)path, g_object_ref (unlock));
 
 	/* No need to prompt */
 	} else {
@@ -403,9 +404,10 @@ service_method_unlock (GkdSecretsService *self, DBusMessage *message)
 	}
 
 	reply = dbus_message_new_method_return (message);
+	objpaths = gkd_secrets_unlock_get_results (unlock, &n_objpaths);
 	dbus_message_append_args (reply,
-	                          DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, gkd_secrets_unlock_get_results (unlock),
-	                          DBUS_TYPE_OBJECT_PATH, path,
+	                          DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &objpaths, n_objpaths,
+	                          DBUS_TYPE_OBJECT_PATH, &path,
 	                          DBUS_TYPE_INVALID);
 
 	gkd_secrets_unlock_reset_results (unlock);
diff --git a/daemon/dbus/gkd-secrets-unlock.c b/daemon/dbus/gkd-secrets-unlock.c
index ce7df4c..5000a27 100644
--- a/daemon/dbus/gkd-secrets-unlock.c
+++ b/daemon/dbus/gkd-secrets-unlock.c
@@ -43,7 +43,7 @@ struct _GkdSecretsUnlock {
 	GArray *results;
 };
 
-G_DEFINE_TYPE (GkdSecretsUnlock, gkd_secrets_unlock, GKD_SECRETS_TYPE_UNLOCK);
+G_DEFINE_TYPE (GkdSecretsUnlock, gkd_secrets_unlock, GKD_SECRETS_TYPE_PROMPT);
 
 /* -----------------------------------------------------------------------------
  * INTERNAL
@@ -319,22 +319,41 @@ gkd_secrets_unlock_new (GkdSecretsService *service, const gchar *caller)
 void
 gkd_secrets_unlock_queue (GkdSecretsUnlock *self, const gchar *objpath)
 {
+	GP11Object *coll;
+	gboolean locked;
+	gchar *path;
+
 	g_return_if_fail (GKD_SECRETS_IS_UNLOCK (self));
 	g_return_if_fail (objpath);
-	g_queue_push_tail (self->queued, g_strdup (objpath));
+
+	coll = gkd_secrets_prompt_lookup_collection (GKD_SECRETS_PROMPT (self), objpath);
+	if (coll == NULL)
+		return;
+
+	if (authenticate_collection (self, coll, &locked)) {
+		path = g_strdup (objpath);
+		if (locked)
+			g_queue_push_tail (self->queued, path);
+		else
+			g_array_append_val (self->results, path);
+	}
+
+	g_object_unref (coll);
 }
 
 gboolean
 gkd_secrets_unlock_have_queued (GkdSecretsUnlock *self)
 {
 	g_return_val_if_fail (GKD_SECRETS_IS_UNLOCK (self), FALSE);
-	return !g_queue_is_empty (self->queued) && !self->current;
+	return !g_queue_is_empty (self->queued) || self->current;
 }
 
 gchar**
-gkd_secrets_unlock_get_results (GkdSecretsUnlock *self)
+gkd_secrets_unlock_get_results (GkdSecretsUnlock *self, gint *n_results)
 {
 	g_return_val_if_fail (GKD_SECRETS_IS_UNLOCK (self), NULL);
+	g_return_val_if_fail (n_results, NULL);
+	*n_results = self->results->len;
 	return (gchar**)self->results->data;
 }
 
diff --git a/daemon/dbus/gkd-secrets-unlock.h b/daemon/dbus/gkd-secrets-unlock.h
index 0dcdff5..a78b54a 100644
--- a/daemon/dbus/gkd-secrets-unlock.h
+++ b/daemon/dbus/gkd-secrets-unlock.h
@@ -36,7 +36,7 @@
 typedef struct _GkdSecretsUnlockClass GkdSecretsUnlockClass;
 
 struct _GkdSecretsUnlockClass {
-	GObjectClass parent_class;
+	GkdSecretsPromptClass parent_class;
 };
 
 GType               gkd_secrets_unlock_get_type               (void);
@@ -49,7 +49,8 @@ void                gkd_secrets_unlock_queue                  (GkdSecretsUnlock
 
 gboolean            gkd_secrets_unlock_have_queued            (GkdSecretsUnlock *self);
 
-gchar**             gkd_secrets_unlock_get_results            (GkdSecretsUnlock *self);
+gchar**             gkd_secrets_unlock_get_results            (GkdSecretsUnlock *self,
+                                                               gint *n_results);
 
 void                gkd_secrets_unlock_reset_results          (GkdSecretsUnlock *self);
 
diff --git a/daemon/gkr-daemon.c b/daemon/gkr-daemon.c
index 5a1392e..c91522e 100644
--- a/daemon/gkr-daemon.c
+++ b/daemon/gkr-daemon.c
@@ -356,7 +356,6 @@ signal_thread (gpointer user_data)
 		case SIGPIPE:
 			/* Ignore */
 			break;
-		case SIGINT:
 		case SIGHUP:
 		case SIGTERM:
 			g_atomic_int_set (&signal_quitting, 1);
@@ -387,7 +386,6 @@ setup_signal_handling (GMainLoop *loop)
 
 	sigemptyset (&signal_set);
 	sigaddset (&signal_set, SIGPIPE);
-	sigaddset (&signal_set, SIGINT);
 	sigaddset (&signal_set, SIGHUP);
 	sigaddset (&signal_set, SIGTERM);
 	pthread_sigmask (SIG_BLOCK, &signal_set, NULL);
diff --git a/daemon/prompt/gkd-prompt.c b/daemon/prompt/gkd-prompt.c
index 89b0cc9..199fe51 100644
--- a/daemon/prompt/gkd-prompt.c
+++ b/daemon/prompt/gkd-prompt.c
@@ -32,6 +32,8 @@
 
 #include <gcrypt.h>
 
+#define DEBUG_PROMPT 1
+
 enum {
 	RESPONDED,
 	COMPLETED,
@@ -89,7 +91,7 @@ mark_completed (GkdPrompt *self)
 static gboolean
 on_standard_input (int fd, gpointer user_data)
 {
-	GkdPrompt *self = GKD_PROMPT (self);
+	GkdPrompt *self = GKD_PROMPT (user_data);
 	gssize ret;
 
 	g_return_val_if_fail (GKD_IS_PROMPT (self), FALSE);
@@ -114,7 +116,7 @@ on_standard_input (int fd, gpointer user_data)
 static gboolean
 on_standard_output (int fd, gpointer user_data)
 {
-	GkdPrompt *self = GKD_PROMPT (self);
+	GkdPrompt *self = GKD_PROMPT (user_data);
 	gchar buffer[1024];
 	gssize ret;
 
@@ -138,7 +140,7 @@ on_standard_output (int fd, gpointer user_data)
 static gboolean
 on_standard_error (int fd, gpointer user_data)
 {
-	GkdPrompt *self = GKD_PROMPT (self);
+	GkdPrompt *self = GKD_PROMPT (user_data);
 	gchar buffer[1024];
 	gssize ret;
 	gchar *ptr;
@@ -171,7 +173,7 @@ on_standard_error (int fd, gpointer user_data)
 static void
 on_io_completed (gpointer user_data)
 {
-	GkdPrompt *self = GKD_PROMPT (self);
+	GkdPrompt *self = GKD_PROMPT (user_data);
 	GError *error = NULL;
 
 	g_return_if_fail (GKD_IS_PROMPT (self));
@@ -189,6 +191,9 @@ on_io_completed (gpointer user_data)
 
 	/* Parse the output data properly */
 	if (!self->pv->failure) {
+#if DEBUG_PROMPT
+		g_printerr ("PROMPT OUTPUT:\n%s\n", self->pv->out_data->str);
+#endif
 		self->pv->output = g_key_file_new ();
 		if (!g_key_file_load_from_data (self->pv->output, self->pv->out_data->str,
 						self->pv->out_data->len, G_KEY_FILE_NONE, &error)) {
@@ -206,7 +211,7 @@ on_io_completed (gpointer user_data)
 static void
 on_child_exited (GPid pid, gint status, gpointer user_data)
 {
-	GkdPrompt *self = GKD_PROMPT (self);
+	GkdPrompt *self = GKD_PROMPT (user_data);
 	gint code;
 
 	if (pid == self->pv->pid) {
@@ -428,6 +433,10 @@ prepare_input_data (GkdPrompt *self)
 		return FALSE;
 	}
 
+#if DEBUG_PROMPT
+	g_printerr ("PROMPT INPUT:\n%s\n", self->pv->in_data);
+#endif
+
 	/* No further modifications to input are possible */
 	g_key_file_free (self->pv->input);
 	self->pv->input = NULL;
@@ -544,7 +553,7 @@ gkd_prompt_constructor (GType type, guint n_props, GObjectConstructParam *props)
 	g_return_val_if_fail (self, NULL);
 
 	if (!self->pv->executable)
-		self->pv->executable = g_strdup (LIBEXECDIR "/gnome-keyring-ask");
+		self->pv->executable = g_strdup (LIBEXECDIR "/gnome-keyring-prompt");
 
 	return G_OBJECT (self);
 }
@@ -573,6 +582,8 @@ gkd_prompt_finalize (GObject *obj)
 	GkdPrompt *self = GKD_PROMPT (obj);
 
 	g_assert (self->pv->pid == 0);
+	g_assert (!self->pv->input);
+	g_assert (!self->pv->output);
 	g_assert (!self->pv->in_data);
 	g_assert (!self->pv->out_data);
 	g_assert (!self->pv->err_data);
@@ -598,13 +609,13 @@ gkd_prompt_class_init (GkdPromptClass *klass)
 
 	g_type_class_add_private (klass, sizeof (GkdPromptPrivate));
 
-	signals[COMPLETED] = g_signal_new ("signal", GKD_TYPE_PROMPT,
+	signals[COMPLETED] = g_signal_new ("completed", GKD_TYPE_PROMPT,
 	                                   G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GkdPromptClass, completed),
 	                                   NULL, NULL, g_cclosure_marshal_VOID__VOID,
 	                                   G_TYPE_NONE, 0);
 
-	signals[RESPONDED] = g_signal_new ("signal", GKD_TYPE_PROMPT,
-	                                   G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GkdPromptClass, responded),
+	signals[RESPONDED] = g_signal_new ("responded", GKD_TYPE_PROMPT,
+	                                   G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GkdPromptClass, responded),
 	                                   g_signal_accumulator_true_handled, NULL, gkd_prompt_marshal_BOOLEAN__VOID,
 	                                   G_TYPE_BOOLEAN, 0);
 }
@@ -788,7 +799,6 @@ void
 gkd_prompt_reset (GkdPrompt *self)
 {
 	g_return_if_fail (GKD_IS_PROMPT (self));
-	g_return_if_fail (self->pv->completed);
 
 	kill_process (self);
 	self->pv->pid = 0;
diff --git a/daemon/prompt/test/test-data/prompt-full b/daemon/prompt/test/test-data/prompt-full
new file mode 100644
index 0000000..326daa4
--- /dev/null
+++ b/daemon/prompt/test/test-data/prompt-full
@@ -0,0 +1,16 @@
+[prompt]
+title=Unlock Keyring
+primary=Enter password for keyring 'sean' to unlock
+secondary=An application wants access to the keyring 'sean', but it is locked
+window-id=
+
+[visibility]
+name_area=false
+original_area=false
+confirm_area=false
+details_area=false
+
+[transport]
+prime=00E9991CBC77057BEB3E8165025E8338722BDB00297A910EA441129EA84ED091AF9DA55681A192E7E7C283FF6FA9EC5A81E03A8C0999F66B19DF80BE867D0A79B1DB3E42AE7EC1FCA057889F3ED666E86C3C248AA47C8E699997183C7A8093242C0D741CE5D4E1BA99CB5ACE895C53B92D9B9FE6B0D8203B5A8286567B8E9C2A33
+base=02
+public=223EB43E58FC3F8CFCBC0BBA039C9A9F918C74290F560FF41DF6F9E9BE6990BA0646F2DDC0643A4565C27FBD4D58E7E870A5964CE718DAD870F5F0E7ECAD794FDC148AEE9A91F192E264E01169E9B931CA4219CDBAA529C128E1873C9E134BE44C5EE4A393CF2B57442955752B9F0A54ED95DC2AC96897ED0A77E6B2FD8F43CA



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]