diff options
| -rw-r--r-- | g10/delkey.c | 8 | ||||
| -rw-r--r-- | g10/getkey.c | 11 | ||||
| -rw-r--r-- | g10/import.c | 9 | ||||
| -rw-r--r-- | g10/keydb.c | 39 | ||||
| -rw-r--r-- | g10/keyedit.c | 3 | ||||
| -rw-r--r-- | g10/keygen.c | 2 | ||||
| -rw-r--r-- | sm/delete.c | 18 | ||||
| -rw-r--r-- | sm/keydb.c | 45 | ||||
| -rw-r--r-- | sm/keydb.h | 2 |
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); |
