X-Git-Url: http://the.earth.li/gitweb/?a=blobdiff_plain;f=keydb_db4.c;h=f4fffa58849b90e7c5f4f0cc93e28b05f29d1300;hb=8d910718e5f13444b2948396564a809b2307f0cf;hp=04d727c6eb8df6df3778f98c67b070686243491e;hpb=5e1b22d763640c4d7a09d07920403d8d491b4410;p=onak.git diff --git a/keydb_db4.c b/keydb_db4.c index 04d727c..f4fffa5 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); @@ -309,7 +330,7 @@ static void db4_initdb(bool readonly) FILE *numdb = NULL; int ret = 0; int i = 0; - u_int32_t flags = 0; + uint32_t flags = 0; struct stat statbuf; int maxlocks; @@ -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(); } @@ -641,7 +683,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; @@ -887,7 +963,7 @@ static int db4_delete_key(uint64_t keyid, bool intrans) worddb_data[ 8] = (keyid >> 24) & 0xFF; worddb_data[ 9] = (keyid >> 16) & 0xFF; worddb_data[10] = (keyid >> 8) & 0xFF; - worddb_data[11] = keyid & 0xFF; + worddb_data[11] = keyid & 0xFF; ret = cursor->c_get(cursor, &key, @@ -896,17 +972,14 @@ static int db4_delete_key(uint64_t keyid, bool intrans) if (ret == 0) { ret = cursor->c_del(cursor, 0); - if (ret != 0) { - logthing(LOGTHING_ERROR, - "Problem deleting word: %s", - db_strerror(ret)); - } } if (ret != 0) { logthing(LOGTHING_ERROR, - "Problem deleting word: %s", - db_strerror(ret)); + "Problem deleting word: %s " + "(0x%016" PRIX64 ")", + db_strerror(ret), + keyid); if (ret == DB_LOCK_DEADLOCK) { deadlock = true; } @@ -915,6 +988,42 @@ static int db4_delete_key(uint64_t keyid, bool intrans) ret = cursor->c_close(cursor); cursor = NULL; + ret = skshashdb->cursor(skshashdb, + txn, + &cursor, + 0); /* flags */ + get_skshash(publickey, &hash); + + memset(&key, 0, sizeof(key)); + memset(&data, 0, sizeof(data)); + key.data = hash.hash; + key.size = sizeof(hash.hash); + data.data = &keyid; + data.size = sizeof(keyid); + + ret = cursor->c_get(cursor, + &key, + &data, + DB_GET_BOTH); + + if (ret == 0) { + ret = cursor->c_del(cursor, 0); + } + + if (ret != 0) { + logthing(LOGTHING_ERROR, + "Problem deleting skshash: %s " + "(0x%016" PRIX64 ")", + db_strerror(ret), + keyid); + if (ret == DB_LOCK_DEADLOCK) { + deadlock = true; + } + } + + ret = cursor->c_close(cursor); + cursor = NULL; + /* * Free our UID and word lists. */ @@ -951,17 +1060,14 @@ static int db4_delete_key(uint64_t keyid, bool intrans) if (ret == 0) { ret = cursor->c_del(cursor, 0); - if (ret != 0) { - logthing(LOGTHING_ERROR, - "Problem deleting short keyid: %s", - db_strerror(ret)); - } } if (ret != 0) { logthing(LOGTHING_ERROR, - "Problem deleting short keyid: %s", - db_strerror(ret)); + "Problem deleting short keyid: %s " + "(0x%016" PRIX64 ")", + db_strerror(ret), + keyid); if (ret == DB_LOCK_DEADLOCK) { deadlock = true; } @@ -970,6 +1076,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)); @@ -986,18 +1107,14 @@ static int db4_delete_key(uint64_t keyid, bool intrans) if (ret == 0) { ret = cursor->c_del(cursor, 0); - if (ret != 0) { - logthing(LOGTHING_ERROR, - "Problem deleting short" - " keyid: %s", - db_strerror(ret)); - } } if (ret != 0) { logthing(LOGTHING_ERROR, - "Problem deleting short keyid: %s", - db_strerror(ret)); + "Problem deleting short keyid: %s " + "(0x%016" PRIX64 ")", + db_strerror(ret), + keyid); if (ret == DB_LOCK_DEADLOCK) { deadlock = true; } @@ -1012,38 +1129,6 @@ static int db4_delete_key(uint64_t keyid, bool intrans) } - if (!deadlock) { - get_skshash(publickey, &hash); - - memset(&key, 0, sizeof(key)); - memset(&data, 0, sizeof(data)); - key.data = hash.hash; - key.size = sizeof(hash.hash); - data.data = &keyid; - data.size = sizeof(keyid); - - ret = cursor->c_get(cursor, - &key, - &data, - DB_GET_BOTH); - - if (ret == 0) { - ret = cursor->c_del(cursor, 0); - } - - if (ret != 0) { - logthing(LOGTHING_ERROR, - "Problem deleting skshash: %s", - db_strerror(ret)); - if (ret == DB_LOCK_DEADLOCK) { - deadlock = true; - } - } - - ret = cursor->c_close(cursor); - cursor = NULL; - } - if (!deadlock) { key.data = &keyid; key.size = sizeof(keyid); @@ -1095,7 +1180,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(); @@ -1258,6 +1346,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));