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