mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
Unification of the search descriptor usage.
This commit is contained in:
parent
bb861ac730
commit
9a96043be4
32 changed files with 501 additions and 599 deletions
230
g10/getkey.c
230
g10/getkey.c
|
@ -536,228 +536,6 @@ seckey_available( u32 *keyid )
|
|||
}
|
||||
|
||||
|
||||
/****************
|
||||
* 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 "()<>[]{}.@-+_,;/&!"
|
||||
* (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 @@ key_byname( GETKEY_CTX *retctx, strlist_t namelist,
|
|||
|
||||
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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue