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.
14 #include <lib-lib/lib-lib.h>
16 #include <lib-sys/unix.h>
18 #include <lib-mime/mime.h>
20 #include <lib-ui/curses.h>
23 #include "mutt_idna.h"
28 * The actual command line formatter.
31 struct pgp_command_context {
32 short need_passphrase; /* %p */
33 const char *fname; /* %f */
34 const char *sig_fname; /* %s */
35 const char *signas; /* %a */
36 const char *ids; /* %r */
41 _mutt_fmt_pgp_command(char *dest, ssize_t destlen,
42 char op, const char *src, const char *prefix,
43 const char *ifstring, const char *elsestring,
44 unsigned long data, format_flag flags)
47 struct pgp_command_context *cctx = (struct pgp_command_context *) data;
48 int optional = (flags & M_FORMAT_OPTIONAL);
54 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
55 snprintf (dest, destlen, fmt, NONULL (cctx->ids));
65 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
66 snprintf (dest, destlen, fmt, NONULL (cctx->signas));
68 else if (!cctx->signas)
76 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
77 snprintf (dest, destlen, fmt, NONULL (cctx->sig_fname));
79 else if (!cctx->sig_fname)
87 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
88 snprintf (dest, destlen, fmt, NONULL (cctx->fname));
90 else if (!cctx->fname)
98 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
99 snprintf (dest, destlen, fmt,
100 cctx->need_passphrase ? "PGPPASSFD=0" : "");
102 else if (!cctx->need_passphrase || pgp_use_gpg_agent ())
114 mutt_FormatString (dest, destlen, ifstring, _mutt_fmt_pgp_command, data,
116 else if (flags & M_FORMAT_OPTIONAL)
117 mutt_FormatString (dest, destlen, elsestring, _mutt_fmt_pgp_command, data,
123 void mutt_pgp_command (char *d, ssize_t dlen, struct pgp_command_context *cctx,
126 mutt_FormatString (d, dlen, NONULL (fmt), _mutt_fmt_pgp_command,
127 (unsigned long) cctx, 0);
135 static pid_t pgp_invoke (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
136 int pgpinfd, int pgpoutfd, int pgperrfd,
137 short need_passphrase,
139 const char *sig_fname,
141 const char *ids, const char *format)
143 struct pgp_command_context cctx;
144 char cmd[HUGE_STRING];
148 if (!format || !*format)
151 cctx.need_passphrase = need_passphrase;
153 cctx.sig_fname = sig_fname;
154 cctx.signas = signas;
157 mutt_pgp_command (cmd, sizeof (cmd), &cctx, format);
159 return mutt_create_filter_fd (cmd, pgpin, pgpout, pgperr,
160 pgpinfd, pgpoutfd, pgperrfd);
165 * The exported interface.
167 * This is historic and may be removed at some point.
172 pid_t pgp_invoke_decode (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
173 int pgpinfd, int pgpoutfd, int pgperrfd,
174 const char *fname, short need_passphrase)
176 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
177 need_passphrase, fname, NULL, NULL, NULL,
181 pid_t pgp_invoke_verify (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
182 int pgpinfd, int pgpoutfd, int pgperrfd,
183 const char *fname, const char *sig_fname)
185 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
186 0, fname, sig_fname, NULL, NULL, PgpVerifyCommand);
189 pid_t pgp_invoke_decrypt (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
190 int pgpinfd, int pgpoutfd, int pgperrfd,
193 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
194 1, fname, NULL, NULL, NULL, PgpDecryptCommand);
197 pid_t pgp_invoke_sign (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
198 int pgpinfd, int pgpoutfd, int pgperrfd,
201 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
202 1, fname, NULL, PgpSignAs, NULL, PgpSignCommand);
206 pid_t pgp_invoke_encrypt (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
207 int pgpinfd, int pgpoutfd, int pgperrfd,
208 const char *fname, const char *uids, int sign)
211 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
212 1, fname, NULL, PgpSignAs, uids,
213 PgpEncryptSignCommand);
215 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
216 0, fname, NULL, NULL, uids, PgpEncryptOnlyCommand);
219 pid_t pgp_invoke_traditional (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
220 int pgpinfd, int pgpoutfd, int pgperrfd,
221 const char *fname, const char *uids, int flags)
224 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
225 flags & SIGN ? 1 : 0, fname, NULL, PgpSignAs, uids,
226 flags & SIGN ? PgpEncryptSignCommand :
227 PgpEncryptOnlyCommand);
229 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
230 1, fname, NULL, PgpSignAs, NULL, PgpClearSignCommand);
234 void pgp_invoke_import (const char *fname)
236 char _fname[_POSIX_PATH_MAX + SHORT_STRING];
237 char cmd[HUGE_STRING];
238 struct pgp_command_context cctx;
242 mutt_quote_filename (_fname, sizeof (_fname), fname);
245 mutt_pgp_command (cmd, sizeof (cmd), &cctx, PgpImportCommand);
249 void pgp_invoke_getkeys (address_t * addr)
251 char buff[LONG_STRING];
252 char tmp[LONG_STRING];
253 char cmd[HUGE_STRING];
258 struct pgp_command_context cctx;
260 if (!PgpGetkeysCommand)
265 personal = addr->personal;
266 addr->personal = NULL;
269 mutt_addrlist_to_local (addr);
270 rfc822_write_address_single (tmp, sizeof (tmp), addr, 0);
271 mutt_quote_filename (buff, sizeof (buff), tmp);
273 addr->personal = personal;
277 mutt_pgp_command (cmd, sizeof (cmd), &cctx, PgpGetkeysCommand);
279 devnull = open ("/dev/null", O_RDWR);
282 mutt_message _("Fetching PGP key...");
292 pid_t pgp_invoke_export (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
293 int pgpinfd, int pgpoutfd, int pgperrfd,
296 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
297 0, NULL, NULL, NULL, uids, PgpExportCommand);
300 pid_t pgp_invoke_verify_key (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
301 int pgpinfd, int pgpoutfd, int pgperrfd,
304 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
305 0, NULL, NULL, NULL, uids, PgpVerifyKeyCommand);
308 pid_t pgp_invoke_list_keys (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
309 int pgpinfd, int pgpoutfd, int pgperrfd,
310 pgp_ring_t keyring, string_list_t * hints)
312 char uids[HUGE_STRING];
313 char tmpuids[HUGE_STRING];
314 char quoted[HUGE_STRING];
318 for (; hints; hints = hints->next) {
319 mutt_quote_filename (quoted, sizeof (quoted), (char *) hints->data);
320 snprintf (tmpuids, sizeof (tmpuids), "%s %s", uids, quoted);
321 strcpy (uids, tmpuids); /* __STRCPY_CHECKED__ */
324 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
325 0, NULL, NULL, NULL, uids,
326 keyring == PGP_SECRING ? PgpListSecringCommand :
327 PgpListPubringCommand);