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>
33 #include <lib-sys/unix.h>
35 #include <lib-mime/mime.h>
37 #include <lib-ui/curses.h>
40 #include "mutt_idna.h"
45 * The actual command line formatter.
48 struct pgp_command_context {
49 short need_passphrase; /* %p */
50 const char *fname; /* %f */
51 const char *sig_fname; /* %s */
52 const char *signas; /* %a */
53 const char *ids; /* %r */
58 _mutt_fmt_pgp_command(char *dest, ssize_t destlen,
59 char op, const char *src, const char *prefix,
60 const char *ifstring, const char *elsestring,
61 unsigned long data, format_flag flags)
64 struct pgp_command_context *cctx = (struct pgp_command_context *) data;
65 int optional = (flags & M_FORMAT_OPTIONAL);
71 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
72 snprintf (dest, destlen, fmt, NONULL (cctx->ids));
82 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
83 snprintf (dest, destlen, fmt, NONULL (cctx->signas));
85 else if (!cctx->signas)
93 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
94 snprintf (dest, destlen, fmt, NONULL (cctx->sig_fname));
96 else if (!cctx->sig_fname)
104 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
105 snprintf (dest, destlen, fmt, NONULL (cctx->fname));
107 else if (!cctx->fname)
115 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
116 snprintf (dest, destlen, fmt,
117 cctx->need_passphrase ? "PGPPASSFD=0" : "");
119 else if (!cctx->need_passphrase || pgp_use_gpg_agent ())
131 mutt_FormatString (dest, destlen, ifstring, _mutt_fmt_pgp_command, data,
133 else if (flags & M_FORMAT_OPTIONAL)
134 mutt_FormatString (dest, destlen, elsestring, _mutt_fmt_pgp_command, data,
140 void mutt_pgp_command (char *d, ssize_t dlen, struct pgp_command_context *cctx,
143 mutt_FormatString (d, dlen, NONULL (fmt), _mutt_fmt_pgp_command,
144 (unsigned long) cctx, 0);
152 static pid_t pgp_invoke (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
153 int pgpinfd, int pgpoutfd, int pgperrfd,
154 short need_passphrase,
156 const char *sig_fname,
158 const char *ids, const char *format)
160 struct pgp_command_context cctx;
161 char cmd[HUGE_STRING];
165 if (!format || !*format)
168 cctx.need_passphrase = need_passphrase;
170 cctx.sig_fname = sig_fname;
171 cctx.signas = signas;
174 mutt_pgp_command (cmd, sizeof (cmd), &cctx, format);
176 return mutt_create_filter_fd (cmd, pgpin, pgpout, pgperr,
177 pgpinfd, pgpoutfd, pgperrfd);
182 * The exported interface.
184 * This is historic and may be removed at some point.
189 pid_t pgp_invoke_decode (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
190 int pgpinfd, int pgpoutfd, int pgperrfd,
191 const char *fname, short need_passphrase)
193 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
194 need_passphrase, fname, NULL, NULL, NULL,
198 pid_t pgp_invoke_verify (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
199 int pgpinfd, int pgpoutfd, int pgperrfd,
200 const char *fname, const char *sig_fname)
202 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
203 0, fname, sig_fname, NULL, NULL, PgpVerifyCommand);
206 pid_t pgp_invoke_decrypt (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
207 int pgpinfd, int pgpoutfd, int pgperrfd,
210 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
211 1, fname, NULL, NULL, NULL, PgpDecryptCommand);
214 pid_t pgp_invoke_sign (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
215 int pgpinfd, int pgpoutfd, int pgperrfd,
218 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
219 1, fname, NULL, PgpSignAs, NULL, PgpSignCommand);
223 pid_t pgp_invoke_encrypt (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
224 int pgpinfd, int pgpoutfd, int pgperrfd,
225 const char *fname, const char *uids, int sign)
228 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
229 1, fname, NULL, PgpSignAs, uids,
230 PgpEncryptSignCommand);
232 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
233 0, fname, NULL, NULL, uids, PgpEncryptOnlyCommand);
236 pid_t pgp_invoke_traditional (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
237 int pgpinfd, int pgpoutfd, int pgperrfd,
238 const char *fname, const char *uids, int flags)
241 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
242 flags & SIGN ? 1 : 0, fname, NULL, PgpSignAs, uids,
243 flags & SIGN ? PgpEncryptSignCommand :
244 PgpEncryptOnlyCommand);
246 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
247 1, fname, NULL, PgpSignAs, NULL, PgpClearSignCommand);
251 void pgp_invoke_import (const char *fname)
253 char _fname[_POSIX_PATH_MAX + SHORT_STRING];
254 char cmd[HUGE_STRING];
255 struct pgp_command_context cctx;
259 mutt_quote_filename (_fname, sizeof (_fname), fname);
262 mutt_pgp_command (cmd, sizeof (cmd), &cctx, PgpImportCommand);
266 void pgp_invoke_getkeys (address_t * addr)
268 char buff[LONG_STRING];
269 char tmp[LONG_STRING];
270 char cmd[HUGE_STRING];
275 struct pgp_command_context cctx;
277 if (!PgpGetkeysCommand)
282 personal = addr->personal;
283 addr->personal = NULL;
286 mutt_addrlist_to_local (addr);
287 rfc822_write_address_single (tmp, sizeof (tmp), addr, 0);
288 mutt_quote_filename (buff, sizeof (buff), tmp);
290 addr->personal = personal;
294 mutt_pgp_command (cmd, sizeof (cmd), &cctx, PgpGetkeysCommand);
296 devnull = open ("/dev/null", O_RDWR);
299 mutt_message _("Fetching PGP key...");
309 pid_t pgp_invoke_export (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
310 int pgpinfd, int pgpoutfd, int pgperrfd,
313 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
314 0, NULL, NULL, NULL, uids, PgpExportCommand);
317 pid_t pgp_invoke_verify_key (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
318 int pgpinfd, int pgpoutfd, int pgperrfd,
321 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
322 0, NULL, NULL, NULL, uids, PgpVerifyKeyCommand);
325 pid_t pgp_invoke_list_keys (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
326 int pgpinfd, int pgpoutfd, int pgperrfd,
327 pgp_ring_t keyring, string_list_t * hints)
329 char uids[HUGE_STRING];
330 char tmpuids[HUGE_STRING];
331 char quoted[HUGE_STRING];
335 for (; hints; hints = hints->next) {
336 mutt_quote_filename (quoted, sizeof (quoted), (char *) hints->data);
337 snprintf (tmpuids, sizeof (tmpuids), "%s %s", uids, quoted);
338 strcpy (uids, tmpuids); /* __STRCPY_CHECKED__ */
341 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
342 0, NULL, NULL, NULL, uids,
343 keyring == PGP_SECRING ? PgpListSecringCommand :
344 PgpListPubringCommand);