[gnome-keyring: 1/2] dbus: Implement <node> children in DBus introspection data
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-keyring: 1/2] dbus: Implement <node> children in DBus introspection data
- Date: Mon, 26 Sep 2011 13:42:09 +0000 (UTC)
commit e337f08d3eaf17b65d739b791618da29ebefd25e
Author: Stef Walter <stefw collabora co uk>
Date: Mon Sep 26 14:34:45 2011 +0200
dbus: Implement <node> children in DBus introspection data
* This allows tools like d-feet to see what's going on in
the service.
https://bugzilla.gnome.org/show_bug.cgi?id=660127
daemon/dbus/gkd-dbus-util.c | 65 ++++++++-
daemon/dbus/gkd-dbus-util.h | 4 +-
daemon/dbus/gkd-secret-introspect.c | 9 +
daemon/dbus/gkd-secret-introspect.h | 1 +
daemon/dbus/gkd-secret-objects.c | 291 ++++++++++++++++++++++-------------
daemon/dbus/gkd-secret-objects.h | 16 ++
daemon/dbus/gkd-secret-prompt.c | 3 +-
daemon/dbus/gkd-secret-service.c | 72 +++++++++-
daemon/dbus/gkd-secret-session.c | 3 +-
daemon/dbus/gkd-secret-unlock.c | 3 +-
10 files changed, 356 insertions(+), 111 deletions(-)
---
diff --git a/daemon/dbus/gkd-dbus-util.c b/daemon/dbus/gkd-dbus-util.c
index 4596ea5..3907c60 100644
--- a/daemon/dbus/gkd-dbus-util.c
+++ b/daemon/dbus/gkd-dbus-util.c
@@ -53,10 +53,59 @@ gkd_dbus_interface_match (const gchar *interface, const gchar *match)
return strcmp (interface, match) == 0;
}
-DBusMessage*
-gkd_dbus_introspect_handle (DBusMessage *message, const gchar *data)
+static gchar *
+build_child_node_xml (const gchar *parent,
+ const gchar **children)
+{
+ GString *result;
+ const gchar *child;
+ guint i;
+
+ result = g_string_new ("");
+ for (i = 0; children != NULL && children[i] != NULL; i++) {
+ if (children[i][0] == '/') {
+ if (!g_str_has_prefix (children[i], parent)) {
+ g_warning ("in introspection data child '%s' is not descendant of parent '%s'",
+ children[i], parent);
+ continue;
+ }
+ child = children[i] + strlen (parent);
+ while (child[0] == '/')
+ child++;
+ } else {
+ child = children[i];
+ }
+
+ g_string_append_printf (result, "\t<node name=\"%s\"/>\n", child);
+ }
+
+ return g_string_free (result, FALSE);
+}
+
+static gboolean
+string_replace (GString *string,
+ const gchar *search,
+ const gchar *replace)
+{
+ const gchar *pos;
+
+ pos = strstr (string->str, search);
+ if (pos == NULL)
+ return FALSE;
+
+ g_string_erase (string, pos - string->str, strlen (search));
+ g_string_insert (string, pos - string->str, replace);
+ return TRUE;
+}
+
+DBusMessage *
+gkd_dbus_introspect_handle (DBusMessage *message,
+ const gchar *data,
+ const gchar **children)
{
DBusMessage *reply;
+ GString *output = NULL;
+ gchar *nodes;
g_return_val_if_fail (message, NULL);
g_return_val_if_fail (data, NULL);
@@ -64,9 +113,21 @@ gkd_dbus_introspect_handle (DBusMessage *message, const gchar *data)
if (dbus_message_is_method_call (message, DBUS_INTERFACE_INTROSPECTABLE, "Introspect") &&
dbus_message_get_args (message, NULL, DBUS_TYPE_INVALID)) {
+ if (children != NULL) {
+ output = g_string_new (data);
+ nodes = build_child_node_xml (dbus_message_get_path (message), children);
+ if (!string_replace (output, "<!-- children@-->", nodes))
+ g_warning ("introspection data contained no location for child nodes");
+ g_free (nodes);
+ data = output->str;
+ }
+
reply = dbus_message_new_method_return (message);
if (!dbus_message_append_args (reply, DBUS_TYPE_STRING, &data, DBUS_TYPE_INVALID))
g_return_val_if_reached (NULL);
+
+ if (output)
+ g_string_free (output, TRUE);
return reply;
}
diff --git a/daemon/dbus/gkd-dbus-util.h b/daemon/dbus/gkd-dbus-util.h
index 44478db..c5506bb 100644
--- a/daemon/dbus/gkd-dbus-util.h
+++ b/daemon/dbus/gkd-dbus-util.h
@@ -34,6 +34,8 @@ GType gkd_dbus_connection_get_boxed_type (void) G_GNUC_CONST;
gboolean gkd_dbus_interface_match (const gchar *interface, const gchar *match);
-DBusMessage* gkd_dbus_introspect_handle (DBusMessage *message, const gchar *data);
+DBusMessage* gkd_dbus_introspect_handle (DBusMessage *message,
+ const gchar *data,
+ const gchar **children);
#endif /* GKD_DBUS_H */
diff --git a/daemon/dbus/gkd-secret-introspect.c b/daemon/dbus/gkd-secret-introspect.c
index cb4aa31..816ea3e 100644
--- a/daemon/dbus/gkd-secret-introspect.c
+++ b/daemon/dbus/gkd-secret-introspect.c
@@ -25,6 +25,13 @@
#include "gkd-secret-introspect.h"
+const gchar *gkd_secret_introspect_root =
+ "<!DOCTYPE node PUBLIC '-//freedesktop//DTD D-BUS Object Introspection 1.0//EN'\n"
+ " 'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>\n"
+ "<node>\n"
+ " <node name='org/freedesktop/secrets'/>\n"
+ "</node>\n";
+
const gchar *gkd_secret_introspect_collection =
"<!DOCTYPE node PUBLIC '-//freedesktop//DTD D-BUS Object Introspection 1.0//EN'\n"
" 'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd'>\n"
@@ -84,6 +91,7 @@ const gchar *gkd_secret_introspect_collection =
" </signal>\n"
" </interface>\n"
"\n"
+ "<!-- children@-->"
"</node>\n";
const gchar *gkd_secret_introspect_item =
@@ -254,6 +262,7 @@ const gchar *gkd_secret_introspect_service =
"\n"
" </interface>\n"
"\n"
+ "<!-- children@-->"
"</node>\n";
const gchar *gkd_secret_introspect_session =
diff --git a/daemon/dbus/gkd-secret-introspect.h b/daemon/dbus/gkd-secret-introspect.h
index 6a3fcf7..ba7a228 100644
--- a/daemon/dbus/gkd-secret-introspect.h
+++ b/daemon/dbus/gkd-secret-introspect.h
@@ -26,6 +26,7 @@
#include <glib.h>
+extern const gchar *gkd_secret_introspect_root;
extern const gchar *gkd_secret_introspect_collection;
extern const gchar *gkd_secret_introspect_item;
extern const gchar *gkd_secret_introspect_prompt;
diff --git a/daemon/dbus/gkd-secret-objects.c b/daemon/dbus/gkd-secret-objects.c
index 325ae04..28a278a 100644
--- a/daemon/dbus/gkd-secret-objects.c
+++ b/daemon/dbus/gkd-secret-objects.c
@@ -100,87 +100,6 @@ parse_object_path (GkdSecretObjects *self, const gchar *path, gchar **collection
return TRUE;
}
-static void
-iter_append_item_path (const gchar *base, GckObject *object, DBusMessageIter *iter)
-{
- GError *error = NULL;
- gpointer identifier;
- gsize n_identifier;
- gchar *path;
- gchar *alloc = NULL;
-
- if (base == NULL) {
- identifier = gck_object_get_data (object, CKA_G_COLLECTION, NULL, &n_identifier, &error);
- if (!identifier) {
- g_warning ("couldn't get item collection identifier: %s", egg_error_message (error));
- g_clear_error (&error);
- return;
- }
-
- base = alloc = gkd_secret_util_build_path (SECRET_COLLECTION_PREFIX, identifier, n_identifier);
- g_free (identifier);
- }
-
- identifier = gck_object_get_data (object, CKA_ID, NULL, &n_identifier, &error);
- if (identifier == NULL) {
- g_warning ("couldn't get item identifier: %s", egg_error_message (error));
- g_clear_error (&error);
- } else {
- path = gkd_secret_util_build_path (base, identifier, n_identifier);
- g_free (identifier);
- dbus_message_iter_append_basic (iter, DBUS_TYPE_OBJECT_PATH, &path);
- g_free (path);
- }
-
- g_free (alloc);
-}
-
-static void
-iter_append_item_paths (const gchar *base, GList *items, DBusMessageIter *iter)
-{
- DBusMessageIter array;
- GList *l;
-
- dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, "o", &array);
-
- for (l = items; l; l = g_list_next (l))
- iter_append_item_path (base, l->data, &array);
-
- dbus_message_iter_close_container (iter, &array);
-}
-
-static void
-iter_append_collection_paths (GList *collections, DBusMessageIter *iter)
-{
- DBusMessageIter array;
- gpointer identifier;
- gsize n_identifier;
- GError *error = NULL;
- gchar *path;
- GList *l;
-
- dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, "o", &array);
-
- for (l = collections; l; l = g_list_next (l)) {
-
- identifier = gck_object_get_data (l->data, CKA_ID, NULL, &n_identifier, &error);
- if (identifier == NULL) {
- g_warning ("couldn't get collection identifier: %s", egg_error_message (error));
- g_clear_error (&error);
- continue;
- }
-
- path = gkd_secret_util_build_path (SECRET_COLLECTION_PREFIX, identifier, n_identifier);
- g_free (identifier);
-
- dbus_message_iter_append_basic (&array, DBUS_TYPE_OBJECT_PATH, &path);
- g_free (path);
- }
-
- dbus_message_iter_close_container (iter, &array);
-}
-
-
static DBusMessage*
object_property_get (GckObject *object, DBusMessage *message,
const gchar *prop_name)
@@ -455,7 +374,7 @@ item_message_handler (GkdSecretObjects *self, GckObject *object, DBusMessage *me
return item_property_getall (object, message);
else if (dbus_message_has_interface (message, DBUS_INTERFACE_INTROSPECTABLE))
- return gkd_dbus_introspect_handle (message, gkd_secret_introspect_item);
+ return gkd_dbus_introspect_handle (message, gkd_secret_introspect_item, NULL);
return NULL;
}
@@ -641,6 +560,43 @@ collection_find_matching_item (GkdSecretObjects *self, GckSession *session,
return result;
}
+static gchar *
+object_path_for_item (const gchar *base,
+ GckObject *object)
+{
+ GError *error = NULL;
+ gpointer identifier;
+ gsize n_identifier;
+ gchar *alloc = NULL;
+ gchar *path = NULL;
+
+ if (base == NULL) {
+ identifier = gck_object_get_data (object, CKA_G_COLLECTION, NULL, &n_identifier, &error);
+ if (!identifier) {
+ g_warning ("couldn't get item collection identifier: %s", egg_error_message (error));
+ g_clear_error (&error);
+ return NULL;
+ }
+
+ base = alloc = gkd_secret_util_build_path (SECRET_COLLECTION_PREFIX, identifier, n_identifier);
+ g_free (identifier);
+ }
+
+ identifier = gck_object_get_data (object, CKA_ID, NULL, &n_identifier, &error);
+ if (identifier == NULL) {
+ g_warning ("couldn't get item identifier: %s", egg_error_message (error));
+ g_clear_error (&error);
+ path = NULL;
+
+ } else {
+ path = gkd_secret_util_build_path (base, identifier, n_identifier);
+ g_free (identifier);
+ }
+
+ g_free (alloc);
+ return path;
+}
+
static DBusMessage*
collection_method_create_item (GkdSecretObjects *self, GckObject *object, DBusMessage *message)
{
@@ -720,7 +676,8 @@ collection_method_create_item (GkdSecretObjects *self, GckObject *object, DBusMe
/* Build up the item identifier */
reply = dbus_message_new_method_return (message);
dbus_message_iter_init_append (reply, &iter);
- iter_append_item_path (base, item, &iter);
+ path = object_path_for_item (base, item);
+ dbus_message_iter_append_basic (&iter, DBUS_TYPE_OBJECT_PATH, &path);
prompt = "/";
dbus_message_iter_append_basic (&iter, DBUS_TYPE_OBJECT_PATH, &prompt);
@@ -778,6 +735,36 @@ collection_method_delete (GkdSecretObjects *self, GckObject *object, DBusMessage
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 *
+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)
{
@@ -805,8 +792,9 @@ collection_message_handler (GkdSecretObjects *self, GckObject *object, DBusMessa
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 gkd_dbus_introspect_handle (message, gkd_secret_introspect_collection);
+ return collection_introspect (self, object, message);
return NULL;
}
@@ -1089,11 +1077,30 @@ gkd_secret_objects_lookup_item (GkdSecretObjects *self, const gchar *caller,
return object;
}
+static void
+objects_foreach_item (GkdSecretObjects *self,
+ GList *items,
+ const gchar *base,
+ GkdSecretObjectsForeach callback,
+ gpointer user_data)
+{
+ gchar *path;
+ GList *l;
+
+ for (l = items; l; l = g_list_next (l)) {
+ path = object_path_for_item (base, l->data);
+ (callback) (self, path, l->data, user_data);
+ g_free (path);
+ }
+}
+
void
-gkd_secret_objects_append_item_paths (GkdSecretObjects *self, const gchar *base,
- DBusMessageIter *iter, DBusMessage *message)
+gkd_secret_objects_foreach_item (GkdSecretObjects *self,
+ DBusMessage *message,
+ const gchar *base,
+ GkdSecretObjectsForeach callback,
+ gpointer user_data)
{
- DBusMessageIter variant;
GckSession *session;
GError *error = NULL;
gchar *identifier;
@@ -1101,9 +1108,8 @@ gkd_secret_objects_append_item_paths (GkdSecretObjects *self, const gchar *base,
GckAttributes *attrs;
g_return_if_fail (GKD_SECRET_IS_OBJECTS (self));
- g_return_if_fail (base);
- g_return_if_fail (iter);
- g_return_if_fail (message);
+ g_return_if_fail (base != NULL);
+ g_return_if_fail (callback != NULL);
/* The session we're using to access the object */
session = gkd_secret_service_get_pkcs11_session (self->service, dbus_message_get_sender (message));
@@ -1121,9 +1127,8 @@ gkd_secret_objects_append_item_paths (GkdSecretObjects *self, const gchar *base,
gck_attributes_unref (attrs);
if (error == NULL) {
- dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, "ao", &variant);
- iter_append_item_paths (base, items, &variant);
- dbus_message_iter_close_container (iter, &variant);
+ objects_foreach_item (self, items, base, callback, user_data);
+
} else {
g_warning ("couldn't lookup items in '%s' collection: %s", identifier, egg_error_message (error));
g_clear_error (&error);
@@ -1133,18 +1138,56 @@ gkd_secret_objects_append_item_paths (GkdSecretObjects *self, const gchar *base,
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_collection_paths (GkdSecretObjects *self, DBusMessageIter *iter,
- DBusMessage *message)
+gkd_secret_objects_append_item_paths (GkdSecretObjects *self,
+ const gchar *base,
+ DBusMessageIter *iter,
+ DBusMessage *message)
{
DBusMessageIter variant;
- GError *error = NULL;
- GckAttributes *attrs;
+ DBusMessageIter array;
+
+ g_return_if_fail (GKD_SECRET_IS_OBJECTS (self));
+ g_return_if_fail (base);
+ g_return_if_fail (iter);
+ g_return_if_fail (message);
+
+
+ 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,
+ GkdSecretObjectsForeach callback,
+ gpointer user_data)
+{
GckSession *session;
- GList *colls;
+ GckAttributes *attrs;
+ GError *error = NULL;
+ GList *collections, *l;
+ gpointer identifier;
+ gsize n_identifier;
+ gchar *path;
g_return_if_fail (GKD_SECRET_IS_OBJECTS (self));
- g_return_if_fail (iter && message);
+ g_return_if_fail (callback);
/* The session we're using to access the object */
session = gkd_secret_service_get_pkcs11_session (self->service, dbus_message_get_sender (message));
@@ -1153,7 +1196,7 @@ gkd_secret_objects_append_collection_paths (GkdSecretObjects *self, DBusMessageI
attrs = gck_attributes_new ();
gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_G_COLLECTION);
- colls = gck_session_find_objects (session, attrs, NULL, &error);
+ collections = gck_session_find_objects (session, attrs, NULL, &error);
gck_attributes_unref (attrs);
@@ -1163,10 +1206,43 @@ gkd_secret_objects_append_collection_paths (GkdSecretObjects *self, DBusMessageI
return;
}
+ for (l = collections; l; l = g_list_next (l)) {
+
+ identifier = gck_object_get_data (l->data, CKA_ID, NULL, &n_identifier, &error);
+ if (identifier == NULL) {
+ g_warning ("couldn't get collection identifier: %s", egg_error_message (error));
+ g_clear_error (&error);
+ continue;
+ }
+
+ path = gkd_secret_util_build_path (SECRET_COLLECTION_PREFIX, identifier, n_identifier);
+ g_free (identifier);
+
+ (callback) (self, path, l->data, user_data);
+ g_free (path);
+ }
+
+ gck_list_unref_free (collections);
+}
+
+void
+gkd_secret_objects_append_collection_paths (GkdSecretObjects *self,
+ DBusMessageIter *iter,
+ DBusMessage *message)
+{
+ DBusMessageIter variant;
+ DBusMessageIter array;
+
+ g_return_if_fail (GKD_SECRET_IS_OBJECTS (self));
+ g_return_if_fail (iter && message);
+
dbus_message_iter_open_container (iter, DBUS_TYPE_VARIANT, "ao", &variant);
- iter_append_collection_paths (colls, &variant);
+ dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, "o", &array);
+
+ gkd_secret_objects_foreach_collection (self, message, on_object_path_append_to_iter, &array);
+
+ dbus_message_iter_close_container (iter, &array);
dbus_message_iter_close_container (iter, &variant);
- gck_list_unref_free (colls);
}
DBusMessage*
@@ -1176,6 +1252,7 @@ gkd_secret_objects_handle_search_items (GkdSecretObjects *self, DBusMessage *mes
GckAttributes *attrs;
GckAttribute *attr;
DBusMessageIter iter;
+ DBusMessageIter array;
GckObject *search;
GckSession *session;
DBusMessage *reply;
@@ -1251,8 +1328,14 @@ gkd_secret_objects_handle_search_items (GkdSecretObjects *self, DBusMessage *mes
/* Prepare the reply message */
reply = dbus_message_new_method_return (message);
dbus_message_iter_init_append (reply, &iter);
- iter_append_item_paths (NULL, unlocked, &iter);
- iter_append_item_paths (NULL, locked, &iter);
+
+ dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "o", &array);
+ objects_foreach_item (self, unlocked, NULL, on_object_path_append_to_iter, &iter);
+ dbus_message_iter_close_container (&iter, &array);
+
+ dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "o", &array);
+ objects_foreach_item (self, locked, NULL, on_object_path_append_to_iter, &iter);
+ dbus_message_iter_close_container (&iter, &array);
g_list_free (locked);
g_list_free (unlocked);
diff --git a/daemon/dbus/gkd-secret-objects.h b/daemon/dbus/gkd-secret-objects.h
index 2d54509..9138856 100644
--- a/daemon/dbus/gkd-secret-objects.h
+++ b/daemon/dbus/gkd-secret-objects.h
@@ -43,6 +43,11 @@ struct _GkdSecretObjectsClass {
GObjectClass parent_class;
};
+typedef void (*GkdSecretObjectsForeach) (GkdSecretObjects *self,
+ const gchar *path,
+ GckObject *object,
+ gpointer user_data);
+
GType gkd_secret_objects_get_type (void);
DBusMessage* gkd_secret_objects_dispatch (GkdSecretObjects *self,
@@ -55,6 +60,17 @@ DBusMessage* gkd_secret_objects_handle_search_items (GkdSecretObjec
DBusMessage* gkd_secret_objects_handle_get_secrets (GkdSecretObjects *self,
DBusMessage *message);
+void gkd_secret_objects_foreach_collection (GkdSecretObjects *self,
+ DBusMessage *message,
+ GkdSecretObjectsForeach callback,
+ gpointer user_data);
+
+void gkd_secret_objects_foreach_item (GkdSecretObjects *self,
+ DBusMessage *message,
+ const gchar *base,
+ GkdSecretObjectsForeach callback,
+ gpointer user_data);
+
void gkd_secret_objects_append_collection_paths (GkdSecretObjects *self,
DBusMessageIter *iter,
DBusMessage *message);
diff --git a/daemon/dbus/gkd-secret-prompt.c b/daemon/dbus/gkd-secret-prompt.c
index 9201ec5..c1edd4d 100644
--- a/daemon/dbus/gkd-secret-prompt.c
+++ b/daemon/dbus/gkd-secret-prompt.c
@@ -283,8 +283,9 @@ gkd_secret_prompt_real_dispatch_message (GkdSecretDispatch *base, DBusMessage *m
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);
+ return gkd_dbus_introspect_handle (message, gkd_secret_introspect_prompt, NULL);
return reply;
}
diff --git a/daemon/dbus/gkd-secret-service.c b/daemon/dbus/gkd-secret-service.c
index 599e2e5..0cd208a 100644
--- a/daemon/dbus/gkd-secret-service.c
+++ b/daemon/dbus/gkd-secret-service.c
@@ -805,6 +805,52 @@ service_method_unlock_with_master_password (GkdSecretService *self, DBusMessage
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_collection,
+ (const gchar **)names->pdata);
+
+ g_ptr_array_unref (names);
+ return reply;
+}
+
static DBusMessage*
service_message_handler (GkdSecretService *self, DBusMessage *message)
{
@@ -875,12 +921,31 @@ service_message_handler (GkdSecretService *self, DBusMessage *message)
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 gkd_dbus_introspect_handle (message, gkd_secret_introspect_service);
+ 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;
+}
+
static void
service_dispatch_message (GkdSecretService *self, DBusMessage *message)
{
@@ -987,6 +1052,11 @@ gkd_secret_service_filter_handler (DBusConnection *conn, DBusMessage *message, g
/* 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 ||
diff --git a/daemon/dbus/gkd-secret-session.c b/daemon/dbus/gkd-secret-session.c
index 483c79c..d59d8f2 100644
--- a/daemon/dbus/gkd-secret-session.c
+++ b/daemon/dbus/gkd-secret-session.c
@@ -314,8 +314,9 @@ gkd_secret_session_real_dispatch_message (GkdSecretDispatch *base, DBusMessage *
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);
+ return gkd_dbus_introspect_handle (message, gkd_secret_introspect_session, NULL);
return NULL;
}
diff --git a/daemon/dbus/gkd-secret-unlock.c b/daemon/dbus/gkd-secret-unlock.c
index 0c466e7..428c2d3 100644
--- a/daemon/dbus/gkd-secret-unlock.c
+++ b/daemon/dbus/gkd-secret-unlock.c
@@ -371,8 +371,9 @@ gkd_secret_unlock_real_dispatch_message (GkdSecretDispatch *base, DBusMessage *m
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);
+ return gkd_dbus_introspect_handle (message, gkd_secret_introspect_prompt, NULL);
return reply;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]