core: Add public function gpgme_get_ctx_flag.
[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, int export_session_key)
1554 {
1555   engine_gpg_t gpg = engine;
1556   gpgme_error_t err;
1557
1558   err = add_arg (gpg, "--decrypt");
1559
1560   if (!err && export_session_key)
1561     err = add_arg (gpg, "--show-session-key");
1562
1563   /* Tell the gpg object about the data.  */
1564   if (!err)
1565     err = add_arg (gpg, "--output");
1566   if (!err)
1567     err = add_arg (gpg, "-");
1568   if (!err)
1569     err = add_data (gpg, plain, 1, 1);
1570   if (!err)
1571     err = add_input_size_hint (gpg, ciph);
1572   if (!err)
1573     err = add_arg (gpg, "--");
1574   if (!err)
1575     err = add_data (gpg, ciph, -1, 0);
1576
1577   if (!err)
1578     err = start (gpg);
1579   return err;
1580 }
1581
1582 static gpgme_error_t
1583 gpg_delete (void *engine, gpgme_key_t key, int allow_secret)
1584 {
1585   engine_gpg_t gpg = engine;
1586   gpgme_error_t err;
1587
1588   err = add_arg (gpg, allow_secret ? "--delete-secret-and-public-key"
1589                  : "--delete-key");
1590   if (!err)
1591     err = add_arg (gpg, "--");
1592   if (!err)
1593     {
1594       if (!key->subkeys || !key->subkeys->fpr)
1595         return gpg_error (GPG_ERR_INV_VALUE);
1596       else
1597         err = add_arg (gpg, key->subkeys->fpr);
1598     }
1599
1600   if (!err)
1601     err = start (gpg);
1602   return err;
1603 }
1604
1605
1606 static gpgme_error_t
1607 gpg_passwd (void *engine, gpgme_key_t key, unsigned int flags)
1608 {
1609   engine_gpg_t gpg = engine;
1610   gpgme_error_t err;
1611
1612   (void)flags;
1613
1614   if (!key || !key->subkeys || !key->subkeys->fpr)
1615     return gpg_error (GPG_ERR_INV_CERT_OBJ);
1616
1617   err = add_arg (gpg, "--passwd");
1618   if (!err)
1619     err = add_arg (gpg, key->subkeys->fpr);
1620   if (!err)
1621     err = start (gpg);
1622   return err;
1623 }
1624
1625
1626 static gpgme_error_t
1627 append_args_from_signers (engine_gpg_t gpg, gpgme_ctx_t ctx /* FIXME */)
1628 {
1629   gpgme_error_t err = 0;
1630   int i;
1631   gpgme_key_t key;
1632
1633   for (i = 0; (key = gpgme_signers_enum (ctx, i)); i++)
1634     {
1635       const char *s = key->subkeys ? key->subkeys->keyid : NULL;
1636       if (s)
1637         {
1638           if (!err)
1639             err = add_arg (gpg, "-u");
1640           if (!err)
1641             err = add_arg (gpg, s);
1642         }
1643       gpgme_key_unref (key);
1644       if (err)
1645         break;
1646     }
1647   return err;
1648 }
1649
1650
1651 static gpgme_error_t
1652 append_args_from_sender (engine_gpg_t gpg, gpgme_ctx_t ctx)
1653 {
1654   gpgme_error_t err;
1655
1656   if (ctx->sender && have_gpg_version (gpg, "2.1.15"))
1657     {
1658       err = add_arg (gpg, "--sender");
1659       if (!err)
1660         err = add_arg (gpg, ctx->sender);
1661     }
1662   else
1663     err = 0;
1664   return err;
1665 }
1666
1667
1668 static gpgme_error_t
1669 append_args_from_sig_notations (engine_gpg_t gpg, gpgme_ctx_t ctx /* FIXME */)
1670 {
1671   gpgme_error_t err = 0;
1672   gpgme_sig_notation_t notation;
1673
1674   notation = gpgme_sig_notation_get (ctx);
1675
1676   while (!err && notation)
1677     {
1678       if (notation->name
1679           && !(notation->flags & GPGME_SIG_NOTATION_HUMAN_READABLE))
1680         err = gpg_error (GPG_ERR_INV_VALUE);
1681       else if (notation->name)
1682         {
1683           char *arg;
1684
1685           /* Maximum space needed is one byte for the "critical" flag,
1686              the name, one byte for '=', the value, and a terminating
1687              '\0'.  */
1688
1689           arg = malloc (1 + notation->name_len + 1 + notation->value_len + 1);
1690           if (!arg)
1691             err = gpg_error_from_syserror ();
1692
1693           if (!err)
1694             {
1695               char *argp = arg;
1696
1697               if (notation->critical)
1698                 *(argp++) = '!';
1699
1700               memcpy (argp, notation->name, notation->name_len);
1701               argp += notation->name_len;
1702
1703               *(argp++) = '=';
1704
1705               /* We know that notation->name is '\0' terminated.  */
1706               strcpy (argp, notation->value);
1707             }
1708
1709           if (!err)
1710             err = add_arg (gpg, "--sig-notation");
1711           if (!err)
1712             err = add_arg (gpg, arg);
1713
1714           if (arg)
1715             free (arg);
1716         }
1717       else
1718         {
1719           /* This is a policy URL.  */
1720
1721           char *value;
1722
1723           if (notation->critical)
1724             {
1725               value = malloc (1 + notation->value_len + 1);
1726               if (!value)
1727                 err = gpg_error_from_syserror ();
1728               else
1729                 {
1730                   value[0] = '!';
1731                   /* We know that notation->value is '\0' terminated.  */
1732                   strcpy (&value[1], notation->value);
1733                 }
1734             }
1735           else
1736             value = notation->value;
1737
1738           if (!err)
1739             err = add_arg (gpg, "--sig-policy-url");
1740           if (!err)
1741             err = add_arg (gpg, value);
1742
1743           if (value != notation->value)
1744             free (value);
1745         }
1746
1747       notation = notation->next;
1748     }
1749   return err;
1750 }
1751
1752
1753 static gpgme_error_t
1754 gpg_edit (void *engine, int type, gpgme_key_t key, gpgme_data_t out,
1755           gpgme_ctx_t ctx /* FIXME */)
1756 {
1757   engine_gpg_t gpg = engine;
1758   gpgme_error_t err;
1759
1760   err = add_arg (gpg, "--with-colons");
1761   if (!err)
1762     err = append_args_from_signers (gpg, ctx);
1763   if (!err)
1764   err = add_arg (gpg, type == 0 ? "--edit-key" : "--card-edit");
1765   if (!err)
1766     err = add_data (gpg, out, 1, 1);
1767   if (!err)
1768     err = add_arg (gpg, "--");
1769   if (!err && type == 0)
1770     {
1771       const char *s = key->subkeys ? key->subkeys->fpr : NULL;
1772       if (!s)
1773         err = gpg_error (GPG_ERR_INV_VALUE);
1774       else
1775         err = add_arg (gpg, s);
1776     }
1777   if (!err)
1778     err = start (gpg);
1779
1780   return err;
1781 }
1782
1783
1784 static gpgme_error_t
1785 append_args_from_recipients (engine_gpg_t gpg, gpgme_key_t recp[])
1786 {
1787   gpgme_error_t err = 0;
1788   int i = 0;
1789
1790   while (recp[i])
1791     {
1792       if (!recp[i]->subkeys || !recp[i]->subkeys->fpr)
1793         err = gpg_error (GPG_ERR_INV_VALUE);
1794       if (!err)
1795         err = add_arg (gpg, "-r");
1796       if (!err)
1797         err = add_arg (gpg, recp[i]->subkeys->fpr);
1798       if (err)
1799         break;
1800       i++;
1801     }
1802   return err;
1803 }
1804
1805
1806 static gpgme_error_t
1807 gpg_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
1808              gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
1809 {
1810   engine_gpg_t gpg = engine;
1811   gpgme_error_t err = 0;
1812
1813   if (recp)
1814     err = add_arg (gpg, "--encrypt");
1815
1816   if (!err && ((flags & GPGME_ENCRYPT_SYMMETRIC) || !recp))
1817     err = add_arg (gpg, "--symmetric");
1818
1819   if (!err && use_armor)
1820     err = add_arg (gpg, "--armor");
1821
1822   if (!err && (flags & GPGME_ENCRYPT_NO_COMPRESS))
1823     err = add_arg (gpg, "--compress-algo=none");
1824
1825   if (gpgme_data_get_encoding (plain) == GPGME_DATA_ENCODING_MIME
1826       && have_gpg_version (gpg, "2.1.14"))
1827     err = add_arg (gpg, "--mimemode");
1828
1829   if (recp)
1830     {
1831       /* If we know that all recipients are valid (full or ultimate trust)
1832          we can suppress further checks.  */
1833       if (!err && (flags & GPGME_ENCRYPT_ALWAYS_TRUST))
1834         err = add_arg (gpg, "--always-trust");
1835
1836       if (!err && (flags & GPGME_ENCRYPT_NO_ENCRYPT_TO))
1837         err = add_arg (gpg, "--no-encrypt-to");
1838
1839       if (!err)
1840         err = append_args_from_recipients (gpg, recp);
1841     }
1842
1843   /* Tell the gpg object about the data.  */
1844   if (!err)
1845     err = add_arg (gpg, "--output");
1846   if (!err)
1847     err = add_arg (gpg, "-");
1848   if (!err)
1849     err = add_data (gpg, ciph, 1, 1);
1850   if (gpgme_data_get_file_name (plain))
1851     {
1852       if (!err)
1853         err = add_arg (gpg, "--set-filename");
1854       if (!err)
1855         err = add_arg (gpg, gpgme_data_get_file_name (plain));
1856     }
1857   if (!err)
1858     err = add_input_size_hint (gpg, plain);
1859   if (!err)
1860     err = add_arg (gpg, "--");
1861   if (!err)
1862     err = add_data (gpg, plain, -1, 0);
1863
1864   if (!err)
1865     err = start (gpg);
1866
1867   return err;
1868 }
1869
1870
1871 static gpgme_error_t
1872 gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
1873                   gpgme_encrypt_flags_t flags, gpgme_data_t plain,
1874                   gpgme_data_t ciph, int use_armor,
1875                   gpgme_ctx_t ctx /* FIXME */)
1876 {
1877   engine_gpg_t gpg = engine;
1878   gpgme_error_t err = 0;
1879
1880   if (recp)
1881     err = add_arg (gpg, "--encrypt");
1882
1883   if (!err && ((flags & GPGME_ENCRYPT_SYMMETRIC) || !recp))
1884     err = add_arg (gpg, "--symmetric");
1885
1886   if (!err)
1887     err = add_arg (gpg, "--sign");
1888   if (!err && use_armor)
1889     err = add_arg (gpg, "--armor");
1890
1891   if (!err && (flags & GPGME_ENCRYPT_NO_COMPRESS))
1892     err = add_arg (gpg, "--compress-algo=none");
1893
1894   if (gpgme_data_get_encoding (plain) == GPGME_DATA_ENCODING_MIME
1895       && have_gpg_version (gpg, "2.1.14"))
1896     err = add_arg (gpg, "--mimemode");
1897
1898   if (recp)
1899     {
1900       /* If we know that all recipients are valid (full or ultimate trust)
1901          we can suppress further checks.  */
1902       if (!err && (flags & GPGME_ENCRYPT_ALWAYS_TRUST))
1903         err = add_arg (gpg, "--always-trust");
1904
1905       if (!err && (flags & GPGME_ENCRYPT_NO_ENCRYPT_TO))
1906         err = add_arg (gpg, "--no-encrypt-to");
1907
1908       if (!err)
1909         err = append_args_from_recipients (gpg, recp);
1910     }
1911
1912   if (!err)
1913     err = append_args_from_signers (gpg, ctx);
1914
1915   if (!err)
1916     err = append_args_from_sender (gpg, ctx);
1917
1918   if (!err)
1919     err = append_args_from_sig_notations (gpg, ctx);
1920
1921   /* Tell the gpg object about the data.  */
1922   if (!err)
1923     err = add_arg (gpg, "--output");
1924   if (!err)
1925     err = add_arg (gpg, "-");
1926   if (!err)
1927     err = add_data (gpg, ciph, 1, 1);
1928   if (gpgme_data_get_file_name (plain))
1929     {
1930       if (!err)
1931         err = add_arg (gpg, "--set-filename");
1932       if (!err)
1933         err = add_arg (gpg, gpgme_data_get_file_name (plain));
1934     }
1935   if (!err)
1936     err = add_input_size_hint (gpg, plain);
1937   if (!err)
1938     err = add_arg (gpg, "--");
1939   if (!err)
1940     err = add_data (gpg, plain, -1, 0);
1941
1942   if (!err)
1943     err = start (gpg);
1944
1945   return err;
1946 }
1947
1948
1949 static gpgme_error_t
1950 export_common (engine_gpg_t gpg, gpgme_export_mode_t mode,
1951                gpgme_data_t keydata, int use_armor)
1952 {
1953   gpgme_error_t err = 0;
1954
1955   if ((mode & ~(GPGME_EXPORT_MODE_EXTERN
1956                 |GPGME_EXPORT_MODE_MINIMAL
1957                 |GPGME_EXPORT_MODE_SECRET)))
1958     return gpg_error (GPG_ERR_NOT_SUPPORTED);
1959
1960   if ((mode & GPGME_EXPORT_MODE_MINIMAL))
1961     err = add_arg (gpg, "--export-options=export-minimal");
1962
1963   if (err)
1964     ;
1965   else if ((mode & GPGME_EXPORT_MODE_EXTERN))
1966     {
1967       err = add_arg (gpg, "--send-keys");
1968     }
1969   else
1970     {
1971       if ((mode & GPGME_EXPORT_MODE_SECRET))
1972         err = add_arg (gpg, "--export-secret-keys");
1973       else
1974         err = add_arg (gpg, "--export");
1975       if (!err && use_armor)
1976         err = add_arg (gpg, "--armor");
1977       if (!err)
1978         err = add_data (gpg, keydata, 1, 1);
1979     }
1980   if (!err)
1981     err = add_arg (gpg, "--");
1982
1983   return err;
1984 }
1985
1986
1987 static gpgme_error_t
1988 gpg_export (void *engine, const char *pattern, gpgme_export_mode_t mode,
1989             gpgme_data_t keydata, int use_armor)
1990 {
1991   engine_gpg_t gpg = engine;
1992   gpgme_error_t err;
1993
1994   err = export_common (gpg, mode, keydata, use_armor);
1995
1996   if (!err && pattern && *pattern)
1997     err = add_arg (gpg, pattern);
1998
1999   if (!err)
2000     err = start (gpg);
2001
2002   return err;
2003 }
2004
2005
2006 static gpgme_error_t
2007 gpg_export_ext (void *engine, const char *pattern[], gpgme_export_mode_t mode,
2008                 gpgme_data_t keydata, int use_armor)
2009 {
2010   engine_gpg_t gpg = engine;
2011   gpgme_error_t err;
2012
2013   err = export_common (gpg, mode, keydata, use_armor);
2014
2015   if (pattern)
2016     {
2017       while (!err && *pattern && **pattern)
2018         err = add_arg (gpg, *(pattern++));
2019     }
2020
2021   if (!err)
2022     err = start (gpg);
2023
2024   return err;
2025 }
2026
2027
2028 \f
2029 /* Helper to add algo, usage, and expire to the list of args.  */
2030 static gpgme_error_t
2031 gpg_add_algo_usage_expire (engine_gpg_t gpg,
2032                            const char *algo,
2033                            unsigned long expires,
2034                            unsigned int flags)
2035 {
2036   gpg_error_t err;
2037
2038   /* This condition is only required to allow the use of gpg < 2.1.16 */
2039   if (algo
2040       || (flags & (GPGME_CREATE_SIGN | GPGME_CREATE_ENCR
2041                    | GPGME_CREATE_CERT | GPGME_CREATE_AUTH))
2042       || expires)
2043     {
2044       err = add_arg (gpg, algo? algo : "default");
2045       if (!err)
2046         {
2047           char tmpbuf[5*4+1];
2048           snprintf (tmpbuf, sizeof tmpbuf, "%s%s%s%s",
2049                     (flags & GPGME_CREATE_SIGN)? " sign":"",
2050                     (flags & GPGME_CREATE_ENCR)? " encr":"",
2051                     (flags & GPGME_CREATE_CERT)? " cert":"",
2052                     (flags & GPGME_CREATE_AUTH)? " auth":"");
2053           err = add_arg (gpg, *tmpbuf? tmpbuf : "default");
2054         }
2055       if (!err && expires)
2056         {
2057           char tmpbuf[8+20];
2058           snprintf (tmpbuf, sizeof tmpbuf, "seconds=%lu", expires);
2059           err = add_arg (gpg, tmpbuf);
2060         }
2061     }
2062   else
2063     err = 0;
2064
2065   return err;
2066 }
2067
2068
2069 static gpgme_error_t
2070 gpg_createkey_from_param (engine_gpg_t gpg,
2071                           gpgme_data_t help_data, unsigned int extraflags)
2072 {
2073   gpgme_error_t err;
2074
2075   err = add_arg (gpg, "--gen-key");
2076   if (!err && (extraflags & GENKEY_EXTRAFLAG_ARMOR))
2077     err = add_arg (gpg, "--armor");
2078   if (!err)
2079     err = add_arg (gpg, "--");
2080   if (!err)
2081     err = add_data (gpg, help_data, -1, 0);
2082   if (!err)
2083     err = start (gpg);
2084   return err;
2085 }
2086
2087
2088 static gpgme_error_t
2089 gpg_createkey (engine_gpg_t gpg,
2090                const char *userid, const char *algo,
2091                unsigned long expires,
2092                unsigned int flags,
2093                unsigned int extraflags)
2094 {
2095   gpgme_error_t err;
2096
2097   err = add_arg (gpg, "--quick-gen-key");
2098   if (!err && (extraflags & GENKEY_EXTRAFLAG_ARMOR))
2099     err = add_arg (gpg, "--armor");
2100   if (!err && (flags & GPGME_CREATE_NOPASSWD))
2101     {
2102       err = add_arg (gpg, "--passphrase");
2103       if (!err)
2104         err = add_arg (gpg, "");
2105     }
2106   if (!err && (flags & GPGME_CREATE_FORCE))
2107     err = add_arg (gpg, "--yes");
2108   if (!err)
2109     err = add_arg (gpg, "--");
2110   if (!err)
2111     err = add_arg (gpg, userid);
2112
2113   if (!err)
2114     err = gpg_add_algo_usage_expire (gpg, algo, expires, flags);
2115
2116   if (!err)
2117     err = start (gpg);
2118   return err;
2119 }
2120
2121
2122 static gpgme_error_t
2123 gpg_addkey (engine_gpg_t gpg,
2124             const char *algo,
2125             unsigned long expires,
2126             gpgme_key_t key,
2127             unsigned int flags,
2128             unsigned int extraflags)
2129 {
2130   gpgme_error_t err;
2131
2132   if (!key || !key->fpr)
2133     return gpg_error (GPG_ERR_INV_ARG);
2134
2135   err = add_arg (gpg, "--quick-addkey");
2136   if (!err && (extraflags & GENKEY_EXTRAFLAG_ARMOR))
2137     err = add_arg (gpg, "--armor");
2138   if (!err && (flags & GPGME_CREATE_NOPASSWD))
2139     {
2140       err = add_arg (gpg, "--passphrase");
2141       if (!err)
2142         err = add_arg (gpg, "");
2143     }
2144   if (!err)
2145     err = add_arg (gpg, "--");
2146   if (!err)
2147     err = add_arg (gpg, key->fpr);
2148
2149   if (!err)
2150     err = gpg_add_algo_usage_expire (gpg, algo, expires, flags);
2151
2152   if (!err)
2153     err = start (gpg);
2154   return err;
2155 }
2156
2157
2158 static gpgme_error_t
2159 gpg_adduid (engine_gpg_t gpg,
2160             gpgme_key_t key,
2161             const char *userid,
2162             unsigned int extraflags)
2163 {
2164   gpgme_error_t err;
2165
2166   if (!key || !key->fpr || !userid)
2167     return gpg_error (GPG_ERR_INV_ARG);
2168
2169   if ((extraflags & GENKEY_EXTRAFLAG_REVOKE))
2170     err = add_arg (gpg, "--quick-revuid");
2171   else
2172     err = add_arg (gpg, "--quick-adduid");
2173
2174   if (!err)
2175     err = add_arg (gpg, "--");
2176   if (!err)
2177     err = add_arg (gpg, key->fpr);
2178   if (!err)
2179     err = add_arg (gpg, userid);
2180
2181   if (!err)
2182     err = start (gpg);
2183   return err;
2184 }
2185
2186
2187 static gpgme_error_t
2188 gpg_genkey (void *engine,
2189             const char *userid, const char *algo,
2190             unsigned long reserved, unsigned long expires,
2191             gpgme_key_t key, unsigned int flags,
2192             gpgme_data_t help_data, unsigned int extraflags,
2193             gpgme_data_t pubkey, gpgme_data_t seckey)
2194 {
2195   engine_gpg_t gpg = engine;
2196   gpgme_error_t err;
2197
2198   (void)reserved;
2199
2200   if (!gpg)
2201     return gpg_error (GPG_ERR_INV_VALUE);
2202
2203   /* If HELP_DATA is given the use of the old interface
2204    * (gpgme_op_genkey) has been requested.  The other modes are:
2205    *
2206    *  USERID && !KEY          - Create a new keyblock.
2207    * !USERID &&  KEY          - Add a new subkey to KEY (gpg >= 2.1.14)
2208    *  USERID &&  KEY && !ALGO - Add a new user id to KEY (gpg >= 2.1.14).
2209    *
2210    */
2211   if (help_data)
2212     {
2213       /* We need a special mechanism to get the fd of a pipe here, so
2214          that we can use this for the %pubring and %secring
2215          parameters.  We don't have this yet, so we implement only the
2216          adding to the standard keyrings.  */
2217       if (pubkey || seckey)
2218         err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
2219       else
2220         err = gpg_createkey_from_param (gpg, help_data, extraflags);
2221     }
2222   else if (!have_gpg_version (gpg, "2.1.13"))
2223     err = gpg_error (GPG_ERR_NOT_SUPPORTED);
2224   else if (userid && !key)
2225     err = gpg_createkey (gpg, userid, algo, expires, flags, extraflags);
2226   else if (!userid && key)
2227     err = gpg_addkey (gpg, algo, expires, key, flags, extraflags);
2228   else if (userid && key && !algo)
2229     err = gpg_adduid (gpg, key, userid, extraflags);
2230   else
2231     err = gpg_error (GPG_ERR_INV_VALUE);
2232
2233   return err;
2234 }
2235
2236 /* Return the next DELIM delimited string from DATA as a C-string.
2237    The caller needs to provide the address of a pointer variable which
2238    he has to set to NULL before the first call.  After the last call
2239    to this function, this function needs to be called once more with
2240    DATA set to NULL so that the function can release its internal
2241    state.  After that the pointer variable is free for use again.
2242    Note that we use a delimiter and thus a trailing delimiter is not
2243    required.  DELIM may not be changed after the first call. */
2244 static const char *
2245 string_from_data (gpgme_data_t data, int delim,
2246                   void **helpptr, gpgme_error_t *r_err)
2247 {
2248 #define MYBUFLEN 2000 /* Fixme: We don't support URLs longer than that.  */
2249   struct {
2250     int  eof_seen;
2251     int  nbytes;      /* Length of the last returned string including
2252                          the delimiter. */
2253     int  buflen;      /* Valid length of BUF.  */
2254     char buf[MYBUFLEN+1];  /* Buffer with one byte extra space.  */
2255   } *self;
2256   char *p;
2257   int nread;
2258
2259   *r_err = 0;
2260   if (!data)
2261     {
2262       if (*helpptr)
2263         {
2264           free (*helpptr);
2265           *helpptr = NULL;
2266         }
2267       return NULL;
2268     }
2269
2270   if (*helpptr)
2271     self = *helpptr;
2272   else
2273     {
2274       self = malloc (sizeof *self);
2275       if (!self)
2276         {
2277           *r_err = gpg_error_from_syserror ();
2278           return NULL;
2279         }
2280       *helpptr = self;
2281       self->eof_seen = 0;
2282       self->nbytes = 0;
2283       self->buflen = 0;
2284     }
2285
2286   if (self->eof_seen)
2287     return NULL;
2288
2289   assert (self->nbytes <= self->buflen);
2290   memmove (self->buf, self->buf + self->nbytes, self->buflen - self->nbytes);
2291   self->buflen -= self->nbytes;
2292   self->nbytes = 0;
2293
2294   do
2295     {
2296       /* Fixme: This is fairly infective scanning because we may scan
2297          the buffer several times.  */
2298       p = memchr (self->buf, delim, self->buflen);
2299       if (p)
2300         {
2301           *p = 0;
2302           self->nbytes = p - self->buf + 1;
2303           return self->buf;
2304         }
2305
2306       if ( !(MYBUFLEN - self->buflen) )
2307         {
2308           /* Not enough space - URL too long.  */
2309           *r_err = gpg_error (GPG_ERR_TOO_LARGE);
2310           return NULL;
2311         }
2312
2313       nread = gpgme_data_read (data, self->buf + self->buflen,
2314                                MYBUFLEN - self->buflen);
2315       if (nread < 0)
2316         {
2317           *r_err = gpg_error_from_syserror ();
2318           return NULL;
2319         }
2320       self->buflen += nread;
2321     }
2322   while (nread);
2323
2324   /* EOF reached.  If we have anything in the buffer, append a Nul and
2325      return it. */
2326   self->eof_seen = 1;
2327   if (self->buflen)
2328     {
2329       self->buf[self->buflen] = 0;  /* (we allocated one extra byte)  */
2330       return self->buf;
2331     }
2332   return NULL;
2333 #undef MYBUFLEN
2334 }
2335
2336
2337
2338 static gpgme_error_t
2339 gpg_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray)
2340 {
2341   engine_gpg_t gpg = engine;
2342   gpgme_error_t err;
2343   int idx;
2344   gpgme_data_encoding_t dataenc;
2345
2346   if (keydata && keyarray)
2347     return gpg_error (GPG_ERR_INV_VALUE); /* Only one is allowed.  */
2348
2349   dataenc = gpgme_data_get_encoding (keydata);
2350
2351   if (keyarray)
2352     {
2353       err = add_arg (gpg, "--recv-keys");
2354       if (!err)
2355         err = add_arg (gpg, "--");
2356       for (idx=0; !err && keyarray[idx]; idx++)
2357         {
2358           if (keyarray[idx]->protocol != GPGME_PROTOCOL_OpenPGP)
2359             ;
2360           else if (!keyarray[idx]->subkeys)
2361             ;
2362           else if (keyarray[idx]->subkeys->fpr && *keyarray[idx]->subkeys->fpr)
2363             err = add_arg (gpg, keyarray[idx]->subkeys->fpr);
2364           else if (*keyarray[idx]->subkeys->keyid)
2365             err = add_arg (gpg, keyarray[idx]->subkeys->keyid);
2366         }
2367     }
2368   else if (dataenc == GPGME_DATA_ENCODING_URL
2369            || dataenc == GPGME_DATA_ENCODING_URL0)
2370     {
2371       void *helpptr;
2372       const char *string;
2373       gpgme_error_t xerr;
2374       int delim = (dataenc == GPGME_DATA_ENCODING_URL)? '\n': 0;
2375
2376       /* FIXME: --fetch-keys is probably not correct because it can't
2377          grok all kinds of URLs.  On Unix it should just work but on
2378          Windows we will build the command line and that may fail for
2379          some embedded control characters.  It is anyway limited to
2380          the maximum size of the command line.  We need another
2381          command which can take its input from a file.  Maybe we
2382          should use an option to gpg to modify such commands (ala
2383          --multifile).  */
2384       err = add_arg (gpg, "--fetch-keys");
2385       if (!err)
2386         err = add_arg (gpg, "--");
2387       helpptr = NULL;
2388       while (!err
2389              && (string = string_from_data (keydata, delim, &helpptr, &xerr)))
2390         err = add_arg (gpg, string);
2391       if (!err)
2392         err = xerr;
2393       string_from_data (NULL, delim, &helpptr, &xerr);
2394     }
2395   else if (dataenc == GPGME_DATA_ENCODING_URLESC)
2396     {
2397       /* Already escaped URLs are not yet supported.  */
2398       err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
2399     }
2400   else
2401     {
2402       err = add_arg (gpg, "--import");
2403       if (!err)
2404         err = add_arg (gpg, "--");
2405       if (!err)
2406         err = add_data (gpg, keydata, -1, 0);
2407     }
2408
2409   if (!err)
2410     err = start (gpg);
2411
2412   return err;
2413 }
2414
2415
2416 /* The output for external keylistings in GnuPG is different from all
2417    the other key listings.  We catch this here with a special
2418    preprocessor that reformats the colon handler lines.  */
2419 static gpgme_error_t
2420 gpg_keylist_preprocess (char *line, char **r_line)
2421 {
2422   enum
2423     {
2424       RT_NONE, RT_INFO, RT_PUB, RT_UID
2425     }
2426   rectype = RT_NONE;
2427 #define NR_FIELDS 16
2428   char *field[NR_FIELDS];
2429   int fields = 0;
2430   size_t n;
2431
2432   *r_line = NULL;
2433
2434   while (line && fields < NR_FIELDS)
2435     {
2436       field[fields++] = line;
2437       line = strchr (line, ':');
2438       if (line)
2439         *(line++) = '\0';
2440     }
2441
2442   if (!strcmp (field[0], "info"))
2443     rectype = RT_INFO;
2444   else if (!strcmp (field[0], "pub"))
2445     rectype = RT_PUB;
2446   else if (!strcmp (field[0], "uid"))
2447     rectype = RT_UID;
2448   else
2449     rectype = RT_NONE;
2450
2451   switch (rectype)
2452     {
2453     case RT_INFO:
2454       /* FIXME: Eventually, check the version number at least.  */
2455       return 0;
2456
2457     case RT_PUB:
2458       if (fields < 7)
2459         return 0;
2460
2461       /* The format is:
2462
2463          pub:<keyid>:<algo>:<keylen>:<creationdate>:<expirationdate>:<flags>
2464
2465          as defined in 5.2. Machine Readable Indexes of the OpenPGP
2466          HTTP Keyserver Protocol (draft).  Modern versions of the SKS
2467          keyserver return the fingerprint instead of the keyid.  We
2468          detect this here and use the v4 fingerprint format to convert
2469          it to a key id.
2470
2471          We want:
2472          pub:o<flags>:<keylen>:<algo>:<keyid>:<creatdate>:<expdate>::::::::
2473       */
2474
2475       n = strlen (field[1]);
2476       if (n > 16)
2477         {
2478           if (asprintf (r_line,
2479                         "pub:o%s:%s:%s:%s:%s:%s::::::::\n"
2480                         "fpr:::::::::%s:",
2481                         field[6], field[3], field[2], field[1] + n - 16,
2482                         field[4], field[5], field[1]) < 0)
2483             return gpg_error_from_syserror ();
2484         }
2485       else
2486         {
2487           if (asprintf (r_line,
2488                         "pub:o%s:%s:%s:%s:%s:%s::::::::",
2489                         field[6], field[3], field[2], field[1],
2490                         field[4], field[5]) < 0)
2491             return gpg_error_from_syserror ();
2492         }
2493
2494       return 0;
2495
2496     case RT_UID:
2497       /* The format is:
2498
2499          uid:<escaped uid string>:<creationdate>:<expirationdate>:<flags>
2500
2501          as defined in 5.2. Machine Readable Indexes of the OpenPGP
2502          HTTP Keyserver Protocol (draft).
2503
2504          We want:
2505          uid:o<flags>::::<creatdate>:<expdate>:::<c-coded uid>:
2506       */
2507
2508       {
2509         /* The user ID is percent escaped, but we want c-coded.
2510            Because we have to replace each '%HL' by '\xHL', we need at
2511            most 4/3 th the number of bytes.  But because we also need
2512            to escape the backslashes we allocate twice as much.  */
2513         char *uid = malloc (2 * strlen (field[1]) + 1);
2514         char *src;
2515         char *dst;
2516
2517         if (! uid)
2518           return gpg_error_from_syserror ();
2519         src = field[1];
2520         dst = uid;
2521         while (*src)
2522           {
2523             if (*src == '%')
2524               {
2525                 *(dst++) = '\\';
2526                 *(dst++) = 'x';
2527                 src++;
2528                 /* Copy the next two bytes unconditionally.  */
2529                 if (*src)
2530                   *(dst++) = *(src++);
2531                 if (*src)
2532                   *(dst++) = *(src++);
2533               }
2534             else if (*src == '\\')
2535               {
2536                 *dst++ = '\\';
2537                 *dst++ = '\\';
2538                 src++;
2539               }
2540             else
2541               *(dst++) = *(src++);
2542           }
2543         *dst = '\0';
2544
2545         if (asprintf (r_line, "uid:o%s::::%s:%s:::%s:",
2546                       field[4], field[2], field[3], uid) < 0)
2547           return gpg_error_from_syserror ();
2548       }
2549       return 0;
2550
2551     case RT_NONE:
2552       /* Unknown record.  */
2553       break;
2554     }
2555   return 0;
2556
2557 }
2558
2559
2560 static gpg_error_t
2561 gpg_keylist_build_options (engine_gpg_t gpg, int secret_only,
2562                            gpgme_keylist_mode_t mode)
2563 {
2564   gpg_error_t err;
2565
2566   err = add_arg (gpg, "--with-colons");
2567
2568   /* Since gpg 2.1.15 fingerprints are always printed, thus there is
2569    * no more need to explicitly request them.  */
2570   if (!have_gpg_version (gpg, "2.1.15"))
2571     {
2572       if (!err)
2573         err = add_arg (gpg, "--fixed-list-mode");
2574       if (!err)
2575         err = add_arg (gpg, "--with-fingerprint");
2576       if (!err)
2577         err = add_arg (gpg, "--with-fingerprint");
2578     }
2579
2580   if (!err && (mode & GPGME_KEYLIST_MODE_WITH_TOFU)
2581       && have_gpg_version (gpg, "2.1.16"))
2582     err = add_arg (gpg, "--with-tofu-info");
2583
2584   if (!err && (mode & GPGME_KEYLIST_MODE_WITH_SECRET))
2585     err = add_arg (gpg, "--with-secret");
2586
2587   if (!err
2588       && (mode & GPGME_KEYLIST_MODE_SIGS)
2589       && (mode & GPGME_KEYLIST_MODE_SIG_NOTATIONS))
2590     {
2591       err = add_arg (gpg, "--list-options");
2592       if (!err)
2593         err = add_arg (gpg, "show-sig-subpackets=\"20,26\"");
2594     }
2595
2596   if (!err)
2597     {
2598       if ( (mode & GPGME_KEYLIST_MODE_EXTERN) )
2599         {
2600           if (secret_only)
2601             err = gpg_error (GPG_ERR_NOT_SUPPORTED);
2602           else if ( (mode & GPGME_KEYLIST_MODE_LOCAL))
2603             {
2604               /* The local+extern mode is special.  It works only with
2605                  gpg >= 2.0.10.  FIXME: We should check that we have
2606                  such a version to that we can return a proper error
2607                  code.  The problem is that we don't know the context
2608                  here and thus can't access the cached version number
2609                  for the engine info structure.  */
2610               err = add_arg (gpg, "--locate-keys");
2611               if ((mode & GPGME_KEYLIST_MODE_SIGS))
2612                 err = add_arg (gpg, "--with-sig-check");
2613             }
2614           else
2615             {
2616               err = add_arg (gpg, "--search-keys");
2617               gpg->colon.preprocess_fnc = gpg_keylist_preprocess;
2618             }
2619         }
2620       else
2621         {
2622           err = add_arg (gpg, secret_only ? "--list-secret-keys"
2623                          : ((mode & GPGME_KEYLIST_MODE_SIGS)
2624                             ? "--check-sigs" : "--list-keys"));
2625         }
2626     }
2627
2628   if (!err)
2629     err = add_arg (gpg, "--");
2630
2631   return err;
2632 }
2633
2634
2635 static gpgme_error_t
2636 gpg_keylist (void *engine, const char *pattern, int secret_only,
2637              gpgme_keylist_mode_t mode, int engine_flags)
2638 {
2639   engine_gpg_t gpg = engine;
2640   gpgme_error_t err;
2641
2642   (void)engine_flags;
2643
2644   err = gpg_keylist_build_options (gpg, secret_only, mode);
2645
2646   if (!err && pattern && *pattern)
2647     err = add_arg (gpg, pattern);
2648
2649   if (!err)
2650     err = start (gpg);
2651
2652   return err;
2653 }
2654
2655
2656 static gpgme_error_t
2657 gpg_keylist_ext (void *engine, const char *pattern[], int secret_only,
2658                  int reserved, gpgme_keylist_mode_t mode, int engine_flags)
2659 {
2660   engine_gpg_t gpg = engine;
2661   gpgme_error_t err;
2662
2663   (void)engine_flags;
2664
2665   if (reserved)
2666     return gpg_error (GPG_ERR_INV_VALUE);
2667
2668   err = gpg_keylist_build_options (gpg, secret_only, mode);
2669
2670   if (pattern)
2671     {
2672       while (!err && *pattern && **pattern)
2673         err = add_arg (gpg, *(pattern++));
2674     }
2675
2676   if (!err)
2677     err = start (gpg);
2678
2679   return err;
2680 }
2681
2682
2683 static gpgme_error_t
2684 gpg_keysign (void *engine, gpgme_key_t key, const char *userid,
2685              unsigned long expire, unsigned int flags,
2686              gpgme_ctx_t ctx)
2687 {
2688   engine_gpg_t gpg = engine;
2689   gpgme_error_t err;
2690   const char *s;
2691
2692   if (!key || !key->fpr)
2693     return gpg_error (GPG_ERR_INV_ARG);
2694
2695   if (!have_gpg_version (gpg, "2.1.12"))
2696     return gpg_error (GPG_ERR_NOT_SUPPORTED);
2697
2698   if ((flags & GPGME_KEYSIGN_LOCAL))
2699     err = add_arg (gpg, "--quick-lsign-key");
2700   else
2701     err = add_arg (gpg, "--quick-sign-key");
2702
2703   if (!err)
2704     err = append_args_from_signers (gpg, ctx);
2705
2706   /* If an expiration time has been given use that.  If none has been
2707    * given the default from gpg.conf is used.  To make sure not to set
2708    * an expiration time at all the flag GPGME_KEYSIGN_NOEXPIRE can be
2709    * used.  */
2710   if (!err && (expire || (flags & GPGME_KEYSIGN_NOEXPIRE)))
2711     {
2712       char tmpbuf[8+20];
2713
2714       if ((flags & GPGME_KEYSIGN_NOEXPIRE))
2715         expire = 0;
2716       snprintf (tmpbuf, sizeof tmpbuf, "seconds=%lu", expire);
2717       err = add_arg (gpg, "--default-cert-expire");
2718       if (!err)
2719         err = add_arg (gpg, tmpbuf);
2720     }
2721
2722   if (!err)
2723     err = add_arg (gpg, "--");
2724
2725   if (!err)
2726     err = add_arg (gpg, key->fpr);
2727   if (!err && userid)
2728     {
2729       if ((flags & GPGME_KEYSIGN_LFSEP))
2730         {
2731           for (; !err && (s = strchr (userid, '\n')); userid = s + 1)
2732             if ((s - userid))
2733               err = add_arg_len (gpg, "=", userid, s - userid);
2734           if (!err && *userid)
2735             err = add_arg_pfx (gpg, "=", userid);
2736         }
2737       else
2738         err = add_arg_pfx (gpg, "=", userid);
2739     }
2740
2741   if (!err)
2742     err = start (gpg);
2743
2744   return err;
2745 }
2746
2747
2748 static gpgme_error_t
2749 gpg_tofu_policy (void *engine, gpgme_key_t key, gpgme_tofu_policy_t policy)
2750 {
2751   engine_gpg_t gpg = engine;
2752   gpgme_error_t err;
2753   const char *policystr = NULL;
2754
2755   if (!key || !key->fpr)
2756     return gpg_error (GPG_ERR_INV_ARG);
2757
2758   switch (policy)
2759     {
2760     case GPGME_TOFU_POLICY_NONE:                           break;
2761     case GPGME_TOFU_POLICY_AUTO:    policystr = "auto";    break;
2762     case GPGME_TOFU_POLICY_GOOD:    policystr = "good";    break;
2763     case GPGME_TOFU_POLICY_BAD:     policystr = "bad";     break;
2764     case GPGME_TOFU_POLICY_ASK:     policystr = "ask";     break;
2765     case GPGME_TOFU_POLICY_UNKNOWN: policystr = "unknown"; break;
2766     }
2767   if (!policystr)
2768     return gpg_error (GPG_ERR_INV_VALUE);
2769
2770   if (!have_gpg_version (gpg, "2.1.10"))
2771     return gpg_error (GPG_ERR_NOT_SUPPORTED);
2772
2773   err = add_arg (gpg, "--tofu-policy");
2774   if (!err)
2775     err = add_arg (gpg, "--");
2776   if (!err)
2777     err = add_arg (gpg, policystr);
2778   if (!err)
2779     err = add_arg (gpg, key->fpr);
2780
2781   if (!err)
2782     err = start (gpg);
2783
2784   return err;
2785 }
2786
2787
2788 static gpgme_error_t
2789 gpg_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
2790           gpgme_sig_mode_t mode, int use_armor, int use_textmode,
2791           int include_certs, gpgme_ctx_t ctx /* FIXME */)
2792 {
2793   engine_gpg_t gpg = engine;
2794   gpgme_error_t err;
2795
2796   (void)include_certs;
2797
2798   if (mode == GPGME_SIG_MODE_CLEAR)
2799     err = add_arg (gpg, "--clearsign");
2800   else
2801     {
2802       err = add_arg (gpg, "--sign");
2803       if (!err && mode == GPGME_SIG_MODE_DETACH)
2804         err = add_arg (gpg, "--detach");
2805       if (!err && use_armor)
2806         err = add_arg (gpg, "--armor");
2807       if (!err)
2808         {
2809           if (gpgme_data_get_encoding (in) == GPGME_DATA_ENCODING_MIME
2810               && have_gpg_version (gpg, "2.1.14"))
2811             err = add_arg (gpg, "--mimemode");
2812           else if (use_textmode)
2813             err = add_arg (gpg, "--textmode");
2814         }
2815     }
2816
2817   if (!err)
2818     err = append_args_from_signers (gpg, ctx);
2819   if (!err)
2820     err = append_args_from_sender (gpg, ctx);
2821   if (!err)
2822     err = append_args_from_sig_notations (gpg, ctx);
2823
2824   if (gpgme_data_get_file_name (in))
2825     {
2826       if (!err)
2827         err = add_arg (gpg, "--set-filename");
2828       if (!err)
2829         err = add_arg (gpg, gpgme_data_get_file_name (in));
2830     }
2831
2832   /* Tell the gpg object about the data.  */
2833   if (!err)
2834     err = add_input_size_hint (gpg, in);
2835   if (!err)
2836     err = add_arg (gpg, "--");
2837   if (!err)
2838     err = add_data (gpg, in, -1, 0);
2839   if (!err)
2840     err = add_data (gpg, out, 1, 1);
2841
2842   if (!err)
2843     err = start (gpg);
2844
2845   return err;
2846 }
2847
2848 static gpgme_error_t
2849 gpg_trustlist (void *engine, const char *pattern)
2850 {
2851   engine_gpg_t gpg = engine;
2852   gpgme_error_t err;
2853
2854   err = add_arg (gpg, "--with-colons");
2855   if (!err)
2856     err = add_arg (gpg, "--list-trust-path");
2857
2858   /* Tell the gpg object about the data.  */
2859   if (!err)
2860     err = add_arg (gpg, "--");
2861   if (!err)
2862     err = add_arg (gpg, pattern);
2863
2864   if (!err)
2865     err = start (gpg);
2866
2867   return err;
2868 }
2869
2870
2871 static gpgme_error_t
2872 gpg_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
2873             gpgme_data_t plaintext, gpgme_ctx_t ctx)
2874 {
2875   engine_gpg_t gpg = engine;
2876   gpgme_error_t err;
2877
2878   err = append_args_from_sender (gpg, ctx);
2879   if (err)
2880     ;
2881   else if (plaintext)
2882     {
2883       /* Normal or cleartext signature.  */
2884       err = add_arg (gpg, "--output");
2885       if (!err)
2886         err = add_arg (gpg, "-");
2887       if (!err)
2888         err = add_input_size_hint (gpg, sig);
2889       if (!err)
2890         err = add_arg (gpg, "--");
2891       if (!err)
2892         err = add_data (gpg, sig, -1, 0);
2893       if (!err)
2894         err = add_data (gpg, plaintext, 1, 1);
2895     }
2896   else
2897     {
2898       err = add_arg (gpg, "--verify");
2899       if (!err)
2900         err = add_input_size_hint (gpg, signed_text);
2901       if (!err)
2902         err = add_arg (gpg, "--");
2903       if (!err)
2904         err = add_data (gpg, sig, -1, 0);
2905       if (!err && signed_text)
2906         err = add_data (gpg, signed_text, -1, 0);
2907     }
2908
2909   if (!err)
2910     err = start (gpg);
2911
2912   return err;
2913 }
2914
2915
2916 static void
2917 gpg_set_io_cbs (void *engine, gpgme_io_cbs_t io_cbs)
2918 {
2919   engine_gpg_t gpg = engine;
2920
2921   gpg->io_cbs = *io_cbs;
2922 }
2923
2924
2925 static gpgme_error_t
2926 gpg_set_pinentry_mode (void *engine, gpgme_pinentry_mode_t mode)
2927 {
2928   engine_gpg_t gpg = engine;
2929
2930   gpg->pinentry_mode = mode;
2931   return 0;
2932 }
2933
2934
2935 \f
2936 struct engine_ops _gpgme_engine_ops_gpg =
2937   {
2938     /* Static functions.  */
2939     _gpgme_get_default_gpg_name,
2940     NULL,
2941     gpg_get_version,
2942     gpg_get_req_version,
2943     gpg_new,
2944
2945     /* Member functions.  */
2946     gpg_release,
2947     NULL,                               /* reset */
2948     gpg_set_status_cb,
2949     gpg_set_status_handler,
2950     gpg_set_command_handler,
2951     gpg_set_colon_line_handler,
2952     gpg_set_locale,
2953     NULL,                               /* set_protocol */
2954     gpg_decrypt,
2955     gpg_decrypt,                        /* decrypt_verify */
2956     gpg_delete,
2957     gpg_edit,
2958     gpg_encrypt,
2959     gpg_encrypt_sign,
2960     gpg_export,
2961     gpg_export_ext,
2962     gpg_genkey,
2963     gpg_import,
2964     gpg_keylist,
2965     gpg_keylist_ext,
2966     gpg_keysign,
2967     gpg_tofu_policy,    /* tofu_policy */
2968     gpg_sign,
2969     gpg_trustlist,
2970     gpg_verify,
2971     NULL,               /* getauditlog */
2972     NULL,               /* opassuan_transact */
2973     NULL,               /* conf_load */
2974     NULL,               /* conf_save */
2975     NULL,               /* query_swdb */
2976     gpg_set_io_cbs,
2977     gpg_io_event,
2978     gpg_cancel,
2979     NULL,               /* cancel_op */
2980     gpg_passwd,
2981     gpg_set_pinentry_mode,
2982     NULL                /* opspawn */
2983   };