Re: Hi all
[notmuch-archives.git] / b0 / 0f0e160fddeebac3b6ed3c150933a88d662ed7
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 C19BA6DE098A\r
6  for <notmuch@notmuchmail.org>; Fri,  8 Jul 2016 03:13:47 -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.067\r
10 X-Spam-Level: \r
11 X-Spam-Status: No, score=0.067 tagged_above=-999 required=5 tests=[AWL=0.067]\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 IrPYMG9PZmAP for <notmuch@notmuchmail.org>;\r
16  Fri,  8 Jul 2016 03:13:39 -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 0ECE76DE02D9\r
19  for <notmuch@notmuchmail.org>; Fri,  8 Jul 2016 03:13:12 -0700 (PDT)\r
20 Received: from fifthhorseman.net (unknown [88.128.80.54])\r
21  by che.mayfirst.org (Postfix) with ESMTPSA id 65A49F98B\r
22  for <notmuch@notmuchmail.org>; Fri,  8 Jul 2016 06:13:11 -0400 (EDT)\r
23 Received: by fifthhorseman.net (Postfix, from userid 1000)\r
24  id 8754120DE3; 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 02/16] Move crypto.c into libutil\r
28 Date: Fri,  8 Jul 2016 11:27:13 +0200\r
29 Message-Id: <1467970047-8013-3-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 MIME-Version: 1.0\r
34 Content-Type: text/plain; charset=UTF-8\r
35 Content-Transfer-Encoding: 8bit\r
36 X-BeenThere: notmuch@notmuchmail.org\r
37 X-Mailman-Version: 2.1.20\r
38 Precedence: list\r
39 List-Id: "Use and development of the notmuch mail system."\r
40  <notmuch.notmuchmail.org>\r
41 List-Unsubscribe: <https://notmuchmail.org/mailman/options/notmuch>,\r
42  <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
43 List-Archive: <http://notmuchmail.org/pipermail/notmuch/>\r
44 List-Post: <mailto:notmuch@notmuchmail.org>\r
45 List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
46 List-Subscribe: <https://notmuchmail.org/mailman/listinfo/notmuch>,\r
47  <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
48 X-List-Received-Date: Fri, 08 Jul 2016 10:13:47 -0000\r
49 \r
50 This prepares us for using the crypto object in both the library and\r
51 the client.\r
52 \r
53 i've prefixed notmuch_crypto with _ to indicate that while this can be\r
54 built into the library when needed, it's not something to be exported\r
55 or used externally.\r
56 ---\r
57  Makefile.local      |   1 -\r
58  crypto.c            | 134 --------------------------------------------------\r
59  mime-node.c         |  12 ++---\r
60  notmuch-client.h    |  23 ++-------\r
61  notmuch-reply.c     |   2 +-\r
62  notmuch-show.c      |   2 +-\r
63  util/Makefile.local |   2 +-\r
64  util/crypto.c       | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++\r
65  util/crypto.h       |  25 ++++++++++\r
66  9 files changed, 175 insertions(+), 164 deletions(-)\r
67  delete mode 100644 crypto.c\r
68  create mode 100644 util/crypto.c\r
69  create mode 100644 util/crypto.h\r
70 \r
71 diff --git a/Makefile.local b/Makefile.local\r
72 index f2ad0c1..c13ba76 100644\r
73 --- a/Makefile.local\r
74 +++ b/Makefile.local\r
75 @@ -293,7 +293,6 @@ notmuch_client_srcs =               \\r
76         sprinter-text.c         \\r
77         query-string.c          \\r
78         mime-node.c             \\r
79 -       crypto.c                \\r
80         tag-util.c\r
81  \r
82  notmuch_client_modules = $(notmuch_client_srcs:.c=.o)\r
83 diff --git a/crypto.c b/crypto.c\r
84 deleted file mode 100644\r
85 index 3e8ce7c..0000000\r
86 --- a/crypto.c\r
87 +++ /dev/null\r
88 @@ -1,134 +0,0 @@\r
89 -/* notmuch - Not much of an email program, (just index and search)\r
90 - *\r
91 - * Copyright © 2012 Jameson Rollins\r
92 - *\r
93 - * This program is free software: you can redistribute it and/or modify\r
94 - * it under the terms of the GNU General Public License as published by\r
95 - * the Free Software Foundation, either version 3 of the License, or\r
96 - * (at your option) any later version.\r
97 - *\r
98 - * This program is distributed in the hope that it will be useful,\r
99 - * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
100 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
101 - * GNU General Public License for more details.\r
102 - *\r
103 - * You should have received a copy of the GNU General Public License\r
104 - * along with this program.  If not, see https://www.gnu.org/licenses/ .\r
105 - *\r
106 - * Authors: Jameson Rollins <jrollins@finestructure.net>\r
107 - */\r
108 -\r
109 -#include "notmuch-client.h"\r
110 -\r
111 -/* Create a GPG context (GMime 2.6) */\r
112 -static notmuch_crypto_context_t *\r
113 -create_gpg_context (notmuch_crypto_t *crypto)\r
114 -{\r
115 -    notmuch_crypto_context_t *gpgctx;\r
116 -\r
117 -    if (crypto->gpgctx)\r
118 -       return crypto->gpgctx;\r
119 -\r
120 -    /* TODO: GMimePasswordRequestFunc */\r
121 -    gpgctx = g_mime_gpg_context_new (NULL, crypto->gpgpath ? crypto->gpgpath : "gpg");\r
122 -    if (! gpgctx) {\r
123 -       fprintf (stderr, "Failed to construct gpg context.\n");\r
124 -       return NULL;\r
125 -    }\r
126 -    crypto->gpgctx = gpgctx;\r
127 -\r
128 -    g_mime_gpg_context_set_use_agent ((GMimeGpgContext *) gpgctx, TRUE);\r
129 -    g_mime_gpg_context_set_always_trust ((GMimeGpgContext *) gpgctx, FALSE);\r
130 -\r
131 -    return gpgctx;\r
132 -}\r
133 -\r
134 -/* Create a PKCS7 context (GMime 2.6) */\r
135 -static notmuch_crypto_context_t *\r
136 -create_pkcs7_context (notmuch_crypto_t *crypto)\r
137 -{\r
138 -    notmuch_crypto_context_t *pkcs7ctx;\r
139 -\r
140 -    if (crypto->pkcs7ctx)\r
141 -       return crypto->pkcs7ctx;\r
142 -\r
143 -    /* TODO: GMimePasswordRequestFunc */\r
144 -    pkcs7ctx = g_mime_pkcs7_context_new (NULL);\r
145 -    if (! pkcs7ctx) {\r
146 -       fprintf (stderr, "Failed to construct pkcs7 context.\n");\r
147 -       return NULL;\r
148 -    }\r
149 -    crypto->pkcs7ctx = pkcs7ctx;\r
150 -\r
151 -    g_mime_pkcs7_context_set_always_trust ((GMimePkcs7Context *) pkcs7ctx,\r
152 -                                          FALSE);\r
153 -\r
154 -    return pkcs7ctx;\r
155 -}\r
156 -static const struct {\r
157 -    const char *protocol;\r
158 -    notmuch_crypto_context_t *(*get_context) (notmuch_crypto_t *crypto);\r
159 -} protocols[] = {\r
160 -    {\r
161 -       .protocol = "application/pgp-signature",\r
162 -       .get_context = create_gpg_context,\r
163 -    },\r
164 -    {\r
165 -       .protocol = "application/pgp-encrypted",\r
166 -       .get_context = create_gpg_context,\r
167 -    },\r
168 -    {\r
169 -       .protocol = "application/pkcs7-signature",\r
170 -       .get_context = create_pkcs7_context,\r
171 -    },\r
172 -    {\r
173 -       .protocol = "application/x-pkcs7-signature",\r
174 -       .get_context = create_pkcs7_context,\r
175 -    },\r
176 -};\r
177 -\r
178 -/* for the specified protocol return the context pointer (initializing\r
179 - * if needed) */\r
180 -notmuch_crypto_context_t *\r
181 -notmuch_crypto_get_context (notmuch_crypto_t *crypto, const char *protocol)\r
182 -{\r
183 -    notmuch_crypto_context_t *cryptoctx = NULL;\r
184 -    size_t i;\r
185 -\r
186 -    if (! protocol) {\r
187 -       fprintf (stderr, "Cryptographic protocol is empty.\n");\r
188 -       return cryptoctx;\r
189 -    }\r
190 -\r
191 -    /* As per RFC 1847 section 2.1: "the [protocol] value token is\r
192 -     * comprised of the type and sub-type tokens of the Content-Type".\r
193 -     * As per RFC 1521 section 2: "Content-Type values, subtypes, and\r
194 -     * parameter names as defined in this document are\r
195 -     * case-insensitive."  Thus, we use strcasecmp for the protocol.\r
196 -     */\r
197 -    for (i = 0; i < ARRAY_SIZE (protocols); i++) {\r
198 -       if (strcasecmp (protocol, protocols[i].protocol) == 0)\r
199 -           return protocols[i].get_context (crypto);\r
200 -    }\r
201 -\r
202 -    fprintf (stderr, "Unknown or unsupported cryptographic protocol %s.\n",\r
203 -            protocol);\r
204 -\r
205 -    return NULL;\r
206 -}\r
207 -\r
208 -int\r
209 -notmuch_crypto_cleanup (notmuch_crypto_t *crypto)\r
210 -{\r
211 -    if (crypto->gpgctx) {\r
212 -       g_object_unref (crypto->gpgctx);\r
213 -       crypto->gpgctx = NULL;\r
214 -    }\r
215 -\r
216 -    if (crypto->pkcs7ctx) {\r
217 -       g_object_unref (crypto->pkcs7ctx);\r
218 -       crypto->pkcs7ctx = NULL;\r
219 -    }\r
220 -\r
221 -    return 0;\r
222 -}\r
223 diff --git a/mime-node.c b/mime-node.c\r
224 index c9b8233..14873ce 100644\r
225 --- a/mime-node.c\r
226 +++ b/mime-node.c\r
227 @@ -33,7 +33,7 @@ typedef struct mime_node_context {\r
228      GMimeMessage *mime_message;\r
229  \r
230      /* Context provided by the caller. */\r
231 -    notmuch_crypto_t *crypto;\r
232 +    _notmuch_crypto_t *crypto;\r
233  } mime_node_context_t;\r
234  \r
235  static int\r
236 @@ -56,7 +56,7 @@ _mime_node_context_free (mime_node_context_t *res)\r
237  \r
238  notmuch_status_t\r
239  mime_node_open (const void *ctx, notmuch_message_t *message,\r
240 -               notmuch_crypto_t *crypto, mime_node_t **root_out)\r
241 +               _notmuch_crypto_t *crypto, mime_node_t **root_out)\r
242  {\r
243      const char *filename = notmuch_message_get_filename (message);\r
244      mime_node_context_t *mctx;\r
245 @@ -151,7 +151,7 @@ set_signature_list_destructor (mime_node_t *node)\r
246  /* Verify a signed mime node (GMime 2.6) */\r
247  static void\r
248  node_verify (mime_node_t *node, GMimeObject *part,\r
249 -            notmuch_crypto_context_t *cryptoctx)\r
250 +            GMimeCryptoContext *cryptoctx)\r
251  {\r
252      GError *err = NULL;\r
253  \r
254 @@ -172,7 +172,7 @@ node_verify (mime_node_t *node, GMimeObject *part,\r
255  /* Decrypt and optionally verify an encrypted mime node (GMime 2.6) */\r
256  static void\r
257  node_decrypt_and_verify (mime_node_t *node, GMimeObject *part,\r
258 -                        notmuch_crypto_context_t *cryptoctx)\r
259 +                        GMimeCryptoContext *cryptoctx)\r
260  {\r
261      GError *err = NULL;\r
262      GMimeDecryptResult *decrypt_result = NULL;\r
263 @@ -207,7 +207,7 @@ static mime_node_t *\r
264  _mime_node_create (mime_node_t *parent, GMimeObject *part)\r
265  {\r
266      mime_node_t *node = talloc_zero (parent, mime_node_t);\r
267 -    notmuch_crypto_context_t *cryptoctx = NULL;\r
268 +    GMimeCryptoContext *cryptoctx = NULL;\r
269  \r
270      /* Set basic node properties */\r
271      node->part = part;\r
272 @@ -244,7 +244,7 @@ _mime_node_create (mime_node_t *parent, GMimeObject *part)\r
273         || (GMIME_IS_MULTIPART_SIGNED (part) && node->ctx->crypto->verify)) {\r
274         GMimeContentType *content_type = g_mime_object_get_content_type (part);\r
275         const char *protocol = g_mime_content_type_get_parameter (content_type, "protocol");\r
276 -       cryptoctx = notmuch_crypto_get_context (node->ctx->crypto, protocol);\r
277 +       cryptoctx = _notmuch_crypto_get_gmime_context (node->ctx->crypto, protocol);\r
278      }\r
279  \r
280      /* Handle PGP/MIME parts */\r
281 diff --git a/notmuch-client.h b/notmuch-client.h\r
282 index 9ce2aef..a65bb6d 100644\r
283 --- a/notmuch-client.h\r
284 +++ b/notmuch-client.h\r
285 @@ -30,10 +30,6 @@\r
286  \r
287  #include <gmime/gmime.h>\r
288  \r
289 -typedef GMimeCryptoContext notmuch_crypto_context_t;\r
290 -/* This is automatically included only since gmime 2.6.10 */\r
291 -#include <gmime/gmime-pkcs7-context.h>\r
292 -\r
293  #include "notmuch.h"\r
294  \r
295  /* This is separate from notmuch-private.h because we're trying to\r
296 @@ -53,6 +49,7 @@ typedef GMimeCryptoContext notmuch_crypto_context_t;\r
297  #include <ctype.h>\r
298  \r
299  #include "talloc-extra.h"\r
300 +#include "crypto.h"\r
301  \r
302  #define unused(x) x __attribute__ ((unused))\r
303  \r
304 @@ -70,21 +67,13 @@ typedef struct notmuch_show_format {\r
305                               const struct notmuch_show_params *params);\r
306  } notmuch_show_format_t;\r
307  \r
308 -typedef struct notmuch_crypto {\r
309 -    notmuch_crypto_context_t* gpgctx;\r
310 -    notmuch_crypto_context_t* pkcs7ctx;\r
311 -    notmuch_bool_t verify;\r
312 -    notmuch_bool_t decrypt;\r
313 -    const char *gpgpath;\r
314 -} notmuch_crypto_t;\r
315 -\r
316  typedef struct notmuch_show_params {\r
317      notmuch_bool_t entire_thread;\r
318      notmuch_bool_t omit_excluded;\r
319      notmuch_bool_t output_body;\r
320      notmuch_bool_t raw;\r
321      int part;\r
322 -    notmuch_crypto_t crypto;\r
323 +    _notmuch_crypto_t crypto;\r
324      notmuch_bool_t include_html;\r
325  } notmuch_show_params_t;\r
326  \r
327 @@ -167,12 +156,6 @@ typedef struct _notmuch_config notmuch_config_t;\r
328  void\r
329  notmuch_exit_if_unsupported_format (void);\r
330  \r
331 -notmuch_crypto_context_t *\r
332 -notmuch_crypto_get_context (notmuch_crypto_t *crypto, const char *protocol);\r
333 -\r
334 -int\r
335 -notmuch_crypto_cleanup (notmuch_crypto_t *crypto);\r
336 -\r
337  int\r
338  notmuch_count_command (notmuch_config_t *config, int argc, char *argv[]);\r
339  \r
340 @@ -423,7 +406,7 @@ struct mime_node {\r
341   */\r
342  notmuch_status_t\r
343  mime_node_open (const void *ctx, notmuch_message_t *message,\r
344 -               notmuch_crypto_t *crypto, mime_node_t **node_out);\r
345 +               _notmuch_crypto_t *crypto, mime_node_t **node_out);\r
346  \r
347  /* Return a new MIME node for the requested child part of parent.\r
348   * parent will be used as the talloc context for the returned child\r
349 diff --git a/notmuch-reply.c b/notmuch-reply.c\r
350 index 4951373..42aef47 100644\r
351 --- a/notmuch-reply.c\r
352 +++ b/notmuch-reply.c\r
353 @@ -862,7 +862,7 @@ notmuch_reply_command (notmuch_config_t *config, int argc, char *argv[])\r
354      if (reply_format_func (config, config, query, &params, reply_all, sp) != 0)\r
355         return EXIT_FAILURE;\r
356  \r
357 -    notmuch_crypto_cleanup (&params.crypto);\r
358 +    _notmuch_crypto_cleanup (&params.crypto);\r
359      notmuch_query_destroy (query);\r
360      notmuch_database_destroy (notmuch);\r
361  \r
362 diff --git a/notmuch-show.c b/notmuch-show.c\r
363 index 22fa655..8ebf4ff 100644\r
364 --- a/notmuch-show.c\r
365 +++ b/notmuch-show.c\r
366 @@ -1171,7 +1171,7 @@ notmuch_show_command (notmuch_config_t *config, int argc, char *argv[])\r
367         ret = do_show (config, query, format, sprinter, &params);\r
368      }\r
369  \r
370 -    notmuch_crypto_cleanup (&params.crypto);\r
371 +    _notmuch_crypto_cleanup (&params.crypto);\r
372      notmuch_query_destroy (query);\r
373      notmuch_database_destroy (notmuch);\r
374  \r
375 diff --git a/util/Makefile.local b/util/Makefile.local\r
376 index 8b2b91b..7590618 100644\r
377 --- a/util/Makefile.local\r
378 +++ b/util/Makefile.local\r
379 @@ -5,7 +5,7 @@ extra_cflags += -I$(srcdir)/$(dir)\r
380  \r
381  libutil_c_srcs := $(dir)/xutil.c $(dir)/error_util.c $(dir)/hex-escape.c \\r
382                   $(dir)/string-util.c $(dir)/talloc-extra.c $(dir)/zlib-extra.c \\r
383 -               $(dir)/util.c $(dir)/search-path.c\r
384 +               $(dir)/util.c $(dir)/search-path.c $(dir)/crypto.c\r
385  \r
386  libutil_modules := $(libutil_c_srcs:.c=.o)\r
387  \r
388 diff --git a/util/crypto.c b/util/crypto.c\r
389 new file mode 100644\r
390 index 0000000..48c20bb\r
391 --- /dev/null\r
392 +++ b/util/crypto.c\r
393 @@ -0,0 +1,138 @@\r
394 +/* notmuch - Not much of an email program, (just index and search)\r
395 + *\r
396 + * Copyright © 2012 Jameson Rollins\r
397 + *\r
398 + * This program is free software: you can redistribute it and/or modify\r
399 + * it under the terms of the GNU General Public License as published by\r
400 + * the Free Software Foundation, either version 3 of the License, or\r
401 + * (at your option) any later version.\r
402 + *\r
403 + * This program is distributed in the hope that it will be useful,\r
404 + * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
405 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
406 + * GNU General Public License for more details.\r
407 + *\r
408 + * You should have received a copy of the GNU General Public License\r
409 + * along with this program.  If not, see https://www.gnu.org/licenses/ .\r
410 + *\r
411 + * Authors: Jameson Rollins <jrollins@finestructure.net>\r
412 + *          Daniel Kahn Gillmor <dkg@fifthhorseman.net>\r
413 + */\r
414 +\r
415 +#include "notmuch.h"\r
416 +#include "crypto.h"\r
417 +#include <string.h>\r
418 +\r
419 +#define ARRAY_SIZE(arr) (sizeof (arr) / sizeof (arr[0]))\r
420 +\r
421 +/* Create a GPG context (GMime 2.6) */\r
422 +static GMimeCryptoContext*\r
423 +create_gpg_context (_notmuch_crypto_t *crypto)\r
424 +{\r
425 +    GMimeCryptoContext *gpgctx;\r
426 +\r
427 +    if (crypto->gpgctx) {\r
428 +       return crypto->gpgctx;\r
429 +    }\r
430 +\r
431 +    /* TODO: GMimePasswordRequestFunc */\r
432 +    gpgctx = g_mime_gpg_context_new (NULL, crypto->gpgpath ? crypto->gpgpath : "gpg");\r
433 +    if (! gpgctx) {\r
434 +       fprintf (stderr, "Failed to construct gpg context.\n");\r
435 +       return NULL;\r
436 +    }\r
437 +    crypto->gpgctx = gpgctx;\r
438 +\r
439 +    g_mime_gpg_context_set_use_agent ((GMimeGpgContext *) gpgctx, TRUE);\r
440 +    g_mime_gpg_context_set_always_trust ((GMimeGpgContext *) gpgctx, FALSE);\r
441 +\r
442 +    return crypto->gpgctx;\r
443 +}\r
444 +\r
445 +/* Create a PKCS7 context (GMime 2.6) */\r
446 +static notmuch_crypto_context_t *\r
447 +create_pkcs7_context (notmuch_crypto_t *crypto)\r
448 +{\r
449 +    notmuch_crypto_context_t *pkcs7ctx;\r
450 +\r
451 +    if (crypto->pkcs7ctx)\r
452 +       return crypto->pkcs7ctx;\r
453 +\r
454 +    /* TODO: GMimePasswordRequestFunc */\r
455 +    pkcs7ctx = g_mime_pkcs7_context_new (NULL);\r
456 +    if (! pkcs7ctx) {\r
457 +       fprintf (stderr, "Failed to construct pkcs7 context.\n");\r
458 +       return NULL;\r
459 +    }\r
460 +    crypto->pkcs7ctx = pkcs7ctx;\r
461 +\r
462 +    g_mime_pkcs7_context_set_always_trust ((GMimePkcs7Context *) pkcs7ctx,\r
463 +                                          FALSE);\r
464 +\r
465 +    return crypto->pkcs7ctx;\r
466 +}\r
467 +static const struct {\r
468 +    const char *protocol;\r
469 +    GMimeCryptoContext *(*get_context) (_notmuch_crypto_t *crypto);\r
470 +} protocols[] = {\r
471 +    {\r
472 +       .protocol = "application/pgp-signature",\r
473 +       .get_context = create_gpg_context,\r
474 +    },\r
475 +    {\r
476 +       .protocol = "application/pgp-encrypted",\r
477 +       .get_context = create_gpg_context,\r
478 +    },\r
479 +    {\r
480 +       .protocol = "application/pkcs7-signature",\r
481 +       .get_context = create_pkcs7_context,\r
482 +    },\r
483 +    {\r
484 +       .protocol = "application/x-pkcs7-signature",\r
485 +       .get_context = create_pkcs7_context,\r
486 +    },\r
487 +};\r
488 +\r
489 +/* for the specified protocol return the context pointer (initializing\r
490 + * if needed) */\r
491 +GMimeCryptoContext *\r
492 +_notmuch_crypto_get_gmime_context (_notmuch_crypto_t *crypto, const char *protocol)\r
493 +{\r
494 +    GMimeCryptoContext *cryptoctx = NULL;\r
495 +    size_t i;\r
496 +\r
497 +    if (! protocol) {\r
498 +       fprintf (stderr, "Cryptographic protocol is empty.\n");\r
499 +       return cryptoctx;\r
500 +    }\r
501 +\r
502 +    /* As per RFC 1847 section 2.1: "the [protocol] value token is\r
503 +     * comprised of the type and sub-type tokens of the Content-Type".\r
504 +     * As per RFC 1521 section 2: "Content-Type values, subtypes, and\r
505 +     * parameter names as defined in this document are\r
506 +     * case-insensitive."  Thus, we use strcasecmp for the protocol.\r
507 +     */\r
508 +    for (i = 0; i < ARRAY_SIZE (protocols); i++) {\r
509 +       if (strcasecmp (protocol, protocols[i].protocol) == 0)\r
510 +           return protocols[i].get_context (crypto);\r
511 +    }\r
512 +\r
513 +    fprintf (stderr, "Unknown or unsupported cryptographic protocol %s.\n",\r
514 +            protocol);\r
515 +\r
516 +    return NULL;\r
517 +}\r
518 +\r
519 +void\r
520 +_notmuch_crypto_cleanup (_notmuch_crypto_t *crypto)\r
521 +{\r
522 +    if (crypto->gpgctx) {\r
523 +       g_object_unref (crypto->gpgctx);\r
524 +       crypto->gpgctx = NULL;\r
525 +    }\r
526 +\r
527 +    if (crypto->pkcs7ctx) {\r
528 +       g_object_unref (crypto->pkcs7ctx);\r
529 +       crypto->pkcs7ctx = NULL;\r
530 +    }\r
531 +}\r
532 diff --git a/util/crypto.h b/util/crypto.h\r
533 new file mode 100644\r
534 index 0000000..d4a51e8\r
535 --- /dev/null\r
536 +++ b/util/crypto.h\r
537 @@ -0,0 +1,25 @@\r
538 +#ifndef _CRYPTO_H\r
539 +#define _CRYPTO_H\r
540 +\r
541 +#include "notmuch.h"\r
542 +#include <gmime/gmime.h>\r
543 +/* This is automatically included only since gmime 2.6.10 */\r
544 +#include <gmime/gmime-pkcs7-context.h>\r
545 +\r
546 +typedef struct _notmuch_crypto {\r
547 +    GMimeCryptoContext* gpgctx;\r
548 +    GMimeCryptoContext* pkcs7ctx;\r
549 +    notmuch_bool_t verify;\r
550 +    notmuch_bool_t decrypt;\r
551 +    const char *gpgpath;\r
552 +} _notmuch_crypto_t;\r
553 +\r
554 +\r
555 +GMimeCryptoContext *\r
556 +_notmuch_crypto_get_gmime_context (_notmuch_crypto_t *crypto, const char *protocol);\r
557 +\r
558 +void\r
559 +_notmuch_crypto_cleanup (_notmuch_crypto_t *crypto);\r
560 +\r
561 +\r
562 +#endif\r
563 -- \r
564 2.8.1\r
565 \r