X-Git-Url: http://git.madism.org/?a=blobdiff_plain;f=lib-crypt%2Fcrypt-gpgme.c;h=7c24186797eabb1b3dd68b8bdf6ca87c3d6ab1ac;hb=e4360f3016dc130069b68459ef3942a26347358c;hp=949d1eb7690f093257e999d22edf86fcd4f3b753;hpb=16534e98723674fa391e3fc29d2a07ce419c13dd;p=apps%2Fmadmutt.git diff --git a/lib-crypt/crypt-gpgme.c b/lib-crypt/crypt-gpgme.c index 949d1eb..7c24186 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 @@ -29,31 +27,19 @@ #include #include - #include #include #include +#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" -#include "crypt-gpgme.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 @@ -96,6 +82,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. */ @@ -685,9 +693,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 +787,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 +803,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; @@ -857,7 +863,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; @@ -898,9 +904,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. @@ -1297,12 +1301,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); } @@ -1447,7 +1451,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; @@ -1485,7 +1489,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]; @@ -1658,14 +1662,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); @@ -1677,9 +1681,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 @@ -1742,7 +1744,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; @@ -1966,12 +1968,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; @@ -2045,7 +2045,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; @@ -2511,7 +2511,7 @@ 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)) @@ -2520,7 +2520,7 @@ static const unsigned char *parse_dn_part (struct dn_array_s *array, 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 */ @@ -2531,7 +2531,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++; } @@ -2552,8 +2552,8 @@ static const unsigned char *parse_dn_part (struct dn_array_s *array, 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 @@ -2975,10 +2975,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 @@ -3718,40 +3715,16 @@ 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; @@ -3827,17 +3800,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; @@ -3882,9 +3855,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) +{ + 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) { - return verify_sender (h, GPGME_PROTOCOL_CMS); + 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