Re: [PATCH v2] Omit User-Agent: header by default
[notmuch-archives.git] / 95 / 690553bf2b104474af1e4d37b94888b434468b
1 Return-Path: <amdragon@mit.edu>\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 55D50429E5F\r
6         for <notmuch@notmuchmail.org>; Tue, 17 Jan 2012 14:26:01 -0800 (PST)\r
7 X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
8 X-Spam-Flag: NO\r
9 X-Spam-Score: -0.7\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5\r
12         tests=[RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled\r
13 Received: from olra.theworths.org ([127.0.0.1])\r
14         by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
15         with ESMTP id T8f+kBEj2HOF for <notmuch@notmuchmail.org>;\r
16         Tue, 17 Jan 2012 14:26:00 -0800 (PST)\r
17 Received: from dmz-mailsec-scanner-1.mit.edu (DMZ-MAILSEC-SCANNER-1.MIT.EDU\r
18         [18.9.25.12])\r
19         by olra.theworths.org (Postfix) with ESMTP id D5E1741ED71\r
20         for <notmuch@notmuchmail.org>; Tue, 17 Jan 2012 14:25:59 -0800 (PST)\r
21 X-AuditID: 1209190c-b7fad6d000000920-f5-4f15f5772c1f\r
22 Received: from mailhub-auth-3.mit.edu ( [18.9.21.43])\r
23         by dmz-mailsec-scanner-1.mit.edu (Symantec Messaging Gateway) with SMTP\r
24         id E3.AC.02336.775F51F4; Tue, 17 Jan 2012 17:25:59 -0500 (EST)\r
25 Received: from outgoing.mit.edu (OUTGOING-AUTH.MIT.EDU [18.7.22.103])\r
26         by mailhub-auth-3.mit.edu (8.13.8/8.9.2) with ESMTP id q0HMPx4Q029413; \r
27         Tue, 17 Jan 2012 17:25:59 -0500\r
28 Received: from awakening.csail.mit.edu (awakening.csail.mit.edu [18.26.4.91])\r
29         (authenticated bits=0)\r
30         (User authenticated as amdragon@ATHENA.MIT.EDU)\r
31         by outgoing.mit.edu (8.13.6/8.12.4) with ESMTP id q0HMPwnY026857\r
32         (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NOT);\r
33         Tue, 17 Jan 2012 17:25:58 -0500 (EST)\r
34 Received: from amthrax by awakening.csail.mit.edu with local (Exim 4.77)\r
35         (envelope-from <amdragon@mit.edu>)\r
36         id 1RnHTO-0008Bm-8G; Tue, 17 Jan 2012 17:25:46 -0500\r
37 Date: Tue, 17 Jan 2012 17:25:46 -0500\r
38 From: Austin Clements <amdragon@MIT.EDU>\r
39 To: Thomas Jost <schnouki@schnouki.net>\r
40 Subject: Re: [PATCH v2 2/2] Add pseudo-compatibility with gmime 2.6\r
41 Message-ID: <20120117222546.GT16740@mit.edu>\r
42 References: <8739bea9lc.fsf@thor.loria.fr>\r
43         <1326797453-9405-1-git-send-email-schnouki@schnouki.net>\r
44         <1326797453-9405-2-git-send-email-schnouki@schnouki.net>\r
45 MIME-Version: 1.0\r
46 Content-Type: text/plain; charset=us-ascii\r
47 Content-Disposition: inline\r
48 In-Reply-To: <1326797453-9405-2-git-send-email-schnouki@schnouki.net>\r
49 User-Agent: Mutt/1.5.21 (2010-09-15)\r
50 X-Brightmail-Tracker:\r
51  H4sIAAAAAAAAA+NgFupnleLIzCtJLcpLzFFi42IR4hTV1i3/KupvMPWMtMX1mzOZLfb1+zsw\r
52         eTxbdYvZY8qsuewBTFFcNimpOZllqUX6dglcGW8u72MqWFxasb3vBWMDY39MFyMnh4SAicS9\r
53         5XvZIGwxiQv31gPZXBxCAvsYJR4/ucEE4WxglOh9fAQqc5JJYtXJNrAWIYEljBIz+h1BbBYB\r
54         VYkzM7+BxdkENCS27V/OCGKLCKhLNMzfDRZnFpCW+Pa7mQnEFhZwlliz/CYLiM0roCNx7dkj\r
55         ZogFCxgl5nXdZ4NICEqcnPmEBaJZS+LGv5dAzRxgg5b/4wAJcwq4Spx6cwWsRFRARWLKyW1s\r
56         ExiFZiHpnoWkexZC9wJG5lWMsim5Vbq5iZk5xanJusXJiXl5qUW6hnq5mSV6qSmlmxjBYS3J\r
57         s4PxzUGlQ4wCHIxKPLwSG0T9hVgTy4orcw8xSnIwKYnyCn0BCvEl5adUZiQWZ8QXleakFh9i\r
58         lOBgVhLhvXQZKMebklhZlVqUD5OS5mBREudV0XrnJySQnliSmp2aWpBaBJOV4eBQkuA9BjJU\r
59         sCg1PbUiLTOnBCHNxMEJMpwHaPgPkBre4oLE3OLMdIj8KUZdjpNrr5xjFGLJy89LlRLnvQ5S\r
60         JABSlFGaBzcHlo5eMYoDvSXMexCkigeYyuAmvQJawgS0JKdVCGRJSSJCSqqBMem1UN1E48ZM\r
61         G98zxVsCVy8OsAxft8h6cVV6Zexl/eR9hQmJ5vO6k+xyM2KviAk+2r2yfp1P6sWpUyJTHyvW\r
62         zDkpaVN17FjZ5QjfXnWBWtM3h//k9/zbbrUnQbap9PUHmztzvs+c0LrAf+av2NTLX6qiW01Z\r
63         tSOS3LK7fW/+uxzYpnPdbdNxJZbijERDLeai4kQALaEXpiIDAAA=\r
64 Cc: notmuch@notmuchmail.org\r
65 X-BeenThere: notmuch@notmuchmail.org\r
66 X-Mailman-Version: 2.1.13\r
67 Precedence: list\r
68 List-Id: "Use and development of the notmuch mail system."\r
69         <notmuch.notmuchmail.org>\r
70 List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
71         <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
72 List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
73 List-Post: <mailto:notmuch@notmuchmail.org>\r
74 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
75 List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
76         <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
77 X-List-Received-Date: Tue, 17 Jan 2012 22:26:01 -0000\r
78 \r
79 Quoth Thomas Jost on Jan 17 at 11:50 am:\r
80 > There are lots of API changes in gmime 2.6 crypto handling. By adding\r
81 > preprocessor directives, it is however possible to add gmime 2.6 compatibility\r
82 > while preserving compatibility with gmime 2.4 too.\r
83\r
84 > This is mostly based on id:"8762i8hrb9.fsf@bookbinder.fernseed.info".\r
85\r
86 > This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, the\r
87 > crypto tests all work fine (as expected). With gmime 2.6.4, one crypto test\r
88 > fails (signature verification with signer key unavailable) but this will be hard\r
89 > to fix since the new API does not report the reason why a signature verification\r
90 > fails (other than the human-readable error message).\r
91 > ---\r
92 >  mime-node.c      |   56 ++++++++++++++++++++++++++++++--\r
93 >  notmuch-client.h |   28 +++++++++++++++-\r
94 >  notmuch-reply.c  |    7 ++++\r
95 >  notmuch-show.c   |   95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++\r
96 >  show-message.c   |    4 ++\r
97 >  5 files changed, 185 insertions(+), 5 deletions(-)\r
98\r
99 > diff --git a/mime-node.c b/mime-node.c\r
100 > index d26bb44..e575e1c 100644\r
101 > --- a/mime-node.c\r
102 > +++ b/mime-node.c\r
103 > @@ -33,7 +33,11 @@ typedef struct mime_node_context {\r
104 >      GMimeMessage *mime_message;\r
105 >  \r
106 >      /* Context provided by the caller. */\r
107 > +#ifdef GMIME_26\r
108 > +    GMimeCryptoContext *cryptoctx;\r
109 > +#else\r
110 >      GMimeCipherContext *cryptoctx;\r
111 > +#endif\r
112 >      notmuch_bool_t decrypt;\r
113 >  } mime_node_context_t;\r
114 >  \r
115 > @@ -57,8 +61,12 @@ _mime_node_context_free (mime_node_context_t *res)\r
116 >  \r
117 >  notmuch_status_t\r
118 >  mime_node_open (const void *ctx, notmuch_message_t *message,\r
119 > -             GMimeCipherContext *cryptoctx, notmuch_bool_t decrypt,\r
120 > -             mime_node_t **root_out)\r
121 > +#ifdef GMIME_26\r
122 > +             GMimeCryptoContext *cryptoctx,\r
123 > +#else\r
124 > +             GMimeCipherContext *cryptoctx,\r
125 > +#endif\r
126 > +             notmuch_bool_t decrypt, mime_node_t **root_out)\r
127 >  {\r
128 >      const char *filename = notmuch_message_get_filename (message);\r
129 >      mime_node_context_t *mctx;\r
130 > @@ -112,12 +120,21 @@ DONE:\r
131 >      return status;\r
132 >  }\r
133 >  \r
134 > +#ifdef GMIME_26\r
135 > +static int\r
136 > +_signature_list_free (GMimeSignatureList **proxy)\r
137 > +{\r
138 > +    g_object_unref (*proxy);\r
139 > +    return 0;\r
140 > +}\r
141 > +#else\r
142 >  static int\r
143 >  _signature_validity_free (GMimeSignatureValidity **proxy)\r
144 >  {\r
145 >      g_mime_signature_validity_free (*proxy);\r
146 >      return 0;\r
147 >  }\r
148 > +#endif\r
149 >  \r
150 >  static mime_node_t *\r
151 >  _mime_node_create (const mime_node_t *parent, GMimeObject *part)\r
152 > @@ -165,11 +182,22 @@ _mime_node_create (const mime_node_t *parent, GMimeObject *part)\r
153 >           GMimeMultipartEncrypted *encrypteddata =\r
154 >               GMIME_MULTIPART_ENCRYPTED (part);\r
155 >           node->decrypt_attempted = TRUE;\r
156 > +#ifdef GMIME_26\r
157 > +         GMimeDecryptResult *decrypt_result = NULL;\r
158 \r
159 Reading through the GMime code, it looks like we do have to unref\r
160 decrypt_result.  I think this is easy, though.  Right after you call\r
161 g_mime_decrypt_result_get_signatures below, do:\r
162 \r
163   g_object_ref (node->sig_list);\r
164   g_object_unref (decrypt_result);\r
165 \r
166 > +         node->decrypted_child = g_mime_multipart_encrypted_decrypt\r
167 > +             (encrypteddata, node->ctx->cryptoctx, &decrypt_result, &err);\r
168 > +#else\r
169 >           node->decrypted_child = g_mime_multipart_encrypted_decrypt\r
170 >               (encrypteddata, node->ctx->cryptoctx, &err);\r
171 > +#endif\r
172 >           if (node->decrypted_child) {\r
173 > -             node->decrypt_success = node->verify_attempted = TRUE;\r
174 > +             node->decrypt_success = node->verify_attempted =TRUE;\r
175 \r
176 Whitespace.  (There should be no diff on the above line)\r
177 \r
178 > +#ifdef GMIME_26\r
179 > +             /* This may be NULL if the part is not signed. */\r
180 > +             node->sig_list = g_mime_decrypt_result_get_signatures (decrypt_result);\r
181 > +#else\r
182 >               node->sig_validity = g_mime_multipart_encrypted_get_signature_validity (encrypteddata);\r
183 > +#endif\r
184 >           } else {\r
185 >               fprintf (stderr, "Failed to decrypt part: %s\n",\r
186 >                        (err ? err->message : "no error explanation given"));\r
187 > @@ -182,6 +210,16 @@ _mime_node_create (const mime_node_t *parent, GMimeObject *part)\r
188 >                    "(must be exactly 2)\n",\r
189 >                    node->nchildren);\r
190 >       } else {\r
191 > +#ifdef GMIME_26\r
192 > +         GMimeSignatureList *sig_list = g_mime_multipart_signed_verify\r
193 > +             (GMIME_MULTIPART_SIGNED (part), node->ctx->cryptoctx, &err);\r
194 > +         node->verify_attempted = TRUE;\r
195 > +         node->sig_list = sig_list;\r
196 \r
197 Just a nit.  This could be\r
198   node->sig_list = g_mime_multipart_signed_verify ( ... )\r
199 To me, the local variable just makes this code more verbose without\r
200 adding anything.  Up to you.\r
201 \r
202 > +\r
203 > +         if (!sig_list)\r
204 > +             fprintf (stderr, "Failed to verify signed part: %s\n",\r
205 > +                      (err ? err->message : "no error explanation given"));\r
206 > +#else\r
207 >           /* For some reason the GMimeSignatureValidity returned\r
208 >            * here is not a const (inconsistent with that\r
209 >            * returned by\r
210 > @@ -200,12 +238,24 @@ _mime_node_create (const mime_node_t *parent, GMimeObject *part)\r
211 >               *proxy = sig_validity;\r
212 >               talloc_set_destructor (proxy, _signature_validity_free);\r
213 >           }\r
214 > +#endif\r
215 >       }\r
216 >      }\r
217 >  \r
218 > +#ifdef GMIME_26\r
219 > +    /* sig_list may be created in both above cases, so we need to\r
220 > +     * cleanly handle it here. */\r
221 > +    if (node->sig_list) {\r
222 > +     GMimeSignatureList **proxy =\r
223 > +         talloc (node, GMimeSignatureList *);\r
224 \r
225 This doesn't need to be split into two lines.\r
226 \r
227 > +     *proxy = node->sig_list;\r
228 > +     talloc_set_destructor (proxy, _signature_list_free);\r
229 > +    }\r
230 > +#else\r
231 >      if (node->verify_attempted && !node->sig_validity)\r
232 >       fprintf (stderr, "Failed to verify signed part: %s\n",\r
233 >                (err ? err->message : "no error explanation given"));\r
234 > +#endif\r
235 \r
236 I'd rather see the above as a separate #ifdef GMIME_26 and #ifndef\r
237 GMIME_26, since they aren't logical alternates of each other.\r
238 \r
239 >  \r
240 >      if (err)\r
241 >       g_error_free (err);\r
242 > diff --git a/notmuch-client.h b/notmuch-client.h\r
243 > index 62ede28..9167042 100644\r
244 > --- a/notmuch-client.h\r
245 > +++ b/notmuch-client.h\r
246 > @@ -30,6 +30,12 @@\r
247 >  \r
248 >  #include <gmime/gmime.h>\r
249 >  \r
250 > +/* GMIME_CHECK_VERSION is only available in gmime >= 2.5. But so are\r
251 > + * GMIME_MAJOR_VERSION and friends. */\r
252 > +#ifdef GMIME_MAJOR_VERSION\r
253 > +#define GMIME_26\r
254 > +#endif\r
255 > +\r
256 >  #include "notmuch.h"\r
257 >  \r
258 >  /* This is separate from notmuch-private.h because we're trying to\r
259 > @@ -69,7 +75,11 @@ typedef struct notmuch_show_format {\r
260 >      void (*part_start) (GMimeObject *part,\r
261 >                       int *part_count);\r
262 >      void (*part_encstatus) (int status);\r
263 > +#ifdef GMIME_26\r
264 > +    void (*part_sigstatus) (GMimeSignatureList* siglist);\r
265 > +#else\r
266 >      void (*part_sigstatus) (const GMimeSignatureValidity* validity);\r
267 > +#endif\r
268 >      void (*part_content) (GMimeObject *part);\r
269 >      void (*part_end) (GMimeObject *part);\r
270 >      const char *part_sep;\r
271 > @@ -83,7 +93,11 @@ typedef struct notmuch_show_params {\r
272 >      int entire_thread;\r
273 >      int raw;\r
274 >      int part;\r
275 > +#ifdef GMIME_26\r
276 > +    GMimeCryptoContext* cryptoctx;\r
277 > +#else\r
278 >      GMimeCipherContext* cryptoctx;\r
279 > +#endif\r
280 >      int decrypt;\r
281 >  } notmuch_show_params_t;\r
282 >  \r
283 > @@ -290,11 +304,17 @@ typedef struct mime_node {\r
284 >  \r
285 >      /* True if signature verification on this part was attempted. */\r
286 >      notmuch_bool_t verify_attempted;\r
287 > +#ifdef GMIME_26\r
288 > +    /* The list of signatures for signed or encrypted containers. If\r
289 > +      * there are no signatures, this will be NULL. */\r
290 \r
291 Spacing.\r
292 \r
293 > +    GMimeSignatureList* sig_list;\r
294 > +#else\r
295 >      /* For signed or encrypted containers, the validity of the\r
296 >       * signature.  May be NULL if signature verification failed.  If\r
297 >       * there are simply no signatures, this will be non-NULL with an\r
298 >       * empty signers list. */\r
299 >      const GMimeSignatureValidity *sig_validity;\r
300 > +#endif\r
301 >  \r
302 >      /* Internal: Context inherited from the root iterator. */\r
303 >      struct mime_node_context *ctx;\r
304 > @@ -319,8 +339,12 @@ typedef struct mime_node {\r
305 >   */\r
306 >  notmuch_status_t\r
307 >  mime_node_open (const void *ctx, notmuch_message_t *message,\r
308 > -             GMimeCipherContext *cryptoctx, notmuch_bool_t decrypt,\r
309 > -             mime_node_t **node_out);\r
310 > +#ifdef GMIME_26\r
311 > +             GMimeCryptoContext *cryptoctx,\r
312 > +#else\r
313 > +             GMimeCipherContext *cryptoctx,\r
314 > +#endif\r
315 > +             notmuch_bool_t decrypt, mime_node_t **node_out);\r
316 >  \r
317 >  /* Return a new MIME node for the requested child part of parent.\r
318 >   * parent will be used as the talloc context for the returned child\r
319 > diff --git a/notmuch-reply.c b/notmuch-reply.c\r
320 > index 0f682db..b3d7127 100644\r
321 > --- a/notmuch-reply.c\r
322 > +++ b/notmuch-reply.c\r
323 > @@ -688,15 +688,22 @@ notmuch_reply_command (void *ctx, int argc, char *argv[])\r
324 >       reply_format_func = notmuch_reply_format_default;\r
325 >  \r
326 >      if (decrypt) {\r
327 > +#ifdef GMIME_26\r
328 > +     /* TODO: GMimePasswordRequestFunc */\r
329 > +     params.cryptoctx = g_mime_gpg_context_new (NULL, "gpg");\r
330 > +#else\r
331 >       GMimeSession* session = g_object_new (g_mime_session_get_type(), NULL);\r
332 >       params.cryptoctx = g_mime_gpg_context_new (session, "gpg");\r
333 > +#endif\r
334 >       if (params.cryptoctx) {\r
335 >           g_mime_gpg_context_set_always_trust ((GMimeGpgContext*) params.cryptoctx, FALSE);\r
336 >           params.decrypt = TRUE;\r
337 >       } else {\r
338 >           fprintf (stderr, "Failed to construct gpg context.\n");\r
339 >       }\r
340 > +#ifndef GMIME_26\r
341 >       g_object_unref (session);\r
342 > +#endif\r
343 >      }\r
344 >  \r
345 >      config = notmuch_config_open (ctx, NULL, NULL);\r
346 > diff --git a/notmuch-show.c b/notmuch-show.c\r
347 > index 91f566c..10223e0 100644\r
348 > --- a/notmuch-show.c\r
349 > +++ b/notmuch-show.c\r
350 > @@ -76,7 +76,11 @@ static void\r
351 >  format_part_encstatus_json (int status);\r
352 >  \r
353 >  static void\r
354 > +#ifdef GMIME_26\r
355 > +format_part_sigstatus_json (GMimeSignatureList* siglist);\r
356 > +#else\r
357 >  format_part_sigstatus_json (const GMimeSignatureValidity* validity);\r
358 > +#endif\r
359 >  \r
360 >  static void\r
361 >  format_part_content_json (GMimeObject *part);\r
362 > @@ -486,6 +490,21 @@ show_text_part_content (GMimeObject *part, GMimeStream *stream_out)\r
363 >       g_object_unref(stream_filter);\r
364 >  }\r
365 >  \r
366 > +#ifdef GMIME_26\r
367 > +static const char*\r
368 > +signature_status_to_string (GMimeSignatureStatus x)\r
369 > +{\r
370 > +    switch (x) {\r
371 > +    case GMIME_SIGNATURE_STATUS_GOOD:\r
372 > +     return "good";\r
373 > +    case GMIME_SIGNATURE_STATUS_BAD:\r
374 > +     return "bad";\r
375 > +    case GMIME_SIGNATURE_STATUS_ERROR:\r
376 > +     return "error";\r
377 > +    }\r
378 > +    return "unknown";\r
379 > +}\r
380 > +#else\r
381 >  static const char*\r
382 >  signer_status_to_string (GMimeSignerStatus x)\r
383 >  {\r
384 > @@ -501,6 +520,7 @@ signer_status_to_string (GMimeSignerStatus x)\r
385 >      }\r
386 >      return "unknown";\r
387 >  }\r
388 > +#endif\r
389 >  \r
390 >  static void\r
391 >  format_part_start_text (GMimeObject *part, int *part_count)\r
392 > @@ -592,6 +612,73 @@ format_part_encstatus_json (int status)\r
393 >      printf ("}]");\r
394 >  }\r
395 >  \r
396 > +#ifdef GMIME_26\r
397 > +static void\r
398 > +format_part_sigstatus_json (GMimeSignatureList *siglist)\r
399 > +{\r
400 > +    printf (", \"sigstatus\": [");\r
401 > +\r
402 > +    if (!siglist) {\r
403 > +     printf ("]");\r
404 > +     return;\r
405 > +     }\r
406 \r
407 Indentation.\r
408 \r
409 > +\r
410 > +    void *ctx_quote = talloc_new (NULL);\r
411 > +    int i;\r
412 > +    for (i = 0; i < g_mime_signature_list_length (siglist); i++) {\r
413 > +     GMimeSignature *signature = g_mime_signature_list_get_signature (siglist, i);\r
414 > +\r
415 > +     if (i > 0)\r
416 > +         printf (", ");\r
417 > +\r
418 > +     printf ("{");\r
419 > +\r
420 > +     /* status */\r
421 > +     GMimeSignatureStatus status = g_mime_signature_get_status (signature);\r
422 > +     printf ("\"status\": %s",\r
423 > +             json_quote_str (ctx_quote,\r
424 > +                             signature_status_to_string (status)));\r
425 > +\r
426 > +     GMimeCertificate *certificate = g_mime_signature_get_certificate (signature);\r
427 > +     if (status == GMIME_SIGNATURE_STATUS_GOOD) {\r
428 > +         if (certificate)\r
429 > +             printf (", \"fingerprint\": %s", json_quote_str (ctx_quote, g_mime_certificate_get_fingerprint (certificate)));\r
430 > +         /* these dates are seconds since the epoch; should we\r
431 > +          * provide a more human-readable format string? */\r
432 > +         time_t created = g_mime_signature_get_created (signature);\r
433 > +         if (created != -1)\r
434 > +             printf (", \"created\": %d", (int) created);\r
435 > +         time_t expires = g_mime_signature_get_expires (signature);\r
436 > +         if (expires > 0)\r
437 > +             printf (", \"expires\": %d", (int) expires);\r
438 > +         /* output user id only if validity is FULL or ULTIMATE. */\r
439 > +         /* note that gmime is using the term "trust" here, which\r
440 > +          * is WRONG.  It's actually user id "validity". */\r
441 > +         if (certificate) {\r
442 > +             const char *name = g_mime_certificate_get_name (certificate);\r
443 > +             GMimeCertificateTrust trust = g_mime_certificate_get_trust (certificate);\r
444 > +             if (name && (trust == GMIME_CERTIFICATE_TRUST_FULLY || trust == GMIME_CERTIFICATE_TRUST_ULTIMATE))\r
445 > +                 printf (", \"userid\": %s", json_quote_str (ctx_quote, name));\r
446 > +         }\r
447 > +     } else if (certificate) {\r
448 > +         const char *key_id = g_mime_certificate_get_key_id (certificate);\r
449 > +         if (key_id)\r
450 > +             printf (", \"keyid\": %s", json_quote_str (ctx_quote, key_id));\r
451 > +     }\r
452 > +\r
453 > +     GMimeSignatureError errors = g_mime_signature_get_errors (signature);\r
454 > +     if (errors != GMIME_SIGNATURE_ERROR_NONE) {\r
455 > +         printf (", \"errors\": %d", errors);\r
456 > +     }\r
457 > +\r
458 > +     printf ("}");\r
459 > +     }\r
460 > +\r
461 > +    printf ("]");\r
462 > +\r
463 > +    talloc_free (ctx_quote);\r
464 > +}\r
465 > +#else\r
466 >  static void\r
467 >  format_part_sigstatus_json (const GMimeSignatureValidity* validity)\r
468 >  {\r
469 > @@ -652,6 +739,7 @@ format_part_sigstatus_json (const GMimeSignatureValidity* validity)\r
470 >  \r
471 >      talloc_free (ctx_quote);\r
472 >  }\r
473 > +#endif\r
474 >  \r
475 >  static void\r
476 >  format_part_content_json (GMimeObject *part)\r
477 > @@ -990,13 +1078,20 @@ notmuch_show_command (void *ctx, unused (int argc), unused (char *argv[]))\r
478 >       } else if ((STRNCMP_LITERAL (argv[i], "--verify") == 0) ||\r
479 >                  (STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) {\r
480 >           if (params.cryptoctx == NULL) {\r
481 > +#ifdef GMIME_26\r
482 > +             /* TODO: GMimePasswordRequestFunc */\r
483 > +             if (NULL == (params.cryptoctx = g_mime_gpg_context_new(NULL, "gpg")))\r
484 > +#else\r
485 >               GMimeSession* session = g_object_new(g_mime_session_get_type(), NULL);\r
486 >               if (NULL == (params.cryptoctx = g_mime_gpg_context_new(session, "gpg")))\r
487 > +#endif\r
488 >                   fprintf (stderr, "Failed to construct gpg context.\n");\r
489 >               else\r
490 >                   g_mime_gpg_context_set_always_trust((GMimeGpgContext*)params.cryptoctx, FALSE);\r
491 > +#ifndef GMIME_26\r
492 >               g_object_unref (session);\r
493 >               session = NULL;\r
494 > +#endif\r
495 >           }\r
496 >           if (STRNCMP_LITERAL (argv[i], "--decrypt") == 0)\r
497 >               params.decrypt = 1;\r
498 > diff --git a/show-message.c b/show-message.c\r
499 > index 8768889..65269fd 100644\r
500 > --- a/show-message.c\r
501 > +++ b/show-message.c\r
502 > @@ -48,7 +48,11 @@ show_message_part (mime_node_t *node,\r
503 >       format->part_encstatus (node->decrypt_success);\r
504 >  \r
505 >      if (node->verify_attempted && format->part_sigstatus)\r
506 > +#ifdef GMIME_26\r
507 > +     format->part_sigstatus (node->sig_list);\r
508 > +#else\r
509 >       format->part_sigstatus (node->sig_validity);\r
510 > +#endif\r
511 >  \r
512 >      format->part_content (part);\r
513 >  \r