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