[gnome-keyring/dbus-api] [dbus] Refactor property parsing.
- From: Stefan Walter <stefw src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-keyring/dbus-api] [dbus] Refactor property parsing.
- Date: Thu, 12 Nov 2009 06:38:13 +0000 (UTC)
commit d6af3eabb5d2e2285c78760059fb055eb450c2bd
Author: Stef Walter <stef memberwebs com>
Date: Thu Nov 12 01:36:59 2009 +0000
[dbus] Refactor property parsing.
Seperate the code that parses property variants into pkcs11
attributes.
daemon/dbus/Makefile.am | 1 +
daemon/dbus/gkd-secret-objects.c | 493 +--------------------------------
daemon/dbus/gkd-secret-objects.h | 4 -
daemon/dbus/gkd-secret-prompt.h | 4 +
daemon/dbus/gkd-secret-property.c | 559 +++++++++++++++++++++++++++++++++++++
daemon/dbus/gkd-secret-property.h | 50 ++++
6 files changed, 625 insertions(+), 486 deletions(-)
---
diff --git a/daemon/dbus/Makefile.am b/daemon/dbus/Makefile.am
index 8353bc9..ab99cad 100644
--- a/daemon/dbus/Makefile.am
+++ b/daemon/dbus/Makefile.am
@@ -19,6 +19,7 @@ libgkr_dbus_la_SOURCES = \
gkd-dbus-session.c \
gkd-dbus-util.c gkd-dbus-util.h \
gkd-secret-objects.c gkd-secret-objects.h \
+ gkd-secret-property.c gkd-secret-property.h \
gkd-secret-prompt.c gkd-secret-prompt.h \
gkd-secret-service.c gkd-secret-service.h \
gkd-secret-session.c gkd-secret-session.h \
diff --git a/daemon/dbus/gkd-secret-objects.c b/daemon/dbus/gkd-secret-objects.c
index b3a3fe1..2a52da4 100644
--- a/daemon/dbus/gkd-secret-objects.c
+++ b/daemon/dbus/gkd-secret-objects.c
@@ -25,6 +25,7 @@
#include "gkd-secret-service.h"
#include "gkd-secret-objects.h"
+#include "gkd-secret-property.h"
#include "gkd-secret-types.h"
#include "gkd-secret-util.h"
@@ -46,438 +47,10 @@ struct _GkdSecretObjects {
G_DEFINE_TYPE (GkdSecretObjects, gkd_secret_objects, G_TYPE_OBJECT);
-typedef enum _DataType {
- DATA_TYPE_INVALID = 0,
-
- /*
- * The attribute is a CK_BBOOL.
- * Property is DBUS_TYPE_BOOLEAN
- */
- DATA_TYPE_BOOL,
-
- /*
- * The attribute is in the format: "%Y%m%d%H%M%S00"
- * Property is DBUS_TYPE_INT64 since 1970 epoch.
- */
- DATA_TYPE_TIME,
-
- /*
- * The attribute is a CK_UTF8_CHAR string, not null-terminated
- * Property is a DBUS_TYPE_STRING
- */
- DATA_TYPE_STRING,
-
- /*
- * The attribute is in the format: name\0value\0name2\0value2
- * Property is dbus dictionary of strings: a{ss}
- */
- DATA_TYPE_FIELDS
-} DataType;
-
/* -----------------------------------------------------------------------------
* INTERNAL
*/
-static gboolean
-property_to_attribute (const gchar *prop_name, CK_ATTRIBUTE_TYPE *attr_type, DataType *data_type)
-{
- g_return_val_if_fail (prop_name, FALSE);
- g_assert (attr_type);
- g_assert (data_type);
-
- if (g_str_equal (prop_name, "Label")) {
- *attr_type = CKA_LABEL;
- *data_type = DATA_TYPE_STRING;
-
- } else if (g_str_equal (prop_name, "Locked")) {
- *attr_type = CKA_G_LOCKED;
- *data_type = DATA_TYPE_BOOL;
-
- } else if (g_str_equal (prop_name, "Created")) {
- *attr_type = CKA_G_CREATED;
- *data_type = DATA_TYPE_TIME;
-
- } else if (g_str_equal (prop_name, "Modified")) {
- *attr_type = CKA_G_MODIFIED;
- *data_type = DATA_TYPE_TIME;
-
- } else if (g_str_equal (prop_name, "Attributes")) {
- *attr_type = CKA_G_FIELDS;
- *data_type = DATA_TYPE_FIELDS;
-
- } else {
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-attribute_to_property (CK_ATTRIBUTE_TYPE attr_type, const gchar **prop_name, DataType *data_type)
-{
- g_assert (prop_name);
- g_assert (data_type);
-
- switch (attr_type) {
- case CKA_LABEL:
- *prop_name = "Label";
- *data_type = DATA_TYPE_STRING;
- break;
- case CKA_G_LOCKED:
- *prop_name = "Locked";
- *data_type = DATA_TYPE_BOOL;
- break;
- case CKA_G_CREATED:
- *prop_name = "Created";
- *data_type = DATA_TYPE_TIME;
- break;
- case CKA_G_MODIFIED:
- *prop_name = "Modified";
- *data_type = DATA_TYPE_TIME;
- break;
- case CKA_G_FIELDS:
- *prop_name = "Attributes";
- *data_type = DATA_TYPE_FIELDS;
- break;
- default:
- return FALSE;
- };
-
- return TRUE;
-}
-
-typedef void (*IterAppendFunc) (DBusMessageIter*, GP11Attribute*);
-typedef gboolean (*IterGetFunc) (DBusMessageIter*, GP11Attribute*);
-
-static void
-iter_append_string (DBusMessageIter *iter, GP11Attribute *attr)
-{
- gchar *value;
-
- g_assert (iter);
- g_assert (attr);
-
- if (attr->length == 0) {
- value = "";
- dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &value);
- } else {
- value = g_strndup ((const gchar*)attr->value, attr->length);
- dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &value);
- g_free (value);
- }
-}
-
-static gboolean
-iter_get_string (DBusMessageIter *iter, GP11Attribute* attr)
-{
- const char *value;
-
- g_assert (iter);
- g_assert (attr);
-
- g_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_STRING, FALSE);
- dbus_message_iter_get_basic (iter, &value);
- if (value == NULL)
- value = "";
- gp11_attribute_init_string (attr, attr->type, value);
- return TRUE;
-}
-
-static void
-iter_append_bool (DBusMessageIter *iter, GP11Attribute *attr)
-{
- dbus_bool_t value;
-
- g_assert (iter);
- g_assert (attr);
-
- value = gp11_attribute_get_boolean (attr) ? TRUE : FALSE;
- dbus_message_iter_append_basic (iter, DBUS_TYPE_BOOLEAN, &value);
-}
-
-static gboolean
-iter_get_bool (DBusMessageIter *iter, GP11Attribute* attr)
-{
- dbus_bool_t value;
-
- g_assert (iter);
- g_assert (attr);
-
- g_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_BOOLEAN, FALSE);
- dbus_message_iter_get_basic (iter, &value);
- gp11_attribute_init_boolean (attr, attr->type, value ? TRUE : FALSE);
- return TRUE;
-}
-
-static void
-iter_append_time (DBusMessageIter *iter, GP11Attribute *attr)
-{
- gint64 value;
- struct tm tm;
- gchar buf[15];
-
- g_assert (iter);
- g_assert (attr);
-
- if (attr->length == 0) {
- value = -1;
-
- } else if (!attr->value || attr->length != 16) {
- g_warning ("invalid length of time attribute");
- value = -1;
-
- } else {
- memset (&tm, 0, sizeof (tm));
- memcpy (buf, attr->value, 14);
- buf[14] = 0;
-
- if (!strptime(buf, "%Y%m%d%H%M%S", &tm)) {
- g_warning ("invalid format of time attribute");
- value = -1;
- }
-
- /* Convert to seconds since epoch */
- value = timegm (&tm);
- if (value < 0) {
- g_warning ("invalid time attribute");
- value = -1;
- }
- }
-
- dbus_message_iter_append_basic (iter, DBUS_TYPE_INT64, &value);
-}
-
-static gboolean
-iter_get_time (DBusMessageIter *iter, GP11Attribute* attr)
-{
- time_t time;
- struct tm tm;
- gchar buf[20];
- gint64 value;
-
- g_assert (iter);
- g_assert (attr);
-
- g_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_INT64, FALSE);
- dbus_message_iter_get_basic (iter, &value);
- if (value < 0) {
- gp11_attribute_init_empty (attr, attr->type);
- return TRUE;
- }
-
- time = value;
- if (!gmtime_r (&time, &tm))
- g_return_val_if_reached (FALSE);
-
- if (!strftime (buf, sizeof (buf), "%Y%m%d%H%M%S00", &tm))
- g_return_val_if_reached (FALSE);
-
- gp11_attribute_init (attr, attr->type, buf, 16);
- return TRUE;
-}
-
-static void
-iter_append_fields (DBusMessageIter *iter, GP11Attribute *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;
-
- g_assert (iter);
- g_assert (attr);
-
- ptr = (gchar*)attr->value;
- last = ptr + attr->length;
- g_return_if_fail (ptr || last == ptr);
-
- dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, "{ss}", &array);
-
- while (ptr && ptr != last) {
- g_assert (ptr < last);
-
- name = ptr;
- ptr = memchr (ptr, 0, last - ptr);
- if (ptr == NULL) /* invalid */
- break;
-
- n_name = ptr - name;
- value = ++ptr;
- ptr = memchr (ptr, 0, last - ptr);
- if (ptr == NULL) /* invalid */
- break;
-
- 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);
-
- string = g_strndup (value, n_value);
- dbus_message_iter_append_basic (&dict, DBUS_TYPE_STRING, &string);
- g_free (string);
-
- dbus_message_iter_close_container (&array, &dict);
- }
-
- dbus_message_iter_close_container (iter, &array);
-}
-
-static gboolean
-iter_get_fields (DBusMessageIter *iter, GP11Attribute* attr)
-{
- DBusMessageIter array;
- DBusMessageIter dict;
- GString *result;
- const gchar *string;
-
- g_assert (iter);
-
- 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);
-
- while (dbus_message_iter_get_arg_type (&array) == DBUS_TYPE_DICT_ENTRY) {
- dbus_message_iter_recurse (&array, &dict);
-
- /* 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_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_c (result, '\0');
-
- dbus_message_iter_next (&array);
- }
-
- gp11_attribute_init (attr, attr->type, result->str, result->len);
- g_string_free (result, TRUE);
- return TRUE;
-}
-
-static void
-iter_append_variant (DBusMessageIter *iter, DataType data_type, GP11Attribute *attr)
-{
- DBusMessageIter sub;
- IterAppendFunc func;
- const gchar *sig;
-
- 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_INT64_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);
-}
-
-static gboolean
-iter_get_variant (DBusMessageIter *iter, DataType data_type, GP11Attribute *attr)
-{
- DBusMessageIter variant;
- IterGetFunc func;
- gboolean ret;
- const gchar *sig;
- char *signature;
-
- g_assert (iter);
- g_assert (attr);
-
- 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;
- break;
- case DATA_TYPE_BOOL:
- func = iter_get_bool;
- sig = DBUS_TYPE_BOOLEAN_AS_STRING;
- break;
- case DATA_TYPE_TIME:
- func = iter_get_time;
- sig = DBUS_TYPE_INT64_AS_STRING;
- break;
- case DATA_TYPE_FIELDS:
- func = iter_get_fields;
- sig = "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);
-
- if (ret == FALSE)
- return FALSE;
-
- return (func) (&variant, attr);
-}
-
-static void
-iter_append_property_dict (DBusMessageIter *iter, GP11Attributes *attrs)
-{
- DBusMessageIter dict;
- GP11Attribute *attr;
- DataType data_type;
- const gchar *name;
- gulong num, i;
-
- num = gp11_attributes_count (attrs);
- for (i = 0; i < num; ++i) {
- attr = gp11_attributes_at (attrs, i);
- if (!attribute_to_property (attr->type, &name, &data_type))
- g_return_if_reached ();
-
- dbus_message_iter_open_container (iter, 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 (iter, &dict);
- }
-}
-
static void
iter_append_item_paths (DBusMessageIter *iter, GList *items)
{
@@ -527,13 +100,10 @@ object_property_get (GP11Object *object, DBusMessage *message,
GError *error = NULL;
DBusMessage *reply;
GP11Attribute attr;
- DataType data_type;
- /* What type of property is it? */
- if (!property_to_attribute (prop_name, &attr.type, &data_type)) {
+ 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);
- }
/* Retrieve the actual attribute */
attr.value = gp11_object_get_data (object, attr.type, &attr.length, &error);
@@ -548,7 +118,7 @@ object_property_get (GP11Object *object, DBusMessage *message,
/* Marshall the data back out */
reply = dbus_message_new_method_return (message);
dbus_message_iter_init_append (reply, &iter);
- iter_append_variant (&iter, data_type, &attr);
+ gkd_secret_property_append_variant (&iter, &attr);
g_free (attr.value);
return reply;
}
@@ -562,22 +132,20 @@ object_property_set (GP11Object *object, DBusMessage *message,
GP11Attribute *attr;
GError *error = NULL;
gulong attr_type;
- DataType data_type;
g_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_VARIANT, NULL);
/* What type of property is it? */
- if (!property_to_attribute (prop_name, &attr_type, &data_type)) {
+ 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);
- }
attrs = gp11_attributes_new ();
gp11_attributes_add_empty (attrs, attr_type);
attr = gp11_attributes_at (attrs, 0);
/* Retrieve the actual attribute value */
- if (!iter_get_variant (iter, data_type, attr)) {
+ if (!gkd_secret_property_parse_variant (iter, prop_name, attr)) {
gp11_attributes_unref (attrs);
return dbus_message_new_error_printf (message, DBUS_ERROR_FAILED,
"The property type or value was invalid: %s", prop_name);
@@ -678,7 +246,7 @@ item_property_getall (GP11Object *object, DBusMessage *message)
dbus_message_iter_init_append (reply, &iter);
dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "{sv}", &array);
- iter_append_property_dict (&array, attrs);
+ gkd_secret_property_append_all (&array, attrs);
dbus_message_iter_close_container (&iter, &array);
return reply;
}
@@ -826,7 +394,7 @@ collection_property_getall (GkdSecretObjects *self, GP11Object *object, DBusMess
dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, "{sv}", &array);
/* Append all the usual properties */
- iter_append_property_dict (&array, attrs);
+ gkd_secret_property_append_all (&array, attrs);
/* Append the Items property */
dbus_message_iter_open_container (&array, DBUS_TYPE_DICT_ENTRY, NULL, &dict);
@@ -903,7 +471,7 @@ collection_method_create_item (GkdSecretObjects *self, GP11Object *object, DBusM
dbus_bool_t replace = FALSE;
GP11Attributes *attrs;
GP11Attribute *fields;
- DBusMessageIter iter;
+ DBusMessageIter iter, array;
GP11Object *item = NULL;
const gchar *prompt;
GError *error = NULL;
@@ -918,7 +486,8 @@ collection_method_create_item (GkdSecretObjects *self, GP11Object *object, DBusM
if (!dbus_message_iter_init (message, &iter))
g_return_val_if_reached (NULL);
attrs = gp11_attributes_new ();
- if (!gkd_secret_objects_parse_item_props (self, &iter, attrs)) {
+ dbus_message_iter_recurse (&iter, &array);
+ if (!gkd_secret_property_parse_all (&array, attrs)) {
gp11_attributes_unref (attrs);
return dbus_message_new_error_printf (message, DBUS_ERROR_INVALID_ARGS,
"Invalid properties");
@@ -1195,46 +764,6 @@ gkd_secret_objects_dispatch (GkdSecretObjects *self, DBusMessage *message)
return reply;
}
-gboolean
-gkd_secret_objects_parse_item_props (GkdSecretObjects *self, DBusMessageIter *iter,
- GP11Attributes *attrs)
-{
- DBusMessageIter array, dict;
- CK_ATTRIBUTE_TYPE attr_type;
- GP11Attribute *attr;
- const char *name;
- DataType data_type;
-
- g_return_val_if_fail (GKD_SECRET_IS_OBJECTS (self), FALSE);
- g_return_val_if_fail (iter, FALSE);
- g_return_val_if_fail (attrs, FALSE);
-
- dbus_message_iter_recurse (iter, &array);
-
- while (dbus_message_iter_get_arg_type (&array) == DBUS_TYPE_DICT_ENTRY) {
- dbus_message_iter_recurse (&array, &dict);
-
- /* Property 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, &attr_type, &data_type))
- return FALSE;
-
- /* Property value */
- g_return_val_if_fail (dbus_message_iter_get_arg_type (&dict) == DBUS_TYPE_VARIANT, FALSE);
- attr = gp11_attributes_add_empty (attrs, attr_type);
- if (!iter_get_variant (&dict, data_type, attr))
- return FALSE;
-
- dbus_message_iter_next (&array);
- }
-
- return TRUE;
-}
-
-
void
gkd_secret_objects_append_item_paths (GkdSecretObjects *self, DBusMessageIter *iter,
DBusMessage *message, GP11Object *collection)
@@ -1332,7 +861,7 @@ gkd_secret_objects_handle_search_items (GkdSecretObjects *self, DBusMessage *mes
attr = gp11_attributes_add_empty (attrs, CKA_G_FIELDS);
dbus_message_iter_init (message, &iter);
- if (!iter_get_fields (&iter, attr)) {
+ if (!gkd_secret_property_parse_fields (&iter, attr)) {
gp11_attributes_unref (attrs);
return dbus_message_new_error (message, DBUS_ERROR_FAILED,
"Invalid data in attributes argument");
diff --git a/daemon/dbus/gkd-secret-objects.h b/daemon/dbus/gkd-secret-objects.h
index bb8fef7..c6dadbe 100644
--- a/daemon/dbus/gkd-secret-objects.h
+++ b/daemon/dbus/gkd-secret-objects.h
@@ -54,10 +54,6 @@ void gkd_secret_objects_append_collection_paths (GkdSecretObjec
DBusMessageIter *iter,
DBusMessage *message);
-gboolean gkd_secret_objects_parse_item_props (GkdSecretObjects *self,
- DBusMessageIter *iter,
- GP11Attributes *attrs);
-
void gkd_secret_objects_append_item_paths (GkdSecretObjects *self,
DBusMessageIter *iter,
DBusMessage *message,
diff --git a/daemon/dbus/gkd-secret-prompt.h b/daemon/dbus/gkd-secret-prompt.h
index 4ca1ac9..de8c069 100644
--- a/daemon/dbus/gkd-secret-prompt.h
+++ b/daemon/dbus/gkd-secret-prompt.h
@@ -28,6 +28,10 @@
#include "prompt/gkd-prompt.h"
+#include "gp11/gp11.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))
diff --git a/daemon/dbus/gkd-secret-property.c b/daemon/dbus/gkd-secret-property.c
new file mode 100644
index 0000000..acd9e56
--- /dev/null
+++ b/daemon/dbus/gkd-secret-property.c
@@ -0,0 +1,559 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2008 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gkd-secret-property.h"
+
+#include "pkcs11/pkcs11i.h"
+
+#include <string.h>
+
+
+typedef enum _DataType {
+ DATA_TYPE_INVALID = 0,
+
+ /*
+ * The attribute is a CK_BBOOL.
+ * Property is DBUS_TYPE_BOOLEAN
+ */
+ DATA_TYPE_BOOL,
+
+ /*
+ * The attribute is in the format: "%Y%m%d%H%M%S00"
+ * Property is DBUS_TYPE_INT64 since 1970 epoch.
+ */
+ DATA_TYPE_TIME,
+
+ /*
+ * The attribute is a CK_UTF8_CHAR string, not null-terminated
+ * Property is a DBUS_TYPE_STRING
+ */
+ DATA_TYPE_STRING,
+
+ /*
+ * The attribute is in the format: name\0value\0name2\0value2
+ * Property is dbus dictionary of strings: a{ss}
+ */
+ DATA_TYPE_FIELDS
+} DataType;
+
+/* -----------------------------------------------------------------------------
+ * INTERNAL
+ */
+
+static gboolean
+property_to_attribute (const gchar *prop_name, CK_ATTRIBUTE_TYPE *attr_type, DataType *data_type)
+{
+ g_return_val_if_fail (prop_name, FALSE);
+ g_assert (attr_type);
+ g_assert (data_type);
+
+ if (g_str_equal (prop_name, "Label")) {
+ *attr_type = CKA_LABEL;
+ *data_type = DATA_TYPE_STRING;
+
+ } else if (g_str_equal (prop_name, "Locked")) {
+ *attr_type = CKA_G_LOCKED;
+ *data_type = DATA_TYPE_BOOL;
+
+ } else if (g_str_equal (prop_name, "Created")) {
+ *attr_type = CKA_G_CREATED;
+ *data_type = DATA_TYPE_TIME;
+
+ } else if (g_str_equal (prop_name, "Modified")) {
+ *attr_type = CKA_G_MODIFIED;
+ *data_type = DATA_TYPE_TIME;
+
+ } else if (g_str_equal (prop_name, "Attributes")) {
+ *attr_type = CKA_G_FIELDS;
+ *data_type = DATA_TYPE_FIELDS;
+
+ } else {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+attribute_to_property (CK_ATTRIBUTE_TYPE attr_type, const gchar **prop_name, DataType *data_type)
+{
+ g_assert (prop_name);
+ g_assert (data_type);
+
+ switch (attr_type) {
+ case CKA_LABEL:
+ *prop_name = "Label";
+ *data_type = DATA_TYPE_STRING;
+ break;
+ case CKA_G_LOCKED:
+ *prop_name = "Locked";
+ *data_type = DATA_TYPE_BOOL;
+ break;
+ case CKA_G_CREATED:
+ *prop_name = "Created";
+ *data_type = DATA_TYPE_TIME;
+ break;
+ case CKA_G_MODIFIED:
+ *prop_name = "Modified";
+ *data_type = DATA_TYPE_TIME;
+ break;
+ case CKA_G_FIELDS:
+ *prop_name = "Attributes";
+ *data_type = DATA_TYPE_FIELDS;
+ break;
+ default:
+ return FALSE;
+ };
+
+ return TRUE;
+}
+
+typedef void (*IterAppendFunc) (DBusMessageIter*, GP11Attribute*);
+typedef gboolean (*IterGetFunc) (DBusMessageIter*, GP11Attribute*);
+
+static void
+iter_append_string (DBusMessageIter *iter, GP11Attribute *attr)
+{
+ gchar *value;
+
+ g_assert (iter);
+ g_assert (attr);
+
+ if (attr->length == 0) {
+ value = "";
+ dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &value);
+ } else {
+ value = g_strndup ((const gchar*)attr->value, attr->length);
+ dbus_message_iter_append_basic (iter, DBUS_TYPE_STRING, &value);
+ g_free (value);
+ }
+}
+
+static gboolean
+iter_get_string (DBusMessageIter *iter, GP11Attribute* attr)
+{
+ const char *value;
+
+ g_assert (iter);
+ g_assert (attr);
+
+ g_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_STRING, FALSE);
+ dbus_message_iter_get_basic (iter, &value);
+ if (value == NULL)
+ value = "";
+ gp11_attribute_init_string (attr, attr->type, value);
+ return TRUE;
+}
+
+static void
+iter_append_bool (DBusMessageIter *iter, GP11Attribute *attr)
+{
+ dbus_bool_t value;
+
+ g_assert (iter);
+ g_assert (attr);
+
+ value = gp11_attribute_get_boolean (attr) ? TRUE : FALSE;
+ dbus_message_iter_append_basic (iter, DBUS_TYPE_BOOLEAN, &value);
+}
+
+static gboolean
+iter_get_bool (DBusMessageIter *iter, GP11Attribute* attr)
+{
+ dbus_bool_t value;
+
+ g_assert (iter);
+ g_assert (attr);
+
+ g_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_BOOLEAN, FALSE);
+ dbus_message_iter_get_basic (iter, &value);
+ gp11_attribute_init_boolean (attr, attr->type, value ? TRUE : FALSE);
+ return TRUE;
+}
+
+static void
+iter_append_time (DBusMessageIter *iter, GP11Attribute *attr)
+{
+ gint64 value;
+ struct tm tm;
+ gchar buf[15];
+
+ g_assert (iter);
+ g_assert (attr);
+
+ if (attr->length == 0) {
+ value = -1;
+
+ } else if (!attr->value || attr->length != 16) {
+ g_warning ("invalid length of time attribute");
+ value = -1;
+
+ } else {
+ memset (&tm, 0, sizeof (tm));
+ memcpy (buf, attr->value, 14);
+ buf[14] = 0;
+
+ if (!strptime(buf, "%Y%m%d%H%M%S", &tm)) {
+ g_warning ("invalid format of time attribute");
+ value = -1;
+ }
+
+ /* Convert to seconds since epoch */
+ value = timegm (&tm);
+ if (value < 0) {
+ g_warning ("invalid time attribute");
+ value = -1;
+ }
+ }
+
+ dbus_message_iter_append_basic (iter, DBUS_TYPE_INT64, &value);
+}
+
+static gboolean
+iter_get_time (DBusMessageIter *iter, GP11Attribute* attr)
+{
+ time_t time;
+ struct tm tm;
+ gchar buf[20];
+ gint64 value;
+
+ g_assert (iter);
+ g_assert (attr);
+
+ g_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_INT64, FALSE);
+ dbus_message_iter_get_basic (iter, &value);
+ if (value < 0) {
+ gp11_attribute_init_empty (attr, attr->type);
+ return TRUE;
+ }
+
+ time = value;
+ if (!gmtime_r (&time, &tm))
+ g_return_val_if_reached (FALSE);
+
+ if (!strftime (buf, sizeof (buf), "%Y%m%d%H%M%S00", &tm))
+ g_return_val_if_reached (FALSE);
+
+ gp11_attribute_init (attr, attr->type, buf, 16);
+ return TRUE;
+}
+
+static void
+iter_append_fields (DBusMessageIter *iter, GP11Attribute *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;
+
+ g_assert (iter);
+ g_assert (attr);
+
+ ptr = (gchar*)attr->value;
+ last = ptr + attr->length;
+ g_return_if_fail (ptr || last == ptr);
+
+ dbus_message_iter_open_container (iter, DBUS_TYPE_ARRAY, "{ss}", &array);
+
+ while (ptr && ptr != last) {
+ g_assert (ptr < last);
+
+ name = ptr;
+ ptr = memchr (ptr, 0, last - ptr);
+ if (ptr == NULL) /* invalid */
+ break;
+
+ n_name = ptr - name;
+ value = ++ptr;
+ ptr = memchr (ptr, 0, last - ptr);
+ if (ptr == NULL) /* invalid */
+ break;
+
+ 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);
+
+ string = g_strndup (value, n_value);
+ dbus_message_iter_append_basic (&dict, DBUS_TYPE_STRING, &string);
+ g_free (string);
+
+ dbus_message_iter_close_container (&array, &dict);
+ }
+
+ dbus_message_iter_close_container (iter, &array);
+}
+
+static gboolean
+iter_get_fields (DBusMessageIter *iter, GP11Attribute* attr)
+{
+ DBusMessageIter array;
+ DBusMessageIter dict;
+ GString *result;
+ const gchar *string;
+
+ g_assert (iter);
+
+ 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);
+
+ while (dbus_message_iter_get_arg_type (&array) == DBUS_TYPE_DICT_ENTRY) {
+ dbus_message_iter_recurse (&array, &dict);
+
+ /* 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_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_c (result, '\0');
+
+ dbus_message_iter_next (&array);
+ }
+
+ gp11_attribute_init (attr, attr->type, result->str, result->len);
+ g_string_free (result, TRUE);
+ return TRUE;
+}
+
+static void
+iter_append_variant (DBusMessageIter *iter, DataType data_type, GP11Attribute *attr)
+{
+ DBusMessageIter sub;
+ IterAppendFunc func;
+ const gchar *sig;
+
+ 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_INT64_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);
+}
+
+static gboolean
+iter_get_variant (DBusMessageIter *iter, DataType data_type, GP11Attribute *attr)
+{
+ DBusMessageIter variant;
+ IterGetFunc func;
+ gboolean ret;
+ const gchar *sig;
+ char *signature;
+
+ g_assert (iter);
+ g_assert (attr);
+
+ 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;
+ break;
+ case DATA_TYPE_BOOL:
+ func = iter_get_bool;
+ sig = DBUS_TYPE_BOOLEAN_AS_STRING;
+ break;
+ case DATA_TYPE_TIME:
+ func = iter_get_time;
+ sig = DBUS_TYPE_INT64_AS_STRING;
+ break;
+ case DATA_TYPE_FIELDS:
+ func = iter_get_fields;
+ sig = "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);
+
+ if (ret == FALSE)
+ return FALSE;
+
+ return (func) (&variant, attr);
+}
+
+/* -----------------------------------------------------------------------------
+ * PUBLIC
+ */
+
+gboolean
+gkd_secret_property_get_type (const gchar *property, CK_ATTRIBUTE_TYPE *type)
+{
+ DataType data_type;
+
+ g_return_val_if_fail (property, FALSE);
+ g_return_val_if_fail (type, FALSE);
+
+ return property_to_attribute (property, type, &data_type);
+}
+
+gboolean
+gkd_secret_property_parse_all (DBusMessageIter *array, GP11Attributes *attrs)
+{
+ DBusMessageIter dict;
+ CK_ATTRIBUTE_TYPE attr_type;
+ GP11Attribute *attr;
+ const char *name;
+ DataType data_type;
+
+ g_return_val_if_fail (array, FALSE);
+ g_return_val_if_fail (attrs, FALSE);
+
+ while (dbus_message_iter_get_arg_type (array) == DBUS_TYPE_DICT_ENTRY) {
+ dbus_message_iter_recurse (array, &dict);
+
+ /* Property 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, &attr_type, &data_type))
+ return FALSE;
+
+ /* Property value */
+ g_return_val_if_fail (dbus_message_iter_get_arg_type (&dict) == DBUS_TYPE_VARIANT, FALSE);
+ attr = gp11_attributes_add_empty (attrs, attr_type);
+ if (!iter_get_variant (&dict, data_type, attr))
+ return FALSE;
+
+ dbus_message_iter_next (array);
+ }
+
+ return TRUE;
+}
+
+gboolean
+gkd_secret_property_append_all (DBusMessageIter *array, GP11Attributes *attrs)
+{
+ DBusMessageIter dict;
+ GP11Attribute *attr;
+ DataType data_type;
+ const gchar *name;
+ gulong num, i;
+
+ g_return_val_if_fail (array, FALSE);
+ g_return_val_if_fail (attrs, FALSE);
+
+ num = gp11_attributes_count (attrs);
+ for (i = 0; i < num; ++i) {
+ attr = gp11_attributes_at (attrs, i);
+ if (!attribute_to_property (attr->type, &name, &data_type))
+ g_return_val_if_reached (FALSE);
+
+ 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);
+ }
+
+ return TRUE;
+}
+
+gboolean
+gkd_secret_property_append_variant (DBusMessageIter *iter, GP11Attribute *attr)
+{
+ const gchar *property;
+ DataType data_type;
+
+ g_return_val_if_fail (attr, FALSE);
+ g_return_val_if_fail (iter, FALSE);
+
+ if (!attribute_to_property (attr->type, &property, &data_type))
+ return FALSE;
+ iter_append_variant (iter, data_type, attr);
+ return TRUE;
+}
+
+gboolean
+gkd_secret_property_parse_variant (DBusMessageIter *iter, const gchar *property,
+ GP11Attribute *attr)
+{
+ CK_ATTRIBUTE_TYPE attr_type;
+ DataType data_type;
+
+ g_return_val_if_fail (attr, FALSE);
+ g_return_val_if_fail (iter, FALSE);
+ g_return_val_if_fail (property, FALSE);
+
+ if (!property_to_attribute (property, &attr_type, &data_type))
+ return FALSE;
+
+ attr->type = attr_type;
+ return iter_get_variant (iter, data_type, attr);
+}
+
+gboolean
+gkd_secret_property_parse_fields (DBusMessageIter *iter, GP11Attribute *attr)
+{
+ g_return_val_if_fail (attr, FALSE);
+ g_return_val_if_fail (iter, FALSE);
+
+ attr->type = CKA_G_FIELDS;
+ return iter_get_fields (iter, attr);
+}
diff --git a/daemon/dbus/gkd-secret-property.h b/daemon/dbus/gkd-secret-property.h
new file mode 100644
index 0000000..c523a03
--- /dev/null
+++ b/daemon/dbus/gkd-secret-property.h
@@ -0,0 +1,50 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2009 Stefan Walter
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef __GKD_SECRET_PROPERTY_H__
+#define __GKD_SECRET_PROPERTY_H__
+
+#include "gkd-secret-types.h"
+
+#include "gp11/gp11.h"
+
+#include <dbus/dbus.h>
+
+gboolean gkd_secret_property_get_type (const gchar *property,
+ CK_ATTRIBUTE_TYPE *type);
+
+gboolean gkd_secret_property_append_variant (DBusMessageIter *iter,
+ GP11Attribute *attr);
+
+gboolean gkd_secret_property_append_all (DBusMessageIter *array,
+ GP11Attributes *attrs);
+
+gboolean gkd_secret_property_parse_variant (DBusMessageIter *iter,
+ const gchar *property,
+ GP11Attribute *attr);
+
+gboolean gkd_secret_property_parse_fields (DBusMessageIter *iter,
+ GP11Attribute *attr);
+
+gboolean gkd_secret_property_parse_all (DBusMessageIter *array,
+ GP11Attributes *attrs);
+
+#endif /* __GKD_SECRET_PROPERTY_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]