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