2 * Copyright (C) 1997-2000 Thomas Roessler <roessler@does-not-exist.org>
4 * This program is free software; you can redistribute it
5 * and/or modify it under the terms of the GNU General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later
10 * This program is distributed in the hope that it will be
11 * useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13 * PURPOSE. See the GNU General Public License for more
16 * You should have received a copy of the GNU General Public
17 * License along with this program; if not, write to the Free
18 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
22 /* This file contains the new pgp invocation code. Note that this
23 * is almost entirely format based.
30 #include <sys/types.h>
41 #include "mutt_curses.h"
42 #include "mutt_idna.h"
47 * The actual command line formatter.
50 struct pgp_command_context {
51 short need_passphrase; /* %p */
52 const char *fname; /* %f */
53 const char *sig_fname; /* %s */
54 const char *signas; /* %a */
55 const char *ids; /* %r */
59 const char *_mutt_fmt_pgp_command (char *dest,
66 const char *elsestring,
71 struct pgp_command_context *cctx = (struct pgp_command_context *) data;
72 int optional = (flags & M_FORMAT_OPTIONAL);
80 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
81 snprintf (dest, destlen, fmt, NONULL (cctx->ids));
92 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
93 snprintf (dest, destlen, fmt, NONULL (cctx->signas));
95 else if (!cctx->signas)
104 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
105 snprintf (dest, destlen, fmt, NONULL (cctx->sig_fname));
107 else if (!cctx->sig_fname)
116 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
117 snprintf (dest, destlen, fmt, NONULL (cctx->fname));
119 else if (!cctx->fname)
128 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
129 snprintf (dest, destlen, fmt, cctx->need_passphrase ? "PGPPASSFD=0" : "");
131 else if (!cctx->need_passphrase || pgp_use_gpg_agent())
143 mutt_FormatString (dest, destlen, col, ifstring, _mutt_fmt_pgp_command, data, 0);
144 else if (flags & M_FORMAT_OPTIONAL)
145 mutt_FormatString (dest, destlen, col, elsestring, _mutt_fmt_pgp_command, data, 0);
150 void mutt_pgp_command (char *d, size_t dlen, struct pgp_command_context *cctx, const char *fmt)
152 mutt_FormatString (d, dlen, 0, NONULL (fmt), _mutt_fmt_pgp_command, (unsigned long) cctx, 0);
153 dprint (2, (debugfile, "mutt_pgp_command: %s\n", d));
161 static pid_t pgp_invoke (FILE **pgpin, FILE **pgpout, FILE **pgperr,
162 int pgpinfd, int pgpoutfd, int pgperrfd,
163 short need_passphrase,
165 const char *sig_fname,
170 struct pgp_command_context cctx;
171 char cmd[HUGE_STRING];
173 memset (&cctx, 0, sizeof (cctx));
175 if (!format || !*format)
178 cctx.need_passphrase = need_passphrase;
180 cctx.sig_fname = sig_fname;
181 cctx.signas = signas;
184 mutt_pgp_command (cmd, sizeof (cmd), &cctx, format);
186 return mutt_create_filter_fd (cmd, pgpin, pgpout, pgperr,
187 pgpinfd, pgpoutfd, pgperrfd);
192 * The exported interface.
194 * This is historic and may be removed at some point.
199 pid_t pgp_invoke_decode (FILE **pgpin, FILE **pgpout, FILE **pgperr,
200 int pgpinfd, int pgpoutfd, int pgperrfd,
201 const char *fname, short need_passphrase)
203 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
204 need_passphrase, fname, NULL, NULL, NULL,
208 pid_t pgp_invoke_verify (FILE **pgpin, FILE **pgpout, FILE **pgperr,
209 int pgpinfd, int pgpoutfd, int pgperrfd,
210 const char *fname, const char *sig_fname)
212 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
213 0, fname, sig_fname, NULL, NULL, PgpVerifyCommand);
216 pid_t pgp_invoke_decrypt (FILE **pgpin, FILE **pgpout, FILE **pgperr,
217 int pgpinfd, int pgpoutfd, int pgperrfd,
220 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
221 1, fname, NULL, NULL, NULL, PgpDecryptCommand);
224 pid_t pgp_invoke_sign (FILE **pgpin, FILE **pgpout, FILE **pgperr,
225 int pgpinfd, int pgpoutfd, int pgperrfd,
228 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
229 1, fname, NULL, PgpSignAs, NULL, PgpSignCommand);
233 pid_t pgp_invoke_encrypt (FILE **pgpin, FILE **pgpout, FILE **pgperr,
234 int pgpinfd, int pgpoutfd, int pgperrfd,
235 const char *fname, const char *uids, int sign)
238 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
239 1, fname, NULL, PgpSignAs, uids,
240 PgpEncryptSignCommand);
242 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
243 0, fname, NULL, NULL, uids,
244 PgpEncryptOnlyCommand);
247 pid_t pgp_invoke_traditional (FILE **pgpin, FILE **pgpout, FILE **pgperr,
248 int pgpinfd, int pgpoutfd, int pgperrfd,
249 const char *fname, const char *uids, int flags)
252 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
253 flags & SIGN ? 1 : 0, fname, NULL, PgpSignAs, uids,
254 flags & SIGN ? PgpEncryptSignCommand : PgpEncryptOnlyCommand);
256 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
257 1, fname, NULL, PgpSignAs, NULL,
258 PgpClearSignCommand);
262 void pgp_invoke_import (const char *fname)
264 char _fname[_POSIX_PATH_MAX + SHORT_STRING];
265 char cmd[HUGE_STRING];
266 struct pgp_command_context cctx;
268 memset (&cctx, 0, sizeof (cctx));
270 mutt_quote_filename (_fname, sizeof (_fname), fname);
273 mutt_pgp_command (cmd, sizeof (cmd), &cctx, PgpImportCommand);
277 void pgp_invoke_getkeys (ADDRESS *addr)
279 char buff[LONG_STRING];
280 char tmp[LONG_STRING];
281 char cmd[HUGE_STRING];
286 struct pgp_command_context cctx;
288 if (!PgpGetkeysCommand) return;
290 memset (&cctx, 0, sizeof (cctx));
292 personal = addr->personal;
293 addr->personal = NULL;
296 mutt_addrlist_to_local (addr);
297 rfc822_write_address_single (tmp, sizeof (tmp), addr, 0);
298 mutt_quote_filename (buff, sizeof (buff), tmp);
300 addr->personal = personal;
304 mutt_pgp_command (cmd, sizeof (cmd), &cctx, PgpGetkeysCommand);
306 devnull = open ("/dev/null", O_RDWR);
308 if (!isendwin ()) mutt_message _("Fetching PGP key...");
312 if (!isendwin ()) mutt_clear_error ();
317 pid_t pgp_invoke_export (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,
326 pid_t pgp_invoke_verify_key (FILE **pgpin, FILE **pgpout, FILE **pgperr,
327 int pgpinfd, int pgpoutfd, int pgperrfd,
330 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
331 0, NULL, NULL, NULL, uids,
332 PgpVerifyKeyCommand);
335 pid_t pgp_invoke_list_keys (FILE **pgpin, FILE **pgpout, FILE **pgperr,
336 int pgpinfd, int pgpoutfd, int pgperrfd,
337 pgp_ring_t keyring, LIST *hints)
339 char uids[HUGE_STRING];
340 char tmpuids[HUGE_STRING];
341 char quoted[HUGE_STRING];
345 for (; hints; hints = hints->next)
347 mutt_quote_filename (quoted, sizeof (quoted), (char *) hints->data);
348 snprintf (tmpuids, sizeof (tmpuids), "%s %s", uids, quoted);
349 strcpy (uids, tmpuids); /* __STRCPY_CHECKED__ */
352 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
353 0, NULL, NULL, NULL, uids,
354 keyring == PGP_SECRING ? PgpListSecringCommand :
355 PgpListPubringCommand);