unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
To: Notmuch Mail <notmuch@notmuchmail.org>
Subject: [PATCH 16/18] crypto: add --try-decrypt=nostash to avoid stashing session keys
Date: Wed, 25 Oct 2017 02:52:01 -0400	[thread overview]
Message-ID: <20171025065203.24403-17-dkg@fifthhorseman.net> (raw)
In-Reply-To: <20171025065203.24403-1-dkg@fifthhorseman.net>

Here's the configuration choice for people who want a cleartext index,
but don't want stashed session keys.

Interestingly, this "nostash" decryption policy is actually the same
policy that should be used by "notmuch show" and "notmuch reply",
since they never modify the index or database when they are invoked
with --decrypt.

We take advantage of this parallel to tune the behavior of those
programs so that we're not requesting session keys from GnuPG during
"show" and "reply" that we would then otherwise just throw away.
---
 completion/notmuch-completion.bash |  6 +++---
 doc/man1/notmuch-config.rst        | 10 ++++++++--
 doc/man1/notmuch-insert.rst        | 11 +++++++----
 doc/man1/notmuch-new.rst           | 11 +++++++----
 doc/man1/notmuch-reindex.rst       | 11 +++++++----
 lib/indexopts.c                    |  2 ++
 lib/notmuch.h                      |  1 +
 notmuch-reply.c                    |  2 +-
 notmuch-show.c                     |  3 ++-
 notmuch.c                          |  1 +
 test/T357-index-decryption.sh      | 26 ++++++++++++++++++++++++++
 util/crypto.c                      |  4 ++--
 12 files changed, 67 insertions(+), 21 deletions(-)

diff --git a/completion/notmuch-completion.bash b/completion/notmuch-completion.bash
index 53d7380b..29256210 100644
--- a/completion/notmuch-completion.bash
+++ b/completion/notmuch-completion.bash
@@ -288,7 +288,7 @@ _notmuch_insert()
 	    return
 	    ;;
 	--try-decrypt)
-	    COMPREPLY=( $( compgen -W "true false auto" -- "${cur}" ) )
+	    COMPREPLY=( $( compgen -W "true false auto nostash" -- "${cur}" ) )
 	    return
 	    ;;
     esac
@@ -320,7 +320,7 @@ _notmuch_new()
     $split &&
     case "${prev}" in
 	--try-decrypt)
-	    COMPREPLY=( $( compgen -W "true false auto" -- "${cur}" ) )
+	    COMPREPLY=( $( compgen -W "true false auto nostash" -- "${cur}" ) )
 	    return
 	    ;;
     esac
@@ -442,7 +442,7 @@ _notmuch_reindex()
     $split &&
     case "${prev}" in
 	--try-decrypt)
-	    COMPREPLY=( $( compgen -W "true false auto" -- "${cur}" ) )
+	    COMPREPLY=( $( compgen -W "true false auto nostash" -- "${cur}" ) )
 	    return
 	    ;;
     esac
diff --git a/doc/man1/notmuch-config.rst b/doc/man1/notmuch-config.rst
index 5adde070..d9e22653 100644
--- a/doc/man1/notmuch-config.rst
+++ b/doc/man1/notmuch-config.rst
@@ -141,6 +141,9 @@ The available configuration items are described below.
     **index.try_decrypt**
 
         **[STORED IN DATABASE]**
+
+        One of ``false``, ``auto``, ``nostash``, or ``true``.
+
         When indexing an encrypted e-mail message, if this variable is
         set to ``true``, notmuch will try to decrypt the message and
         index the cleartext, stashing a copy of any discovered session
@@ -150,11 +153,14 @@ The available configuration items are described below.
         secret keys.  Use ``false`` to avoid decrypting even when a
         stashed session key is already present.
 
+        ``nostash`` is the same as ``true`` except that it will not
+        stash newly-discovered session keys in the database.
+
         Be aware that the notmuch index is likely sufficient to
         reconstruct the cleartext of the message itself, so please
         ensure that the notmuch message index is adequately protected.
-        DO NOT USE ``index.try_decrypt=true`` without considering the
-        security of your index.
+        DO NOT USE ``index.try_decrypt=true`` or ``index-only``
+        without considering the security of your index.
 
         Default: ``auto``.
 
diff --git a/doc/man1/notmuch-insert.rst b/doc/man1/notmuch-insert.rst
index 3e6f538d..bf659a3d 100644
--- a/doc/man1/notmuch-insert.rst
+++ b/doc/man1/notmuch-insert.rst
@@ -50,10 +50,10 @@ Supported options for **insert** include
     ``--no-hooks``
         Prevent hooks from being run.
 
-    ``--try-decrypt=(true|auto|false)``
+    ``--try-decrypt=(true|nostash|auto|false)``
 
         If ``true`` and the message is encrypted, try to decrypt the
-        message while indexing, storing any session keys discovered.
+        message while indexing, stashing any session keys discovered.
         If ``auto``, and notmuch already knows about a session key for
         the message, it will try decrypting using that session key but
         will not try to access the user's secret keys.  If decryption
@@ -61,11 +61,14 @@ Supported options for **insert** include
         message is always stored to disk in its original form
         (ciphertext).
 
+        ``nostash`` is the same as ``true`` except that it will not
+        stash newly-discovered session keys in the database.
+
         Be aware that the index is likely sufficient to reconstruct
         the cleartext of the message itself, so please ensure that the
         notmuch message index is adequately protected. DO NOT USE
-        ``--try-decrypt=true`` without considering the security of
-        your index.
+        ``--try-decrypt=true`` or ``nostash`` without considering
+        the security of your index.
 
         See also ``index.try_decrypt`` in **notmuch-config(1)**.
 
diff --git a/doc/man1/notmuch-new.rst b/doc/man1/notmuch-new.rst
index 351b7591..2660988d 100644
--- a/doc/man1/notmuch-new.rst
+++ b/doc/man1/notmuch-new.rst
@@ -43,20 +43,23 @@ Supported options for **new** include
     ``--quiet``
         Do not print progress or results.
 
-    ``--try-decrypt=(true|auto|false)``
+    ``--try-decrypt=(true|nostash|auto|false)``
 
         If ``true``, when encountering an encrypted message, try to
-        decrypt it while indexing, and store any discovered session
+        decrypt it while indexing, and stash any discovered session
         keys.  If ``auto``, try to use any session key already known
         to belong to this message, but do not attempt to use the
         user's secret keys.  If decryption is successful, index the
         cleartext of the message.
 
+        ``nostash`` is the same as ``true`` except that it will not
+        stash newly-discovered session keys in the database.
+
         Be aware that the index is likely sufficient to reconstruct
         the cleartext of the message itself, so please ensure that the
         notmuch message index is adequately protected.  DO NOT USE
-        ``--try-decrypt=true`` without considering the security of
-        your index.
+        ``--try-decrypt=true`` or ``nostash`` without considering
+        the security of your index.
 
         See also ``index.try_decrypt`` in **notmuch-config(1)**.
 
diff --git a/doc/man1/notmuch-reindex.rst b/doc/man1/notmuch-reindex.rst
index 3b99b934..7883e0cb 100644
--- a/doc/man1/notmuch-reindex.rst
+++ b/doc/man1/notmuch-reindex.rst
@@ -21,23 +21,26 @@ messages using the supplied options.
 
 Supported options for **reindex** include
 
-    ``--try-decrypt=(true|auto|false)``
+    ``--try-decrypt=(true|nostash|auto|false)``
 
         If ``true``, when encountering an encrypted message, try to
-        decrypt it while reindexing, storing any session keys
+        decrypt it while reindexing, stashing any session keys
         discovered.  If ``auto``, and notmuch already knows about a
         session key for the message, it will try decrypting using that
         session key but will not try to access the user's secret keys.
         If decryption is successful, index the cleartext itself.
 
+        ``nostash`` is the same as ``true`` except that it will not
+        stash newly-discovered session keys in the database.
+
         If ``false``, notmuch reindex will also delete any stashed
         session keys for all messages matching the search terms.
 
         Be aware that the index is likely sufficient to reconstruct
         the cleartext of the message itself, so please ensure that the
         notmuch message index is adequately protected. DO NOT USE
-        ``--try-decrypt=true`` without considering the security of
-        your index.
+        ``--try-decrypt=true`` or ``nostash`` without considering
+        the security of your index.
 
         See also ``index.try_decrypt`` in **notmuch-config(1)**.
 
diff --git a/lib/indexopts.c b/lib/indexopts.c
index a61d6420..e698dcea 100644
--- a/lib/indexopts.c
+++ b/lib/indexopts.c
@@ -42,6 +42,8 @@ notmuch_database_get_default_indexopts (notmuch_database_t *db)
 		 (!(strcasecmp(try_decrypt, "no"))) ||
 		 (!(strcasecmp(try_decrypt, "0"))))
 	    notmuch_indexopts_set_try_decrypt (ret, NOTMUCH_DECRYPT_FALSE);
+	else if (!strcasecmp(try_decrypt, "nostash"))
+	    notmuch_indexopts_set_try_decrypt (ret, NOTMUCH_DECRYPT_NOSTASH);
     }
 
     free (try_decrypt);
diff --git a/lib/notmuch.h b/lib/notmuch.h
index 7b1c61ad..103a7091 100644
--- a/lib/notmuch.h
+++ b/lib/notmuch.h
@@ -2242,6 +2242,7 @@ typedef enum {
     NOTMUCH_DECRYPT_FALSE,
     NOTMUCH_DECRYPT_TRUE,
     NOTMUCH_DECRYPT_AUTO,
+    NOTMUCH_DECRYPT_NOSTASH,
 } notmuch_decryption_policy_t;
 
 /**
diff --git a/notmuch-reply.c b/notmuch-reply.c
index fd990a9a..5cdf642b 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -730,7 +730,7 @@ notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[])
 
     notmuch_process_shared_options (argv[0]);
     if (decrypt_set)
-	params.crypto.decrypt = decrypt ? NOTMUCH_DECRYPT_TRUE : NOTMUCH_DECRYPT_FALSE;
+	params.crypto.decrypt = decrypt ? NOTMUCH_DECRYPT_NOSTASH : NOTMUCH_DECRYPT_FALSE;
 
     notmuch_exit_if_unsupported_format ();
 
diff --git a/notmuch-show.c b/notmuch-show.c
index c8f5a48f..4e22424b 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -1121,7 +1121,8 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])
 
     if (decrypt_set) {
 	if (decrypt) {
-	    params.crypto.decrypt = NOTMUCH_DECRYPT_TRUE;
+	    /* we do not need or want to ask for session keys */
+	    params.crypto.decrypt = NOTMUCH_DECRYPT_NOSTASH;
 	    /* decryption implies verification */
 	    params.crypto.verify = true;
 	} else {
diff --git a/notmuch.c b/notmuch.c
index 62706748..2f43ad28 100644
--- a/notmuch.c
+++ b/notmuch.c
@@ -104,6 +104,7 @@ const notmuch_opt_desc_t  notmuch_shared_indexing_options [] = {
       (notmuch_keyword_t []){ { "false", NOTMUCH_DECRYPT_FALSE },
 			      { "true", NOTMUCH_DECRYPT_TRUE },
 			      { "auto", NOTMUCH_DECRYPT_AUTO },
+			      { "nostash", NOTMUCH_DECRYPT_NOSTASH },
 			      { 0, 0 } },
       .name = "try-decrypt" },
     { }
diff --git a/test/T357-index-decryption.sh b/test/T357-index-decryption.sh
index 3ac8c43e..8aef4354 100755
--- a/test/T357-index-decryption.sh
+++ b/test/T357-index-decryption.sh
@@ -182,6 +182,32 @@ test_expect_equal \
     "$output" \
     "$expected"
 
+test_begin_subtest "index cleartext without keeping session keys"
+test_expect_success "notmuch reindex --try-decrypt=nostash tag:blarney"
+
+test_begin_subtest "Ensure that the indexed terms are present"
+output=$(notmuch search wumpus)
+test_expect_equal \
+    "$output" \
+    "$expected"
+
+test_begin_subtest "show one of the messages with --decrypt"
+output=$(notmuch show --decrypt thread:0000000000000001 | awk '/^\014part}/{ f=0 }; { if (f) { print $0 } } /^\014part{ ID: 3/{ f=1 }')
+expected='This is a test encrypted message with a wumpus.'
+test_expect_equal \
+    "$output" \
+    "$expected"
+
+test_begin_subtest "Ensure that we cannot show the message without --decrypt"
+output=$(notmuch show thread:0000000000000001 | awk '/^\014part}/{ f=0 }; { if (f) { print $0 } } /^\014part{ ID: 3/{ f=1 }')
+expected='Non-text part: application/octet-stream'
+test_expect_equal \
+    "$output" \
+    "$expected"
+
+
+
+
 add_email_corpus crypto
 
 test_begin_subtest "indexing message fails when secret key not available"
diff --git a/util/crypto.c b/util/crypto.c
index ba9bfa7b..ac018005 100644
--- a/util/crypto.c
+++ b/util/crypto.c
@@ -190,7 +190,7 @@ _notmuch_crypto_decrypt (bool *attempted,
 #if (GMIME_MAJOR_VERSION < 3)
 #if (GMIME_MAJOR_VERSION == 2 && GMIME_MINOR_VERSION == 6 && GMIME_MICRO_VERSION >= 21)
     gboolean oldgetsk = g_mime_crypto_context_get_retrieve_session_key (crypto_ctx);
-    gboolean newgetsk = (decrypt_result);
+    gboolean newgetsk = (decrypt == NOTMUCH_DECRYPT_TRUE && decrypt_result);
     if (newgetsk != oldgetsk)
 	/* This could return an error, but we can't do anything about it, so ignore it */
 	g_mime_crypto_context_set_retrieve_session_key (crypto_ctx, newgetsk, NULL);
@@ -203,7 +203,7 @@ _notmuch_crypto_decrypt (bool *attempted,
 #endif
 #else
     GMimeDecryptFlags flags = GMIME_DECRYPT_NONE;
-    if (decrypt_result)
+    if (decrypt == NOTMUCH_DECRYPT_TRUE && decrypt_result)
 	flags |= GMIME_DECRYPT_EXPORT_SESSION_KEY;
     ret = g_mime_multipart_encrypted_decrypt(part, flags, NULL,
 					     decrypt_result, err);
-- 
2.14.2

  parent reply	other threads:[~2017-10-25  6:52 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-25  6:51 Stashed session keys Daniel Kahn Gillmor
2017-10-25  6:51 ` [PATCH 01/18] mime-node: handle decrypt_result more safely Daniel Kahn Gillmor
2017-10-25  6:51 ` [PATCH 02/18] crypto: add _notmuch_crypto_decrypt wrapper function Daniel Kahn Gillmor
2017-10-25  6:51 ` [PATCH 03/18] crypto: use stashed session-key properties for decryption, if available Daniel Kahn Gillmor
2017-10-26 19:00   ` Daniel Kahn Gillmor
2017-11-14 13:02   ` David Bremner
2017-11-14 13:54     ` Daniel Kahn Gillmor
2017-11-15 12:59       ` David Bremner
2017-10-25  6:51 ` [PATCH 04/18] test/corpora: add an encrypted message for index decryption tests Daniel Kahn Gillmor
2017-10-25  6:51 ` [PATCH 05/18] crypto: Test restore of cleartext index from stashed session keys Daniel Kahn Gillmor
2017-11-14 13:13   ` David Bremner
2017-11-14 13:58     ` Daniel Kahn Gillmor
2017-11-14 14:27       ` David Bremner
2017-10-25  6:51 ` [PATCH 06/18] lib: convert notmuch decryption policy to an enum Daniel Kahn Gillmor
2017-10-25  6:51 ` [PATCH 07/18] crypto: new decryption policy "auto" Daniel Kahn Gillmor
2017-11-11 23:14   ` Jameson Graef Rollins
2017-11-12  3:39     ` Daniel Kahn Gillmor
2017-11-12 15:26       ` Jameson Graef Rollins
2017-11-14 13:21   ` David Bremner
2017-10-25  6:51 ` [PATCH 08/18] cli/reply: use decryption policy "auto" by default Daniel Kahn Gillmor
2017-10-25  6:51 ` [PATCH 09/18] cli/show: " Daniel Kahn Gillmor
2017-10-25  6:51 ` [PATCH 10/18] cli/show, reply: document use of stashed session keys in notmuch-properties Daniel Kahn Gillmor
2017-10-25  6:51 ` [PATCH 11/18] cli/new, insert, reindex: update documentation for --try-decrypt=auto Daniel Kahn Gillmor
2017-11-15 20:02   ` David Bremner
2017-10-25  6:51 ` [PATCH 12/18] crypto: record whether an actual decryption attempt happened Daniel Kahn Gillmor
2017-10-25  6:51 ` [PATCH 13/18] cli/new, insert, reindex: change index.try_decrypt to "auto" by default Daniel Kahn Gillmor
2017-11-16 12:40   ` David Bremner
2017-11-30  6:16     ` Daniel Kahn Gillmor
2017-10-25  6:51 ` [PATCH 14/18] cli/reindex: destroy stashed session keys when --try-decrypt=false Daniel Kahn Gillmor
2017-10-25  6:52 ` [PATCH 15/18] crypto: actually stash session keys when try-decrypt=true Daniel Kahn Gillmor
2017-11-16 12:53   ` David Bremner
2017-11-30 15:57     ` Daniel Kahn Gillmor
2017-12-02  1:56       ` David Bremner
2017-10-25  6:52 ` Daniel Kahn Gillmor [this message]
2017-10-25 14:46   ` [PATCH 16/18] crypto: add --try-decrypt=nostash to avoid stashing session keys Daniel Kahn Gillmor
2017-11-16 13:02   ` David Bremner
2017-10-25  6:52 ` [PATCH 17/18] docs: clean up documentation about decryption policies Daniel Kahn Gillmor
2017-10-25  6:52 ` [PATCH 18/18] python: add try_decrypt argument to Database.index_file() Daniel Kahn Gillmor
2017-11-16 13:06   ` David Bremner
2017-11-30 15:58     ` Daniel Kahn Gillmor
2017-11-11  7:56 ` Stashed session keys Daniel Kahn Gillmor
2017-11-11 23:31 ` Jameson Graef Rollins
2017-11-12  3:51   ` Daniel Kahn Gillmor
2017-11-12 15:15     ` Jameson Graef Rollins
2017-11-12 18:51     ` Daniel Kahn Gillmor
2017-11-15 22:41 ` meskio
2017-11-16 16:03   ` Daniel Kahn Gillmor

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://notmuchmail.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171025065203.24403-17-dkg@fifthhorseman.net \
    --to=dkg@fifthhorseman.net \
    --cc=notmuch@notmuchmail.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).