summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stefw@gnome.org>2013-04-27 21:48:58 +0200
committerStef Walter <stefw@gnome.org>2013-04-30 18:59:11 +0200
commitb570ac71b7e037abbb7b14d246d5a37f0afd6ba8 (patch)
tree5e7236e24923330cb0afcd876d994f700cd433a8
parent6f955eeed2728f0d8cf6dc7adb4265a8725d7d50 (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.c50
-rw-r--r--daemon/dbus/gkd-secret-lock.h3
-rw-r--r--daemon/dbus/gkd-secret-service.c12
-rw-r--r--daemon/dbus/gkd-secret-unlock.c1
-rw-r--r--daemon/dbus/tests/Makefile.am3
-rw-r--r--daemon/dbus/tests/test-secret-lock.c134
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 ();
+}