[gnome-keyring/dbus-api] [secret-store] Finish up textual reading code, and test.
- From: Stefan Walter <stefw src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-keyring/dbus-api] [secret-store] Finish up textual reading code, and test.
- Date: Fri, 14 Aug 2009 22:50:22 +0000 (UTC)
commit e741f9810746a0980fcb5029e6dbfad9a564ffb8
Author: Stef Walter <stef memberwebs com>
Date: Fri Aug 14 21:18:52 2009 +0000
[secret-store] Finish up textual reading code, and test.
Add tests for gck_secret_textual_read/write, and fix the problems found.
pkcs11/secret-store/gck-secret-item.c | 2 +
pkcs11/secret-store/gck-secret-textual.c | 315 ++++++++++----------
pkcs11/secret-store/gck-secret-textual.h | 4 +-
pkcs11/secret-store/tests/Makefile.am | 1 +
.../tests/test-data/plain-bad-number.keyring | 23 ++
pkcs11/secret-store/tests/test-data/plain.keyring | 55 ++++
.../secret-store/tests/unit-test-secret-textual.c | 220 ++++++++++++++
7 files changed, 455 insertions(+), 165 deletions(-)
---
diff --git a/pkcs11/secret-store/gck-secret-item.c b/pkcs11/secret-store/gck-secret-item.c
index d7b4fa8..48f400d 100644
--- a/pkcs11/secret-store/gck-secret-item.c
+++ b/pkcs11/secret-store/gck-secret-item.c
@@ -317,6 +317,8 @@ GHashTable*
gck_secret_item_get_fields (GckSecretItem *self)
{
g_return_val_if_fail (GCK_IS_SECRET_ITEM (self), NULL);
+ if (self->fields == NULL)
+ self->fields = gck_secret_fields_new ();
return self->fields;
}
diff --git a/pkcs11/secret-store/gck-secret-textual.c b/pkcs11/secret-store/gck-secret-textual.c
index 7f83937..070ac64 100644
--- a/pkcs11/secret-store/gck-secret-textual.c
+++ b/pkcs11/secret-store/gck-secret-textual.c
@@ -25,11 +25,13 @@
#include "gck-secret-collection.h"
#include "gck-secret-compat.h"
+#include "gck-secret-data.h"
#include "gck-secret-fields.h"
#include "gck-secret-item.h"
#include "gck-secret-textual.h"
#include "egg/egg-secure-memory.h"
+#include "egg/egg-hex.h"
#include "gck/gck-secret.h"
@@ -71,138 +73,94 @@ key_file_get_uint64 (GKeyFile *file, const gchar *group,
return TRUE;
}
-typedef struct _AttributesCtx {
- GckSecretItem *item;
- gint index;
- GKeyFile *file;
- const gchar *compat_uint32;
-} AttributesCtx;
-
-static gboolean
-attribute_name_in_space_string (const gchar *string, const gchar *name)
-{
- const gchar *at;
- gsize len = strlen (name);
-
- if (len == 0)
- return FALSE;
-
- for (;;) {
- at = strstr (string, name);
- if (at == NULL)
- return FALSE;
-
- /* The word exists, is at beginning or end, or spaces around it */
- if ((at == string || isspace (*(at - 1))) &&
- (*(at + len) == 0 || isspace (*(at + len))))
- return TRUE;
-
- string = at + len;
- }
-
- g_assert_not_reached ();
-}
-
-static void
-generate_each_attribute (gpointer key, gpointer value, gpointer user_data)
-{
- AttributesCtx *ctx = user_data;
- const gchar *name = key;
- const gchar *string = value;
- gchar *groupname;
-
- groupname = g_strdup_printf ("%s:attribute%d",
- gck_secret_object_get_identifier (GCK_SECRET_OBJECT (ctx->item)),
- ctx->index);
-
- g_key_file_set_string (ctx->file, groupname, "name", name);
-
- /*
- * COMPATIBILITY:
- *
- * Our new Secrets API doesn't support integer attributes. However, to have
- * compatibility with old keyring code reading this file, we need to set
- * the type=uint32 attribute appropriately where expected.
- *
- * If there's an extra compat-uint32 attribute and the name of this attribute
- * is contained in that list, then write as a uint32.
- */
-
- /* Determine if it's a uint32 compatible value, and store as such if it is */
- if (attribute_name_in_space_string (ctx->compat_uint32, name))
- g_key_file_set_string (ctx->file, groupname, "type", "uint32");
- else
- g_key_file_set_string (ctx->file, groupname, "type", "string");
-
- g_key_file_set_string (ctx->file, groupname, "value", string);
-
- g_free (groupname);
- ++ctx->index;
-}
-
static void
generate_attributes (GKeyFile *file, GckSecretItem *item)
{
GHashTable *attributes;
- AttributesCtx ctx;
-
+ gchar *groupname;
+ GList *names, *l;
+ guint32 number;
+ gint index = 0;
+
attributes = gck_secret_item_get_fields (item);
- if (!attributes)
- return;
-
- ctx.item = item;
- ctx.index = 0;
- ctx.file = file;
- ctx.compat_uint32 = g_hash_table_lookup (attributes, "compat-uint32");
- if (!ctx.compat_uint32)
- ctx.compat_uint32 = "";
-
- g_hash_table_foreach (attributes, generate_each_attribute, &ctx);
+ g_return_if_fail (attributes);
+
+ names = gck_secret_fields_get_names (attributes);
+ for (l = names; l; l = g_list_next (l)) {
+ groupname = g_strdup_printf ("%s:attribute%d",
+ gck_secret_object_get_identifier (GCK_SECRET_OBJECT (item)),
+ index);
+
+ g_key_file_set_string (file, groupname, "name", l->data);
+
+ /*
+ * COMPATIBILITY:
+ *
+ * Our new Secrets API doesn't support integer attributes. However, to have
+ * compatibility with old keyring code reading this file, we need to set
+ * the type=uint32 attribute appropriately where expected.
+ *
+ * If there's an extra compat-uint32 attribute and the name of this attribute
+ * is contained in that list, then write as a uint32.
+ */
+
+ /* Determine if it's a uint32 compatible value, and store as such if it is */
+ if (gck_secret_fields_get_compat_uint32 (attributes, l->data, &number)) {
+ g_key_file_set_string (file, groupname, "type", "uint32");
+ key_file_set_uint64 (file, groupname, "value", number);
+
+ /* A normal string attribute */
+ } else {
+ g_key_file_set_string (file, groupname, "type", "string");
+ g_key_file_set_string (file, groupname, "value", gck_secret_fields_get (attributes, l->data));
+ }
+
+ g_free (groupname);
+ ++index;
+ }
}
static void
parse_attributes (GKeyFile *file, GckSecretItem *item, const gchar **groups)
{
GHashTable *attributes;
- GString *compat_uint32;
const gchar *identifier;
const gchar **g;
gchar *prefix;
gchar *name, *type;
+ guint64 number;
/* Now do the attributes */
identifier = gck_secret_object_get_identifier (GCK_SECRET_OBJECT (item));
prefix = g_strdup_printf ("%s:attribute", identifier);
attributes = gck_secret_fields_new ();
- compat_uint32 = NULL;
for (g = groups; *g; ++g) {
if (!g_str_has_prefix (*g, prefix))
continue;
name = g_key_file_get_string (file, *g, "name", NULL);
- if (!name || g_key_file_has_key (file, *g, "value", NULL))
+ if (!name)
continue;
type = g_key_file_get_string (file, *g, "type", NULL);
+
+ /* A uint32 type value */
if (type && g_str_equal (type, "uint32")) {
- if (!compat_uint32)
- compat_uint32 = g_string_new ("");
- g_string_append (compat_uint32, name);
- g_string_append_c (compat_uint32, ' ');
+ if (key_file_get_uint64 (file, *g, "value", &number))
+ gck_secret_fields_add_compat_uint32 (attributes, name, number);
+ g_free (name);
+
+ /* A string type value */
+ } else {
+ gck_secret_fields_take (attributes, name,
+ g_key_file_get_string (file, *g, "value", NULL));
}
g_free (type);
-
- g_hash_table_replace (attributes, name,
- g_key_file_get_string (file, *g, "value", NULL));
}
- if (compat_uint32)
- g_hash_table_replace (attributes, g_strdup ("compat-uint32"),
- g_string_free (compat_uint32, FALSE));
-
g_free (prefix);
}
@@ -301,75 +259,85 @@ parse_acl (GKeyFile *file, GckSecretItem *item, const gchar **groups)
}
static void
-generate_item (GKeyFile *file, GckSecretItem *item)
+generate_item (GKeyFile *file, GckSecretItem *item, GckSecretData *sdata)
{
GckSecretObject *obj;
GHashTable *attributes;
const gchar *value;
- const gchar *groupname;
- GckSecret *secret;
- const gchar *password;
- gsize n_password;
-
+ const gchar *identifier;
+ const guchar *secret;
+ gsize n_secret;
+ gchar *hex;
+
+ g_assert (file);
+ g_assert (GCK_IS_SECRET_ITEM (item));
+ g_assert (GCK_IS_SECRET_DATA (sdata));
+
obj = GCK_SECRET_OBJECT (item);
- groupname = gck_secret_object_get_identifier (obj);
+ identifier = gck_secret_object_get_identifier (obj);
attributes = gck_secret_item_get_fields (item);
-
+
/*
* COMPATIBILITY: We no longer have the concept of an item type.
* The gkr:item-type field serves that purpose.
*/
-
- value = g_hash_table_lookup (attributes, "gkr:item-type");
- g_key_file_set_integer (file, groupname, "item-type",
+
+ value = gck_secret_fields_get (attributes, "gkr:item-type");
+ g_key_file_set_integer (file, identifier, "item-type",
gck_secret_compat_parse_item_type (value));
value = gck_secret_object_get_label (obj);
if (value != NULL)
- g_key_file_set_string (file, groupname, "display-name", value);
-
-#if 0
- secret = gck_secret_item_get_secret (item);
-#endif
-g_assert_not_reached ();
+ g_key_file_set_string (file, identifier, "display-name", value);
+
+ secret = gck_secret_data_get_raw (sdata, identifier, &n_secret);
if (secret != NULL) {
- password = gck_secret_get_password (secret, &n_password);
- /* TODO: What about non-textual passwords? */
- if (password != NULL)
- g_key_file_set_value (file, groupname, "secret", (gchar*)password);
+ /* A textual secret. Note that secrets are always null-terminated. */
+ if (g_utf8_validate ((gchar*)secret, n_secret, NULL)) {
+ g_key_file_set_value (file, identifier, "secret", (gchar*)secret);
+
+ /* A non-textual secret */
+ } else {
+ hex = egg_hex_encode (secret, n_secret);
+ g_key_file_set_value (file, identifier, "binary-secret", hex);
+ g_free (hex);
+ }
}
- key_file_set_uint64 (file, groupname, "mtime", gck_secret_object_get_modified (obj));
- key_file_set_uint64 (file, groupname, "ctime", gck_secret_object_get_created (obj));
-
+ key_file_set_uint64 (file, identifier, "mtime", gck_secret_object_get_modified (obj));
+ key_file_set_uint64 (file, identifier, "ctime", gck_secret_object_get_created (obj));
+
generate_attributes (file, item);
generate_acl (file, item);
}
static void
-parse_item (GKeyFile *file, GckSecretItem *item, const gchar **groups)
+parse_item (GKeyFile *file, GckSecretItem *item, GckSecretData *sdata,
+ const gchar **groups)
{
GckSecretObject *obj;
GHashTable *attributes;
- const gchar *groupname;
+ const gchar *identifier;
GError *err = NULL;
GckSecret *secret;
+ guchar *binary;
+ gsize n_binary;
gchar *val;
guint64 num;
gint type;
-
+
/* First the main item data */
-
+
obj = GCK_SECRET_OBJECT (item);
- groupname = gck_secret_object_get_identifier (obj);
+ identifier = gck_secret_object_get_identifier (obj);
attributes = gck_secret_item_get_fields (item);
-
+
/*
* COMPATIBILITY: We no longer have the concept of an item type.
* The gkr:item-type field serves that purpose.
*/
- type = g_key_file_get_integer (file, groupname, "item-type", &err);
+ type = g_key_file_get_integer (file, identifier, "item-type", &err);
if (err) {
g_clear_error (&err);
type = 0;
@@ -378,31 +346,41 @@ parse_item (GKeyFile *file, GckSecretItem *item, const gchar **groups)
gck_secret_fields_add (attributes, "gkr:item-type",
gck_secret_compat_format_item_type (type));
- val = g_key_file_get_string (file, groupname, "display-name", NULL);
+ val = g_key_file_get_string (file, identifier, "display-name", NULL);
gck_secret_object_set_label (obj, val);
g_free (val);
- val = g_key_file_get_string (file, groupname, "secret", NULL);
- if (val == NULL) {
-#if 0
- gck_secret_item_set_secret (item, NULL);
-#endif
-g_assert_not_reached ();
- } else {
- secret = gck_secret_new ((guchar*)val, strlen (val));
-#if 0
- gck_secret_item_set_secret (item, secret);
-#endif
-g_assert_not_reached ();
- g_object_unref (secret);
- g_free (val);
+ if (sdata) {
+ secret = NULL;
+
+ /* A textual secret */
+ val = g_key_file_get_string (file, identifier, "secret", NULL);
+ if (val != NULL) {
+ secret = gck_secret_new_from_password (val);
+ g_free (val);
+
+ /* A binary secret */
+ } else {
+ val = g_key_file_get_string (file, identifier, "binary-secret", NULL);
+ if (val != NULL) {
+ binary = egg_hex_decode (val, -1, &n_binary);
+ secret = gck_secret_new (binary, n_binary);
+ g_free (binary);
+ g_free (val);
+ }
+ }
+
+ /* Put the secret in the right place */
+ gck_secret_data_set_secret (sdata, identifier, secret);
+ if (secret)
+ g_object_unref (secret);
}
num = 0;
- if (key_file_get_uint64 (file, groupname, "mtime", &num))
+ if (key_file_get_uint64 (file, identifier, "mtime", &num))
gck_secret_object_set_modified (obj, num);
num = 0;
- if (key_file_get_uint64 (file, groupname, "ctime", &num))
+ if (key_file_get_uint64 (file, identifier, "ctime", &num))
gck_secret_object_set_created (obj, num);
/* Now the other stuff */
@@ -411,7 +389,8 @@ g_assert_not_reached ();
}
GckDataResult
-gck_secret_textual_write (GckSecretCollection *collection, guchar **result, gsize *n_result)
+gck_secret_textual_write (GckSecretCollection *collection, GckSecretData *sdata,
+ guchar **data, gsize *n_data)
{
GckSecretObject *obj;
GList *items, *l;
@@ -420,37 +399,40 @@ gck_secret_textual_write (GckSecretCollection *collection, guchar **result, gsiz
GError *err = NULL;
gboolean idle_lock;
gint idle_timeout;
-
- obj = GCK_SECRET_OBJECT (collection);
+ g_return_val_if_fail (GCK_IS_SECRET_COLLECTION (collection), GCK_DATA_FAILURE);
+ g_return_val_if_fail (GCK_IS_SECRET_DATA (sdata), GCK_DATA_LOCKED);
+ g_return_val_if_fail (data && n_data, GCK_DATA_FAILURE);
+
+ obj = GCK_SECRET_OBJECT (collection);
file = g_key_file_new ();
-
+
value = gck_secret_object_get_label (obj);
if (value != NULL)
g_key_file_set_string (file, "keyring", "display-name", value);
-
+
key_file_set_uint64 (file, "keyring", "ctime", gck_secret_object_get_created (obj));
key_file_set_uint64 (file, "keyring", "mtime", gck_secret_object_get_modified (obj));
-
+
/* Not currently used :( */
idle_lock = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (collection), "lock-on-idle"));
g_key_file_set_boolean (file, "keyring", "lock-on-idle", idle_lock);
idle_timeout = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (collection), "lock-timeout"));
g_key_file_set_integer (file, "keyring", "lock-timeout", idle_timeout);
-
+
items = gck_secret_collection_get_items (collection);
for (l = items; l; l = g_list_next (l))
- generate_item (file, l->data);
+ generate_item (file, l->data, sdata);
g_list_free (items);
- *result = (guchar*)g_key_file_to_data (file, n_result, &err);
+ *data = (guchar*)g_key_file_to_data (file, n_data, &err);
g_key_file_free (file);
-
- if (!*result) {
+
+ if (!*data) {
g_warning ("couldn't generate textual keyring file: %s", err->message);
return GCK_DATA_FAILURE;
}
-
+
return GCK_DATA_SUCCESS;
}
@@ -470,7 +452,8 @@ remove_unavailable_item (gpointer key, gpointer dummy, gpointer user_data)
}
GckDataResult
-gck_secret_textual_read (GckSecretCollection *collection, const guchar *data, gsize n_data)
+gck_secret_textual_read (GckSecretCollection *collection, GckSecretData *sdata,
+ const guchar *data, gsize n_data)
{
GckSecretObject *obj;
GckSecretItem *item;
@@ -487,7 +470,10 @@ gck_secret_textual_read (GckSecretCollection *collection, const guchar *data, gs
gchar *value;
guint64 num;
gchar **g;
-
+
+ g_return_val_if_fail (GCK_IS_SECRET_COLLECTION (collection), GCK_DATA_FAILURE);
+ g_return_val_if_fail (!sdata || GCK_IS_SECRET_DATA (sdata), GCK_DATA_FAILURE);
+
file = g_key_file_new ();
obj = GCK_SECRET_OBJECT (collection);
@@ -528,11 +514,12 @@ gck_secret_textual_read (GckSecretCollection *collection, const guchar *data, gs
identifier = gck_secret_object_get_identifier (l->data);
g_hash_table_replace (checks, g_strdup (identifier), "unused");
}
-
+ g_list_free (items);
+
groups = g_key_file_get_groups (file, NULL);
for (g = groups; *g; ++g) {
identifier = *g;
- if (g_str_equal (identifier, "keyring"))
+ if (g_str_equal (identifier, "keyring") || strchr (identifier, ':'))
continue;
/* We've seen this id */
@@ -541,12 +528,12 @@ gck_secret_textual_read (GckSecretCollection *collection, const guchar *data, gs
item = gck_secret_collection_get_item (collection, identifier);
if (item == NULL)
item = gck_secret_collection_create_item (collection, identifier);
- parse_item (file, item, (const gchar**)groups);
+ parse_item (file, item, sdata, (const gchar**)groups);
}
-
+
g_hash_table_foreach (checks, (GHFunc)remove_unavailable_item, collection);
res = GCK_DATA_SUCCESS;
-
+
done:
if (checks)
g_hash_table_destroy (checks);
@@ -556,5 +543,5 @@ done:
g_free (start);
g_clear_error (&err);
- return res;
+ return res;
}
diff --git a/pkcs11/secret-store/gck-secret-textual.h b/pkcs11/secret-store/gck-secret-textual.h
index 6dc66cd..0a59f4a 100644
--- a/pkcs11/secret-store/gck-secret-textual.h
+++ b/pkcs11/secret-store/gck-secret-textual.h
@@ -27,10 +27,12 @@
#include "gck/gck-data-types.h"
GckDataResult gck_secret_textual_read (GckSecretCollection *collection,
+ GckSecretData *sdata,
const guchar *data,
gsize n_data);
-GckDataResult gck_secret_textual_write (GckSecretCollection *collection,
+GckDataResult gck_secret_textual_write (GckSecretCollection *collection,
+ GckSecretData *sdata,
guchar **data,
gsize *n_data);
diff --git a/pkcs11/secret-store/tests/Makefile.am b/pkcs11/secret-store/tests/Makefile.am
index 4a491bf..8f277a2 100644
--- a/pkcs11/secret-store/tests/Makefile.am
+++ b/pkcs11/secret-store/tests/Makefile.am
@@ -5,6 +5,7 @@ UNIT_AUTO = \
unit-test-secret-fields.c \
unit-test-secret-item.c \
unit-test-secret-object.c \
+ unit-test-secret-textual.c \
test-secret-module.c test-secret-module.h
UNIT_PROMPT =
diff --git a/pkcs11/secret-store/tests/test-data/plain-bad-number.keyring b/pkcs11/secret-store/tests/test-data/plain-bad-number.keyring
new file mode 100644
index 0000000..e5ff5ac
--- /dev/null
+++ b/pkcs11/secret-store/tests/test-data/plain-bad-number.keyring
@@ -0,0 +1,23 @@
+
+[keyring]
+display-name=plain-bad-number
+ctime=1198027852
+mtime=1198027852
+lock-on-idle=false
+lock-timeout=0
+
+[1]
+item-type=0
+display-name=Bad Number
+secret=secret
+mtime=1198027852
+ctime=1198027852
+
+[1:attribute0]
+name=bad-number
+type=uint32
+value=not-a-number
+
+[1:attribute1]
+name=missing-number
+type=uint32
diff --git a/pkcs11/secret-store/tests/test-data/plain.keyring b/pkcs11/secret-store/tests/test-data/plain.keyring
new file mode 100644
index 0000000..c048aa1
--- /dev/null
+++ b/pkcs11/secret-store/tests/test-data/plain.keyring
@@ -0,0 +1,55 @@
+
+[keyring]
+display-name=unit-test-keyring
+ctime=1198027852
+mtime=1198027852
+lock-on-idle=false
+lock-timeout=0
+
+[2]
+item-type=0
+display-name=Another display name
+secret=item-secret
+mtime=1198027852
+ctime=1198027852
+
+[2:acl0]
+display-name=run-auto-test
+path=/data/projects/gnome-keyring/library/tests/.libs/run-auto-test
+read-access=true
+write-access=true
+remove-access=true
+
+[3]
+item-type=0
+display-name=Barnyard
+secret=item-secret
+mtime=1198027852
+ctime=1198027852
+
+[3:attribute0]
+name=dog
+type=string
+value=woof
+
+[3:attribute1]
+name=bird
+type=string
+value=cheep
+
+[3:attribute2]
+name=iguana
+type=string
+value=
+
+[3:attribute3]
+name=num
+type=uint32
+value=3
+
+[3:acl0]
+display-name=run-auto-test
+path=/data/projects/gnome-keyring/library/tests/.libs/run-auto-test
+read-access=true
+write-access=true
+remove-access=true
diff --git a/pkcs11/secret-store/tests/unit-test-secret-textual.c b/pkcs11/secret-store/tests/unit-test-secret-textual.c
new file mode 100644
index 0000000..0736673
--- /dev/null
+++ b/pkcs11/secret-store/tests/unit-test-secret-textual.c
@@ -0,0 +1,220 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* unit-test-secret-textual.c: Test textual keyring read and write
+
+ Copyright (C) 2009 Stefan Walter
+
+ 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 <stef memberwebs com>
+*/
+
+#include "config.h"
+
+#include "run-auto-test.h"
+#include "test-secret-module.h"
+
+#include "gck-secret-collection.h"
+#include "gck-secret-data.h"
+#include "gck-secret-fields.h"
+#include "gck-secret-item.h"
+#include "gck-secret-textual.h"
+
+#include "gck/gck-secret.h"
+
+#include "pkcs11/pkcs11i.h"
+
+#include <glib.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+static GckModule *module = NULL;
+static GckSession *session = NULL;
+static GckSecretCollection *collection = NULL;
+static GckSecretData *sdata = NULL;
+
+DEFINE_SETUP(textual)
+{
+ module = test_secret_module_initialize_and_enter ();
+ session = test_secret_module_open_session (TRUE);
+
+ collection = g_object_new (GCK_TYPE_SECRET_COLLECTION,
+ "module", module,
+ "identifier", "test",
+ "label", "brigadooooooooooooon",
+ NULL);
+
+ sdata = g_object_new (GCK_TYPE_SECRET_DATA, NULL);
+
+ g_assert (GCK_IS_SECRET_COLLECTION (collection));
+
+}
+
+DEFINE_TEARDOWN(textual)
+{
+ if (collection)
+ g_object_unref (collection);
+ collection = NULL;
+
+ if (sdata)
+ g_object_unref (sdata);
+ sdata = NULL;
+
+ test_secret_module_leave_and_finalize ();
+ module = NULL;
+ session = NULL;
+}
+
+static void
+fill_in_collection (void)
+{
+ GckSecretItem *item;
+ GHashTable *fields;
+ GckSecret *secret;
+
+ item = gck_secret_collection_create_item (collection, "4");
+ gck_secret_object_set_label (GCK_SECRET_OBJECT (item), "Noises");
+ secret = gck_secret_new_from_password ("4's secret");
+ gck_secret_data_set_secret (sdata, "4", secret);
+ g_object_unref (secret);
+ fields = gck_secret_item_get_fields (item);
+ gck_secret_fields_add (fields, "doggy", "fart");
+ gck_secret_fields_add (fields, "pig", "grunt");
+ gck_secret_fields_add_compat_uint32 (fields, "how-many", 292929);
+
+ item = gck_secret_collection_create_item (collection, "5");
+ gck_secret_object_set_label (GCK_SECRET_OBJECT (item), "Colors");
+ secret = gck_secret_new_from_password ("5's secret");
+ gck_secret_data_set_secret (sdata, "5", secret);
+ g_object_unref (secret);
+ fields = gck_secret_item_get_fields (item);
+ gck_secret_fields_add (fields, "barney", "purple");
+ gck_secret_fields_add (fields, "piglet", "pink");
+ gck_secret_fields_add_compat_uint32 (fields, "number", 8);
+
+ item = gck_secret_collection_create_item (collection, "6");
+ gck_secret_object_set_label (GCK_SECRET_OBJECT (item), "Binary Secret");
+ secret = gck_secret_new ((guchar*)"binary\0secret", 13);
+ gck_secret_data_set_secret (sdata, "6", secret);
+ g_object_unref (secret);
+ fields = gck_secret_item_get_fields (item);
+ gck_secret_fields_add (fields, "train", "zoom");
+ gck_secret_fields_add (fields, "hummer", NULL);
+ gck_secret_fields_add_compat_uint32 (fields, "number", 2);
+}
+
+DEFINE_TEST(textual_read)
+{
+ GckDataResult res;
+ guchar *data;
+ gsize n_data;
+
+ data = test_read_testdata ("plain.keyring", &n_data);
+ res = gck_secret_textual_read (collection, sdata, data, n_data);
+ g_free (data);
+
+ g_assert (res == GCK_DATA_SUCCESS);
+}
+
+DEFINE_TEST(textual_read_wrong_format)
+{
+ GckDataResult res;
+ guchar *data;
+ gsize n_data;
+
+ data = test_read_testdata ("encrypted.keyring", &n_data);
+ res = gck_secret_textual_read (collection, sdata, data, n_data);
+ g_free (data);
+
+ g_assert (res == GCK_DATA_UNRECOGNIZED);
+}
+
+DEFINE_TEST(textual_read_bad_number)
+{
+ GckSecretItem *item;
+ GckDataResult res;
+ const gchar *value;
+ guchar *data;
+ gsize n_data;
+
+ data = test_read_testdata ("plain-bad-number.keyring", &n_data);
+ res = gck_secret_textual_read (collection, sdata, data, n_data);
+ g_free (data);
+
+ g_assert (res == GCK_DATA_SUCCESS);
+
+ item = gck_secret_collection_get_item (collection, "1");
+ g_assert (GCK_IS_SECRET_ITEM (item));
+ value = gck_secret_fields_get (gck_secret_item_get_fields (item), "bad-number");
+ g_assert (value == NULL);
+ value = gck_secret_fields_get (gck_secret_item_get_fields (item), "missing-number");
+ g_assert (value == NULL);
+}
+
+DEFINE_TEST(textual_write)
+{
+ GckDataResult res;
+ guchar *data;
+ gsize n_data;
+
+ fill_in_collection ();
+
+ res = gck_secret_textual_write (collection, sdata, &data, &n_data);
+ g_assert (res == GCK_DATA_SUCCESS);
+ g_assert (data);
+ g_assert (n_data);
+
+ /* Try parsing it again */
+ res = gck_secret_textual_read (collection, sdata, data, n_data);
+ g_assert (res == GCK_DATA_SUCCESS);
+}
+
+DEFINE_TEST(textual_remove_unavailable)
+{
+ GckDataResult res;
+ GList *items;
+ guchar *data;
+ gsize n_data;
+
+ data = test_read_testdata ("plain.keyring", &n_data);
+ res = gck_secret_textual_read (collection, sdata, data, n_data);
+ g_assert (res == GCK_DATA_SUCCESS);
+
+ /* Two items from the file */
+ items = gck_secret_collection_get_items (collection);
+ g_assert_cmpint (g_list_length (items), ==, 2);
+ g_list_free (items);
+
+ /* Fill in some more data */
+ fill_in_collection ();
+
+ /* Should have added three more */
+ items = gck_secret_collection_get_items (collection);
+ g_assert_cmpint (g_list_length (items), ==, 5);
+ g_list_free (items);
+
+ /* Re-read the keyring */
+ res = gck_secret_textual_read (collection, sdata, data, n_data);
+ g_assert (res == GCK_DATA_SUCCESS);
+
+ /* And we're back to two */
+ items = gck_secret_collection_get_items (collection);
+ g_assert_cmpint (g_list_length (items), ==, 2);
+ g_list_free (items);
+
+ g_free (data);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]