[PATCH 7/9] add a gpg_path value for notmuch_database_t
authorDaniel Kahn Gillmor <dkg@fifthhorseman.net>
Thu, 10 Dec 2015 03:39:44 +0000 (22:39 +1900)
committerW. Trevor King <wking@tremily.us>
Sat, 20 Aug 2016 21:50:09 +0000 (14:50 -0700)
4e/28e9989209db194a821fb944f145698d7d517e [new file with mode: 0644]

diff --git a/4e/28e9989209db194a821fb944f145698d7d517e b/4e/28e9989209db194a821fb944f145698d7d517e
new file mode 100644 (file)
index 0000000..83e7f4f
--- /dev/null
@@ -0,0 +1,242 @@
+Return-Path: <dkg@fifthhorseman.net>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+ by arlo.cworth.org (Postfix) with ESMTP id 99EC46DE1601\r
+ for <notmuch@notmuchmail.org>; Wed,  9 Dec 2015 19:40:15 -0800 (PST)\r
+X-Virus-Scanned: Debian amavisd-new at cworth.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: -0.033\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=-0.033 tagged_above=-999 required=5\r
+ tests=[AWL=-0.033] autolearn=disabled\r
+Received: from arlo.cworth.org ([127.0.0.1])\r
+ by localhost (arlo.cworth.org [127.0.0.1]) (amavisd-new, port 10024)\r
+ with ESMTP id sMav7f67XOXL for <notmuch@notmuchmail.org>;\r
+ Wed,  9 Dec 2015 19:40:13 -0800 (PST)\r
+Received: from che.mayfirst.org (che.mayfirst.org [209.234.253.108])\r
+ by arlo.cworth.org (Postfix) with ESMTP id 9D7606DE18EC\r
+ for <notmuch@notmuchmail.org>; Wed,  9 Dec 2015 19:40:06 -0800 (PST)\r
+Received: from fifthhorseman.net (unknown [38.109.115.130])\r
+ by che.mayfirst.org (Postfix) with ESMTPSA id 5965FF989\r
+ for <notmuch@notmuchmail.org>; Wed,  9 Dec 2015 22:40:04 -0500 (EST)\r
+Received: by fifthhorseman.net (Postfix, from userid 1000)\r
+ id BC38D21227; Wed,  9 Dec 2015 22:40:03 -0500 (EST)\r
+From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>\r
+To: Notmuch Mail <notmuch@notmuchmail.org>\r
+Subject: [PATCH 7/9] add a gpg_path value for notmuch_database_t\r
+Date: Wed,  9 Dec 2015 22:39:44 -0500\r
+Message-Id: <1449718786-28000-8-git-send-email-dkg@fifthhorseman.net>\r
+X-Mailer: git-send-email 2.6.2\r
+In-Reply-To: <1449718786-28000-1-git-send-email-dkg@fifthhorseman.net>\r
+References: <1449718786-28000-1-git-send-email-dkg@fifthhorseman.net>\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.20\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+ <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <https://notmuchmail.org/mailman/options/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch/>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <https://notmuchmail.org/mailman/listinfo/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Thu, 10 Dec 2015 03:40:16 -0000\r
+\r
+Exposing this to the user of the library lets the user point to\r
+arbitrary gpg executables when trying to decrypt.\r
+---\r
+ lib/database-private.h |  3 ++\r
+ lib/database.cc        | 93 +++++++++++++++++++++++++++++++++++++++++++-------\r
+ lib/notmuch.h          | 31 +++++++++++++++++\r
+ 3 files changed, 115 insertions(+), 12 deletions(-)\r
+\r
+diff --git a/lib/database-private.h b/lib/database-private.h\r
+index 1bf76c5..9a35044 100644\r
+--- a/lib/database-private.h\r
++++ b/lib/database-private.h\r
+@@ -171,6 +171,9 @@ struct _notmuch_database {\r
+      * notmuch_database_new_revision. */\r
+     unsigned long revision;\r
+     const char *uuid;\r
++\r
++    /* can be NULL, meaning "try to find gpg2 or gpg if possible" */\r
++    char *gpg_path;\r
+     GMimeCryptoContext *gpg_crypto_ctx;\r
\r
+     Xapian::QueryParser *query_parser;\r
+diff --git a/lib/database.cc b/lib/database.cc\r
+index d0e8800..c40ce77 100644\r
+--- a/lib/database.cc\r
++++ b/lib/database.cc\r
+@@ -996,6 +996,7 @@ notmuch_database_open_verbose (const char *path,\r
+           notmuch, notmuch->xapian_db->get_uuid ().c_str ());\r
\r
+       notmuch->gpg_crypto_ctx = NULL;\r
++      notmuch->gpg_path = NULL;\r
+       \r
+       notmuch->query_parser = new Xapian::QueryParser;\r
+       notmuch->term_gen = new Xapian::TermGenerator;\r
+@@ -1096,6 +1097,10 @@ notmuch_database_close (notmuch_database_t *notmuch)\r
+       g_object_unref (notmuch->gpg_crypto_ctx);\r
+       notmuch->gpg_crypto_ctx = NULL;\r
+     }\r
++    if (notmuch->gpg_path) {\r
++      talloc_free(notmuch->gpg_path);\r
++      notmuch->gpg_path = NULL;\r
++    }\r
+     \r
+     return status;\r
+ }\r
+@@ -2393,17 +2398,6 @@ _notmuch_database_link_message (notmuch_database_t *notmuch,\r
+     return status;\r
+ }\r
\r
+-static const char*\r
+-_notmuch_database_get_gpg_path (notmuch_database_t *notmuch)\r
+-{\r
+-#define try_gpg_path(z) if (!access(z, X_OK)) return z\r
+-    try_gpg_path("/usr/bin/gpg2");\r
+-    try_gpg_path("/bin/gpg2");\r
+-    try_gpg_path("/usr/bin/gpg");\r
+-    try_gpg_path("/bin/gpg");\r
+-    return NULL;\r
+-}\r
+-\r
+ notmuch_private_status_t\r
+ _notmuch_database_get_crypto_for_protocol (notmuch_database_t *notmuch,\r
+                                          const char *protocol,\r
+@@ -2425,7 +2419,7 @@ _notmuch_database_get_crypto_for_protocol (notmuch_database_t *notmuch,\r
+            * here? how would this config get into the library?  Is\r
+            * this an option we can set on the database object?  Or\r
+            * elsewhere?  */\r
+-          notmuch->gpg_crypto_ctx = g_mime_gpg_context_new (NULL, _notmuch_database_get_gpg_path(notmuch));\r
++          notmuch->gpg_crypto_ctx = g_mime_gpg_context_new (NULL, notmuch_database_get_gpg_path(notmuch));\r
+           if (! notmuch->gpg_crypto_ctx)\r
+               return NOTMUCH_PRIVATE_STATUS_FAILED_CRYPTO_CONTEXT_CREATION;\r
\r
+@@ -2752,3 +2746,78 @@ notmuch_database_status_string (const notmuch_database_t *notmuch)\r
+ {\r
+     return notmuch->status_string;\r
+ }\r
++\r
++\r
++static notmuch_bool_t\r
++_find_in_path(const char* path)\r
++{\r
++    char *c = NULL, *save = NULL, *tok;\r
++    size_t n;\r
++    int dfd = -1;\r
++    notmuch_bool_t ret = FALSE;\r
++    \r
++    n = confstr(_CS_PATH, NULL, 0);\r
++    c = (char*)talloc_size(NULL, n);\r
++    if (!c)\r
++      return FALSE;\r
++    confstr(_CS_PATH, c, n);\r
++\r
++    tok = strtok_r(c, ":", &save);\r
++    while (tok) {\r
++      dfd = open(tok, O_DIRECTORY | O_RDONLY);\r
++      if (dfd != -1) {\r
++          if (!faccessat(dfd, path, X_OK, 0)) {\r
++              ret = TRUE;\r
++              goto done;\r
++          }\r
++          close(dfd);\r
++      }\r
++      tok = strtok_r(NULL, ":", &save);\r
++    }\r
++done:\r
++    if (dfd != -1)\r
++      close(dfd);\r
++    if (c)\r
++      talloc_free(c);\r
++    return ret;\r
++}\r
++\r
++notmuch_status_t\r
++notmuch_database_set_gpg_path (notmuch_database_t *notmuch, const char* path)\r
++{\r
++    /* return success if this matches what is already configured */\r
++    if ((!path && !notmuch->gpg_path) ||\r
++      (path && notmuch->gpg_path && 0 == strcmp(path, notmuch->gpg_path)))\r
++      return NOTMUCH_STATUS_SUCCESS;\r
++    \r
++    if (!path && !_find_in_path(path))\r
++      return NOTMUCH_STATUS_FILE_ERROR;\r
++\r
++    /* clear any existing gpg_crypto_ctx, since things are changing */\r
++    if (notmuch->gpg_crypto_ctx) {\r
++      g_object_unref (notmuch->gpg_crypto_ctx);\r
++      notmuch->gpg_crypto_ctx = NULL;\r
++    }\r
++\r
++    if (notmuch->gpg_path) {\r
++      talloc_free(notmuch->gpg_path);\r
++      notmuch->gpg_path = NULL;\r
++    }\r
++\r
++    if (path)\r
++      notmuch->gpg_path = talloc_strdup (notmuch, path);\r
++    \r
++    return NOTMUCH_STATUS_SUCCESS;\r
++}\r
++\r
++const char*\r
++notmuch_database_get_gpg_path (const notmuch_database_t *notmuch)\r
++{\r
++    if (notmuch->gpg_path)\r
++      return notmuch->gpg_path;\r
++\r
++#define try_gpg_path(z) if (_find_in_path(z)) return z\r
++    try_gpg_path("gpg2");\r
++    try_gpg_path("gpg");\r
++    return NULL;\r
++}\r
+diff --git a/lib/notmuch.h b/lib/notmuch.h\r
+index 809a2ea..e9cfed3 100644\r
+--- a/lib/notmuch.h\r
++++ b/lib/notmuch.h\r
+@@ -591,6 +591,37 @@ notmuch_database_add_message_try_decrypt (notmuch_database_t *database,\r
+                                         notmuch_message_t **message);\r
\r
+ /**\r
++ * Tell the notmuch database where to find GnuPG.\r
++ *\r
++ * This is only useful when notmuch might try to use GnuPG to decrypt\r
++ * MIME parts (see for example\r
++ * notmuch_database_add_message_try_decrypt).  The argument needs to\r
++ * be an executable version of gpg.\r
++ * \r
++ * If this function has never been invoked, notmuch will try to find\r
++ * gpg in reasonable places.\r
++ *\r
++ * This value is not currently stored in the database on disk, it is\r
++ * only used for this notmuch_database_t while it exists.\r
++ *\r
++ * Return value:\r
++ *\r
++ * NOTMUCH_STATUS_SUCCESS: the path was accepted and will be used.\r
++ * \r
++ * NOTMUCH_STATUS_FILE_ERROR: the path given either wasn't found or\r
++ *      wasn't executable.\r
++ */\r
++notmuch_status_t\r
++notmuch_database_set_gpg_path (notmuch_database_t *database, const char* path);\r
++                             \r
++/**\r
++ * Find out where the notmuch database will try to find gpg if it\r
++ * needs to use it.\r
++ */\r
++const char*\r
++notmuch_database_get_gpg_path (const notmuch_database_t *database);\r
++\r
++/**\r
+  * Remove a message filename from the given notmuch database. If the\r
+  * message has no more filenames, remove the message.\r
+  *\r
+-- \r
+2.6.2\r
+\r