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., 59 Temple Place - Suite 330,
19 * Boston, MA 02111, 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,
65 const char *elsestring,
66 unsigned long data, format_flag flags)
69 struct pgp_command_context *cctx = (struct pgp_command_context *) data;
70 int optional = (flags & M_FORMAT_OPTIONAL);
76 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
77 snprintf (dest, destlen, fmt, NONULL (cctx->ids));
87 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
88 snprintf (dest, destlen, fmt, NONULL (cctx->signas));
90 else if (!cctx->signas)
98 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
99 snprintf (dest, destlen, fmt, NONULL (cctx->sig_fname));
101 else if (!cctx->sig_fname)
109 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
110 snprintf (dest, destlen, fmt, NONULL (cctx->fname));
112 else if (!cctx->fname)
120 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
121 snprintf (dest, destlen, fmt,
122 cctx->need_passphrase ? "PGPPASSFD=0" : "");
124 else if (!cctx->need_passphrase || pgp_use_gpg_agent ())
136 mutt_FormatString (dest, destlen, ifstring, _mutt_fmt_pgp_command, data,
138 else if (flags & M_FORMAT_OPTIONAL)
139 mutt_FormatString (dest, destlen, elsestring, _mutt_fmt_pgp_command, data,
145 void mutt_pgp_command (char *d, size_t dlen, struct pgp_command_context *cctx,
148 mutt_FormatString (d, dlen, NONULL (fmt), _mutt_fmt_pgp_command,
149 (unsigned long) cctx, 0);
150 dprint (2, (debugfile, "mutt_pgp_command: %s\n", d));
158 static pid_t pgp_invoke (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
159 int pgpinfd, int pgpoutfd, int pgperrfd,
160 short need_passphrase,
162 const char *sig_fname,
164 const char *ids, const char *format)
166 struct pgp_command_context cctx;
167 char cmd[HUGE_STRING];
169 memset (&cctx, 0, sizeof (cctx));
171 if (!format || !*format)
174 cctx.need_passphrase = need_passphrase;
176 cctx.sig_fname = sig_fname;
177 cctx.signas = signas;
180 mutt_pgp_command (cmd, sizeof (cmd), &cctx, format);
182 return mutt_create_filter_fd (cmd, pgpin, pgpout, pgperr,
183 pgpinfd, pgpoutfd, pgperrfd);
188 * The exported interface.
190 * This is historic and may be removed at some point.
195 pid_t pgp_invoke_decode (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
196 int pgpinfd, int pgpoutfd, int pgperrfd,
197 const char *fname, short need_passphrase)
199 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
200 need_passphrase, fname, NULL, NULL, NULL,
204 pid_t pgp_invoke_verify (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
205 int pgpinfd, int pgpoutfd, int pgperrfd,
206 const char *fname, const char *sig_fname)
208 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
209 0, fname, sig_fname, NULL, NULL, PgpVerifyCommand);
212 pid_t pgp_invoke_decrypt (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
213 int pgpinfd, int pgpoutfd, int pgperrfd,
216 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
217 1, fname, NULL, NULL, NULL, PgpDecryptCommand);
220 pid_t pgp_invoke_sign (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
221 int pgpinfd, int pgpoutfd, int pgperrfd,
224 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
225 1, fname, NULL, PgpSignAs, NULL, PgpSignCommand);
229 pid_t pgp_invoke_encrypt (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
230 int pgpinfd, int pgpoutfd, int pgperrfd,
231 const char *fname, const char *uids, int sign)
234 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
235 1, fname, NULL, PgpSignAs, uids,
236 PgpEncryptSignCommand);
238 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
239 0, fname, NULL, NULL, uids, PgpEncryptOnlyCommand);
242 pid_t pgp_invoke_traditional (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
243 int pgpinfd, int pgpoutfd, int pgperrfd,
244 const char *fname, const char *uids, int flags)
247 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
248 flags & SIGN ? 1 : 0, fname, NULL, PgpSignAs, uids,
249 flags & SIGN ? PgpEncryptSignCommand :
250 PgpEncryptOnlyCommand);
252 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
253 1, fname, NULL, PgpSignAs, NULL, PgpClearSignCommand);
257 void pgp_invoke_import (const char *fname)
259 char _fname[_POSIX_PATH_MAX + SHORT_STRING];
260 char cmd[HUGE_STRING];
261 struct pgp_command_context cctx;
263 memset (&cctx, 0, sizeof (cctx));
265 mutt_quote_filename (_fname, sizeof (_fname), fname);
268 mutt_pgp_command (cmd, sizeof (cmd), &cctx, PgpImportCommand);
272 void pgp_invoke_getkeys (ADDRESS * addr)
274 char buff[LONG_STRING];
275 char tmp[LONG_STRING];
276 char cmd[HUGE_STRING];
281 struct pgp_command_context cctx;
283 if (!PgpGetkeysCommand)
286 memset (&cctx, 0, sizeof (cctx));
288 personal = addr->personal;
289 addr->personal = NULL;
292 mutt_addrlist_to_local (addr);
293 rfc822_write_address_single (tmp, sizeof (tmp), addr, 0);
294 mutt_quote_filename (buff, sizeof (buff), tmp);
296 addr->personal = personal;
300 mutt_pgp_command (cmd, sizeof (cmd), &cctx, PgpGetkeysCommand);
302 devnull = open ("/dev/null", O_RDWR);
305 mutt_message _("Fetching PGP key...");
315 pid_t pgp_invoke_export (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
316 int pgpinfd, int pgpoutfd, int pgperrfd,
319 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
320 0, NULL, NULL, NULL, uids, PgpExportCommand);
323 pid_t pgp_invoke_verify_key (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
324 int pgpinfd, int pgpoutfd, int pgperrfd,
327 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
328 0, NULL, NULL, NULL, uids, PgpVerifyKeyCommand);
331 pid_t pgp_invoke_list_keys (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
332 int pgpinfd, int pgpoutfd, int pgperrfd,
333 pgp_ring_t keyring, LIST * hints)
335 char uids[HUGE_STRING];
336 char tmpuids[HUGE_STRING];
337 char quoted[HUGE_STRING];
341 for (; hints; hints = hints->next) {
342 mutt_quote_filename (quoted, sizeof (quoted), (char *) hints->data);
343 snprintf (tmpuids, sizeof (tmpuids), "%s %s", uids, quoted);
344 strcpy (uids, tmpuids); /* __STRCPY_CHECKED__ */
347 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
348 0, NULL, NULL, NULL, uids,
349 keyring == PGP_SECRING ? PgpListSecringCommand :
350 PgpListPubringCommand);