mirror of
git://git.gnupg.org/gnupg.git
synced 2025-07-02 22:46:30 +02:00
* keybox.h (keybox_flag_t): New.
* keybox-search.c (get_flag_from_image, keybox_get_flags): New. (_keybox_get_flag_location): New. * certchain.c (gpgsm_validate_chain): Mark revoked certs in the keybox. * keylist.c (list_cert_colon): New arg VALIDITY; use it to print a revoked flag. (list_internal_keys): Retrieve validity flag. (list_external_cb): Pass 0 as validity flag. * keydb.c (keydb_get_flags, keydb_set_flags): New. (keydb_set_cert_flags): New. (lock_all): Return a proper error code. (keydb_lock): New. (keydb_delete): Don't lock but check that it has been locked. (keydb_update_keyblock): Ditto. * delete.c (delete_one): Take a lock.
This commit is contained in:
parent
bdae155c7b
commit
5bda9a8e74
12 changed files with 439 additions and 30 deletions
160
sm/keydb.c
160
sm/keydb.c
|
@ -1,5 +1,5 @@
|
|||
/* keydb.c - key database dispatcher
|
||||
* Copyright (C) 2001, 2003 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc.
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
|
@ -373,6 +373,21 @@ keydb_set_ephemeral (KEYDB_HANDLE hd, int yes)
|
|||
}
|
||||
|
||||
|
||||
/* If the keyring has not yet been locked, lock it now. This
|
||||
operation is required before any update opeations; it is optionaly
|
||||
for an insert operation. The lock is released with
|
||||
keydb_released. */
|
||||
gpg_error_t
|
||||
keydb_lock (KEYDB_HANDLE hd)
|
||||
{
|
||||
if (!hd)
|
||||
return gpg_error (GPG_ERR_INV_HANDLE);
|
||||
if (hd->locked)
|
||||
return 0; /* Already locked. */
|
||||
return lock_all (hd);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
lock_all (KEYDB_HANDLE hd)
|
||||
|
@ -380,8 +395,8 @@ lock_all (KEYDB_HANDLE hd)
|
|||
int i, rc = 0;
|
||||
|
||||
/* Fixme: This locking scheme may lead to deadlock if the resources
|
||||
are not added in the same sequence by all processes. We are
|
||||
cuurently only allowing one resource so it is not a problem. */
|
||||
are not added in the same order all processes. We are
|
||||
currently only allowing one resource so it is not a problem. */
|
||||
for (i=0; i < hd->used; i++)
|
||||
{
|
||||
switch (hd->active[i].type)
|
||||
|
@ -416,7 +431,10 @@ lock_all (KEYDB_HANDLE hd)
|
|||
else
|
||||
hd->locked = 1;
|
||||
|
||||
return rc;
|
||||
/* make_dotlock () does not yet guarantee that errno is set, thus
|
||||
we can't rely on the error reason and will simply use
|
||||
EACCES. */
|
||||
return rc? gpg_error (GPG_ERR_EACCES) : 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -490,9 +508,8 @@ keydb_update_keyblock (KEYDB_HANDLE hd, KBNODE kb)
|
|||
if( opt.dry_run )
|
||||
return 0;
|
||||
|
||||
rc = lock_all (hd);
|
||||
if (rc)
|
||||
return rc;
|
||||
if (!hd->locked)
|
||||
return gpg_error (GPG_ERR_CONFLICT);
|
||||
|
||||
switch (hd->active[hd->found].type) {
|
||||
case KEYDB_RESOURCE_TYPE_NONE:
|
||||
|
@ -552,7 +569,7 @@ keydb_insert_keyblock (KEYDB_HANDLE hd, KBNODE kb)
|
|||
|
||||
|
||||
/*
|
||||
Return the last found keybox. Caller must free it. The returned
|
||||
Return the last found object. Caller must free it. The returned
|
||||
keyblock has the kbode flag bit 0 set for the node with the public
|
||||
key used to locate the keyblock or flag bit 1 set for the user ID
|
||||
node. */
|
||||
|
@ -580,6 +597,67 @@ keydb_get_cert (KEYDB_HANDLE hd, ksba_cert_t *r_cert)
|
|||
return rc;
|
||||
}
|
||||
|
||||
/* Return a flag of the last found object. WHICH is the flag requested;
|
||||
it should be one of the KEYBOX_FLAG_ values. If the operation is
|
||||
successful, the flag value will be stored at the address given by
|
||||
VALUE. Return 0 on success or an error code. */
|
||||
gpg_error_t
|
||||
keydb_get_flags (KEYDB_HANDLE hd, int which, int idx, unsigned int *value)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
if (!hd)
|
||||
return gpg_error (GPG_ERR_INV_VALUE);
|
||||
|
||||
if ( hd->found < 0 || hd->found >= hd->used)
|
||||
return gpg_error (GPG_ERR_NOTHING_FOUND);
|
||||
|
||||
switch (hd->active[hd->found].type)
|
||||
{
|
||||
case KEYDB_RESOURCE_TYPE_NONE:
|
||||
err = gpg_error (GPG_ERR_GENERAL); /* oops */
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYBOX:
|
||||
err = keybox_get_flags (hd->active[hd->found].u.kr, which, idx, value);
|
||||
break;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Set a flag of the last found object. WHICH is the flag to be set; it
|
||||
should be one of the KEYBOX_FLAG_ values. If the operation is
|
||||
successful, the flag value will be stored in the keybox. Note,
|
||||
that some flag values can't be updated and thus may retrun an
|
||||
error, some other flag values may be masked out before an update.
|
||||
Returns 0 on success or an error code. */
|
||||
gpg_error_t
|
||||
keydb_set_flags (KEYDB_HANDLE hd, int which, int idx, unsigned int value)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
if (!hd)
|
||||
return gpg_error (GPG_ERR_INV_VALUE);
|
||||
|
||||
if ( hd->found < 0 || hd->found >= hd->used)
|
||||
return gpg_error (GPG_ERR_NOTHING_FOUND);
|
||||
|
||||
if (!hd->locked)
|
||||
return gpg_error (GPG_ERR_CONFLICT);
|
||||
|
||||
switch (hd->active[hd->found].type)
|
||||
{
|
||||
case KEYDB_RESOURCE_TYPE_NONE:
|
||||
err = gpg_error (GPG_ERR_GENERAL); /* oops */
|
||||
break;
|
||||
case KEYDB_RESOURCE_TYPE_KEYBOX:
|
||||
err = keybox_set_flags (hd->active[hd->found].u.kr, which, idx, value);
|
||||
break;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert a new Certificate into one of the resources.
|
||||
*/
|
||||
|
@ -679,9 +757,8 @@ keydb_delete (KEYDB_HANDLE hd)
|
|||
if( opt.dry_run )
|
||||
return 0;
|
||||
|
||||
rc = lock_all (hd);
|
||||
if (rc)
|
||||
return rc;
|
||||
if (!hd->locked)
|
||||
return gpg_error (GPG_ERR_CONFLICT); /* ...NOT_LOCKED would be better. */
|
||||
|
||||
switch (hd->active[hd->found].type)
|
||||
{
|
||||
|
@ -1279,4 +1356,65 @@ keydb_store_cert (ksba_cert_t cert, int ephemeral, int *existed)
|
|||
}
|
||||
|
||||
|
||||
/* This is basically keydb_set_flags but it implements a complete
|
||||
transaction by locating teh certificate in the DB and updating the
|
||||
flags. */
|
||||
gpg_error_t
|
||||
keydb_set_cert_flags (ksba_cert_t cert, int which, int idx, unsigned int value)
|
||||
{
|
||||
KEYDB_HANDLE kh;
|
||||
gpg_error_t err;
|
||||
unsigned char fpr[20];
|
||||
unsigned int old_value;
|
||||
|
||||
if (!gpgsm_get_fingerprint (cert, 0, fpr, NULL))
|
||||
{
|
||||
log_error (_("failed to get the fingerprint\n"));
|
||||
return gpg_error (GPG_ERR_GENERAL);
|
||||
}
|
||||
|
||||
kh = keydb_new (0);
|
||||
if (!kh)
|
||||
{
|
||||
log_error (_("failed to allocate keyDB handle\n"));
|
||||
return gpg_error (GPG_ERR_ENOMEM);;
|
||||
}
|
||||
|
||||
err = keydb_lock (kh);
|
||||
if (err)
|
||||
{
|
||||
log_error (_("error locking keybox: %s\n"), gpg_strerror (err));
|
||||
keydb_release (kh);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = keydb_search_fpr (kh, fpr);
|
||||
if (err)
|
||||
{
|
||||
log_error (_("problem re-searching certificate: %s\n"),
|
||||
gpg_strerror (err));
|
||||
keydb_release (kh);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = keydb_get_flags (kh, which, idx, &old_value);
|
||||
if (err)
|
||||
{
|
||||
log_error (_("error getting stored flags: %s\n"), gpg_strerror (err));
|
||||
keydb_release (kh);
|
||||
return err;
|
||||
}
|
||||
if (value != old_value)
|
||||
{
|
||||
err = keydb_set_flags (kh, which, idx, value);
|
||||
if (err)
|
||||
{
|
||||
log_error (_("error storing flags: %s\n"), gpg_strerror (err));
|
||||
keydb_release (kh);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
keydb_release (kh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue