From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by arlo.cworth.org (Postfix) with ESMTP id 041C66DE0B64 for ; Thu, 10 May 2018 23:58:14 -0700 (PDT) X-Virus-Scanned: Debian amavisd-new at cworth.org X-Spam-Flag: NO X-Spam-Score: -0.018 X-Spam-Level: X-Spam-Status: No, score=-0.018 tagged_above=-999 required=5 tests=[AWL=-0.018, RCVD_IN_DNSWL_NONE=-0.0001] 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 GEmH_mcP8i2L for ; Thu, 10 May 2018 23:58:13 -0700 (PDT) Received: from che.mayfirst.org (che.mayfirst.org [162.247.75.118]) by arlo.cworth.org (Postfix) with ESMTPS id 464216DE0262 for ; Thu, 10 May 2018 23:58:10 -0700 (PDT) Received: from fifthhorseman.net (unknown [38.109.115.130]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by che.mayfirst.org (Postfix) with ESMTPSA id 59541F99B for ; Fri, 11 May 2018 02:58:08 -0400 (EDT) Received: by fifthhorseman.net (Postfix, from userid 1000) id 7FB70211DF; Fri, 11 May 2018 02:58:03 -0400 (EDT) From: Daniel Kahn Gillmor To: Notmuch Mail Subject: [PATCH v3 8/8] cli/show: enable --decrypt=stash Date: Fri, 11 May 2018 02:57:59 -0400 Message-Id: <20180511065759.8556-9-dkg@fifthhorseman.net> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180511065759.8556-1-dkg@fifthhorseman.net> References: <20180511065759.8556-1-dkg@fifthhorseman.net> X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.26 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: Fri, 11 May 2018 06:58:14 -0000 Add fancy new feature, which makes "notmuch show" capable of actually indexing messages that it just decrypted. This enables a workflow where messages can come in in the background and be indexed using "--decrypt=auto". But when showing an encrypted message for the first time, it gets automatically indexed. This is something of a departure for "notmuch show" -- in particular, because it requires read/write access to the database. However, this might be a common use case -- people get mail delivered and indexed in the background, but only want access to their secret key to happen when they're directly interacting with notmuch itself. In such a scenario, they couldn't search newly-delivered, encrypted messages, but they could search for them once they've read them. Documentation of this new feature also uses a table form, similar to that found in the description of index.decrypt in notmuch-config(1). A notmuch UI that wants to facilitate this workflow while also offering an interactive search interface might instead make use of these additional commands while the user is at the console: Count received encrypted messages (if > 0, there are some things we haven't yet tried to index, and therefore can't yet search): notmuch count tag:encrypted and \ not property:index.decryption=success and \ not property:index.decryption=failure Reindex those messages: notmuch reindex --try-decrypt=true tag:encrypted and \ not property:index.decryption=success and \ not property:index.decryption=failure --- completion/notmuch-completion.bash | 2 +- doc/man1/notmuch-show.rst | 40 +++++++++++++++++++++++++----- notmuch-show.c | 9 +++++-- test/T357-index-decryption.sh | 18 ++++++++++++++ 4 files changed, 60 insertions(+), 9 deletions(-) diff --git a/completion/notmuch-completion.bash b/completion/notmuch-completion.bash index 249b9664..15425697 100644 --- a/completion/notmuch-completion.bash +++ b/completion/notmuch-completion.bash @@ -522,7 +522,7 @@ _notmuch_show() return ;; --decrypt) - COMPREPLY=( $( compgen -W "true auto false" -- "${cur}" ) ) + COMPREPLY=( $( compgen -W "true auto false stash" -- "${cur}" ) ) return ;; esac diff --git a/doc/man1/notmuch-show.rst b/doc/man1/notmuch-show.rst index 2b825ccc..b2667537 100644 --- a/doc/man1/notmuch-show.rst +++ b/doc/man1/notmuch-show.rst @@ -110,7 +110,7 @@ Supported options for **show** include supported with --format=json and --format=sexp), and the multipart/signed part will be replaced by the signed data. -``--decrypt=(false|auto|true)`` +``--decrypt=(false|auto|true|stash)`` If ``true``, decrypt any MIME encrypted parts found in the selected content (i.e. "multipart/encrypted" parts). Status of the decryption will be reported (currently only supported @@ -118,17 +118,45 @@ Supported options for **show** include decryption the multipart/encrypted part will be replaced by the decrypted content. + ``stash`` behaves like ``true``, but upon successful decryption it + will also stash the message's session key in the database, and + index the cleartext of the message, enabling automatic decryption + in the future. + If ``auto``, and a session key is already known for the message, then it will be decrypted, but notmuch will not try to access the user's keys. Use ``false`` to avoid even automatic decryption. - Non-automatic decryption expects a functioning - **gpg-agent(1)** to provide any needed credentials. Without - one, the decryption will fail. - - Note: ``true`` implies --verify. + Non-automatic decryption (``stash`` or ``true``, in the absence of + a stashed session key) expects a functioning **gpg-agent(1)** to + provide any needed credentials. Without one, the decryption will + fail. + + Note: setting either ``true`` or ``stash`` here implies + ``--verify``. + + Here is a table that summarizes each of these policies: + + +------------------------+-------+------+------+-------+ + | | false | auto | true | stash | + +========================+=======+======+======+=======+ + | Show cleartext if | | X | X | X | + | session key is | | | | | + | already known | | | | | + +------------------------+-------+------+------+-------+ + | Use secret keys to | | | X | X | + | show cleartext | | | | | + +------------------------+-------+------+------+-------+ + | Stash any newly | | | | X | + | recovered session keys,| | | | | + | reindexing message if | | | | | + | found | | | | | + +------------------------+-------+------+------+-------+ + + Note: ``--decrypt=stash`` requires write access to the database. + Otherwise, ``notmuch show`` operates entirely in read-only mode. Default: ``auto`` diff --git a/notmuch-show.c b/notmuch-show.c index f34cf941..be3e4b50 100644 --- a/notmuch-show.c +++ b/notmuch-show.c @@ -1123,6 +1123,7 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[]) (notmuch_keyword_t []){ { "false", NOTMUCH_DECRYPT_FALSE }, { "auto", NOTMUCH_DECRYPT_AUTO }, { "true", NOTMUCH_DECRYPT_NOSTASH }, + { "stash", NOTMUCH_DECRYPT_TRUE }, { 0, 0 } } }, { .opt_bool = ¶ms.crypto.verify, .name = "verify" }, { .opt_bool = ¶ms.output_body, .name = "body" }, @@ -1138,7 +1139,8 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[]) notmuch_process_shared_options (argv[0]); /* explicit decryption implies verification */ - if (params.crypto.decrypt == NOTMUCH_DECRYPT_NOSTASH) + if (params.crypto.decrypt == NOTMUCH_DECRYPT_NOSTASH || + params.crypto.decrypt == NOTMUCH_DECRYPT_TRUE) params.crypto.verify = true; /* specifying a part implies single message display */ @@ -1201,8 +1203,11 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[]) params.crypto.gpgpath = notmuch_config_get_crypto_gpg_path (config); #endif + notmuch_database_mode_t mode = NOTMUCH_DATABASE_MODE_READ_ONLY; + if (params.crypto.decrypt == NOTMUCH_DECRYPT_TRUE) + mode = NOTMUCH_DATABASE_MODE_READ_WRITE; if (notmuch_database_open (notmuch_config_get_database_path (config), - NOTMUCH_DATABASE_MODE_READ_ONLY, ¬much)) + mode, ¬much)) return EXIT_FAILURE; notmuch_exit_if_unmatched_db_uuid (notmuch); diff --git a/test/T357-index-decryption.sh b/test/T357-index-decryption.sh index ad6c3616..c5435f4f 100755 --- a/test/T357-index-decryption.sh +++ b/test/T357-index-decryption.sh @@ -80,6 +80,24 @@ test_expect_equal \ "$output" \ "$expected" +# show the message using stashing decryption +test_begin_subtest "stash decryption during show" +output=$(notmuch show --decrypt=stash tag:encrypted subject:002 | notmuch_show_part 3) +expected='This is a test encrypted message with a wumpus.' +test_expect_equal \ + "$output" \ + "$expected" + +test_begin_subtest "search should now find the contents" +output=$(notmuch search wumpus) +expected='thread:0000000000000003 2000-01-01 [1/1] Notmuch Test Suite; test encrypted message for cleartext index 002 (encrypted inbox unread)' +if [ $NOTMUCH_HAVE_GMIME_SESSION_KEYS -eq 0 ]; then + test_subtest_known_broken +fi +test_expect_equal \ + "$output" \ + "$expected" + # try reinserting it with decryption, should appear again, but now we # have two copies of the message: test_begin_subtest "message cleartext is present after reinserting with --decrypt=true" -- 2.17.0