--locate-key now returns several keys if they all match.

This commit is contained in:
Werner Koch 2008-05-07 18:19:41 +00:00
parent 69ae16636c
commit 99361140a2
6 changed files with 82 additions and 23 deletions

View File

@ -1,11 +1,13 @@
2008-05-07 Werner Koch <wk@g10code.com>
* getkey.c (get_pubkey_byname): Fix nodefault case.
* gpg.c: New command --locate-keys. New options --with-sig-list
and --with-sig-check.
* keylist.c (locate_one): New.
(public_key_list): Add arg LOCATE_MODE and use locate_one.
* getkey.c (get_pubkey_byname): Fix nodefault case. Add option
RETCTX, change all callers.
(struct getkey_ctx_s): Add field extra_ptr;
(get_pubkey_end): Free it.
2008-04-18 Werner Koch <wk@g10code.com>

View File

@ -47,7 +47,8 @@ struct getkey_ctx_s {
int exact;
KBNODE keyblock;
KBPOS kbpos;
KBNODE found_key; /* pointer into some keyblock */
KBNODE found_key; /* Pointer into some keyblock. */
strlist_t *extra_list; /* Will be freed when releasing the context. */
int last_rc;
int req_usage;
int req_algo;
@ -917,7 +918,7 @@ key_byname( GETKEY_CTX *retctx, strlist_t namelist,
to import the key via the online mechanisms defined by
--auto-key-locate. */
int
get_pubkey_byname (PKT_public_key *pk,
get_pubkey_byname (GETKEY_CTX *retctx, PKT_public_key *pk,
const char *name, KBNODE *ret_keyblock,
KEYDB_HANDLE *ret_kdbhd, int include_unusable,
int no_akl)
@ -927,12 +928,22 @@ get_pubkey_byname (PKT_public_key *pk,
struct akl *akl;
int is_mbox;
int nodefault = 0;
int anylocalfirst = 0;
if (retctx)
*retctx = NULL;
is_mbox = is_valid_mailbox (name);
/* Check whether we the default local search has been disabled.
This is the case if either the "nodefault" or the "local" keyword
are in the list of auto key locate mechanisms. */
are in the list of auto key locate mechanisms.
ANYLOCALFIRST is set if the search order has the local method
before any other or if "local" is used first by default. This
makes sure that if a RETCTX is used it gets only set if a local
search has precedence over the other search methods and only then
a followup call to get_pubkey_next shall succeed. */
if (!no_akl)
{
for (akl=opt.auto_key_locate; akl; akl=akl->next)
@ -941,8 +952,18 @@ get_pubkey_byname (PKT_public_key *pk,
nodefault = 1;
break;
}
for (akl=opt.auto_key_locate; akl; akl=akl->next)
if (akl->type != AKL_NODEFAULT)
{
if (akl->type == AKL_LOCAL)
anylocalfirst = 1;
break;
}
}
if (!nodefault)
anylocalfirst = 1;
if (nodefault && is_mbox)
{
/* Nodefault but a mailbox - let the AKL locate the key. */
@ -951,7 +972,7 @@ get_pubkey_byname (PKT_public_key *pk,
else
{
add_to_strlist (&namelist, name);
rc = key_byname (NULL, namelist, pk, NULL, 0,
rc = key_byname (retctx, namelist, pk, NULL, 0,
include_unusable, ret_keyblock, ret_kdbhd);
}
@ -967,7 +988,7 @@ get_pubkey_byname (PKT_public_key *pk,
int no_fingerprint = 0;
const char *mechanism = "?";
switch(akl->type)
switch(akl->type)
{
case AKL_NODEFAULT:
/* This is a dummy mechanism. */
@ -978,8 +999,14 @@ get_pubkey_byname (PKT_public_key *pk,
case AKL_LOCAL:
mechanism = "Local";
did_key_byname = 1;
if (retctx)
{
get_pubkey_end (*retctx);
*retctx = NULL;
}
add_to_strlist (&namelist, name);
rc = key_byname (NULL, namelist, pk, NULL, 0,
rc = key_byname (anylocalfirst? retctx:NULL,
namelist, pk, NULL, 0,
include_unusable, ret_keyblock, ret_kdbhd);
break;
@ -1068,8 +1095,16 @@ get_pubkey_byname (PKT_public_key *pk,
fpr = NULL;
if (!rc && !did_key_byname)
rc = key_byname (NULL, namelist, pk, NULL, 0,
include_unusable, ret_keyblock, ret_kdbhd);
{
if (retctx)
{
get_pubkey_end (*retctx);
*retctx = NULL;
}
rc = key_byname (anylocalfirst?retctx:NULL,
namelist, pk, NULL, 0,
include_unusable, ret_keyblock, ret_kdbhd);
}
if (!rc)
{
/* Key found. */
@ -1084,10 +1119,24 @@ get_pubkey_byname (PKT_public_key *pk,
}
}
free_strlist( namelist );
if (rc && retctx)
{
get_pubkey_end (*retctx);
*retctx = NULL;
}
if (retctx && *retctx)
{
assert (!(*retctx)->extra_list);
(*retctx)->extra_list = namelist;
}
else
free_strlist (namelist);
return rc;
}
int
get_pubkey_bynames( GETKEY_CTX *retctx, PKT_public_key *pk,
strlist_t names, KBNODE *ret_keyblock )
@ -1113,6 +1162,7 @@ get_pubkey_end( GETKEY_CTX ctx )
if( ctx ) {
memset (&ctx->kbpos, 0, sizeof ctx->kbpos);
keydb_release (ctx->kr_handle);
free_strlist (ctx->extra_list);
if( !ctx->not_allocated )
xfree( ctx );
}

View File

@ -221,7 +221,7 @@ void getkey_disable_caches(void);
int get_pubkey( PKT_public_key *pk, u32 *keyid );
int get_pubkey_fast ( PKT_public_key *pk, u32 *keyid );
KBNODE get_pubkeyblock( u32 *keyid );
int get_pubkey_byname( PKT_public_key *pk, const char *name,
int get_pubkey_byname (GETKEY_CTX *rx, PKT_public_key *pk, const char *name,
KBNODE *ret_keyblock, KEYDB_HANDLE *ret_kdbhd,
int include_unusable, int no_akl );
int get_pubkey_bynames( GETKEY_CTX *rx, PKT_public_key *pk,

View File

@ -1544,7 +1544,7 @@ keyedit_menu( const char *username, strlist_t locusr,
#endif
/* Get the public key */
rc = get_pubkey_byname (NULL, username, &keyblock, &kdbhd, 1, 1);
rc = get_pubkey_byname (NULL, NULL, username, &keyblock, &kdbhd, 1, 1);
if( rc )
goto leave;
if( fix_keyblock( keyblock ) )
@ -3396,7 +3396,7 @@ menu_addrevoker( KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive )
GnuPG both can handle a designated revokation from a
subkey. */
revoker_pk->req_usage=PUBKEY_USAGE_CERT;
rc=get_pubkey_byname(revoker_pk,answer,NULL,NULL,1, 1);
rc=get_pubkey_byname (NULL, revoker_pk,answer,NULL,NULL,1, 1);
if(rc)
{
log_error (_("key \"%s\" not found: %s\n"),answer,g10_errstr(rc));

View File

@ -537,14 +537,15 @@ locate_one (strlist_t names)
{
int rc = 0;
strlist_t sl;
GETKEY_CTX ctx = NULL;
KBNODE keyblock = NULL;
struct sig_stats stats;
memset(&stats,0,sizeof(stats));
memset (&stats,0,sizeof(stats));
for (sl=names; sl; sl = sl->next)
{
rc = get_pubkey_byname (NULL, sl->d, &keyblock, NULL, 1, 0);
rc = get_pubkey_byname (&ctx, NULL, sl->d, &keyblock, NULL, 1, 0);
if (rc)
{
if (gpg_err_code (rc) != GPG_ERR_NO_PUBKEY)
@ -552,9 +553,15 @@ locate_one (strlist_t names)
}
else
{
list_keyblock (keyblock, 0, opt.fingerprint,
opt.check_sigs? &stats : NULL );
release_kbnode (keyblock);
do
{
list_keyblock (keyblock, 0, opt.fingerprint,
opt.check_sigs? &stats : NULL );
release_kbnode (keyblock);
}
while ( ctx && !get_pubkey_next (ctx, NULL, &keyblock));
get_pubkey_end (ctx);
ctx = NULL;
}
}

View File

@ -826,7 +826,7 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use )
/* We explicitly allow encrypt-to to an disabled key; thus
we pass 1for the second last argument and 1 as the last
argument to disable AKL. */
if ( (rc = get_pubkey_byname (pk, rov->d, NULL, NULL, 1, 1)) )
if ( (rc = get_pubkey_byname (NULL, pk, rov->d, NULL, NULL, 1, 1)) )
{
free_public_key ( pk ); pk = NULL;
log_error (_("%s: skipped: %s\n"), rov->d, g10_errstr(rc) );
@ -965,7 +965,7 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use )
free_public_key (pk);
pk = xmalloc_clear( sizeof *pk );
pk->req_usage = use;
rc = get_pubkey_byname( pk, answer, NULL, NULL, 0, 0 );
rc = get_pubkey_byname (NULL, pk, answer, NULL, NULL, 0, 0 );
if (rc)
tty_printf(_("No such user ID.\n"));
else if ( !(rc=openpgp_pk_test_algo2 (pk->pubkey_algo, use)) )
@ -1039,7 +1039,7 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use )
/* The default recipient is allowed to be disabled; thus pass 1
as second last argument. We also don't want an AKL. */
rc = get_pubkey_byname (pk, def_rec, NULL, NULL, 1, 1);
rc = get_pubkey_byname (NULL, pk, def_rec, NULL, NULL, 1, 1);
if (rc)
log_error(_("unknown default recipient \"%s\"\n"), def_rec );
else if ( !(rc=openpgp_pk_test_algo2(pk->pubkey_algo, use)) )
@ -1079,7 +1079,7 @@ build_pk_list( strlist_t rcpts, PK_LIST *ret_pk_list, unsigned int use )
pk = xmalloc_clear( sizeof *pk );
pk->req_usage = use;
if ( (rc = get_pubkey_byname( pk, remusr->d, NULL, NULL, 0, 0 )) )
if ((rc = get_pubkey_byname (NULL, pk, remusr->d, NULL, NULL, 0, 0)))
{
/* Key not found or other error. */
free_public_key( pk ); pk = NULL;