2017-10-21 04:25:46 +02:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
|
|
|
# TODO: test index.decryption=failed
|
|
|
|
|
|
|
|
test_description='indexing decrypted mail'
|
|
|
|
. $(dirname "$0")/test-lib.sh || exit 1
|
2021-05-15 22:47:44 +02:00
|
|
|
. $(dirname "$0")/test-lib-emacs.sh || exit 1
|
2017-10-21 04:25:46 +02:00
|
|
|
|
|
|
|
##################################################
|
|
|
|
|
2021-05-01 13:54:16 +02:00
|
|
|
test_require_emacs
|
2017-10-21 04:25:46 +02:00
|
|
|
add_gnupg_home
|
|
|
|
|
|
|
|
# create a test encrypted message
|
|
|
|
test_begin_subtest 'emacs delivery of encrypted message'
|
|
|
|
test_expect_success \
|
|
|
|
'emacs_fcc_message \
|
|
|
|
"test encrypted message for cleartext index 001" \
|
|
|
|
"This is a test encrypted message with a wumpus.\n" \
|
|
|
|
"(mml-secure-message-encrypt)"'
|
|
|
|
|
|
|
|
test_begin_subtest "search for unindexed cleartext"
|
|
|
|
output=$(notmuch search wumpus)
|
|
|
|
expected=''
|
|
|
|
test_expect_equal \
|
|
|
|
"$output" \
|
|
|
|
"$expected"
|
|
|
|
|
|
|
|
# create a test encrypted message that is indexed in the clear
|
|
|
|
test_begin_subtest 'emacs delivery of encrypted message'
|
|
|
|
test_expect_success \
|
2017-12-08 07:23:50 +01:00
|
|
|
'emacs_fcc_message --decrypt=true \
|
2017-10-21 04:25:46 +02:00
|
|
|
"test encrypted message for cleartext index 002" \
|
|
|
|
"This is a test encrypted message with a wumpus.\n" \
|
|
|
|
"(mml-secure-message-encrypt)"'
|
|
|
|
|
|
|
|
test_begin_subtest "emacs delivery of encrypted message, indexed cleartext"
|
|
|
|
output=$(notmuch search wumpus)
|
|
|
|
expected='thread:0000000000000002 2000-01-01 [1/1] Notmuch Test Suite; test encrypted message for cleartext index 002 (encrypted inbox)'
|
|
|
|
test_expect_equal \
|
|
|
|
"$output" \
|
|
|
|
"$expected"
|
|
|
|
|
|
|
|
# and the same search, but by property ($expected is untouched):
|
|
|
|
test_begin_subtest "emacs search by property for one message"
|
|
|
|
output=$(notmuch search property:index.decryption=success)
|
|
|
|
test_expect_equal \
|
|
|
|
"$output" \
|
|
|
|
"$expected"
|
|
|
|
|
2017-12-08 07:24:01 +01:00
|
|
|
test_begin_subtest "show the message body of the encrypted message"
|
|
|
|
notmuch dump wumpus
|
2018-05-11 08:57:58 +02:00
|
|
|
output=$(notmuch show wumpus | notmuch_show_part 3)
|
2017-12-08 07:24:01 +01:00
|
|
|
expected='This is a test encrypted message with a wumpus.'
|
|
|
|
test_expect_equal \
|
|
|
|
"$output" \
|
|
|
|
"$expected"
|
|
|
|
|
2017-10-21 04:25:47 +02:00
|
|
|
|
|
|
|
test_begin_subtest "message should go away after deletion"
|
|
|
|
# cache the message in an env var and remove it:
|
|
|
|
fname=$(notmuch search --output=files wumpus)
|
|
|
|
contents="$(notmuch show --format=raw wumpus)"
|
|
|
|
rm -f "$fname"
|
|
|
|
notmuch new
|
|
|
|
output=$(notmuch search wumpus)
|
|
|
|
expected=''
|
|
|
|
test_expect_equal \
|
|
|
|
"$output" \
|
|
|
|
"$expected"
|
|
|
|
|
|
|
|
# try reinserting it without decryption, should stay the same:
|
|
|
|
test_begin_subtest "message cleartext not present after insert"
|
|
|
|
notmuch insert --folder=sent <<<"$contents"
|
|
|
|
output=$(notmuch search wumpus)
|
|
|
|
test_expect_equal \
|
|
|
|
"$output" \
|
|
|
|
"$expected"
|
|
|
|
|
cli/show: enable --decrypt=stash
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
2018-05-11 08:57:59 +02:00
|
|
|
# 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)'
|
|
|
|
test_expect_equal \
|
|
|
|
"$output" \
|
|
|
|
"$expected"
|
|
|
|
|
2017-10-21 04:25:47 +02:00
|
|
|
# try reinserting it with decryption, should appear again, but now we
|
|
|
|
# have two copies of the message:
|
2017-12-08 07:23:52 +01:00
|
|
|
test_begin_subtest "message cleartext is present after reinserting with --decrypt=true"
|
|
|
|
notmuch insert --folder=sent --decrypt=true <<<"$contents"
|
2017-10-21 04:25:47 +02:00
|
|
|
output=$(notmuch search wumpus)
|
|
|
|
expected='thread:0000000000000003 2000-01-01 [1/1(2)] Notmuch Test Suite; test encrypted message for cleartext index 002 (encrypted inbox unread)'
|
|
|
|
test_expect_equal \
|
|
|
|
"$output" \
|
|
|
|
"$expected"
|
|
|
|
|
|
|
|
# remove all copies
|
|
|
|
test_begin_subtest "delete all copies of the message"
|
|
|
|
mid="$(notmuch search --output=messages wumpus)"
|
|
|
|
rm -f $(notmuch search --output=files wumpus)
|
|
|
|
notmuch new
|
|
|
|
output=$(notmuch search "id:$mid")
|
|
|
|
expected=''
|
|
|
|
test_expect_equal \
|
|
|
|
"$output" \
|
|
|
|
"$expected"
|
|
|
|
|
|
|
|
# try inserting it with decryption, should appear as a single copy
|
|
|
|
# (note: i think thread id skips 4 because of duplicate message-id
|
|
|
|
# insertion, above)
|
2017-12-08 07:23:52 +01:00
|
|
|
test_begin_subtest "message cleartext is present with insert --decrypt=true"
|
|
|
|
notmuch insert --folder=sent --decrypt=true <<<"$contents"
|
2017-10-21 04:25:47 +02:00
|
|
|
output=$(notmuch search wumpus)
|
|
|
|
expected='thread:0000000000000005 2000-01-01 [1/1] Notmuch Test Suite; test encrypted message for cleartext index 002 (encrypted inbox unread)'
|
|
|
|
test_expect_equal \
|
|
|
|
"$output" \
|
|
|
|
"$expected"
|
|
|
|
|
|
|
|
|
2017-10-21 04:25:48 +02:00
|
|
|
# add a tag to all messages to ensure that it stays after reindexing
|
|
|
|
test_begin_subtest 'tagging all messages'
|
|
|
|
test_expect_success 'notmuch tag +blarney "encrypted message"'
|
|
|
|
test_begin_subtest "verify that tags have not changed"
|
|
|
|
output=$(notmuch search tag:blarney)
|
|
|
|
expected='thread:0000000000000001 2000-01-01 [1/1] Notmuch Test Suite; test encrypted message for cleartext index 001 (blarney encrypted inbox)
|
|
|
|
thread:0000000000000005 2000-01-01 [1/1] Notmuch Test Suite; test encrypted message for cleartext index 002 (blarney encrypted inbox unread)'
|
|
|
|
test_expect_equal \
|
|
|
|
"$output" \
|
|
|
|
"$expected"
|
|
|
|
|
2017-12-08 07:23:50 +01:00
|
|
|
# see if first message shows up after reindexing with --decrypt=true (same $expected, untouched):
|
2017-10-21 04:25:48 +02:00
|
|
|
test_begin_subtest 'reindex old messages'
|
2017-12-08 07:23:50 +01:00
|
|
|
test_expect_success 'notmuch reindex --decrypt=true tag:encrypted and not property:index.decryption=success'
|
2017-10-21 04:25:48 +02:00
|
|
|
test_begin_subtest "reindexed encrypted message, including cleartext"
|
|
|
|
output=$(notmuch search wumpus)
|
|
|
|
test_expect_equal \
|
|
|
|
"$output" \
|
|
|
|
"$expected"
|
|
|
|
|
|
|
|
# and the same search, but by property ($expected is untouched):
|
|
|
|
test_begin_subtest "emacs search by property for both messages"
|
|
|
|
output=$(notmuch search property:index.decryption=success)
|
|
|
|
test_expect_equal \
|
|
|
|
"$output" \
|
|
|
|
"$expected"
|
|
|
|
|
2017-12-08 07:24:01 +01:00
|
|
|
# try a simple reindex
|
|
|
|
test_begin_subtest 'reindex in auto mode'
|
|
|
|
test_expect_success 'notmuch reindex tag:encrypted and property:index.decryption=success'
|
|
|
|
test_begin_subtest "reindexed encrypted messages, should not have changed"
|
|
|
|
output=$(notmuch search wumpus)
|
|
|
|
test_expect_equal \
|
|
|
|
"$output" \
|
|
|
|
"$expected"
|
2017-10-21 04:25:48 +02:00
|
|
|
|
|
|
|
# try to remove cleartext indexing
|
|
|
|
test_begin_subtest 'reindex without cleartext'
|
2017-12-08 07:24:01 +01:00
|
|
|
test_expect_success 'notmuch reindex --decrypt=false tag:encrypted and property:index.decryption=success'
|
2017-10-21 04:25:48 +02:00
|
|
|
test_begin_subtest "reindexed encrypted messages, without cleartext"
|
|
|
|
output=$(notmuch search wumpus)
|
|
|
|
expected=''
|
|
|
|
test_expect_equal \
|
|
|
|
"$output" \
|
|
|
|
"$expected"
|
|
|
|
|
2017-12-08 07:23:53 +01:00
|
|
|
# ensure no session keys are present:
|
|
|
|
test_begin_subtest 'reindex using only session keys'
|
2017-12-08 07:23:59 +01:00
|
|
|
test_expect_success 'notmuch reindex tag:encrypted and property:index.decryption=success'
|
2017-12-08 07:23:53 +01:00
|
|
|
test_begin_subtest "reindexed encrypted messages, decrypting only with session keys"
|
|
|
|
output=$(notmuch search wumpus)
|
|
|
|
expected=''
|
|
|
|
test_expect_equal \
|
|
|
|
"$output" \
|
|
|
|
"$expected"
|
|
|
|
|
2017-10-21 04:25:48 +02:00
|
|
|
# and the same search, but by property ($expected is untouched):
|
|
|
|
test_begin_subtest "emacs search by property with both messages unindexed"
|
|
|
|
output=$(notmuch search property:index.decryption=success)
|
|
|
|
test_expect_equal \
|
|
|
|
"$output" \
|
|
|
|
"$expected"
|
|
|
|
|
|
|
|
# ensure that the tags remain even when we are dropping the cleartext.
|
|
|
|
test_begin_subtest "verify that tags remain without cleartext"
|
|
|
|
output=$(notmuch search tag:blarney)
|
|
|
|
expected='thread:0000000000000001 2000-01-01 [1/1] Notmuch Test Suite; test encrypted message for cleartext index 001 (blarney encrypted inbox)
|
|
|
|
thread:0000000000000005 2000-01-01 [1/1] Notmuch Test Suite; test encrypted message for cleartext index 002 (blarney encrypted inbox unread)'
|
|
|
|
test_expect_equal \
|
|
|
|
"$output" \
|
|
|
|
"$expected"
|
|
|
|
|
2017-12-08 07:24:02 +01:00
|
|
|
test_begin_subtest "index cleartext without keeping session keys"
|
|
|
|
test_expect_success "notmuch reindex --decrypt=nostash tag:blarney"
|
|
|
|
|
|
|
|
test_begin_subtest "Ensure that the indexed terms are present"
|
|
|
|
output=$(notmuch search wumpus)
|
|
|
|
test_expect_equal \
|
|
|
|
"$output" \
|
|
|
|
"$expected"
|
|
|
|
|
2017-12-19 17:40:54 +01:00
|
|
|
test_begin_subtest "show one of the messages with --decrypt=true"
|
2018-05-11 08:57:58 +02:00
|
|
|
output=$(notmuch show --decrypt=true thread:0000000000000001 | notmuch_show_part 3)
|
2017-12-08 07:24:02 +01:00
|
|
|
expected='This is a test encrypted message with a wumpus.'
|
|
|
|
test_expect_equal \
|
|
|
|
"$output" \
|
|
|
|
"$expected"
|
|
|
|
|
2017-12-19 17:40:54 +01:00
|
|
|
test_begin_subtest "Ensure that we cannot show the message with --decrypt=auto"
|
2018-05-11 08:57:58 +02:00
|
|
|
output=$(notmuch show thread:0000000000000001 | notmuch_show_part 3)
|
2017-12-08 07:24:02 +01:00
|
|
|
expected='Non-text part: application/octet-stream'
|
|
|
|
test_expect_equal \
|
|
|
|
"$output" \
|
|
|
|
"$expected"
|
|
|
|
|
2017-11-30 09:59:31 +01:00
|
|
|
add_email_corpus crypto
|
|
|
|
|
|
|
|
test_begin_subtest "indexing message fails when secret key not available"
|
2017-12-08 07:23:52 +01:00
|
|
|
notmuch reindex --decrypt=true id:simple-encrypted@crypto.notmuchmail.org
|
2019-05-06 19:43:27 +02:00
|
|
|
output=$(notmuch dump | LC_ALL=C sort)
|
|
|
|
expected='#= simple-encrypted@crypto.notmuchmail.org index.decryption=failure
|
|
|
|
#notmuch-dump batch-tag:3 config,properties,tags
|
|
|
|
+encrypted +inbox +unread -- id:basic-encrypted@crypto.notmuchmail.org
|
2019-05-30 02:09:44 +02:00
|
|
|
+encrypted +inbox +unread -- id:encrypted-signed@crypto.notmuchmail.org
|
2019-05-06 19:43:27 +02:00
|
|
|
+encrypted +inbox +unread -- id:simple-encrypted@crypto.notmuchmail.org'
|
2017-11-30 09:59:31 +01:00
|
|
|
test_expect_equal \
|
|
|
|
"$output" \
|
|
|
|
"$expected"
|
|
|
|
|
|
|
|
test_begin_subtest "cannot find cleartext index"
|
|
|
|
output=$(notmuch search sekrit)
|
|
|
|
expected=''
|
|
|
|
test_expect_equal \
|
|
|
|
"$output" \
|
|
|
|
"$expected"
|
|
|
|
|
|
|
|
test_begin_subtest "cleartext index recovery on reindexing with stashed session keys"
|
|
|
|
notmuch restore <<EOF
|
|
|
|
#notmuch-dump batch-tag:3 config,properties,tags
|
|
|
|
#= simple-encrypted@crypto.notmuchmail.org session-key=9%3AFC09987F5F927CC0CC0EE80A96E4C5BBF4A499818FB591207705DFDDD6112CF9
|
|
|
|
EOF
|
2017-12-08 07:23:59 +01:00
|
|
|
notmuch reindex id:simple-encrypted@crypto.notmuchmail.org
|
2019-05-06 19:43:27 +02:00
|
|
|
output=$(notmuch search sekrit | notmuch_search_sanitize)
|
|
|
|
expected='thread:XXX 2016-12-22 [1/1] Daniel Kahn Gillmor; encrypted message (encrypted inbox unread)'
|
2017-11-30 09:59:31 +01:00
|
|
|
test_expect_equal \
|
|
|
|
"$output" \
|
|
|
|
"$expected"
|
|
|
|
|
2017-12-08 07:23:54 +01:00
|
|
|
test_begin_subtest "notmuch reply should show cleartext if session key is present"
|
|
|
|
output=$(notmuch reply id:simple-encrypted@crypto.notmuchmail.org | grep '^>')
|
|
|
|
expected='> This is a top sekrit message.'
|
|
|
|
test_expect_equal \
|
|
|
|
"$output" \
|
|
|
|
"$expected"
|
|
|
|
|
2017-12-08 07:23:55 +01:00
|
|
|
test_begin_subtest "notmuch show should show cleartext if session key is present"
|
2018-05-11 08:57:58 +02:00
|
|
|
output=$(notmuch show id:simple-encrypted@crypto.notmuchmail.org | notmuch_show_part 3)
|
2017-12-08 07:23:55 +01:00
|
|
|
expected='This is a top sekrit message.'
|
|
|
|
test_expect_equal \
|
|
|
|
"$output" \
|
|
|
|
"$expected"
|
|
|
|
|
|
|
|
test_begin_subtest "notmuch show should show nothing if decryption is explicitly disallowed"
|
2018-05-11 08:57:58 +02:00
|
|
|
output=$(notmuch show --decrypt=false id:simple-encrypted@crypto.notmuchmail.org | notmuch_show_part 3)
|
2017-12-08 07:23:55 +01:00
|
|
|
expected='Non-text part: application/octet-stream'
|
|
|
|
test_expect_equal \
|
|
|
|
"$output" \
|
|
|
|
"$expected"
|
|
|
|
|
2017-12-08 07:24:00 +01:00
|
|
|
test_begin_subtest "purging stashed session keys should lose access to the cleartext"
|
|
|
|
notmuch reindex --decrypt=false id:simple-encrypted@crypto.notmuchmail.org
|
|
|
|
output=$(notmuch search sekrit)
|
|
|
|
expected=''
|
|
|
|
test_expect_equal \
|
|
|
|
"$output" \
|
|
|
|
"$expected"
|
|
|
|
|
|
|
|
test_begin_subtest "and cleartext should be unrecoverable now that there are no stashed session keys"
|
|
|
|
notmuch dump
|
|
|
|
notmuch reindex --decrypt=true id:simple-encrypted@crypto.notmuchmail.org
|
|
|
|
output=$(notmuch search sekrit)
|
|
|
|
expected=''
|
|
|
|
test_expect_equal \
|
|
|
|
"$output" \
|
|
|
|
"$expected"
|
|
|
|
|
2019-05-30 02:09:44 +02:00
|
|
|
goodsig='good_sig:[0][0][0]["crypto"]["signed"]["status"][0]["status"]="good"'
|
|
|
|
nosig='no_sig:[0][0][0]["crypto"]!"signed"'
|
|
|
|
|
|
|
|
test_begin_subtest "verify signature without a session key stashed when --decrypt=true"
|
|
|
|
output=$(notmuch show --format=json --decrypt=true id:encrypted-signed@crypto.notmuchmail.org)
|
|
|
|
test_json_nodes <<<"$output" "$goodsig"
|
|
|
|
|
|
|
|
test_begin_subtest "do not verify sig without a session key stashed if --decrypt=auto"
|
|
|
|
output=$(notmuch show --format=json id:encrypted-signed@crypto.notmuchmail.org)
|
|
|
|
test_json_nodes <<<"$output" "$nosig"
|
|
|
|
|
|
|
|
test_begin_subtest "verify signature when --decrypt=stash"
|
|
|
|
output=$(notmuch show --format=json --decrypt=stash id:encrypted-signed@crypto.notmuchmail.org)
|
|
|
|
test_json_nodes <<<"$output" "$goodsig"
|
|
|
|
|
|
|
|
test_begin_subtest "verify signature with stashed session key"
|
|
|
|
output=$(notmuch show --format=json id:encrypted-signed@crypto.notmuchmail.org)
|
2020-07-02 20:00:49 +02:00
|
|
|
if [ $NOTMUCH_GMIME_VERIFY_WITH_SESSION_KEY -ne 1 ]; then
|
|
|
|
test_subtest_known_broken
|
|
|
|
fi
|
2019-05-30 02:09:44 +02:00
|
|
|
test_json_nodes <<<"$output" "$goodsig"
|
2017-10-21 04:25:48 +02:00
|
|
|
|
|
|
|
# TODO: test removal of a message from the message store between
|
|
|
|
# indexing and reindexing.
|
2017-10-21 04:25:47 +02:00
|
|
|
|
2017-10-21 04:25:48 +02:00
|
|
|
# TODO: insert the same message into the message store twice, index,
|
|
|
|
# remove one of them from the message store, and then reindex.
|
|
|
|
# reindexing should return a failure but the message should still be
|
|
|
|
# present? -- or what should the semantics be if you ask to reindex a
|
|
|
|
# message whose underlying files have been renamed or moved or
|
|
|
|
# removed?
|
2017-10-21 04:25:47 +02:00
|
|
|
|
2017-10-21 04:25:46 +02:00
|
|
|
test_done
|