gpg: Add push/pop found state feature to keydb.

* g10/keydb.c (keydb_handle): Add field saved_found.
(keydb_new): Init new field.
(keydb_push_found_state, keydb_pop_found_state): New.
* g10/keyring.c (kyring_handle): Add field saved_found.
(keyring_push_found_state, keyring_pop_found_state): New.
--

We have the same feature in gpgsm.  It is very useful to check for an
unambiguous user id with a follow up update of the keyblock.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2015-05-08 15:51:11 +02:00
parent b772e459fa
commit 3c439c0447
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
4 changed files with 88 additions and 5 deletions

View File

@ -1,7 +1,6 @@
/* keydb.c - key database dispatcher /* keydb.c - key database dispatcher
* Copyright (C) 2001, 2002, 2003, 2004, 2005, * Copyright (C) 2001-2013 Free Software Foundation, Inc.
* 2008, 2009, 2011, 2013 Free Software Foundation, Inc. * Coyrright (C) 2001-2015 Werner Koch
* Coyrright (C) 2013 Werner Koch
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -67,6 +66,7 @@ struct keydb_handle
{ {
int locked; int locked;
int found; int found;
int saved_found;
unsigned long skipped_long_blobs; unsigned long skipped_long_blobs;
int no_caching; int no_caching;
int current; int current;
@ -542,6 +542,7 @@ keydb_new (void)
hd = xmalloc_clear (sizeof *hd); hd = xmalloc_clear (sizeof *hd);
hd->found = -1; hd->found = -1;
hd->saved_found = -1;
assert (used_resources <= MAX_KEYDB_RESOURCES); assert (used_resources <= MAX_KEYDB_RESOURCES);
for (i=j=0; i < used_resources; i++) for (i=j=0; i < used_resources; i++)
@ -741,6 +742,64 @@ unlock_all (KEYDB_HANDLE hd)
} }
/* Push the last found state if any. */
void
keydb_push_found_state (KEYDB_HANDLE hd)
{
if (!hd)
return;
if (hd->found < 0 || hd->found >= hd->used)
{
hd->saved_found = -1;
return;
}
switch (hd->active[hd->found].type)
{
case KEYDB_RESOURCE_TYPE_NONE:
break;
case KEYDB_RESOURCE_TYPE_KEYRING:
keyring_push_found_state (hd->active[hd->found].u.kr);
break;
case KEYDB_RESOURCE_TYPE_KEYBOX:
keybox_push_found_state (hd->active[hd->found].u.kb);
break;
}
hd->saved_found = hd->found;
hd->found = -1;
}
/* Pop the last found state. */
void
keydb_pop_found_state (KEYDB_HANDLE hd)
{
if (!hd)
return;
hd->found = hd->saved_found;
hd->saved_found = -1;
if (hd->found < 0 || hd->found >= hd->used)
return;
switch (hd->active[hd->found].type)
{
case KEYDB_RESOURCE_TYPE_NONE:
break;
case KEYDB_RESOURCE_TYPE_KEYRING:
keyring_pop_found_state (hd->active[hd->found].u.kr);
break;
case KEYDB_RESOURCE_TYPE_KEYBOX:
keybox_pop_found_state (hd->active[hd->found].u.kb);
break;
}
}
static gpg_error_t static gpg_error_t
parse_keyblock_image (iobuf_t iobuf, int pk_no, int uid_no, parse_keyblock_image (iobuf_t iobuf, int pk_no, int uid_no,
const u32 *sigstatus, kbnode_t *r_keyblock) const u32 *sigstatus, kbnode_t *r_keyblock)

View File

@ -136,6 +136,8 @@ gpg_error_t keydb_add_resource (const char *url, unsigned int flags);
KEYDB_HANDLE keydb_new (void); KEYDB_HANDLE keydb_new (void);
void keydb_release (KEYDB_HANDLE hd); void keydb_release (KEYDB_HANDLE hd);
void keydb_disable_caching (KEYDB_HANDLE hd); void keydb_disable_caching (KEYDB_HANDLE hd);
void keydb_push_found_state (KEYDB_HANDLE hd);
void keydb_pop_found_state (KEYDB_HANDLE hd);
const char *keydb_get_resource_name (KEYDB_HANDLE hd); const char *keydb_get_resource_name (KEYDB_HANDLE hd);
gpg_error_t keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb); gpg_error_t keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb);
gpg_error_t keydb_update_keyblock (KEYDB_HANDLE hd, kbnode_t kb); gpg_error_t keydb_update_keyblock (KEYDB_HANDLE hd, kbnode_t kb);

View File

@ -1,5 +1,6 @@
/* keyring.c - keyring file handling /* keyring.c - keyring file handling
* Copyright (C) 2001, 2004, 2009, 2010 Free Software Foundation, Inc. * Copyright (C) 1998-2010 Free Software Foundation, Inc.
* Copyright (C) 1997-2015 Werner Koch
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -83,7 +84,7 @@ struct keyring_handle
size_t pk_no; size_t pk_no;
size_t uid_no; size_t uid_no;
unsigned int n_packets; /*used for delete and update*/ unsigned int n_packets; /*used for delete and update*/
} found; } found, saved_found;
struct { struct {
char *name; char *name;
char *pattern; char *pattern;
@ -279,6 +280,25 @@ keyring_release (KEYRING_HANDLE hd)
} }
/* Save the current found state in HD for later retrieval by
keybox_pop_found_state. Only one state may be saved. */
void
keyring_push_found_state (KEYRING_HANDLE hd)
{
hd->saved_found = hd->found;
hd->found.kr = NULL;
}
/* Restore the saved found state in HD. */
void
keyring_pop_found_state (KEYRING_HANDLE hd)
{
hd->found = hd->saved_found;
hd->saved_found.kr = NULL;
}
const char * const char *
keyring_get_resource_name (KEYRING_HANDLE hd) keyring_get_resource_name (KEYRING_HANDLE hd)
{ {

View File

@ -29,6 +29,8 @@ int keyring_is_writable (void *token);
KEYRING_HANDLE keyring_new (void *token); KEYRING_HANDLE keyring_new (void *token);
void keyring_release (KEYRING_HANDLE hd); void keyring_release (KEYRING_HANDLE hd);
void keyring_push_found_state (KEYRING_HANDLE hd);
void keyring_pop_found_state (KEYRING_HANDLE hd);
const char *keyring_get_resource_name (KEYRING_HANDLE hd); const char *keyring_get_resource_name (KEYRING_HANDLE hd);
int keyring_lock (KEYRING_HANDLE hd, int yes); int keyring_lock (KEYRING_HANDLE hd, int yes);
int keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb); int keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb);