2 * Copyright notice from original mutt:
3 * Copyright (C) 1997-2000 Thomas Roessler <roessler@does-not-exist.org>
5 * This file is part of mutt-ng, see http://www.muttng.org/.
6 * It's licensed under the GNU General Public License,
7 * please see the file GPL in the top level source directory.
10 /* This file contains the new pgp invocation code. Note that this
11 * is almost entirely format based.
18 #include <sys/types.h>
28 #include <lib-lib/mem.h>
29 #include <lib-lib/str.h>
30 #include <lib-lib/macros.h>
31 #include <lib-lib/file.h>
32 #include <lib-lib/debug.h>
34 #include <lib-sys/unix.h>
36 #include <lib-mime/mime.h>
38 #include <lib-ui/curses.h>
41 #include "mutt_idna.h"
46 * The actual command line formatter.
49 struct pgp_command_context {
50 short need_passphrase; /* %p */
51 const char *fname; /* %f */
52 const char *sig_fname; /* %s */
53 const char *signas; /* %a */
54 const char *ids; /* %r */
58 const char *_mutt_fmt_pgp_command (char *dest,
64 const char *elsestring,
65 unsigned long data, format_flag flags)
68 struct pgp_command_context *cctx = (struct pgp_command_context *) data;
69 int optional = (flags & M_FORMAT_OPTIONAL);
75 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
76 snprintf (dest, destlen, fmt, NONULL (cctx->ids));
86 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
87 snprintf (dest, destlen, fmt, NONULL (cctx->signas));
89 else if (!cctx->signas)
97 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
98 snprintf (dest, destlen, fmt, NONULL (cctx->sig_fname));
100 else if (!cctx->sig_fname)
108 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
109 snprintf (dest, destlen, fmt, NONULL (cctx->fname));
111 else if (!cctx->fname)
119 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
120 snprintf (dest, destlen, fmt,
121 cctx->need_passphrase ? "PGPPASSFD=0" : "");
123 else if (!cctx->need_passphrase || pgp_use_gpg_agent ())
135 mutt_FormatString (dest, destlen, ifstring, _mutt_fmt_pgp_command, data,
137 else if (flags & M_FORMAT_OPTIONAL)
138 mutt_FormatString (dest, destlen, elsestring, _mutt_fmt_pgp_command, data,
144 void mutt_pgp_command (char *d, size_t dlen, struct pgp_command_context *cctx,
147 mutt_FormatString (d, dlen, NONULL (fmt), _mutt_fmt_pgp_command,
148 (unsigned long) cctx, 0);
149 debug_print (2, ("%s\n", d));
157 static pid_t pgp_invoke (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
158 int pgpinfd, int pgpoutfd, int pgperrfd,
159 short need_passphrase,
161 const char *sig_fname,
163 const char *ids, const char *format)
165 struct pgp_command_context cctx;
166 char cmd[HUGE_STRING];
170 if (!format || !*format)
173 cctx.need_passphrase = need_passphrase;
175 cctx.sig_fname = sig_fname;
176 cctx.signas = signas;
179 mutt_pgp_command (cmd, sizeof (cmd), &cctx, format);
181 return mutt_create_filter_fd (cmd, pgpin, pgpout, pgperr,
182 pgpinfd, pgpoutfd, pgperrfd);
187 * The exported interface.
189 * This is historic and may be removed at some point.
194 pid_t pgp_invoke_decode (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
195 int pgpinfd, int pgpoutfd, int pgperrfd,
196 const char *fname, short need_passphrase)
198 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
199 need_passphrase, fname, NULL, NULL, NULL,
203 pid_t pgp_invoke_verify (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
204 int pgpinfd, int pgpoutfd, int pgperrfd,
205 const char *fname, const char *sig_fname)
207 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
208 0, fname, sig_fname, NULL, NULL, PgpVerifyCommand);
211 pid_t pgp_invoke_decrypt (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
212 int pgpinfd, int pgpoutfd, int pgperrfd,
215 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
216 1, fname, NULL, NULL, NULL, PgpDecryptCommand);
219 pid_t pgp_invoke_sign (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
220 int pgpinfd, int pgpoutfd, int pgperrfd,
223 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
224 1, fname, NULL, PgpSignAs, NULL, PgpSignCommand);
228 pid_t pgp_invoke_encrypt (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
229 int pgpinfd, int pgpoutfd, int pgperrfd,
230 const char *fname, const char *uids, int sign)
233 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
234 1, fname, NULL, PgpSignAs, uids,
235 PgpEncryptSignCommand);
237 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
238 0, fname, NULL, NULL, uids, PgpEncryptOnlyCommand);
241 pid_t pgp_invoke_traditional (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
242 int pgpinfd, int pgpoutfd, int pgperrfd,
243 const char *fname, const char *uids, int flags)
246 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
247 flags & SIGN ? 1 : 0, fname, NULL, PgpSignAs, uids,
248 flags & SIGN ? PgpEncryptSignCommand :
249 PgpEncryptOnlyCommand);
251 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
252 1, fname, NULL, PgpSignAs, NULL, PgpClearSignCommand);
256 void pgp_invoke_import (const char *fname)
258 char _fname[_POSIX_PATH_MAX + SHORT_STRING];
259 char cmd[HUGE_STRING];
260 struct pgp_command_context cctx;
264 mutt_quote_filename (_fname, sizeof (_fname), fname);
267 mutt_pgp_command (cmd, sizeof (cmd), &cctx, PgpImportCommand);
271 void pgp_invoke_getkeys (address_t * addr)
273 char buff[LONG_STRING];
274 char tmp[LONG_STRING];
275 char cmd[HUGE_STRING];
280 struct pgp_command_context cctx;
282 if (!PgpGetkeysCommand)
287 personal = addr->personal;
288 addr->personal = NULL;
291 mutt_addrlist_to_local (addr);
292 rfc822_write_address_single (tmp, sizeof (tmp), addr, 0);
293 mutt_quote_filename (buff, sizeof (buff), tmp);
295 addr->personal = personal;
299 mutt_pgp_command (cmd, sizeof (cmd), &cctx, PgpGetkeysCommand);
301 devnull = open ("/dev/null", O_RDWR);
304 mutt_message _("Fetching PGP key...");
314 pid_t pgp_invoke_export (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
315 int pgpinfd, int pgpoutfd, int pgperrfd,
318 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
319 0, NULL, NULL, NULL, uids, PgpExportCommand);
322 pid_t pgp_invoke_verify_key (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
323 int pgpinfd, int pgpoutfd, int pgperrfd,
326 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
327 0, NULL, NULL, NULL, uids, PgpVerifyKeyCommand);
330 pid_t pgp_invoke_list_keys (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
331 int pgpinfd, int pgpoutfd, int pgperrfd,
332 pgp_ring_t keyring, string_list_t * hints)
334 char uids[HUGE_STRING];
335 char tmpuids[HUGE_STRING];
336 char quoted[HUGE_STRING];
340 for (; hints; hints = hints->next) {
341 mutt_quote_filename (quoted, sizeof (quoted), (char *) hints->data);
342 snprintf (tmpuids, sizeof (tmpuids), "%s %s", uids, quoted);
343 strcpy (uids, tmpuids); /* __STRCPY_CHECKED__ */
346 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
347 0, NULL, NULL, NULL, uids,
348 keyring == PGP_SECRING ? PgpListSecringCommand :
349 PgpListPubringCommand);