[gnome-keyring] gcr: Implement loading of attributes in GcrGnupgCollection
- From: Stefan Walter <stefw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-keyring] gcr: Implement loading of attributes in GcrGnupgCollection
- Date: Tue, 12 Jul 2011 12:54:16 +0000 (UTC)
commit dac5daa5fbe0013a712ecfd241800f1242920e27
Author: Stef Walter <stefw collabora co uk>
Date: Thu May 12 19:18:41 2011 +0200
gcr: Implement loading of attributes in GcrGnupgCollection
* These attributes can contain photo ids.
* Add various definitions for dealing with attributes.
* Since we like everything in the --with-colons gnupg format,
we implement our own record type 'xa1' and cram the attribute
(photo id) into there, along with all data.
https://bugzilla.gnome.org/show_bug.cgi?id=650433
docs/reference/gcr/gcr-sections.txt | 6 ++
gcr/Makefile.am | 1 +
gcr/gcr-gnupg-collection.c | 161 ++++++++++++++++++++++++++++++++---
gcr/gcr-gnupg-key.c | 11 +++
gcr/gcr-gnupg-key.h | 2 +
gcr/gcr-gnupg-util.c | 102 ++++++++++++++++++++++
gcr/gcr-gnupg-util.h | 41 +++++++++
gcr/gcr-record.h | 43 +++++++++-
gcr/tests/test-gnupg-collection.c | 45 +++++++++--
9 files changed, 393 insertions(+), 19 deletions(-)
---
diff --git a/docs/reference/gcr/gcr-sections.txt b/docs/reference/gcr/gcr-sections.txt
index e8df765..8d8b22b 100644
--- a/docs/reference/gcr/gcr-sections.txt
+++ b/docs/reference/gcr/gcr-sections.txt
@@ -456,6 +456,9 @@ GcrUnlockOptionsWidgetPrivate
GCR_RECORD_SCHEMA_PUB
GCR_RECORD_SCHEMA_UID
GCR_RECORD_SCHEMA_SEC
+GCR_RECORD_SCHEMA_ATTRIBUTE
+GCR_RECORD_SCHEMA_FPR
+GCR_RECORD_SCHEMA_XA1
GCR_GNUPG_COLLECTION
GCR_GNUPG_COLLECTION_CLASS
GCR_GNUPG_COLLECTION_GET_CLASS
@@ -474,6 +477,9 @@ GcrRecordColumns
GcrRecordPubColumns
GcrRecordUidColumns
GcrRecordSecColumns
+GcrRecordAttributeColumns
+GcrRecordFprColumns
+GcrRecordXa1Columns
GcrRecord
GCR_GNUPG_PROCESS
GCR_GNUPG_PROCESS_CLASS
diff --git a/gcr/Makefile.am b/gcr/Makefile.am
index 5a5270c..496f9d3 100644
--- a/gcr/Makefile.am
+++ b/gcr/Makefile.am
@@ -91,6 +91,7 @@ libgcr_ GCR_MAJOR@_la_SOURCES = \
gcr-gnupg-key.c gcr-gnupg-key.h \
gcr-fingerprint.c gcr-fingerprint.h \
gcr-gnupg-process.c gcr-gnupg-process.h \
+ gcr-gnupg-util.c gcr-gnupg-util.h \
gcr-icons.c gcr-icons.h \
gcr-import-dialog.c gcr-import-dialog.h \
gcr-importer.c gcr-importer.h \
diff --git a/gcr/gcr-gnupg-collection.c b/gcr/gcr-gnupg-collection.c
index 1fc2e21..82991e5 100644
--- a/gcr/gcr-gnupg-collection.c
+++ b/gcr/gcr-gnupg-collection.c
@@ -30,6 +30,7 @@
#include "gcr-gnupg-collection.h"
#include "gcr-gnupg-key.h"
#include "gcr-gnupg-process.h"
+#include "gcr-gnupg-util.h"
#include "gcr-internal.h"
#include "gcr-util.h"
@@ -165,7 +166,7 @@ static GList*
gcr_gnupg_collection_real_get_objects (GcrCollection *coll)
{
GcrGnupgCollection *self = GCR_GNUPG_COLLECTION (coll);
- return g_hash_table_get_keys (self->pv->items);
+ return g_hash_table_get_values (self->pv->items);
}
static void
@@ -229,6 +230,10 @@ typedef struct {
guint error_sig;
guint status_sig;
guint attribute_sig;
+
+ GQueue *attribute_queue; /* Queue of unprocessed GcrRecord* status records */
+ GByteArray *attribute_buf; /* Buffer of unprocessed attribute data received */
+ GHashTable *attributes; /* Processed attributes waiting for a matching key */
} GcrGnupgCollectionLoad;
/* Forward declarations */
@@ -259,6 +264,17 @@ _gcr_gnupg_collection_load_free (gpointer data)
if (load->cancel)
g_object_unref (load->cancel);
+
+ if (load->attribute_queue) {
+ while (!g_queue_is_empty (load->attribute_queue))
+ _gcr_record_free (g_queue_pop_head (load->attribute_queue));
+ g_queue_free (load->attribute_queue);
+ }
+ if (load->attribute_buf)
+ g_byte_array_unref (load->attribute_buf);
+ if (load->attributes)
+ g_hash_table_destroy (load->attributes);
+
g_slice_free (GcrGnupgCollectionLoad, load);
}
@@ -266,7 +282,29 @@ static void
process_records_as_public_key (GcrGnupgCollectionLoad *load, GPtrArray *records,
const gchar *keyid)
{
+ GPtrArray *attr_records = NULL;
+ const gchar *fingerprint;
GcrGnupgKey *key;
+ guint i;
+
+ /* Add in any attributes we have loaded */
+ fingerprint = _gcr_gnupg_key_get_fingerprint_for_records (records);
+ if (fingerprint && load->attributes)
+ attr_records = g_hash_table_lookup (load->attributes, fingerprint);
+ if (attr_records) {
+ _gcr_debug ("adding %d user id attribute(s) to key/fingerprint: %s/%s",
+ (gint)attr_records->len, keyid, fingerprint);
+
+ if (!g_hash_table_steal (load->attributes, fingerprint))
+ g_assert_not_reached ();
+
+ /* Move all the attribute records over to main records set */
+ for (i = 0; i < attr_records->len; i++)
+ g_ptr_array_add (records, attr_records->pdata[i]);
+
+ /* Shallow free of attr_records array */
+ g_free (g_ptr_array_free (attr_records, FALSE));
+ }
/* Note that we've seen this keyid */
g_hash_table_remove (load->difference, keyid);
@@ -340,6 +378,76 @@ process_records_as_key (GcrGnupgCollectionLoad *load)
g_ptr_array_unref (records);
}
+static gboolean
+process_outstanding_attribute (GcrGnupgCollectionLoad *load, GcrRecord *record)
+{
+ const gchar *fingerprint;
+ GPtrArray *records;
+ GcrRecord *xa1;
+ guint length;
+
+ if (!_gcr_record_get_uint (record, GCR_RECORD_ATTRIBUTE_LENGTH, &length))
+ g_return_val_if_reached (FALSE);
+ fingerprint = _gcr_record_get_raw (record, GCR_RECORD_ATTRIBUTE_FINGERPRINT);
+ g_return_val_if_fail (fingerprint != NULL, FALSE);
+
+ /* Do we have enough data for this attribute? */
+ if (!load->attribute_buf || load->attribute_buf->len < length) {
+ _gcr_debug ("not enough attribute data in buffer: %u", length);
+ return FALSE;
+ }
+
+ if (!load->attributes)
+ load->attributes = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, (GDestroyNotify)g_ptr_array_unref);
+
+ records = g_hash_table_lookup (load->attributes, fingerprint);
+ if (!records) {
+ records = g_ptr_array_new_with_free_func (_gcr_record_free);
+ g_hash_table_insert (load->attributes, g_strdup (fingerprint), records);
+ }
+
+ _gcr_debug ("new attribute of length %d for key with fingerprint %s",
+ length, fingerprint);
+
+ xa1 = _gcr_gnupg_build_xa1_record (record, load->attribute_buf->data, length);
+ g_ptr_array_add (records, xa1);
+
+ /* Did we use up all the attribute data? Get rid of the buffer */
+ if (length == load->attribute_buf->len) {
+ g_byte_array_unref (load->attribute_buf);
+ load->attribute_buf = NULL;
+
+ /* Otherwise clear out the used data from buffer */
+ } else {
+ g_byte_array_remove_range (load->attribute_buf, 0, length);
+ }
+
+ return TRUE;
+}
+
+static void
+process_outstanding_attributes (GcrGnupgCollectionLoad *load)
+{
+ GcrRecord *record;
+
+ if (load->attribute_queue == NULL)
+ return;
+
+ _gcr_debug ("%d outstanding attribute records",
+ (gint)g_queue_get_length (load->attribute_queue));
+
+ for (;;) {
+ record = g_queue_peek_head (load->attribute_queue);
+ if (record == NULL)
+ break;
+ if (!process_outstanding_attribute (load, record))
+ break;
+ g_queue_pop_head (load->attribute_queue);
+ _gcr_record_free (record);
+ }
+}
+
static void
on_line_parse_output (const gchar *line, gpointer user_data)
{
@@ -370,9 +478,10 @@ on_line_parse_output (const gchar *line, gpointer user_data)
record = NULL;
/*
- * 'uid' schema lines get added to the key that came before.
+ * 'uid' and 'fpr' schema lines get added to the key that came before.
*/
- } else if (schema == GCR_RECORD_SCHEMA_UID) {
+ } else if (schema == GCR_RECORD_SCHEMA_UID ||
+ schema == GCR_RECORD_SCHEMA_FPR) {
if (load->records->len) {
g_ptr_array_add (load->records, record);
record = NULL;
@@ -403,6 +512,41 @@ on_gnupg_process_error_line (GcrGnupgProcess *process, const gchar *line,
}
static void
+on_gnupg_process_status_record (GcrGnupgProcess *process, GcrRecord *record,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
+ GcrGnupgCollectionLoad *load = g_simple_async_result_get_op_res_gpointer (res);
+
+ if (GCR_RECORD_SCHEMA_ATTRIBUTE != _gcr_record_get_schema (record))
+ return;
+
+ if (!load->attribute_queue)
+ load->attribute_queue = g_queue_new ();
+
+ g_queue_push_tail (load->attribute_queue, _gcr_record_copy (record));
+ process_outstanding_attributes (load);
+}
+
+static void
+on_gnupg_process_attribute_data (GcrGnupgProcess *process, GByteArray *buffer,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
+ GcrGnupgCollectionLoad *load = g_simple_async_result_get_op_res_gpointer (res);
+
+ /* If we don't have a buffer, just claim this one */
+ if (!load->attribute_buf)
+ load->attribute_buf = g_byte_array_ref (buffer);
+
+ /* If we have data remaining over, add it to our buffer */
+ else
+ g_byte_array_append (load->attribute_buf, buffer->data, buffer->len);
+
+ process_outstanding_attributes (load);
+}
+
+static void
on_gnupg_process_completed (GObject *source, GAsyncResult *result, gpointer user_data)
{
GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
@@ -486,14 +630,9 @@ spawn_gnupg_list_process (GcrGnupgCollectionLoad *load, GSimpleAsyncResult *res)
g_ptr_array_add (argv, (gpointer)"--fixed-list-mode");
g_ptr_array_add (argv, (gpointer)"--with-colons");
+ g_ptr_array_add (argv, (gpointer)"--with-fingerprint");
g_ptr_array_add (argv, NULL);
- if (_gcr_debugging) {
- gchar *command = g_strjoinv (" ", (gchar**)argv->pdata);
- _gcr_debug ("spawning gnupg process: %s", command);
- g_free (command);
- }
-
/* res is unreffed in on_gnupg_process_completed */
_gcr_gnupg_process_run_async (load->process, (const gchar**)argv->pdata, NULL, flags,
load->cancel, on_gnupg_process_completed,
@@ -537,10 +676,8 @@ _gcr_gnupg_collection_load_async (GcrGnupgCollection *self, GCancellable *cancel
load->process = _gcr_gnupg_process_new (self->pv->directory, NULL);
load->output_sig = g_signal_connect (load->process, "output-data", G_CALLBACK (on_gnupg_process_output_data), res);
load->error_sig = g_signal_connect (load->process, "error-line", G_CALLBACK (on_gnupg_process_error_line), res);
-#if 0
- load->status_sig = g_signal_connect (load->process, "status-message", G_CALLBACK (on_gnupg_process_status_message), res);
+ load->status_sig = g_signal_connect (load->process, "status-record", G_CALLBACK (on_gnupg_process_status_record), res);
load->attribute_sig = g_signal_connect (load->process, "attribute-data", G_CALLBACK (on_gnupg_process_attribute_data), res);
-#endif
/*
* Track all the keys we currently have, at end remove those that
diff --git a/gcr/gcr-gnupg-key.c b/gcr/gcr-gnupg-key.c
index 31ab77b..3bf768f 100644
--- a/gcr/gcr-gnupg-key.c
+++ b/gcr/gcr-gnupg-key.c
@@ -410,6 +410,17 @@ _gcr_gnupg_key_get_keyid_for_records (GPtrArray *records)
return NULL;
}
+const gchar*
+_gcr_gnupg_key_get_fingerprint_for_records (GPtrArray *records)
+{
+ GcrRecord *record;
+
+ record = _gcr_record_find (records, GCR_RECORD_SCHEMA_FPR);
+ if (record != NULL)
+ return _gcr_record_get_raw (record, GCR_RECORD_FPR_FINGERPRINT);
+ return NULL;
+}
+
/**
* _gcr_gnupg_key_get_columns:
*
diff --git a/gcr/gcr-gnupg-key.h b/gcr/gcr-gnupg-key.h
index dcef960..271bb90 100644
--- a/gcr/gcr-gnupg-key.h
+++ b/gcr/gcr-gnupg-key.h
@@ -78,6 +78,8 @@ void _gcr_gnupg_key_set_secret_records (GcrGnupgKey *s
const gchar* _gcr_gnupg_key_get_keyid_for_records (GPtrArray *records);
+const gchar* _gcr_gnupg_key_get_fingerprint_for_records (GPtrArray *records);
+
G_END_DECLS
#endif /* __GCR_GNUPG_KEY_H__ */
diff --git a/gcr/gcr-gnupg-util.c b/gcr/gcr-gnupg-util.c
new file mode 100644
index 0000000..5e0025f
--- /dev/null
+++ b/gcr/gcr-gnupg-util.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * 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.
+ *
+ * Author: Stef Walter <stefw collabora co uk>
+ */
+
+#include "config.h"
+
+#include "egg/egg-hex.h"
+
+#include "gcr-gnupg-util.h"
+
+#include <gcrypt.h>
+
+GcrRecord*
+_gcr_gnupg_build_xa1_record (GcrRecord *meta, gpointer attribute,
+ gsize n_attribute)
+{
+ gchar hash[20];
+ gchar *hex;
+ gchar *status = "";
+ gint state, save;
+ gsize length;
+ gsize n_prefix, estimate;
+ GString *output;
+ GcrRecord *record;
+ guint flags, type;
+ const gchar *fingerprint, *created, *expiry;
+
+ g_return_val_if_fail (meta, NULL);
+
+ gcry_md_hash_buffer (GCRY_MD_RMD160, hash, attribute, n_attribute);
+ hex = egg_hex_encode_full (hash, sizeof (hash), TRUE, 0, 1);
+
+ if (!_gcr_record_get_uint (meta, GCR_RECORD_ATTRIBUTE_FLAGS, &flags))
+ flags = 0;
+
+ if (!_gcr_record_get_uint (meta, GCR_RECORD_ATTRIBUTE_TYPE, &type))
+ type = 0;
+
+ fingerprint = _gcr_record_get_raw (meta, GCR_RECORD_ATTRIBUTE_FINGERPRINT);
+ if (fingerprint == NULL)
+ fingerprint = "";
+
+ created = _gcr_record_get_raw (meta, GCR_RECORD_ATTRIBUTE_TIMESTAMP);
+ if (created == NULL)
+ created = "0";
+
+ expiry = _gcr_record_get_raw (meta, GCR_RECORD_ATTRIBUTE_EXPIRY);
+ if (expiry == NULL)
+ expiry = "";
+
+ if (flags & 0x02)
+ status = "r";
+ else if (flags & 0x04)
+ status = "e";
+ else if (flags & 0x01)
+ status = "P";
+
+ /* Algorithm from Glib reference */
+ estimate = n_attribute * 4 / 3 + n_attribute * 4 / (3 * 65) + 7;
+
+ output = g_string_sized_new (64 + estimate);
+ g_string_append_printf (output, "xa1::%u:%u:%s:%s:%s:%s:%s:",
+ (guint)n_attribute, type, fingerprint,
+ created, expiry, hex, status);
+
+ g_free (hex);
+
+ /* Resize string to fit the base64 data. */
+ n_prefix = output->len;
+ g_string_set_size (output, n_prefix + estimate);
+
+ /* The actual base64 data, without line breaks */
+ state = save = 0;
+ length = g_base64_encode_step ((guchar*)attribute, n_attribute, FALSE,
+ output->str + n_prefix, &state, &save);
+ length += g_base64_encode_close (TRUE, output->str + n_prefix + length,
+ &state, &save);
+
+ g_assert (length <= estimate);
+ g_string_set_size (output, n_prefix + length);
+ record = _gcr_record_take_colons (g_string_free (output, FALSE));
+ g_assert (record);
+
+ return record;
+}
diff --git a/gcr/gcr-gnupg-util.h b/gcr/gcr-gnupg-util.h
new file mode 100644
index 0000000..49b0e4f
--- /dev/null
+++ b/gcr/gcr-gnupg-util.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * 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.
+ *
+ * Author: Stef Walter <stefw collabora co uk>
+ */
+
+#if !defined (__GCR_H_INSIDE__) && !defined (GCR_COMPILATION)
+#error "Only <gcr/gcr.h> can be included directly."
+#endif
+
+#ifndef GCR_GNUPG_UTIL_H
+#define GCR_GNUPG_UTIL_H
+
+#include <glib.h>
+
+#include "gcr-record.h"
+
+G_BEGIN_DECLS
+
+GcrRecord* _gcr_gnupg_build_xa1_record (GcrRecord *meta,
+ gpointer attribute,
+ gsize n_attribute);
+
+G_END_DECLS
+
+#endif /* __GCR_GNUPG_KEY_H__ */
diff --git a/gcr/gcr-record.h b/gcr/gcr-record.h
index 3cc6d8d..5b1b69a 100644
--- a/gcr/gcr-record.h
+++ b/gcr/gcr-record.h
@@ -51,9 +51,12 @@
G_BEGIN_DECLS
-#define GCR_RECORD_SCHEMA_UID (g_quark_from_static_string ("uid"))
+#define GCR_RECORD_SCHEMA_ATTRIBUTE (g_quark_from_static_string ("ATTRIBUTE"))
+#define GCR_RECORD_SCHEMA_FPR (g_quark_from_static_string ("fpr"))
#define GCR_RECORD_SCHEMA_PUB (g_quark_from_static_string ("pub"))
#define GCR_RECORD_SCHEMA_SEC (g_quark_from_static_string ("sec"))
+#define GCR_RECORD_SCHEMA_UID (g_quark_from_static_string ("uid"))
+#define GCR_RECORD_SCHEMA_XA1 (g_quark_from_static_string ("xa1"))
/* Common columns for all schemas */
typedef enum {
@@ -61,6 +64,28 @@ typedef enum {
} GcrRecordColumns;
/*
+ * Columns for ATTRIBUTE status message. eg:
+ * [GNUPG:] ATTRIBUTE FBAFC70D60AE13D560764062B547B5580EEB5A80 10604 1 1 1 1227936754 0 1
+ */
+typedef enum {
+ GCR_RECORD_ATTRIBUTE_FINGERPRINT = 1,
+ GCR_RECORD_ATTRIBUTE_LENGTH = 2,
+ GCR_RECORD_ATTRIBUTE_TYPE = 3,
+ GCR_RECORD_ATTRIBUTE_TIMESTAMP = 6,
+ GCR_RECORD_ATTRIBUTE_EXPIRY = 7,
+ GCR_RECORD_ATTRIBUTE_FLAGS = 8
+} GcrRecordAttributeColumns;
+
+/*
+ * Columns for fpr schema, add them as they're used. eg:
+ * fpr:::::::::ECAF7590EB3443B5C7CF3ACB6C7EE1B8621CC013:
+ */
+typedef enum {
+ GCR_RECORD_FPR_FINGERPRINT = 9
+} GcrRecordFprColumns;
+
+
+/*
* Columns for pub schema, add them as they're used. eg:
* pub:f:1024:17:6C7EE1B8621CC013:899817715:1055898235::m:::scESC:
*/
@@ -84,6 +109,22 @@ typedef enum {
GCR_RECORD_UID_NAME = 9
} GcrRecordUidColumns;
+/*
+ * Columns for xa1 schema. This is a schema that we've invented ourselves
+ * for representing the actual data of openpgp attribute packets. eg:
+ * xa1::10838:1:ECAF7590EB3443B5C7CF3ACB6C7EE1B8621CC013:1998-02-02:0:ECAF7590EB3443B5C7CF3ACB6C7EE1B8621CC013:P:...
+ */
+typedef enum {
+ GCR_RECORD_XA1_LENGTH = 2,
+ GCR_RECORD_XA1_TYPE = 3,
+ GCR_RECORD_XA1_FINGERPRINT = 4,
+ GCR_RECORD_XA1_TIMESTAMP = 5,
+ GCR_RECORD_XA1_EXPIRY = 6,
+ GCR_RECORD_XA1_HASH = 7,
+ GCR_RECORD_XA1_STATUS = 8,
+ GCR_RECORD_XA1_DATA = 9,
+} GcrRecordXa1Columns;
+
typedef struct _GcrRecord GcrRecord;
#define GCR_TYPE_RECORD (_gcr_record_get_type ())
diff --git a/gcr/tests/test-gnupg-collection.c b/gcr/tests/test-gnupg-collection.c
index c164ea6..3808596 100644
--- a/gcr/tests/test-gnupg-collection.c
+++ b/gcr/tests/test-gnupg-collection.c
@@ -25,6 +25,7 @@
#include "gcr/gcr.h"
#include "gcr/gcr-gnupg-collection.h"
#include "gcr/gcr-gnupg-key.h"
+#include "gcr/gcr-record.h"
#include "egg/egg-testing.h"
@@ -35,6 +36,7 @@
typedef struct {
GcrGnupgCollection *collection;
+ gchar *directory;
GHashTable *keys;
GAsyncResult *result;
} Test;
@@ -81,19 +83,17 @@ setup (Test *test, gconstpointer unused)
{
GcrCollection *collection;
gchar *directory;
- gchar *path;
directory = g_get_current_dir ();
- path = g_build_filename (directory, "files", "gnupg-homedir", NULL);
+ test->directory = g_build_filename (directory, "files", "gnupg-homedir", NULL);
- collection = _gcr_gnupg_collection_new (path);
+ collection = _gcr_gnupg_collection_new (test->directory);
test->collection = GCR_GNUPG_COLLECTION (collection);
test->keys = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
g_signal_connect (collection, "added", G_CALLBACK (on_collection_added), test);
g_signal_connect (collection, "removed", G_CALLBACK (on_collection_removed), test);
- g_free (path);
g_free (directory);
}
@@ -106,6 +106,7 @@ teardown (Test *test, gconstpointer unused)
g_object_unref (test->result);
g_object_unref (test->collection);
+ g_free (test->directory);
}
static void
@@ -119,13 +120,24 @@ on_async_ready (GObject *source, GAsyncResult *res, gpointer user_data)
}
static void
+test_properties (Test *test, gconstpointer unused)
+{
+ gchar *directory;
+ g_object_get (test->collection, "directory", &directory, NULL);
+ g_assert_cmpstr (directory, ==, test->directory);
+ g_free (directory);
+}
+
+static void
test_load (Test *test, gconstpointer unused)
{
GError *error = NULL;
GcrGnupgKey *key;
+ GList *l, *objects;
+ GcrRecord *record;
_gcr_gnupg_collection_load_async (test->collection, NULL, on_async_ready, test);
- egg_test_wait_until (500);
+ egg_test_wait_until (500000);
g_assert (test->result);
_gcr_gnupg_collection_load_finish (test->collection, test->result, &error);
@@ -140,6 +152,26 @@ test_load (Test *test, gconstpointer unused)
key = g_hash_table_lookup (test->keys, "268FEE686262C395");
g_assert (GCR_IS_GNUPG_KEY (key));
g_assert (_gcr_gnupg_key_get_secret_records (key));
+
+ /* The length of collection should be correct */
+ g_assert_cmpuint (g_hash_table_size (test->keys), ==,
+ gcr_collection_get_length (GCR_COLLECTION (test->collection)));
+
+ /* The list of objects should be correct */
+ objects = gcr_collection_get_objects (GCR_COLLECTION (test->collection));
+ g_assert_cmpuint (g_hash_table_size (test->keys), ==, g_list_length (objects));
+ for (l = objects; l != NULL; l = g_list_next (l)) {
+ g_assert (GCR_IS_GNUPG_KEY (l->data));
+ key = g_hash_table_lookup (test->keys, _gcr_gnupg_key_get_keyid (l->data));
+ g_assert (key == l->data);
+ }
+ g_list_free (objects);
+
+ /* Phillip R. Zimmerman's key should have a photo */
+ key = g_hash_table_lookup (test->keys, "C7463639B2D7795E");
+ g_assert (GCR_IS_GNUPG_KEY (key));
+ record = _gcr_record_find (_gcr_gnupg_key_get_public_records (key), GCR_RECORD_SCHEMA_XA1);
+ g_assert (record);
}
static void
@@ -158,7 +190,7 @@ test_reload (Test *test, gconstpointer unused)
test->result = NULL;
_gcr_gnupg_collection_load_async (test->collection, NULL, on_async_ready, test);
- egg_test_wait_until (500);
+ egg_test_wait_until (500000);
g_assert (test->result);
_gcr_gnupg_collection_load_finish (test->collection, test->result, &error);
g_assert_no_error (error);
@@ -187,6 +219,7 @@ main (int argc, char **argv)
if (srcdir && chdir (srcdir) < 0)
g_error ("couldn't change directory to: %s: %s", srcdir, g_strerror (errno));
+ g_test_add ("/gcr/gnupg-collection/properties", Test, NULL, setup, test_properties, teardown);
g_test_add ("/gcr/gnupg-collection/load", Test, NULL, setup, test_load, teardown);
g_test_add ("/gcr/gnupg-collection/reload", Test, NULL, setup, test_reload, teardown);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]