809806c4df480b32553e19877b07eceabcaea5b2
[gpgme.git] / src / engine-gpg.c
1 /* engine-gpg.c - Gpg Engine.
2    Copyright (C) 2000 Werner Koch (dd9jn)
3    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007,
4                  2009, 2010, 2012, 2013 g10 Code GmbH
5
6    This file is part of GPGME.
7
8    GPGME is free software; you can redistribute it and/or modify it
9    under the terms of the GNU Lesser General Public License as
10    published by the Free Software Foundation; either version 2.1 of
11    the License, or (at your option) any later version.
12
13    GPGME is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    Lesser General Public License for more details.
17
18    You should have received a copy of the GNU Lesser General Public
19    License along with this program; if not, see <https://www.gnu.org/licenses/>.
20 */
21
22 #if HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <assert.h>
29 #include <errno.h>
30 #ifdef HAVE_UNISTD_H
31 # include <unistd.h>
32 #endif
33 #ifdef HAVE_LOCALE_H
34 #include <locale.h>
35 #endif
36
37 #include "gpgme.h"
38 #include "util.h"
39 #include "ops.h"
40 #include "wait.h"
41 #include "context.h"  /*temp hack until we have GpmeData methods to do I/O */
42 #include "priv-io.h"
43 #include "sema.h"
44 #include "debug.h"
45 #include "data.h"
46
47 #include "engine-backend.h"
48
49
50 /* This type is used to build a list of gpg arguments and data
51    sources/sinks.  */
52 struct arg_and_data_s
53 {
54   struct arg_and_data_s *next;
55   gpgme_data_t data;  /* If this is not NULL, use arg below.  */
56   int inbound;     /* True if this is used for reading from gpg.  */
57   int dup_to;
58   int print_fd;    /* Print the fd number and not the special form of it.  */
59   int *arg_locp;   /* Write back the argv idx of this argument when
60                       building command line to this location.  */
61   char arg[1];     /* Used if data above is not used.  */
62 };
63
64
65 struct fd_data_map_s
66 {
67   gpgme_data_t data;
68   int inbound;  /* true if this is used for reading from gpg */
69   int dup_to;
70   int fd;       /* the fd to use */
71   int peer_fd;  /* the other side of the pipe */
72   int arg_loc;  /* The index into the argv for translation purposes.  */
73   void *tag;
74 };
75
76
77 /* NB.: R_LINE is allocated an gpgrt function and thus gpgrt_free
78  * shall be used to release it.  This takes care of custom memory
79  * allocators and avoids problems on Windows with different runtimes
80  * used for libgpg-error/gpgrt and gpgme.  */
81 typedef gpgme_error_t (*colon_preprocessor_t) (char *line, char **rline);
82
83 struct engine_gpg
84 {
85   char *file_name;
86   char *version;
87
88   char *lc_messages;
89   char *lc_ctype;
90
91   struct arg_and_data_s *arglist;
92   struct arg_and_data_s **argtail;
93
94   struct
95   {
96     int fd[2];
97     int arg_loc;
98     size_t bufsize;
99     char *buffer;
100     size_t readpos;
101     int eof;
102     engine_status_handler_t fnc;
103     void *fnc_value;
104     gpgme_status_cb_t mon_cb;
105     void *mon_cb_value;
106     void *tag;
107   } status;
108
109   /* This is a kludge - see the comment at colon_line_handler.  */
110   struct
111   {
112     int fd[2];
113     int arg_loc;
114     size_t bufsize;
115     char *buffer;
116     size_t readpos;
117     int eof;
118     engine_colon_line_handler_t fnc;  /* this indicate use of this structrue */
119     void *fnc_value;
120     void *tag;
121     colon_preprocessor_t preprocess_fnc;
122   } colon;
123
124   char **argv;
125   struct fd_data_map_s *fd_data_map;
126
127   /* stuff needed for interactive (command) mode */
128   struct
129   {
130     int used;
131     int fd;
132     void *cb_data;
133     int idx;            /* Index in fd_data_map */
134     gpgme_status_code_t code;  /* last code */
135     char *keyword;       /* what has been requested (malloced) */
136     engine_command_handler_t fnc;
137     void *fnc_value;
138     /* The kludges never end.  This is used to couple command handlers
139        with output data in edit key mode.  */
140     gpgme_data_t linked_data;
141     int linked_idx;
142   } cmd;
143
144   struct gpgme_io_cbs io_cbs;
145   gpgme_pinentry_mode_t pinentry_mode;
146   char request_origin[10];
147
148   struct {
149     unsigned int no_symkey_cache : 1;
150   } flags;
151
152   /* NULL or the data object fed to --override_session_key-fd.  */
153   gpgme_data_t override_session_key;
154 };
155
156 typedef struct engine_gpg *engine_gpg_t;
157
158 \f
159 static void
160 gpg_io_event (void *engine, gpgme_event_io_t type, void *type_data)
161 {
162   engine_gpg_t gpg = engine;
163
164   TRACE3 (DEBUG_ENGINE, "gpgme:gpg_io_event", gpg,
165           "event %p, type %d, type_data %p",
166           gpg->io_cbs.event, type, type_data);
167   if (gpg->io_cbs.event)
168     (*gpg->io_cbs.event) (gpg->io_cbs.event_priv, type, type_data);
169 }
170
171
172 static void
173 close_notify_handler (int fd, void *opaque)
174 {
175   engine_gpg_t gpg = opaque;
176   assert (fd != -1);
177
178   if (gpg->status.fd[0] == fd)
179     {
180       if (gpg->status.tag)
181         (*gpg->io_cbs.remove) (gpg->status.tag);
182       gpg->status.fd[0] = -1;
183     }
184   else if (gpg->status.fd[1] == fd)
185     gpg->status.fd[1] = -1;
186   else if (gpg->colon.fd[0] == fd)
187     {
188       if (gpg->colon.tag)
189         (*gpg->io_cbs.remove) (gpg->colon.tag);
190       gpg->colon.fd[0] = -1;
191     }
192   else if (gpg->colon.fd[1] == fd)
193     gpg->colon.fd[1] = -1;
194   else if (gpg->cmd.fd == fd)
195     gpg->cmd.fd = -1;
196   else if (gpg->fd_data_map)
197     {
198       int i;
199
200       for (i = 0; gpg->fd_data_map[i].data; i++)
201         {
202           if (gpg->fd_data_map[i].fd == fd)
203             {
204               if (gpg->fd_data_map[i].tag)
205                 (*gpg->io_cbs.remove) (gpg->fd_data_map[i].tag);
206               gpg->fd_data_map[i].fd = -1;
207               break;
208             }
209           if (gpg->fd_data_map[i].peer_fd == fd)
210             {
211               gpg->fd_data_map[i].peer_fd = -1;
212               break;
213             }
214         }
215     }
216 }
217
218 /* If FRONT is true, push at the front of the list.  Use this for
219    options added late in the process.  */
220 static gpgme_error_t
221 _add_arg (engine_gpg_t gpg, const char *prefix, const char *arg, size_t arglen,
222           int front, int *arg_locp)
223 {
224   struct arg_and_data_s *a;
225   size_t prefixlen = prefix? strlen (prefix) : 0;
226
227   assert (gpg);
228   assert (arg);
229
230   a = malloc (sizeof *a + prefixlen + arglen);
231   if (!a)
232     return gpg_error_from_syserror ();
233
234   a->data = NULL;
235   a->dup_to = -1;
236   a->arg_locp = arg_locp;
237
238   if (prefixlen)
239     memcpy (a->arg, prefix, prefixlen);
240   memcpy (a->arg + prefixlen, arg, arglen);
241   a->arg[prefixlen + arglen] = 0;
242   if (front)
243     {
244       a->next = gpg->arglist;
245       if (!gpg->arglist)
246         {
247           /* If this is the first argument, we need to update the tail
248              pointer.  */
249           gpg->argtail = &a->next;
250         }
251       gpg->arglist = a;
252     }
253   else
254     {
255       a->next = NULL;
256       *gpg->argtail = a;
257       gpg->argtail = &a->next;
258     }
259
260   return 0;
261 }
262
263
264 static gpgme_error_t
265 add_arg_ext (engine_gpg_t gpg, const char *arg, int front)
266 {
267   return _add_arg (gpg, NULL, arg, strlen (arg), front, NULL);
268 }
269
270 static gpgme_error_t
271 add_arg_with_locp (engine_gpg_t gpg, const char *arg, int *locp)
272 {
273   return _add_arg (gpg, NULL, arg, strlen (arg), 0, locp);
274 }
275
276 static gpgme_error_t
277 add_arg (engine_gpg_t gpg, const char *arg)
278 {
279   return _add_arg (gpg, NULL, arg, strlen (arg), 0, NULL);
280 }
281
282 static gpgme_error_t
283 add_arg_pfx (engine_gpg_t gpg, const char *prefix, const char *arg)
284 {
285   return _add_arg (gpg, prefix, arg, strlen (arg), 0, NULL);
286 }
287
288 static gpgme_error_t
289 add_arg_len (engine_gpg_t gpg, const char *prefix,
290              const char *arg, size_t arglen)
291 {
292   return _add_arg (gpg, prefix, arg, arglen, 0, NULL);
293 }
294
295
296 static gpgme_error_t
297 add_data (engine_gpg_t gpg, gpgme_data_t data, int dup_to, int inbound)
298 {
299   struct arg_and_data_s *a;
300
301   assert (gpg);
302   assert (data);
303
304   a = malloc (sizeof *a - 1);
305   if (!a)
306     return gpg_error_from_syserror ();
307   a->next = NULL;
308   a->data = data;
309   a->inbound = inbound;
310   a->arg_locp = NULL;
311
312   if (dup_to == -2)
313     {
314       a->print_fd = 1;
315       a->dup_to = -1;
316     }
317   else
318     {
319       a->print_fd = 0;
320       a->dup_to = dup_to;
321     }
322   *gpg->argtail = a;
323   gpg->argtail = &a->next;
324   return 0;
325 }
326
327
328 /* Return true if the engine's version is at least VERSION.  */
329 static int
330 have_gpg_version (engine_gpg_t gpg, const char *version)
331 {
332   return _gpgme_compare_versions (gpg->version, version);
333 }
334
335
336 \f
337 static char *
338 gpg_get_version (const char *file_name)
339 {
340   return _gpgme_get_program_version (file_name ? file_name
341                                      : _gpgme_get_default_gpg_name ());
342 }
343
344
345 static const char *
346 gpg_get_req_version (void)
347 {
348   return "1.4.0";
349 }
350
351
352 static void
353 free_argv (char **argv)
354 {
355   int i;
356
357   for (i = 0; argv[i]; i++)
358     free (argv[i]);
359   free (argv);
360 }
361
362
363 static void
364 free_fd_data_map (struct fd_data_map_s *fd_data_map)
365 {
366   int i;
367
368   if (!fd_data_map)
369     return;
370
371   for (i = 0; fd_data_map[i].data; i++)
372     {
373       if (fd_data_map[i].fd != -1)
374         _gpgme_io_close (fd_data_map[i].fd);
375       if (fd_data_map[i].peer_fd != -1)
376         _gpgme_io_close (fd_data_map[i].peer_fd);
377       /* Don't release data because this is only a reference.  */
378     }
379   free (fd_data_map);
380 }
381
382
383 static gpgme_error_t
384 gpg_cancel (void *engine)
385 {
386   engine_gpg_t gpg = engine;
387
388   if (!gpg)
389     return gpg_error (GPG_ERR_INV_VALUE);
390
391   /* If gpg may be waiting for a cmd, close the cmd fd first.  On
392      Windows, close operations block on the reader/writer thread.  */
393   if (gpg->cmd.used)
394     {
395       if (gpg->cmd.fd != -1)
396         _gpgme_io_close (gpg->cmd.fd);
397       else if (gpg->fd_data_map
398                && gpg->fd_data_map[gpg->cmd.idx].fd != -1)
399         _gpgme_io_close (gpg->fd_data_map[gpg->cmd.idx].fd);
400     }
401
402   if (gpg->status.fd[0] != -1)
403     _gpgme_io_close (gpg->status.fd[0]);
404   if (gpg->status.fd[1] != -1)
405     _gpgme_io_close (gpg->status.fd[1]);
406   if (gpg->colon.fd[0] != -1)
407     _gpgme_io_close (gpg->colon.fd[0]);
408   if (gpg->colon.fd[1] != -1)
409     _gpgme_io_close (gpg->colon.fd[1]);
410   if (gpg->fd_data_map)
411     {
412       free_fd_data_map (gpg->fd_data_map);
413       gpg->fd_data_map = NULL;
414     }
415
416   return 0;
417 }
418
419 static void
420 gpg_release (void *engine)
421 {
422   engine_gpg_t gpg = engine;
423
424   if (!gpg)
425     return;
426
427   gpg_cancel (engine);
428
429   if (gpg->file_name)
430     free (gpg->file_name);
431   if (gpg->version)
432     free (gpg->version);
433
434   if (gpg->lc_messages)
435     free (gpg->lc_messages);
436   if (gpg->lc_ctype)
437     free (gpg->lc_ctype);
438
439   while (gpg->arglist)
440     {
441       struct arg_and_data_s *next = gpg->arglist->next;
442
443       free (gpg->arglist);
444       gpg->arglist = next;
445     }
446
447   if (gpg->status.buffer)
448     free (gpg->status.buffer);
449   if (gpg->colon.buffer)
450     free (gpg->colon.buffer);
451   if (gpg->argv)
452     free_argv (gpg->argv);
453   if (gpg->cmd.keyword)
454     free (gpg->cmd.keyword);
455
456   gpgme_data_release (gpg->override_session_key);
457
458   free (gpg);
459 }
460
461
462 static gpgme_error_t
463 gpg_new (void **engine, const char *file_name, const char *home_dir,
464          const char *version)
465 {
466   engine_gpg_t gpg;
467   gpgme_error_t rc = 0;
468   char *dft_display = NULL;
469   char dft_ttyname[64];
470   char *dft_ttytype = NULL;
471   char *env_tty = NULL;
472
473   gpg = calloc (1, sizeof *gpg);
474   if (!gpg)
475     return gpg_error_from_syserror ();
476
477   if (file_name)
478     {
479       gpg->file_name = strdup (file_name);
480       if (!gpg->file_name)
481         {
482           rc = gpg_error_from_syserror ();
483           goto leave;
484         }
485     }
486
487   if (version)
488     {
489       gpg->version = strdup (version);
490       if (!gpg->version)
491         {
492           rc = gpg_error_from_syserror ();
493           goto leave;
494         }
495     }
496
497   gpg->argtail = &gpg->arglist;
498   gpg->status.fd[0] = -1;
499   gpg->status.fd[1] = -1;
500   gpg->colon.fd[0] = -1;
501   gpg->colon.fd[1] = -1;
502   gpg->cmd.fd = -1;
503   gpg->cmd.idx = -1;
504   gpg->cmd.linked_data = NULL;
505   gpg->cmd.linked_idx = -1;
506
507   /* Allocate the read buffer for the status pipe.  */
508   gpg->status.bufsize = 1024;
509   gpg->status.readpos = 0;
510   gpg->status.buffer = malloc (gpg->status.bufsize);
511   if (!gpg->status.buffer)
512     {
513       rc = gpg_error_from_syserror ();
514       goto leave;
515     }
516   /* In any case we need a status pipe - create it right here and
517      don't handle it with our generic gpgme_data_t mechanism.  */
518   if (_gpgme_io_pipe (gpg->status.fd, 1) == -1)
519     {
520       rc = gpg_error_from_syserror ();
521       goto leave;
522     }
523   if (_gpgme_io_set_close_notify (gpg->status.fd[0],
524                                   close_notify_handler, gpg)
525       || _gpgme_io_set_close_notify (gpg->status.fd[1],
526                                      close_notify_handler, gpg))
527     {
528       rc = gpg_error (GPG_ERR_GENERAL);
529       goto leave;
530     }
531   gpg->status.eof = 0;
532
533   if (home_dir)
534     {
535       rc = add_arg (gpg, "--homedir");
536       if (!rc)
537         rc = add_arg (gpg, home_dir);
538       if (rc)
539         goto leave;
540     }
541
542   rc = add_arg (gpg, "--status-fd");
543   if (rc)
544     goto leave;
545
546   {
547     char buf[25];
548     _gpgme_io_fd2str (buf, sizeof (buf), gpg->status.fd[1]);
549     rc = add_arg_with_locp (gpg, buf, &gpg->status.arg_loc);
550     if (rc)
551       goto leave;
552   }
553
554   rc = add_arg (gpg, "--no-tty");
555   if (!rc)
556     rc = add_arg (gpg, "--charset");
557   if (!rc)
558     rc = add_arg (gpg, "utf8");
559   if (!rc)
560     rc = add_arg (gpg, "--enable-progress-filter");
561   if (!rc && have_gpg_version (gpg, "2.1.11"))
562     rc = add_arg (gpg, "--exit-on-status-write-error");
563   if (rc)
564     goto leave;
565
566   rc = _gpgme_getenv ("DISPLAY", &dft_display);
567   if (rc)
568     goto leave;
569   if (dft_display)
570     {
571       rc = add_arg (gpg, "--display");
572       if (!rc)
573         rc = add_arg (gpg, dft_display);
574
575       free (dft_display);
576       if (rc)
577         goto leave;
578     }
579
580   rc = _gpgme_getenv ("GPG_TTY", &env_tty);
581   if (isatty (1) || env_tty || rc)
582     {
583       int err = 0;
584
585       if (rc)
586         goto leave;
587       else if (env_tty)
588         {
589           snprintf (dft_ttyname, sizeof (dft_ttyname), "%s", env_tty);
590           free (env_tty);
591         }
592       else
593         err = ttyname_r (1, dft_ttyname, sizeof (dft_ttyname));
594
595       /* Even though isatty() returns 1, ttyname_r() may fail in many
596          ways, e.g., when /dev/pts is not accessible under chroot.  */
597       if (!err)
598         {
599           if (*dft_ttyname)
600             {
601               rc = add_arg (gpg, "--ttyname");
602               if (!rc)
603                 rc = add_arg (gpg, dft_ttyname);
604             }
605           else
606             rc = 0;
607           if (!rc)
608             {
609               rc = _gpgme_getenv ("TERM", &dft_ttytype);
610               if (rc)
611                 goto leave;
612
613               if (dft_ttytype)
614                 {
615                   rc = add_arg (gpg, "--ttytype");
616                   if (!rc)
617                     rc = add_arg (gpg, dft_ttytype);
618                 }
619
620               free (dft_ttytype);
621             }
622           if (rc)
623             goto leave;
624         }
625     }
626
627  leave:
628   if (rc)
629     gpg_release (gpg);
630   else
631     *engine = gpg;
632   return rc;
633 }
634
635
636 /* Copy flags from CTX into the engine object.  */
637 static void
638 gpg_set_engine_flags (void *engine, const gpgme_ctx_t ctx)
639 {
640   engine_gpg_t gpg = engine;
641
642   if (ctx->request_origin && have_gpg_version (gpg, "2.2.6"))
643     {
644       if (strlen (ctx->request_origin) + 1 > sizeof gpg->request_origin)
645         strcpy (gpg->request_origin, "xxx"); /* Too long  - force error */
646       else
647         strcpy (gpg->request_origin, ctx->request_origin);
648     }
649   else if (ctx->no_symkey_cache && have_gpg_version (gpg, "2.2.7"))
650     {
651       gpg->flags.no_symkey_cache = 1;
652     }
653   else
654     *gpg->request_origin = 0;
655 }
656
657
658 static gpgme_error_t
659 gpg_set_locale (void *engine, int category, const char *value)
660 {
661   engine_gpg_t gpg = engine;
662
663   if (0)
664     ;
665 #ifdef LC_CTYPE
666   else if (category == LC_CTYPE)
667     {
668       if (gpg->lc_ctype)
669         {
670           free (gpg->lc_ctype);
671           gpg->lc_ctype = NULL;
672         }
673       if (value)
674         {
675           gpg->lc_ctype = strdup (value);
676           if (!gpg->lc_ctype)
677             return gpg_error_from_syserror ();
678         }
679     }
680 #endif
681 #ifdef LC_MESSAGES
682   else if (category == LC_MESSAGES)
683     {
684       if (gpg->lc_messages)
685         {
686           free (gpg->lc_messages);
687           gpg->lc_messages = NULL;
688         }
689       if (value)
690         {
691           gpg->lc_messages = strdup (value);
692           if (!gpg->lc_messages)
693             return gpg_error_from_syserror ();
694         }
695     }
696 #endif /* LC_MESSAGES */
697   else
698     return gpg_error (GPG_ERR_INV_VALUE);
699
700   return 0;
701 }
702
703 /* This sets a status callback for monitoring status lines before they
704  * are passed to a caller set handler.  */
705 static void
706 gpg_set_status_cb (void *engine, gpgme_status_cb_t cb, void *cb_value)
707 {
708   engine_gpg_t gpg = engine;
709
710   gpg->status.mon_cb = cb;
711   gpg->status.mon_cb_value = cb_value;
712 }
713
714
715 /* Note, that the status_handler is allowed to modifiy the args
716    value.  */
717 static void
718 gpg_set_status_handler (void *engine, engine_status_handler_t fnc,
719                         void *fnc_value)
720 {
721   engine_gpg_t gpg = engine;
722
723   gpg->status.fnc = fnc;
724   gpg->status.fnc_value = fnc_value;
725 }
726
727 /* Kludge to process --with-colon output.  */
728 static gpgme_error_t
729 gpg_set_colon_line_handler (void *engine, engine_colon_line_handler_t fnc,
730                             void *fnc_value)
731 {
732   engine_gpg_t gpg = engine;
733
734   gpg->colon.bufsize = 1024;
735   gpg->colon.readpos = 0;
736   gpg->colon.buffer = malloc (gpg->colon.bufsize);
737   if (!gpg->colon.buffer)
738     return gpg_error_from_syserror ();
739
740   if (_gpgme_io_pipe (gpg->colon.fd, 1) == -1)
741     {
742       int saved_err = gpg_error_from_syserror ();
743       free (gpg->colon.buffer);
744       gpg->colon.buffer = NULL;
745       return saved_err;
746     }
747   if (_gpgme_io_set_close_notify (gpg->colon.fd[0], close_notify_handler, gpg)
748       || _gpgme_io_set_close_notify (gpg->colon.fd[1],
749                                      close_notify_handler, gpg))
750     return gpg_error (GPG_ERR_GENERAL);
751   gpg->colon.eof = 0;
752   gpg->colon.fnc = fnc;
753   gpg->colon.fnc_value = fnc_value;
754   return 0;
755 }
756
757
758 static gpgme_error_t
759 command_handler (void *opaque, int fd)
760 {
761   struct io_cb_data *data = (struct io_cb_data *) opaque;
762   engine_gpg_t gpg = (engine_gpg_t) data->handler_value;
763   gpgme_error_t err;
764   int processed = 0;
765   assert (gpg->cmd.used);
766   assert (gpg->cmd.code);
767   assert (gpg->cmd.fnc);
768
769   err = gpg->cmd.fnc (gpg->cmd.fnc_value, gpg->cmd.code, gpg->cmd.keyword, fd,
770                       &processed);
771
772   gpg->cmd.code = 0;
773   /* And sleep again until read_status will wake us up again.  */
774   /* XXX We must check if there are any more fds active after removing
775      this one.  */
776   (*gpg->io_cbs.remove) (gpg->fd_data_map[gpg->cmd.idx].tag);
777   gpg->cmd.fd = gpg->fd_data_map[gpg->cmd.idx].fd;
778   gpg->fd_data_map[gpg->cmd.idx].fd = -1;
779
780   if (err)
781     return err;
782
783   /* We always need to send at least a newline character.  */
784   if (!processed)
785     _gpgme_io_write (fd, "\n", 1);
786
787   return 0;
788 }
789
790
791
792 /* The Fnc will be called to get a value for one of the commands with
793    a key KEY.  If the Code passed to FNC is 0, the function may release
794    resources associated with the returned value from another call.  To
795    match such a second call to a first call, the returned value from
796    the first call is passed as keyword.  */
797 static gpgme_error_t
798 gpg_set_command_handler (void *engine, engine_command_handler_t fnc,
799                          void *fnc_value, gpgme_data_t linked_data)
800 {
801   engine_gpg_t gpg = engine;
802   gpgme_error_t rc;
803
804   rc = add_arg (gpg, "--command-fd");
805   if (rc)
806     return rc;
807
808   /* This is a hack.  We don't have a real data object.  The only
809      thing that matters is that we use something unique, so we use the
810      address of the cmd structure in the gpg object.  */
811   rc = add_data (gpg, (void *) &gpg->cmd, -2, 0);
812   if (rc)
813     return rc;
814
815   gpg->cmd.fnc = fnc;
816   gpg->cmd.cb_data = (void *) &gpg->cmd;
817   gpg->cmd.fnc_value = fnc_value;
818   gpg->cmd.linked_data = linked_data;
819   gpg->cmd.used = 1;
820   return 0;
821 }
822
823
824 static gpgme_error_t
825 build_argv (engine_gpg_t gpg, const char *pgmname)
826 {
827   gpgme_error_t err;
828   struct arg_and_data_s *a;
829   struct fd_data_map_s *fd_data_map;
830   size_t datac=0, argc=0;
831   char **argv;
832   int need_special = 0;
833   int use_agent = 0;
834   char *p;
835
836   if (_gpgme_in_gpg_one_mode ())
837     {
838       /* In GnuPG-1 mode we don't want to use the agent with a
839          malformed environment variable.  This is only a very basic
840          test but sufficient to make our life in the regression tests
841          easier.  With GnuPG-2 the agent is anyway required and on
842          modern installations GPG_AGENT_INFO is optional.  */
843       err = _gpgme_getenv ("GPG_AGENT_INFO", &p);
844       if (err)
845         return err;
846       use_agent = (p && strchr (p, ':'));
847       if (p)
848         free (p);
849     }
850
851   if (gpg->argv)
852     {
853       free_argv (gpg->argv);
854       gpg->argv = NULL;
855     }
856   if (gpg->fd_data_map)
857     {
858       free_fd_data_map (gpg->fd_data_map);
859       gpg->fd_data_map = NULL;
860     }
861
862   argc++;       /* For argv[0].  */
863   for (a = gpg->arglist; a; a = a->next)
864     {
865       argc++;
866       if (a->data)
867         {
868           /*fprintf (stderr, "build_argv: data\n" );*/
869           datac++;
870           if (a->dup_to == -1 && !a->print_fd)
871             need_special = 1;
872         }
873       else
874         {
875           /*   fprintf (stderr, "build_argv: arg=`%s'\n", a->arg );*/
876         }
877     }
878   if (need_special)
879     argc++;
880   if (use_agent)
881     argc++;
882   if (gpg->pinentry_mode)
883     argc++;
884   if (!gpg->cmd.used)
885     argc++;     /* --batch */
886   argc += 3;    /* --no-sk-comments, --request-origin, --no-symkey-cache */
887
888   argv = calloc (argc + 1, sizeof *argv);
889   if (!argv)
890     return gpg_error_from_syserror ();
891   fd_data_map = calloc (datac + 1, sizeof *fd_data_map);
892   if (!fd_data_map)
893     {
894       int saved_err = gpg_error_from_syserror ();
895       free_argv (argv);
896       return saved_err;
897     }
898
899   argc = datac = 0;
900   argv[argc] = strdup (_gpgme_get_basename (pgmname)); /* argv[0] */
901   if (!argv[argc])
902     {
903       int saved_err = gpg_error_from_syserror ();
904       free (fd_data_map);
905       free_argv (argv);
906       return saved_err;
907     }
908   argc++;
909   if (need_special)
910     {
911       argv[argc] = strdup ("--enable-special-filenames");
912       if (!argv[argc])
913         {
914           int saved_err = gpg_error_from_syserror ();
915           free (fd_data_map);
916           free_argv (argv);
917           return saved_err;
918         }
919       argc++;
920     }
921   if (use_agent)
922     {
923       argv[argc] = strdup ("--use-agent");
924       if (!argv[argc])
925         {
926           int saved_err = gpg_error_from_syserror ();
927           free (fd_data_map);
928           free_argv (argv);
929           return saved_err;
930         }
931       argc++;
932     }
933
934   if (*gpg->request_origin)
935     {
936       argv[argc] = _gpgme_strconcat ("--request-origin=",
937                                      gpg->request_origin, NULL);
938       if (!argv[argc])
939         {
940           int saved_err = gpg_error_from_syserror ();
941           free (fd_data_map);
942           free_argv (argv);
943           return saved_err;
944         }
945       argc++;
946     }
947
948   if (gpg->flags.no_symkey_cache)
949     {
950       argv[argc] = strdup ("--no-symkey-cache");
951       if (!argv[argc])
952         {
953           int saved_err = gpg_error_from_syserror ();
954           free (fd_data_map);
955           free_argv (argv);
956           return saved_err;
957         }
958       argc++;
959     }
960
961   if (gpg->pinentry_mode && have_gpg_version (gpg, "2.1.0"))
962     {
963       const char *s = NULL;
964       switch (gpg->pinentry_mode)
965         {
966         case GPGME_PINENTRY_MODE_DEFAULT: break;
967         case GPGME_PINENTRY_MODE_ASK:     s = "--pinentry-mode=ask"; break;
968         case GPGME_PINENTRY_MODE_CANCEL:  s = "--pinentry-mode=cancel"; break;
969         case GPGME_PINENTRY_MODE_ERROR:   s = "--pinentry-mode=error"; break;
970         case GPGME_PINENTRY_MODE_LOOPBACK:s = "--pinentry-mode=loopback"; break;
971         }
972       if (s)
973         {
974           argv[argc] = strdup (s);
975           if (!argv[argc])
976             {
977               int saved_err = gpg_error_from_syserror ();
978               free (fd_data_map);
979               free_argv (argv);
980               return saved_err;
981             }
982           argc++;
983         }
984     }
985
986   if (!gpg->cmd.used)
987     {
988       argv[argc] = strdup ("--batch");
989       if (!argv[argc])
990         {
991           int saved_err = gpg_error_from_syserror ();
992           free (fd_data_map);
993           free_argv (argv);
994           return saved_err;
995         }
996       argc++;
997     }
998   argv[argc] = strdup ("--no-sk-comments");
999   if (!argv[argc])
1000     {
1001       int saved_err = gpg_error_from_syserror ();
1002       free (fd_data_map);
1003       free_argv (argv);
1004       return saved_err;
1005     }
1006   argc++;
1007   for (a = gpg->arglist; a; a = a->next)
1008     {
1009       if (a->arg_locp)
1010         *(a->arg_locp) = argc;
1011
1012       if (a->data)
1013         {
1014           /* Create a pipe to pass it down to gpg.  */
1015           fd_data_map[datac].inbound = a->inbound;
1016
1017           /* Create a pipe.  */
1018           {
1019             int fds[2];
1020
1021             if (_gpgme_io_pipe (fds, fd_data_map[datac].inbound ? 1 : 0)
1022                 == -1)
1023               {
1024                 int saved_errno = errno;
1025                 free (fd_data_map);
1026                 free_argv (argv);
1027                 return gpg_error (saved_errno);
1028               }
1029             if (_gpgme_io_set_close_notify (fds[0],
1030                                             close_notify_handler, gpg)
1031                 || _gpgme_io_set_close_notify (fds[1],
1032                                                close_notify_handler,
1033                                                gpg))
1034               {
1035                 /* We leak fd_data_map and the fds.  This is not easy
1036                    to avoid and given that we reach this here only
1037                    after a malloc failure for a small object, it is
1038                    probably better not to do anything.  */
1039                 return gpg_error (GPG_ERR_GENERAL);
1040               }
1041             /* If the data_type is FD, we have to do a dup2 here.  */
1042             if (fd_data_map[datac].inbound)
1043               {
1044                 fd_data_map[datac].fd       = fds[0];
1045                 fd_data_map[datac].peer_fd  = fds[1];
1046               }
1047             else
1048               {
1049                 fd_data_map[datac].fd       = fds[1];
1050                 fd_data_map[datac].peer_fd  = fds[0];
1051               }
1052           }
1053
1054           /* Hack to get hands on the fd later.  */
1055           if (gpg->cmd.used)
1056             {
1057               if (gpg->cmd.cb_data == a->data)
1058                 {
1059                   assert (gpg->cmd.idx == -1);
1060                   gpg->cmd.idx = datac;
1061                 }
1062               else if (gpg->cmd.linked_data == a->data)
1063                 {
1064                   assert (gpg->cmd.linked_idx == -1);
1065                   gpg->cmd.linked_idx = datac;
1066                 }
1067             }
1068
1069           fd_data_map[datac].data = a->data;
1070           fd_data_map[datac].dup_to = a->dup_to;
1071
1072           if (a->dup_to == -1)
1073             {
1074               char *ptr;
1075               int buflen = 25;
1076
1077               argv[argc] = malloc (buflen);
1078               if (!argv[argc])
1079                 {
1080                   int saved_err = gpg_error_from_syserror ();
1081                   free (fd_data_map);
1082                   free_argv (argv);
1083                   return saved_err;
1084                 }
1085
1086               ptr = argv[argc];
1087               if (!a->print_fd)
1088                 {
1089                   *(ptr++) = '-';
1090                   *(ptr++) = '&';
1091                   buflen -= 2;
1092                 }
1093
1094               _gpgme_io_fd2str (ptr, buflen, fd_data_map[datac].peer_fd);
1095               fd_data_map[datac].arg_loc = argc;
1096               argc++;
1097             }
1098           datac++;
1099         }
1100       else
1101         {
1102           argv[argc] = strdup (a->arg);
1103           if (!argv[argc])
1104             {
1105               int saved_err = gpg_error_from_syserror ();
1106               free (fd_data_map);
1107               free_argv (argv);
1108               return saved_err;
1109             }
1110             argc++;
1111         }
1112     }
1113
1114   gpg->argv = argv;
1115   gpg->fd_data_map = fd_data_map;
1116   return 0;
1117 }
1118
1119
1120 static gpgme_error_t
1121 add_io_cb (engine_gpg_t gpg, int fd, int dir, gpgme_io_cb_t handler, void *data,
1122            void **tag)
1123 {
1124   gpgme_error_t err;
1125
1126   err = (*gpg->io_cbs.add) (gpg->io_cbs.add_priv, fd, dir, handler, data, tag);
1127   if (err)
1128     return err;
1129   if (!dir)
1130     /* FIXME Kludge around poll() problem.  */
1131     err = _gpgme_io_set_nonblocking (fd);
1132   return err;
1133 }
1134
1135
1136 /* Handle the status output of GnuPG.  This function does read entire
1137    lines and passes them as C strings to the callback function (we can
1138    use C Strings because the status output is always UTF-8 encoded).
1139    Of course we have to buffer the lines to cope with long lines
1140    e.g. with a large user ID.  Note: We can optimize this to only cope
1141    with status line code we know about and skip all other stuff
1142    without buffering (i.e. without extending the buffer).  */
1143 static gpgme_error_t
1144 read_status (engine_gpg_t gpg)
1145 {
1146   char *p;
1147   int nread;
1148   size_t bufsize = gpg->status.bufsize;
1149   char *buffer = gpg->status.buffer;
1150   size_t readpos = gpg->status.readpos;
1151   gpgme_error_t err;
1152
1153   assert (buffer);
1154   if (bufsize - readpos < 256)
1155     {
1156       /* Need more room for the read.  */
1157       bufsize += 1024;
1158       buffer = realloc (buffer, bufsize);
1159       if (!buffer)
1160         return gpg_error_from_syserror ();
1161     }
1162
1163   nread = _gpgme_io_read (gpg->status.fd[0],
1164                           buffer + readpos, bufsize-readpos);
1165   if (nread == -1)
1166     return gpg_error_from_syserror ();
1167
1168   if (!nread)
1169     {
1170       err = 0;
1171       gpg->status.eof = 1;
1172       if (gpg->status.mon_cb)
1173         err = gpg->status.mon_cb (gpg->status.mon_cb_value, "", "");
1174       if (gpg->status.fnc)
1175         {
1176           char emptystring[1] = {0};
1177           err = gpg->status.fnc (gpg->status.fnc_value,
1178                                  GPGME_STATUS_EOF, emptystring);
1179           if (gpg_err_code (err) == GPG_ERR_FALSE)
1180             err = 0; /* Drop special error code.  */
1181         }
1182
1183       return err;
1184     }
1185
1186   while (nread > 0)
1187     {
1188       for (p = buffer + readpos; nread; nread--, p++)
1189         {
1190           if (*p == '\n')
1191             {
1192               /* (we require that the last line is terminated by a LF) */
1193               if (p > buffer && p[-1] == '\r')
1194                 p[-1] = 0;
1195               *p = 0;
1196               if (!strncmp (buffer, "[GNUPG:] ", 9)
1197                   && buffer[9] >= 'A' && buffer[9] <= 'Z')
1198                 {
1199                   char *rest;
1200                   gpgme_status_code_t r;
1201
1202                   rest = strchr (buffer + 9, ' ');
1203                   if (!rest)
1204                     rest = p; /* Set to an empty string.  */
1205                   else
1206                     *rest++ = 0;
1207
1208                   r = _gpgme_parse_status (buffer + 9);
1209                   if (gpg->status.mon_cb && r != GPGME_STATUS_PROGRESS)
1210                     {
1211                       /* Note that we call the monitor even if we do
1212                        * not know the status code (r < 0).  */
1213                       err = gpg->status.mon_cb (gpg->status.mon_cb_value,
1214                                                 buffer + 9, rest);
1215                       if (err)
1216                         return err;
1217                     }
1218                   if (r >= 0)
1219                     {
1220                       if (gpg->cmd.used
1221                           && (r == GPGME_STATUS_GET_BOOL
1222                               || r == GPGME_STATUS_GET_LINE
1223                               || r == GPGME_STATUS_GET_HIDDEN))
1224                         {
1225                           gpg->cmd.code = r;
1226                           if (gpg->cmd.keyword)
1227                             free (gpg->cmd.keyword);
1228                           gpg->cmd.keyword = strdup (rest);
1229                           if (!gpg->cmd.keyword)
1230                             return gpg_error_from_syserror ();
1231                           /* This should be the last thing we have
1232                              received and the next thing will be that
1233                              the command handler does its action.  */
1234                           if (nread > 1)
1235                             TRACE0 (DEBUG_CTX, "gpgme:read_status", 0,
1236                                     "error: unexpected data");
1237
1238                           add_io_cb (gpg, gpg->cmd.fd, 0,
1239                                      command_handler, gpg,
1240                                      &gpg->fd_data_map[gpg->cmd.idx].tag);
1241                           gpg->fd_data_map[gpg->cmd.idx].fd = gpg->cmd.fd;
1242                           gpg->cmd.fd = -1;
1243                         }
1244                       else if (gpg->status.fnc)
1245                         {
1246                           err = gpg->status.fnc (gpg->status.fnc_value,
1247                                                  r, rest);
1248                           if (gpg_err_code (err) == GPG_ERR_FALSE)
1249                             err = 0; /* Drop special error code.  */
1250                           if (err)
1251                             return err;
1252                         }
1253
1254                       if (r == GPGME_STATUS_END_STREAM)
1255                         {
1256                           if (gpg->cmd.used)
1257                             {
1258                               /* Before we can actually add the
1259                                  command fd, we might have to flush
1260                                  the linked output data pipe.  */
1261                               if (gpg->cmd.linked_idx != -1
1262                                   && gpg->fd_data_map[gpg->cmd.linked_idx].fd
1263                                   != -1)
1264                                 {
1265                                   struct io_select_fd_s fds;
1266                                   fds.fd =
1267                                     gpg->fd_data_map[gpg->cmd.linked_idx].fd;
1268                                   fds.for_read = 1;
1269                                   fds.for_write = 0;
1270                                   fds.opaque = NULL;
1271                                   do
1272                                     {
1273                                       fds.signaled = 0;
1274                                       _gpgme_io_select (&fds, 1, 1);
1275                                       if (fds.signaled)
1276                                         _gpgme_data_inbound_handler
1277                                           (gpg->cmd.linked_data, fds.fd);
1278                                     }
1279                                   while (fds.signaled);
1280                                 }
1281
1282                               /* XXX We must check if there are any
1283                                  more fds active after removing this
1284                                  one.  */
1285                               (*gpg->io_cbs.remove)
1286                                 (gpg->fd_data_map[gpg->cmd.idx].tag);
1287                               gpg->cmd.fd = gpg->fd_data_map[gpg->cmd.idx].fd;
1288                               gpg->fd_data_map[gpg->cmd.idx].fd = -1;
1289                             }
1290                         }
1291                     }
1292                 }
1293               /* To reuse the buffer for the next line we have to
1294                  shift the remaining data to the buffer start and
1295                  restart the loop Hmmm: We can optimize this function
1296                  by looking forward in the buffer to see whether a
1297                  second complete line is available and in this case
1298                  avoid the memmove for this line.  */
1299               nread--; p++;
1300               if (nread)
1301                 memmove (buffer, p, nread);
1302               readpos = 0;
1303               break; /* the for loop */
1304             }
1305           else
1306             readpos++;
1307         }
1308     }
1309
1310   /* Update the gpg object.  */
1311   gpg->status.bufsize = bufsize;
1312   gpg->status.buffer = buffer;
1313   gpg->status.readpos = readpos;
1314   return 0;
1315 }
1316
1317
1318 static gpgme_error_t
1319 status_handler (void *opaque, int fd)
1320 {
1321   struct io_cb_data *data = (struct io_cb_data *) opaque;
1322   engine_gpg_t gpg = (engine_gpg_t) data->handler_value;
1323   int err;
1324
1325   assert (fd == gpg->status.fd[0]);
1326   err = read_status (gpg);
1327   if (err)
1328     return err;
1329   if (gpg->status.eof)
1330     _gpgme_io_close (fd);
1331   return 0;
1332 }
1333
1334
1335 static gpgme_error_t
1336 read_colon_line (engine_gpg_t gpg)
1337 {
1338   char *p;
1339   int nread;
1340   size_t bufsize = gpg->colon.bufsize;
1341   char *buffer = gpg->colon.buffer;
1342   size_t readpos = gpg->colon.readpos;
1343
1344   assert (buffer);
1345   if (bufsize - readpos < 256)
1346     {
1347       /* Need more room for the read.  */
1348       bufsize += 1024;
1349       buffer = realloc (buffer, bufsize);
1350       if (!buffer)
1351         return gpg_error_from_syserror ();
1352     }
1353
1354   nread = _gpgme_io_read (gpg->colon.fd[0], buffer+readpos, bufsize-readpos);
1355   if (nread == -1)
1356     return gpg_error_from_syserror ();
1357
1358   if (!nread)
1359     {
1360       gpg->colon.eof = 1;
1361       assert (gpg->colon.fnc);
1362       gpg->colon.fnc (gpg->colon.fnc_value, NULL);
1363       return 0;
1364     }
1365
1366   while (nread > 0)
1367     {
1368       for (p = buffer + readpos; nread; nread--, p++)
1369         {
1370           if ( *p == '\n' )
1371             {
1372               /* (we require that the last line is terminated by a LF)
1373                  and we skip empty lines.  Note: we use UTF8 encoding
1374                  and escaping of special characters.  We require at
1375                  least one colon to cope with some other printed
1376                  information.  */
1377               *p = 0;
1378               if (*buffer && strchr (buffer, ':'))
1379                 {
1380                   char *line = NULL;
1381
1382                   if (gpg->colon.preprocess_fnc)
1383                     {
1384                       gpgme_error_t err;
1385
1386                       err = gpg->colon.preprocess_fnc (buffer, &line);
1387                       if (err)
1388                         return err;
1389                     }
1390
1391                   assert (gpg->colon.fnc);
1392                   if (line)
1393                     {
1394                       char *linep = line;
1395                       char *endp;
1396
1397                       do
1398                         {
1399                           endp = strchr (linep, '\n');
1400                           if (endp)
1401                             *endp++ = 0;
1402                           gpg->colon.fnc (gpg->colon.fnc_value, linep);
1403                           linep = endp;
1404                         }
1405                       while (linep && *linep);
1406
1407                       gpgrt_free (line);
1408                     }
1409                   else
1410                     gpg->colon.fnc (gpg->colon.fnc_value, buffer);
1411                 }
1412
1413               /* To reuse the buffer for the next line we have to
1414                  shift the remaining data to the buffer start and
1415                  restart the loop Hmmm: We can optimize this function
1416                  by looking forward in the buffer to see whether a
1417                  second complete line is available and in this case
1418                  avoid the memmove for this line.  */
1419               nread--; p++;
1420               if (nread)
1421                 memmove (buffer, p, nread);
1422               readpos = 0;
1423               break; /* The for loop.  */
1424             }
1425           else
1426             readpos++;
1427         }
1428     }
1429
1430   /* Update the gpg object.  */
1431   gpg->colon.bufsize = bufsize;
1432   gpg->colon.buffer  = buffer;
1433   gpg->colon.readpos = readpos;
1434   return 0;
1435 }
1436
1437
1438 /* This colonline handler thing is not the clean way to do it.  It
1439    might be better to enhance the gpgme_data_t object to act as a wrapper
1440    for a callback.  Same goes for the status thing.  For now we use
1441    this thing here because it is easier to implement.  */
1442 static gpgme_error_t
1443 colon_line_handler (void *opaque, int fd)
1444 {
1445   struct io_cb_data *data = (struct io_cb_data *) opaque;
1446   engine_gpg_t gpg = (engine_gpg_t) data->handler_value;
1447   gpgme_error_t rc = 0;
1448
1449   assert (fd == gpg->colon.fd[0]);
1450   rc = read_colon_line (gpg);
1451   if (rc)
1452     return rc;
1453   if (gpg->colon.eof)
1454     _gpgme_io_close (fd);
1455   return 0;
1456 }
1457
1458
1459 static gpgme_error_t
1460 start (engine_gpg_t gpg)
1461 {
1462   gpgme_error_t rc;
1463   int i, n;
1464   int status;
1465   struct spawn_fd_item_s *fd_list;
1466   pid_t pid;
1467   const char *pgmname;
1468
1469   if (!gpg)
1470     return gpg_error (GPG_ERR_INV_VALUE);
1471
1472   if (!gpg->file_name && !_gpgme_get_default_gpg_name ())
1473     return trace_gpg_error (GPG_ERR_INV_ENGINE);
1474
1475   if (gpg->lc_ctype)
1476     {
1477       rc = add_arg_ext (gpg, gpg->lc_ctype, 1);
1478       if (!rc)
1479         rc = add_arg_ext (gpg, "--lc-ctype", 1);
1480       if (rc)
1481         return rc;
1482     }
1483
1484   if (gpg->lc_messages)
1485     {
1486       rc = add_arg_ext (gpg, gpg->lc_messages, 1);
1487       if (!rc)
1488         rc = add_arg_ext (gpg, "--lc-messages", 1);
1489       if (rc)
1490         return rc;
1491     }
1492
1493   pgmname = gpg->file_name ? gpg->file_name : _gpgme_get_default_gpg_name ();
1494   rc = build_argv (gpg, pgmname);
1495   if (rc)
1496     return rc;
1497
1498   /* status_fd, colon_fd and end of list.  */
1499   n = 3;
1500   for (i = 0; gpg->fd_data_map[i].data; i++)
1501     n++;
1502   fd_list = calloc (n, sizeof *fd_list);
1503   if (! fd_list)
1504     return gpg_error_from_syserror ();
1505
1506   /* Build the fd list for the child.  */
1507   n = 0;
1508   fd_list[n].fd = gpg->status.fd[1];
1509   fd_list[n].dup_to = -1;
1510   fd_list[n].arg_loc = gpg->status.arg_loc;
1511   n++;
1512   if (gpg->colon.fnc)
1513     {
1514       fd_list[n].fd = gpg->colon.fd[1];
1515       fd_list[n].dup_to = 1;
1516       n++;
1517     }
1518   for (i = 0; gpg->fd_data_map[i].data; i++)
1519     {
1520       fd_list[n].fd = gpg->fd_data_map[i].peer_fd;
1521       fd_list[n].dup_to = gpg->fd_data_map[i].dup_to;
1522       fd_list[n].arg_loc = gpg->fd_data_map[i].arg_loc;
1523       n++;
1524     }
1525   fd_list[n].fd = -1;
1526   fd_list[n].dup_to = -1;
1527
1528   status = _gpgme_io_spawn (pgmname, gpg->argv,
1529                             (IOSPAWN_FLAG_DETACHED |IOSPAWN_FLAG_ALLOW_SET_FG),
1530                             fd_list, NULL, NULL, &pid);
1531   {
1532     int saved_err = gpg_error_from_syserror ();
1533     free (fd_list);
1534     if (status == -1)
1535       return saved_err;
1536   }
1537
1538   /*_gpgme_register_term_handler ( closure, closure_value, pid );*/
1539
1540   rc = add_io_cb (gpg, gpg->status.fd[0], 1, status_handler, gpg,
1541                   &gpg->status.tag);
1542   if (rc)
1543     /* FIXME: kill the child */
1544     return rc;
1545
1546   if (gpg->colon.fnc)
1547     {
1548       assert (gpg->colon.fd[0] != -1);
1549       rc = add_io_cb (gpg, gpg->colon.fd[0], 1, colon_line_handler, gpg,
1550                       &gpg->colon.tag);
1551       if (rc)
1552         /* FIXME: kill the child */
1553         return rc;
1554     }
1555
1556   for (i = 0; gpg->fd_data_map[i].data; i++)
1557     {
1558       if (gpg->cmd.used && i == gpg->cmd.idx)
1559         {
1560           /* Park the cmd fd.  */
1561           gpg->cmd.fd = gpg->fd_data_map[i].fd;
1562           gpg->fd_data_map[i].fd = -1;
1563         }
1564       else
1565         {
1566           rc = add_io_cb (gpg, gpg->fd_data_map[i].fd,
1567                           gpg->fd_data_map[i].inbound,
1568                           gpg->fd_data_map[i].inbound
1569                           ? _gpgme_data_inbound_handler
1570                           : _gpgme_data_outbound_handler,
1571                           gpg->fd_data_map[i].data, &gpg->fd_data_map[i].tag);
1572
1573           if (rc)
1574             /* FIXME: kill the child */
1575             return rc;
1576         }
1577     }
1578
1579   gpg_io_event (gpg, GPGME_EVENT_START, NULL);
1580
1581   /* fixme: check what data we can release here */
1582   return 0;
1583 }
1584
1585
1586 /* Add the --input-size-hint option if requested.  */
1587 static gpgme_error_t
1588 add_input_size_hint (engine_gpg_t gpg, gpgme_data_t data)
1589 {
1590   gpgme_error_t err;
1591   gpgme_off_t value = _gpgme_data_get_size_hint (data);
1592   char numbuf[50];  /* Large enough for even 2^128 in base-10.  */
1593   char *p;
1594
1595   if (!value || !have_gpg_version (gpg, "2.1.15"))
1596     return 0;
1597
1598   err = add_arg (gpg, "--input-size-hint");
1599   if (!err)
1600     {
1601       p = numbuf + sizeof numbuf;
1602       *--p = 0;
1603       do
1604         {
1605           *--p = '0' + (value % 10);
1606           value /= 10;
1607         }
1608       while (value);
1609       err = add_arg (gpg, p);
1610     }
1611   return err;
1612 }
1613
1614
1615 static gpgme_error_t
1616 gpg_decrypt (void *engine,
1617              gpgme_decrypt_flags_t flags,
1618              gpgme_data_t ciph, gpgme_data_t plain,
1619              int export_session_key, const char *override_session_key,
1620              int auto_key_retrieve)
1621 {
1622   engine_gpg_t gpg = engine;
1623   gpgme_error_t err;
1624
1625   err = add_arg (gpg, "--decrypt");
1626
1627   if (!err && (flags & GPGME_DECRYPT_UNWRAP))
1628     {
1629       if (!have_gpg_version (gpg, "2.1.12"))
1630         err = gpg_error (GPG_ERR_NOT_SUPPORTED);
1631       else
1632         err = add_arg (gpg, "--unwrap");
1633     }
1634
1635   if (!err && export_session_key)
1636     err = add_arg (gpg, "--show-session-key");
1637
1638   if (!err && auto_key_retrieve)
1639     err = add_arg (gpg, "--auto-key-retrieve");
1640
1641   if (!err && override_session_key && *override_session_key)
1642     {
1643       if (have_gpg_version (gpg, "2.1.16"))
1644         {
1645           gpgme_data_release (gpg->override_session_key);
1646           TRACE2 (DEBUG_ENGINE, "override", gpg, "seskey='%s' len=%zu\n",
1647                   override_session_key,
1648                   strlen (override_session_key));
1649
1650           err = gpgme_data_new_from_mem (&gpg->override_session_key,
1651                                          override_session_key,
1652                                          strlen (override_session_key), 1);
1653           if (!err)
1654             {
1655               err = add_arg (gpg, "--override-session-key-fd");
1656               if (!err)
1657                 err = add_data (gpg, gpg->override_session_key, -2, 0);
1658             }
1659         }
1660       else
1661         {
1662           /* Using that option may leak the session key via ps(1).  */
1663           err = add_arg (gpg, "--override-session-key");
1664           if (!err)
1665             err = add_arg (gpg, override_session_key);
1666         }
1667     }
1668
1669   /* Tell the gpg object about the data.  */
1670   if (!err)
1671     err = add_arg (gpg, "--output");
1672   if (!err)
1673     err = add_arg (gpg, "-");
1674   if (!err)
1675     err = add_data (gpg, plain, 1, 1);
1676   if (!err)
1677     err = add_input_size_hint (gpg, ciph);
1678   if (!err)
1679     err = add_arg (gpg, "--");
1680   if (!err)
1681     err = add_data (gpg, ciph, -1, 0);
1682
1683   if (!err)
1684     err = start (gpg);
1685   return err;
1686 }
1687
1688 static gpgme_error_t
1689 gpg_delete (void *engine, gpgme_key_t key, unsigned int flags)
1690 {
1691   engine_gpg_t gpg = engine;
1692   gpgme_error_t err = 0;
1693   int allow_secret = flags & GPGME_DELETE_ALLOW_SECRET;
1694   int force = flags & GPGME_DELETE_FORCE;
1695
1696   if (force)
1697     err = add_arg (gpg, "--yes");
1698   if (!err)
1699     err = add_arg (gpg, allow_secret ? "--delete-secret-and-public-key"
1700                    : "--delete-key");
1701   if (!err)
1702     err = add_arg (gpg, "--");
1703   if (!err)
1704     {
1705       if (!key->subkeys || !key->subkeys->fpr)
1706         return gpg_error (GPG_ERR_INV_VALUE);
1707       else
1708         err = add_arg (gpg, key->subkeys->fpr);
1709     }
1710
1711   if (!err)
1712     err = start (gpg);
1713   return err;
1714 }
1715
1716
1717 static gpgme_error_t
1718 gpg_passwd (void *engine, gpgme_key_t key, unsigned int flags)
1719 {
1720   engine_gpg_t gpg = engine;
1721   gpgme_error_t err;
1722
1723   (void)flags;
1724
1725   if (!key || !key->subkeys || !key->subkeys->fpr)
1726     return gpg_error (GPG_ERR_INV_CERT_OBJ);
1727
1728   err = add_arg (gpg, "--passwd");
1729   if (!err)
1730     err = add_arg (gpg, key->subkeys->fpr);
1731   if (!err)
1732     err = start (gpg);
1733   return err;
1734 }
1735
1736
1737 static gpgme_error_t
1738 append_args_from_signers (engine_gpg_t gpg, gpgme_ctx_t ctx /* FIXME */)
1739 {
1740   gpgme_error_t err = 0;
1741   int i;
1742   gpgme_key_t key;
1743
1744   for (i = 0; (key = gpgme_signers_enum (ctx, i)); i++)
1745     {
1746       const char *s = key->subkeys ? key->subkeys->keyid : NULL;
1747       if (s)
1748         {
1749           if (!err)
1750             err = add_arg (gpg, "-u");
1751           if (!err)
1752             err = add_arg (gpg, s);
1753         }
1754       gpgme_key_unref (key);
1755       if (err)
1756         break;
1757     }
1758   return err;
1759 }
1760
1761
1762 static gpgme_error_t
1763 append_args_from_sender (engine_gpg_t gpg, gpgme_ctx_t ctx)
1764 {
1765   gpgme_error_t err;
1766
1767   if (ctx->sender && have_gpg_version (gpg, "2.1.15"))
1768     {
1769       err = add_arg (gpg, "--sender");
1770       if (!err)
1771         err = add_arg (gpg, ctx->sender);
1772     }
1773   else
1774     err = 0;
1775   return err;
1776 }
1777
1778
1779 static gpgme_error_t
1780 append_args_from_sig_notations (engine_gpg_t gpg, gpgme_ctx_t ctx /* FIXME */)
1781 {
1782   gpgme_error_t err = 0;
1783   gpgme_sig_notation_t notation;
1784
1785   notation = gpgme_sig_notation_get (ctx);
1786
1787   while (!err && notation)
1788     {
1789       if (notation->name
1790           && !(notation->flags & GPGME_SIG_NOTATION_HUMAN_READABLE))
1791         err = gpg_error (GPG_ERR_INV_VALUE);
1792       else if (notation->name)
1793         {
1794           char *arg;
1795
1796           /* Maximum space needed is one byte for the "critical" flag,
1797              the name, one byte for '=', the value, and a terminating
1798              '\0'.  */
1799
1800           arg = malloc (1 + notation->name_len + 1 + notation->value_len + 1);
1801           if (!arg)
1802             err = gpg_error_from_syserror ();
1803
1804           if (!err)
1805             {
1806               char *argp = arg;
1807
1808               if (notation->critical)
1809                 *(argp++) = '!';
1810
1811               memcpy (argp, notation->name, notation->name_len);
1812               argp += notation->name_len;
1813
1814               *(argp++) = '=';
1815
1816               /* We know that notation->name is '\0' terminated.  */
1817               strcpy (argp, notation->value);
1818             }
1819
1820           if (!err)
1821             err = add_arg (gpg, "--sig-notation");
1822           if (!err)
1823             err = add_arg (gpg, arg);
1824
1825           if (arg)
1826             free (arg);
1827         }
1828       else
1829         {
1830           /* This is a policy URL.  */
1831
1832           char *value;
1833
1834           if (notation->critical)
1835             {
1836               value = malloc (1 + notation->value_len + 1);
1837               if (!value)
1838                 err = gpg_error_from_syserror ();
1839               else
1840                 {
1841                   value[0] = '!';
1842                   /* We know that notation->value is '\0' terminated.  */
1843                   strcpy (&value[1], notation->value);
1844                 }
1845             }
1846           else
1847             value = notation->value;
1848
1849           if (!err)
1850             err = add_arg (gpg, "--sig-policy-url");
1851           if (!err)
1852             err = add_arg (gpg, value);
1853
1854           if (value != notation->value)
1855             free (value);
1856         }
1857
1858       notation = notation->next;
1859     }
1860   return err;
1861 }
1862
1863
1864 static gpgme_error_t
1865 gpg_edit (void *engine, int type, gpgme_key_t key, gpgme_data_t out,
1866           gpgme_ctx_t ctx /* FIXME */)
1867 {
1868   engine_gpg_t gpg = engine;
1869   gpgme_error_t err;
1870
1871   err = add_arg (gpg, "--with-colons");
1872   if (!err)
1873     err = append_args_from_signers (gpg, ctx);
1874   if (!err)
1875   err = add_arg (gpg, type == 0 ? "--edit-key" : "--card-edit");
1876   if (!err)
1877     err = add_data (gpg, out, 1, 1);
1878   if (!err)
1879     err = add_arg (gpg, "--");
1880   if (!err && type == 0)
1881     {
1882       const char *s = key->subkeys ? key->subkeys->fpr : NULL;
1883       if (!s)
1884         err = gpg_error (GPG_ERR_INV_VALUE);
1885       else
1886         err = add_arg (gpg, s);
1887     }
1888   if (!err)
1889     err = start (gpg);
1890
1891   return err;
1892 }
1893
1894
1895 static gpgme_error_t
1896 append_args_from_recipients (engine_gpg_t gpg, gpgme_key_t recp[])
1897 {
1898   gpgme_error_t err = 0;
1899   int i = 0;
1900
1901   while (recp[i])
1902     {
1903       if (!recp[i]->subkeys || !recp[i]->subkeys->fpr)
1904         err = gpg_error (GPG_ERR_INV_VALUE);
1905       if (!err)
1906         err = add_arg (gpg, "-r");
1907       if (!err)
1908         err = add_arg (gpg, recp[i]->subkeys->fpr);
1909       if (err)
1910         break;
1911       i++;
1912     }
1913   return err;
1914 }
1915
1916
1917 /* Take recipients from the LF delimited STRING and add -r args.  */
1918 static gpg_error_t
1919 append_args_from_recipients_string (engine_gpg_t gpg, const char *string)
1920 {
1921   gpg_error_t err = 0;
1922   int any = 0;
1923   const char *s;
1924   int n;
1925
1926   do
1927     {
1928       /* Skip leading white space */
1929       while (*string == ' ' || *string == '\t')
1930         string++;
1931       if (!*string)
1932         break;
1933
1934       /* Look for the LF. */
1935       s = strchr (string, '\n');
1936       if (s)
1937         n = s - string;
1938       else
1939         n = strlen (string);
1940       while (n && (string[n-1] == ' ' || string[n-1] == '\t'))
1941         n--;
1942
1943       /* Add arg if it is not empty.  */
1944       if (n)
1945         {
1946           err = add_arg (gpg, "-r");
1947           if (!err)
1948             err = add_arg_len (gpg, NULL, string, n);
1949           if (!err)
1950             any = 1;
1951         }
1952
1953       string += n + !!s;
1954     }
1955   while (!err);
1956
1957   if (!err && !any)
1958     err = gpg_error (GPG_ERR_MISSING_KEY);
1959   return err;
1960 }
1961
1962
1963 static gpgme_error_t
1964 gpg_encrypt (void *engine, gpgme_key_t recp[], const char *recpstring,
1965              gpgme_encrypt_flags_t flags,
1966              gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
1967 {
1968   engine_gpg_t gpg = engine;
1969   gpgme_error_t err = 0;
1970
1971   if (recp || recpstring)
1972     err = add_arg (gpg, "--encrypt");
1973
1974   if (!err && ((flags & GPGME_ENCRYPT_SYMMETRIC) || (!recp && !recpstring)))
1975     err = add_arg (gpg, "--symmetric");
1976
1977   if (!err && use_armor)
1978     err = add_arg (gpg, "--armor");
1979
1980   if (!err && (flags & GPGME_ENCRYPT_WRAP))
1981     {
1982       /* gpg is current not able to detect already compressed
1983        * packets.  Thus when using
1984        *   gpg --unwrap -d | gpg --no-literal -e
1985        * the encryption would add an additional compression layer.
1986        * We better suppress that.  */
1987       flags |= GPGME_ENCRYPT_NO_COMPRESS;
1988       err = add_arg (gpg, "--no-literal");
1989     }
1990
1991   if (!err && (flags & GPGME_ENCRYPT_NO_COMPRESS))
1992     err = add_arg (gpg, "--compress-algo=none");
1993
1994   if (!err && (flags & GPGME_ENCRYPT_THROW_KEYIDS))
1995     err = add_arg (gpg, "--throw-keyids");
1996
1997   if (gpgme_data_get_encoding (plain) == GPGME_DATA_ENCODING_MIME
1998       && have_gpg_version (gpg, "2.1.14"))
1999     err = add_arg (gpg, "--mimemode");
2000
2001   if (recp || recpstring)
2002     {
2003       /* If we know that all recipients are valid (full or ultimate trust)
2004          we can suppress further checks.  */
2005       if (!err && (flags & GPGME_ENCRYPT_ALWAYS_TRUST))
2006         err = add_arg (gpg, "--always-trust");
2007
2008       if (!err && (flags & GPGME_ENCRYPT_NO_ENCRYPT_TO))
2009         err = add_arg (gpg, "--no-encrypt-to");
2010
2011       if (!err && !recp && recpstring)
2012         err = append_args_from_recipients_string (gpg, recpstring);
2013       else if (!err)
2014         err = append_args_from_recipients (gpg, recp);
2015     }
2016
2017   /* Tell the gpg object about the data.  */
2018   if (!err)
2019     err = add_arg (gpg, "--output");
2020   if (!err)
2021     err = add_arg (gpg, "-");
2022   if (!err)
2023     err = add_data (gpg, ciph, 1, 1);
2024   if (gpgme_data_get_file_name (plain))
2025     {
2026       if (!err)
2027         err = add_arg (gpg, "--set-filename");
2028       if (!err)
2029         err = add_arg (gpg, gpgme_data_get_file_name (plain));
2030     }
2031   if (!err)
2032     err = add_input_size_hint (gpg, plain);
2033   if (!err)
2034     err = add_arg (gpg, "--");
2035   if (!err)
2036     err = add_data (gpg, plain, -1, 0);
2037
2038   if (!err)
2039     err = start (gpg);
2040
2041   return err;
2042 }
2043
2044
2045 static gpgme_error_t
2046 gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
2047                   const char *recpstring,
2048                   gpgme_encrypt_flags_t flags, gpgme_data_t plain,
2049                   gpgme_data_t ciph, int use_armor,
2050                   gpgme_ctx_t ctx /* FIXME */)
2051 {
2052   engine_gpg_t gpg = engine;
2053   gpgme_error_t err = 0;
2054
2055   if (recp || recpstring)
2056     err = add_arg (gpg, "--encrypt");
2057
2058   if (!err && ((flags & GPGME_ENCRYPT_SYMMETRIC) || (!recp && !recpstring)))
2059     err = add_arg (gpg, "--symmetric");
2060
2061   if (!err)
2062     err = add_arg (gpg, "--sign");
2063   if (!err && use_armor)
2064     err = add_arg (gpg, "--armor");
2065
2066   if (!err && (flags & GPGME_ENCRYPT_NO_COMPRESS))
2067     err = add_arg (gpg, "--compress-algo=none");
2068
2069   if (!err && (flags & GPGME_ENCRYPT_THROW_KEYIDS))
2070     err = add_arg (gpg, "--throw-keyids");
2071
2072   if (gpgme_data_get_encoding (plain) == GPGME_DATA_ENCODING_MIME
2073       && have_gpg_version (gpg, "2.1.14"))
2074     err = add_arg (gpg, "--mimemode");
2075
2076   if (recp || recpstring)
2077     {
2078       /* If we know that all recipients are valid (full or ultimate trust)
2079          we can suppress further checks.  */
2080       if (!err && (flags & GPGME_ENCRYPT_ALWAYS_TRUST))
2081         err = add_arg (gpg, "--always-trust");
2082
2083       if (!err && (flags & GPGME_ENCRYPT_NO_ENCRYPT_TO))
2084         err = add_arg (gpg, "--no-encrypt-to");
2085
2086       if (!err && !recp && recpstring)
2087         err = append_args_from_recipients_string (gpg, recpstring);
2088       else if (!err)
2089         err = append_args_from_recipients (gpg, recp);
2090     }
2091
2092   if (!err)
2093     err = append_args_from_signers (gpg, ctx);
2094
2095   if (!err)
2096     err = append_args_from_sender (gpg, ctx);
2097
2098   if (!err)
2099     err = append_args_from_sig_notations (gpg, ctx);
2100
2101   /* Tell the gpg object about the data.  */
2102   if (!err)
2103     err = add_arg (gpg, "--output");
2104   if (!err)
2105     err = add_arg (gpg, "-");
2106   if (!err)
2107     err = add_data (gpg, ciph, 1, 1);
2108   if (gpgme_data_get_file_name (plain))
2109     {
2110       if (!err)
2111         err = add_arg (gpg, "--set-filename");
2112       if (!err)
2113         err = add_arg (gpg, gpgme_data_get_file_name (plain));
2114     }
2115   if (!err)
2116     err = add_input_size_hint (gpg, plain);
2117   if (!err)
2118     err = add_arg (gpg, "--");
2119   if (!err)
2120     err = add_data (gpg, plain, -1, 0);
2121
2122   if (!err)
2123     err = start (gpg);
2124
2125   return err;
2126 }
2127
2128
2129 static gpgme_error_t
2130 export_common (engine_gpg_t gpg, gpgme_export_mode_t mode,
2131                gpgme_data_t keydata, int use_armor)
2132 {
2133   gpgme_error_t err = 0;
2134
2135   if ((mode & ~(GPGME_EXPORT_MODE_EXTERN
2136                 |GPGME_EXPORT_MODE_MINIMAL
2137                 |GPGME_EXPORT_MODE_SECRET)))
2138     return gpg_error (GPG_ERR_NOT_SUPPORTED);
2139
2140   if ((mode & GPGME_EXPORT_MODE_MINIMAL))
2141     err = add_arg (gpg, "--export-options=export-minimal");
2142
2143   if (err)
2144     ;
2145   else if ((mode & GPGME_EXPORT_MODE_EXTERN))
2146     {
2147       err = add_arg (gpg, "--send-keys");
2148     }
2149   else
2150     {
2151       if ((mode & GPGME_EXPORT_MODE_SECRET))
2152         err = add_arg (gpg, "--export-secret-keys");
2153       else
2154         err = add_arg (gpg, "--export");
2155       if (!err && use_armor)
2156         err = add_arg (gpg, "--armor");
2157       if (!err)
2158         err = add_data (gpg, keydata, 1, 1);
2159     }
2160   if (!err)
2161     err = add_arg (gpg, "--");
2162
2163   return err;
2164 }
2165
2166
2167 static gpgme_error_t
2168 gpg_export (void *engine, const char *pattern, gpgme_export_mode_t mode,
2169             gpgme_data_t keydata, int use_armor)
2170 {
2171   engine_gpg_t gpg = engine;
2172   gpgme_error_t err;
2173
2174   err = export_common (gpg, mode, keydata, use_armor);
2175
2176   if (!err && pattern && *pattern)
2177     err = add_arg (gpg, pattern);
2178
2179   if (!err)
2180     err = start (gpg);
2181
2182   return err;
2183 }
2184
2185
2186 static gpgme_error_t
2187 gpg_export_ext (void *engine, const char *pattern[], gpgme_export_mode_t mode,
2188                 gpgme_data_t keydata, int use_armor)
2189 {
2190   engine_gpg_t gpg = engine;
2191   gpgme_error_t err;
2192
2193   err = export_common (gpg, mode, keydata, use_armor);
2194
2195   if (pattern)
2196     {
2197       while (!err && *pattern && **pattern)
2198         err = add_arg (gpg, *(pattern++));
2199     }
2200
2201   if (!err)
2202     err = start (gpg);
2203
2204   return err;
2205 }
2206
2207
2208 \f
2209 /* Helper to add algo, usage, and expire to the list of args.  */
2210 static gpgme_error_t
2211 gpg_add_algo_usage_expire (engine_gpg_t gpg,
2212                            const char *algo,
2213                            unsigned long expires,
2214                            unsigned int flags)
2215 {
2216   gpg_error_t err;
2217
2218   /* This condition is only required to allow the use of gpg < 2.1.16 */
2219   if (algo
2220       || (flags & (GPGME_CREATE_SIGN | GPGME_CREATE_ENCR
2221                    | GPGME_CREATE_CERT | GPGME_CREATE_AUTH
2222                    | GPGME_CREATE_NOEXPIRE))
2223       || expires)
2224     {
2225       err = add_arg (gpg, algo? algo : "default");
2226       if (!err)
2227         {
2228           char tmpbuf[5*4+1];
2229           snprintf (tmpbuf, sizeof tmpbuf, "%s%s%s%s",
2230                     (flags & GPGME_CREATE_SIGN)? " sign":"",
2231                     (flags & GPGME_CREATE_ENCR)? " encr":"",
2232                     (flags & GPGME_CREATE_CERT)? " cert":"",
2233                     (flags & GPGME_CREATE_AUTH)? " auth":"");
2234           err = add_arg (gpg, *tmpbuf? tmpbuf : "default");
2235         }
2236       if (!err)
2237         {
2238           if ((flags & GPGME_CREATE_NOEXPIRE))
2239             err = add_arg (gpg, "never");
2240           else if (expires == 0)
2241             err = add_arg (gpg, "-");
2242           else
2243             {
2244               char tmpbuf[8+20];
2245               snprintf (tmpbuf, sizeof tmpbuf, "seconds=%lu", expires);
2246               err = add_arg (gpg, tmpbuf);
2247             }
2248         }
2249     }
2250   else
2251     err = 0;
2252
2253   return err;
2254 }
2255
2256
2257 static gpgme_error_t
2258 gpg_createkey_from_param (engine_gpg_t gpg,
2259                           gpgme_data_t help_data, unsigned int extraflags)
2260 {
2261   gpgme_error_t err;
2262
2263   err = add_arg (gpg, "--gen-key");
2264   if (!err && (extraflags & GENKEY_EXTRAFLAG_ARMOR))
2265     err = add_arg (gpg, "--armor");
2266   if (!err)
2267     err = add_arg (gpg, "--");
2268   if (!err)
2269     err = add_data (gpg, help_data, -1, 0);
2270   if (!err)
2271     err = start (gpg);
2272   return err;
2273 }
2274
2275
2276 static gpgme_error_t
2277 gpg_createkey (engine_gpg_t gpg,
2278                const char *userid, const char *algo,
2279                unsigned long expires,
2280                unsigned int flags,
2281                unsigned int extraflags)
2282 {
2283   gpgme_error_t err;
2284
2285   err = add_arg (gpg, "--quick-gen-key");
2286   if (!err && (extraflags & GENKEY_EXTRAFLAG_ARMOR))
2287     err = add_arg (gpg, "--armor");
2288   if (!err && (flags & GPGME_CREATE_NOPASSWD))
2289     {
2290       err = add_arg (gpg, "--passphrase");
2291       if (!err)
2292         err = add_arg (gpg, "");
2293       if (!err)
2294         err = add_arg (gpg, "--batch");
2295     }
2296   if (!err && (flags & GPGME_CREATE_FORCE))
2297     err = add_arg (gpg, "--yes");
2298   if (!err)
2299     err = add_arg (gpg, "--");
2300   if (!err)
2301     err = add_arg (gpg, userid);
2302
2303   if (!err)
2304     err = gpg_add_algo_usage_expire (gpg, algo, expires, flags);
2305
2306   if (!err)
2307     err = start (gpg);
2308   return err;
2309 }
2310
2311
2312 static gpgme_error_t
2313 gpg_addkey (engine_gpg_t gpg,
2314             const char *algo,
2315             unsigned long expires,
2316             gpgme_key_t key,
2317             unsigned int flags,
2318             unsigned int extraflags)
2319 {
2320   gpgme_error_t err;
2321
2322   if (!key || !key->fpr)
2323     return gpg_error (GPG_ERR_INV_ARG);
2324
2325   err = add_arg (gpg, "--quick-addkey");
2326   if (!err && (extraflags & GENKEY_EXTRAFLAG_ARMOR))
2327     err = add_arg (gpg, "--armor");
2328   if (!err && (flags & GPGME_CREATE_NOPASSWD))
2329     {
2330       err = add_arg (gpg, "--passphrase");
2331       if (!err)
2332         err = add_arg (gpg, "");
2333       if (!err)
2334         err = add_arg (gpg, "--batch");
2335     }
2336   if (!err)
2337     err = add_arg (gpg, "--");
2338   if (!err)
2339     err = add_arg (gpg, key->fpr);
2340
2341   if (!err)
2342     err = gpg_add_algo_usage_expire (gpg, algo, expires, flags);
2343
2344   if (!err)
2345     err = start (gpg);
2346   return err;
2347 }
2348
2349
2350 static gpgme_error_t
2351 gpg_adduid (engine_gpg_t gpg,
2352             gpgme_key_t key,
2353             const char *userid,
2354             unsigned int extraflags)
2355 {
2356   gpgme_error_t err;
2357
2358   if (!key || !key->fpr || !userid)
2359     return gpg_error (GPG_ERR_INV_ARG);
2360
2361   if ((extraflags & GENKEY_EXTRAFLAG_SETPRIMARY))
2362     {
2363       if (!have_gpg_version (gpg, "2.1.20"))
2364         err = gpg_error (GPG_ERR_NOT_SUPPORTED);
2365       else
2366         err = add_arg (gpg, "--quick-set-primary-uid");
2367     }
2368   else if ((extraflags & GENKEY_EXTRAFLAG_REVOKE))
2369     err = add_arg (gpg, "--quick-revuid");
2370   else
2371     err = add_arg (gpg, "--quick-adduid");
2372
2373   if (!err)
2374     err = add_arg (gpg, "--");
2375   if (!err)
2376     err = add_arg (gpg, key->fpr);
2377   if (!err)
2378     err = add_arg (gpg, userid);
2379
2380   if (!err)
2381     err = start (gpg);
2382   return err;
2383 }
2384
2385
2386 static gpgme_error_t
2387 gpg_genkey (void *engine,
2388             const char *userid, const char *algo,
2389             unsigned long reserved, unsigned long expires,
2390             gpgme_key_t key, unsigned int flags,
2391             gpgme_data_t help_data, unsigned int extraflags,
2392             gpgme_data_t pubkey, gpgme_data_t seckey)
2393 {
2394   engine_gpg_t gpg = engine;
2395   gpgme_error_t err;
2396
2397   (void)reserved;
2398
2399   if (!gpg)
2400     return gpg_error (GPG_ERR_INV_VALUE);
2401
2402   /* If HELP_DATA is given the use of the old interface
2403    * (gpgme_op_genkey) has been requested.  The other modes are:
2404    *
2405    *  USERID && !KEY          - Create a new keyblock.
2406    * !USERID &&  KEY          - Add a new subkey to KEY (gpg >= 2.1.14)
2407    *  USERID &&  KEY && !ALGO - Add a new user id to KEY (gpg >= 2.1.14).
2408    *                            or set a flag on a user id.
2409    */
2410   if (help_data)
2411     {
2412       /* We need a special mechanism to get the fd of a pipe here, so
2413          that we can use this for the %pubring and %secring
2414          parameters.  We don't have this yet, so we implement only the
2415          adding to the standard keyrings.  */
2416       if (pubkey || seckey)
2417         err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
2418       else
2419         err = gpg_createkey_from_param (gpg, help_data, extraflags);
2420     }
2421   else if (!have_gpg_version (gpg, "2.1.13"))
2422     err = gpg_error (GPG_ERR_NOT_SUPPORTED);
2423   else if (userid && !key)
2424     err = gpg_createkey (gpg, userid, algo, expires, flags, extraflags);
2425   else if (!userid && key)
2426     err = gpg_addkey (gpg, algo, expires, key, flags, extraflags);
2427   else if (userid && key && !algo)
2428     err = gpg_adduid (gpg, key, userid, extraflags);
2429   else
2430     err = gpg_error (GPG_ERR_INV_VALUE);
2431
2432   return err;
2433 }
2434
2435 /* Return the next DELIM delimited string from DATA as a C-string.
2436    The caller needs to provide the address of a pointer variable which
2437    he has to set to NULL before the first call.  After the last call
2438    to this function, this function needs to be called once more with
2439    DATA set to NULL so that the function can release its internal
2440    state.  After that the pointer variable is free for use again.
2441    Note that we use a delimiter and thus a trailing delimiter is not
2442    required.  DELIM may not be changed after the first call. */
2443 static const char *
2444 string_from_data (gpgme_data_t data, int delim,
2445                   void **helpptr, gpgme_error_t *r_err)
2446 {
2447 #define MYBUFLEN 2000 /* Fixme: We don't support URLs longer than that.  */
2448   struct {
2449     int  eof_seen;
2450     int  nbytes;      /* Length of the last returned string including
2451                          the delimiter. */
2452     int  buflen;      /* Valid length of BUF.  */
2453     char buf[MYBUFLEN+1];  /* Buffer with one byte extra space.  */
2454   } *self;
2455   char *p;
2456   int nread;
2457
2458   *r_err = 0;
2459   if (!data)
2460     {
2461       if (*helpptr)
2462         {
2463           free (*helpptr);
2464           *helpptr = NULL;
2465         }
2466       return NULL;
2467     }
2468
2469   if (*helpptr)
2470     self = *helpptr;
2471   else
2472     {
2473       self = malloc (sizeof *self);
2474       if (!self)
2475         {
2476           *r_err = gpg_error_from_syserror ();
2477           return NULL;
2478         }
2479       *helpptr = self;
2480       self->eof_seen = 0;
2481       self->nbytes = 0;
2482       self->buflen = 0;
2483     }
2484
2485   if (self->eof_seen)
2486     return NULL;
2487
2488   assert (self->nbytes <= self->buflen);
2489   memmove (self->buf, self->buf + self->nbytes, self->buflen - self->nbytes);
2490   self->buflen -= self->nbytes;
2491   self->nbytes = 0;
2492
2493   do
2494     {
2495       /* Fixme: This is fairly infective scanning because we may scan
2496          the buffer several times.  */
2497       p = memchr (self->buf, delim, self->buflen);
2498       if (p)
2499         {
2500           *p = 0;
2501           self->nbytes = p - self->buf + 1;
2502           return self->buf;
2503         }
2504
2505       if ( !(MYBUFLEN - self->buflen) )
2506         {
2507           /* Not enough space - URL too long.  */
2508           *r_err = gpg_error (GPG_ERR_TOO_LARGE);
2509           return NULL;
2510         }
2511
2512       nread = gpgme_data_read (data, self->buf + self->buflen,
2513                                MYBUFLEN - self->buflen);
2514       if (nread < 0)
2515         {
2516           *r_err = gpg_error_from_syserror ();
2517           return NULL;
2518         }
2519       self->buflen += nread;
2520     }
2521   while (nread);
2522
2523   /* EOF reached.  If we have anything in the buffer, append a Nul and
2524      return it. */
2525   self->eof_seen = 1;
2526   if (self->buflen)
2527     {
2528       self->buf[self->buflen] = 0;  /* (we allocated one extra byte)  */
2529       return self->buf;
2530     }
2531   return NULL;
2532 #undef MYBUFLEN
2533 }
2534
2535
2536
2537 static gpgme_error_t
2538 gpg_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray)
2539 {
2540   engine_gpg_t gpg = engine;
2541   gpgme_error_t err;
2542   int idx;
2543   gpgme_data_encoding_t dataenc;
2544
2545   if (keydata && keyarray)
2546     return gpg_error (GPG_ERR_INV_VALUE); /* Only one is allowed.  */
2547
2548   dataenc = gpgme_data_get_encoding (keydata);
2549
2550   if (keyarray)
2551     {
2552       err = add_arg (gpg, "--recv-keys");
2553       if (!err)
2554         err = add_arg (gpg, "--");
2555       for (idx=0; !err && keyarray[idx]; idx++)
2556         {
2557           if (keyarray[idx]->protocol != GPGME_PROTOCOL_OpenPGP)
2558             ;
2559           else if (!keyarray[idx]->subkeys)
2560             ;
2561           else if (keyarray[idx]->subkeys->fpr && *keyarray[idx]->subkeys->fpr)
2562             err = add_arg (gpg, keyarray[idx]->subkeys->fpr);
2563           else if (*keyarray[idx]->subkeys->keyid)
2564             err = add_arg (gpg, keyarray[idx]->subkeys->keyid);
2565         }
2566     }
2567   else if (dataenc == GPGME_DATA_ENCODING_URL
2568            || dataenc == GPGME_DATA_ENCODING_URL0)
2569     {
2570       void *helpptr;
2571       const char *string;
2572       gpgme_error_t xerr;
2573       int delim = (dataenc == GPGME_DATA_ENCODING_URL)? '\n': 0;
2574
2575       /* FIXME: --fetch-keys is probably not correct because it can't
2576          grok all kinds of URLs.  On Unix it should just work but on
2577          Windows we will build the command line and that may fail for
2578          some embedded control characters.  It is anyway limited to
2579          the maximum size of the command line.  We need another
2580          command which can take its input from a file.  Maybe we
2581          should use an option to gpg to modify such commands (ala
2582          --multifile).  */
2583       err = add_arg (gpg, "--fetch-keys");
2584       if (!err)
2585         err = add_arg (gpg, "--");
2586       helpptr = NULL;
2587       while (!err
2588              && (string = string_from_data (keydata, delim, &helpptr, &xerr)))
2589         err = add_arg (gpg, string);
2590       if (!err)
2591         err = xerr;
2592       string_from_data (NULL, delim, &helpptr, &xerr);
2593     }
2594   else if (dataenc == GPGME_DATA_ENCODING_URLESC)
2595     {
2596       /* Already escaped URLs are not yet supported.  */
2597       err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
2598     }
2599   else
2600     {
2601       err = add_arg (gpg, "--import");
2602       if (!err)
2603         err = add_arg (gpg, "--");
2604       if (!err)
2605         err = add_data (gpg, keydata, -1, 0);
2606     }
2607
2608   if (!err)
2609     err = start (gpg);
2610
2611   return err;
2612 }
2613
2614
2615 /* The output for external keylistings in GnuPG is different from all
2616    the other key listings.  We catch this here with a special
2617    preprocessor that reformats the colon handler lines.  */
2618 static gpgme_error_t
2619 gpg_keylist_preprocess (char *line, char **r_line)
2620 {
2621   enum
2622     {
2623       RT_NONE, RT_INFO, RT_PUB, RT_UID
2624     }
2625   rectype = RT_NONE;
2626 #define NR_FIELDS 16
2627   char *field[NR_FIELDS];
2628   int fields = 0;
2629   size_t n;
2630
2631   *r_line = NULL;
2632
2633   while (line && fields < NR_FIELDS)
2634     {
2635       field[fields++] = line;
2636       line = strchr (line, ':');
2637       if (line)
2638         *(line++) = '\0';
2639     }
2640
2641   if (!strcmp (field[0], "info"))
2642     rectype = RT_INFO;
2643   else if (!strcmp (field[0], "pub"))
2644     rectype = RT_PUB;
2645   else if (!strcmp (field[0], "uid"))
2646     rectype = RT_UID;
2647   else
2648     rectype = RT_NONE;
2649
2650   switch (rectype)
2651     {
2652     case RT_INFO:
2653       /* FIXME: Eventually, check the version number at least.  */
2654       return 0;
2655
2656     case RT_PUB:
2657       if (fields < 7)
2658         return 0;
2659
2660       /* The format is:
2661
2662          pub:<keyid>:<algo>:<keylen>:<creationdate>:<expirationdate>:<flags>
2663
2664          as defined in 5.2. Machine Readable Indexes of the OpenPGP
2665          HTTP Keyserver Protocol (draft).  Modern versions of the SKS
2666          keyserver return the fingerprint instead of the keyid.  We
2667          detect this here and use the v4 fingerprint format to convert
2668          it to a key id.
2669
2670          We want:
2671          pub:o<flags>:<keylen>:<algo>:<keyid>:<creatdate>:<expdate>::::::::
2672       */
2673
2674       n = strlen (field[1]);
2675       if (n > 16)
2676         {
2677           if (gpgrt_asprintf (r_line,
2678                         "pub:o%s:%s:%s:%s:%s:%s::::::::\n"
2679                         "fpr:::::::::%s:",
2680                         field[6], field[3], field[2], field[1] + n - 16,
2681                         field[4], field[5], field[1]) < 0)
2682             return gpg_error_from_syserror ();
2683         }
2684       else
2685         {
2686           if (gpgrt_asprintf (r_line,
2687                         "pub:o%s:%s:%s:%s:%s:%s::::::::",
2688                         field[6], field[3], field[2], field[1],
2689                         field[4], field[5]) < 0)
2690             return gpg_error_from_syserror ();
2691         }
2692
2693       return 0;
2694
2695     case RT_UID:
2696       /* The format is:
2697
2698          uid:<escaped uid string>:<creationdate>:<expirationdate>:<flags>
2699
2700          as defined in 5.2. Machine Readable Indexes of the OpenPGP
2701          HTTP Keyserver Protocol (draft).
2702
2703          For an ldap keyserver the format is:
2704          uid:<escaped uid string>
2705
2706          We want:
2707          uid:o<flags>::::<creatdate>:<expdate>:::<c-coded uid>:
2708       */
2709
2710       {
2711         /* The user ID is percent escaped, but we want c-coded.
2712            Because we have to replace each '%HL' by '\xHL', we need at
2713            most 4/3 th the number of bytes.  But because we also need
2714            to escape the backslashes we allocate twice as much.  */
2715         char *uid = malloc (2 * strlen (field[1]) + 1);
2716         char *src;
2717         char *dst;
2718
2719         if (! uid)
2720           return gpg_error_from_syserror ();
2721         src = field[1];
2722         dst = uid;
2723         while (*src)
2724           {
2725             if (*src == '%')
2726               {
2727                 *(dst++) = '\\';
2728                 *(dst++) = 'x';
2729                 src++;
2730                 /* Copy the next two bytes unconditionally.  */
2731                 if (*src)
2732                   *(dst++) = *(src++);
2733                 if (*src)
2734                   *(dst++) = *(src++);
2735               }
2736             else if (*src == '\\')
2737               {
2738                 *dst++ = '\\';
2739                 *dst++ = '\\';
2740                 src++;
2741               }
2742             else
2743               *(dst++) = *(src++);
2744           }
2745         *dst = '\0';
2746
2747         if (fields < 4)
2748           {
2749             if (gpgrt_asprintf (r_line, "uid:o::::::::%s:", uid) < 0)
2750               return gpg_error_from_syserror ();
2751           }
2752         else
2753           {
2754             if (gpgrt_asprintf (r_line, "uid:o%s::::%s:%s:::%s:",
2755                                 field[4], field[2], field[3], uid) < 0)
2756               return gpg_error_from_syserror ();
2757           }
2758       }
2759       return 0;
2760
2761     case RT_NONE:
2762       /* Unknown record.  */
2763       break;
2764     }
2765   return 0;
2766
2767 }
2768
2769
2770 static gpg_error_t
2771 gpg_keylist_build_options (engine_gpg_t gpg, int secret_only,
2772                            gpgme_keylist_mode_t mode)
2773 {
2774   gpg_error_t err;
2775
2776   err = add_arg (gpg, "--with-colons");
2777
2778   /* Since gpg 2.1.15 fingerprints are always printed, thus there is
2779    * no more need to explicitly request them.  */
2780   if (!have_gpg_version (gpg, "2.1.15"))
2781     {
2782       if (!err)
2783         err = add_arg (gpg, "--fixed-list-mode");
2784       if (!err)
2785         err = add_arg (gpg, "--with-fingerprint");
2786       if (!err)
2787         err = add_arg (gpg, "--with-fingerprint");
2788     }
2789
2790   if (!err && (mode & GPGME_KEYLIST_MODE_WITH_TOFU)
2791       && have_gpg_version (gpg, "2.1.16"))
2792     err = add_arg (gpg, "--with-tofu-info");
2793
2794   if (!err && (mode & GPGME_KEYLIST_MODE_WITH_SECRET))
2795     err = add_arg (gpg, "--with-secret");
2796
2797   if (!err
2798       && (mode & GPGME_KEYLIST_MODE_SIGS)
2799       && (mode & GPGME_KEYLIST_MODE_SIG_NOTATIONS))
2800     {
2801       err = add_arg (gpg, "--list-options");
2802       if (!err)
2803         err = add_arg (gpg, "show-sig-subpackets=\"20,26\"");
2804     }
2805
2806   if (!err)
2807     {
2808       if ( (mode & GPGME_KEYLIST_MODE_EXTERN) )
2809         {
2810           if (secret_only)
2811             err = gpg_error (GPG_ERR_NOT_SUPPORTED);
2812           else if ( (mode & GPGME_KEYLIST_MODE_LOCAL))
2813             {
2814               /* The local+extern mode is special.  It works only with
2815                  gpg >= 2.0.10.  FIXME: We should check that we have
2816                  such a version to that we can return a proper error
2817                  code.  The problem is that we don't know the context
2818                  here and thus can't access the cached version number
2819                  for the engine info structure.  */
2820               err = add_arg (gpg, "--locate-keys");
2821               if ((mode & GPGME_KEYLIST_MODE_SIGS))
2822                 err = add_arg (gpg, "--with-sig-check");
2823             }
2824           else
2825             {
2826               err = add_arg (gpg, "--search-keys");
2827               gpg->colon.preprocess_fnc = gpg_keylist_preprocess;
2828             }
2829         }
2830       else
2831         {
2832           err = add_arg (gpg, secret_only ? "--list-secret-keys"
2833                          : ((mode & GPGME_KEYLIST_MODE_SIGS)
2834                             ? "--check-sigs" : "--list-keys"));
2835         }
2836     }
2837
2838   if (!err)
2839     err = add_arg (gpg, "--");
2840
2841   return err;
2842 }
2843
2844
2845 static gpgme_error_t
2846 gpg_keylist (void *engine, const char *pattern, int secret_only,
2847              gpgme_keylist_mode_t mode, int engine_flags)
2848 {
2849   engine_gpg_t gpg = engine;
2850   gpgme_error_t err;
2851
2852   (void)engine_flags;
2853
2854   err = gpg_keylist_build_options (gpg, secret_only, mode);
2855
2856   if (!err && pattern && *pattern)
2857     err = add_arg (gpg, pattern);
2858
2859   if (!err)
2860     err = start (gpg);
2861
2862   return err;
2863 }
2864
2865
2866 static gpgme_error_t
2867 gpg_keylist_ext (void *engine, const char *pattern[], int secret_only,
2868                  int reserved, gpgme_keylist_mode_t mode, int engine_flags)
2869 {
2870   engine_gpg_t gpg = engine;
2871   gpgme_error_t err;
2872
2873   (void)engine_flags;
2874
2875   if (reserved)
2876     return gpg_error (GPG_ERR_INV_VALUE);
2877
2878   err = gpg_keylist_build_options (gpg, secret_only, mode);
2879
2880   if (pattern)
2881     {
2882       while (!err && *pattern && **pattern)
2883         err = add_arg (gpg, *(pattern++));
2884     }
2885
2886   if (!err)
2887     err = start (gpg);
2888
2889   return err;
2890 }
2891
2892
2893 static gpgme_error_t
2894 gpg_keylist_data (void *engine, gpgme_data_t data)
2895 {
2896   engine_gpg_t gpg = engine;
2897   gpgme_error_t err;
2898
2899   if (!have_gpg_version (gpg, "2.1.14"))
2900     return gpg_error (GPG_ERR_NOT_SUPPORTED);
2901
2902   err = add_arg (gpg, "--with-colons");
2903   if (!err)
2904     err = add_arg (gpg, "--with-fingerprint");
2905   if (!err)
2906     err = add_arg (gpg, "--import-options");
2907   if (!err)
2908     err = add_arg (gpg, "import-show");
2909   if (!err)
2910     err = add_arg (gpg, "--dry-run");
2911   if (!err)
2912     err = add_arg (gpg, "--import");
2913   if (!err)
2914     err = add_arg (gpg, "--");
2915   if (!err)
2916     err = add_data (gpg, data, -1, 0);
2917
2918   if (!err)
2919     err = start (gpg);
2920
2921   return err;
2922 }
2923
2924
2925 static gpgme_error_t
2926 gpg_keysign (void *engine, gpgme_key_t key, const char *userid,
2927              unsigned long expire, unsigned int flags,
2928              gpgme_ctx_t ctx)
2929 {
2930   engine_gpg_t gpg = engine;
2931   gpgme_error_t err;
2932   const char *s;
2933
2934   if (!key || !key->fpr)
2935     return gpg_error (GPG_ERR_INV_ARG);
2936
2937   if (!have_gpg_version (gpg, "2.1.12"))
2938     return gpg_error (GPG_ERR_NOT_SUPPORTED);
2939
2940   if ((flags & GPGME_KEYSIGN_LOCAL))
2941     err = add_arg (gpg, "--quick-lsign-key");
2942   else
2943     err = add_arg (gpg, "--quick-sign-key");
2944
2945   if (!err)
2946     err = append_args_from_signers (gpg, ctx);
2947
2948   /* If an expiration time has been given use that.  If none has been
2949    * given the default from gpg.conf is used.  To make sure not to set
2950    * an expiration time at all the flag GPGME_KEYSIGN_NOEXPIRE can be
2951    * used.  */
2952   if (!err && (expire || (flags & GPGME_KEYSIGN_NOEXPIRE)))
2953     {
2954       char tmpbuf[8+20];
2955
2956       if ((flags & GPGME_KEYSIGN_NOEXPIRE))
2957         expire = 0;
2958       snprintf (tmpbuf, sizeof tmpbuf, "seconds=%lu", expire);
2959       err = add_arg (gpg, "--default-cert-expire");
2960       if (!err)
2961         err = add_arg (gpg, tmpbuf);
2962     }
2963
2964   if (!err)
2965     err = add_arg (gpg, "--");
2966
2967   if (!err)
2968     err = add_arg (gpg, key->fpr);
2969   if (!err && userid)
2970     {
2971       if ((flags & GPGME_KEYSIGN_LFSEP))
2972         {
2973           for (; !err && (s = strchr (userid, '\n')); userid = s + 1)
2974             if ((s - userid))
2975               err = add_arg_len (gpg, "=", userid, s - userid);
2976           if (!err && *userid)
2977             err = add_arg_pfx (gpg, "=", userid);
2978         }
2979       else
2980         err = add_arg_pfx (gpg, "=", userid);
2981     }
2982
2983   if (!err)
2984     err = start (gpg);
2985
2986   return err;
2987 }
2988
2989
2990 static gpgme_error_t
2991 gpg_tofu_policy (void *engine, gpgme_key_t key, gpgme_tofu_policy_t policy)
2992 {
2993   engine_gpg_t gpg = engine;
2994   gpgme_error_t err;
2995   const char *policystr = NULL;
2996
2997   if (!key || !key->fpr)
2998     return gpg_error (GPG_ERR_INV_ARG);
2999
3000   switch (policy)
3001     {
3002     case GPGME_TOFU_POLICY_NONE:                           break;
3003     case GPGME_TOFU_POLICY_AUTO:    policystr = "auto";    break;
3004     case GPGME_TOFU_POLICY_GOOD:    policystr = "good";    break;
3005     case GPGME_TOFU_POLICY_BAD:     policystr = "bad";     break;
3006     case GPGME_TOFU_POLICY_ASK:     policystr = "ask";     break;
3007     case GPGME_TOFU_POLICY_UNKNOWN: policystr = "unknown"; break;
3008     }
3009   if (!policystr)
3010     return gpg_error (GPG_ERR_INV_VALUE);
3011
3012   if (!have_gpg_version (gpg, "2.1.10"))
3013     return gpg_error (GPG_ERR_NOT_SUPPORTED);
3014
3015   err = add_arg (gpg, "--tofu-policy");
3016   if (!err)
3017     err = add_arg (gpg, "--");
3018   if (!err)
3019     err = add_arg (gpg, policystr);
3020   if (!err)
3021     err = add_arg (gpg, key->fpr);
3022
3023   if (!err)
3024     err = start (gpg);
3025
3026   return err;
3027 }
3028
3029
3030 static gpgme_error_t
3031 gpg_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
3032           gpgme_sig_mode_t mode, int use_armor, int use_textmode,
3033           int include_certs, gpgme_ctx_t ctx /* FIXME */)
3034 {
3035   engine_gpg_t gpg = engine;
3036   gpgme_error_t err;
3037
3038   (void)include_certs;
3039
3040   if (mode == GPGME_SIG_MODE_CLEAR)
3041     err = add_arg (gpg, "--clearsign");
3042   else
3043     {
3044       err = add_arg (gpg, "--sign");
3045       if (!err && mode == GPGME_SIG_MODE_DETACH)
3046         err = add_arg (gpg, "--detach");
3047       if (!err && use_armor)
3048         err = add_arg (gpg, "--armor");
3049       if (!err)
3050         {
3051           if (gpgme_data_get_encoding (in) == GPGME_DATA_ENCODING_MIME
3052               && have_gpg_version (gpg, "2.1.14"))
3053             err = add_arg (gpg, "--mimemode");
3054           else if (use_textmode)
3055             err = add_arg (gpg, "--textmode");
3056         }
3057     }
3058
3059   if (!err)
3060     err = append_args_from_signers (gpg, ctx);
3061   if (!err)
3062     err = append_args_from_sender (gpg, ctx);
3063   if (!err)
3064     err = append_args_from_sig_notations (gpg, ctx);
3065
3066   if (gpgme_data_get_file_name (in))
3067     {
3068       if (!err)
3069         err = add_arg (gpg, "--set-filename");
3070       if (!err)
3071         err = add_arg (gpg, gpgme_data_get_file_name (in));
3072     }
3073
3074   /* Tell the gpg object about the data.  */
3075   if (!err)
3076     err = add_input_size_hint (gpg, in);
3077   if (!err)
3078     err = add_arg (gpg, "--");
3079   if (!err)
3080     err = add_data (gpg, in, -1, 0);
3081   if (!err)
3082     err = add_data (gpg, out, 1, 1);
3083
3084   if (!err)
3085     err = start (gpg);
3086
3087   return err;
3088 }
3089
3090 static gpgme_error_t
3091 gpg_trustlist (void *engine, const char *pattern)
3092 {
3093   engine_gpg_t gpg = engine;
3094   gpgme_error_t err;
3095
3096   err = add_arg (gpg, "--with-colons");
3097   if (!err)
3098     err = add_arg (gpg, "--list-trust-path");
3099
3100   /* Tell the gpg object about the data.  */
3101   if (!err)
3102     err = add_arg (gpg, "--");
3103   if (!err)
3104     err = add_arg (gpg, pattern);
3105
3106   if (!err)
3107     err = start (gpg);
3108
3109   return err;
3110 }
3111
3112
3113 static gpgme_error_t
3114 gpg_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
3115             gpgme_data_t plaintext, gpgme_ctx_t ctx)
3116 {
3117   engine_gpg_t gpg = engine;
3118   gpgme_error_t err;
3119
3120   err = append_args_from_sender (gpg, ctx);
3121   if (!err && ctx->auto_key_retrieve)
3122     err = add_arg (gpg, "--auto-key-retrieve");
3123
3124   if (err)
3125     ;
3126   else if (plaintext)
3127     {
3128       /* Normal or cleartext signature.  */
3129       err = add_arg (gpg, "--output");
3130       if (!err)
3131         err = add_arg (gpg, "-");
3132       if (!err)
3133         err = add_input_size_hint (gpg, sig);
3134       if (!err)
3135         err = add_arg (gpg, "--");
3136       if (!err)
3137         err = add_data (gpg, sig, -1, 0);
3138       if (!err)
3139         err = add_data (gpg, plaintext, 1, 1);
3140     }
3141   else
3142     {
3143       err = add_arg (gpg, "--verify");
3144       if (!err)
3145         err = add_input_size_hint (gpg, signed_text);
3146       if (!err)
3147         err = add_arg (gpg, "--");
3148       if (!err)
3149         err = add_data (gpg, sig, -1, 0);
3150       if (!err && signed_text)
3151         err = add_data (gpg, signed_text, -1, 0);
3152     }
3153
3154   if (!err)
3155     err = start (gpg);
3156
3157   return err;
3158 }
3159
3160
3161 static void
3162 gpg_set_io_cbs (void *engine, gpgme_io_cbs_t io_cbs)
3163 {
3164   engine_gpg_t gpg = engine;
3165
3166   gpg->io_cbs = *io_cbs;
3167 }
3168
3169
3170 static gpgme_error_t
3171 gpg_set_pinentry_mode (void *engine, gpgme_pinentry_mode_t mode)
3172 {
3173   engine_gpg_t gpg = engine;
3174
3175   gpg->pinentry_mode = mode;
3176   return 0;
3177 }
3178
3179
3180 \f
3181 struct engine_ops _gpgme_engine_ops_gpg =
3182   {
3183     /* Static functions.  */
3184     _gpgme_get_default_gpg_name,
3185     NULL,
3186     gpg_get_version,
3187     gpg_get_req_version,
3188     gpg_new,
3189
3190     /* Member functions.  */
3191     gpg_release,
3192     NULL,                               /* reset */
3193     gpg_set_status_cb,
3194     gpg_set_status_handler,
3195     gpg_set_command_handler,
3196     gpg_set_colon_line_handler,
3197     gpg_set_locale,
3198     NULL,                               /* set_protocol */
3199     gpg_set_engine_flags,               /* set_engine_flags */
3200     gpg_decrypt,
3201     gpg_delete,
3202     gpg_edit,
3203     gpg_encrypt,
3204     gpg_encrypt_sign,
3205     gpg_export,
3206     gpg_export_ext,
3207     gpg_genkey,
3208     gpg_import,
3209     gpg_keylist,
3210     gpg_keylist_ext,
3211     gpg_keylist_data,
3212     gpg_keysign,
3213     gpg_tofu_policy,    /* tofu_policy */
3214     gpg_sign,
3215     gpg_trustlist,
3216     gpg_verify,
3217     NULL,               /* getauditlog */
3218     NULL,               /* opassuan_transact */
3219     NULL,               /* conf_load */
3220     NULL,               /* conf_save */
3221     NULL,               /* conf_dir */
3222     NULL,               /* query_swdb */
3223     gpg_set_io_cbs,
3224     gpg_io_event,
3225     gpg_cancel,
3226     NULL,               /* cancel_op */
3227     gpg_passwd,
3228     gpg_set_pinentry_mode,
3229     NULL                /* opspawn */
3230   };