aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--g10/delkey.c8
-rw-r--r--g10/getkey.c11
-rw-r--r--g10/import.c9
-rw-r--r--g10/keydb.c39
-rw-r--r--g10/keyedit.c3
-rw-r--r--g10/keygen.c2
-rw-r--r--sm/delete.c18
-rw-r--r--sm/keydb.c45
-rw-r--r--sm/keydb.h2
9 files changed, 77 insertions, 60 deletions
diff --git a/g10/delkey.c b/g10/delkey.c
index 458c451e0..904f4c26e 100644
--- a/g10/delkey.c
+++ b/g10/delkey.c
@@ -74,6 +74,14 @@ do_delete_key (ctrl_t ctrl, const char *username, int secret, int force,
err = classify_user_id (username, &desc, 1);
exactmatch = (desc.mode == KEYDB_SEARCH_MODE_FPR);
thiskeyonly = desc.exact;
+
+ err = keydb_lock (hd);
+ if (err)
+ {
+ keydb_release (hd);
+ goto leave;
+ }
+
if (!err)
err = keydb_search (hd, &desc, 1, NULL);
if (err)
diff --git a/g10/getkey.c b/g10/getkey.c
index 6af6dc0a5..efb157645 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -799,10 +799,10 @@ leave:
should be freed using release_kbnode().
If RET_KDBHD is not NULL, then the new database handle used to
- conduct the search is returned in *RET_KDBHD. This can be used to
- get subsequent results using keydb_search_next. Note: in this
- case, no advanced filtering is done for subsequent results (e.g.,
- WANT_SECRET and PK->REQ_USAGE are not respected).
+ conduct the search is returned in *RET_KDBHD, holding the lock.
+ This can be used to get subsequent results using keydb_search_next.
+ Note: in this case, no advanced filtering is done for subsequent
+ results (e.g., WANT_SECRET and PK->REQ_USAGE are not respected).
This function returns 0 on success. Otherwise, an error code is
returned. In particular, GPG_ERR_NO_PUBKEY or GPG_ERR_NO_SECKEY
@@ -895,6 +895,9 @@ key_byname (ctrl_t ctrl, GETKEY_CTX *retctx, strlist_t namelist,
if (!ret_kb)
ret_kb = &help_kb;
+ if (ret_kdbhd)
+ keydb_lock (ctx->kr_handle);
+
if (pk)
{
/* It is a bit tricky to allow returning an ADSK key: lookup
diff --git a/g10/import.c b/g10/import.c
index 1ee818d61..effc38a93 100644
--- a/g10/import.c
+++ b/g10/import.c
@@ -2280,7 +2280,7 @@ import_one_real (ctrl_t ctrl,
}
}
- err = keydb_insert_keyblock (hd, keyblock );
+ err = keydb_insert_keyblock (hd, keyblock);
if (err)
log_error (_("error writing keyring '%s': %s\n"),
keydb_get_resource_name (hd), gpg_strerror (err));
@@ -3618,6 +3618,13 @@ import_revoke_cert (ctrl_t ctrl, kbnode_t node, unsigned int options,
goto leave;
}
+ rc = keydb_lock (hd);
+ if (rc)
+ {
+ keydb_release (hd);
+ goto leave;
+ }
+
{
byte afp[MAX_FINGERPRINT_LEN];
size_t an;
diff --git a/g10/keydb.c b/g10/keydb.c
index cdad8a450..208622b33 100644
--- a/g10/keydb.c
+++ b/g10/keydb.c
@@ -1434,6 +1434,10 @@ internal_keydb_update_keyblock (ctrl_t ctrl, KEYDB_HANDLE hd, kbnode_t kb)
size_t len;
log_assert (!hd->use_keyboxd);
+
+ if (!hd->locked)
+ return gpg_error (GPG_ERR_NOT_LOCKED);
+
pk = kb->pkt->pkt.public_key;
kid_not_found_flush ();
@@ -1442,10 +1446,6 @@ internal_keydb_update_keyblock (ctrl_t ctrl, KEYDB_HANDLE hd, kbnode_t kb)
if (opt.dry_run)
return 0;
- err = lock_all (hd);
- if (err)
- return err;
-
#ifdef USE_TOFU
tofu_notice_key_changed (ctrl, kb);
#else
@@ -1493,7 +1493,6 @@ internal_keydb_update_keyblock (ctrl_t ctrl, KEYDB_HANDLE hd, kbnode_t kb)
break;
}
- unlock_all (hd);
if (!err)
keydb_stats.update_keyblocks++;
return err;
@@ -1514,11 +1513,14 @@ internal_keydb_update_keyblock (ctrl_t ctrl, KEYDB_HANDLE hd, kbnode_t kb)
gpg_error_t
internal_keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
{
- gpg_error_t err;
+ gpg_error_t err = 0;
int idx;
log_assert (!hd->use_keyboxd);
+ if (!hd->locked)
+ return gpg_error (GPG_ERR_NOT_LOCKED);
+
kid_not_found_flush ();
keyblock_cache_clear (hd);
@@ -1532,10 +1534,6 @@ internal_keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
else
return gpg_error (GPG_ERR_GENERAL);
- err = lock_all (hd);
- if (err)
- return err;
-
switch (hd->active[idx].type)
{
case KEYDB_RESOURCE_TYPE_NONE:
@@ -1564,7 +1562,6 @@ internal_keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
break;
}
- unlock_all (hd);
if (!err)
keydb_stats.insert_keyblocks++;
return err;
@@ -1579,10 +1576,13 @@ internal_keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
gpg_error_t
internal_keydb_delete_keyblock (KEYDB_HANDLE hd)
{
- gpg_error_t rc;
+ gpg_error_t err = 0;
log_assert (!hd->use_keyboxd);
+ if (!hd->locked)
+ return gpg_error (GPG_ERR_NOT_LOCKED);
+
kid_not_found_flush ();
keyblock_cache_clear (hd);
@@ -1592,27 +1592,22 @@ internal_keydb_delete_keyblock (KEYDB_HANDLE hd)
if (opt.dry_run)
return 0;
- rc = lock_all (hd);
- if (rc)
- return rc;
-
switch (hd->active[hd->found].type)
{
case KEYDB_RESOURCE_TYPE_NONE:
- rc = gpg_error (GPG_ERR_GENERAL);
+ err = gpg_error (GPG_ERR_GENERAL);
break;
case KEYDB_RESOURCE_TYPE_KEYRING:
- rc = keyring_delete_keyblock (hd->active[hd->found].u.kr);
+ err = keyring_delete_keyblock (hd->active[hd->found].u.kr);
break;
case KEYDB_RESOURCE_TYPE_KEYBOX:
- rc = keybox_delete (hd->active[hd->found].u.kb);
+ err = keybox_delete (hd->active[hd->found].u.kb);
break;
}
- unlock_all (hd);
- if (!rc)
+ if (!err)
keydb_stats.delete_keyblocks++;
- return rc;
+ return err;
}
diff --git a/g10/keyedit.c b/g10/keyedit.c
index 0c54a448b..bae79b37e 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -2583,6 +2583,9 @@ quick_find_keyblock (ctrl_t ctrl, const char *username, int want_secret,
err = gpg_error_from_syserror ();
goto leave;
}
+ err = keydb_lock (kdbhd);
+ if (err)
+ goto leave;
err = classify_user_id (username, &desc, 1);
if (!err)
diff --git a/g10/keygen.c b/g10/keygen.c
index 1f4388f39..305604894 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -6660,6 +6660,8 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
if (err)
log_error (_("no writable public keyring found: %s\n"),
gpg_strerror (err));
+ else
+ err = keydb_lock (pub_hd);
}
if (!err && opt.verbose)
diff --git a/sm/delete.c b/sm/delete.c
index ccd389313..46d3a6f2a 100644
--- a/sm/delete.c
+++ b/sm/delete.c
@@ -60,6 +60,14 @@ delete_one (ctrl_t ctrl, const char *username)
goto leave;
}
+ /* Note that the lock is kept until the KH is released. */
+ rc = keydb_lock (kh);
+ if (rc)
+ {
+ log_error (_("error locking keybox: %s\n"), gpg_strerror (rc));
+ goto leave;
+ }
+
/* If the key is specified in a unique way, include ephemeral keys
in the search. */
if ( desc.mode == KEYDB_SEARCH_MODE_FPR
@@ -112,15 +120,7 @@ delete_one (ctrl_t ctrl, const char *username)
goto leave;
}
- /* We need to search again to get back to the right position. Note
- * that the lock is kept until the KH is released. */
- rc = keydb_lock (kh);
- if (rc)
- {
- log_error (_("error locking keybox: %s\n"), gpg_strerror (rc));
- goto leave;
- }
-
+ /* We need to search again to get back to the right position. */
do
{
keydb_search_reset (kh);
diff --git a/sm/keydb.c b/sm/keydb.c
index 72bad2d60..878781cd4 100644
--- a/sm/keydb.c
+++ b/sm/keydb.c
@@ -1096,8 +1096,8 @@ keydb_get_flags (KEYDB_HANDLE hd, int which, int idx, unsigned int *value)
that some flag values can't be updated and thus may return 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)
+static gpg_error_t
+do_set_flags (KEYDB_HANDLE hd, int which, int idx, unsigned int value)
{
gpg_error_t err = 0;
@@ -1226,6 +1226,12 @@ do_insert_cert (KEYDB_HANDLE hd, ksba_cert_t cert)
goto leave;
}
+ if (!hd->locked)
+ {
+ err = gpg_error (GPG_ERR_NOT_LOCKED);
+ goto leave;
+ }
+
if ( hd->found >= 0 && hd->found < hd->used)
idx = hd->found;
else if ( hd->current >= 0 && hd->current < hd->used)
@@ -1236,12 +1242,6 @@ do_insert_cert (KEYDB_HANDLE hd, ksba_cert_t cert)
goto leave;
}
- if (!hd->locked)
- {
- err = gpg_error (GPG_ERR_NOT_LOCKED);
- goto leave;
- }
-
gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL); /* kludge*/
err = gpg_error (GPG_ERR_BUG);
@@ -1278,6 +1278,18 @@ keydb_update_cert (KEYDB_HANDLE hd, ksba_cert_t cert)
if (!hd)
return gpg_error (GPG_ERR_INV_VALUE);
+ if (hd->use_keyboxd)
+ {
+ /* FIXME */
+ goto leave;
+ }
+
+ if (!hd->locked)
+ {
+ err = gpg_error (GPG_ERR_NOT_LOCKED);
+ goto leave;
+ }
+
if ( hd->found < 0 || hd->found >= hd->used)
return gpg_error (GPG_ERR_NOT_FOUND);
@@ -1287,16 +1299,6 @@ keydb_update_cert (KEYDB_HANDLE hd, ksba_cert_t cert)
if (DBG_CLOCK)
log_clock ("%s: enter (hd=%p)\n", __func__, hd);
- if (hd->use_keyboxd)
- {
- /* FIXME */
- goto leave;
- }
-
- err = lock_all (hd);
- if (err)
- goto leave;
-
gpgsm_get_fingerprint (cert, GCRY_MD_SHA1, digest, NULL); /* kludge*/
err = gpg_error (GPG_ERR_BUG);
@@ -1310,7 +1312,6 @@ keydb_update_cert (KEYDB_HANDLE hd, ksba_cert_t cert)
break;
}
- unlock_all (hd);
leave:
if (DBG_CLOCK)
log_clock ("%s: leave (err=%s)\n", __func__, gpg_strerror (err));
@@ -2032,7 +2033,7 @@ keydb_store_cert (ctrl_t ctrl, ksba_cert_t cert, int ephemeral, int *existed)
}
-/* This is basically keydb_set_flags but it implements a complete
+/* This is basically do_set_flags but it implements a complete
transaction by locating the certificate in the DB and updating the
flags. */
gpg_error_t
@@ -2094,7 +2095,7 @@ keydb_set_cert_flags (ctrl_t ctrl, ksba_cert_t cert, int ephemeral,
if (value != old_value)
{
- err = keydb_set_flags (kh, which, idx, value);
+ err = do_set_flags (kh, which, idx, value);
if (err)
{
log_error (_("error storing flags: %s\n"), gpg_strerror (err));
@@ -2186,7 +2187,7 @@ keydb_clear_some_cert_flags (ctrl_t ctrl, strlist_t names)
value = (old_value & ~VALIDITY_REVOKED);
if (value != old_value)
{
- err = keydb_set_flags (hd, KEYBOX_FLAG_VALIDITY, 0, value);
+ err = do_set_flags (hd, KEYBOX_FLAG_VALIDITY, 0, value);
if (err)
{
log_error (_("error storing flags: %s\n"), gpg_strerror (err));
diff --git a/sm/keydb.h b/sm/keydb.h
index 2725cadc6..8c453f9cd 100644
--- a/sm/keydb.h
+++ b/sm/keydb.h
@@ -42,8 +42,6 @@ gpg_error_t keydb_lock (KEYDB_HANDLE hd);
gpg_error_t keydb_get_flags (KEYDB_HANDLE hd, int which, int idx,
unsigned int *value);
-gpg_error_t keydb_set_flags (KEYDB_HANDLE hd, int which, int idx,
- unsigned int value);
void keydb_push_found_state (KEYDB_HANDLE hd);
void keydb_pop_found_state (KEYDB_HANDLE hd);
int keydb_get_cert (KEYDB_HANDLE hd, ksba_cert_t *r_cert);