Initialize the gmime for upstream
[platform/upstream/gmime.git] / gmime / gmime-gpg-context.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*  GMime
3  *  Copyright (C) 2000-2012 Jeffrey Stedfast
4  *
5  *  This library is free software; you can redistribute it and/or
6  *  modify it under the terms of the GNU Lesser General Public License
7  *  as published by the Free Software Foundation; either version 2.1
8  *  of the License, or (at your option) any later version.
9  *
10  *  This library is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  *  Lesser General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Lesser General Public
16  *  License along with this library; if not, write to the Free
17  *  Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
18  *  02110-1301, USA.
19  */
20
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #ifdef __APPLE__
27 #undef HAVE_POLL_H
28 #undef HAVE_POLL
29 typedef unsigned int nfds_t;
30 #endif
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <sys/time.h>
36 #include <sys/types.h>
37 #include <sys/ioctl.h>
38 #include <sys/stat.h>
39 #include <sys/wait.h>
40 #include <termios.h>
41 #include <signal.h>
42 #include <unistd.h>
43 #include <fcntl.h>
44 #include <errno.h>
45 #include <ctype.h>
46 #ifdef HAVE_POLL_H
47 #include <poll.h>
48 #endif
49
50 #include "gmime-gpg-context.h"
51 #ifdef ENABLE_CRYPTOGRAPHY
52 #include "gmime-filter-charset.h"
53 #include "gmime-stream-filter.h"
54 #include "gmime-stream-pipe.h"
55 #include "gmime-stream-mem.h"
56 #include "gmime-stream-fs.h"
57 #include "gmime-charset.h"
58 #endif /* ENABLE_CRYPTOGRAPHY */
59 #include "gmime-error.h"
60
61 #ifdef ENABLE_DEBUG
62 #define d(x) x
63 #else
64 #define d(x)
65 #endif
66
67 #define _(x) x
68
69
70 /**
71  * SECTION: gmime-gpg-context
72  * @title: GMimeGpgContext
73  * @short_description: GnuPG crypto contexts
74  * @see_also: #GMimeCryptoContext
75  *
76  * A #GMimeGpgContext is a #GMimeCryptoContext that uses GnuPG to do
77  * all of the encryption and digital signatures.
78  **/
79
80
81 static void g_mime_gpg_context_class_init (GMimeGpgContextClass *klass);
82 static void g_mime_gpg_context_init (GMimeGpgContext *ctx, GMimeGpgContextClass *klass);
83 static void g_mime_gpg_context_finalize (GObject *object);
84
85 static GMimeDigestAlgo gpg_digest_id (GMimeCryptoContext *ctx, const char *name);
86
87 static const char *gpg_digest_name (GMimeCryptoContext *ctx, GMimeDigestAlgo digest);
88
89 static int gpg_sign (GMimeCryptoContext *ctx, const char *userid,
90                      GMimeDigestAlgo digest, GMimeStream *istream,
91                      GMimeStream *ostream, GError **err);
92
93 static const char *gpg_get_signature_protocol (GMimeCryptoContext *ctx);
94
95 static const char *gpg_get_encryption_protocol (GMimeCryptoContext *ctx);
96
97 static const char *gpg_get_key_exchange_protocol (GMimeCryptoContext *ctx);
98
99 static GMimeSignatureList *gpg_verify (GMimeCryptoContext *ctx, GMimeDigestAlgo digest,
100                                        GMimeStream *istream, GMimeStream *sigstream,
101                                        GError **err);
102
103 static int gpg_encrypt (GMimeCryptoContext *ctx, gboolean sign, const char *userid,
104                         GMimeDigestAlgo digest, GPtrArray *recipients, GMimeStream *istream,
105                         GMimeStream *ostream, GError **err);
106
107 static GMimeDecryptResult *gpg_decrypt (GMimeCryptoContext *ctx, GMimeStream *istream,
108                                         GMimeStream *ostream, GError **err);
109
110 static int gpg_import_keys (GMimeCryptoContext *ctx, GMimeStream *istream,
111                             GError **err);
112
113 static int gpg_export_keys (GMimeCryptoContext *ctx, GPtrArray *keys,
114                             GMimeStream *ostream, GError **err);
115
116
117 static GMimeCryptoContextClass *parent_class = NULL;
118
119
120 GType
121 g_mime_gpg_context_get_type (void)
122 {
123         static GType type = 0;
124         
125         if (!type) {
126                 static const GTypeInfo info = {
127                         sizeof (GMimeGpgContextClass),
128                         NULL, /* base_class_init */
129                         NULL, /* base_class_finalize */
130                         (GClassInitFunc) g_mime_gpg_context_class_init,
131                         NULL, /* class_finalize */
132                         NULL, /* class_data */
133                         sizeof (GMimeGpgContext),
134                         0,    /* n_preallocs */
135                         (GInstanceInitFunc) g_mime_gpg_context_init,
136                 };
137                 
138                 type = g_type_register_static (GMIME_TYPE_CRYPTO_CONTEXT, "GMimeGpgContext", &info, 0);
139         }
140         
141         return type;
142 }
143
144
145 static void
146 g_mime_gpg_context_class_init (GMimeGpgContextClass *klass)
147 {
148         GObjectClass *object_class = G_OBJECT_CLASS (klass);
149         GMimeCryptoContextClass *crypto_class = GMIME_CRYPTO_CONTEXT_CLASS (klass);
150         
151         parent_class = g_type_class_ref (G_TYPE_OBJECT);
152         
153         object_class->finalize = g_mime_gpg_context_finalize;
154         
155         crypto_class->digest_id = gpg_digest_id;
156         crypto_class->digest_name = gpg_digest_name;
157         crypto_class->sign = gpg_sign;
158         crypto_class->verify = gpg_verify;
159         crypto_class->encrypt = gpg_encrypt;
160         crypto_class->decrypt = gpg_decrypt;
161         crypto_class->import_keys = gpg_import_keys;
162         crypto_class->export_keys = gpg_export_keys;
163         crypto_class->get_signature_protocol = gpg_get_signature_protocol;
164         crypto_class->get_encryption_protocol = gpg_get_encryption_protocol;
165         crypto_class->get_key_exchange_protocol = gpg_get_key_exchange_protocol;
166 }
167
168 static void
169 g_mime_gpg_context_init (GMimeGpgContext *ctx, GMimeGpgContextClass *klass)
170 {
171         ctx->auto_key_retrieve = FALSE;
172         ctx->always_trust = FALSE;
173         ctx->use_agent = FALSE;
174         ctx->path = NULL;
175 }
176
177 static void
178 g_mime_gpg_context_finalize (GObject *object)
179 {
180         GMimeGpgContext *ctx = (GMimeGpgContext *) object;
181         
182         g_free (ctx->path);
183         
184         G_OBJECT_CLASS (parent_class)->finalize (object);
185 }
186
187 static GMimeDigestAlgo
188 gpg_digest_id (GMimeCryptoContext *ctx, const char *name)
189 {
190         if (name == NULL)
191                 return GMIME_DIGEST_ALGO_DEFAULT;
192         
193         if (!g_ascii_strcasecmp (name, "pgp-"))
194                 name += 4;
195         
196         if (!g_ascii_strcasecmp (name, "md2"))
197                 return GMIME_DIGEST_ALGO_MD2;
198         else if (!g_ascii_strcasecmp (name, "md4"))
199                 return GMIME_DIGEST_ALGO_MD4;
200         else if (!g_ascii_strcasecmp (name, "md5"))
201                 return GMIME_DIGEST_ALGO_MD5;
202         else if (!g_ascii_strcasecmp (name, "sha1"))
203                 return GMIME_DIGEST_ALGO_SHA1;
204         else if (!g_ascii_strcasecmp (name, "sha224"))
205                 return GMIME_DIGEST_ALGO_SHA224;
206         else if (!g_ascii_strcasecmp (name, "sha256"))
207                 return GMIME_DIGEST_ALGO_SHA256;
208         else if (!g_ascii_strcasecmp (name, "sha384"))
209                 return GMIME_DIGEST_ALGO_SHA384;
210         else if (!g_ascii_strcasecmp (name, "sha512"))
211                 return GMIME_DIGEST_ALGO_SHA512;
212         else if (!g_ascii_strcasecmp (name, "ripemd160"))
213                 return GMIME_DIGEST_ALGO_RIPEMD160;
214         else if (!g_ascii_strcasecmp (name, "tiger192"))
215                 return GMIME_DIGEST_ALGO_TIGER192;
216         else if (!g_ascii_strcasecmp (name, "haval-5-160"))
217                 return GMIME_DIGEST_ALGO_HAVAL5160;
218         
219         return GMIME_DIGEST_ALGO_DEFAULT;
220 }
221
222 static const char *
223 gpg_digest_name (GMimeCryptoContext *ctx, GMimeDigestAlgo digest)
224 {
225         switch (digest) {
226         case GMIME_DIGEST_ALGO_MD2:
227                 return "pgp-md2";
228         case GMIME_DIGEST_ALGO_MD4:
229                 return "pgp-md4";
230         case GMIME_DIGEST_ALGO_MD5:
231                 return "pgp-md5";
232         case GMIME_DIGEST_ALGO_SHA1:
233                 return "pgp-sha1";
234         case GMIME_DIGEST_ALGO_SHA224:
235                 return "pgp-sha224";
236         case GMIME_DIGEST_ALGO_SHA256:
237                 return "pgp-sha256";
238         case GMIME_DIGEST_ALGO_SHA384:
239                 return "pgp-sha384";
240         case GMIME_DIGEST_ALGO_SHA512:
241                 return "pgp-sha512";
242         case GMIME_DIGEST_ALGO_RIPEMD160:
243                 return "pgp-ripemd160";
244         case GMIME_DIGEST_ALGO_TIGER192:
245                 return "pgp-tiger192";
246         case GMIME_DIGEST_ALGO_HAVAL5160:
247                 return "pgp-haval-5-160";
248         default:
249                 return "pgp-sha1";
250         }
251 }
252
253 static const char *
254 gpg_get_signature_protocol (GMimeCryptoContext *ctx)
255 {
256         return "application/pgp-signature";
257 }
258
259 static const char *
260 gpg_get_encryption_protocol (GMimeCryptoContext *ctx)
261 {
262         return "application/pgp-encrypted";
263 }
264
265 static const char *
266 gpg_get_key_exchange_protocol (GMimeCryptoContext *ctx)
267 {
268         return "application/pgp-keys";
269 }
270
271 #ifdef ENABLE_CRYPTOGRAPHY
272 enum _GpgCtxMode {
273         GPG_CTX_MODE_SIGN,
274         GPG_CTX_MODE_VERIFY,
275         GPG_CTX_MODE_ENCRYPT,
276         GPG_CTX_MODE_SIGN_ENCRYPT,
277         GPG_CTX_MODE_DECRYPT,
278         GPG_CTX_MODE_IMPORT,
279         GPG_CTX_MODE_EXPORT,
280 };
281
282 struct _GpgCtx {
283         enum _GpgCtxMode mode;
284         GHashTable *userid_hint;
285         GMimeGpgContext *ctx;
286         pid_t pid;
287         
288         char *userid;
289         GPtrArray *recipients;
290         GMimeCipherAlgo cipher;
291         GMimeDigestAlgo digest;
292         
293         int stdin_fd;
294         int stdout_fd;
295         int stderr_fd;
296         int status_fd;
297         int secret_fd;  /* used for sign/decrypt/verify */
298         
299         /* status-fd buffer */
300         char *statusbuf;
301         char *statusptr;
302         guint statusleft;
303         
304         char *need_id;
305         
306         GMimeStream *sigstream;
307         GMimeStream *istream;
308         GMimeStream *ostream;
309         
310         GByteArray *diag;
311         GMimeStream *diagnostics;
312         
313         GMimeCertificateList *encrypted_to;  /* full list of encrypted-to recipients */
314         GMimeSignatureList *signatures;
315         GMimeSignature *signature;
316         
317         int exit_status;
318         
319         unsigned int utf8:1;
320         unsigned int exited:1;
321         unsigned int complete:1;
322         unsigned int seen_eof1:1;
323         unsigned int seen_eof2:1;
324         unsigned int flushed:1;      /* flushed the diagnostics stream (aka stderr) */
325         unsigned int always_trust:1;
326         unsigned int use_agent:1;
327         unsigned int armor:1;
328         unsigned int need_passwd:1;
329         unsigned int bad_passwds:2;
330         unsigned int decrypt_okay:1;
331         
332         unsigned int padding:19;
333 };
334
335 static struct _GpgCtx *
336 gpg_ctx_new (GMimeGpgContext *ctx)
337 {
338         struct _GpgCtx *gpg;
339         const char *charset;
340         GMimeStream *stream;
341         
342         gpg = g_slice_new (struct _GpgCtx);
343         gpg->mode = GPG_CTX_MODE_SIGN;
344         gpg->ctx = ctx;
345         gpg->userid_hint = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
346         gpg->decrypt_okay = FALSE;
347         gpg->complete = FALSE;
348         gpg->seen_eof1 = TRUE;
349         gpg->seen_eof2 = FALSE;
350         gpg->pid = (pid_t) -1;
351         gpg->exit_status = 0;
352         gpg->flushed = FALSE;
353         gpg->exited = FALSE;
354         
355         gpg->userid = NULL;
356         gpg->recipients = NULL;
357         gpg->cipher = GMIME_CIPHER_ALGO_DEFAULT;
358         gpg->digest = GMIME_DIGEST_ALGO_DEFAULT;
359         gpg->always_trust = FALSE;
360         gpg->use_agent = FALSE;
361         gpg->armor = FALSE;
362         
363         gpg->stdin_fd = -1;
364         gpg->stdout_fd = -1;
365         gpg->stderr_fd = -1;
366         gpg->status_fd = -1;
367         gpg->secret_fd = -1;
368         
369         gpg->statusbuf = g_malloc (128);
370         gpg->statusptr = gpg->statusbuf;
371         gpg->statusleft = 128;
372         
373         gpg->bad_passwds = 0;
374         gpg->need_passwd = FALSE;
375         gpg->need_id = NULL;
376         
377         gpg->encrypted_to = NULL;
378         gpg->signatures = NULL;
379         gpg->signature = NULL;
380         
381         gpg->sigstream = NULL;
382         gpg->istream = NULL;
383         gpg->ostream = NULL;
384         
385         stream = g_mime_stream_mem_new ();
386         gpg->diag = GMIME_STREAM_MEM (stream)->buffer;
387         charset = g_mime_charset_iconv_name (g_mime_locale_charset ());
388         if (g_ascii_strcasecmp (charset, "UTF-8") != 0) {
389                 GMimeStream *fstream;
390                 GMimeFilter *filter;
391                 
392                 fstream = g_mime_stream_filter_new (stream);
393                 filter = g_mime_filter_charset_new (charset, "UTF-8");
394                 g_mime_stream_filter_add ((GMimeStreamFilter *) fstream, filter);
395                 g_object_unref (stream);
396                 g_object_unref (filter);
397                 
398                 gpg->diagnostics = fstream;
399                 
400                 gpg->utf8 = FALSE;
401         } else {
402                 /* system charset is UTF-8, shouldn't need any conversion */
403                 gpg->diagnostics = stream;
404                 
405                 gpg->utf8 = TRUE;
406         }
407         
408         return gpg;
409 }
410
411 static void
412 gpg_ctx_set_mode (struct _GpgCtx *gpg, enum _GpgCtxMode mode)
413 {
414         gpg->mode = mode;
415         gpg->need_passwd = ((gpg->mode == GPG_CTX_MODE_SIGN) || (gpg->mode == GPG_CTX_MODE_DECRYPT) || (gpg->mode == GPG_CTX_MODE_SIGN_ENCRYPT));
416 }
417
418 static void
419 gpg_ctx_set_digest (struct _GpgCtx *gpg, GMimeDigestAlgo digest)
420 {
421         gpg->digest = digest;
422 }
423
424 static void
425 gpg_ctx_set_always_trust (struct _GpgCtx *gpg, gboolean trust)
426 {
427         gpg->always_trust = trust;
428 }
429
430 static void
431 gpg_ctx_set_use_agent (struct _GpgCtx *gpg, gboolean use_agent)
432 {
433         gpg->use_agent = use_agent;
434 }
435
436 static void
437 gpg_ctx_set_userid (struct _GpgCtx *gpg, const char *userid)
438 {
439         g_free (gpg->userid);
440         gpg->userid = g_strdup (userid);
441 }
442
443 static void
444 gpg_ctx_add_recipient (struct _GpgCtx *gpg, const char *keyid)
445 {
446         if (gpg->mode != GPG_CTX_MODE_ENCRYPT &&
447             gpg->mode != GPG_CTX_MODE_SIGN_ENCRYPT &&
448             gpg->mode != GPG_CTX_MODE_EXPORT)
449                 return;
450         
451         if (!gpg->recipients)
452                 gpg->recipients = g_ptr_array_new ();
453         
454         g_ptr_array_add (gpg->recipients, g_strdup (keyid));
455 }
456
457 static void
458 gpg_ctx_set_armor (struct _GpgCtx *gpg, gboolean armor)
459 {
460         gpg->armor = armor;
461 }
462
463 static void
464 gpg_ctx_set_istream (struct _GpgCtx *gpg, GMimeStream *istream)
465 {
466         g_object_ref (istream);
467         if (gpg->istream)
468                 g_object_unref (gpg->istream);
469         gpg->istream = istream;
470 }
471
472 static void
473 gpg_ctx_set_ostream (struct _GpgCtx *gpg, GMimeStream *ostream)
474 {
475         g_object_ref (ostream);
476         if (gpg->ostream)
477                 g_object_unref (gpg->ostream);
478         gpg->ostream = ostream;
479         gpg->seen_eof1 = FALSE;
480 }
481
482 static void
483 gpg_ctx_set_sigstream (struct _GpgCtx *gpg, GMimeStream *sigstream)
484 {
485         g_object_ref (sigstream);
486         if (gpg->sigstream)
487                 g_object_unref (gpg->sigstream);
488         gpg->sigstream = sigstream;
489 }
490
491 static const char *
492 gpg_ctx_get_diagnostics (struct _GpgCtx *gpg)
493 {
494         if (!gpg->flushed) {
495                 g_mime_stream_flush (gpg->diagnostics);
496                 g_byte_array_append (gpg->diag, (unsigned char *) "", 1);
497                 gpg->flushed = TRUE;
498         }
499         
500         return (const char *) gpg->diag->data;
501 }
502
503 static void
504 gpg_ctx_free (struct _GpgCtx *gpg)
505 {
506         guint i;
507         
508         g_hash_table_destroy (gpg->userid_hint);
509         
510         g_free (gpg->userid);
511         
512         if (gpg->recipients) {
513                 for (i = 0; i < gpg->recipients->len; i++)
514                         g_free (gpg->recipients->pdata[i]);
515         
516                 g_ptr_array_free (gpg->recipients, TRUE);
517         }
518         
519         if (gpg->stdin_fd != -1)
520                 close (gpg->stdin_fd);
521         if (gpg->stdout_fd != -1)
522                 close (gpg->stdout_fd);
523         if (gpg->stderr_fd != -1)
524                 close (gpg->stderr_fd);
525         if (gpg->status_fd != -1)
526                 close (gpg->status_fd);
527         if (gpg->secret_fd != -1)
528                 close (gpg->secret_fd);
529         
530         g_free (gpg->statusbuf);
531         
532         g_free (gpg->need_id);
533         
534         if (gpg->sigstream)
535                 g_object_unref (gpg->sigstream);
536         
537         if (gpg->istream)
538                 g_object_unref (gpg->istream);
539         
540         if (gpg->ostream)
541                 g_object_unref (gpg->ostream);
542         
543         g_object_unref (gpg->diagnostics);
544         
545         if (gpg->encrypted_to)
546                 g_object_unref (gpg->encrypted_to);
547         
548         if (gpg->signatures)
549                 g_object_unref (gpg->signatures);
550         
551         g_slice_free (struct _GpgCtx, gpg);
552 }
553
554 static const char *
555 gpg_digest_str (GMimeDigestAlgo digest)
556 {
557         switch (digest) {
558         case GMIME_DIGEST_ALGO_MD2:
559                 return "--digest-algo=MD2";
560         case GMIME_DIGEST_ALGO_MD5:
561                 return "--digest-algo=MD5";
562         case GMIME_DIGEST_ALGO_SHA1:
563                 return "--digest-algo=SHA1";
564         case GMIME_DIGEST_ALGO_SHA224:
565                 return "--digest-algo=SHA224";
566         case GMIME_DIGEST_ALGO_SHA256:
567                 return "--digest-algo=SHA256";
568         case GMIME_DIGEST_ALGO_SHA384:
569                 return "--digest-algo=SHA384";
570         case GMIME_DIGEST_ALGO_SHA512:
571                 return "--digest-algo=SHA512";
572         case GMIME_DIGEST_ALGO_RIPEMD160:
573                 return "--digest-algo=RIPEMD160";
574         case GMIME_DIGEST_ALGO_TIGER192:
575                 return "--digest-algo=TIGER192";
576         case GMIME_DIGEST_ALGO_MD4:
577                 return "--digest-algo=MD4";
578         default:
579                 return NULL;
580         }
581 }
582
583 static char **
584 gpg_ctx_get_argv (struct _GpgCtx *gpg, int status_fd, int secret_fd, char ***strv)
585 {
586         const char *digest_str;
587         char **argv, *buf;
588         GPtrArray *args;
589         int v = 0;
590         guint i;
591         
592         *strv = g_new (char *, 3);
593         
594         args = g_ptr_array_new ();
595         g_ptr_array_add (args, "gpg");
596         
597         g_ptr_array_add (args, "--verbose");
598         g_ptr_array_add (args, "--no-secmem-warning");
599         g_ptr_array_add (args, "--no-greeting");
600         g_ptr_array_add (args, "--no-tty");
601         
602         if (!gpg->need_passwd) {
603                 /* only use batch mode if we don't intend on using the
604                    interactive --command-fd option to send it the
605                    user's password */
606                 g_ptr_array_add (args, "--batch");
607                 g_ptr_array_add (args, "--yes");
608         }
609         
610         g_ptr_array_add (args, "--charset=UTF-8");
611         
612         (*strv)[v++] = buf = g_strdup_printf ("--status-fd=%d", status_fd);
613         g_ptr_array_add (args, buf);
614         
615         if (gpg->need_passwd) {
616                 (*strv)[v++] = buf = g_strdup_printf ("--command-fd=%d", secret_fd);
617                 g_ptr_array_add (args, buf);
618         }
619         
620         switch (gpg->mode) {
621         case GPG_CTX_MODE_SIGN:
622                 if (gpg->use_agent)
623                         g_ptr_array_add (args, "--use-agent");
624                 
625                 g_ptr_array_add (args, "--sign");
626                 g_ptr_array_add (args, "--detach");
627                 if (gpg->armor)
628                         g_ptr_array_add (args, "--armor");
629                 if ((digest_str = gpg_digest_str (gpg->digest)))
630                         g_ptr_array_add (args, (char *) digest_str);
631                 if (gpg->userid) {
632                         g_ptr_array_add (args, "-u");
633                         g_ptr_array_add (args, (char *) gpg->userid);
634                 }
635                 g_ptr_array_add (args, "--output");
636                 g_ptr_array_add (args, "-");
637                 break;
638         case GPG_CTX_MODE_VERIFY:
639                 if (!gpg->ctx->auto_key_retrieve) {
640                         g_ptr_array_add (args, "--keyserver-options");
641                         g_ptr_array_add (args, "no-auto-key-retrieve");
642                 }
643                 
644                 g_ptr_array_add (args, "--enable-special-filenames");
645                 g_ptr_array_add (args, "--verify");
646                 g_ptr_array_add (args, "--");
647                 
648                 /* signature stream must come first */
649                 (*strv)[v++] = buf = g_strdup_printf ("-&%d", secret_fd);
650                 g_ptr_array_add (args, buf);
651                 
652                 /* followed by the content stream (in this case, stdin) */
653                 g_ptr_array_add (args, "-");
654                 break;
655         case GPG_CTX_MODE_SIGN_ENCRYPT:
656                 if (gpg->use_agent)
657                         g_ptr_array_add (args, "--use-agent");
658                 
659                 g_ptr_array_add (args, "--sign");
660                 
661                 if ((digest_str = gpg_digest_str (gpg->digest)))
662                         g_ptr_array_add (args, (char *) digest_str);
663                 
664                 /* fall thru... */
665         case GPG_CTX_MODE_ENCRYPT:
666                 g_ptr_array_add (args, "--encrypt");
667                 
668                 if (gpg->armor)
669                         g_ptr_array_add (args, "--armor");
670                 
671                 if (gpg->always_trust)
672                         g_ptr_array_add (args, "--always-trust");
673                 
674                 if (gpg->userid) {
675                         g_ptr_array_add (args, "-u");
676                         g_ptr_array_add (args, (char *) gpg->userid);
677                 }
678                 
679                 if (gpg->recipients) {
680                         for (i = 0; i < gpg->recipients->len; i++) {
681                                 g_ptr_array_add (args, "-r");
682                                 g_ptr_array_add (args, gpg->recipients->pdata[i]);
683                         }
684                 }
685                 g_ptr_array_add (args, "--output");
686                 g_ptr_array_add (args, "-");
687                 break;
688         case GPG_CTX_MODE_DECRYPT:
689                 if (gpg->use_agent)
690                         g_ptr_array_add (args, "--use-agent");
691                 
692                 g_ptr_array_add (args, "--decrypt");
693                 g_ptr_array_add (args, "--output");
694                 g_ptr_array_add (args, "-");
695                 break;
696         case GPG_CTX_MODE_IMPORT:
697                 g_ptr_array_add (args, "--import");
698                 g_ptr_array_add (args, "-");
699                 break;
700         case GPG_CTX_MODE_EXPORT:
701                 if (gpg->armor)
702                         g_ptr_array_add (args, "--armor");
703                 g_ptr_array_add (args, "--export");
704                 for (i = 0; i < gpg->recipients->len; i++)
705                         g_ptr_array_add (args, gpg->recipients->pdata[i]);
706                 break;
707         }
708         
709 #if d(!)0
710         for (i = 0; i < args->len; i++)
711                 printf ("%s ", (char *) args->pdata[i]);
712         printf ("\n");
713 #endif
714         
715         g_ptr_array_add (args, NULL);
716         (*strv)[v] = NULL;
717         
718         argv = (char **) args->pdata;
719         g_ptr_array_free (args, FALSE);
720         
721         return argv;
722 }
723
724 static int
725 gpg_ctx_op_start (struct _GpgCtx *gpg)
726 {
727         int i, maxfd, errnosave, fds[10];
728         char **argv, **strv = NULL;
729         int flags;
730         
731         for (i = 0; i < 10; i++)
732                 fds[i] = -1;
733         
734         maxfd = (gpg->need_passwd || gpg->sigstream) ? 10 : 8;
735         for (i = 0; i < maxfd; i += 2) {
736                 if (pipe (fds + i) == -1)
737                         goto exception;
738         }
739         
740         argv = gpg_ctx_get_argv (gpg, fds[7], fds[8], &strv);
741         
742         if (!(gpg->pid = fork ())) {
743                 /* child process */
744                 
745                 if ((dup2 (fds[0], STDIN_FILENO) < 0) ||
746                     (dup2 (fds[3], STDOUT_FILENO) < 0) ||
747                     (dup2 (fds[5], STDERR_FILENO) < 0)) {
748                         _exit (255);
749                 }
750                 
751                 /* Dissociate from gmime's controlling terminal so
752                  * that gpg won't be able to read from it.
753                  */
754                 setsid ();
755                 
756                 maxfd = sysconf (_SC_OPEN_MAX);
757                 for (i = 3; i < maxfd; i++) {
758                         /* don't close the status-fd or the passwd-fd */
759                         if (i != fds[7] && i != fds[8])
760                                 fcntl (i, F_SETFD, FD_CLOEXEC);
761                 }
762                 
763                 /* run gpg */
764                 execvp (gpg->ctx->path, argv);
765                 _exit (255);
766         } else if (gpg->pid < 0) {
767                 g_strfreev (strv);
768                 g_free (argv);
769                 goto exception;
770         }
771         
772         /* parent process */
773         
774         g_strfreev (strv);
775         g_free (argv);
776         
777         close (fds[0]);
778         gpg->stdin_fd = fds[1];
779         gpg->stdout_fd = fds[2];
780         close (fds[3]);
781         gpg->stderr_fd = fds[4];
782         close (fds[5]);
783         gpg->status_fd = fds[6];
784         close (fds[7]);
785         
786         if (fds[8] != -1) {
787                 flags = (flags = fcntl (fds[9], F_GETFL)) == -1 ? O_WRONLY : flags;
788                 fcntl (fds[9], F_SETFL, flags | O_NONBLOCK);
789                 gpg->secret_fd = fds[9];
790                 close (fds[8]);
791         }
792         
793         flags = (flags = fcntl (gpg->stdin_fd, F_GETFL)) == -1 ? O_WRONLY : flags;
794         fcntl (gpg->stdin_fd, F_SETFL, flags | O_NONBLOCK);
795         
796         flags = (flags = fcntl (gpg->stdout_fd, F_GETFL)) == -1 ? O_RDONLY : flags;
797         fcntl (gpg->stdout_fd, F_SETFL, flags | O_NONBLOCK);
798         
799         flags = (flags = fcntl (gpg->stderr_fd, F_GETFL)) == -1 ? O_RDONLY : flags;
800         fcntl (gpg->stderr_fd, F_SETFL, flags | O_NONBLOCK);
801         
802         flags = (flags = fcntl (gpg->status_fd, F_GETFL)) == -1 ? O_RDONLY : flags;
803         fcntl (gpg->status_fd, F_SETFL, flags | O_NONBLOCK);
804         
805         return 0;
806         
807  exception:
808         
809         errnosave = errno;
810         
811         for (i = 0; i < maxfd; i++) {
812                 if (fds[i] != -1)
813                         close (fds[i]);
814         }
815         
816         errno = errnosave;
817         
818         return -1;
819 }
820
821 static char *
822 next_token (char *in, char **token)
823 {
824         char *start, *inptr = in;
825         
826         while (*inptr == ' ')
827                 inptr++;
828         
829         if (*inptr == '\0' || *inptr == '\n') {
830                 if (token)
831                         *token = NULL;
832                 return inptr;
833         }
834         
835         start = inptr;
836         while (*inptr && *inptr != ' ' && *inptr != '\n')
837                 inptr++;
838         
839         if (token)
840                 *token = g_strndup (start, (size_t) (inptr - start));
841         
842         return inptr;
843 }
844
845 /**
846  * gpg_ctx_add_signature:
847  * @gpg: GnuPG context
848  * @status: a #GMimeSignatureStatus
849  * @info: a string with the signature info
850  *
851  * Parses GOODSIG, BADSIG, EXPSIG, EXPKEYSIG, and REVKEYSIG status messages
852  * into a newly allocated #GMimeSignature and adds it to @gpg's signature list.
853  **/
854 static void
855 gpg_ctx_add_signature (struct _GpgCtx *gpg, GMimeSignatureStatus status, char *info)
856 {
857         GMimeSignature *sig;
858         
859         if (!gpg->signatures)
860                 gpg->signatures = g_mime_signature_list_new ();
861         
862         gpg->signature = sig = g_mime_signature_new ();
863         g_mime_signature_set_status (sig, status);
864         g_mime_signature_list_add (gpg->signatures, sig);
865         g_object_unref (sig);
866         
867         /* get the key id of the signer */
868         info = next_token (info, &sig->cert->keyid);
869         
870         /* the rest of the string is the signer's name */
871         sig->cert->name = g_strdup (info);
872 }
873
874 static void
875 gpg_ctx_parse_signer_info (struct _GpgCtx *gpg, char *status)
876 {
877         GMimeSignature *sig;
878         char *inend;
879         
880         if (!strncmp (status, "SIG_ID ", 7)) {
881                 /* not sure if this contains anything we care about... */
882         } else if (!strncmp (status, "GOODSIG ", 8)) {
883                 gpg_ctx_add_signature (gpg, GMIME_SIGNATURE_STATUS_GOOD, status + 8);
884         } else if (!strncmp (status, "BADSIG ", 7)) {
885                 gpg_ctx_add_signature (gpg, GMIME_SIGNATURE_STATUS_BAD, status + 7);
886         } else if (!strncmp (status, "EXPSIG ", 7)) {
887                 gpg_ctx_add_signature (gpg, GMIME_SIGNATURE_STATUS_ERROR, status + 7);
888                 gpg->signature->errors |= GMIME_SIGNATURE_ERROR_EXPSIG;
889         } else if (!strncmp (status, "EXPKEYSIG ", 10)) {
890                 gpg_ctx_add_signature (gpg, GMIME_SIGNATURE_STATUS_ERROR, status + 10);
891                 gpg->signature->errors |= GMIME_SIGNATURE_ERROR_EXPKEYSIG;
892         } else if (!strncmp (status, "REVKEYSIG ", 10)) {
893                 gpg_ctx_add_signature (gpg, GMIME_SIGNATURE_STATUS_ERROR, status + 10);
894                 gpg->signature->errors |= GMIME_SIGNATURE_ERROR_REVKEYSIG;
895         } else if (!strncmp (status, "ERRSIG ", 7)) {
896                 /* Note: NO_PUBKEY often comes after an ERRSIG */
897                 status += 7;
898                 
899                 if (!gpg->signatures)
900                         gpg->signatures = g_mime_signature_list_new ();
901                 
902                 gpg->signature = sig = g_mime_signature_new ();
903                 g_mime_signature_set_status (sig, GMIME_SIGNATURE_STATUS_ERROR);
904                 g_mime_signature_list_add (gpg->signatures, sig);
905                 g_object_unref (sig);
906                 
907                 /* get the key id of the signer */
908                 status = next_token (status, &sig->cert->keyid);
909                 
910                 /* the second token is the public-key algorithm id */
911                 sig->cert->pubkey_algo = strtoul (status, &inend, 10);
912                 if (inend == status || *inend != ' ') {
913                         sig->cert->pubkey_algo = 0;
914                         return;
915                 }
916                 
917                 status = inend + 1;
918                 
919                 /* the third token is the digest algorithm id */
920                 sig->cert->digest_algo = strtoul (status, &inend, 10);
921                 if (inend == status || *inend != ' ') {
922                         sig->cert->digest_algo = 0;
923                         return;
924                 }
925                 
926                 status = inend + 1;
927                 
928                 /* the fourth token is the signature class */
929                 /*sig->sig_class =*/ strtoul (status, &inend, 10);
930                 if (inend == status || *inend != ' ') {
931                         /*signer->sig_class = 0;*/
932                         return;
933                 }
934                 
935                 status = inend + 1;
936                 
937                 /* the fifth token is the signature expiration date (or 0 for never) */
938                 sig->expires = strtoul (status, &inend, 10);
939                 if (inend == status || *inend != ' ') {
940                         sig->expires = 0;
941                         return;
942                 }
943                 
944                 status = inend + 1;
945                 
946                 /* the sixth token is the return code */
947                 switch (strtol (status, NULL, 10)) {
948                 case 4: sig->errors |= GMIME_SIGNATURE_ERROR_UNSUPP_ALGO; break;
949                 case 9: sig->errors |= GMIME_SIGNATURE_ERROR_NO_PUBKEY; break;
950                 default: break;
951                 }
952         } else if (!strncmp (status, "NO_PUBKEY ", 10)) {
953                 /* the only token is the keyid, but we've already got it */
954                 gpg->signature->errors |= GMIME_SIGNATURE_ERROR_NO_PUBKEY;
955         } else if (!strncmp (status, "VALIDSIG ", 9)) {
956                 sig = gpg->signature;
957                 status += 9;
958                 
959                 /* the first token is the fingerprint */
960                 status = next_token (status, &sig->cert->fingerprint);
961                 
962                 /* the second token is the date the stream was signed YYYY-MM-DD */
963                 status = next_token (status, NULL);
964                 
965                 /* the third token is the signature creation date (or 0 for unknown?) */
966                 sig->created = strtoul (status, &inend, 10);
967                 if (inend == status || *inend != ' ') {
968                         sig->created = 0;
969                         return;
970                 }
971                 
972                 status = inend + 1;
973                 
974                 /* the fourth token is the signature expiration date (or 0 for never) */
975                 sig->expires = strtoul (status, &inend, 10);
976                 if (inend == status || *inend != ' ') {
977                         sig->expires = 0;
978                         return;
979                 }
980                 
981                 status = inend + 1;
982                 
983                 /* the fifth token is the signature version */
984                 /*sig->sig_ver =*/ strtoul (status, &inend, 10);
985                 if (inend == status || *inend != ' ') {
986                         /*signer->sig_ver = 0;*/
987                         return;
988                 }
989                 
990                 status = inend + 1;
991                 
992                 /* the sixth token is a reserved numeric value (ignore for now) */
993                 status = next_token (status, NULL);
994                 
995                 /* the seventh token is the public-key algorithm id */
996                 sig->cert->pubkey_algo = strtoul (status, &inend, 10);
997                 if (inend == status || *inend != ' ') {
998                         sig->cert->pubkey_algo = 0;
999                         return;
1000                 }
1001                 
1002                 status = inend + 1;
1003                 
1004                 /* the eighth token is the digest algorithm id */
1005                 sig->cert->digest_algo = strtoul (status, &inend, 10);
1006                 if (inend == status || *inend != ' ') {
1007                         sig->cert->digest_algo = 0;
1008                         return;
1009                 }
1010                 
1011                 status = inend + 1;
1012                 
1013                 /* the nineth token is the signature class */
1014                 /*sig->sig_class =*/ strtoul (status, &inend, 10);
1015                 if (inend == status || *inend != ' ') {
1016                         /*sig->sig_class = 0;*/
1017                         return;
1018                 }
1019                 
1020                 status = inend + 1;
1021                 
1022                 /* the rest is the primary key fingerprint */
1023         } else if (!strncmp (status, "TRUST_", 6)) {
1024                 status += 6;
1025                 
1026                 sig = gpg->signature;
1027                 if (!strncmp (status, "NEVER", 5)) {
1028                         sig->cert->trust = GMIME_CERTIFICATE_TRUST_NEVER;
1029                 } else if (!strncmp (status, "MARGINAL", 8)) {
1030                         sig->cert->trust = GMIME_CERTIFICATE_TRUST_MARGINAL;
1031                 } else if (!strncmp (status, "FULLY", 5)) {
1032                         sig->cert->trust = GMIME_CERTIFICATE_TRUST_FULLY;
1033                 } else if (!strncmp (status, "ULTIMATE", 8)) {
1034                         sig->cert->trust = GMIME_CERTIFICATE_TRUST_ULTIMATE;
1035                 } else if (!strncmp (status, "UNDEFINED", 9)) {
1036                         sig->cert->trust = GMIME_CERTIFICATE_TRUST_UNDEFINED;
1037                 }
1038         }
1039 }
1040
1041 static int
1042 gpg_ctx_parse_status (struct _GpgCtx *gpg, GError **err)
1043 {
1044         size_t nread, nwritten;
1045         register char *inptr;
1046         char *status, *tmp;
1047         int len;
1048         
1049  parse:
1050         
1051         g_clear_error (err);
1052         
1053         inptr = gpg->statusbuf;
1054         while (inptr < gpg->statusptr && *inptr != '\n')
1055                 inptr++;
1056         
1057         if (*inptr != '\n') {
1058                 /* we don't have enough data buffered to parse this status line */
1059                 return 0;
1060         }
1061         
1062         *inptr++ = '\0';
1063         status = gpg->statusbuf;
1064         
1065         d(printf ("status: %s\n", status));
1066         
1067         if (strncmp (status, "[GNUPG:] ", 9) != 0) {
1068                 if (!gpg->utf8)
1069                         tmp = g_locale_to_utf8 (status, -1, &nread, &nwritten, NULL);
1070                 else
1071                         tmp = status;
1072                 
1073                 g_set_error (err, GMIME_ERROR, GMIME_ERROR_PARSE_ERROR,
1074                              _("Unexpected GnuPG status message encountered:\n\n%s"),
1075                              tmp);
1076                 
1077                 if (!gpg->utf8)
1078                         g_free (tmp);
1079                 
1080                 return -1;
1081         }
1082         
1083         status += 9;
1084         
1085         if (!strncmp (status, "USERID_HINT ", 12)) {
1086                 size_t nread, nwritten;
1087                 char *hint, *user;
1088                 
1089                 status += 12;
1090                 
1091                 status = next_token (status, &hint);
1092                 if (!hint) {
1093                         g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_PARSE_ERROR,
1094                                              _("Failed to parse gpg userid hint."));
1095                         return -1;
1096                 }
1097                 
1098                 if (g_hash_table_lookup (gpg->userid_hint, hint)) {
1099                         /* we already have this userid hint... */
1100                         g_free (hint);
1101                         goto recycle;
1102                 }
1103                 
1104                 if (gpg->utf8 || !(user = g_locale_to_utf8 (status, -1, &nread, &nwritten, NULL)))
1105                         user = g_strdup (status);
1106                 
1107                 g_strstrip (user);
1108                 
1109                 g_hash_table_insert (gpg->userid_hint, hint, user);
1110         } else if (!strncmp (status, "NEED_PASSPHRASE ", 16)) {
1111                 char *userid;
1112                 
1113                 status += 16;
1114                 
1115                 status = next_token (status, &userid);
1116                 if (!userid) {
1117                         g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_PARSE_ERROR,
1118                                              _("Failed to parse gpg passphrase request."));
1119                         return -1;
1120                 }
1121                 
1122                 g_free (gpg->need_id);
1123                 gpg->need_id = userid;
1124         } else if (!strncmp (status, "NEED_PASSPHRASE_PIN ", 20)) {
1125                 char *userid;
1126                 
1127                 status += 20;
1128                 
1129                 status = next_token (status, &userid);
1130                 if (!userid) {
1131                         g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_PARSE_ERROR,
1132                                              _("Failed to parse gpg passphrase request."));
1133                         return -1;
1134                 }
1135                 
1136                 g_free (gpg->need_id);
1137                 gpg->need_id = userid;
1138         } else if (!strncmp (status, "GET_HIDDEN ", 11)) {
1139                 GMimeStream *filtered_stream, *passwd;
1140                 GMimeCryptoContext *ctx;
1141                 GMimeFilter *filter;
1142                 const char *charset;
1143                 char *prompt = NULL;
1144                 const char *name;
1145                 gboolean ok;
1146                 
1147                 status += 11;
1148                 
1149                 ctx = (GMimeCryptoContext *) gpg->ctx;
1150                 if (!ctx->request_passwd) {
1151                         /* can't ask for a passwd w/o a way to request it from the user... */
1152                         g_set_error_literal (err, GMIME_ERROR, ECANCELED, _("Canceled."));
1153                         return -1;
1154                 }
1155                 
1156                 if (!(name = g_hash_table_lookup (gpg->userid_hint, gpg->need_id)))
1157                         name = gpg->userid;
1158                 
1159                 if (!strncmp (status, "passphrase.pin.ask", 18)) {
1160                         prompt = g_strdup_printf (_("You need a PIN to unlock the key for your\n"
1161                                                     "SmartCard: \"%s\""), name);
1162                 } else if (!strncmp (status, "passphrase.enter", 16)) {
1163                         prompt = g_strdup_printf (_("You need a passphrase to unlock the key for\n"
1164                                                     "user: \"%s\""), name);
1165                 } else {
1166                         next_token (status, &prompt);
1167                         g_set_error (err, GMIME_ERROR, GMIME_ERROR_GENERAL,
1168                                      _("Unexpected request from GnuPG for `%s'"), prompt);
1169                         g_free (prompt);
1170                         return -1;
1171                 }
1172                 
1173                 /* create a stream for the application to write the passwd to */
1174                 passwd = g_mime_stream_pipe_new (gpg->secret_fd);
1175                 g_mime_stream_pipe_set_owner ((GMimeStreamPipe *) passwd, FALSE);
1176                 
1177                 if (!gpg->utf8) {
1178                         /* we'll need to transcode the UTF-8 password that the application
1179                          * will write to our stream into the locale charset used by gpg */
1180                         filtered_stream = g_mime_stream_filter_new (passwd);
1181                         g_object_unref (passwd);
1182                         
1183                         charset = g_mime_locale_charset ();
1184                         filter = g_mime_filter_charset_new ("UTF-8", charset);
1185                         
1186                         g_mime_stream_filter_add ((GMimeStreamFilter *) filtered_stream, filter);
1187                         g_object_unref (filter);
1188                         
1189                         passwd = filtered_stream;
1190                 }
1191                 
1192                 if ((ok = ctx->request_passwd (ctx, name, prompt, gpg->bad_passwds > 0, passwd, err))) {
1193                         if (g_mime_stream_flush (passwd) == -1)
1194                                 ok = FALSE;
1195                 }
1196                 
1197                 g_object_unref (passwd);
1198                 g_free (prompt);
1199                 
1200                 if (!ok)
1201                         return -1;
1202         } else if (!strncmp (status, "GOOD_PASSPHRASE", 15)) {
1203                 gpg->bad_passwds = 0;
1204         } else if (!strncmp (status, "BAD_PASSPHRASE", 14)) {
1205                 gpg->bad_passwds++;
1206                 
1207                 if (gpg->bad_passwds == 3) {
1208                         g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_BAD_PASSWORD,
1209                                              _("Failed to unlock secret key: 3 bad passphrases given."));
1210                         return -1;
1211                 }
1212         } else if (!strncmp (status, "UNEXPECTED ", 11)) {
1213                 /* this is an error */
1214                 if (!gpg->utf8)
1215                         tmp = g_locale_to_utf8 (status + 11, -1, &nread, &nwritten, NULL);
1216                 else
1217                         tmp = status + 11;
1218                 
1219                 g_set_error (err, GMIME_ERROR, GMIME_ERROR_GENERAL,
1220                              _("Unexpected response from GnuPG: %s"),
1221                              tmp);
1222                 
1223                 if (!gpg->utf8)
1224                         g_free (tmp);
1225                 
1226                 return -1;
1227         } else if (!strncmp (status, "NODATA", 6)) {
1228                 /* this is an error */
1229                 const char *diagnostics;
1230                 
1231                 diagnostics = gpg_ctx_get_diagnostics (gpg);
1232                 if (diagnostics && *diagnostics)
1233                         g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_GENERAL, diagnostics);
1234                 else
1235                         g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_GENERAL, _("No data provided"));
1236                 
1237                 return -1;
1238         } else {
1239                 GMimeCertificate *cert;
1240                 char *inend;
1241                 
1242                 switch (gpg->mode) {
1243                 case GPG_CTX_MODE_SIGN:
1244                         if (strncmp (status, "SIG_CREATED ", 12) != 0)
1245                                 break;
1246                         
1247                         status += 12;
1248                         
1249                         /* skip the next single-char token ("D" for detached) */
1250                         status = next_token (status, NULL);
1251                         
1252                         /* skip the public-key algorithm id token */
1253                         status = next_token (status, NULL);
1254                         
1255                         /* this token is the digest algorithm used */
1256                         gpg->digest = strtoul (status, NULL, 10);
1257                         break;
1258                 case GPG_CTX_MODE_VERIFY:
1259                         gpg_ctx_parse_signer_info (gpg, status);
1260                         break;
1261                 case GPG_CTX_MODE_SIGN_ENCRYPT:
1262                 case GPG_CTX_MODE_ENCRYPT:
1263                         if (!strncmp (status, "BEGIN_ENCRYPTION", 16)) {
1264                                 /* nothing to do... but we know to expect data on stdout soon */
1265                         } else if (!strncmp (status, "END_ENCRYPTION", 14)) {
1266                                 /* nothing to do, but we know the end is near? */
1267                         } else if (!strncmp (status, "NO_RECP", 7)) {
1268                                 g_set_error_literal (err, GMIME_ERROR, GMIME_ERROR_NO_VALID_RECIPIENTS,
1269                                                      _("Failed to encrypt: No valid recipients specified."));
1270                                 return -1;
1271                         }
1272                         break;
1273                 case GPG_CTX_MODE_DECRYPT:
1274                         if (!strncmp (status, "BEGIN_DECRYPTION", 16)) {
1275                                 /* nothing to do... but we know to expect data on stdout soon */
1276                         } else if (!strncmp (status, "DECRYPTION_INFO ", 16)) {
1277                                 /* new feature added in gnupg-2.1.x which gives mdc and cipher algorithms used */
1278                                 status += 16;
1279                                 
1280                                 /* first token is the mdc algorithm (or 0 if not used) */
1281                                 gpg->digest = strtoul (status, &inend, 10);
1282                                 if (inend == status || *inend != ' ') {
1283                                         gpg->digest = 0;
1284                                         break;
1285                                 }
1286                                 
1287                                 status = inend + 1;
1288                                 
1289                                 /* second token is the cipher algorithm */
1290                                 gpg->cipher = strtoul (status, &inend, 10);
1291                         } else if (!strncmp (status, "DECRYPTION_OKAY", 15)) {
1292                                 /* decryption succeeded */
1293                                 gpg->decrypt_okay = TRUE;
1294                         } else if (!strncmp (status, "DECRYPTION_FAILED", 17)) {
1295                                 /* nothing to do... but we know gpg failed to decrypt :-( */
1296                         } else if (!strncmp (status, "END_DECRYPTION", 14)) {
1297                                 /* nothing to do, but we know we're done */
1298                         } else if (!strncmp (status, "ENC_TO ", 7)) {
1299                                 /* parse the recipient info */
1300                                 if (!gpg->encrypted_to)
1301                                         gpg->encrypted_to = g_mime_certificate_list_new ();
1302                                 
1303                                 cert = g_mime_certificate_new ();
1304                                 g_mime_certificate_list_add (gpg->encrypted_to, cert);
1305                                 
1306                                 status += 7;
1307                                 
1308                                 /* first token is the recipient's keyid */
1309                                 status = next_token (status, &cert->keyid);
1310                                 
1311                                 /* second token is the recipient's pubkey algo */
1312                                 cert->pubkey_algo = strtoul (status, &inend, 10);
1313                                 if (inend == status || *inend != ' ') {
1314                                         cert->pubkey_algo = 0;
1315                                         g_object_unref (cert);
1316                                         break;
1317                                 }
1318                                 
1319                                 g_object_unref (cert);
1320                                 status = inend + 1;
1321                                 
1322                                 /* third token is a dummy value which is always '0' */
1323                         } else if (!strncmp (status, "GOODMDC", 7)) {
1324                                 /* nothing to do... we'll grab the MDC used in DECRYPTION_INFO */
1325                         } else if (!strncmp (status, "BADMDC", 6)) {
1326                                 /* nothing to do, this will only be sent after DECRYPTION_FAILED */
1327                         } else {
1328                                 gpg_ctx_parse_signer_info (gpg, status);
1329                         }
1330                         break;
1331                 case GPG_CTX_MODE_IMPORT:
1332                         /* no-op */
1333                         break;
1334                 case GPG_CTX_MODE_EXPORT:
1335                         /* no-op */
1336                         break;
1337                 }
1338         }
1339         
1340  recycle:
1341         
1342         /* recycle our statusbuf by moving inptr to the beginning of statusbuf */
1343         len = gpg->statusptr - inptr;
1344         memmove (gpg->statusbuf, inptr, len);
1345         
1346         len = inptr - gpg->statusbuf;
1347         gpg->statusleft += len;
1348         gpg->statusptr -= len;
1349         
1350         /* if we have more data, try parsing the next line? */
1351         if (gpg->statusptr > gpg->statusbuf)
1352                 goto parse;
1353         
1354         return 0;
1355 }
1356
1357 #ifdef ALLOC_NEAREST_POW2
1358 static inline size_t
1359 nearest_pow (size_t num)
1360 {
1361         size_t n;
1362         
1363         if (num == 0)
1364                 return 0;
1365         
1366         n = num - 1;
1367 #if defined (__GNUC__) && defined (__i386__)
1368         __asm__("bsrl %1,%0\n\t"
1369                 "jnz 1f\n\t"
1370                 "movl $-1,%0\n"
1371                 "1:" : "=r" (n) : "rm" (n));
1372         n = (1 << (n + 1));
1373 #else
1374         n |= n >> 1;
1375         n |= n >> 2;
1376         n |= n >> 4;
1377         n |= n >> 8;
1378         n |= n >> 16;
1379         n++;
1380 #endif
1381         
1382         return n;
1383 }
1384
1385 #define next_alloc_size(n) nearest_pow (n)
1386 #else
1387 static inline size_t
1388 next_alloc_size (size_t n)
1389 {
1390         return (n + 63) & ~63;
1391 }
1392 #endif
1393
1394 #define status_backup(gpg, start, len) G_STMT_START {                     \
1395         if (gpg->statusleft <= len) {                                     \
1396                 size_t slen, soff;                                        \
1397                                                                           \
1398                 soff = gpg->statusptr - gpg->statusbuf;                   \
1399                 slen = next_alloc_size (soff + len + 1);                  \
1400                                                                           \
1401                 gpg->statusbuf = g_realloc (gpg->statusbuf, slen);        \
1402                 gpg->statusptr = gpg->statusbuf + soff;                   \
1403                 gpg->statusleft = (slen - 1) - soff;                      \
1404         }                                                                 \
1405                                                                           \
1406         memcpy (gpg->statusptr, start, len);                              \
1407         gpg->statusptr += len;                                            \
1408         gpg->statusleft -= len;                                           \
1409 } G_STMT_END
1410
1411 enum {
1412         GPG_STDIN_FD,
1413         GPG_STDOUT_FD,
1414         GPG_STDERR_FD,
1415         GPG_STATUS_FD,
1416         GPG_VERIFY_FD,
1417         GPG_N_FDS
1418 };
1419
1420 #ifndef HAVE_POLL
1421 struct pollfd {
1422         int fd;
1423         short events;
1424         short revents;
1425 };
1426
1427 #define POLLIN   (1 << 0)
1428 #define POLLPRI  (1 << 1)
1429 #define POLLOUT  (1 << 2)
1430 #define POLLERR  (1 << 3)
1431 #define POLLHUP  (1 << 4)
1432 #define POLLNVAL (1 << 5)
1433
1434 #ifdef HAVE_SELECT
1435 static int
1436 poll (struct pollfd *pfds, nfds_t nfds, int timeout)
1437 {
1438         fd_set rset, wset, xset;
1439         struct timeval tv;
1440         int maxfd = 0;
1441         int ready;
1442         nfds_t i;
1443         
1444         if (nfds == 0)
1445                 return 0;
1446         
1447         /* initialize our select() timeout */
1448         tv.tv_sec = timeout / 1000;
1449         tv.tv_usec = (timeout % 1000) * 1000;
1450         
1451         /* initialize our select() fd sets */
1452         FD_ZERO (&rset);
1453         FD_ZERO (&wset);
1454         FD_ZERO (&xset);
1455         
1456         for (i = 0; i < nfds; i++) {
1457                 pfds[i].revents = 0;
1458                 if (pfds[i].fd < 0)
1459                         continue;
1460                 
1461                 if (pfds[i].events & POLLIN)
1462                         FD_SET (pfds[i].fd, &rset);
1463                 if (pfds[i].events & POLLOUT)
1464                         FD_SET (pfds[i].fd, &wset);
1465                 if (pfds[i].events != 0)
1466                         FD_SET (pfds[i].fd, &xset);
1467                 if (pfds[i].fd > maxfd)
1468                         maxfd = pfds[i].fd;
1469         }
1470         
1471         /* poll our fds... */
1472         if ((ready = select (maxfd + 1, &rset, &wset, &xset, timeout != -1 ? &tv : NULL)) > 0) {
1473                 ready = 0;
1474                 
1475                 for (i = 0; i < nfds; i++) {
1476                         if (pfds[i].fd < 0)
1477                                 continue;
1478                         
1479                         if (FD_ISSET (pfds[i].fd, &rset))
1480                                 pfds[i].revents |= POLLIN;
1481                         if (FD_ISSET (pfds[i].fd, &wset))
1482                                 pfds[i].revents |= POLLOUT;
1483                         if (FD_ISSET (pfds[i].fd, &xset))
1484                                 pfds[i].revents |= POLLERR | POLLHUP;
1485                         
1486                         if (pfds[i].revents != 0)
1487                                 ready++;
1488                 }
1489         }
1490         
1491         return ready;
1492 }
1493 #else
1494 static int
1495 poll (struct pollfd *pfds, nfds_t nfds, int timeout)
1496 {
1497         errno = EIO;
1498         return -1;
1499 }
1500 #endif /* HAVE_SELECT */
1501 #endif /* ! HAVE_POLL */
1502
1503 static int
1504 gpg_ctx_op_step (struct _GpgCtx *gpg, GError **err)
1505 {
1506         const char *diagnostics, *mode;
1507         struct pollfd pfds[GPG_N_FDS];
1508         int ready, save;
1509         nfds_t n;
1510         
1511         for (n = 0; n < GPG_N_FDS; n++) {
1512                 pfds[n].events = 0;
1513                 pfds[n].fd = -1;
1514         }
1515         
1516         if (!gpg->seen_eof1) {
1517                 pfds[GPG_STDOUT_FD].fd = gpg->stdout_fd;
1518                 pfds[GPG_STDOUT_FD].events = POLLIN;
1519         }
1520         
1521         if (!gpg->seen_eof2) {
1522                 pfds[GPG_STDERR_FD].fd = gpg->stderr_fd;
1523                 pfds[GPG_STDERR_FD].events = POLLIN;
1524         }
1525         
1526         if (!gpg->complete) {
1527                 pfds[GPG_STATUS_FD].fd = gpg->status_fd;
1528                 pfds[GPG_STATUS_FD].events = POLLIN;
1529         }
1530         
1531         pfds[GPG_STDIN_FD].fd = gpg->stdin_fd;
1532         pfds[GPG_STDIN_FD].events = POLLOUT;
1533         
1534         if (gpg->mode == GPG_CTX_MODE_VERIFY) {
1535                 pfds[GPG_VERIFY_FD].fd = gpg->secret_fd;
1536                 pfds[GPG_VERIFY_FD].events = POLLOUT;
1537         }
1538         
1539         do {
1540                 for (n = 0; n < GPG_N_FDS; n++)
1541                         pfds[n].revents = 0;
1542                 ready = poll (pfds, GPG_N_FDS, 10 * 1000);
1543         } while (ready == -1 && errno == EINTR);
1544         
1545         if (ready == -1) {
1546                 d(printf ("poll() failed: %s\n", g_strerror (errno)));
1547                 goto exception;
1548         } else if (ready == 0) {
1549                 /* timed out */
1550                 return 0;
1551         }
1552         
1553         /* Test each and every file descriptor to see if it's 'ready',
1554            and if so - do what we can with it and then drop through to
1555            the next file descriptor and so on until we've done what we
1556            can to all of them. If one fails along the way, return
1557            -1. */
1558         
1559         if (pfds[GPG_STATUS_FD].revents & (POLLIN | POLLHUP)) {
1560                 /* read the status message and decide what to do... */
1561                 char buffer[4096];
1562                 ssize_t nread;
1563                 
1564                 d(printf ("reading from gpg's status-fd...\n"));
1565                 
1566                 do {
1567                         nread = read (gpg->status_fd, buffer, sizeof (buffer));
1568                 } while (nread == -1 && (errno == EINTR || errno == EAGAIN));
1569                 
1570                 if (nread == -1)
1571                         goto exception;
1572                 
1573                 if (nread > 0) {
1574                         status_backup (gpg, buffer, (size_t) nread);
1575                         if (gpg_ctx_parse_status (gpg, err) == -1)
1576                                 return -1;
1577                 } else {
1578                         gpg->complete = TRUE;
1579                 }
1580         }
1581         
1582         if ((pfds[GPG_STDOUT_FD].revents & (POLLIN | POLLHUP)) && gpg->ostream) {
1583                 char buffer[4096];
1584                 ssize_t nread;
1585                 
1586                 d(printf ("reading gpg's stdout...\n"));
1587                 
1588                 do {
1589                         nread = read (gpg->stdout_fd, buffer, sizeof (buffer));
1590                 } while (nread == -1 && (errno == EINTR || errno == EAGAIN));
1591                 
1592                 if (nread == -1)
1593                         goto exception;
1594                 
1595                 if (nread > 0) {
1596                         if (g_mime_stream_write (gpg->ostream, buffer, (size_t) nread) == -1)
1597                                 goto exception;
1598                 } else {
1599                         gpg->seen_eof1 = TRUE;
1600                 }
1601         }
1602         
1603         if (pfds[GPG_STDERR_FD].revents & (POLLIN | POLLHUP)) {
1604                 char buffer[4096];
1605                 ssize_t nread;
1606                 
1607                 d(printf ("reading gpg's stderr...\n"));
1608                 
1609                 do {
1610                         nread = read (gpg->stderr_fd, buffer, sizeof (buffer));
1611                 } while (nread == -1 && (errno == EINTR || errno == EAGAIN));
1612                 
1613                 if (nread == -1)
1614                         goto exception;
1615                 
1616                 if (nread > 0) {
1617                         g_mime_stream_write (gpg->diagnostics, buffer, nread);
1618                 } else {
1619                         gpg->seen_eof2 = TRUE;
1620                 }
1621         }
1622         
1623         if ((pfds[GPG_VERIFY_FD].revents & (POLLOUT | POLLHUP))) {
1624                 char buffer[4096];
1625                 ssize_t nread;
1626                 
1627                 d(printf ("streaming digital signature to gpg...\n"));
1628                 
1629                 /* write our signature stream to gpg's special fd */
1630                 nread = g_mime_stream_read (gpg->sigstream, buffer, sizeof (buffer));
1631                 if (nread > 0) {
1632                         ssize_t w, nwritten = 0;
1633                         
1634                         do {
1635                                 do {
1636                                         w = write (gpg->secret_fd, buffer + nwritten, nread - nwritten);
1637                                 } while (w == -1 && (errno == EINTR || errno == EAGAIN));
1638                                 
1639                                 if (w > 0)
1640                                         nwritten += w;
1641                         } while (nwritten < nread && w != -1);
1642                         
1643                         if (w == -1)
1644                                 goto exception;
1645                 }
1646                 
1647                 if (g_mime_stream_eos (gpg->sigstream)) {
1648                         close (gpg->secret_fd);
1649                         gpg->secret_fd = -1;
1650                 }
1651         }
1652         
1653         if ((pfds[GPG_STDIN_FD].revents & (POLLOUT | POLLHUP)) && gpg->istream) {
1654                 char buffer[4096];
1655                 ssize_t nread;
1656                 
1657                 d(printf ("writing to gpg's stdin...\n"));
1658                 
1659                 /* write our stream to gpg's stdin */
1660                 nread = g_mime_stream_read (gpg->istream, buffer, sizeof (buffer));
1661                 if (nread > 0) {
1662                         ssize_t w, nwritten = 0;
1663                         
1664                         do {
1665                                 do {
1666                                         w = write (gpg->stdin_fd, buffer + nwritten, nread - nwritten);
1667                                 } while (w == -1 && (errno == EINTR || errno == EAGAIN));
1668                                 
1669                                 if (w > 0)
1670                                         nwritten += w;
1671                         } while (nwritten < nread && w != -1);
1672                         
1673                         if (w == -1)
1674                                 goto exception;
1675                 }
1676                 
1677                 if (g_mime_stream_eos (gpg->istream)) {
1678                         close (gpg->stdin_fd);
1679                         gpg->stdin_fd = -1;
1680                 }
1681         }
1682         
1683         return 0;
1684         
1685  exception:
1686         
1687         switch (gpg->mode) {
1688         case GPG_CTX_MODE_SIGN:
1689                 mode = "sign";
1690                 break;
1691         case GPG_CTX_MODE_VERIFY:
1692                 mode = "verify";
1693                 break;
1694         case GPG_CTX_MODE_SIGN_ENCRYPT:
1695         case GPG_CTX_MODE_ENCRYPT:
1696                 mode = "encrypt";
1697                 break;
1698         case GPG_CTX_MODE_DECRYPT:
1699                 mode = "decrypt";
1700                 break;
1701         case GPG_CTX_MODE_IMPORT:
1702                 mode = "import keys";
1703                 break;
1704         case GPG_CTX_MODE_EXPORT:
1705                 mode = "export keys";
1706                 break;
1707         default:
1708                 g_assert_not_reached ();
1709                 mode = NULL;
1710                 break;
1711         }
1712         
1713         save = errno;
1714         diagnostics = gpg_ctx_get_diagnostics (gpg);
1715         errno = save;
1716         
1717         if (diagnostics && *diagnostics) {
1718                 g_set_error (err, GMIME_ERROR, errno,
1719                              _("Failed to %s via GnuPG: %s\n\n%s"),
1720                              mode, g_strerror (errno),
1721                              diagnostics);
1722         } else {
1723                 g_set_error (err, GMIME_ERROR, errno,
1724                              _("Failed to %s via GnuPG: %s\n"),
1725                              mode, g_strerror (errno));
1726         }
1727         
1728         return -1;
1729 }
1730
1731 static gboolean
1732 gpg_ctx_op_complete (struct _GpgCtx *gpg)
1733 {
1734         return gpg->complete && gpg->seen_eof1 && gpg->seen_eof2;
1735 }
1736
1737 #if 0
1738 static gboolean
1739 gpg_ctx_op_exited (struct _GpgCtx *gpg)
1740 {
1741         int status;
1742         
1743         if (waitpid (gpg->pid, &status, WNOHANG) == gpg->pid) {
1744                 gpg->exit_status = status;
1745                 gpg->exited = TRUE;
1746                 return TRUE;
1747         }
1748         
1749         return FALSE;
1750 }
1751 #endif
1752
1753 static void
1754 gpg_ctx_op_cancel (struct _GpgCtx *gpg)
1755 {
1756         int status;
1757         
1758         if (gpg->exited)
1759                 return;
1760         
1761         kill (gpg->pid, SIGTERM);
1762         sleep (1);
1763         if (waitpid (gpg->pid, &status, WNOHANG) == 0) {
1764                 /* no more mr nice guy... */
1765                 kill (gpg->pid, SIGKILL);
1766                 sleep (1);
1767                 waitpid (gpg->pid, &status, WNOHANG);
1768         }
1769 }
1770
1771 static int
1772 gpg_ctx_op_wait (struct _GpgCtx *gpg)
1773 {
1774         int errnosave, status;
1775         sigset_t mask, omask;
1776         pid_t retval;
1777         
1778         if (!gpg->exited) {
1779                 sigemptyset (&mask);
1780                 sigaddset (&mask, SIGALRM);
1781                 sigprocmask (SIG_BLOCK, &mask, &omask);
1782                 
1783                 alarm (1);
1784                 retval = waitpid (gpg->pid, &status, 0);
1785                 errnosave = errno;
1786                 alarm (0);
1787                 
1788                 sigprocmask (SIG_SETMASK, &omask, NULL);
1789                 errno = errnosave;
1790                 
1791                 if (retval == (pid_t) -1 && errno == EINTR) {
1792                         /* gpg is hanging... */
1793                         kill (gpg->pid, SIGTERM);
1794                         sleep (1);
1795                         
1796                         retval = waitpid (gpg->pid, &status, WNOHANG);
1797                         if (retval == (pid_t) 0) {
1798                                 /* still hanging... */
1799                                 kill (gpg->pid, SIGKILL);
1800                                 sleep (1);
1801                                 retval = waitpid (gpg->pid, &status, WNOHANG);
1802                         }
1803                 }
1804         } else {
1805                 status = gpg->exit_status;
1806                 retval = gpg->pid;
1807         }
1808         
1809         if (retval != (pid_t) -1 && WIFEXITED (status))
1810                 return WEXITSTATUS (status);
1811         else
1812                 return -1;
1813 }
1814 #endif /* ENABLE_CRYPTOGRAPHY */
1815
1816 static int
1817 gpg_sign (GMimeCryptoContext *context, const char *userid, GMimeDigestAlgo digest,
1818           GMimeStream *istream, GMimeStream *ostream, GError **err)
1819 {
1820 #ifdef ENABLE_CRYPTOGRAPHY
1821         GMimeGpgContext *ctx = (GMimeGpgContext *) context;
1822         struct _GpgCtx *gpg;
1823         
1824         gpg = gpg_ctx_new (ctx);
1825         gpg_ctx_set_mode (gpg, GPG_CTX_MODE_SIGN);
1826         gpg_ctx_set_use_agent (gpg, ctx->use_agent);
1827         gpg_ctx_set_digest (gpg, digest);
1828         gpg_ctx_set_armor (gpg, TRUE);
1829         gpg_ctx_set_userid (gpg, userid);
1830         gpg_ctx_set_istream (gpg, istream);
1831         gpg_ctx_set_ostream (gpg, ostream);
1832         
1833         if (gpg_ctx_op_start (gpg) == -1) {
1834                 g_set_error (err, GMIME_ERROR, errno,
1835                              _("Failed to execute gpg: %s"),
1836                              errno ? g_strerror (errno) : _("Unknown"));
1837                 gpg_ctx_free (gpg);
1838                 
1839                 return -1;
1840         }
1841         
1842         while (!gpg_ctx_op_complete (gpg)) {
1843                 if (gpg_ctx_op_step (gpg, err) == -1) {
1844                         gpg_ctx_op_cancel (gpg);
1845                         gpg_ctx_free (gpg);
1846                         
1847                         return -1;
1848                 }
1849         }
1850         
1851         if (gpg_ctx_op_wait (gpg) != 0) {
1852                 const char *diagnostics;
1853                 int save;
1854                 
1855                 save = errno;
1856                 diagnostics = gpg_ctx_get_diagnostics (gpg);
1857                 errno = save;
1858                 
1859                 g_set_error_literal (err, GMIME_ERROR, errno, diagnostics);
1860                 gpg_ctx_free (gpg);
1861                 
1862                 return -1;
1863         }
1864         
1865         /* save the digest used */
1866         digest = gpg->digest;
1867         
1868         gpg_ctx_free (gpg);
1869         
1870         return digest;
1871 #else
1872         g_set_error (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED, _("PGP support is not enabled in this build"));
1873         
1874         return -1;
1875 #endif /* ENABLE_CRYPTOGRAPHY */
1876 }
1877
1878
1879 static GMimeSignatureList *
1880 gpg_verify (GMimeCryptoContext *context, GMimeDigestAlgo digest,
1881             GMimeStream *istream, GMimeStream *sigstream,
1882             GError **err)
1883 {
1884 #ifdef ENABLE_CRYPTOGRAPHY
1885         GMimeGpgContext *ctx = (GMimeGpgContext *) context;
1886         GMimeSignatureList *signatures;
1887         struct _GpgCtx *gpg;
1888         
1889         gpg = gpg_ctx_new (ctx);
1890         gpg_ctx_set_mode (gpg, GPG_CTX_MODE_VERIFY);
1891         gpg_ctx_set_sigstream (gpg, sigstream);
1892         gpg_ctx_set_istream (gpg, istream);
1893         gpg_ctx_set_digest (gpg, digest);
1894         
1895         if (gpg_ctx_op_start (gpg) == -1) {
1896                 g_set_error (err, GMIME_ERROR, errno,
1897                              _("Failed to execute gpg: %s"),
1898                              errno ? g_strerror (errno) : _("Unknown"));
1899                 gpg_ctx_free (gpg);
1900                 
1901                 return NULL;
1902         }
1903         
1904         while (!gpg_ctx_op_complete (gpg)) {
1905                 if (gpg_ctx_op_step (gpg, err) == -1) {
1906                         gpg_ctx_op_cancel (gpg);
1907                         gpg_ctx_free (gpg);
1908                         return NULL;
1909                 }
1910         }
1911         
1912         /* Only set the GError if we got no signature information from gpg */
1913         if (gpg_ctx_op_wait (gpg) != 0 && !gpg->signatures) {
1914                 const char *diagnostics;
1915                 int save;
1916                 
1917                 save = errno;
1918                 diagnostics = gpg_ctx_get_diagnostics (gpg);
1919                 errno = save;
1920                 
1921                 g_set_error_literal (err, GMIME_ERROR, errno, diagnostics);
1922                 gpg_ctx_free (gpg);
1923                 
1924                 return NULL;
1925         }
1926         
1927         signatures = gpg->signatures;
1928         gpg->signatures = NULL;
1929         gpg_ctx_free (gpg);
1930         
1931         return signatures;
1932 #else
1933         g_set_error (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED, _("PGP support is not enabled in this build"));
1934         
1935         return NULL;
1936 #endif /* ENABLE_CRYPTOGRAPHY */
1937 }
1938
1939
1940 static int
1941 gpg_encrypt (GMimeCryptoContext *context, gboolean sign, const char *userid,
1942              GMimeDigestAlgo digest, GPtrArray *recipients, GMimeStream *istream,
1943              GMimeStream *ostream, GError **err)
1944 {
1945 #ifdef ENABLE_CRYPTOGRAPHY
1946         GMimeGpgContext *ctx = (GMimeGpgContext *) context;
1947         struct _GpgCtx *gpg;
1948         guint i;
1949         
1950         gpg = gpg_ctx_new (ctx);
1951         if (sign) {
1952                 gpg_ctx_set_mode (gpg, GPG_CTX_MODE_SIGN_ENCRYPT);
1953                 gpg_ctx_set_use_agent (gpg, ctx->use_agent);
1954         } else {
1955                 gpg_ctx_set_mode (gpg, GPG_CTX_MODE_ENCRYPT);
1956         }
1957         
1958         gpg_ctx_set_always_trust (gpg, ctx->always_trust);
1959         gpg_ctx_set_digest (gpg, digest);
1960         gpg_ctx_set_armor (gpg, TRUE);
1961         gpg_ctx_set_userid (gpg, userid);
1962         gpg_ctx_set_istream (gpg, istream);
1963         gpg_ctx_set_ostream (gpg, ostream);
1964         
1965         for (i = 0; i < recipients->len; i++)
1966                 gpg_ctx_add_recipient (gpg, recipients->pdata[i]);
1967         
1968         if (gpg_ctx_op_start (gpg) == -1) {
1969                 g_set_error (err, GMIME_ERROR, errno,
1970                              _("Failed to execute gpg: %s"),
1971                              errno ? g_strerror (errno) : _("Unknown"));
1972                 gpg_ctx_free (gpg);
1973                 
1974                 return -1;
1975         }
1976         
1977         while (!gpg_ctx_op_complete (gpg)) {
1978                 if (gpg_ctx_op_step (gpg, err) == -1) {
1979                         gpg_ctx_op_cancel (gpg);
1980                         gpg_ctx_free (gpg);
1981                         
1982                         return -1;
1983                 }
1984         }
1985         
1986         if (gpg_ctx_op_wait (gpg) != 0) {
1987                 const char *diagnostics;
1988                 int save;
1989                 
1990                 save = errno;
1991                 diagnostics = gpg_ctx_get_diagnostics (gpg);
1992                 errno = save;
1993                 
1994                 g_set_error_literal (err, GMIME_ERROR, errno, diagnostics);
1995                 gpg_ctx_free (gpg);
1996                 
1997                 return -1;
1998         }
1999         
2000         gpg_ctx_free (gpg);
2001         
2002         return 0;
2003 #else
2004         g_set_error (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED, _("PGP support is not enabled in this build"));
2005         
2006         return -1;
2007 #endif /* ENABLE_CRYPTOGRAPHY */
2008 }
2009
2010
2011 static GMimeDecryptResult *
2012 gpg_decrypt (GMimeCryptoContext *context, GMimeStream *istream,
2013              GMimeStream *ostream, GError **err)
2014 {
2015 #ifdef ENABLE_CRYPTOGRAPHY
2016         GMimeGpgContext *ctx = (GMimeGpgContext *) context;
2017         GMimeDecryptResult *result;
2018         const char *diagnostics;
2019         struct _GpgCtx *gpg;
2020         int save;
2021         
2022         gpg = gpg_ctx_new (ctx);
2023         gpg_ctx_set_mode (gpg, GPG_CTX_MODE_DECRYPT);
2024         gpg_ctx_set_use_agent (gpg, ctx->use_agent);
2025         gpg_ctx_set_istream (gpg, istream);
2026         gpg_ctx_set_ostream (gpg, ostream);
2027         
2028         if (gpg_ctx_op_start (gpg) == -1) {
2029                 g_set_error (err, GMIME_ERROR, errno,
2030                              _("Failed to execute gpg: %s"),
2031                              errno ? g_strerror (errno) : _("Unknown"));
2032                 gpg_ctx_free (gpg);
2033                 
2034                 return NULL;
2035         }
2036         
2037         while (!gpg_ctx_op_complete (gpg)) {
2038                 if (gpg_ctx_op_step (gpg, err) == -1) {
2039                         gpg_ctx_op_cancel (gpg);
2040                         gpg_ctx_free (gpg);
2041                         
2042                         return NULL;
2043                 }
2044         }
2045         
2046         if (gpg_ctx_op_wait (gpg) != 0 && !gpg->decrypt_okay) {
2047                 save = errno;
2048                 diagnostics = gpg_ctx_get_diagnostics (gpg);
2049                 errno = save;
2050                 
2051                 g_set_error_literal (err, GMIME_ERROR, errno, diagnostics);
2052                 gpg_ctx_free (gpg);
2053                 
2054                 return NULL;
2055         }
2056         
2057         result = g_mime_decrypt_result_new ();
2058         result->recipients = gpg->encrypted_to;
2059         result->signatures = gpg->signatures;
2060         result->cipher = gpg->cipher;
2061         result->mdc = gpg->digest;
2062         gpg->encrypted_to = NULL;
2063         gpg->signatures = NULL;
2064         
2065         gpg_ctx_free (gpg);
2066         
2067         return result;
2068 #else
2069         g_set_error (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED, _("PGP support is not enabled in this build"));
2070         
2071         return NULL;
2072 #endif /* ENABLE_CRYPTOGRAPHY */
2073 }
2074
2075 static int
2076 gpg_import_keys (GMimeCryptoContext *context, GMimeStream *istream, GError **err)
2077 {
2078 #ifdef ENABLE_CRYPTOGRAPHY
2079         GMimeGpgContext *ctx = (GMimeGpgContext *) context;
2080         struct _GpgCtx *gpg;
2081         
2082         gpg = gpg_ctx_new (ctx);
2083         gpg_ctx_set_mode (gpg, GPG_CTX_MODE_IMPORT);
2084         gpg_ctx_set_istream (gpg, istream);
2085         
2086         if (gpg_ctx_op_start (gpg) == -1) {
2087                 g_set_error (err, GMIME_ERROR, errno,
2088                              _("Failed to execute gpg: %s"),
2089                              errno ? g_strerror (errno) : _("Unknown"));
2090                 gpg_ctx_free (gpg);
2091                 
2092                 return -1;
2093         }
2094         
2095         while (!gpg_ctx_op_complete (gpg)) {
2096                 if (gpg_ctx_op_step (gpg, err) == -1) {
2097                         gpg_ctx_op_cancel (gpg);
2098                         gpg_ctx_free (gpg);
2099                         
2100                         return -1;
2101                 }
2102         }
2103         
2104         if (gpg_ctx_op_wait (gpg) != 0) {
2105                 const char *diagnostics;
2106                 int save;
2107                 
2108                 save = errno;
2109                 diagnostics = gpg_ctx_get_diagnostics (gpg);
2110                 errno = save;
2111                 
2112                 g_set_error_literal (err, GMIME_ERROR, errno, diagnostics);
2113                 gpg_ctx_free (gpg);
2114                 
2115                 return -1;
2116         }
2117         
2118         gpg_ctx_free (gpg);
2119         
2120         return 0;
2121 #else
2122         g_set_error (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED, _("PGP support is not enabled in this build"));
2123         
2124         return -1;
2125 #endif /* ENABLE_CRYPTOGRAPHY */
2126 }
2127
2128 static int
2129 gpg_export_keys (GMimeCryptoContext *context, GPtrArray *keys, GMimeStream *ostream, GError **err)
2130 {
2131 #ifdef ENABLE_CRYPTOGRAPHY
2132         GMimeGpgContext *ctx = (GMimeGpgContext *) context;
2133         struct _GpgCtx *gpg;
2134         guint i;
2135         
2136         gpg = gpg_ctx_new (ctx);
2137         gpg_ctx_set_mode (gpg, GPG_CTX_MODE_EXPORT);
2138         gpg_ctx_set_armor (gpg, TRUE);
2139         gpg_ctx_set_ostream (gpg, ostream);
2140         
2141         for (i = 0; i < keys->len; i++) {
2142                 gpg_ctx_add_recipient (gpg, keys->pdata[i]);
2143         }
2144         
2145         if (gpg_ctx_op_start (gpg) == -1) {
2146                 g_set_error (err, GMIME_ERROR, errno,
2147                              _("Failed to execute gpg: %s"),
2148                              errno ? g_strerror (errno) : _("Unknown"));
2149                 gpg_ctx_free (gpg);
2150                 
2151                 return -1;
2152         }
2153         
2154         while (!gpg_ctx_op_complete (gpg)) {
2155                 if (gpg_ctx_op_step (gpg, err) == -1) {
2156                         gpg_ctx_op_cancel (gpg);
2157                         gpg_ctx_free (gpg);
2158                         
2159                         return -1;
2160                 }
2161         }
2162         
2163         if (gpg_ctx_op_wait (gpg) != 0) {
2164                 const char *diagnostics;
2165                 int save;
2166                 
2167                 save = errno;
2168                 diagnostics = gpg_ctx_get_diagnostics (gpg);
2169                 errno = save;
2170                 
2171                 g_set_error_literal (err, GMIME_ERROR, errno, diagnostics);
2172                 gpg_ctx_free (gpg);
2173                 
2174                 return -1;
2175         }
2176         
2177         gpg_ctx_free (gpg);
2178         
2179         return 0;
2180 #else
2181         g_set_error (err, GMIME_ERROR, GMIME_ERROR_NOT_SUPPORTED, _("PGP support is not enabled in this build"));
2182         
2183         return -1;
2184 #endif /* ENABLE_CRYPTOGRAPHY */
2185 }
2186
2187
2188 /**
2189  * g_mime_gpg_context_new:
2190  * @request_passwd: a #GMimePasswordRequestFunc
2191  * @path: path to gpg binary
2192  *
2193  * Creates a new gpg crypto context object.
2194  *
2195  * Returns: a new gpg crypto context object.
2196  **/
2197 GMimeCryptoContext *
2198 g_mime_gpg_context_new (GMimePasswordRequestFunc request_passwd, const char *path)
2199 {
2200 #ifdef ENABLE_CRYPTOGRAPHY
2201         GMimeCryptoContext *crypto;
2202         GMimeGpgContext *ctx;
2203         
2204         g_return_val_if_fail (path != NULL, NULL);
2205         
2206         ctx = g_object_newv (GMIME_TYPE_GPG_CONTEXT, 0, NULL);
2207         ctx->path = g_strdup (path);
2208         
2209         crypto = (GMimeCryptoContext *) ctx;
2210         crypto->request_passwd = request_passwd;
2211         
2212         return crypto;
2213 #else
2214         return NULL;
2215 #endif /* ENABLE_CRYPTOGRAPHY */
2216 }
2217
2218
2219 /**
2220  * g_mime_gpg_context_get_auto_key_retrieve:
2221  * @ctx: a #GMimeGpgContext
2222  *
2223  * Gets the @auto_key_retrieve flag on the gpg context.
2224  *
2225  * Returns: the @auto_key_retrieve flag on the gpg context.
2226  **/
2227 gboolean
2228 g_mime_gpg_context_get_auto_key_retrieve (GMimeGpgContext *ctx)
2229 {
2230         g_return_val_if_fail (GMIME_IS_GPG_CONTEXT (ctx), FALSE);
2231         
2232         return ctx->auto_key_retrieve;
2233 }
2234
2235
2236 /**
2237  * g_mime_gpg_context_set_auto_key_retrieve:
2238  * @ctx: a #GMimeGpgContext
2239  * @auto_key_retrieve: auto-retrieve keys from a keys server
2240  *
2241  * Sets the @auto_key_retrieve flag on the gpg context which is used
2242  * for signature verification.
2243  **/
2244 void
2245 g_mime_gpg_context_set_auto_key_retrieve (GMimeGpgContext *ctx, gboolean auto_key_retrieve)
2246 {
2247         g_return_if_fail (GMIME_IS_GPG_CONTEXT (ctx));
2248         
2249         ctx->auto_key_retrieve = auto_key_retrieve;
2250 }
2251
2252
2253 /**
2254  * g_mime_gpg_context_get_always_trust:
2255  * @ctx: a #GMimeGpgContext
2256  *
2257  * Gets the always_trust flag on the gpg context.
2258  *
2259  * Returns: the always_trust flag on the gpg context.
2260  **/
2261 gboolean
2262 g_mime_gpg_context_get_always_trust (GMimeGpgContext *ctx)
2263 {
2264         g_return_val_if_fail (GMIME_IS_GPG_CONTEXT (ctx), FALSE);
2265         
2266         return ctx->always_trust;
2267 }
2268
2269
2270 /**
2271  * g_mime_gpg_context_set_always_trust:
2272  * @ctx: a #GMimeGpgContext
2273  * @always_trust: always trust flag
2274  *
2275  * Sets the @always_trust flag on the gpg context which is used for
2276  * encryption.
2277  **/
2278 void
2279 g_mime_gpg_context_set_always_trust (GMimeGpgContext *ctx, gboolean always_trust)
2280 {
2281         g_return_if_fail (GMIME_IS_GPG_CONTEXT (ctx));
2282         
2283         ctx->always_trust = always_trust;
2284 }
2285
2286
2287 /**
2288  * g_mime_gpg_context_get_use_agent:
2289  * @ctx: a #GMimeGpgContext
2290  *
2291  * Gets the use_agent flag on the gpg context.
2292  *
2293  * Returns: the use_agent flag on the gpg context, which indicates
2294  * that GnuPG should attempt to use gpg-agent for credentials.
2295  **/
2296 gboolean
2297 g_mime_gpg_context_get_use_agent (GMimeGpgContext *ctx)
2298 {
2299         g_return_val_if_fail (GMIME_IS_GPG_CONTEXT (ctx), FALSE);
2300         
2301         return ctx->use_agent;
2302 }
2303
2304
2305 /**
2306  * g_mime_gpg_context_set_use_agent:
2307  * @ctx: a #GMimeGpgContext
2308  * @use_agent: always trust flag
2309  *
2310  * Sets the @use_agent flag on the gpg context, which indicates that
2311  * GnuPG should attempt to use gpg-agent for credentials.
2312  **/
2313 void
2314 g_mime_gpg_context_set_use_agent (GMimeGpgContext *ctx, gboolean use_agent)
2315 {
2316         g_return_if_fail (GMIME_IS_GPG_CONTEXT (ctx));
2317         
2318         ctx->use_agent = use_agent;
2319 }