]> git.notmuchmail.org Git - notmuch/blob - test/T357-index-decryption.sh
lib/n_d_index_file: re-use thread-id of existing message
[notmuch] / test / T357-index-decryption.sh
1 #!/usr/bin/env bash
2
3 # TODO: test index.decryption=failed
4
5 test_description='indexing decrypted mail'
6 . $(dirname "$0")/test-lib.sh || exit 1
7
8 ##################################################
9
10 add_gnupg_home
11
12 # create a test encrypted message
13 test_begin_subtest 'emacs delivery of encrypted message'
14 test_expect_success \
15 'emacs_fcc_message \
16     "test encrypted message for cleartext index 001" \
17     "This is a test encrypted message with a wumpus.\n" \
18     "(mml-secure-message-encrypt)"'
19
20 test_begin_subtest "search for unindexed cleartext"
21 output=$(notmuch search wumpus)
22 expected=''
23 test_expect_equal \
24     "$output" \
25     "$expected"
26
27 # create a test encrypted message that is indexed in the clear
28 test_begin_subtest 'emacs delivery of encrypted message'
29 test_expect_success \
30 'emacs_fcc_message --decrypt=true \
31     "test encrypted message for cleartext index 002" \
32     "This is a test encrypted message with a wumpus.\n" \
33     "(mml-secure-message-encrypt)"'
34
35 test_begin_subtest "emacs delivery of encrypted message, indexed cleartext"
36 output=$(notmuch search wumpus)
37 expected='thread:0000000000000002   2000-01-01 [1/1] Notmuch Test Suite; test encrypted message for cleartext index 002 (encrypted inbox)'
38 test_expect_equal \
39     "$output" \
40     "$expected"
41
42 # and the same search, but by property ($expected is untouched):
43 test_begin_subtest "emacs search by property for one message"
44 output=$(notmuch search property:index.decryption=success)
45 test_expect_equal \
46     "$output" \
47     "$expected"
48
49 test_begin_subtest "show the message body of the encrypted message"
50 notmuch dump wumpus
51 output=$(notmuch show wumpus | notmuch_show_part 3)
52 expected='This is a test encrypted message with a wumpus.'
53 test_expect_equal \
54     "$output" \
55     "$expected"
56
57
58 test_begin_subtest "message should go away after deletion"
59 # cache the message in an env var and remove it:
60 fname=$(notmuch search --output=files wumpus)
61 contents="$(notmuch show --format=raw wumpus)"
62 rm -f "$fname"
63 notmuch new
64 output=$(notmuch search wumpus)
65 expected=''
66 test_expect_equal \
67     "$output" \
68     "$expected"
69
70 # try reinserting it without decryption, should stay the same:
71 test_begin_subtest "message cleartext not present after insert"
72 notmuch insert --folder=sent <<<"$contents"
73 output=$(notmuch search wumpus)
74 test_expect_equal \
75     "$output" \
76     "$expected"
77
78 # show the message using stashing decryption
79 test_begin_subtest "stash decryption during show"
80 output=$(notmuch show --decrypt=stash tag:encrypted subject:002 | notmuch_show_part 3)
81 expected='This is a test encrypted message with a wumpus.'
82 test_expect_equal \
83     "$output" \
84     "$expected"
85
86 test_begin_subtest "search should now find the contents"
87 output=$(notmuch search wumpus)
88 expected='thread:0000000000000003   2000-01-01 [1/1] Notmuch Test Suite; test encrypted message for cleartext index 002 (encrypted inbox unread)'
89 test_expect_equal \
90     "$output" \
91     "$expected"
92
93 # try reinserting it with decryption, should appear again, but now we
94 # have two copies of the message:
95 test_begin_subtest "message cleartext is present after reinserting with --decrypt=true"
96 notmuch insert --folder=sent --decrypt=true <<<"$contents"
97 output=$(notmuch search wumpus)
98 expected='thread:0000000000000003   2000-01-01 [1/1(2)] Notmuch Test Suite; test encrypted message for cleartext index 002 (encrypted inbox unread)'
99 test_expect_equal \
100     "$output" \
101     "$expected"
102
103 # remove all copies
104 test_begin_subtest "delete all copies of the message"
105 mid="$(notmuch search --output=messages wumpus)"
106 rm -f $(notmuch search --output=files wumpus)
107 notmuch new
108 output=$(notmuch search "id:$mid")
109 expected=''
110 test_expect_equal \
111     "$output" \
112     "$expected"
113
114 # try inserting it with decryption, should appear as a single copy
115 test_begin_subtest "message cleartext is present with insert --decrypt=true"
116 notmuch insert --folder=sent --decrypt=true <<<"$contents"
117 output=$(notmuch search wumpus | notmuch_search_sanitize)
118 expected='thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; test encrypted message for cleartext index 002 (encrypted inbox unread)'
119 test_expect_equal \
120     "$output" \
121     "$expected"
122
123
124 # add a tag to all messages to ensure that it stays after reindexing
125 test_begin_subtest 'tagging all messages'
126 test_expect_success 'notmuch tag +blarney "encrypted message"'
127 test_begin_subtest "verify that tags have not changed"
128 output=$(notmuch search tag:blarney | notmuch_search_sanitize)
129 expected='thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; test encrypted message for cleartext index 001 (blarney encrypted inbox)
130 thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; test encrypted message for cleartext index 002 (blarney encrypted inbox unread)'
131 test_expect_equal \
132     "$output" \
133     "$expected"
134
135 # see if first message shows up after reindexing with --decrypt=true (same $expected, untouched):
136 test_begin_subtest 'reindex old messages'
137 test_expect_success 'notmuch reindex --decrypt=true tag:encrypted and not property:index.decryption=success'
138 test_begin_subtest "reindexed encrypted message, including cleartext"
139 output=$(notmuch search wumpus | notmuch_search_sanitize)
140 test_expect_equal \
141     "$output" \
142     "$expected"
143
144 # and the same search, but by property ($expected is untouched):
145 test_begin_subtest "emacs search by property for both messages"
146 output=$(notmuch search property:index.decryption=success | notmuch_search_sanitize)
147 test_expect_equal \
148     "$output" \
149     "$expected"
150
151 # try a simple reindex
152 test_begin_subtest 'reindex in auto mode'
153 test_expect_success 'notmuch reindex tag:encrypted and property:index.decryption=success'
154 test_begin_subtest "reindexed encrypted messages, should not have changed"
155 output=$(notmuch search wumpus | notmuch_search_sanitize)
156 test_expect_equal \
157     "$output" \
158     "$expected"
159
160 # try to remove cleartext indexing
161 test_begin_subtest 'reindex without cleartext'
162 test_expect_success 'notmuch reindex --decrypt=false tag:encrypted and property:index.decryption=success'
163 test_begin_subtest "reindexed encrypted messages, without cleartext"
164 output=$(notmuch search wumpus)
165 expected=''
166 test_expect_equal \
167     "$output" \
168     "$expected"
169
170 # ensure no session keys are present:
171 test_begin_subtest 'reindex using only session keys'
172 test_expect_success 'notmuch reindex tag:encrypted and property:index.decryption=success'
173 test_begin_subtest "reindexed encrypted messages, decrypting only with session keys"
174 output=$(notmuch search wumpus)
175 expected=''
176 test_expect_equal \
177     "$output" \
178     "$expected"
179
180 # and the same search, but by property ($expected is untouched):
181 test_begin_subtest "emacs search by property with both messages unindexed"
182 output=$(notmuch search property:index.decryption=success)
183 test_expect_equal \
184     "$output" \
185     "$expected"
186
187 # ensure that the tags remain even when we are dropping the cleartext.
188 test_begin_subtest "verify that tags remain without cleartext"
189 output=$(notmuch search tag:blarney | notmuch_search_sanitize)
190 expected='thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; test encrypted message for cleartext index 001 (blarney encrypted inbox)
191 thread:XXX   2000-01-01 [1/1] Notmuch Test Suite; test encrypted message for cleartext index 002 (blarney encrypted inbox unread)'
192 test_expect_equal \
193     "$output" \
194     "$expected"
195
196 test_begin_subtest "index cleartext without keeping session keys"
197 test_expect_success "notmuch reindex --decrypt=nostash tag:blarney"
198
199 test_begin_subtest "Ensure that the indexed terms are present"
200 output=$(notmuch search wumpus | notmuch_search_sanitize)
201 test_expect_equal \
202     "$output" \
203     "$expected"
204
205 test_begin_subtest "show one of the messages with --decrypt=true"
206 output=$(notmuch show --decrypt=true thread:0000000000000001 | notmuch_show_part 3)
207 expected='This is a test encrypted message with a wumpus.'
208 test_expect_equal \
209     "$output" \
210     "$expected"
211
212 test_begin_subtest "Ensure that we cannot show the message with --decrypt=auto"
213 output=$(notmuch show thread:0000000000000001 | notmuch_show_part 3)
214 expected='Non-text part: application/octet-stream'
215 test_expect_equal \
216     "$output" \
217     "$expected"
218
219 add_email_corpus crypto
220
221 test_begin_subtest "indexing message fails when secret key not available"
222 notmuch reindex --decrypt=true id:simple-encrypted@crypto.notmuchmail.org
223 output=$(notmuch dump | LC_ALL=C sort)
224 expected='#= simple-encrypted@crypto.notmuchmail.org index.decryption=failure
225 #notmuch-dump batch-tag:3 config,properties,tags
226 +encrypted +inbox +unread -- id:basic-encrypted@crypto.notmuchmail.org
227 +encrypted +inbox +unread -- id:encrypted-signed@crypto.notmuchmail.org
228 +encrypted +inbox +unread -- id:simple-encrypted@crypto.notmuchmail.org'
229 test_expect_equal \
230     "$output" \
231     "$expected"
232
233 test_begin_subtest "cannot find cleartext index"
234 output=$(notmuch search sekrit)
235 expected=''
236 test_expect_equal \
237     "$output" \
238     "$expected"
239
240 test_begin_subtest "cleartext index recovery on reindexing with stashed session keys"
241 notmuch restore <<EOF
242 #notmuch-dump batch-tag:3 config,properties,tags
243 #= simple-encrypted@crypto.notmuchmail.org session-key=9%3AFC09987F5F927CC0CC0EE80A96E4C5BBF4A499818FB591207705DFDDD6112CF9
244 EOF
245 notmuch reindex id:simple-encrypted@crypto.notmuchmail.org
246 output=$(notmuch search sekrit | notmuch_search_sanitize)
247 expected='thread:XXX   2016-12-22 [1/1] Daniel Kahn Gillmor; encrypted message (encrypted inbox unread)'
248 test_expect_equal \
249     "$output" \
250     "$expected"
251
252 test_begin_subtest "notmuch reply should show cleartext if session key is present"
253 output=$(notmuch reply id:simple-encrypted@crypto.notmuchmail.org | grep '^>')
254 expected='> This is a top sekrit message.'
255 test_expect_equal \
256     "$output" \
257     "$expected"
258
259 test_begin_subtest "notmuch show should show cleartext if session key is present"
260 output=$(notmuch show id:simple-encrypted@crypto.notmuchmail.org | notmuch_show_part 3)
261 expected='This is a top sekrit message.'
262 test_expect_equal \
263     "$output" \
264     "$expected"
265
266 test_begin_subtest "notmuch show should show nothing if decryption is explicitly disallowed"
267 output=$(notmuch show --decrypt=false id:simple-encrypted@crypto.notmuchmail.org | notmuch_show_part 3)
268 expected='Non-text part: application/octet-stream'
269 test_expect_equal \
270     "$output" \
271     "$expected"
272
273 test_begin_subtest "purging stashed session keys should lose access to the cleartext"
274 notmuch reindex --decrypt=false id:simple-encrypted@crypto.notmuchmail.org
275 output=$(notmuch search sekrit)
276 expected=''
277 test_expect_equal \
278     "$output" \
279     "$expected"
280
281 test_begin_subtest "and cleartext should be unrecoverable now that there are no stashed session keys"
282 notmuch dump
283 notmuch reindex --decrypt=true id:simple-encrypted@crypto.notmuchmail.org
284 output=$(notmuch search sekrit)
285 expected=''
286 test_expect_equal \
287     "$output" \
288     "$expected"
289
290 goodsig='good_sig:[0][0][0]["crypto"]["signed"]["status"][0]["status"]="good"'
291 nosig='no_sig:[0][0][0]["crypto"]!"signed"'
292
293 test_begin_subtest "verify signature without a session key stashed when --decrypt=true"
294 output=$(notmuch show --format=json --decrypt=true id:encrypted-signed@crypto.notmuchmail.org)
295 test_json_nodes <<<"$output" "$goodsig"
296
297 test_begin_subtest "do not verify sig without a session key stashed if --decrypt=auto"
298 output=$(notmuch show --format=json id:encrypted-signed@crypto.notmuchmail.org)
299 test_json_nodes <<<"$output" "$nosig"
300
301 test_begin_subtest "verify signature when --decrypt=stash"
302 output=$(notmuch show --format=json --decrypt=stash id:encrypted-signed@crypto.notmuchmail.org)
303 test_json_nodes <<<"$output" "$goodsig"
304
305 test_begin_subtest "verify signature with stashed session key"
306 output=$(notmuch show --format=json id:encrypted-signed@crypto.notmuchmail.org)
307 if [ $NOTMUCH_GMIME_VERIFY_WITH_SESSION_KEY -ne 1 ]; then
308     test_subtest_known_broken
309 fi
310 test_json_nodes <<<"$output" "$goodsig"
311
312 # TODO: test removal of a message from the message store between
313 # indexing and reindexing.
314
315 # TODO: insert the same message into the message store twice, index,
316 # remove one of them from the message store, and then reindex.
317 # reindexing should return a failure but the message should still be
318 # present? -- or what should the semantics be if you ask to reindex a
319 # message whose underlying files have been renamed or moved or
320 # removed?
321
322 test_done