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>
29 #include "mutt_curses.h"
30 #include "mutt_idna.h"
37 #include "lib/debug.h"
40 * The actual command line formatter.
43 struct pgp_command_context {
44 short need_passphrase; /* %p */
45 const char *fname; /* %f */
46 const char *sig_fname; /* %s */
47 const char *signas; /* %a */
48 const char *ids; /* %r */
52 const char *_mutt_fmt_pgp_command (char *dest,
58 const char *elsestring,
59 unsigned long data, format_flag flags)
62 struct pgp_command_context *cctx = (struct pgp_command_context *) data;
63 int optional = (flags & M_FORMAT_OPTIONAL);
69 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
70 snprintf (dest, destlen, fmt, NONULL (cctx->ids));
80 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
81 snprintf (dest, destlen, fmt, NONULL (cctx->signas));
83 else if (!cctx->signas)
91 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
92 snprintf (dest, destlen, fmt, NONULL (cctx->sig_fname));
94 else if (!cctx->sig_fname)
102 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
103 snprintf (dest, destlen, fmt, NONULL (cctx->fname));
105 else if (!cctx->fname)
113 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
114 snprintf (dest, destlen, fmt,
115 cctx->need_passphrase ? "PGPPASSFD=0" : "");
117 else if (!cctx->need_passphrase || pgp_use_gpg_agent ())
129 mutt_FormatString (dest, destlen, ifstring, _mutt_fmt_pgp_command, data,
131 else if (flags & M_FORMAT_OPTIONAL)
132 mutt_FormatString (dest, destlen, elsestring, _mutt_fmt_pgp_command, data,
138 void mutt_pgp_command (char *d, size_t dlen, struct pgp_command_context *cctx,
141 mutt_FormatString (d, dlen, NONULL (fmt), _mutt_fmt_pgp_command,
142 (unsigned long) cctx, 0);
143 debug_print (2, ("%s\n", d));
151 static pid_t pgp_invoke (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
152 int pgpinfd, int pgpoutfd, int pgperrfd,
153 short need_passphrase,
155 const char *sig_fname,
157 const char *ids, const char *format)
159 struct pgp_command_context cctx;
160 char cmd[HUGE_STRING];
162 memset (&cctx, 0, sizeof (cctx));
164 if (!format || !*format)
167 cctx.need_passphrase = need_passphrase;
169 cctx.sig_fname = sig_fname;
170 cctx.signas = signas;
173 mutt_pgp_command (cmd, sizeof (cmd), &cctx, format);
175 return mutt_create_filter_fd (cmd, pgpin, pgpout, pgperr,
176 pgpinfd, pgpoutfd, pgperrfd);
181 * The exported interface.
183 * This is historic and may be removed at some point.
188 pid_t pgp_invoke_decode (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
189 int pgpinfd, int pgpoutfd, int pgperrfd,
190 const char *fname, short need_passphrase)
192 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
193 need_passphrase, fname, NULL, NULL, NULL,
197 pid_t pgp_invoke_verify (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
198 int pgpinfd, int pgpoutfd, int pgperrfd,
199 const char *fname, const char *sig_fname)
201 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
202 0, fname, sig_fname, NULL, NULL, PgpVerifyCommand);
205 pid_t pgp_invoke_decrypt (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
206 int pgpinfd, int pgpoutfd, int pgperrfd,
209 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
210 1, fname, NULL, NULL, NULL, PgpDecryptCommand);
213 pid_t pgp_invoke_sign (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
214 int pgpinfd, int pgpoutfd, int pgperrfd,
217 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
218 1, fname, NULL, PgpSignAs, NULL, PgpSignCommand);
222 pid_t pgp_invoke_encrypt (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
223 int pgpinfd, int pgpoutfd, int pgperrfd,
224 const char *fname, const char *uids, int sign)
227 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
228 1, fname, NULL, PgpSignAs, uids,
229 PgpEncryptSignCommand);
231 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
232 0, fname, NULL, NULL, uids, PgpEncryptOnlyCommand);
235 pid_t pgp_invoke_traditional (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
236 int pgpinfd, int pgpoutfd, int pgperrfd,
237 const char *fname, const char *uids, int flags)
240 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
241 flags & SIGN ? 1 : 0, fname, NULL, PgpSignAs, uids,
242 flags & SIGN ? PgpEncryptSignCommand :
243 PgpEncryptOnlyCommand);
245 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
246 1, fname, NULL, PgpSignAs, NULL, PgpClearSignCommand);
250 void pgp_invoke_import (const char *fname)
252 char _fname[_POSIX_PATH_MAX + SHORT_STRING];
253 char cmd[HUGE_STRING];
254 struct pgp_command_context cctx;
256 memset (&cctx, 0, sizeof (cctx));
258 mutt_quote_filename (_fname, sizeof (_fname), fname);
261 mutt_pgp_command (cmd, sizeof (cmd), &cctx, PgpImportCommand);
265 void pgp_invoke_getkeys (ADDRESS * addr)
267 char buff[LONG_STRING];
268 char tmp[LONG_STRING];
269 char cmd[HUGE_STRING];
274 struct pgp_command_context cctx;
276 if (!PgpGetkeysCommand)
279 memset (&cctx, 0, sizeof (cctx));
281 personal = addr->personal;
282 addr->personal = NULL;
285 mutt_addrlist_to_local (addr);
286 rfc822_write_address_single (tmp, sizeof (tmp), addr, 0);
287 mutt_quote_filename (buff, sizeof (buff), tmp);
289 addr->personal = personal;
293 mutt_pgp_command (cmd, sizeof (cmd), &cctx, PgpGetkeysCommand);
295 devnull = open ("/dev/null", O_RDWR);
298 mutt_message _("Fetching PGP key...");
308 pid_t pgp_invoke_export (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
309 int pgpinfd, int pgpoutfd, int pgperrfd,
312 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
313 0, NULL, NULL, NULL, uids, PgpExportCommand);
316 pid_t pgp_invoke_verify_key (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
317 int pgpinfd, int pgpoutfd, int pgperrfd,
320 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
321 0, NULL, NULL, NULL, uids, PgpVerifyKeyCommand);
324 pid_t pgp_invoke_list_keys (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
325 int pgpinfd, int pgpoutfd, int pgperrfd,
326 pgp_ring_t keyring, LIST * hints)
328 char uids[HUGE_STRING];
329 char tmpuids[HUGE_STRING];
330 char quoted[HUGE_STRING];
334 for (; hints; hints = hints->next) {
335 mutt_quote_filename (quoted, sizeof (quoted), (char *) hints->data);
336 snprintf (tmpuids, sizeof (tmpuids), "%s %s", uids, quoted);
337 strcpy (uids, tmpuids); /* __STRCPY_CHECKED__ */
340 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
341 0, NULL, NULL, NULL, uids,
342 keyring == PGP_SECRING ? PgpListSecringCommand :
343 PgpListPubringCommand);