X-Git-Url: http://the.earth.li/gitweb/?a=blobdiff_plain;f=keydb_db4.c;h=dae8a2a91f8f9ad830908baa82a405b500d7f559;hb=cab77e4ffc25ba4fb2e5289beaa47c7d915de942;hp=802903caed6b8c373ab0ece3843494c19ebb74e5;hpb=d393825d164f31fe0194221b6ed90f3c320d8d44;p=onak.git diff --git a/keydb_db4.c b/keydb_db4.c index 802903c..dae8a2a 100644 --- a/keydb_db4.c +++ b/keydb_db4.c @@ -74,6 +74,11 @@ static DB *id32db = NULL; */ static DB *skshashdb = NULL; +/** + * subkeydb - our connection to the subkey ID lookup database. + */ +static DB *subkeydb = NULL; + /** * txn - our current transaction id. */ @@ -175,6 +180,10 @@ static void db4_cleanupdb(void) if (dbenv != NULL) { dbenv->txn_checkpoint(dbenv, 0, 0, 0); + if (subkeydb != NULL) { + subkeydb->close(subkeydb, 0); + subkeydb = NULL; + } if (skshashdb != NULL) { skshashdb->close(skshashdb, 0); skshashdb = NULL; @@ -289,6 +298,18 @@ static int db4_upgradedb(int numdb) db_strerror(ret)); } + ret = db_create(&curdb, NULL, 0); + if (ret == 0) { + snprintf(buf, sizeof(buf) - 1, "%s/subkeydb", config.db_dir); + logthing(LOGTHING_DEBUG, "Upgrading %s", buf); + ret = curdb->upgrade(curdb, buf, 0); + curdb->close(curdb, 0); + } else { + logthing(LOGTHING_ERROR, "Error upgrading DB %s : %s", + buf, + db_strerror(ret)); + } + snprintf(buf, sizeof(buf) - 1, "%s/%s", config.db_dir, DB4_UPGRADE_FILE); unlink(buf); @@ -535,6 +556,27 @@ static void db4_initdb(bool readonly) } } + if (ret == 0) { + ret = db_create(&subkeydb, dbenv, 0); + if (ret != 0) { + logthing(LOGTHING_CRITICAL, "db_create: %s", + db_strerror(ret)); + } + } + + if (ret == 0) { + ret = subkeydb->open(subkeydb, txn, "subkeydb", "subkeydb", + DB_HASH, + flags, + 0664); + if (ret != 0) { + logthing(LOGTHING_CRITICAL, + "Error opening subkey database: %s (%s)", + "subkeydb", + db_strerror(ret)); + } + } + if (txn != NULL) { db4_endtrans(); } @@ -599,7 +641,7 @@ static uint64_t db4_getfullkeyid(uint64_t keyid) } /** - * fetch_key - Given a keyid fetch the key from storage. + * fetch_key_id - Given a keyid fetch the key from storage. * @keyid: The keyid to fetch. * @publickey: A pointer to a structure to return the key in. * @intrans: If we're already in a transaction. @@ -610,7 +652,8 @@ static uint64_t db4_getfullkeyid(uint64_t keyid) * in and then parse_keys() to parse the packets into a publickey * structure. */ -static int db4_fetch_key(uint64_t keyid, struct openpgp_publickey **publickey, +static int db4_fetch_key_id(uint64_t keyid, + struct openpgp_publickey **publickey, bool intrans) { struct openpgp_packet_list *packets = NULL; @@ -641,7 +684,41 @@ static int db4_fetch_key(uint64_t keyid, struct openpgp_publickey **publickey, &key, &data, 0); /* flags*/ - + + if (ret == DB_NOTFOUND) { + /* If we didn't find the key ID see if it's a subkey ID */ + memset(&key, 0, sizeof(key)); + memset(&data, 0, sizeof(data)); + data.size = 0; + data.data = NULL; + key.size = sizeof(keyid); + key.data = &keyid; + + ret = subkeydb->get(subkeydb, + txn, + &key, + &data, + 0); /* flags*/ + + if (ret == 0) { + /* We got a subkey match; retrieve the actual key */ + keyid = *(uint64_t *) data.data; + + memset(&key, 0, sizeof(key)); + memset(&data, 0, sizeof(data)); + data.size = 0; + data.data = NULL; + key.size = sizeof(keyid); + key.data = &keyid; + + ret = keydb(keyid)->get(keydb(keyid), + txn, + &key, + &data, + 0); /* flags*/ + } + } + if (ret == 0) { fetchbuf.buffer = data.data; fetchbuf.offset = 0; @@ -764,7 +841,7 @@ static int db4_fetch_key_text(const char *search, db4_starttrans(); for (i = 0; i < keylist.count; i++) { - numkeys += db4_fetch_key(keylist.keys[i], + numkeys += db4_fetch_key_id(keylist.keys[i], publickey, true); } @@ -813,7 +890,7 @@ static int db4_fetch_key_skshash(const struct skshash *hash, ret = cursor->c_close(cursor); cursor = NULL; - return db4_fetch_key(keyid, publickey, false); + return db4_fetch_key_id(keyid, publickey, false); } /** @@ -845,7 +922,7 @@ static int db4_delete_key(uint64_t keyid, bool intrans) db4_starttrans(); } - db4_fetch_key(keyid, &publickey, true); + db4_fetch_key_id(keyid, &publickey, true); /* * Walk through the uids removing the words from the worddb. @@ -1000,6 +1077,21 @@ static int db4_delete_key(uint64_t keyid, bool intrans) subkeyids = keysubkeys(publickey); i = 0; while (subkeyids != NULL && subkeyids[i] != 0) { + memset(&key, 0, sizeof(key)); + key.data = &subkeyids[i]; + key.size = sizeof(subkeyids[i]); + subkeydb->del(subkeydb, txn, &key, 0); + if (ret != 0) { + logthing(LOGTHING_ERROR, + "Problem deleting subkey id: %s " + "(0x%016" PRIX64 ")", + db_strerror(ret), + keyid); + if (ret == DB_LOCK_DEADLOCK) { + deadlock = true; + } + } + shortkeyid = subkeyids[i++] & 0xFFFFFFFF; memset(&key, 0, sizeof(key)); @@ -1089,7 +1181,10 @@ static int db4_store_key(struct openpgp_publickey *publickey, bool intrans, bool deadlock = false; struct skshash hash; - keyid = get_keyid(publickey); + if (get_keyid(publickey, &keyid) != ONAK_E_OK) { + logthing(LOGTHING_ERROR, "Couldn't find key ID for key."); + return 0; + } if (!intrans) { db4_starttrans(); @@ -1252,6 +1347,29 @@ static int db4_store_key(struct openpgp_publickey *publickey, bool intrans, subkeyids = keysubkeys(publickey); i = 0; while (subkeyids != NULL && subkeyids[i] != 0) { + /* Store the subkey ID -> main key ID mapping */ + memset(&key, 0, sizeof(key)); + memset(&data, 0, sizeof(data)); + key.data = &subkeyids[i]; + key.size = sizeof(subkeyids[i]); + data.data = &keyid; + data.size = sizeof(keyid); + + ret = subkeydb->put(subkeydb, + txn, + &key, + &data, + 0); + if (ret != 0) { + logthing(LOGTHING_ERROR, + "Problem storing subkey keyid: %s", + db_strerror(ret)); + if (ret == DB_LOCK_DEADLOCK) { + deadlock = true; + } + } + + /* Store the short subkey ID -> main key ID mapping */ shortkeyid = subkeyids[i++] & 0xFFFFFFFF; memset(&key, 0, sizeof(key)); @@ -1384,6 +1502,7 @@ static int db4_iterate_keys(void (*iterfunc)(void *ctx, #define NEED_GETKEYSIGS 1 #define NEED_KEYID2UID 1 #define NEED_UPDATEKEYS 1 +#define NEED_GET_FP 1 #include "keydb.c" struct dbfuncs keydb_db4_funcs = { @@ -1391,7 +1510,8 @@ struct dbfuncs keydb_db4_funcs = { .cleanupdb = db4_cleanupdb, .starttrans = db4_starttrans, .endtrans = db4_endtrans, - .fetch_key = db4_fetch_key, + .fetch_key_id = db4_fetch_key_id, + .fetch_key_fp = generic_fetch_key_fp, .fetch_key_text = db4_fetch_key_text, .fetch_key_skshash = db4_fetch_key_skshash, .store_key = db4_store_key,