[gmime: 13/23] Autocrypt: introduce GMimeAutocryptHeaderList
- From: Jeffrey Stedfast <fejj src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gmime: 13/23] Autocrypt: introduce GMimeAutocryptHeaderList
- Date: Sun, 29 Oct 2017 14:16:44 +0000 (UTC)
commit ca5fe60a9c983159c6f3cad16b00e5102509801a
Author: Daniel Kahn Gillmor <dkg fifthhorseman net>
Date: Mon Oct 23 03:20:38 2017 -0400
Autocrypt: introduce GMimeAutocryptHeaderList
MUAs that implement Autocrypt are likely to deal with batches of
Autocrypt headers associated with an e-mail.
In the weird corner case where an e-mail has multiple addresses listed
in the From: line, for example, it's possible for there to be multiple
Autocrypt headers that relate to the different senders of the e-mail.
Likewise, gossiped keys (simplified key introductions usually sent
with encrypted mail), we'll also need to deal with a set of Autocrypt
headers.
This abstraction will be useful for MUA implementors when scanning
e-mail that has multiple addresses either from or to.
docs/reference/gmime-sections.txt | 16 +++
gmime/gmime-autocrypt.c | 213 +++++++++++++++++++++++++++++++++++++
gmime/gmime-autocrypt.h | 41 +++++++
3 files changed, 270 insertions(+), 0 deletions(-)
---
diff --git a/docs/reference/gmime-sections.txt b/docs/reference/gmime-sections.txt
index 4b4e410..e6660da 100644
--- a/docs/reference/gmime-sections.txt
+++ b/docs/reference/gmime-sections.txt
@@ -1609,10 +1609,19 @@ g_mime_autocrypt_header_is_complete
g_mime_autocrypt_header_get_string
g_mime_autocrypt_header_compare
g_mime_autocrypt_header_clone
+GMimeAutocryptHeaderList
+g_mime_autocrypt_header_list_new
+g_mime_autocrypt_header_list_add_missing_addresses
+g_mime_autocrypt_header_list_add
+g_mime_autocrypt_header_list_get_count
+g_mime_autocrypt_header_list_get_header_at
+g_mime_autocrypt_header_list_get_header_for_address
+g_mime_autocrypt_header_list_remove_incomplete
<SUBSECTION Private>
g_mime_autocrypt_header_get_type
+g_mime_autocrypt_header_list_get_type
<SUBSECTION Standard>
GMIME_AUTOCRYPT_HEADER
@@ -1622,4 +1631,11 @@ GMIME_AUTOCRYPT_HEADER_CLASS
GMIME_IS_AUTOCRYPT_HEADER_CLASS
GMIME_AUTOCRYPT_HEADER_GET_CLASS
GMimeAutocryptHeaderClass
+GMIME_AUTOCRYPT_HEADER_LIST
+GMIME_IS_AUTOCRYPT_HEADER_LIST
+GMIME_TYPE_AUTOCRYPT_HEADER_LIST
+GMIME_AUTOCRYPT_HEADER_LIST_CLASS
+GMIME_IS_AUTOCRYPT_HEADER_LIST_CLASS
+GMIME_AUTOCRYPT_HEADER_LIST_GET_CLASS
+GMimeAutocryptHeaderListClass
</SECTION>
diff --git a/gmime/gmime-autocrypt.c b/gmime/gmime-autocrypt.c
index 8bd4321..7b1fcd3 100644
--- a/gmime/gmime-autocrypt.c
+++ b/gmime/gmime-autocrypt.c
@@ -616,3 +616,216 @@ g_mime_autocrypt_header_clone (GMimeAutocryptHeader *dst, GMimeAutocryptHeader *
} else
dst->effective_date = NULL;
}
+
+
+/* GMimeAutocryptHeaderList */
+
+
+static void g_mime_autocrypt_header_list_class_init (GMimeAutocryptHeaderListClass *klass);
+static void g_mime_autocrypt_header_list_init (GMimeAutocryptHeaderList *ahl, GMimeAutocryptHeaderListClass
*klass);
+static void g_mime_autocrypt_header_list_finalize (GObject *object);
+
+static GObjectClass *ahl_parent_class = NULL;
+
+
+GType
+g_mime_autocrypt_header_list_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ static const GTypeInfo info = {
+ sizeof (GMimeAutocryptHeaderListClass),
+ NULL, /* base_class_init */
+ NULL, /* base_class_finalize */
+ (GClassInitFunc) g_mime_autocrypt_header_list_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GMimeAutocryptHeaderList),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) g_mime_autocrypt_header_list_init,
+ };
+
+ type = g_type_register_static (G_TYPE_OBJECT, "GMimeAutocryptHeaderList", &info, 0);
+ }
+
+ return type;
+}
+
+static void
+g_mime_autocrypt_header_list_class_init (GMimeAutocryptHeaderListClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ ahl_parent_class = g_type_class_ref (G_TYPE_OBJECT);
+
+ object_class->finalize = g_mime_autocrypt_header_list_finalize;
+}
+
+static void
+g_mime_autocrypt_header_list_init (GMimeAutocryptHeaderList *ahl, GMimeAutocryptHeaderListClass *klass)
+{
+ ahl->array = g_ptr_array_new_with_free_func (g_object_unref);
+}
+
+static void
+g_mime_autocrypt_header_list_finalize (GObject *object)
+{
+ GMimeAutocryptHeaderList *ahl = (GMimeAutocryptHeaderList *) object;
+
+ g_ptr_array_unref (ahl->array);
+ G_OBJECT_CLASS (ahl_parent_class)->finalize (object);
+}
+
+
+/**
+ * g_mime_autocrypt_header_list_new:
+ *
+ * Creates a new #GMimeAutocryptHeaderList object.
+ *
+ * Returns: (transfer full): a new #GMimeAutocryptHeaderList object.
+ **/
+GMimeAutocryptHeaderList *
+g_mime_autocrypt_header_list_new (void)
+{
+ return g_object_new (GMIME_TYPE_AUTOCRYPT_HEADER_LIST, NULL);
+}
+
+
+/**
+ * g_mime_autocrypt_header_list_add_missing_addresses:
+ * @acheaders: a #GMimeAutocryptHeaderList object
+ * @addresses: an #InternetAddressList object
+ *
+ * Adds a new incomplete #GMimeAutocryptHeader object for each
+ * InternetAddressMailbox found in #addresses.
+ *
+ * Returns: the number of addresses added
+ **/
+guint
+g_mime_autocrypt_header_list_add_missing_addresses (GMimeAutocryptHeaderList *acheaders, InternetAddressList
*list)
+{
+ g_return_val_if_fail (GMIME_IS_AUTOCRYPT_HEADER_LIST (acheaders), 0);
+ guint ret = 0;
+ guint i;
+ for (i = 0; i < internet_address_list_length (list); i++) {
+ InternetAddress *a = internet_address_list_get_address (list, i);
+ if (INTERNET_ADDRESS_IS_GROUP(a)) {
+ ret += g_mime_autocrypt_header_list_add_missing_addresses (acheaders,
internet_address_group_get_members (INTERNET_ADDRESS_GROUP (a)));
+ } else if (INTERNET_ADDRESS_IS_MAILBOX(a)) {
+ InternetAddressMailbox *m = INTERNET_ADDRESS_MAILBOX (a);
+ GMimeAutocryptHeader *ah = g_mime_autocrypt_header_list_get_header_for_address
(acheaders, m);
+ if (ah == NULL) {
+ ah = g_mime_autocrypt_header_new ();
+ g_mime_autocrypt_header_set_address (ah, m);
+ g_mime_autocrypt_header_list_add (acheaders, ah);
+ ret += 1;
+ }
+ } else {
+ /* FIXME: what do we do here? what is this
+ thing if it's neither mailbox nor group?
+ It should be safe to just ignore it. */
+ }
+ }
+ return ret;
+}
+
+
+/**
+ * g_mime_autocrypt_header_list_add:
+ * @acheaders: a #GMimeAutocryptHeaderList object
+ * @ah: a #GMimeAutocryptHeader object
+ *
+ * Adds a the passed #GMimeAutocryptHeader to the list.
+ **/
+void
+g_mime_autocrypt_header_list_add (GMimeAutocryptHeaderList *acheaders, GMimeAutocryptHeader *ah)
+{
+ g_return_if_fail (GMIME_IS_AUTOCRYPT_HEADER_LIST (acheaders));
+ g_return_if_fail (GMIME_IS_AUTOCRYPT_HEADER (ah));
+
+ g_object_ref (ah);
+ g_ptr_array_add (acheaders->array, ah);
+}
+
+/**
+ * g_mime_autocrypt_header_list_get_count:
+ * @acheaders: a #GMimeAutocryptHeaderList object
+ *
+ * See how many Autocrypt headers are in the list.
+ *
+ * Returns: the number of available Autocrypt headers
+ **/
+guint
+g_mime_autocrypt_header_list_get_count (GMimeAutocryptHeaderList *acheaders)
+{
+ g_return_val_if_fail (GMIME_IS_AUTOCRYPT_HEADER_LIST (acheaders), 0);
+
+ return acheaders->array->len;
+}
+
+/**
+ * g_mime_autocrypt_header_list_get_header_at:
+ * @acheaders: a #GMimeAutocryptHeaderList object
+ * @n: an index into the list
+ *
+ * Get the Nth header in the list (returns %NULL on error, or if n is out of bounds)
+ *
+ * Returns: (transfer none): a pointer to the Nth header in the list.
+ **/
+GMimeAutocryptHeader *
+g_mime_autocrypt_header_list_get_header_at (GMimeAutocryptHeaderList *acheaders, guint n)
+{
+ g_return_val_if_fail (GMIME_IS_AUTOCRYPT_HEADER_LIST (acheaders), NULL);
+
+ if (n < acheaders->array->len)
+ return (GMimeAutocryptHeader*)(acheaders->array->pdata[n]);
+}
+
+/**
+ * g_mime_autocrypt_header_list_get_header_for_address:
+ * @acheaders: a #GMimeAutocryptHeaderList object
+ * @addr: an #InternetAddressMailbox object
+ *
+ * returns an Autocrypt header corresponding to the given
+ * InternetAddressMailbox.
+ *
+ * Returns: (transfer none): a pointer to the header in the list which
+ * matches the requested address, or %NULL if no such header exists in
+ * the list.
+ **/
+GMimeAutocryptHeader *
+g_mime_autocrypt_header_list_get_header_for_address (GMimeAutocryptHeaderList *acheaders,
InternetAddressMailbox *addr)
+{
+ g_return_val_if_fail (GMIME_IS_AUTOCRYPT_HEADER_LIST (acheaders), NULL);
+ g_return_val_if_fail (INTERNET_ADDRESS_IS_MAILBOX (addr), NULL);
+
+ guint i;
+ for (i = 0; i < acheaders->array->len; i++) {
+ GMimeAutocryptHeader* ah = (GMimeAutocryptHeader*)(acheaders->array->pdata[i]);
+ if (g_strcmp0 (internet_address_mailbox_get_idn_addr (addr),
internet_address_mailbox_get_idn_addr (ah->address)) == 0)
+ return ah;
+ }
+ return NULL;
+}
+
+/**
+ * g_mime_autocrypt_header_list_remove_incomplete:
+ * @acheaders: a #GMimeAutocryptHeaderList object
+ *
+ * Remove all incomplete Autocrypt headers from the list.
+ **/
+void
+g_mime_autocrypt_header_list_remove_incomplete (GMimeAutocryptHeaderList *acheaders)
+{
+ g_return_if_fail (GMIME_IS_AUTOCRYPT_HEADER_LIST (acheaders));
+
+ guint i;
+ for (i = 0; i < acheaders->array->len; i++) {
+ GMimeAutocryptHeader* ah = (GMimeAutocryptHeader*)(acheaders->array->pdata[i]);
+ if (!g_mime_autocrypt_header_is_complete (ah)) {
+ g_ptr_array_remove_index (acheaders->array, i);
+ i--;
+ }
+ }
+}
diff --git a/gmime/gmime-autocrypt.h b/gmime/gmime-autocrypt.h
index 859733b..d2405e4 100644
--- a/gmime/gmime-autocrypt.h
+++ b/gmime/gmime-autocrypt.h
@@ -36,9 +36,20 @@ G_BEGIN_DECLS
#define GMIME_IS_AUTOCRYPT_HEADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),
GMIME_TYPE_AUTOCRYPT_HEADER))
#define GMIME_AUTOCRYPT_HEADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),
GMIME_TYPE_AUTOCRYPT_HEADER, GMimeAutocryptHeaderClass))
+
+#define GMIME_TYPE_AUTOCRYPT_HEADER_LIST (g_mime_autocrypt_header_list_get_type ())
+#define GMIME_AUTOCRYPT_HEADER_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
GMIME_TYPE_AUTOCRYPT_HEADER_LIST, GMimeAutocryptHeaderList))
+#define GMIME_AUTOCRYPT_HEADER_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),
GMIME_TYPE_AUTOCRYPT_HEADER_LIST, GMimeAutocryptHeaderListClass))
+#define GMIME_IS_AUTOCRYPT_HEADER_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),
GMIME_TYPE_AUTOCRYPT_HEADER_LIST))
+#define GMIME_IS_AUTOCRYPT_HEADER_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),
GMIME_TYPE_AUTOCRYPT_HEADER_LIST))
+#define GMIME_AUTOCRYPT_HEADER_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),
GMIME_TYPE_AUTOCRYPT_HEADER_LIST, GMimeAutocryptHeaderListClass))
+
typedef struct _GMimeAutocryptHeader GMimeAutocryptHeader;
typedef struct _GMimeAutocryptHeaderClass GMimeAutocryptHeaderClass;
+typedef struct _GMimeAutocryptHeaderList GMimeAutocryptHeaderList;
+typedef struct _GMimeAutocryptHeaderListClass GMimeAutocryptHeaderListClass;
+
/**
* GMimeAutocryptPreferEncrypt:
* @GMIME_AUTOCRYPT_PREFER_ENCRYPT_NONE: No preference stated.
@@ -107,6 +118,36 @@ gboolean g_mime_autocrypt_header_is_complete (GMimeAutocryptHeader *ah);
int g_mime_autocrypt_header_compare (GMimeAutocryptHeader *ah1, GMimeAutocryptHeader *ah2);
void g_mime_autocrypt_header_clone (GMimeAutocryptHeader *dst, GMimeAutocryptHeader *src);
+
+/**
+ * GMimeAutocryptHeaderList:
+ *
+ * A list of Autocrypt headers, typically extracted from a GMimeMessage.
+ **/
+struct _GMimeAutocryptHeaderList {
+ GObject parent_object;
+
+ /* < private > */
+ GPtrArray *array;
+};
+
+struct _GMimeAutocryptHeaderListClass {
+ GObjectClass parent_class;
+
+};
+
+GType g_mime_autocrypt_header_list_get_type (void);
+
+GMimeAutocryptHeaderList *g_mime_autocrypt_header_list_new ();
+guint g_mime_autocrypt_header_list_add_missing_addresses (GMimeAutocryptHeaderList *ahl, InternetAddressList
*list);
+void g_mime_autocrypt_header_list_add (GMimeAutocryptHeaderList *ahl, GMimeAutocryptHeader *ah);
+
+guint g_mime_autocrypt_header_list_get_count (GMimeAutocryptHeaderList *acheaders);
+GMimeAutocryptHeader *g_mime_autocrypt_header_list_get_header_at (GMimeAutocryptHeaderList *acheaders, guint
n);
+GMimeAutocryptHeader *g_mime_autocrypt_header_list_get_header_for_address (GMimeAutocryptHeaderList
*acheaders, InternetAddressMailbox *addr);
+void g_mime_autocrypt_header_list_remove_incomplete (GMimeAutocryptHeaderList *acheaders);
+
+
G_END_DECLS
#endif /* __GMIME_AUTOCRYPT_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]