notmuch.el: controlling what does and doesn't get expanded in searches
[notmuch-archives.git] / 74 / 116c49e7c50600466f0a2da9406e04f6ccf42e
1 Return-Path: <dkg@fifthhorseman.net>\r
2 X-Original-To: notmuch@notmuchmail.org\r
3 Delivered-To: notmuch@notmuchmail.org\r
4 Received: from localhost (localhost [127.0.0.1])\r
5  by arlo.cworth.org (Postfix) with ESMTP id 756666DE1B50\r
6  for <notmuch@notmuchmail.org>; Sun, 31 Jan 2016 12:40:19 -0800 (PST)\r
7 X-Virus-Scanned: Debian amavisd-new at cworth.org\r
8 X-Spam-Flag: NO\r
9 X-Spam-Score: 0\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=0 tagged_above=-999 required=5 tests=[none]\r
12  autolearn=disabled\r
13 Received: from arlo.cworth.org ([127.0.0.1])\r
14  by localhost (arlo.cworth.org [127.0.0.1]) (amavisd-new, port 10024)\r
15  with ESMTP id DJVWgiBGX0rn for <notmuch@notmuchmail.org>;\r
16  Sun, 31 Jan 2016 12:40:17 -0800 (PST)\r
17 Received: from che.mayfirst.org (che.mayfirst.org [209.234.253.108])\r
18  by arlo.cworth.org (Postfix) with ESMTP id 7F7836DE1AC4\r
19  for <notmuch@notmuchmail.org>; Sun, 31 Jan 2016 12:40:09 -0800 (PST)\r
20 Received: from fifthhorseman.net (ip-64-134-185-108.public.wayport.net\r
21  [64.134.185.108])\r
22  by che.mayfirst.org (Postfix) with ESMTPSA id 81A78F99E\r
23  for <notmuch@notmuchmail.org>; Sun, 31 Jan 2016 15:40:06 -0500 (EST)\r
24 Received: by fifthhorseman.net (Postfix, from userid 1000)\r
25  id 4DA8421028; Sun, 31 Jan 2016 15:40:06 -0500 (EST)\r
26 From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>\r
27 To: Notmuch Mail <notmuch@notmuchmail.org>\r
28 Subject: [PATCH v3 09/16] index encrypted parts when asked.\r
29 Date: Sun, 31 Jan 2016 15:39:54 -0500\r
30 Message-Id: <1454272801-23623-10-git-send-email-dkg@fifthhorseman.net>\r
31 X-Mailer: git-send-email 2.7.0.rc3\r
32 In-Reply-To: <1454272801-23623-1-git-send-email-dkg@fifthhorseman.net>\r
33 References: <1454272801-23623-1-git-send-email-dkg@fifthhorseman.net>\r
34 X-BeenThere: notmuch@notmuchmail.org\r
35 X-Mailman-Version: 2.1.20\r
36 Precedence: list\r
37 List-Id: "Use and development of the notmuch mail system."\r
38  <notmuch.notmuchmail.org>\r
39 List-Unsubscribe: <https://notmuchmail.org/mailman/options/notmuch>,\r
40  <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
41 List-Archive: <http://notmuchmail.org/pipermail/notmuch/>\r
42 List-Post: <mailto:notmuch@notmuchmail.org>\r
43 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
44 List-Subscribe: <https://notmuchmail.org/mailman/listinfo/notmuch>,\r
45  <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
46 X-List-Received-Date: Sun, 31 Jan 2016 20:40:19 -0000\r
47 \r
48 If we see index options that ask us to decrypt when indexing a\r
49 message, and we encounter an encrypted part, we'll try to descend into\r
50 it.\r
51 \r
52 If we can decrypt, we tag the message with index-decrypted.\r
53 \r
54 If we can't decrypt (or recognize the encrypted type of mail), we tag\r
55 with decryption-failed.\r
56 \r
57 Note that a single message may be tagged with "encrypted" and\r
58 "index-decrypted" and "decryption-failed".  For example, consider a\r
59 message that includes multiple layers of encryption.  It is\r
60 automatically tagged with "encrypted".  If we decrypt the outer layer\r
61 ("index-decrypted"), but fail on the inner layer\r
62 ("decryption-failed").\r
63 ---\r
64  lib/database.cc       |  3 ++-\r
65  lib/index.cc          | 64 ++++++++++++++++++++++++++++++++++++++++++++++++---\r
66  lib/notmuch-private.h |  1 +\r
67  3 files changed, 64 insertions(+), 4 deletions(-)\r
68 \r
69 diff --git a/lib/database.cc b/lib/database.cc\r
70 index 0d4dc9b..7d88f69 100644\r
71 --- a/lib/database.cc\r
72 +++ b/lib/database.cc\r
73 @@ -2402,6 +2402,7 @@ notmuch_database_add_message (notmuch_database_t *notmuch,\r
74      notmuch_status_t ret = NOTMUCH_STATUS_SUCCESS, ret2;\r
75      notmuch_private_status_t private_status;\r
76      notmuch_bool_t is_ghost = false;\r
77 +    notmuch_indexopts_t *indexopts = NULL;\r
78  \r
79      const char *date, *header;\r
80      const char *from, *to, *subject;\r
81 @@ -2514,7 +2515,7 @@ notmuch_database_add_message (notmuch_database_t *notmuch,\r
82             date = _notmuch_message_file_get_header (message_file, "date");\r
83             _notmuch_message_set_header_values (message, date, from, subject);\r
84  \r
85 -           ret = _notmuch_message_index_file (message, message_file);\r
86 +           ret = _notmuch_message_index_file (message, indexopts, message_file);\r
87             if (ret)\r
88                 goto DONE;\r
89         } else {\r
90 diff --git a/lib/index.cc b/lib/index.cc\r
91 index ab0fd78..eb406d2 100644\r
92 --- a/lib/index.cc\r
93 +++ b/lib/index.cc\r
94 @@ -300,9 +300,14 @@ _index_address_list (notmuch_message_t *message,\r
95      }\r
96  }\r
97  \r
98 +static void\r
99 +_index_encrypted_mime_part (notmuch_message_t *message, notmuch_indexopts_t *indexopts,\r
100 +                           GMimeContentType *content_type, GMimeMultipartEncrypted *part);\r
101 +\r
102  /* Callback to generate terms for each mime part of a message. */\r
103  static void\r
104  _index_mime_part (notmuch_message_t *message,\r
105 +                 notmuch_indexopts_t *indexopts,\r
106                   GMimeObject *part)\r
107  {\r
108      GMimeStream *stream, *filter;\r
109 @@ -340,17 +345,19 @@ _index_mime_part (notmuch_message_t *message,\r
110             /* FIXME: is it always just the first part that is signed in\r
111              all multipart/signed messages?*/\r
112             _index_mime_part (message,\r
113 +                             indexopts,\r
114                               g_mime_multipart_get_part (multipart, 0));\r
115             \r
116             if (g_mime_multipart_get_count (multipart) > 2)\r
117                 _notmuch_database_log (_notmuch_message_database (message),\r
118                                        "Warning: Unexpected extra parts of multipart/signed. Indexing anyway.\n");\r
119         } else if (GMIME_IS_MULTIPART_ENCRYPTED (multipart)) {\r
120 -           /* Don't index encrypted parts */\r
121             _notmuch_message_add_term (message, "tag", "encrypted");\r
122 +           _index_encrypted_mime_part(message, indexopts, content_type, GMIME_MULTIPART_ENCRYPTED (part));\r
123         } else {\r
124             for (i = 0; i < g_mime_multipart_get_count (multipart); i++) {\r
125                 _index_mime_part (message,\r
126 +                                 indexopts,\r
127                                   g_mime_multipart_get_part (multipart, i));\r
128             }\r
129         }\r
130 @@ -362,7 +369,7 @@ _index_mime_part (notmuch_message_t *message,\r
131  \r
132         mime_message = g_mime_message_part_get_message (GMIME_MESSAGE_PART (part));\r
133  \r
134 -       _index_mime_part (message, g_mime_message_get_mime_part (mime_message));\r
135 +       _index_mime_part (message, indexopts, g_mime_message_get_mime_part (mime_message));\r
136  \r
137         return;\r
138      }\r
139 @@ -432,8 +439,59 @@ _index_mime_part (notmuch_message_t *message,\r
140      }\r
141  }\r
142  \r
143 +/* descend (if desired) into the cleartext part of an encrypted MIME\r
144 + * part while indexing. */\r
145 +static void\r
146 +_index_encrypted_mime_part (notmuch_message_t *message,\r
147 +                           notmuch_indexopts_t *indexopts,\r
148 +                           GMimeContentType *content_type,\r
149 +                           GMimeMultipartEncrypted *encrypted_data)\r
150 +{\r
151 +    notmuch_status_t status;\r
152 +    GMimeCryptoContext* crypto_ctx = NULL;\r
153 +    const char *protocol = NULL;\r
154 +    GError *err = NULL;\r
155 +    notmuch_database_t * notmuch = NULL;\r
156 +    GMimeObject *clear = NULL;\r
157 +\r
158 +    if (!indexopts || !notmuch_indexopts_get_try_decrypt (indexopts))\r
159 +       return;\r
160 +\r
161 +    protocol = g_mime_content_type_get_parameter (content_type, "protocol");\r
162 +    notmuch = _notmuch_message_database (message);\r
163 +    \r
164 +    status = _notmuch_crypto_get_gmime_ctx_for_protocol (&(indexopts->crypto),\r
165 +                                                        protocol, &crypto_ctx);\r
166 +    if (status) {\r
167 +       _notmuch_database_log (notmuch, "Warning: setup failed for decrypting "\r
168 +                              "during indexing. (%d)\n", status);\r
169 +       _notmuch_message_add_term (message, "tag", "index-decryption-failed");\r
170 +       return;\r
171 +    }\r
172 +\r
173 +    /* we don't need the GMimeDecryptResult, because we're not looking\r
174 +     * at validating signatures, and we don't care about indexing who\r
175 +     * the message was ostensibly encrypted to.\r
176 +     */\r
177 +    clear = g_mime_multipart_encrypted_decrypt(encrypted_data, crypto_ctx,\r
178 +                                              NULL, &err);\r
179 +    if (err) {\r
180 +       _notmuch_database_log (notmuch, "Failed to decrypt during indexing. (%d:%d) [%s]\n",\r
181 +                              err->domain, err->code, err->message);\r
182 +       g_error_free(err);\r
183 +       /* Indicate that we failed to decrypt during indexing */\r
184 +       _notmuch_message_add_term (message, "tag", "index-decryption-failed");\r
185 +       return;\r
186 +    }\r
187 +    _index_mime_part (message, indexopts, clear);\r
188 +    g_object_unref (clear);\r
189 +    \r
190 +    _notmuch_message_add_term (message, "tag", "index-decrypted");\r
191 +}\r
192 +\r
193  notmuch_status_t\r
194  _notmuch_message_index_file (notmuch_message_t *message,\r
195 +                            notmuch_indexopts_t *indexopts,\r
196                              notmuch_message_file_t *message_file)\r
197  {\r
198      GMimeMessage *mime_message;\r
199 @@ -463,7 +521,7 @@ _notmuch_message_index_file (notmuch_message_t *message,\r
200      subject = g_mime_message_get_subject (mime_message);\r
201      _notmuch_message_gen_terms (message, "subject", subject);\r
202  \r
203 -    _index_mime_part (message, g_mime_message_get_mime_part (mime_message));\r
204 +    _index_mime_part (message, indexopts, g_mime_message_get_mime_part (mime_message));\r
205  \r
206      return NOTMUCH_STATUS_SUCCESS;\r
207  }\r
208 diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h\r
209 index e9c1e8a..9bd4f33 100644\r
210 --- a/lib/notmuch-private.h\r
211 +++ b/lib/notmuch-private.h\r
212 @@ -425,6 +425,7 @@ _notmuch_message_file_get_header (notmuch_message_file_t *message,\r
213  \r
214  notmuch_status_t\r
215  _notmuch_message_index_file (notmuch_message_t *message,\r
216 +                            notmuch_indexopts_t *indexopts,\r
217                              notmuch_message_file_t *message_file);\r
218  \r
219  /* messages.c */\r
220 -- \r
221 2.7.0.rc3\r
222 \r