diff options
author | Stef Walter <stefw@gnome.org> | 2013-04-27 21:48:58 +0200 |
---|---|---|
committer | Stef Walter <stefw@gnome.org> | 2013-04-30 18:59:11 +0200 |
commit | b570ac71b7e037abbb7b14d246d5a37f0afd6ba8 (patch) | |
tree | 5e7236e24923330cb0afcd876d994f700cd433a8 | |
parent | 6f955eeed2728f0d8cf6dc7adb4265a8725d7d50 (diff) |
Fix implementation of LockService dbus method
This prevented gnome_keyring_lock_all() in libgnome-keyring from
working as expected.
https://bugzilla.gnome.org/show_bug.cgi?id=690466
-rw-r--r-- | daemon/dbus/gkd-secret-lock.c | 50 | ||||
-rw-r--r-- | daemon/dbus/gkd-secret-lock.h | 3 | ||||
-rw-r--r-- | daemon/dbus/gkd-secret-service.c | 12 | ||||
-rw-r--r-- | daemon/dbus/gkd-secret-unlock.c | 1 | ||||
-rw-r--r-- | daemon/dbus/tests/Makefile.am | 3 | ||||
-rw-r--r-- | daemon/dbus/tests/test-secret-lock.c | 134 |
6 files changed, 201 insertions, 2 deletions
diff --git a/daemon/dbus/gkd-secret-lock.c b/daemon/dbus/gkd-secret-lock.c index 9b68c464..64f0151a 100644 --- a/daemon/dbus/gkd-secret-lock.c +++ b/daemon/dbus/gkd-secret-lock.c @@ -65,3 +65,53 @@ gkd_secret_lock (GckObject *collection, DBusError *derr) gck_list_unref_free (objects); return TRUE; } + +gboolean +gkd_secret_lock_all (GckSession *session, + DBusError *derr) +{ + GckBuilder builder = GCK_BUILDER_INIT; + GError *error = NULL; + GList *objects, *l; + + /* Lock all the main collections */ + gck_builder_add_ulong (&builder, CKA_CLASS, CKO_G_CREDENTIAL); + gck_builder_add_boolean (&builder, CKA_GNOME_TRANSIENT, TRUE); + + objects = gck_session_find_objects (session, gck_builder_end (&builder), NULL, &error); + if (error != NULL) { + g_warning ("couldn't search for credential objects: %s", egg_error_message (error)); + dbus_set_error (derr, DBUS_ERROR_FAILED, "Couldn't lock service"); + g_clear_error (&error); + return FALSE; + } + + for (l = objects; l; l = g_list_next (l)) { + if (!gck_object_destroy (l->data, NULL, &error)) { + g_warning ("couldn't destroy credential object: %s", egg_error_message (error)); + g_clear_error (&error); + } + } + + /* Now delete all session objects */ + gck_builder_add_ulong (&builder, CKA_CLASS, CKO_SECRET_KEY); + gck_builder_add_string (&builder, CKA_G_COLLECTION, "session"); + + objects = gck_session_find_objects (session, gck_builder_end (&builder), NULL, &error); + if (error != NULL) { + g_warning ("couldn't search for session items: %s", egg_error_message (error)); + dbus_set_error (derr, DBUS_ERROR_FAILED, "Couldn't lock service"); + g_clear_error (&error); + return FALSE; + } + + for (l = objects; l; l = g_list_next (l)) { + if (!gck_object_destroy (l->data, NULL, &error)) { + g_warning ("couldn't destroy session item: %s", egg_error_message (error)); + g_clear_error (&error); + } + } + + gck_list_unref_free (objects); + return TRUE; +} diff --git a/daemon/dbus/gkd-secret-lock.h b/daemon/dbus/gkd-secret-lock.h index e8f03a71..31bd7c79 100644 --- a/daemon/dbus/gkd-secret-lock.h +++ b/daemon/dbus/gkd-secret-lock.h @@ -31,4 +31,7 @@ gboolean gkd_secret_lock (GckObject *collection, DBusError *derr); +gboolean gkd_secret_lock_all (GckSession *session, + DBusError *derr); + #endif /* __GKD_SECRET_LOCK_H__ */ diff --git a/daemon/dbus/gkd-secret-service.c b/daemon/dbus/gkd-secret-service.c index 11cdb60d..de61822a 100644 --- a/daemon/dbus/gkd-secret-service.c +++ b/daemon/dbus/gkd-secret-service.c @@ -485,10 +485,20 @@ service_method_create_collection (GkdSecretService *self, DBusMessage *message) static DBusMessage* service_method_lock_service (GkdSecretService *self, DBusMessage *message) { + DBusError derr = DBUS_ERROR_INIT; + GckSession *session; + const char *caller; + if (!dbus_message_get_args (message, NULL, DBUS_TYPE_INVALID)) return NULL; - /* TODO: Need to implement */ + caller = dbus_message_get_sender (message); + session = gkd_secret_service_get_pkcs11_session (self, caller); + g_return_val_if_fail (session != NULL, NULL); + + if (!gkd_secret_lock_all (session, &derr)) + return gkd_secret_error_to_reply (message, &derr); + return dbus_message_new_method_return (message); } diff --git a/daemon/dbus/gkd-secret-unlock.c b/daemon/dbus/gkd-secret-unlock.c index 82330c4c..b16f5f62 100644 --- a/daemon/dbus/gkd-secret-unlock.c +++ b/daemon/dbus/gkd-secret-unlock.c @@ -286,6 +286,7 @@ perform_next_unlock (GkdSecretUnlock *self) */ if (proceed) { common_unlock_attributes (&builder, collection); + gck_builder_add_boolean (&builder, CKA_GNOME_TRANSIENT, TRUE); gck_builder_add_data (&builder, CKA_VALUE, NULL, 0); session = gkd_secret_service_get_pkcs11_session (self->service, self->caller); diff --git a/daemon/dbus/tests/Makefile.am b/daemon/dbus/tests/Makefile.am index 68a7af29..d16a7dcc 100644 --- a/daemon/dbus/tests/Makefile.am +++ b/daemon/dbus/tests/Makefile.am @@ -29,7 +29,8 @@ TEST_PROGS = \ test-secret-util \ test-secret-search \ test-secret-items \ - test-secret-signals + test-secret-signals \ + test-secret-lock check_PROGRAMS = $(TEST_PROGS) diff --git a/daemon/dbus/tests/test-secret-lock.c b/daemon/dbus/tests/test-secret-lock.c new file mode 100644 index 00000000..3bb28e45 --- /dev/null +++ b/daemon/dbus/tests/test-secret-lock.c @@ -0,0 +1,134 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* test-secret-lock.c: Test secret lock + + Copyright (C) 2013 Red Hat Inc + + 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 <stefw@gnome.org> +*/ + +#include "config.h" + +#include "gkd-secret-types.h" + +#include "test-service.h" + +#include "egg/egg-testing.h" + +typedef struct { + TestService service; +} Test; + +static void +setup (Test *test, + gconstpointer unused) +{ + test_service_setup (&test->service); +} + +static void +teardown (Test *test, + gconstpointer unused) +{ + test_service_teardown (&test->service); +} + +static gboolean +get_locked (Test *test, + const gchar *path, + const gchar *interface) +{ + GVariant *retval; + GVariant *prop; + GError *error = NULL; + gboolean locked; + + retval = g_dbus_connection_call_sync (test->service.connection, + test->service.bus_name, + path, "org.freedesktop.DBus.Properties", + "Get", g_variant_new ("(ss)", interface, "Locked"), + G_VARIANT_TYPE ("(v)"), + G_DBUS_CALL_FLAGS_NO_AUTO_START, -1, NULL, &error); + g_assert_no_error (error); + + g_variant_get (retval, "(v)", &prop); + g_variant_unref (retval); + + locked = g_variant_get_boolean (prop); + g_variant_unref (prop); + + return locked; +} + + +static void +test_lock_service (Test *test, + gconstpointer unused) +{ + GError *error = NULL; + GVariant *retval; + + g_assert (get_locked (test, "/org/freedesktop/secrets/collection/test", SECRET_COLLECTION_INTERFACE) == TRUE); + + /* Unlock the test collection */ + retval = g_dbus_connection_call_sync (test->service.connection, + test->service.bus_name, + SECRET_SERVICE_PATH, + INTERNAL_SERVICE_INTERFACE, + "UnlockWithMasterPassword", + g_variant_new ("(o@(oayays))", + "/org/freedesktop/secrets/collection/test", + test_service_build_secret (&test->service, "booo")), + G_VARIANT_TYPE ("()"), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + -1, NULL, &error); + g_assert_no_error (error); + g_variant_unref (retval); + + /* Check not locked */ + g_assert (get_locked (test, "/org/freedesktop/secrets/collection/test", SECRET_COLLECTION_INTERFACE) == FALSE); + + /* Lock everything */ + retval = g_dbus_connection_call_sync (test->service.connection, + test->service.bus_name, + "/org/freedesktop/secrets", + SECRET_SERVICE_INTERFACE, + "LockService", + g_variant_new ("()"), + G_VARIANT_TYPE ("()"), + G_DBUS_CALL_FLAGS_NO_AUTO_START, + -1, NULL, &error); + g_assert_no_error (error); + g_variant_unref (retval); + + /* Check locked */ + g_assert (get_locked (test, "/org/freedesktop/secrets/collection/test", SECRET_COLLECTION_INTERFACE) == TRUE); +} + +int +main (int argc, char **argv) +{ +#if !GLIB_CHECK_VERSION(2,35,0) + g_type_init (); +#endif + g_test_init (&argc, &argv, NULL); + + g_test_add ("/secret-lock/service", Test, NULL, + setup, test_lock_service, teardown); + + return egg_tests_run_with_loop (); +} |