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