X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=blobdiff_plain;f=crypt.c;h=2fc0924c571cf504a2ce504d281a433b3c3d8490;hp=b22d616f52dd25c878b2c1fe74f9f05a48a11e75;hb=d6390d86146aebd0e2eacb4674a49954514edaff;hpb=576172ff50f9dd94dd2f5cc91d247c1e50dbe7fc diff --git a/crypt.c b/crypt.c index b22d616..2fc0924 100644 --- a/crypt.c +++ b/crypt.c @@ -22,7 +22,6 @@ #include #include "crypt.h" - #include "lib.h" #include "alias.h" #include "handler.h" @@ -76,15 +75,33 @@ static gpgme_key_t signature_key = NULL; * General helper functions. */ -/* return true when S points to a didgit or letter. */ -static int digit_or_letter (const unsigned char *s) +static void convert_to_7bit (BODY * a) { - return ((*s >= '0' && *s <= '9') - || (*s >= 'A' && *s <= 'Z') - || (*s >= 'a' && *s <= 'z')); + while (a) { + if (a->type == TYPEMULTIPART) { + if (a->encoding != ENC7BIT) { + a->encoding = ENC7BIT; + convert_to_7bit (a->parts); + } else { + convert_to_7bit (a->parts); + } + } + else if (a->type == TYPEMESSAGE && + m_strcasecmp(a->subtype, "delivery-status")) { + if (a->encoding != ENC7BIT) + mutt_message_to_7bit (a, NULL); + } + else if (a->encoding == ENC8BIT) + a->encoding = ENCQUOTEDPRINTABLE; + else if (a->encoding == ENCBINARY) + a->encoding = ENCBASE64; + else if (a->content && a->encoding != ENCBASE64 && + (a->content->from || a->content->space)) + a->encoding = ENCQUOTEDPRINTABLE; + a = a->next; + } } - /* Print the utf-8 encoded string BUF of length LEN bytes to stream FP. Convert the character set. */ static void print_utf8 (FILE * fp, const char *buf, ssize_t len) @@ -781,24 +798,13 @@ static BODY *sign_message (BODY * a, int use_smime) return a; } - -BODY *crypt_pgp_sign_message (BODY * a) -{ - return sign_message (a, 0); -} - -BODY *crypt_smime_sign_message (BODY * a) -{ - return sign_message (a, 1); -} - /* * Implementation of `encrypt_message'. */ /* Encrypt the mail body A to all keys given as space separated keyids or fingerprints in KEYLIST and return the encrypted body. */ -BODY *crypt_pgp_encrypt_message (BODY * a, char *keylist, int sign) +static BODY *crypt_pgp_encrypt_message (BODY * a, char *keylist, int sign) { char *outfile = NULL; BODY *t; @@ -858,7 +864,7 @@ BODY *crypt_pgp_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 *crypt_smime_build_smime_entity (BODY * a, char *keylist) +static BODY *crypt_smime_build_smime_entity (BODY * a, char *keylist) { char *outfile = NULL; BODY *t; @@ -1198,7 +1204,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!) */ -int crypt_verify_one(BODY *sigbdy, STATE *s, FILE *fp, int is_smime) +static int crypt_verify_one(BODY *sigbdy, STATE *s, FILE *fp, int is_smime) { int badsig = -1; int anywarn = 0; @@ -2612,7 +2618,7 @@ failure: displayed in a proper way, which does mean to reorder some parts for S/MIME's DNs. USERID is a string as returned by the gpgme key functions. It is utf-8 encoded. */ -static void parse_and_print_user_id (FILE * fp, const char *userid) +static void parse_and_print_user_id(FILE * fp, const char *userid) { const char *s; int i; @@ -2624,7 +2630,7 @@ static void parse_and_print_user_id (FILE * fp, const char *userid) } else if (*userid == '(') fputs (_("[Can't display this user ID (unknown encoding)]"), fp); - else if (!digit_or_letter ((const unsigned char *) userid)) + else if (*userid & ~127 || __m_strdigits[(int)*userid] == 255) fputs (_("[Can't display this user ID (invalid encoding)]"), fp); else { struct dn_array_s *dn = parse_dn ((const unsigned char *) userid); @@ -3176,47 +3182,47 @@ static crypt_key_t *crypt_select_key (crypt_key_t * keys, keymax = i = 0; key_table = NULL; for (k = keys; k; k = k->next) { - if (!option (OPTPGPSHOWUNUSABLE) && (k->flags & KEYFLAG_CANTUSE)) { - unusable = 1; - continue; - } + if (!option (OPTPGPSHOWUNUSABLE) && (k->flags & KEYFLAG_CANTUSE)) { + unusable = 1; + continue; + } - if (i == keymax) { - keymax += 20; - p_realloc(&key_table, keymax); - } + if (i == keymax) { + keymax += 20; + p_realloc(&key_table, keymax); + } - key_table[i++] = k; + key_table[i++] = k; } if (!i && unusable) { - mutt_error _("All matching keys are marked expired/revoked."); + mutt_error _("All matching keys are marked expired/revoked."); - mutt_sleep (1); - return NULL; + mutt_sleep (1); + return NULL; } switch (PgpSortKeys & SORT_MASK) { - case SORT_DATE: - f = crypt_compare_date; - break; - case SORT_KEYID: - f = crypt_compare_keyid; - break; - case SORT_ADDRESS: - f = crypt_compare_address; - break; - case SORT_TRUST: - default: - f = crypt_compare_trust; - break; + case SORT_DATE: + f = crypt_compare_date; + break; + case SORT_KEYID: + f = crypt_compare_keyid; + break; + case SORT_ADDRESS: + f = crypt_compare_address; + break; + case SORT_TRUST: + default: + f = crypt_compare_trust; + break; } qsort (key_table, i, sizeof (crypt_key_t *), f); if (app & APPLICATION_PGP) - menu_to_use = MENU_KEY_SELECT_PGP; + menu_to_use = MENU_KEY_SELECT_PGP; else if (app & APPLICATION_SMIME) - menu_to_use = MENU_KEY_SELECT_SMIME; + menu_to_use = MENU_KEY_SELECT_SMIME; helpstr[0] = 0; mutt_make_help (buf, sizeof (buf), _("Exit "), menu_to_use, OP_EXIT); @@ -3238,106 +3244,106 @@ static crypt_key_t *crypt_select_key (crypt_key_t * keys, menu->data = key_table; { - const char *ts; - - if ((app & APPLICATION_PGP) && (app & APPLICATION_SMIME)) - ts = _("PGP and S/MIME keys matching"); - else if ((app & APPLICATION_PGP)) - ts = _("PGP keys matching"); - else if ((app & APPLICATION_SMIME)) - ts = _("S/MIME keys matching"); - else - ts = _("keys matching"); + const char *ts; + + if ((app & APPLICATION_PGP) && (app & APPLICATION_SMIME)) + ts = _("PGP and S/MIME keys matching"); + else if ((app & APPLICATION_PGP)) + ts = _("PGP keys matching"); + else if ((app & APPLICATION_SMIME)) + ts = _("S/MIME keys matching"); + else + ts = _("keys matching"); - if (p) - snprintf (buf, sizeof (buf), _("%s <%s>."), ts, p->mailbox); - else - snprintf (buf, sizeof (buf), _("%s \"%s\"."), ts, s); - menu->title = buf; + if (p) + snprintf (buf, sizeof (buf), _("%s <%s>."), ts, p->mailbox); + else + snprintf (buf, sizeof (buf), _("%s \"%s\"."), ts, s); + menu->title = buf; } mutt_clear_error (); k = NULL; while (!done) { - *forced_valid = 0; - switch (mutt_menuLoop (menu)) { - case OP_VERIFY_KEY: - verify_key (key_table[menu->current]); - menu->redraw = REDRAW_FULL; - break; - - case OP_VIEW_ID: - mutt_message ("%s", key_table[menu->current]->uid); - break; - - case OP_GENERIC_SELECT_ENTRY: - /* FIXME make error reporting more verbose - this should be - easy because gpgme provides more information */ - if (option (OPTPGPCHECKTRUST)) { - if (!crypt_key_is_valid (key_table[menu->current])) { - mutt_error _("This key can't be used: " - "expired/disabled/revoked."); + *forced_valid = 0; + switch (mutt_menuLoop (menu)) { + case OP_VERIFY_KEY: + verify_key (key_table[menu->current]); + menu->redraw = REDRAW_FULL; break; - } - } - if (option (OPTPGPCHECKTRUST) && - (!crypt_id_is_valid (key_table[menu->current]) - || !crypt_id_is_strong (key_table[menu->current]))) { - const char *warn_s; - char buff[LONG_STRING]; + case OP_VIEW_ID: + mutt_message ("%s", key_table[menu->current]->uid); + break; - if (key_table[menu->current]->flags & KEYFLAG_CANTUSE) - s = N_("ID is expired/disabled/revoked."); - else { - gpgme_validity_t val = GPGME_VALIDITY_UNKNOWN; - gpgme_user_id_t uid = NULL; - int j = 0; - - warn_s = "??"; - - uid = key_table[menu->current]->kobj->uids; - for (j = 0; (j < key_table[menu->current]->idx) && uid; - j++, uid = uid->next); - if (uid) - val = uid->validity; - - switch (val) { - case GPGME_VALIDITY_UNKNOWN: - case GPGME_VALIDITY_UNDEFINED: - warn_s = N_("ID has undefined validity."); - break; - case GPGME_VALIDITY_NEVER: - warn_s = N_("ID is not valid."); - break; - case GPGME_VALIDITY_MARGINAL: - warn_s = N_("ID is only marginally valid."); - break; - case GPGME_VALIDITY_FULL: - case GPGME_VALIDITY_ULTIMATE: - break; + case OP_GENERIC_SELECT_ENTRY: + /* FIXME make error reporting more verbose - this should be + easy because gpgme provides more information */ + if (option (OPTPGPCHECKTRUST)) { + if (!crypt_key_is_valid (key_table[menu->current])) { + mutt_error _("This key can't be used: " + "expired/disabled/revoked."); + break; + } } - snprintf (buff, sizeof (buff), - _("%s Do you really want to use the key?"), _(warn_s)); - - if (mutt_yesorno (buff, 0) != 1) { - mutt_clear_error (); - break; + if (option (OPTPGPCHECKTRUST) && + (!crypt_id_is_valid (key_table[menu->current]) + || !crypt_id_is_strong (key_table[menu->current]))) { + const char *warn_s; + char buff[LONG_STRING]; + + if (key_table[menu->current]->flags & KEYFLAG_CANTUSE) + s = N_("ID is expired/disabled/revoked."); + else { + gpgme_validity_t val = GPGME_VALIDITY_UNKNOWN; + gpgme_user_id_t uid = NULL; + int j = 0; + + warn_s = "??"; + + uid = key_table[menu->current]->kobj->uids; + for (j = 0; (j < key_table[menu->current]->idx) && uid; + j++, uid = uid->next); + if (uid) + val = uid->validity; + + switch (val) { + case GPGME_VALIDITY_UNKNOWN: + case GPGME_VALIDITY_UNDEFINED: + warn_s = N_("ID has undefined validity."); + break; + case GPGME_VALIDITY_NEVER: + warn_s = N_("ID is not valid."); + break; + case GPGME_VALIDITY_MARGINAL: + warn_s = N_("ID is only marginally valid."); + break; + case GPGME_VALIDITY_FULL: + case GPGME_VALIDITY_ULTIMATE: + break; + } + + snprintf (buff, sizeof (buff), + _("%s Do you really want to use the key?"), _(warn_s)); + + if (mutt_yesorno (buff, 0) != 1) { + mutt_clear_error (); + break; + } + *forced_valid = 1; + } } - *forced_valid = 1; - } - } - k = crypt_copy_key (key_table[menu->current]); - done = 1; - break; + k = crypt_copy_key (key_table[menu->current]); + done = 1; + break; - case OP_EXIT: - k = NULL; - done = 1; - break; - } + case OP_EXIT: + k = NULL; + done = 1; + break; + } } mutt_menuDestroy (&menu); @@ -3351,92 +3357,92 @@ static crypt_key_t *crypt_select_key (crypt_key_t * keys, static crypt_key_t *crypt_getkeybyaddr (address_t * a, short abilities, unsigned int app, int *forced_valid) { - address_t *r, *p; - string_list_t *hints = NULL; - - int weak = 0; - int invalid = 0; - int multi = 0; - int this_key_has_strong; - int this_key_has_weak; - int this_key_has_invalid; - int match; + address_t *r, *p; + string_list_t *hints = NULL; + + int weak = 0; + int invalid = 0; + int multi = 0; + int this_key_has_strong; + int this_key_has_weak; + int this_key_has_invalid; + int match; + + crypt_key_t *keys, *k; + crypt_key_t *the_valid_key = NULL; + crypt_key_t *matches = NULL; + crypt_key_t **matches_endp = &matches; - crypt_key_t *keys, *k; - crypt_key_t *the_valid_key = NULL; - crypt_key_t *matches = NULL; - crypt_key_t **matches_endp = &matches; - - *forced_valid = 0; + *forced_valid = 0; - if (a && a->mailbox) - hints = crypt_add_string_to_hints (hints, a->mailbox); - if (a && a->personal) - hints = crypt_add_string_to_hints (hints, a->personal); + if (a && a->mailbox) + hints = crypt_add_string_to_hints (hints, a->mailbox); + if (a && a->personal) + hints = crypt_add_string_to_hints (hints, a->personal); - mutt_message (_("Looking for keys matching \"%s\"..."), a->mailbox); - keys = get_candidates (hints, app, (abilities & KEYFLAG_CANSIGN)); + mutt_message (_("Looking for keys matching \"%s\"..."), a->mailbox); + keys = get_candidates (hints, app, (abilities & KEYFLAG_CANSIGN)); - string_list_wipe(&hints); + string_list_wipe(&hints); - if (!keys) - return NULL; + if (!keys) + return NULL; - for (k = keys; k; k = k->next) { - if (abilities && !(k->flags & abilities)) { - continue; - } + for (k = keys; k; k = k->next) { + if (abilities && !(k->flags & abilities)) { + continue; + } - this_key_has_weak = 0; /* weak but valid match */ - this_key_has_invalid = 0; /* invalid match */ - this_key_has_strong = 0; /* strong and valid match */ - match = 0; /* any match */ - - r = rfc822_parse_adrlist (NULL, k->uid); - for (p = r; p; p = p->next) { - int validity = crypt_id_matches_addr (a, p, k); - - if (validity & CRYPT_KV_MATCH) /* something matches */ - match = 1; - - /* is this key a strong candidate? */ - if ((validity & CRYPT_KV_VALID) - && (validity & CRYPT_KV_STRONGID) - && (validity & CRYPT_KV_ADDR)) { - if (the_valid_key && the_valid_key != k) - multi = 1; - the_valid_key = k; - this_key_has_strong = 1; - } - else if ((validity & CRYPT_KV_MATCH) - && !(validity & CRYPT_KV_VALID)) - this_key_has_invalid = 1; - else if ((validity & CRYPT_KV_MATCH) - && (!(validity & CRYPT_KV_STRONGID) - || !(validity & CRYPT_KV_ADDR))) - this_key_has_weak = 1; - } - address_list_wipe(&r); + this_key_has_weak = 0; /* weak but valid match */ + this_key_has_invalid = 0; /* invalid match */ + this_key_has_strong = 0; /* strong and valid match */ + match = 0; /* any match */ + + r = rfc822_parse_adrlist (NULL, k->uid); + for (p = r; p; p = p->next) { + int validity = crypt_id_matches_addr (a, p, k); + + if (validity & CRYPT_KV_MATCH) /* something matches */ + match = 1; + + /* is this key a strong candidate? */ + if ((validity & CRYPT_KV_VALID) + && (validity & CRYPT_KV_STRONGID) + && (validity & CRYPT_KV_ADDR)) { + if (the_valid_key && the_valid_key != k) + multi = 1; + the_valid_key = k; + this_key_has_strong = 1; + } + else if ((validity & CRYPT_KV_MATCH) + && !(validity & CRYPT_KV_VALID)) + this_key_has_invalid = 1; + else if ((validity & CRYPT_KV_MATCH) + && (!(validity & CRYPT_KV_STRONGID) + || !(validity & CRYPT_KV_ADDR))) + this_key_has_weak = 1; + } + address_list_wipe(&r); - if (match) { - crypt_key_t *tmp; + if (match) { + crypt_key_t *tmp; - if (!this_key_has_strong && this_key_has_invalid) - invalid = 1; - if (!this_key_has_strong && this_key_has_weak) - weak = 1; + if (!this_key_has_strong && this_key_has_invalid) + invalid = 1; + if (!this_key_has_strong && this_key_has_weak) + weak = 1; - *matches_endp = tmp = crypt_copy_key (k); - matches_endp = &tmp->next; - the_valid_key = tmp; + *matches_endp = tmp = crypt_copy_key (k); + matches_endp = &tmp->next; + the_valid_key = tmp; + } } - } - crypt_free_key (&keys); + crypt_free_key (&keys); - if (matches) { - if (the_valid_key && !multi && !weak - && !(invalid && option (OPTPGPSHOWUNUSABLE))) { + 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 @@ -3518,10 +3524,9 @@ static crypt_key_t *crypt_getkeybystr (const char *p, short abilities, default. ABILITIES describe the required key abilities (sign, encrypt) and APP the type of the requested key; ether S/MIME or PGP. Return a copy of the key or NULL if not found. */ -static crypt_key_t *crypt_ask_for_key (char *tag, - char *whatfor, - short abilities, - unsigned int app, int *forced_valid) +static crypt_key_t * +crypt_ask_for_key(char *tag, char *whatfor, short abilities, + unsigned int app, int *forced_valid) { crypt_key_t *key; char resp[STRING]; @@ -3536,7 +3541,6 @@ static crypt_key_t *crypt_ask_for_key (char *tag, *forced_valid = 0; resp[0] = 0; if (whatfor) { - for (l = id_defaults; l; l = l->next) if (!m_strcasecmp(whatfor, l->what)) { m_strcpy(resp, sizeof(resp), NONULL(l->dflt)); @@ -3544,7 +3548,6 @@ static crypt_key_t *crypt_ask_for_key (char *tag, } } - for (;;) { resp[0] = 0; if (mutt_get_field (tag, resp, sizeof (resp), M_CLEAR) != 0) @@ -3650,9 +3653,9 @@ static char *find_keys (address_t * to, address_t * cc, address_t * bcc, app, &forced_valid)) == NULL) { snprintf (buf, sizeof (buf), _("Enter keyID for %s: "), q->mailbox); - if ((key = crypt_ask_for_key (buf, q->mailbox, KEYFLAG_CANENCRYPT, - app, - &forced_valid)) == NULL) { + if ((key = crypt_ask_for_key (buf, q->mailbox, KEYFLAG_CANENCRYPT, app, + &forced_valid)) == NULL) + { p_delete(&keylist); address_list_wipe(&tmp); address_list_wipe(&addr); @@ -3745,7 +3748,8 @@ int crypt_send_menu (HEADER * msg, int *redraw, int is_smime) case 3: /* sign (a)s */ if ((p = crypt_ask_for_key (_("Sign as: "), NULL, KEYFLAG_CANSIGN, is_smime ? APPLICATION_SMIME : - APPLICATION_PGP, NULL))) { + APPLICATION_PGP, NULL))) + { snprintf (input_signas, sizeof (input_signas), "0x%s", crypt_keyid (p)); m_strreplace(is_smime ? &SmimeDefaultKey : &PgpSignAs, input_signas); @@ -3825,7 +3829,7 @@ int crypt_smime_verify_sender (HEADER * h) return ret; } -void crypt_invoke_import(FILE *stream, int smime) +static void crypt_invoke_import(FILE *stream, int smime) { gpgme_ctx_t ctx = create_gpgme_context(smime); gpgme_data_t data; @@ -3935,14 +3939,14 @@ int mutt_protect (HEADER * msg, char *keylist) if (msg->security & SIGN) { if (msg->security & APPLICATION_SMIME) { - if (!(tmp_pbody = crypt_smime_sign_message (msg->content))) + if (!(tmp_pbody = sign_message(msg->content, 1))) return -1; pbody = tmp_smime_pbody = tmp_pbody; } if ((msg->security & APPLICATION_PGP) && (!(flags & ENCRYPT) || option (OPTPGPRETAINABLESIG))) { - if (!(tmp_pbody = crypt_pgp_sign_message (msg->content))) + if (!(tmp_pbody = sign_message(msg->content, 0))) return -1; flags &= ~SIGN; @@ -4086,36 +4090,6 @@ static void crypt_write_signed(BODY * a, STATE * s, FILE *fp) } } - - -void convert_to_7bit (BODY * a) -{ - while (a) { - if (a->type == TYPEMULTIPART) { - if (a->encoding != ENC7BIT) { - a->encoding = ENC7BIT; - convert_to_7bit (a->parts); - } else { - convert_to_7bit (a->parts); - } - } - else if (a->type == TYPEMESSAGE && - m_strcasecmp(a->subtype, "delivery-status")) { - if (a->encoding != ENC7BIT) - mutt_message_to_7bit (a, NULL); - } - else if (a->encoding == ENC8BIT) - a->encoding = ENCQUOTEDPRINTABLE; - else if (a->encoding == ENCBINARY) - a->encoding = ENCBASE64; - else if (a->content && a->encoding != ENCBASE64 && - (a->content->from || a->content->space)) - a->encoding = ENCQUOTEDPRINTABLE; - a = a->next; - } -} - - static void extract_keys_aux(FILE *fpout, HEADER *h) { mutt_parse_mime_message (Context, h);