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