X-Git-Url: https://the.earth.li/gitweb/?a=blobdiff_plain;f=keydb_stacked.c;fp=keydb_stacked.c;h=0000000000000000000000000000000000000000;hb=51c1a7dd950efef6a4d00df1878341777f8064ff;hp=7e997d99d08cf784bc48e29e7f5d4f67fb502ebc;hpb=dfab9e96ee1fa4a10acf9c1cf644d7a4366a5af6;p=onak.git diff --git a/keydb_stacked.c b/keydb_stacked.c deleted file mode 100644 index 7e997d9..0000000 --- a/keydb_stacked.c +++ /dev/null @@ -1,386 +0,0 @@ -/* - * keydb_stacked.c - backend that stacks other backends together - * - * Copyright 2016 Jonathan McDowell - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ - -#include -#include -#include -#include -#include - -#include "cleankey.h" -#include "keydb.h" -#include "keystructs.h" -#include "ll.h" -#include "log.h" -#include "onak-conf.h" - -struct onak_stacked_dbctx { - struct ll *backends; - bool store_on_fallback; -}; - -/* - * The following functions only apply to the first backend. - */ - -static bool stacked_starttrans(struct onak_dbctx *dbctx) -{ - struct onak_stacked_dbctx *privctx = - (struct onak_stacked_dbctx *) dbctx->priv; - struct onak_dbctx *backend = - (struct onak_dbctx *) privctx->backends->object; - - return backend->starttrans(backend); -} - -static void stacked_endtrans(struct onak_dbctx *dbctx) -{ - struct onak_stacked_dbctx *privctx = - (struct onak_stacked_dbctx *) dbctx->priv; - struct onak_dbctx *backend = - (struct onak_dbctx *) privctx->backends->object; - - backend->starttrans(backend); -} - -static int stacked_store_key(struct onak_dbctx *dbctx, - struct openpgp_publickey *publickey, bool intrans, - bool update) -{ - struct onak_stacked_dbctx *privctx = - (struct onak_stacked_dbctx *) dbctx->priv; - struct onak_dbctx *backend = - (struct onak_dbctx *) privctx->backends->object; - - return backend->store_key(backend, - publickey, intrans, update); -} - -static int stacked_delete_key(struct onak_dbctx *dbctx, - struct openpgp_fingerprint *fp, - bool intrans) -{ - struct onak_stacked_dbctx *privctx = - (struct onak_stacked_dbctx *) dbctx->priv; - struct onak_dbctx *backend = - (struct onak_dbctx *) privctx->backends->object; - - return backend->delete_key(backend, - fp, intrans); -} - -static int stacked_update_keys(struct onak_dbctx *dbctx, - struct openpgp_publickey **keys, - struct keyarray *blacklist, - bool updateonly, - bool sendsync) -{ - struct onak_stacked_dbctx *privctx = - (struct onak_stacked_dbctx *) dbctx->priv; - struct onak_dbctx *backend = - (struct onak_dbctx *) privctx->backends->object; - - return backend->update_keys(backend, keys, blacklist, updateonly, - sendsync); -} - -static int stacked_iterate_keys(struct onak_dbctx *dbctx, - void (*iterfunc)(void *ctx, struct openpgp_publickey *key), - void *ctx) -{ - struct onak_stacked_dbctx *privctx = - (struct onak_stacked_dbctx *) dbctx->priv; - struct onak_dbctx *backend = - (struct onak_dbctx *) privctx->backends->object; - - return backend->iterate_keys(backend, iterfunc, ctx); -} - -static void store_on_fallback(struct onak_stacked_dbctx *privctx, - struct openpgp_publickey *publickey, bool intrans) -{ - struct onak_dbctx *backend = - (struct onak_dbctx *) privctx->backends->object; - struct openpgp_publickey *curkey; - - cleankeys(&publickey, config.clean_policies); - /* - * If we walked the stack at all, store the key in the first - * backend if configured to do so. It's not an update as we - * know it's not there or we wouldn't have fallen back. - */ - for (curkey = publickey; curkey != NULL; curkey = curkey->next) { - backend->store_key(backend, curkey, intrans, false); - } -} - -/* - * The functions below will walk along the backend stack until they - * reach the end or get a successful result. - */ - -static int stacked_fetch_key_id(struct onak_dbctx *dbctx, uint64_t keyid, - struct openpgp_publickey **publickey, bool intrans) -{ - struct onak_stacked_dbctx *privctx = - (struct onak_stacked_dbctx *) dbctx->priv; - struct onak_dbctx *backend; - struct ll *cur; - int res = 0; - - for (cur = privctx->backends; cur != NULL && res == 0; - cur = cur->next) { - backend = (struct onak_dbctx *) cur->object; - res = backend->fetch_key_id(backend, keyid, publickey, - intrans); - } - - if (privctx->store_on_fallback && cur != privctx->backends) { - store_on_fallback(privctx, *publickey, intrans); - } - - return res; -} - -static int stacked_fetch_key_fp(struct onak_dbctx *dbctx, - struct openpgp_fingerprint *fingerprint, - struct openpgp_publickey **publickey, bool intrans) -{ - struct onak_stacked_dbctx *privctx = - (struct onak_stacked_dbctx *) dbctx->priv; - struct onak_dbctx *backend; - struct ll *cur; - int res = 0; - - for (cur = privctx->backends; cur != NULL && res == 0; - cur = cur->next) { - backend = (struct onak_dbctx *) cur->object; - res = backend->fetch_key_fp(backend, fingerprint, publickey, - intrans); - } - - if (privctx->store_on_fallback && cur != privctx->backends) { - store_on_fallback(privctx, *publickey, intrans); - } - - return res; -} - -static int stacked_fetch_key_text(struct onak_dbctx *dbctx, - const char *search, - struct openpgp_publickey **publickey) -{ - struct onak_stacked_dbctx *privctx = - (struct onak_stacked_dbctx *) dbctx->priv; - struct onak_dbctx *backend; - struct ll *cur; - int res = 0; - - for (cur = privctx->backends; cur != NULL && res == 0; - cur = cur->next) { - backend = (struct onak_dbctx *) cur->object; - res = backend->fetch_key_text(backend, search, publickey); - } - - if (privctx->store_on_fallback && cur != privctx->backends) { - store_on_fallback(privctx, *publickey, false); - } - - return res; -} - -static int stacked_fetch_key_skshash(struct onak_dbctx *dbctx, - const struct skshash *hash, - struct openpgp_publickey **publickey) -{ - struct onak_stacked_dbctx *privctx = - (struct onak_stacked_dbctx *) dbctx->priv; - struct onak_dbctx *backend; - struct ll *cur; - int res = 0; - - for (cur = privctx->backends; cur != NULL && res == 0; - cur = cur->next) { - backend = (struct onak_dbctx *) cur->object; - res = backend->fetch_key_skshash(backend, hash, publickey); - } - - if (privctx->store_on_fallback && cur != privctx->backends) { - store_on_fallback(privctx, *publickey, false); - } - - return res; -} - -/* - * Include the basic keydb routines so we can use them for fall back. - * For all of the following we try the top keydb backend and if that doesn't - * have answer fall back to the generics, which will do a retrieve from a - * backend further down the stack, then a fallback store. - */ -#define NEED_KEYID2UID 1 -#define NEED_GETKEYSIGS 1 -#define NEED_UPDATEKEYS 1 -#include "keydb.c" - -static struct ll *stacked_getkeysigs(struct onak_dbctx *dbctx, - uint64_t keyid, bool *revoked) -{ - struct onak_stacked_dbctx *privctx = - (struct onak_stacked_dbctx *) dbctx->priv; - struct onak_dbctx *backend = - (struct onak_dbctx *) privctx->backends->object; - struct ll *res; - - res = backend->getkeysigs(backend, keyid, revoked); - if (res == NULL) { - res = generic_getkeysigs(dbctx, keyid, revoked); - } - - return res; -} - -static struct ll *stacked_cached_getkeysigs(struct onak_dbctx *dbctx, - uint64_t keyid) -{ - struct onak_stacked_dbctx *privctx = - (struct onak_stacked_dbctx *) dbctx->priv; - struct onak_dbctx *backend = - (struct onak_dbctx *) privctx->backends->object; - struct ll *res; - - res = backend->cached_getkeysigs(backend, keyid); - if (res == NULL) { - res = generic_cached_getkeysigs(dbctx, keyid); - } - - return res; -} - -static char *stacked_keyid2uid(struct onak_dbctx *dbctx, - uint64_t keyid) -{ - struct onak_stacked_dbctx *privctx = - (struct onak_stacked_dbctx *) dbctx->priv; - struct onak_dbctx *backend = - (struct onak_dbctx *) privctx->backends->object; - char *res = NULL; - - res = backend->keyid2uid(backend, keyid); - if (!res) { - res = generic_keyid2uid(dbctx, keyid); - } - - return res; -} - -static void stacked_cleanupdb(struct onak_dbctx *dbctx) -{ - struct onak_stacked_dbctx *privctx = - (struct onak_stacked_dbctx *) dbctx->priv; - struct onak_dbctx *backend; - struct ll *cur; - int res = 0; - - for (cur = privctx->backends; cur != NULL && res == 0; - cur = cur->next) { - backend = (struct onak_dbctx *) cur->object; - backend->cleanupdb(backend); - } - - if (dbctx->priv != NULL) { - free(dbctx->priv); - dbctx->priv = NULL; - } - - if (dbctx != NULL) { - free(dbctx); - } -} - -struct onak_dbctx *keydb_stacked_init(struct onak_db_config *dbcfg, - bool readonly) -{ - struct onak_dbctx *dbctx; - struct onak_stacked_dbctx *privctx; - struct onak_dbctx *backend; - struct onak_db_config *backend_cfg; - char *backend_name, *saveptr = NULL; - - if (dbcfg == NULL) { - logthing(LOGTHING_CRITICAL, - "No backend database configuration supplied."); - return NULL; - } - - dbctx = malloc(sizeof(struct onak_dbctx)); - - if (dbctx == NULL) { - return NULL; - } - - dbctx->config = dbcfg; - dbctx->priv = privctx = malloc(sizeof(struct onak_stacked_dbctx)); - if (dbctx->priv == NULL) { - free(dbctx); - return (NULL); - } - - /* TODO: Make configurable? */ - privctx->store_on_fallback = true; - privctx->backends = NULL; - - backend_name = strtok_r(dbcfg->location, ":", &saveptr); - while (backend_name != NULL) { - backend_cfg = find_db_backend_config(config.backends, - backend_name); - if (backend_cfg == NULL) { - logthing(LOGTHING_CRITICAL, - "Couldn't find configuration for %s backend", - backend_name); - stacked_cleanupdb(dbctx); - return NULL; - } - logthing(LOGTHING_INFO, "Loading stacked backend: %s", - backend_cfg->name); - - backend = config.dbinit(backend_cfg, readonly); - privctx->backends = lladdend(privctx->backends, backend); - - backend_name = strtok_r(NULL, ":", &saveptr); - } - - if (privctx->backends != NULL) { - dbctx->cleanupdb = stacked_cleanupdb; - dbctx->starttrans = stacked_starttrans; - dbctx->endtrans = stacked_endtrans; - dbctx->fetch_key_id = stacked_fetch_key_id; - dbctx->fetch_key_fp = stacked_fetch_key_fp; - dbctx->fetch_key_text = stacked_fetch_key_text; - dbctx->fetch_key_skshash = stacked_fetch_key_skshash; - dbctx->store_key = stacked_store_key; - dbctx->update_keys = stacked_update_keys; - dbctx->delete_key = stacked_delete_key; - dbctx->getkeysigs = stacked_getkeysigs; - dbctx->cached_getkeysigs = stacked_cached_getkeysigs; - dbctx->keyid2uid = stacked_keyid2uid; - dbctx->iterate_keys = stacked_iterate_keys; - } - - return dbctx; -}