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