[PATCH 11/13] emacs: remove no longer used functions from notmuch-show.el
[notmuch-archives.git] / 37 / d3a9ca9460d5adce23caa3db509ee11c6c63a8
1 Return-Path: <jrollins@servo.finestructure.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 olra.theworths.org (Postfix) with ESMTP id D1255429E53\r
6         for <notmuch@notmuchmail.org>; Wed, 25 May 2011 18:01:39 -0700 (PDT)\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
8 X-Spam-Flag: NO\r
9 X-Spam-Score: -1.921\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=-1.921 tagged_above=-999 required=5\r
12         tests=[NO_DNS_FOR_FROM=0.379, RCVD_IN_DNSWL_MED=-2.3]\r
13         autolearn=disabled\r
14 Received: from olra.theworths.org ([127.0.0.1])\r
15         by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
16         with ESMTP id LBv5ZjnunMC2 for <notmuch@notmuchmail.org>;\r
17         Wed, 25 May 2011 18:01:36 -0700 (PDT)\r
18 Received: from outgoing-mail.its.caltech.edu (outgoing-mail.its.caltech.edu\r
19         [131.215.239.19])\r
20         by olra.theworths.org (Postfix) with ESMTP id 4A7D2429E39\r
21         for <notmuch@notmuchmail.org>; Wed, 25 May 2011 18:01:34 -0700 (PDT)\r
22 Received: from fire-doxen.imss.caltech.edu (localhost [127.0.0.1])\r
23         by fire-doxen-postvirus (Postfix) with ESMTP id 4BFAF3281DB;\r
24         Wed, 25 May 2011 17:55:19 -0700 (PDT)\r
25 X-Spam-Scanned: at Caltech-IMSS on fire-doxen by amavisd-new\r
26 Received: from servo.finestructure.net (gwave-104.ligo.caltech.edu\r
27         [131.215.114.104]) (Authenticated sender: jrollins)\r
28         by fire-doxen-submit (Postfix) with ESMTP id 37D343282CE;\r
29         Wed, 25 May 2011 17:55:14 -0700 (PDT)\r
30 Received: by servo.finestructure.net (Postfix, from userid 1000)\r
31         id 82A837CB; Wed, 25 May 2011 18:01:26 -0700 (PDT)\r
32 From: Jameson Graef Rollins <jrollins@finestructure.net>\r
33 To: notmuch@notmuchmail.org\r
34 Subject: [PATCH 09/11] Add decryption of PGP/MIME-encrypted parts with\r
35         --decrypt.\r
36 Date: Wed, 25 May 2011 18:01:18 -0700\r
37 Message-Id: <1306371680-19441-10-git-send-email-jrollins@finestructure.net>\r
38 X-Mailer: git-send-email 1.7.4.4\r
39 In-Reply-To: <1306371680-19441-1-git-send-email-jrollins@finestructure.net>\r
40 References: <1306371680-19441-1-git-send-email-jrollins@finestructure.net>\r
41 X-BeenThere: notmuch@notmuchmail.org\r
42 X-Mailman-Version: 2.1.13\r
43 Precedence: list\r
44 List-Id: "Use and development of the notmuch mail system."\r
45         <notmuch.notmuchmail.org>\r
46 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
47         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
48 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
49 List-Post: <mailto:notmuch@notmuchmail.org>\r
50 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
51 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
52         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
53 X-List-Received-Date: Thu, 26 May 2011 01:01:40 -0000\r
54 \r
55 This adds support for decrypting PGP/MIME-encrypted parts to\r
56 notmuch-show and notmuch-reply.  The --decrypt option implies\r
57 --verify.  Once decryption (and possibly signature verification) is\r
58 done, a new part_encstatus formatter is emitted, the part_sigstatus\r
59 formatter is emitted, and the entire multipart/encrypted part is\r
60 replaced by the contents of the encrypted part.\r
61 \r
62 At the moment only a json part_encstatus formatting function is\r
63 available, even though decryption is done for all formats.  Emacs\r
64 support to follow.\r
65 ---\r
66  notmuch-client.h |    2 ++\r
67  notmuch-reply.c  |   36 ++++++++++++++++++++++++++++--------\r
68  notmuch-show.c   |   25 ++++++++++++++++++++++++-\r
69  notmuch.1        |   11 +++++++++++\r
70  notmuch.c        |    8 ++++++++\r
71  show-message.c   |   29 ++++++++++++++++++++++++++++-\r
72  6 files changed, 101 insertions(+), 10 deletions(-)\r
73 \r
74 diff --git a/notmuch-client.h b/notmuch-client.h\r
75 index dc4ed7a..8a27260 100644\r
76 --- a/notmuch-client.h\r
77 +++ b/notmuch-client.h\r
78 @@ -67,6 +67,7 @@ typedef struct notmuch_show_format {\r
79      const char *body_start;\r
80      void (*part_start) (GMimeObject *part,\r
81                         int *part_count);\r
82 +    void (*part_encstatus) (int status);\r
83      void (*part_sigstatus) (const GMimeSignatureValidity* validity);\r
84      void (*part_content) (GMimeObject *part);\r
85      void (*part_end) (GMimeObject *part);\r
86 @@ -82,6 +83,7 @@ typedef struct notmuch_show_params {\r
87      int raw;\r
88      int part;\r
89      GMimeCipherContext* cryptoctx;\r
90 +    int decrypt;\r
91  } notmuch_show_params_t;\r
92  \r
93  /* There's no point in continuing when we've detected that we've done\r
94 diff --git a/notmuch-reply.c b/notmuch-reply.c\r
95 index 99bb15f..5265af6 100644\r
96 --- a/notmuch-reply.c\r
97 +++ b/notmuch-reply.c\r
98 @@ -34,6 +34,7 @@ static const notmuch_show_format_t format_reply = {\r
99             "",\r
100                 NULL,\r
101                 NULL,\r
102 +               NULL,\r
103                 reply_part_content,\r
104                 NULL,\r
105                 "",\r
106 @@ -438,7 +439,10 @@ guess_from_received_header (notmuch_config_t *config, notmuch_message_t *message\r
107  }\r
108  \r
109  static int\r
110 -notmuch_reply_format_default(void *ctx, notmuch_config_t *config, notmuch_query_t *query)\r
111 +notmuch_reply_format_default(void *ctx,\r
112 +                            notmuch_config_t *config,\r
113 +                            notmuch_query_t *query,\r
114 +                            notmuch_show_params_t *params)\r
115  {\r
116      GMimeMessage *reply;\r
117      notmuch_messages_t *messages;\r
118 @@ -446,9 +450,6 @@ notmuch_reply_format_default(void *ctx, notmuch_config_t *config, notmuch_query_\r
119      const char *subject, *from_addr = NULL;\r
120      const char *in_reply_to, *orig_references, *references;\r
121      const notmuch_show_format_t *format = &format_reply;\r
122 -    notmuch_show_params_t params;\r
123 -    params.part = -1;\r
124 -    params.cryptoctx = NULL;\r
125  \r
126      for (messages = notmuch_query_search_messages (query);\r
127          notmuch_messages_valid (messages);\r
128 @@ -508,7 +509,7 @@ notmuch_reply_format_default(void *ctx, notmuch_config_t *config, notmuch_query_\r
129                 notmuch_message_get_header (message, "from"));\r
130  \r
131         show_message_body (notmuch_message_get_filename (message),\r
132 -                          format, &params);\r
133 +                          format, params);\r
134  \r
135         notmuch_message_destroy (message);\r
136      }\r
137 @@ -517,7 +518,10 @@ notmuch_reply_format_default(void *ctx, notmuch_config_t *config, notmuch_query_\r
138  \r
139  /* This format is currently tuned for a git send-email --notmuch hook */\r
140  static int\r
141 -notmuch_reply_format_headers_only(void *ctx, notmuch_config_t *config, notmuch_query_t *query)\r
142 +notmuch_reply_format_headers_only(void *ctx,\r
143 +                                 notmuch_config_t *config,\r
144 +                                 notmuch_query_t *query,\r
145 +                                 unused (notmuch_show_params_t *params))\r
146  {\r
147      GMimeMessage *reply;\r
148      notmuch_messages_t *messages;\r
149 @@ -579,9 +583,12 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])\r
150      notmuch_query_t *query;\r
151      char *opt, *query_string;\r
152      int i, ret = 0;\r
153 -    int (*reply_format_func)(void *ctx, notmuch_config_t *config, notmuch_query_t *query);\r
154 +    int (*reply_format_func)(void *ctx, notmuch_config_t *config, notmuch_query_t *query, notmuch_show_params_t *params);\r
155 +    notmuch_show_params_t params;\r
156  \r
157      reply_format_func = notmuch_reply_format_default;\r
158 +    params.part = -1;\r
159 +    params.cryptoctx = NULL;\r
160  \r
161      for (i = 0; i < argc && argv[i][0] == '-'; i++) {\r
162         if (strcmp (argv[i], "--") == 0) {\r
163 @@ -598,6 +605,16 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])\r
164                 fprintf (stderr, "Invalid value for --format: %s\n", opt);\r
165                 return 1;\r
166             }\r
167 +       } else if ((STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) {\r
168 +           if (params.cryptoctx == NULL) {\r
169 +               GMimeSession* session = g_object_new(notmuch_gmime_session_get_type(), NULL);\r
170 +               if (NULL == (params.cryptoctx = g_mime_gpg_context_new(session, "gpg")))\r
171 +                   fprintf (stderr, "Failed to construct gpg context.\n");\r
172 +               else\r
173 +                   g_mime_gpg_context_set_always_trust((GMimeGpgContext*)params.cryptoctx, FALSE);\r
174 +               g_object_unref (session);\r
175 +               session = NULL;\r
176 +           }\r
177         } else {\r
178             fprintf (stderr, "Unrecognized option: %s\n", argv[i]);\r
179             return 1;\r
180 @@ -633,11 +650,14 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])\r
181         return 1;\r
182      }\r
183  \r
184 -    if (reply_format_func (ctx, config, query) != 0)\r
185 +    if (reply_format_func (ctx, config, query, &params) != 0)\r
186         return 1;\r
187  \r
188      notmuch_query_destroy (query);\r
189      notmuch_database_close (notmuch);\r
190  \r
191 +    if (params.cryptoctx)\r
192 +       g_object_unref(params.cryptoctx);\r
193 +\r
194      return ret;\r
195  }\r
196 diff --git a/notmuch-show.c b/notmuch-show.c\r
197 index bb54e56..e90f07e 100644\r
198 --- a/notmuch-show.c\r
199 +++ b/notmuch-show.c\r
200 @@ -45,6 +45,7 @@ static const notmuch_show_format_t format_text = {\r
201             "\fbody{\n",\r
202                 format_part_start_text,\r
203                 NULL,\r
204 +               NULL,\r
205                 format_part_content_text,\r
206                 format_part_end_text,\r
207                 "",\r
208 @@ -66,6 +67,9 @@ format_part_start_json (unused (GMimeObject *part),\r
209                         int *part_count);\r
210  \r
211  static void\r
212 +format_part_encstatus_json (int status);\r
213 +\r
214 +static void\r
215  format_part_sigstatus_json (const GMimeSignatureValidity* validity);\r
216  \r
217  static void\r
218 @@ -80,6 +84,7 @@ static const notmuch_show_format_t format_json = {\r
219             ", \"headers\": {", format_headers_json, "}",\r
220             ", \"body\": [",\r
221                 format_part_start_json,\r
222 +               format_part_encstatus_json,\r
223                 format_part_sigstatus_json,\r
224                 format_part_content_json,\r
225                 format_part_end_json,\r
226 @@ -103,6 +108,7 @@ static const notmuch_show_format_t format_mbox = {\r
227                  NULL,\r
228                  NULL,\r
229                  NULL,\r
230 +                NULL,\r
231                  "",\r
232              "",\r
233          "", "",\r
234 @@ -119,6 +125,7 @@ static const notmuch_show_format_t format_raw = {\r
235              "",\r
236                  NULL,\r
237                  NULL,\r
238 +                NULL,\r
239                  format_part_content_raw,\r
240                  NULL,\r
241                  "",\r
242 @@ -496,6 +503,18 @@ format_part_start_json (unused (GMimeObject *part), int *part_count)\r
243  }\r
244  \r
245  static void\r
246 +format_part_encstatus_json (int status)\r
247 +{\r
248 +    printf (", \"encstatus\": [{\"status\": ");\r
249 +    if (status) {\r
250 +       printf ("\"good\"");\r
251 +    } else {\r
252 +       printf ("\"bad\"");\r
253 +    }\r
254 +    printf ("}]");\r
255 +}\r
256 +\r
257 +static void\r
258  format_part_sigstatus_json (const GMimeSignatureValidity* validity)\r
259  {\r
260      printf (", \"sigstatus\": [");\r
261 @@ -822,6 +841,7 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))\r
262      params.raw = 0;\r
263      params.part = -1;\r
264      params.cryptoctx = NULL;\r
265 +    params.decrypt = 0;\r
266  \r
267      for (i = 0; i < argc && argv[i][0] == '-'; i++) {\r
268         if (strcmp (argv[i], "--") == 0) {\r
269 @@ -850,7 +870,8 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))\r
270             params.part = atoi(argv[i] + sizeof ("--part=") - 1);\r
271         } else if (STRNCMP_LITERAL (argv[i], "--entire-thread") == 0) {\r
272             params.entire_thread = 1;\r
273 -       } else if (STRNCMP_LITERAL (argv[i], "--verify") == 0) {\r
274 +       } else if ((STRNCMP_LITERAL (argv[i], "--verify") == 0) ||\r
275 +                  (STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) {\r
276             if (params.cryptoctx == NULL) {\r
277                 GMimeSession* session = g_object_new(notmuch_gmime_session_get_type(), NULL);\r
278                 if (NULL == (params.cryptoctx = g_mime_gpg_context_new(session, "gpg")))\r
279 @@ -860,6 +881,8 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))\r
280                 g_object_unref (session);\r
281                 session = NULL;\r
282             }\r
283 +           if (STRNCMP_LITERAL (argv[i], "--decrypt") == 0)\r
284 +               params.decrypt = 1;\r
285         } else {\r
286             fprintf (stderr, "Unrecognized option: %s\n", argv[i]);\r
287             return 1;\r
288 diff --git a/notmuch.1 b/notmuch.1\r
289 index daa9c6f..c1aa4e3 100644\r
290 --- a/notmuch.1\r
291 +++ b/notmuch.1\r
292 @@ -332,6 +332,17 @@ of the signature will be reported (currently only supported with\r
293  signed data.\r
294  .RE\r
295  \r
296 +.RS 4\r
297 +.TP 4\r
298 +.B \-\-decrypt\r
299 +\r
300 +Decrypt any MIME encrypted parts found in the selected content\r
301 +(ie. "multipart/encrypted" parts). Status of the decryption will be\r
302 +reported (currently only supported with --format=json) and the\r
303 +multipart/encrypted part will be replaced by the decrypted\r
304 +content.\r
305 +.RE\r
306 +\r
307  A common use of\r
308  .B notmuch show\r
309  is to display a single thread of email messages. For this, use a\r
310 diff --git a/notmuch.c b/notmuch.c\r
311 index cd3cb1b..93f3194 100644\r
312 --- a/notmuch.c\r
313 +++ b/notmuch.c\r
314 @@ -302,6 +302,14 @@ static command_t commands[] = {\r
315        "\t\treported (currently only supported with --format=json) and\n"\r
316        "\t\tthe multipart/signed part will be replaced by the signed data.\n"\r
317        "\n"\r
318 +      "\t--decrypt\n"\r
319 +      "\n"\r
320 +      "\t\tDecrypt any MIME encrypted parts found in the selected content\n"\r
321 +      "\t\t(ie. \"multipart/encrypted\" parts). Status of the decryption\n"\r
322 +      "\t\twill be reported (currently only supported with --format=json)\n"\r
323 +      "\t\tand the multipart/encrypted part will be replaced by the\n"\r
324 +      "\t\tdecrypted content.\n"\r
325 +      "\n"\r
326        "\n"\r
327        "\tA common use of \"notmuch show\" is to display a single\n"\r
328        "\tthread of email messages. For this, use a search term of\n"\r
329 diff --git a/show-message.c b/show-message.c\r
330 index c90f310..37252b2 100644\r
331 --- a/show-message.c\r
332 +++ b/show-message.c\r
333 @@ -58,7 +58,34 @@ show_message_part (GMimeObject *part,\r
334         GMimeMultipart *multipart = GMIME_MULTIPART (part);\r
335         GError* err = NULL;\r
336  \r
337 -       if (GMIME_IS_MULTIPART_SIGNED (part))\r
338 +       if (GMIME_IS_MULTIPART_ENCRYPTED (part) && params->decrypt)\r
339 +       {\r
340 +           if ( g_mime_multipart_get_count (multipart) != 2 ) {\r
341 +               /* this violates RFC 3156 section 4, so we won't bother with it. */\r
342 +               fprintf (stderr,\r
343 +                        "Error: %d part(s) for a multipart/encrypted message (should be exactly 2)\n",\r
344 +                        g_mime_multipart_get_count (multipart));\r
345 +           } else {\r
346 +               GMimeMultipartEncrypted *encrypteddata = GMIME_MULTIPART_ENCRYPTED (part);\r
347 +               GMimeObject *decryptedpart = g_mime_multipart_encrypted_decrypt (encrypteddata, params->cryptoctx, &err);\r
348 +               if (decryptedpart) {\r
349 +                   if ((selected || state->in_zone) && format->part_encstatus)\r
350 +                       format->part_encstatus (1);\r
351 +                   const GMimeSignatureValidity *sigvalidity = g_mime_multipart_encrypted_get_signature_validity (encrypteddata);\r
352 +                   if (!sigvalidity)\r
353 +                       fprintf (stderr, "Failed to verify signed part: %s\n", (err ? err->message : "no error explanation given"));\r
354 +                   if ((selected || state->in_zone) && format->part_sigstatus)\r
355 +                       format->part_sigstatus (sigvalidity);\r
356 +                   /* swap the part with the decrypted part */\r
357 +                   part = decryptedpart;\r
358 +               } else {\r
359 +                   fprintf (stderr, "Failed to decrypt part: %s\n", (err ? err->message : "no error explanation given"));\r
360 +                   if ((selected || state->in_zone) && format->part_encstatus)\r
361 +                       format->part_encstatus (0);\r
362 +               }\r
363 +           }\r
364 +       }\r
365 +       else if (GMIME_IS_MULTIPART_SIGNED (part))\r
366         {\r
367             if ( g_mime_multipart_get_count (multipart) != 2 ) {\r
368                 /* this violates RFC 3156 section 5, so we won't bother with it. */\r
369 -- \r
370 1.7.4.4\r
371 \r