#include <lib-mx/mx.h>
#include "crypt.h"
-
#include "lib.h"
#include "alias.h"
#include "handler.h"
}
}
-
-/* return true when S points to a didgit or letter. */
-static int digit_or_letter (const unsigned char *s)
-{
- return ((*s >= '0' && *s <= '9')
- || (*s >= 'A' && *s <= 'Z')
- || (*s >= 'a' && *s <= 'z'));
-}
-
-
/* 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)
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;
}
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);
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);
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);
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;
+ 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;
- 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;
-
- *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
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];
*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));
}
}
-
for (;;) {
resp[0] = 0;
if (mutt_get_field (tag, resp, sizeof (resp), M_CLEAR) != 0)
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);
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);