[gnome-keyring] secret-store: Support the xdg:schema attribute correctly
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-keyring] secret-store: Support the xdg:schema attribute correctly
- Date: Wed, 27 Jun 2012 09:42:07 +0000 (UTC)
commit 3b12a96aa41af835a651c6a62def94472346969d
Author: Stef Walter <stefw gnome org>
Date: Mon Jun 25 17:06:39 2012 +0200
secret-store: Support the xdg:schema attribute correctly
* libsecret uses that attribute to store the 'schema' describing
the other attributes.
* The old way of having a special 'Type' dbus argument, or
CKA_G_SCHEMA pkcs#11 attribute is deprecated ... to be more
inline with the Secret Service spec.
daemon/dbus/gkd-secret-property.c | 2 +
pkcs11/secret-store/gkm-secret-fields.c | 72 ++++++++++++--------
pkcs11/secret-store/gkm-secret-fields.h | 6 +-
pkcs11/secret-store/gkm-secret-item.c | 12 ++-
pkcs11/secret-store/gkm-secret-search.c | 4 +-
pkcs11/secret-store/tests/test-secret-fields.c | 86 +++++++++++++++++++++--
6 files changed, 138 insertions(+), 44 deletions(-)
---
diff --git a/daemon/dbus/gkd-secret-property.c b/daemon/dbus/gkd-secret-property.c
index 590836c..3086fef 100644
--- a/daemon/dbus/gkd-secret-property.c
+++ b/daemon/dbus/gkd-secret-property.c
@@ -83,6 +83,7 @@ property_to_attribute (const gchar *prop_name, const gchar *interface,
*attr_type = CKA_LABEL;
*data_type = DATA_TYPE_STRING;
+ /* Non-standard property for type schema */
} else if (g_str_equal (prop_name, "Type")) {
*attr_type = CKA_G_SCHEMA;
*data_type = DATA_TYPE_STRING;
@@ -121,6 +122,7 @@ attribute_to_property (CK_ATTRIBUTE_TYPE attr_type, const gchar **prop_name, Dat
*prop_name = "Label";
*data_type = DATA_TYPE_STRING;
break;
+ /* Non-standard property for type schema */
case CKA_G_SCHEMA:
*prop_name = "Type";
*data_type = DATA_TYPE_STRING;
diff --git a/pkcs11/secret-store/gkm-secret-fields.c b/pkcs11/secret-store/gkm-secret-fields.c
index 279f216..8145b89 100644
--- a/pkcs11/secret-store/gkm-secret-fields.c
+++ b/pkcs11/secret-store/gkm-secret-fields.c
@@ -145,7 +145,9 @@ gkm_secret_fields_new (void)
}
CK_RV
-gkm_secret_fields_parse (CK_ATTRIBUTE_PTR attr, GHashTable **fields)
+gkm_secret_fields_parse (CK_ATTRIBUTE_PTR attr,
+ GHashTable **fields,
+ gchar **schema_name)
{
GHashTable *result;
const gchar *name;
@@ -201,48 +203,62 @@ gkm_secret_fields_parse (CK_ATTRIBUTE_PTR attr, GHashTable **fields)
g_hash_table_replace (result, g_strndup (name, n_name), g_strndup (value, n_value));
}
+ if (schema_name)
+ *schema_name = g_strdup (g_hash_table_lookup (result, "xdg:schema"));
+
*fields = result;
return CKR_OK;
}
-static void
-each_field_append (gpointer key, gpointer value, gpointer user_data)
-{
- GString *result = user_data;
- g_string_append (result, key);
- g_string_append_c (result, '\0');
- g_string_append (result, value);
- g_string_append_c (result, '\0');
-}
-
-static void
-each_field_length (gpointer key, gpointer value, gpointer user_data)
-{
- gsize *length = user_data;
- *length += strlen (key);
- *length += strlen (value);
- *length += 2;
-}
-
CK_RV
-gkm_secret_fields_serialize (CK_ATTRIBUTE_PTR attr, GHashTable *fields)
+gkm_secret_fields_serialize (CK_ATTRIBUTE_PTR attr,
+ GHashTable *fields,
+ const gchar *schema_name)
{
+ GHashTableIter iter;
+ gboolean saw_schema;
+ gpointer key;
+ gpointer value;
GString *result;
- gsize length;
CK_RV rv;
- g_assert (attr);
- g_assert (fields);
+ g_assert (attr != NULL);
+ g_assert (fields != NULL);
if (!attr->pValue) {
- length = 0;
- g_hash_table_foreach (fields, each_field_length, &length);
- attr->ulValueLen = length;
+ attr->ulValueLen = 0;
+ g_hash_table_iter_init (&iter, fields);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ if (g_str_equal (key, "xdg:schema"))
+ saw_schema = TRUE;
+ attr->ulValueLen += strlen (key);
+ attr->ulValueLen += strlen (value);
+ attr->ulValueLen += 2;
+ }
+ if (schema_name && !saw_schema) {
+ attr->ulValueLen += strlen ("xdg:schema");
+ attr->ulValueLen += strlen (schema_name);
+ attr->ulValueLen += 2;
+ }
return CKR_OK;
}
result = g_string_sized_new (256);
- g_hash_table_foreach (fields, each_field_append, result);
+ g_hash_table_iter_init (&iter, fields);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ if (g_str_equal (key, "xdg:schema"))
+ saw_schema = TRUE;
+ g_string_append (result, key);
+ g_string_append_c (result, '\0');
+ g_string_append (result, value);
+ g_string_append_c (result, '\0');
+ }
+ if (schema_name && !saw_schema) {
+ g_string_append (result, "xdg:schema");
+ g_string_append_c (result, '\0');
+ g_string_append (result, schema_name);
+ g_string_append_c (result, '\0');
+ }
rv = gkm_attribute_set_data (attr, result->str, result->len);
g_string_free (result, TRUE);
diff --git a/pkcs11/secret-store/gkm-secret-fields.h b/pkcs11/secret-store/gkm-secret-fields.h
index aef7945..ed28f44 100644
--- a/pkcs11/secret-store/gkm-secret-fields.h
+++ b/pkcs11/secret-store/gkm-secret-fields.h
@@ -65,10 +65,12 @@ const gchar* gkm_secret_fields_get (GHashTable *field
const gchar *name);
CK_RV gkm_secret_fields_parse (CK_ATTRIBUTE_PTR attr,
- GHashTable **fields);
+ GHashTable **fields,
+ gchar **schema_name);
CK_RV gkm_secret_fields_serialize (CK_ATTRIBUTE_PTR attr,
- GHashTable *fields);
+ GHashTable *fields,
+ const gchar *schema_name);
gboolean gkm_secret_fields_match (GHashTable *haystack,
GHashTable *needle);
diff --git a/pkcs11/secret-store/gkm-secret-item.c b/pkcs11/secret-store/gkm-secret-item.c
index d03c4a8..35698da 100644
--- a/pkcs11/secret-store/gkm-secret-item.c
+++ b/pkcs11/secret-store/gkm-secret-item.c
@@ -235,7 +235,7 @@ gkm_secret_item_real_get_attribute (GkmObject *base, GkmSession *session, CK_ATT
case CKA_G_FIELDS:
if (!self->fields)
return gkm_attribute_set_data (attr, NULL, 0);
- return gkm_secret_fields_serialize (attr, self->fields);
+ return gkm_secret_fields_serialize (attr, self->fields, self->schema);
case CKA_G_SCHEMA:
return gkm_attribute_set_string (attr, self->schema);
@@ -252,6 +252,7 @@ gkm_secret_item_real_set_attribute (GkmObject *base, GkmSession *session,
const gchar *identifier;
GkmSecretData *sdata;
GHashTable *fields;
+ gchar *schema_name;
GkmSecret *secret;
gchar *schema;
CK_RV rv;
@@ -281,11 +282,14 @@ gkm_secret_item_real_set_attribute (GkmObject *base, GkmSession *session,
return;
case CKA_G_FIELDS:
- rv = gkm_secret_fields_parse (attr, &fields);
- if (rv != CKR_OK)
+ rv = gkm_secret_fields_parse (attr, &fields, &schema_name);
+ if (rv != CKR_OK) {
gkm_transaction_fail (transaction, rv);
- else
+ } else {
begin_set_fields (self, transaction, fields);
+ if (schema_name)
+ begin_set_schema (self, transaction, schema_name);
+ }
return;
case CKA_G_SCHEMA:
diff --git a/pkcs11/secret-store/gkm-secret-search.c b/pkcs11/secret-store/gkm-secret-search.c
index 02eb9e9..3f7a77d 100644
--- a/pkcs11/secret-store/gkm-secret-search.c
+++ b/pkcs11/secret-store/gkm-secret-search.c
@@ -194,7 +194,7 @@ factory_create_search (GkmSession *session, GkmTransaction *transaction,
}
/* Parse the fields, into our internal representation */
- rv = gkm_secret_fields_parse (attr, &fields);
+ rv = gkm_secret_fields_parse (attr, &fields, NULL);
gkm_attribute_consume (attr);
if (rv != CKR_OK) {
gkm_transaction_fail (transaction, rv);
@@ -307,7 +307,7 @@ gkm_secret_search_get_attribute (GkmObject *base, GkmSession *session, CK_ATTRIB
return gkm_attribute_set_empty (attr);
return gkm_attribute_set_string (attr, self->collection_id);
case CKA_G_FIELDS:
- return gkm_secret_fields_serialize (attr, self->fields);
+ return gkm_secret_fields_serialize (attr, self->fields, NULL);
case CKA_G_MATCHED:
return attribute_set_handles (self->objects, attr);
}
diff --git a/pkcs11/secret-store/tests/test-secret-fields.c b/pkcs11/secret-store/tests/test-secret-fields.c
index 96bb607..9e85eda 100644
--- a/pkcs11/secret-store/tests/test-secret-fields.c
+++ b/pkcs11/secret-store/tests/test-secret-fields.c
@@ -74,11 +74,12 @@ static void
test_parse (void)
{
CK_ATTRIBUTE attr = { CKA_G_FIELDS, "one\0value1\0two\0value2\0three\0value3\0", 35 };
+ gchar *schema_name;
GHashTable *fields;
const gchar *value;
CK_RV rv;
- rv = gkm_secret_fields_parse (&attr, &fields);
+ rv = gkm_secret_fields_parse (&attr, &fields, &schema_name);
g_assert (rv == CKR_OK);
g_assert_cmpuint (g_hash_table_size (fields), ==, 3);
@@ -89,6 +90,34 @@ test_parse (void)
value = g_hash_table_lookup (fields, "three");
g_assert_cmpstr (value, ==, "value3");
+ g_assert (schema_name == NULL);
+
+ g_hash_table_unref (fields);
+}
+
+static void
+test_parse_schema (void)
+{
+ CK_ATTRIBUTE attr = { CKA_G_FIELDS, "one\0value1\0two\0valu\0xdg:schema\0xxx\0", 35 };
+ gchar *schema_name;
+ GHashTable *fields;
+ const gchar *value;
+ CK_RV rv;
+
+ rv = gkm_secret_fields_parse (&attr, &fields, &schema_name);
+ g_assert (rv == CKR_OK);
+
+ g_assert_cmpuint (g_hash_table_size (fields), ==, 3);
+ value = g_hash_table_lookup (fields, "one");
+ g_assert_cmpstr (value, ==, "value1");
+ value = g_hash_table_lookup (fields, "two");
+ g_assert_cmpstr (value, ==, "valu");
+ value = g_hash_table_lookup (fields, "xdg:schema");
+ g_assert_cmpstr (value, ==, "xxx");
+
+ g_assert_cmpstr (schema_name, ==, "xxx");
+
+ g_free (schema_name);
g_hash_table_unref (fields);
}
@@ -99,7 +128,7 @@ test_parse_empty (void)
GHashTable *fields;
CK_RV rv;
- rv = gkm_secret_fields_parse (&attr, &fields);
+ rv = gkm_secret_fields_parse (&attr, &fields, NULL);
g_assert (rv == CKR_OK);
g_assert_cmpuint (g_hash_table_size (fields), == , 0);
@@ -114,7 +143,7 @@ test_parse_null_invalid (void)
GHashTable *fields;
CK_RV rv;
- rv = gkm_secret_fields_parse (&attr, &fields);
+ rv = gkm_secret_fields_parse (&attr, &fields, NULL);
g_assert (rv == CKR_ATTRIBUTE_VALUE_INVALID);
}
@@ -125,7 +154,7 @@ test_parse_missing_value (void)
GHashTable *fields;
CK_RV rv;
- rv = gkm_secret_fields_parse (&attr, &fields);
+ rv = gkm_secret_fields_parse (&attr, &fields, NULL);
g_assert (rv == CKR_ATTRIBUTE_VALUE_INVALID);
}
@@ -136,7 +165,7 @@ test_parse_missing_terminator (void)
GHashTable *fields;
CK_RV rv;
- rv = gkm_secret_fields_parse (&attr, &fields);
+ rv = gkm_secret_fields_parse (&attr, &fields, NULL);
g_assert (rv == CKR_ATTRIBUTE_VALUE_INVALID);
}
@@ -147,7 +176,7 @@ test_parse_not_utf8 (void)
GHashTable *fields;
CK_RV rv;
- rv = gkm_secret_fields_parse (&attr, &fields);
+ rv = gkm_secret_fields_parse (&attr, &fields, NULL);
g_assert (rv == CKR_ATTRIBUTE_VALUE_INVALID);
}
@@ -162,7 +191,7 @@ test_serialize (void)
fields = gkm_secret_fields_new ();
gkm_secret_fields_add (fields, "one", "value1");
- rv = gkm_secret_fields_serialize (&attr, fields);
+ rv = gkm_secret_fields_serialize (&attr, fields, NULL);
g_assert (rv == CKR_OK);
g_assert (attr.ulValueLen == 11);
g_assert (memcmp (buffer, "one\0value1\0", 11) == 0);
@@ -171,6 +200,44 @@ test_serialize (void)
}
static void
+test_serialize_schema (void)
+{
+ gchar buffer[32];
+ CK_ATTRIBUTE attr = { CKA_G_FIELDS, buffer, 32 };
+ GHashTable *fields;
+ CK_RV rv;
+
+ fields = gkm_secret_fields_new ();
+ gkm_secret_fields_add (fields, "one", "value1");
+
+ rv = gkm_secret_fields_serialize (&attr, fields, "xxx");
+ g_assert (rv == CKR_OK);
+ g_assert_cmpint (attr.ulValueLen, ==, 26);
+ g_assert (memcmp (buffer, "one\0value1\0xdg:schema\0xxx\0", 26) == 0);
+
+ g_hash_table_unref (fields);
+}
+
+static void
+test_serialize_schema_already (void)
+{
+ gchar buffer[32];
+ CK_ATTRIBUTE attr = { CKA_G_FIELDS, buffer, 32 };
+ GHashTable *fields;
+ CK_RV rv;
+
+ fields = gkm_secret_fields_new ();
+ gkm_secret_fields_add (fields, "xdg:schema", "yyy");
+
+ rv = gkm_secret_fields_serialize (&attr, fields, "xxx");
+ g_assert (rv == CKR_OK);
+ g_assert (attr.ulValueLen == 15);
+ g_assert (memcmp (buffer, "xdg:schema\0yyy\0", 15) == 0);
+
+ g_hash_table_unref (fields);
+}
+
+static void
test_serialize_length (void)
{
CK_ATTRIBUTE attr = { CKA_G_FIELDS, NULL, 0 };
@@ -180,7 +247,7 @@ test_serialize_length (void)
fields = gkm_secret_fields_new ();
gkm_secret_fields_add (fields, "one", "value1");
- rv = gkm_secret_fields_serialize (&attr, fields);
+ rv = gkm_secret_fields_serialize (&attr, fields, NULL);
g_assert (rv == CKR_OK);
g_assert (attr.ulValueLen == 11);
@@ -416,12 +483,15 @@ main (int argc, char **argv)
g_test_add_func ("/secret-store/fields/boxed", test_boxed);
g_test_add_func ("/secret-store/fields/add_get_values", test_add_get_values);
g_test_add_func ("/secret-store/fields/parse", test_parse);
+ g_test_add_func ("/secret-store/fields/parse_schema", test_parse_schema);
g_test_add_func ("/secret-store/fields/parse_empty", test_parse_empty);
g_test_add_func ("/secret-store/fields/parse_null_invalid", test_parse_null_invalid);
g_test_add_func ("/secret-store/fields/parse_missing_value", test_parse_missing_value);
g_test_add_func ("/secret-store/fields/parse_missing_terminator", test_parse_missing_terminator);
g_test_add_func ("/secret-store/fields/parse_not_utf8", test_parse_not_utf8);
g_test_add_func ("/secret-store/fields/serialize", test_serialize);
+ g_test_add_func ("/secret-store/fields/serialize_schema", test_serialize_schema);
+ g_test_add_func ("/secret-store/fields/serialize_schema_already", test_serialize_schema_already);
g_test_add_func ("/secret-store/fields/serialize_length", test_serialize_length);
g_test_add_func ("/secret-store/fields/add_get_compat_uint32", test_add_get_compat_uint32);
g_test_add_func ("/secret-store/fields/get_compat_uint32_fail", test_get_compat_uint32_fail);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]