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