changeset: 6399:63ad7cf0d0de
user:      Eike Rathke <[email protected]>
date:      Sun Jan 18 17:45:41 2015 +0100
link:      http://dev.mutt.org/hg/mutt/rev/63ad7cf0d0de

Allow short and long key ID user input in pgp_getkeybystr()

The following did not work, e.g. when leaving a key list, and at the "Sign as"
or "Encrypt to" prompt attempting to enter a key ID:
* set pgp_long_ids=no
  * enter a long key ID, with or without leading 0x
* set pgp_long_ids=yes
  * enter a short key ID without leading 0x

Specifically entering a long key ID should always be possible as evil32.com
has shown.

This also cleans up the logic used to determine the matching condition, which
was quite convoluted.. it even slightly speeds up the loop as less string
operations are involved in the inner condition.

This only changes how the result obtained from the pgp_* command line
interface is filtered.

changeset: 6400:6e5a62946141
user:      Eike Rathke <[email protected]>
date:      Sun Jan 18 17:50:42 2015 +0100
link:      http://dev.mutt.org/hg/mutt/rev/6e5a62946141

Allow short and long key ID user input in crypt_getkeybystr()

The following did not work, e.g. when leaving a key list, and at the "Sign as"
or "Encrypt to" prompt attempting to enter a key ID:
* set pgp_long_ids=no
  * enter a long key ID, with or without leading 0x
* set pgp_long_ids=yes
  * enter a short key ID without leading 0x

Specifically entering a long key ID should always be possible as evil32.com
has shown.

This also cleans up the logic used to determine the matching condition, which
was quite convoluted.. it even slightly speeds up the loop as less string
operations are involved in the inner condition.

This only changes how the result obtained from the crypt_* gpgme interface is
filtered.

diffs (181 lines):

diff -r 58a9dbfd0d25 -r 6e5a62946141 crypt-gpgme.c
--- a/crypt-gpgme.c     Sat Jan 17 14:34:13 2015 -0800
+++ b/crypt-gpgme.c     Sun Jan 18 17:50:42 2015 +0100
@@ -179,6 +179,34 @@
   return s;
 }
 
+/* Return the long keyID for the key K. */
+static const char *crypt_long_keyid (crypt_key_t *k)
+{
+  const char *s = "????????????????";
+
+  if (k->kobj && k->kobj->subkeys)
+    {
+      s = k->kobj->subkeys->keyid;
+    }
+
+  return s;
+}
+
+/* Return the short keyID for the key K. */
+static const char *crypt_short_keyid (crypt_key_t *k)
+{
+  const char *s = "????????";
+
+  if (k->kobj && k->kobj->subkeys)
+    {
+      s = k->kobj->subkeys->keyid;
+      if (strlen (s) == 16)
+        s += 8;
+    }
+
+  return s;
+}
+
 /* Return the hexstring fingerprint from the key K. */
 static const char *crypt_fpr (crypt_key_t *k)
 {
@@ -4171,6 +4199,7 @@
   crypt_key_t *matches = NULL;
   crypt_key_t **matches_endp = &matches;
   crypt_key_t *k;
+  const char *ps, *pl;
 
   mutt_message (_("Looking for keys matching \"%s\"..."), p);
 
@@ -4182,6 +4211,19 @@
 
   if (!keys)
     return NULL;
+
+  /* User input may be short or long key ID, independent of OPTPGPLONGIDS.
+   * crypt_key_t->keyid should always contain a long key ID without 0x.
+   * Strip leading "0x" before loops so it doesn't have to be done over and
+   * over again, and prepare pl and ps to simplify logic in the loop's inner
+   * condition.
+   */
+  pl = (!mutt_strncasecmp (p, "0x", 2) ? p + 2 : p);
+  ps = (mutt_strlen (pl) == 16 ? pl + 8 : pl);
+
+  /* If ps != pl it means a long ID (or name of 16 characters) was given, do
+   * not attempt to match short IDs then. Also, it is unnecessary to try to
+   * match pl against long IDs if ps == pl as pl could not be a long ID. */
   
   for (k = keys; k; k = k->next)
     {
@@ -4189,15 +4231,11 @@
         continue;
 
       dprint (5, (debugfile, "crypt_getkeybystr: matching \"%s\" against "
-                  "key %s, \"%s\": ",  p, crypt_keyid (k), k->uid));
+                  "key %s, \"%s\": ",  p, crypt_long_keyid (k), k->uid));
 
       if (!*p
-          || !mutt_strcasecmp (p, crypt_keyid (k))
-          || (!mutt_strncasecmp (p, "0x", 2)
-              && !mutt_strcasecmp (p + 2, crypt_keyid (k)))
-          || (option (OPTPGPLONGIDS)
-              && !mutt_strncasecmp (p, "0x", 2) 
-              && !mutt_strcasecmp (p + 2, crypt_keyid (k) + 8))
+          || (ps != pl && mutt_strcasecmp (pl, crypt_long_keyid (k)) == 0)
+          || (ps == pl && mutt_strcasecmp (ps, crypt_short_keyid (k)) == 0)
           || mutt_stristr (k->uid, p))
         {
           crypt_key_t *tmp;
diff -r 58a9dbfd0d25 -r 6e5a62946141 pgp.c
--- a/pgp.c     Sat Jan 17 14:34:13 2015 -0800
+++ b/pgp.c     Sun Jan 18 17:50:42 2015 +0100
@@ -117,11 +117,32 @@
   return 1;
 }
 
-char *pgp_keyid(pgp_key_t k)
+static pgp_key_t _pgp_parent(pgp_key_t k)
 {
   if((k->flags & KEYFLAG_SUBKEY) && k->parent && option(OPTPGPIGNORESUB))
     k = k->parent;
 
+  return k;
+}
+
+char *pgp_long_keyid(pgp_key_t k)
+{
+  k = _pgp_parent(k);
+
+  return k->keyid;
+}
+
+char *pgp_short_keyid(pgp_key_t k)
+{
+  k = _pgp_parent(k);
+
+  return k->keyid + 8;
+}
+
+char *pgp_keyid(pgp_key_t k)
+{
+  k = _pgp_parent(k);
+
   return _pgp_keyid(k);
 }
 
diff -r 58a9dbfd0d25 -r 6e5a62946141 pgp.h
--- a/pgp.h     Sat Jan 17 14:34:13 2015 -0800
+++ b/pgp.h     Sun Jan 18 17:50:42 2015 +0100
@@ -35,6 +35,8 @@
 
 char *_pgp_keyid (pgp_key_t);
 char *pgp_keyid (pgp_key_t);
+char *pgp_short_keyid (pgp_key_t);
+char *pgp_long_keyid (pgp_key_t);
 
 
 int mutt_check_pgp (HEADER * h);
diff -r 58a9dbfd0d25 -r 6e5a62946141 pgpkey.c
--- a/pgpkey.c  Sat Jan 17 14:34:13 2015 -0800
+++ b/pgpkey.c  Sun Jan 18 17:50:42 2015 +0100
@@ -932,6 +932,7 @@
   pgp_uid_t *a;
   short match;
   size_t l;
+  const char *ps, *pl;
 
   if ((l = mutt_strlen (p)) && p[l-1] == '!')
     p[l-1] = 0;
@@ -945,6 +946,19 @@
   if (!keys)
     goto out;
 
+  /* User input may be short or long key ID, independent of OPTPGPLONGIDS.
+   * pgp_key_t->keyid should always contain a long key ID without 0x.
+   * Strip leading "0x" before loops so it doesn't have to be done over and
+   * over again, and prepare pl and ps to simplify logic in the loop's inner
+   * condition.
+   */
+  pl = (!mutt_strncasecmp (p, "0x", 2) ? p + 2 : p);
+  ps = (mutt_strlen (pl) == 16 ? pl + 8 : pl);
+
+  /* If ps != pl it means a long ID (or name of 16 characters) was given, do
+   * not attempt to match short IDs then. Also, it is unnecessary to try to
+   * match pl against long IDs if ps == pl as pl could not be a long ID. */
+
   for (k = keys; k; k = kn)
   {
     kn = k->next;
@@ -956,11 +970,10 @@
     for (a = k->address; a; a = a->next)
     {
       dprint (5, (debugfile, "pgp_getkeybystr: matching \"%s\" against key %s, 
\"%s\": ",
-                 p, pgp_keyid (k), NONULL (a->addr)));
-      if (!*p || mutt_strcasecmp (p, pgp_keyid (k)) == 0 ||
-         (!mutt_strncasecmp (p, "0x", 2) && !mutt_strcasecmp (p + 2, pgp_keyid 
(k))) ||
-         (option (OPTPGPLONGIDS) && !mutt_strncasecmp (p, "0x", 2) &&
-          !mutt_strcasecmp (p + 2, k->keyid + 8)) ||
+                  p, pgp_long_keyid (k), NONULL (a->addr)));
+      if (!*p ||
+          (ps != pl && mutt_strcasecmp (pl, pgp_long_keyid (k)) == 0) ||
+          (ps == pl && mutt_strcasecmp (ps, pgp_short_keyid (k)) == 0) ||
          mutt_stristr (a->addr, p))
       {
        dprint (5, (debugfile, "match.\n"));

Reply via email to