[svn] GnuPG - r5220 - in trunk: . agent common g10 kbx sm

svn author wk cvs at cvs.gnupg.org
Tue Dec 8 17:30:34 CET 2009


Author: wk
Date: 2009-12-08 17:30:33 +0100 (Tue, 08 Dec 2009)
New Revision: 5220

Added:
   trunk/common/userids.c
   trunk/common/userids.h
Modified:
   trunk/NEWS
   trunk/agent/ChangeLog
   trunk/agent/protect.c
   trunk/common/ChangeLog
   trunk/common/Makefile.am
   trunk/common/dns-cert.c
   trunk/g10/ChangeLog
   trunk/g10/delkey.c
   trunk/g10/export.c
   trunk/g10/getkey.c
   trunk/g10/gpg.h
   trunk/g10/keydb.h
   trunk/g10/keyring.h
   trunk/g10/keyserver.c
   trunk/g10/packet.h
   trunk/g10/pkclist.c
   trunk/g10/revoke.c
   trunk/g10/trustdb.c
   trunk/kbx/ChangeLog
   trunk/kbx/keybox-search-desc.h
   trunk/kbx/keybox-search.c
   trunk/sm/ChangeLog
   trunk/sm/certlist.c
   trunk/sm/delete.c
   trunk/sm/export.c
   trunk/sm/import.c
   trunk/sm/keydb.c
   trunk/sm/keydb.h
   trunk/sm/keylist.c
   trunk/sm/sign.c
Log:
Unification of the search descriptor usage.


[The diff below has been truncated]

Modified: trunk/agent/ChangeLog
===================================================================
--- trunk/agent/ChangeLog	2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/agent/ChangeLog	2009-12-08 16:30:33 UTC (rev 5220)
@@ -1,3 +1,7 @@
+2009-12-08  Werner Koch  <wk at g10code.com>
+
+	* protect.c (agent_unprotect): Avoid compiler warning.
+
 2009-12-08  Marcus Brinkmann  <marcus at g10code.de>
 
 	* call-pinentry.c (start_pinentry): Convert posix fd to assuan fd.

Modified: trunk/common/ChangeLog
===================================================================
--- trunk/common/ChangeLog	2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/common/ChangeLog	2009-12-08 16:30:33 UTC (rev 5220)
@@ -1,11 +1,14 @@
 2009-12-08  Werner Koch  <wk at g10code.com>
 
+	* userids.h, userids.c: New.
+	(classify_user_id): Merged from similar fucntions in sm/ and g10/.
+
 	* dns-cert.c (get_dns_cert): Add support for ADNS.
 
 2009-12-08  Marcus Brinkmann  <marcus at g10code.de>
 
 	* asshelp.c (start_new_gpg_agent): Convert posix FD to assuan FD.
-	
+
 	* asshelp.c (start_new_gpg_agent) [HAVE_W32_SYSTEM]: Add missing
 	argument in assuan_socket_connect invocation.
 	* iobuf.c (iobuf_open_fd_or_name): Fix type of FD in function

Modified: trunk/g10/ChangeLog
===================================================================
--- trunk/g10/ChangeLog	2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/g10/ChangeLog	2009-12-08 16:30:33 UTC (rev 5220)
@@ -1,3 +1,23 @@
+2009-12-08  Werner Koch  <wk at g10code.com>
+
+	* keyring.h: Include userids.h. 
+	* gpg.h (KEYDB_SEARCH_DESC): Remove.
+	* packet.h: Include userids.h.
+	(PKT_user_id): Declare using gpg_pkt_user_id_s.
+	* keydb.h (KeydbSearchMode, struct keydb_search_desc): Remove.  We
+	now use those in ../kbx.
+	* getkey.c (classify_user_id): Remove.  It is now in common/.
+	(key_byname): Adjust for changed classify_user_id.
+	* delkey.c (do_delete_key): Ditto.
+	* trustdb.c (register_trusted_key): Ditto.
+	* revoke.c (gen_desig_revoke, gen_revoke): Ditto.
+	* keyserver.c (parse_keyrec, keyserver_export, keyserver_import)
+	(keyidlist): Ditto.
+	* export.c (do_export_stream): Ditto.
+
+	* pkclist.c (find_and_check_key): Replace GPG_ERR_INV_NAME by
+	GPG_ERR_INV_USER_ID.
+
 2009-12-04  Werner Koch  <wk at g10code.com>
 
 	* keygen.c (DEFAULT_STD_ALGO, DEFAULT_STD_KEYSIZE): New.

Modified: trunk/kbx/ChangeLog
===================================================================
--- trunk/kbx/ChangeLog	2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/kbx/ChangeLog	2009-12-08 16:30:33 UTC (rev 5220)
@@ -1,3 +1,11 @@
+2009-12-08  Werner Koch  <wk at g10code.com>
+
+	* keybox-search-desc.h (keydb_search_desc): Use u32 type for
+	KID. Extend the skip function ptr.
+	(gpg_pkt_user_id_t): New.
+	* keybox-search.c (has_short_kid, has_long_kid): Change to use u32
+	args for KID.
+
 2008-12-09  Werner Koch  <wk at g10code.com>
 
 	* kbxutil.c (main): Call i18n_init before init_common_subsystems.

Modified: trunk/sm/ChangeLog
===================================================================
--- trunk/sm/ChangeLog	2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/sm/ChangeLog	2009-12-08 16:30:33 UTC (rev 5220)
@@ -1,3 +1,12 @@
+2009-12-08  Werner Koch  <wk at g10code.com>
+
+	* keydb.c (keydb_search_kid): Fix code even that it is not used.
+	(classify_user_id): Adjust for change of u.kid type.
+	(keydb_classify_name): Replace GPG_ERR_INV_NAME by
+	GPG_ERR_INV_USER_ID.
+	(keydb_classify_name): Remove.  Replace all callers by
+	classify_user_id.
+
 2009-12-08  Marcus Brinkmann  <marcus at g10code.de>
 
 	* call-dirmngr.c (start_dirmngr_ext): Convert posix fd to assuan fd.

Modified: trunk/NEWS
===================================================================
--- trunk/NEWS	2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/NEWS	2009-12-08 16:30:33 UTC (rev 5220)
@@ -14,7 +14,7 @@
  * Numerical values may now be used as an alternative to the
    debug-level keywords.
 
- * Support SRV and PKA records on W32.
+ * Support DNS lookups for SRV, PKA and CERT on W32.
 
 
 Noteworthy changes in version 2.0.13 (2009-09-04)

Modified: trunk/agent/protect.c
===================================================================
--- trunk/agent/protect.c	2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/agent/protect.c	2009-12-08 16:30:33 UTC (rev 5220)
@@ -775,6 +775,7 @@
   if (!n)
     return gpg_error (GPG_ERR_INV_SEXP); 
   
+  cleartext = NULL; /* Avoid cc warning. */
   rc = do_decryption (s, n,
                       passphrase, s2ksalt, s2kcount,
                       iv, 16,

Modified: trunk/common/Makefile.am
===================================================================
--- trunk/common/Makefile.am	2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/common/Makefile.am	2009-12-08 16:30:33 UTC (rev 5220)
@@ -70,6 +70,7 @@
 	http.c http.h \
 	localename.c \
 	session-env.c session-env.h \
+	userids.c userids.h \
 	helpfile.c
 
 # Sources only useful without PTH.

Modified: trunk/common/dns-cert.c
===================================================================
--- trunk/common/dns-cert.c	2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/common/dns-cert.c	2009-12-08 16:30:33 UTC (rev 5220)
@@ -1,5 +1,5 @@
 /* dns-cert.c - DNS CERT code
- * Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+ * Copyright (C) 2005, 2006, 2009 Free Software Foundation, Inc.
  *
  * This file is part of GNUPG.
  *

Added: trunk/common/userids.c
===================================================================
--- trunk/common/userids.c	                        (rev 0)
+++ trunk/common/userids.c	2009-12-08 16:30:33 UTC (rev 5220)
@@ -0,0 +1,322 @@
+/* userids.c - Utility functions for user ids.
+ * Copyright (C) 2001, 2003, 2004, 2006,
+ *               2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* This file implements a few utility functions useful when working
+   with canonical encrypted S-expresions (i.e. not the S-exprssion
+   objects from libgcrypt).  */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "util.h"
+#include "userids.h"
+
+
+/* Parse the user-id NAME and build a search description for it.
+ * Returns 0 on succdess or an error code.  DESC may be NULL to merely
+ * check the validity of a user-id.
+ *
+ * Some used rules:
+ * - If the username starts with 8,9,16 or 17 hex-digits (the first one
+ *   must be in the range 0..9), this is considered a keyid; depending
+ *   on the length a short or complete one.
+ * - If the username starts with 32,33,40 or 41 hex-digits (the first one
+ *   must be in the range 0..9), this is considered a fingerprint.
+ * - If the username starts with a left angle, we assume it is a complete
+ *   email address and look only at this part.
+ * - If the username starts with a colon we assume it is a unified 
+ *   key specfification. 
+ * - If the username starts with a '.', we assume it is the ending
+ *   part of an email address
+ * - If the username starts with an '@', we assume it is a part of an
+ *   email address
+ * - If the userid start with an '=' an exact compare is done.
+ * - If the userid starts with a '*' a case insensitive substring search is
+ *   done (This is the default).
+ * - If the userid starts with a '+' we will compare individual words
+ *   and a match requires that all the words are in the userid.
+ *   Words are delimited by white space or "()<>[]{}. at -+_,;/&!"
+ *   (note that you can't search for these characters). Compare
+ *   is not case sensitive.
+ * - If the userid starts with a '&' a 40 hex digits keygrip is expected.
+ */
+
+gpg_error_t
+classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc)
+{
+  const char *s;
+  int hexprefix = 0;
+  int hexlength;
+  int mode = 0;   
+  KEYDB_SEARCH_DESC dummy_desc;
+
+  if (!desc)
+    desc = &dummy_desc;
+    
+  /* Clear the structure so that the mode field is set to zero unless
+     we set it to the correct value right at the end of this
+     function. */
+  memset (desc, 0, sizeof *desc);
+
+  /* Skip leading spaces.  */
+  for(s = name; *s && spacep (s); s++ )
+    ;
+
+  switch (*s) 
+    {
+    case 0:  /* Empty string is an error.  */
+      return gpg_error (GPG_ERR_INV_USER_ID);
+
+    case '.': /* An email address, compare from end.  Note that this
+                 has not yet been implemented in the search code.  */
+      mode = KEYDB_SEARCH_MODE_MAILEND;
+      s++;
+      desc->u.name = s;
+      break;
+
+    case '<': /* An email address.  */
+      mode = KEYDB_SEARCH_MODE_MAIL;
+      s++;
+      desc->u.name = s;
+      break;
+
+    case '@':  /* Part of an email address.  */
+      mode = KEYDB_SEARCH_MODE_MAILSUB;
+      s++;
+      desc->u.name = s;
+      break;
+
+    case '=':  /* Exact compare.  */
+      mode = KEYDB_SEARCH_MODE_EXACT;
+      s++;
+      desc->u.name = s;
+      break;
+
+    case '*':  /* Case insensitive substring search.  */
+      mode = KEYDB_SEARCH_MODE_SUBSTR;
+      s++;
+      desc->u.name = s;
+      break;
+
+    case '+':  /* Compare individual words.  Note that this has not
+                  yet been implemented in the search code.  */
+      mode = KEYDB_SEARCH_MODE_WORDS;
+      s++;
+      desc->u.name = s;
+      break;
+
+    case '/': /* Subject's DN.  */
+      s++;
+      if (!*s || spacep (s)) /* No DN or prefixed with a space.  */
+        return gpg_error (GPG_ERR_INV_USER_ID);
+      desc->u.name = s;
+      mode = KEYDB_SEARCH_MODE_SUBJECT;
+      break;
+
+    case '#': /* S/N with optional issuer id or just issuer id.  */
+      { 
+        const char *si;
+        
+        s++;
+        if ( *s == '/')
+          { /* "#/" indicates an issuer's DN.  */
+            s++;
+            if (!*s || spacep (s)) /* No DN or prefixed with a space.  */
+              return gpg_error (GPG_ERR_INV_USER_ID); 
+            desc->u.name = s;
+            mode = KEYDB_SEARCH_MODE_ISSUER;
+          }
+        else 
+          { /* Serialnumber + optional issuer ID.  */
+            for (si=s; *si && *si != '/'; si++)
+              {
+                 /* Check for an invalid digit in the serial number. */
+                if (!strchr("01234567890abcdefABCDEF", *si))
+                  return gpg_error (GPG_ERR_INV_USER_ID);
+              }
+            desc->sn = (const unsigned char*)s;
+            desc->snlen = -1;
+            if (!*si)
+              mode = KEYDB_SEARCH_MODE_SN;
+            else
+              {
+                s = si+1;
+                if (!*s || spacep (s))  /* No DN or prefixed with a space.  */
+                  return gpg_error (GPG_ERR_INV_USER_ID);
+                desc->u.name = s;
+                mode = KEYDB_SEARCH_MODE_ISSUER_SN;
+              }
+          }
+      }
+      break;
+
+    case ':': /* Unified fingerprint. */
+      {  
+        const char *se, *si;
+        int i;
+        
+        se = strchr (++s,':');
+        if (!se)
+          return gpg_error (GPG_ERR_INV_USER_ID);
+        for (i=0,si=s; si < se; si++, i++ )
+          {
+            if (!strchr("01234567890abcdefABCDEF", *si))
+              return gpg_error (GPG_ERR_INV_USER_ID); /* Invalid digit.  */
+          }
+        if (i != 32 && i != 40)
+          return gpg_error (GPG_ERR_INV_USER_ID); /* Invalid length of fpr.  */
+        for (i=0,si=s; si < se; i++, si +=2) 
+          desc->u.fpr[i] = hextobyte(si);
+        for (; i < 20; i++)
+          desc->u.fpr[i]= 0;
+        s = se + 1;
+        mode = KEYDB_SEARCH_MODE_FPR;
+      } 
+      break;
+
+    case '&': /* Keygrip*/
+      {  
+        if (hex2bin (s+1, desc->u.grip, 20) < 0)
+          return gpg_error (GPG_ERR_INV_USER_ID); /* Invalid. */
+        mode = KEYDB_SEARCH_MODE_KEYGRIP;
+      } 
+      break;
+
+    default:
+      if (s[0] == '0' && s[1] == 'x')
+        {
+          hexprefix = 1;
+          s += 2;
+        }
+
+      hexlength = strspn(s, "0123456789abcdefABCDEF");
+      if (hexlength >= 8 && s[hexlength] =='!')
+        {
+          desc->exact = 1;
+          hexlength++; /* Just for the following check.  */
+        }
+      
+      /* Check if a hexadecimal number is terminated by EOS or blank.  */
+      if (hexlength && s[hexlength] && !spacep (s+hexlength)) 
+        {
+          if (hexprefix) /* A "0x" prefix without a correct
+                            termination is an error.  */
+            return gpg_error (GPG_ERR_INV_USER_ID); 
+          /* The first characters looked like a hex number, but the
+             entire string is not.  */
+          hexlength = 0;  
+        }
+      
+      if (desc->exact)
+        hexlength--; /* Remove the bang.  */
+
+      if (hexlength == 8
+          || (!hexprefix && hexlength == 9 && *s == '0'))
+        { 
+          /* Short keyid.  */
+          if (hexlength == 9)
+            s++; 
+          desc->u.kid[1] = strtoul( s, NULL, 16 );
+          mode = KEYDB_SEARCH_MODE_SHORT_KID;
+        }
+      else if (hexlength == 16
+               || (!hexprefix && hexlength == 17 && *s == '0'))
+        { 
+          /* Long keyid.  */
+          char buf[9];
+          if (hexlength == 17)
+            s++;
+          mem2str (buf, s, 9);
+          desc->u.kid[0] = strtoul (buf, NULL, 16);
+          desc->u.kid[1] = strtoul (s+8, NULL, 16);
+          mode = KEYDB_SEARCH_MODE_LONG_KID;
+        }
+      else if (hexlength == 32
+               || (!hexprefix && hexlength == 33 && *s == '0'))
+        { 
+          /* MD5 fingerprint.  */
+          int i;
+          if (hexlength == 33)
+            s++;
+          memset (desc->u.fpr+16, 0, 4); 
+          for (i=0; i < 16; i++, s+=2) 
+            {
+              int c = hextobyte(s);
+              if (c == -1)
+                return gpg_error (GPG_ERR_INV_USER_ID);
+              desc->u.fpr[i] = c;
+            }
+          mode = KEYDB_SEARCH_MODE_FPR16;
+        }
+      else if (hexlength == 40
+               || (!hexprefix && hexlength == 41 && *s == '0'))
+        { 
+          /* SHA1/RMD160 fingerprint.  */
+          int i;
+          if (hexlength == 41)
+            s++;
+          for (i=0; i < 20; i++, s+=2) 
+            {
+              int c = hextobyte(s);
+              if (c == -1)
+                return gpg_error (GPG_ERR_INV_USER_ID);
+              desc->u.fpr[i] = c;
+            }
+          mode = KEYDB_SEARCH_MODE_FPR20;
+        }
+      else if (!hexprefix)
+        { 
+          /* The fingerprint in an X.509 listing is often delimited by
+             colons, so we try to single this case out. */
+          mode = 0;
+          hexlength = strspn (s, ":0123456789abcdefABCDEF");
+          if (hexlength == 59 && (!s[hexlength] || spacep (s+hexlength))) 
+            {
+              int i;
+
+              for (i=0; i < 20; i++, s += 3) 
+                {
+                  int c = hextobyte(s);
+                  if (c == -1 || (i < 19 && s[2] != ':'))
+                    break;
+                  desc->u.fpr[i] = c;
+                }
+              if (i == 20)
+                mode = KEYDB_SEARCH_MODE_FPR20;
+            }
+          if (!mode) /* Default to substring search.  */
+            { 
+              desc->exact = 0;
+              desc->u.name = s;
+              mode = KEYDB_SEARCH_MODE_SUBSTR; 
+            }
+        }
+      else
+	{ 
+          /* Hex number with a prefix but with a wrong length.  */
+          return gpg_error (GPG_ERR_INV_USER_ID);
+        }
+    }
+  
+  desc->mode = mode;
+  return 0;
+}

Added: trunk/common/userids.h
===================================================================
--- trunk/common/userids.h	                        (rev 0)
+++ trunk/common/userids.h	2009-12-08 16:30:33 UTC (rev 5220)
@@ -0,0 +1,28 @@
+/* userids.h - Utility functions for user ids.
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GNUPG_COMMON_USERIDS_H
+#define GNUPG_COMMON_USERIDS_H
+
+#include "../kbx/keybox-search-desc.h"
+
+gpg_error_t classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc);
+
+
+#endif /*GNUPG_COMMON_USERIDS_H*/

Modified: trunk/g10/delkey.c
===================================================================
--- trunk/g10/delkey.c	2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/g10/delkey.c	2009-12-08 16:30:33 UTC (rev 5220)
@@ -63,12 +63,13 @@
 
     *r_sec_avail = 0;
 
-    /* search the userid */
-    classify_user_id (username, &desc);
+    /* Search the userid */
+    rc = classify_user_id (username, &desc);
     exactmatch = (desc.mode == KEYDB_SEARCH_MODE_FPR
                   || desc.mode == KEYDB_SEARCH_MODE_FPR16
                   || desc.mode == KEYDB_SEARCH_MODE_FPR20);
-    rc = desc.mode? keydb_search (hd, &desc, 1):G10ERR_INV_USER_ID;
+    if (!rc)
+      rc = keydb_search (hd, &desc, 1);
     if (rc) {
 	log_error (_("key \"%s\" not found: %s\n"), username, g10_errstr (rc));
 	write_status_text( STATUS_DELETE_PROBLEM, "1" );

Modified: trunk/g10/export.c
===================================================================
--- trunk/g10/export.c	2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/g10/export.c	2009-12-08 16:30:33 UTC (rev 5220)
@@ -293,6 +293,7 @@
 		  KBNODE *keyblock_out, unsigned int options, int *any )
 {
     int rc = 0;
+    gpg_error_t err;
     PACKET pkt;
     KBNODE keyblock = NULL;
     KBNODE kbctx, node;
@@ -318,11 +319,11 @@
         desc = xmalloc ( ndesc * sizeof *desc);
         
         for (ndesc=0, sl=users; sl; sl = sl->next) {
-	    if (classify_user_id (sl->d, desc+ndesc))
+            if (!(err=classify_user_id (sl->d, desc+ndesc)))
                 ndesc++;
             else
                 log_error (_("key \"%s\" not found: %s\n"),
-                           sl->d, g10_errstr (G10ERR_INV_USER_ID));
+                           sl->d, gpg_strerror (err));
         }
 
         /* It would be nice to see which of the given users did

Modified: trunk/g10/getkey.c
===================================================================
--- trunk/g10/getkey.c	2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/g10/getkey.c	2009-12-08 16:30:33 UTC (rev 5220)
@@ -536,229 +536,7 @@
 }
 
 
-/****************
- * Return the type of the user id:
- *
- * Please use the constants KEYDB_SERCH_MODE_xxx
- *  0 = Invalid user ID
- *  1 = exact match
- *  2 = match a substring
- *  3 = match an email address
- *  4 = match a substring of an email address
- *  5 = match an email address, but compare from end
- *  6 = word match mode
- * 10 = it is a short KEYID (don't care about keyid[0])
- * 11 = it is a long  KEYID
- * 12 = it is a trustdb index (keyid is looked up)
- * 16 = it is a 16 byte fingerprint
- * 20 = it is a 20 byte fingerprint
- * 21 = Unified fingerprint :fpr:pk_algo:
- *      (We don't use pk_algo yet)
- *
- * Rules used:
- * - If the username starts with 8,9,16 or 17 hex-digits (the first one
- *   must be in the range 0..9), this is considered a keyid; depending
- *   on the length a short or complete one.
- * - If the username starts with 32,33,40 or 41 hex-digits (the first one
- *   must be in the range 0..9), this is considered a fingerprint.
- * - If the username starts with a left angle, we assume it is a complete
- *   email address and look only at this part.
- * - If the username starts with a colon we assume it is a unified 
- *   key specfification. 
- * - If the username starts with a '.', we assume it is the ending
- *   part of an email address
- * - If the username starts with an '@', we assume it is a part of an
- *   email address
- * - If the userid start with an '=' an exact compare is done.
- * - If the userid starts with a '*' a case insensitive substring search is
- *   done (This is the default).
- * - If the userid starts with a '+' we will compare individual words
- *   and a match requires that all the words are in the userid.
- *   Words are delimited by white space or "()<>[]{}. at -+_,;/&!"
- *   (note that you can't search for these characters). Compare
- *   is not case sensitive.
- * - If the userid starts with a '&' a 40 hex digits keygrip is expected.
- */
 
-int
-classify_user_id( const char *name, KEYDB_SEARCH_DESC *desc )
-{
-    const char *s;
-    int hexprefix = 0;
-    int hexlength;
-    int mode = 0;   
-    KEYDB_SEARCH_DESC dummy_desc;
-
-    if (!desc)
-        desc = &dummy_desc;
-
-    /* clear the structure so that the mode field is set to zero unless
-     * we set it to the correct value right at the end of this function */
-    memset (desc, 0, sizeof *desc);
-
-    /* skip leading spaces.  Fixme: what is with trailing spaces? */
-    for(s = name; *s && spacep (s); s++ )
-	;
-
-    switch (*s) {
-	case 0:    /* empty string is an error */
-	    return 0;
-
-#if 0
-	case '.':  /* an email address, compare from end */
-	    mode = KEYDB_SEARCH_MODE_MAILEND;
-	    s++;
-            desc->u.name = s;
-	    break;
-#endif
-
-	case '<':  /* an email address */
-	    mode = KEYDB_SEARCH_MODE_MAIL;
-            desc->u.name = s;
-	    break;
-
-	case '@':  /* part of an email address */
-	    mode = KEYDB_SEARCH_MODE_MAILSUB;
-	    s++;
-            desc->u.name = s;
-	    break;
-
-	case '=':  /* exact compare */
-	    mode = KEYDB_SEARCH_MODE_EXACT;
-	    s++;
-            desc->u.name = s;
-	    break;
-
-	case '*':  /* case insensitive substring search */
-	    mode = KEYDB_SEARCH_MODE_SUBSTR;
-	    s++;
-            desc->u.name = s;
-	    break;
-
-#if 0
-	case '+':  /* compare individual words */
-	    mode = KEYDB_SEARCH_MODE_WORDS;
-	    s++;
-            desc->u.name = s;
-	    break;
-#endif
-
-	case '#':  /* local user id */
-            return 0; /* This is now obsolete and can't not be used anymore*/
-        
-        case ':': /*Unified fingerprint */
-            {  
-                const char *se, *si;
-                int i;
-                
-                se = strchr( ++s,':');
-                if ( !se )
-                    return 0;
-                for (i=0,si=s; si < se; si++, i++ ) {
-                    if ( !strchr("01234567890abcdefABCDEF", *si ) )
-                        return 0; /* invalid digit */
-                }
-                if (i != 32 && i != 40)
-                    return 0; /* invalid length of fpr*/
-                for (i=0,si=s; si < se; i++, si +=2) 
-                    desc->u.fpr[i] = hextobyte(si);
-                for ( ; i < 20; i++)
-                    desc->u.fpr[i]= 0;
-                s = se + 1;
-                mode = KEYDB_SEARCH_MODE_FPR;
-            } 
-            break;
-           
-	case '&':  /* keygrip */
-          return 0; /* Not yet implememted. */
-
-	default:
-	    if (s[0] == '0' && s[1] == 'x') {
-		hexprefix = 1;
-		s += 2;
-	    }
-
-	    hexlength = strspn(s, "0123456789abcdefABCDEF");
-            if (hexlength >= 8 && s[hexlength] =='!') {
-		desc->exact = 1;
-                hexlength++; /* just for the following check */
-            }
-
-	    /* check if a hexadecimal number is terminated by EOS or blank */
-	    if (hexlength && s[hexlength] && !spacep(s+hexlength)) {
-		if (hexprefix)	    /* a "0x" prefix without correct */
-		    return 0;	    /* termination is an error */
-		else		    /* The first chars looked like */
-		    hexlength = 0;  /* a hex number, but really were not. */
-	    }
-
-            if (desc->exact)
-                hexlength--;
-
-	    if (hexlength == 8
-                || (!hexprefix && hexlength == 9 && *s == '0')){
-		/* short keyid */
-		if (hexlength == 9)
-		    s++;
-                desc->u.kid[0] = 0;
-                desc->u.kid[1] = strtoul( s, NULL, 16 );
-		mode = KEYDB_SEARCH_MODE_SHORT_KID;
-	    }
-	    else if (hexlength == 16
-                     || (!hexprefix && hexlength == 17 && *s == '0')) {
-		/* complete keyid */
-		char buf[9];
-		if (hexlength == 17)
-		    s++;
-		mem2str(buf, s, 9 );
-		desc->u.kid[0] = strtoul( buf, NULL, 16 );
-		desc->u.kid[1] = strtoul( s+8, NULL, 16 );
-		mode = KEYDB_SEARCH_MODE_LONG_KID;
-	    }
-	    else if (hexlength == 32 || (!hexprefix && hexlength == 33
-							    && *s == '0')) {
-		/* md5 fingerprint */
-		int i;
-		if (hexlength == 33)
-		    s++;
-                memset(desc->u.fpr+16, 0, 4); 
-                for (i=0; i < 16; i++, s+=2) {
-                    int c = hextobyte(s);
-                    if (c == -1)
-                        return 0;
-                    desc->u.fpr[i] = c;
-                }
-		mode = KEYDB_SEARCH_MODE_FPR16;
-	    }
-	    else if (hexlength == 40 || (!hexprefix && hexlength == 41
-							      && *s == '0')) {
-		/* sha1/rmd160 fingerprint */
-		int i;
-		if (hexlength == 41)
-		    s++;
-                for (i=0; i < 20; i++, s+=2) {
-                    int c = hextobyte(s);
-                    if (c == -1)
-                        return 0;
-                    desc->u.fpr[i] = c;
-                }
-		mode = KEYDB_SEARCH_MODE_FPR20;
-	    }
-	    else {
-		if (hexprefix)	/* This was a hex number with a prefix */
-		    return 0;	/* and a wrong length */
-
-		desc->exact = 0;
-                desc->u.name = s;
-		mode = KEYDB_SEARCH_MODE_SUBSTR;   /* default mode */
-	    }
-    }
-
-    desc->mode = mode;
-    return mode;
-}
-
-
 static int
 skip_unusable (void *dummy, u32 *keyid, PKT_user_id *uid)
 {
@@ -851,14 +629,16 @@
 
 	for(n=0, r=namelist; r; r = r->next, n++ )
 	  {
-	    classify_user_id (r->d, &ctx->items[n]);
+            gpg_error_t err;
+
+	    err = classify_user_id (r->d, &ctx->items[n]);
         
 	    if (ctx->items[n].exact)
 	      ctx->exact = 1;
-	    if (!ctx->items[n].mode)
+	    if (err)
 	      {
 		xfree (ctx);
-		return G10ERR_INV_USER_ID;
+		return gpg_err_code (err); /* FIXME: remove gpg_err_code.  */
 	      }
 	    if(!include_unusable
 	       && ctx->items[n].mode!=KEYDB_SEARCH_MODE_SHORT_KID

Modified: trunk/g10/gpg.h
===================================================================
--- trunk/g10/gpg.h	2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/g10/gpg.h	2009-12-08 16:30:33 UTC (rev 5220)
@@ -50,11 +50,8 @@
 
 /* Object used to describe a keyblok node.  */
 typedef struct kbnode_struct *KBNODE;
-/* Object used for looking ob keys.  */
-typedef struct keydb_search_desc KEYDB_SEARCH_DESC;
 
 
-
 /* Session control object.  This object is passed to most functions to
    convey the status of a session.  Note that the defaults are set by
    gpg_init_default_ctrl(). */

Modified: trunk/g10/keydb.h
===================================================================
--- trunk/g10/keydb.h	2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/g10/keydb.h	2009-12-08 16:30:33 UTC (rev 5220)
@@ -115,36 +115,7 @@
 
 typedef struct keydb_handle *KEYDB_HANDLE;
 
-typedef enum {
-    KEYDB_SEARCH_MODE_NONE,
-    KEYDB_SEARCH_MODE_EXACT,
-    KEYDB_SEARCH_MODE_SUBSTR,
-    KEYDB_SEARCH_MODE_MAIL,
-    KEYDB_SEARCH_MODE_MAILSUB,
-    KEYDB_SEARCH_MODE_MAILEND,
-    KEYDB_SEARCH_MODE_WORDS,
-    KEYDB_SEARCH_MODE_SHORT_KID,
-    KEYDB_SEARCH_MODE_LONG_KID,
-    KEYDB_SEARCH_MODE_FPR16,
-    KEYDB_SEARCH_MODE_FPR20,
-    KEYDB_SEARCH_MODE_FPR,
-    KEYDB_SEARCH_MODE_FIRST,
-    KEYDB_SEARCH_MODE_NEXT
-} KeydbSearchMode;
 
-struct keydb_search_desc {
-    KeydbSearchMode mode;
-    int (*skipfnc)(void *,u32*,PKT_user_id*);
-    void *skipfncvalue;
-    union {
-        const char *name;
-        byte fpr[MAX_FINGERPRINT_LEN];
-        u32  kid[2];
-    } u;
-    int exact;
-};
-
-
 /* Helper type for preference fucntions. */
 union pref_hint
 {
@@ -221,7 +192,6 @@
 void next_to_last_passphrase(void);
 
 /*-- getkey.c --*/
-int classify_user_id( const char *name, KEYDB_SEARCH_DESC *desc);
 void cache_public_key( PKT_public_key *pk );
 void getkey_disable_caches(void);
 int get_pubkey( PKT_public_key *pk, u32 *keyid );

Modified: trunk/g10/keyring.h
===================================================================
--- trunk/g10/keyring.h	2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/g10/keyring.h	2009-12-08 16:30:33 UTC (rev 5220)
@@ -20,6 +20,7 @@
 #ifndef GPG_KEYRING_H
 #define GPG_KEYRING_H 1
 
+#include "../common/userids.h"
 
 typedef struct keyring_handle *KEYRING_HANDLE;
 

Modified: trunk/g10/keyserver.c
===================================================================
--- trunk/g10/keyserver.c	2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/g10/keyserver.c	2009-12-08 16:30:33 UTC (rev 5220)
@@ -46,6 +46,7 @@
 #include "srv.h"
 #endif
 
+
 #ifdef HAVE_W32_SYSTEM
 /* It seems Vista doesn't grok X_OK and so fails access() tests.
    Previous versions interpreted X_OK as F_OK anyway, so we'll just
@@ -595,6 +596,7 @@
   if(ascii_strcasecmp("pub",record)==0)
     {
       char *tok;
+      gpg_error_t err;
 
       if(work->desc.mode)
 	{
@@ -606,11 +608,11 @@
       if((tok=strsep(&keystring,":"))==NULL)
 	return ret;
 
-      classify_user_id(tok,&work->desc);
-      if(work->desc.mode!=KEYDB_SEARCH_MODE_SHORT_KID
-	 && work->desc.mode!=KEYDB_SEARCH_MODE_LONG_KID
-	 && work->desc.mode!=KEYDB_SEARCH_MODE_FPR16
-	 && work->desc.mode!=KEYDB_SEARCH_MODE_FPR20)
+      err = classify_user_id (tok, &work->desc);
+      if (err || (work->desc.mode    != KEYDB_SEARCH_MODE_SHORT_KID
+                  && work->desc.mode != KEYDB_SEARCH_MODE_LONG_KID
+                  && work->desc.mode != KEYDB_SEARCH_MODE_FPR16
+                  && work->desc.mode != KEYDB_SEARCH_MODE_FPR20))
 	{
 	  work->desc.mode=KEYDB_SEARCH_MODE_NONE;
 	  return ret;
@@ -1598,6 +1600,7 @@
 int 
 keyserver_export(strlist_t users)
 {
+  gpg_error_t err;
   strlist_t sl=NULL;
   KEYDB_SEARCH_DESC desc;
   int rc=0;
@@ -1605,11 +1608,11 @@
   /* Weed out descriptors that we don't support sending */
   for(;users;users=users->next)
     {
-      classify_user_id (users->d, &desc);
-      if(desc.mode!=KEYDB_SEARCH_MODE_SHORT_KID &&
-	 desc.mode!=KEYDB_SEARCH_MODE_LONG_KID &&
-	 desc.mode!=KEYDB_SEARCH_MODE_FPR16 &&
-	 desc.mode!=KEYDB_SEARCH_MODE_FPR20)
+      err = classify_user_id (users->d, &desc);
+      if (err || (desc.mode    != KEYDB_SEARCH_MODE_SHORT_KID
+                  && desc.mode != KEYDB_SEARCH_MODE_LONG_KID
+                  && desc.mode != KEYDB_SEARCH_MODE_FPR16
+                  && desc.mode != KEYDB_SEARCH_MODE_FPR20))
 	{
 	  log_error(_("\"%s\" not a key ID: skipping\n"),users->d);
 	  continue;
@@ -1630,6 +1633,7 @@
 int 
 keyserver_import(strlist_t users)
 {
+  gpg_error_t err;
   KEYDB_SEARCH_DESC *desc;
   int num=100,count=0;
   int rc=0;
@@ -1639,13 +1643,13 @@
 
   for(;users;users=users->next)
     {
-      classify_user_id (users->d, &desc[count]);
-      if(desc[count].mode!=KEYDB_SEARCH_MODE_SHORT_KID &&
-	 desc[count].mode!=KEYDB_SEARCH_MODE_LONG_KID &&
-	 desc[count].mode!=KEYDB_SEARCH_MODE_FPR16 &&
-	 desc[count].mode!=KEYDB_SEARCH_MODE_FPR20)
+      err = classify_user_id (users->d, &desc[count]);
+      if (err || (desc[count].mode    != KEYDB_SEARCH_MODE_SHORT_KID
+                  && desc[count].mode != KEYDB_SEARCH_MODE_LONG_KID
+                  && desc[count].mode != KEYDB_SEARCH_MODE_FPR16
+                  && desc[count].mode != KEYDB_SEARCH_MODE_FPR20))
 	{
-	  log_error(_("\"%s\" not a key ID: skipping\n"),users->d);
+	  log_error (_("\"%s\" not a key ID: skipping\n"), users->d);
 	  continue;
 	}
 
@@ -1731,11 +1735,12 @@
         
       for (ndesc=0, sl=users; sl; sl = sl->next)
 	{
-	  if(classify_user_id (sl->d, desc+ndesc))
+          gpg_error_t err; 
+	  if (!(err = classify_user_id (sl->d, desc+ndesc)))
 	    ndesc++;
 	  else
 	    log_error (_("key \"%s\" not found: %s\n"),
-		       sl->d, g10_errstr (G10ERR_INV_USER_ID));
+		       sl->d, gpg_strerror (err));
 	}
     }
 

Modified: trunk/g10/packet.h
===================================================================
--- trunk/g10/packet.h	2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/g10/packet.h	2009-12-08 16:30:33 UTC (rev 5220)
@@ -27,6 +27,7 @@
 #include "cipher.h"
 #include "filter.h"
 #include "../common/openpgpdefs.h"
+#include "../common/userids.h"
 
 #define DEBUG_PARSE_PACKET 1
 
@@ -151,14 +152,16 @@
 
 #define ATTRIB_IMAGE 1
 
-/* This is the cooked form of attributes */
+/* This is the cooked form of attributes.  */
 struct user_attribute {
   byte type;
   const byte *data;
   u32 len;
 };
 
-typedef struct
+
+/* (See also keybox-search-desc.h) */
+struct gpg_pkt_user_id_s
 {
   int ref;              /* reference counter */
   int len;	        /* length of the name */
@@ -181,13 +184,16 @@
   struct
   {
     /* TODO: Move more flags here */
-    unsigned mdc:1;
-    unsigned ks_modify:1;
-    unsigned compacted:1;
+    unsigned int mdc:1;
+    unsigned int ks_modify:1;
+    unsigned int compacted:1;
   } flags;
   char name[1];
-} PKT_user_id;
+};
+typedef struct gpg_pkt_user_id_s PKT_user_id;
 
+
+
 struct revoke_info
 {
   /* revoked at this date */

Modified: trunk/g10/pkclist.c
===================================================================
--- trunk/g10/pkclist.c	2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/g10/pkclist.c	2009-12-08 16:30:33 UTC (rev 5220)
@@ -787,7 +787,7 @@
   int trustlevel;
 
   if (!name || !*name)
-    return gpg_error (GPG_ERR_INV_NAME);
+    return gpg_error (GPG_ERR_INV_USER_ID);
 
   pk = xtrycalloc (1, sizeof *pk);
   if (!pk)

Modified: trunk/g10/revoke.c
===================================================================
--- trunk/g10/revoke.c	2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/g10/revoke.c	2009-12-08 16:30:33 UTC (rev 5220)
@@ -220,8 +220,9 @@
     afx = new_armor_context ();
 
     kdbhd = keydb_new (0);
-    classify_user_id (uname, &desc);
-    rc = desc.mode? keydb_search (kdbhd, &desc, 1) : G10ERR_INV_USER_ID;
+    rc = classify_user_id (uname, &desc);
+    if (!rc)
+      rc = keydb_search (kdbhd, &desc, 1);
     if (rc) {
 	log_error (_("key \"%s\" not found: %s\n"),uname, g10_errstr (rc));
 	goto leave;
@@ -463,8 +464,9 @@
      * We don't want the whole getkey stuff here but the entire keyblock
      */
     kdbhd = keydb_new (1);
-    classify_user_id (uname, &desc);
-    rc = desc.mode? keydb_search (kdbhd, &desc, 1) : G10ERR_INV_USER_ID;
+    rc = classify_user_id (uname, &desc);
+    if (!rc)
+      rc = keydb_search (kdbhd, &desc, 1);
     if (rc)
       {
 	log_error (_("secret key \"%s\" not found: %s\n"),

Modified: trunk/g10/trustdb.c
===================================================================
--- trunk/g10/trustdb.c	2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/g10/trustdb.c	2009-12-08 16:30:33 UTC (rev 5220)
@@ -214,9 +214,11 @@
 void
 register_trusted_key( const char *string )
 {
+  gpg_error_t err;
   KEYDB_SEARCH_DESC desc;
 
-  if (classify_user_id (string, &desc) != KEYDB_SEARCH_MODE_LONG_KID )
+  err = classify_user_id (string, &desc);
+  if (err || desc.mode != KEYDB_SEARCH_MODE_LONG_KID )
     {
       log_error(_("`%s' is not a valid long keyID\n"), string );
       return;

Modified: trunk/kbx/keybox-search-desc.h
===================================================================
--- trunk/kbx/keybox-search-desc.h	2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/kbx/keybox-search-desc.h	2009-12-08 16:30:33 UTC (rev 5220)
@@ -48,24 +48,31 @@
   KEYDB_SEARCH_MODE_NEXT
 } KeydbSearchMode;
 
-struct keydb_search_desc {
+
+/* Forwward declaration.  See g10/packet.h.  */
+struct gpg_pkt_user_id_s;
+typedef struct gpg_pkt_user_id_s *gpg_pkt_user_id_t;
+
+/* A search descriptor.  */
+struct keydb_search_desc 
+{
   KeydbSearchMode mode;
-  int (*skipfnc)(void *,void*); /* used to be: void*, u32* */
+  int (*skipfnc)(void *, u32 *, gpg_pkt_user_id_t); 
   void *skipfncvalue;
   const unsigned char *sn; 
   int snlen;  /* -1 := sn is a hex string */
   union {
     const char *name;
     unsigned char fpr[24];
-    unsigned char kid[8]; 
+    u32 kid[2]; /* Note that this is in native endianess.  */
     unsigned char grip[20];
   } u;
+  int exact;    /* Use exactly this key ('!' suffix in gpg).  */
 };
 
 
 struct keydb_search_desc;
 typedef struct keydb_search_desc KEYDB_SEARCH_DESC;
-
 typedef struct keydb_search_desc KEYBOX_SEARCH_DESC;
 
 

Modified: trunk/kbx/keybox-search.c
===================================================================
--- trunk/kbx/keybox-search.c	2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/kbx/keybox-search.c	2009-12-08 16:30:33 UTC (rev 5220)
@@ -530,15 +530,29 @@
   The has_foo functions are used as helpers for search 
 */
 static inline int
-has_short_kid (KEYBOXBLOB blob, const unsigned char *kid)
+has_short_kid (KEYBOXBLOB blob, u32 lkid)
 {
-  return blob_cmp_fpr_part (blob, kid+4, 16, 4);
+  unsigned char buf[4];
+  buf[0] = lkid >> 24;
+  buf[1] = lkid >> 16;
+  buf[2] = lkid >> 8;
+  buf[3] = lkid;
+  return blob_cmp_fpr_part (blob, buf, 16, 4);
 }
 
 static inline int
-has_long_kid (KEYBOXBLOB blob, const unsigned char *kid)
+has_long_kid (KEYBOXBLOB blob, u32 mkid, u32 lkid)
 {
-  return blob_cmp_fpr_part (blob, kid, 12, 8);
+  unsigned char buf[8];
+  buf[0] = mkid >> 24;
+  buf[1] = mkid >> 16;
+  buf[2] = mkid >> 8;
+  buf[3] = mkid;
+  buf[4] = lkid >> 24;
+  buf[5] = lkid >> 16;
+  buf[6] = lkid >> 8;
+  buf[7] = lkid;
+  return blob_cmp_fpr_part (blob, buf, 12, 8);
 }
 
 static inline int
@@ -877,11 +891,11 @@
                 goto found;
               break;
             case KEYDB_SEARCH_MODE_SHORT_KID: 
-              if (has_short_kid (blob, desc[n].u.kid))
+              if (has_short_kid (blob, desc[n].u.kid[1]))
                 goto found;
               break;
             case KEYDB_SEARCH_MODE_LONG_KID:
-              if (has_long_kid (blob, desc[n].u.kid))
+              if (has_long_kid (blob, desc[n].u.kid[0], desc[n].u.kid[1]))
                 goto found;
               break;
             case KEYDB_SEARCH_MODE_FPR:
@@ -909,7 +923,7 @@
       for (n=any_skip?0:ndesc; n < ndesc; n++) 
         {
 /*            if (desc[n].skipfnc */
-/*                && desc[n].skipfnc (desc[n].skipfncvalue, aki)) */
+/*                && desc[n].skipfnc (desc[n].skipfncvalue, aki, NULL)) */
 /*              break; */
         }
       if (n == ndesc)

Modified: trunk/sm/certlist.c
===================================================================
--- trunk/sm/certlist.c	2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/sm/certlist.c	2009-12-08 16:30:33 UTC (rev 5220)
@@ -301,7 +301,7 @@
   KEYDB_HANDLE kh = NULL;
   ksba_cert_t cert = NULL;
 
-  rc = keydb_classify_name (name, &desc);
+  rc = classify_user_id (name, &desc);
   if (!rc)
     {
       kh = keydb_new (0);
@@ -480,7 +480,7 @@
   KEYDB_HANDLE kh = NULL;
 
   *r_cert = NULL;
-  rc = keydb_classify_name (name, &desc);
+  rc = classify_user_id (name, &desc);
   if (!rc)
     {
       kh = keydb_new (0);

Modified: trunk/sm/delete.c
===================================================================
--- trunk/sm/delete.c	2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/sm/delete.c	2009-12-08 16:30:33 UTC (rev 5220)
@@ -45,7 +45,7 @@
   int duplicates = 0;
   int is_ephem = 0;
   
-  rc = keydb_classify_name (username, &desc);
+  rc = classify_user_id (username, &desc);
   if (rc)
     {
       log_error (_("certificate `%s' not found: %s\n"),

Modified: trunk/sm/export.c
===================================================================
--- trunk/sm/export.c	2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/sm/export.c	2009-12-08 16:30:33 UTC (rev 5220)
@@ -180,7 +180,7 @@
     {
       for (ndesc=0, sl=names; sl; sl = sl->next) 
         {
-          rc = keydb_classify_name (sl->d, desc+ndesc);
+          rc = classify_user_id (sl->d, desc+ndesc);
           if (rc)
             {
               log_error ("key `%s' not found: %s\n",
@@ -359,7 +359,7 @@
       goto leave;
     }
 
-  rc = keydb_classify_name (name, desc);
+  rc = classify_user_id (name, desc);
   if (rc)
     {
       log_error ("key `%s' not found: %s\n",

Modified: trunk/sm/import.c
===================================================================
--- trunk/sm/import.c	2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/sm/import.c	2009-12-08 16:30:33 UTC (rev 5220)
@@ -452,7 +452,7 @@
     
       stats->count++;
 
-      err = keydb_classify_name (line, &desc);
+      err = classify_user_id (line, &desc);
       if (err)
         {
           print_import_problem (ctrl, NULL, 0);

Modified: trunk/sm/keydb.c
===================================================================
--- trunk/sm/keydb.c	2009-12-08 12:43:27 UTC (rev 5219)
+++ trunk/sm/keydb.c	2009-12-08 16:30:33 UTC (rev 5220)
@@ -949,8 +949,8 @@
   
   memset (&desc, 0, sizeof desc);
   desc.mode = KEYDB_SEARCH_MODE_LONG_KID;
-/*    desc.u.kid[0] = kid[0]; */
-/*    desc.u.kid[1] = kid[1]; */
+  desc.u.kid[0] = kid[0];
+  desc.u.kid[1] = kid[1];
   return keydb_search (hd, &desc, 1);
 }
 
@@ -1016,284 +1016,6 @@
 }
 
 
-static int
-classify_user_id (const char *name, 
-                  KEYDB_SEARCH_DESC *desc,
-                  int *force_exact )
-{
-  const char *s;
-  int hexprefix = 0;
-  int hexlength;
-  int mode = 0;   
-    
-  /* clear the structure so that the mode field is set to zero unless
-   * we set it to the correct value right at the end of this function */
-  memset (desc, 0, sizeof *desc);
-  *force_exact = 0;
-  /* Skip leading spaces.  Fixme: what about trailing white space? */
-  for(s = name; *s && spacep (s); s++ )
-    ;
-
-  switch (*s) 
-    {
-    case 0:  /* empty string is an error */
-      return 0;
-
-    case '.': /* an email address, compare from end */
-      mode = KEYDB_SEARCH_MODE_MAILEND;
-      s++;
-      desc->u.name = s;
-      break;
-
-    case '<': /* an email address */
-      mode = KEYDB_SEARCH_MODE_MAIL;
-      s++;
-      desc->u.name = s;
-      break;
-
-    case '@':  /* part of an email address */
-      mode = KEYDB_SEARCH_MODE_MAILSUB;
-      s++;
-      desc->u.name = s;
-      break;
-
-    case '=':  /* exact compare */
-      mode = KEYDB_SEARCH_MODE_EXACT;
-      s++;
-      desc->u.name = s;
-      break;
-
-    case '*':  /* case insensitive substring search */
-      mode = KEYDB_SEARCH_MODE_SUBSTR;
-      s++;
-      desc->u.name = s;
-      break;
-
-    case '+':  /* compare individual words */
-      mode = KEYDB_SEARCH_MODE_WORDS;
-      s++;
-      desc->u.name = s;
-      break;
-
-    case '/': /* subject's DN */
-      s++;
-      if (!*s || spacep (s))
-        return 0; /* no DN or prefixed with a space */
-      desc->u.name = s;
-      mode = KEYDB_SEARCH_MODE_SUBJECT;
-      break;
-
-    case '#':
-      { 
-        const char *si;
-        
-        s++;
-        if ( *s == '/')
-          { /* "#/" indicates an issuer's DN */
-            s++;
-            if (!*s || spacep (s))
-              return 0; /* no DN or prefixed with a space */
-            desc->u.name = s;
-            mode = KEYDB_SEARCH_MODE_ISSUER;
-          }
-        else 
-          { /* serialnumber + optional issuer ID */
-            for (si=s; *si && *si != '/'; si++)
-              {
-                if (!strchr("01234567890abcdefABCDEF", *si))
-                  return 0; /* invalid digit in serial number*/
-              }
-            desc->sn = (const unsigned char*)s;
-            desc->snlen = -1;
-            if (!*si)
-              mode = KEYDB_SEARCH_MODE_SN;
-            else
-              {
-                s = si+1;
-                if (!*s || spacep (s))
-                  return 0; /* no DN or prefixed with a space */
-                desc->u.name = s;
-                mode = KEYDB_SEARCH_MODE_ISSUER_SN;
-              }
-          }
-      }
-      break;
-
-    case ':': /*Unified fingerprint */
-      {  
-        const char *se, *si;
-        int i;
-        
-        se = strchr (++s,':');
-        if (!se)
-          return 0;
-        for (i=0,si=s; si < se; si++, i++ )
-          {
-            if (!strchr("01234567890abcdefABCDEF", *si))
-              return 0; /* invalid digit */
-          }
-        if (i != 32 && i != 40)
-          return 0; /* invalid length of fpr*/
-        for (i=0,si=s; si < se; i++, si +=2) 
-          desc->u.fpr[i] = hextobyte(si);
-        for (; i < 20; i++)
-          desc->u.fpr[i]= 0;
-        s = se + 1;
-        mode = KEYDB_SEARCH_MODE_FPR;
-      } 
-      break;
-
-    case '&': /* Keygrip*/
-      {  
-        if (hex2bin (s+1, desc->u.grip, 20) < 0)
-          return 0; /* Invalid. */
-        mode = KEYDB_SEARCH_MODE_KEYGRIP;
-      } 
-      break;
-
-    default:
-      if (s[0] == '0' && s[1] == 'x')
-        {
-          hexprefix = 1;
-          s += 2;
-        }
-
-      hexlength = strspn(s, "0123456789abcdefABCDEF");
-      if (hexlength >= 8 && s[hexlength] =='!')
-        {
-          *force_exact = 1;
-          hexlength++; /* just for the following check */
-        }
-      
-      /* check if a hexadecimal number is terminated by EOS or blank */
-      if (hexlength && s[hexlength] && !spacep (s+hexlength)) 
-        {
-          if (hexprefix) /* a "0x" prefix without correct */
-            return 0;	 /* termination is an error */
-          /* The first chars looked like a hex number, but really is
-             not */
-          hexlength = 0;  
-        }
-      
-      if (*force_exact)
-        hexlength--; /* remove the bang */
-
-      if (hexlength == 8
-          || (!hexprefix && hexlength == 9 && *s == '0'))
-        { /* short keyid */
-          unsigned long kid;
-          if (hexlength == 9)
-            s++;
-          kid = strtoul( s, NULL, 16 );
-          desc->u.kid[4] = kid >> 24; 
-          desc->u.kid[5] = kid >> 16; 
-          desc->u.kid[6] = kid >>  8; 
-          desc->u.kid[7] = kid; 
-          mode = KEYDB_SEARCH_MODE_SHORT_KID;
-        }
-      else if (hexlength == 16
-               || (!hexprefix && hexlength == 17 && *s == '0'))
-        { /* complete keyid */
-          unsigned long kid0, kid1;
-          char buf[9];
-          if (hexlength == 17)
-            s++;
-          mem2str(buf, s, 9 );
-          kid0 = strtoul (buf, NULL, 16);
-          kid1 = strtoul (s+8, NULL, 16);
-          desc->u.kid[0] = kid0 >> 24; 
-          desc->u.kid[1] = kid0 >> 16; 
-          desc->u.kid[2] = kid0 >>  8; 
-          desc->u.kid[3] = kid0; 
-          desc->u.kid[4] = kid1 >> 24; 
-          desc->u.kid[5] = kid1 >> 16; 
-          desc->u.kid[6] = kid1 >>  8; 
-          desc->u.kid[7] = kid1; 
-          mode = KEYDB_SEARCH_MODE_LONG_KID;
-        }
-      else if (hexlength == 32
-               || (!hexprefix && hexlength == 33 && *s == '0'))
-        { /* md5 fingerprint */
-          int i;
-          if (hexlength == 33)
-            s++;
-          memset(desc->u.fpr+16, 0, 4); 
-          for (i=0; i < 16; i++, s+=2) 
-            {
-              int c = hextobyte(s);
-              if (c == -1)
-                return 0;
-              desc->u.fpr[i] = c;
-            }
-          mode = KEYDB_SEARCH_MODE_FPR16;
-        }
-      else if (hexlength == 40
-               || (!hexprefix && hexlength == 41 && *s == '0'))
-        { /* sha1/rmd160 fingerprint */
-          int i;
-          if (hexlength == 41)
-            s++;
-          for (i=0; i < 20; i++, s+=2) 
-            {
-              int c = hextobyte(s);
-              if (c == -1)
-                return 0;
-              desc->u.fpr[i] = c;
-            }
-          mode = KEYDB_SEARCH_MODE_FPR20;
-        }
-      else if (!hexprefix)
-        { 
-          /* The fingerprint in an X.509 listing is often delimited by
-             colons, so we try to single this case out. */
-          mode = 0;
-          hexlength = strspn (s, ":0123456789abcdefABCDEF");
-          if (hexlength == 59 && (!s[hexlength] || spacep (s+hexlength))) 
-            {
-              int i;
-
-              for (i=0; i < 20; i++, s += 3) 
-                {
-                  int c = hextobyte(s);
-                  if (c == -1 || (i < 19 && s[2] != ':'))
-                    break;
-                  desc->u.fpr[i] = c;
-                }
-              if (i == 20)
-                mode = KEYDB_SEARCH_MODE_FPR20;
-            }
-          if (!mode) /* default is substring search */
-            { 
-              *force_exact = 0;
-              desc->u.name = s;
-              mode = KEYDB_SEARCH_MODE_SUBSTR; 
-            }
-        }
-      else
-	{ /* hex number with a prefix but a wrong length */
-          return 0;
-        }
-    }
-  
-  desc->mode = mode;
-  return mode;
-}
-
-
-int
-keydb_classify_name (const char *name, KEYDB_SEARCH_DESC *desc)
-{
-  int dummy;
-  KEYDB_SEARCH_DESC dummy_desc;
-
-  if (!desc)
-    desc = &dummy_desc;
-
-  if (!classify_user_id (name, desc, &dummy))
-    return gpg_error (GPG_ERR_INV_NAME);
-  return 0;
-}
-
 
 /* Store the certificate in the key DB but make sure that it does not
    already exists.  We do this simply by comparing the fingerprint.
@@ -1483,7 +1205,7 @@
     {
       for (ndesc=0, sl=names; sl; sl = sl->next) 
         {
-          rc = keydb_classify_name (sl->d, desc+ndesc);




More information about the Gnupg-commits mailing list