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>
17 #include <lib-mime/mime.h>
18 #include <lib-ui/curses.h>
20 #include "mutt_idna.h"
25 * The actual command line formatter.
28 struct pgp_command_context {
29 short need_passphrase; /* %p */
30 const char *fname; /* %f */
31 const char *sig_fname; /* %s */
32 const char *signas; /* %a */
33 const char *ids; /* %r */
38 _mutt_fmt_pgp_command(char *dest, ssize_t destlen,
39 char op, const char *src, const char *prefix,
40 const char *ifstring, const char *elsestring,
41 unsigned long data, format_flag flags)
44 struct pgp_command_context *cctx = (struct pgp_command_context *) data;
45 int optional = (flags & M_FORMAT_OPTIONAL);
51 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
52 snprintf (dest, destlen, fmt, NONULL (cctx->ids));
62 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
63 snprintf (dest, destlen, fmt, NONULL (cctx->signas));
65 else if (!cctx->signas)
73 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
74 snprintf (dest, destlen, fmt, NONULL (cctx->sig_fname));
76 else if (!cctx->sig_fname)
84 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
85 snprintf (dest, destlen, fmt, NONULL (cctx->fname));
87 else if (!cctx->fname)
95 snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
96 snprintf (dest, destlen, fmt,
97 cctx->need_passphrase ? "PGPPASSFD=0" : "");
99 else if (!cctx->need_passphrase || pgp_use_gpg_agent ())
111 m_strformat(dest, destlen, ifstring, _mutt_fmt_pgp_command, data, 0);
112 else if (flags & M_FORMAT_OPTIONAL)
113 m_strformat(dest, destlen, elsestring, _mutt_fmt_pgp_command, data, 0);
119 mutt_pgp_command(char *d, ssize_t dlen, struct pgp_command_context *cctx,
122 m_strformat (d, dlen, NONULL (fmt), _mutt_fmt_pgp_command,
123 (unsigned long) cctx, 0);
131 static pid_t pgp_invoke (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
132 int pgpinfd, int pgpoutfd, int pgperrfd,
133 short need_passphrase,
135 const char *sig_fname,
137 const char *ids, const char *format)
139 struct pgp_command_context cctx;
140 char cmd[HUGE_STRING];
144 if (!format || !*format)
147 cctx.need_passphrase = need_passphrase;
149 cctx.sig_fname = sig_fname;
150 cctx.signas = signas;
153 mutt_pgp_command (cmd, sizeof (cmd), &cctx, format);
155 return mutt_create_filter_fd (cmd, pgpin, pgpout, pgperr,
156 pgpinfd, pgpoutfd, pgperrfd);
161 * The exported interface.
163 * This is historic and may be removed at some point.
168 pid_t pgp_invoke_decode (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
169 int pgpinfd, int pgpoutfd, int pgperrfd,
170 const char *fname, short need_passphrase)
172 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
173 need_passphrase, fname, NULL, NULL, NULL,
177 pid_t pgp_invoke_verify (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
178 int pgpinfd, int pgpoutfd, int pgperrfd,
179 const char *fname, const char *sig_fname)
181 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
182 0, fname, sig_fname, NULL, NULL, PgpVerifyCommand);
185 pid_t pgp_invoke_decrypt (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
186 int pgpinfd, int pgpoutfd, int pgperrfd,
189 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
190 1, fname, NULL, NULL, NULL, PgpDecryptCommand);
193 pid_t pgp_invoke_sign (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
194 int pgpinfd, int pgpoutfd, int pgperrfd,
197 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
198 1, fname, NULL, PgpSignAs, NULL, PgpSignCommand);
202 pid_t pgp_invoke_encrypt (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
203 int pgpinfd, int pgpoutfd, int pgperrfd,
204 const char *fname, const char *uids, int sign)
207 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
208 1, fname, NULL, PgpSignAs, uids,
209 PgpEncryptSignCommand);
211 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
212 0, fname, NULL, NULL, uids, PgpEncryptOnlyCommand);
215 pid_t pgp_invoke_traditional (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
216 int pgpinfd, int pgpoutfd, int pgperrfd,
217 const char *fname, const char *uids, int flags)
220 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
221 flags & SIGN ? 1 : 0, fname, NULL, PgpSignAs, uids,
222 flags & SIGN ? PgpEncryptSignCommand :
223 PgpEncryptOnlyCommand);
225 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
226 1, fname, NULL, PgpSignAs, NULL, PgpClearSignCommand);
230 void pgp_invoke_import (const char *fname)
232 char _fname[_POSIX_PATH_MAX + STRING];
233 char cmd[HUGE_STRING];
234 struct pgp_command_context cctx;
238 mutt_quote_filename (_fname, sizeof (_fname), fname);
241 mutt_pgp_command (cmd, sizeof (cmd), &cctx, PgpImportCommand);
245 void pgp_invoke_getkeys (address_t * addr)
247 char buff[LONG_STRING];
248 char tmp[LONG_STRING];
249 char cmd[HUGE_STRING];
254 struct pgp_command_context cctx;
256 if (!PgpGetkeysCommand)
261 personal = addr->personal;
262 addr->personal = NULL;
264 mutt_addrlist_to_local(addr);
265 rfc822_addrcpy(tmp, sizeof(tmp), addr, 0);
266 mutt_quote_filename(buff, sizeof(buff), tmp);
268 addr->personal = personal;
272 mutt_pgp_command (cmd, sizeof (cmd), &cctx, PgpGetkeysCommand);
274 devnull = open ("/dev/null", O_RDWR);
277 mutt_message _("Fetching PGP key...");
287 pid_t pgp_invoke_export (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
288 int pgpinfd, int pgpoutfd, int pgperrfd,
291 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
292 0, NULL, NULL, NULL, uids, PgpExportCommand);
295 pid_t pgp_invoke_verify_key (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
296 int pgpinfd, int pgpoutfd, int pgperrfd,
299 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
300 0, NULL, NULL, NULL, uids, PgpVerifyKeyCommand);
303 pid_t pgp_invoke_list_keys (FILE ** pgpin, FILE ** pgpout, FILE ** pgperr,
304 int pgpinfd, int pgpoutfd, int pgperrfd,
305 pgp_ring_t keyring, string_list_t * hints)
307 char uids[HUGE_STRING];
308 char tmpuids[HUGE_STRING];
309 char quoted[HUGE_STRING];
313 for (; hints; hints = hints->next) {
314 mutt_quote_filename (quoted, sizeof (quoted), (char *) hints->data);
315 snprintf (tmpuids, sizeof (tmpuids), "%s %s", uids, quoted);
316 m_strcpy(uids, sizeof(uids), tmpuids);
319 return pgp_invoke (pgpin, pgpout, pgperr, pgpinfd, pgpoutfd, pgperrfd,
320 0, NULL, NULL, NULL, uids,
321 keyring == PGP_SECRING ? PgpListSecringCommand :
322 PgpListPubringCommand);