X-Git-Url: http://git.madism.org/?a=blobdiff_plain;f=lib-crypt%2Fcrypt-gpgme.c;h=5bd3173c801955ec20a9818b7fad87914d8a20dd;hb=132d06d5920f9a496a8623acfbbabe9739618489;hp=c6142af4c3c1970b00ebb444765ae8ec17dd2ae1;hpb=0e61856236c91a428ad77f6e2a61b744cf4973e1;p=apps%2Fmadmutt.git diff --git a/lib-crypt/crypt-gpgme.c b/lib-crypt/crypt-gpgme.c index c6142af..5bd3173 100644 --- a/lib-crypt/crypt-gpgme.c +++ b/lib-crypt/crypt-gpgme.c @@ -6,24 +6,13 @@ * Copyright (C) 2001 Thomas Roessler * Oliver Ehli * Copyright (C) 2002, 2003, 2004 g10 Code GmbH - * - * This file is part of mutt-ng, see http://www.muttng.org/. - * It's licensed under the GNU General Public License, - * please see the file GPL in the top level source directory. + */ +/* + * Copyright © 2006 Pierre Habouzit */ #include -#ifdef HAVE_LOCALE_H -# include -#endif -#ifdef HAVE_LANGINFO_D_T_FMT -# include -#endif -#ifdef HAVE_SYS_RESOURCE_H -# include -#endif - #include #include @@ -82,17 +71,6 @@ 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. */ @@ -487,6 +465,33 @@ static char *data_object_to_tempfile (gpgme_data_t data, FILE ** ret_fp) } +/* FIXME: stolen from gpgme to avoid "ambiguous identity" errors */ +static gpgme_error_t +gpgme_get_key2 (gpgme_ctx_t ctx, const char *fpr, gpgme_key_t *r_key, + int secret) +{ + gpgme_ctx_t listctx; + gpgme_error_t err; + + if (!ctx || !r_key || !fpr) + return gpg_error (GPG_ERR_INV_VALUE); + + if (strlen (fpr) < 8) /* We have at least a key ID. */ + return gpg_error (GPG_ERR_INV_VALUE); + + /* FIXME: We use our own context because we have to avoid the user's + I/O callback handlers. */ + err = gpgme_new (&listctx); + if (err) + return err; + gpgme_set_protocol (listctx, gpgme_get_protocol (ctx)); + err = gpgme_op_keylist_start (listctx, fpr, secret); + if (!err) + err = gpgme_op_keylist_next (listctx, r_key); + gpgme_release (listctx); + return err; +} + /* Create a GpgmeRecipientSet from the keys in the string KEYLIST. The keys must be space delimited. */ static gpgme_key_t *create_recipient_set (const char *keylist, @@ -519,13 +524,13 @@ static gpgme_key_t *create_recipient_set (const char *keylist, key. */ buf[i - 1] = 0; - err = gpgme_get_key (context, buf, &key, 0); + err = gpgme_get_key2 (context, buf, &key, 0); if (!err) key->uids->validity = GPGME_VALIDITY_FULL; buf[i - 1] = '!'; } else - err = gpgme_get_key (context, buf, &key, 0); + err = gpgme_get_key2 (context, buf, &key, 0); if (!err) { p_realloc(&rset, rset_n + 1); @@ -1115,7 +1120,7 @@ static int show_one_sig_status (gpgme_ctx_t ctx, int idx, STATE * s) if (gpg_err_code (sig->status) != GPG_ERR_NO_ERROR) anybad = 1; - err = gpgme_get_key (ctx, fpr, &key, 0); /* secret key? */ + err = gpgme_get_key2 (ctx, fpr, &key, 0); /* secret key? */ if (!err) { uid = (key->uids && key->uids->uid) ? key->uids->uid : "[?]"; if (!signature_key) @@ -1192,8 +1197,7 @@ static int show_one_sig_status (gpgme_ctx_t ctx, int idx, STATE * s) /* Do the actual verification step. With IS_SMIME set to true we assume S/MIME (surprise!) */ -static int verify_one (BODY * sigbdy, STATE * s, - const char *tempfile, int is_smime) +int crypt_verify_one(BODY *sigbdy, STATE *s, FILE *fp, int is_smime) { int badsig = -1; int anywarn = 0; @@ -1210,7 +1214,7 @@ static int verify_one (BODY * sigbdy, STATE * s, if (is_smime) gpgme_data_set_encoding (signature, GPGME_DATA_ENCODING_BASE64); - err = gpgme_data_new_from_file (&message, tempfile, 1); + err = gpgme_data_new_from_stream(&message, fp); if (err) { gpgme_data_release (signature); mutt_error (_("error allocating data object: %s\n"), gpgme_strerror (err)); @@ -1290,16 +1294,6 @@ static int verify_one (BODY * sigbdy, STATE * s, return badsig ? 1 : anywarn ? 2 : 0; } -int crypt_pgp_verify_one (BODY * sigbdy, STATE * s, const char *tempfile) -{ - return verify_one (sigbdy, s, tempfile, 0); -} - -int crypt_smime_verify_one (BODY * sigbdy, STATE * s, const char *tempfile) -{ - return verify_one (sigbdy, s, tempfile, 1); -} - /* * Implementation of `decrypt_part'. */ @@ -3082,26 +3076,6 @@ static crypt_key_t *get_candidates (string_list_t * hints, unsigned int app, if (key_check_cap (key, KEY_CAP_CAN_SIGN)) flags |= KEYFLAG_CANSIGN; -#if 0 /* DISABLED code */ - if (!flags) { - /* Bug in gpg. Capabilities are not listed for secret - keys. Try to deduce them from the algorithm. */ - - switch (key->subkeys[0].pubkey_algo) { - case GPGME_PK_RSA: - flags |= KEYFLAG_CANENCRYPT; - flags |= KEYFLAG_CANSIGN; - break; - case GPGME_PK_ELG_E: - flags |= KEYFLAG_CANENCRYPT; - break; - case GPGME_PK_DSA: - flags |= KEYFLAG_CANSIGN; - break; - } - } -#endif /* DISABLED code */ - for (idx = 0, uid = key->uids; uid; idx++, uid = uid->next) { k = p_new(crypt_key_t, 1); k->kobj = key; @@ -3704,17 +3678,37 @@ static char *find_keys (address_t * to, address_t * cc, address_t * bcc, return (keylist); } -char *crypt_pgp_findkeys (address_t * to, address_t * cc, address_t * bcc) +int crypt_get_keys (HEADER * msg, char **keylist) { - return find_keys (to, cc, bcc, APPLICATION_PGP); -} + /* Do a quick check to make sure that we can find all of the encryption + * keys if the user has requested this service. + */ -char *crypt_smime_findkeys (address_t * to, address_t * cc, address_t * bcc) -{ - return find_keys (to, cc, bcc, APPLICATION_SMIME); + *keylist = NULL; + + if (msg->security & ENCRYPT) { + if (msg->security & APPLICATION_PGP) { + set_option(OPTPGPCHECKTRUST); + *keylist = find_keys(msg->env->to, msg->env->cc, msg->env->bcc, + APPLICATION_PGP); + unset_option(OPTPGPCHECKTRUST); + if (!*keylist) + return -1; + } + + if (msg->security & APPLICATION_SMIME) { + *keylist = find_keys(msg->env->to, msg->env->cc, msg->env->bcc, + APPLICATION_SMIME); + if (!*keylist) + return -1; + } + } + + return (0); } -static int gpgme_send_menu (HEADER * msg, int *redraw, int is_smime) + +int crypt_send_menu (HEADER * msg, int *redraw, int is_smime) { crypt_key_t *p; char input_signas[STRING]; @@ -3729,12 +3723,12 @@ static int gpgme_send_menu (HEADER * msg, int *redraw, int is_smime) choice = mutt_multi_choice (_ ("S/MIME (e)ncrypt, (s)ign, sign (a)s, (b)oth, (p)gp or (c)lear?"), - _("esabpfc")); + _("esabpc")); else choice = mutt_multi_choice (_ ("PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, s/(m)ime or (c)lear?"), - _("esabmfc")); + _("esabmc")); switch (choice) { case 1: /* (e)ncrypt */ @@ -3748,7 +3742,6 @@ static int gpgme_send_menu (HEADER * msg, int *redraw, int is_smime) break; case 3: /* sign (a)s */ -/* unset_option(OPTCRYPTCHECKTRUST); */ if ((p = crypt_ask_for_key (_("Sign as: "), NULL, KEYFLAG_CANSIGN, is_smime ? APPLICATION_SMIME : APPLICATION_PGP, NULL))) { @@ -3772,31 +3765,18 @@ static int gpgme_send_menu (HEADER * msg, int *redraw, int is_smime) break; case 6: /* (c)lear */ - msg->security = 0; - break; + return msg->security = 0; } - if (choice == 6 || choice == 7); - else if (is_smime) { + if (is_smime) { msg->security &= ~APPLICATION_PGP; msg->security |= APPLICATION_SMIME; - } - else { + } else { msg->security &= ~APPLICATION_SMIME; msg->security |= APPLICATION_PGP; } - return (msg->security); -} - -int crypt_pgp_send_menu(HEADER * msg, int *redraw) -{ - return gpgme_send_menu(msg, redraw, 0); -} - -int crypt_smime_send_menu(HEADER * msg, int *redraw) -{ - return gpgme_send_menu (msg, redraw, 1); + return msg->security; } int crypt_smime_verify_sender (HEADER * h) @@ -3844,13 +3824,13 @@ int crypt_smime_verify_sender (HEADER * h) return ret; } -static void invoke_import(const char *fname, int smime) +void crypt_invoke_import(FILE *stream, 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); + err = gpgme_data_new_from_stream(&data, stream); if (err) { mutt_error (_("error allocating data object: %s\n"), gpgme_strerror (err)); gpgme_release(ctx); @@ -3870,38 +3850,24 @@ static void invoke_import(const char *fname, int smime) return; } -void crypt_pgp_invoke_import(const char *fname) -{ - invoke_import(fname, 0); -} - -void crypt_smime_invoke_import(const char *fname) +static void pgp_extract_keys_from_attachment(FILE * fp, BODY * top) { - 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); + STATE s; + FILE *tmpfp = tmpfile(); - s.fpin = fp; - s.fpout = tempfp; + if (tmpfp == NULL) { + mutt_perror (_("Can't create temporary file")); + return; + } - mutt_body_handler (top, &s); + p_clear(&s, 1); + s.fpin = fp; + s.fpout = tmpfp; + mutt_body_handler(top, &s); - m_fclose(&tempfp); - crypt_pgp_invoke_import(tempfname); - mutt_unlink (tempfname); + rewind(tmpfp); + crypt_invoke_import(tmpfp, 0); + m_fclose(&tmpfp); } void crypt_pgp_extract_keys_from_attachment_list(FILE * fp, int tag, BODY * top) @@ -3920,3 +3886,24 @@ void crypt_pgp_extract_keys_from_attachment_list(FILE * fp, int tag, BODY * top) unset_option (OPTDONTHANDLEPGPKEYS); } + +/* TODO */ + +/* fixme: needs documentation. */ +void crypt_pgp_invoke_getkeys (address_t * addr) +{ +} + +/* Generate a PGP public key attachment. */ +BODY *crypt_pgp_make_key_attachment (char *tempf) +{ + return NULL; +} + +/* S/MIME */ + +/* fixme: Needs documentation. */ +void crypt_smime_getkeys (ENVELOPE * env) +{ +} +