[gnome-keyring/wip/gdbus: 1/9] Port gnome-keyring-daemon to GDBus



commit 38342631b75695817df10377178cf4bdd31437b2
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Sat Nov 1 14:16:39 2014 -0700

    Port gnome-keyring-daemon to GDBus
    
    This commit ports gnome-keyring-daemon from libdbus1 to GDBus.
    Unfortunately it's not really possible to split this commit into
    multiple while keeping the code building.
    
    Noteworthy is the different approach that GDBus allows us to use;
    instead of filtering every message and writing our own internal message
    routing, we can more naturally use generated skeletons and
    register/unregister them on the bus as needed.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=622905

 configure.ac                                       |    2 +-
 daemon/dbus/Makefile.am                            |   39 +-
 daemon/dbus/gkd-dbus-environment.c                 |   78 +-
 daemon/dbus/gkd-dbus-private.h                     |   18 +-
 daemon/dbus/gkd-dbus-secrets.c                     |   54 +-
 daemon/dbus/gkd-dbus-session.c                     |  183 +--
 daemon/dbus/gkd-dbus-util.c                        |  134 --
 daemon/dbus/gkd-dbus-util.h                        |   40 -
 daemon/dbus/gkd-dbus.c                             |  252 ++--
 daemon/dbus/gkd-secret-change.c                    |   12 +-
 daemon/dbus/gkd-secret-create.c                    |    9 +-
 daemon/dbus/gkd-secret-dispatch.c                  |    8 -
 daemon/dbus/gkd-secret-dispatch.h                  |    6 -
 daemon/dbus/gkd-secret-error.c                     |   70 +-
 daemon/dbus/gkd-secret-error.h                     |   24 +-
 daemon/dbus/gkd-secret-introspect.c                |  283 ----
 daemon/dbus/gkd-secret-introspect.h                |   35 -
 daemon/dbus/gkd-secret-lock.c                      |   13 +-
 daemon/dbus/gkd-secret-lock.h                      |    6 +-
 daemon/dbus/gkd-secret-objects.c                   | 1621 ++++++++++----------
 daemon/dbus/gkd-secret-objects.h                   |   45 +-
 daemon/dbus/gkd-secret-prompt.c                    |  127 +-
 daemon/dbus/gkd-secret-prompt.h                    |    5 +-
 daemon/dbus/gkd-secret-property.c                  |  235 +--
 daemon/dbus/gkd-secret-property.h                  |   14 +-
 daemon/dbus/gkd-secret-secret.c                    |  121 +-
 daemon/dbus/gkd-secret-secret.h                    |   11 +-
 daemon/dbus/gkd-secret-service.c                   | 1240 +++++++---------
 daemon/dbus/gkd-secret-service.h                   |   12 +-
 daemon/dbus/gkd-secret-session.c                   |  264 ++--
 daemon/dbus/gkd-secret-session.h                   |   12 +-
 daemon/dbus/gkd-secret-types.h                     |    7 +-
 daemon/dbus/gkd-secret-unlock.c                    |  145 +-
 daemon/dbus/gkd-secret-unlock.h                    |    2 +-
 daemon/dbus/gkd-secret-util.h                      |    2 -
 daemon/dbus/org.freedesktop.Secrets.xml            |  167 ++
 daemon/dbus/org.gnome.keyring.Daemon.xml           |   13 +
 ...ing.InternalUnsupportedGuiltRiddenInterface.xml |   25 +
 38 files changed, 2312 insertions(+), 3022 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index fee25ab..ecc84e8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -72,7 +72,7 @@ PKG_CHECK_MODULES(GOBJECT, glib-2.0 gobject-2.0)
 AC_SUBST(GOBJECT_CFLAGS)
 AC_SUBST(GOBJECT_LIBS)
 
-PKG_CHECK_MODULES(GIO, glib-2.0 gio-2.0)
+PKG_CHECK_MODULES(GIO, glib-2.0 gio-2.0 gio-unix-2.0)
 AC_SUBST(GIO_CFLAGS)
 AC_SUBST(GIO_LIBS)
 
diff --git a/daemon/dbus/Makefile.am b/daemon/dbus/Makefile.am
index 5a031ed..a4de436 100644
--- a/daemon/dbus/Makefile.am
+++ b/daemon/dbus/Makefile.am
@@ -1,15 +1,46 @@
 
 noinst_LTLIBRARIES += libgkd-dbus.la
 
+daemon/dbus/gkd-secrets-generated.h: daemon/dbus/org.freedesktop.Secrets.xml Makefile.am
+       $(AM_V_GEN) gdbus-codegen --interface-prefix org.freedesktop.Secrets. \
+       --generate-c-code $(srcdir)/daemon/dbus/gkd-secrets-generated \
+       --c-namespace Gkd \
+       $(srcdir)/daemon/dbus/org.freedesktop.Secrets.xml
+daemon/dbus/gkd-secrets-generated.c: daemon/dbus/gkd-secrets-generated.h
+       @: # generated as a side-effect
+
+daemon/dbus/gkd-daemon-generated.h: daemon/dbus/org.gnome.keyring.Daemon.xml Makefile.am
+       $(AM_V_GEN) gdbus-codegen --interface-prefix org.gnome.keyring.Daemon. \
+       --generate-c-code $(srcdir)/daemon/dbus/gkd-daemon-generated \
+       --c-namespace Gkd \
+       $(srcdir)/daemon/dbus/org.gnome.keyring.Daemon.xml
+daemon/dbus/gkd-daemon-generated.c: daemon/dbus/gkd-daemon-generated.h
+       @: # generated as a side-effect
+
+daemon/dbus/gkd-internal-generated.h: 
daemon/dbus/org.gnome.keyring.InternalUnsupportedGuiltRiddenInterface.xml Makefile.am
+       $(AM_V_GEN) gdbus-codegen --interface-prefix 
org.gnome.keyring.InternalUnsupportedGuiltRiddenInterface. \
+       --generate-c-code $(srcdir)/daemon/dbus/gkd-internal-generated \
+       --c-namespace Gkd \
+       $(srcdir)/daemon/dbus/org.gnome.keyring.InternalUnsupportedGuiltRiddenInterface.xml
+daemon/dbus/gkd-internal-generated.c: daemon/dbus/gkd-internal-generated.h
+       @: # generated as a side-effect
+
+BUILT_SOURCES += \
+       daemon/dbus/gkd-daemon-generated.c \
+       daemon/dbus/gkd-daemon-generated.h \
+       daemon/dbus/gkd-internal-generated.c \
+       daemon/dbus/gkd-internal-generated.h \
+       daemon/dbus/gkd-secrets-generated.c \
+       daemon/dbus/gkd-secrets-generated.h
+
 libgkd_dbus_la_SOURCES = \
+       $(BUILT_SOURCES) \
        daemon/dbus/gkd-dbus.c \
        daemon/dbus/gkd-dbus.h \
        daemon/dbus/gkd-dbus-environment.c \
        daemon/dbus/gkd-dbus-private.h \
        daemon/dbus/gkd-dbus-secrets.c \
        daemon/dbus/gkd-dbus-session.c \
-       daemon/dbus/gkd-dbus-util.c \
-       daemon/dbus/gkd-dbus-util.h \
        daemon/dbus/gkd-secret-change.c \
        daemon/dbus/gkd-secret-change.h \
        daemon/dbus/gkd-secret-create.c \
@@ -20,8 +51,6 @@ libgkd_dbus_la_SOURCES = \
        daemon/dbus/gkd-secret-error.h \
        daemon/dbus/gkd-secret-exchange.c \
        daemon/dbus/gkd-secret-exchange.h \
-       daemon/dbus/gkd-secret-introspect.c \
-       daemon/dbus/gkd-secret-introspect.h \
        daemon/dbus/gkd-secret-lock.c \
        daemon/dbus/gkd-secret-lock.h \
        daemon/dbus/gkd-secret-objects.c \
@@ -44,12 +73,14 @@ libgkd_dbus_la_SOURCES = \
        $(NULL)
 
 libgkd_dbus_la_LIBADD = \
+       $(GIO_LIBS) \
        $(GLIB_LIBS) \
        $(GOBJECT_LIBS)
 
 libgkd_dbus_la_CFLAGS = \
        $(DAEMON_CFLAGS) \
        $(GCR_BASE_CFLAGS) \
+       $(GIO_CFLAGS) \
        $(GOBJECT_CFLAGS)
 
 # -------------------------------------------------------------------
diff --git a/daemon/dbus/gkd-dbus-environment.c b/daemon/dbus/gkd-dbus-environment.c
index 2047226..11279bf 100644
--- a/daemon/dbus/gkd-dbus-environment.c
+++ b/daemon/dbus/gkd-dbus-environment.c
@@ -26,8 +26,6 @@
 
 #include "daemon/gkd-util.h"
 
-#include <dbus/dbus.h>
-
 #include <string.h>
 
 #define SERVICE_SESSION_MANAGER        "org.gnome.SessionManager"
@@ -35,38 +33,36 @@
 #define IFACE_SESSION_MANAGER   "org.gnome.SessionManager"
 
 void
-gkd_dbus_environment_cleanup (DBusConnection *conn)
+gkd_dbus_environment_cleanup (GDBusConnection *conn)
 {
        /* Nothing to do here */
 }
 
 static void
-on_setenv_reply (DBusPendingCall *pending, void *user_data)
+on_setenv_reply (GObject *source,
+                GAsyncResult *result,
+                gpointer user_data)
 {
-       DBusMessage *reply;
-       DBusError derr = DBUS_ERROR_INIT;
+       GError *error = NULL;
 
-       reply = dbus_pending_call_steal_reply (pending);
-       g_return_if_fail (reply);
+       g_dbus_connection_call_finish (G_DBUS_CONNECTION (source), result, &error);
 
-       if (dbus_set_error_from_message (&derr, reply)) {
-               if (dbus_error_has_name (&derr, "org.gnome.SessionManager.NotInInitialization") ||
-                   dbus_error_has_name (&derr, DBUS_ERROR_SERVICE_UNKNOWN))
-                       g_debug ("couldn't set environment variable in session: %s", derr.message);
+       if (error != NULL) {
+               gchar *dbus_error;
+               dbus_error = g_dbus_error_get_remote_error (error);
+               if (g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_SERVICE_UNKNOWN) ||
+                   g_strcmp0 (dbus_error, "org.gnome.SessionManager.NotInInitialization"))
+                       g_debug ("couldn't set environment variable in session: %s", error->message);
                else
-                       g_message ("couldn't set environment variable in session: %s", derr.message);
-               dbus_error_free (&derr);
+                       g_message ("couldn't set environment variable in session: %s", error->message);
+               g_error_free (error);
+               g_free (dbus_error);
        }
-
-       dbus_message_unref (reply);
 }
 
 static void
-setenv_request (DBusConnection *conn, const gchar *env)
+setenv_request (GDBusConnection *conn, const gchar *env)
 {
-       DBusPendingCall *pending = NULL;
-       DBusError derr = DBUS_ERROR_INIT;
-       DBusMessage *msg;
        const gchar *value;
        gchar *name;
 
@@ -78,43 +74,31 @@ setenv_request (DBusConnection *conn, const gchar *env)
        name = g_strndup (env, value - env);
        ++value;
 
-       msg = dbus_message_new_method_call (SERVICE_SESSION_MANAGER,
-                                           PATH_SESSION_MANAGER,
-                                           IFACE_SESSION_MANAGER,
-                                           "Setenv");
-       g_return_if_fail (msg);
-
-       if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &name,
-                                      DBUS_TYPE_STRING, &value,
-                                      DBUS_TYPE_INVALID))
-               g_return_if_reached ();
+       g_dbus_connection_call (conn,
+                               SERVICE_SESSION_MANAGER,
+                               PATH_SESSION_MANAGER,
+                               IFACE_SESSION_MANAGER,
+                               "Setenv",
+                               g_variant_new ("(ss)",
+                                              name,
+                                              value),
+                               NULL, G_DBUS_CALL_FLAGS_NONE,
+                               -1, NULL,
+                               on_setenv_reply, NULL);
 
        g_free (name);
-       value = name = NULL;
-
-       /* Send message and get a handle for a reply */
-       dbus_connection_send_with_reply (conn, msg, &pending, -1);
-       dbus_message_unref (msg);
-       if (pending) {
-               dbus_pending_call_set_notify (pending, on_setenv_reply, NULL, NULL);
-               dbus_pending_call_unref (pending);
-       } else {
-               g_warning ("couldn't send dbus message: %s",
-                          derr.message ? derr.message : "");
-               dbus_error_free (&derr);
-       }
 }
 
 static void
 on_watch_environment (gpointer data, gpointer user_data)
 {
-       DBusConnection *conn = user_data;
+       GDBusConnection *conn = user_data;
        const gchar *env = data;
        setenv_request (conn, env);
 }
 
 void
-gkd_dbus_environment_init (DBusConnection *conn)
+gkd_dbus_environment_init (GDBusConnection *conn)
 {
        const gchar **envp;
 
@@ -127,6 +111,6 @@ gkd_dbus_environment_init (DBusConnection *conn)
        for (; *envp; ++envp)
                setenv_request (conn, *envp);
 
-       gkd_util_watch_environment (on_watch_environment, dbus_connection_ref (conn),
-                                   (GDestroyNotify)dbus_connection_unref);
+       gkd_util_watch_environment (on_watch_environment, g_object_ref (conn),
+                                   (GDestroyNotify) g_object_unref);
 }
diff --git a/daemon/dbus/gkd-dbus-private.h b/daemon/dbus/gkd-dbus-private.h
index 893281a..1955880 100644
--- a/daemon/dbus/gkd-dbus-private.h
+++ b/daemon/dbus/gkd-dbus-private.h
@@ -24,22 +24,22 @@
 #define GKD_DBUS_PRIVATE_H
 
 #include <glib.h>
-#include <dbus/dbus.h>
+#include <gio/gio.h>
 
 /* DBus environment variables sent to session */
-void   gkd_dbus_environment_init        (DBusConnection *conn);
-void   gkd_dbus_environment_cleanup     (DBusConnection *conn);
+void   gkd_dbus_environment_init        (GDBusConnection *conn);
+void   gkd_dbus_environment_cleanup     (GDBusConnection *conn);
 
 /* The gnome-keyring Dbus service, very simple */
-void   gkd_dbus_service_init            (DBusConnection *conn);
-void   gkd_dbus_service_cleanup         (DBusConnection *conn);
+void   gkd_dbus_service_init            (GDBusConnection *conn);
+void   gkd_dbus_service_cleanup         (GDBusConnection *conn);
 
 /* DBus desktop session interaction */
-void   gkd_dbus_session_init            (DBusConnection *conn);
-void   gkd_dbus_session_cleanup         (DBusConnection *conn);
+void   gkd_dbus_session_init            (GDBusConnection *conn);
+void   gkd_dbus_session_cleanup         (GDBusConnection *conn);
 
 /* DBus secrets API */
-void   gkd_dbus_secrets_init            (DBusConnection *conn);
-void   gkd_dbus_secrets_cleanup         (DBusConnection *conn);
+void   gkd_dbus_secrets_init            (GDBusConnection *conn);
+void   gkd_dbus_secrets_cleanup         (GDBusConnection *conn);
 
 #endif /* GKD_DBUS_PRIVATE_H */
diff --git a/daemon/dbus/gkd-dbus-secrets.c b/daemon/dbus/gkd-dbus-secrets.c
index 58e0a8f..f4e38fc 100644
--- a/daemon/dbus/gkd-dbus-secrets.c
+++ b/daemon/dbus/gkd-dbus-secrets.c
@@ -33,7 +33,7 @@
 
 #include <gck/gck.h>
 
-static DBusConnection *dbus_conn = NULL;
+static GDBusConnection *dbus_conn = NULL;
 static GkdSecretService *secrets_service = NULL;
 
 static GckSlot*
@@ -66,18 +66,19 @@ calculate_secrets_slot (void)
 gboolean
 gkd_dbus_secrets_startup (void)
 {
-       DBusError error = DBUS_ERROR_INIT;
-       dbus_uint32_t result = 0;
        const gchar *service = NULL;
        unsigned int flags = 0;
        GckSlot *slot;
+       GError *error = NULL;
+       GVariant *request_variant;
+       guint res;
 
        g_return_val_if_fail (dbus_conn, FALSE);
 
 #ifdef WITH_DEBUG
        service = g_getenv ("GNOME_KEYRING_TEST_SERVICE");
        if (service && service[0])
-               flags = DBUS_NAME_FLAG_ALLOW_REPLACEMENT | DBUS_NAME_FLAG_REPLACE_EXISTING;
+               flags = G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT | G_BUS_NAME_OWNER_FLAGS_REPLACE;
        else
 #endif
                service = SECRET_SERVICE;
@@ -87,29 +88,37 @@ gkd_dbus_secrets_startup (void)
        g_return_val_if_fail (slot, FALSE);
 
        /* Try and grab our name */
-       result = dbus_bus_request_name (dbus_conn, service, flags, &error);
-       if (dbus_error_is_set (&error)) {
+       request_variant = g_dbus_connection_call_sync (dbus_conn,
+                                                      "org.freedesktop.DBus",  /* bus name */
+                                                      "/org/freedesktop/DBus", /* object path */
+                                                      "org.freedesktop.DBus",  /* interface name */
+                                                      "RequestName",           /* method name */
+                                                      g_variant_new ("(su)",
+                                                                     service,
+                                                                     flags),
+                                                      G_VARIANT_TYPE ("(u)"),
+                                                      G_DBUS_CALL_FLAGS_NONE,
+                                                      -1, NULL, &error);
+
+       if (error != NULL) {
                g_message ("couldn't request name '%s' on session bus: %s",
-                          service, error.message);
-               dbus_error_free (&error);
-
+                          service, error->message);
+               g_error_free (error);
        } else {
-               switch (result) {
+               g_variant_get (request_variant, "(u)", &res);
+               g_variant_unref (request_variant);
 
+               switch (res) {
                /* We acquired the service name */
-               case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER:
-                       break;
-
+               case 1: /* DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER */
                /* We already acquired the service name. */
-               case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:
+               case 4: /* DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER */
                        break;
-
                /* Another daemon is running */
-               case DBUS_REQUEST_NAME_REPLY_IN_QUEUE:
-               case DBUS_REQUEST_NAME_REPLY_EXISTS:
+               case 2: /* DBUS_REQUEST_NAME_REPLY_IN_QUEUE */
+               case 3: /* DBUS_REQUEST_NAME_REPLY_EXISTS */
                        g_message ("another secret service is running");
                        break;
-
                default:
                        g_return_val_if_reached (FALSE);
                        break;
@@ -128,19 +137,18 @@ static void
 cleanup_dbus_conn (gpointer unused)
 {
        g_assert (dbus_conn);
-       dbus_connection_unref (dbus_conn);
-       dbus_conn = NULL;
+       g_clear_object (&dbus_conn);
 }
 
 void
-gkd_dbus_secrets_init (DBusConnection *conn)
+gkd_dbus_secrets_init (GDBusConnection *conn)
 {
-       dbus_conn = dbus_connection_ref (conn);
+       dbus_conn = g_object_ref (conn);
        egg_cleanup_register (cleanup_dbus_conn, NULL);
 }
 
 void
-gkd_dbus_secrets_cleanup (DBusConnection *conn)
+gkd_dbus_secrets_cleanup (GDBusConnection *conn)
 {
        if (secrets_service) {
                g_object_run_dispose (G_OBJECT (secrets_service));
diff --git a/daemon/dbus/gkd-dbus-session.c b/daemon/dbus/gkd-dbus-session.c
index 5f09772..5fe687a 100644
--- a/daemon/dbus/gkd-dbus-session.c
+++ b/daemon/dbus/gkd-dbus-session.c
@@ -26,8 +26,6 @@
 
 #include "daemon/gkd-main.h"
 
-#include <dbus/dbus.h>
-
 #include <string.h>
 
 #define SERVICE_SESSION_MANAGER        "org.gnome.SessionManager"
@@ -37,108 +35,89 @@
 #define IFACE_SESSION_PRIVATE   "org.gnome.SessionManager.ClientPrivate"
 
 static gchar *client_session_path = NULL;
-static gchar *client_session_rule = NULL;
+static guint  client_session_signal_id = 0;
 
 static void
-send_end_session_response (DBusConnection *conn)
+send_end_session_response (GDBusConnection *conn)
 {
-       DBusMessageIter args;
-       DBusMessage *msg;
-       DBusMessage *reply;
-       DBusError derr = { 0 };
        const gchar *reason = "";
-       dbus_bool_t is_ok = TRUE;
+       gboolean is_ok = TRUE;
+       GError *error = NULL;
 
        g_return_if_fail (client_session_path);
 
-       msg = dbus_message_new_method_call (SERVICE_SESSION_MANAGER,
-                                           client_session_path,
-                                           IFACE_SESSION_PRIVATE,
-                                           "EndSessionResponse");
-       g_return_if_fail (msg);
-
-       dbus_message_iter_init_append (msg, &args);
-       if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_BOOLEAN, &is_ok) ||
-           !dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &reason))
-               g_return_if_reached ();
-
-       reply = dbus_connection_send_with_reply_and_block (conn, msg, 1000, &derr);
-       dbus_message_unref (msg);
-
-       if (!reply) {
-               g_message ("dbus failure responding to ending session: %s", derr.message);
+       g_dbus_connection_call_sync (conn,
+                                    SERVICE_SESSION_MANAGER,
+                                    client_session_path,
+                                    IFACE_SESSION_PRIVATE,
+                                    "EndSessionResponse",
+                                    g_variant_new ("(bs)",
+                                                   is_ok,
+                                                   reason),
+                                    NULL,
+                                    G_DBUS_CALL_FLAGS_NONE, 1000,
+                                    NULL, &error);
+
+       if (error != NULL) {
+               g_message ("dbus failure responding to ending session: %s", error->message);
+               g_error_free (error);
                return;
        }
-
-       dbus_message_unref (reply);
 }
 
 static void
-unregister_daemon_in_session (DBusConnection *conn)
+unregister_daemon_in_session (GDBusConnection *conn)
 {
-       DBusMessageIter args;
-       DBusMessage *msg;
-
-       if (client_session_rule) {
-               dbus_bus_remove_match (conn, client_session_rule, NULL);
-               g_free (client_session_rule);
-               client_session_rule = NULL;
+       if (client_session_signal_id) {
+               g_dbus_connection_signal_unsubscribe (conn, client_session_signal_id);
+               client_session_signal_id = 0;
        }
 
        if (!client_session_path)
                return;
 
-       msg = dbus_message_new_method_call (SERVICE_SESSION_MANAGER,
-                                           PATH_SESSION_MANAGER,
-                                           IFACE_SESSION_MANAGER,
-                                           "UnregisterClient");
-       g_return_if_fail (msg);
-
-       dbus_message_iter_init_append (msg, &args);
-       if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_OBJECT_PATH, &client_session_path))
-               g_return_if_reached ();
-
-       dbus_message_set_no_reply (msg, TRUE);
-       dbus_connection_send (conn, msg, NULL);
-       dbus_connection_flush (conn);
-       dbus_message_unref (msg);
+       g_dbus_connection_call_sync (conn,
+                                    SERVICE_SESSION_MANAGER,
+                                    PATH_SESSION_MANAGER,
+                                    IFACE_SESSION_MANAGER,
+                                    "UnregisterClient",
+                                    g_variant_new ("(o)", client_session_path),
+                                    NULL, G_DBUS_CALL_FLAGS_NONE,
+                                    -1, NULL, NULL);
 
        g_free (client_session_path);
        client_session_path = NULL;
 }
 
-static DBusHandlerResult
-signal_filter (DBusConnection *conn, DBusMessage *msg, void *user_data)
+static void
+signal_filter (GDBusConnection *conn,
+              const gchar *sender_name,
+              const gchar *object_path,
+              const gchar *interface_name,
+              const gchar *signal_name,
+              GVariant *parameters,
+              gpointer user_data)
 {
        /* Quit the daemon when the session is over */
-       if (dbus_message_is_signal (msg, IFACE_SESSION_PRIVATE, "Stop")) {
+       if (g_strcmp0 (signal_name, "Stop") == 0) {
                unregister_daemon_in_session (conn);
                gkd_main_quit ();
-               return DBUS_HANDLER_RESULT_HANDLED;
-       } else if (dbus_message_is_signal (msg, IFACE_SESSION_PRIVATE, "QueryEndSession")) {
+       } else if (g_strcmp0 (signal_name, "QueryEndSession") == 0) {
                send_end_session_response (conn);
-               return DBUS_HANDLER_RESULT_HANDLED;
-       } else if (dbus_message_is_signal (msg, IFACE_SESSION_PRIVATE, "EndSession")) {
+       } else if (g_strcmp0 (signal_name, "EndSession") == 0) {
                send_end_session_response (conn);
                unregister_daemon_in_session (conn);
                gkd_main_quit ();
-               return DBUS_HANDLER_RESULT_HANDLED;
-       } else if (dbus_message_is_signal (msg, DBUS_INTERFACE_LOCAL, "Disconnected")) {
+       } else if (g_strcmp0 (signal_name, "Disconnected") == 0) {
                gkd_main_quit ();
-               return DBUS_HANDLER_RESULT_HANDLED;
        }
-
-       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 }
 
 void
-gkd_dbus_session_cleanup (DBusConnection *conn)
+gkd_dbus_session_cleanup (GDBusConnection *conn)
 {
        g_free (client_session_path);
        client_session_path = NULL;
-
-       g_free (client_session_rule);
-       client_session_rule = NULL;
 }
 
 /*
@@ -146,50 +125,37 @@ gkd_dbus_session_cleanup (DBusConnection *conn)
  * session manager via DBus.
  */
 void
-gkd_dbus_session_init (DBusConnection *conn)
+gkd_dbus_session_init (GDBusConnection *conn)
 {
-       DBusMessageIter args;
-       DBusMessage *msg;
-       DBusMessage *reply;
-       DBusError derr = { 0 };
        const gchar *app_id = "gnome-keyring-daemon";
        const gchar *client_id;
+       GError *error = NULL;
+       GVariant *object_path_variant;
 
        client_id = g_getenv ("DESKTOP_AUTOSTART_ID");
        if (!client_id)
                return;
 
-       msg = dbus_message_new_method_call (SERVICE_SESSION_MANAGER,
-                                           PATH_SESSION_MANAGER,
-                                           IFACE_SESSION_MANAGER,
-                                           "RegisterClient");
-       g_return_if_fail (msg);
-
-       dbus_message_iter_init_append (msg, &args);
-       if (!dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &app_id) ||
-           !dbus_message_iter_append_basic (&args, DBUS_TYPE_STRING, &client_id))
-               g_return_if_reached ();
-
-       /* Send message and get a handle for a reply */
-       reply = dbus_connection_send_with_reply_and_block (conn, msg, 1000, &derr);
-       dbus_message_unref (msg);
-
-       if (!reply) {
-               g_message ("couldn't register in session: %s", derr.message);
-               dbus_error_free (&derr);
+       object_path_variant = g_dbus_connection_call_sync (conn,
+                                                          SERVICE_SESSION_MANAGER,
+                                                          PATH_SESSION_MANAGER,
+                                                          IFACE_SESSION_MANAGER,
+                                                          "RegisterClient",
+                                                          g_variant_new ("(ss)",
+                                                                         app_id,
+                                                                         client_id),
+                                                          G_VARIANT_TYPE ("(o)"),
+                                                          G_DBUS_CALL_FLAGS_NONE, 1000,
+                                                          NULL, &error);
+
+       if (error != NULL) {
+               g_message ("couldn't register in session: %s", error->message);
+               g_error_free (error);
                return;
        }
 
-       /* Get out our client path */
-       if (!dbus_message_iter_init (reply, &args) ||
-           dbus_message_iter_get_arg_type (&args) != DBUS_TYPE_OBJECT_PATH) {
-               g_message ("invalid register response from session");
-       } else {
-               dbus_message_iter_get_basic (&args, &client_session_path);
-               client_session_path = g_strdup (client_session_path);
-       }
-
-       dbus_message_unref (reply);
+       g_variant_get (object_path_variant, "(o)", &client_session_path);
+       g_variant_unref (object_path_variant);
 
        /*
         * Unset DESKTOP_AUTOSTART_ID in order to avoid child processes to
@@ -201,19 +167,10 @@ gkd_dbus_session_init (DBusConnection *conn)
         * Now we register for DBus signals on that client session path
         * These are fired specifically for us.
         */
-       client_session_rule = g_strdup_printf("type='signal',"
-                                             "interface='org.gnome.SessionManager.ClientPrivate',"
-                                             "path='%s'",
-                                             client_session_path);
-       dbus_bus_add_match (conn, client_session_rule, &derr);
-
-       if(dbus_error_is_set(&derr)) {
-               g_message ("couldn't listen for signals in session: %s", derr.message);
-               dbus_error_free (&derr);
-               g_free (client_session_rule);
-               client_session_rule = NULL;
-               return;
-       }
-
-       dbus_connection_add_filter (conn, signal_filter, NULL, NULL);
+       g_dbus_connection_signal_subscribe (conn,
+                                           NULL,
+                                           "org.gnome.SessionManager.ClientPrivate", NULL,
+                                           client_session_path, NULL,
+                                           G_DBUS_SIGNAL_FLAGS_NONE,
+                                           signal_filter, NULL, NULL);
 }
diff --git a/daemon/dbus/gkd-dbus.c b/daemon/dbus/gkd-dbus.c
index e13e88d..a7a4a72 100644
--- a/daemon/dbus/gkd-dbus.c
+++ b/daemon/dbus/gkd-dbus.c
@@ -22,6 +22,7 @@
 
 #include "config.h"
 
+#include "gkd-daemon-generated.h"
 #include "gkd-dbus.h"
 #include "gkd-dbus-private.h"
 
@@ -32,10 +33,9 @@
 #include "egg/egg-dbus.h"
 
 #include <glib.h>
+#include <gio/gio.h>
 
-#include <dbus/dbus.h>
-
-static DBusConnection *dbus_conn = NULL;
+static GDBusConnection *dbus_conn = NULL;
 static gboolean object_registered = FALSE;
 static gboolean acquired_asked = FALSE;
 static gboolean acquired_service = FALSE;
@@ -50,9 +50,7 @@ cleanup_session_bus (gpointer unused)
        if (!dbus_conn)
                return;
 
-       egg_dbus_disconnect_from_mainloop (dbus_conn, NULL);
-       dbus_connection_unref (dbus_conn);
-       dbus_conn = NULL;
+       g_clear_object (&dbus_conn);
 }
 
 static void
@@ -65,112 +63,78 @@ on_connection_close (gpointer user_data)
 static gboolean
 connect_to_session_bus (void)
 {
-       DBusError derr = { 0 };
+       GError *error = NULL;
 
        if (dbus_conn)
                return TRUE;
 
-       dbus_error_init (&derr);
-
-       /* Get the dbus bus and hook up */
-       dbus_conn = dbus_bus_get (DBUS_BUS_SESSION, &derr);
+       dbus_conn = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
        if (!dbus_conn) {
-               g_message ("couldn't connect to dbus session bus: %s", derr.message);
-               dbus_error_free (&derr);
+               g_message ("couldn't connect to dbus session bus: %s", error->message);
+               g_error_free (error);
                return FALSE;
        }
 
-       egg_dbus_connect_with_mainloop (dbus_conn, NULL, on_connection_close);
-       dbus_connection_set_exit_on_disconnect (dbus_conn, FALSE);
+       g_signal_connect (dbus_conn, "closed",
+                         G_CALLBACK (on_connection_close), NULL);
        egg_cleanup_register (cleanup_session_bus, NULL);
        return TRUE;
 }
 
-static DBusHandlerResult
-message_handler_cb (DBusConnection *conn, DBusMessage *message, void *user_data)
+static gboolean
+handle_get_environment (GkdOrgGnomeKeyringDaemon *skeleton,
+                       GDBusMethodInvocation *invocation,
+                       gpointer user_data)
 {
-       /*
-        * Here we handle the requests to our own gnome-keyring DBus interfaces
-        */
-
-       DBusMessageIter args;
-       DBusMessage *reply = NULL;
-
-       /* GetEnvironment */
-       if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL &&
-           dbus_message_is_method_call (message, GNOME_KEYRING_DAEMON_INTERFACE, "GetEnvironment") &&
-           g_str_equal (dbus_message_get_signature (message), "")) {
-
-               const gchar **env;
-               DBusMessageIter items, entry;
-               gchar **parts;
-
-               env = gkd_util_get_environment ();
-               g_return_val_if_fail (env, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
-
-               /* Setup the result */
-               reply = dbus_message_new_method_return (message);
-               dbus_message_iter_init_append (reply, &args);
-               if (!dbus_message_iter_open_container (&args, DBUS_TYPE_ARRAY, "{ss}", &items))
-                       g_return_val_if_reached (DBUS_HANDLER_RESULT_NEED_MEMORY);
-               while (*env) {
-                       parts = g_strsplit (*env, "=", 2);
-                       g_return_val_if_fail (parts && parts[0] && parts[1], 
DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
-                       if (!dbus_message_iter_open_container (&items, DBUS_TYPE_DICT_ENTRY, NULL, &entry) ||
-                           !dbus_message_iter_append_basic (&entry, DBUS_TYPE_STRING, &parts[0]) ||
-                           !dbus_message_iter_append_basic (&entry, DBUS_TYPE_STRING, &parts[1]) ||
-                           !dbus_message_iter_close_container (&items, &entry))
-                               g_return_val_if_reached (DBUS_HANDLER_RESULT_NEED_MEMORY);
-                       ++env;
-               }
-               if (!dbus_message_iter_close_container (&args, &items))
-                       g_return_val_if_reached (DBUS_HANDLER_RESULT_NEED_MEMORY);
-
-       /* GetControlDirectory */
-       } else if (dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL &&
-                  dbus_message_is_method_call (message, GNOME_KEYRING_DAEMON_INTERFACE, 
"GetControlDirectory") &&
-                  g_str_equal (dbus_message_get_signature (message), "")) {
-
-               /* Setup the result */
-               const gchar *directory = gkd_util_get_master_directory ();
-               reply = dbus_message_new_method_return (message);
-               dbus_message_append_args (reply, DBUS_TYPE_STRING, &directory, DBUS_TYPE_INVALID);
-
-       /* Unknown call */
-       } else {
-               return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-       }
+       const gchar **env;
+       gchar **parts;
+       GVariantBuilder builder;
 
-       /* Send the reply */
-       if (!dbus_connection_send (conn, reply, NULL))
-               g_return_val_if_reached (DBUS_HANDLER_RESULT_NEED_MEMORY);
-       dbus_connection_flush (conn);
+       env = gkd_util_get_environment ();
+       g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}"));
 
-       return DBUS_HANDLER_RESULT_HANDLED;
+       while (*env) {
+               parts = g_strsplit (*env, "=", 2);
+               g_variant_builder_add (&builder, "{ss}", parts[0], parts[1]);
+               g_strfreev (parts);
+       }
+
+       gkd_org_gnome_keyring_daemon_complete_get_environment (skeleton, invocation,
+                                                              g_variant_builder_end (&builder));
+       return TRUE;
 }
 
-static DBusObjectPathVTable object_vtable  = {
-       NULL,
-       message_handler_cb,
-       NULL,
-};
+static gboolean
+handle_get_control_directory (GkdOrgGnomeKeyringDaemon *skeleton,
+                             GDBusMethodInvocation *invocation,
+                             gpointer user_data)
+{
+       gkd_org_gnome_keyring_daemon_complete_get_control_directory (skeleton, invocation,
+                                                                    gkd_util_get_master_directory ());
+       return TRUE;
+}
 
 static void
-cleanup_singleton (gpointer unused)
+cleanup_singleton (gpointer user_data)
 {
+       GkdOrgGnomeKeyringDaemon *skeleton = user_data;
+
        g_return_if_fail (dbus_conn);
-       if (object_registered)
-               dbus_connection_unregister_object_path (dbus_conn, GNOME_KEYRING_DAEMON_PATH);
+       if (object_registered) {
+               g_dbus_interface_skeleton_unexport_from_connection (G_DBUS_INTERFACE_SKELETON (skeleton), 
dbus_conn);
+               g_object_unref (skeleton);
+       }
        object_registered = FALSE;
 }
 
 gboolean
 gkd_dbus_singleton_acquire (gboolean *acquired)
 {
-       DBusError derr = DBUS_ERROR_INIT;
-       dbus_uint32_t res = 0;
        const gchar *service = NULL;
-       unsigned int flags = 0;
+       GBusNameOwnerFlags flags = G_BUS_NAME_OWNER_FLAGS_NONE;
+       GVariant *acquire_variant;
+       guint res;
+       GError *error = NULL;
 
        g_assert (acquired);
 
@@ -179,63 +143,88 @@ gkd_dbus_singleton_acquire (gboolean *acquired)
 
        /* First register the object */
        if (!object_registered) {
-               if (dbus_connection_register_object_path (dbus_conn, GNOME_KEYRING_DAEMON_PATH,
-                                                         &object_vtable, NULL)) {
+               GError *error = NULL;
+               GkdOrgGnomeKeyringDaemon *skeleton = gkd_org_gnome_keyring_daemon_skeleton_new ();
+
+               g_signal_connect (skeleton, "handle-get-control-directory",
+                                 G_CALLBACK (handle_get_control_directory), NULL);
+               g_signal_connect (skeleton, "handle-get-environment",
+                                 G_CALLBACK (handle_get_environment), NULL);
+
+               g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (skeleton), dbus_conn,
+                                                 GNOME_KEYRING_DAEMON_PATH, &error);
+
+               if (error == NULL) {
                        object_registered = TRUE;
-                       egg_cleanup_register (cleanup_singleton, NULL);
+                       egg_cleanup_register (cleanup_singleton, skeleton);
                } else {
-                       g_message ("couldn't register dbus object path");
+                       g_message ("couldn't register dbus object path: %s", error->message);
+                       g_error_free (error);
                }
        }
 
        /* Try and grab our name */
        if (!acquired_asked) {
-
 #ifdef WITH_DEBUG
                service = g_getenv ("GNOME_KEYRING_TEST_SERVICE");
                if (service && service[0])
-                       flags = DBUS_NAME_FLAG_ALLOW_REPLACEMENT | DBUS_NAME_FLAG_REPLACE_EXISTING;
+                       flags = G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT | G_BUS_NAME_OWNER_FLAGS_REPLACE;
                else
 #endif
                        service = GNOME_KEYRING_DAEMON_SERVICE;
 
-               res = dbus_bus_request_name (dbus_conn, service, flags, &derr);
-               if (dbus_error_is_set (&derr)) {
-                       g_message ("couldn't request name '%s' on session bus: %s", service, derr.message);
-                       dbus_error_free (&derr);
+               /* attempt to acquire the name */
+               acquire_variant = g_dbus_connection_call_sync (dbus_conn,
+                                                              "org.freedesktop.DBus",  /* bus name */
+                                                              "/org/freedesktop/DBus", /* object path */
+                                                              "org.freedesktop.DBus",  /* interface name */
+                                                              "RequestName",           /* method name */
+                                                              g_variant_new ("(su)",
+                                                                             service,
+                                                                             flags),
+                                                              G_VARIANT_TYPE ("(u)"),
+                                                              G_DBUS_CALL_FLAGS_NONE,
+                                                              -1, NULL, &error);
+
+               if (error != NULL) {
+                       g_message ("couldn't request name '%s' on session bus: %s", service, error->message);
+                       g_error_free (error);
                        return FALSE;
                }
 
                acquired_asked = TRUE;
+               g_variant_get (acquire_variant, "(u)", &res);
+               g_variant_unref (acquire_variant);
+
                switch (res) {
-               /* We acquired the service name */
-               case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER:
-               case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:
-                       acquired_service = TRUE;
-                       break;
-                       /* Another daemon is running */
-               case DBUS_REQUEST_NAME_REPLY_IN_QUEUE:
-               case DBUS_REQUEST_NAME_REPLY_EXISTS:
-                       acquired_service = FALSE;
-                       break;
-               default:
-                       acquired_service = FALSE;
-                       g_return_val_if_reached (FALSE);
-                       break;
-               };
+               /* We acquired the service name */
+               case 1: /* DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER */
+               case 4: /* DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER */
+                       acquired_service = TRUE;
+                       break;
+               /* Another daemon is running */
+               case 2: /* DBUS_REQUEST_NAME_REPLY_IN_QUEUE */
+               case 3: /* DBUS_REQUEST_NAME_REPLY_EXISTS */
+                       acquired_service = FALSE;
+                       break;
+               default:
+                       acquired_service = FALSE;
+                       g_return_val_if_reached (FALSE);
+                       break;
+               };
        }
 
        *acquired = acquired_service;
+
        return TRUE;
 }
 
 gchar*
 gkd_dbus_singleton_control (void)
 {
-       DBusError derr = DBUS_ERROR_INIT;
-       DBusMessage *msg, *reply;
        gchar *control = NULL;
-       const char *path;
+       GError *error = NULL;
+       GVariant *control_variant;
 
        /* If tried to aquire the service must have failed */
        g_return_val_if_fail (!acquired_service, NULL);
@@ -243,34 +232,25 @@ gkd_dbus_singleton_control (void)
        if (!connect_to_session_bus ())
                return NULL;
 
-       msg = dbus_message_new_method_call (GNOME_KEYRING_DAEMON_SERVICE,
-                                           GNOME_KEYRING_DAEMON_PATH,
-                                           GNOME_KEYRING_DAEMON_INTERFACE,
-                                           "GetControlDirectory");
-       g_return_val_if_fail (msg, NULL);
-       dbus_message_set_auto_start (msg, FALSE);
-
-       /* Send message and get a handle for a reply */
-       reply = dbus_connection_send_with_reply_and_block (dbus_conn, msg, 1000, &derr);
-       dbus_message_unref (msg);
-
-       if (!reply) {
-               if (!dbus_error_has_name (&derr, "org.freedesktop.DBus.Error.NameHasNoOwner"))
-                       g_message ("couldn't communicate with already running daemon: %s", derr.message);
-               dbus_error_free (&derr);
+       control_variant = g_dbus_connection_call_sync (dbus_conn,
+                                                      GNOME_KEYRING_DAEMON_SERVICE,
+                                                      GNOME_KEYRING_DAEMON_PATH,
+                                                      GNOME_KEYRING_DAEMON_INTERFACE,
+                                                      "GetControlDirectory",
+                                                      NULL, NULL,
+                                                      G_DBUS_CALL_FLAGS_NO_AUTO_START,
+                                                      1000, NULL, &error);
+
+       if (error != NULL) {
+               if (!g_error_matches (error, G_DBUS_ERROR, G_DBUS_ERROR_NAME_HAS_NO_OWNER))
+                       g_message ("couldn't communicate with already running daemon: %s", error->message);
+               g_error_free (error);
                return NULL;
        }
 
-       /* Get out our client path */
-       if (!dbus_message_get_args (reply, &derr, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID)) {
-               g_message ("couldn't parse response from already running daemon: %s", derr.message);
-               dbus_error_free (&derr);
-               control = NULL;
-       } else {
-               control = g_strdup (path);
-       }
+       g_variant_get (control_variant, "(s)", &control);
+       g_variant_unref (control_variant);
 
-       dbus_message_unref (reply);
        return control;
 }
 
diff --git a/daemon/dbus/gkd-secret-change.c b/daemon/dbus/gkd-secret-change.c
index 62a1519..24466ea 100644
--- a/daemon/dbus/gkd-secret-change.c
+++ b/daemon/dbus/gkd-secret-change.c
@@ -26,7 +26,6 @@
 #include "gkd-secret-service.h"
 #include "gkd-secret-session.h"
 #include "gkd-secret-types.h"
-#include "gkd-secret-util.h"
 
 #include "egg/egg-error.h"
 #include "egg/egg-secure-memory.h"
@@ -337,15 +336,10 @@ gkd_secret_change_prompt_ready (GkdSecretPrompt *prompt)
        g_clear_object (&collection);
 }
 
-static void
-gkd_secret_change_encode_result (GkdSecretPrompt *base, DBusMessageIter *iter)
+static GVariant *
+gkd_secret_change_encode_result (GkdSecretPrompt *base)
 {
-       DBusMessageIter variant;
-       const gchar *string = "";
-
-       dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, "s", &variant);
-       dbus_message_iter_append_basic (&variant, DBUS_TYPE_STRING, &string);
-       dbus_message_iter_close_container (iter, &variant);
+        return g_variant_new_variant (g_variant_new_string (""));
 }
 
 static void
diff --git a/daemon/dbus/gkd-secret-create.c b/daemon/dbus/gkd-secret-create.c
index 9452941..9e7c2d4 100644
--- a/daemon/dbus/gkd-secret-create.c
+++ b/daemon/dbus/gkd-secret-create.c
@@ -292,17 +292,14 @@ gkd_secret_create_prompt_ready (GkdSecretPrompt *prompt)
        perform_prompting (GKD_SECRET_CREATE (prompt));
 }
 
-static void
-gkd_secret_create_encode_result (GkdSecretPrompt *base, DBusMessageIter *iter)
+static GVariant *
+gkd_secret_create_encode_result (GkdSecretPrompt *base)
 {
        GkdSecretCreate *self = GKD_SECRET_CREATE (base);
-       DBusMessageIter variant;
        const gchar *path;
 
-       dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, "o", &variant);
        path = self->result_path ? self->result_path : "/";
-       dbus_message_iter_append_basic (&variant, DBUS_TYPE_OBJECT_PATH, &path);
-       dbus_message_iter_close_container (iter, &variant);
+        return g_variant_new_variant (g_variant_new_object_path (path));
 }
 
 static void
diff --git a/daemon/dbus/gkd-secret-dispatch.c b/daemon/dbus/gkd-secret-dispatch.c
index d1d9450..fed4c13 100644
--- a/daemon/dbus/gkd-secret-dispatch.c
+++ b/daemon/dbus/gkd-secret-dispatch.c
@@ -54,14 +54,6 @@ gkd_secret_dispatch_get_type (void)
        return type;
 }
 
-DBusMessage*
-gkd_secret_dispatch_message (GkdSecretDispatch *self, DBusMessage *message)
-{
-       g_return_val_if_fail (GKD_SECRET_IS_DISPATCH (self), NULL);
-       g_return_val_if_fail (GKD_SECRET_DISPATCH_GET_INTERFACE (self)->dispatch_message, NULL);
-       return GKD_SECRET_DISPATCH_GET_INTERFACE (self)->dispatch_message (self, message);
-}
-
 const gchar*
 gkd_secret_dispatch_get_object_path (GkdSecretDispatch *self)
 {
diff --git a/daemon/dbus/gkd-secret-dispatch.h b/daemon/dbus/gkd-secret-dispatch.h
index 5f0470a..6958603 100644
--- a/daemon/dbus/gkd-secret-dispatch.h
+++ b/daemon/dbus/gkd-secret-dispatch.h
@@ -23,8 +23,6 @@
 
 #include "gkd-secret-types.h"
 
-#include <dbus/dbus.h>
-
 #include <glib-object.h>
 
 G_BEGIN_DECLS
@@ -40,16 +38,12 @@ struct _GkdSecretDispatchIface {
        GTypeInterface parent;
 
        const gchar* (*get_path) (GkdSecretDispatch *self);
-       DBusMessage* (*dispatch_message) (GkdSecretDispatch *self, DBusMessage *message);
 };
 
 GType                  gkd_secret_dispatch_get_type                          (void) G_GNUC_CONST;
 
 const gchar*           gkd_secret_dispatch_get_object_path                   (GkdSecretDispatch *self);
 
-DBusMessage*           gkd_secret_dispatch_message                           (GkdSecretDispatch *self,
-                                                                              DBusMessage *message);
-
 G_END_DECLS
 
 #endif /* __GKD_SECRET_DISPATCH_H__ */
diff --git a/daemon/dbus/gkd-secret-error.c b/daemon/dbus/gkd-secret-error.c
index dd06eca..de286c4 100644
--- a/daemon/dbus/gkd-secret-error.c
+++ b/daemon/dbus/gkd-secret-error.c
@@ -28,52 +28,66 @@
 
 #include <glib.h>
 
-DBusMessage*
-gkd_secret_error_no_such_object (DBusMessage *message)
+static const GDBusErrorEntry gkd_secret_error_entries[] = {
+        { GKD_SECRET_ERROR_ALREADY_EXISTS, SECRET_INTERFACE_PREFIX "Error.AlreadyExists" },
+        { GKD_SECRET_ERROR_IS_LOCKED, SECRET_INTERFACE_PREFIX "Error.IsLocked" },
+        { GKD_SECRET_ERROR_NO_SESSION, SECRET_INTERFACE_PREFIX "Error.NoSession" },
+        { GKD_SECRET_ERROR_NO_SUCH_OBJECT, SECRET_INTERFACE_PREFIX "Error.NoSuchObject" }
+};
+
+GQuark
+gkd_secret_error_quark (void)
 {
-       g_return_val_if_fail (message, NULL);
-       return dbus_message_new_error_printf (message, SECRET_ERROR_NO_SUCH_OBJECT,
-                                             "The '%s' object does not exist", dbus_message_get_path 
(message));
+        static volatile gsize quark_volatile = 0;
+
+        g_dbus_error_register_error_domain ("gkd_secret_error",
+                                            &quark_volatile,
+                                            gkd_secret_error_entries,
+                                            G_N_ELEMENTS (gkd_secret_error_entries));
+        return quark_volatile;
 }
 
-DBusMessage*
-gkd_secret_error_to_reply (DBusMessage *message, DBusError *derr)
-{
-       DBusMessage *reply;
+static const GDBusErrorEntry gkd_secret_daemon_error_entries[] = {
+       { GKD_SECRET_DAEMON_ERROR_DENIED, "org.gnome.keyring.Error.Denied" }
+};
 
-       g_return_val_if_fail (message, NULL);
-       g_return_val_if_fail (derr, NULL);
-       g_return_val_if_fail (dbus_error_is_set (derr), NULL);
+GQuark
+gkd_secret_daemon_error_quark (void)
+{
+        static volatile gsize quark_volatile = 0;
 
-       reply = dbus_message_new_error (message, derr->name, derr->message);
-       dbus_error_free (derr);
-       return reply;
+        g_dbus_error_register_error_domain ("gkd_secret_daemon_error",
+                                            &quark_volatile,
+                                            gkd_secret_daemon_error_entries,
+                                            G_N_ELEMENTS (gkd_secret_daemon_error_entries));
+        return quark_volatile;
 }
 
-DBusMessage *
-gkd_secret_propagate_error (DBusMessage *message,
+void
+gkd_secret_propagate_error (GDBusMethodInvocation *invocation,
                             const gchar *description,
                             GError *error)
 {
-       DBusError derr = DBUS_ERROR_INIT;
-
-       g_return_val_if_fail (error != NULL, NULL);
-
        if (g_error_matches (error, GCK_ERROR, CKR_USER_NOT_LOGGED_IN) ||
            g_error_matches (error, GCK_ERROR, CKR_PIN_INCORRECT)) {
-               dbus_set_error (&derr, INTERNAL_ERROR_DENIED, "The password was invalid");
-
+               g_dbus_method_invocation_return_error_literal (invocation,
+                                                               GKD_SECRET_DAEMON_ERROR,
+                                                              GKD_SECRET_DAEMON_ERROR_DENIED,
+                                                              "The password was invalid");
        } else if (g_error_matches (error, GCK_ERROR, CKR_WRAPPED_KEY_INVALID) ||
                   g_error_matches (error, GCK_ERROR, CKR_WRAPPED_KEY_LEN_RANGE) ||
                   g_error_matches (error, GCK_ERROR, CKR_MECHANISM_PARAM_INVALID)) {
-               dbus_set_error_const (&derr, DBUS_ERROR_INVALID_ARGS,
-                                     "The secret was transferred or encrypted in an invalid way.");
-
+               g_dbus_method_invocation_return_error_literal (invocation,
+                                                               G_DBUS_ERROR,
+                                                               G_DBUS_ERROR_INVALID_ARGS,
+                                                               "The secret was transferred or encrypted in 
an invalid way.");
        } else {
                g_warning ("%s: %s", description, egg_error_message (error));
-               dbus_set_error (&derr, DBUS_ERROR_FAILED, "Couldn't create new collection");
+               g_dbus_method_invocation_return_error_literal (invocation,
+                                                               G_DBUS_ERROR,
+                                                               G_DBUS_ERROR_FAILED,
+                                                               "Couldn't create new collection");
        }
 
        g_error_free (error);
-       return gkd_secret_error_to_reply (message, &derr);
 }
diff --git a/daemon/dbus/gkd-secret-error.h b/daemon/dbus/gkd-secret-error.h
index f5c483d..8c40222 100644
--- a/daemon/dbus/gkd-secret-error.h
+++ b/daemon/dbus/gkd-secret-error.h
@@ -25,15 +25,27 @@
 
 #include <glib.h>
 
-#include <dbus/dbus.h>
+#include <gio/gio.h>
 
-DBusMessage *     gkd_secret_error_no_such_object             (DBusMessage *message);
+enum _GkdSecretDaemonError {
+  GKD_SECRET_DAEMON_ERROR_DENIED
+};
 
-DBusMessage *     gkd_secret_propagate_error                  (DBusMessage *message,
+enum _GkdSecretError {
+  GKD_SECRET_ERROR_ALREADY_EXISTS,
+  GKD_SECRET_ERROR_IS_LOCKED,
+  GKD_SECRET_ERROR_NO_SESSION,
+  GKD_SECRET_ERROR_NO_SUCH_OBJECT
+};
+
+#define GKD_SECRET_DAEMON_ERROR gkd_secret_daemon_error_quark ()
+GQuark            gkd_secret_daemon_error_quark (void);
+
+#define GKD_SECRET_ERROR gkd_secret_error_quark ()
+GQuark            gkd_secret_error_quark (void);
+
+void              gkd_secret_propagate_error                  (GDBusMethodInvocation *invocation,
                                                                const gchar *description,
                                                                GError *error);
 
-DBusMessage *     gkd_secret_error_to_reply                   (DBusMessage *message,
-                                                               DBusError *derr);
-
 #endif /* __GKD_SECRET_ERROR_H__ */
diff --git a/daemon/dbus/gkd-secret-lock.c b/daemon/dbus/gkd-secret-lock.c
index c6650db..70e3483 100644
--- a/daemon/dbus/gkd-secret-lock.c
+++ b/daemon/dbus/gkd-secret-lock.c
@@ -30,7 +30,8 @@
 #include <gck/gck.h>
 
 gboolean
-gkd_secret_lock (GckObject *collection, DBusError *derr)
+gkd_secret_lock (GckObject *collection,
+                 GError **error_out)
 {
        GckBuilder builder = GCK_BUILDER_INIT;
        GError *error = NULL;
@@ -49,7 +50,9 @@ gkd_secret_lock (GckObject *collection, DBusError *derr)
 
        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 collection");
+                g_set_error_literal (error_out, G_DBUS_ERROR,
+                                     G_DBUS_ERROR_FAILED,
+                                     "Couldn't lock collection");
                g_clear_error (&error);
                return FALSE;
        }
@@ -67,7 +70,7 @@ gkd_secret_lock (GckObject *collection, DBusError *derr)
 
 gboolean
 gkd_secret_lock_all (GckSession *session,
-                     DBusError *derr)
+                     GError **error_out)
 {
        GckBuilder builder = GCK_BUILDER_INIT;
        GError *error = NULL;
@@ -80,7 +83,7 @@ gkd_secret_lock_all (GckSession *session,
        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_set_error (error_out, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Couldn't lock service");
                g_clear_error (&error);
                return FALSE;
        }
@@ -99,7 +102,7 @@ gkd_secret_lock_all (GckSession *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_set_error (error_out, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, "Couldn't lock service");
                g_clear_error (&error);
                return FALSE;
        }
diff --git a/daemon/dbus/gkd-secret-lock.h b/daemon/dbus/gkd-secret-lock.h
index b6035fa..7c3fc0f 100644
--- a/daemon/dbus/gkd-secret-lock.h
+++ b/daemon/dbus/gkd-secret-lock.h
@@ -25,12 +25,10 @@
 
 #include <gck/gck.h>
 
-#include <dbus/dbus.h>
-
 gboolean            gkd_secret_lock                (GckObject *collection,
-                                                    DBusError *derr);
+                                                    GError **error);
 
 gboolean            gkd_secret_lock_all            (GckSession *session,
-                                                    DBusError *derr);
+                                                    GError **error);
 
 #endif /* __GKD_SECRET_LOCK_H__ */
diff --git a/daemon/dbus/gkd-secret-objects.c b/daemon/dbus/gkd-secret-objects.c
index dda2760..495605a 100644
--- a/daemon/dbus/gkd-secret-objects.c
+++ b/daemon/dbus/gkd-secret-objects.c
@@ -20,10 +20,7 @@
 
 #include "config.h"
 
-#include "gkd-dbus-util.h"
-
 #include "gkd-secret-error.h"
-#include "gkd-secret-introspect.h"
 #include "gkd-secret-objects.h"
 #include "gkd-secret-property.h"
 #include "gkd-secret-secret.h"
@@ -31,6 +28,7 @@
 #include "gkd-secret-session.h"
 #include "gkd-secret-types.h"
 #include "gkd-secret-util.h"
+#include "gkd-secrets-generated.h"
 
 #include "egg/egg-error.h"
 
@@ -38,241 +36,501 @@
 
 #include <string.h>
 
-enum {
-       PROP_0,
-       PROP_PKCS11_SLOT,
-       PROP_SERVICE
-};
-
 struct _GkdSecretObjects {
        GObject parent;
        GkdSecretService *service;
        GckSlot *pkcs11_slot;
+       GHashTable *collections_to_skeletons;
+       GHashTable *items_to_skeletons;
 };
 
-static gchar *    object_path_for_item          (const gchar *base,
-                                                 GckObject *item);
 
-static gchar *    object_path_for_collection    (GckObject *collection);
+/* -----------------------------------------------------------------------------
+ * SKELETON
+ */
 
-static gchar *    collection_path_for_item      (GckObject *item);
+typedef struct {
+       GkdOrgFreedesktopSecretCollectionSkeleton parent;
+       GkdSecretObjects *objects;
+} GkdSecretCollectionSkeleton;
+typedef struct {
+       GkdOrgFreedesktopSecretCollectionSkeletonClass parent_class;
+} GkdSecretCollectionSkeletonClass;
+typedef struct {
+       GkdOrgFreedesktopSecretItemSkeleton parent;
+       GkdSecretObjects *objects;
+} GkdSecretItemSkeleton;
+typedef struct {
+       GkdOrgFreedesktopSecretItemSkeletonClass parent_class;
+} GkdSecretItemSkeletonClass;
+
+static GckObject * secret_objects_lookup_gck_object_for_path (GkdSecretObjects *self,
+                                                             const gchar *sender,
+                                                             const gchar *path,
+                                                             GError **error);
+
+GType gkd_secret_collection_skeleton_get_type (void);
+G_DEFINE_TYPE (GkdSecretCollectionSkeleton, gkd_secret_collection_skeleton, 
GKD_TYPE_ORG_FREEDESKTOP_SECRET_COLLECTION_SKELETON)
+GType gkd_secret_item_skeleton_get_type (void);
+G_DEFINE_TYPE (GkdSecretItemSkeleton, gkd_secret_item_skeleton, 
GKD_TYPE_ORG_FREEDESKTOP_SECRET_ITEM_SKELETON)
 
-G_DEFINE_TYPE (GkdSecretObjects, gkd_secret_objects, G_TYPE_OBJECT);
+static void
+on_object_path_append_to_builder (GkdSecretObjects *self,
+                                 const gchar *path,
+                                 GckObject *object,
+                                 gpointer user_data)
+{
+       GVariantBuilder *builder = user_data;
+       g_variant_builder_add (builder, "o", path);
+}
 
-/* -----------------------------------------------------------------------------
- * INTERNAL
- */
+static GVariant *
+gkd_secret_objects_append_item_paths (GkdSecretObjects *self,
+                                     const gchar *caller,
+                                      const gchar *base)
+{
+       GVariantBuilder builder;
+
+       g_return_val_if_fail (GKD_SECRET_IS_OBJECTS (self), NULL);
+       g_return_val_if_fail (base, NULL);
+
+       g_variant_builder_init (&builder, G_VARIANT_TYPE ("ao"));
+       gkd_secret_objects_foreach_item (self, caller, base, on_object_path_append_to_builder, &builder);
+
+       return g_variant_builder_end (&builder);
+}
+
+static gchar **
+gkd_secret_objects_get_collection_items (GkdSecretObjects *self,
+                                         const gchar *collection_path)
+{
+       GVariant *items_variant;
+       gchar **items;
+
+       items_variant = gkd_secret_objects_append_item_paths (self, NULL, collection_path);
+       items = g_variant_dup_objv (items_variant, NULL);
+       g_variant_unref (items_variant);
+
+       return items;
+}
 
 static gboolean
-parse_object_path (GkdSecretObjects *self, const gchar *path, gchar **collection, gchar **item)
+object_property_set (GkdSecretObjects *objects,
+                    GckObject *object,
+                     const gchar *prop_name,
+                     GVariant *value,
+                     GError **error_out)
 {
-       const gchar *replace;
+       GckBuilder builder = GCK_BUILDER_INIT;
+       GError *error = NULL;
+       gulong attr_type;
 
-       g_assert (self);
-       g_assert (path);
-       g_assert (collection);
+       /* What type of property is it? */
+       if (!gkd_secret_property_get_type (prop_name, &attr_type)) {
+               g_set_error (error_out, G_DBUS_ERROR,
+                            G_DBUS_ERROR_FAILED,
+                            "Object does not have the '%s' property",
+                            prop_name);
+               return FALSE;
+        }
 
-       if (!gkd_secret_util_parse_path (path, collection, item))
+       /* Retrieve the actual attribute value */
+       if (!gkd_secret_property_parse_variant (value, prop_name, &builder)) {
+               gck_builder_clear (&builder);
+                g_set_error (error_out, G_DBUS_ERROR,
+                             G_DBUS_ERROR_FAILED,
+                             "The property type or value was invalid: %s",
+                             prop_name);
                return FALSE;
+       }
 
-       if (g_str_has_prefix (path, SECRET_ALIAS_PREFIX)) {
-               replace = gkd_secret_service_get_alias (self->service, *collection);
-               if (!replace) {
-                       g_free (*collection);
-                       *collection = NULL;
-                       if (item) {
-                               g_free (*item);
-                               *item = NULL;
-                       }
-                       return FALSE;
-               }
-               g_free (*collection);
-               *collection = g_strdup (replace);
+       gck_object_set (object, gck_builder_end (&builder), NULL, &error);
+
+       if (error != NULL) {
+               if (g_error_matches (error, GCK_ERROR, CKR_USER_NOT_LOGGED_IN))
+                       g_set_error (error_out, GKD_SECRET_ERROR,
+                                    GKD_SECRET_ERROR_IS_LOCKED,
+                                    "Cannot set property on a locked object");
+               else
+                       g_set_error (error_out, G_DBUS_ERROR,
+                                    G_DBUS_ERROR_FAILED,
+                                    "Couldn't set '%s' property: %s",
+                                    prop_name, egg_error_message (error));
+               g_clear_error (&error);
+               return FALSE;
        }
 
        return TRUE;
 }
 
-static DBusMessage*
-object_property_get (GckObject *object, DBusMessage *message,
-                     const gchar *prop_name)
+static GVariant *
+object_property_get (GkdSecretObjects *objects,
+                    GckObject *object,
+                     const gchar *prop_name,
+                    GError **error_out)
 {
-       DBusMessageIter iter;
        GError *error = NULL;
-       DBusMessage *reply;
        GckAttribute attr;
        gpointer value;
        gsize length;
+       GVariant *res;
 
-       if (!gkd_secret_property_get_type (prop_name, &attr.type))
-               return dbus_message_new_error_printf (message, DBUS_ERROR_FAILED,
-                                                     "Object does not have the '%s' property", prop_name);
+       if (!gkd_secret_property_get_type (prop_name, &attr.type)) {
+               g_set_error (error_out, G_DBUS_ERROR,
+                            G_DBUS_ERROR_FAILED,
+                            "Object does not have the '%s' property",
+                            prop_name);
+               return NULL;
+       }
 
        /* Retrieve the actual attribute */
        attr.value = value = gck_object_get_data (object, attr.type, NULL, &length, &error);
        if (error != NULL) {
-               reply = dbus_message_new_error_printf (message, DBUS_ERROR_FAILED,
-                                                      "Couldn't retrieve '%s' property: %s",
-                                                      prop_name, egg_error_message (error));
+               g_set_error (error_out, G_DBUS_ERROR,
+                            G_DBUS_ERROR_FAILED,
+                            "Couldn't retrieve '%s' property: %s",
+                            prop_name, egg_error_message (error));
                g_clear_error (&error);
-               return reply;
+               return NULL;
        }
 
        /* Marshall the data back out */
        attr.length = length;
-       reply = dbus_message_new_method_return (message);
-       dbus_message_iter_init_append (reply, &iter);
-       gkd_secret_property_append_variant (&iter, &attr);
+       res = gkd_secret_property_append_variant (&attr);
        g_free (value);
-       return reply;
+
+       return res;
 }
 
-static DBusMessage*
-object_property_set (GckObject *object,
-                     DBusMessage *message,
-                     DBusMessageIter *iter,
-                     const gchar *prop_name)
+static gboolean
+gkd_secret_collection_skeleton_set_property_dbus (GDBusConnection *connection,
+                                                 const gchar *sender,
+                                                 const gchar *object_path,
+                                                 const gchar *interface_name,
+                                                 const gchar *property_name,
+                                                  GVariant *value,
+                                                 GError **error,
+                                                 gpointer user_data)
 {
-       GckBuilder builder = GCK_BUILDER_INIT;
-       DBusMessage *reply;
-       GError *error = NULL;
-       gulong attr_type;
+       GkdSecretCollectionSkeleton *self = (GkdSecretCollectionSkeleton *) user_data;
+       GckObject *object;
 
-       g_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_VARIANT, NULL);
+       object = secret_objects_lookup_gck_object_for_path (self->objects, sender, object_path, error);
+       if (!object)
+               return FALSE;
 
-       /* What type of property is it? */
-       if (!gkd_secret_property_get_type (prop_name, &attr_type))
-               return dbus_message_new_error_printf (message, DBUS_ERROR_FAILED,
-                                                     "Object does not have the '%s' property", prop_name);
+       if (!object_property_set (self->objects, object, property_name, value, error)) {
+               g_object_unref (object);
+               return FALSE;
+       }
 
-       /* Retrieve the actual attribute value */
-       if (!gkd_secret_property_parse_variant (iter, prop_name, &builder)) {
-               gck_builder_clear (&builder);
-               return dbus_message_new_error_printf (message, DBUS_ERROR_FAILED,
-                                                     "The property type or value was invalid: %s", 
prop_name);
+       if (g_strcmp0 (property_name, "Label") == 0) {
+               gkd_org_freedesktop_secret_collection_set_label (GKD_ORG_FREEDESKTOP_SECRET_COLLECTION (self),
+                                                                g_variant_get_string (value, NULL));
        }
 
-       gck_object_set (object, gck_builder_end (&builder), NULL, &error);
+       gkd_secret_service_emit_collection_changed (self->objects->service, object_path);
+       g_object_unref (object);
 
-       if (error != NULL) {
-               if (g_error_matches (error, GCK_ERROR, CKR_USER_NOT_LOGGED_IN))
-                       reply = dbus_message_new_error (message, SECRET_ERROR_IS_LOCKED,
-                                                       "Cannot set property on a locked object");
-               else
-                       reply = dbus_message_new_error_printf (message, DBUS_ERROR_FAILED,
-                                                              "Couldn't set '%s' property: %s",
-                                                              prop_name, egg_error_message (error));
-               g_clear_error (&error);
-               return reply;
+       return TRUE;
+}
+
+static GVariant *
+gkd_secret_collection_skeleton_get_property_dbus (GDBusConnection *connection,
+                                                 const gchar *sender,
+                                                 const gchar *object_path,
+                                                 const gchar *interface_name,
+                                                 const gchar *property_name,
+                                                 GError **error,
+                                                 gpointer user_data)
+{
+       GkdSecretCollectionSkeleton *self = (GkdSecretCollectionSkeleton *) user_data;
+       GckObject *object;
+       GVariant *variant;
+
+       object = secret_objects_lookup_gck_object_for_path (self->objects, sender, object_path, error);
+       if (!object)
+               return FALSE;
+
+       if (g_strcmp0 (property_name, "Items") == 0)
+               variant = gkd_secret_objects_append_item_paths (self->objects, sender, object_path);
+       else
+               variant = object_property_get (self->objects, object, property_name, error);
+
+
+       g_object_unref (object);
+       return variant;
+}
+
+static GDBusInterfaceVTable *
+gkd_secret_collection_skeleton_get_vtable (GDBusInterfaceSkeleton *skeleton)
+{
+       static GDBusInterfaceVTable vtable;
+       GDBusInterfaceVTable *parent_vtable;
+
+       parent_vtable = G_DBUS_INTERFACE_SKELETON_CLASS 
(gkd_secret_collection_skeleton_parent_class)->get_vtable (skeleton);
+
+       (&vtable)->get_property = gkd_secret_collection_skeleton_get_property_dbus;
+       (&vtable)->set_property = gkd_secret_collection_skeleton_set_property_dbus;
+       (&vtable)->method_call = parent_vtable->method_call;
+
+       return &vtable;
+}
+
+static void
+gkd_secret_collection_skeleton_class_init (GkdSecretCollectionSkeletonClass *klass)
+{
+       GDBusInterfaceSkeletonClass *skclass = G_DBUS_INTERFACE_SKELETON_CLASS (klass);
+       skclass->get_vtable = gkd_secret_collection_skeleton_get_vtable;
+}
+
+static void
+gkd_secret_collection_skeleton_init (GkdSecretCollectionSkeleton *self)
+{
+}
+
+static GkdOrgFreedesktopSecretCollection *
+gkd_secret_collection_skeleton_new (GkdSecretObjects *objects)
+{
+       GkdOrgFreedesktopSecretCollection *self = g_object_new (gkd_secret_collection_skeleton_get_type (), 
NULL);
+       ((GkdSecretCollectionSkeleton *) self)->objects = objects;
+       return self;
+}
+
+static gboolean
+gkd_secret_item_skeleton_set_property_dbus (GDBusConnection *connection,
+                                           const gchar *sender,
+                                           const gchar *object_path,
+                                           const gchar *interface_name,
+                                           const gchar *property_name,
+                                           GVariant *value,
+                                           GError **error,
+                                           gpointer user_data)
+{
+       GkdSecretItemSkeleton *self = (GkdSecretItemSkeleton *) user_data;
+       GckObject *object;
+
+       object = secret_objects_lookup_gck_object_for_path (self->objects, sender, object_path, error);
+       if (!object)
+               return FALSE;
+
+        if (!object_property_set (self->objects, object, property_name, value, error)) {
+               g_object_unref (object);
+               return FALSE;
+       }
+
+       if (g_strcmp0 (property_name, "Attributes") == 0) {
+               gkd_org_freedesktop_secret_item_set_attributes (GKD_ORG_FREEDESKTOP_SECRET_ITEM (self),
+                                                               g_variant_get_variant (value));
+       } else if (g_strcmp0 (property_name, "Label") == 0) {
+               gkd_org_freedesktop_secret_item_set_label (GKD_ORG_FREEDESKTOP_SECRET_ITEM (self),
+                                                          g_variant_get_string (value, NULL));
        }
 
-       return dbus_message_new_method_return (message);
+       gkd_secret_objects_emit_item_changed (self->objects, object);
+       g_object_unref (object);
+
+       return TRUE;
 }
 
-static DBusMessage*
-item_property_get (GckObject *object, DBusMessage *message)
+static GVariant *
+gkd_secret_item_skeleton_get_property_dbus (GDBusConnection *connection,
+                                           const gchar *sender,
+                                           const gchar *object_path,
+                                           const gchar *interface_name,
+                                           const gchar *property_name,
+                                           GError **error,
+                                           gpointer user_data)
 {
-       const gchar *interface;
-       const gchar *name;
+       GkdSecretItemSkeleton *self = (GkdSecretItemSkeleton *) user_data;
+       GckObject *object;
+       GVariant *variant;
 
-       if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &interface,
-                                   DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID))
+       object = secret_objects_lookup_gck_object_for_path (self->objects, sender, object_path, error);
+       if (!object)
                return NULL;
 
-       if (!gkd_dbus_interface_match (SECRET_ITEM_INTERFACE, interface))
-               return dbus_message_new_error_printf (message, DBUS_ERROR_FAILED,
-                                                     "Object does not have properties on interface '%s'",
-                                                     interface);
+       variant = object_property_get (self->objects, object, property_name, error);
+       g_object_unref (object);
 
-       return object_property_get (object, message, name);
+       return variant;
 }
 
-static DBusMessage*
-item_property_set (GkdSecretObjects *self,
-                   GckObject *object,
-                   DBusMessage *message)
+static GDBusInterfaceVTable *
+gkd_secret_item_skeleton_get_vtable (GDBusInterfaceSkeleton *skeleton)
 {
-       DBusMessageIter iter;
-       const char *interface;
-       const char *name;
-       DBusMessage *reply;
+       static GDBusInterfaceVTable vtable;
+       GDBusInterfaceVTable *parent_vtable;
 
-       if (!dbus_message_has_signature (message, "ssv"))
-               return NULL;
+       parent_vtable = G_DBUS_INTERFACE_SKELETON_CLASS (gkd_secret_item_skeleton_parent_class)->get_vtable 
(skeleton);
 
-       dbus_message_iter_init (message, &iter);
-       dbus_message_iter_get_basic (&iter, &interface);
-       dbus_message_iter_next (&iter);
-       dbus_message_iter_get_basic (&iter, &name);
-       dbus_message_iter_next (&iter);
+       (&vtable)->get_property = gkd_secret_item_skeleton_get_property_dbus;
+       (&vtable)->set_property = gkd_secret_item_skeleton_set_property_dbus;
+       (&vtable)->method_call = parent_vtable->method_call;
 
-       if (!gkd_dbus_interface_match (SECRET_ITEM_INTERFACE, interface))
-               return dbus_message_new_error_printf (message, DBUS_ERROR_FAILED,
-                                                     "Object does not have properties on interface '%s'",
-                                                     interface);
+       return &vtable;
+}
 
-       reply = object_property_set (object, message, &iter, name);
+static void
+gkd_secret_item_skeleton_class_init (GkdSecretItemSkeletonClass *klass)
+{
+       GDBusInterfaceSkeletonClass *skclass = G_DBUS_INTERFACE_SKELETON_CLASS (klass);
+       skclass->get_vtable = gkd_secret_item_skeleton_get_vtable;
+}
 
-       /* Notify everyone a property changed */
-       if (reply && dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
-               gkd_secret_objects_emit_item_changed (self, object, name, NULL);
+static void
+gkd_secret_item_skeleton_init (GkdSecretItemSkeleton *self)
+{
+}
 
-       return reply;
+static GkdOrgFreedesktopSecretItem *
+gkd_secret_item_skeleton_new (GkdSecretObjects *objects)
+{
+       GkdOrgFreedesktopSecretItem *self = g_object_new (gkd_secret_item_skeleton_get_type (), NULL);
+       ((GkdSecretItemSkeleton *) self)->objects = objects;
+       return self;
 }
 
-static DBusMessage*
-item_property_getall (GckObject *object, DBusMessage *message)
+enum {
+       PROP_0,
+       PROP_PKCS11_SLOT,
+       PROP_SERVICE
+};
+
+static gchar *    object_path_for_item          (const gchar *base,
+                                                 GckObject *item);
+
+static gchar *    object_path_for_collection    (GckObject *collection);
+
+static gchar *    collection_path_for_item      (GckObject *item);
+
+G_DEFINE_TYPE (GkdSecretObjects, gkd_secret_objects, G_TYPE_OBJECT);
+
+/* -----------------------------------------------------------------------------
+ * INTERNAL
+ */
+
+static gboolean
+parse_object_path (GkdSecretObjects *self, const gchar *path, gchar **collection, gchar **item)
+{
+       const gchar *replace;
+
+       g_assert (self);
+       g_assert (path);
+       g_assert (collection);
+
+       if (!gkd_secret_util_parse_path (path, collection, item))
+               return FALSE;
+
+       if (g_str_has_prefix (path, SECRET_ALIAS_PREFIX)) {
+               replace = gkd_secret_service_get_alias (self->service, *collection);
+               if (!replace) {
+                       g_free (*collection);
+                       *collection = NULL;
+                       if (item) {
+                               g_free (*item);
+                               *item = NULL;
+                       }
+                       return FALSE;
+               }
+               g_free (*collection);
+               *collection = g_strdup (replace);
+       }
+
+       return TRUE;
+}
+
+static GckObject *
+secret_objects_lookup_gck_object_for_path (GkdSecretObjects *self,
+                                          const gchar *sender,
+                                          const gchar *path,
+                                          GError **error_out)
+{
+       GckBuilder builder = GCK_BUILDER_INIT;
+       GList *objects;
+       GckSession *session;
+       gchar *c_ident;
+       gchar *i_ident;
+       GckObject *object = NULL;
+        GError *error = NULL;
+
+       g_return_val_if_fail (path, FALSE);
+
+       if (!parse_object_path (self, path, &c_ident, &i_ident) || !c_ident)
+               goto out;
+
+       /* The session we're using to access the object */
+       session = gkd_secret_service_get_pkcs11_session (self->service, sender);
+       g_return_val_if_fail (session, FALSE);
+
+       if (i_ident) {
+               gck_builder_add_ulong (&builder, CKA_CLASS, CKO_SECRET_KEY);
+               gck_builder_add_string (&builder, CKA_G_COLLECTION, c_ident);
+               gck_builder_add_string (&builder, CKA_ID, i_ident);
+       } else {
+               gck_builder_add_ulong (&builder, CKA_CLASS, CKO_G_COLLECTION);
+               gck_builder_add_string (&builder, CKA_ID, c_ident);
+       }
+
+       objects = gck_session_find_objects (session, gck_builder_end (&builder), NULL, &error);
+
+       g_free (c_ident);
+       g_free (i_ident);
+
+       if (error != NULL) {
+               g_warning ("couldn't lookup object: %s: %s", path, egg_error_message (error));
+               g_clear_error (&error);
+       }
+
+       if (!objects)
+               goto out;
+
+       object = g_object_ref (objects->data);
+       gck_list_unref_free (objects);
+
+ out:
+       if (!object)
+               g_set_error (error_out, GKD_SECRET_ERROR,
+                            GKD_SECRET_ERROR_NO_SUCH_OBJECT,
+                            "The '%s' object does not exist",
+                            path);
+
+       return object;
+}
+
+static GckObject *
+secret_objects_lookup_gck_object_for_invocation (GkdSecretObjects *self,
+                                                GDBusMethodInvocation *invocation)
 {
-       GckAttributes *attrs;
-       DBusMessageIter iter;
-       DBusMessageIter array;
        GError *error = NULL;
-       DBusMessage *reply;
-       const gchar *interface;
+       GckObject *object;
 
-       if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &interface, DBUS_TYPE_INVALID))
-               return NULL;
+       object = secret_objects_lookup_gck_object_for_path (self,
+                                                           g_dbus_method_invocation_get_sender (invocation),
+                                                           g_dbus_method_invocation_get_object_path 
(invocation),
+                                                           &error);
 
-       if (!gkd_dbus_interface_match (SECRET_ITEM_INTERFACE, interface))
-               return dbus_message_new_error_printf (message, DBUS_ERROR_FAILED,
-                                                     "Object does not have properties on interface '%s'",
-                                                     interface);
-
-       attrs = gck_object_get (object, NULL, &error,
-                                CKA_LABEL,
-                                CKA_G_SCHEMA,
-                                CKA_G_LOCKED,
-                                CKA_G_CREATED,
-                                CKA_G_MODIFIED,
-                                CKA_G_FIELDS,
-                                GCK_INVALID);
-
-       if (error != NULL)
-               return dbus_message_new_error_printf (message, DBUS_ERROR_FAILED,
-                                                     "Couldn't retrieve properties: %s",
-                                                     egg_error_message (error));
-
-       reply = dbus_message_new_method_return (message);
-
-       dbus_message_iter_init_append (reply, &iter);
-       dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "{sv}", &array);
-       gkd_secret_property_append_all (&array, attrs);
-       dbus_message_iter_close_container (&iter, &array);
-       return reply;
+       if (!object)
+               g_dbus_method_invocation_take_error (invocation, error);
+
+       return object;
 }
 
-static DBusMessage*
-item_method_delete (GkdSecretObjects *self, GckObject *object, DBusMessage *message)
+static gboolean
+item_method_delete (GkdOrgFreedesktopSecretItem *skeleton,
+                   GDBusMethodInvocation *invocation,
+                   GkdSecretObjects *self)
 {
        GError *error = NULL;
        gchar *collection_path;
        gchar *item_path;
-       DBusMessage *reply;
-       const gchar *prompt;
        GckObject *collection;
+       GckObject *object;
 
-       if (!dbus_message_get_args (message, NULL, DBUS_TYPE_INVALID))
-               return NULL;
+       object = secret_objects_lookup_gck_object_for_invocation (self, invocation);
+       if (!object) {
+               return TRUE;
+       }
 
        collection_path = collection_path_for_item (object);
        item_path = object_path_for_item (NULL, object);
@@ -284,113 +542,108 @@ item_method_delete (GkdSecretObjects *self, GckObject *object, DBusMessage *mess
                        g_object_unref (collection);
                }
 
-               prompt = "/"; /* No prompt necessary */
-               reply = dbus_message_new_method_return (message);
-               dbus_message_append_args (reply, DBUS_TYPE_OBJECT_PATH, &prompt, DBUS_TYPE_INVALID);
+               /* No prompt necessary */
+               gkd_org_freedesktop_secret_item_complete_delete (skeleton, invocation, "/");
 
        } else {
                if (g_error_matches (error, GCK_ERROR, CKR_USER_NOT_LOGGED_IN))
-                       reply = dbus_message_new_error_printf (message, SECRET_ERROR_IS_LOCKED,
-                                                              "Cannot delete a locked item");
+                       g_dbus_method_invocation_return_error_literal (invocation, GKD_SECRET_ERROR,
+                                                                      GKD_SECRET_ERROR_IS_LOCKED,
+                                                                      "Cannot delete a locked item");
                else
-                       reply = dbus_message_new_error_printf (message, DBUS_ERROR_FAILED,
-                                                              "Couldn't delete collection: %s",
-                                                              egg_error_message (error));
+                       g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+                                                              G_DBUS_ERROR_FAILED,
+                                                              "Couldn't delete collection: %s",
+                                                              egg_error_message (error));
 
                g_clear_error (&error);
        }
 
        g_free (collection_path);
        g_free (item_path);
-       return reply;
+       g_object_unref (object);
+
+       return TRUE;
 }
 
-static DBusMessage*
-item_method_get_secret (GkdSecretObjects *self, GckObject *item, DBusMessage *message)
+static gboolean
+item_method_get_secret (GkdOrgFreedesktopSecretItem *skeleton,
+                       GDBusMethodInvocation *invocation,
+                       gchar *path,
+                       GkdSecretObjects *self)
 {
-       DBusError derr = DBUS_ERROR_INIT;
        GkdSecretSession *session;
        GkdSecretSecret *secret;
-       DBusMessage *reply;
-       DBusMessageIter iter;
-       const char *path;
+       GckObject *item;
+       GError *error = NULL;
 
-       if (!dbus_message_get_args (message, NULL, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID))
-               return NULL;
+       item = secret_objects_lookup_gck_object_for_invocation (self, invocation);
+       if (!item) {
+               return TRUE;
+       }
 
-       session = gkd_secret_service_lookup_session (self->service, path, dbus_message_get_sender (message));
-       if (session == NULL)
-               return dbus_message_new_error (message, SECRET_ERROR_NO_SESSION, "The session does not 
exist");
+       session = gkd_secret_service_lookup_session (self->service, path,
+                                                    g_dbus_method_invocation_get_sender (invocation));
+       if (session == NULL) {
+               g_dbus_method_invocation_return_error_literal (invocation, GKD_SECRET_ERROR,
+                                                              GKD_SECRET_ERROR_NO_SESSION,
+                                                              "The session does not exist");
+               goto cleanup;
+       }
 
-       secret = gkd_secret_session_get_item_secret (session, item, &derr);
-       if (secret == NULL)
-               return gkd_secret_error_to_reply (message, &derr);
+       secret = gkd_secret_session_get_item_secret (session, item, &error);
+       if (secret == NULL) {
+               g_dbus_method_invocation_take_error (invocation, error);
+               goto cleanup;
+       }
 
-       reply = dbus_message_new_method_return (message);
-       dbus_message_iter_init_append (reply, &iter);
-       gkd_secret_secret_append (secret, &iter);
+       gkd_org_freedesktop_secret_item_complete_get_secret (skeleton, invocation,
+                                                            gkd_secret_secret_append (secret));
        gkd_secret_secret_free (secret);
-       return reply;
+
+ cleanup:
+       g_object_unref (item);
+       return TRUE;
 }
 
-static DBusMessage*
-item_method_set_secret (GkdSecretObjects *self, GckObject *item, DBusMessage *message)
+static gboolean
+item_method_set_secret (GkdOrgFreedesktopSecretItem *skeleton,
+                       GDBusMethodInvocation *invocation,
+                       GVariant *secret_variant,
+                       GkdSecretObjects *self)
 {
-       DBusError derr = DBUS_ERROR_INIT;
-       DBusMessageIter iter;
        GkdSecretSecret *secret;
        const char *caller;
+       GckObject *item;
+       GError *error = NULL;
 
-       if (!dbus_message_has_signature (message, "(oayays)"))
-               return NULL;
-       dbus_message_iter_init (message, &iter);
-       secret = gkd_secret_secret_parse (self->service, message, &iter, &derr);
-       if (secret == NULL)
-               return gkd_secret_error_to_reply (message, &derr);
+       item = secret_objects_lookup_gck_object_for_invocation (self, invocation);
+       if (!item) {
+               return TRUE;
+       }
 
-       caller = dbus_message_get_sender (message);
-       g_return_val_if_fail (caller, NULL);
+       caller = g_dbus_method_invocation_get_sender (invocation);
+       secret = gkd_secret_secret_parse (self->service, caller, secret_variant, &error);
+       if (error != NULL) {
+               goto cleanup;
+       }
 
-       gkd_secret_session_set_item_secret (secret->session, item, secret, &derr);
+       gkd_secret_session_set_item_secret (secret->session, item, secret, &error);
        gkd_secret_secret_free (secret);
 
-       if (dbus_error_is_set (&derr))
-               return gkd_secret_error_to_reply (message, &derr);
-
-       return dbus_message_new_method_return (message);
-}
-
-static DBusMessage*
-item_message_handler (GkdSecretObjects *self, GckObject *object, DBusMessage *message)
-{
-       /* org.freedesktop.Secret.Item.Delete() */
-       if (dbus_message_is_method_call (message, SECRET_ITEM_INTERFACE, "Delete"))
-               return item_method_delete (self, object, message);
-
-       /* org.freedesktop.Secret.Session.GetSecret() */
-       else if (dbus_message_is_method_call (message, SECRET_ITEM_INTERFACE, "GetSecret"))
-               return item_method_get_secret (self, object, message);
-
-       /* org.freedesktop.Secret.Session.SetSecret() */
-       else if (dbus_message_is_method_call (message, SECRET_ITEM_INTERFACE, "SetSecret"))
-               return item_method_set_secret (self, object, message);
-
-       /* org.freedesktop.DBus.Properties.Get */
-       if (dbus_message_is_method_call (message, DBUS_INTERFACE_PROPERTIES, "Get"))
-               return item_property_get (object, message);
-
-       /* org.freedesktop.DBus.Properties.Set */
-       else if (dbus_message_is_method_call (message, DBUS_INTERFACE_PROPERTIES, "Set"))
-               return item_property_set (self, object, message);
-
-       /* org.freedesktop.DBus.Properties.GetAll */
-       else if (dbus_message_is_method_call (message, DBUS_INTERFACE_PROPERTIES, "GetAll"))
-               return item_property_getall (object, message);
+       if (error != NULL) {
+               goto cleanup;
+       }
 
-       else if (dbus_message_has_interface (message, DBUS_INTERFACE_INTROSPECTABLE))
-               return gkd_dbus_introspect_handle (message, gkd_secret_introspect_item, NULL);
+ cleanup:
+       if (error != NULL) {
+               g_dbus_method_invocation_take_error (invocation, error);
+       } else {
+               gkd_org_freedesktop_secret_item_complete_set_secret (skeleton, invocation);
+       }
 
-       return NULL;
+       g_object_unref (item);
+       return TRUE;
 }
 
 static void
@@ -428,120 +681,15 @@ item_cleanup_search_results (GckSession *session, GList *items,
        *unlocked = g_list_reverse (*unlocked);
 }
 
-static DBusMessage*
-collection_property_get (GkdSecretObjects *self, GckObject *object, DBusMessage *message)
-{
-       DBusMessageIter iter;
-       DBusMessage *reply;
-       const gchar *interface;
-       const gchar *name;
-
-       if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &interface,
-                                   DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID))
-               return NULL;
-
-       if (!gkd_dbus_interface_match (SECRET_COLLECTION_INTERFACE, interface))
-               return dbus_message_new_error_printf (message, DBUS_ERROR_FAILED,
-                                                     "Object does not have properties on interface '%s'",
-                                                     interface);
-
-       /* Special case, the Items property */
-       if (g_str_equal (name, "Items")) {
-               reply = dbus_message_new_method_return (message);
-               dbus_message_iter_init_append (reply, &iter);
-               gkd_secret_objects_append_item_paths (self, dbus_message_get_path (message), &iter, message);
-               return reply;
-       }
-
-       return object_property_get (object, message, name);
-}
-
-static DBusMessage*
-collection_property_set (GkdSecretObjects *self, GckObject *object, DBusMessage *message)
-{
-       DBusMessageIter iter;
-       DBusMessage *reply;
-       const char *interface;
-       const char *name;
-
-       if (!dbus_message_has_signature (message, "ssv"))
-               return NULL;
-
-       dbus_message_iter_init (message, &iter);
-       dbus_message_iter_get_basic (&iter, &interface);
-       dbus_message_iter_next (&iter);
-       dbus_message_iter_get_basic (&iter, &name);
-       dbus_message_iter_next (&iter);
-
-       if (!gkd_dbus_interface_match (SECRET_COLLECTION_INTERFACE, interface))
-               return dbus_message_new_error_printf (message, DBUS_ERROR_FAILED,
-                                                     "Object does not have properties on interface '%s'",
-                                                     interface);
-
-       reply = object_property_set (object, message, &iter, name);
-
-       /* Notify everyone a property changed */
-       if (reply && dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
-               gkd_secret_objects_emit_collection_changed (self, object, name, NULL);
-
-       return reply;
-}
-
-static DBusMessage*
-collection_property_getall (GkdSecretObjects *self, GckObject *object, DBusMessage *message)
-{
-       GckAttributes *attrs;
-       DBusMessageIter iter;
-       DBusMessageIter array;
-       DBusMessageIter dict;
-       GError *error = NULL;
-       DBusMessage *reply;
-       const gchar *name;
-       const gchar *interface;
-
-       if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &interface, DBUS_TYPE_INVALID))
-               return NULL;
-
-       if (!gkd_dbus_interface_match (SECRET_COLLECTION_INTERFACE, interface))
-               return dbus_message_new_error_printf (message, DBUS_ERROR_FAILED,
-                                                     "Object does not have properties on interface '%s'",
-                                                     interface);
-
-       attrs = gck_object_get (object, NULL, &error,
-                               CKA_LABEL,
-                               CKA_G_LOCKED,
-                               CKA_G_CREATED,
-                               CKA_G_MODIFIED,
-                               GCK_INVALID);
-
-       if (error != NULL)
-               return dbus_message_new_error_printf (message, DBUS_ERROR_FAILED,
-                                                     "Couldn't retrieve properties: %s",
-                                                     egg_error_message (error));
-
-       reply = dbus_message_new_method_return (message);
-
-       dbus_message_iter_init_append (reply, &iter);
-       dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "{sv}", &array);
-
-       /* Append all the usual properties */
-       gkd_secret_property_append_all (&array, attrs);
-
-       /* Append the Items property */
-       dbus_message_iter_open_container (&array, DBUS_TYPE_DICT_ENTRY, NULL, &dict);
-       name = "Items";
-       dbus_message_iter_append_basic (&dict, DBUS_TYPE_STRING, &name);
-       gkd_secret_objects_append_item_paths (self, dbus_message_get_path (message), &dict, message);
-       dbus_message_iter_close_container (&array, &dict);
-
-       dbus_message_iter_close_container (&iter, &array);
-       return reply;
-}
-
-static DBusMessage*
-collection_method_search_items (GkdSecretObjects *self, GckObject *object, DBusMessage *message)
+static gboolean
+collection_method_search_items (GkdOrgFreedesktopSecretCollection *skeleton,
+                               GDBusMethodInvocation *invocation,
+                               GVariant *attributes,
+                               GkdSecretObjects *self)
 {
-       return gkd_secret_objects_handle_search_items (self, message, dbus_message_get_path (message), FALSE);
+       return gkd_secret_objects_handle_search_items (self, invocation, attributes,
+                                                      g_dbus_method_invocation_get_object_path (invocation),
+                                                      FALSE);
 }
 
 static GckObject*
@@ -654,53 +802,55 @@ object_path_for_collection (GckObject *collection)
        return path;
 }
 
-static DBusMessage*
-collection_method_create_item (GkdSecretObjects *self, GckObject *object, DBusMessage *message)
+static gboolean
+collection_method_create_item (GkdOrgFreedesktopSecretCollection *skeleton,
+                              GDBusMethodInvocation *invocation,
+                              GVariant *properties,
+                              GVariant *secret_variant,
+                              gboolean replace,
+                              GkdSecretObjects *self)
 {
        GckBuilder builder = GCK_BUILDER_INIT;
        GckSession *pkcs11_session = NULL;
-       DBusError derr = DBUS_ERROR_INIT;
        GkdSecretSecret *secret = NULL;
-       dbus_bool_t replace = FALSE;
        GckAttributes *attrs = NULL;
        const GckAttribute *fields;
-       DBusMessageIter iter, array;
        GckObject *item = NULL;
-       const gchar *prompt;
        const gchar *base;
        GError *error = NULL;
-       DBusMessage *reply = NULL;
        gchar *path = NULL;
        gchar *identifier;
        gboolean created = FALSE;
+       GckObject *object;
 
-       /* Parse the message */
-       if (!dbus_message_has_signature (message, "a{sv}(oayays)b"))
-               return NULL;
-       if (!dbus_message_iter_init (message, &iter))
-               g_return_val_if_reached (NULL);
-       dbus_message_iter_recurse (&iter, &array);
-       if (!gkd_secret_property_parse_all (&array, SECRET_ITEM_INTERFACE, &builder)) {
-               reply = dbus_message_new_error (message, DBUS_ERROR_INVALID_ARGS,
-                                               "Invalid properties argument");
+       object = secret_objects_lookup_gck_object_for_invocation (self, invocation);
+       if (!object) {
+               return TRUE;
+       }
+
+       if (!gkd_secret_property_parse_all (properties, SECRET_ITEM_INTERFACE, &builder)) {
+               g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR,
+                                                              G_DBUS_ERROR_INVALID_ARGS,
+                                                              "Invalid properties argument");
                goto cleanup;
        }
-       dbus_message_iter_next (&iter);
-       secret = gkd_secret_secret_parse (self->service, message, &iter, &derr);
+
+       base = g_dbus_method_invocation_get_object_path (invocation);
+       secret = gkd_secret_secret_parse (self->service, g_dbus_method_invocation_get_sender (invocation),
+                                         secret_variant, &error);
+
        if (secret == NULL) {
-               reply = gkd_secret_error_to_reply (message, &derr);
+               g_dbus_method_invocation_take_error (invocation, error);
+               error = NULL;
                goto cleanup;
        }
-       dbus_message_iter_next (&iter);
-       dbus_message_iter_get_basic (&iter, &replace);
 
-       base = dbus_message_get_path (message);
        if (!parse_object_path (self, base, &identifier, NULL))
-               g_return_val_if_reached (NULL);
-       g_return_val_if_fail (identifier, NULL);
+               g_return_val_if_reached (FALSE);
+       g_return_val_if_fail (identifier, FALSE);
 
        pkcs11_session = gck_object_get_session (object);
-       g_return_val_if_fail (pkcs11_session, NULL);
+       g_return_val_if_fail (pkcs11_session, FALSE);
 
        attrs = gck_attributes_ref_sink (gck_builder_end (&builder));
 
@@ -727,41 +877,31 @@ collection_method_create_item (GkdSecretObjects *self, GckObject *object, DBusMe
        }
 
        /* Set the secret */
-       if (!gkd_secret_session_set_item_secret (secret->session, item, secret, &derr)) {
+       if (!gkd_secret_session_set_item_secret (secret->session, item, secret, &error)) {
                if (created) /* If we created, then try to destroy on failure */
                        gck_object_destroy (item, NULL, NULL);
                goto cleanup;
        }
 
        path = object_path_for_item (base, item);
-       gkd_secret_objects_emit_item_created (self, object, item);
+       gkd_secret_objects_emit_item_created (self, object, path);
 
-       /* Build up the item identifier */
-       reply = dbus_message_new_method_return (message);
-       dbus_message_iter_init_append (reply, &iter);
-       dbus_message_iter_append_basic (&iter, DBUS_TYPE_OBJECT_PATH, &path);
-       prompt = "/";
-       dbus_message_iter_append_basic (&iter, DBUS_TYPE_OBJECT_PATH, &prompt);
+       gkd_org_freedesktop_secret_collection_complete_create_item (skeleton, invocation, path, "/");
 
 cleanup:
        if (error) {
-               if (!reply) {
-                       if (g_error_matches (error, GCK_ERROR, CKR_USER_NOT_LOGGED_IN))
-                               reply = dbus_message_new_error_printf (message, SECRET_ERROR_IS_LOCKED,
-                                                                      "Cannot create an item in a locked 
collection");
-                       else
-                               reply = dbus_message_new_error_printf (message, DBUS_ERROR_FAILED,
-                                                                      "Couldn't create item: %s", 
egg_error_message (error));
-               }
+               if (g_error_matches (error, GCK_ERROR, CKR_USER_NOT_LOGGED_IN))
+                       g_dbus_method_invocation_return_error_literal (invocation, GKD_SECRET_ERROR,
+                                                                      GKD_SECRET_ERROR_IS_LOCKED,
+                                                                      "Cannot create an item in a locked 
collection");
+               else
+                       g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+                                                              G_DBUS_ERROR_FAILED,
+                                                              "Couldn't create item: %s",
+                                                              egg_error_message (error));
                g_clear_error (&error);
        }
 
-       if (dbus_error_is_set (&derr)) {
-               if (!reply)
-                       reply = dbus_message_new_error (message, derr.name, derr.message);
-               dbus_error_free (&derr);
-       }
-
        gkd_secret_secret_free (secret);
        gck_attributes_unref (attrs);
        if (item)
@@ -769,127 +909,68 @@ cleanup:
        if (pkcs11_session)
                g_object_unref (pkcs11_session);
        g_free (path);
+       g_object_unref (object);
 
-       return reply;
+       return TRUE;
 }
 
-static DBusMessage*
-collection_method_delete (GkdSecretObjects *self, GckObject *object, DBusMessage *message)
+static gboolean
+collection_method_delete (GkdOrgFreedesktopSecretCollection *skeleton,
+                         GDBusMethodInvocation *invocation,
+                         GkdSecretObjects *self)
 {
        GError *error = NULL;
-       DBusMessage *reply;
-       const gchar *prompt;
        gchar *path;
+       GckObject *object;
 
-       if (!dbus_message_get_args (message, NULL, DBUS_TYPE_INVALID))
-               return NULL;
+       object = secret_objects_lookup_gck_object_for_invocation (self, invocation);
+       if (!object) {
+               return TRUE;
+       }
 
        path = object_path_for_collection (object);
-       g_return_val_if_fail (path != NULL, NULL);
+       g_return_val_if_fail (path != NULL, FALSE);
 
        if (!gck_object_destroy (object, NULL, &error)) {
-               reply = dbus_message_new_error_printf (message, DBUS_ERROR_FAILED,
+               g_dbus_method_invocation_return_error (invocation,
+                                                      G_DBUS_ERROR,
+                                                      G_DBUS_ERROR_FAILED,
                                                       "Couldn't delete collection: %s",
                                                       egg_error_message (error));
                g_clear_error (&error);
-               g_free (path);
-               return reply;
+               goto cleanup;
        }
 
        /* Notify the callers that a collection was deleted */
        gkd_secret_service_emit_collection_deleted (self->service, path);
-       g_free (path);
-
-       prompt = "/";
-       reply = dbus_message_new_method_return (message);
-       dbus_message_append_args (reply, DBUS_TYPE_OBJECT_PATH, &prompt, DBUS_TYPE_INVALID);
-       return reply;
-}
-
-static void
-on_each_path_append_to_array (GkdSecretObjects *self,
-                              const gchar *path,
-                              GckObject *object,
-                              gpointer user_data)
-{
-       GPtrArray *array = user_data;
-       g_ptr_array_add (array, g_strdup (path));
-}
+       gkd_org_freedesktop_secret_collection_complete_delete (skeleton, invocation, "/");
 
-static DBusMessage *
-collection_introspect (GkdSecretObjects *self,
-                       GckObject *object,
-                       DBusMessage *message)
-{
-       GPtrArray *names;
-       DBusMessage *reply;
-
-       names = g_ptr_array_new_with_free_func (g_free);
-       gkd_secret_objects_foreach_item (self, message, dbus_message_get_path (message),
-                                        on_each_path_append_to_array, names);
-       g_ptr_array_add (names, NULL);
-
-       reply = gkd_dbus_introspect_handle (message, gkd_secret_introspect_collection,
-                                           (const gchar **)names->pdata);
-
-       g_ptr_array_unref (names);
-       return reply;
-}
-
-static DBusMessage*
-collection_message_handler (GkdSecretObjects *self, GckObject *object, DBusMessage *message)
-{
-       /* org.freedesktop.Secret.Collection.Delete() */
-       if (dbus_message_is_method_call (message, SECRET_COLLECTION_INTERFACE, "Delete"))
-               return collection_method_delete (self, object, message);
-
-       /* org.freedesktop.Secret.Collection.SearchItems() */
-       if (dbus_message_is_method_call (message, SECRET_COLLECTION_INTERFACE, "SearchItems"))
-               return collection_method_search_items (self, object, message);
-
-       /* org.freedesktop.Secret.Collection.CreateItem() */
-       if (dbus_message_is_method_call (message, SECRET_COLLECTION_INTERFACE, "CreateItem"))
-               return collection_method_create_item (self, object, message);
-
-       /* org.freedesktop.DBus.Properties.Get() */
-       if (dbus_message_is_method_call (message, DBUS_INTERFACE_PROPERTIES, "Get"))
-               return collection_property_get (self, object, message);
-
-       /* org.freedesktop.DBus.Properties.Set() */
-       else if (dbus_message_is_method_call (message, DBUS_INTERFACE_PROPERTIES, "Set"))
-               return collection_property_set (self, object, message);
-
-       /* org.freedesktop.DBus.Properties.GetAll() */
-       else if (dbus_message_is_method_call (message, DBUS_INTERFACE_PROPERTIES, "GetAll"))
-               return collection_property_getall (self, object, message);
-
-       /* org.freedesktop.DBus.Introspectable.Introspect() */
-       else if (dbus_message_has_interface (message, DBUS_INTERFACE_INTROSPECTABLE))
-               return collection_introspect (self, object, message);
+ cleanup:
+       g_free (path);
+       g_object_unref (object);
 
-       return NULL;
+       return TRUE;
 }
 
 /* -----------------------------------------------------------------------------
  * OBJECT
  */
 
-static GObject*
-gkd_secret_objects_constructor (GType type, guint n_props, GObjectConstructParam *props)
+static void
+skeleton_destroy_func (gpointer user_data)
 {
-       GkdSecretObjects *self = GKD_SECRET_OBJECTS (G_OBJECT_CLASS 
(gkd_secret_objects_parent_class)->constructor(type, n_props, props));
-
-       g_return_val_if_fail (self, NULL);
-       g_return_val_if_fail (self->pkcs11_slot, NULL);
-       g_return_val_if_fail (self->service, NULL);
-
-       return G_OBJECT (self);
+       GDBusInterfaceSkeleton *skeleton = user_data;
+       g_dbus_interface_skeleton_unexport (skeleton);
+       g_object_unref (skeleton);
 }
 
 static void
 gkd_secret_objects_init (GkdSecretObjects *self)
 {
-
+       self->collections_to_skeletons = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                                               g_free, skeleton_destroy_func);
+       self->items_to_skeletons = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                                         g_free, skeleton_destroy_func);
 }
 
 static void
@@ -908,6 +989,9 @@ gkd_secret_objects_dispose (GObject *obj)
                self->service = NULL;
        }
 
+       g_clear_pointer (&self->collections_to_skeletons, g_hash_table_unref);
+       g_clear_pointer (&self->items_to_skeletons, g_hash_table_unref);
+
        G_OBJECT_CLASS (gkd_secret_objects_parent_class)->dispose (obj);
 }
 
@@ -971,7 +1055,6 @@ gkd_secret_objects_class_init (GkdSecretObjectsClass *klass)
 {
        GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 
-       gobject_class->constructor = gkd_secret_objects_constructor;
        gobject_class->dispose = gkd_secret_objects_dispose;
        gobject_class->finalize = gkd_secret_objects_finalize;
        gobject_class->set_property = gkd_secret_objects_set_property;
@@ -997,65 +1080,6 @@ gkd_secret_objects_get_pkcs11_slot (GkdSecretObjects *self)
        return self->pkcs11_slot;
 }
 
-DBusMessage*
-gkd_secret_objects_dispatch (GkdSecretObjects *self, DBusMessage *message)
-{
-       GckBuilder builder = GCK_BUILDER_INIT;
-       DBusMessage *reply = NULL;
-       GError *error = NULL;
-       GList *objects;
-       GckSession *session;
-       gchar *c_ident;
-       gchar *i_ident;
-       gboolean is_item;
-       const char *path;
-
-       g_return_val_if_fail (GKD_SECRET_IS_OBJECTS (self), NULL);
-       g_return_val_if_fail (message, NULL);
-
-       path = dbus_message_get_path (message);
-       g_return_val_if_fail (path, NULL);
-
-       if (!parse_object_path (self, path, &c_ident, &i_ident) || !c_ident)
-               return gkd_secret_error_no_such_object (message);
-
-       /* The session we're using to access the object */
-       session = gkd_secret_service_get_pkcs11_session (self->service, dbus_message_get_sender (message));
-       g_return_val_if_fail (session, NULL);
-
-       if (i_ident) {
-               is_item = TRUE;
-               gck_builder_add_ulong (&builder, CKA_CLASS, CKO_SECRET_KEY);
-               gck_builder_add_string (&builder, CKA_G_COLLECTION, c_ident);
-               gck_builder_add_string (&builder, CKA_ID, i_ident);
-       } else {
-               is_item = FALSE;
-               gck_builder_add_ulong (&builder, CKA_CLASS, CKO_G_COLLECTION);
-               gck_builder_add_string (&builder, CKA_ID, c_ident);
-       }
-
-       objects = gck_session_find_objects (session, gck_builder_end (&builder), NULL, &error);
-
-       g_free (c_ident);
-       g_free (i_ident);
-
-       if (error != NULL) {
-               g_warning ("couldn't lookup object: %s: %s", path, egg_error_message (error));
-               g_clear_error (&error);
-       }
-
-       if (!objects)
-               return gkd_secret_error_no_such_object (message);
-
-       if (is_item)
-               reply = item_message_handler (self, objects->data, message);
-       else
-               reply = collection_message_handler (self, objects->data, message);
-
-       gck_list_unref_free (objects);
-       return reply;
-}
-
 GckObject*
 gkd_secret_objects_lookup_collection (GkdSecretObjects *self, const gchar *caller,
                                       const gchar *path)
@@ -1162,7 +1186,7 @@ objects_foreach_item (GkdSecretObjects *self,
 
 void
 gkd_secret_objects_foreach_item (GkdSecretObjects *self,
-                                 DBusMessage *message,
+                                const gchar *caller,
                                  const gchar *base,
                                  GkdSecretObjectsForeach callback,
                                  gpointer user_data)
@@ -1178,11 +1202,10 @@ gkd_secret_objects_foreach_item (GkdSecretObjects *self,
        g_return_if_fail (callback != NULL);
 
        /* The session we're using to access the object */
-       if (message == NULL) {
+       if (caller == NULL) {
                session = gkd_secret_service_internal_pkcs11_session (self->service);
        } else {
-               session = gkd_secret_service_get_pkcs11_session (self->service,
-                                                                dbus_message_get_sender (message));
+               session = gkd_secret_service_get_pkcs11_session (self->service, caller);
        }
 
        if (!parse_object_path (self, base, &identifier, NULL))
@@ -1205,42 +1228,9 @@ gkd_secret_objects_foreach_item (GkdSecretObjects *self,
        g_free (identifier);
 }
 
-static void
-on_object_path_append_to_iter (GkdSecretObjects *self,
-                               const gchar *path,
-                               GckObject *object,
-                               gpointer user_data)
-{
-       DBusMessageIter *array = user_data;
-       dbus_message_iter_append_basic (array, DBUS_TYPE_OBJECT_PATH, &path);
-}
-
-void
-gkd_secret_objects_append_item_paths (GkdSecretObjects *self,
-                                      const gchar *base,
-                                      DBusMessageIter *iter,
-                                      DBusMessage *message)
-{
-       DBusMessageIter variant;
-       DBusMessageIter array;
-
-       g_return_if_fail (GKD_SECRET_IS_OBJECTS (self));
-       g_return_if_fail (base);
-       g_return_if_fail (iter);
-
-
-       dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, "ao", &variant);
-       dbus_message_iter_open_container (&variant, DBUS_TYPE_ARRAY, "o", &array);
-
-       gkd_secret_objects_foreach_item (self, message, base, on_object_path_append_to_iter, &array);
-
-       dbus_message_iter_close_container (&variant, &array);
-       dbus_message_iter_close_container (iter, &variant);
-}
-
 void
 gkd_secret_objects_foreach_collection (GkdSecretObjects *self,
-                                       DBusMessage *message,
+                                      const gchar *caller,
                                        GkdSecretObjectsForeach callback,
                                        gpointer user_data)
 {
@@ -1256,11 +1246,10 @@ gkd_secret_objects_foreach_collection (GkdSecretObjects *self,
        g_return_if_fail (callback);
 
        /* The session we're using to access the object */
-       if (message == NULL) {
+       if (caller == NULL) {
                session = gkd_secret_service_internal_pkcs11_session (self->service);
        } else {
-               session = gkd_secret_service_get_pkcs11_session (self->service,
-                                                                dbus_message_get_sender (message));
+               session = gkd_secret_service_get_pkcs11_session (self->service, caller);
        }
 
        gck_builder_add_ulong (&builder, CKA_CLASS, CKO_G_COLLECTION);
@@ -1292,61 +1281,50 @@ gkd_secret_objects_foreach_collection (GkdSecretObjects *self,
        gck_list_unref_free (collections);
 }
 
-void
+GVariant *
 gkd_secret_objects_append_collection_paths (GkdSecretObjects *self,
-                                            DBusMessageIter *iter,
-                                            DBusMessage *message)
+                                           const gchar *caller)
 {
-       DBusMessageIter variant;
-       DBusMessageIter array;
+       GVariantBuilder builder;
 
-       g_return_if_fail (GKD_SECRET_IS_OBJECTS (self));
-       g_return_if_fail (iter != NULL);
-
-       dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, "ao", &variant);
-       dbus_message_iter_open_container (&variant, DBUS_TYPE_ARRAY, "o", &array);
+       g_return_val_if_fail (GKD_SECRET_IS_OBJECTS (self), NULL);
 
-       gkd_secret_objects_foreach_collection (self, message, on_object_path_append_to_iter, &array);
+       g_variant_builder_init (&builder, G_VARIANT_TYPE ("ao"));
+       gkd_secret_objects_foreach_collection (self, caller, on_object_path_append_to_builder, &builder);
 
-       dbus_message_iter_close_container (&variant, &array);
-       dbus_message_iter_close_container (iter, &variant);
+       return g_variant_builder_end (&builder);
 }
 
-DBusMessage*
+gboolean
 gkd_secret_objects_handle_search_items (GkdSecretObjects *self,
-                                        DBusMessage *message,
+                                        GDBusMethodInvocation *invocation,
+                                        GVariant *attributes,
                                         const gchar *base,
                                         gboolean separate_locked)
 {
        GckBuilder builder = GCK_BUILDER_INIT;
-       DBusMessageIter iter;
-       DBusMessageIter array;
        GckObject *search;
        GckSession *session;
-       DBusMessage *reply;
        GError *error = NULL;
        gchar *identifier;
        gpointer data;
        gsize n_data;
        GList *locked, *unlocked;
        GList *items;
+       GVariantBuilder result;
 
-       g_return_val_if_fail (GKD_SECRET_IS_OBJECTS (self), NULL);
-       g_return_val_if_fail (message, NULL);
-
-       if (!dbus_message_has_signature (message, "a{ss}"))
-               return NULL;
-
-       dbus_message_iter_init (message, &iter);
-       if (!gkd_secret_property_parse_fields (&iter, &builder)) {
+       if (!gkd_secret_property_parse_fields (attributes, &builder)) {
                gck_builder_clear (&builder);
-               return dbus_message_new_error (message, DBUS_ERROR_FAILED,
-                                              "Invalid data in attributes argument");
+                g_dbus_method_invocation_return_error_literal (invocation,
+                                                               G_DBUS_ERROR,
+                                                               G_DBUS_ERROR_FAILED,
+                                                               "Invalid data in attributes argument");
+                return TRUE;
        }
 
        if (base != NULL) {
                if (!parse_object_path (self, base, &identifier, NULL))
-                       g_return_val_if_reached (NULL);
+                       g_return_val_if_reached (FALSE);
                gck_builder_add_string (&builder, CKA_G_COLLECTION, identifier);
                g_free (identifier);
        }
@@ -1355,18 +1333,20 @@ gkd_secret_objects_handle_search_items (GkdSecretObjects *self,
        gck_builder_add_boolean (&builder, CKA_TOKEN, FALSE);
 
        /* The session we're using to access the object */
-       session = gkd_secret_service_get_pkcs11_session (self->service, dbus_message_get_sender (message));
-       g_return_val_if_fail (session, NULL);
+       session = gkd_secret_service_get_pkcs11_session (self->service, g_dbus_method_invocation_get_sender 
(invocation));
+       g_return_val_if_fail (session, FALSE);
 
        /* Create the search object */
        search = gck_session_create_object (session, gck_builder_end (&builder), NULL, &error);
 
        if (error != NULL) {
-               reply = dbus_message_new_error_printf (message, DBUS_ERROR_FAILED,
+               g_dbus_method_invocation_return_error (invocation,
+                                                      G_DBUS_ERROR,
+                                                      G_DBUS_ERROR_FAILED,
                                                       "Couldn't search for items: %s",
                                                       egg_error_message (error));
                g_clear_error (&error);
-               return reply;
+               return TRUE;
        }
 
        /* Get the matched item handles, and delete the search object */
@@ -1375,116 +1355,108 @@ gkd_secret_objects_handle_search_items (GkdSecretObjects *self,
        g_object_unref (search);
 
        if (error != NULL) {
-               reply = dbus_message_new_error_printf (message, DBUS_ERROR_FAILED,
+               g_dbus_method_invocation_return_error (invocation,
+                                                      G_DBUS_ERROR,
+                                                      G_DBUS_ERROR_FAILED,
                                                       "Couldn't retrieve matched items: %s",
                                                       egg_error_message (error));
                g_clear_error (&error);
-               return reply;
+               return TRUE;
        }
 
        /* Build a list of object handles */
        items = gck_objects_from_handle_array (session, data, n_data / sizeof (CK_OBJECT_HANDLE));
        g_free (data);
 
-       /* Prepare the reply message */
-       reply = dbus_message_new_method_return (message);
-       dbus_message_iter_init_append (reply, &iter);
-
        /* Filter out the locked items */
        if (separate_locked) {
+               GVariant *unlocked_variant, *locked_variant;
+
                item_cleanup_search_results (session, items, &locked, &unlocked);
 
-               dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "o", &array);
-               objects_foreach_item (self, unlocked, NULL, on_object_path_append_to_iter, &array);
-               dbus_message_iter_close_container (&iter, &array);
+               g_variant_builder_init (&result, G_VARIANT_TYPE ("ao"));
+               objects_foreach_item (self, unlocked, NULL, on_object_path_append_to_builder, &result);
+               unlocked_variant = g_variant_builder_end (&result);
 
-               dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "o", &array);
-               objects_foreach_item (self, locked, NULL, on_object_path_append_to_iter, &array);
-               dbus_message_iter_close_container (&iter, &array);
+               g_variant_builder_init (&result, G_VARIANT_TYPE ("ao"));
+               objects_foreach_item (self, locked, NULL, on_object_path_append_to_builder, &result);
+               locked_variant = g_variant_builder_end (&result);
 
                g_list_free (locked);
                g_list_free (unlocked);
 
+               g_dbus_method_invocation_return_value (invocation,
+                                                      g_variant_new ("(@ao ao)",
+                                                                     unlocked_variant,
+                                                                     locked_variant));
        } else {
-               dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "o", &array);
-               objects_foreach_item (self, items, NULL, on_object_path_append_to_iter, &array);
-               dbus_message_iter_close_container (&iter, &array);
+               g_variant_builder_init (&result, G_VARIANT_TYPE ("ao"));
+               objects_foreach_item (self, items, NULL, on_object_path_append_to_builder, &result);
+
+               g_dbus_method_invocation_return_value (invocation,
+                                                      g_variant_new ("(@ao)", g_variant_builder_end 
(&result)));
        }
 
        gck_list_unref_free (items);
 
-       return reply;
+       return TRUE;
 }
 
-DBusMessage*
-gkd_secret_objects_handle_get_secrets (GkdSecretObjects *self, DBusMessage *message)
+gboolean
+gkd_secret_objects_handle_get_secrets (GkdSecretObjects *self,
+                                      GDBusMethodInvocation *invocation,
+                                      const gchar **paths,
+                                      const gchar *session_path)
 {
-       DBusError derr = DBUS_ERROR_INIT;
        GkdSecretSession *session;
        GkdSecretSecret *secret;
-       DBusMessage *reply;
        GckObject *item;
-       DBusMessageIter iter, array, dict;
-       const char *session_path;
        const char *caller;
-       char **paths;
-       int n_paths, i;
-
-       if (!dbus_message_get_args (message, NULL,
-                                   DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &paths, &n_paths,
-                                   DBUS_TYPE_OBJECT_PATH, &session_path,
-                                   DBUS_TYPE_INVALID))
-               return NULL;
-
-       caller = dbus_message_get_sender (message);
-       g_return_val_if_fail (caller, NULL);
+       int i;
+       GVariantBuilder builder;
+       GError *error = NULL;
 
-       session = gkd_secret_service_lookup_session (self->service, session_path,
-                                                    dbus_message_get_sender (message));
-       if (session == NULL)
-               return dbus_message_new_error (message, SECRET_ERROR_NO_SESSION, "The session does not 
exist");
+       caller = g_dbus_method_invocation_get_sender (invocation);
+       session = gkd_secret_service_lookup_session (self->service, session_path, caller);
+       if (session == NULL) {
+               g_dbus_method_invocation_return_error_literal (invocation, GKD_SECRET_ERROR,
+                                                              GKD_SECRET_ERROR_NO_SESSION,
+                                                              "The session does not exist");
+               return TRUE;
+       }
 
-       reply = dbus_message_new_method_return (message);
-       dbus_message_iter_init_append (reply, &iter);
-       dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "{o(oayays)}", &array);
+       g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{o(oayays)"));
 
-       for (i = 0; i < n_paths; ++i) {
+       for (i = 0; paths[i] != NULL; ++i) {
 
                /* Try to find the item, if it doesn't exist, just ignore */
                item = gkd_secret_objects_lookup_item (self, caller, paths[i]);
                if (!item)
                        continue;
 
-               secret = gkd_secret_session_get_item_secret (session, item, &derr);
+               secret = gkd_secret_session_get_item_secret (session, item, &error);
                g_object_unref (item);
 
                if (secret == NULL) {
                        /* We ignore is locked, and just leave out from response */
-                       if (dbus_error_has_name (&derr, SECRET_ERROR_IS_LOCKED)) {
-                               dbus_error_free (&derr);
+                       if (g_error_matches (error, GKD_SECRET_ERROR, GKD_SECRET_ERROR_IS_LOCKED)) {
+                               g_clear_error (&error);
                                continue;
 
                        /* All other errors stop the operation */
                        } else {
-                               dbus_message_unref (reply);
-                               reply = dbus_message_new_error (message, derr.name, derr.message);
-                               dbus_error_free (&derr);
-                               break;
+                               g_dbus_method_invocation_take_error (invocation, error);
+                               return TRUE;
                        }
                }
 
-               dbus_message_iter_open_container (&array, DBUS_TYPE_DICT_ENTRY, NULL, &dict);
-               dbus_message_iter_append_basic (&dict, DBUS_TYPE_OBJECT_PATH, &(paths[i]));
-               gkd_secret_secret_append (secret, &dict);
+               g_variant_builder_add (&builder, "o@(oayays)", paths[i], gkd_secret_secret_append (secret));
                gkd_secret_secret_free (secret);
-               dbus_message_iter_close_container (&array, &dict);
        }
 
-       if (i == n_paths)
-               dbus_message_iter_close_container (&iter, &array);
-       dbus_free_string_array (paths);
-
-       return reply;
+       g_dbus_method_invocation_return_value (invocation,
+                                              g_variant_new ("(@a{o(oayays)})", g_variant_builder_end 
(&builder)));
+       return TRUE;
 }
 
 static void
@@ -1493,196 +1465,150 @@ on_each_item_emit_locked (GkdSecretObjects *self,
                           GckObject *object,
                           gpointer user_data)
 {
-       gkd_secret_objects_emit_item_changed (self, object, "Locked", NULL);
+       GkdOrgFreedesktopSecretItem *skeleton;
+       GVariant *value;
+       GError *error = NULL;
+
+       skeleton = g_hash_table_lookup (self->items_to_skeletons, path);
+       if (skeleton == NULL) {
+               g_warning ("setting locked state on item %s, but no skeleton found", path);
+               return;
+       }
+
+       value = object_property_get (self, object, "Locked", &error);
+       if (!value) {
+               g_warning ("setting locked state on item %s, but no property value: %s",
+                          path, error->message);
+               g_error_free (error);
+               return;
+       }
+
+       gkd_org_freedesktop_secret_item_set_locked (skeleton, g_variant_get_boolean (value));
+       g_variant_unref (value);
+
+        gkd_secret_objects_emit_item_changed (self, object);
 }
 
 void
 gkd_secret_objects_emit_collection_locked (GkdSecretObjects *self,
                                            GckObject *collection)
 {
-       const gchar *collection_path;
+       gchar *collection_path;
+       GkdOrgFreedesktopSecretCollection *skeleton;
+       GVariant *value;
+       GError *error = NULL;
 
        collection_path = object_path_for_collection (collection);
        gkd_secret_objects_foreach_item (self, NULL, collection_path,
                                         on_each_item_emit_locked, NULL);
 
-       gkd_secret_objects_emit_collection_changed (self, collection, "Locked", NULL);
+       skeleton = g_hash_table_lookup (self->collections_to_skeletons, collection_path);
+       if (skeleton == NULL) {
+               g_warning ("setting locked state on collection %s, but no skeleton found", collection_path);
+               return;
+       }
+
+       value = object_property_get (self, collection, "Locked", &error);
+       if (!value) {
+               g_warning ("setting locked state on item %s, but no property value: %s",
+                          collection_path, error->message);
+               g_error_free (error);
+               return;
+       }
+
+       gkd_org_freedesktop_secret_collection_set_locked (skeleton, g_variant_get_boolean (value));
+       g_variant_unref (value);
+
+       gkd_secret_service_emit_collection_changed (self->service, collection_path);
+        g_free (collection_path);
 }
 
 static void
-emit_object_properties_changed (GkdSecretObjects *self,
-                                GckObject *object,
-                                const gchar *path,
-                                const gchar *iface,
-                                va_list va)
+gkd_secret_objects_register_item (GkdSecretObjects *self,
+                                 const gchar *item_path)
 {
-       gchar *collection_path;
-       const gchar *propname;
-       DBusMessage *message;
-       DBusMessageIter iter;
-       DBusMessageIter array;
-       DBusMessageIter dict;
-       CK_ATTRIBUTE_TYPE type;
-       GckAttributes *attrs;
+       GkdOrgFreedesktopSecretItem *skeleton;
        GError *error = NULL;
-       gboolean items = FALSE;
-       GArray *types;
-
-       types = g_array_new (FALSE, FALSE, sizeof (CK_ATTRIBUTE_TYPE));
-       while ((propname = va_arg (va, const gchar *)) != NULL) {
 
-               /* Special case the Items property */
-               if (g_str_equal (propname, "Items")) {
-                       items = TRUE;
-                       continue;
-               }
-
-               if (gkd_secret_property_get_type (propname, &type))
-                       g_array_append_val (types, type);
-               else
-                       g_warning ("invalid property: %s", propname);
+       skeleton = g_hash_table_lookup (self->items_to_skeletons, item_path);
+       if (skeleton != NULL) {
+               g_warning ("asked to register item %p, but it's already registered", item_path);
+               return;
        }
 
-       attrs = gck_object_get_full (object, (CK_ATTRIBUTE_TYPE *)types->data,
-                                    types->len, NULL, &error);
-       g_array_free (types, TRUE);
+       skeleton = gkd_secret_item_skeleton_new (self);
+       g_hash_table_insert (self->items_to_skeletons, g_strdup (item_path), skeleton);
 
+       g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (skeleton),
+                                         gkd_secret_service_get_connection (self->service),
+                                         item_path, &error);
        if (error != NULL) {
-               g_warning ("couldn't retrieve properties: %s", egg_error_message (error));
-               return;
-       }
-
-       message = dbus_message_new_signal (path, DBUS_INTERFACE_PROPERTIES,
-                                          "PropertiesChanged");
-
-       dbus_message_iter_init_append (message, &iter);
-       dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &iface);
-       dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "{sv}", &array);
-       gkd_secret_property_append_all (&array, attrs);
-
-       /* Append the Items property */
-       if (items) {
-               collection_path = object_path_for_collection (object);
-               dbus_message_iter_open_container (&array, DBUS_TYPE_DICT_ENTRY, NULL, &dict);
-               propname = "Items";
-               dbus_message_iter_append_basic (&dict, DBUS_TYPE_STRING, &propname);
-               gkd_secret_objects_append_item_paths (self, collection_path, &dict, NULL);
-               dbus_message_iter_close_container (&array, &dict);
-               g_free (collection_path);
+               g_warning ("could not register secret item on session bus: %s", error->message);
+               g_error_free (error);
        }
 
-       dbus_message_iter_close_container (&iter, &array);
-       dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "s", &array);
-       dbus_message_iter_close_container (&iter, &array);
-
-       if (!dbus_connection_send (gkd_secret_service_get_connection (self->service),
-                                  message, NULL))
-               g_return_if_reached ();
-       dbus_message_unref (message);
-
-       gck_attributes_unref (attrs);
+       g_signal_connect (skeleton, "handle-delete",
+                         G_CALLBACK (item_method_delete), self);
+       g_signal_connect (skeleton, "handle-get-secret",
+                         G_CALLBACK (item_method_get_secret), self);
+       g_signal_connect (skeleton, "handle-set-secret",
+                         G_CALLBACK (item_method_set_secret), self);
 }
 
-void
-gkd_secret_objects_emit_collection_changed (GkdSecretObjects *self,
-                                            GckObject *collection,
-                                            ...)
+static void
+gkd_secret_objects_unregister_item (GkdSecretObjects *self,
+                                   const gchar *item_path)
 {
-       DBusMessage *message;
-       gchar *collection_path;
-       va_list va;
-
-       g_return_if_fail (GKD_SECRET_IS_OBJECTS (self));
-       g_return_if_fail (GCK_OBJECT (collection));
-
-       collection_path = object_path_for_collection (collection);
-
-       message = dbus_message_new_signal (SECRET_SERVICE_PATH,
-                                          SECRET_SERVICE_INTERFACE,
-                                          "CollectionChanged");
-       dbus_message_append_args (message, DBUS_TYPE_OBJECT_PATH, &collection_path,
-                                 DBUS_TYPE_INVALID);
-
-       if (!dbus_connection_send (gkd_secret_service_get_connection (self->service),
-                                  message, NULL))
-               g_return_if_reached ();
-
-       dbus_message_unref (message);
-
-       va_start (va, collection);
-       emit_object_properties_changed (self, collection, collection_path,
-                                       SECRET_COLLECTION_INTERFACE, va);
-       va_end (va);
-
-       g_free (collection_path);
+       if (!g_hash_table_remove (self->items_to_skeletons, item_path)) {
+               g_warning ("asked to unregister item %p, but it wasn't found", item_path);
+               return;
+       }
 }
 
 void
 gkd_secret_objects_emit_item_created (GkdSecretObjects *self,
                                       GckObject *collection,
-                                      GckObject *item)
+                                      const gchar *item_path)
 {
-       DBusMessage *message;
+       GkdOrgFreedesktopSecretCollection *skeleton;
        gchar *collection_path;
-       gchar *item_path;
+       gchar **items;
 
        g_return_if_fail (GKD_SECRET_IS_OBJECTS (self));
        g_return_if_fail (GCK_OBJECT (collection));
-       g_return_if_fail (GCK_OBJECT (item));
+       g_return_if_fail (item_path != NULL);
 
        collection_path = object_path_for_collection (collection);
-       item_path = object_path_for_item (collection_path, item);
-
-       message = dbus_message_new_signal (collection_path,
-                                          SECRET_COLLECTION_INTERFACE,
-                                          "ItemCreated");
-       dbus_message_append_args (message, DBUS_TYPE_OBJECT_PATH, &item_path,
-                                 DBUS_TYPE_INVALID);
+       skeleton = g_hash_table_lookup (self->collections_to_skeletons, collection_path);
+       g_return_if_fail (skeleton != NULL);
 
-       if (!dbus_connection_send (gkd_secret_service_get_connection (self->service),
-                                  message, NULL))
-               g_return_if_reached ();
-
-       dbus_message_unref (message);
+       gkd_secret_objects_register_item (self, item_path);
+       gkd_org_freedesktop_secret_collection_emit_item_created (skeleton, item_path);
 
-       gkd_secret_objects_emit_collection_changed (self, collection, "Items", NULL);
+       items = gkd_secret_objects_get_collection_items (self, collection_path);
+       gkd_org_freedesktop_secret_collection_set_items (skeleton, (const gchar **) items);
 
-       g_free (item_path);
        g_free (collection_path);
+       g_strfreev (items);
 }
 
 void
 gkd_secret_objects_emit_item_changed (GkdSecretObjects *self,
-                                      GckObject *item,
-                                      ...)
+                                      GckObject *item)
 {
-       DBusMessage *message;
+       GkdOrgFreedesktopSecretCollection *skeleton;
        gchar *collection_path;
        gchar *item_path;
-       va_list va;
 
        g_return_if_fail (GKD_SECRET_IS_OBJECTS (self));
        g_return_if_fail (GCK_OBJECT (item));
 
        collection_path = collection_path_for_item (item);
-       item_path = object_path_for_item (collection_path, item);
-
-       message = dbus_message_new_signal (collection_path,
-                                          SECRET_COLLECTION_INTERFACE,
-                                          "ItemChanged");
-       dbus_message_append_args (message, DBUS_TYPE_OBJECT_PATH, &item_path,
-                                 DBUS_TYPE_INVALID);
-
-       if (!dbus_connection_send (gkd_secret_service_get_connection (self->service),
-                                  message, NULL))
-               g_return_if_reached ();
+       skeleton = g_hash_table_lookup (self->collections_to_skeletons, collection_path);
+       g_return_if_fail (skeleton != NULL);
 
-       dbus_message_unref (message);
-
-       va_start (va, item);
-       emit_object_properties_changed (self, item, item_path,
-                                       SECRET_ITEM_INTERFACE, va);
-       va_end (va);
+       item_path = object_path_for_item (collection_path, item);
+       gkd_org_freedesktop_secret_collection_emit_item_changed (skeleton, item_path);
 
        g_free (item_path);
        g_free (collection_path);
@@ -1693,27 +1619,82 @@ gkd_secret_objects_emit_item_deleted (GkdSecretObjects *self,
                                       GckObject *collection,
                                       const gchar *item_path)
 {
-       DBusMessage *message;
+       GkdOrgFreedesktopSecretCollection *skeleton;
        gchar *collection_path;
+       gchar **items;
 
        g_return_if_fail (GKD_SECRET_IS_OBJECTS (self));
        g_return_if_fail (GCK_OBJECT (collection));
        g_return_if_fail (item_path != NULL);
 
        collection_path = object_path_for_collection (collection);
+       skeleton = g_hash_table_lookup (self->collections_to_skeletons, collection_path);
+       g_return_if_fail (skeleton != NULL);
 
-       message = dbus_message_new_signal (collection_path,
-                                          SECRET_COLLECTION_INTERFACE,
-                                          "ItemDeleted");
-       dbus_message_append_args (message, DBUS_TYPE_OBJECT_PATH, &item_path,
-                                 DBUS_TYPE_INVALID);
+       gkd_secret_objects_unregister_item (self, item_path);
+       gkd_org_freedesktop_secret_collection_emit_item_deleted (skeleton, item_path);
 
-       if (!dbus_connection_send (gkd_secret_service_get_connection (self->service),
-                                  message, NULL))
-               g_return_if_reached ();
+       items = gkd_secret_objects_get_collection_items (self, collection_path);
+       gkd_org_freedesktop_secret_collection_set_items (skeleton, (const gchar **) items);
 
-       dbus_message_unref (message);
+       g_strfreev (items);
        g_free (collection_path);
+}
+
+static void
+gkd_secret_objects_init_collection_items (GkdSecretObjects *self,
+                                          const gchar *collection_path)
+{
+       gchar **items;
+       gint idx;
+
+       items = gkd_secret_objects_get_collection_items (self, collection_path);
+       for (idx = 0; items[idx] != NULL; idx++)
+               gkd_secret_objects_register_item (self, items[idx]);
+
+       g_strfreev (items);
+}
+
+void
+gkd_secret_objects_register_collection (GkdSecretObjects *self,
+                                       const gchar *collection_path)
+{
+       GkdOrgFreedesktopSecretCollection *skeleton;
+       GError *error = NULL;
+
+       skeleton = g_hash_table_lookup (self->collections_to_skeletons, collection_path);
+       if (skeleton != NULL) {
+               g_warning ("asked to register collection %p, but it's already registered", collection_path);
+               return;
+       }
+
+       skeleton = gkd_secret_collection_skeleton_new (self);
+       g_hash_table_insert (self->collections_to_skeletons, g_strdup (collection_path), skeleton);
+
+       g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (skeleton),
+                                         gkd_secret_service_get_connection (self->service),
+                                         collection_path, &error);
+       if (error != NULL) {
+               g_warning ("could not register secret collection on session bus: %s", error->message);
+               g_error_free (error);
+       }
+
+       g_signal_connect (skeleton, "handle-create-item",
+                         G_CALLBACK (collection_method_create_item), self);
+       g_signal_connect (skeleton, "handle-delete",
+                         G_CALLBACK (collection_method_delete), self);
+       g_signal_connect (skeleton, "handle-search-items",
+                         G_CALLBACK (collection_method_search_items), self);
+
+        gkd_secret_objects_init_collection_items (self, collection_path);
+}
 
-       gkd_secret_objects_emit_collection_changed (self, collection, "Items", NULL);
+void
+gkd_secret_objects_unregister_collection (GkdSecretObjects *self,
+                                         const gchar *collection_path)
+{
+       if (!g_hash_table_remove (self->collections_to_skeletons, collection_path)) {
+               g_warning ("asked to unregister collection %p, but it wasn't found", collection_path);
+               return;
+       }
 }
diff --git a/daemon/dbus/gkd-secret-objects.h b/daemon/dbus/gkd-secret-objects.h
index ca224ff..e9b61d4 100644
--- a/daemon/dbus/gkd-secret-objects.h
+++ b/daemon/dbus/gkd-secret-objects.h
@@ -27,8 +27,6 @@
 
 #include <glib-object.h>
 
-#include <dbus/dbus.h>
-
 #define GKD_SECRET_TYPE_OBJECTS               (gkd_secret_objects_get_type ())
 #define GKD_SECRET_OBJECTS(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GKD_SECRET_TYPE_OBJECTS, 
GkdSecretObjects))
 #define GKD_SECRET_OBJECTS_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GKD_SECRET_TYPE_OBJECTS, 
GkdSecretObjectsClass))
@@ -49,36 +47,30 @@ typedef void        (*GkdSecretObjectsForeach)                  (GkdSecretObject
 
 GType               gkd_secret_objects_get_type                 (void);
 
-DBusMessage*        gkd_secret_objects_dispatch                  (GkdSecretObjects *self,
-                                                                  DBusMessage *message);
-
-DBusMessage*        gkd_secret_objects_handle_search_items       (GkdSecretObjects *self,
-                                                                  DBusMessage *message,
+gboolean            gkd_secret_objects_handle_search_items       (GkdSecretObjects *self,
+                                                                  GDBusMethodInvocation *invocation,
+                                                                  GVariant *attributes,
                                                                   const gchar *base,
                                                                   gboolean separate_locked);
 
-DBusMessage*        gkd_secret_objects_handle_get_secrets        (GkdSecretObjects *self,
-                                                                  DBusMessage *message);
+gboolean            gkd_secret_objects_handle_get_secrets        (GkdSecretObjects *self,
+                                                                  GDBusMethodInvocation *invocation,
+                                                                  const gchar **paths,
+                                                                  const gchar *session_path);
 
 void                gkd_secret_objects_foreach_collection        (GkdSecretObjects *self,
-                                                                  DBusMessage *message,
+                                                                  const gchar *caller,
                                                                   GkdSecretObjectsForeach callback,
                                                                   gpointer user_data);
 
 void                gkd_secret_objects_foreach_item              (GkdSecretObjects *self,
-                                                                  DBusMessage *message,
+                                                                  const gchar *caller,
                                                                   const gchar *base,
                                                                   GkdSecretObjectsForeach callback,
                                                                   gpointer user_data);
 
-void                gkd_secret_objects_append_collection_paths   (GkdSecretObjects *self,
-                                                                  DBusMessageIter *iter,
-                                                                  DBusMessage *message);
-
-void                gkd_secret_objects_append_item_paths         (GkdSecretObjects *self,
-                                                                  const gchar *base,
-                                                                  DBusMessageIter *iter,
-                                                                  DBusMessage *message);
+GVariant*           gkd_secret_objects_append_collection_paths   (GkdSecretObjects *self,
+                                                                  const gchar *caller);
 
 GckSlot*            gkd_secret_objects_get_pkcs11_slot           (GkdSecretObjects *self);
 
@@ -93,20 +85,21 @@ GckObject*          gkd_secret_objects_lookup_item               (GkdSecretObjec
 void                gkd_secret_objects_emit_collection_locked    (GkdSecretObjects *self,
                                                                   GckObject *collection);
 
-void                gkd_secret_objects_emit_collection_changed   (GkdSecretObjects *self,
-                                                                  GckObject *collection,
-                                                                  ...) G_GNUC_NULL_TERMINATED;
-
 void                gkd_secret_objects_emit_item_created         (GkdSecretObjects *self,
                                                                   GckObject *collection,
-                                                                  GckObject *item);
+                                                                  const gchar *item_path);
 
 void                gkd_secret_objects_emit_item_changed         (GkdSecretObjects *self,
-                                                                  GckObject *item,
-                                                                  ...) G_GNUC_NULL_TERMINATED;
+                                                                  GckObject *item);
 
 void                gkd_secret_objects_emit_item_deleted         (GkdSecretObjects *self,
                                                                   GckObject *collection,
                                                                   const gchar *item_path);
 
+void                gkd_secret_objects_register_collection       (GkdSecretObjects *self,
+                                                                  const gchar *collection_path);
+
+void                gkd_secret_objects_unregister_collection     (GkdSecretObjects *self,
+                                                                  const gchar *collection_path);
+
 #endif /* __GKD_SECRET_OBJECTS_H__ */
diff --git a/daemon/dbus/gkd-secret-prompt.c b/daemon/dbus/gkd-secret-prompt.c
index 21c4a5a..464a4e2 100644
--- a/daemon/dbus/gkd-secret-prompt.c
+++ b/daemon/dbus/gkd-secret-prompt.c
@@ -20,10 +20,9 @@
 
 #include "config.h"
 
-#include "gkd-dbus-util.h"
 #include "gkd-secret-dispatch.h"
+#include "gkd-secret-error.h"
 #include "gkd-secret-exchange.h"
-#include "gkd-secret-introspect.h"
 #include "gkd-secret-service.h"
 #include "gkd-secret-prompt.h"
 #include "gkd-secret-objects.h"
@@ -31,6 +30,7 @@
 #include "gkd-secret-session.h"
 #include "gkd-secret-types.h"
 #include "gkd-secret-util.h"
+#include "gkd-secrets-generated.h"
 
 #include "egg/egg-dh.h"
 #include "egg/egg-error.h"
@@ -48,6 +48,7 @@ struct _GkdSecretPromptPrivate {
        gchar *object_path;
        GkdSecretService *service;
        GkdSecretExchange *exchange;
+       GkdOrgFreedesktopSecretPrompt *skeleton;
        GCancellable *cancellable;
        gboolean prompted;
        gboolean completed;
@@ -65,23 +66,13 @@ static guint unique_prompt_number = 0;
 static void
 emit_completed (GkdSecretPrompt *self, gboolean dismissed)
 {
-       DBusMessage *signal;
-       DBusMessageIter iter;
-       dbus_bool_t bval;
-
-       signal = dbus_message_new_signal (self->pv->object_path, SECRET_PROMPT_INTERFACE,
-                                         "Completed");
-       dbus_message_set_destination (signal, self->pv->caller);
-       dbus_message_iter_init_append (signal, &iter);
-
-       bval = dismissed;
-       dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &bval);
+       GVariant *variant;
 
        g_return_if_fail (GKD_SECRET_PROMPT_GET_CLASS (self)->encode_result);
-       GKD_SECRET_PROMPT_GET_CLASS (self)->encode_result (self, &iter);
+       variant = GKD_SECRET_PROMPT_GET_CLASS (self)->encode_result (self);
 
-       gkd_secret_service_send (self->pv->service, signal);
-       dbus_message_unref (signal);
+       gkd_org_freedesktop_secret_prompt_emit_completed (self->pv->skeleton,
+                                                         dismissed, variant);
 }
 
 static void
@@ -106,25 +97,23 @@ on_system_prompt_inited (GObject *source,
        }
 }
 
-static DBusMessage*
-prompt_method_prompt (GkdSecretPrompt *self,
-                      DBusMessage *message)
+static gboolean
+prompt_method_prompt (GkdOrgFreedesktopSecretPrompt *skeleton,
+                     GDBusMethodInvocation *invocation,
+                     gchar *window_id,
+                     GkdSecretPrompt *self)
 {
-       DBusMessage *reply;
-       const char *window_id;
-
        /* Act as if this object no longer exists */
        if (self->pv->completed)
-               return NULL;
-
-       if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING,
-                                   &window_id, DBUS_TYPE_INVALID))
-               return NULL;
+               return FALSE;
 
        /* Prompt can only be called once */
-       if (self->pv->prompted)
-               return dbus_message_new_error (message, SECRET_ERROR_ALREADY_EXISTS,
-                                              "This prompt has already been shown.");
+       if (self->pv->prompted) {
+               g_dbus_method_invocation_return_error_literal (invocation, GKD_SECRET_ERROR,
+                                                              GKD_SECRET_ERROR_ALREADY_EXISTS,
+                                                              "This prompt has already been shown.");
+               return TRUE;
+       }
 
        self->pv->prompted = TRUE;
 
@@ -133,28 +122,23 @@ prompt_method_prompt (GkdSecretPrompt *self,
        g_async_initable_init_async (G_ASYNC_INITABLE (self), G_PRIORITY_DEFAULT,
                                     self->pv->cancellable, on_system_prompt_inited, NULL);
 
-       reply = dbus_message_new_method_return (message);
-       dbus_message_append_args (reply, DBUS_TYPE_INVALID);
-       return reply;
+       gkd_org_freedesktop_secret_prompt_complete_prompt (skeleton, invocation);
+       return TRUE;
 }
 
-static DBusMessage*
-prompt_method_dismiss (GkdSecretPrompt *self, DBusMessage *message)
+static gboolean
+prompt_method_dismiss (GkdOrgFreedesktopSecretPrompt *skeleton,
+                      GDBusMethodInvocation *invocation,
+                      GkdSecretPrompt *self)
 {
-       DBusMessage *reply;
-
        /* Act as if this object no longer exists */
        if (self->pv->completed)
-               return NULL;
-
-       if (!dbus_message_get_args (message, NULL, DBUS_TYPE_INVALID))
-               return NULL;
+               return FALSE;
 
        gkd_secret_prompt_dismiss (self);
 
-       reply = dbus_message_new_method_return (message);
-       dbus_message_append_args (reply, DBUS_TYPE_INVALID);
-       return reply;
+       gkd_org_freedesktop_secret_prompt_complete_dismiss (skeleton, invocation);
+       return TRUE;
 }
 
 static void
@@ -164,49 +148,18 @@ gkd_secret_prompt_real_prompt_ready (GkdSecretPrompt *self)
        g_return_if_reached ();
 }
 
-static void
-gkd_secret_prompt_real_encode_result (GkdSecretPrompt *self, DBusMessageIter *iter)
+static GVariant *
+gkd_secret_prompt_real_encode_result (GkdSecretPrompt *self)
 {
        /* Default implementation, unused */
-       g_return_if_reached ();
+       g_return_val_if_reached (NULL);
 }
 
-static DBusMessage*
-gkd_secret_prompt_real_dispatch_message (GkdSecretDispatch *base, DBusMessage *message)
-{
-       DBusMessage *reply = NULL;
-       GkdSecretPrompt *self;
-       const gchar *caller;
-
-       g_return_val_if_fail (message, NULL);
-       g_return_val_if_fail (GKD_SECRET_IS_PROMPT (base), NULL);
-       self = GKD_SECRET_PROMPT (base);
-
-       /* This should already have been caught elsewhere */
-       caller = dbus_message_get_sender (message);
-       if (!caller || !g_str_equal (caller, self->pv->caller))
-               g_return_val_if_reached (NULL);
-
-       /* org.freedesktop.Secret.Prompt.Prompt() */
-       else if (dbus_message_is_method_call (message, SECRET_PROMPT_INTERFACE, "Prompt"))
-               reply = prompt_method_prompt (self, message);
-
-       /* org.freedesktop.Secret.Prompt.Negotiate() */
-       else if (dbus_message_is_method_call (message, SECRET_PROMPT_INTERFACE, "Dismiss"))
-               reply = prompt_method_dismiss (self, message);
-
-       /* org.freedesktop.DBus.Introspectable.Introspect() */
-       else if (dbus_message_has_interface (message, DBUS_INTERFACE_INTROSPECTABLE))
-               return gkd_dbus_introspect_handle (message, gkd_secret_introspect_prompt, NULL);
-
-       return reply;
-}
-
-
 static void
 gkd_secret_prompt_constructed (GObject *obj)
 {
        GkdSecretPrompt *self = GKD_SECRET_PROMPT (obj);
+       GError *error = NULL;
 
        G_OBJECT_CLASS (gkd_secret_prompt_parent_class)->constructed (obj);
 
@@ -220,6 +173,21 @@ gkd_secret_prompt_constructed (GObject *obj)
 
        /* Set the exchange for the prompt */
        g_object_set (self, "secret-exchange", self->pv->exchange, NULL);
+
+        self->pv->skeleton = gkd_org_freedesktop_secret_prompt_skeleton_new ();
+        g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (self->pv->skeleton),
+                                          gkd_secret_service_get_connection (self->pv->service), 
self->pv->object_path,
+                                          &error);
+
+        if (error != NULL) {
+               g_warning ("could not register secret prompt on session bus: %s", error->message);
+               g_error_free (error);
+       }
+
+       g_signal_connect (self->pv->skeleton, "handle-dismiss",
+                         G_CALLBACK (prompt_method_dismiss), self);
+       g_signal_connect (self->pv->skeleton, "handle-prompt",
+                         G_CALLBACK (prompt_method_prompt), self);
 }
 
 static void
@@ -344,7 +312,6 @@ gkd_secret_prompt_class_init (GkdSecretPromptClass *klass)
 static void
 gkd_secret_dispatch_iface (GkdSecretDispatchIface *iface)
 {
-       iface->dispatch_message = gkd_secret_prompt_real_dispatch_message;
 }
 
 /* -----------------------------------------------------------------------------
diff --git a/daemon/dbus/gkd-secret-prompt.h b/daemon/dbus/gkd-secret-prompt.h
index 297750b..0b52ea0 100644
--- a/daemon/dbus/gkd-secret-prompt.h
+++ b/daemon/dbus/gkd-secret-prompt.h
@@ -28,8 +28,6 @@
 #include <gck/gck.h>
 #include <gcr/gcr-base.h>
 
-#include <dbus/dbus.h>
-
 #define GKD_SECRET_TYPE_PROMPT               (gkd_secret_prompt_get_type ())
 #define GKD_SECRET_PROMPT(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GKD_SECRET_TYPE_PROMPT, 
GkdSecretPrompt))
 #define GKD_SECRET_PROMPT_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GKD_SECRET_TYPE_PROMPT, 
GkdSecretPromptClass))
@@ -50,8 +48,7 @@ struct _GkdSecretPromptClass {
 
        void       (*prompt_ready)       (GkdSecretPrompt *self);
 
-       void       (*encode_result)      (GkdSecretPrompt *self,
-                                         DBusMessageIter *iter);
+       GVariant * (*encode_result)      (GkdSecretPrompt *self);
 };
 
 GType               gkd_secret_prompt_get_type                (void) G_GNUC_CONST;
diff --git a/daemon/dbus/gkd-secret-property.c b/daemon/dbus/gkd-secret-property.c
index bfa3739..9c30d80 100644
--- a/daemon/dbus/gkd-secret-property.c
+++ b/daemon/dbus/gkd-secret-property.c
@@ -149,86 +149,69 @@ attribute_to_property (CK_ATTRIBUTE_TYPE attr_type, const gchar **prop_name, Dat
        return TRUE;
 }
 
-typedef void (*IterAppendFunc) (DBusMessageIter*, const GckAttribute *);
-typedef gboolean (*IterGetFunc) (DBusMessageIter*, gulong, GckBuilder *);
+typedef GVariant * (*IterAppendFunc) (const GckAttribute *);
+typedef gboolean (*IterGetFunc) (GVariant *, gulong, GckBuilder *);
 
-static void
-iter_append_string (DBusMessageIter *iter,
-                    const GckAttribute *attr)
+static GVariant *
+iter_append_string (const GckAttribute *attr)
 {
-       gchar *value;
-
-       g_assert (iter);
        g_assert (attr);
 
        if (attr->length == 0) {
-               value = "";
-               dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &value);
+               return g_variant_new_string ("");
        } else {
-               value = g_strndup ((const gchar*)attr->value, attr->length);
-               dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &value);
-               g_free (value);
+               return g_variant_new_take_string (g_strndup ((const gchar*)attr->value, attr->length));
        }
 }
 
 static gboolean
-iter_get_string (DBusMessageIter *iter,
+iter_get_string (GVariant *variant,
                  gulong attr_type,
                  GckBuilder *builder)
 {
        const char *value;
 
-       g_assert (iter != NULL);
+       g_assert (variant != NULL);
        g_assert (builder != NULL);
 
-       g_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_STRING, FALSE);
-       dbus_message_iter_get_basic (iter, &value);
+        value = g_variant_get_string (variant, NULL);
        if (value == NULL)
                value = "";
        gck_builder_add_string (builder, attr_type, value);
        return TRUE;
 }
 
-static void
-iter_append_bool (DBusMessageIter *iter,
-                  const GckAttribute *attr)
+static GVariant *
+iter_append_bool (const GckAttribute *attr)
 {
-       dbus_bool_t value;
-
-       g_assert (iter);
        g_assert (attr);
 
-       value = gck_attribute_get_boolean (attr) ? TRUE : FALSE;
-       dbus_message_iter_append_basic (iter, DBUS_TYPE_BOOLEAN, &value);
+       return g_variant_new_boolean (gck_attribute_get_boolean (attr));
 }
 
 static gboolean
-iter_get_bool (DBusMessageIter *iter,
+iter_get_bool (GVariant *variant,
                gulong attr_type,
                GckBuilder *builder)
 {
-       dbus_bool_t value;
+       gboolean value;
 
-       g_assert (iter != NULL);
+       g_assert (variant != NULL);
        g_assert (builder != NULL);
 
-       g_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_BOOLEAN, FALSE);
-       dbus_message_iter_get_basic (iter, &value);
-
-       gck_builder_add_boolean (builder, attr_type, value ? TRUE : FALSE);
+        value = g_variant_get_boolean (variant);
+       gck_builder_add_boolean (builder, attr_type, value);
        return TRUE;
 }
 
-static void
-iter_append_time (DBusMessageIter *iter,
-                  const GckAttribute *attr)
+static GVariant *
+iter_append_time (const GckAttribute *attr)
 {
        guint64 value;
        struct tm tm;
        gchar buf[15];
        time_t time;
 
-       g_assert (iter);
        g_assert (attr);
 
        if (attr->length == 0) {
@@ -258,11 +241,11 @@ iter_append_time (DBusMessageIter *iter,
                }
        }
 
-       dbus_message_iter_append_basic (iter, DBUS_TYPE_UINT64, &value);
+       return g_variant_new_uint64 (value);
 }
 
 static gboolean
-iter_get_time (DBusMessageIter *iter,
+iter_get_time (GVariant *variant,
                gulong attr_type,
                GckBuilder *builder)
 {
@@ -271,11 +254,10 @@ iter_get_time (DBusMessageIter *iter,
        gchar buf[20];
        guint64 value;
 
-       g_assert (iter != NULL);
+       g_assert (variant != NULL);
        g_assert (builder != NULL);
 
-       g_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_UINT64, FALSE);
-       dbus_message_iter_get_basic (iter, &value);
+        value = g_variant_get_uint64 (variant);
        if (value == 0) {
                gck_builder_add_empty (builder, attr_type);
                return TRUE;
@@ -292,28 +274,25 @@ iter_get_time (DBusMessageIter *iter,
        return TRUE;
 }
 
-static void
-iter_append_fields (DBusMessageIter *iter,
-                    const GckAttribute *attr)
+static GVariant *
+iter_append_fields (const GckAttribute *attr)
 {
-       DBusMessageIter array;
-       DBusMessageIter dict;
        const gchar *ptr;
        const gchar *last;
        const gchar *name;
        gsize n_name;
        const gchar *value;
        gsize n_value;
-       gchar *string;
+       gchar *name_string, *value_string;
+       GVariantBuilder builder;
 
-       g_assert (iter);
        g_assert (attr);
 
        ptr = (gchar*)attr->value;
        last = ptr + attr->length;
-       g_return_if_fail (ptr || last == ptr);
+       g_return_val_if_fail (ptr || last == ptr, NULL);
 
-       dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, "{ss}", &array);
+       g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}"));
 
        while (ptr && ptr != last) {
                g_assert (ptr < last);
@@ -332,58 +311,43 @@ iter_append_fields (DBusMessageIter *iter,
                n_value = ptr - value;
                ++ptr;
 
-               dbus_message_iter_open_container (&array, DBUS_TYPE_DICT_ENTRY, NULL, &dict);
-
-               string = g_strndup (name, n_name);
-               dbus_message_iter_append_basic (&dict, DBUS_TYPE_STRING, &string);
-               g_free (string);
+               name_string = g_strndup (name, n_name);
+               value_string = g_strndup (value, n_value);
 
-               string = g_strndup (value, n_value);
-               dbus_message_iter_append_basic (&dict, DBUS_TYPE_STRING, &string);
-               g_free (string);
+               g_variant_builder_add (&builder, "{ss}", name_string, value_string);
 
-               dbus_message_iter_close_container (&array, &dict);
+               g_free (name_string);
+               g_free (value_string);
        }
 
-       dbus_message_iter_close_container (iter, &array);
+       return g_variant_builder_end (&builder);
 }
 
 static gboolean
-iter_get_fields (DBusMessageIter *iter,
+iter_get_fields (GVariant *variant,
                  gulong attr_type,
                  GckBuilder *builder)
 {
-       DBusMessageIter array;
-       DBusMessageIter dict;
        GString *result;
-       const gchar *string;
+       const gchar *key, *value;
+        GVariantIter iter;
 
-       g_assert (iter != NULL);
+       g_assert (variant != NULL);
        g_assert (builder != NULL);
 
-       result = g_string_new ("");
-
-       g_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY, FALSE);
-       dbus_message_iter_recurse (iter, &array);
+       g_return_val_if_fail (g_variant_type_is_array (g_variant_get_type (variant)), FALSE);
 
-       while (dbus_message_iter_get_arg_type (&array) == DBUS_TYPE_DICT_ENTRY) {
-               dbus_message_iter_recurse (&array, &dict);
+       result = g_string_new ("");
+        g_variant_iter_init (&iter, variant);
 
+        while (g_variant_iter_next (&iter, "{&s&s}", &key, &value)) {
                /* Key */
-               g_return_val_if_fail (dbus_message_iter_get_arg_type (&dict) == DBUS_TYPE_STRING, FALSE);
-               dbus_message_iter_get_basic (&dict, &string);
-               g_string_append (result, string);
+               g_string_append (result, key);
                g_string_append_c (result, '\0');
 
-               dbus_message_iter_next (&dict);
-
                /* Value */
-               g_return_val_if_fail (dbus_message_iter_get_arg_type (&dict) == DBUS_TYPE_STRING, FALSE);
-               dbus_message_iter_get_basic (&dict, &string);
-               g_string_append (result, string);
+               g_string_append (result, value);
                g_string_append_c (result, '\0');
-
-               dbus_message_iter_next (&array);
        }
 
        gck_builder_add_data (builder, attr_type, (const guchar *)result->str, result->len);
@@ -391,94 +355,75 @@ iter_get_fields (DBusMessageIter *iter,
        return TRUE;
 }
 
-static void
-iter_append_variant (DBusMessageIter *iter,
-                     DataType data_type,
+static GVariant *
+iter_append_variant (DataType data_type,
                      const GckAttribute *attr)
 {
-       DBusMessageIter sub;
        IterAppendFunc func = NULL;
-       const gchar *sig = NULL;
 
-       g_assert (iter);
        g_assert (attr);
 
        switch (data_type) {
        case DATA_TYPE_STRING:
                func = iter_append_string;
-               sig = DBUS_TYPE_STRING_AS_STRING;
                break;
        case DATA_TYPE_BOOL:
                func = iter_append_bool;
-               sig = DBUS_TYPE_BOOLEAN_AS_STRING;
                break;
        case DATA_TYPE_TIME:
                func = iter_append_time;
-               sig = DBUS_TYPE_UINT64_AS_STRING;
                break;
        case DATA_TYPE_FIELDS:
                func = iter_append_fields;
-               sig = "a{ss}";
                break;
        default:
                g_assert (FALSE);
                break;
        }
 
-       dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, sig, &sub);
-       (func) (&sub, attr);
-       dbus_message_iter_close_container (iter, &sub);
+       return (func) (attr);
 }
 
 static gboolean
-iter_get_variant (DBusMessageIter *iter,
+iter_get_variant (GVariant *variant,
                   DataType data_type,
                   gulong attr_type,
                   GckBuilder *builder)
 {
-       DBusMessageIter variant;
        IterGetFunc func = NULL;
        gboolean ret;
-       const gchar *sig = NULL;
-       char *signature;
+        const GVariantType *sig;
 
-       g_assert (iter != NULL);
+       g_assert (variant != NULL);
        g_assert (builder != NULL);
 
-       g_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_VARIANT, FALSE);
-       dbus_message_iter_recurse (iter, &variant);
-
        switch (data_type) {
        case DATA_TYPE_STRING:
                func = iter_get_string;
-               sig = DBUS_TYPE_STRING_AS_STRING;
+                sig = G_VARIANT_TYPE_STRING;
                break;
        case DATA_TYPE_BOOL:
                func = iter_get_bool;
-               sig = DBUS_TYPE_BOOLEAN_AS_STRING;
+                sig = G_VARIANT_TYPE_BOOLEAN;
                break;
        case DATA_TYPE_TIME:
                func = iter_get_time;
-               sig = DBUS_TYPE_UINT64_AS_STRING;
+                sig = G_VARIANT_TYPE_UINT64;
                break;
        case DATA_TYPE_FIELDS:
                func = iter_get_fields;
-               sig = "a{ss}";
+                sig = G_VARIANT_TYPE ("a{ss}");
                break;
        default:
                g_assert (FALSE);
                break;
        }
 
-       signature = dbus_message_iter_get_signature (&variant);
-       g_return_val_if_fail (signature, FALSE);
-       ret = g_str_equal (sig, signature);
-       dbus_free (signature);
-
+        ret = g_variant_type_equal (g_variant_get_type (variant), sig);
        if (ret == FALSE)
                return FALSE;
 
-       return (func) (&variant, attr_type, builder);
+       return (func) (variant, attr_type, builder);
 }
 
 /* -----------------------------------------------------------------------------
@@ -497,107 +442,99 @@ gkd_secret_property_get_type (const gchar *property, CK_ATTRIBUTE_TYPE *type)
 }
 
 gboolean
-gkd_secret_property_parse_all (DBusMessageIter *array,
+gkd_secret_property_parse_all (GVariant *array,
                                const gchar *interface,
                                GckBuilder *builder)
 {
-       DBusMessageIter dict;
        CK_ATTRIBUTE_TYPE attr_type;
        const char *name;
        DataType data_type;
+        GVariantIter iter;
+        GVariant *variant;
 
        g_return_val_if_fail (array != NULL, FALSE);
        g_return_val_if_fail (builder != NULL, FALSE);
 
-       while (dbus_message_iter_get_arg_type (array) == DBUS_TYPE_DICT_ENTRY) {
-               dbus_message_iter_recurse (array, &dict);
+        g_variant_iter_init (&iter, array);
 
+       while (g_variant_iter_loop (&iter, "{sv}", &name, &variant)) {
                /* Property interface.name */
-               g_return_val_if_fail (dbus_message_iter_get_arg_type (&dict) == DBUS_TYPE_STRING, FALSE);
-               dbus_message_iter_get_basic (&dict, &name);
-               dbus_message_iter_next (&dict);
-
                if (!property_to_attribute (name, interface, &attr_type, &data_type))
                        return FALSE;
 
                /* Property value */
-               g_return_val_if_fail (dbus_message_iter_get_arg_type (&dict) == DBUS_TYPE_VARIANT, FALSE);
-               if (!iter_get_variant (&dict, data_type, attr_type, builder))
+               if (!iter_get_variant (variant, data_type, attr_type, builder))
                        return FALSE;
-
-               dbus_message_iter_next (array);
        }
 
        return TRUE;
 }
 
-gboolean
-gkd_secret_property_append_all (DBusMessageIter *array, GckAttributes *attrs)
+GVariant *
+gkd_secret_property_append_all (GckAttributes *attrs)
 {
-       DBusMessageIter dict;
        const GckAttribute *attr;
        DataType data_type;
        const gchar *name;
        gulong num, i;
+       GVariantBuilder builder;
+       GVariant *variant;
 
-       g_return_val_if_fail (array, FALSE);
-       g_return_val_if_fail (attrs, FALSE);
+       g_return_val_if_fail (attrs, NULL);
 
+       g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
        num = gck_attributes_count (attrs);
+
        for (i = 0; i < num; ++i) {
                attr = gck_attributes_at (attrs, i);
                if (!attribute_to_property (attr->type, &name, &data_type))
-                       g_return_val_if_reached (FALSE);
+                       g_return_val_if_reached (NULL);
 
-               dbus_message_iter_open_container (array, DBUS_TYPE_DICT_ENTRY, NULL, &dict);
-               dbus_message_iter_append_basic (&dict, DBUS_TYPE_STRING, &name);
-               iter_append_variant (&dict, data_type, attr);
-               dbus_message_iter_close_container (array, &dict);
+               variant = iter_append_variant (data_type, attr);
+               g_variant_builder_add (&builder, "{sv}", name, variant);
+               g_variant_unref (variant);
        }
 
-       return TRUE;
+       return g_variant_builder_end (&builder);
 }
 
-gboolean
-gkd_secret_property_append_variant (DBusMessageIter *iter,
-                                    const GckAttribute *attr)
+GVariant *
+gkd_secret_property_append_variant (const GckAttribute *attr)
 {
        const gchar *property;
        DataType data_type;
 
-       g_return_val_if_fail (attr, FALSE);
-       g_return_val_if_fail (iter, FALSE);
+       g_return_val_if_fail (attr, NULL);
 
        if (!attribute_to_property (attr->type, &property, &data_type))
-               return FALSE;
-       iter_append_variant (iter, data_type, attr);
-       return TRUE;
+               return NULL;
+       return iter_append_variant (data_type, attr);
 }
 
 gboolean
-gkd_secret_property_parse_variant (DBusMessageIter *iter,
+gkd_secret_property_parse_variant (GVariant *variant,
                                    const gchar *property,
                                    GckBuilder *builder)
 {
        CK_ATTRIBUTE_TYPE attr_type;
        DataType data_type;
 
-       g_return_val_if_fail (iter, FALSE);
+       g_return_val_if_fail (variant, FALSE);
        g_return_val_if_fail (property, FALSE);
        g_return_val_if_fail (builder != NULL, FALSE);
 
        if (!property_to_attribute (property, NULL, &attr_type, &data_type))
                return FALSE;
 
-       return iter_get_variant (iter, data_type, attr_type, builder);
+       return iter_get_variant (variant, data_type, attr_type, builder);
 }
 
 gboolean
-gkd_secret_property_parse_fields (DBusMessageIter *iter,
+gkd_secret_property_parse_fields (GVariant *variant,
                                   GckBuilder *builder)
 {
-       g_return_val_if_fail (iter != NULL, FALSE);
+       g_return_val_if_fail (variant != NULL, FALSE);
        g_return_val_if_fail (builder != NULL, FALSE);
 
-       return iter_get_fields (iter, CKA_G_FIELDS, builder);
+       return iter_get_fields (variant, CKA_G_FIELDS, builder);
 }
diff --git a/daemon/dbus/gkd-secret-property.h b/daemon/dbus/gkd-secret-property.h
index 3b37b9f..b5f161e 100644
--- a/daemon/dbus/gkd-secret-property.h
+++ b/daemon/dbus/gkd-secret-property.h
@@ -25,25 +25,23 @@
 
 #include <gck/gck.h>
 
-#include <dbus/dbus.h>
+#include <gio/gio.h>
 
 gboolean               gkd_secret_property_get_type               (const gchar *property,
                                                                    CK_ATTRIBUTE_TYPE *type);
 
-gboolean               gkd_secret_property_append_variant         (DBusMessageIter *iter,
-                                                                   const GckAttribute *attr);
+GVariant *             gkd_secret_property_append_variant         (const GckAttribute *attr);
 
-gboolean               gkd_secret_property_append_all             (DBusMessageIter *array,
-                                                                   GckAttributes *attrs);
+GVariant *             gkd_secret_property_append_all             (GckAttributes *attrs);
 
-gboolean               gkd_secret_property_parse_variant          (DBusMessageIter *iter,
+gboolean               gkd_secret_property_parse_variant          (GVariant *variant,
                                                                    const gchar *property,
                                                                    GckBuilder *builder);
 
-gboolean               gkd_secret_property_parse_fields           (DBusMessageIter *iter,
+gboolean               gkd_secret_property_parse_fields           (GVariant *variant,
                                                                    GckBuilder *builder);
 
-gboolean               gkd_secret_property_parse_all              (DBusMessageIter *array,
+gboolean               gkd_secret_property_parse_all              (GVariant *variant,
                                                                    const gchar *interface,
                                                                    GckBuilder *builder);
 
diff --git a/daemon/dbus/gkd-secret-secret.c b/daemon/dbus/gkd-secret-secret.c
index e70efd6..336ea49 100644
--- a/daemon/dbus/gkd-secret-secret.c
+++ b/daemon/dbus/gkd-secret-secret.c
@@ -21,6 +21,7 @@
 #include "config.h"
 
 #include "gkd-secret-dispatch.h"
+#include "gkd-secret-error.h"
 #include "gkd-secret-secret.h"
 #include "gkd-secret-service.h"
 #include "gkd-secret-session.h"
@@ -76,112 +77,74 @@ gkd_secret_secret_new_take_memory (GkdSecretSession *session,
 }
 
 GkdSecretSecret*
-gkd_secret_secret_parse (GkdSecretService *service, DBusMessage *message,
-                         DBusMessageIter *iter, DBusError *derr)
+gkd_secret_secret_parse (GkdSecretService *service,
+                         const char *sender,
+                         GVariant *variant,
+                         GError **error)
 {
-       GkdSecretSecret *secret;
+       GkdSecretSecret *secret = NULL;
        GkdSecretSession *session;
-       DBusMessageIter struc, array;
-       void *parameter, *value;
-       int n_value, n_parameter;
-       char *path, *content_type;
+       const char *parameter, *value, *path, *content_type;
+        gsize n_parameter, n_value;
+        GVariant *parameter_variant, *value_variant;
 
        g_return_val_if_fail (GKD_SECRET_IS_SERVICE (service), NULL);
-       g_return_val_if_fail (message, NULL);
-       g_return_val_if_fail (iter, NULL);
+       g_return_val_if_fail (variant, NULL);
+       g_return_val_if_fail (sender, NULL);
 
-       g_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_STRUCT, NULL);
-       dbus_message_iter_recurse (iter, &struc);
+        g_variant_get (variant, "(&o^&ay^&ay&s)", &path, NULL, NULL, &content_type);
 
-       /* Get the path */
-       if (dbus_message_iter_get_arg_type (&struc) != DBUS_TYPE_OBJECT_PATH) {
-               dbus_set_error (derr, DBUS_ERROR_INVALID_ARGS, "Invalid secret argument");
-               return NULL;
-       }
-       dbus_message_iter_get_basic (&struc, &path);
-
-       /* Get the parameter */
-       if (!dbus_message_iter_next (&struc) ||
-           dbus_message_iter_get_arg_type (&struc) != DBUS_TYPE_ARRAY ||
-           dbus_message_iter_get_element_type(&struc) != DBUS_TYPE_BYTE) {
-               dbus_set_error (derr, DBUS_ERROR_INVALID_ARGS, "Invalid secret argument");
-               return NULL;
-       }
-       dbus_message_iter_recurse (&struc, &array);
-       dbus_message_iter_get_fixed_array (&array, &parameter, &n_parameter);
-
-       /* Get the value */
-       if (!dbus_message_iter_next (&struc) ||
-           dbus_message_iter_get_arg_type (&struc) != DBUS_TYPE_ARRAY ||
-           dbus_message_iter_get_element_type(&struc) != DBUS_TYPE_BYTE) {
-               dbus_set_error (derr, DBUS_ERROR_INVALID_ARGS, "Invalid secret argument");
-               return NULL;
-       }
-       dbus_message_iter_recurse (&struc, &array);
-       dbus_message_iter_get_fixed_array (&array, &value, &n_value);
+        /* parameter */
+        parameter_variant = g_variant_get_child_value (variant, 1);
+        parameter = g_variant_get_fixed_array (parameter_variant, &n_parameter, sizeof (guint8));
 
-       /*
-        * TODO: We currently don't do anythinrg with the content type, because
-        * we have nowhere to store it.
-        */
-       if (!dbus_message_iter_next (&struc) ||
-           dbus_message_iter_get_arg_type (&struc) != DBUS_TYPE_STRING) {
-               dbus_set_error (derr, DBUS_ERROR_INVALID_ARGS, "Invalid content type argument");
-               return NULL;
-       }
-       dbus_message_iter_get_basic (&struc, &content_type);
+        /* value */
+        value_variant = g_variant_get_child_value (variant, 2);
+        value = g_variant_get_fixed_array (value_variant, &n_value, sizeof (guint8));
 
        /* Try to lookup the session */
-       session = gkd_secret_service_lookup_session (service, path,
-                                                    dbus_message_get_sender (message));
-
+       session = gkd_secret_service_lookup_session (service, path, sender);
        if (session == NULL) {
-               dbus_set_error (derr, SECRET_ERROR_NO_SESSION,
-                               "The session wrapping the secret does not exist");
-               return NULL;
+               g_set_error_literal (error, GKD_SECRET_ERROR,
+                                     GKD_SECRET_ERROR_NO_SESSION,
+                                    "The session wrapping the secret does not exist");
+               goto out;
        }
 
        secret = g_slice_new0 (GkdSecretSecret);
        secret->session = g_object_ref (session);
-       secret->parameter = parameter;
+       secret->parameter = g_strndup (parameter, n_parameter);
        secret->n_parameter = n_parameter;
-       secret->value = value;
+       secret->value = g_strndup (value, n_value);
        secret->n_value = n_value;
 
-       /* All the memory is owned by the message */
-       secret->destroy_data = dbus_message_ref (message);
-       secret->destroy_func = (GDestroyNotify)dbus_message_unref;
+ out:
+        g_variant_unref (parameter_variant);
+        g_variant_unref (value_variant);
+
        return secret;
 }
 
-void
-gkd_secret_secret_append (GkdSecretSecret *secret, DBusMessageIter *iter)
+GVariant *
+gkd_secret_secret_append (GkdSecretSecret *secret)
 {
+       GVariantBuilder builder;
        const gchar *content_type = "text/plain";
-       DBusMessageIter struc, array;
        const gchar *path;
-       int length;
+       GVariant *parameter, *value;
 
        path = gkd_secret_dispatch_get_object_path (GKD_SECRET_DISPATCH (secret->session));
-       g_return_if_fail (path);
-
-       dbus_message_iter_open_container (iter, DBUS_TYPE_STRUCT, NULL, &struc);
-       dbus_message_iter_append_basic (&struc, DBUS_TYPE_OBJECT_PATH, &path);
-       dbus_message_iter_open_container (&struc, DBUS_TYPE_ARRAY, "y", &array);
-       length = secret->n_parameter;
-       dbus_message_iter_append_fixed_array (&array, DBUS_TYPE_BYTE, &(secret->parameter), length);
-       dbus_message_iter_close_container (&struc, &array);
-       dbus_message_iter_open_container (&struc, DBUS_TYPE_ARRAY, "y", &array);
-       length = secret->n_value;
-       dbus_message_iter_append_fixed_array (&array, DBUS_TYPE_BYTE, &(secret->value), length);
-       dbus_message_iter_close_container (&struc, &array);
+       g_return_val_if_fail (path, NULL);
 
-       /*
-        * TODO: We're just putting a place holder value here for now.
-        */
-       dbus_message_iter_append_basic (&struc, DBUS_TYPE_STRING, &content_type);
+       g_variant_builder_init (&builder, G_VARIANT_TYPE ("ay"));
+       g_variant_builder_add (&builder, "y", secret->parameter);
+       parameter = g_variant_builder_end (&builder);
+
+       g_variant_builder_init (&builder, G_VARIANT_TYPE ("ay"));
+       g_variant_builder_add (&builder, "y", secret->value);
+       value = g_variant_builder_end (&builder);
 
-       dbus_message_iter_close_container (iter, &struc);
+       return g_variant_new ("(o ay@ays)", path, parameter, value, content_type);
 }
 
 void
diff --git a/daemon/dbus/gkd-secret-secret.h b/daemon/dbus/gkd-secret-secret.h
index 39c09f4..2520077 100644
--- a/daemon/dbus/gkd-secret-secret.h
+++ b/daemon/dbus/gkd-secret-secret.h
@@ -25,8 +25,6 @@
 
 #include <glib.h>
 
-#include <dbus/dbus.h>
-
 struct _GkdSecretSecret {
        GkdSecretSession *session;
 
@@ -52,12 +50,11 @@ GkdSecretSecret*       gkd_secret_secret_new_take_memory          (GkdSecretSess
                                                                    gsize n_value);
 
 GkdSecretSecret*       gkd_secret_secret_parse                    (GkdSecretService *service,
-                                                                   DBusMessage *message,
-                                                                   DBusMessageIter *iter,
-                                                                   DBusError *derr);
+                                                                   const char *sender,
+                                                                   GVariant *variant,
+                                                                   GError **error);
 
-void                   gkd_secret_secret_append                   (GkdSecretSecret *secret,
-                                                                   DBusMessageIter *iter);
+GVariant *             gkd_secret_secret_append                   (GkdSecretSecret *secret);
 
 void                   gkd_secret_secret_free                     (gpointer data);
 
diff --git a/daemon/dbus/gkd-secret-service.c b/daemon/dbus/gkd-secret-service.c
index 4c62bbe..1a37b6b 100644
--- a/daemon/dbus/gkd-secret-service.c
+++ b/daemon/dbus/gkd-secret-service.c
@@ -20,12 +20,10 @@
 
 #include "config.h"
 
-#include "gkd-dbus-util.h"
 #include "gkd-secret-change.h"
 #include "gkd-secret-create.h"
 #include "gkd-secret-dispatch.h"
 #include "gkd-secret-error.h"
-#include "gkd-secret-introspect.h"
 #include "gkd-secret-lock.h"
 #include "gkd-secret-objects.h"
 #include "gkd-secret-prompt.h"
@@ -37,6 +35,9 @@
 #include "gkd-secret-unlock.h"
 #include "gkd-secret-util.h"
 
+#include "gkd-internal-generated.h"
+#include "gkd-secrets-generated.h"
+
 #include "egg/egg-error.h"
 #include "egg/egg-unix-credentials.h"
 
@@ -46,6 +47,73 @@
 
 #include <string.h>
 
+/* -----------------------------------------------------------------------------
+ * SKELETON
+ */
+typedef struct {
+       GkdOrgFreedesktopSecretServiceSkeleton parent;
+       GkdSecretService *service;
+} GkdSecretServiceSkeleton;
+typedef struct {
+       GkdOrgFreedesktopSecretServiceSkeletonClass parent_class;
+} GkdSecretServiceSkeletonClass;
+
+GType gkd_secret_service_skeleton_get_type (void);
+G_DEFINE_TYPE (GkdSecretServiceSkeleton, gkd_secret_service_skeleton, 
GKD_TYPE_ORG_FREEDESKTOP_SECRET_SERVICE_SKELETON)
+
+enum {
+       PROP_COLLECTIONS = 1
+};
+
+static void
+gkd_secret_service_skeleton_get_property (GObject *object,
+                                         guint prop_id,
+                                         GValue *value,
+                                         GParamSpec *pspec)
+{
+       GkdSecretServiceSkeleton *skeleton = (GkdSecretServiceSkeleton *) object;
+
+       switch (prop_id) {
+       case PROP_COLLECTIONS:
+               g_value_take_boxed (value, gkd_secret_service_get_collections (skeleton->service));
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+               break;
+       }
+}
+
+static void
+gkd_secret_service_skeleton_set_property (GObject *object,
+                                         guint prop_id,
+                                         const GValue *value,
+                                         GParamSpec *pspec)
+{
+       G_OBJECT_CLASS (gkd_secret_service_skeleton_parent_class)->set_property (object, prop_id, value, 
pspec);
+}
+
+static void
+gkd_secret_service_skeleton_class_init (GkdSecretServiceSkeletonClass *klass)
+{
+       GObjectClass *oclass = G_OBJECT_CLASS (klass);
+       oclass->get_property = gkd_secret_service_skeleton_get_property;
+        oclass->set_property = gkd_secret_service_skeleton_set_property;
+       gkd_org_freedesktop_secret_service_override_properties (oclass, PROP_COLLECTIONS);
+}
+
+static void
+gkd_secret_service_skeleton_init (GkdSecretServiceSkeleton *self)
+{
+}
+
+static GkdOrgFreedesktopSecretService *
+gkd_secret_service_skeleton_new (GkdSecretService *service)
+{
+       GkdOrgFreedesktopSecretService *skeleton = g_object_new (gkd_secret_service_skeleton_get_type (), 
NULL);
+       ((GkdSecretServiceSkeleton *) skeleton)->service = service;
+       return skeleton;
+}
+
 enum {
        PROP_0,
        PROP_CONNECTION,
@@ -54,9 +122,13 @@ enum {
 
 struct _GkdSecretService {
        GObject parent;
-       DBusConnection *connection;
+
+       GDBusConnection *connection;
+       GkdOrgFreedesktopSecretService *skeleton;
+       GkdOrgGnomeKeyringInternalUnsupportedGuiltRiddenInterface *internal_skeleton;
+       guint name_owner_id;
+
        GHashTable *clients;
-       gchar *match_rule;
        GkdSecretObjects *objects;
        GHashTable *aliases;
        GckSession *internal_session;
@@ -72,9 +144,6 @@ typedef struct _ServiceClient {
        GHashTable *dispatch;
 } ServiceClient;
 
-/* Forward declaration */
-static void service_dispatch_message (GkdSecretService *, DBusMessage *);
-
 G_DEFINE_TYPE (GkdSecretService, gkd_secret_service, G_TYPE_OBJECT);
 
 /* -----------------------------------------------------------------------------
@@ -210,57 +279,39 @@ free_client (gpointer data)
        g_free (client);
 }
 
-typedef struct _on_get_connection_unix_process_id_args {
-       GkdSecretService *self;
-       DBusMessage *message;
-} on_get_connection_unix_process_id_args;
-
-static void
-free_on_get_connection_unix_process_id_args (gpointer data)
-{
-       on_get_connection_unix_process_id_args *args = data;
-       if (args != NULL) {
-               g_object_unref (args->self);
-               dbus_message_unref (args->message);
-               g_free (args);
-       }
-}
-
 static void
-on_get_connection_unix_process_id (DBusPendingCall *pending, gpointer user_data)
+initialize_service_client (GkdSecretService *self,
+                          const gchar *caller)
 {
-       on_get_connection_unix_process_id_args *args = user_data;
-       DBusMessage *reply = NULL;
-       DBusError error = DBUS_ERROR_INIT;
-       dbus_uint32_t caller_pid = 0;
-       GkdSecretService *self;
+       GError *error = NULL;
+       guint32 caller_pid;
+       GVariant *variant;
        ServiceClient *client;
-       const gchar *caller;
-
-       g_return_if_fail (GKD_SECRET_IS_SERVICE (args->self));
-       self = args->self;
-
-       /* Get the resulting process ID */
-       reply = dbus_pending_call_steal_reply (pending);
-       g_return_if_fail (reply);
-
-       caller = dbus_message_get_sender (args->message);
-       g_return_if_fail (caller);
-
-       client = g_hash_table_lookup (self->clients, caller);
-       if (client == NULL) {
-
-               /* An error returned from GetConnectionUnixProcessID */
-               if (dbus_set_error_from_message (&error, reply)) {
-                       g_message ("couldn't get the caller's unix process id: %s", error.message);
-                       caller_pid = 0;
-                       dbus_error_free (&error);
 
-               /* A PID was returned from GetConnectionUnixProcessID */
-               } else {
-                       if (!dbus_message_get_args (reply, NULL, DBUS_TYPE_UINT32, &caller_pid, 
DBUS_TYPE_INVALID))
-                               g_return_if_reached ();
-               }
+       g_assert (GKD_SECRET_IS_SERVICE (self));
+       g_assert (caller);
+
+       variant = g_dbus_connection_call_sync (self->connection,
+                                              "org.freedesktop.DBus",
+                                              "/org/freedesktop/DBus",
+                                              "org.freedesktop.DBus",
+                                              "GetConnectionUnixProcessID",
+                                              g_variant_new ("(s)", caller),
+                                              G_VARIANT_TYPE ("(u)"),
+                                              G_DBUS_CALL_FLAGS_NONE,
+                                              2000,
+                                              NULL, &error);
+
+       /* An error returned from GetConnectionUnixProcessID */
+       if (error != NULL) {
+               g_message ("couldn't get the caller's unix process id: %s", error->message);
+               caller_pid = 0;
+               g_error_free (error);
+
+       /* A PID was returned from GetConnectionUnixProcessID */
+       } else {
+               g_variant_get (variant, "(u)", &caller_pid);
+               g_variant_unref (variant);
 
                /* Initialize the client object */
                client = g_new0 (ServiceClient, 1);
@@ -276,186 +327,109 @@ on_get_connection_unix_process_id (DBusPendingCall *pending, gpointer user_data)
                /* Update default collection each time someone connects */
                update_default (self, TRUE);
        }
-
-       dbus_message_unref (reply);
-
-       /* Dispatch the original message again */
-       service_dispatch_message (self, args->message);
 }
 
 static void
-initialize_service_client (GkdSecretService *self, DBusMessage *message)
+gkd_secret_service_ensure_client (GkdSecretService *self,
+                                  GDBusMethodInvocation *invocation)
 {
-       on_get_connection_unix_process_id_args *args;
-       DBusMessage *request;
-       DBusPendingCall *pending;
-       const gchar *caller;
-
-       g_assert (GKD_SECRET_IS_SERVICE (self));
-       g_assert (message);
-
-       args = g_new0 (on_get_connection_unix_process_id_args, 1);
-       args->self = g_object_ref (self);
-       args->message = dbus_message_ref (message);
-
-       caller = dbus_message_get_sender (message);
-       g_return_if_fail (caller);
+       ServiceClient *client;
+        const gchar *caller;
 
-       /* Message org.freedesktop.DBus.GetConnectionUnixProcessID(IN String caller) */
-       request = dbus_message_new_method_call ("org.freedesktop.DBus", "/org/freedesktop/DBus",
-                                               "org.freedesktop.DBus", "GetConnectionUnixProcessID");
-       if (!request || !dbus_message_append_args (request, DBUS_TYPE_STRING, &caller, DBUS_TYPE_INVALID))
-               g_return_if_reached ();
-
-       /*
-        * Send of request for GetConnectionUnixProcessID, with lowish timeout.
-        * We're only talking to the session bus, so the reply should be fast.
-        * In addition we want to send off a reply to our caller, before it
-        * times out.
-        */
-       if (!dbus_connection_send_with_reply (self->connection, request, &pending, 2000))
-               g_return_if_reached ();
-       dbus_message_unref (request);
-
-       /* Track our new session object, on this call */
-       dbus_pending_call_set_notify (pending, on_get_connection_unix_process_id, args,
-                                     free_on_get_connection_unix_process_id_args);
-       dbus_pending_call_unref (pending);
+        caller = g_dbus_method_invocation_get_sender (invocation);
+       client = g_hash_table_lookup (self->clients, caller);
+       if (client == NULL) {
+               initialize_service_client (self, caller);
+       }
 }
 
 /* -----------------------------------------------------------------------------
  * DBUS
  */
 
-static DBusMessage*
-service_property_get (GkdSecretService *self, DBusMessage *message)
+static gboolean
+service_method_open_session (GkdOrgFreedesktopSecretService *skeleton,
+                            GDBusMethodInvocation *invocation,
+                            gchar *algorithm,
+                            GVariant *input,
+                            GkdSecretService *self)
 {
-       DBusMessage *reply = NULL;
-       DBusMessageIter iter;
-       const gchar *interface;
-       const gchar *name;
-
-       if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &interface,
-                                   DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID))
-               return NULL;
-
-       if (!gkd_dbus_interface_match (SECRET_SERVICE_INTERFACE, interface))
-               return dbus_message_new_error_printf (message, DBUS_ERROR_FAILED,
-                                                     "Object does not have properties on interface '%s'",
-                                                     interface);
+       GkdSecretSession *session;
+       GVariant *output = NULL;
+       gchar *result = NULL;
+       GError *error = NULL;
+       const gchar *caller;
+        GVariant *input_payload;
 
-       /* The "Collections" property */
-       if (g_str_equal (name, "Collections")) {
-               reply = dbus_message_new_method_return (message);
-               dbus_message_iter_init_append (reply, &iter);
-               gkd_secret_objects_append_collection_paths (self->objects, &iter, message);
+        gkd_secret_service_ensure_client (self, invocation);
+       caller = g_dbus_method_invocation_get_sender (invocation);
 
-       /* No such property */
+       /* Now we can create a session with this information */
+       session = gkd_secret_session_new (self, caller);
+        input_payload = g_variant_get_variant (input);
+       gkd_secret_session_handle_open (session, algorithm, input_payload,
+                                       &output, &result,
+                                       &error);
+        g_variant_unref (input_payload);
+
+       if (error != NULL) {
+               g_dbus_method_invocation_take_error (invocation, error);
        } else {
-               reply = dbus_message_new_error_printf (message, DBUS_ERROR_FAILED,
-                                                      "Object does not have the '%s' property", name);
+               gkd_secret_service_publish_dispatch (self, caller,
+                                                    GKD_SECRET_DISPATCH (session));
+               gkd_org_freedesktop_secret_service_complete_open_session (skeleton, invocation, output, 
result);
+               g_free (result);
        }
 
-       return reply;
-}
-
-static DBusMessage*
-service_property_set (GkdSecretService *self, DBusMessage *message)
-{
-       return NULL; /* TODO: Need to implement */
+       g_object_unref (session);
+       return TRUE;
 }
 
-static void
-service_append_all_properties (GkdSecretService *self,
-                               DBusMessageIter *iter)
+static gboolean
+service_method_search_items (GkdOrgFreedesktopSecretService *skeleton,
+                            GDBusMethodInvocation *invocation,
+                            GVariant *attributes,
+                            GkdSecretService *self)
 {
-       DBusMessageIter array;
-       DBusMessageIter dict;
-       const gchar *name;
-
-       dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, "{sv}", &array);
-
-       name = "Collections";
-       dbus_message_iter_open_container (&array, DBUS_TYPE_DICT_ENTRY, NULL, &dict);
-       dbus_message_iter_append_basic (&dict, DBUS_TYPE_STRING, &name);
-       gkd_secret_objects_append_collection_paths (self->objects, &dict, NULL);
-       dbus_message_iter_close_container (&array, &dict);
-
-       dbus_message_iter_close_container (iter, &array);
+       gkd_secret_service_ensure_client (self, invocation);
+       return gkd_secret_objects_handle_search_items (self->objects, invocation,
+                                                      attributes, NULL, TRUE);
 }
 
-static DBusMessage*
-service_property_getall (GkdSecretService *self, DBusMessage *message)
+static gboolean
+service_method_get_secrets (GkdOrgFreedesktopSecretService *skeleton,
+                           GDBusMethodInvocation *invocation,
+                           gchar **items,
+                           gchar *session,
+                           GkdSecretService *self)
 {
-       DBusMessage *reply = NULL;
-       DBusMessageIter iter;
-       const gchar *interface;
-
-       if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &interface, DBUS_TYPE_INVALID))
-               return NULL;
-
-       if (!gkd_dbus_interface_match (SECRET_SERVICE_INTERFACE, interface))
-               return dbus_message_new_error_printf (message, DBUS_ERROR_FAILED,
-                                                     "Object does not have properties on interface '%s'",
-                                                     interface);
-
-       reply = dbus_message_new_method_return (message);
-       dbus_message_iter_init_append (reply, &iter);
-       service_append_all_properties (self, &iter);
-       return reply;
+       gkd_secret_service_ensure_client (self, invocation);
+       return gkd_secret_objects_handle_get_secrets (self->objects, invocation,
+                                                     (const gchar **) items, session);
 }
 
-static DBusMessage*
-service_method_open_session (GkdSecretService *self, DBusMessage *message)
-{
-       GkdSecretSession *session;
-       DBusMessage *reply = NULL;
-       const gchar *caller;
-
-       if (!dbus_message_has_signature (message, "sv"))
-               return NULL;
-
-       caller = dbus_message_get_sender (message);
-
-       /* Now we can create a session with this information */
-       session = gkd_secret_session_new (self, caller);
-       reply = gkd_secret_session_handle_open (session, message);
-
-       if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
-               gkd_secret_service_publish_dispatch (self, caller,
-                                                    GKD_SECRET_DISPATCH (session));
-
-       g_object_unref (session);
-       return reply;
-}
-
-static DBusMessage*
-service_method_create_collection (GkdSecretService *self, DBusMessage *message)
+static gboolean
+service_method_create_collection (GkdOrgFreedesktopSecretService *skeleton,
+                                 GDBusMethodInvocation *invocation,
+                                 GVariant *properties,
+                                 gchar *alias,
+                                 GkdSecretService *self)
 {
        GckBuilder builder = GCK_BUILDER_INIT;
-       DBusMessageIter iter, array;
        GckAttributes *attrs;
        GkdSecretCreate *create;
-       DBusMessage *reply;
        const gchar *path;
-       const gchar *alias;
        const char *caller;
-       const gchar *coll;
 
-       /* Parse the incoming message */
-       if (!dbus_message_has_signature (message, "a{sv}s"))
-               return NULL;
-       if (!dbus_message_iter_init (message, &iter))
-               g_return_val_if_reached (NULL);
-       dbus_message_iter_recurse (&iter, &array);
-       if (!gkd_secret_property_parse_all (&array, SECRET_COLLECTION_INTERFACE, &builder)) {
+       gkd_secret_service_ensure_client (self, invocation);
+
+       if (!gkd_secret_property_parse_all (properties, SECRET_COLLECTION_INTERFACE, &builder)) {
                gck_builder_clear (&builder);
-               return dbus_message_new_error_printf (message, DBUS_ERROR_INVALID_ARGS,
-                                                     "Invalid properties");
+               g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR,
+                                                              G_DBUS_ERROR_INVALID_ARGS,
+                                                              "Invalid properties");
+               return TRUE;
        }
-       if (!dbus_message_iter_next (&iter))
-               g_return_val_if_reached (NULL);
-       dbus_message_iter_get_basic (&iter, &alias);
 
        /* Empty alias is no alias */
        if (alias) {
@@ -463,8 +437,10 @@ service_method_create_collection (GkdSecretService *self, DBusMessage *message)
                        alias = NULL;
                } else if (!g_str_equal (alias, "default")) {
                        gck_builder_clear (&builder);
-                       return dbus_message_new_error (message, DBUS_ERROR_NOT_SUPPORTED,
-                                                      "Only the 'default' alias is supported");
+                       g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR,
+                                                                      G_DBUS_ERROR_NOT_SUPPORTED,
+                                                                      "Only the 'default' alias is 
supported");
+                       return TRUE;
                }
        }
 
@@ -472,7 +448,7 @@ service_method_create_collection (GkdSecretService *self, DBusMessage *message)
        attrs = gck_attributes_ref_sink (gck_builder_end (&builder));
 
        /* Create the prompt object, for the password */
-       caller = dbus_message_get_sender (message);
+       caller = g_dbus_method_invocation_get_sender (invocation);
        create = gkd_secret_create_new (self, caller, attrs, alias);
        gck_attributes_unref (attrs);
 
@@ -480,57 +456,52 @@ service_method_create_collection (GkdSecretService *self, DBusMessage *message)
        gkd_secret_service_publish_dispatch (self, caller,
                                             GKD_SECRET_DISPATCH (create));
 
-       coll = "/";
-       reply = dbus_message_new_method_return (message);
-       dbus_message_append_args (reply,
-                                 DBUS_TYPE_OBJECT_PATH, &coll,
-                                 DBUS_TYPE_OBJECT_PATH, &path,
-                                 DBUS_TYPE_INVALID);
-
-       g_object_unref (create);
-       return reply;
+       gkd_org_freedesktop_secret_service_complete_create_collection (skeleton, invocation,
+                                                                       "/", path);
+       return TRUE;
 }
 
-static DBusMessage*
-service_method_lock_service (GkdSecretService *self, DBusMessage *message)
+static gboolean
+service_method_lock_service (GkdOrgFreedesktopSecretService *skeleton,
+                            GDBusMethodInvocation *invocation,
+                            GkdSecretService *self)
 {
-       DBusError derr = DBUS_ERROR_INIT;
+       GError *error = NULL;
        GckSession *session;
        const char *caller;
 
-       if (!dbus_message_get_args (message, NULL, DBUS_TYPE_INVALID))
-               return NULL;
+       gkd_secret_service_ensure_client (self, invocation);
 
-       caller = dbus_message_get_sender (message);
+       caller = g_dbus_method_invocation_get_sender (invocation);
        session = gkd_secret_service_get_pkcs11_session (self, caller);
-       g_return_val_if_fail (session != NULL, NULL);
+       g_return_val_if_fail (session != NULL, FALSE);
 
-       if (!gkd_secret_lock_all (session, &derr))
-               return gkd_secret_error_to_reply (message, &derr);
+       if (!gkd_secret_lock_all (session, &error))
+               g_dbus_method_invocation_take_error (invocation, error);
+       else
+               gkd_org_freedesktop_secret_service_complete_lock_service (skeleton, invocation);
 
-       return dbus_message_new_method_return (message);
+       return TRUE;
 }
 
-static DBusMessage*
-service_method_unlock (GkdSecretService *self, DBusMessage *message)
+static gboolean
+service_method_unlock (GkdOrgFreedesktopSecretService *skeleton,
+                      GDBusMethodInvocation *invocation,
+                      gchar **objpaths,
+                      GkdSecretService *self)
 {
        GkdSecretUnlock *unlock;
-       DBusMessage *reply;
        const char *caller;
        const gchar *path;
-       int n_objpaths, i;
-       char **objpaths;
+       int i, n_unlocked;
+       gchar **unlocked;
 
-       if (!dbus_message_get_args (message, NULL,
-                                   DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &objpaths, &n_objpaths,
-                                   DBUS_TYPE_INVALID))
-               return NULL;
+       gkd_secret_service_ensure_client (self, invocation);
 
-       caller = dbus_message_get_sender (message);
+       caller = g_dbus_method_invocation_get_sender (invocation);
        unlock = gkd_secret_unlock_new (self, caller, NULL);
-       for (i = 0; i < n_objpaths; ++i)
+       for (i = 0; objpaths[i] != NULL; ++i)
                gkd_secret_unlock_queue (unlock, objpaths[i]);
-       dbus_free_string_array (objpaths);
 
        /* So do we need to prompt? */
        if (gkd_secret_unlock_have_queued (unlock)) {
@@ -543,38 +514,33 @@ service_method_unlock (GkdSecretService *self, DBusMessage *message)
                path = "/";
        }
 
-       reply = dbus_message_new_method_return (message);
-       objpaths = gkd_secret_unlock_get_results (unlock, &n_objpaths);
-       dbus_message_append_args (reply,
-                                 DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &objpaths, n_objpaths,
-                                 DBUS_TYPE_OBJECT_PATH, &path,
-                                 DBUS_TYPE_INVALID);
+       unlocked = gkd_secret_unlock_get_results (unlock, &n_unlocked);
+       gkd_org_freedesktop_secret_service_complete_unlock (skeleton, invocation,
+                                                           (const gchar **) unlocked, path);
 
        gkd_secret_unlock_reset_results (unlock);
        g_object_unref (unlock);
 
-       return reply;
+       return TRUE;
 }
 
-static DBusMessage*
-service_method_lock (GkdSecretService *self, DBusMessage *message)
+static gboolean
+service_method_lock (GkdOrgFreedesktopSecretService *skeleton,
+                    GDBusMethodInvocation *invocation,
+                    gchar **objpaths,
+                    GkdSecretService *self)
 {
-       DBusMessage *reply;
        const char *caller;
-       const gchar *prompt;
        GckObject *collection;
-       int n_objpaths, i;
-       char **objpaths;
+       int i;
+       char **locked;
        GPtrArray *array;
 
-       if (!dbus_message_get_args (message, NULL,
-                                   DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &objpaths, &n_objpaths,
-                                   DBUS_TYPE_INVALID))
-               return NULL;
+       gkd_secret_service_ensure_client (self, invocation);
 
-       caller = dbus_message_get_sender (message);
+       caller = g_dbus_method_invocation_get_sender (invocation);
        array = g_ptr_array_new ();
-       for (i = 0; i < n_objpaths; ++i) {
+       for (i = 0; objpaths[i] != NULL; ++i) {
                collection = gkd_secret_objects_lookup_collection (self->objects, caller, objpaths[i]);
                if (collection != NULL) {
                        if (gkd_secret_lock (collection, NULL)) {
@@ -586,60 +552,80 @@ service_method_lock (GkdSecretService *self, DBusMessage *message)
                }
        }
 
-       prompt = "/";
-       reply = dbus_message_new_method_return (message);
-       dbus_message_append_args (reply,
-                                 DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &array->pdata, array->len,
-                                 DBUS_TYPE_OBJECT_PATH, &prompt,
-                                 DBUS_TYPE_INVALID);
+       g_ptr_array_add (array, NULL);
+
+       locked = (gchar **) g_ptr_array_free (array, FALSE);
+       gkd_org_freedesktop_secret_service_complete_lock (skeleton, invocation,
+                                                         (const gchar **) locked, "/");
 
-       dbus_free_string_array (objpaths);
-       return reply;
+       return TRUE;
 }
 
-static DBusMessage*
-service_method_change_lock (GkdSecretService *self, DBusMessage *message)
+static gboolean
+method_change_lock_internal (GkdSecretService *self,
+                            GDBusMethodInvocation *invocation,
+                            const gchar *collection_path)
 {
        GkdSecretChange *change;
-       DBusMessage *reply;
        const char *caller;
        const gchar *path;
        GckObject *collection;
 
-       caller = dbus_message_get_sender (message);
-       if (!dbus_message_get_args (message, NULL, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID))
-               return NULL;
+       caller = g_dbus_method_invocation_get_sender (invocation);
 
        /* Make sure it exists */
-       collection = gkd_secret_objects_lookup_collection (self->objects, caller, path);
-       if (!collection)
-               return dbus_message_new_error (message, SECRET_ERROR_NO_SUCH_OBJECT,
-                                              "The collection does not exist");
+       collection = gkd_secret_objects_lookup_collection (self->objects, caller, collection_path);
+       if (!collection) {
+               g_dbus_method_invocation_return_error_literal (invocation, GKD_SECRET_ERROR,
+                                                               GKD_SECRET_ERROR_NO_SUCH_OBJECT,
+                                                               "The collection does not exist");
+               return TRUE;
+       }
+
        g_object_unref (collection);
 
-       change = gkd_secret_change_new (self, caller, path);
+       change = gkd_secret_change_new (self, caller, collection_path);
        path = gkd_secret_dispatch_get_object_path (GKD_SECRET_DISPATCH (change));
        gkd_secret_service_publish_dispatch (self, caller,
                                             GKD_SECRET_DISPATCH (change));
 
-       reply = dbus_message_new_method_return (message);
-       dbus_message_append_args (reply, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID);
-
+       g_dbus_method_invocation_return_value (invocation, g_variant_new ("(o)", path));
        g_object_unref (change);
-       return reply;
+
+       return TRUE;
+}
+
+static gboolean
+service_method_change_lock (GkdOrgFreedesktopSecretService *skeleton,
+                           GDBusMethodInvocation *invocation,
+                           gchar *collection_path,
+                           GkdSecretService *self)
+{
+       gkd_secret_service_ensure_client (self, invocation);
+       return method_change_lock_internal (self, invocation, collection_path);
 }
 
-static DBusMessage*
-service_method_read_alias (GkdSecretService *self, DBusMessage *message)
+static gboolean
+service_method_change_with_prompt (GkdOrgGnomeKeyringInternalUnsupportedGuiltRiddenInterface *skeleton,
+                                  GDBusMethodInvocation *invocation,
+                                  gchar *collection_path,
+                                  GkdSecretService *self)
+{
+       gkd_secret_service_ensure_client (self, invocation);
+       return method_change_lock_internal (self, invocation, collection_path);
+}
+
+static gboolean
+service_method_read_alias (GkdOrgFreedesktopSecretService *skeleton,
+                          GDBusMethodInvocation *invocation,
+                          gchar *alias,
+                          GkdSecretService *self)
 {
-       DBusMessage *reply;
-       const char *alias;
        gchar *path = NULL;
        const gchar *identifier;
        GckObject  *collection = NULL;
 
-       if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &alias, DBUS_TYPE_INVALID))
-               return NULL;
+       gkd_secret_service_ensure_client (self, invocation);
 
        identifier = gkd_secret_service_get_alias (self, alias);
        if (identifier)
@@ -648,7 +634,8 @@ service_method_read_alias (GkdSecretService *self, DBusMessage *message)
        /* Make sure it actually exists */
        if (path)
                collection = gkd_secret_objects_lookup_collection (self->objects,
-                                                                  dbus_message_get_sender (message), path);
+                                                                  g_dbus_method_invocation_get_sender 
(invocation),
+                                                                  path);
        if (collection == NULL) {
                g_free (path);
                path = NULL;
@@ -656,33 +643,33 @@ service_method_read_alias (GkdSecretService *self, DBusMessage *message)
                g_object_unref (collection);
        }
 
-       reply = dbus_message_new_method_return (message);
        if (path == NULL)
                path = g_strdup ("/");
-       dbus_message_append_args (reply, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID);
+
+       gkd_org_freedesktop_secret_service_complete_read_alias (skeleton, invocation, path);
        g_free (path);
 
-       return reply;
+       return TRUE;
 }
 
-static DBusMessage*
-service_method_set_alias (GkdSecretService *self, DBusMessage *message)
+static gboolean
+service_method_set_alias (GkdOrgFreedesktopSecretService *skeleton,
+                         GDBusMethodInvocation *invocation,
+                         gchar *alias,
+                         gchar *path,
+                         GkdSecretService *self)
 {
        GckObject *collection;
        gchar *identifier;
-       const char *alias;
-       const char *path;
 
-       if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &alias,
-                                   DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID))
-               return NULL;
+       gkd_secret_service_ensure_client (self, invocation);
 
-       g_return_val_if_fail (alias, NULL);
-       g_return_val_if_fail (path, NULL);
-
-       if (!g_str_equal (alias, "default"))
-               return dbus_message_new_error (message, DBUS_ERROR_NOT_SUPPORTED,
-                                              "Only the 'default' alias is supported");
+       if (!g_str_equal (alias, "default")) {
+               g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR,
+                                                              G_DBUS_ERROR_NOT_SUPPORTED,
+                                                              "Only the 'default' alias is supported");
+               return TRUE;
+       }
 
        /* No default collection */
        if (g_str_equal (path, "/")) {
@@ -691,16 +678,22 @@ service_method_set_alias (GkdSecretService *self, DBusMessage *message)
        /* Find a collection with that path */
        } else {
                if (!object_path_has_prefix (path, SECRET_COLLECTION_PREFIX) ||
-                   !gkd_secret_util_parse_path (path, &identifier, NULL))
-                       return dbus_message_new_error (message, DBUS_ERROR_INVALID_ARGS,
-                                                      "Invalid collection object path");
+                   !gkd_secret_util_parse_path (path, &identifier, NULL)) {
+                       g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR,
+                                                                      G_DBUS_ERROR_INVALID_ARGS,
+                                                                      "Invalid collection object path");
+                       return TRUE;
+               }
 
                collection = gkd_secret_objects_lookup_collection (self->objects,
-                                                                  dbus_message_get_sender (message), path);
+                                                                  g_dbus_method_invocation_get_sender 
(invocation),
+                                                                  path);
                if (collection == NULL) {
                        g_free (identifier);
-                       return dbus_message_new_error (message, SECRET_ERROR_NO_SUCH_OBJECT,
-                                                      "No such collection exists");
+                       g_dbus_method_invocation_return_error_literal (invocation, GKD_SECRET_ERROR,
+                                                                       GKD_SECRET_ERROR_NO_SUCH_OBJECT,
+                                                                       "The collection does not exist");
+                       return TRUE;
                }
 
                g_object_unref (collection);
@@ -709,37 +702,43 @@ service_method_set_alias (GkdSecretService *self, DBusMessage *message)
        gkd_secret_service_set_alias (self, alias, identifier);
        g_free (identifier);
 
-       return dbus_message_new_method_return (message);
+       gkd_org_freedesktop_secret_service_complete_set_alias (skeleton, invocation);
+
+       return TRUE;
 }
 
-static DBusMessage*
-service_method_create_with_master_password (GkdSecretService *self, DBusMessage *message)
+static gboolean
+service_method_create_with_master_password (GkdOrgGnomeKeyringInternalUnsupportedGuiltRiddenInterface 
*skeleton,
+                                           GDBusMethodInvocation *invocation,
+                                           GVariant *attributes,
+                                           GVariant *master,
+                                           GkdSecretService *self)
 {
        GckBuilder builder = GCK_BUILDER_INIT;
-       DBusError derr = DBUS_ERROR_INIT;
-       DBusMessageIter iter, array;
-       DBusMessage *reply = NULL;
        GkdSecretSecret *secret = NULL;
        GckAttributes *attrs = NULL;
        GError *error = NULL;
        gchar *path;
+       const gchar *caller;
 
-       /* Parse the incoming message */
-       if (!dbus_message_has_signature (message, "a{sv}(oayays)"))
-               return NULL;
-       if (!dbus_message_iter_init (message, &iter))
-               g_return_val_if_reached (NULL);
-       dbus_message_iter_recurse (&iter, &array);
-       if (!gkd_secret_property_parse_all (&array, SECRET_COLLECTION_INTERFACE, &builder)) {
+       gkd_secret_service_ensure_client (self, invocation);
+
+       if (!gkd_secret_property_parse_all (attributes, SECRET_COLLECTION_INTERFACE, &builder)) {
                gck_builder_clear (&builder);
-               return dbus_message_new_error (message, DBUS_ERROR_INVALID_ARGS,
-                                              "Invalid properties argument");
+               g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR,
+                                                               G_DBUS_ERROR_INVALID_ARGS,
+                                                               "Invalid properties argument");
+               return TRUE;
        }
-       dbus_message_iter_next (&iter);
-       secret = gkd_secret_secret_parse (self, message, &iter, &derr);
+
+       caller = g_dbus_method_invocation_get_sender (invocation);
+       secret = gkd_secret_secret_parse (self,
+                                         caller,
+                                         master, &error);
        if (secret == NULL) {
                gck_builder_clear (&builder);
-               return gkd_secret_error_to_reply (message, &derr);
+               g_dbus_method_invocation_take_error (invocation, error);
+               return TRUE;
        }
 
        gck_builder_add_boolean (&builder, CKA_TOKEN, TRUE);
@@ -748,64 +747,73 @@ service_method_create_with_master_password (GkdSecretService *self, DBusMessage
        gck_attributes_unref (attrs);
        gkd_secret_secret_free (secret);
 
-       if (path == NULL)
-               return gkd_secret_propagate_error (message, "Couldn't create collection", error);
+       if (path == NULL) {
+               gkd_secret_propagate_error (invocation, "Couldn't create collection", error);
+               return TRUE;
+       }
 
        /* Notify the callers that a collection was created */
+        g_message ("emit collection_Created");
        gkd_secret_service_emit_collection_created (self, path);
 
-       reply = dbus_message_new_method_return (message);
-       dbus_message_append_args (reply, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID);
+       gkd_org_gnome_keyring_internal_unsupported_guilt_ridden_interface_complete_create_with_master_password
+               (skeleton, invocation, path);
        g_free (path);
 
-       return reply;
+       return TRUE;
 }
 
-static DBusMessage*
-service_method_change_with_master_password (GkdSecretService *self, DBusMessage *message)
+static gboolean
+service_method_change_with_master_password (GkdOrgGnomeKeyringInternalUnsupportedGuiltRiddenInterface 
*skeleton,
+                                           GDBusMethodInvocation *invocation,
+                                           gchar *path,
+                                           GVariant *original_variant,
+                                           GVariant *master_variant,
+                                           GkdSecretService *self)
 {
-       DBusError derr = DBUS_ERROR_INIT;
        GkdSecretSecret *original, *master;
        GckObject *collection;
-       DBusMessageIter iter;
-       DBusMessage *reply;
        GError *error = NULL;
-       const gchar *path;
+       const gchar *sender;
+
+       gkd_secret_service_ensure_client (self, invocation);
+
+       sender = g_dbus_method_invocation_get_sender (invocation);
 
        /* Parse the incoming message */
-       if (!dbus_message_has_signature (message, "o(oayays)(oayays)"))
-               return NULL;
-       if (!dbus_message_iter_init (message, &iter))
-               g_return_val_if_reached (NULL);
-       dbus_message_iter_get_basic (&iter, &path);
-       dbus_message_iter_next (&iter);
-       original = gkd_secret_secret_parse (self, message, &iter, &derr);
-       if (original == NULL)
-               return gkd_secret_error_to_reply (message, &derr);
-       dbus_message_iter_next (&iter);
-       master = gkd_secret_secret_parse (self, message, &iter, &derr);
+       original = gkd_secret_secret_parse (self, sender,
+                                           original_variant, &error);
+       if (original == NULL) {
+               g_dbus_method_invocation_take_error (invocation, error);
+               return TRUE;
+       }
+
+       master = gkd_secret_secret_parse (self, sender,
+                                         master_variant, &error);
        if (master == NULL) {
-               gkd_secret_secret_free (original);
-               return gkd_secret_error_to_reply (message, &derr);
+               g_dbus_method_invocation_take_error (invocation, error);
+               return TRUE;
        }
 
        /* Make sure we have such a collection */
-       collection = gkd_secret_objects_lookup_collection (self->objects,
-                                                          dbus_message_get_sender (message),
+       collection = gkd_secret_objects_lookup_collection (self->objects, sender,
                                                           path);
 
        /* No such collection */
-       if (collection == NULL)
-               reply = dbus_message_new_error (message, SECRET_ERROR_NO_SUCH_OBJECT,
-                                               "The collection does not exist");
+       if (collection == NULL) {
+          g_dbus_method_invocation_return_error_literal (invocation, GKD_SECRET_ERROR,
+                                                         GKD_SECRET_ERROR_NO_SUCH_OBJECT,
+                                                         "The collection does not exist");
+       }
 
        /* Success */
        else if (gkd_secret_change_with_secrets (collection, NULL, original, master, &error))
-               reply = dbus_message_new_method_return (message);
+               
gkd_org_gnome_keyring_internal_unsupported_guilt_ridden_interface_complete_change_with_master_password
+                       (skeleton, invocation);
 
        /* Failure */
        else
-               reply = gkd_secret_propagate_error (message, "Couldn't change collection password", error);
+               gkd_secret_propagate_error (invocation, "Couldn't change collection password", error);
 
        gkd_secret_secret_free (original);
        gkd_secret_secret_free (master);
@@ -813,49 +821,50 @@ service_method_change_with_master_password (GkdSecretService *self, DBusMessage
        if (collection)
                g_object_unref (collection);
 
-       return reply;
+       return TRUE;
 }
 
-static DBusMessage*
-service_method_unlock_with_master_password (GkdSecretService *self, DBusMessage *message)
+static gboolean
+service_method_unlock_with_master_password (GkdOrgGnomeKeyringInternalUnsupportedGuiltRiddenInterface 
*skeleton,
+                                           GDBusMethodInvocation *invocation,
+                                           gchar *path,
+                                           GVariant *master_variant,
+                                           GkdSecretService *self)
 {
-       DBusError derr = DBUS_ERROR_INIT;
        GkdSecretSecret *master;
        GError *error = NULL;
        GckObject *collection;
-       DBusMessageIter iter;
-       DBusMessage *reply;
-       const gchar *path;
+       const gchar *sender;
+
+       gkd_secret_service_ensure_client (self, invocation);
+
+       sender = g_dbus_method_invocation_get_sender (invocation);
 
        /* Parse the incoming message */
-       if (!dbus_message_has_signature (message, "o(oayays)"))
-               return NULL;
-       if (!dbus_message_iter_init (message, &iter))
-               g_return_val_if_reached (NULL);
-       dbus_message_iter_get_basic (&iter, &path);
-       dbus_message_iter_next (&iter);
-       master = gkd_secret_secret_parse (self, message, &iter, &derr);
-       if (master == NULL)
-               return gkd_secret_error_to_reply (message, &derr);
+       master = gkd_secret_secret_parse (self, sender, master_variant, &error);
+       if (master == NULL) {
+               g_dbus_method_invocation_take_error (invocation, error);
+               return TRUE;
+       }
 
        /* Make sure we have such a collection */
-       collection = gkd_secret_objects_lookup_collection (self->objects,
-                                                          dbus_message_get_sender (message),
-                                                          path);
+       collection = gkd_secret_objects_lookup_collection (self->objects, sender, path);
 
        /* No such collection */
        if (collection == NULL) {
-               reply = dbus_message_new_error (message, SECRET_ERROR_NO_SUCH_OBJECT,
-                                               "The collection does not exist");
+               g_dbus_method_invocation_return_error_literal (invocation, GKD_SECRET_ERROR,
+                                                               GKD_SECRET_ERROR_NO_SUCH_OBJECT,
+                                                               "The collection does not exist");
 
        /* Success */
        } else if (gkd_secret_unlock_with_secret (collection, master, &error)) {
-               reply = dbus_message_new_method_return (message);
                gkd_secret_objects_emit_collection_locked (self->objects, collection);
+               
gkd_org_gnome_keyring_internal_unsupported_guilt_ridden_interface_complete_unlock_with_master_password
+                       (skeleton, invocation);
 
        /* Failure */
        } else {
-               reply = gkd_secret_propagate_error (message, "Couldn't unlock collection", error);
+               gkd_secret_propagate_error (invocation, "Couldn't unlock collection", error);
        }
 
        gkd_secret_secret_free (master);
@@ -863,299 +872,55 @@ service_method_unlock_with_master_password (GkdSecretService *self, DBusMessage
        if (collection)
                g_object_unref (collection);
 
-       return reply;
-}
-
-static void
-on_each_path_append_to_array (GkdSecretObjects *self,
-                              const gchar *path,
-                              GckObject *object,
-                              gpointer user_data)
-{
-       GPtrArray *array = user_data;
-       g_ptr_array_add (array, g_strdup (path));
-}
-
-static DBusMessage *
-service_introspect (GkdSecretService *self,
-                    DBusMessage *message)
-{
-       GPtrArray *names;
-       DBusMessage *reply;
-       ServiceClient *client;
-       const gchar *caller;
-       const gchar *path;
-       GHashTableIter iter;
-
-       names = g_ptr_array_new_with_free_func (g_free);
-       gkd_secret_objects_foreach_collection (self->objects, message,
-                                              on_each_path_append_to_array,
-                                              names);
-
-       /* Lookup all sessions and prompts for this client */
-       caller = dbus_message_get_sender (message);
-       if (caller != NULL) {
-               client = g_hash_table_lookup (self->clients, caller);
-               if (client != NULL) {
-                       g_hash_table_iter_init (&iter, client->dispatch);
-                       while (g_hash_table_iter_next (&iter, (gpointer *)&path, NULL))
-                               g_ptr_array_add (names, g_strdup (path));
-               }
-       }
-
-       g_ptr_array_add (names, NULL);
-
-       reply = gkd_dbus_introspect_handle (message, gkd_secret_introspect_service,
-                                           (const gchar **)names->pdata);
-
-       g_ptr_array_unref (names);
-       return reply;
-}
-
-static DBusMessage*
-service_message_handler (GkdSecretService *self, DBusMessage *message)
-{
-       g_return_val_if_fail (message, NULL);
-       g_return_val_if_fail (GKD_SECRET_IS_SERVICE (self), NULL);
-
-       /* org.freedesktop.Secret.Service.OpenSession() */
-       if (dbus_message_is_method_call (message, SECRET_SERVICE_INTERFACE, "OpenSession"))
-               return service_method_open_session (self, message);
-
-       /* org.freedesktop.Secret.Service.CreateCollection() */
-       if (dbus_message_is_method_call (message, SECRET_SERVICE_INTERFACE, "CreateCollection"))
-               return service_method_create_collection (self, message);
-
-       /* org.freedesktop.Secret.Service.LockService() */
-       if (dbus_message_is_method_call (message, SECRET_SERVICE_INTERFACE, "LockService"))
-               return service_method_lock_service (self, message);
-
-       /* org.freedesktop.Secret.Service.SearchItems() */
-       if (dbus_message_is_method_call (message, SECRET_SERVICE_INTERFACE, "SearchItems"))
-               return gkd_secret_objects_handle_search_items (self->objects, message, NULL, TRUE);
-
-       /* org.freedesktop.Secret.Service.GetSecrets() */
-       if (dbus_message_is_method_call (message, SECRET_SERVICE_INTERFACE, "GetSecrets"))
-               return gkd_secret_objects_handle_get_secrets (self->objects, message);
-
-       /* org.freedesktop.Secret.Service.Unlock() */
-       if (dbus_message_is_method_call (message, SECRET_SERVICE_INTERFACE, "Unlock"))
-               return service_method_unlock (self, message);
-
-       /* org.freedesktop.Secret.Service.Lock() */
-       if (dbus_message_is_method_call (message, SECRET_SERVICE_INTERFACE, "Lock"))
-               return service_method_lock (self, message);
-
-       /* org.gnome.keyring.InternalUnsupportedGuiltRiddenInterface.ChangeWithPrompt() */
-       if (dbus_message_is_method_call (message, INTERNAL_SERVICE_INTERFACE, "ChangeWithPrompt") ||
-           dbus_message_is_method_call (message, SECRET_SERVICE_INTERFACE, "ChangeLock"))
-               return service_method_change_lock (self, message);
-
-       /* org.freedesktop.Secret.Service.ReadAlias() */
-       if (dbus_message_is_method_call (message, SECRET_SERVICE_INTERFACE, "ReadAlias"))
-               return service_method_read_alias (self, message);
-
-       /* org.freedesktop.Secret.Service.SetAlias() */
-       if (dbus_message_is_method_call (message, SECRET_SERVICE_INTERFACE, "SetAlias"))
-               return service_method_set_alias (self, message);
-
-       /* org.gnome.keyring.InternalUnsupportedGuiltRiddenInterface.CreateWithMasterPassword */
-       if (dbus_message_is_method_call (message, INTERNAL_SERVICE_INTERFACE, "CreateWithMasterPassword"))
-               return service_method_create_with_master_password (self, message);
-
-       /* org.gnome.keyring.InternalUnsupportedGuiltRiddenInterface.ChangeWithMasterPassword() */
-       if (dbus_message_is_method_call (message, INTERNAL_SERVICE_INTERFACE, "ChangeWithMasterPassword"))
-               return service_method_change_with_master_password (self, message);
-
-       /* org.gnome.keyring.InternalUnsupportedGuiltRiddenInterface.UnlockWithMasterPassword() */
-       if (dbus_message_is_method_call (message, INTERNAL_SERVICE_INTERFACE, "UnlockWithMasterPassword"))
-               return service_method_unlock_with_master_password (self, message);
-
-       /* org.freedesktop.DBus.Properties.Get() */
-       if (dbus_message_is_method_call (message, DBUS_INTERFACE_PROPERTIES, "Get"))
-               return service_property_get (self, message);
-
-       /* org.freedesktop.DBus.Properties.Set() */
-       else if (dbus_message_is_method_call (message, DBUS_INTERFACE_PROPERTIES, "Set"))
-               return service_property_set (self, message);
-
-       /* org.freedesktop.DBus.Properties.GetAll() */
-       else if (dbus_message_is_method_call (message, DBUS_INTERFACE_PROPERTIES, "GetAll"))
-               return service_property_getall (self, message);
-
-       /* org.freedesktop.DBus.Introspectable.Introspect() */
-       else if (dbus_message_has_interface (message, DBUS_INTERFACE_INTROSPECTABLE))
-               return service_introspect (self, message);
-
-       return NULL;
-}
-
-static gboolean
-root_dispatch_message (GkdSecretService *self,
-                       DBusMessage *message)
-{
-       DBusMessage *reply = NULL;
-
-       if (dbus_message_has_interface (message, DBUS_INTERFACE_INTROSPECTABLE))
-               reply = gkd_dbus_introspect_handle (message, gkd_secret_introspect_root, NULL);
-
-       if (reply != NULL) {
-               dbus_connection_send (self->connection, reply, NULL);
-               dbus_message_unref (reply);
-               return TRUE;
-       }
-
-       return FALSE;
+       return TRUE;
 }
 
 static void
-service_dispatch_message (GkdSecretService *self, DBusMessage *message)
+service_name_owner_changed (GDBusConnection *connection,
+                           const gchar *sender_name,
+                           const gchar *object_path,
+                           const gchar *interface_name,
+                           const gchar *signal_name,
+                           GVariant *parameters,
+                           gpointer user_data)
 {
-       DBusMessage *reply = NULL;
-       const gchar *caller;
-       ServiceClient *client;
-       const gchar *path;
-       gpointer object;
-
-       g_assert (GKD_SECRET_IS_SERVICE (self));
-       g_assert (message);
-
-       /* The first thing we do is try to allocate a client context */
-       caller = dbus_message_get_sender (message);
-       if (caller == NULL) {
-               reply = dbus_message_new_error (message, DBUS_ERROR_FAILED,
-                                               "Could not not identify calling client application");
-               dbus_connection_send (self->connection, reply, NULL);
-               dbus_message_unref (reply);
-               return;
-       }
-
-       client = g_hash_table_lookup (self->clients, caller);
-       if (client == NULL) {
-               initialize_service_client (self, message);
-               return; /* This function called again, when client is initialized */
-       }
-
-       path = dbus_message_get_path (message);
-       g_return_if_fail (path);
-
-       /* Dispatched to a session or prompt */
-       if (object_path_has_prefix (path, SECRET_SESSION_PREFIX) ||
-           object_path_has_prefix (path, SECRET_PROMPT_PREFIX)) {
-               object = g_hash_table_lookup (client->dispatch, path);
-               if (object == NULL)
-                       reply = gkd_secret_error_no_such_object (message);
-               else
-                       reply = gkd_secret_dispatch_message (GKD_SECRET_DISPATCH (object), message);
-
-       /* Dispatched to a collection, off it goes */
-       } else if (object_path_has_prefix (path, SECRET_COLLECTION_PREFIX) ||
-                  object_path_has_prefix (path, SECRET_ALIAS_PREFIX)) {
-               reply = gkd_secret_objects_dispatch (self->objects, message);
-
-       /* Addressed to the service */
-       } else if (g_str_equal (path, SECRET_SERVICE_PATH)) {
-               reply = service_message_handler (self, message);
-       }
-
-       /* Should we send an error? */
-       if (!reply && dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL) {
-               if (!dbus_message_get_no_reply (message)) {
-                       reply = dbus_message_new_error_printf (message, DBUS_ERROR_UNKNOWN_METHOD,
-                                                              "Method \"%s\" with signature \"%s\" on 
interface \"%s\" doesn't exist\n",
-                                                              dbus_message_get_member (message),
-                                                              dbus_message_get_signature (message),
-                                                              dbus_message_get_interface (message));
-               }
-       }
-
-       if (reply) {
-               dbus_connection_send (self->connection, reply, NULL);
-               dbus_message_unref (reply);
-       }
-}
-
-static DBusHandlerResult
-gkd_secret_service_filter_handler (DBusConnection *conn, DBusMessage *message, gpointer user_data)
-{
-       GkdSecretService *self = user_data;
        const gchar *object_name;
        const gchar *old_owner;
        const gchar *new_owner;
-       const gchar *path;
-       const gchar *interface;
-
-       g_return_val_if_fail (conn && message, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
-       g_return_val_if_fail (GKD_SECRET_IS_SERVICE (self), DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
-
-       /* org.freedesktop.DBus.NameOwnerChanged(STRING name, STRING old_owner, STRING new_owner) */
-       if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "NameOwnerChanged") &&
-           dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &object_name,
-                                  DBUS_TYPE_STRING, &old_owner, DBUS_TYPE_STRING, &new_owner,
-                                  DBUS_TYPE_INVALID)) {
+        GkdSecretService *self = user_data;
 
-               /*
-                * A peer is connecting or disconnecting from the bus,
-                * remove any client info, when client gone.
-                */
-
-               g_return_val_if_fail (object_name && new_owner, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
-               if (g_str_equal (new_owner, "") && object_name[0] == ':')
-                       g_hash_table_remove (self->clients, object_name);
-
-               return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-       }
-
-       /*
-        * If the path is a within our object tree, then we do our own dispatch.
+       /* A peer is connecting or disconnecting from the bus,
+        * remove any client info, when client gone.
         */
-       path = dbus_message_get_path (message);
-       switch (dbus_message_get_type (message)) {
-
-       /* Dispatch any method call on our interfaces, for our objects */
-       case DBUS_MESSAGE_TYPE_METHOD_CALL:
-               if (path != NULL && g_str_equal (path, "/")) {
-                       if (root_dispatch_message (self, message))
-                               return DBUS_HANDLER_RESULT_HANDLED;
-               }
-
-               if (object_path_has_prefix (path, SECRET_SERVICE_PATH)) {
-                       interface = dbus_message_get_interface (message);
-                       if (interface == NULL ||
-                           g_str_has_prefix (interface, SECRET_INTERFACE_PREFIX) ||
-                           g_str_equal (interface, DBUS_INTERFACE_PROPERTIES) ||
-                           g_str_equal (interface, INTERNAL_SERVICE_INTERFACE) ||
-                           g_str_equal (interface, DBUS_INTERFACE_INTROSPECTABLE)) {
-                               service_dispatch_message (self, message);
-                               return DBUS_HANDLER_RESULT_HANDLED;
-                       }
-               }
-               break;
+       g_variant_get (parameters, "(&s&s&s)", &object_name, &old_owner, &new_owner);
 
-       /* Dispatch any signal for one of our objects */
-       case DBUS_MESSAGE_TYPE_SIGNAL:
-               if (object_path_has_prefix (path, SECRET_SERVICE_PATH)) {
-                       service_dispatch_message (self, message);
-                       return DBUS_HANDLER_RESULT_HANDLED;
-               }
-               break;
-
-       default:
-               break;
-       }
-
-       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+       if (g_str_equal (new_owner, "") && object_name[0] == ':')
+               g_hash_table_remove (self->clients, object_name);
 }
 
 /* -----------------------------------------------------------------------------
  * OBJECT
  */
 
+static void
+gkd_secret_service_init_collections (GkdSecretService *self)
+{
+        gchar **collections = gkd_secret_service_get_collections (self);
+        gint idx;
+
+        for (idx = 0; collections[idx] != NULL; idx++)
+               gkd_secret_objects_register_collection (self->objects, collections[idx]);
+
+       g_strfreev (collections);
+}
+
 static GObject*
-gkd_secret_service_constructor (GType type, guint n_props, GObjectConstructParam *props)
+gkd_secret_service_constructor (GType type,
+                                guint n_props,
+                                GObjectConstructParam *props)
 {
        GkdSecretService *self = GKD_SECRET_SERVICE (G_OBJECT_CLASS 
(gkd_secret_service_parent_class)->constructor(type, n_props, props));
-       DBusError error = DBUS_ERROR_INIT;
+       GError *error = NULL;
        GckSlot *slot = NULL;
        guint i;
 
@@ -1173,19 +938,65 @@ gkd_secret_service_constructor (GType type, guint n_props, GObjectConstructParam
        self->objects = g_object_new (GKD_SECRET_TYPE_OBJECTS,
                                      "pkcs11-slot", slot, "service", self, NULL);
 
-       /* Register for signals that let us know when clients leave the bus */
-       self->match_rule = g_strdup_printf ("type='signal',member=NameOwnerChanged,"
-                                           "interface='" DBUS_INTERFACE_DBUS "'");
-       dbus_bus_add_match (self->connection, self->match_rule, &error);
-       if (dbus_error_is_set (&error)) {
-               g_warning ("couldn't listen for NameOwnerChanged signal on session bus: %s", error.message);
-               dbus_error_free (&error);
-               g_free (self->match_rule);
-               self->match_rule = NULL;
+        self->skeleton = gkd_secret_service_skeleton_new (self);
+       g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (self->skeleton),
+                                          self->connection,
+                                         SECRET_SERVICE_PATH, &error);
+       if (error != NULL) {
+               g_warning ("could not register secret service on session bus: %s", error->message);
+               g_clear_error (&error);
        }
 
-       if (!dbus_connection_add_filter (self->connection, gkd_secret_service_filter_handler, self, NULL))
-               g_return_val_if_reached (NULL);
+       g_signal_connect (self->skeleton, "handle-change-lock",
+                         G_CALLBACK (service_method_change_lock), self);
+       g_signal_connect (self->skeleton, "handle-create-collection",
+                         G_CALLBACK (service_method_create_collection), self);
+       g_signal_connect (self->skeleton, "handle-get-secrets",
+                         G_CALLBACK (service_method_get_secrets), self);
+       g_signal_connect (self->skeleton, "handle-lock",
+                         G_CALLBACK (service_method_lock), self);
+       g_signal_connect (self->skeleton, "handle-lock-service",
+                         G_CALLBACK (service_method_lock_service), self);
+       g_signal_connect (self->skeleton, "handle-open-session",
+                         G_CALLBACK (service_method_open_session), self);
+       g_signal_connect (self->skeleton, "handle-read-alias",
+                         G_CALLBACK (service_method_read_alias), self);
+       g_signal_connect (self->skeleton, "handle-search-items",
+                         G_CALLBACK (service_method_search_items), self);
+       g_signal_connect (self->skeleton, "handle-set-alias",
+                         G_CALLBACK (service_method_set_alias), self);
+       g_signal_connect (self->skeleton, "handle-unlock",
+                         G_CALLBACK (service_method_unlock), self);
+
+        self->internal_skeleton = 
gkd_org_gnome_keyring_internal_unsupported_guilt_ridden_interface_skeleton_new ();
+       g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (self->internal_skeleton),
+                                          self->connection,
+                                         SECRET_SERVICE_PATH, &error);
+
+       if (error != NULL) {
+               g_warning ("could not register internal interface service on session bus: %s", 
error->message);
+               g_clear_error (&error);
+       }
+
+       g_signal_connect (self->internal_skeleton, "handle-change-with-master-password",
+                         G_CALLBACK (service_method_change_with_master_password), self);
+       g_signal_connect (self->internal_skeleton, "handle-change-with-prompt",
+                         G_CALLBACK (service_method_change_with_prompt), self);
+       g_signal_connect (self->internal_skeleton, "handle-create-with-master-password",
+                         G_CALLBACK (service_method_create_with_master_password), self);
+       g_signal_connect (self->internal_skeleton, "handle-unlock-with-master-password",
+                         G_CALLBACK (service_method_unlock_with_master_password), self);
+
+       self->name_owner_id = g_dbus_connection_signal_subscribe (self->connection,
+                                                                 NULL,
+                                                                 "org.freedesktop.DBus",
+                                                                 "NameOwnerChanged",
+                                                                 NULL, NULL,
+                                                                 G_DBUS_SIGNAL_FLAGS_NONE,
+                                                                 service_name_owner_changed,
+                                                                 self, NULL);
+
+        gkd_secret_service_init_collections (self);
 
        return G_OBJECT (self);
 }
@@ -1202,11 +1013,9 @@ gkd_secret_service_dispose (GObject *obj)
 {
        GkdSecretService *self = GKD_SECRET_SERVICE (obj);
 
-       if (self->match_rule) {
-               g_return_if_fail (self->connection);
-               dbus_bus_remove_match (self->connection, self->match_rule, NULL);
-               g_free (self->match_rule);
-               self->match_rule = NULL;
+       if (self->name_owner_id) {
+               g_dbus_connection_signal_unsubscribe (self->connection, self->name_owner_id);
+               self->name_owner_id = 0;
        }
 
        /* Closes all the clients */
@@ -1219,11 +1028,7 @@ gkd_secret_service_dispose (GObject *obj)
                self->objects = NULL;
        }
 
-       if (self->connection) {
-               dbus_connection_remove_filter (self->connection, gkd_secret_service_filter_handler, self);
-               dbus_connection_unref (self->connection);
-               self->connection = NULL;
-       }
+       g_clear_object (&self->connection);
 
        if (self->internal_session) {
                dispose_and_unref (self->internal_session);
@@ -1260,7 +1065,7 @@ gkd_secret_service_set_property (GObject *obj, guint prop_id, const GValue *valu
        switch (prop_id) {
        case PROP_CONNECTION:
                g_return_if_fail (!self->connection);
-               self->connection = g_value_dup_boxed (value);
+               self->connection = g_value_dup_object (value);
                g_return_if_fail (self->connection);
                break;
        case PROP_PKCS11_SLOT:
@@ -1280,7 +1085,7 @@ gkd_secret_service_get_property (GObject *obj, guint prop_id, GValue *value,
 
        switch (prop_id) {
        case PROP_CONNECTION:
-               g_value_set_boxed (value, gkd_secret_service_get_connection (self));
+               g_value_set_object (value, gkd_secret_service_get_connection (self));
                break;
        case PROP_PKCS11_SLOT:
                g_value_set_object (value, gkd_secret_service_get_pkcs11_slot (self));
@@ -1303,8 +1108,8 @@ gkd_secret_service_class_init (GkdSecretServiceClass *klass)
        gobject_class->get_property = gkd_secret_service_get_property;
 
        g_object_class_install_property (gobject_class, PROP_CONNECTION,
-               g_param_spec_boxed ("connection", "Connection", "DBus Connection",
-                                   GKD_DBUS_TYPE_CONNECTION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+               g_param_spec_object ("connection", "Connection", "DBus Connection",
+                                     G_TYPE_DBUS_CONNECTION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
        g_object_class_install_property (gobject_class, PROP_PKCS11_SLOT,
                g_param_spec_object ("pkcs11-slot", "Pkcs11 Slot", "PKCS#11 slot that we use for secrets",
@@ -1315,13 +1120,6 @@ gkd_secret_service_class_init (GkdSecretServiceClass *klass)
  * PUBLIC
  */
 
-void
-gkd_secret_service_send (GkdSecretService *self, DBusMessage *message)
-{
-       g_return_if_fail (GKD_SECRET_IS_SERVICE (self));
-       dbus_connection_send (self->connection, message, NULL);
-}
-
 GkdSecretObjects*
 gkd_secret_service_get_objects (GkdSecretService *self)
 {
@@ -1329,7 +1127,7 @@ gkd_secret_service_get_objects (GkdSecretService *self)
        return self->objects;
 }
 
-DBusConnection*
+GDBusConnection*
 gkd_secret_service_get_connection (GkdSecretService *self)
 {
        g_return_val_if_fail (GKD_SECRET_IS_SERVICE (self), NULL);
@@ -1552,69 +1350,63 @@ gkd_secret_service_publish_dispatch (GkdSecretService *self, const gchar *caller
        g_hash_table_replace (client->dispatch, (gpointer)path, g_object_ref (object));
 }
 
-static void
-emit_collections_properties_changed (GkdSecretService *self)
+gchar **
+gkd_secret_service_get_collections (GkdSecretService *self)
 {
-       const gchar *iface = SECRET_SERVICE_INTERFACE;
-       DBusMessage *message;
-       DBusMessageIter array;
-       DBusMessageIter iter;
-
-       message = dbus_message_new_signal (SECRET_SERVICE_PATH,
-                                          DBUS_INTERFACE_PROPERTIES,
-                                          "PropertiesChanged");
-
-       dbus_message_iter_init_append (message, &iter);
-       dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &iface);
-       service_append_all_properties (self, &iter);
-       dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "s", &array);
-       dbus_message_iter_close_container (&iter, &array);
-
-       if (!dbus_connection_send (self->connection, message, NULL))
-               g_return_if_reached ();
-       dbus_message_unref (message);
+       GVariant *collections_variant;
+       gchar **collections;
+
+       g_return_val_if_fail (GKD_SECRET_IS_SERVICE (self), NULL);
+
+       collections_variant = gkd_secret_objects_append_collection_paths (self->objects, NULL);
+        collections = g_variant_dup_objv (collections_variant, NULL);
+       g_variant_unref (collections_variant);
+
+       return collections;
 }
 
 void
 gkd_secret_service_emit_collection_created (GkdSecretService *self,
                                             const gchar *collection_path)
 {
-       DBusMessage *message;
+       gchar **collections;
 
        g_return_if_fail (GKD_SECRET_IS_SERVICE (self));
        g_return_if_fail (collection_path != NULL);
 
-       message = dbus_message_new_signal (SECRET_SERVICE_PATH,
-                                          SECRET_SERVICE_INTERFACE,
-                                          "CollectionCreated");
-       dbus_message_append_args (message, DBUS_TYPE_OBJECT_PATH, &collection_path,
-                                 DBUS_TYPE_INVALID);
+       gkd_secret_objects_register_collection (self->objects, collection_path);
 
-       if (!dbus_connection_send (self->connection, message, NULL))
-               g_return_if_reached ();
-       dbus_message_unref (message);
+       collections = gkd_secret_service_get_collections (self);
+       gkd_org_freedesktop_secret_service_set_collections (self->skeleton, (const gchar **) collections);
+       gkd_org_freedesktop_secret_service_emit_collection_created (self->skeleton, collection_path);
 
-       emit_collections_properties_changed (self);
+       g_strfreev (collections);
 }
 
 void
 gkd_secret_service_emit_collection_deleted (GkdSecretService *self,
                                             const gchar *collection_path)
 {
-       DBusMessage *message;
+       gchar **collections;
 
        g_return_if_fail (GKD_SECRET_IS_SERVICE (self));
        g_return_if_fail (collection_path != NULL);
 
-       message = dbus_message_new_signal (SECRET_SERVICE_PATH,
-                                          SECRET_SERVICE_INTERFACE,
-                                          "CollectionDeleted");
-       dbus_message_append_args (message, DBUS_TYPE_OBJECT_PATH, &collection_path,
-                                 DBUS_TYPE_INVALID);
+       gkd_secret_objects_unregister_collection (self->objects, collection_path);
+
+       collections = gkd_secret_service_get_collections (self);
+       gkd_org_freedesktop_secret_service_set_collections (self->skeleton, (const gchar **) collections);
+       gkd_org_freedesktop_secret_service_emit_collection_deleted (self->skeleton, collection_path);
 
-       if (!dbus_connection_send (self->connection, message, NULL))
-               g_return_if_reached ();
-       dbus_message_unref (message);
+       g_strfreev (collections);
+}
+
+void
+gkd_secret_service_emit_collection_changed (GkdSecretService *self,
+                                            const gchar *collection_path)
+{
+       g_return_if_fail (GKD_SECRET_IS_SERVICE (self));
+       g_return_if_fail (collection_path != NULL);
 
-       emit_collections_properties_changed (self);
+       gkd_org_freedesktop_secret_service_emit_collection_changed (self->skeleton, collection_path);
 }
diff --git a/daemon/dbus/gkd-secret-service.h b/daemon/dbus/gkd-secret-service.h
index a1845e7..f95ac96 100644
--- a/daemon/dbus/gkd-secret-service.h
+++ b/daemon/dbus/gkd-secret-service.h
@@ -25,8 +25,6 @@
 
 #include <gck/gck.h>
 
-#include <dbus/dbus.h>
-
 #include <glib-object.h>
 
 #define GKD_SECRET_TYPE_SERVICE               (gkd_secret_service_get_type ())
@@ -44,7 +42,7 @@ struct _GkdSecretServiceClass {
 
 GType                   gkd_secret_service_get_type                (void);
 
-DBusConnection*         gkd_secret_service_get_connection          (GkdSecretService *self);
+GDBusConnection*        gkd_secret_service_get_connection          (GkdSecretService *self);
 
 GckSlot*                gkd_secret_service_get_pkcs11_slot         (GkdSecretService *self);
 
@@ -64,9 +62,6 @@ GkdSecretSession*       gkd_secret_service_lookup_session          (GkdSecretSer
 void                    gkd_secret_service_close_session           (GkdSecretService *self,
                                                                     GkdSecretSession *sess);
 
-void                    gkd_secret_service_send                    (GkdSecretService *self,
-                                                                    DBusMessage *message);
-
 const gchar*            gkd_secret_service_get_alias               (GkdSecretService *self,
                                                                     const gchar *alias);
 
@@ -84,4 +79,9 @@ void                    gkd_secret_service_emit_collection_created (GkdSecretSer
 void                    gkd_secret_service_emit_collection_deleted (GkdSecretService *self,
                                                                     const gchar *collection_path);
 
+void                    gkd_secret_service_emit_collection_changed (GkdSecretService *self,
+                                                                    const gchar *collection_path);
+
+gchar **                gkd_secret_service_get_collections         (GkdSecretService *self);
+
 #endif /* ___SECRET_SERVICE_H__ */
diff --git a/daemon/dbus/gkd-secret-session.c b/daemon/dbus/gkd-secret-session.c
index 0d0fae2..834e00c 100644
--- a/daemon/dbus/gkd-secret-session.c
+++ b/daemon/dbus/gkd-secret-session.c
@@ -21,13 +21,13 @@
 #include "config.h"
 
 #include "gkd-secret-dispatch.h"
-#include "gkd-secret-introspect.h"
+#include "gkd-secret-error.h"
 #include "gkd-secret-secret.h"
 #include "gkd-secret-service.h"
 #include "gkd-secret-session.h"
 #include "gkd-secret-types.h"
 #include "gkd-secret-util.h"
-#include "gkd-dbus-util.h"
+#include "gkd-secrets-generated.h"
 
 #include "egg/egg-dh.h"
 #include "egg/egg-error.h"
@@ -50,6 +50,7 @@ struct _GkdSecretSession {
        /* Information about this object */
        gchar *object_path;
        GkdSecretService *service;
+       GkdOrgFreedesktopSecretSession *skeleton;
        gchar *caller_exec;
        gchar *caller;
 
@@ -166,24 +167,31 @@ aes_derive_key (GckSession *session, GckObject *priv_key,
        return TRUE;
 }
 
-static DBusMessage*
-aes_negotiate (GkdSecretSession *self, DBusMessage *message, gconstpointer input, gsize n_input)
+static gboolean
+aes_negotiate (GkdSecretSession *self,
+              GVariant *input_variant,
+              GVariant **output_variant,
+              gchar **result,
+              GError **error_out)
 {
-       DBusMessageIter iter, variant, array;
        GckSession *session;
        GckObject *pub, *priv, *key;
        GError *error = NULL;
-       DBusMessage *reply;
        gpointer output;
        gsize n_output;
+        const gchar *input;
+        gsize n_input;
        gboolean ret;
 
        session = gkd_secret_service_get_pkcs11_session (self->service, self->caller);
-       g_return_val_if_fail (session, NULL);
+       g_return_val_if_fail (session, FALSE);
 
-       if (!aes_create_dh_keys (session, "ietf-ike-grp-modp-1024", &pub, &priv))
-               return dbus_message_new_error_printf (message, DBUS_ERROR_FAILED,
-                                                      "Failed to create necessary crypto keys.");
+       if (!aes_create_dh_keys (session, "ietf-ike-grp-modp-1024", &pub, &priv)) {
+               g_set_error_literal (error_out, G_DBUS_ERROR,
+                                    G_DBUS_ERROR_FAILED,
+                                    "Failed to create necessary crypto keys.");
+               return FALSE;
+       }
 
        /* Get the output data */
        output = gck_object_get_data (pub, CKA_VALUE, NULL, &n_output, &error);
@@ -194,10 +202,13 @@ aes_negotiate (GkdSecretSession *self, DBusMessage *message, gconstpointer input
                g_warning ("couldn't get public key DH value: %s", egg_error_message (error));
                g_clear_error (&error);
                g_object_unref (priv);
-               return dbus_message_new_error_printf (message, DBUS_ERROR_FAILED,
-                                                     "Failed to retrieve necessary crypto keys.");
+               g_set_error_literal (error_out, G_DBUS_ERROR,
+                                    G_DBUS_ERROR_FAILED,
+                                    "Failed to retrieve necessary crypto keys.");
+               return FALSE;
        }
 
+        input = g_variant_get_fixed_array (input_variant, &n_input, sizeof (guint8));
        ret = aes_derive_key (session, priv, input, n_input, &key);
 
        gck_object_destroy (priv, NULL, NULL);
@@ -205,38 +216,44 @@ aes_negotiate (GkdSecretSession *self, DBusMessage *message, gconstpointer input
 
        if (ret == FALSE) {
                g_free (output);
-               return dbus_message_new_error_printf (message, DBUS_ERROR_FAILED,
-                                                      "Failed to create necessary crypto key.");
+               g_set_error_literal (error_out, G_DBUS_ERROR,
+                                    G_DBUS_ERROR_FAILED,
+                                    "Failed to create necessary crypto key.");
+               return FALSE;
        }
 
        take_session_key (self, key, CKM_AES_CBC_PAD);
 
-       reply = dbus_message_new_method_return (message);
-       dbus_message_iter_init_append (reply, &iter);
-       dbus_message_iter_open_container (&iter, DBUS_TYPE_VARIANT, "ay", &variant);
-       dbus_message_iter_open_container (&variant, DBUS_TYPE_ARRAY, "y", &array);
-       dbus_message_iter_append_fixed_array (&array, DBUS_TYPE_BYTE, &output, n_output);
-       dbus_message_iter_close_container (&variant, &array);
-       dbus_message_iter_close_container (&iter, &variant);
-       dbus_message_iter_append_basic (&iter, DBUS_TYPE_OBJECT_PATH, &self->object_path);
+       if (output_variant != NULL) {
+               GVariantBuilder builder;
+
+               g_variant_builder_init (&builder, G_VARIANT_TYPE ("ay"));
+               g_variant_builder_add (&builder, "y", (const gchar *) output);
+               *output_variant = g_variant_new_variant (g_variant_builder_end (&builder));
+       }
+
+       if (result != NULL) {
+               *result = g_strdup (self->object_path);
+       }
 
        g_free (output);
-       return reply;
+
+       return TRUE;
 }
 
-static DBusMessage*
-plain_negotiate (GkdSecretSession *self, DBusMessage *message)
+static gboolean
+plain_negotiate (GkdSecretSession *self,
+                GVariant **output,
+                gchar **result,
+                GError **error_out)
 {
        GckBuilder builder = GCK_BUILDER_INIT;
-       DBusMessageIter iter, variant;
        GError *error = NULL;
-       const char *output = "";
-       DBusMessage *reply;
        GckObject *key;
        GckSession *session;
 
        session = gkd_secret_service_get_pkcs11_session (self->service, self->caller);
-       g_return_val_if_fail (session, NULL);
+       g_return_val_if_fail (session, FALSE);
 
        gck_builder_add_ulong (&builder, CKA_CLASS, CKO_SECRET_KEY);
        gck_builder_add_ulong (&builder, CKA_KEY_TYPE, CKK_G_NULL);
@@ -246,76 +263,47 @@ plain_negotiate (GkdSecretSession *self, DBusMessage *message)
        if (key == NULL) {
                g_warning ("couldn't create null key: %s", egg_error_message (error));
                g_clear_error (&error);
-               return dbus_message_new_error_printf (message, DBUS_ERROR_FAILED,
-                                                     "Failed to create necessary plain keys.");
+               g_set_error_literal (error_out, G_DBUS_ERROR,
+                                    G_DBUS_ERROR_FAILED,
+                                    "Failed to create necessary plain keys.");
+               return FALSE;
        }
 
        take_session_key (self, key, CKM_G_NULL);
 
-       reply = dbus_message_new_method_return (message);
-       dbus_message_iter_init_append (reply, &iter);
-       dbus_message_iter_open_container (&iter, DBUS_TYPE_VARIANT, "s", &variant);
-       dbus_message_iter_append_basic (&variant, DBUS_TYPE_STRING, &output);
-       dbus_message_iter_close_container (&iter, &variant);
-       dbus_message_iter_append_basic (&iter, DBUS_TYPE_OBJECT_PATH, &self->object_path);
-       return reply;
+       if (output != NULL) {
+               *output = g_variant_new_variant (g_variant_new_string (""));
+       }
+
+       if (result != NULL) {
+               *result = g_strdup (self->object_path);
+       }
+
+       return TRUE;
 }
 
 /* -----------------------------------------------------------------------------
  * DBUS
  */
-
-static DBusMessage*
-session_method_close (GkdSecretSession *self, DBusMessage *message)
+static gboolean
+session_method_close (GkdOrgFreedesktopSecretSession *skeleton,
+                     GDBusMethodInvocation *invocation,
+                     GkdSecretSession *self)
 {
-       DBusMessage *reply;
-
-       g_return_val_if_fail (self->service, NULL);
-
-       if (!dbus_message_get_args (message, NULL, DBUS_TYPE_INVALID))
-               return NULL;
-
        gkd_secret_service_close_session (self->service, self);
+       gkd_org_freedesktop_secret_session_complete_close (skeleton, invocation);
 
-       reply = dbus_message_new_method_return (message);
-       dbus_message_append_args (reply, DBUS_TYPE_INVALID);
-       return reply;
+       return TRUE;
 }
 
 /* -----------------------------------------------------------------------------
  * OBJECT
  */
-
-static DBusMessage*
-gkd_secret_session_real_dispatch_message (GkdSecretDispatch *base, DBusMessage *message)
-{
-       const gchar *caller;
-       GkdSecretSession *self;
-
-       g_return_val_if_fail (message, NULL);
-       g_return_val_if_fail (GKD_SECRET_IS_SESSION (base), NULL);
-       self = GKD_SECRET_SESSION (base);
-
-       /* This should already have been caught elsewhere */
-       caller = dbus_message_get_sender (message);
-       if (!caller || !g_str_equal (caller, self->caller))
-               g_return_val_if_reached (NULL);
-
-       /* org.freedesktop.Secret.Session.Close() */
-       else if (dbus_message_is_method_call (message, SECRET_SESSION_INTERFACE, "Close"))
-               return session_method_close (self, message);
-
-       /* org.freedesktop.DBus.Introspectable.Introspect() */
-       else if (dbus_message_has_interface (message, DBUS_INTERFACE_INTROSPECTABLE))
-               return gkd_dbus_introspect_handle (message, gkd_secret_introspect_session, NULL);
-
-       return NULL;
-}
-
 static GObject*
 gkd_secret_session_constructor (GType type, guint n_props, GObjectConstructParam *props)
 {
        GkdSecretSession *self = GKD_SECRET_SESSION (G_OBJECT_CLASS 
(gkd_secret_session_parent_class)->constructor(type, n_props, props));
+       GError *error = NULL;
 
        g_return_val_if_fail (self, NULL);
        g_return_val_if_fail (self->caller, NULL);
@@ -324,6 +312,19 @@ gkd_secret_session_constructor (GType type, guint n_props, GObjectConstructParam
        /* Setup the path for the object */
        self->object_path = g_strdup_printf (SECRET_SESSION_PREFIX "/s%d", ++unique_session_number);
 
+       self->skeleton = gkd_org_freedesktop_secret_session_skeleton_new ();
+       g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (self->skeleton),
+                                         gkd_secret_service_get_connection (self->service),
+                                         self->object_path, &error);
+
+       if (error != NULL) {
+               g_warning ("could not register secret session on session bus: %s", error->message);
+               g_error_free (error);
+       }
+
+       g_signal_connect (self->skeleton, "handle-close",
+                         G_CALLBACK (session_method_close), self);
+
        return G_OBJECT (self);
 }
 
@@ -341,6 +342,11 @@ gkd_secret_session_dispose (GObject *obj)
        g_free (self->object_path);
        self->object_path = NULL;
 
+       if (self->skeleton) {
+               g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (self->skeleton));
+               g_clear_object (&self->skeleton);
+       }
+
        if (self->service) {
                g_object_remove_weak_pointer (G_OBJECT (self->service),
                                              (gpointer*)&(self->service));
@@ -457,7 +463,6 @@ gkd_secret_session_class_init (GkdSecretSessionClass *klass)
 static void
 gkd_secret_dispatch_iface (GkdSecretDispatchIface *iface)
 {
-       iface->dispatch_message = gkd_secret_session_real_dispatch_message;
 }
 
 /* -----------------------------------------------------------------------------
@@ -526,47 +531,49 @@ gkd_secret_session_complete (GkdSecretSession *self, gconstpointer peer,
        return TRUE;
 }
 
-DBusMessage*
-gkd_secret_session_handle_open (GkdSecretSession *self, DBusMessage *message)
+gboolean
+gkd_secret_session_handle_open (GkdSecretSession *self,
+                               const gchar *algorithm,
+                               GVariant *input,
+                               GVariant **output,
+                               gchar **result,
+                               GError **error)
 {
-       DBusMessage *reply;
-       const char *algorithm;
-       DBusMessageIter iter, variant, array;
-       gconstpointer input;
-       int n_input;
-
-       /* Parse the incoming message */
-       if (!dbus_message_has_signature (message, "sv"))
-               return NULL;
-       if (!dbus_message_iter_init (message, &iter))
-               g_return_val_if_reached (NULL);
-       dbus_message_iter_get_basic (&iter, &algorithm);
-       g_return_val_if_fail (algorithm, NULL);
-       if (!dbus_message_iter_next (&iter))
-               g_return_val_if_reached (NULL);
-       dbus_message_iter_recurse (&iter, &variant);
+       const GVariantType *variant_type;
+
+       variant_type = g_variant_get_type (input);
 
        /* Plain transfers? just remove our session key */
        if (g_str_equal (algorithm, "plain")) {
-               if (!g_str_equal ("s", dbus_message_iter_get_signature (&variant)))
-                       return dbus_message_new_error (message, DBUS_ERROR_INVALID_ARGS,
-                                                      "The session algorithm input argument was invalid");
-               reply = plain_negotiate (self, message);
+               if (!g_variant_type_equal (variant_type, G_VARIANT_TYPE_STRING)) {
+                       g_set_error (error, G_DBUS_ERROR,
+                                    G_DBUS_ERROR_INVALID_ARGS,
+                                    "The session algorithm input argument (%s) was invalid",
+                                    algorithm);
+                       return FALSE;
+               }
+
+               return plain_negotiate (self, output, result, error);
 
        } else if (g_str_equal (algorithm, "dh-ietf1024-sha256-aes128-cbc-pkcs7")) {
-               if (!g_str_equal ("ay", dbus_message_iter_get_signature (&variant)))
-                       return dbus_message_new_error (message, DBUS_ERROR_INVALID_ARGS,
-                                                      "The session algorithm input argument was invalid");
-               dbus_message_iter_recurse (&variant, &array);
-               dbus_message_iter_get_fixed_array (&array, &input, &n_input);
-               reply = aes_negotiate (self, message, input, n_input);
+               if (!g_variant_type_equal (variant_type, G_VARIANT_TYPE_BYTESTRING)) {
+                       g_set_error (error, G_DBUS_ERROR,
+                                     G_DBUS_ERROR_INVALID_ARGS,
+                                     "The session algorithm input argument (%s) was invalid",
+                                     algorithm);
+                       return FALSE;
+               }
+
+               return aes_negotiate (self, input, output, result, error);
 
        } else {
-               reply = dbus_message_new_error_printf (message, DBUS_ERROR_NOT_SUPPORTED,
-                                                      "The algorithm '%s' is not supported", algorithm);
+               g_set_error (error, G_DBUS_ERROR,
+                            G_DBUS_ERROR_NOT_SUPPORTED,
+                            "The algorithm '%s' is not supported", algorithm);
+               return FALSE;
        }
 
-       return reply;
+       g_assert_not_reached ();
 }
 
 
@@ -593,7 +600,7 @@ gkd_secret_session_get_pkcs11_session (GkdSecretSession *self)
 
 GkdSecretSecret*
 gkd_secret_session_get_item_secret (GkdSecretSession *self, GckObject *item,
-                                    DBusError *derr)
+                                   GError **error_out)
 {
        GckMechanism mech = { 0UL, NULL, 0 };
        GckSession *session;
@@ -624,12 +631,14 @@ gkd_secret_session_get_item_secret (GkdSecretSession *self, GckObject *item,
 
        if (error != NULL) {
                if (g_error_matches (error, GCK_ERROR, CKR_USER_NOT_LOGGED_IN)) {
-                       dbus_set_error_const (derr, SECRET_ERROR_IS_LOCKED,
-                                             "Cannot get secret of a locked object");
+                       g_set_error_literal (error_out, GKD_SECRET_ERROR,
+                                            GKD_SECRET_ERROR_IS_LOCKED,
+                                            "Cannot get secret of a locked object");
                } else {
                        g_message ("couldn't wrap item secret: %s", egg_error_message (error));
-                       dbus_set_error_const (derr, DBUS_ERROR_FAILED,
-                                             "Couldn't get item secret");
+                       g_set_error_literal (error_out, G_DBUS_ERROR,
+                                            G_DBUS_ERROR_FAILED,
+                                            "Couldn't get item secret");
                }
                g_clear_error (&error);
                g_free (iv);
@@ -641,7 +650,7 @@ gkd_secret_session_get_item_secret (GkdSecretSession *self, GckObject *item,
 
 gboolean
 gkd_secret_session_set_item_secret (GkdSecretSession *self, GckObject *item,
-                                    GkdSecretSecret *secret, DBusError *derr)
+                                    GkdSecretSecret *secret, GError **error_out)
 {
        GckBuilder builder = GCK_BUILDER_INIT;
        GckMechanism mech;
@@ -663,8 +672,9 @@ gkd_secret_session_set_item_secret (GkdSecretSession *self, GckObject *item,
 
        attrs = gck_object_get (item, NULL, &error, CKA_ID, CKA_G_COLLECTION, GCK_INVALID);
        if (attrs == NULL) {
-               g_message ("couldn't get item attributes: %s", egg_error_message (error));
-               dbus_set_error_const (derr, DBUS_ERROR_FAILED, "Couldn't set item secret");
+               g_set_error_literal (error_out, G_DBUS_ERROR,
+                                    G_DBUS_ERROR_FAILED,
+                                    "Couldn't set item secret");
                g_clear_error (&error);
                return FALSE;
        }
@@ -684,16 +694,20 @@ gkd_secret_session_set_item_secret (GkdSecretSession *self, GckObject *item,
 
        if (object == NULL) {
                if (g_error_matches (error, GCK_ERROR, CKR_USER_NOT_LOGGED_IN)) {
-                       dbus_set_error_const (derr, SECRET_ERROR_IS_LOCKED,
-                                             "Cannot set secret of a locked item");
+                       g_set_error_literal (error_out, GKD_SECRET_ERROR,
+                                            GKD_SECRET_ERROR_IS_LOCKED,
+                                            "Cannot set secret of a locked item");
                } else if (g_error_matches (error, GCK_ERROR, CKR_WRAPPED_KEY_INVALID) ||
                           g_error_matches (error, GCK_ERROR, CKR_WRAPPED_KEY_LEN_RANGE) ||
                           g_error_matches (error, GCK_ERROR, CKR_MECHANISM_PARAM_INVALID)) {
-                       dbus_set_error_const (derr, DBUS_ERROR_INVALID_ARGS,
-                                             "The secret was transferred or encrypted in an invalid way.");
+                       g_set_error_literal (error_out, G_DBUS_ERROR,
+                                            G_DBUS_ERROR_INVALID_ARGS,
+                                            "The secret was transferred or encrypted in an invalid way.");
                } else {
                        g_message ("couldn't unwrap item secret: %s", egg_error_message (error));
-                       dbus_set_error_const (derr, DBUS_ERROR_FAILED, "Couldn't set item secret");
+                       g_set_error_literal (error_out, G_DBUS_ERROR,
+                                            G_DBUS_ERROR_FAILED,
+                                            "Couldn't set item secret");
                }
                g_clear_error (&error);
                return FALSE;
@@ -701,7 +715,9 @@ gkd_secret_session_set_item_secret (GkdSecretSession *self, GckObject *item,
 
        if (!gck_object_equal (object, item)) {
                g_warning ("unwrapped secret went to new object, instead of item");
-               dbus_set_error_const (derr, DBUS_ERROR_FAILED, "Couldn't set item secret");
+               g_set_error_literal (error_out, G_DBUS_ERROR,
+                                    G_DBUS_ERROR_FAILED,
+                                    "Couldn't set item secret");
                g_object_unref (object);
                return FALSE;
        }
diff --git a/daemon/dbus/gkd-secret-session.h b/daemon/dbus/gkd-secret-session.h
index 8ea6584..0090f56 100644
--- a/daemon/dbus/gkd-secret-session.h
+++ b/daemon/dbus/gkd-secret-session.h
@@ -59,12 +59,12 @@ GckSession*         gkd_secret_session_get_pkcs11_session      (GkdSecretSession
 
 GkdSecretSecret*    gkd_secret_session_get_item_secret         (GkdSecretSession *self,
                                                                 GckObject *item,
-                                                                DBusError *derr);
+                                                                GError **error);
 
 gboolean            gkd_secret_session_set_item_secret         (GkdSecretSession *self,
                                                                 GckObject *item,
                                                                 GkdSecretSecret *secret,
-                                                                DBusError *derr);
+                                                                GError **error);
 
 GckObject*          gkd_secret_session_create_credential       (GkdSecretSession *self,
                                                                 GckSession *session,
@@ -72,7 +72,11 @@ GckObject*          gkd_secret_session_create_credential       (GkdSecretSession
                                                                 GkdSecretSecret *secret,
                                                                 GError **error);
 
-DBusMessage*        gkd_secret_session_handle_open             (GkdSecretSession *self,
-                                                                DBusMessage *message);
+gboolean            gkd_secret_session_handle_open             (GkdSecretSession *self,
+                                                                const gchar *algorithm,
+                                                                GVariant *input,
+                                                                GVariant **output,
+                                                                gchar **result,
+                                                                GError **error);
 
 #endif /* __GKD_SECRET_SESSION_H__ */
diff --git a/daemon/dbus/gkd-secret-types.h b/daemon/dbus/gkd-secret-types.h
index 06b7dd9..1f756d2 100644
--- a/daemon/dbus/gkd-secret-types.h
+++ b/daemon/dbus/gkd-secret-types.h
@@ -22,7 +22,6 @@
 #define __GKD_SECRET_TYPES_H__
 
 #define INTERNAL_SERVICE_INTERFACE     "org.gnome.keyring.InternalUnsupportedGuiltRiddenInterface"
-#define INTERNAL_ERROR_DENIED          "org.gnome.keyring.Error.Denied"
 
 #define SECRET_COLLECTION_INTERFACE    "org.freedesktop.Secret.Collection"
 #define SECRET_ITEM_INTERFACE          "org.freedesktop.Secret.Item"
@@ -39,10 +38,8 @@
 #define SECRET_PROMPT_PREFIX           "/org/freedesktop/secrets/prompt"
 #define SECRET_ALIAS_PREFIX            "/org/freedesktop/secrets/aliases"
 
-#define SECRET_ERROR_ALREADY_EXISTS    "org.freedesktop.Secret.Error.AlreadyExists"
-#define SECRET_ERROR_IS_LOCKED         "org.freedesktop.Secret.Error.IsLocked"
-#define SECRET_ERROR_NO_SESSION        "org.freedesktop.Secret.Error.NoSession"
-#define SECRET_ERROR_NO_SUCH_OBJECT    "org.freedesktop.Secret.Error.NoSuchObject"
+typedef enum _GkdSecretDaemonError GkdSecretDaemonError;
+typedef enum _GkdSecretError GkdSecretError;
 
 typedef struct _GkdSecretCollection GkdSecretCollection;
 typedef struct _GkdSecretChange GkdSecretChange;
diff --git a/daemon/dbus/gkd-secret-unlock.c b/daemon/dbus/gkd-secret-unlock.c
index 1335cdb..290837c 100644
--- a/daemon/dbus/gkd-secret-unlock.c
+++ b/daemon/dbus/gkd-secret-unlock.c
@@ -20,9 +20,8 @@
 
 #include "config.h"
 
-#include "gkd-dbus-util.h"
 #include "gkd-secret-dispatch.h"
-#include "gkd-secret-introspect.h"
+#include "gkd-secret-error.h"
 #include "gkd-secret-objects.h"
 #include "gkd-secret-secret.h"
 #include "gkd-secret-session.h"
@@ -30,6 +29,7 @@
 #include "gkd-secret-types.h"
 #include "gkd-secret-unlock.h"
 #include "gkd-secret-util.h"
+#include "gkd-secrets-generated.h"
 
 #include "egg/egg-error.h"
 #include "egg/egg-secure-memory.h"
@@ -62,6 +62,7 @@ struct _GkdSecretUnlock {
        GObject parent;
        gchar *object_path;
        GkdSecretService *service;
+       GkdOrgFreedesktopSecretPrompt *skeleton;
        gchar *caller;
        gchar *window_id;
        GQueue *queued;
@@ -144,39 +145,23 @@ static gboolean
 mark_as_complete (GkdSecretUnlock *self, gboolean dismissed)
 {
        GkdSecretUnlock *other;
-       DBusMessage *signal;
-       DBusMessageIter iter;
-       dbus_bool_t bval;
-       DBusMessageIter variant;
-       DBusMessageIter array;
        const char *value;
        gint i;
+       GVariantBuilder builder;
 
        if (self->completed)
                return FALSE;
        self->completed = TRUE;
 
-       signal = dbus_message_new_signal (self->object_path, SECRET_PROMPT_INTERFACE,
-                                         "Completed");
-       dbus_message_set_destination (signal, self->caller);
-       dbus_message_iter_init_append (signal, &iter);
-
-       bval = dismissed;
-       dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &bval);
-
-       dbus_message_iter_open_container (&iter, DBUS_TYPE_VARIANT, "ao", &variant);
-       dbus_message_iter_open_container (&variant, DBUS_TYPE_ARRAY, "o", &array);
-
+       g_variant_builder_init (&builder, G_VARIANT_TYPE ("ao"));
        for (i = 0; i < self->results->len; ++i) {
                value = g_array_index (self->results, gchar*, i);
-               dbus_message_iter_append_basic (&array, DBUS_TYPE_OBJECT_PATH, &value);
+               g_variant_builder_add (&builder, "o", value);
        }
 
-       dbus_message_iter_close_container (&variant, &array);
-       dbus_message_iter_close_container (&iter, &variant);
-
-       gkd_secret_service_send (self->service, signal);
-       dbus_message_unref (signal);
+       gkd_org_freedesktop_secret_prompt_emit_completed (self->skeleton,
+                                                         dismissed,
+                                                         g_variant_new_variant (g_variant_builder_end 
(&builder)));
 
        /* Fire off the next item in the unlock prompt queue */
        other = g_queue_pop_head (&unlock_prompt_queue);
@@ -313,87 +298,51 @@ perform_next_unlock (GkdSecretUnlock *self)
  * DBUS
  */
 
-static DBusMessage*
-prompt_method_prompt (GkdSecretUnlock *self, DBusMessage *message)
+static gboolean
+prompt_method_prompt (GkdOrgFreedesktopSecretPrompt *skeleton,
+                     GDBusMethodInvocation *invocation,
+                     gchar *window_id,
+                     GkdSecretUnlock *self)
 {
-       DBusMessage *reply;
-       const char *window_id;
-
        /* Act as if this object no longer exists */
        if (self->completed)
-               return NULL;
-
-       if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING,
-                                   &window_id, DBUS_TYPE_INVALID))
-               return NULL;
+               return FALSE;
 
        /* Prompt can only be called once */
-       if (self->prompted)
-               return dbus_message_new_error (message, SECRET_ERROR_ALREADY_EXISTS,
-                                              "This prompt has already been shown.");
+       if (self->prompted) {
+               g_dbus_method_invocation_return_error_literal (invocation,
+                                                               GKD_SECRET_ERROR,
+                                                               GKD_SECRET_ERROR_ALREADY_EXISTS,
+                                                               "This prompt has already been shown.");
+               return TRUE;
+       }
 
        gkd_secret_unlock_call_prompt (self, window_id);
 
-       reply = dbus_message_new_method_return (message);
-       dbus_message_append_args (reply, DBUS_TYPE_INVALID);
-       return reply;
+       gkd_org_freedesktop_secret_prompt_complete_prompt (skeleton, invocation);
+       return TRUE;
 }
 
-static DBusMessage*
-prompt_method_dismiss (GkdSecretUnlock *self, DBusMessage *message)
+static gboolean
+prompt_method_dismiss (GkdOrgFreedesktopSecretPrompt *skeleton,
+                      GDBusMethodInvocation *invocation,
+                      GkdSecretUnlock *self)
 {
-       DBusMessage *reply;
-
        /* Act as if this object no longer exists */
        if (self->completed)
-               return NULL;
-
-       if (!dbus_message_get_args (message, NULL, DBUS_TYPE_INVALID))
-               return NULL;
+               return FALSE;
 
        g_cancellable_cancel (self->cancellable);
        mark_as_complete (self, TRUE);
 
-       reply = dbus_message_new_method_return (message);
-       dbus_message_append_args (reply, DBUS_TYPE_INVALID);
-       return reply;
+       gkd_org_freedesktop_secret_prompt_complete_dismiss (skeleton, invocation);
+       return TRUE;
 }
 
 /* -----------------------------------------------------------------------------
  * OBJECT
  */
 
-static DBusMessage*
-gkd_secret_unlock_real_dispatch_message (GkdSecretDispatch *base, DBusMessage *message)
-{
-       DBusMessage *reply = NULL;
-       GkdSecretUnlock *self;
-       const gchar *caller;
-
-       g_return_val_if_fail (message, NULL);
-       g_return_val_if_fail (GKD_SECRET_IS_UNLOCK (base), NULL);
-       self = GKD_SECRET_UNLOCK (base);
-
-       /* This should already have been caught elsewhere */
-       caller = dbus_message_get_sender (message);
-       if (!caller || !g_str_equal (caller, self->caller))
-               g_return_val_if_reached (NULL);
-
-       /* org.freedesktop.Secret.Prompt.Prompt() */
-       else if (dbus_message_is_method_call (message, SECRET_PROMPT_INTERFACE, "Prompt"))
-               reply = prompt_method_prompt (self, message);
-
-       /* org.freedesktop.Secret.Prompt.Negotiate() */
-       else if (dbus_message_is_method_call (message, SECRET_PROMPT_INTERFACE, "Dismiss"))
-               reply = prompt_method_dismiss (self, message);
-
-       /* org.freedesktop.DBus.Introspectable.Introspect() */
-       else if (dbus_message_has_interface (message, DBUS_INTERFACE_INTROSPECTABLE))
-               return gkd_dbus_introspect_handle (message, gkd_secret_introspect_prompt, NULL);
-
-       return reply;
-}
-
 static void
 gkd_secret_unlock_init (GkdSecretUnlock *self)
 {
@@ -406,6 +355,7 @@ static GObject*
 gkd_secret_unlock_constructor (GType type, guint n_props, GObjectConstructParam *props)
 {
        GkdSecretUnlock *self = GKD_SECRET_UNLOCK (G_OBJECT_CLASS 
(gkd_secret_unlock_parent_class)->constructor(type, n_props, props));
+        GError *error = NULL;
 
        g_return_val_if_fail (self, NULL);
        g_return_val_if_fail (self->caller, NULL);
@@ -415,6 +365,21 @@ gkd_secret_unlock_constructor (GType type, guint n_props, GObjectConstructParam
        if (!self->object_path)
                self->object_path = g_strdup_printf (SECRET_PROMPT_PREFIX "/u%d", ++unique_prompt_number);
 
+        self->skeleton = gkd_org_freedesktop_secret_prompt_skeleton_new ();
+        g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (self->skeleton),
+                                          gkd_secret_service_get_connection (self->service), 
self->object_path,
+                                          &error);
+
+        if (error != NULL) {
+               g_warning ("could not register secret prompt on session bus: %s", error->message);
+               g_error_free (error);
+       }
+
+       g_signal_connect (self->skeleton, "handle-dismiss",
+                         G_CALLBACK (prompt_method_dismiss), self);
+       g_signal_connect (self->skeleton, "handle-prompt",
+                         G_CALLBACK (prompt_method_prompt), self);
+
        return G_OBJECT (self);
 }
 
@@ -423,6 +388,11 @@ gkd_secret_unlock_dispose (GObject *obj)
 {
        GkdSecretUnlock *self = GKD_SECRET_UNLOCK (obj);
 
+       if (self->skeleton) {
+               g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (self->skeleton));
+               g_clear_object (&self->skeleton);
+       }
+
        if (self->service) {
                g_object_remove_weak_pointer (G_OBJECT (self->service),
                                              (gpointer*)&(self->service));
@@ -552,7 +522,6 @@ gkd_secret_unlock_class_init (GkdSecretUnlockClass *klass)
 static void
 gkd_secret_dispatch_iface (GkdSecretDispatchIface *iface)
 {
-       iface->dispatch_message = gkd_secret_unlock_real_dispatch_message;
 }
 
 /* -----------------------------------------------------------------------------
@@ -674,7 +643,7 @@ gkd_secret_unlock_with_secret (GckObject *collection,
 
 gboolean
 gkd_secret_unlock_with_password (GckObject *collection, const guchar *password,
-                                 gsize n_password, DBusError *derr)
+                                 gsize n_password, GError **error_out)
 {
        GckBuilder builder = GCK_BUILDER_INIT;
        GError *error = NULL;
@@ -700,10 +669,14 @@ gkd_secret_unlock_with_password (GckObject *collection, const guchar *password,
        cred = gck_session_create_object (session, gck_builder_end (&builder), NULL, &error);
        if (cred == NULL) {
                if (g_error_matches (error, GCK_ERROR, CKR_PIN_INCORRECT)) {
-                       dbus_set_error_const (derr, INTERNAL_ERROR_DENIED, "The password was incorrect.");
+                       g_set_error_literal (error_out, GKD_SECRET_DAEMON_ERROR,
+                                            GKD_SECRET_DAEMON_ERROR_DENIED,
+                                            "The password was incorrect.");
                } else {
                        g_message ("couldn't create credential: %s", egg_error_message (error));
-                       dbus_set_error_const (derr, DBUS_ERROR_FAILED, "Couldn't use credentials");
+                       g_set_error_literal (error_out, G_DBUS_ERROR,
+                                            G_DBUS_ERROR_FAILED,
+                                            "Couldn't use credentials");
                }
                g_clear_error (&error);
                return FALSE;
diff --git a/daemon/dbus/gkd-secret-unlock.h b/daemon/dbus/gkd-secret-unlock.h
index 0f399e3..77319c5 100644
--- a/daemon/dbus/gkd-secret-unlock.h
+++ b/daemon/dbus/gkd-secret-unlock.h
@@ -66,6 +66,6 @@ gboolean            gkd_secret_unlock_with_secret             (GckObject *collec
 gboolean            gkd_secret_unlock_with_password           (GckObject *collection,
                                                                const guchar *password,
                                                                gsize n_password,
-                                                               DBusError *derr);
+                                                               GError **error);
 
 #endif /* __GKD_SECRET_UNLOCK_H__ */
diff --git a/daemon/dbus/gkd-secret-util.h b/daemon/dbus/gkd-secret-util.h
index f81e3e6..99e7814 100644
--- a/daemon/dbus/gkd-secret-util.h
+++ b/daemon/dbus/gkd-secret-util.h
@@ -25,8 +25,6 @@
 
 #include <glib.h>
 
-#include <dbus/dbus.h>
-
 gboolean          gkd_secret_util_parse_path                            (const gchar *path,
                                                                          gchar **collection,
                                                                          gchar **item);
diff --git a/daemon/dbus/org.freedesktop.Secrets.xml b/daemon/dbus/org.freedesktop.Secrets.xml
new file mode 100644
index 0000000..c1624ef
--- /dev/null
+++ b/daemon/dbus/org.freedesktop.Secrets.xml
@@ -0,0 +1,167 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd";>
+
+<node name="/org/freedesktop/Secrets">
+
+       <interface name="org.freedesktop.Secret.Service">
+               <property name="Collections" type="ao" access="read" />
+
+               <method name="OpenSession">
+                       <arg name="algorithm" type="s" direction="in"/>
+                       <arg name="input" type="v" direction="in"/>
+                       <arg name="output" type="v" direction="out"/>
+                       <arg name="result" type="o" direction="out"/>
+               </method>
+
+               <method name="CreateCollection">
+                       <arg name="properties" type="a{sv}" direction="in"/>
+                       <arg name="alias" type="s" direction="in"/>
+                       <arg name="collection" type="o" direction="out"/>
+                       <arg name="prompt" type="o" direction="out"/>
+               </method>
+
+               <method name="SearchItems">
+                       <arg name="attributes" type="a{ss}" direction="in"/>
+                       <arg name="unlocked" type="ao" direction="out"/>
+                       <arg name="locked" type="ao" direction="out"/>
+               </method>
+
+               <method name="Unlock">
+                       <arg name="objects" type="ao" direction="in"/>
+                       <arg name="unlocked" type="ao" direction="out"/>
+                       <arg name="prompt" type="o" direction="out"/>
+               </method>
+
+               <method name="Lock">
+                       <arg name="objects" type="ao" direction="in"/>
+                       <arg name="locked" type="ao" direction="out"/>
+                       <arg name="Prompt" type="o" direction="out"/>
+               </method>
+
+               <method name="LockService"/>
+
+               <method name="ChangeLock">
+                       <arg name="collection" type="o" direction="in"/>
+                       <arg name="prompt" type="o" direction="out"/>
+               </method>
+
+               <method name="GetSecrets">
+                       <arg name="items" type="ao" direction="in"/>
+                       <arg name="session" type="o" direction="in"/>
+                       <arg name="secrets" type="a{o(oayays)}" direction="out"/>
+               </method>
+
+               <method name="ReadAlias">
+                       <arg name="name" type='s' direction='in'/>
+                       <arg name="collection" type='o' direction='out'/>
+               </method>
+
+               <method name="SetAlias">
+                       <arg name="name" type='s' direction='in'/>
+                       <arg name="collection" type='o' direction='in'/>
+               </method>
+
+               <signal name="CollectionCreated">
+                       <arg name="collection" type="o"/>
+               </signal>
+
+               <signal name="CollectionDeleted">
+                       <arg name="collection" type="o"/>
+               </signal>
+
+               <signal name="CollectionChanged">
+                       <arg name="collection" type="o"/>
+               </signal>
+
+       </interface>
+
+       <interface name="org.freedesktop.Secret.Collection">
+
+               <property name="Items" type="ao" access="read"/>
+               <property name="Label" type="s" access="readwrite"/>
+               <property name="Locked" type="b" access="read"/>
+               <property name="Created" type="t" access="read"/>
+               <property name="Modified" type="t" access="read"/>
+
+               <method name="Delete">
+                       <arg name="prompt" type="o" direction="out"/>
+               </method>
+
+               <method name="SearchItems">
+                       <arg name="attributes" type="a{ss}" direction="in"/>
+                       <arg name="results" type="ao" direction="out"/>
+               </method>
+
+               <method name="CreateItem">
+                       <arg name="properties" type="a{sv}" direction="in"/>
+                       <arg name="secret" type="(oayays)" direction="in"/>
+                       <arg name="replace" type="b" direction="in"/>
+                       <arg name="item" type="o" direction="out"/>
+                       <arg name="prompt" type="o" direction="out"/>
+               </method>
+
+               <signal name="ItemCreated">
+                       <arg name="item" type="o"/>
+               </signal>
+
+               <signal name="ItemDeleted">
+                       <arg name="item" type="o"/>
+               </signal>
+
+               <signal name="ItemChanged">
+                       <arg name="item" type="o"/>
+               </signal>
+
+       </interface>
+
+       <interface name="org.freedesktop.Secret.Item">
+
+               <property name="Locked" type="b" access="read"/>
+
+               <property name="Attributes" type="a{ss}" access="readwrite"/>
+
+               <property name="Label" type="s" access="readwrite"/>
+
+               <property name="Created" type="t" access="read"/>
+
+               <property name="Modified" type="t" access="read"/>
+
+               <method name="Delete">
+                       <arg name="Prompt" type="o" direction="out"/>
+               </method>
+
+               <method name="GetSecret">
+                       <arg name="session" type="o" direction="in"/>
+                       <arg name="secret" type="(oayays)" direction="out"/>
+               </method>
+
+               <method name="SetSecret">
+                       <arg name="secret" type="(oayays)" direction="in"/>
+               </method>
+
+       </interface>
+
+
+       <interface name="org.freedesktop.Secret.Session">
+
+               <method name="Close">
+               </method>
+
+       </interface>
+
+       <interface name="org.freedesktop.Secret.Prompt">
+
+               <method name="Prompt">
+                       <arg name="window_id" type="s" direction="in"/>
+               </method>
+
+               <method name="Dismiss">
+               </method>
+
+               <signal name="Completed">
+                       <arg name="dismissed" type="b"/>
+                       <arg name="result" type="v"/>
+               </signal>
+       </interface>
+s
+</node>
diff --git a/daemon/dbus/org.gnome.keyring.Daemon.xml b/daemon/dbus/org.gnome.keyring.Daemon.xml
new file mode 100644
index 0000000..b4334d9
--- /dev/null
+++ b/daemon/dbus/org.gnome.keyring.Daemon.xml
@@ -0,0 +1,13 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd";>
+
+<node name="/org/gnome/keyring/daemon">
+  <interface name="org.gnome.keyring.Daemon">
+    <method name="GetEnvironment">
+      <arg name="Environment" type="a{ss}" direction="out"/>
+    </method>
+    <method name="GetControlDirectory">
+      <arg name="ControlDirectory" type="s" direction="out"/>
+    </method>
+  </interface>
+</node>
diff --git a/daemon/dbus/org.gnome.keyring.InternalUnsupportedGuiltRiddenInterface.xml 
b/daemon/dbus/org.gnome.keyring.InternalUnsupportedGuiltRiddenInterface.xml
new file mode 100644
index 0000000..c722a00
--- /dev/null
+++ b/daemon/dbus/org.gnome.keyring.InternalUnsupportedGuiltRiddenInterface.xml
@@ -0,0 +1,25 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd";>
+
+<node name="/org/gnome/keyring/InternalUnsupportedGuiltRiddenInterface">
+  <interface name="org.gnome.keyring.InternalUnsupportedGuiltRiddenInterface">
+    <method name="ChangeWithMasterPassword">
+      <arg name="collection" type="o" direction="in"/>
+      <arg name="original" type="(oayays)" direction="in"/>
+      <arg name="master" type="(oayays)" direction="in"/>
+    </method>
+    <method name="ChangeWithPrompt">
+      <arg name="collection" type="o" direction="in"/>
+      <arg name="prompt" type="o" direction="out"/>
+    </method>
+    <method name="CreateWithMasterPassword">
+      <arg name="attributes" type="a{sv}" direction="in"/>
+      <arg name="master" type="(oayays)" direction="in"/>
+      <arg name="collection" type="o" direction="out"/>
+    </method>
+    <method name="UnlockWithMasterPassword">
+      <arg name="collection" type="o" direction="in"/>
+      <arg name="master" type="(oayays)" direction="in"/>
+    </method>
+  </interface>
+</node>


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