core: Minor change of the gpgme_op_edit semantics.
[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           if (gpg_err_code (err) == GPG_ERR_FALSE)
1106             err = 0; /* Drop special error code.  */
1107         }
1108
1109       return err;
1110     }
1111
1112   while (nread > 0)
1113     {
1114       for (p = buffer + readpos; nread; nread--, p++)
1115         {
1116           if (*p == '\n')
1117             {
1118               /* (we require that the last line is terminated by a LF) */
1119               if (p > buffer && p[-1] == '\r')
1120                 p[-1] = 0;
1121               *p = 0;
1122               if (!strncmp (buffer, "[GNUPG:] ", 9)
1123                   && buffer[9] >= 'A' && buffer[9] <= 'Z')
1124                 {
1125                   char *rest;
1126                   gpgme_status_code_t r;
1127
1128                   rest = strchr (buffer + 9, ' ');
1129                   if (!rest)
1130                     rest = p; /* Set to an empty string.  */
1131                   else
1132                     *rest++ = 0;
1133
1134                   r = _gpgme_parse_status (buffer + 9);
1135                   if (gpg->status.mon_cb && r != GPGME_STATUS_PROGRESS)
1136                     {
1137                       /* Note that we call the monitor even if we do
1138                        * not know the status code (r < 0).  */
1139                       err = gpg->status.mon_cb (gpg->status.mon_cb_value,
1140                                                 buffer + 9, rest);
1141                       if (err)
1142                         return err;
1143                     }
1144                   if (r >= 0)
1145                     {
1146                       if (gpg->cmd.used
1147                           && (r == GPGME_STATUS_GET_BOOL
1148                               || r == GPGME_STATUS_GET_LINE
1149                               || r == GPGME_STATUS_GET_HIDDEN))
1150                         {
1151                           gpg->cmd.code = r;
1152                           if (gpg->cmd.keyword)
1153                             free (gpg->cmd.keyword);
1154                           gpg->cmd.keyword = strdup (rest);
1155                           if (!gpg->cmd.keyword)
1156                             return gpg_error_from_syserror ();
1157                           /* This should be the last thing we have
1158                              received and the next thing will be that
1159                              the command handler does its action.  */
1160                           if (nread > 1)
1161                             TRACE0 (DEBUG_CTX, "gpgme:read_status", 0,
1162                                     "error: unexpected data");
1163
1164                           add_io_cb (gpg, gpg->cmd.fd, 0,
1165                                      command_handler, gpg,
1166                                      &gpg->fd_data_map[gpg->cmd.idx].tag);
1167                           gpg->fd_data_map[gpg->cmd.idx].fd = gpg->cmd.fd;
1168                           gpg->cmd.fd = -1;
1169                         }
1170                       else if (gpg->status.fnc)
1171                         {
1172                           err = gpg->status.fnc (gpg->status.fnc_value,
1173                                                  r, rest);
1174                           if (gpg_err_code (err) == GPG_ERR_FALSE)
1175                             err = 0; /* Drop special error code.  */
1176                           if (err)
1177                             return err;
1178                         }
1179
1180                       if (r == GPGME_STATUS_END_STREAM)
1181                         {
1182                           if (gpg->cmd.used)
1183                             {
1184                               /* Before we can actually add the
1185                                  command fd, we might have to flush
1186                                  the linked output data pipe.  */
1187                               if (gpg->cmd.linked_idx != -1
1188                                   && gpg->fd_data_map[gpg->cmd.linked_idx].fd
1189                                   != -1)
1190                                 {
1191                                   struct io_select_fd_s fds;
1192                                   fds.fd =
1193                                     gpg->fd_data_map[gpg->cmd.linked_idx].fd;
1194                                   fds.for_read = 1;
1195                                   fds.for_write = 0;
1196                                   fds.opaque = NULL;
1197                                   do
1198                                     {
1199                                       fds.signaled = 0;
1200                                       _gpgme_io_select (&fds, 1, 1);
1201                                       if (fds.signaled)
1202                                         _gpgme_data_inbound_handler
1203                                           (gpg->cmd.linked_data, fds.fd);
1204                                     }
1205                                   while (fds.signaled);
1206                                 }
1207
1208                               /* XXX We must check if there are any
1209                                  more fds active after removing this
1210                                  one.  */
1211                               (*gpg->io_cbs.remove)
1212                                 (gpg->fd_data_map[gpg->cmd.idx].tag);
1213                               gpg->cmd.fd = gpg->fd_data_map[gpg->cmd.idx].fd;
1214                               gpg->fd_data_map[gpg->cmd.idx].fd = -1;
1215                             }
1216                         }
1217                     }
1218                 }
1219               /* To reuse the buffer for the next line we have to
1220                  shift the remaining data to the buffer start and
1221                  restart the loop Hmmm: We can optimize this function
1222                  by looking forward in the buffer to see whether a
1223                  second complete line is available and in this case
1224                  avoid the memmove for this line.  */
1225               nread--; p++;
1226               if (nread)
1227                 memmove (buffer, p, nread);
1228               readpos = 0;
1229               break; /* the for loop */
1230             }
1231           else
1232             readpos++;
1233         }
1234     }
1235
1236   /* Update the gpg object.  */
1237   gpg->status.bufsize = bufsize;
1238   gpg->status.buffer = buffer;
1239   gpg->status.readpos = readpos;
1240   return 0;
1241 }
1242
1243
1244 static gpgme_error_t
1245 status_handler (void *opaque, int fd)
1246 {
1247   struct io_cb_data *data = (struct io_cb_data *) opaque;
1248   engine_gpg_t gpg = (engine_gpg_t) data->handler_value;
1249   int err;
1250
1251   assert (fd == gpg->status.fd[0]);
1252   err = read_status (gpg);
1253   if (err)
1254     return err;
1255   if (gpg->status.eof)
1256     _gpgme_io_close (fd);
1257   return 0;
1258 }
1259
1260
1261 static gpgme_error_t
1262 read_colon_line (engine_gpg_t gpg)
1263 {
1264   char *p;
1265   int nread;
1266   size_t bufsize = gpg->colon.bufsize;
1267   char *buffer = gpg->colon.buffer;
1268   size_t readpos = gpg->colon.readpos;
1269
1270   assert (buffer);
1271   if (bufsize - readpos < 256)
1272     {
1273       /* Need more room for the read.  */
1274       bufsize += 1024;
1275       buffer = realloc (buffer, bufsize);
1276       if (!buffer)
1277         return gpg_error_from_syserror ();
1278     }
1279
1280   nread = _gpgme_io_read (gpg->colon.fd[0], buffer+readpos, bufsize-readpos);
1281   if (nread == -1)
1282     return gpg_error_from_syserror ();
1283
1284   if (!nread)
1285     {
1286       gpg->colon.eof = 1;
1287       assert (gpg->colon.fnc);
1288       gpg->colon.fnc (gpg->colon.fnc_value, NULL);
1289       return 0;
1290     }
1291
1292   while (nread > 0)
1293     {
1294       for (p = buffer + readpos; nread; nread--, p++)
1295         {
1296           if ( *p == '\n' )
1297             {
1298               /* (we require that the last line is terminated by a LF)
1299                  and we skip empty lines.  Note: we use UTF8 encoding
1300                  and escaping of special characters.  We require at
1301                  least one colon to cope with some other printed
1302                  information.  */
1303               *p = 0;
1304               if (*buffer && strchr (buffer, ':'))
1305                 {
1306                   char *line = NULL;
1307
1308                   if (gpg->colon.preprocess_fnc)
1309                     {
1310                       gpgme_error_t err;
1311
1312                       err = gpg->colon.preprocess_fnc (buffer, &line);
1313                       if (err)
1314                         return err;
1315                     }
1316
1317                   assert (gpg->colon.fnc);
1318                   if (line)
1319                     {
1320                       char *linep = line;
1321                       char *endp;
1322
1323                       do
1324                         {
1325                           endp = strchr (linep, '\n');
1326                           if (endp)
1327                             *endp++ = 0;
1328                           gpg->colon.fnc (gpg->colon.fnc_value, linep);
1329                           linep = endp;
1330                         }
1331                       while (linep && *linep);
1332
1333                       free (line);
1334                     }
1335                   else
1336                     gpg->colon.fnc (gpg->colon.fnc_value, buffer);
1337                 }
1338
1339               /* To reuse the buffer for the next line we have to
1340                  shift the remaining data to the buffer start and
1341                  restart the loop Hmmm: We can optimize this function
1342                  by looking forward in the buffer to see whether a
1343                  second complete line is available and in this case
1344                  avoid the memmove for this line.  */
1345               nread--; p++;
1346               if (nread)
1347                 memmove (buffer, p, nread);
1348               readpos = 0;
1349               break; /* The for loop.  */
1350             }
1351           else
1352             readpos++;
1353         }
1354     }
1355
1356   /* Update the gpg object.  */
1357   gpg->colon.bufsize = bufsize;
1358   gpg->colon.buffer  = buffer;
1359   gpg->colon.readpos = readpos;
1360   return 0;
1361 }
1362
1363
1364 /* This colonline handler thing is not the clean way to do it.  It
1365    might be better to enhance the gpgme_data_t object to act as a wrapper
1366    for a callback.  Same goes for the status thing.  For now we use
1367    this thing here because it is easier to implement.  */
1368 static gpgme_error_t
1369 colon_line_handler (void *opaque, int fd)
1370 {
1371   struct io_cb_data *data = (struct io_cb_data *) opaque;
1372   engine_gpg_t gpg = (engine_gpg_t) data->handler_value;
1373   gpgme_error_t rc = 0;
1374
1375   assert (fd == gpg->colon.fd[0]);
1376   rc = read_colon_line (gpg);
1377   if (rc)
1378     return rc;
1379   if (gpg->colon.eof)
1380     _gpgme_io_close (fd);
1381   return 0;
1382 }
1383
1384
1385 static gpgme_error_t
1386 start (engine_gpg_t gpg)
1387 {
1388   gpgme_error_t rc;
1389   int i, n;
1390   int status;
1391   struct spawn_fd_item_s *fd_list;
1392   pid_t pid;
1393   const char *pgmname;
1394
1395   if (!gpg)
1396     return gpg_error (GPG_ERR_INV_VALUE);
1397
1398   if (!gpg->file_name && !_gpgme_get_default_gpg_name ())
1399     return trace_gpg_error (GPG_ERR_INV_ENGINE);
1400
1401   if (gpg->lc_ctype)
1402     {
1403       rc = add_arg_ext (gpg, gpg->lc_ctype, 1);
1404       if (!rc)
1405         rc = add_arg_ext (gpg, "--lc-ctype", 1);
1406       if (rc)
1407         return rc;
1408     }
1409
1410   if (gpg->lc_messages)
1411     {
1412       rc = add_arg_ext (gpg, gpg->lc_messages, 1);
1413       if (!rc)
1414         rc = add_arg_ext (gpg, "--lc-messages", 1);
1415       if (rc)
1416         return rc;
1417     }
1418
1419   pgmname = gpg->file_name ? gpg->file_name : _gpgme_get_default_gpg_name ();
1420   rc = build_argv (gpg, pgmname);
1421   if (rc)
1422     return rc;
1423
1424   /* status_fd, colon_fd and end of list.  */
1425   n = 3;
1426   for (i = 0; gpg->fd_data_map[i].data; i++)
1427     n++;
1428   fd_list = calloc (n, sizeof *fd_list);
1429   if (! fd_list)
1430     return gpg_error_from_syserror ();
1431
1432   /* Build the fd list for the child.  */
1433   n = 0;
1434   fd_list[n].fd = gpg->status.fd[1];
1435   fd_list[n].dup_to = -1;
1436   fd_list[n].arg_loc = gpg->status.arg_loc;
1437   n++;
1438   if (gpg->colon.fnc)
1439     {
1440       fd_list[n].fd = gpg->colon.fd[1];
1441       fd_list[n].dup_to = 1;
1442       n++;
1443     }
1444   for (i = 0; gpg->fd_data_map[i].data; i++)
1445     {
1446       fd_list[n].fd = gpg->fd_data_map[i].peer_fd;
1447       fd_list[n].dup_to = gpg->fd_data_map[i].dup_to;
1448       fd_list[n].arg_loc = gpg->fd_data_map[i].arg_loc;
1449       n++;
1450     }
1451   fd_list[n].fd = -1;
1452   fd_list[n].dup_to = -1;
1453
1454   status = _gpgme_io_spawn (pgmname, gpg->argv,
1455                             (IOSPAWN_FLAG_DETACHED |IOSPAWN_FLAG_ALLOW_SET_FG),
1456                             fd_list, NULL, NULL, &pid);
1457   {
1458     int saved_err = gpg_error_from_syserror ();
1459     free (fd_list);
1460     if (status == -1)
1461       return saved_err;
1462   }
1463
1464   /*_gpgme_register_term_handler ( closure, closure_value, pid );*/
1465
1466   rc = add_io_cb (gpg, gpg->status.fd[0], 1, status_handler, gpg,
1467                   &gpg->status.tag);
1468   if (rc)
1469     /* FIXME: kill the child */
1470     return rc;
1471
1472   if (gpg->colon.fnc)
1473     {
1474       assert (gpg->colon.fd[0] != -1);
1475       rc = add_io_cb (gpg, gpg->colon.fd[0], 1, colon_line_handler, gpg,
1476                       &gpg->colon.tag);
1477       if (rc)
1478         /* FIXME: kill the child */
1479         return rc;
1480     }
1481
1482   for (i = 0; gpg->fd_data_map[i].data; i++)
1483     {
1484       if (gpg->cmd.used && i == gpg->cmd.idx)
1485         {
1486           /* Park the cmd fd.  */
1487           gpg->cmd.fd = gpg->fd_data_map[i].fd;
1488           gpg->fd_data_map[i].fd = -1;
1489         }
1490       else
1491         {
1492           rc = add_io_cb (gpg, gpg->fd_data_map[i].fd,
1493                           gpg->fd_data_map[i].inbound,
1494                           gpg->fd_data_map[i].inbound
1495                           ? _gpgme_data_inbound_handler
1496                           : _gpgme_data_outbound_handler,
1497                           gpg->fd_data_map[i].data, &gpg->fd_data_map[i].tag);
1498
1499           if (rc)
1500             /* FIXME: kill the child */
1501             return rc;
1502         }
1503     }
1504
1505   gpg_io_event (gpg, GPGME_EVENT_START, NULL);
1506
1507   /* fixme: check what data we can release here */
1508   return 0;
1509 }
1510
1511
1512 /* Add the --input-size-hint option if requested.  */
1513 static gpgme_error_t
1514 add_input_size_hint (engine_gpg_t gpg, gpgme_data_t data)
1515 {
1516   gpgme_error_t err;
1517   gpgme_off_t value = _gpgme_data_get_size_hint (data);
1518   char numbuf[50];  /* Large enough for even 2^128 in base-10.  */
1519   char *p;
1520
1521   if (!value || !have_gpg_version (gpg, "2.1.15"))
1522     return 0;
1523
1524   err = add_arg (gpg, "--input-size-hint");
1525   if (!err)
1526     {
1527       p = numbuf + sizeof numbuf;
1528       *--p = 0;
1529       do
1530         {
1531           *--p = '0' + (value % 10);
1532           value /= 10;
1533         }
1534       while (value);
1535       err = add_arg (gpg, p);
1536     }
1537   return err;
1538 }
1539
1540
1541 static gpgme_error_t
1542 gpg_decrypt (void *engine, gpgme_data_t ciph, gpgme_data_t plain)
1543 {
1544   engine_gpg_t gpg = engine;
1545   gpgme_error_t err;
1546
1547   err = add_arg (gpg, "--decrypt");
1548
1549   /* Tell the gpg object about the data.  */
1550   if (!err)
1551     err = add_arg (gpg, "--output");
1552   if (!err)
1553     err = add_arg (gpg, "-");
1554   if (!err)
1555     err = add_data (gpg, plain, 1, 1);
1556   if (!err)
1557     err = add_input_size_hint (gpg, ciph);
1558   if (!err)
1559     err = add_arg (gpg, "--");
1560   if (!err)
1561     err = add_data (gpg, ciph, -1, 0);
1562
1563   if (!err)
1564     err = start (gpg);
1565   return err;
1566 }
1567
1568 static gpgme_error_t
1569 gpg_delete (void *engine, gpgme_key_t key, int allow_secret)
1570 {
1571   engine_gpg_t gpg = engine;
1572   gpgme_error_t err;
1573
1574   err = add_arg (gpg, allow_secret ? "--delete-secret-and-public-key"
1575                  : "--delete-key");
1576   if (!err)
1577     err = add_arg (gpg, "--");
1578   if (!err)
1579     {
1580       if (!key->subkeys || !key->subkeys->fpr)
1581         return gpg_error (GPG_ERR_INV_VALUE);
1582       else
1583         err = add_arg (gpg, key->subkeys->fpr);
1584     }
1585
1586   if (!err)
1587     err = start (gpg);
1588   return err;
1589 }
1590
1591
1592 static gpgme_error_t
1593 gpg_passwd (void *engine, gpgme_key_t key, unsigned int flags)
1594 {
1595   engine_gpg_t gpg = engine;
1596   gpgme_error_t err;
1597
1598   (void)flags;
1599
1600   if (!key || !key->subkeys || !key->subkeys->fpr)
1601     return gpg_error (GPG_ERR_INV_CERT_OBJ);
1602
1603   err = add_arg (gpg, "--passwd");
1604   if (!err)
1605     err = add_arg (gpg, key->subkeys->fpr);
1606   if (!err)
1607     err = start (gpg);
1608   return err;
1609 }
1610
1611
1612 static gpgme_error_t
1613 append_args_from_signers (engine_gpg_t gpg, gpgme_ctx_t ctx /* FIXME */)
1614 {
1615   gpgme_error_t err = 0;
1616   int i;
1617   gpgme_key_t key;
1618
1619   for (i = 0; (key = gpgme_signers_enum (ctx, i)); i++)
1620     {
1621       const char *s = key->subkeys ? key->subkeys->keyid : NULL;
1622       if (s)
1623         {
1624           if (!err)
1625             err = add_arg (gpg, "-u");
1626           if (!err)
1627             err = add_arg (gpg, s);
1628         }
1629       gpgme_key_unref (key);
1630       if (err)
1631         break;
1632     }
1633   return err;
1634 }
1635
1636
1637 static gpgme_error_t
1638 append_args_from_sig_notations (engine_gpg_t gpg, gpgme_ctx_t ctx /* FIXME */)
1639 {
1640   gpgme_error_t err = 0;
1641   gpgme_sig_notation_t notation;
1642
1643   notation = gpgme_sig_notation_get (ctx);
1644
1645   while (!err && notation)
1646     {
1647       if (notation->name
1648           && !(notation->flags & GPGME_SIG_NOTATION_HUMAN_READABLE))
1649         err = gpg_error (GPG_ERR_INV_VALUE);
1650       else if (notation->name)
1651         {
1652           char *arg;
1653
1654           /* Maximum space needed is one byte for the "critical" flag,
1655              the name, one byte for '=', the value, and a terminating
1656              '\0'.  */
1657
1658           arg = malloc (1 + notation->name_len + 1 + notation->value_len + 1);
1659           if (!arg)
1660             err = gpg_error_from_syserror ();
1661
1662           if (!err)
1663             {
1664               char *argp = arg;
1665
1666               if (notation->critical)
1667                 *(argp++) = '!';
1668
1669               memcpy (argp, notation->name, notation->name_len);
1670               argp += notation->name_len;
1671
1672               *(argp++) = '=';
1673
1674               /* We know that notation->name is '\0' terminated.  */
1675               strcpy (argp, notation->value);
1676             }
1677
1678           if (!err)
1679             err = add_arg (gpg, "--sig-notation");
1680           if (!err)
1681             err = add_arg (gpg, arg);
1682
1683           if (arg)
1684             free (arg);
1685         }
1686       else
1687         {
1688           /* This is a policy URL.  */
1689
1690           char *value;
1691
1692           if (notation->critical)
1693             {
1694               value = malloc (1 + notation->value_len + 1);
1695               if (!value)
1696                 err = gpg_error_from_syserror ();
1697               else
1698                 {
1699                   value[0] = '!';
1700                   /* We know that notation->value is '\0' terminated.  */
1701                   strcpy (&value[1], notation->value);
1702                 }
1703             }
1704           else
1705             value = notation->value;
1706
1707           if (!err)
1708             err = add_arg (gpg, "--sig-policy-url");
1709           if (!err)
1710             err = add_arg (gpg, value);
1711
1712           if (value != notation->value)
1713             free (value);
1714         }
1715
1716       notation = notation->next;
1717     }
1718   return err;
1719 }
1720
1721
1722 static gpgme_error_t
1723 gpg_edit (void *engine, int type, gpgme_key_t key, gpgme_data_t out,
1724           gpgme_ctx_t ctx /* FIXME */)
1725 {
1726   engine_gpg_t gpg = engine;
1727   gpgme_error_t err;
1728
1729   err = add_arg (gpg, "--with-colons");
1730   if (!err)
1731     err = append_args_from_signers (gpg, ctx);
1732   if (!err)
1733   err = add_arg (gpg, type == 0 ? "--edit-key" : "--card-edit");
1734   if (!err)
1735     err = add_data (gpg, out, 1, 1);
1736   if (!err)
1737     err = add_arg (gpg, "--");
1738   if (!err && type == 0)
1739     {
1740       const char *s = key->subkeys ? key->subkeys->fpr : NULL;
1741       if (!s)
1742         err = gpg_error (GPG_ERR_INV_VALUE);
1743       else
1744         err = add_arg (gpg, s);
1745     }
1746   if (!err)
1747     err = start (gpg);
1748
1749   return err;
1750 }
1751
1752
1753 static gpgme_error_t
1754 append_args_from_recipients (engine_gpg_t gpg, gpgme_key_t recp[])
1755 {
1756   gpgme_error_t err = 0;
1757   int i = 0;
1758
1759   while (recp[i])
1760     {
1761       if (!recp[i]->subkeys || !recp[i]->subkeys->fpr)
1762         err = gpg_error (GPG_ERR_INV_VALUE);
1763       if (!err)
1764         err = add_arg (gpg, "-r");
1765       if (!err)
1766         err = add_arg (gpg, recp[i]->subkeys->fpr);
1767       if (err)
1768         break;
1769       i++;
1770     }
1771   return err;
1772 }
1773
1774
1775 static gpgme_error_t
1776 gpg_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
1777              gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
1778 {
1779   engine_gpg_t gpg = engine;
1780   gpgme_error_t err = 0;
1781
1782   if (recp)
1783     err = add_arg (gpg, "--encrypt");
1784
1785   if (!err && ((flags & GPGME_ENCRYPT_SYMMETRIC) || !recp))
1786     err = add_arg (gpg, "--symmetric");
1787
1788   if (!err && use_armor)
1789     err = add_arg (gpg, "--armor");
1790
1791   if (!err && (flags & GPGME_ENCRYPT_NO_COMPRESS))
1792     err = add_arg (gpg, "--compress-algo=none");
1793
1794   if (gpgme_data_get_encoding (plain) == GPGME_DATA_ENCODING_MIME
1795       && have_gpg_version (gpg, "2.1.14"))
1796     err = add_arg (gpg, "--mimemode");
1797
1798   if (recp)
1799     {
1800       /* If we know that all recipients are valid (full or ultimate trust)
1801          we can suppress further checks.  */
1802       if (!err && (flags & GPGME_ENCRYPT_ALWAYS_TRUST))
1803         err = add_arg (gpg, "--always-trust");
1804
1805       if (!err && (flags & GPGME_ENCRYPT_NO_ENCRYPT_TO))
1806         err = add_arg (gpg, "--no-encrypt-to");
1807
1808       if (!err)
1809         err = append_args_from_recipients (gpg, recp);
1810     }
1811
1812   /* Tell the gpg object about the data.  */
1813   if (!err)
1814     err = add_arg (gpg, "--output");
1815   if (!err)
1816     err = add_arg (gpg, "-");
1817   if (!err)
1818     err = add_data (gpg, ciph, 1, 1);
1819   if (gpgme_data_get_file_name (plain))
1820     {
1821       if (!err)
1822         err = add_arg (gpg, "--set-filename");
1823       if (!err)
1824         err = add_arg (gpg, gpgme_data_get_file_name (plain));
1825     }
1826   if (!err)
1827     err = add_input_size_hint (gpg, plain);
1828   if (!err)
1829     err = add_arg (gpg, "--");
1830   if (!err)
1831     err = add_data (gpg, plain, -1, 0);
1832
1833   if (!err)
1834     err = start (gpg);
1835
1836   return err;
1837 }
1838
1839
1840 static gpgme_error_t
1841 gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
1842                   gpgme_encrypt_flags_t flags, gpgme_data_t plain,
1843                   gpgme_data_t ciph, int use_armor,
1844                   gpgme_ctx_t ctx /* FIXME */)
1845 {
1846   engine_gpg_t gpg = engine;
1847   gpgme_error_t err = 0;
1848
1849   if (recp)
1850     err = add_arg (gpg, "--encrypt");
1851
1852   if (!err && ((flags & GPGME_ENCRYPT_SYMMETRIC) || !recp))
1853     err = add_arg (gpg, "--symmetric");
1854
1855   if (!err)
1856     err = add_arg (gpg, "--sign");
1857   if (!err && use_armor)
1858     err = add_arg (gpg, "--armor");
1859
1860   if (!err && (flags & GPGME_ENCRYPT_NO_COMPRESS))
1861     err = add_arg (gpg, "--compress-algo=none");
1862
1863   if (gpgme_data_get_encoding (plain) == GPGME_DATA_ENCODING_MIME
1864       && have_gpg_version (gpg, "2.1.14"))
1865     err = add_arg (gpg, "--mimemode");
1866
1867   if (recp)
1868     {
1869       /* If we know that all recipients are valid (full or ultimate trust)
1870          we can suppress further checks.  */
1871       if (!err && (flags & GPGME_ENCRYPT_ALWAYS_TRUST))
1872         err = add_arg (gpg, "--always-trust");
1873
1874       if (!err && (flags & GPGME_ENCRYPT_NO_ENCRYPT_TO))
1875         err = add_arg (gpg, "--no-encrypt-to");
1876
1877       if (!err)
1878         err = append_args_from_recipients (gpg, recp);
1879     }
1880
1881   if (!err)
1882     err = append_args_from_signers (gpg, ctx);
1883
1884   if (!err)
1885     err = append_args_from_sig_notations (gpg, ctx);
1886
1887   /* Tell the gpg object about the data.  */
1888   if (!err)
1889     err = add_arg (gpg, "--output");
1890   if (!err)
1891     err = add_arg (gpg, "-");
1892   if (!err)
1893     err = add_data (gpg, ciph, 1, 1);
1894   if (gpgme_data_get_file_name (plain))
1895     {
1896       if (!err)
1897         err = add_arg (gpg, "--set-filename");
1898       if (!err)
1899         err = add_arg (gpg, gpgme_data_get_file_name (plain));
1900     }
1901   if (!err)
1902     err = add_input_size_hint (gpg, plain);
1903   if (!err)
1904     err = add_arg (gpg, "--");
1905   if (!err)
1906     err = add_data (gpg, plain, -1, 0);
1907
1908   if (!err)
1909     err = start (gpg);
1910
1911   return err;
1912 }
1913
1914
1915 static gpgme_error_t
1916 export_common (engine_gpg_t gpg, gpgme_export_mode_t mode,
1917                gpgme_data_t keydata, int use_armor)
1918 {
1919   gpgme_error_t err = 0;
1920
1921   if ((mode & ~(GPGME_EXPORT_MODE_EXTERN
1922                 |GPGME_EXPORT_MODE_MINIMAL
1923                 |GPGME_EXPORT_MODE_SECRET)))
1924     return gpg_error (GPG_ERR_NOT_SUPPORTED);
1925
1926   if ((mode & GPGME_EXPORT_MODE_MINIMAL))
1927     err = add_arg (gpg, "--export-options=export-minimal");
1928
1929   if (err)
1930     ;
1931   else if ((mode & GPGME_EXPORT_MODE_EXTERN))
1932     {
1933       err = add_arg (gpg, "--send-keys");
1934     }
1935   else
1936     {
1937       if ((mode & GPGME_EXPORT_MODE_SECRET))
1938         err = add_arg (gpg, "--export-secret-keys");
1939       else
1940         err = add_arg (gpg, "--export");
1941       if (!err && use_armor)
1942         err = add_arg (gpg, "--armor");
1943       if (!err)
1944         err = add_data (gpg, keydata, 1, 1);
1945     }
1946   if (!err)
1947     err = add_arg (gpg, "--");
1948
1949   return err;
1950 }
1951
1952
1953 static gpgme_error_t
1954 gpg_export (void *engine, const char *pattern, gpgme_export_mode_t mode,
1955             gpgme_data_t keydata, int use_armor)
1956 {
1957   engine_gpg_t gpg = engine;
1958   gpgme_error_t err;
1959
1960   err = export_common (gpg, mode, keydata, use_armor);
1961
1962   if (!err && pattern && *pattern)
1963     err = add_arg (gpg, pattern);
1964
1965   if (!err)
1966     err = start (gpg);
1967
1968   return err;
1969 }
1970
1971
1972 static gpgme_error_t
1973 gpg_export_ext (void *engine, const char *pattern[], gpgme_export_mode_t mode,
1974                 gpgme_data_t keydata, int use_armor)
1975 {
1976   engine_gpg_t gpg = engine;
1977   gpgme_error_t err;
1978
1979   err = export_common (gpg, mode, keydata, use_armor);
1980
1981   if (pattern)
1982     {
1983       while (!err && *pattern && **pattern)
1984         err = add_arg (gpg, *(pattern++));
1985     }
1986
1987   if (!err)
1988     err = start (gpg);
1989
1990   return err;
1991 }
1992
1993
1994 \f
1995 /* Helper to add algo, usage, and expire to the list of args.  */
1996 static gpgme_error_t
1997 gpg_add_algo_usage_expire (engine_gpg_t gpg,
1998                            const char *algo,
1999                            unsigned long expires,
2000                            unsigned int flags)
2001 {
2002   gpg_error_t err;
2003
2004   /* This condition is only required to allow the use of gpg < 2.1.16 */
2005   if (algo
2006       || (flags & (GPGME_CREATE_SIGN | GPGME_CREATE_ENCR
2007                    | GPGME_CREATE_CERT | GPGME_CREATE_AUTH))
2008       || expires)
2009     {
2010       err = add_arg (gpg, algo? algo : "default");
2011       if (!err)
2012         {
2013           char tmpbuf[5*4+1];
2014           snprintf (tmpbuf, sizeof tmpbuf, "%s%s%s%s",
2015                     (flags & GPGME_CREATE_SIGN)? " sign":"",
2016                     (flags & GPGME_CREATE_ENCR)? " encr":"",
2017                     (flags & GPGME_CREATE_CERT)? " cert":"",
2018                     (flags & GPGME_CREATE_AUTH)? " auth":"");
2019           err = add_arg (gpg, *tmpbuf? tmpbuf : "default");
2020         }
2021       if (!err && expires)
2022         {
2023           char tmpbuf[8+20];
2024           snprintf (tmpbuf, sizeof tmpbuf, "seconds=%lu", expires);
2025           err = add_arg (gpg, tmpbuf);
2026         }
2027     }
2028   else
2029     err = 0;
2030
2031   return err;
2032 }
2033
2034
2035 static gpgme_error_t
2036 gpg_createkey_from_param (engine_gpg_t gpg,
2037                           gpgme_data_t help_data, unsigned int extraflags)
2038 {
2039   gpgme_error_t err;
2040
2041   err = add_arg (gpg, "--gen-key");
2042   if (!err && (extraflags & GENKEY_EXTRAFLAG_ARMOR))
2043     err = add_arg (gpg, "--armor");
2044   if (!err)
2045     err = add_arg (gpg, "--");
2046   if (!err)
2047     err = add_data (gpg, help_data, -1, 0);
2048   if (!err)
2049     err = start (gpg);
2050   return err;
2051 }
2052
2053
2054 /* This is used for gpg versions which do not support the quick-genkey
2055  * command to emulate the gpgme_op_createkey API.  */
2056 static gpgme_error_t
2057 gpg_createkey_legacy (engine_gpg_t gpg,
2058                const char *userid, const char *algo,
2059                unsigned long expires,
2060                unsigned int flags,
2061                unsigned int extraflags)
2062 {
2063   (void)gpg;
2064   (void)userid;
2065   (void)algo;
2066   (void)expires;
2067   (void)flags;
2068   (void)extraflags;
2069   return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
2070 }
2071
2072
2073 static gpgme_error_t
2074 gpg_createkey (engine_gpg_t gpg,
2075                const char *userid, const char *algo,
2076                unsigned long expires,
2077                unsigned int flags,
2078                unsigned int extraflags)
2079 {
2080   gpgme_error_t err;
2081
2082   err = add_arg (gpg, "--quick-gen-key");
2083   if (!err && (extraflags & GENKEY_EXTRAFLAG_ARMOR))
2084     err = add_arg (gpg, "--armor");
2085   if (!err && (flags & GPGME_CREATE_NOPASSWD))
2086     {
2087       err = add_arg (gpg, "--passphrase");
2088       if (!err)
2089         err = add_arg (gpg, "");
2090     }
2091   if (!err && (flags & GPGME_CREATE_FORCE))
2092     err = add_arg (gpg, "--yes");
2093   if (!err)
2094     err = add_arg (gpg, "--");
2095   if (!err)
2096     err = add_arg (gpg, userid);
2097
2098   if (!err)
2099     err = gpg_add_algo_usage_expire (gpg, algo, expires, flags);
2100
2101   if (!err)
2102     err = start (gpg);
2103   return err;
2104 }
2105
2106
2107 static gpgme_error_t
2108 gpg_addkey (engine_gpg_t gpg,
2109             const char *algo,
2110             unsigned long expires,
2111             gpgme_key_t key,
2112             unsigned int flags,
2113             unsigned int extraflags)
2114 {
2115   gpgme_error_t err;
2116
2117   if (!key || !key->fpr)
2118     return gpg_error (GPG_ERR_INV_ARG);
2119
2120   err = add_arg (gpg, "--quick-addkey");
2121   if (!err && (extraflags & GENKEY_EXTRAFLAG_ARMOR))
2122     err = add_arg (gpg, "--armor");
2123   if (!err && (flags & GPGME_CREATE_NOPASSWD))
2124     {
2125       err = add_arg (gpg, "--passphrase");
2126       if (!err)
2127         err = add_arg (gpg, "");
2128     }
2129   if (!err)
2130     err = add_arg (gpg, "--");
2131   if (!err)
2132     err = add_arg (gpg, key->fpr);
2133
2134   if (!err)
2135     err = gpg_add_algo_usage_expire (gpg, algo, expires, flags);
2136
2137   if (!err)
2138     err = start (gpg);
2139   return err;
2140 }
2141
2142
2143 static gpgme_error_t
2144 gpg_adduid (engine_gpg_t gpg,
2145             gpgme_key_t key,
2146             const char *userid,
2147             unsigned int extraflags)
2148 {
2149   gpgme_error_t err;
2150
2151   if (!key || !key->fpr || !userid)
2152     return gpg_error (GPG_ERR_INV_ARG);
2153
2154   if ((extraflags & GENKEY_EXTRAFLAG_REVOKE))
2155     err = add_arg (gpg, "--quick-revuid");
2156   else
2157     err = add_arg (gpg, "--quick-adduid");
2158
2159   if (!err)
2160     err = add_arg (gpg, "--");
2161   if (!err)
2162     err = add_arg (gpg, key->fpr);
2163   if (!err)
2164     err = add_arg (gpg, userid);
2165
2166   if (!err)
2167     err = start (gpg);
2168   return err;
2169 }
2170
2171
2172 static gpgme_error_t
2173 gpg_genkey (void *engine,
2174             const char *userid, const char *algo,
2175             unsigned long reserved, unsigned long expires,
2176             gpgme_key_t key, unsigned int flags,
2177             gpgme_data_t help_data, unsigned int extraflags,
2178             gpgme_data_t pubkey, gpgme_data_t seckey)
2179 {
2180   engine_gpg_t gpg = engine;
2181   gpgme_error_t err;
2182
2183   (void)reserved;
2184
2185   if (!gpg)
2186     return gpg_error (GPG_ERR_INV_VALUE);
2187
2188   /* If HELP_DATA is given the use of the old interface
2189    * (gpgme_op_genkey) has been requested.  The other modes are:
2190    *
2191    *  USERID && !KEY          - Create a new keyblock.
2192    * !USERID &&  KEY          - Add a new subkey to KEY (gpg >= 2.1.14)
2193    *  USERID &&  KEY && !ALGO - Add a new user id to KEY (gpg >= 2.1.14).
2194    *
2195    */
2196   if (help_data)
2197     {
2198       /* We need a special mechanism to get the fd of a pipe here, so
2199          that we can use this for the %pubring and %secring
2200          parameters.  We don't have this yet, so we implement only the
2201          adding to the standard keyrings.  */
2202       if (pubkey || seckey)
2203         err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
2204       else
2205         err = gpg_createkey_from_param (gpg, help_data, extraflags);
2206     }
2207   else if (userid && !key)
2208     {
2209       if (!have_gpg_version (gpg, "2.1.13"))
2210         err = gpg_createkey_legacy (gpg, userid, algo, expires, flags,
2211                                     extraflags);
2212       else
2213         err = gpg_createkey (gpg, userid, algo, expires, flags, extraflags);
2214     }
2215   else if (!have_gpg_version (gpg, "2.1.13"))
2216     err = gpg_error (GPG_ERR_NOT_SUPPORTED);
2217   else if (!userid && key)
2218     err = gpg_addkey (gpg, algo, expires, key, flags, extraflags);
2219   else if (userid && key && !algo)
2220     err = gpg_adduid (gpg, key, userid, extraflags);
2221   else
2222     err = gpg_error (GPG_ERR_INV_VALUE);
2223
2224   return err;
2225 }
2226
2227 /* Return the next DELIM delimited string from DATA as a C-string.
2228    The caller needs to provide the address of a pointer variable which
2229    he has to set to NULL before the first call.  After the last call
2230    to this function, this function needs to be called once more with
2231    DATA set to NULL so that the function can release its internal
2232    state.  After that the pointer variable is free for use again.
2233    Note that we use a delimiter and thus a trailing delimiter is not
2234    required.  DELIM may not be changed after the first call. */
2235 static const char *
2236 string_from_data (gpgme_data_t data, int delim,
2237                   void **helpptr, gpgme_error_t *r_err)
2238 {
2239 #define MYBUFLEN 2000 /* Fixme: We don't support URLs longer than that.  */
2240   struct {
2241     int  eof_seen;
2242     int  nbytes;      /* Length of the last returned string including
2243                          the delimiter. */
2244     int  buflen;      /* Valid length of BUF.  */
2245     char buf[MYBUFLEN+1];  /* Buffer with one byte extra space.  */
2246   } *self;
2247   char *p;
2248   int nread;
2249
2250   *r_err = 0;
2251   if (!data)
2252     {
2253       if (*helpptr)
2254         {
2255           free (*helpptr);
2256           *helpptr = NULL;
2257         }
2258       return NULL;
2259     }
2260
2261   if (*helpptr)
2262     self = *helpptr;
2263   else
2264     {
2265       self = malloc (sizeof *self);
2266       if (!self)
2267         {
2268           *r_err = gpg_error_from_syserror ();
2269           return NULL;
2270         }
2271       *helpptr = self;
2272       self->eof_seen = 0;
2273       self->nbytes = 0;
2274       self->buflen = 0;
2275     }
2276
2277   if (self->eof_seen)
2278     return NULL;
2279
2280   assert (self->nbytes <= self->buflen);
2281   memmove (self->buf, self->buf + self->nbytes, self->buflen - self->nbytes);
2282   self->buflen -= self->nbytes;
2283   self->nbytes = 0;
2284
2285   do
2286     {
2287       /* Fixme: This is fairly infective scanning because we may scan
2288          the buffer several times.  */
2289       p = memchr (self->buf, delim, self->buflen);
2290       if (p)
2291         {
2292           *p = 0;
2293           self->nbytes = p - self->buf + 1;
2294           return self->buf;
2295         }
2296
2297       if ( !(MYBUFLEN - self->buflen) )
2298         {
2299           /* Not enough space - URL too long.  */
2300           *r_err = gpg_error (GPG_ERR_TOO_LARGE);
2301           return NULL;
2302         }
2303
2304       nread = gpgme_data_read (data, self->buf + self->buflen,
2305                                MYBUFLEN - self->buflen);
2306       if (nread < 0)
2307         {
2308           *r_err = gpg_error_from_syserror ();
2309           return NULL;
2310         }
2311       self->buflen += nread;
2312     }
2313   while (nread);
2314
2315   /* EOF reached.  If we have anything in the buffer, append a Nul and
2316      return it. */
2317   self->eof_seen = 1;
2318   if (self->buflen)
2319     {
2320       self->buf[self->buflen] = 0;  /* (we allocated one extra byte)  */
2321       return self->buf;
2322     }
2323   return NULL;
2324 #undef MYBUFLEN
2325 }
2326
2327
2328
2329 static gpgme_error_t
2330 gpg_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray)
2331 {
2332   engine_gpg_t gpg = engine;
2333   gpgme_error_t err;
2334   int idx;
2335   gpgme_data_encoding_t dataenc;
2336
2337   if (keydata && keyarray)
2338     return gpg_error (GPG_ERR_INV_VALUE); /* Only one is allowed.  */
2339
2340   dataenc = gpgme_data_get_encoding (keydata);
2341
2342   if (keyarray)
2343     {
2344       err = add_arg (gpg, "--recv-keys");
2345       if (!err)
2346         err = add_arg (gpg, "--");
2347       for (idx=0; !err && keyarray[idx]; idx++)
2348         {
2349           if (keyarray[idx]->protocol != GPGME_PROTOCOL_OpenPGP)
2350             ;
2351           else if (!keyarray[idx]->subkeys)
2352             ;
2353           else if (keyarray[idx]->subkeys->fpr && *keyarray[idx]->subkeys->fpr)
2354             err = add_arg (gpg, keyarray[idx]->subkeys->fpr);
2355           else if (*keyarray[idx]->subkeys->keyid)
2356             err = add_arg (gpg, keyarray[idx]->subkeys->keyid);
2357         }
2358     }
2359   else if (dataenc == GPGME_DATA_ENCODING_URL
2360            || dataenc == GPGME_DATA_ENCODING_URL0)
2361     {
2362       void *helpptr;
2363       const char *string;
2364       gpgme_error_t xerr;
2365       int delim = (dataenc == GPGME_DATA_ENCODING_URL)? '\n': 0;
2366
2367       /* FIXME: --fetch-keys is probably not correct because it can't
2368          grok all kinds of URLs.  On Unix it should just work but on
2369          Windows we will build the command line and that may fail for
2370          some embedded control characters.  It is anyway limited to
2371          the maximum size of the command line.  We need another
2372          command which can take its input from a file.  Maybe we
2373          should use an option to gpg to modify such commands (ala
2374          --multifile).  */
2375       err = add_arg (gpg, "--fetch-keys");
2376       if (!err)
2377         err = add_arg (gpg, "--");
2378       helpptr = NULL;
2379       while (!err
2380              && (string = string_from_data (keydata, delim, &helpptr, &xerr)))
2381         err = add_arg (gpg, string);
2382       if (!err)
2383         err = xerr;
2384       string_from_data (NULL, delim, &helpptr, &xerr);
2385     }
2386   else if (dataenc == GPGME_DATA_ENCODING_URLESC)
2387     {
2388       /* Already escaped URLs are not yet supported.  */
2389       err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
2390     }
2391   else
2392     {
2393       err = add_arg (gpg, "--import");
2394       if (!err)
2395         err = add_arg (gpg, "--");
2396       if (!err)
2397         err = add_data (gpg, keydata, -1, 0);
2398     }
2399
2400   if (!err)
2401     err = start (gpg);
2402
2403   return err;
2404 }
2405
2406
2407 /* The output for external keylistings in GnuPG is different from all
2408    the other key listings.  We catch this here with a special
2409    preprocessor that reformats the colon handler lines.  */
2410 static gpgme_error_t
2411 gpg_keylist_preprocess (char *line, char **r_line)
2412 {
2413   enum
2414     {
2415       RT_NONE, RT_INFO, RT_PUB, RT_UID
2416     }
2417   rectype = RT_NONE;
2418 #define NR_FIELDS 16
2419   char *field[NR_FIELDS];
2420   int fields = 0;
2421   size_t n;
2422
2423   *r_line = NULL;
2424
2425   while (line && fields < NR_FIELDS)
2426     {
2427       field[fields++] = line;
2428       line = strchr (line, ':');
2429       if (line)
2430         *(line++) = '\0';
2431     }
2432
2433   if (!strcmp (field[0], "info"))
2434     rectype = RT_INFO;
2435   else if (!strcmp (field[0], "pub"))
2436     rectype = RT_PUB;
2437   else if (!strcmp (field[0], "uid"))
2438     rectype = RT_UID;
2439   else
2440     rectype = RT_NONE;
2441
2442   switch (rectype)
2443     {
2444     case RT_INFO:
2445       /* FIXME: Eventually, check the version number at least.  */
2446       return 0;
2447
2448     case RT_PUB:
2449       if (fields < 7)
2450         return 0;
2451
2452       /* The format is:
2453
2454          pub:<keyid>:<algo>:<keylen>:<creationdate>:<expirationdate>:<flags>
2455
2456          as defined in 5.2. Machine Readable Indexes of the OpenPGP
2457          HTTP Keyserver Protocol (draft).  Modern versions of the SKS
2458          keyserver return the fingerprint instead of the keyid.  We
2459          detect this here and use the v4 fingerprint format to convert
2460          it to a key id.
2461
2462          We want:
2463          pub:o<flags>:<keylen>:<algo>:<keyid>:<creatdate>:<expdate>::::::::
2464       */
2465
2466       n = strlen (field[1]);
2467       if (n > 16)
2468         {
2469           if (asprintf (r_line,
2470                         "pub:o%s:%s:%s:%s:%s:%s::::::::\n"
2471                         "fpr:::::::::%s:",
2472                         field[6], field[3], field[2], field[1] + n - 16,
2473                         field[4], field[5], field[1]) < 0)
2474             return gpg_error_from_syserror ();
2475         }
2476       else
2477         {
2478           if (asprintf (r_line,
2479                         "pub:o%s:%s:%s:%s:%s:%s::::::::",
2480                         field[6], field[3], field[2], field[1],
2481                         field[4], field[5]) < 0)
2482             return gpg_error_from_syserror ();
2483         }
2484
2485       return 0;
2486
2487     case RT_UID:
2488       /* The format is:
2489
2490          uid:<escaped uid string>:<creationdate>:<expirationdate>:<flags>
2491
2492          as defined in 5.2. Machine Readable Indexes of the OpenPGP
2493          HTTP Keyserver Protocol (draft).
2494
2495          We want:
2496          uid:o<flags>::::<creatdate>:<expdate>:::<c-coded uid>:
2497       */
2498
2499       {
2500         /* The user ID is percent escaped, but we want c-coded.
2501            Because we have to replace each '%HL' by '\xHL', we need at
2502            most 4/3 th the number of bytes.  But because we also need
2503            to escape the backslashes we allocate twice as much.  */
2504         char *uid = malloc (2 * strlen (field[1]) + 1);
2505         char *src;
2506         char *dst;
2507
2508         if (! uid)
2509           return gpg_error_from_syserror ();
2510         src = field[1];
2511         dst = uid;
2512         while (*src)
2513           {
2514             if (*src == '%')
2515               {
2516                 *(dst++) = '\\';
2517                 *(dst++) = 'x';
2518                 src++;
2519                 /* Copy the next two bytes unconditionally.  */
2520                 if (*src)
2521                   *(dst++) = *(src++);
2522                 if (*src)
2523                   *(dst++) = *(src++);
2524               }
2525             else if (*src == '\\')
2526               {
2527                 *dst++ = '\\';
2528                 *dst++ = '\\';
2529                 src++;
2530               }
2531             else
2532               *(dst++) = *(src++);
2533           }
2534         *dst = '\0';
2535
2536         if (asprintf (r_line, "uid:o%s::::%s:%s:::%s:",
2537                       field[4], field[2], field[3], uid) < 0)
2538           return gpg_error_from_syserror ();
2539       }
2540       return 0;
2541
2542     case RT_NONE:
2543       /* Unknown record.  */
2544       break;
2545     }
2546   return 0;
2547
2548 }
2549
2550
2551 static gpg_error_t
2552 gpg_keylist_build_options (engine_gpg_t gpg, int secret_only,
2553                            gpgme_keylist_mode_t mode)
2554 {
2555   gpg_error_t err;
2556
2557   err = add_arg (gpg, "--with-colons");
2558
2559   /* Since gpg 2.1.15 fingerprints are always printed, thus there is
2560    * no more need to explictly request them.  */
2561   if (!have_gpg_version (gpg, "2.1.15"))
2562     {
2563       if (!err)
2564         err = add_arg (gpg, "--fixed-list-mode");
2565       if (!err)
2566         err = add_arg (gpg, "--with-fingerprint");
2567       if (!err)
2568         err = add_arg (gpg, "--with-fingerprint");
2569     }
2570
2571   if (!err && (mode & GPGME_KEYLIST_MODE_WITH_TOFU)
2572       && have_gpg_version (gpg, "2.1.16"))
2573     err = add_arg (gpg, "--with-tofu-info");
2574
2575   if (!err && (mode & GPGME_KEYLIST_MODE_WITH_SECRET))
2576     err = add_arg (gpg, "--with-secret");
2577
2578   if (!err
2579       && (mode & GPGME_KEYLIST_MODE_SIGS)
2580       && (mode & GPGME_KEYLIST_MODE_SIG_NOTATIONS))
2581     {
2582       err = add_arg (gpg, "--list-options");
2583       if (!err)
2584         err = add_arg (gpg, "show-sig-subpackets=\"20,26\"");
2585     }
2586
2587   if (!err)
2588     {
2589       if ( (mode & GPGME_KEYLIST_MODE_EXTERN) )
2590         {
2591           if (secret_only)
2592             err = gpg_error (GPG_ERR_NOT_SUPPORTED);
2593           else if ( (mode & GPGME_KEYLIST_MODE_LOCAL))
2594             {
2595               /* The local+extern mode is special.  It works only with
2596                  gpg >= 2.0.10.  FIXME: We should check that we have
2597                  such a version to that we can return a proper error
2598                  code.  The problem is that we don't know the context
2599                  here and thus can't access the cached version number
2600                  for the engine info structure.  */
2601               err = add_arg (gpg, "--locate-keys");
2602               if ((mode & GPGME_KEYLIST_MODE_SIGS))
2603                 err = add_arg (gpg, "--with-sig-check");
2604             }
2605           else
2606             {
2607               err = add_arg (gpg, "--search-keys");
2608               gpg->colon.preprocess_fnc = gpg_keylist_preprocess;
2609             }
2610         }
2611       else
2612         {
2613           err = add_arg (gpg, secret_only ? "--list-secret-keys"
2614                          : ((mode & GPGME_KEYLIST_MODE_SIGS)
2615                             ? "--check-sigs" : "--list-keys"));
2616         }
2617     }
2618
2619   if (!err)
2620     err = add_arg (gpg, "--");
2621
2622   return err;
2623 }
2624
2625
2626 static gpgme_error_t
2627 gpg_keylist (void *engine, const char *pattern, int secret_only,
2628              gpgme_keylist_mode_t mode, int engine_flags)
2629 {
2630   engine_gpg_t gpg = engine;
2631   gpgme_error_t err;
2632
2633   (void)engine_flags;
2634
2635   err = gpg_keylist_build_options (gpg, secret_only, mode);
2636
2637   if (!err && pattern && *pattern)
2638     err = add_arg (gpg, pattern);
2639
2640   if (!err)
2641     err = start (gpg);
2642
2643   return err;
2644 }
2645
2646
2647 static gpgme_error_t
2648 gpg_keylist_ext (void *engine, const char *pattern[], int secret_only,
2649                  int reserved, gpgme_keylist_mode_t mode, int engine_flags)
2650 {
2651   engine_gpg_t gpg = engine;
2652   gpgme_error_t err;
2653
2654   (void)engine_flags;
2655
2656   if (reserved)
2657     return gpg_error (GPG_ERR_INV_VALUE);
2658
2659   err = gpg_keylist_build_options (gpg, secret_only, mode);
2660
2661   if (pattern)
2662     {
2663       while (!err && *pattern && **pattern)
2664         err = add_arg (gpg, *(pattern++));
2665     }
2666
2667   if (!err)
2668     err = start (gpg);
2669
2670   return err;
2671 }
2672
2673
2674 static gpgme_error_t
2675 gpg_keysign (void *engine, gpgme_key_t key, const char *userid,
2676              unsigned long expire, unsigned int flags,
2677              gpgme_ctx_t ctx)
2678 {
2679   engine_gpg_t gpg = engine;
2680   gpgme_error_t err;
2681   const char *s;
2682
2683   if (!key || !key->fpr)
2684     return gpg_error (GPG_ERR_INV_ARG);
2685
2686   if (!have_gpg_version (gpg, "2.1.12"))
2687     return gpg_error (GPG_ERR_NOT_SUPPORTED);
2688
2689   if ((flags & GPGME_KEYSIGN_LOCAL))
2690     err = add_arg (gpg, "--quick-lsign-key");
2691   else
2692     err = add_arg (gpg, "--quick-sign-key");
2693
2694   if (!err)
2695     err = append_args_from_signers (gpg, ctx);
2696
2697   /* If an expiration time has been given use that.  If none has been
2698    * given the default from gpg.conf is used.  To make sure not to set
2699    * an expiration time at all the flag GPGME_KEYSIGN_NOEXPIRE can be
2700    * used.  */
2701   if (!err && (expire || (flags & GPGME_KEYSIGN_NOEXPIRE)))
2702     {
2703       char tmpbuf[8+20];
2704
2705       if ((flags & GPGME_KEYSIGN_NOEXPIRE))
2706         expire = 0;
2707       snprintf (tmpbuf, sizeof tmpbuf, "seconds=%lu", expire);
2708       err = add_arg (gpg, "--default-cert-expire");
2709       if (!err)
2710         err = add_arg (gpg, tmpbuf);
2711     }
2712
2713   if (!err)
2714     err = add_arg (gpg, "--");
2715
2716   if (!err)
2717     err = add_arg (gpg, key->fpr);
2718   if (!err && userid)
2719     {
2720       if ((flags & GPGME_KEYSIGN_LFSEP))
2721         {
2722           for (; !err && (s = strchr (userid, '\n')); userid = s + 1)
2723             if ((s - userid))
2724               err = add_arg_len (gpg, "=", userid, s - userid);
2725           if (!err && *userid)
2726             err = add_arg_pfx (gpg, "=", userid);
2727         }
2728       else
2729         err = add_arg_pfx (gpg, "=", userid);
2730     }
2731
2732   if (!err)
2733     err = start (gpg);
2734
2735   return err;
2736 }
2737
2738
2739 static gpgme_error_t
2740 gpg_tofu_policy (void *engine, gpgme_key_t key, gpgme_tofu_policy_t policy)
2741 {
2742   engine_gpg_t gpg = engine;
2743   gpgme_error_t err;
2744   const char *policystr = NULL;
2745
2746   if (!key || !key->fpr)
2747     return gpg_error (GPG_ERR_INV_ARG);
2748
2749   switch (policy)
2750     {
2751     case GPGME_TOFU_POLICY_NONE:                           break;
2752     case GPGME_TOFU_POLICY_AUTO:    policystr = "auto";    break;
2753     case GPGME_TOFU_POLICY_GOOD:    policystr = "good";    break;
2754     case GPGME_TOFU_POLICY_BAD:     policystr = "bad";     break;
2755     case GPGME_TOFU_POLICY_ASK:     policystr = "ask";     break;
2756     case GPGME_TOFU_POLICY_UNKNOWN: policystr = "unknown"; break;
2757     }
2758   if (!policystr)
2759     return gpg_error (GPG_ERR_INV_VALUE);
2760
2761   if (!have_gpg_version (gpg, "2.1.10"))
2762     return gpg_error (GPG_ERR_NOT_SUPPORTED);
2763
2764   err = add_arg (gpg, "--tofu-policy");
2765   if (!err)
2766     err = add_arg (gpg, "--");
2767   if (!err)
2768     err = add_arg (gpg, policystr);
2769   if (!err)
2770     err = add_arg (gpg, key->fpr);
2771
2772   if (!err)
2773     err = start (gpg);
2774
2775   return err;
2776 }
2777
2778
2779 static gpgme_error_t
2780 gpg_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
2781           gpgme_sig_mode_t mode, int use_armor, int use_textmode,
2782           int include_certs, gpgme_ctx_t ctx /* FIXME */)
2783 {
2784   engine_gpg_t gpg = engine;
2785   gpgme_error_t err;
2786
2787   (void)include_certs;
2788
2789   if (mode == GPGME_SIG_MODE_CLEAR)
2790     err = add_arg (gpg, "--clearsign");
2791   else
2792     {
2793       err = add_arg (gpg, "--sign");
2794       if (!err && mode == GPGME_SIG_MODE_DETACH)
2795         err = add_arg (gpg, "--detach");
2796       if (!err && use_armor)
2797         err = add_arg (gpg, "--armor");
2798       if (!err)
2799         {
2800           if (gpgme_data_get_encoding (in) == GPGME_DATA_ENCODING_MIME
2801               && have_gpg_version (gpg, "2.1.14"))
2802             err = add_arg (gpg, "--mimemode");
2803           else if (use_textmode)
2804             err = add_arg (gpg, "--textmode");
2805         }
2806     }
2807
2808   if (!err)
2809     err = append_args_from_signers (gpg, ctx);
2810   if (!err)
2811     err = append_args_from_sig_notations (gpg, ctx);
2812
2813   if (gpgme_data_get_file_name (in))
2814     {
2815       if (!err)
2816         err = add_arg (gpg, "--set-filename");
2817       if (!err)
2818         err = add_arg (gpg, gpgme_data_get_file_name (in));
2819     }
2820
2821   /* Tell the gpg object about the data.  */
2822   if (!err)
2823     err = add_input_size_hint (gpg, in);
2824   if (!err)
2825     err = add_arg (gpg, "--");
2826   if (!err)
2827     err = add_data (gpg, in, -1, 0);
2828   if (!err)
2829     err = add_data (gpg, out, 1, 1);
2830
2831   if (!err)
2832     err = start (gpg);
2833
2834   return err;
2835 }
2836
2837 static gpgme_error_t
2838 gpg_trustlist (void *engine, const char *pattern)
2839 {
2840   engine_gpg_t gpg = engine;
2841   gpgme_error_t err;
2842
2843   err = add_arg (gpg, "--with-colons");
2844   if (!err)
2845     err = add_arg (gpg, "--list-trust-path");
2846
2847   /* Tell the gpg object about the data.  */
2848   if (!err)
2849     err = add_arg (gpg, "--");
2850   if (!err)
2851     err = add_arg (gpg, pattern);
2852
2853   if (!err)
2854     err = start (gpg);
2855
2856   return err;
2857 }
2858
2859
2860 static gpgme_error_t
2861 gpg_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
2862             gpgme_data_t plaintext)
2863 {
2864   engine_gpg_t gpg = engine;
2865   gpgme_error_t err = 0;
2866
2867   if (plaintext)
2868     {
2869       /* Normal or cleartext signature.  */
2870       err = add_arg (gpg, "--output");
2871       if (!err)
2872         err = add_arg (gpg, "-");
2873       if (!err)
2874         err = add_input_size_hint (gpg, sig);
2875       if (!err)
2876         err = add_arg (gpg, "--");
2877       if (!err)
2878         err = add_data (gpg, sig, -1, 0);
2879       if (!err)
2880         err = add_data (gpg, plaintext, 1, 1);
2881     }
2882   else
2883     {
2884       err = add_arg (gpg, "--verify");
2885       if (!err)
2886         err = add_input_size_hint (gpg, signed_text);
2887       if (!err)
2888         err = add_arg (gpg, "--");
2889       if (!err)
2890         err = add_data (gpg, sig, -1, 0);
2891       if (!err && signed_text)
2892         err = add_data (gpg, signed_text, -1, 0);
2893     }
2894
2895   if (!err)
2896     err = start (gpg);
2897
2898   return err;
2899 }
2900
2901
2902 static void
2903 gpg_set_io_cbs (void *engine, gpgme_io_cbs_t io_cbs)
2904 {
2905   engine_gpg_t gpg = engine;
2906
2907   gpg->io_cbs = *io_cbs;
2908 }
2909
2910
2911 static gpgme_error_t
2912 gpg_set_pinentry_mode (void *engine, gpgme_pinentry_mode_t mode)
2913 {
2914   engine_gpg_t gpg = engine;
2915
2916   gpg->pinentry_mode = mode;
2917   return 0;
2918 }
2919
2920
2921 \f
2922 struct engine_ops _gpgme_engine_ops_gpg =
2923   {
2924     /* Static functions.  */
2925     _gpgme_get_default_gpg_name,
2926     NULL,
2927     gpg_get_version,
2928     gpg_get_req_version,
2929     gpg_new,
2930
2931     /* Member functions.  */
2932     gpg_release,
2933     NULL,                               /* reset */
2934     gpg_set_status_cb,
2935     gpg_set_status_handler,
2936     gpg_set_command_handler,
2937     gpg_set_colon_line_handler,
2938     gpg_set_locale,
2939     NULL,                               /* set_protocol */
2940     gpg_decrypt,
2941     gpg_decrypt,                        /* decrypt_verify */
2942     gpg_delete,
2943     gpg_edit,
2944     gpg_encrypt,
2945     gpg_encrypt_sign,
2946     gpg_export,
2947     gpg_export_ext,
2948     gpg_genkey,
2949     gpg_import,
2950     gpg_keylist,
2951     gpg_keylist_ext,
2952     gpg_keysign,
2953     gpg_tofu_policy,    /* tofu_policy */
2954     gpg_sign,
2955     gpg_trustlist,
2956     gpg_verify,
2957     NULL,               /* getauditlog */
2958     NULL,               /* opassuan_transact */
2959     NULL,               /* conf_load */
2960     NULL,               /* conf_save */
2961     gpg_set_io_cbs,
2962     gpg_io_event,
2963     gpg_cancel,
2964     NULL,               /* cancel_op */
2965     gpg_passwd,
2966     gpg_set_pinentry_mode,
2967     NULL                /* opspawn */
2968   };