Fix GPGME_CREATE_NOPASSWD without pinentry loopback.
[gpgme.git] / src / engine-gpg.c
1 /* engine-gpg.c - Gpg Engine.
2    Copyright (C) 2000 Werner Koch (dd9jn)
3    Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007,
4                  2009, 2010, 2012, 2013 g10 Code GmbH
5
6    This file is part of GPGME.
7
8    GPGME is free software; you can redistribute it and/or modify it
9    under the terms of the GNU Lesser General Public License as
10    published by the Free Software Foundation; either version 2.1 of
11    the License, or (at your option) any later version.
12
13    GPGME is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    Lesser General Public License for more details.
17
18    You should have received a copy of the GNU Lesser General Public
19    License along with this program; if not, see <https://www.gnu.org/licenses/>.
20 */
21
22 #if HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <assert.h>
29 #include <errno.h>
30 #ifdef HAVE_UNISTD_H
31 # include <unistd.h>
32 #endif
33 #ifdef HAVE_LOCALE_H
34 #include <locale.h>
35 #endif
36
37 #include "gpgme.h"
38 #include "util.h"
39 #include "ops.h"
40 #include "wait.h"
41 #include "context.h"  /*temp hack until we have GpmeData methods to do I/O */
42 #include "priv-io.h"
43 #include "sema.h"
44 #include "debug.h"
45 #include "data.h"
46
47 #include "engine-backend.h"
48
49
50 /* This type is used to build a list of gpg arguments and data
51    sources/sinks.  */
52 struct arg_and_data_s
53 {
54   struct arg_and_data_s *next;
55   gpgme_data_t data;  /* If this is not NULL, use arg below.  */
56   int inbound;     /* True if this is used for reading from gpg.  */
57   int dup_to;
58   int print_fd;    /* Print the fd number and not the special form of it.  */
59   int *arg_locp;   /* Write back the argv idx of this argument when
60                       building command line to this location.  */
61   char arg[1];     /* Used if data above is not used.  */
62 };
63
64
65 struct fd_data_map_s
66 {
67   gpgme_data_t data;
68   int inbound;  /* true if this is used for reading from gpg */
69   int dup_to;
70   int fd;       /* the fd to use */
71   int peer_fd;  /* the other side of the pipe */
72   int arg_loc;  /* The index into the argv for translation purposes.  */
73   void *tag;
74 };
75
76
77 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       if (!err)
2140         err = add_arg (gpg, "--batch");
2141     }
2142   if (!err && (flags & GPGME_CREATE_FORCE))
2143     err = add_arg (gpg, "--yes");
2144   if (!err)
2145     err = add_arg (gpg, "--");
2146   if (!err)
2147     err = add_arg (gpg, userid);
2148
2149   if (!err)
2150     err = gpg_add_algo_usage_expire (gpg, algo, expires, flags);
2151
2152   if (!err)
2153     err = start (gpg);
2154   return err;
2155 }
2156
2157
2158 static gpgme_error_t
2159 gpg_addkey (engine_gpg_t gpg,
2160             const char *algo,
2161             unsigned long expires,
2162             gpgme_key_t key,
2163             unsigned int flags,
2164             unsigned int extraflags)
2165 {
2166   gpgme_error_t err;
2167
2168   if (!key || !key->fpr)
2169     return gpg_error (GPG_ERR_INV_ARG);
2170
2171   err = add_arg (gpg, "--quick-addkey");
2172   if (!err && (extraflags & GENKEY_EXTRAFLAG_ARMOR))
2173     err = add_arg (gpg, "--armor");
2174   if (!err && (flags & GPGME_CREATE_NOPASSWD))
2175     {
2176       err = add_arg (gpg, "--passphrase");
2177       if (!err)
2178         err = add_arg (gpg, "");
2179     }
2180   if (!err)
2181     err = add_arg (gpg, "--");
2182   if (!err)
2183     err = add_arg (gpg, key->fpr);
2184
2185   if (!err)
2186     err = gpg_add_algo_usage_expire (gpg, algo, expires, flags);
2187
2188   if (!err)
2189     err = start (gpg);
2190   return err;
2191 }
2192
2193
2194 static gpgme_error_t
2195 gpg_adduid (engine_gpg_t gpg,
2196             gpgme_key_t key,
2197             const char *userid,
2198             unsigned int extraflags)
2199 {
2200   gpgme_error_t err;
2201
2202   if (!key || !key->fpr || !userid)
2203     return gpg_error (GPG_ERR_INV_ARG);
2204
2205   if ((extraflags & GENKEY_EXTRAFLAG_REVOKE))
2206     err = add_arg (gpg, "--quick-revuid");
2207   else
2208     err = add_arg (gpg, "--quick-adduid");
2209
2210   if (!err)
2211     err = add_arg (gpg, "--");
2212   if (!err)
2213     err = add_arg (gpg, key->fpr);
2214   if (!err)
2215     err = add_arg (gpg, userid);
2216
2217   if (!err)
2218     err = start (gpg);
2219   return err;
2220 }
2221
2222
2223 static gpgme_error_t
2224 gpg_genkey (void *engine,
2225             const char *userid, const char *algo,
2226             unsigned long reserved, unsigned long expires,
2227             gpgme_key_t key, unsigned int flags,
2228             gpgme_data_t help_data, unsigned int extraflags,
2229             gpgme_data_t pubkey, gpgme_data_t seckey)
2230 {
2231   engine_gpg_t gpg = engine;
2232   gpgme_error_t err;
2233
2234   (void)reserved;
2235
2236   if (!gpg)
2237     return gpg_error (GPG_ERR_INV_VALUE);
2238
2239   /* If HELP_DATA is given the use of the old interface
2240    * (gpgme_op_genkey) has been requested.  The other modes are:
2241    *
2242    *  USERID && !KEY          - Create a new keyblock.
2243    * !USERID &&  KEY          - Add a new subkey to KEY (gpg >= 2.1.14)
2244    *  USERID &&  KEY && !ALGO - Add a new user id to KEY (gpg >= 2.1.14).
2245    *
2246    */
2247   if (help_data)
2248     {
2249       /* We need a special mechanism to get the fd of a pipe here, so
2250          that we can use this for the %pubring and %secring
2251          parameters.  We don't have this yet, so we implement only the
2252          adding to the standard keyrings.  */
2253       if (pubkey || seckey)
2254         err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
2255       else
2256         err = gpg_createkey_from_param (gpg, help_data, extraflags);
2257     }
2258   else if (!have_gpg_version (gpg, "2.1.13"))
2259     err = gpg_error (GPG_ERR_NOT_SUPPORTED);
2260   else if (userid && !key)
2261     err = gpg_createkey (gpg, userid, algo, expires, flags, extraflags);
2262   else if (!userid && key)
2263     err = gpg_addkey (gpg, algo, expires, key, flags, extraflags);
2264   else if (userid && key && !algo)
2265     err = gpg_adduid (gpg, key, userid, extraflags);
2266   else
2267     err = gpg_error (GPG_ERR_INV_VALUE);
2268
2269   return err;
2270 }
2271
2272 /* Return the next DELIM delimited string from DATA as a C-string.
2273    The caller needs to provide the address of a pointer variable which
2274    he has to set to NULL before the first call.  After the last call
2275    to this function, this function needs to be called once more with
2276    DATA set to NULL so that the function can release its internal
2277    state.  After that the pointer variable is free for use again.
2278    Note that we use a delimiter and thus a trailing delimiter is not
2279    required.  DELIM may not be changed after the first call. */
2280 static const char *
2281 string_from_data (gpgme_data_t data, int delim,
2282                   void **helpptr, gpgme_error_t *r_err)
2283 {
2284 #define MYBUFLEN 2000 /* Fixme: We don't support URLs longer than that.  */
2285   struct {
2286     int  eof_seen;
2287     int  nbytes;      /* Length of the last returned string including
2288                          the delimiter. */
2289     int  buflen;      /* Valid length of BUF.  */
2290     char buf[MYBUFLEN+1];  /* Buffer with one byte extra space.  */
2291   } *self;
2292   char *p;
2293   int nread;
2294
2295   *r_err = 0;
2296   if (!data)
2297     {
2298       if (*helpptr)
2299         {
2300           free (*helpptr);
2301           *helpptr = NULL;
2302         }
2303       return NULL;
2304     }
2305
2306   if (*helpptr)
2307     self = *helpptr;
2308   else
2309     {
2310       self = malloc (sizeof *self);
2311       if (!self)
2312         {
2313           *r_err = gpg_error_from_syserror ();
2314           return NULL;
2315         }
2316       *helpptr = self;
2317       self->eof_seen = 0;
2318       self->nbytes = 0;
2319       self->buflen = 0;
2320     }
2321
2322   if (self->eof_seen)
2323     return NULL;
2324
2325   assert (self->nbytes <= self->buflen);
2326   memmove (self->buf, self->buf + self->nbytes, self->buflen - self->nbytes);
2327   self->buflen -= self->nbytes;
2328   self->nbytes = 0;
2329
2330   do
2331     {
2332       /* Fixme: This is fairly infective scanning because we may scan
2333          the buffer several times.  */
2334       p = memchr (self->buf, delim, self->buflen);
2335       if (p)
2336         {
2337           *p = 0;
2338           self->nbytes = p - self->buf + 1;
2339           return self->buf;
2340         }
2341
2342       if ( !(MYBUFLEN - self->buflen) )
2343         {
2344           /* Not enough space - URL too long.  */
2345           *r_err = gpg_error (GPG_ERR_TOO_LARGE);
2346           return NULL;
2347         }
2348
2349       nread = gpgme_data_read (data, self->buf + self->buflen,
2350                                MYBUFLEN - self->buflen);
2351       if (nread < 0)
2352         {
2353           *r_err = gpg_error_from_syserror ();
2354           return NULL;
2355         }
2356       self->buflen += nread;
2357     }
2358   while (nread);
2359
2360   /* EOF reached.  If we have anything in the buffer, append a Nul and
2361      return it. */
2362   self->eof_seen = 1;
2363   if (self->buflen)
2364     {
2365       self->buf[self->buflen] = 0;  /* (we allocated one extra byte)  */
2366       return self->buf;
2367     }
2368   return NULL;
2369 #undef MYBUFLEN
2370 }
2371
2372
2373
2374 static gpgme_error_t
2375 gpg_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray)
2376 {
2377   engine_gpg_t gpg = engine;
2378   gpgme_error_t err;
2379   int idx;
2380   gpgme_data_encoding_t dataenc;
2381
2382   if (keydata && keyarray)
2383     return gpg_error (GPG_ERR_INV_VALUE); /* Only one is allowed.  */
2384
2385   dataenc = gpgme_data_get_encoding (keydata);
2386
2387   if (keyarray)
2388     {
2389       err = add_arg (gpg, "--recv-keys");
2390       if (!err)
2391         err = add_arg (gpg, "--");
2392       for (idx=0; !err && keyarray[idx]; idx++)
2393         {
2394           if (keyarray[idx]->protocol != GPGME_PROTOCOL_OpenPGP)
2395             ;
2396           else if (!keyarray[idx]->subkeys)
2397             ;
2398           else if (keyarray[idx]->subkeys->fpr && *keyarray[idx]->subkeys->fpr)
2399             err = add_arg (gpg, keyarray[idx]->subkeys->fpr);
2400           else if (*keyarray[idx]->subkeys->keyid)
2401             err = add_arg (gpg, keyarray[idx]->subkeys->keyid);
2402         }
2403     }
2404   else if (dataenc == GPGME_DATA_ENCODING_URL
2405            || dataenc == GPGME_DATA_ENCODING_URL0)
2406     {
2407       void *helpptr;
2408       const char *string;
2409       gpgme_error_t xerr;
2410       int delim = (dataenc == GPGME_DATA_ENCODING_URL)? '\n': 0;
2411
2412       /* FIXME: --fetch-keys is probably not correct because it can't
2413          grok all kinds of URLs.  On Unix it should just work but on
2414          Windows we will build the command line and that may fail for
2415          some embedded control characters.  It is anyway limited to
2416          the maximum size of the command line.  We need another
2417          command which can take its input from a file.  Maybe we
2418          should use an option to gpg to modify such commands (ala
2419          --multifile).  */
2420       err = add_arg (gpg, "--fetch-keys");
2421       if (!err)
2422         err = add_arg (gpg, "--");
2423       helpptr = NULL;
2424       while (!err
2425              && (string = string_from_data (keydata, delim, &helpptr, &xerr)))
2426         err = add_arg (gpg, string);
2427       if (!err)
2428         err = xerr;
2429       string_from_data (NULL, delim, &helpptr, &xerr);
2430     }
2431   else if (dataenc == GPGME_DATA_ENCODING_URLESC)
2432     {
2433       /* Already escaped URLs are not yet supported.  */
2434       err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
2435     }
2436   else
2437     {
2438       err = add_arg (gpg, "--import");
2439       if (!err)
2440         err = add_arg (gpg, "--");
2441       if (!err)
2442         err = add_data (gpg, keydata, -1, 0);
2443     }
2444
2445   if (!err)
2446     err = start (gpg);
2447
2448   return err;
2449 }
2450
2451
2452 /* The output for external keylistings in GnuPG is different from all
2453    the other key listings.  We catch this here with a special
2454    preprocessor that reformats the colon handler lines.  */
2455 static gpgme_error_t
2456 gpg_keylist_preprocess (char *line, char **r_line)
2457 {
2458   enum
2459     {
2460       RT_NONE, RT_INFO, RT_PUB, RT_UID
2461     }
2462   rectype = RT_NONE;
2463 #define NR_FIELDS 16
2464   char *field[NR_FIELDS];
2465   int fields = 0;
2466   size_t n;
2467
2468   *r_line = NULL;
2469
2470   while (line && fields < NR_FIELDS)
2471     {
2472       field[fields++] = line;
2473       line = strchr (line, ':');
2474       if (line)
2475         *(line++) = '\0';
2476     }
2477
2478   if (!strcmp (field[0], "info"))
2479     rectype = RT_INFO;
2480   else if (!strcmp (field[0], "pub"))
2481     rectype = RT_PUB;
2482   else if (!strcmp (field[0], "uid"))
2483     rectype = RT_UID;
2484   else
2485     rectype = RT_NONE;
2486
2487   switch (rectype)
2488     {
2489     case RT_INFO:
2490       /* FIXME: Eventually, check the version number at least.  */
2491       return 0;
2492
2493     case RT_PUB:
2494       if (fields < 7)
2495         return 0;
2496
2497       /* The format is:
2498
2499          pub:<keyid>:<algo>:<keylen>:<creationdate>:<expirationdate>:<flags>
2500
2501          as defined in 5.2. Machine Readable Indexes of the OpenPGP
2502          HTTP Keyserver Protocol (draft).  Modern versions of the SKS
2503          keyserver return the fingerprint instead of the keyid.  We
2504          detect this here and use the v4 fingerprint format to convert
2505          it to a key id.
2506
2507          We want:
2508          pub:o<flags>:<keylen>:<algo>:<keyid>:<creatdate>:<expdate>::::::::
2509       */
2510
2511       n = strlen (field[1]);
2512       if (n > 16)
2513         {
2514           if (asprintf (r_line,
2515                         "pub:o%s:%s:%s:%s:%s:%s::::::::\n"
2516                         "fpr:::::::::%s:",
2517                         field[6], field[3], field[2], field[1] + n - 16,
2518                         field[4], field[5], field[1]) < 0)
2519             return gpg_error_from_syserror ();
2520         }
2521       else
2522         {
2523           if (asprintf (r_line,
2524                         "pub:o%s:%s:%s:%s:%s:%s::::::::",
2525                         field[6], field[3], field[2], field[1],
2526                         field[4], field[5]) < 0)
2527             return gpg_error_from_syserror ();
2528         }
2529
2530       return 0;
2531
2532     case RT_UID:
2533       /* The format is:
2534
2535          uid:<escaped uid string>:<creationdate>:<expirationdate>:<flags>
2536
2537          as defined in 5.2. Machine Readable Indexes of the OpenPGP
2538          HTTP Keyserver Protocol (draft).
2539
2540          We want:
2541          uid:o<flags>::::<creatdate>:<expdate>:::<c-coded uid>:
2542       */
2543
2544       {
2545         /* The user ID is percent escaped, but we want c-coded.
2546            Because we have to replace each '%HL' by '\xHL', we need at
2547            most 4/3 th the number of bytes.  But because we also need
2548            to escape the backslashes we allocate twice as much.  */
2549         char *uid = malloc (2 * strlen (field[1]) + 1);
2550         char *src;
2551         char *dst;
2552
2553         if (! uid)
2554           return gpg_error_from_syserror ();
2555         src = field[1];
2556         dst = uid;
2557         while (*src)
2558           {
2559             if (*src == '%')
2560               {
2561                 *(dst++) = '\\';
2562                 *(dst++) = 'x';
2563                 src++;
2564                 /* Copy the next two bytes unconditionally.  */
2565                 if (*src)
2566                   *(dst++) = *(src++);
2567                 if (*src)
2568                   *(dst++) = *(src++);
2569               }
2570             else if (*src == '\\')
2571               {
2572                 *dst++ = '\\';
2573                 *dst++ = '\\';
2574                 src++;
2575               }
2576             else
2577               *(dst++) = *(src++);
2578           }
2579         *dst = '\0';
2580
2581         if (asprintf (r_line, "uid:o%s::::%s:%s:::%s:",
2582                       field[4], field[2], field[3], uid) < 0)
2583           return gpg_error_from_syserror ();
2584       }
2585       return 0;
2586
2587     case RT_NONE:
2588       /* Unknown record.  */
2589       break;
2590     }
2591   return 0;
2592
2593 }
2594
2595
2596 static gpg_error_t
2597 gpg_keylist_build_options (engine_gpg_t gpg, int secret_only,
2598                            gpgme_keylist_mode_t mode)
2599 {
2600   gpg_error_t err;
2601
2602   err = add_arg (gpg, "--with-colons");
2603
2604   /* Since gpg 2.1.15 fingerprints are always printed, thus there is
2605    * no more need to explicitly request them.  */
2606   if (!have_gpg_version (gpg, "2.1.15"))
2607     {
2608       if (!err)
2609         err = add_arg (gpg, "--fixed-list-mode");
2610       if (!err)
2611         err = add_arg (gpg, "--with-fingerprint");
2612       if (!err)
2613         err = add_arg (gpg, "--with-fingerprint");
2614     }
2615
2616   if (!err && (mode & GPGME_KEYLIST_MODE_WITH_TOFU)
2617       && have_gpg_version (gpg, "2.1.16"))
2618     err = add_arg (gpg, "--with-tofu-info");
2619
2620   if (!err && (mode & GPGME_KEYLIST_MODE_WITH_SECRET))
2621     err = add_arg (gpg, "--with-secret");
2622
2623   if (!err
2624       && (mode & GPGME_KEYLIST_MODE_SIGS)
2625       && (mode & GPGME_KEYLIST_MODE_SIG_NOTATIONS))
2626     {
2627       err = add_arg (gpg, "--list-options");
2628       if (!err)
2629         err = add_arg (gpg, "show-sig-subpackets=\"20,26\"");
2630     }
2631
2632   if (!err)
2633     {
2634       if ( (mode & GPGME_KEYLIST_MODE_EXTERN) )
2635         {
2636           if (secret_only)
2637             err = gpg_error (GPG_ERR_NOT_SUPPORTED);
2638           else if ( (mode & GPGME_KEYLIST_MODE_LOCAL))
2639             {
2640               /* The local+extern mode is special.  It works only with
2641                  gpg >= 2.0.10.  FIXME: We should check that we have
2642                  such a version to that we can return a proper error
2643                  code.  The problem is that we don't know the context
2644                  here and thus can't access the cached version number
2645                  for the engine info structure.  */
2646               err = add_arg (gpg, "--locate-keys");
2647               if ((mode & GPGME_KEYLIST_MODE_SIGS))
2648                 err = add_arg (gpg, "--with-sig-check");
2649             }
2650           else
2651             {
2652               err = add_arg (gpg, "--search-keys");
2653               gpg->colon.preprocess_fnc = gpg_keylist_preprocess;
2654             }
2655         }
2656       else
2657         {
2658           err = add_arg (gpg, secret_only ? "--list-secret-keys"
2659                          : ((mode & GPGME_KEYLIST_MODE_SIGS)
2660                             ? "--check-sigs" : "--list-keys"));
2661         }
2662     }
2663
2664   if (!err)
2665     err = add_arg (gpg, "--");
2666
2667   return err;
2668 }
2669
2670
2671 static gpgme_error_t
2672 gpg_keylist (void *engine, const char *pattern, int secret_only,
2673              gpgme_keylist_mode_t mode, int engine_flags)
2674 {
2675   engine_gpg_t gpg = engine;
2676   gpgme_error_t err;
2677
2678   (void)engine_flags;
2679
2680   err = gpg_keylist_build_options (gpg, secret_only, mode);
2681
2682   if (!err && pattern && *pattern)
2683     err = add_arg (gpg, pattern);
2684
2685   if (!err)
2686     err = start (gpg);
2687
2688   return err;
2689 }
2690
2691
2692 static gpgme_error_t
2693 gpg_keylist_ext (void *engine, const char *pattern[], int secret_only,
2694                  int reserved, gpgme_keylist_mode_t mode, int engine_flags)
2695 {
2696   engine_gpg_t gpg = engine;
2697   gpgme_error_t err;
2698
2699   (void)engine_flags;
2700
2701   if (reserved)
2702     return gpg_error (GPG_ERR_INV_VALUE);
2703
2704   err = gpg_keylist_build_options (gpg, secret_only, mode);
2705
2706   if (pattern)
2707     {
2708       while (!err && *pattern && **pattern)
2709         err = add_arg (gpg, *(pattern++));
2710     }
2711
2712   if (!err)
2713     err = start (gpg);
2714
2715   return err;
2716 }
2717
2718
2719 static gpgme_error_t
2720 gpg_keysign (void *engine, gpgme_key_t key, const char *userid,
2721              unsigned long expire, unsigned int flags,
2722              gpgme_ctx_t ctx)
2723 {
2724   engine_gpg_t gpg = engine;
2725   gpgme_error_t err;
2726   const char *s;
2727
2728   if (!key || !key->fpr)
2729     return gpg_error (GPG_ERR_INV_ARG);
2730
2731   if (!have_gpg_version (gpg, "2.1.12"))
2732     return gpg_error (GPG_ERR_NOT_SUPPORTED);
2733
2734   if ((flags & GPGME_KEYSIGN_LOCAL))
2735     err = add_arg (gpg, "--quick-lsign-key");
2736   else
2737     err = add_arg (gpg, "--quick-sign-key");
2738
2739   if (!err)
2740     err = append_args_from_signers (gpg, ctx);
2741
2742   /* If an expiration time has been given use that.  If none has been
2743    * given the default from gpg.conf is used.  To make sure not to set
2744    * an expiration time at all the flag GPGME_KEYSIGN_NOEXPIRE can be
2745    * used.  */
2746   if (!err && (expire || (flags & GPGME_KEYSIGN_NOEXPIRE)))
2747     {
2748       char tmpbuf[8+20];
2749
2750       if ((flags & GPGME_KEYSIGN_NOEXPIRE))
2751         expire = 0;
2752       snprintf (tmpbuf, sizeof tmpbuf, "seconds=%lu", expire);
2753       err = add_arg (gpg, "--default-cert-expire");
2754       if (!err)
2755         err = add_arg (gpg, tmpbuf);
2756     }
2757
2758   if (!err)
2759     err = add_arg (gpg, "--");
2760
2761   if (!err)
2762     err = add_arg (gpg, key->fpr);
2763   if (!err && userid)
2764     {
2765       if ((flags & GPGME_KEYSIGN_LFSEP))
2766         {
2767           for (; !err && (s = strchr (userid, '\n')); userid = s + 1)
2768             if ((s - userid))
2769               err = add_arg_len (gpg, "=", userid, s - userid);
2770           if (!err && *userid)
2771             err = add_arg_pfx (gpg, "=", userid);
2772         }
2773       else
2774         err = add_arg_pfx (gpg, "=", userid);
2775     }
2776
2777   if (!err)
2778     err = start (gpg);
2779
2780   return err;
2781 }
2782
2783
2784 static gpgme_error_t
2785 gpg_tofu_policy (void *engine, gpgme_key_t key, gpgme_tofu_policy_t policy)
2786 {
2787   engine_gpg_t gpg = engine;
2788   gpgme_error_t err;
2789   const char *policystr = NULL;
2790
2791   if (!key || !key->fpr)
2792     return gpg_error (GPG_ERR_INV_ARG);
2793
2794   switch (policy)
2795     {
2796     case GPGME_TOFU_POLICY_NONE:                           break;
2797     case GPGME_TOFU_POLICY_AUTO:    policystr = "auto";    break;
2798     case GPGME_TOFU_POLICY_GOOD:    policystr = "good";    break;
2799     case GPGME_TOFU_POLICY_BAD:     policystr = "bad";     break;
2800     case GPGME_TOFU_POLICY_ASK:     policystr = "ask";     break;
2801     case GPGME_TOFU_POLICY_UNKNOWN: policystr = "unknown"; break;
2802     }
2803   if (!policystr)
2804     return gpg_error (GPG_ERR_INV_VALUE);
2805
2806   if (!have_gpg_version (gpg, "2.1.10"))
2807     return gpg_error (GPG_ERR_NOT_SUPPORTED);
2808
2809   err = add_arg (gpg, "--tofu-policy");
2810   if (!err)
2811     err = add_arg (gpg, "--");
2812   if (!err)
2813     err = add_arg (gpg, policystr);
2814   if (!err)
2815     err = add_arg (gpg, key->fpr);
2816
2817   if (!err)
2818     err = start (gpg);
2819
2820   return err;
2821 }
2822
2823
2824 static gpgme_error_t
2825 gpg_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
2826           gpgme_sig_mode_t mode, int use_armor, int use_textmode,
2827           int include_certs, gpgme_ctx_t ctx /* FIXME */)
2828 {
2829   engine_gpg_t gpg = engine;
2830   gpgme_error_t err;
2831
2832   (void)include_certs;
2833
2834   if (mode == GPGME_SIG_MODE_CLEAR)
2835     err = add_arg (gpg, "--clearsign");
2836   else
2837     {
2838       err = add_arg (gpg, "--sign");
2839       if (!err && mode == GPGME_SIG_MODE_DETACH)
2840         err = add_arg (gpg, "--detach");
2841       if (!err && use_armor)
2842         err = add_arg (gpg, "--armor");
2843       if (!err)
2844         {
2845           if (gpgme_data_get_encoding (in) == GPGME_DATA_ENCODING_MIME
2846               && have_gpg_version (gpg, "2.1.14"))
2847             err = add_arg (gpg, "--mimemode");
2848           else if (use_textmode)
2849             err = add_arg (gpg, "--textmode");
2850         }
2851     }
2852
2853   if (!err)
2854     err = append_args_from_signers (gpg, ctx);
2855   if (!err)
2856     err = append_args_from_sender (gpg, ctx);
2857   if (!err)
2858     err = append_args_from_sig_notations (gpg, ctx);
2859
2860   if (gpgme_data_get_file_name (in))
2861     {
2862       if (!err)
2863         err = add_arg (gpg, "--set-filename");
2864       if (!err)
2865         err = add_arg (gpg, gpgme_data_get_file_name (in));
2866     }
2867
2868   /* Tell the gpg object about the data.  */
2869   if (!err)
2870     err = add_input_size_hint (gpg, in);
2871   if (!err)
2872     err = add_arg (gpg, "--");
2873   if (!err)
2874     err = add_data (gpg, in, -1, 0);
2875   if (!err)
2876     err = add_data (gpg, out, 1, 1);
2877
2878   if (!err)
2879     err = start (gpg);
2880
2881   return err;
2882 }
2883
2884 static gpgme_error_t
2885 gpg_trustlist (void *engine, const char *pattern)
2886 {
2887   engine_gpg_t gpg = engine;
2888   gpgme_error_t err;
2889
2890   err = add_arg (gpg, "--with-colons");
2891   if (!err)
2892     err = add_arg (gpg, "--list-trust-path");
2893
2894   /* Tell the gpg object about the data.  */
2895   if (!err)
2896     err = add_arg (gpg, "--");
2897   if (!err)
2898     err = add_arg (gpg, pattern);
2899
2900   if (!err)
2901     err = start (gpg);
2902
2903   return err;
2904 }
2905
2906
2907 static gpgme_error_t
2908 gpg_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
2909             gpgme_data_t plaintext, gpgme_ctx_t ctx)
2910 {
2911   engine_gpg_t gpg = engine;
2912   gpgme_error_t err;
2913
2914   err = append_args_from_sender (gpg, ctx);
2915   if (err)
2916     ;
2917   else if (plaintext)
2918     {
2919       /* Normal or cleartext signature.  */
2920       err = add_arg (gpg, "--output");
2921       if (!err)
2922         err = add_arg (gpg, "-");
2923       if (!err)
2924         err = add_input_size_hint (gpg, sig);
2925       if (!err)
2926         err = add_arg (gpg, "--");
2927       if (!err)
2928         err = add_data (gpg, sig, -1, 0);
2929       if (!err)
2930         err = add_data (gpg, plaintext, 1, 1);
2931     }
2932   else
2933     {
2934       err = add_arg (gpg, "--verify");
2935       if (!err)
2936         err = add_input_size_hint (gpg, signed_text);
2937       if (!err)
2938         err = add_arg (gpg, "--");
2939       if (!err)
2940         err = add_data (gpg, sig, -1, 0);
2941       if (!err && signed_text)
2942         err = add_data (gpg, signed_text, -1, 0);
2943     }
2944
2945   if (!err)
2946     err = start (gpg);
2947
2948   return err;
2949 }
2950
2951
2952 static void
2953 gpg_set_io_cbs (void *engine, gpgme_io_cbs_t io_cbs)
2954 {
2955   engine_gpg_t gpg = engine;
2956
2957   gpg->io_cbs = *io_cbs;
2958 }
2959
2960
2961 static gpgme_error_t
2962 gpg_set_pinentry_mode (void *engine, gpgme_pinentry_mode_t mode)
2963 {
2964   engine_gpg_t gpg = engine;
2965
2966   gpg->pinentry_mode = mode;
2967   return 0;
2968 }
2969
2970
2971 \f
2972 struct engine_ops _gpgme_engine_ops_gpg =
2973   {
2974     /* Static functions.  */
2975     _gpgme_get_default_gpg_name,
2976     NULL,
2977     gpg_get_version,
2978     gpg_get_req_version,
2979     gpg_new,
2980
2981     /* Member functions.  */
2982     gpg_release,
2983     NULL,                               /* reset */
2984     gpg_set_status_cb,
2985     gpg_set_status_handler,
2986     gpg_set_command_handler,
2987     gpg_set_colon_line_handler,
2988     gpg_set_locale,
2989     NULL,                               /* set_protocol */
2990     gpg_decrypt,
2991     gpg_decrypt,                        /* decrypt_verify */
2992     gpg_delete,
2993     gpg_edit,
2994     gpg_encrypt,
2995     gpg_encrypt_sign,
2996     gpg_export,
2997     gpg_export_ext,
2998     gpg_genkey,
2999     gpg_import,
3000     gpg_keylist,
3001     gpg_keylist_ext,
3002     gpg_keysign,
3003     gpg_tofu_policy,    /* tofu_policy */
3004     gpg_sign,
3005     gpg_trustlist,
3006     gpg_verify,
3007     NULL,               /* getauditlog */
3008     NULL,               /* opassuan_transact */
3009     NULL,               /* conf_load */
3010     NULL,               /* conf_save */
3011     NULL,               /* query_swdb */
3012     gpg_set_io_cbs,
3013     gpg_io_event,
3014     gpg_cancel,
3015     NULL,               /* cancel_op */
3016     gpg_passwd,
3017     gpg_set_pinentry_mode,
3018     NULL                /* opspawn */
3019   };