wibble
[apps/madmutt.git] / crypt.c
diff --git a/crypt.c b/crypt.c
index d044e9a..2fc0924 100644 (file)
--- a/crypt.c
+++ b/crypt.c
@@ -22,7 +22,6 @@
 #include <lib-mx/mx.h>
 
 #include "crypt.h"
-
 #include "lib.h"
 #include "alias.h"
 #include "handler.h"
@@ -103,16 +102,6 @@ static void convert_to_7bit (BODY * a)
   }
 }
 
-
-/* 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)
@@ -2629,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;
@@ -2641,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);
@@ -3193,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);
@@ -3255,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);
@@ -3368,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;
+    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
@@ -3535,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];
@@ -3553,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));
@@ -3561,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)
@@ -3667,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);
@@ -3762,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);