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