[PATCH 2/9] Add a lazily-initialized crypto context to notmuch_database_t

Daniel Kahn Gillmor dkg at fifthhorseman.net
Wed Dec 9 19:39:39 PST 2015


This is in large part a duplicate of parts of crypto.c, but that code
is in the client (outside the library), and we don't want to entangle
the libgmime API with the libnotmuch API.

I welcome better proposals for how to share this code explicitly
between the library and the client.
---
 lib/database-private.h |  1 +
 lib/database.cc        | 42 ++++++++++++++++++++++++++++++++++++++++++
 lib/notmuch-private.h  |  8 ++++++++
 3 files changed, 51 insertions(+)

diff --git a/lib/database-private.h b/lib/database-private.h
index 3fb10f7..1bf76c5 100644
--- a/lib/database-private.h
+++ b/lib/database-private.h
@@ -171,6 +171,7 @@ struct _notmuch_database {
      * notmuch_database_new_revision. */
     unsigned long revision;
     const char *uuid;
+    GMimeCryptoContext *gpg_crypto_ctx;
 
     Xapian::QueryParser *query_parser;
     Xapian::TermGenerator *term_gen;
diff --git a/lib/database.cc b/lib/database.cc
index 3b342f1..13b0bad 100644
--- a/lib/database.cc
+++ b/lib/database.cc
@@ -995,6 +995,8 @@ notmuch_database_open_verbose (const char *path,
 	notmuch->uuid = talloc_strdup (
 	    notmuch, notmuch->xapian_db->get_uuid ().c_str ());
 
+	notmuch->gpg_crypto_ctx = NULL;
+	
 	notmuch->query_parser = new Xapian::QueryParser;
 	notmuch->term_gen = new Xapian::TermGenerator;
 	notmuch->term_gen->set_stemmer (Xapian::Stem ("english"));
@@ -1090,6 +1092,11 @@ notmuch_database_close (notmuch_database_t *notmuch)
     delete notmuch->last_mod_range_processor;
     notmuch->last_mod_range_processor = NULL;
 
+    if (notmuch->gpg_crypto_ctx) {
+	g_object_unref (notmuch->gpg_crypto_ctx);
+	notmuch->gpg_crypto_ctx = NULL;
+    }
+    
     return status;
 }
 
@@ -2386,6 +2393,41 @@ _notmuch_database_link_message (notmuch_database_t *notmuch,
     return status;
 }
 
+notmuch_private_status_t
+_notmuch_database_get_crypto_for_protocol (notmuch_database_t *notmuch,
+					   const char *protocol,
+					   GMimeCryptoContext **crypto_ctx)
+{
+    if (! protocol)
+	return NOTMUCH_PRIVATE_STATUS_MALFORMED_CRYPTO_PROTOCOL;
+    
+    /* As per RFC 1847 section 2.1: "the [protocol] value token is
+     * comprised of the type and sub-type tokens of the Content-Type".
+     * As per RFC 1521 section 2: "Content-Type values, subtypes, and
+     * parameter names as defined in this document are
+     * case-insensitive."  Thus, we use strcasecmp for the protocol.
+     */
+    if (strcasecmp (protocol, "application/pgp-signature") == 0 ||
+	strcasecmp (protocol, "application/pgp-encrypted") == 0) {
+	if (! notmuch->gpg_crypto_ctx) {
+	    /* FIXME: how do we allow for configuring the gpg binary
+	     * here? how would this config get into the library?  Is
+	     * this an option we can set on the database object?  Or
+	     * elsewhere?  */
+	    notmuch->gpg_crypto_ctx = g_mime_gpg_context_new (NULL, "gpg");
+	    if (! notmuch->gpg_crypto_ctx)
+		return NOTMUCH_PRIVATE_STATUS_FAILED_CRYPTO_CONTEXT_CREATION;
+
+	    g_mime_gpg_context_set_use_agent ((GMimeGpgContext *) notmuch->gpg_crypto_ctx, TRUE);
+	    g_mime_gpg_context_set_always_trust ((GMimeGpgContext *) notmuch->gpg_crypto_ctx, FALSE);
+	}
+	*crypto_ctx = notmuch->gpg_crypto_ctx;
+	return NOTMUCH_PRIVATE_STATUS_SUCCESS;
+    } else {
+	return NOTMUCH_PRIVATE_STATUS_UNKNOWN_CRYPTO_PROTOCOL;
+    }
+}
+
 notmuch_status_t
 notmuch_database_add_message (notmuch_database_t *notmuch,
 			      const char *filename,
diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h
index 5dd4770..f6fd36a 100644
--- a/lib/notmuch-private.h
+++ b/lib/notmuch-private.h
@@ -141,6 +141,9 @@ typedef enum _notmuch_private_status {
     /* Then add our own private values. */
     NOTMUCH_PRIVATE_STATUS_TERM_TOO_LONG = NOTMUCH_STATUS_LAST_STATUS,
     NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND,
+    NOTMUCH_PRIVATE_STATUS_MALFORMED_CRYPTO_PROTOCOL,
+    NOTMUCH_PRIVATE_STATUS_FAILED_CRYPTO_CONTEXT_CREATION,
+    NOTMUCH_PRIVATE_STATUS_UNKNOWN_CRYPTO_PROTOCOL,
 
     NOTMUCH_PRIVATE_STATUS_LAST_STATUS
 } notmuch_private_status_t;
@@ -239,6 +242,11 @@ _notmuch_database_filename_to_direntry (void *ctx,
 					notmuch_find_flags_t flags,
 					char **direntry);
 
+notmuch_private_status_t
+_notmuch_database_get_crypto_for_protocol (notmuch_database_t *notmuch,
+					   const char *protocol,
+					   GMimeCryptoContext **crypto_ctx);
+
 /* directory.cc */
 
 notmuch_directory_t *
-- 
2.6.2



More information about the notmuch mailing list