diff options
| author | Stef Walter <stef@memberwebs.com> | 2010-02-18 17:18:48 (GMT) |
|---|---|---|
| committer | Stef Walter <stef@memberwebs.com> | 2010-02-18 17:18:48 (GMT) |
| commit | 5e37e8cc09712fd8cab60e42636f260f23bacd7e (patch) | |
| tree | 60173432120c0b4b438bb1ec1750b7e95cba7ea3 | |
| parent | cf04a806f7cbd12bfb664a481b7a551650cb85b2 (diff) | |
| download | libgnome-keyring-5e37e8cc09712fd8cab60e42636f260f23bacd7e.zip libgnome-keyring-5e37e8cc09712fd8cab60e42636f260f23bacd7e.tar.xz | |
Can create a new default keyring when creating item.
When no default keyring exists, and creating an item, and
the default keyring was the desired keyring for the item,
prompt to create a new default keyring.
This mirrors the behavior in the old gnome-keyring-daemon.
However this functionality has now been moved to the library.
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | library/gnome-keyring.c | 180 | ||||
| -rw-r--r-- | library/tests/Makefile.am | 18 | ||||
| -rw-r--r-- | library/tests/test-prompting.c | 59 |
4 files changed, 235 insertions, 23 deletions
@@ -111,6 +111,7 @@ run-auto-test.h # /library/tests /library/tests/Makefile /library/tests/Makefile.in +/library/tests/test-prompting # /po /po/*.gmo diff --git a/library/gnome-keyring.c b/library/gnome-keyring.c index 8931fe5..92dcef5 100644 --- a/library/gnome-keyring.c +++ b/library/gnome-keyring.c @@ -2407,6 +2407,7 @@ gnome_keyring_find_itemsv_sync (GnomeKeyringItemType type, typedef struct _item_create_args { DBusMessage *request; DBusMessageIter iter; + gboolean is_default; gboolean update_if_exists; gchar *secret; } item_create_args; @@ -2463,17 +2464,11 @@ item_create_prepare (const gchar *path, GnomeKeyringItemType type, const gchar * return req; } -static gboolean -item_create_check_unlock (const char *path, gpointer user_data) -{ - gboolean *unlocked = user_data; - *unlocked = TRUE; - return FALSE; -} - static void -item_create_4_reply (GkrOperation *op, DBusMessage *reply, gpointer data) +item_create_3_created_reply (GkrOperation *op, DBusMessage *reply, gpointer data) { + /* Called after trying to create item */ + const char *path; const char *prompt; guint32 id; @@ -2496,8 +2491,10 @@ item_create_4_reply (GkrOperation *op, DBusMessage *reply, gpointer data) } static void -item_create_3_reply (GkrOperation *op, GkrSession *session, gpointer data) +item_create_2_session_reply (GkrOperation *op, GkrSession *session, gpointer data) { + /* Called after we have a session, start creating item */ + item_create_args *args = data; dbus_bool_t replace; @@ -2509,14 +2506,130 @@ item_create_3_reply (GkrOperation *op, GkrSession *session, gpointer data) replace = args->update_if_exists; dbus_message_iter_append_basic (&args->iter, DBUS_TYPE_BOOLEAN, &replace); - gkr_operation_push (op, item_create_4_reply, GKR_CALLBACK_OP_MSG, NULL, NULL); + gkr_operation_push (op, item_create_3_created_reply, GKR_CALLBACK_OP_MSG, NULL, NULL); + gkr_operation_set_keyring_hint (op); gkr_operation_request (op, args->request); } static void -item_create_2_reply (GkrOperation *op, DBusMessage *reply, gpointer data) +item_create_2_session_request (GkrOperation *op, gpointer data) { - item_create_args *args = data; + /* Called to get us a valid session */ + + gkr_operation_push (op, item_create_2_session_reply, GKR_CALLBACK_OP_SESSION, data, NULL); + gkr_session_negotiate (op); +} + +static void +item_create_1_default_reply (GkrOperation *op, DBusMessage *reply, gpointer data) +{ + /* Called after setting newly created keyring to default */ + + if (gkr_operation_handle_errors (op, reply)) + return; + + item_create_2_session_request (op, data); +} + +static void +item_create_1_default_request (GkrOperation *op, const gchar *path, gpointer data) +{ + /* Called to request setting newly created keyring to default */ + + DBusMessage *req; + const char *string; + + req = dbus_message_new_method_call (gkr_service_name (), SERVICE_PATH, + SERVICE_INTERFACE, "SetAlias"); + + string = "default"; + dbus_message_append_args (req, DBUS_TYPE_STRING, &string, + DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID); + + gkr_operation_push (op, item_create_1_default_reply, GKR_CALLBACK_OP_MSG, data, NULL); + gkr_operation_set_keyring_hint (op); + gkr_operation_request (op, req); + dbus_message_unref (req); +} + +static void +item_create_1_create_prompt_reply (GkrOperation *op, DBusMessage *reply, gpointer data) +{ + /* Called after prompting to create default collection for item */ + + DBusMessageIter iter, variant; + const char *path; + + if (gkr_operation_handle_errors (op, reply)) + return; + + if (!dbus_message_has_signature (reply, "bv")) { + gkr_operation_complete (op, decode_invalid_response (reply)); + return; + } + + /* Skip over dismissed, already parsed */ + if (!dbus_message_iter_init (reply, &iter) || + !dbus_message_iter_next (&iter)) + g_return_if_reached (); + + /* Dig out the variant */ + dbus_message_iter_recurse (&iter, &variant); + if (!g_str_equal (dbus_message_iter_get_signature (&variant), "o")) { + gkr_operation_complete (op, decode_invalid_response (reply)); + return; + } + + g_return_if_fail (dbus_message_iter_get_arg_type (&variant) == DBUS_TYPE_OBJECT_PATH); + dbus_message_iter_get_basic (&variant, &path); + + /* Set this keyring as the default keyring */ + item_create_1_default_request (op, path, data); +} + +static void +item_create_1_collection_reply (GkrOperation *op, DBusMessage *reply, gpointer data) +{ + /* Called after trying to create default collection to create item in */ + + const char *collection; + const char *prompt; + + if (gkr_operation_handle_errors (op, reply)) + return; + + /* Parse the response */ + if (!dbus_message_get_args (reply, NULL, DBUS_TYPE_OBJECT_PATH, &collection, + DBUS_TYPE_OBJECT_PATH, &prompt, DBUS_TYPE_INVALID)) { + g_warning ("bad response to CreateCollection from service"); + gkr_callback_invoke_res (gkr_operation_pop (op), GNOME_KEYRING_RESULT_IO_ERROR); + return; + } + + /* No prompt, set keyring as default */ + g_return_if_fail (prompt); + if (g_str_equal (prompt, "/")) { + item_create_1_default_request (op, collection, data); + + /* A prompt, display it get the response */ + } else { + gkr_operation_push (op, item_create_1_create_prompt_reply, GKR_CALLBACK_OP_MSG, data, NULL); + gkr_operation_prompt (op, prompt); + } +} + +static gboolean +item_create_check_unlock (const char *path, gpointer user_data) +{ + gboolean *unlocked = user_data; + *unlocked = TRUE; + return FALSE; +} + +static void +item_create_1_unlock_prompt_reply (GkrOperation *op, DBusMessage *reply, gpointer data) +{ + /* Called after unlocking the collection we're going to create item in */ gboolean dismissed = FALSE; gboolean unlocked = FALSE; @@ -2531,15 +2644,18 @@ item_create_2_reply (GkrOperation *op, DBusMessage *reply, gpointer data) } /* Now that its unlocked, we need a session to transfer the secret */ - gkr_operation_push (op, item_create_3_reply, GKR_CALLBACK_OP_SESSION, args, NULL); - gkr_session_negotiate (op); + item_create_2_session_request (op, data); } static void -item_create_1_reply (GkrOperation *op, DBusMessage *reply, gpointer data) +item_create_1_unlock_reply (GkrOperation *op, DBusMessage *reply, gpointer data) { + /* Called after trying to unlock keyring we're going to create item in */ + item_create_args *args = data; - gboolean unlocked; + DBusMessageIter iter; + DBusMessage *req; + gboolean unlocked = FALSE; const char *prompt; if (gkr_operation_handle_errors (op, reply)) @@ -2552,13 +2668,30 @@ item_create_1_reply (GkrOperation *op, DBusMessage *reply, gpointer data) /* Prompt to unlock the collection */ if (!g_str_equal (prompt, "/")) { - gkr_operation_push (op, item_create_2_reply, GKR_CALLBACK_OP_MSG, args, NULL); + gkr_operation_push (op, item_create_1_unlock_prompt_reply, GKR_CALLBACK_OP_MSG, args, NULL); gkr_operation_prompt (op, prompt); - /* We need a session to transfer the secret */ + /* No such keyring, no prompt, and not unlocked */ + } else if (!unlocked) { + + /* Caller asked for default keyring, and there is no such keyring. Create */ + if (args->is_default) { + req = dbus_message_new_method_call (gkr_service_name (), SERVICE_PATH, + SERVICE_INTERFACE, "CreateCollection"); + dbus_message_iter_init_append (req, &iter); + create_keyring_encode_properties (&iter, "default"); + gkr_operation_push (op, item_create_1_collection_reply, GKR_CALLBACK_OP_MSG, args, NULL); + gkr_operation_request (op, req); + dbus_message_unref (req); + + /* No such keyring, error */ + } else { + gkr_operation_complete (op, GNOME_KEYRING_RESULT_NO_SUCH_KEYRING); + } + + /* Successfully unlocked, or not locked. We need a session to transfer the secret */ } else { - gkr_operation_push (op, item_create_3_reply, GKR_CALLBACK_OP_SESSION, args, NULL); - gkr_session_negotiate (op); + item_create_2_session_request (op, args); } } @@ -2616,6 +2749,7 @@ gnome_keyring_item_create (const char *keyring, args = g_slice_new0 (item_create_args); args->update_if_exists = update_if_exists; args->secret = egg_secure_strdup (secret); + args->is_default = (keyring == NULL); path = gkr_encode_keyring_name (keyring); args->request = item_create_prepare (path, type, display_name, attributes, &args->iter); @@ -2626,7 +2760,7 @@ gnome_keyring_item_create (const char *keyring, g_free (path); op = gkr_operation_new (callback, GKR_CALLBACK_RES_UINT, data, destroy_data); - gkr_operation_push (op, item_create_1_reply, GKR_CALLBACK_OP_MSG, args, item_create_free); + gkr_operation_push (op, item_create_1_unlock_reply, GKR_CALLBACK_OP_MSG, args, item_create_free); gkr_operation_set_keyring_hint (op); gkr_operation_request (op, req); gkr_operation_unref (op); @@ -4379,7 +4513,7 @@ find_password_1_reply (GkrOperation *op, const char *path, gpointer user_data) /* All done, complete the operation here */ if (path == NULL) { cb = gkr_operation_pop (op); - gkr_callback_invoke_ok_string (cb, NULL); + gkr_callback_invoke_res (cb, GNOME_KEYRING_RESULT_NO_MATCH); /* We need a session to get the secret for this item */ } else { diff --git a/library/tests/Makefile.am b/library/tests/Makefile.am index 62634a9..3605fa1 100644 --- a/library/tests/Makefile.am +++ b/library/tests/Makefile.am @@ -10,3 +10,21 @@ UNIT_LIBS = \ $(top_builddir)/library/libgnome-keyring.la include $(top_srcdir)/tests/gtest.make + +# ------------------------------------------------------------------ + +noinst_PROGRAMS += \ + test-prompting + +test_prompting_SOURCES = \ + test-prompting.c + +test_prompting_CFLAGS = \ + $(GLIB_CFLAGS) + +test_prompting_LDADD = \ + $(top_builddir)/library/libgnome-keyring.la \ + $(GLIB_LIBS) + +EXTRA_DIST = \ + test-data
\ No newline at end of file diff --git a/library/tests/test-prompting.c b/library/tests/test-prompting.c new file mode 100644 index 0000000..bfba694 --- /dev/null +++ b/library/tests/test-prompting.c @@ -0,0 +1,59 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* unit-test-other.c: Test some prompts + + Copyright (C) 2010 Stefan Walter + + The Gnome Keyring Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Keyring Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Stef Walter <stef@memberwebs.com> +*/ + +#include "config.h" +#include "gnome-keyring.h" + +#include <glib.h> + +static int +test_create_item (void) +{ + GnomeKeyringResult res; + guint32 item_id; + + res = gnome_keyring_item_create_sync (NULL, GNOME_KEYRING_ITEM_GENERIC_SECRET, + "Test Create Prompt Item", NULL, "secret", FALSE, &item_id); + + if (res == GNOME_KEYRING_RESULT_CANCELLED) + g_printerr ("creating item cancelled\n"); + else if (res != GNOME_KEYRING_RESULT_OK) + g_printerr ("creating item failed: %s", gnome_keyring_result_to_message (res)); + else + g_print ("item id: %u", (guint)item_id); + + return 0; +} + +int +main (int argc, char *argv[]) +{ + if (argc == 2) { + if (g_str_equal (argv[1], "--create-item")) { + return test_create_item (); + } + } + + g_printerr ("usage: test-prompting --create-item\n"); + return 2; +} |