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
6 This file is part of GPGME.
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.
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.
18 You should have received a copy of the GNU Lesser General Public
19 License along with this program; if not, see <https://www.gnu.org/licenses/>.
41 #include "context.h" /*temp hack until we have GpmeData methods to do I/O */
47 #include "engine-backend.h"
50 /* This type is used to build a list of gpg arguments and data
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. */
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. */
68 int inbound; /* true if this is used for reading from gpg */
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. */
77 /* NB.: R_LINE is allocated an gpgrt function and thus gpgrt_free
78 * shall be used to release it. This takes care of custom memory
79 * allocators and avoids problems on Windows with different runtimes
80 * used for libgpg-error/gpgrt and gpgme. */
81 typedef gpgme_error_t (*colon_preprocessor_t) (char *line, char **rline);
91 struct arg_and_data_s *arglist;
92 struct arg_and_data_s **argtail;
102 engine_status_handler_t fnc;
104 gpgme_status_cb_t mon_cb;
109 /* This is a kludge - see the comment at colon_line_handler. */
118 engine_colon_line_handler_t fnc; /* this indicate use of this structrue */
121 colon_preprocessor_t preprocess_fnc;
125 struct fd_data_map_s *fd_data_map;
127 /* stuff needed for interactive (command) mode */
133 int idx; /* Index in fd_data_map */
134 gpgme_status_code_t code; /* last code */
135 char *keyword; /* what has been requested (malloced) */
136 engine_command_handler_t fnc;
138 /* The kludges never end. This is used to couple command handlers
139 with output data in edit key mode. */
140 gpgme_data_t linked_data;
144 struct gpgme_io_cbs io_cbs;
145 gpgme_pinentry_mode_t pinentry_mode;
146 char request_origin[10];
148 /* NULL or the data object fed to --override_session_key-fd. */
149 gpgme_data_t override_session_key;
152 typedef struct engine_gpg *engine_gpg_t;
156 gpg_io_event (void *engine, gpgme_event_io_t type, void *type_data)
158 engine_gpg_t gpg = engine;
160 TRACE3 (DEBUG_ENGINE, "gpgme:gpg_io_event", gpg,
161 "event %p, type %d, type_data %p",
162 gpg->io_cbs.event, type, type_data);
163 if (gpg->io_cbs.event)
164 (*gpg->io_cbs.event) (gpg->io_cbs.event_priv, type, type_data);
169 close_notify_handler (int fd, void *opaque)
171 engine_gpg_t gpg = opaque;
174 if (gpg->status.fd[0] == fd)
177 (*gpg->io_cbs.remove) (gpg->status.tag);
178 gpg->status.fd[0] = -1;
180 else if (gpg->status.fd[1] == fd)
181 gpg->status.fd[1] = -1;
182 else if (gpg->colon.fd[0] == fd)
185 (*gpg->io_cbs.remove) (gpg->colon.tag);
186 gpg->colon.fd[0] = -1;
188 else if (gpg->colon.fd[1] == fd)
189 gpg->colon.fd[1] = -1;
190 else if (gpg->cmd.fd == fd)
192 else if (gpg->fd_data_map)
196 for (i = 0; gpg->fd_data_map[i].data; i++)
198 if (gpg->fd_data_map[i].fd == fd)
200 if (gpg->fd_data_map[i].tag)
201 (*gpg->io_cbs.remove) (gpg->fd_data_map[i].tag);
202 gpg->fd_data_map[i].fd = -1;
205 if (gpg->fd_data_map[i].peer_fd == fd)
207 gpg->fd_data_map[i].peer_fd = -1;
214 /* If FRONT is true, push at the front of the list. Use this for
215 options added late in the process. */
217 _add_arg (engine_gpg_t gpg, const char *prefix, const char *arg, size_t arglen,
218 int front, int *arg_locp)
220 struct arg_and_data_s *a;
221 size_t prefixlen = prefix? strlen (prefix) : 0;
226 a = malloc (sizeof *a + prefixlen + arglen);
228 return gpg_error_from_syserror ();
232 a->arg_locp = arg_locp;
235 memcpy (a->arg, prefix, prefixlen);
236 memcpy (a->arg + prefixlen, arg, arglen);
237 a->arg[prefixlen + arglen] = 0;
240 a->next = gpg->arglist;
243 /* If this is the first argument, we need to update the tail
245 gpg->argtail = &a->next;
253 gpg->argtail = &a->next;
261 add_arg_ext (engine_gpg_t gpg, const char *arg, int front)
263 return _add_arg (gpg, NULL, arg, strlen (arg), front, NULL);
267 add_arg_with_locp (engine_gpg_t gpg, const char *arg, int *locp)
269 return _add_arg (gpg, NULL, arg, strlen (arg), 0, locp);
273 add_arg (engine_gpg_t gpg, const char *arg)
275 return _add_arg (gpg, NULL, arg, strlen (arg), 0, NULL);
279 add_arg_pfx (engine_gpg_t gpg, const char *prefix, const char *arg)
281 return _add_arg (gpg, prefix, arg, strlen (arg), 0, NULL);
285 add_arg_len (engine_gpg_t gpg, const char *prefix,
286 const char *arg, size_t arglen)
288 return _add_arg (gpg, prefix, arg, arglen, 0, NULL);
293 add_data (engine_gpg_t gpg, gpgme_data_t data, int dup_to, int inbound)
295 struct arg_and_data_s *a;
300 a = malloc (sizeof *a - 1);
302 return gpg_error_from_syserror ();
305 a->inbound = inbound;
319 gpg->argtail = &a->next;
324 /* Return true if the engine's version is at least VERSION. */
326 have_gpg_version (engine_gpg_t gpg, const char *version)
328 return _gpgme_compare_versions (gpg->version, version);
334 gpg_get_version (const char *file_name)
336 return _gpgme_get_program_version (file_name ? file_name
337 : _gpgme_get_default_gpg_name ());
342 gpg_get_req_version (void)
349 free_argv (char **argv)
353 for (i = 0; argv[i]; i++)
360 free_fd_data_map (struct fd_data_map_s *fd_data_map)
367 for (i = 0; fd_data_map[i].data; i++)
369 if (fd_data_map[i].fd != -1)
370 _gpgme_io_close (fd_data_map[i].fd);
371 if (fd_data_map[i].peer_fd != -1)
372 _gpgme_io_close (fd_data_map[i].peer_fd);
373 /* Don't release data because this is only a reference. */
380 gpg_cancel (void *engine)
382 engine_gpg_t gpg = engine;
385 return gpg_error (GPG_ERR_INV_VALUE);
387 /* If gpg may be waiting for a cmd, close the cmd fd first. On
388 Windows, close operations block on the reader/writer thread. */
391 if (gpg->cmd.fd != -1)
392 _gpgme_io_close (gpg->cmd.fd);
393 else if (gpg->fd_data_map
394 && gpg->fd_data_map[gpg->cmd.idx].fd != -1)
395 _gpgme_io_close (gpg->fd_data_map[gpg->cmd.idx].fd);
398 if (gpg->status.fd[0] != -1)
399 _gpgme_io_close (gpg->status.fd[0]);
400 if (gpg->status.fd[1] != -1)
401 _gpgme_io_close (gpg->status.fd[1]);
402 if (gpg->colon.fd[0] != -1)
403 _gpgme_io_close (gpg->colon.fd[0]);
404 if (gpg->colon.fd[1] != -1)
405 _gpgme_io_close (gpg->colon.fd[1]);
406 if (gpg->fd_data_map)
408 free_fd_data_map (gpg->fd_data_map);
409 gpg->fd_data_map = NULL;
416 gpg_release (void *engine)
418 engine_gpg_t gpg = engine;
426 free (gpg->file_name);
430 if (gpg->lc_messages)
431 free (gpg->lc_messages);
433 free (gpg->lc_ctype);
437 struct arg_and_data_s *next = gpg->arglist->next;
443 if (gpg->status.buffer)
444 free (gpg->status.buffer);
445 if (gpg->colon.buffer)
446 free (gpg->colon.buffer);
448 free_argv (gpg->argv);
449 if (gpg->cmd.keyword)
450 free (gpg->cmd.keyword);
452 gpgme_data_release (gpg->override_session_key);
459 gpg_new (void **engine, const char *file_name, const char *home_dir,
463 gpgme_error_t rc = 0;
464 char *dft_display = NULL;
465 char dft_ttyname[64];
466 char *dft_ttytype = NULL;
467 char *env_tty = NULL;
469 gpg = calloc (1, sizeof *gpg);
471 return gpg_error_from_syserror ();
475 gpg->file_name = strdup (file_name);
478 rc = gpg_error_from_syserror ();
485 gpg->version = strdup (version);
488 rc = gpg_error_from_syserror ();
493 gpg->argtail = &gpg->arglist;
494 gpg->status.fd[0] = -1;
495 gpg->status.fd[1] = -1;
496 gpg->colon.fd[0] = -1;
497 gpg->colon.fd[1] = -1;
500 gpg->cmd.linked_data = NULL;
501 gpg->cmd.linked_idx = -1;
503 /* Allocate the read buffer for the status pipe. */
504 gpg->status.bufsize = 1024;
505 gpg->status.readpos = 0;
506 gpg->status.buffer = malloc (gpg->status.bufsize);
507 if (!gpg->status.buffer)
509 rc = gpg_error_from_syserror ();
512 /* In any case we need a status pipe - create it right here and
513 don't handle it with our generic gpgme_data_t mechanism. */
514 if (_gpgme_io_pipe (gpg->status.fd, 1) == -1)
516 rc = gpg_error_from_syserror ();
519 if (_gpgme_io_set_close_notify (gpg->status.fd[0],
520 close_notify_handler, gpg)
521 || _gpgme_io_set_close_notify (gpg->status.fd[1],
522 close_notify_handler, gpg))
524 rc = gpg_error (GPG_ERR_GENERAL);
531 rc = add_arg (gpg, "--homedir");
533 rc = add_arg (gpg, home_dir);
538 rc = add_arg (gpg, "--status-fd");
544 _gpgme_io_fd2str (buf, sizeof (buf), gpg->status.fd[1]);
545 rc = add_arg_with_locp (gpg, buf, &gpg->status.arg_loc);
550 rc = add_arg (gpg, "--no-tty");
552 rc = add_arg (gpg, "--charset");
554 rc = add_arg (gpg, "utf8");
556 rc = add_arg (gpg, "--enable-progress-filter");
557 if (!rc && have_gpg_version (gpg, "2.1.11"))
558 rc = add_arg (gpg, "--exit-on-status-write-error");
562 rc = _gpgme_getenv ("DISPLAY", &dft_display);
567 rc = add_arg (gpg, "--display");
569 rc = add_arg (gpg, dft_display);
576 rc = _gpgme_getenv ("GPG_TTY", &env_tty);
577 if (isatty (1) || env_tty || rc)
585 snprintf (dft_ttyname, sizeof (dft_ttyname), "%s", env_tty);
589 err = ttyname_r (1, dft_ttyname, sizeof (dft_ttyname));
591 /* Even though isatty() returns 1, ttyname_r() may fail in many
592 ways, e.g., when /dev/pts is not accessible under chroot. */
597 rc = add_arg (gpg, "--ttyname");
599 rc = add_arg (gpg, dft_ttyname);
605 rc = _gpgme_getenv ("TERM", &dft_ttytype);
611 rc = add_arg (gpg, "--ttytype");
613 rc = add_arg (gpg, dft_ttytype);
632 /* Copy flags from CTX into the engine object. */
634 gpg_set_engine_flags (void *engine, const gpgme_ctx_t ctx)
636 engine_gpg_t gpg = engine;
638 if (ctx->request_origin && have_gpg_version (gpg, "2.2.6"))
640 if (strlen (ctx->request_origin) + 1 > sizeof gpg->request_origin)
641 strcpy (gpg->request_origin, "xxx"); /* Too long - force error */
643 strcpy (gpg->request_origin, ctx->request_origin);
646 *gpg->request_origin = 0;
651 gpg_set_locale (void *engine, int category, const char *value)
653 engine_gpg_t gpg = engine;
658 else if (category == LC_CTYPE)
662 free (gpg->lc_ctype);
663 gpg->lc_ctype = NULL;
667 gpg->lc_ctype = strdup (value);
669 return gpg_error_from_syserror ();
674 else if (category == LC_MESSAGES)
676 if (gpg->lc_messages)
678 free (gpg->lc_messages);
679 gpg->lc_messages = NULL;
683 gpg->lc_messages = strdup (value);
684 if (!gpg->lc_messages)
685 return gpg_error_from_syserror ();
688 #endif /* LC_MESSAGES */
690 return gpg_error (GPG_ERR_INV_VALUE);
695 /* This sets a status callback for monitoring status lines before they
696 * are passed to a caller set handler. */
698 gpg_set_status_cb (void *engine, gpgme_status_cb_t cb, void *cb_value)
700 engine_gpg_t gpg = engine;
702 gpg->status.mon_cb = cb;
703 gpg->status.mon_cb_value = cb_value;
707 /* Note, that the status_handler is allowed to modifiy the args
710 gpg_set_status_handler (void *engine, engine_status_handler_t fnc,
713 engine_gpg_t gpg = engine;
715 gpg->status.fnc = fnc;
716 gpg->status.fnc_value = fnc_value;
719 /* Kludge to process --with-colon output. */
721 gpg_set_colon_line_handler (void *engine, engine_colon_line_handler_t fnc,
724 engine_gpg_t gpg = engine;
726 gpg->colon.bufsize = 1024;
727 gpg->colon.readpos = 0;
728 gpg->colon.buffer = malloc (gpg->colon.bufsize);
729 if (!gpg->colon.buffer)
730 return gpg_error_from_syserror ();
732 if (_gpgme_io_pipe (gpg->colon.fd, 1) == -1)
734 int saved_err = gpg_error_from_syserror ();
735 free (gpg->colon.buffer);
736 gpg->colon.buffer = NULL;
739 if (_gpgme_io_set_close_notify (gpg->colon.fd[0], close_notify_handler, gpg)
740 || _gpgme_io_set_close_notify (gpg->colon.fd[1],
741 close_notify_handler, gpg))
742 return gpg_error (GPG_ERR_GENERAL);
744 gpg->colon.fnc = fnc;
745 gpg->colon.fnc_value = fnc_value;
751 command_handler (void *opaque, int fd)
753 struct io_cb_data *data = (struct io_cb_data *) opaque;
754 engine_gpg_t gpg = (engine_gpg_t) data->handler_value;
757 assert (gpg->cmd.used);
758 assert (gpg->cmd.code);
759 assert (gpg->cmd.fnc);
761 err = gpg->cmd.fnc (gpg->cmd.fnc_value, gpg->cmd.code, gpg->cmd.keyword, fd,
765 /* And sleep again until read_status will wake us up again. */
766 /* XXX We must check if there are any more fds active after removing
768 (*gpg->io_cbs.remove) (gpg->fd_data_map[gpg->cmd.idx].tag);
769 gpg->cmd.fd = gpg->fd_data_map[gpg->cmd.idx].fd;
770 gpg->fd_data_map[gpg->cmd.idx].fd = -1;
775 /* We always need to send at least a newline character. */
777 _gpgme_io_write (fd, "\n", 1);
784 /* The Fnc will be called to get a value for one of the commands with
785 a key KEY. If the Code passed to FNC is 0, the function may release
786 resources associated with the returned value from another call. To
787 match such a second call to a first call, the returned value from
788 the first call is passed as keyword. */
790 gpg_set_command_handler (void *engine, engine_command_handler_t fnc,
791 void *fnc_value, gpgme_data_t linked_data)
793 engine_gpg_t gpg = engine;
796 rc = add_arg (gpg, "--command-fd");
800 /* This is a hack. We don't have a real data object. The only
801 thing that matters is that we use something unique, so we use the
802 address of the cmd structure in the gpg object. */
803 rc = add_data (gpg, (void *) &gpg->cmd, -2, 0);
808 gpg->cmd.cb_data = (void *) &gpg->cmd;
809 gpg->cmd.fnc_value = fnc_value;
810 gpg->cmd.linked_data = linked_data;
817 build_argv (engine_gpg_t gpg, const char *pgmname)
820 struct arg_and_data_s *a;
821 struct fd_data_map_s *fd_data_map;
822 size_t datac=0, argc=0;
824 int need_special = 0;
828 if (_gpgme_in_gpg_one_mode ())
830 /* In GnuPG-1 mode we don't want to use the agent with a
831 malformed environment variable. This is only a very basic
832 test but sufficient to make our life in the regression tests
833 easier. With GnuPG-2 the agent is anyway required and on
834 modern installations GPG_AGENT_INFO is optional. */
835 err = _gpgme_getenv ("GPG_AGENT_INFO", &p);
838 use_agent = (p && strchr (p, ':'));
845 free_argv (gpg->argv);
848 if (gpg->fd_data_map)
850 free_fd_data_map (gpg->fd_data_map);
851 gpg->fd_data_map = NULL;
854 argc++; /* For argv[0]. */
855 for (a = gpg->arglist; a; a = a->next)
860 /*fprintf (stderr, "build_argv: data\n" );*/
862 if (a->dup_to == -1 && !a->print_fd)
867 /* fprintf (stderr, "build_argv: arg=`%s'\n", a->arg );*/
874 if (gpg->pinentry_mode)
877 argc++; /* --batch */
878 argc += 2; /* --no-sk-comments, --request-origin */
880 argv = calloc (argc + 1, sizeof *argv);
882 return gpg_error_from_syserror ();
883 fd_data_map = calloc (datac + 1, sizeof *fd_data_map);
886 int saved_err = gpg_error_from_syserror ();
892 argv[argc] = strdup (_gpgme_get_basename (pgmname)); /* argv[0] */
895 int saved_err = gpg_error_from_syserror ();
903 argv[argc] = strdup ("--enable-special-filenames");
906 int saved_err = gpg_error_from_syserror ();
915 argv[argc] = strdup ("--use-agent");
918 int saved_err = gpg_error_from_syserror ();
926 if (*gpg->request_origin)
928 argv[argc] = _gpgme_strconcat ("--request-origin=",
929 gpg->request_origin, NULL);
932 int saved_err = gpg_error_from_syserror ();
940 if (gpg->pinentry_mode && have_gpg_version (gpg, "2.1.0"))
942 const char *s = NULL;
943 switch (gpg->pinentry_mode)
945 case GPGME_PINENTRY_MODE_DEFAULT: break;
946 case GPGME_PINENTRY_MODE_ASK: s = "--pinentry-mode=ask"; break;
947 case GPGME_PINENTRY_MODE_CANCEL: s = "--pinentry-mode=cancel"; break;
948 case GPGME_PINENTRY_MODE_ERROR: s = "--pinentry-mode=error"; break;
949 case GPGME_PINENTRY_MODE_LOOPBACK:s = "--pinentry-mode=loopback"; break;
953 argv[argc] = strdup (s);
956 int saved_err = gpg_error_from_syserror ();
967 argv[argc] = strdup ("--batch");
970 int saved_err = gpg_error_from_syserror ();
977 argv[argc] = strdup ("--no-sk-comments");
980 int saved_err = gpg_error_from_syserror ();
986 for (a = gpg->arglist; a; a = a->next)
989 *(a->arg_locp) = argc;
993 /* Create a pipe to pass it down to gpg. */
994 fd_data_map[datac].inbound = a->inbound;
1000 if (_gpgme_io_pipe (fds, fd_data_map[datac].inbound ? 1 : 0)
1003 int saved_errno = errno;
1006 return gpg_error (saved_errno);
1008 if (_gpgme_io_set_close_notify (fds[0],
1009 close_notify_handler, gpg)
1010 || _gpgme_io_set_close_notify (fds[1],
1011 close_notify_handler,
1014 /* We leak fd_data_map and the fds. This is not easy
1015 to avoid and given that we reach this here only
1016 after a malloc failure for a small object, it is
1017 probably better not to do anything. */
1018 return gpg_error (GPG_ERR_GENERAL);
1020 /* If the data_type is FD, we have to do a dup2 here. */
1021 if (fd_data_map[datac].inbound)
1023 fd_data_map[datac].fd = fds[0];
1024 fd_data_map[datac].peer_fd = fds[1];
1028 fd_data_map[datac].fd = fds[1];
1029 fd_data_map[datac].peer_fd = fds[0];
1033 /* Hack to get hands on the fd later. */
1036 if (gpg->cmd.cb_data == a->data)
1038 assert (gpg->cmd.idx == -1);
1039 gpg->cmd.idx = datac;
1041 else if (gpg->cmd.linked_data == a->data)
1043 assert (gpg->cmd.linked_idx == -1);
1044 gpg->cmd.linked_idx = datac;
1048 fd_data_map[datac].data = a->data;
1049 fd_data_map[datac].dup_to = a->dup_to;
1051 if (a->dup_to == -1)
1056 argv[argc] = malloc (buflen);
1059 int saved_err = gpg_error_from_syserror ();
1073 _gpgme_io_fd2str (ptr, buflen, fd_data_map[datac].peer_fd);
1074 fd_data_map[datac].arg_loc = argc;
1081 argv[argc] = strdup (a->arg);
1084 int saved_err = gpg_error_from_syserror ();
1094 gpg->fd_data_map = fd_data_map;
1099 static gpgme_error_t
1100 add_io_cb (engine_gpg_t gpg, int fd, int dir, gpgme_io_cb_t handler, void *data,
1105 err = (*gpg->io_cbs.add) (gpg->io_cbs.add_priv, fd, dir, handler, data, tag);
1109 /* FIXME Kludge around poll() problem. */
1110 err = _gpgme_io_set_nonblocking (fd);
1115 /* Handle the status output of GnuPG. This function does read entire
1116 lines and passes them as C strings to the callback function (we can
1117 use C Strings because the status output is always UTF-8 encoded).
1118 Of course we have to buffer the lines to cope with long lines
1119 e.g. with a large user ID. Note: We can optimize this to only cope
1120 with status line code we know about and skip all other stuff
1121 without buffering (i.e. without extending the buffer). */
1122 static gpgme_error_t
1123 read_status (engine_gpg_t gpg)
1127 size_t bufsize = gpg->status.bufsize;
1128 char *buffer = gpg->status.buffer;
1129 size_t readpos = gpg->status.readpos;
1133 if (bufsize - readpos < 256)
1135 /* Need more room for the read. */
1137 buffer = realloc (buffer, bufsize);
1139 return gpg_error_from_syserror ();
1142 nread = _gpgme_io_read (gpg->status.fd[0],
1143 buffer + readpos, bufsize-readpos);
1145 return gpg_error_from_syserror ();
1150 gpg->status.eof = 1;
1151 if (gpg->status.mon_cb)
1152 err = gpg->status.mon_cb (gpg->status.mon_cb_value, "", "");
1153 if (gpg->status.fnc)
1155 char emptystring[1] = {0};
1156 err = gpg->status.fnc (gpg->status.fnc_value,
1157 GPGME_STATUS_EOF, emptystring);
1158 if (gpg_err_code (err) == GPG_ERR_FALSE)
1159 err = 0; /* Drop special error code. */
1167 for (p = buffer + readpos; nread; nread--, p++)
1171 /* (we require that the last line is terminated by a LF) */
1172 if (p > buffer && p[-1] == '\r')
1175 if (!strncmp (buffer, "[GNUPG:] ", 9)
1176 && buffer[9] >= 'A' && buffer[9] <= 'Z')
1179 gpgme_status_code_t r;
1181 rest = strchr (buffer + 9, ' ');
1183 rest = p; /* Set to an empty string. */
1187 r = _gpgme_parse_status (buffer + 9);
1188 if (gpg->status.mon_cb && r != GPGME_STATUS_PROGRESS)
1190 /* Note that we call the monitor even if we do
1191 * not know the status code (r < 0). */
1192 err = gpg->status.mon_cb (gpg->status.mon_cb_value,
1200 && (r == GPGME_STATUS_GET_BOOL
1201 || r == GPGME_STATUS_GET_LINE
1202 || r == GPGME_STATUS_GET_HIDDEN))
1205 if (gpg->cmd.keyword)
1206 free (gpg->cmd.keyword);
1207 gpg->cmd.keyword = strdup (rest);
1208 if (!gpg->cmd.keyword)
1209 return gpg_error_from_syserror ();
1210 /* This should be the last thing we have
1211 received and the next thing will be that
1212 the command handler does its action. */
1214 TRACE0 (DEBUG_CTX, "gpgme:read_status", 0,
1215 "error: unexpected data");
1217 add_io_cb (gpg, gpg->cmd.fd, 0,
1218 command_handler, gpg,
1219 &gpg->fd_data_map[gpg->cmd.idx].tag);
1220 gpg->fd_data_map[gpg->cmd.idx].fd = gpg->cmd.fd;
1223 else if (gpg->status.fnc)
1225 err = gpg->status.fnc (gpg->status.fnc_value,
1227 if (gpg_err_code (err) == GPG_ERR_FALSE)
1228 err = 0; /* Drop special error code. */
1233 if (r == GPGME_STATUS_END_STREAM)
1237 /* Before we can actually add the
1238 command fd, we might have to flush
1239 the linked output data pipe. */
1240 if (gpg->cmd.linked_idx != -1
1241 && gpg->fd_data_map[gpg->cmd.linked_idx].fd
1244 struct io_select_fd_s fds;
1246 gpg->fd_data_map[gpg->cmd.linked_idx].fd;
1253 _gpgme_io_select (&fds, 1, 1);
1255 _gpgme_data_inbound_handler
1256 (gpg->cmd.linked_data, fds.fd);
1258 while (fds.signaled);
1261 /* XXX We must check if there are any
1262 more fds active after removing this
1264 (*gpg->io_cbs.remove)
1265 (gpg->fd_data_map[gpg->cmd.idx].tag);
1266 gpg->cmd.fd = gpg->fd_data_map[gpg->cmd.idx].fd;
1267 gpg->fd_data_map[gpg->cmd.idx].fd = -1;
1272 /* To reuse the buffer for the next line we have to
1273 shift the remaining data to the buffer start and
1274 restart the loop Hmmm: We can optimize this function
1275 by looking forward in the buffer to see whether a
1276 second complete line is available and in this case
1277 avoid the memmove for this line. */
1280 memmove (buffer, p, nread);
1282 break; /* the for loop */
1289 /* Update the gpg object. */
1290 gpg->status.bufsize = bufsize;
1291 gpg->status.buffer = buffer;
1292 gpg->status.readpos = readpos;
1297 static gpgme_error_t
1298 status_handler (void *opaque, int fd)
1300 struct io_cb_data *data = (struct io_cb_data *) opaque;
1301 engine_gpg_t gpg = (engine_gpg_t) data->handler_value;
1304 assert (fd == gpg->status.fd[0]);
1305 err = read_status (gpg);
1308 if (gpg->status.eof)
1309 _gpgme_io_close (fd);
1314 static gpgme_error_t
1315 read_colon_line (engine_gpg_t gpg)
1319 size_t bufsize = gpg->colon.bufsize;
1320 char *buffer = gpg->colon.buffer;
1321 size_t readpos = gpg->colon.readpos;
1324 if (bufsize - readpos < 256)
1326 /* Need more room for the read. */
1328 buffer = realloc (buffer, bufsize);
1330 return gpg_error_from_syserror ();
1333 nread = _gpgme_io_read (gpg->colon.fd[0], buffer+readpos, bufsize-readpos);
1335 return gpg_error_from_syserror ();
1340 assert (gpg->colon.fnc);
1341 gpg->colon.fnc (gpg->colon.fnc_value, NULL);
1347 for (p = buffer + readpos; nread; nread--, p++)
1351 /* (we require that the last line is terminated by a LF)
1352 and we skip empty lines. Note: we use UTF8 encoding
1353 and escaping of special characters. We require at
1354 least one colon to cope with some other printed
1357 if (*buffer && strchr (buffer, ':'))
1361 if (gpg->colon.preprocess_fnc)
1365 err = gpg->colon.preprocess_fnc (buffer, &line);
1370 assert (gpg->colon.fnc);
1378 endp = strchr (linep, '\n');
1381 gpg->colon.fnc (gpg->colon.fnc_value, linep);
1384 while (linep && *linep);
1389 gpg->colon.fnc (gpg->colon.fnc_value, buffer);
1392 /* To reuse the buffer for the next line we have to
1393 shift the remaining data to the buffer start and
1394 restart the loop Hmmm: We can optimize this function
1395 by looking forward in the buffer to see whether a
1396 second complete line is available and in this case
1397 avoid the memmove for this line. */
1400 memmove (buffer, p, nread);
1402 break; /* The for loop. */
1409 /* Update the gpg object. */
1410 gpg->colon.bufsize = bufsize;
1411 gpg->colon.buffer = buffer;
1412 gpg->colon.readpos = readpos;
1417 /* This colonline handler thing is not the clean way to do it. It
1418 might be better to enhance the gpgme_data_t object to act as a wrapper
1419 for a callback. Same goes for the status thing. For now we use
1420 this thing here because it is easier to implement. */
1421 static gpgme_error_t
1422 colon_line_handler (void *opaque, int fd)
1424 struct io_cb_data *data = (struct io_cb_data *) opaque;
1425 engine_gpg_t gpg = (engine_gpg_t) data->handler_value;
1426 gpgme_error_t rc = 0;
1428 assert (fd == gpg->colon.fd[0]);
1429 rc = read_colon_line (gpg);
1433 _gpgme_io_close (fd);
1438 static gpgme_error_t
1439 start (engine_gpg_t gpg)
1444 struct spawn_fd_item_s *fd_list;
1446 const char *pgmname;
1449 return gpg_error (GPG_ERR_INV_VALUE);
1451 if (!gpg->file_name && !_gpgme_get_default_gpg_name ())
1452 return trace_gpg_error (GPG_ERR_INV_ENGINE);
1456 rc = add_arg_ext (gpg, gpg->lc_ctype, 1);
1458 rc = add_arg_ext (gpg, "--lc-ctype", 1);
1463 if (gpg->lc_messages)
1465 rc = add_arg_ext (gpg, gpg->lc_messages, 1);
1467 rc = add_arg_ext (gpg, "--lc-messages", 1);
1472 pgmname = gpg->file_name ? gpg->file_name : _gpgme_get_default_gpg_name ();
1473 rc = build_argv (gpg, pgmname);
1477 /* status_fd, colon_fd and end of list. */
1479 for (i = 0; gpg->fd_data_map[i].data; i++)
1481 fd_list = calloc (n, sizeof *fd_list);
1483 return gpg_error_from_syserror ();
1485 /* Build the fd list for the child. */
1487 fd_list[n].fd = gpg->status.fd[1];
1488 fd_list[n].dup_to = -1;
1489 fd_list[n].arg_loc = gpg->status.arg_loc;
1493 fd_list[n].fd = gpg->colon.fd[1];
1494 fd_list[n].dup_to = 1;
1497 for (i = 0; gpg->fd_data_map[i].data; i++)
1499 fd_list[n].fd = gpg->fd_data_map[i].peer_fd;
1500 fd_list[n].dup_to = gpg->fd_data_map[i].dup_to;
1501 fd_list[n].arg_loc = gpg->fd_data_map[i].arg_loc;
1505 fd_list[n].dup_to = -1;
1507 status = _gpgme_io_spawn (pgmname, gpg->argv,
1508 (IOSPAWN_FLAG_DETACHED |IOSPAWN_FLAG_ALLOW_SET_FG),
1509 fd_list, NULL, NULL, &pid);
1511 int saved_err = gpg_error_from_syserror ();
1517 /*_gpgme_register_term_handler ( closure, closure_value, pid );*/
1519 rc = add_io_cb (gpg, gpg->status.fd[0], 1, status_handler, gpg,
1522 /* FIXME: kill the child */
1527 assert (gpg->colon.fd[0] != -1);
1528 rc = add_io_cb (gpg, gpg->colon.fd[0], 1, colon_line_handler, gpg,
1531 /* FIXME: kill the child */
1535 for (i = 0; gpg->fd_data_map[i].data; i++)
1537 if (gpg->cmd.used && i == gpg->cmd.idx)
1539 /* Park the cmd fd. */
1540 gpg->cmd.fd = gpg->fd_data_map[i].fd;
1541 gpg->fd_data_map[i].fd = -1;
1545 rc = add_io_cb (gpg, gpg->fd_data_map[i].fd,
1546 gpg->fd_data_map[i].inbound,
1547 gpg->fd_data_map[i].inbound
1548 ? _gpgme_data_inbound_handler
1549 : _gpgme_data_outbound_handler,
1550 gpg->fd_data_map[i].data, &gpg->fd_data_map[i].tag);
1553 /* FIXME: kill the child */
1558 gpg_io_event (gpg, GPGME_EVENT_START, NULL);
1560 /* fixme: check what data we can release here */
1565 /* Add the --input-size-hint option if requested. */
1566 static gpgme_error_t
1567 add_input_size_hint (engine_gpg_t gpg, gpgme_data_t data)
1570 gpgme_off_t value = _gpgme_data_get_size_hint (data);
1571 char numbuf[50]; /* Large enough for even 2^128 in base-10. */
1574 if (!value || !have_gpg_version (gpg, "2.1.15"))
1577 err = add_arg (gpg, "--input-size-hint");
1580 p = numbuf + sizeof numbuf;
1584 *--p = '0' + (value % 10);
1588 err = add_arg (gpg, p);
1594 static gpgme_error_t
1595 gpg_decrypt (void *engine,
1596 gpgme_decrypt_flags_t flags,
1597 gpgme_data_t ciph, gpgme_data_t plain,
1598 int export_session_key, const char *override_session_key,
1599 int auto_key_retrieve)
1601 engine_gpg_t gpg = engine;
1604 err = add_arg (gpg, "--decrypt");
1606 if (!err && (flags & GPGME_DECRYPT_UNWRAP))
1608 if (!have_gpg_version (gpg, "2.1.12"))
1609 err = gpg_error (GPG_ERR_NOT_SUPPORTED);
1611 err = add_arg (gpg, "--unwrap");
1614 if (!err && export_session_key)
1615 err = add_arg (gpg, "--show-session-key");
1617 if (!err && auto_key_retrieve)
1618 err = add_arg (gpg, "--auto-key-retrieve");
1620 if (!err && override_session_key && *override_session_key)
1622 if (have_gpg_version (gpg, "2.1.16"))
1624 gpgme_data_release (gpg->override_session_key);
1625 TRACE2 (DEBUG_ENGINE, "override", gpg, "seskey='%s' len=%zu\n",
1626 override_session_key,
1627 strlen (override_session_key));
1629 err = gpgme_data_new_from_mem (&gpg->override_session_key,
1630 override_session_key,
1631 strlen (override_session_key), 1);
1634 err = add_arg (gpg, "--override-session-key-fd");
1636 err = add_data (gpg, gpg->override_session_key, -2, 0);
1641 /* Using that option may leak the session key via ps(1). */
1642 err = add_arg (gpg, "--override-session-key");
1644 err = add_arg (gpg, override_session_key);
1648 /* Tell the gpg object about the data. */
1650 err = add_arg (gpg, "--output");
1652 err = add_arg (gpg, "-");
1654 err = add_data (gpg, plain, 1, 1);
1656 err = add_input_size_hint (gpg, ciph);
1658 err = add_arg (gpg, "--");
1660 err = add_data (gpg, ciph, -1, 0);
1667 static gpgme_error_t
1668 gpg_delete (void *engine, gpgme_key_t key, unsigned int flags)
1670 engine_gpg_t gpg = engine;
1671 gpgme_error_t err = 0;
1672 int allow_secret = flags & GPGME_DELETE_ALLOW_SECRET;
1673 int force = flags & GPGME_DELETE_FORCE;
1676 err = add_arg (gpg, "--yes");
1678 err = add_arg (gpg, allow_secret ? "--delete-secret-and-public-key"
1681 err = add_arg (gpg, "--");
1684 if (!key->subkeys || !key->subkeys->fpr)
1685 return gpg_error (GPG_ERR_INV_VALUE);
1687 err = add_arg (gpg, key->subkeys->fpr);
1696 static gpgme_error_t
1697 gpg_passwd (void *engine, gpgme_key_t key, unsigned int flags)
1699 engine_gpg_t gpg = engine;
1704 if (!key || !key->subkeys || !key->subkeys->fpr)
1705 return gpg_error (GPG_ERR_INV_CERT_OBJ);
1707 err = add_arg (gpg, "--passwd");
1709 err = add_arg (gpg, key->subkeys->fpr);
1716 static gpgme_error_t
1717 append_args_from_signers (engine_gpg_t gpg, gpgme_ctx_t ctx /* FIXME */)
1719 gpgme_error_t err = 0;
1723 for (i = 0; (key = gpgme_signers_enum (ctx, i)); i++)
1725 const char *s = key->subkeys ? key->subkeys->keyid : NULL;
1729 err = add_arg (gpg, "-u");
1731 err = add_arg (gpg, s);
1733 gpgme_key_unref (key);
1741 static gpgme_error_t
1742 append_args_from_sender (engine_gpg_t gpg, gpgme_ctx_t ctx)
1746 if (ctx->sender && have_gpg_version (gpg, "2.1.15"))
1748 err = add_arg (gpg, "--sender");
1750 err = add_arg (gpg, ctx->sender);
1758 static gpgme_error_t
1759 append_args_from_sig_notations (engine_gpg_t gpg, gpgme_ctx_t ctx /* FIXME */)
1761 gpgme_error_t err = 0;
1762 gpgme_sig_notation_t notation;
1764 notation = gpgme_sig_notation_get (ctx);
1766 while (!err && notation)
1769 && !(notation->flags & GPGME_SIG_NOTATION_HUMAN_READABLE))
1770 err = gpg_error (GPG_ERR_INV_VALUE);
1771 else if (notation->name)
1775 /* Maximum space needed is one byte for the "critical" flag,
1776 the name, one byte for '=', the value, and a terminating
1779 arg = malloc (1 + notation->name_len + 1 + notation->value_len + 1);
1781 err = gpg_error_from_syserror ();
1787 if (notation->critical)
1790 memcpy (argp, notation->name, notation->name_len);
1791 argp += notation->name_len;
1795 /* We know that notation->name is '\0' terminated. */
1796 strcpy (argp, notation->value);
1800 err = add_arg (gpg, "--sig-notation");
1802 err = add_arg (gpg, arg);
1809 /* This is a policy URL. */
1813 if (notation->critical)
1815 value = malloc (1 + notation->value_len + 1);
1817 err = gpg_error_from_syserror ();
1821 /* We know that notation->value is '\0' terminated. */
1822 strcpy (&value[1], notation->value);
1826 value = notation->value;
1829 err = add_arg (gpg, "--sig-policy-url");
1831 err = add_arg (gpg, value);
1833 if (value != notation->value)
1837 notation = notation->next;
1843 static gpgme_error_t
1844 gpg_edit (void *engine, int type, gpgme_key_t key, gpgme_data_t out,
1845 gpgme_ctx_t ctx /* FIXME */)
1847 engine_gpg_t gpg = engine;
1850 err = add_arg (gpg, "--with-colons");
1852 err = append_args_from_signers (gpg, ctx);
1854 err = add_arg (gpg, type == 0 ? "--edit-key" : "--card-edit");
1856 err = add_data (gpg, out, 1, 1);
1858 err = add_arg (gpg, "--");
1859 if (!err && type == 0)
1861 const char *s = key->subkeys ? key->subkeys->fpr : NULL;
1863 err = gpg_error (GPG_ERR_INV_VALUE);
1865 err = add_arg (gpg, s);
1874 static gpgme_error_t
1875 append_args_from_recipients (engine_gpg_t gpg, gpgme_key_t recp[])
1877 gpgme_error_t err = 0;
1882 if (!recp[i]->subkeys || !recp[i]->subkeys->fpr)
1883 err = gpg_error (GPG_ERR_INV_VALUE);
1885 err = add_arg (gpg, "-r");
1887 err = add_arg (gpg, recp[i]->subkeys->fpr);
1896 static gpgme_error_t
1897 gpg_encrypt (void *engine, gpgme_key_t recp[], gpgme_encrypt_flags_t flags,
1898 gpgme_data_t plain, gpgme_data_t ciph, int use_armor)
1900 engine_gpg_t gpg = engine;
1901 gpgme_error_t err = 0;
1904 err = add_arg (gpg, "--encrypt");
1906 if (!err && ((flags & GPGME_ENCRYPT_SYMMETRIC) || !recp))
1907 err = add_arg (gpg, "--symmetric");
1909 if (!err && use_armor)
1910 err = add_arg (gpg, "--armor");
1912 if (!err && (flags & GPGME_ENCRYPT_WRAP))
1914 /* gpg is current not able to detect already compressed
1915 * packets. Thus when using
1916 * gpg --unwrap -d | gpg --no-literal -e
1917 * the encryption would add an additional compression layer.
1918 * We better suppress that. */
1919 flags |= GPGME_ENCRYPT_NO_COMPRESS;
1920 err = add_arg (gpg, "--no-literal");
1923 if (!err && (flags & GPGME_ENCRYPT_NO_COMPRESS))
1924 err = add_arg (gpg, "--compress-algo=none");
1926 if (!err && (flags & GPGME_ENCRYPT_THROW_KEYIDS))
1927 err = add_arg (gpg, "--throw-keyids");
1929 if (gpgme_data_get_encoding (plain) == GPGME_DATA_ENCODING_MIME
1930 && have_gpg_version (gpg, "2.1.14"))
1931 err = add_arg (gpg, "--mimemode");
1935 /* If we know that all recipients are valid (full or ultimate trust)
1936 we can suppress further checks. */
1937 if (!err && (flags & GPGME_ENCRYPT_ALWAYS_TRUST))
1938 err = add_arg (gpg, "--always-trust");
1940 if (!err && (flags & GPGME_ENCRYPT_NO_ENCRYPT_TO))
1941 err = add_arg (gpg, "--no-encrypt-to");
1944 err = append_args_from_recipients (gpg, recp);
1947 /* Tell the gpg object about the data. */
1949 err = add_arg (gpg, "--output");
1951 err = add_arg (gpg, "-");
1953 err = add_data (gpg, ciph, 1, 1);
1954 if (gpgme_data_get_file_name (plain))
1957 err = add_arg (gpg, "--set-filename");
1959 err = add_arg (gpg, gpgme_data_get_file_name (plain));
1962 err = add_input_size_hint (gpg, plain);
1964 err = add_arg (gpg, "--");
1966 err = add_data (gpg, plain, -1, 0);
1975 static gpgme_error_t
1976 gpg_encrypt_sign (void *engine, gpgme_key_t recp[],
1977 gpgme_encrypt_flags_t flags, gpgme_data_t plain,
1978 gpgme_data_t ciph, int use_armor,
1979 gpgme_ctx_t ctx /* FIXME */)
1981 engine_gpg_t gpg = engine;
1982 gpgme_error_t err = 0;
1985 err = add_arg (gpg, "--encrypt");
1987 if (!err && ((flags & GPGME_ENCRYPT_SYMMETRIC) || !recp))
1988 err = add_arg (gpg, "--symmetric");
1991 err = add_arg (gpg, "--sign");
1992 if (!err && use_armor)
1993 err = add_arg (gpg, "--armor");
1995 if (!err && (flags & GPGME_ENCRYPT_NO_COMPRESS))
1996 err = add_arg (gpg, "--compress-algo=none");
1998 if (!err && (flags & GPGME_ENCRYPT_THROW_KEYIDS))
1999 err = add_arg (gpg, "--throw-keyids");
2001 if (gpgme_data_get_encoding (plain) == GPGME_DATA_ENCODING_MIME
2002 && have_gpg_version (gpg, "2.1.14"))
2003 err = add_arg (gpg, "--mimemode");
2007 /* If we know that all recipients are valid (full or ultimate trust)
2008 we can suppress further checks. */
2009 if (!err && (flags & GPGME_ENCRYPT_ALWAYS_TRUST))
2010 err = add_arg (gpg, "--always-trust");
2012 if (!err && (flags & GPGME_ENCRYPT_NO_ENCRYPT_TO))
2013 err = add_arg (gpg, "--no-encrypt-to");
2016 err = append_args_from_recipients (gpg, recp);
2020 err = append_args_from_signers (gpg, ctx);
2023 err = append_args_from_sender (gpg, ctx);
2026 err = append_args_from_sig_notations (gpg, ctx);
2028 /* Tell the gpg object about the data. */
2030 err = add_arg (gpg, "--output");
2032 err = add_arg (gpg, "-");
2034 err = add_data (gpg, ciph, 1, 1);
2035 if (gpgme_data_get_file_name (plain))
2038 err = add_arg (gpg, "--set-filename");
2040 err = add_arg (gpg, gpgme_data_get_file_name (plain));
2043 err = add_input_size_hint (gpg, plain);
2045 err = add_arg (gpg, "--");
2047 err = add_data (gpg, plain, -1, 0);
2056 static gpgme_error_t
2057 export_common (engine_gpg_t gpg, gpgme_export_mode_t mode,
2058 gpgme_data_t keydata, int use_armor)
2060 gpgme_error_t err = 0;
2062 if ((mode & ~(GPGME_EXPORT_MODE_EXTERN
2063 |GPGME_EXPORT_MODE_MINIMAL
2064 |GPGME_EXPORT_MODE_SECRET)))
2065 return gpg_error (GPG_ERR_NOT_SUPPORTED);
2067 if ((mode & GPGME_EXPORT_MODE_MINIMAL))
2068 err = add_arg (gpg, "--export-options=export-minimal");
2072 else if ((mode & GPGME_EXPORT_MODE_EXTERN))
2074 err = add_arg (gpg, "--send-keys");
2078 if ((mode & GPGME_EXPORT_MODE_SECRET))
2079 err = add_arg (gpg, "--export-secret-keys");
2081 err = add_arg (gpg, "--export");
2082 if (!err && use_armor)
2083 err = add_arg (gpg, "--armor");
2085 err = add_data (gpg, keydata, 1, 1);
2088 err = add_arg (gpg, "--");
2094 static gpgme_error_t
2095 gpg_export (void *engine, const char *pattern, gpgme_export_mode_t mode,
2096 gpgme_data_t keydata, int use_armor)
2098 engine_gpg_t gpg = engine;
2101 err = export_common (gpg, mode, keydata, use_armor);
2103 if (!err && pattern && *pattern)
2104 err = add_arg (gpg, pattern);
2113 static gpgme_error_t
2114 gpg_export_ext (void *engine, const char *pattern[], gpgme_export_mode_t mode,
2115 gpgme_data_t keydata, int use_armor)
2117 engine_gpg_t gpg = engine;
2120 err = export_common (gpg, mode, keydata, use_armor);
2124 while (!err && *pattern && **pattern)
2125 err = add_arg (gpg, *(pattern++));
2136 /* Helper to add algo, usage, and expire to the list of args. */
2137 static gpgme_error_t
2138 gpg_add_algo_usage_expire (engine_gpg_t gpg,
2140 unsigned long expires,
2145 /* This condition is only required to allow the use of gpg < 2.1.16 */
2147 || (flags & (GPGME_CREATE_SIGN | GPGME_CREATE_ENCR
2148 | GPGME_CREATE_CERT | GPGME_CREATE_AUTH
2149 | GPGME_CREATE_NOEXPIRE))
2152 err = add_arg (gpg, algo? algo : "default");
2156 snprintf (tmpbuf, sizeof tmpbuf, "%s%s%s%s",
2157 (flags & GPGME_CREATE_SIGN)? " sign":"",
2158 (flags & GPGME_CREATE_ENCR)? " encr":"",
2159 (flags & GPGME_CREATE_CERT)? " cert":"",
2160 (flags & GPGME_CREATE_AUTH)? " auth":"");
2161 err = add_arg (gpg, *tmpbuf? tmpbuf : "default");
2165 if ((flags & GPGME_CREATE_NOEXPIRE))
2166 err = add_arg (gpg, "never");
2167 else if (expires == 0)
2168 err = add_arg (gpg, "-");
2172 snprintf (tmpbuf, sizeof tmpbuf, "seconds=%lu", expires);
2173 err = add_arg (gpg, tmpbuf);
2184 static gpgme_error_t
2185 gpg_createkey_from_param (engine_gpg_t gpg,
2186 gpgme_data_t help_data, unsigned int extraflags)
2190 err = add_arg (gpg, "--gen-key");
2191 if (!err && (extraflags & GENKEY_EXTRAFLAG_ARMOR))
2192 err = add_arg (gpg, "--armor");
2194 err = add_arg (gpg, "--");
2196 err = add_data (gpg, help_data, -1, 0);
2203 static gpgme_error_t
2204 gpg_createkey (engine_gpg_t gpg,
2205 const char *userid, const char *algo,
2206 unsigned long expires,
2208 unsigned int extraflags)
2212 err = add_arg (gpg, "--quick-gen-key");
2213 if (!err && (extraflags & GENKEY_EXTRAFLAG_ARMOR))
2214 err = add_arg (gpg, "--armor");
2215 if (!err && (flags & GPGME_CREATE_NOPASSWD))
2217 err = add_arg (gpg, "--passphrase");
2219 err = add_arg (gpg, "");
2221 err = add_arg (gpg, "--batch");
2223 if (!err && (flags & GPGME_CREATE_FORCE))
2224 err = add_arg (gpg, "--yes");
2226 err = add_arg (gpg, "--");
2228 err = add_arg (gpg, userid);
2231 err = gpg_add_algo_usage_expire (gpg, algo, expires, flags);
2239 static gpgme_error_t
2240 gpg_addkey (engine_gpg_t gpg,
2242 unsigned long expires,
2245 unsigned int extraflags)
2249 if (!key || !key->fpr)
2250 return gpg_error (GPG_ERR_INV_ARG);
2252 err = add_arg (gpg, "--quick-addkey");
2253 if (!err && (extraflags & GENKEY_EXTRAFLAG_ARMOR))
2254 err = add_arg (gpg, "--armor");
2255 if (!err && (flags & GPGME_CREATE_NOPASSWD))
2257 err = add_arg (gpg, "--passphrase");
2259 err = add_arg (gpg, "");
2261 err = add_arg (gpg, "--batch");
2264 err = add_arg (gpg, "--");
2266 err = add_arg (gpg, key->fpr);
2269 err = gpg_add_algo_usage_expire (gpg, algo, expires, flags);
2277 static gpgme_error_t
2278 gpg_adduid (engine_gpg_t gpg,
2281 unsigned int extraflags)
2285 if (!key || !key->fpr || !userid)
2286 return gpg_error (GPG_ERR_INV_ARG);
2288 if ((extraflags & GENKEY_EXTRAFLAG_SETPRIMARY))
2290 if (!have_gpg_version (gpg, "2.1.20"))
2291 err = gpg_error (GPG_ERR_NOT_SUPPORTED);
2293 err = add_arg (gpg, "--quick-set-primary-uid");
2295 else if ((extraflags & GENKEY_EXTRAFLAG_REVOKE))
2296 err = add_arg (gpg, "--quick-revuid");
2298 err = add_arg (gpg, "--quick-adduid");
2301 err = add_arg (gpg, "--");
2303 err = add_arg (gpg, key->fpr);
2305 err = add_arg (gpg, userid);
2313 static gpgme_error_t
2314 gpg_genkey (void *engine,
2315 const char *userid, const char *algo,
2316 unsigned long reserved, unsigned long expires,
2317 gpgme_key_t key, unsigned int flags,
2318 gpgme_data_t help_data, unsigned int extraflags,
2319 gpgme_data_t pubkey, gpgme_data_t seckey)
2321 engine_gpg_t gpg = engine;
2327 return gpg_error (GPG_ERR_INV_VALUE);
2329 /* If HELP_DATA is given the use of the old interface
2330 * (gpgme_op_genkey) has been requested. The other modes are:
2332 * USERID && !KEY - Create a new keyblock.
2333 * !USERID && KEY - Add a new subkey to KEY (gpg >= 2.1.14)
2334 * USERID && KEY && !ALGO - Add a new user id to KEY (gpg >= 2.1.14).
2335 * or set a flag on a user id.
2339 /* We need a special mechanism to get the fd of a pipe here, so
2340 that we can use this for the %pubring and %secring
2341 parameters. We don't have this yet, so we implement only the
2342 adding to the standard keyrings. */
2343 if (pubkey || seckey)
2344 err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
2346 err = gpg_createkey_from_param (gpg, help_data, extraflags);
2348 else if (!have_gpg_version (gpg, "2.1.13"))
2349 err = gpg_error (GPG_ERR_NOT_SUPPORTED);
2350 else if (userid && !key)
2351 err = gpg_createkey (gpg, userid, algo, expires, flags, extraflags);
2352 else if (!userid && key)
2353 err = gpg_addkey (gpg, algo, expires, key, flags, extraflags);
2354 else if (userid && key && !algo)
2355 err = gpg_adduid (gpg, key, userid, extraflags);
2357 err = gpg_error (GPG_ERR_INV_VALUE);
2362 /* Return the next DELIM delimited string from DATA as a C-string.
2363 The caller needs to provide the address of a pointer variable which
2364 he has to set to NULL before the first call. After the last call
2365 to this function, this function needs to be called once more with
2366 DATA set to NULL so that the function can release its internal
2367 state. After that the pointer variable is free for use again.
2368 Note that we use a delimiter and thus a trailing delimiter is not
2369 required. DELIM may not be changed after the first call. */
2371 string_from_data (gpgme_data_t data, int delim,
2372 void **helpptr, gpgme_error_t *r_err)
2374 #define MYBUFLEN 2000 /* Fixme: We don't support URLs longer than that. */
2377 int nbytes; /* Length of the last returned string including
2379 int buflen; /* Valid length of BUF. */
2380 char buf[MYBUFLEN+1]; /* Buffer with one byte extra space. */
2400 self = malloc (sizeof *self);
2403 *r_err = gpg_error_from_syserror ();
2415 assert (self->nbytes <= self->buflen);
2416 memmove (self->buf, self->buf + self->nbytes, self->buflen - self->nbytes);
2417 self->buflen -= self->nbytes;
2422 /* Fixme: This is fairly infective scanning because we may scan
2423 the buffer several times. */
2424 p = memchr (self->buf, delim, self->buflen);
2428 self->nbytes = p - self->buf + 1;
2432 if ( !(MYBUFLEN - self->buflen) )
2434 /* Not enough space - URL too long. */
2435 *r_err = gpg_error (GPG_ERR_TOO_LARGE);
2439 nread = gpgme_data_read (data, self->buf + self->buflen,
2440 MYBUFLEN - self->buflen);
2443 *r_err = gpg_error_from_syserror ();
2446 self->buflen += nread;
2450 /* EOF reached. If we have anything in the buffer, append a Nul and
2455 self->buf[self->buflen] = 0; /* (we allocated one extra byte) */
2464 static gpgme_error_t
2465 gpg_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray)
2467 engine_gpg_t gpg = engine;
2470 gpgme_data_encoding_t dataenc;
2472 if (keydata && keyarray)
2473 return gpg_error (GPG_ERR_INV_VALUE); /* Only one is allowed. */
2475 dataenc = gpgme_data_get_encoding (keydata);
2479 err = add_arg (gpg, "--recv-keys");
2481 err = add_arg (gpg, "--");
2482 for (idx=0; !err && keyarray[idx]; idx++)
2484 if (keyarray[idx]->protocol != GPGME_PROTOCOL_OpenPGP)
2486 else if (!keyarray[idx]->subkeys)
2488 else if (keyarray[idx]->subkeys->fpr && *keyarray[idx]->subkeys->fpr)
2489 err = add_arg (gpg, keyarray[idx]->subkeys->fpr);
2490 else if (*keyarray[idx]->subkeys->keyid)
2491 err = add_arg (gpg, keyarray[idx]->subkeys->keyid);
2494 else if (dataenc == GPGME_DATA_ENCODING_URL
2495 || dataenc == GPGME_DATA_ENCODING_URL0)
2500 int delim = (dataenc == GPGME_DATA_ENCODING_URL)? '\n': 0;
2502 /* FIXME: --fetch-keys is probably not correct because it can't
2503 grok all kinds of URLs. On Unix it should just work but on
2504 Windows we will build the command line and that may fail for
2505 some embedded control characters. It is anyway limited to
2506 the maximum size of the command line. We need another
2507 command which can take its input from a file. Maybe we
2508 should use an option to gpg to modify such commands (ala
2510 err = add_arg (gpg, "--fetch-keys");
2512 err = add_arg (gpg, "--");
2515 && (string = string_from_data (keydata, delim, &helpptr, &xerr)))
2516 err = add_arg (gpg, string);
2519 string_from_data (NULL, delim, &helpptr, &xerr);
2521 else if (dataenc == GPGME_DATA_ENCODING_URLESC)
2523 /* Already escaped URLs are not yet supported. */
2524 err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
2528 err = add_arg (gpg, "--import");
2530 err = add_arg (gpg, "--");
2532 err = add_data (gpg, keydata, -1, 0);
2542 /* The output for external keylistings in GnuPG is different from all
2543 the other key listings. We catch this here with a special
2544 preprocessor that reformats the colon handler lines. */
2545 static gpgme_error_t
2546 gpg_keylist_preprocess (char *line, char **r_line)
2550 RT_NONE, RT_INFO, RT_PUB, RT_UID
2553 #define NR_FIELDS 16
2554 char *field[NR_FIELDS];
2560 while (line && fields < NR_FIELDS)
2562 field[fields++] = line;
2563 line = strchr (line, ':');
2568 if (!strcmp (field[0], "info"))
2570 else if (!strcmp (field[0], "pub"))
2572 else if (!strcmp (field[0], "uid"))
2580 /* FIXME: Eventually, check the version number at least. */
2589 pub:<keyid>:<algo>:<keylen>:<creationdate>:<expirationdate>:<flags>
2591 as defined in 5.2. Machine Readable Indexes of the OpenPGP
2592 HTTP Keyserver Protocol (draft). Modern versions of the SKS
2593 keyserver return the fingerprint instead of the keyid. We
2594 detect this here and use the v4 fingerprint format to convert
2598 pub:o<flags>:<keylen>:<algo>:<keyid>:<creatdate>:<expdate>::::::::
2601 n = strlen (field[1]);
2604 if (gpgrt_asprintf (r_line,
2605 "pub:o%s:%s:%s:%s:%s:%s::::::::\n"
2607 field[6], field[3], field[2], field[1] + n - 16,
2608 field[4], field[5], field[1]) < 0)
2609 return gpg_error_from_syserror ();
2613 if (gpgrt_asprintf (r_line,
2614 "pub:o%s:%s:%s:%s:%s:%s::::::::",
2615 field[6], field[3], field[2], field[1],
2616 field[4], field[5]) < 0)
2617 return gpg_error_from_syserror ();
2625 uid:<escaped uid string>:<creationdate>:<expirationdate>:<flags>
2627 as defined in 5.2. Machine Readable Indexes of the OpenPGP
2628 HTTP Keyserver Protocol (draft).
2630 For an ldap keyserver the format is:
2631 uid:<escaped uid string>
2634 uid:o<flags>::::<creatdate>:<expdate>:::<c-coded uid>:
2638 /* The user ID is percent escaped, but we want c-coded.
2639 Because we have to replace each '%HL' by '\xHL', we need at
2640 most 4/3 th the number of bytes. But because we also need
2641 to escape the backslashes we allocate twice as much. */
2642 char *uid = malloc (2 * strlen (field[1]) + 1);
2647 return gpg_error_from_syserror ();
2657 /* Copy the next two bytes unconditionally. */
2659 *(dst++) = *(src++);
2661 *(dst++) = *(src++);
2663 else if (*src == '\\')
2670 *(dst++) = *(src++);
2676 if (gpgrt_asprintf (r_line, "uid:o::::::::%s:", uid) < 0)
2677 return gpg_error_from_syserror ();
2681 if (gpgrt_asprintf (r_line, "uid:o%s::::%s:%s:::%s:",
2682 field[4], field[2], field[3], uid) < 0)
2683 return gpg_error_from_syserror ();
2689 /* Unknown record. */
2698 gpg_keylist_build_options (engine_gpg_t gpg, int secret_only,
2699 gpgme_keylist_mode_t mode)
2703 err = add_arg (gpg, "--with-colons");
2705 /* Since gpg 2.1.15 fingerprints are always printed, thus there is
2706 * no more need to explicitly request them. */
2707 if (!have_gpg_version (gpg, "2.1.15"))
2710 err = add_arg (gpg, "--fixed-list-mode");
2712 err = add_arg (gpg, "--with-fingerprint");
2714 err = add_arg (gpg, "--with-fingerprint");
2717 if (!err && (mode & GPGME_KEYLIST_MODE_WITH_TOFU)
2718 && have_gpg_version (gpg, "2.1.16"))
2719 err = add_arg (gpg, "--with-tofu-info");
2721 if (!err && (mode & GPGME_KEYLIST_MODE_WITH_SECRET))
2722 err = add_arg (gpg, "--with-secret");
2725 && (mode & GPGME_KEYLIST_MODE_SIGS)
2726 && (mode & GPGME_KEYLIST_MODE_SIG_NOTATIONS))
2728 err = add_arg (gpg, "--list-options");
2730 err = add_arg (gpg, "show-sig-subpackets=\"20,26\"");
2735 if ( (mode & GPGME_KEYLIST_MODE_EXTERN) )
2738 err = gpg_error (GPG_ERR_NOT_SUPPORTED);
2739 else if ( (mode & GPGME_KEYLIST_MODE_LOCAL))
2741 /* The local+extern mode is special. It works only with
2742 gpg >= 2.0.10. FIXME: We should check that we have
2743 such a version to that we can return a proper error
2744 code. The problem is that we don't know the context
2745 here and thus can't access the cached version number
2746 for the engine info structure. */
2747 err = add_arg (gpg, "--locate-keys");
2748 if ((mode & GPGME_KEYLIST_MODE_SIGS))
2749 err = add_arg (gpg, "--with-sig-check");
2753 err = add_arg (gpg, "--search-keys");
2754 gpg->colon.preprocess_fnc = gpg_keylist_preprocess;
2759 err = add_arg (gpg, secret_only ? "--list-secret-keys"
2760 : ((mode & GPGME_KEYLIST_MODE_SIGS)
2761 ? "--check-sigs" : "--list-keys"));
2766 err = add_arg (gpg, "--");
2772 static gpgme_error_t
2773 gpg_keylist (void *engine, const char *pattern, int secret_only,
2774 gpgme_keylist_mode_t mode, int engine_flags)
2776 engine_gpg_t gpg = engine;
2781 err = gpg_keylist_build_options (gpg, secret_only, mode);
2783 if (!err && pattern && *pattern)
2784 err = add_arg (gpg, pattern);
2793 static gpgme_error_t
2794 gpg_keylist_ext (void *engine, const char *pattern[], int secret_only,
2795 int reserved, gpgme_keylist_mode_t mode, int engine_flags)
2797 engine_gpg_t gpg = engine;
2803 return gpg_error (GPG_ERR_INV_VALUE);
2805 err = gpg_keylist_build_options (gpg, secret_only, mode);
2809 while (!err && *pattern && **pattern)
2810 err = add_arg (gpg, *(pattern++));
2820 static gpgme_error_t
2821 gpg_keylist_data (void *engine, gpgme_data_t data)
2823 engine_gpg_t gpg = engine;
2826 if (!have_gpg_version (gpg, "2.1.14"))
2827 return gpg_error (GPG_ERR_NOT_SUPPORTED);
2829 err = add_arg (gpg, "--with-colons");
2831 err = add_arg (gpg, "--with-fingerprint");
2833 err = add_arg (gpg, "--import-options");
2835 err = add_arg (gpg, "import-show");
2837 err = add_arg (gpg, "--dry-run");
2839 err = add_arg (gpg, "--import");
2841 err = add_arg (gpg, "--");
2843 err = add_data (gpg, data, -1, 0);
2852 static gpgme_error_t
2853 gpg_keysign (void *engine, gpgme_key_t key, const char *userid,
2854 unsigned long expire, unsigned int flags,
2857 engine_gpg_t gpg = engine;
2861 if (!key || !key->fpr)
2862 return gpg_error (GPG_ERR_INV_ARG);
2864 if (!have_gpg_version (gpg, "2.1.12"))
2865 return gpg_error (GPG_ERR_NOT_SUPPORTED);
2867 if ((flags & GPGME_KEYSIGN_LOCAL))
2868 err = add_arg (gpg, "--quick-lsign-key");
2870 err = add_arg (gpg, "--quick-sign-key");
2873 err = append_args_from_signers (gpg, ctx);
2875 /* If an expiration time has been given use that. If none has been
2876 * given the default from gpg.conf is used. To make sure not to set
2877 * an expiration time at all the flag GPGME_KEYSIGN_NOEXPIRE can be
2879 if (!err && (expire || (flags & GPGME_KEYSIGN_NOEXPIRE)))
2883 if ((flags & GPGME_KEYSIGN_NOEXPIRE))
2885 snprintf (tmpbuf, sizeof tmpbuf, "seconds=%lu", expire);
2886 err = add_arg (gpg, "--default-cert-expire");
2888 err = add_arg (gpg, tmpbuf);
2892 err = add_arg (gpg, "--");
2895 err = add_arg (gpg, key->fpr);
2898 if ((flags & GPGME_KEYSIGN_LFSEP))
2900 for (; !err && (s = strchr (userid, '\n')); userid = s + 1)
2902 err = add_arg_len (gpg, "=", userid, s - userid);
2903 if (!err && *userid)
2904 err = add_arg_pfx (gpg, "=", userid);
2907 err = add_arg_pfx (gpg, "=", userid);
2917 static gpgme_error_t
2918 gpg_tofu_policy (void *engine, gpgme_key_t key, gpgme_tofu_policy_t policy)
2920 engine_gpg_t gpg = engine;
2922 const char *policystr = NULL;
2924 if (!key || !key->fpr)
2925 return gpg_error (GPG_ERR_INV_ARG);
2929 case GPGME_TOFU_POLICY_NONE: break;
2930 case GPGME_TOFU_POLICY_AUTO: policystr = "auto"; break;
2931 case GPGME_TOFU_POLICY_GOOD: policystr = "good"; break;
2932 case GPGME_TOFU_POLICY_BAD: policystr = "bad"; break;
2933 case GPGME_TOFU_POLICY_ASK: policystr = "ask"; break;
2934 case GPGME_TOFU_POLICY_UNKNOWN: policystr = "unknown"; break;
2937 return gpg_error (GPG_ERR_INV_VALUE);
2939 if (!have_gpg_version (gpg, "2.1.10"))
2940 return gpg_error (GPG_ERR_NOT_SUPPORTED);
2942 err = add_arg (gpg, "--tofu-policy");
2944 err = add_arg (gpg, "--");
2946 err = add_arg (gpg, policystr);
2948 err = add_arg (gpg, key->fpr);
2957 static gpgme_error_t
2958 gpg_sign (void *engine, gpgme_data_t in, gpgme_data_t out,
2959 gpgme_sig_mode_t mode, int use_armor, int use_textmode,
2960 int include_certs, gpgme_ctx_t ctx /* FIXME */)
2962 engine_gpg_t gpg = engine;
2965 (void)include_certs;
2967 if (mode == GPGME_SIG_MODE_CLEAR)
2968 err = add_arg (gpg, "--clearsign");
2971 err = add_arg (gpg, "--sign");
2972 if (!err && mode == GPGME_SIG_MODE_DETACH)
2973 err = add_arg (gpg, "--detach");
2974 if (!err && use_armor)
2975 err = add_arg (gpg, "--armor");
2978 if (gpgme_data_get_encoding (in) == GPGME_DATA_ENCODING_MIME
2979 && have_gpg_version (gpg, "2.1.14"))
2980 err = add_arg (gpg, "--mimemode");
2981 else if (use_textmode)
2982 err = add_arg (gpg, "--textmode");
2987 err = append_args_from_signers (gpg, ctx);
2989 err = append_args_from_sender (gpg, ctx);
2991 err = append_args_from_sig_notations (gpg, ctx);
2993 if (gpgme_data_get_file_name (in))
2996 err = add_arg (gpg, "--set-filename");
2998 err = add_arg (gpg, gpgme_data_get_file_name (in));
3001 /* Tell the gpg object about the data. */
3003 err = add_input_size_hint (gpg, in);
3005 err = add_arg (gpg, "--");
3007 err = add_data (gpg, in, -1, 0);
3009 err = add_data (gpg, out, 1, 1);
3017 static gpgme_error_t
3018 gpg_trustlist (void *engine, const char *pattern)
3020 engine_gpg_t gpg = engine;
3023 err = add_arg (gpg, "--with-colons");
3025 err = add_arg (gpg, "--list-trust-path");
3027 /* Tell the gpg object about the data. */
3029 err = add_arg (gpg, "--");
3031 err = add_arg (gpg, pattern);
3040 static gpgme_error_t
3041 gpg_verify (void *engine, gpgme_data_t sig, gpgme_data_t signed_text,
3042 gpgme_data_t plaintext, gpgme_ctx_t ctx)
3044 engine_gpg_t gpg = engine;
3047 err = append_args_from_sender (gpg, ctx);
3048 if (!err && ctx->auto_key_retrieve)
3049 err = add_arg (gpg, "--auto-key-retrieve");
3055 /* Normal or cleartext signature. */
3056 err = add_arg (gpg, "--output");
3058 err = add_arg (gpg, "-");
3060 err = add_input_size_hint (gpg, sig);
3062 err = add_arg (gpg, "--");
3064 err = add_data (gpg, sig, -1, 0);
3066 err = add_data (gpg, plaintext, 1, 1);
3070 err = add_arg (gpg, "--verify");
3072 err = add_input_size_hint (gpg, signed_text);
3074 err = add_arg (gpg, "--");
3076 err = add_data (gpg, sig, -1, 0);
3077 if (!err && signed_text)
3078 err = add_data (gpg, signed_text, -1, 0);
3089 gpg_set_io_cbs (void *engine, gpgme_io_cbs_t io_cbs)
3091 engine_gpg_t gpg = engine;
3093 gpg->io_cbs = *io_cbs;
3097 static gpgme_error_t
3098 gpg_set_pinentry_mode (void *engine, gpgme_pinentry_mode_t mode)
3100 engine_gpg_t gpg = engine;
3102 gpg->pinentry_mode = mode;
3108 struct engine_ops _gpgme_engine_ops_gpg =
3110 /* Static functions. */
3111 _gpgme_get_default_gpg_name,
3114 gpg_get_req_version,
3117 /* Member functions. */
3121 gpg_set_status_handler,
3122 gpg_set_command_handler,
3123 gpg_set_colon_line_handler,
3125 NULL, /* set_protocol */
3126 gpg_set_engine_flags, /* set_engine_flags */
3140 gpg_tofu_policy, /* tofu_policy */
3144 NULL, /* getauditlog */
3145 NULL, /* opassuan_transact */
3146 NULL, /* conf_load */
3147 NULL, /* conf_save */
3148 NULL, /* conf_dir */
3149 NULL, /* query_swdb */
3153 NULL, /* cancel_op */
3155 gpg_set_pinentry_mode,