[gnome-keyring] Fix implementation of LockService dbus method



commit b570ac71b7e037abbb7b14d246d5a37f0afd6ba8
Author: Stef Walter <stefw gnome org>
Date:   Sat Apr 27 21:48:58 2013 +0200

    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

 daemon/dbus/gkd-secret-lock.c        |   50 +++++++++++++
 daemon/dbus/gkd-secret-lock.h        |    3 +
 daemon/dbus/gkd-secret-service.c     |   12 +++-
 daemon/dbus/gkd-secret-unlock.c      |    1 +
 daemon/dbus/tests/Makefile.am        |    3 +-
 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 9b68c46..64f0151 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 e8f03a7..31bd7c7 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 11cdb60..de61822 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 82330c4..b16f5f6 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 68a7af2..d16a7dc 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 0000000..3bb28e4
--- /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 ();
+}


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