summaryrefslogtreecommitdiff
path: root/pkcs11/secret-store
diff options
context:
space:
mode:
authorStef Walter <stefw@gnome.org>2012-07-16 12:38:19 +0200
committerStef Walter <stefw@gnome.org>2012-07-16 12:38:19 +0200
commit8f894d33b164dc216f53c24c5deeb8d8913f7ea0 (patch)
treebfbaab2be687a580af2f7305ef90213e25b697c0 /pkcs11/secret-store
parent9d5c86537af8940d26a573da82cafb69640438b2 (diff)
downloadgnome-keyring-8f894d33b164dc216f53c24c5deeb8d8913f7ea0.tar.gz
Match common old GnomeKeyringItemType schemas to xdg:schema attribute
* Properly handle the case where no xdg:schema attribute is stored in the keyring, and the caller tries to search with schema names: - org.gnome.keyring.NetworkPassword - org.gnome.keyring.Note * This allows the above items stored by libgnome-keyring to be matched by libsecret.
Diffstat (limited to 'pkcs11/secret-store')
-rw-r--r--pkcs11/secret-store/gkm-secret-fields.c109
-rw-r--r--pkcs11/secret-store/gkm-secret-fields.h6
-rw-r--r--pkcs11/secret-store/gkm-secret-search.c59
-rw-r--r--pkcs11/secret-store/gkm-secret-search.h2
-rw-r--r--pkcs11/secret-store/tests/Makefile.am4
-rw-r--r--pkcs11/secret-store/tests/files/schema1.keyringbin0 -> 769 bytes
-rw-r--r--pkcs11/secret-store/tests/files/schema2.keyringbin0 -> 1005 bytes
-rw-r--r--pkcs11/secret-store/tests/test-secret-fields.c4
-rw-r--r--pkcs11/secret-store/tests/test-secret-schema.c240
9 files changed, 368 insertions, 56 deletions
diff --git a/pkcs11/secret-store/gkm-secret-fields.c b/pkcs11/secret-store/gkm-secret-fields.c
index 8145b895..34c01835 100644
--- a/pkcs11/secret-store/gkm-secret-fields.c
+++ b/pkcs11/secret-store/gkm-secret-fields.c
@@ -204,7 +204,7 @@ gkm_secret_fields_parse (CK_ATTRIBUTE_PTR attr,
}
if (schema_name)
- *schema_name = g_strdup (g_hash_table_lookup (result, "xdg:schema"));
+ *schema_name = g_strdup (g_hash_table_lookup (result, GKM_SECRET_FIELD_SCHEMA));
*fields = result;
return CKR_OK;
@@ -229,14 +229,14 @@ gkm_secret_fields_serialize (CK_ATTRIBUTE_PTR attr,
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"))
+ if (g_str_equal (key, GKM_SECRET_FIELD_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 (GKM_SECRET_FIELD_SCHEMA);
attr->ulValueLen += strlen (schema_name);
attr->ulValueLen += 2;
}
@@ -246,7 +246,7 @@ gkm_secret_fields_serialize (CK_ATTRIBUTE_PTR attr,
result = g_string_sized_new (256);
g_hash_table_iter_init (&iter, fields);
while (g_hash_table_iter_next (&iter, &key, &value)) {
- if (g_str_equal (key, "xdg:schema"))
+ if (g_str_equal (key, GKM_SECRET_FIELD_SCHEMA))
saw_schema = TRUE;
g_string_append (result, key);
g_string_append_c (result, '\0');
@@ -254,7 +254,7 @@ gkm_secret_fields_serialize (CK_ATTRIBUTE_PTR attr,
g_string_append_c (result, '\0');
}
if (schema_name && !saw_schema) {
- g_string_append (result, "xdg:schema");
+ g_string_append (result, GKM_SECRET_FIELD_SCHEMA);
g_string_append_c (result, '\0');
g_string_append (result, schema_name);
g_string_append_c (result, '\0');
@@ -267,62 +267,73 @@ gkm_secret_fields_serialize (CK_ATTRIBUTE_PTR attr,
}
gboolean
-gkm_secret_fields_match (GHashTable *haystack, GHashTable *needle)
+gkm_secret_fields_match_one (GHashTable *haystack,
+ const gchar *needle_key,
+ const gchar *needle_value)
{
- GHashTableIter iter;
- const gchar *key, *value, *hay;
+ const gchar *hay;
gchar *other_key, *hashed;
- gboolean match;
guint32 number;
+ gboolean match;
- g_return_val_if_fail (haystack, FALSE);
- g_return_val_if_fail (needle, FALSE);
+ g_return_val_if_fail (haystack != NULL, FALSE);
+ g_return_val_if_fail (needle_key != NULL, FALSE);
+ g_return_val_if_fail (needle_value != NULL, FALSE);
- g_hash_table_iter_init (&iter, needle);
- while (g_hash_table_iter_next (&iter, (gpointer*)&key, (gpointer*)&value)) {
- g_assert (key && value);
+ /* Compat attributes in the needle make no difference */
+ if (is_compat_name (needle_key))
+ return TRUE;
- /* Compat attributes in the needle make no difference */
- if (is_compat_name (key))
- continue;
+ /* A direct match? */
+ if (g_hash_table_lookup_extended (haystack, needle_key, NULL, (gpointer*)&hay))
+ return string_ptr_equal (hay, needle_value);
- /* A direct match? */
- if (g_hash_table_lookup_extended (haystack, key, NULL, (gpointer*)&hay)) {
- match = string_ptr_equal (hay, value);
- if (!match)
- return FALSE;
- continue;
- }
+ /* Try to find a hashed value? */
+ other_key = make_compat_hashed_name (needle_key);
+ match = g_hash_table_lookup_extended (haystack, other_key, NULL, (gpointer*)&hay);
+ g_free (other_key);
- /* Try to find a hashed value? */
- other_key = make_compat_hashed_name (key);
- match = g_hash_table_lookup_extended (haystack, other_key, NULL, (gpointer*)&hay);
- g_free (other_key);
+ if (!match)
+ return FALSE;
- if (!match)
- return FALSE;
+ /*
+ * Now since the old keyring code would hash in two different
+ * ways depending on whether it was a uint32 or string,
+ * we need to do the same here.
+ */
+
+ other_key = make_compat_uint32_name (needle_key);
+ if (g_hash_table_lookup (haystack, other_key)) {
+ hashed = NULL;
+ if (compat_hash_value_as_uint32 (needle_value, &number))
+ hashed = format_uint32 (number);
+ } else {
+ hashed = compat_hash_value_as_string (needle_value);
+ }
+ g_free (other_key);
- /*
- * Now since the old keyring code would hash in two different
- * ways depending on whether it was a uint32 or string,
- * we need to do the same here.
- */
-
- other_key = make_compat_uint32_name (key);
- if (g_hash_table_lookup (haystack, other_key)) {
- hashed = NULL;
- if (compat_hash_value_as_uint32 (value, &number))
- hashed = format_uint32 (number);
- } else {
- hashed = compat_hash_value_as_string (value);
- }
- g_free (other_key);
+ /* Does the incoming hashed value match our hashed value? */
+ match = string_ptr_equal (hay, hashed);
+ g_free (hashed);
+
+ return match;
+}
+
+gboolean
+gkm_secret_fields_match (GHashTable *haystack,
+ GHashTable *needle)
+{
+ GHashTableIter iter;
+ const gchar *key, *value;
+
+ g_return_val_if_fail (haystack, FALSE);
+ g_return_val_if_fail (needle, FALSE);
- /* Does the incoming hashed value match our hashed value? */
- match = string_ptr_equal (hay, hashed);
- g_free (hashed);
+ g_hash_table_iter_init (&iter, needle);
+ while (g_hash_table_iter_next (&iter, (gpointer*)&key, (gpointer*)&value)) {
+ g_assert (key && value);
- if (!match)
+ if (!gkm_secret_fields_match_one (haystack, key, value))
return FALSE;
}
diff --git a/pkcs11/secret-store/gkm-secret-fields.h b/pkcs11/secret-store/gkm-secret-fields.h
index ed28f447..31f9d5cc 100644
--- a/pkcs11/secret-store/gkm-secret-fields.h
+++ b/pkcs11/secret-store/gkm-secret-fields.h
@@ -47,6 +47,8 @@
* of xxxx.
*/
+#define GKM_SECRET_FIELD_SCHEMA "xdg:schema"
+
#define GKM_BOXED_SECRET_FIELDS (gkm_secret_fields_boxed_type ())
GType gkm_secret_fields_boxed_type (void);
@@ -75,6 +77,10 @@ CK_RV gkm_secret_fields_serialize (CK_ATTRIBUTE_PTR
gboolean gkm_secret_fields_match (GHashTable *haystack,
GHashTable *needle);
+gboolean gkm_secret_fields_match_one (GHashTable *haystack,
+ const gchar *needle_key,
+ const gchar *needle_value);
+
GList* gkm_secret_fields_get_names (GHashTable *fields);
/* COMPAT ------------------------------------------------------------------------ */
diff --git a/pkcs11/secret-store/gkm-secret-search.c b/pkcs11/secret-store/gkm-secret-search.c
index 3f7a77d7..19b70310 100644
--- a/pkcs11/secret-store/gkm-secret-search.c
+++ b/pkcs11/secret-store/gkm-secret-search.c
@@ -40,13 +40,15 @@
enum {
PROP_0,
PROP_COLLECTION_ID,
- PROP_FIELDS
+ PROP_FIELDS,
+ PROP_SCHEMA_NAME
};
struct _GkmSecretSearch {
GkmObject parent;
gchar *collection_id;
GHashTable *fields;
+ gchar *schema_name;
GList *managers;
GHashTable *objects;
};
@@ -60,6 +62,7 @@ match_object_against_criteria (GkmSecretSearch *self, GkmObject *object)
GkmSecretItem *item;
GHashTable *fields;
const gchar *identifier;
+ const gchar *schema;
if (!GKM_IS_SECRET_ITEM (object))
return FALSE;
@@ -76,8 +79,25 @@ match_object_against_criteria (GkmSecretSearch *self, GkmObject *object)
return FALSE;
}
- /* Fields should match using our special algorithm */
fields = gkm_secret_item_get_fields (item);
+
+ /* Match the schema, if we have one */
+ if (self->schema_name) {
+ schema = gkm_secret_item_get_schema (item);
+
+ /* Does the item has a schema set from the item type? */
+ if (schema != NULL) {
+ if (!g_str_equal (schema, self->schema_name))
+ return FALSE;
+
+ /* See if the item has a schema set in the attributes */
+ } else {
+ if (!gkm_secret_fields_match_one (fields, GKM_SECRET_FIELD_SCHEMA, self->schema_name))
+ return FALSE;
+ }
+ }
+
+ /* Fields should match using our special algorithm */
return gkm_secret_fields_match (fields, self->fields);
}
@@ -180,6 +200,7 @@ factory_create_search (GkmSession *session, GkmTransaction *transaction,
gchar *identifier = NULL;
CK_ATTRIBUTE *attr;
GHashTable *fields;
+ gchar *schema_name;
GkmModule *module;
CK_RV rv;
@@ -194,13 +215,16 @@ factory_create_search (GkmSession *session, GkmTransaction *transaction,
}
/* Parse the fields, into our internal representation */
- rv = gkm_secret_fields_parse (attr, &fields, NULL);
+ rv = gkm_secret_fields_parse (attr, &fields, &schema_name);
gkm_attribute_consume (attr);
if (rv != CKR_OK) {
gkm_transaction_fail (transaction, rv);
return NULL;
}
+ /* Remove the schema name from the search fields, handle that separately */
+ g_hash_table_remove (fields, GKM_SECRET_FIELD_SCHEMA);
+
s_manager = gkm_session_get_manager (session);
module = gkm_session_get_module (session);
m_manager = gkm_module_get_manager (module);
@@ -210,6 +234,7 @@ factory_create_search (GkmSession *session, GkmTransaction *transaction,
if (attr) {
rv = gkm_attribute_get_string (attr, &identifier);
if (rv != CKR_OK) {
+ g_free (schema_name);
g_hash_table_unref (fields);
gkm_transaction_fail (transaction, rv);
return NULL;
@@ -220,6 +245,7 @@ factory_create_search (GkmSession *session, GkmTransaction *transaction,
"module", module,
"manager", s_manager,
"fields", fields,
+ "schema-name", schema_name,
"collection-id", identifier,
NULL);
@@ -231,6 +257,10 @@ factory_create_search (GkmSession *session, GkmTransaction *transaction,
gkm_session_complete_object_creation (session, transaction, GKM_OBJECT (search),
TRUE, attrs, n_attrs);
+
+ g_hash_table_unref (fields);
+ g_free (schema_name);
+
return GKM_OBJECT (search);
}
@@ -307,7 +337,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, NULL);
+ return gkm_secret_fields_serialize (attr, self->fields, self->schema_name);
case CKA_G_MATCHED:
return attribute_set_handles (self->objects, attr);
}
@@ -348,6 +378,10 @@ gkm_secret_search_set_property (GObject *obj, guint prop_id, const GValue *value
self->fields = g_value_dup_boxed (value);
g_return_if_fail (self->fields);
break;
+ case PROP_SCHEMA_NAME:
+ g_return_if_fail (self->schema_name == NULL);
+ self->schema_name = g_value_dup_string (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
@@ -367,6 +401,9 @@ gkm_secret_search_get_property (GObject *obj, guint prop_id, GValue *value,
g_return_if_fail (self->fields);
g_value_set_boxed (value, gkm_secret_search_get_fields (self));
break;
+ case PROP_SCHEMA_NAME:
+ g_value_set_string (value, self->schema_name);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
break;
@@ -403,6 +440,9 @@ gkm_secret_search_finalize (GObject *obj)
g_assert (!self->managers);
+ g_free (self->schema_name);
+ self->schema_name = NULL;
+
if (self->fields)
g_hash_table_destroy (self->fields);
self->fields = NULL;
@@ -435,6 +475,10 @@ gkm_secret_search_class_init (GkmSecretSearchClass *klass)
g_object_class_install_property (gobject_class, PROP_FIELDS,
g_param_spec_boxed ("fields", "Fields", "Item's fields",
GKM_BOXED_SECRET_FIELDS, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (gobject_class, PROP_SCHEMA_NAME,
+ g_param_spec_string ("schema_name", "Schema Name", "Schema name to match",
+ NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
}
/* -----------------------------------------------------------------------------
@@ -468,6 +512,13 @@ gkm_secret_search_get_fields (GkmSecretSearch *self)
return self->fields;
}
+const gchar *
+gkm_secret_search_get_schema_name (GkmSecretSearch *self)
+{
+ g_return_val_if_fail (GKM_IS_SECRET_SEARCH (self), NULL);
+ return self->schema_name;
+}
+
const gchar*
gkm_secret_search_get_collection_id (GkmSecretSearch *self)
{
diff --git a/pkcs11/secret-store/gkm-secret-search.h b/pkcs11/secret-store/gkm-secret-search.h
index b82c969e..bbd1bbfc 100644
--- a/pkcs11/secret-store/gkm-secret-search.h
+++ b/pkcs11/secret-store/gkm-secret-search.h
@@ -51,4 +51,6 @@ GHashTable* gkm_secret_search_get_fields (GkmSecretSearch *self);
const gchar* gkm_secret_search_get_collection_id (GkmSecretSearch *self);
+const gchar * gkm_secret_search_get_schema_name (GkmSecretSearch *self);
+
#endif /* __GKM_SECRET_SEARCH_H__ */
diff --git a/pkcs11/secret-store/tests/Makefile.am b/pkcs11/secret-store/tests/Makefile.am
index 051e2101..5a77f0f5 100644
--- a/pkcs11/secret-store/tests/Makefile.am
+++ b/pkcs11/secret-store/tests/Makefile.am
@@ -29,9 +29,11 @@ TEST_PROGS = \
test-secret-object \
test-secret-collection \
test-secret-item \
+ test-secret-schema \
test-secret-search \
test-secret-textual \
- test-secret-binary
+ test-secret-binary \
+ test-secret-schema
check_PROGRAMS = $(TEST_PROGS)
diff --git a/pkcs11/secret-store/tests/files/schema1.keyring b/pkcs11/secret-store/tests/files/schema1.keyring
new file mode 100644
index 00000000..579a8614
--- /dev/null
+++ b/pkcs11/secret-store/tests/files/schema1.keyring
Binary files differ
diff --git a/pkcs11/secret-store/tests/files/schema2.keyring b/pkcs11/secret-store/tests/files/schema2.keyring
new file mode 100644
index 00000000..8c0fcbc4
--- /dev/null
+++ b/pkcs11/secret-store/tests/files/schema2.keyring
Binary files differ
diff --git a/pkcs11/secret-store/tests/test-secret-fields.c b/pkcs11/secret-store/tests/test-secret-fields.c
index 9e85eda3..50763d64 100644
--- a/pkcs11/secret-store/tests/test-secret-fields.c
+++ b/pkcs11/secret-store/tests/test-secret-fields.c
@@ -112,7 +112,7 @@ test_parse_schema (void)
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");
+ value = g_hash_table_lookup (fields, GKM_SECRET_FIELD_SCHEMA);
g_assert_cmpstr (value, ==, "xxx");
g_assert_cmpstr (schema_name, ==, "xxx");
@@ -227,7 +227,7 @@ test_serialize_schema_already (void)
CK_RV rv;
fields = gkm_secret_fields_new ();
- gkm_secret_fields_add (fields, "xdg:schema", "yyy");
+ gkm_secret_fields_add (fields, GKM_SECRET_FIELD_SCHEMA, "yyy");
rv = gkm_secret_fields_serialize (&attr, fields, "xxx");
g_assert (rv == CKR_OK);
diff --git a/pkcs11/secret-store/tests/test-secret-schema.c b/pkcs11/secret-store/tests/test-secret-schema.c
new file mode 100644
index 00000000..22ef8c5c
--- /dev/null
+++ b/pkcs11/secret-store/tests/test-secret-schema.c
@@ -0,0 +1,240 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ Copyright (C) 2012 Red Hat Ltd.
+
+ The Gnome Keyring Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Keyring Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Stef Walter <stefw@gnome.org>
+*/
+
+#include "config.h"
+
+#include "mock-secret-module.h"
+
+#include "secret-store/gkm-secret-collection.h"
+#include "secret-store/gkm-secret-item.h"
+#include "secret-store/gkm-secret-search.h"
+
+#include "gkm/gkm-credential.h"
+#include "gkm/gkm-secret.h"
+#include "gkm/gkm-serializable.h"
+#include "gkm/gkm-session.h"
+#include "gkm/gkm-transaction.h"
+#include "gkm/gkm-test.h"
+
+#include "pkcs11/pkcs11i.h"
+
+#include "egg/egg-testing.h"
+
+#include <glib.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+typedef struct {
+ GkmModule *module;
+ GkmSession *session;
+ GkmSecretCollection *collection;
+} Test;
+
+static void
+setup (Test *test,
+ gconstpointer unused)
+{
+ GkmDataResult res;
+
+ test->module = test_secret_module_initialize_and_enter ();
+ test->session = test_secret_module_open_session (TRUE);
+
+ test->collection = g_object_new (GKM_TYPE_SECRET_COLLECTION,
+ "module", test->module,
+ "manager", gkm_session_get_manager (test->session),
+ "identifier", "test-collection",
+ NULL);
+
+ /*
+ * This file contains entries that don't actually have any xdg:schema
+ * entries. It does contain the old libgnome-keyring style item types,
+ * and these should be used to match the appropriate schemas.
+ */
+
+ gkm_secret_collection_set_filename (test->collection,
+ SRCDIR "/files/schema1.keyring");
+
+ /* Load the collection */
+ res = gkm_secret_collection_load (test->collection);
+ g_assert (res == GKM_DATA_SUCCESS);
+ gkm_object_expose (GKM_OBJECT (test->collection), TRUE);
+}
+
+static void
+teardown (Test *test,
+ gconstpointer unused)
+{
+ g_object_unref (test->collection);
+ test_secret_module_leave_and_finalize ();
+}
+
+static gint
+count_number_of_matched (Test *test,
+ CK_ATTRIBUTE *attrs,
+ CK_ULONG n_attrs)
+{
+ GkmObject *object = NULL;
+ gpointer vdata;
+ gsize vsize;
+ guint count;
+
+ object = gkm_session_create_object_for_factory (test->session, GKM_FACTORY_SECRET_SEARCH, NULL, attrs, 2);
+ g_assert (object != NULL);
+ g_assert (GKM_IS_SECRET_SEARCH (object));
+
+ /* One object matched */
+ vdata = gkm_object_get_attribute_data (object, test->session, CKA_G_MATCHED, &vsize);
+ g_assert (vdata);
+ g_assert (vsize % sizeof (CK_OBJECT_HANDLE) == 0);
+ count = vsize / sizeof (CK_OBJECT_HANDLE);
+ g_free (vdata);
+
+ g_object_unref (object);
+
+ return count;
+}
+
+static void
+test_match_network_xdg_schema_without_schema_unlocked (Test *test,
+ gconstpointer unused)
+{
+ GkmCredential *cred;
+ CK_RV rv;
+
+ CK_ATTRIBUTE attrs[] = {
+ { CKA_G_FIELDS, "xdg:schema\0org.gnome.keyring.NetworkPassword\0", 45 },
+ { CKA_G_COLLECTION, "test-collection", 15 },
+ };
+
+ /* Unlock the collection */
+ rv = gkm_credential_create (test->module, gkm_session_get_manager (test->session),
+ GKM_OBJECT (test->collection), (CK_UTF8CHAR_PTR)"booo", 4, &cred);
+ gkm_assert_cmprv (rv, ==, CKR_OK);
+
+ g_assert_cmpint (count_number_of_matched (test, attrs, 2), ==, 1);
+
+ g_object_unref (cred);
+}
+
+static void
+test_match_note_xdg_schema_without_schema_unlocked (Test *test,
+ gconstpointer unused)
+{
+ GkmCredential *cred;
+ CK_RV rv;
+
+ CK_ATTRIBUTE attrs[] = {
+ { CKA_G_FIELDS, "xdg:schema\0org.gnome.keyring.Note\0", 34 },
+ { CKA_G_COLLECTION, "test-collection", 15 },
+ };
+
+ /* Unlock the collection */
+ rv = gkm_credential_create (test->module, gkm_session_get_manager (test->session),
+ GKM_OBJECT (test->collection), (CK_UTF8CHAR_PTR)"booo", 4, &cred);
+ gkm_assert_cmprv (rv, ==, CKR_OK);
+
+ g_assert_cmpint (count_number_of_matched (test, attrs, 2), ==, 1);
+
+ g_object_unref (cred);
+}
+
+static void
+test_match_network_xdg_schema_without_schema_locked (Test *test,
+ gconstpointer unused)
+{
+ CK_ATTRIBUTE attrs[] = {
+ { CKA_G_FIELDS, "xdg:schema\0org.gnome.keyring.NetworkPassword\0", 45 },
+ { CKA_G_COLLECTION, "test-collection", 15 },
+ };
+
+ g_assert_cmpint (count_number_of_matched (test, attrs, 2), ==, 1);
+}
+
+static void
+test_match_note_xdg_schema_without_schema_locked (Test *test,
+ gconstpointer unused)
+{
+ CK_ATTRIBUTE attrs[] = {
+ { CKA_G_FIELDS, "xdg:schema\0org.gnome.keyring.Note\0", 34 },
+ { CKA_G_COLLECTION, "test-collection", 15 },
+ };
+
+ g_assert_cmpint (count_number_of_matched (test, attrs, 2), ==, 1);
+}
+
+static void
+test_match_unknown_xdg_schema_without_schema_unlocked (Test *test,
+ gconstpointer unused)
+{
+ GkmCredential *cred;
+ CK_RV rv;
+
+ CK_ATTRIBUTE attrs[] = {
+ { CKA_G_FIELDS, "xdg:schema\0org.gnome.Unknown\0", 29 },
+ { CKA_G_COLLECTION, "test-collection", 15 },
+ };
+
+ /* Unlock the collection */
+ rv = gkm_credential_create (test->module, gkm_session_get_manager (test->session),
+ GKM_OBJECT (test->collection), (CK_UTF8CHAR_PTR)"booo", 4, &cred);
+ gkm_assert_cmprv (rv, ==, CKR_OK);
+
+ g_assert_cmpint (count_number_of_matched (test, attrs, 2), ==, 0);
+
+ g_object_unref (cred);
+}
+
+static void
+test_match_unknown_xdg_schema_without_schema_locked (Test *test,
+ gconstpointer unused)
+{
+ CK_ATTRIBUTE attrs[] = {
+ { CKA_G_FIELDS, "xdg:schema\0org.gnome.Unknown\0", 29 },
+ { CKA_G_COLLECTION, "test-collection", 15 },
+ };
+
+ g_assert_cmpint (count_number_of_matched (test, attrs, 2), ==, 0);
+}
+
+int
+main (int argc, char **argv)
+{
+ g_type_init ();
+ g_test_init (&argc, &argv, NULL);
+
+ g_test_add ("/secret-store/schema/network-xdg-schema-without-schema-unlocked",
+ Test, NULL, setup, test_match_network_xdg_schema_without_schema_unlocked, teardown);
+ g_test_add ("/secret-store/schema/network-xdg-schema-without-schema-locked",
+ Test, NULL, setup, test_match_network_xdg_schema_without_schema_locked, teardown);
+ g_test_add ("/secret-store/schema/note-xdg-schema-without-schema-unlocked",
+ Test, NULL, setup, test_match_note_xdg_schema_without_schema_unlocked, teardown);
+ g_test_add ("/secret-store/schema/unknown-schema-without-schema-locked",
+ Test, NULL, setup, test_match_note_xdg_schema_without_schema_locked, teardown);
+ g_test_add ("/secret-store/schema/unknown-schema-without-schema-unlocked",
+ Test, NULL, setup, test_match_unknown_xdg_schema_without_schema_unlocked, teardown);
+ g_test_add ("/secret-store/schema/unknown-schema-without-schema-locked",
+ Test, NULL, setup, test_match_unknown_xdg_schema_without_schema_locked, teardown);
+
+ return g_test_run ();
+}