X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=lib-crypt%2Fcrypt-gpgme.c;h=c6142af4c3c1970b00ebb444765ae8ec17dd2ae1;hp=3afaea001d0345eef3a8938dcfe5ed6a8e5584f4;hb=0e61856236c91a428ad77f6e2a61b744cf4973e1;hpb=69f4685e616347559d4ec714fd826d7f97a472ef diff --git a/lib-crypt/crypt-gpgme.c b/lib-crypt/crypt-gpgme.c index 3afaea0..c6142af 100644 --- a/lib-crypt/crypt-gpgme.c +++ b/lib-crypt/crypt-gpgme.c @@ -12,19 +12,7 @@ * please see the file GPL in the top level source directory. */ -#if HAVE_CONFIG_H -# include "config.h" -#endif - -#ifdef CRYPT_BACKEND_GPGME - -#include -#include -#include -#include -#include -#include -#include +#include #ifdef HAVE_LOCALE_H # include @@ -32,48 +20,27 @@ #ifdef HAVE_LANGINFO_D_T_FMT # include #endif -#ifdef HAVE_SYS_TIME_H -# include -#endif #ifdef HAVE_SYS_RESOURCE_H # include #endif #include -#include -#include -#include -#include -#include - #include - #include #include #include -#include "mutt.h" +#include "crypt.h" + #include "lib.h" #include "alias.h" -#include #include "handler.h" #include "copy.h" #include "pager.h" #include "recvattach.h" #include "sort.h" -/* - * Helper macros. - */ -#define digitp(p) (*(p) >= '0' && *(p) <= '9') -#define hexdigitp(a) (digitp (a) \ - || (*(a) >= 'A' && *(a) <= 'F') \ - || (*(a) >= 'a' && *(a) <= 'f')) -#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ - *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) -#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) - /* Values used for comparing addresses. */ #define CRYPT_KV_VALID 1 #define CRYPT_KV_ADDR 2 @@ -115,6 +82,17 @@ typedef struct crypt_entry { static struct crypt_cache *id_defaults = NULL; static gpgme_key_t signature_key = NULL; +/* 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. */ @@ -135,7 +113,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); } @@ -367,10 +345,9 @@ static gpgme_data_t body_to_data_object (BODY * a, int convert) int err = 0; gpgme_data_t data; - mutt_mktemp (tempfile); - fptmp = safe_fopen (tempfile, "w+"); + fptmp = m_tempfile(tempfile, sizeof(tempfile), NONULL(MCore.tmpdir), NULL); if (!fptmp) { - mutt_perror (tempfile); + mutt_perror (_("Can't create temporary file")); return NULL; } @@ -399,13 +376,11 @@ static gpgme_data_t body_to_data_object (BODY * a, int convert) buf[0] = c; gpgme_data_write (data, buf, 1); } - fclose (fptmp); gpgme_data_seek (data, 0, SEEK_SET); - } - else { - fclose (fptmp); + } else { err = gpgme_data_new_from_file (&data, tempfile, 1); } + m_fclose(&fptmp); unlink (tempfile); if (err) { mutt_error (_("error allocating data object: %s\n"), gpgme_strerror (err)); @@ -476,10 +451,9 @@ static char *data_object_to_tempfile (gpgme_data_t data, FILE ** ret_fp) FILE *fp; ssize_t nread = 0; - mutt_mktemp (tempfile); - fp = safe_fopen (tempfile, "w+"); + fp = m_tempfile(tempfile, sizeof(tempfile), NONULL(MCore.tmpdir), NULL); if (!fp) { - mutt_perror (tempfile); + mutt_perror (_("Can't create temporary file")); return NULL; } @@ -490,8 +464,8 @@ static char *data_object_to_tempfile (gpgme_data_t data, FILE ** ret_fp) while ((nread = gpgme_data_read (data, buf, sizeof (buf)))) { if (fwrite (buf, nread, 1, fp) != 1) { - mutt_perror (tempfile); - fclose (fp); + mutt_perror (_("Can't create temporary file")); + m_fclose(&fp); unlink (tempfile); return NULL; } @@ -500,11 +474,11 @@ static char *data_object_to_tempfile (gpgme_data_t data, FILE ** ret_fp) if (ret_fp) rewind (fp); else - fclose (fp); + m_fclose(&fp); if (nread == -1) { mutt_error (_("error reading data object: %s\n"), gpgme_strerror (err)); unlink (tempfile); - fclose (fp); + m_fclose(&fp); return NULL; } if (ret_fp) @@ -708,9 +682,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 @@ -758,7 +730,7 @@ static BODY *sign_message (BODY * a, int use_smime) return NULL; } - t = mutt_new_body (); + t = body_new(); t->type = TYPEMULTIPART; t->subtype = m_strdup("signed"); t->encoding = ENC7BIT; @@ -780,7 +752,7 @@ static BODY *sign_message (BODY * a, int use_smime) t->parts = a; a = t; - t->parts->next = mutt_new_body (); + t->parts->next = body_new(); t = t->parts->next; t->type = TYPEAPPLICATION; if (use_smime) { @@ -804,12 +776,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); } @@ -820,7 +792,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; @@ -845,7 +817,7 @@ BODY *pgp_gpgme_encrypt_message (BODY * a, char *keylist, int sign) if (!outfile) return NULL; - t = mutt_new_body (); + t = body_new(); t->type = TYPEMULTIPART; t->subtype = m_strdup("encrypted"); t->encoding = ENC7BIT; @@ -855,12 +827,12 @@ BODY *pgp_gpgme_encrypt_message (BODY * a, char *keylist, int sign) parameter_set_boundary(&t->parameter); parameter_setval(&t->parameter, "protocol", "application/pgp-encrypted"); - t->parts = mutt_new_body (); + t->parts = body_new(); t->parts->type = TYPEAPPLICATION; t->parts->subtype = m_strdup("pgp-encrypted"); t->parts->encoding = ENC7BIT; - t->parts->next = mutt_new_body (); + t->parts->next = body_new(); t->parts->next->type = TYPEAPPLICATION; t->parts->next->subtype = m_strdup("octet-stream"); t->parts->next->encoding = ENC7BIT; @@ -880,7 +852,7 @@ BODY *pgp_gpgme_encrypt_message (BODY * a, char *keylist, int sign) /* Encrypt the mail body A to all keys given as space separated fingerprints in KEYLIST and return the S/MIME encrypted body. */ -BODY *smime_gpgme_build_smime_entity (BODY * a, char *keylist) +BODY *crypt_smime_build_smime_entity (BODY * a, char *keylist) { char *outfile = NULL; BODY *t; @@ -903,7 +875,7 @@ BODY *smime_gpgme_build_smime_entity (BODY * a, char *keylist) if (!outfile) return NULL; - t = mutt_new_body (); + t = body_new(); t->type = TYPEAPPLICATION; t->subtype = m_strdup("pkcs7-mime"); parameter_setval(&t->parameter, "name", "smime.p7m"); @@ -921,9 +893,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. @@ -1025,6 +995,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; @@ -1033,8 +1004,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++) { @@ -1104,7 +1076,7 @@ static void show_one_sig_validity (gpgme_ctx_t ctx, int idx, STATE * s) /* Show information about one signature. This fucntion is called with the context CTX of a sucessful verification operation and the enumerator IDX which should start at 0 and incremete for each - call/signature. + call/signature. Return values are: 0 for normal procession, 1 for a bad signature, 2 for a signature with a warning or -1 for no more signature. */ @@ -1318,12 +1290,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); } @@ -1468,7 +1440,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; @@ -1488,9 +1460,9 @@ int pgp_gpgme_decrypt_mime (FILE * fpin, FILE ** fpout, BODY * b, BODY ** cur) p_clear(&s, 1); s.fpin = fpin; - mutt_mktemp (tempfile); - if (!(*fpout = safe_fopen (tempfile, "w+"))) { - mutt_perror (tempfile); + *fpout = m_tempfile(tempfile, sizeof(tempfile), NONULL(MCore.tmpdir), NULL); + if (!*fpout) { + mutt_perror (_("Can't create temporary file")); return -1; } unlink (tempfile); @@ -1506,7 +1478,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]; @@ -1533,9 +1505,9 @@ int smime_gpgme_decrypt_mime (FILE * fpin, FILE ** fpout, BODY * b, p_clear(&s, 1); s.fpin = fpin; fseeko (s.fpin, b->offset, 0); - mutt_mktemp (tempfile); - if (!(tmpfp = safe_fopen (tempfile, "w+"))) { - mutt_perror (tempfile); + tmpfp = m_tempfile (tempfile, sizeof(tempfile), NONULL(MCore.tmpdir), NULL); + if (!tmpfp) { + mutt_perror (_("Can't create temporary file")); return -1; } mutt_unlink (tempfile); @@ -1550,9 +1522,9 @@ int smime_gpgme_decrypt_mime (FILE * fpin, FILE ** fpout, BODY * b, p_clear(&s, 1); s.fpin = tmpfp; s.fpout = 0; - mutt_mktemp (tempfile); - if (!(*fpout = safe_fopen (tempfile, "w+"))) { - mutt_perror (tempfile); + *fpout = m_tempfile(tempfile, sizeof(tempfile), NONULL(MCore.tmpdir), NULL); + if (!*fpout) { + mutt_perror (_("Can't create temporary file")); return -1; } mutt_unlink (tempfile); @@ -1563,7 +1535,7 @@ int smime_gpgme_decrypt_mime (FILE * fpin, FILE ** fpout, BODY * b, b->type = saved_b_type; b->length = saved_b_length; b->offset = saved_b_offset; - fclose (tmpfp); + m_fclose(&tmpfp); rewind (*fpout); if (*cur && !is_signed && !(*cur)->parts && mutt_is_application_smime (*cur)) { @@ -1585,9 +1557,9 @@ int smime_gpgme_decrypt_mime (FILE * fpin, FILE ** fpout, BODY * b, p_clear(&s, 1); s.fpin = *fpout; fseeko (s.fpin, bb->offset, 0); - mutt_mktemp (tempfile); - if (!(tmpfp = safe_fopen (tempfile, "w+"))) { - mutt_perror (tempfile); + tmpfp = m_tempfile (tempfile, sizeof(tempfile), NONULL(MCore.tmpdir), NULL); + if (!tmpfp) { + mutt_perror (_("Can't create temporary file")); return -1; } mutt_unlink (tempfile); @@ -1598,14 +1570,14 @@ int smime_gpgme_decrypt_mime (FILE * fpin, FILE ** fpout, BODY * b, bb->length = ftello (s.fpout); bb->offset = 0; rewind (tmpfp); - fclose (*fpout); + m_fclose(&*fpout); p_clear(&s, 1); s.fpin = tmpfp; s.fpout = 0; - mutt_mktemp (tempfile); - if (!(*fpout = safe_fopen (tempfile, "w+"))) { - mutt_perror (tempfile); + *fpout = m_tempfile(tempfile, sizeof(tempfile), NONULL(MCore.tmpdir), NULL); + if (!*fpout) { + mutt_perror (_("Can't create temporary file")); return -1; } mutt_unlink (tempfile); @@ -1616,16 +1588,16 @@ int smime_gpgme_decrypt_mime (FILE * fpin, FILE ** fpout, BODY * b, bb->type = saved_b_type; bb->length = saved_b_length; bb->offset = saved_b_offset; - fclose (tmpfp); + m_fclose(&tmpfp); rewind (*fpout); - mutt_free_body (cur); + body_list_wipe(cur); *cur = tmp_b; } return *cur ? 0 : -1; } -/* +/* * Implementation of `pgp_check_traditional'. */ @@ -1635,6 +1607,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; @@ -1645,13 +1618,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; } @@ -1664,7 +1637,7 @@ static int pgp_check_traditional_one_body (FILE * fp, BODY * b, sgn = 1; } } - safe_fclose (&tfp); + m_fclose(&tfp); unlink (tempfile); if (!enc && !sgn) @@ -1678,14 +1651,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); @@ -1697,18 +1670,16 @@ 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 dash-escaping. - + XXX - charset handling: We assume that it is safe to do character set decoding first, dash decoding second here, while we do it the other way around in the main handler. - + (Note that we aren't worse than Outlook & Cie in this, and also note that we can successfully handle anything produced by any existing versions of mutt.) */ @@ -1727,7 +1698,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; @@ -1757,12 +1728,12 @@ static void copy_clearsigned (gpgme_data_t data, STATE * s, char *charset) } fgetconv_close (&fc); - fclose (fp); + m_fclose(&fp); } /* 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; @@ -1924,7 +1895,7 @@ int pgp_gpgme_application_handler (BODY * m, STATE * s) /* * Now, copy cleartext to the screen. NOTE - we expect that PGP - * outputs utf-8 cleartext. This may not always be true, but it + * outputs utf-8 cleartext. This may not always be true, but it * seems to be a reasonable guess. */ @@ -1945,7 +1916,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) @@ -1965,7 +1936,7 @@ int pgp_gpgme_application_handler (BODY * m, STATE * s) } if (pgpout) { - safe_fclose (&pgpout); + m_fclose(&pgpout); } } else { @@ -1986,12 +1957,10 @@ int pgp_gpgme_application_handler (BODY * m, STATE * s) return (err); } -/* - * Implementation of `encrypted_handler'. - */ +/* Implementation of `encrypted_handler'. */ /* MIME handler for pgp/mime encrypted messages. */ -int pgp_gpgme_encrypted_handler (BODY * a, STATE * s) +int crypt_pgp_encrypted_handler (BODY * a, STATE * s) { char tempfile[_POSIX_PATH_MAX]; FILE *fpout; @@ -2014,8 +1983,8 @@ int pgp_gpgme_encrypted_handler (BODY * a, STATE * s) /* Move forward to the application/pgp-encrypted body. */ a = a->next; - mutt_mktemp (tempfile); - if (!(fpout = safe_fopen (tempfile, "w+"))) { + 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! " "--]\n"), s); @@ -2040,7 +2009,7 @@ int pgp_gpgme_encrypted_handler (BODY * a, STATE * s) s->fpin = savefp; } - /* + /* * if a multipart/signed is the _only_ sub-part of a * multipart/encrypted, cache signature verification * status. @@ -2056,16 +2025,16 @@ int pgp_gpgme_encrypted_handler (BODY * a, STATE * s) : _("[-- End of PGP/MIME encrypted data --]\n"), s); } - mutt_free_body (&tattach); + body_list_wipe(&tattach); } - fclose (fpout); + m_fclose(&fpout); mutt_unlink (tempfile); return (rc); } /* 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; @@ -2074,8 +2043,8 @@ int smime_gpgme_application_handler (BODY * a, STATE * s) int rc = 0; a->warnsig = 0; - mutt_mktemp (tempfile); - if (!(fpout = safe_fopen (tempfile, "w+"))) { + 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! " "--]\n"), s); @@ -2099,7 +2068,7 @@ int smime_gpgme_application_handler (BODY * a, STATE * s) s->fpin = savefp; } - /* + /* * if a multipart/signed is the _only_ sub-part of a * multipart/encrypted, cache signature verification * status. @@ -2120,10 +2089,10 @@ int smime_gpgme_application_handler (BODY * a, STATE * s) _("[-- End of S/MIME encrypted data --]\n"), s); } - mutt_free_body (&tattach); + body_list_wipe(&tattach); } - fclose (fpout); + m_fclose(&fpout); mutt_unlink (tempfile); return (rc); } @@ -2131,7 +2100,7 @@ int smime_gpgme_application_handler (BODY * a, STATE * s) /* * Format an entry on the CRYPT key selection menu. - * + * * %n number * %k key id %K key id of the principal key * %u user id @@ -2147,8 +2116,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; @@ -2158,7 +2127,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)) */ @@ -2171,7 +2140,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; @@ -2329,11 +2298,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. */ @@ -2345,8 +2313,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. */ @@ -2532,16 +2500,16 @@ static const unsigned char *parse_dn_part (struct dn_array_s *array, if (*string == '#') { /* hexstring */ string++; - for (s = string; hexdigitp (s); s++) + for (s = string; hexval(*s) >= 0; s++) s++; n = s - string; 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); + *p++ = (hexval(*s1) << 8) | hexval(*s1); *p = 0; } else { /* regular v3 quoted string */ @@ -2552,7 +2520,7 @@ static const unsigned char *parse_dn_part (struct dn_array_s *array, || *s == '<' || *s == '>' || *s == '#' || *s == ';' || *s == '\\' || *s == '\"' || *s == ' ') n++; - else if (hexdigitp (s) && hexdigitp (s + 1)) { + else if (hexval(*s) >= 0 && hexval(*s + 1) >= 0) { s++; n++; } @@ -2568,13 +2536,13 @@ 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 == '\\') { s++; - if (hexdigitp (s)) { - *p++ = xtoi_2 (s); + if (hexval(*s) >= 0) { + *p++ = (hexval(*s) << 8) | hexval(*s + 1); s++; } else @@ -2722,7 +2690,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; @@ -2946,10 +2914,9 @@ static void verify_key (crypt_key_t * key) gpgme_key_t k = NULL; int maxdepth = 100; - mutt_mktemp (tempfile); - if (!(fp = safe_fopen (tempfile, "w"))) { + fp = m_tempfile (tempfile, sizeof(tempfile), NONULL(MCore.tmpdir), NULL); + if (!fp) { mutt_perror (_("Can't create temporary file")); - return; } mutt_message _("Collecting data..."); @@ -2991,16 +2958,13 @@ static void verify_key (crypt_key_t * key) leave: gpgme_key_release (k); gpgme_release (listctx); - fclose (fp); + m_fclose(&fp); mutt_clear_error (); snprintf (cmd, sizeof (cmd), _("Key ID: 0x%s"), crypt_keyid (key)); 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 @@ -3225,7 +3189,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; @@ -3281,15 +3245,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; @@ -3498,17 +3462,17 @@ static crypt_key_t *crypt_getkeybyaddr (address_t * a, short abilities, if (matches) { if (the_valid_key && !multi && !weak && !(invalid && option (OPTPGPSHOWUNUSABLE))) { - /* + /* * There was precisely one strong match on a valid ID, there * were no valid keys with weak matches, and we aren't * interested in seeing invalid keys. - * + * * Proceed without asking the user. */ k = crypt_copy_key (the_valid_key); } else { - /* + /* * Else: Ask the user. */ k = crypt_select_key (matches, a, NULL, app, forced_valid); @@ -3522,7 +3486,7 @@ static crypt_key_t *crypt_getkeybyaddr (address_t * a, short abilities, } -static crypt_key_t *crypt_getkeybystr (char *p, short abilities, +static crypt_key_t *crypt_getkeybystr (const char *p, short abilities, unsigned int app, int *forced_valid) { string_list_t *hints = NULL; @@ -3585,7 +3549,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; @@ -3636,7 +3600,8 @@ static crypt_key_t *crypt_ask_for_key (char *tag, static char *find_keys (address_t * to, address_t * cc, address_t * bcc, unsigned int app) { - char *keyID, *keylist = NULL, *t; + char *keylist = NULL, *t; + const char *keyID; ssize_t keylist_size = 0; ssize_t keylist_used = 0; address_t *tmp = NULL, *addr = NULL; @@ -3670,10 +3635,8 @@ static char *find_keys (address_t * to, address_t * cc, address_t * bcc, last = &((*last)->next); } - if (fqdn) - rfc822_qualify (tmp, fqdn); - - tmp = mutt_remove_duplicates (tmp); + rfc822_qualify(tmp, fqdn); + address_list_uniq(tmp); for (p = tmp; p; p = p->next) { char buf[LONG_STRING]; @@ -3691,18 +3654,12 @@ 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 { -#if 0 - k_info = crypt_getkeybystr (keyID, KEYFLAG_CANENCRYPT, - *r_application, &forced_valid); -#else k_info = crypt_getkeybystr (keyID, KEYFLAG_CANENCRYPT, app, &forced_valid); -#endif } } else if (r == -1) { @@ -3719,11 +3676,7 @@ static char *find_keys (address_t * to, address_t * cc, address_t * bcc, snprintf (buf, sizeof (buf), _("Enter keyID for %s: "), q->mailbox); if ((key = crypt_ask_for_key (buf, q->mailbox, KEYFLAG_CANENCRYPT, -#if 0 - *r_application, -#else app, -#endif &forced_valid)) == NULL) { p_delete(&keylist); address_list_wipe(&tmp); @@ -3737,16 +3690,9 @@ static char *find_keys (address_t * to, address_t * cc, address_t * bcc, { const char *s = crypt_fpr (key); -#if 0 - if (key->flags & KEYFLAG_ISX509) - *r_application &= ~APPLICATION_PGP; - if (!(key->flags & KEYFLAG_ISX509)) - *r_application &= ~APPLICATION_SMIME; -#endif - 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); @@ -3758,44 +3704,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) @@ -3837,11 +3759,6 @@ static int gpgme_send_menu (HEADER * msg, int *redraw, int is_smime) msg->security |= (is_smime ? SMIMESIGN : PGPSIGN); } -#if 0 - else { - msg->security &= (is_smime ? ~SMIMESIGN : ~PGPSIGN); - } -#endif *redraw = REDRAW_FULL; break; @@ -3872,17 +3789,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; @@ -3909,7 +3826,7 @@ static int verify_sender (HEADER * h, gpgme_protocol_t protocol __attribute__((u if (1 && (uid->email[0] == '<') && (uid->email[uid_length - 1] == '>') && (uid_length == sender_length + 2) - && (!strncmp (uid->email + 1, sender->mailbox, sender_length))) + && (!m_strncmp (uid->email + 1, sender->mailbox, sender_length))) ret = 0; } } @@ -3927,9 +3844,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