aboutsummaryrefslogtreecommitdiffstats
path: root/g10/keydb.c
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2019-09-09 12:34:09 +0000
committerWerner Koch <[email protected]>2019-09-09 13:01:47 +0000
commitaba82684fe14289cf62b4694bc398f3a274b4762 (patch)
treeb66c13bcb29f62f64c4aaa603d510b0fd65cb7cc /g10/keydb.c
parentkbx: Fix keyboxd search first. (diff)
downloadgnupg-aba82684fe14289cf62b4694bc398f3a274b4762.tar.gz
gnupg-aba82684fe14289cf62b4694bc398f3a274b4762.zip
gpg: New option --use-keyboxd.
* g10/gpg.c (oUseKeyboxd,oKeyboxdProgram): New consts. (opts): New options --use-keyboxd and --keyboxd-program. (main): Implement them. * g10/keydb.c: Move some defs out to ... * g10/keydb-private.h: new file. * g10/keydb.c: prefix function names with "internal" and move original functions to ... * g10/call-keyboxd.c: new file. Divert to the internal fucntion if --use-keyboxd is used. Add a CTRL arg to most fucntions and change all callers. * g10/Makefile.am (common_source): Add new files. (noinst_PROGRAMS): Do bot build gpgcompose. -- Note that this is just the framework with only a basic implementation of searching via keyboxd. Signed-off-by: Werner Koch <[email protected]>
Diffstat (limited to 'g10/keydb.c')
-rw-r--r--g10/keydb.c240
1 files changed, 56 insertions, 184 deletions
diff --git a/g10/keydb.c b/g10/keydb.c
index d3a2709bc..6ca239475 100644
--- a/g10/keydb.c
+++ b/g10/keydb.c
@@ -37,25 +37,10 @@
#include "keydb.h"
#include "../common/i18n.h"
-static int active_handles;
+#include "keydb-private.h" /* For struct keydb_handle_s */
-typedef enum
- {
- KEYDB_RESOURCE_TYPE_NONE = 0,
- KEYDB_RESOURCE_TYPE_KEYRING,
- KEYDB_RESOURCE_TYPE_KEYBOX
- } KeydbResourceType;
-#define MAX_KEYDB_RESOURCES 40
+static int active_handles;
-struct resource_item
-{
- KeydbResourceType type;
- union {
- KEYRING_HANDLE kr;
- KEYBOX_HANDLE kb;
- } u;
- void *token;
-};
static struct resource_item all_resources[MAX_KEYDB_RESOURCES];
static int used_resources;
@@ -67,74 +52,6 @@ static void *primary_keydb;
/* Whether we have successfully registered any resource. */
static int any_registered;
-/* This is a simple cache used to return the last result of a
- successful fingerprint search. This works only for keybox resources
- because (due to lack of a copy_keyblock function) we need to store
- an image of the keyblock which is fortunately instantly available
- for keyboxes. */
-enum keyblock_cache_states {
- KEYBLOCK_CACHE_EMPTY,
- KEYBLOCK_CACHE_PREPARED,
- KEYBLOCK_CACHE_FILLED
-};
-
-struct keyblock_cache {
- enum keyblock_cache_states state;
- byte fpr[MAX_FINGERPRINT_LEN];
- byte fprlen;
- iobuf_t iobuf; /* Image of the keyblock. */
- int pk_no;
- int uid_no;
- /* Offset of the record in the keybox. */
- int resource;
- off_t offset;
-};
-
-
-struct keydb_handle
-{
- /* When we locked all of the resources in ACTIVE (using keyring_lock
- / keybox_lock, as appropriate). */
- int locked;
-
- /* If this flag is set a lock will only be released by
- * keydb_release. */
- int keep_lock;
-
- /* The index into ACTIVE of the resources in which the last search
- result was found. Initially -1. */
- int found;
-
- /* Initially -1 (invalid). This is used to save a search result and
- later restore it as the selected result. */
- int saved_found;
-
- /* The number of skipped long blobs since the last search
- (keydb_search_reset). */
- unsigned long skipped_long_blobs;
-
- /* If set, this disables the use of the keyblock cache. */
- int no_caching;
-
- /* Whether the next search will be from the beginning of the
- database (and thus consider all records). */
- int is_reset;
-
- /* The "file position." In our case, this is index of the current
- resource in ACTIVE. */
- int current;
-
- /* The number of resources in ACTIVE. */
- int used;
-
- /* Cache of the last found and parsed key block (only used for
- keyboxes, not keyrings). */
- struct keyblock_cache keyblock_cache;
-
- /* Copy of ALL_RESOURCES when keydb_new is called. */
- struct resource_item active[MAX_KEYDB_RESOURCES];
-};
-
/* Looking up keys is expensive. To hide the cost, we cache whether
keys exist in the key database. Then, if we know a key does not
exist, we don't have to spend time looking it up. This
@@ -273,7 +190,7 @@ kid_not_found_flush (void)
static void
-keyblock_cache_clear (struct keydb_handle *hd)
+keyblock_cache_clear (struct keydb_handle_s *hd)
{
hd->keyblock_cache.state = KEYBLOCK_CACHE_EMPTY;
iobuf_close (hd->keyblock_cache.iobuf);
@@ -875,26 +792,17 @@ keydb_dump_stats (void)
}
-/* Create a new database handle. A database handle is similar to a
- file handle: it contains a local file position. This is used when
- searching: subsequent searches resume where the previous search
- left off. To rewind the position, use keydb_search_reset(). This
- function returns NULL on error, sets ERRNO, and prints an error
- diagnostic. */
-KEYDB_HANDLE
-keydb_new (void)
+/* keydb_new diverts to here in non-keyboxd mode. HD is just the
+ * calloced structure with the handle type intialized. */
+gpg_error_t
+internal_keydb_init (KEYDB_HANDLE hd)
{
- KEYDB_HANDLE hd;
+ gpg_error_t err = 0;
int i, j;
int die = 0;
int reterrno;
- if (DBG_CLOCK)
- log_clock ("keydb_new");
-
- hd = xtrycalloc (1, sizeof *hd);
- if (!hd)
- goto leave;
+ log_assert (!hd->use_keyboxd);
hd->found = -1;
hd->saved_found = -1;
hd->is_reset = 1;
@@ -936,28 +844,21 @@ keydb_new (void)
keydb_stats.handles++;
if (die)
- {
- keydb_release (hd);
- gpg_err_set_errno (reterrno);
- hd = NULL;
- }
+ err = gpg_error_from_errno (reterrno);
- leave:
- if (!hd)
- log_error (_("error opening key DB: %s\n"),
- gpg_strerror (gpg_error_from_syserror()));
-
- return hd;
+ return err;
}
+/* Free all non-keyboxd resources owned by the database handle.
+ * keydb_release diverts to here. */
void
-keydb_release (KEYDB_HANDLE hd)
+internal_keydb_deinit (KEYDB_HANDLE hd)
{
int i;
- if (!hd)
- return;
+ log_assert (!hd->use_keyboxd);
+
log_assert (active_handles > 0);
active_handles--;
@@ -979,19 +880,17 @@ keydb_release (KEYDB_HANDLE hd)
}
keyblock_cache_clear (hd);
- xfree (hd);
}
/* Take a lock on the files immediately and not only during insert or
* update. This lock is released with keydb_release. */
gpg_error_t
-keydb_lock (KEYDB_HANDLE hd)
+internal_keydb_lock (KEYDB_HANDLE hd)
{
gpg_error_t err;
- if (!hd)
- return gpg_error (GPG_ERR_INV_ARG);
+ log_assert (!hd->use_keyboxd);
err = lock_all (hd);
if (!err)
@@ -1007,7 +906,7 @@ keydb_lock (KEYDB_HANDLE hd)
void
keydb_disable_caching (KEYDB_HANDLE hd)
{
- if (hd)
+ if (hd && !hd->use_keyboxd)
hd->no_caching = 1;
}
@@ -1029,6 +928,9 @@ keydb_get_resource_name (KEYDB_HANDLE hd)
if (!hd)
return NULL;
+ if (!hd->use_keyboxd)
+ return "[keyboxd]";
+
if ( hd->found >= 0 && hd->found < hd->used)
idx = hd->found;
else if ( hd->current >= 0 && hd->current < hd->used)
@@ -1152,6 +1054,8 @@ unlock_all (KEYDB_HANDLE hd)
* Note: it is only possible to save a single save state at a time.
* In other words, the save stack only has room for a single
* instance of the state. */
+/* FIXME(keyboxd): This function is used only at one place - see how
+ * we can avoid it. */
void
keydb_push_found_state (KEYDB_HANDLE hd)
{
@@ -1183,6 +1087,8 @@ keydb_push_found_state (KEYDB_HANDLE hd)
/* Restore the previous save state. If the saved state is NULL or
invalid, this is a NOP. */
+/* FIXME(keyboxd): This function is used only at one place - see how
+ * we can avoid it. */
void
keydb_pop_found_state (KEYDB_HANDLE hd)
{
@@ -1347,6 +1253,7 @@ parse_keyblock_image (iobuf_t iobuf, int pk_no, int uid_no,
/* Return the keyblock last found by keydb_search() in *RET_KB.
+ * keydb_get_keyblock divert to here in the non-keyboxd mode.
*
* On success, the function returns 0 and the caller must free *RET_KB
* using release_kbnode(). Otherwise, the function returns an error
@@ -1356,17 +1263,11 @@ parse_keyblock_image (iobuf_t iobuf, int pk_no, int uid_no,
* with the public key used to locate the keyblock or flag bit 1 set
* for the user ID node. */
gpg_error_t
-keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
+internal_keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
{
gpg_error_t err = 0;
- *ret_kb = NULL;
-
- if (!hd)
- return gpg_error (GPG_ERR_INV_ARG);
-
- if (DBG_CLOCK)
- log_clock ("keydb_get_keybock enter");
+ log_assert (!hd->use_keyboxd);
if (hd->keyblock_cache.state == KEYBLOCK_CACHE_FILLED)
{
@@ -1385,8 +1286,7 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
if (err)
keyblock_cache_clear (hd);
if (DBG_CLOCK)
- log_clock (err? "keydb_get_keyblock leave (cached, failed)"
- : "keydb_get_keyblock leave (cached)");
+ log_clock ("%s leave (cached mode)", __func__);
return err;
}
}
@@ -1434,9 +1334,6 @@ keydb_get_keyblock (KEYDB_HANDLE hd, KBNODE *ret_kb)
if (!err)
keydb_stats.get_keyblocks++;
- if (DBG_CLOCK)
- log_clock (err? "keydb_get_keyblock leave (failed)"
- : "keydb_get_keyblock leave");
return err;
}
@@ -1485,6 +1382,7 @@ build_keyblock_image (kbnode_t keyblock, iobuf_t *r_iobuf)
/* Update the keyblock KB (i.e., extract the fingerprint and find the
* corresponding keyblock in the keyring).
+ * keydb_update_keyblock diverts to here in the non-keyboxd mode.
*
* This doesn't do anything if --dry-run was specified.
*
@@ -1499,20 +1397,16 @@ build_keyblock_image (kbnode_t keyblock, iobuf_t *r_iobuf)
* you should use keydb_push_found_state and keydb_pop_found_state to
* save and restore it. */
gpg_error_t
-keydb_update_keyblock (ctrl_t ctrl, KEYDB_HANDLE hd, kbnode_t kb)
+internal_keydb_update_keyblock (ctrl_t ctrl, KEYDB_HANDLE hd, kbnode_t kb)
{
gpg_error_t err;
PKT_public_key *pk;
KEYDB_SEARCH_DESC desc;
size_t len;
- log_assert (kb);
- log_assert (kb->pkt->pkttype == PKT_PUBLIC_KEY);
+ log_assert (!hd->use_keyboxd);
pk = kb->pkt->pkt.public_key;
- if (!hd)
- return gpg_error (GPG_ERR_INV_ARG);
-
kid_not_found_flush ();
keyblock_cache_clear (hd);
@@ -1575,6 +1469,7 @@ keydb_update_keyblock (ctrl_t ctrl, KEYDB_HANDLE hd, kbnode_t kb)
/* Insert a keyblock into one of the underlying keyrings or keyboxes.
+ * keydb_insert_keyblock diverts to here in the non-keyboxd mode.
*
* Be default, the keyring / keybox from which the last search result
* came is used. If there was no previous search result (or
@@ -1585,13 +1480,12 @@ keydb_update_keyblock (ctrl_t ctrl, KEYDB_HANDLE hd, kbnode_t kb)
*
* Returns 0 on success. Otherwise, it returns an error code. */
gpg_error_t
-keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
+internal_keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
{
gpg_error_t err;
int idx;
- if (!hd)
- return gpg_error (GPG_ERR_INV_ARG);
+ log_assert (!hd->use_keyboxd);
kid_not_found_flush ();
keyblock_cache_clear (hd);
@@ -1650,12 +1544,11 @@ keydb_insert_keyblock (KEYDB_HANDLE hd, kbnode_t kb)
*
* Returns 0 on success or an error code, if an error occurs. */
gpg_error_t
-keydb_delete_keyblock (KEYDB_HANDLE hd)
+internal_keydb_delete_keyblock (KEYDB_HANDLE hd)
{
gpg_error_t rc;
- if (!hd)
- return gpg_error (GPG_ERR_INV_ARG);
+ log_assert (!hd->use_keyboxd);
kid_not_found_flush ();
keyblock_cache_clear (hd);
@@ -1708,6 +1601,9 @@ keydb_locate_writable (KEYDB_HANDLE hd)
if (!hd)
return GPG_ERR_INV_ARG;
+ if (hd->use_keyboxd)
+ return 0; /* No need for this here. */
+
rc = keydb_search_reset (hd); /* this does reset hd->current */
if (rc)
return rc;
@@ -1759,6 +1655,9 @@ keydb_rebuild_caches (ctrl_t ctrl, int noisy)
{
int i, rc;
+ if (opt.use_keyboxd)
+ return; /* No need for this here. */
+
for (i=0; i < used_resources; i++)
{
if (!keyring_is_writable (all_resources[i].token))
@@ -1781,38 +1680,33 @@ keydb_rebuild_caches (ctrl_t ctrl, int noisy)
}
-/* Return the number of skipped blocks (because they were to large to
+/* Return the number of skipped blocks (because they were too large to
read from a keybox) since the last search reset. */
unsigned long
keydb_get_skipped_counter (KEYDB_HANDLE hd)
{
- return hd ? hd->skipped_long_blobs : 0;
+ /*FIXME(keyboxd): Do we need this? */
+ return hd && !hd->use_keyboxd? hd->skipped_long_blobs : 0;
}
/* Clears the current search result and resets the handle's position
* so that the next search starts at the beginning of the database
* (the start of the first resource).
+ * keydb_search_reset diverts to here in the non-keyboxd mode.
*
* Returns 0 on success and an error code if an error occurred.
* (Currently, this function always returns 0 if HD is valid.) */
gpg_error_t
-keydb_search_reset (KEYDB_HANDLE hd)
+internal_keydb_search_reset (KEYDB_HANDLE hd)
{
gpg_error_t rc = 0;
int i;
- if (!hd)
- return gpg_error (GPG_ERR_INV_ARG);
+ log_assert (!hd->use_keyboxd);
keyblock_cache_clear (hd);
- if (DBG_CLOCK)
- log_clock ("keydb_search_reset");
-
- if (DBG_CACHE)
- log_debug ("keydb_search: reset (hd=%p)", hd);
-
hd->skipped_long_blobs = 0;
hd->current = 0;
hd->found = -1;
@@ -1840,6 +1734,7 @@ keydb_search_reset (KEYDB_HANDLE hd)
/* Search the database for keys matching the search description. If
* the DB contains any legacy keys, these are silently ignored.
+ * keydb_search diverts to here in the non-keyboxd mode.
*
* DESC is an array of search terms with NDESC entries. The search
* terms are or'd together. That is, the next entry in the DB that
@@ -1857,21 +1752,16 @@ keydb_search_reset (KEYDB_HANDLE hd)
* The returned key is considered to be selected and the raw data can,
* for instance, be returned by calling keydb_get_keyblock(). */
gpg_error_t
-keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
- size_t ndesc, size_t *descindex)
+internal_keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
+ size_t ndesc, size_t *descindex)
{
- int i;
gpg_error_t rc;
int was_reset = hd->is_reset;
/* If an entry is already in the cache, then don't add it again. */
int already_in_cache = 0;
int fprlen;
- if (descindex)
- *descindex = 0; /* Make sure it is always set on return. */
-
- if (!hd)
- return gpg_error (GPG_ERR_INV_ARG);
+ log_assert (!hd->use_keyboxd);
if (!any_registered)
{
@@ -1879,26 +1769,11 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
return gpg_error (GPG_ERR_NOT_FOUND);
}
- if (DBG_CLOCK)
- log_clock ("keydb_search enter");
-
- if (DBG_LOOKUP)
- {
- log_debug ("%s: %zd search descriptions:\n", __func__, ndesc);
- for (i = 0; i < ndesc; i ++)
- {
- char *t = keydb_search_desc_dump (&desc[i]);
- log_debug ("%s %d: %s\n", __func__, i, t);
- xfree (t);
- }
- }
-
-
if (ndesc == 1 && desc[0].mode == KEYDB_SEARCH_MODE_LONG_KID
&& (already_in_cache = kid_not_found_p (desc[0].u.kid)) == 1 )
{
if (DBG_CLOCK)
- log_clock ("keydb_search leave (not found, cached)");
+ log_clock ("%s leave (not found, cached)", __func__);
keydb_stats.notfound_cached++;
return gpg_error (GPG_ERR_NOT_FOUND);
}
@@ -1926,7 +1801,7 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
{
/* (DESCINDEX is already set). */
if (DBG_CLOCK)
- log_clock ("keydb_search leave (cached)");
+ log_clock ("%s leave (cached)", __func__);
hd->current = hd->keyblock_cache.resource;
/* HD->KEYBLOCK_CACHE.OFFSET is the last byte in the record.
@@ -2016,9 +1891,6 @@ keydb_search (KEYDB_HANDLE hd, KEYDB_SEARCH_DESC *desc,
&& !already_in_cache)
kid_not_found_insert (desc[0].u.kid);
- if (DBG_CLOCK)
- log_clock (rc? "keydb_search leave (not found)"
- : "keydb_search leave (found)");
if (!rc)
keydb_stats.found++;
else