aboutsummaryrefslogtreecommitdiffstats
path: root/sm/keydb.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2004-02-02 17:09:35 +0000
committerWerner Koch <[email protected]>2004-02-02 17:09:35 +0000
commit5bda9a8e74753da5d7ee912c32a0137ebce2abd8 (patch)
tree17d077c8da8a9cba7a1d9919f8021424fcbd9ece /sm/keydb.c
parentFix copyright line. (diff)
downloadgnupg-5bda9a8e74753da5d7ee912c32a0137ebce2abd8.tar.gz
gnupg-5bda9a8e74753da5d7ee912c32a0137ebce2abd8.zip
* 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.
Diffstat (limited to 'sm/keydb.c')
-rw-r--r--sm/keydb.c160
1 files changed, 149 insertions, 11 deletions
diff --git a/sm/keydb.c b/sm/keydb.c
index 62e3ab2f3..f770135c1 100644
--- a/sm/keydb.c
+++ b/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;
+}