remove lot of code, round 1
[apps/madmutt.git] / lib-crypt / pgpkey.c
diff --git a/lib-crypt/pgpkey.c b/lib-crypt/pgpkey.c
deleted file mode 100644 (file)
index 96db58a..0000000
+++ /dev/null
@@ -1,938 +0,0 @@
-/*
- * Copyright notice from original mutt:
- * Copyright (C) 1996,1997 Michael R. Elkins <me@mutt.org>
- * Copyright (c) 1998,1999 Thomas Roessler <roessler@does-not-exist.org>
- *
- * 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.
- */
-
-#include <lib-lib/lib-lib.h>
-
-#include <lib-mime/mime.h>
-#include <lib-sys/unix.h>
-
-#include <lib-ui/curses.h>
-#include <lib-ui/enter.h>
-#include <lib-ui/menu.h>
-
-#include "recvattach.h"
-#include "pgp.h"
-#include "pager.h"
-#include "sort.h"
-
-struct pgp_cache {
-  char *what;
-  char *dflt;
-  struct pgp_cache *next;
-};
-
-static struct pgp_cache *id_defaults = NULL;
-
-static char trust_flags[] = "?- +";
-
-static char *pgp_key_abilities (int flags)
-{
-  static char buff[3];
-
-  if (!(flags & KEYFLAG_CANENCRYPT))
-    buff[0] = '-';
-  else if (flags & KEYFLAG_PREFER_SIGNING)
-    buff[0] = '.';
-  else
-    buff[0] = 'e';
-
-  if (!(flags & KEYFLAG_CANSIGN))
-    buff[1] = '-';
-  else if (flags & KEYFLAG_PREFER_ENCRYPTION)
-    buff[1] = '.';
-  else
-    buff[1] = 's';
-
-  buff[2] = '\0';
-
-  return buff;
-}
-
-static char pgp_flags (int flags)
-{
-  if (flags & KEYFLAG_REVOKED)
-    return 'R';
-  else if (flags & KEYFLAG_EXPIRED)
-    return 'X';
-  else if (flags & KEYFLAG_DISABLED)
-    return 'd';
-  else if (flags & KEYFLAG_CRITICAL)
-    return 'c';
-  else
-    return ' ';
-}
-
-static pgp_key_t pgp_principal_key (pgp_key_t key)
-{
-  if (key->flags & KEYFLAG_SUBKEY && key->parent)
-    return key->parent;
-  else
-    return key;
-}
-
-/*
- * Format an entry on the PGP key selection menu.
- * 
- * %n  number
- * %k  key id          %K      key id of the principal key
- * %u  user id
- * %a  algorithm       %A      algorithm of the princ. key
- * %l  length          %L      length of the princ. key
- * %f  flags           %F      flags of the princ. key
- * %c  capabilities    %C      capabilities of the princ. key
- * %t  trust/validity of the key-uid association
- * %[...] date of key using strftime(3)
- */
-
-typedef struct pgp_entry {
-  ssize_t num;
-  pgp_uid_t *uid;
-} pgp_entry_t;
-
-static const char *
-pgp_entry_fmt (char *dest, ssize_t destlen, char op,
-               const char *src, const char *prefix,
-               const char *ifstr, const char *elstr,
-               anytype data, format_flag flags)
-{
-  char fmt[16];
-  pgp_entry_t *entry;
-  pgp_uid_t *uid;
-  pgp_key_t key, pkey;
-  int kflags = 0;
-  int optional = (flags & M_FORMAT_OPTIONAL);
-
-  entry = data.ptr;
-  uid = entry->uid;
-  key = uid->parent;
-  pkey = pgp_principal_key (key);
-
-  if (isupper ((unsigned char) op))
-    key = pkey;
-
-  kflags = key->flags | (pkey->flags & KEYFLAG_RESTRICTIONS)
-    | uid->flags;
-
-  switch (ascii_tolower (op)) {
-  case '[':
-
-    {
-      const char *cp;
-      char buf2[STRING], *p;
-      int do_locales;
-      struct tm *tm;
-      ssize_t len;
-
-      p = dest;
-
-      cp = src;
-      if (*cp == '!') {
-        do_locales = 0;
-        cp++;
-      }
-      else
-        do_locales = 1;
-
-      len = destlen - 1;
-      while (len > 0 && *cp != ']') {
-        if (*cp == '%') {
-          cp++;
-          if (len >= 2) {
-            *p++ = '%';
-            *p++ = *cp;
-            len -= 2;
-          }
-          else
-            break;              /* not enough space */
-          cp++;
-        }
-        else {
-          *p++ = *cp++;
-          len--;
-        }
-      }
-      *p = 0;
-
-      if (do_locales && Locale)
-        setlocale (LC_TIME, Locale);
-
-      tm = localtime (&key->gen_time);
-
-      strftime (buf2, sizeof (buf2), dest, tm);
-
-      if (do_locales)
-        setlocale (LC_TIME, "C");
-
-      snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
-      snprintf (dest, destlen, fmt, buf2);
-      if (len > 0)
-        src = cp + 1;
-    }
-    break;
-  case 'n':
-    if (!optional) {
-      snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
-      snprintf (dest, destlen, fmt, entry->num);
-    }
-    break;
-  case 'k':
-    if (!optional) {
-      snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
-      snprintf (dest, destlen, fmt, _pgp_keyid (key));
-    }
-    break;
-  case 'u':
-    if (!optional) {
-      snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
-      snprintf (dest, destlen, fmt, uid->addr);
-    }
-    break;
-  case 'a':
-    if (!optional) {
-      snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
-      snprintf (dest, destlen, fmt, key->algorithm);
-    }
-    break;
-  case 'l':
-    if (!optional) {
-      snprintf (fmt, sizeof (fmt), "%%%sd", prefix);
-      snprintf (dest, destlen, fmt, key->keylen);
-    }
-    break;
-  case 'f':
-    if (!optional) {
-      snprintf (fmt, sizeof (fmt), "%%%sc", prefix);
-      snprintf (dest, destlen, fmt, pgp_flags (kflags));
-    }
-    else if (!(kflags & (KEYFLAG_RESTRICTIONS)))
-      optional = 0;
-    break;
-  case 'c':
-    if (!optional) {
-      snprintf (fmt, sizeof (fmt), "%%%ss", prefix);
-      snprintf (dest, destlen, fmt, pgp_key_abilities (kflags));
-    }
-    else if (!(kflags & (KEYFLAG_ABILITIES)))
-      optional = 0;
-    break;
-  case 't':
-    if (!optional) {
-      snprintf (fmt, sizeof (fmt), "%%%sc", prefix);
-      snprintf (dest, destlen, fmt, trust_flags[uid->trust & 0x03]);
-    }
-    else if (!(uid->trust & 0x03))
-      /* undefined trust */
-      optional = 0;
-    break;
-  default:
-    *dest = '\0';
-  }
-
-  if (flags & M_FORMAT_OPTIONAL)
-    m_strformat(dest, destlen, 0, optional ? ifstr : elstr,
-                mutt_attach_fmt, data, 0);
-  return src;
-}
-
-static void pgp_entry (char *s, ssize_t l, MUTTMENU * menu, int num)
-{
-  pgp_uid_t **KeyTable = (pgp_uid_t **) menu->data;
-  pgp_entry_t entry;
-
-  entry.uid = KeyTable[num];
-  entry.num = num + 1;
-
-  m_strformat(s, l, COLS - SW, PgpEntryFormat, pgp_entry_fmt, &entry,
-              option(OPTARROWCURSOR) ? M_FORMAT_ARROWCURSOR : 0);
-}
-
-static int _pgp_compare_address (const void *a, const void *b)
-{
-  int r;
-
-  pgp_uid_t **s = (pgp_uid_t **) a;
-  pgp_uid_t **t = (pgp_uid_t **) b;
-
-  if ((r = m_strcasecmp((*s)->addr, (*t)->addr)))
-    return r > 0;
-  else
-    return (m_strcasecmp(_pgp_keyid ((*s)->parent),
-                             _pgp_keyid ((*t)->parent)) > 0);
-}
-
-static int pgp_compare_address (const void *a, const void *b)
-{
-  return ((PgpSortKeys & SORT_REVERSE) ? !_pgp_compare_address (a, b)
-          : _pgp_compare_address (a, b));
-}
-
-
-
-static int _pgp_compare_keyid (const void *a, const void *b)
-{
-  int r;
-
-  pgp_uid_t **s = (pgp_uid_t **) a;
-  pgp_uid_t **t = (pgp_uid_t **) b;
-
-  if ((r = m_strcasecmp(_pgp_keyid ((*s)->parent),
-                            _pgp_keyid ((*t)->parent))))
-    return r > 0;
-  else
-    return (m_strcasecmp((*s)->addr, (*t)->addr)) > 0;
-}
-
-static int pgp_compare_keyid (const void *a, const void *b)
-{
-  return ((PgpSortKeys & SORT_REVERSE) ? !_pgp_compare_keyid (a, b)
-          : _pgp_compare_keyid (a, b));
-}
-
-static int _pgp_compare_date (const void *a, const void *b)
-{
-  int r;
-  pgp_uid_t **s = (pgp_uid_t **) a;
-  pgp_uid_t **t = (pgp_uid_t **) b;
-
-  if ((r = ((*s)->parent->gen_time - (*t)->parent->gen_time)))
-    return r > 0;
-  return (m_strcasecmp((*s)->addr, (*t)->addr)) > 0;
-}
-
-static int pgp_compare_date (const void *a, const void *b)
-{
-  return ((PgpSortKeys & SORT_REVERSE) ? !_pgp_compare_date (a, b)
-          : _pgp_compare_date (a, b));
-}
-
-static int _pgp_compare_trust (const void *a, const void *b)
-{
-  int r;
-
-  pgp_uid_t **s = (pgp_uid_t **) a;
-  pgp_uid_t **t = (pgp_uid_t **) b;
-
-  if ((r = (((*s)->parent->flags & (KEYFLAG_RESTRICTIONS))
-            - ((*t)->parent->flags & (KEYFLAG_RESTRICTIONS)))))
-    return r > 0;
-  if ((r = ((*s)->trust - (*t)->trust)))
-    return r < 0;
-  if ((r = ((*s)->parent->keylen - (*t)->parent->keylen)))
-    return r < 0;
-  if ((r = ((*s)->parent->gen_time - (*t)->parent->gen_time)))
-    return r < 0;
-  if ((r = m_strcasecmp((*s)->addr, (*t)->addr)))
-    return r > 0;
-  return (m_strcasecmp(_pgp_keyid ((*s)->parent),
-                           _pgp_keyid ((*t)->parent))) > 0;
-}
-
-static int pgp_compare_trust (const void *a, const void *b)
-{
-  return ((PgpSortKeys & SORT_REVERSE) ? !_pgp_compare_trust (a, b)
-          : _pgp_compare_trust (a, b));
-}
-
-static int pgp_key_is_valid (pgp_key_t k)
-{
-  pgp_key_t pk = pgp_principal_key (k);
-
-  if (k->flags & KEYFLAG_CANTUSE)
-    return 0;
-  if (pk->flags & KEYFLAG_CANTUSE)
-    return 0;
-
-  return 1;
-}
-
-static int pgp_id_is_strong (pgp_uid_t * uid)
-{
-  if ((uid->trust & 3) < 3)
-    return 0;
-  /* else */
-  return 1;
-}
-
-static int pgp_id_is_valid (pgp_uid_t * uid)
-{
-  if (!pgp_key_is_valid (uid->parent))
-    return 0;
-  if (uid->flags & KEYFLAG_CANTUSE)
-    return 0;
-  /* else */
-  return 1;
-}
-
-#define PGP_KV_VALID   1
-#define PGP_KV_ADDR    2
-#define PGP_KV_STRING  4
-#define PGP_KV_STRONGID 8
-
-#define PGP_KV_MATCH (PGP_KV_ADDR|PGP_KV_STRING)
-
-static int pgp_id_matches_addr (address_t * addr, address_t * u_addr,
-                                pgp_uid_t * uid)
-{
-  int rv = 0;
-
-  if (pgp_id_is_valid (uid))
-    rv |= PGP_KV_VALID;
-
-  if (pgp_id_is_strong (uid))
-    rv |= PGP_KV_STRONGID;
-
-  if (addr->mailbox && u_addr->mailbox
-      && m_strcasecmp(addr->mailbox, u_addr->mailbox) == 0)
-    rv |= PGP_KV_ADDR;
-
-  if (addr->personal && u_addr->personal
-      && m_strcasecmp(addr->personal, u_addr->personal) == 0)
-    rv |= PGP_KV_STRING;
-
-  return rv;
-}
-
-static pgp_key_t pgp_select_key (pgp_key_t keys, address_t * p, const char *s)
-{
-  int keymax;
-  pgp_uid_t **KeyTable;
-  MUTTMENU *menu;
-  int i, done = 0;
-  char helpstr[STRING], buf[LONG_STRING], tmpbuf[STRING];
-  char cmd[LONG_STRING], tempfile[_POSIX_PATH_MAX];
-  FILE *fp, *devnull;
-  pid_t thepid;
-  pgp_key_t kp;
-  pgp_uid_t *a;
-  int (*f) (const void *, const void *);
-
-  int unusable = 0;
-
-  keymax = 0;
-  KeyTable = NULL;
-
-  for (i = 0, kp = keys; kp; kp = kp->next) {
-    if (!option (OPTPGPSHOWUNUSABLE) && (kp->flags & KEYFLAG_CANTUSE)) {
-      unusable = 1;
-      continue;
-    }
-
-    for (a = kp->address; a; a = a->next) {
-      if (!option (OPTPGPSHOWUNUSABLE) && (a->flags & KEYFLAG_CANTUSE)) {
-        unusable = 1;
-        continue;
-      }
-
-      if (i == keymax) {
-        keymax += 5;
-        p_realloc(&KeyTable, keymax);
-      }
-
-      KeyTable[i++] = a;
-    }
-  }
-
-  if (!i && unusable) {
-    mutt_error _("All matching keys are expired, revoked, or disabled.");
-
-    mutt_sleep (1);
-    return NULL;
-  }
-
-  switch (PgpSortKeys & SORT_MASK) {
-  case SORT_DATE:
-    f = pgp_compare_date;
-    break;
-  case SORT_KEYID:
-    f = pgp_compare_keyid;
-    break;
-  case SORT_ADDRESS:
-    f = pgp_compare_address;
-    break;
-  case SORT_TRUST:
-  default:
-    f = pgp_compare_trust;
-    break;
-  }
-  qsort (KeyTable, i, sizeof (pgp_uid_t *), f);
-
-  helpstr[0] = 0;
-  mutt_make_help (buf, sizeof (buf), _("Exit  "), MENU_PGP, OP_EXIT);
-  m_strcat(helpstr, sizeof(helpstr), buf);
-  mutt_make_help (buf, sizeof (buf), _("Select  "), MENU_PGP,
-                  OP_GENERIC_SELECT_ENTRY);
-  m_strcat(helpstr, sizeof(helpstr), buf);
-  mutt_make_help (buf, sizeof (buf), _("Check key  "), MENU_PGP,
-                  OP_VERIFY_KEY);
-  m_strcat(helpstr, sizeof(helpstr), buf);
-  mutt_make_help (buf, sizeof (buf), _("Help"), MENU_PGP, OP_HELP);
-  m_strcat(helpstr, sizeof(helpstr), buf);
-
-  menu = mutt_new_menu ();
-  menu->max = i;
-  menu->make_entry = pgp_entry;
-  menu->menu = MENU_PGP;
-  menu->help = helpstr;
-  menu->data = KeyTable;
-
-  if (p)
-    snprintf (buf, sizeof (buf), _("PGP keys matching <%s>."), p->mailbox);
-  else
-    snprintf (buf, sizeof (buf), _("PGP keys matching \"%s\"."), s);
-
-
-  menu->title = buf;
-
-  kp = NULL;
-
-  mutt_clear_error ();
-
-  while (!done) {
-    switch (mutt_menuLoop (menu)) {
-
-    case OP_VERIFY_KEY:
-
-      if ((devnull = fopen("/dev/null", "w")) == NULL) {
-        mutt_perror (_("Can't open /dev/null"));
-
-        break;
-      }
-
-      fp = m_tempfile (tempfile, sizeof(tempfile), NONULL(MCore.tmpdir), NULL);
-      if (!fp) {
-        m_fclose(&devnull);
-        mutt_perror (_("Can't create temporary file"));
-
-        break;
-      }
-
-      mutt_message _("Invoking PGP...");
-
-      snprintf (tmpbuf, sizeof (tmpbuf), "0x%s",
-                pgp_keyid (pgp_principal_key
-                           (KeyTable[menu->current]->parent)));
-
-      if ((thepid = pgp_invoke_verify_key (NULL, NULL, NULL, -1,
-                                           fileno (fp), fileno (devnull),
-                                           tmpbuf)) == -1) {
-        mutt_perror (_("Can't create filter"));
-
-        unlink (tempfile);
-        m_fclose(&fp);
-        m_fclose(&devnull);
-      }
-
-      mutt_wait_filter (thepid);
-      m_fclose(&fp);
-      m_fclose(&devnull);
-      mutt_clear_error ();
-      snprintf (cmd, sizeof (cmd), _("Key ID: 0x%s"),
-                pgp_keyid (pgp_principal_key
-                           (KeyTable[menu->current]->parent)));
-      mutt_do_pager (cmd, tempfile, 0, NULL);
-      menu->redraw = REDRAW_FULL;
-
-      break;
-
-    case OP_VIEW_ID:
-
-      mutt_message ("%s", KeyTable[menu->current]->addr);
-      break;
-
-    case OP_GENERIC_SELECT_ENTRY:
-
-
-      /* XXX make error reporting more verbose */
-
-      if (option (OPTPGPCHECKTRUST))
-        if (!pgp_key_is_valid (KeyTable[menu->current]->parent)) {
-          mutt_error _("This key can't be used: expired/disabled/revoked.");
-
-          break;
-        }
-
-      if (option (OPTPGPCHECKTRUST) &&
-          (!pgp_id_is_valid (KeyTable[menu->current])
-           || !pgp_id_is_strong (KeyTable[menu->current]))) {
-        const char *q = "";
-        char buff[LONG_STRING];
-
-        if (KeyTable[menu->current]->flags & KEYFLAG_CANTUSE)
-          q = N_("ID is expired/disabled/revoked.");
-        else
-          switch (KeyTable[menu->current]->trust & 0x03) {
-          case 0:
-            q = N_("ID has undefined validity.");
-            break;
-          case 1:
-            q = N_("ID is not valid.");
-            break;
-          case 2:
-            q = N_("ID is only marginally valid.");
-            break;
-          }
-
-        snprintf (buff, sizeof (buff),
-                  _("%s Do you really want to use the key?"), _(q));
-
-        if (mutt_yesorno (buff, M_NO) != M_YES) {
-          mutt_clear_error ();
-          break;
-        }
-      }
-
-# if 0
-      kp = pgp_principal_key (KeyTable[menu->current]->parent);
-# else
-      kp = KeyTable[menu->current]->parent;
-# endif
-      done = 1;
-      break;
-
-    case OP_EXIT:
-
-      kp = NULL;
-      done = 1;
-      break;
-    }
-  }
-
-  mutt_menuDestroy (&menu);
-  p_delete(&KeyTable);
-
-  set_option (OPTNEEDREDRAW);
-
-  return (kp);
-}
-
-pgp_key_t pgp_ask_for_key (char *tag, char *whatfor,
-                           short abilities, pgp_ring_t keyring)
-{
-  pgp_key_t key;
-  char resp[STRING];
-  struct pgp_cache *l = NULL;
-
-  mutt_clear_error ();
-
-  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));
-        break;
-      }
-  }
-
-
-  for (;;) {
-    resp[0] = 0;
-    if (mutt_get_field (tag, resp, sizeof (resp), M_CLEAR) != 0)
-      return NULL;
-
-    if (whatfor) {
-      if (l)
-        m_strreplace(&l->dflt, resp);
-      else {
-        l = p_new(struct pgp_cache, 1);
-        l->next = id_defaults;
-        id_defaults = l;
-        l->what = m_strdup(whatfor);
-        l->dflt = m_strdup(resp);
-      }
-    }
-
-    if ((key = pgp_getkeybystr (resp, abilities, keyring)))
-      return key;
-
-    BEEP ();
-  }
-  /* not reached */
-}
-
-/* generate a public key attachment */
-
-BODY *pgp_make_key_attachment (char *tempf)
-{
-  BODY *att;
-  char buff[LONG_STRING];
-  char tempfb[_POSIX_PATH_MAX], tmp[STRING];
-  FILE *tempfp;
-  FILE *devnull;
-  struct stat sb;
-  pid_t thepid;
-  pgp_key_t key;
-
-  unset_option (OPTPGPCHECKTRUST);
-
-  key =
-    pgp_ask_for_key (_("Please enter the key ID: "), NULL, 0, PGP_PUBRING);
-
-  if (!key)
-    return NULL;
-
-  snprintf (tmp, sizeof (tmp), "0x%s", pgp_keyid (pgp_principal_key (key)));
-  pgp_free_key (&key);
-
-  if (!tempf) {
-    tempfp = m_tempfile (tempfb, sizeof(tempfb), NONULL(MCore.tmpdir), NULL);
-    tempf = tempfb;
-  } else {
-    tempfp = safe_fopen(tempf, "a");
-  }
-
-  if (!tempfp) {
-    mutt_perror (_("Can't create temporary file"));
-    return NULL;
-  }
-
-  if ((devnull = fopen("/dev/null", "w")) == NULL) {
-    mutt_perror (_("Can't open /dev/null"));
-
-    m_fclose(&tempfp);
-    if (tempf == tempfb)
-      unlink (tempf);
-    return NULL;
-  }
-
-  mutt_message _("Invoking pgp...");
-
-
-  if ((thepid =
-       pgp_invoke_export (NULL, NULL, NULL, -1,
-                          fileno (tempfp), fileno (devnull), tmp)) == -1) {
-    mutt_perror (_("Can't create filter"));
-
-    unlink (tempf);
-    m_fclose(&tempfp);
-    m_fclose(&devnull);
-    return NULL;
-  }
-
-  mutt_wait_filter (thepid);
-
-  m_fclose(&tempfp);
-  m_fclose(&devnull);
-
-  att = body_new();
-  att->filename = m_strdup(tempf);
-  att->unlink = 1;
-  att->use_disp = 0;
-  att->type = TYPEAPPLICATION;
-  att->subtype = m_strdup("pgp-keys");
-  snprintf (buff, sizeof (buff), _("PGP Key %s."), tmp);
-  att->description = m_strdup(buff);
-  mutt_update_encoding (att);
-
-  stat (tempf, &sb);
-  att->length = sb.st_size;
-
-  return att;
-}
-
-static string_list_t *pgp_add_string_to_hints (string_list_t * hints, const char *str)
-{
-  char *scratch;
-  char *t;
-
-  if ((scratch = m_strdup(str)) == NULL)
-    return hints;
-
-  for (t = strtok (scratch, " ,.:\"()<>\n"); t;
-       t = strtok (NULL, " ,.:\"()<>\n")) {
-    if (m_strlen(t) > 3)
-      hints = mutt_add_list (hints, t);
-  }
-
-  p_delete(&scratch);
-  return hints;
-}
-
-static pgp_key_t *pgp_get_lastp (pgp_key_t p)
-{
-  for (; p; p = p->next)
-    if (!p->next)
-      return &p->next;
-
-  return NULL;
-}
-
-pgp_key_t pgp_getkeybyaddr (address_t * a, short abilities, pgp_ring_t keyring)
-{
-  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;
-
-  pgp_key_t keys, k, kn;
-  pgp_key_t the_valid_key = NULL;
-  pgp_key_t matches = NULL;
-  pgp_key_t *last = &matches;
-  pgp_uid_t *q;
-
-  if (a && a->mailbox)
-    hints = pgp_add_string_to_hints (hints, a->mailbox);
-  if (a && a->personal)
-    hints = pgp_add_string_to_hints (hints, a->personal);
-
-  mutt_message (_("Looking for keys matching \"%s\"..."), a->mailbox);
-  keys = pgp_get_candidates (keyring, hints);
-
-  string_list_wipe(&hints);
-
-  if (!keys)
-    return NULL;
-
-  for (k = keys; k; k = kn) {
-    kn = 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              */
-
-    for (q = k->address; q; q = q->next) {
-      r = rfc822_parse_adrlist (NULL, q->addr);
-
-      for (p = r; p; p = p->next) {
-        int validity = pgp_id_matches_addr (a, p, q);
-
-        if (validity & PGP_KV_MATCH)    /* something matches */
-          match = 1;
-
-        /* is this key a strong candidate? */
-        if ((validity & PGP_KV_VALID) && (validity & PGP_KV_STRONGID)
-            && (validity & PGP_KV_ADDR)) {
-          if (the_valid_key && the_valid_key != k)
-            multi = 1;
-          the_valid_key = k;
-          this_key_has_strong = 1;
-        }
-        else if ((validity & PGP_KV_MATCH) && !(validity & PGP_KV_VALID))
-          this_key_has_invalid = 1;
-        else if ((validity & PGP_KV_MATCH)
-                 && (!(validity & PGP_KV_STRONGID)
-                     || !(validity & PGP_KV_ADDR)))
-          this_key_has_weak = 1;
-      }
-
-      address_list_wipe(&r);
-    }
-
-    if (match && !this_key_has_strong && this_key_has_invalid)
-      invalid = 1;
-    if (match && !this_key_has_strong && this_key_has_weak)
-      weak = 1;
-
-    if (match) {
-      *last = pgp_principal_key (k);
-      kn = pgp_remove_key (&keys, *last);
-      last = pgp_get_lastp (k);
-    }
-  }
-
-  pgp_free_key (&keys);
-
-  if (matches) {
-    if (the_valid_key && !multi /* && !weak 
-                                   && !(invalid && option (OPTPGPSHOWUNUSABLE)) */ ) {
-      /*
-       * There was precisely one strong match on a valid ID.
-       * 
-       * Proceed without asking the user.
-       */
-      pgp_remove_key (&matches, the_valid_key);
-      pgp_free_key (&matches);
-      k = the_valid_key;
-    }
-    else {
-      /* 
-       * Else: Ask the user.
-       */
-      if ((k = pgp_select_key (matches, a, NULL)))
-        pgp_remove_key (&matches, k);
-      pgp_free_key (&matches);
-    }
-
-    return k;
-  }
-
-  return NULL;
-}
-
-pgp_key_t pgp_getkeybystr (const char *p, short abilities, pgp_ring_t keyring)
-{
-  string_list_t *hints = NULL;
-  pgp_key_t keys;
-  pgp_key_t matches = NULL;
-  pgp_key_t *last = &matches;
-  pgp_key_t k, kn;
-  pgp_uid_t *a;
-  short match;
-
-  mutt_message (_("Looking for keys matching \"%s\"..."), p);
-
-  hints = pgp_add_string_to_hints (hints, p);
-  keys = pgp_get_candidates (keyring, hints);
-  string_list_wipe(&hints);
-
-  if (!keys)
-    return NULL;
-
-
-  for (k = keys; k; k = kn) {
-    kn = k->next;
-    if (abilities && !(k->flags & abilities))
-      continue;
-
-    match = 0;
-
-    for (a = k->address; a; a = a->next) {
-      if (!*p || m_strcasecmp(p, pgp_keyid (k)) == 0
-          || (!m_strncasecmp(p, "0x", 2)
-              && !m_strcasecmp(p + 2, pgp_keyid (k)))
-          || (option (OPTPGPLONGIDS) && !m_strncasecmp(p, "0x", 2)
-              && !m_strcasecmp(p + 2, k->keyid + 8))
-          || m_stristr(a->addr, p)) {
-        match = 1;
-        break;
-      }
-    }
-
-    if (match) {
-      *last = pgp_principal_key (k);
-      kn = pgp_remove_key (&keys, *last);
-      last = pgp_get_lastp (k);
-    }
-  }
-
-  pgp_free_key (&keys);
-
-  if (matches) {
-    if ((k = pgp_select_key (matches, NULL, p)))
-      pgp_remove_key (&matches, k);
-
-    pgp_free_key (&matches);
-    return k;
-  }
-
-  return NULL;
-}
-