Hi Kevin,

On Sunday, 2015-01-18 13:29:12 -0800, Kevin J. McCarthy wrote:

> > +static pgp_key_t *_pgp_parent(pgp_key_t k)
> 
> This should be
>    static pgp_key_t _pgp_parent(pgp_key_t k)

Oops, yes, of course.
Attached is an amended patch.

> Otherwise, I think this patch looks good.  If there are no comments in a
> few days, I will push this.

Thanks
  Eike

-- 
OpenPGP/GnuPG encrypted mail preferred in all private communication.
Key "ID" 0x65632D3A - 2265 D7F3 A7B0 95CC 3918  630B 6A6C D5B7 6563 2D3A
Better use 64-bit 0x6A6CD5B765632D3A here is why: https://evil32.com/
Care about Free Software, support the FSFE https://fsfe.org/support/?erack
Use LibreOffice! https://www.libreoffice.org/
# HG changeset patch
# User Eike Rathke <er...@erack.de>
# Date 1421599541 -3600
# Node ID aa1783ebf072af28d136308d360758fcf93137d3
# Parent  cc790394468778ced239dc4d3245199cf3bd551e
allow short and long key ID user input in any pgp_long_ids mode for pgp_*

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.

diff --git a/pgp.c b/pgp.c
--- a/pgp.c
+++ b/pgp.c
@@ -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 --git a/pgp.h b/pgp.h
--- a/pgp.h
+++ b/pgp.h
@@ -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 --git a/pgpkey.c b/pgpkey.c
--- a/pgpkey.c
+++ b/pgpkey.c
@@ -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"));

Attachment: signature.asc
Description: Digital signature

Reply via email to