X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=lib-crypt%2Fcrypt-gpgme.c;h=7b6787ecd6a765fccbbcc635850ec9b3cd5fe4c9;hp=4737fed3ab7fe7ad5304bfdb48b33de325e84946;hb=64a23f5574b096605383ef1886c7d0d6c42aeeee;hpb=81efbf8081bad2eed7ad07209b301ca35fe183e8 diff --git a/lib-crypt/crypt-gpgme.c b/lib-crypt/crypt-gpgme.c index 4737fed..7b6787e 100644 --- a/lib-crypt/crypt-gpgme.c +++ b/lib-crypt/crypt-gpgme.c @@ -14,8 +14,6 @@ #include -#ifdef CRYPT_BACKEND_GPGME - #ifdef HAVE_LOCALE_H # include #endif @@ -96,6 +94,28 @@ typedef struct crypt_entry { static struct crypt_cache *id_defaults = NULL; static gpgme_key_t signature_key = NULL; +/* Initialization. */ +void crypt_init(void) +{ + /* Make sure that gpg-agent is running. */ + if (!getenv ("GPG_AGENT_INFO")) { + mutt_error ("\nUsing GPGME backend, although no gpg-agent is running"); + if (mutt_any_key_to_continue (NULL) == -1) + mutt_exit (1); + } +} + +/* Show a message that a backend will be invoked. */ +void crypt_invoke_message (int type) +{ + if (type & APPLICATION_PGP) { + mutt_message _("Invoking PGP..."); + } + else if (type & APPLICATION_SMIME) { + mutt_message _("Invoking S/MIME..."); + } +} + /* * General helper functions. */ @@ -116,7 +136,7 @@ static void print_utf8 (FILE * fp, const char *buf, ssize_t len) char *tstr; tstr = p_dupstr(buf, len); - mutt_convert_string (&tstr, "utf-8", Charset, M_ICONV_HOOK_FROM); + mutt_convert_string (&tstr, "utf-8", MCharset.charset, M_ICONV_HOOK_FROM); fputs (tstr, fp); p_delete(&tstr); } @@ -348,7 +368,7 @@ static gpgme_data_t body_to_data_object (BODY * a, int convert) int err = 0; gpgme_data_t data; - fptmp = m_tempfile(tempfile, sizeof(tempfile), NONULL(Tempdir), NULL); + fptmp = m_tempfile(tempfile, sizeof(tempfile), NONULL(MCore.tmpdir), NULL); if (!fptmp) { mutt_perror (_("Can't create temporary file")); return NULL; @@ -454,7 +474,7 @@ static char *data_object_to_tempfile (gpgme_data_t data, FILE ** ret_fp) FILE *fp; ssize_t nread = 0; - fp = m_tempfile(tempfile, sizeof(tempfile), NONULL(Tempdir), NULL); + fp = m_tempfile(tempfile, sizeof(tempfile), NONULL(MCore.tmpdir), NULL); if (!fp) { mutt_perror (_("Can't create temporary file")); return NULL; @@ -685,9 +705,7 @@ static void print_time (time_t t, STATE * s) state_attach_puts (p, s); } -/* - * Implementation of `sign_message'. - */ +/* Implementation of `sign_message'. */ /* Sign the MESSAGE in body A either using OpenPGP or S/MIME when USE_SMIME is passed as true. Returns the new body or NULL on @@ -781,12 +799,12 @@ static BODY *sign_message (BODY * a, int use_smime) } -BODY *pgp_gpgme_sign_message (BODY * a) +BODY *crypt_pgp_sign_message (BODY * a) { return sign_message (a, 0); } -BODY *smime_gpgme_sign_message (BODY * a) +BODY *crypt_smime_sign_message (BODY * a) { return sign_message (a, 1); } @@ -797,7 +815,7 @@ BODY *smime_gpgme_sign_message (BODY * a) /* Encrypt the mail body A to all keys given as space separated keyids or fingerprints in KEYLIST and return the encrypted body. */ -BODY *pgp_gpgme_encrypt_message (BODY * a, char *keylist, int sign) +BODY *crypt_pgp_encrypt_message (BODY * a, char *keylist, int sign) { char *outfile = NULL; BODY *t; @@ -898,9 +916,7 @@ BODY *smime_gpgme_build_smime_entity (BODY * a, char *keylist) } -/* - * Implementation of `verify_one'. - */ +/* Implementation of `verify_one'. */ /* Display the common attributes of the signature summary SUM. Return 1 if there is is a severe warning. @@ -1002,6 +1018,7 @@ static void show_fingerprint (gpgme_key_t key, STATE * state) int i, is_pgp; char *buf, *p; const char *prefix = _("Fingerprint: "); + ssize_t bufsize; if (!key) return; @@ -1010,8 +1027,9 @@ static void show_fingerprint (gpgme_key_t key, STATE * state) return; is_pgp = (key->protocol == GPGME_PROTOCOL_OpenPGP); - buf = xmalloc(m_strlen(prefix) + m_strlen(s) * 4 + 2); - strcpy (buf, prefix); /* __STRCPY_CHECKED__ */ + bufsize = m_strlen(prefix) + m_strlen(s) * 4 + 2; + buf = p_new(char, bufsize); + m_strcpy(buf, bufsize, prefix); p = buf + m_strlen(buf); if (is_pgp && m_strlen(s) == 40) { /* PGP v4 style formatted. */ for (i = 0; *s && s[1] && s[2] && s[3] && s[4]; s += 4, i++) { @@ -1295,12 +1313,12 @@ static int verify_one (BODY * sigbdy, STATE * s, return badsig ? 1 : anywarn ? 2 : 0; } -int pgp_gpgme_verify_one (BODY * sigbdy, STATE * s, const char *tempfile) +int crypt_pgp_verify_one (BODY * sigbdy, STATE * s, const char *tempfile) { return verify_one (sigbdy, s, tempfile, 0); } -int smime_gpgme_verify_one (BODY * sigbdy, STATE * s, const char *tempfile) +int crypt_smime_verify_one (BODY * sigbdy, STATE * s, const char *tempfile) { return verify_one (sigbdy, s, tempfile, 1); } @@ -1445,7 +1463,7 @@ restart: /* Decrypt a PGP/MIME message in FPIN and B and return a new body and the stream in CUR and FPOUT. Returns 0 on success. */ -int pgp_gpgme_decrypt_mime (FILE * fpin, FILE ** fpout, BODY * b, BODY ** cur) +int crypt_pgp_decrypt_mime (FILE * fpin, FILE ** fpout, BODY * b, BODY ** cur) { char tempfile[_POSIX_PATH_MAX]; STATE s; @@ -1465,7 +1483,7 @@ int pgp_gpgme_decrypt_mime (FILE * fpin, FILE ** fpout, BODY * b, BODY ** cur) p_clear(&s, 1); s.fpin = fpin; - *fpout = m_tempfile(tempfile, sizeof(tempfile), NONULL(Tempdir), NULL); + *fpout = m_tempfile(tempfile, sizeof(tempfile), NONULL(MCore.tmpdir), NULL); if (!*fpout) { mutt_perror (_("Can't create temporary file")); return -1; @@ -1483,7 +1501,7 @@ int pgp_gpgme_decrypt_mime (FILE * fpin, FILE ** fpout, BODY * b, BODY ** cur) /* Decrypt a S/MIME message in FPIN and B and return a new body and the stream in CUR and FPOUT. Returns 0 on success. */ -int smime_gpgme_decrypt_mime (FILE * fpin, FILE ** fpout, BODY * b, +int crypt_smime_decrypt_mime (FILE * fpin, FILE ** fpout, BODY * b, BODY ** cur) { char tempfile[_POSIX_PATH_MAX]; @@ -1510,7 +1528,7 @@ int smime_gpgme_decrypt_mime (FILE * fpin, FILE ** fpout, BODY * b, p_clear(&s, 1); s.fpin = fpin; fseeko (s.fpin, b->offset, 0); - tmpfp = m_tempfile (tempfile, sizeof(tempfile), NONULL(Tempdir), NULL); + tmpfp = m_tempfile (tempfile, sizeof(tempfile), NONULL(MCore.tmpdir), NULL); if (!tmpfp) { mutt_perror (_("Can't create temporary file")); return -1; @@ -1527,7 +1545,7 @@ int smime_gpgme_decrypt_mime (FILE * fpin, FILE ** fpout, BODY * b, p_clear(&s, 1); s.fpin = tmpfp; s.fpout = 0; - *fpout = m_tempfile(tempfile, sizeof(tempfile), NONULL(Tempdir), NULL); + *fpout = m_tempfile(tempfile, sizeof(tempfile), NONULL(MCore.tmpdir), NULL); if (!*fpout) { mutt_perror (_("Can't create temporary file")); return -1; @@ -1562,7 +1580,7 @@ int smime_gpgme_decrypt_mime (FILE * fpin, FILE ** fpout, BODY * b, p_clear(&s, 1); s.fpin = *fpout; fseeko (s.fpin, bb->offset, 0); - tmpfp = m_tempfile (tempfile, sizeof(tempfile), NONULL(Tempdir), NULL); + tmpfp = m_tempfile (tempfile, sizeof(tempfile), NONULL(MCore.tmpdir), NULL); if (!tmpfp) { mutt_perror (_("Can't create temporary file")); return -1; @@ -1580,7 +1598,7 @@ int smime_gpgme_decrypt_mime (FILE * fpin, FILE ** fpout, BODY * b, p_clear(&s, 1); s.fpin = tmpfp; s.fpout = 0; - *fpout = m_tempfile(tempfile, sizeof(tempfile), NONULL(Tempdir), NULL); + *fpout = m_tempfile(tempfile, sizeof(tempfile), NONULL(MCore.tmpdir), NULL); if (!*fpout) { mutt_perror (_("Can't create temporary file")); return -1; @@ -1612,6 +1630,7 @@ static int pgp_check_traditional_one_body (FILE * fp, BODY * b, char tempfile[_POSIX_PATH_MAX]; char buf[HUGE_STRING]; FILE *tfp; + int tempfd; short sgn = 0; short enc = 0; @@ -1622,13 +1641,13 @@ static int pgp_check_traditional_one_body (FILE * fp, BODY * b, if (tagged_only && !b->tagged) return 0; - mutt_mktemp (tempfile); - if (mutt_decode_save_attachment (fp, b, tempfile, 0, 0) != 0) { + tempfd = m_tempfd(tempfile, sizeof(tempfile), NONULL(MCore.tmpdir), NULL); + if (mutt_decode_save_attachment (fp, b, tempfd, 0) != 0) { unlink (tempfile); return 0; } - if ((tfp = fopen (tempfile, "r")) == NULL) { + if ((tfp = fopen(tempfile, "r")) == NULL) { unlink (tempfile); return 0; } @@ -1655,14 +1674,14 @@ static int pgp_check_traditional_one_body (FILE * fp, BODY * b, return 1; } -int pgp_gpgme_check_traditional (FILE * fp, BODY * b, int tagged_only) +int crypt_pgp_check_traditional (FILE * fp, BODY * b, int tagged_only) { int rv = 0; int r; for (; b; b = b->next) { if (is_multipart (b)) - rv = (pgp_gpgme_check_traditional (fp, b->parts, tagged_only) || rv); + rv = (crypt_pgp_check_traditional (fp, b->parts, tagged_only) || rv); else if (b->type == TYPETEXT) { if ((r = mutt_is_application_pgp (b))) rv = (rv || r); @@ -1674,9 +1693,7 @@ int pgp_gpgme_check_traditional (FILE * fp, BODY * b, int tagged_only) } -/* - * Implementation of `application_handler'. - */ +/* Implementation of `application_handler'. */ /* Copy a clearsigned message, and strip the signature and PGP's @@ -1704,7 +1721,7 @@ static void copy_clearsigned (gpgme_data_t data, STATE * s, char *charset) unlink (fname); p_delete(&fname); - fc = fgetconv_open (fp, charset, Charset, M_ICONV_HOOK_FROM); + fc = fgetconv_open (fp, charset, MCharset.charset, M_ICONV_HOOK_FROM); for (complete = 1, armor_header = 1; fgetconvs (buf, sizeof (buf), fc) != NULL; @@ -1739,7 +1756,7 @@ static void copy_clearsigned (gpgme_data_t data, STATE * s, char *charset) /* Support for classic_application/pgp */ -int pgp_gpgme_application_handler (BODY * m, STATE * s) +int crypt_pgp_application_pgp_handler (BODY * m, STATE * s) { int needpass = -1, pgp_keyblock = 0; int clearsign = 0; @@ -1922,7 +1939,7 @@ int pgp_gpgme_application_handler (BODY * m, STATE * s) int c; rewind (pgpout); - fc = fgetconv_open (pgpout, "utf-8", Charset, 0); + fc = fgetconv_open (pgpout, "utf-8", MCharset.charset, 0); while ((c = fgetconv (fc)) != EOF) { state_putc (c, s); if (c == '\n' && s->prefix) @@ -1991,7 +2008,7 @@ int pgp_gpgme_encrypted_handler (BODY * a, STATE * s) /* Move forward to the application/pgp-encrypted body. */ a = a->next; - fpout = m_tempfile(tempfile, sizeof(tempfile), NONULL(Tempdir), NULL); + fpout = m_tempfile(tempfile, sizeof(tempfile), NONULL(MCore.tmpdir), NULL); if (!fpout) { if (s->flags & M_DISPLAY) state_attach_puts (_("[-- Error: could not create temporary file! " @@ -2042,7 +2059,7 @@ int pgp_gpgme_encrypted_handler (BODY * a, STATE * s) } /* Support for application/smime */ -int smime_gpgme_application_handler (BODY * a, STATE * s) +int crypt_smime_application_smime_handler (BODY * a, STATE * s) { char tempfile[_POSIX_PATH_MAX]; FILE *fpout; @@ -2051,7 +2068,7 @@ int smime_gpgme_application_handler (BODY * a, STATE * s) int rc = 0; a->warnsig = 0; - fpout = m_tempfile(tempfile, sizeof(tempfile), NONULL(Tempdir), NULL); + fpout = m_tempfile(tempfile, sizeof(tempfile), NONULL(MCore.tmpdir), NULL); if (!fpout) { if (s->flags & M_DISPLAY) state_attach_puts (_("[-- Error: could not create temporary file! " @@ -2124,8 +2141,8 @@ int smime_gpgme_application_handler (BODY * a, STATE * s) static const char * crypt_entry_fmt (char *dest, ssize_t destlen, char op, const char *src, const char *prefix, - const char *ifstring, const char *elsestring, - unsigned long data, format_flag flags) + const char *ifstr, const char *elstr, + anytype data, format_flag flags) { char fmt[16]; crypt_entry_t *entry; @@ -2135,7 +2152,7 @@ crypt_entry_fmt (char *dest, ssize_t destlen, char op, const char *s = NULL; unsigned long val; - entry = (crypt_entry_t *) data; + entry = data.ptr; key = entry->key; /* if (isupper ((unsigned char) op)) */ @@ -2148,7 +2165,7 @@ crypt_entry_fmt (char *dest, ssize_t destlen, char op, case '[': { const char *cp; - char buf2[SHORT_STRING], *p; + char buf2[STRING], *p; int do_locales; struct tm *tm; ssize_t len; @@ -2306,11 +2323,10 @@ crypt_entry_fmt (char *dest, ssize_t destlen, char op, *dest = '\0'; } - if (optional) - mutt_FormatString (dest, destlen, ifstring, mutt_attach_fmt, data, 0); - else if (flags & M_FORMAT_OPTIONAL) - mutt_FormatString (dest, destlen, elsestring, mutt_attach_fmt, data, 0); - return (src); + if (flags & M_FORMAT_OPTIONAL) + m_strformat(dest, destlen, 0, optional ? ifstr: elstr, + mutt_attach_fmt, data, 0); + return src; } /* Used by the display fucntion to format a line. */ @@ -2322,8 +2338,8 @@ static void crypt_entry (char *s, ssize_t l, MUTTMENU * menu, int num) entry.key = key_table[num]; entry.num = num + 1; - mutt_FormatString (s, l, NONULL (PgpEntryFormat), crypt_entry_fmt, - (unsigned long) &entry, M_FORMAT_ARROWCURSOR); + m_strformat(s, l, COLS - SW, PgpEntryFormat, crypt_entry_fmt, &entry, + option(OPTARROWCURSOR) ? M_FORMAT_ARROWCURSOR : 0); } /* Compare two addresses and the keyid to be used for sorting. */ @@ -2515,7 +2531,7 @@ static const unsigned char *parse_dn_part (struct dn_array_s *array, if (!n || (n & 1)) return NULL; /* empty or odd number of digits */ n /= 2; - p = xmalloc(n + 1); + p = p_new(unsigned char, n + 1); array->value = (char *) p; for (s1 = string; n; s1 += 2, n--) *p++ = xtoi_2 (s1); @@ -2545,7 +2561,7 @@ static const unsigned char *parse_dn_part (struct dn_array_s *array, n++; } - p = xmalloc(n + 1); + p = p_new(unsigned char, n + 1); array->value = (char *) p; for (s = string; n; s++, n--) { if (*s == '\\') { @@ -2699,7 +2715,7 @@ static void print_key_info (gpgme_key_t key, FILE * fp) const char *s = NULL, *s2 = NULL; time_t tt = 0; struct tm *tm; - char shortbuf[SHORT_STRING]; + char shortbuf[STRING]; unsigned long aval = 0; const char *delim; int is_pgp = 0; @@ -2923,7 +2939,7 @@ static void verify_key (crypt_key_t * key) gpgme_key_t k = NULL; int maxdepth = 100; - fp = m_tempfile (tempfile, sizeof(tempfile), NONULL(Tempdir), NULL); + fp = m_tempfile (tempfile, sizeof(tempfile), NONULL(MCore.tmpdir), NULL); if (!fp) { mutt_perror (_("Can't create temporary file")); return; @@ -2973,10 +2989,7 @@ leave: mutt_do_pager (cmd, tempfile, 0, NULL); } -/* - * Implementation of `findkeys'. - */ - +/* Implementation of `findkeys'. */ /* Convert string_list_t into a pattern string suitable to be passed to GPGME. We need to convert spaces in an item into a '+' and '%' into @@ -3201,7 +3214,7 @@ static crypt_key_t *crypt_select_key (crypt_key_t * keys, crypt_key_t **key_table; MUTTMENU *menu; int i, done = 0; - char helpstr[SHORT_STRING], buf[LONG_STRING]; + char helpstr[STRING], buf[LONG_STRING]; crypt_key_t *k; int (*f) (const void *, const void *); int menu_to_use = 0; @@ -3257,15 +3270,15 @@ static crypt_key_t *crypt_select_key (crypt_key_t * keys, helpstr[0] = 0; mutt_make_help (buf, sizeof (buf), _("Exit "), menu_to_use, OP_EXIT); - strcat (helpstr, buf); /* __STRCAT_CHECKED__ */ + m_strcat(helpstr, sizeof(helpstr), buf); mutt_make_help (buf, sizeof (buf), _("Select "), menu_to_use, OP_GENERIC_SELECT_ENTRY); - strcat (helpstr, buf); /* __STRCAT_CHECKED__ */ + m_strcat(helpstr, sizeof(helpstr), buf); mutt_make_help (buf, sizeof (buf), _("Check key "), menu_to_use, OP_VERIFY_KEY); - strcat (helpstr, buf); /* __STRCAT_CHECKED__ */ + m_strcat(helpstr, sizeof(helpstr), buf); mutt_make_help (buf, sizeof (buf), _("Help"), menu_to_use, OP_HELP); - strcat (helpstr, buf); /* __STRCAT_CHECKED__ */ + m_strcat(helpstr, sizeof(helpstr), buf); menu = mutt_new_menu (); menu->max = i; @@ -3561,7 +3574,7 @@ static crypt_key_t *crypt_ask_for_key (char *tag, unsigned int app, int *forced_valid) { crypt_key_t *key; - char resp[SHORT_STRING]; + char resp[STRING]; struct crypt_cache *l = NULL; int dummy; @@ -3647,9 +3660,7 @@ static char *find_keys (address_t * to, address_t * cc, address_t * bcc, last = &((*last)->next); } - if (fqdn) - rfc822_qualify (tmp, fqdn); - + rfc822_qualify(tmp, fqdn); address_list_uniq(tmp); for (p = tmp; p; p = p->next) { @@ -3668,8 +3679,7 @@ static char *find_keys (address_t * to, address_t * cc, address_t * bcc, /* check for e-mail address */ if ((t = strchr (keyID, '@')) && (addr = rfc822_parse_adrlist (NULL, keyID))) { - if (fqdn) - rfc822_qualify (addr, fqdn); + rfc822_qualify(addr, fqdn); q = addr; } else { @@ -3707,7 +3717,7 @@ static char *find_keys (address_t * to, address_t * cc, address_t * bcc, keylist_size += m_strlen(s) + 4 + 1; p_realloc(&keylist, keylist_size); - sprintf (keylist + keylist_used, "%s0x%s%s", /* __SPRINTF_CHECKED__ */ + sprintf (keylist + keylist_used, "%s0x%s%s", keylist_used ? " " : "", s, forced_valid ? "!" : ""); } keylist_used = m_strlen(keylist); @@ -3719,44 +3729,20 @@ static char *find_keys (address_t * to, address_t * cc, address_t * bcc, return (keylist); } -char *pgp_gpgme_findkeys (address_t * to, address_t * cc, address_t * bcc) +char *crypt_pgp_findkeys (address_t * to, address_t * cc, address_t * bcc) { return find_keys (to, cc, bcc, APPLICATION_PGP); } -char *smime_gpgme_findkeys (address_t * to, address_t * cc, address_t * bcc) +char *crypt_smime_findkeys (address_t * to, address_t * cc, address_t * bcc) { return find_keys (to, cc, bcc, APPLICATION_SMIME); } -/* - * Implementation of `init'. - */ - -/* Initialization. */ -static void init_gpgme (void) -{ - /* Make sure that gpg-agent is running. */ - if (!getenv ("GPG_AGENT_INFO")) { - mutt_error ("\nUsing GPGME backend, although no gpg-agent is running"); - if (mutt_any_key_to_continue (NULL) == -1) - mutt_exit (1); - } -} - -void pgp_gpgme_init (void) -{ - init_gpgme (); -} - -void smime_gpgme_init (void) -{ -} - static int gpgme_send_menu (HEADER * msg, int *redraw, int is_smime) { crypt_key_t *p; - char input_signas[SHORT_STRING]; + char input_signas[STRING]; int choice; if (msg->security & APPLICATION_PGP) @@ -3828,17 +3814,17 @@ static int gpgme_send_menu (HEADER * msg, int *redraw, int is_smime) return (msg->security); } -int pgp_gpgme_send_menu (HEADER * msg, int *redraw) +int crypt_pgp_send_menu(HEADER * msg, int *redraw) { - return gpgme_send_menu (msg, redraw, 0); + return gpgme_send_menu(msg, redraw, 0); } -int smime_gpgme_send_menu (HEADER * msg, int *redraw) +int crypt_smime_send_menu(HEADER * msg, int *redraw) { return gpgme_send_menu (msg, redraw, 1); } -static int verify_sender (HEADER * h, gpgme_protocol_t protocol __attribute__((unused))) +int crypt_smime_verify_sender (HEADER * h) { address_t *sender = NULL; unsigned int ret = 1; @@ -3883,9 +3869,79 @@ static int verify_sender (HEADER * h, gpgme_protocol_t protocol __attribute__((u return ret; } -int smime_gpgme_verify_sender (HEADER * h) +static void invoke_import(const char *fname, int smime) { - return verify_sender (h, GPGME_PROTOCOL_CMS); + gpgme_ctx_t ctx = create_gpgme_context(smime); + gpgme_data_t data; + gpgme_error_t err; + + err = gpgme_data_new_from_file(&data, fname, 1); + if (err) { + mutt_error (_("error allocating data object: %s\n"), gpgme_strerror (err)); + gpgme_release(ctx); + return; + } + + err = gpgme_op_import(ctx, data); + if (err) { + mutt_error(_("error importing gpg data: %s\n"), gpgme_strerror(err)); + gpgme_data_release(data); + gpgme_release(ctx); + return; + } + + gpgme_data_release(data); + gpgme_release(ctx); + return; +} + +void crypt_pgp_invoke_import(const char *fname) +{ + invoke_import(fname, 0); +} + +void crypt_smime_invoke_import(const char *fname) +{ + invoke_import(fname, 1); +} + +static void pgp_extract_keys_from_attachment (FILE * fp, BODY * top) +{ + STATE s; + FILE *tempfp; + char tempfname[_POSIX_PATH_MAX]; + + tempfp = m_tempfile(tempfname, sizeof(tempfname), NONULL(MCore.tmpdir), NULL); + if (tempfp == NULL) { + mutt_perror (_("Can't create temporary file")); + return; + } + + p_clear(&s, 1); + + s.fpin = fp; + s.fpout = tempfp; + + mutt_body_handler (top, &s); + + m_fclose(&tempfp); + crypt_pgp_invoke_import(tempfname); + mutt_unlink (tempfname); +} + +void crypt_pgp_extract_keys_from_attachment_list(FILE * fp, int tag, BODY * top) +{ + mutt_endwin (NULL); + set_option (OPTDONTHANDLEPGPKEYS); + + for (; top; top = top->next) { + if (!tag || top->tagged) + pgp_extract_keys_from_attachment (fp, top); + + if (!tag) + break; + } + + unset_option (OPTDONTHANDLEPGPKEYS); } -#endif