python: Release the GIL during calls into GPGME.
[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 static gpgme_error_t
2055 gpg_createkey (engine_gpg_t gpg,
2056                const char *userid, const char *algo,
2057                unsigned long expires,
2058                unsigned int flags,
2059                unsigned int extraflags)
2060 {
2061   gpgme_error_t err;
2062
2063   err = add_arg (gpg, "--quick-gen-key");
2064   if (!err && (extraflags & GENKEY_EXTRAFLAG_ARMOR))
2065     err = add_arg (gpg, "--armor");
2066   if (!err && (flags & GPGME_CREATE_NOPASSWD))
2067     {
2068       err = add_arg (gpg, "--passphrase");
2069       if (!err)
2070         err = add_arg (gpg, "");
2071     }
2072   if (!err && (flags & GPGME_CREATE_FORCE))
2073     err = add_arg (gpg, "--yes");
2074   if (!err)
2075     err = add_arg (gpg, "--");
2076   if (!err)
2077     err = add_arg (gpg, userid);
2078
2079   if (!err)
2080     err = gpg_add_algo_usage_expire (gpg, algo, expires, flags);
2081
2082   if (!err)
2083     err = start (gpg);
2084   return err;
2085 }
2086
2087
2088 static gpgme_error_t
2089 gpg_addkey (engine_gpg_t gpg,
2090             const char *algo,
2091             unsigned long expires,
2092             gpgme_key_t key,
2093             unsigned int flags,
2094             unsigned int extraflags)
2095 {
2096   gpgme_error_t err;
2097
2098   if (!key || !key->fpr)
2099     return gpg_error (GPG_ERR_INV_ARG);
2100
2101   err = add_arg (gpg, "--quick-addkey");
2102   if (!err && (extraflags & GENKEY_EXTRAFLAG_ARMOR))
2103     err = add_arg (gpg, "--armor");
2104   if (!err && (flags & GPGME_CREATE_NOPASSWD))
2105     {
2106       err = add_arg (gpg, "--passphrase");
2107       if (!err)
2108         err = add_arg (gpg, "");
2109     }
2110   if (!err)
2111     err = add_arg (gpg, "--");
2112   if (!err)
2113     err = add_arg (gpg, key->fpr);
2114
2115   if (!err)
2116     err = gpg_add_algo_usage_expire (gpg, algo, expires, flags);
2117
2118   if (!err)
2119     err = start (gpg);
2120   return err;
2121 }
2122
2123
2124 static gpgme_error_t
2125 gpg_adduid (engine_gpg_t gpg,
2126             gpgme_key_t key,
2127             const char *userid,
2128             unsigned int extraflags)
2129 {
2130   gpgme_error_t err;
2131
2132   if (!key || !key->fpr || !userid)
2133     return gpg_error (GPG_ERR_INV_ARG);
2134
2135   if ((extraflags & GENKEY_EXTRAFLAG_REVOKE))
2136     err = add_arg (gpg, "--quick-revuid");
2137   else
2138     err = add_arg (gpg, "--quick-adduid");
2139
2140   if (!err)
2141     err = add_arg (gpg, "--");
2142   if (!err)
2143     err = add_arg (gpg, key->fpr);
2144   if (!err)
2145     err = add_arg (gpg, userid);
2146
2147   if (!err)
2148     err = start (gpg);
2149   return err;
2150 }
2151
2152
2153 static gpgme_error_t
2154 gpg_genkey (void *engine,
2155             const char *userid, const char *algo,
2156             unsigned long reserved, unsigned long expires,
2157             gpgme_key_t key, unsigned int flags,
2158             gpgme_data_t help_data, unsigned int extraflags,
2159             gpgme_data_t pubkey, gpgme_data_t seckey)
2160 {
2161   engine_gpg_t gpg = engine;
2162   gpgme_error_t err;
2163
2164   (void)reserved;
2165
2166   if (!gpg)
2167     return gpg_error (GPG_ERR_INV_VALUE);
2168
2169   /* If HELP_DATA is given the use of the old interface
2170    * (gpgme_op_genkey) has been requested.  The other modes are:
2171    *
2172    *  USERID && !KEY          - Create a new keyblock.
2173    * !USERID &&  KEY          - Add a new subkey to KEY (gpg >= 2.1.14)
2174    *  USERID &&  KEY && !ALGO - Add a new user id to KEY (gpg >= 2.1.14).
2175    *
2176    */
2177   if (help_data)
2178     {
2179       /* We need a special mechanism to get the fd of a pipe here, so
2180          that we can use this for the %pubring and %secring
2181          parameters.  We don't have this yet, so we implement only the
2182          adding to the standard keyrings.  */
2183       if (pubkey || seckey)
2184         err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
2185       else
2186         err = gpg_createkey_from_param (gpg, help_data, extraflags);
2187     }
2188   else if (!have_gpg_version (gpg, "2.1.13"))
2189     err = gpg_error (GPG_ERR_NOT_SUPPORTED);
2190   else if (userid && !key)
2191     err = gpg_createkey (gpg, userid, algo, expires, flags, extraflags);
2192   else if (!userid && key)
2193     err = gpg_addkey (gpg, algo, expires, key, flags, extraflags);
2194   else if (userid && key && !algo)
2195     err = gpg_adduid (gpg, key, userid, extraflags);
2196   else
2197     err = gpg_error (GPG_ERR_INV_VALUE);
2198
2199   return err;
2200 }
2201
2202 /* Return the next DELIM delimited string from DATA as a C-string.
2203    The caller needs to provide the address of a pointer variable which
2204    he has to set to NULL before the first call.  After the last call
2205    to this function, this function needs to be called once more with
2206    DATA set to NULL so that the function can release its internal
2207    state.  After that the pointer variable is free for use again.
2208    Note that we use a delimiter and thus a trailing delimiter is not
2209    required.  DELIM may not be changed after the first call. */
2210 static const char *
2211 string_from_data (gpgme_data_t data, int delim,
2212                   void **helpptr, gpgme_error_t *r_err)
2213 {
2214 #define MYBUFLEN 2000 /* Fixme: We don't support URLs longer than that.  */
2215   struct {
2216     int  eof_seen;
2217     int  nbytes;      /* Length of the last returned string including
2218                          the delimiter. */
2219     int  buflen;      /* Valid length of BUF.  */
2220     char buf[MYBUFLEN+1];  /* Buffer with one byte extra space.  */
2221   } *self;
2222   char *p;
2223   int nread;
2224
2225   *r_err = 0;
2226   if (!data)
2227     {
2228       if (*helpptr)
2229         {
2230           free (*helpptr);
2231           *helpptr = NULL;
2232         }
2233       return NULL;
2234     }
2235
2236   if (*helpptr)
2237     self = *helpptr;
2238   else
2239     {
2240       self = malloc (sizeof *self);
2241       if (!self)
2242         {
2243           *r_err = gpg_error_from_syserror ();
2244           return NULL;
2245         }
2246       *helpptr = self;
2247       self->eof_seen = 0;
2248       self->nbytes = 0;
2249       self->buflen = 0;
2250     }
2251
2252   if (self->eof_seen)
2253     return NULL;
2254
2255   assert (self->nbytes <= self->buflen);
2256   memmove (self->buf, self->buf + self->nbytes, self->buflen - self->nbytes);
2257   self->buflen -= self->nbytes;
2258   self->nbytes = 0;
2259
2260   do
2261     {
2262       /* Fixme: This is fairly infective scanning because we may scan
2263          the buffer several times.  */
2264       p = memchr (self->buf, delim, self->buflen);
2265       if (p)
2266         {
2267           *p = 0;
2268           self->nbytes = p - self->buf + 1;
2269           return self->buf;
2270         }
2271
2272       if ( !(MYBUFLEN - self->buflen) )
2273         {
2274           /* Not enough space - URL too long.  */
2275           *r_err = gpg_error (GPG_ERR_TOO_LARGE);
2276           return NULL;
2277         }
2278
2279       nread = gpgme_data_read (data, self->buf + self->buflen,
2280                                MYBUFLEN - self->buflen);
2281       if (nread < 0)
2282         {
2283           *r_err = gpg_error_from_syserror ();
2284           return NULL;
2285         }
2286       self->buflen += nread;
2287     }
2288   while (nread);
2289
2290   /* EOF reached.  If we have anything in the buffer, append a Nul and
2291      return it. */
2292   self->eof_seen = 1;
2293   if (self->buflen)
2294     {
2295       self->buf[self->buflen] = 0;  /* (we allocated one extra byte)  */
2296       return self->buf;
2297     }
2298   return NULL;
2299 #undef MYBUFLEN
2300 }
2301
2302
2303
2304 static gpgme_error_t
2305 gpg_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray)
2306 {
2307   engine_gpg_t gpg = engine;
2308   gpgme_error_t err;
2309   int idx;
2310   gpgme_data_encoding_t dataenc;
2311
2312   if (keydata && keyarray)
2313     return gpg_error (GPG_ERR_INV_VALUE); /* Only one is allowed.  */
2314
2315   dataenc = gpgme_data_get_encoding (keydata);
2316
2317   if (keyarray)
2318     {
2319       err = add_arg (gpg, "--recv-keys");
2320       if (!err)
2321         err = add_arg (gpg, "--");
2322       for (idx=0; !err && keyarray[idx]; idx++)
2323         {
2324           if (keyarray[idx]->protocol != GPGME_PROTOCOL_OpenPGP)
2325             ;
2326           else if (!keyarray[idx]->subkeys)
2327             ;
2328           else if (keyarray[idx]->subkeys->fpr && *keyarray[idx]->subkeys->fpr)
2329             err = add_arg (gpg, keyarray[idx]->subkeys->fpr);
2330           else if (*keyarray[idx]->subkeys->keyid)
2331             err = add_arg (gpg, keyarray[idx]->subkeys->keyid);
2332         }
2333     }
2334   else if (dataenc == GPGME_DATA_ENCODING_URL
2335            || dataenc == GPGME_DATA_ENCODING_URL0)
2336     {
2337       void *helpptr;
2338       const char *string;
2339       gpgme_error_t xerr;
2340       int delim = (dataenc == GPGME_DATA_ENCODING_URL)? '\n': 0;
2341
2342       /* FIXME: --fetch-keys is probably not correct because it can't
2343          grok all kinds of URLs.  On Unix it should just work but on
2344          Windows we will build the command line and that may fail for
2345          some embedded control characters.  It is anyway limited to
2346          the maximum size of the command line.  We need another
2347          command which can take its input from a file.  Maybe we
2348          should use an option to gpg to modify such commands (ala
2349          --multifile).  */
2350       err = add_arg (gpg, "--fetch-keys");
2351       if (!err)
2352         err = add_arg (gpg, "--");
2353       helpptr = NULL;
2354       while (!err
2355              && (string = string_from_data (keydata, delim, &helpptr, &xerr)))
2356         err = add_arg (gpg, string);
2357       if (!err)
2358         err = xerr;
2359       string_from_data (NULL, delim, &helpptr, &xerr);
2360     }
2361   else if (dataenc == GPGME_DATA_ENCODING_URLESC)
2362     {
2363       /* Already escaped URLs are not yet supported.  */
2364       err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
2365     }
2366   else
2367     {
2368       err = add_arg (gpg, "--import");
2369       if (!err)
2370         err = add_arg (gpg, "--");
2371       if (!err)
2372         err = add_data (gpg, keydata, -1, 0);
2373     }
2374
2375   if (!err)
2376     err = start (gpg);
2377
2378   return err;
2379 }
2380
2381
2382 /* The output for external keylistings in GnuPG is different from all
2383    the other key listings.  We catch this here with a special
2384    preprocessor that reformats the colon handler lines.  */
2385 static gpgme_error_t
2386 gpg_keylist_preprocess (char *line, char **r_line)
2387 {
2388   enum
2389     {
2390       RT_NONE, RT_INFO, RT_PUB, RT_UID
2391     }
2392   rectype = RT_NONE;
2393 #define NR_FIELDS 16
2394   char *field[NR_FIELDS];
2395   int fields = 0;
2396   size_t n;
2397
2398   *r_line = NULL;
2399
2400   while (line && fields < NR_FIELDS)
2401     {
2402       field[fields++] = line;
2403       line = strchr (line, ':');
2404       if (line)
2405         *(line++) = '\0';
2406     }
2407
2408   if (!strcmp (field[0], "info"))
2409     rectype = RT_INFO;
2410   else if (!strcmp (field[0], "pub"))
2411     rectype = RT_PUB;
2412   else if (!strcmp (field[0], "uid"))
2413     rectype = RT_UID;
2414   else
2415     rectype = RT_NONE;
2416
2417   switch (rectype)
2418     {
2419     case RT_INFO:
2420       /* FIXME: Eventually, check the version number at least.  */
2421       return 0;
2422
2423     case RT_PUB:
2424       if (fields < 7)
2425         return 0;
2426
2427       /* The format is:
2428
2429          pub:<keyid>:<algo>:<keylen>:<creationdate>:<expirationdate>:<flags>
2430
2431          as defined in 5.2. Machine Readable Indexes of the OpenPGP
2432          HTTP Keyserver Protocol (draft).  Modern versions of the SKS
2433          keyserver return the fingerprint instead of the keyid.  We
2434          detect this here and use the v4 fingerprint format to convert
2435          it to a key id.
2436
2437          We want:
2438          pub:o<flags>:<keylen>:<algo>:<keyid>:<creatdate>:<expdate>::::::::
2439       */
2440
2441       n = strlen (field[1]);
2442       if (n > 16)
2443         {
2444           if (asprintf (r_line,
2445                         "pub:o%s:%s:%s:%s:%s:%s::::::::\n"
2446                         "fpr:::::::::%s:",
2447                         field[6], field[3], field[2], field[1] + n - 16,
2448                         field[4], field[5], field[1]) < 0)
2449             return gpg_error_from_syserror ();
2450         }
2451       else
2452         {
2453           if (asprintf (r_line,
2454                         "pub:o%s:%s:%s:%s:%s:%s::::::::",
2455                         field[6], field[3], field[2], field[1],
2456                         field[4], field[5]) < 0)
2457             return gpg_error_from_syserror ();
2458         }
2459
2460       return 0;
2461
2462     case RT_UID:
2463       /* The format is:
2464
2465          uid:<escaped uid string>:<creationdate>:<expirationdate>:<flags>
2466
2467          as defined in 5.2. Machine Readable Indexes of the OpenPGP
2468          HTTP Keyserver Protocol (draft).
2469
2470          We want:
2471          uid:o<flags>::::<creatdate>:<expdate>:::<c-coded uid>:
2472       */
2473
2474       {
2475         /* The user ID is percent escaped, but we want c-coded.
2476            Because we have to replace each '%HL' by '\xHL', we need at
2477            most 4/3 th the number of bytes.  But because we also need
2478            to escape the backslashes we allocate twice as much.  */
2479         char *uid = malloc (2 * strlen (field[1]) + 1);
2480         char *src;
2481         char *dst;
2482
2483         if (! uid)
2484           return gpg_error_from_syserror ();
2485         src = field[1];
2486         dst = uid;
2487         while (*src)
2488           {
2489             if (*src == '%')
2490               {
2491                 *(dst++) = '\\';
2492                 *(dst++) = 'x';
2493                 src++;
2494                 /* Copy the next two bytes unconditionally.  */
2495                 if (*src)
2496                   *(dst++) = *(src++);
2497                 if (*src)
2498                   *(dst++) = *(src++);
2499               }
2500             else if (*src == '\\')
2501               {
2502                 *dst++ = '\\';
2503                 *dst++ = '\\';
2504                 src++;
2505               }
2506             else
2507               *(dst++) = *(src++);
2508           }
2509         *dst = '\0';
2510
2511         if (asprintf (r_line, "uid:o%s::::%s:%s:::%s:",
2512                       field[4], field[2], field[3], uid) < 0)
2513           return gpg_error_from_syserror ();
2514       }
2515       return 0;
2516
2517     case RT_NONE:
2518       /* Unknown record.  */
2519       break;
2520     }
2521   return 0;
2522
2523 }
2524
2525
2526 static gpg_error_t
2527 gpg_keylist_build_options (engine_gpg_t gpg, int secret_only,
2528                            gpgme_keylist_mode_t mode)
2529 {
2530   gpg_error_t err;
2531
2532   err = add_arg (gpg, "--with-colons");
2533
2534   /* Since gpg 2.1.15 fingerprints are always printed, thus there is
2535    * no more need to explictly request them.  */
2536   if (!have_gpg_version (gpg, "2.1.15"))
2537     {
2538       if (!err)
2539         err = add_arg (gpg, "--fixed-list-mode");
2540       if (!err)
2541         err = add_arg (gpg, "--with-fingerprint");
2542       if (!err)
2543         err = add_arg (gpg, "--with-fingerprint");
2544     }
2545
2546   if (!err && (mode & GPGME_KEYLIST_MODE_WITH_TOFU)
2547       && have_gpg_version (gpg, "2.1.16"))
2548     err = add_arg (gpg, "--with-tofu-info");
2549
2550   if (!err && (mode & GPGME_KEYLIST_MODE_WITH_SECRET))
2551     err = add_arg (gpg, "--with-secret");
2552
2553   if (!err
2554       && (mode & GPGME_KEYLIST_MODE_SIGS)
2555       && (mode & GPGME_KEYLIST_MODE_SIG_NOTATIONS))
2556     {
2557       err = add_arg (gpg, "--list-options");
2558       if (!err)
2559         err = add_arg (gpg, "show-sig-subpackets=\"20,26\"");
2560     }
2561
2562   if (!err)
2563     {
2564       if ( (mode & GPGME_KEYLIST_MODE_EXTERN) )
2565         {
2566           if (secret_only)
2567             err = gpg_error (GPG_ERR_NOT_SUPPORTED);
2568           else if ( (mode & GPGME_KEYLIST_MODE_LOCAL))
2569             {
2570               /* The local+extern mode is special.  It works only with
2571                  gpg >= 2.0.10.  FIXME: We should check that we have
2572                  such a version to that we can return a proper error
2573                  code.  The problem is that we don't know the context
2574                  here and thus can't access the cached version number
2575                  for the engine info structure.  */
2576               err = add_arg (gpg, "--locate-keys");
2577               if ((mode & GPGME_KEYLIST_MODE_SIGS))
2578                 err = add_arg (gpg, "--with-sig-check");
2579             }
2580           else
2581             {
2582               err = add_arg (gpg, "--search-keys");
2583               gpg->colon.preprocess_fnc = gpg_keylist_preprocess;
2584             }
2585         }
2586       else
2587         {
2588           err = add_arg (gpg, secret_only ? "--list-secret-keys"
2589                          : ((mode & GPGME_KEYLIST_MODE_SIGS)
2590                             ? "--check-sigs" : "--list-keys"));
2591         }
2592     }
2593
2594   if (!err)
2595     err = add_arg (gpg, "--");
2596
2597   return err;
2598 }
2599
2600
2601 static gpgme_error_t
2602 gpg_keylist (void *engine, const char *pattern, int secret_only,
2603              gpgme_keylist_mode_t mode, int engine_flags)
2604 {
2605   engine_gpg_t gpg = engine;
2606   gpgme_error_t err;
2607
2608   (void)engine_flags;
2609
2610   err = gpg_keylist_build_options (gpg, secret_only, mode);
2611
2612   if (!err && pattern && *pattern)
2613     err = add_arg (gpg, pattern);
2614
2615   if (!err)
2616     err = start (gpg);
2617
2618   return err;
2619 }
2620
2621
2622 static gpgme_error_t
2623 gpg_keylist_ext (void *engine, const char *pattern[], int secret_only,
2624                  int reserved, gpgme_keylist_mode_t mode, int engine_flags)
2625 {
2626   engine_gpg_t gpg = engine;
2627   gpgme_error_t err;
2628
2629   (void)engine_flags;
2630
2631   if (reserved)
2632     return gpg_error (GPG_ERR_INV_VALUE);
2633
2634   err = gpg_keylist_build_options (gpg, secret_only, mode);
2635
2636   if (pattern)
2637     {
2638       while (!err && *pattern && **pattern)
2639         err = add_arg (gpg, *(pattern++));
2640     }
2641
2642   if (!err)
2643     err = start (gpg);
2644
2645   return err;
2646 }
2647
2648
2649 static gpgme_error_t
2650 gpg_keysign (void *engine, gpgme_key_t key, const char *userid,
2651              unsigned long expire, unsigned int flags,
2652              gpgme_ctx_t ctx)
2653 {
2654   engine_gpg_t gpg = engine;
2655   gpgme_error_t err;
2656   const char *s;
2657
2658   if (!key || !key->fpr)
2659     return gpg_error (GPG_ERR_INV_ARG);
2660
2661   if (!have_gpg_version (gpg, "2.1.12"))
2662     return gpg_error (GPG_ERR_NOT_SUPPORTED);
2663
2664   if ((flags & GPGME_KEYSIGN_LOCAL))
2665     err = add_arg (gpg, "--quick-lsign-key");
2666   else
2667     err = add_arg (gpg, "--quick-sign-key");
2668
2669   if (!err)
2670     err = append_args_from_signers (gpg, ctx);
2671
2672   /* If an expiration time has been given use that.  If none has been
2673    * given the default from gpg.conf is used.  To make sure not to set
2674    * an expiration time at all the flag GPGME_KEYSIGN_NOEXPIRE can be
2675    * used.  */
2676   if (!err && (expire || (flags & GPGME_KEYSIGN_NOEXPIRE)))
2677     {
2678       char tmpbuf[8+20];
2679
2680       if ((flags & GPGME_KEYSIGN_NOEXPIRE))
2681         expire = 0;
2682       snprintf (tmpbuf, sizeof tmpbuf, "seconds=%lu", expire);
2683       err = add_arg (gpg, "--default-cert-expire");
2684       if (!err)
2685         err = add_arg (gpg, tmpbuf);
2686     }
2687
2688   if (!err)
2689     err = add_arg (gpg, "--");
2690
2691   if (!err)
2692     err = add_arg (gpg, key->fpr);
2693   if (!err && userid)
2694     {
2695       if ((flags & GPGME_KEYSIGN_LFSEP))
2696         {
2697           for (; !err && (s = strchr (userid, '\n')); userid = s + 1)
2698             if ((s - userid))
2699               err = add_arg_len (gpg, "=", userid, s - userid);
2700           if (!err && *userid)
2701             err = add_arg_pfx (gpg, "=", userid);
2702         }
2703       else
2704         err = add_arg_pfx (gpg, "=", userid);
2705     }
2706
2707   if (!err)
2708     err = start (gpg);
2709
2710   return err;
2711 }
2712
2713
2714 static gpgme_error_t
2715 gpg_tofu_policy (void *engine, gpgme_key_t key, gpgme_tofu_policy_t policy)
2716 {
2717   engine_gpg_t gpg = engine;
2718   gpgme_error_t err;
2719   const char *policystr = NULL;
2720
2721   if (!key || !key->fpr)
2722     return gpg_error (GPG_ERR_INV_ARG);
2723
2724   switch (policy)
2725     {
2726     case GPGME_TOFU_POLICY_NONE:                           break;
2727     case GPGME_TOFU_POLICY_AUTO:    policystr = "auto";    break;
2728     case GPGME_TOFU_POLICY_GOOD:    policystr = "good";    break;
2729     case GPGME_TOFU_POLICY_BAD:     policystr = "bad";     break;
2730     case GPGME_TOFU_POLICY_ASK:     policystr = "ask";     break;
2731     case GPGME_TOFU_POLICY_UNKNOWN: policystr = "unknown"; break;
2732     }
2733   if (!policystr)
2734     return gpg_error (GPG_ERR_INV_VALUE);
2735
2736   if (!have_gpg_version (gpg, "2.1.10"))
2737     return gpg_error (GPG_ERR_NOT_SUPPORTED);
2738
2739   err = add_arg (gpg, "--tofu-policy");
2740   if (!err)
2741     err = add_arg (gpg, "--");
2742   if (!err)
2743     err = add_arg (gpg, policystr);
2744   if (!err)
2745     err = add_arg (gpg, key->fpr);
2746
2747   if (!err)
2748     err = start (gpg);
2749
2750   return err;
2751 }
2752
2753
2754 static gpgme_error_t
2755 gpg_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
2756           gpgme_sig_mode_t mode, int use_armor, int use_textmode,
2757           int include_certs, gpgme_ctx_t ctx /* FIXME */)
2758 {
2759   engine_gpg_t gpg = engine;
2760   gpgme_error_t err;
2761
2762   (void)include_certs;
2763
2764   if (mode == GPGME_SIG_MODE_CLEAR)
2765     err = add_arg (gpg, "--clearsign");
2766   else
2767     {
2768       err = add_arg (gpg, "--sign");
2769       if (!err && mode == GPGME_SIG_MODE_DETACH)
2770         err = add_arg (gpg, "--detach");
2771       if (!err && use_armor)
2772         err = add_arg (gpg, "--armor");
2773       if (!err)
2774         {
2775           if (gpgme_data_get_encoding (in) == GPGME_DATA_ENCODING_MIME
2776               && have_gpg_version (gpg, "2.1.14"))
2777             err = add_arg (gpg, "--mimemode");
2778           else if (use_textmode)
2779             err = add_arg (gpg, "--textmode");
2780         }
2781     }
2782
2783   if (!err)
2784     err = append_args_from_signers (gpg, ctx);
2785   if (!err)
2786     err = append_args_from_sig_notations (gpg, ctx);
2787
2788   if (gpgme_data_get_file_name (in))
2789     {
2790       if (!err)
2791         err = add_arg (gpg, "--set-filename");
2792       if (!err)
2793         err = add_arg (gpg, gpgme_data_get_file_name (in));
2794     }
2795
2796   /* Tell the gpg object about the data.  */
2797   if (!err)
2798     err = add_input_size_hint (gpg, in);
2799   if (!err)
2800     err = add_arg (gpg, "--");
2801   if (!err)
2802     err = add_data (gpg, in, -1, 0);
2803   if (!err)
2804     err = add_data (gpg, out, 1, 1);
2805
2806   if (!err)
2807     err = start (gpg);
2808
2809   return err;
2810 }
2811
2812 static gpgme_error_t
2813 gpg_trustlist (void *engine, const char *pattern)
2814 {
2815   engine_gpg_t gpg = engine;
2816   gpgme_error_t err;
2817
2818   err = add_arg (gpg, "--with-colons");
2819   if (!err)
2820     err = add_arg (gpg, "--list-trust-path");
2821
2822   /* Tell the gpg object about the data.  */
2823   if (!err)
2824     err = add_arg (gpg, "--");
2825   if (!err)
2826     err = add_arg (gpg, pattern);
2827
2828   if (!err)
2829     err = start (gpg);
2830
2831   return err;
2832 }
2833
2834
2835 static gpgme_error_t
2836 gpg_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
2837             gpgme_data_t plaintext)
2838 {
2839   engine_gpg_t gpg = engine;
2840   gpgme_error_t err = 0;
2841
2842   if (plaintext)
2843     {
2844       /* Normal or cleartext signature.  */
2845       err = add_arg (gpg, "--output");
2846       if (!err)
2847         err = add_arg (gpg, "-");
2848       if (!err)
2849         err = add_input_size_hint (gpg, sig);
2850       if (!err)
2851         err = add_arg (gpg, "--");
2852       if (!err)
2853         err = add_data (gpg, sig, -1, 0);
2854       if (!err)
2855         err = add_data (gpg, plaintext, 1, 1);
2856     }
2857   else
2858     {
2859       err = add_arg (gpg, "--verify");
2860       if (!err)
2861         err = add_input_size_hint (gpg, signed_text);
2862       if (!err)
2863         err = add_arg (gpg, "--");
2864       if (!err)
2865         err = add_data (gpg, sig, -1, 0);
2866       if (!err && signed_text)
2867         err = add_data (gpg, signed_text, -1, 0);
2868     }
2869
2870   if (!err)
2871     err = start (gpg);
2872
2873   return err;
2874 }
2875
2876
2877 static void
2878 gpg_set_io_cbs (void *engine, gpgme_io_cbs_t io_cbs)
2879 {
2880   engine_gpg_t gpg = engine;
2881
2882   gpg->io_cbs = *io_cbs;
2883 }
2884
2885
2886 static gpgme_error_t
2887 gpg_set_pinentry_mode (void *engine, gpgme_pinentry_mode_t mode)
2888 {
2889   engine_gpg_t gpg = engine;
2890
2891   gpg->pinentry_mode = mode;
2892   return 0;
2893 }
2894
2895
2896 \f
2897 struct engine_ops _gpgme_engine_ops_gpg =
2898   {
2899     /* Static functions.  */
2900     _gpgme_get_default_gpg_name,
2901     NULL,
2902     gpg_get_version,
2903     gpg_get_req_version,
2904     gpg_new,
2905
2906     /* Member functions.  */
2907     gpg_release,
2908     NULL,                               /* reset */
2909     gpg_set_status_cb,
2910     gpg_set_status_handler,
2911     gpg_set_command_handler,
2912     gpg_set_colon_line_handler,
2913     gpg_set_locale,
2914     NULL,                               /* set_protocol */
2915     gpg_decrypt,
2916     gpg_decrypt,                        /* decrypt_verify */
2917     gpg_delete,
2918     gpg_edit,
2919     gpg_encrypt,
2920     gpg_encrypt_sign,
2921     gpg_export,
2922     gpg_export_ext,
2923     gpg_genkey,
2924     gpg_import,
2925     gpg_keylist,
2926     gpg_keylist_ext,
2927     gpg_keysign,
2928     gpg_tofu_policy,    /* tofu_policy */
2929     gpg_sign,
2930     gpg_trustlist,
2931     gpg_verify,
2932     NULL,               /* getauditlog */
2933     NULL,               /* opassuan_transact */
2934     NULL,               /* conf_load */
2935     NULL,               /* conf_save */
2936     gpg_set_io_cbs,
2937     gpg_io_event,
2938     gpg_cancel,
2939     NULL,               /* cancel_op */
2940     gpg_passwd,
2941     gpg_set_pinentry_mode,
2942     NULL                /* opspawn */
2943   };