2 * keydb_db2.c - Routines to store and fetch keys in a DB2 file (a la pksd)
4 * Copyright 2002-2004 Jonathan McDowell <noodles@earth.li>
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc., 51
17 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include <sys/types.h>
30 #include "charfuncs.h"
34 #include "keystructs.h"
37 #include "onak-conf.h"
40 #define KEYDB_KEYID_BYTES 4
43 * db2_numdb - The number of database files we have.
45 static int db2_numdb = 16;
48 * db2_keydbfiles - An array of DB structs for our key database files.
50 static DB **db2_keydbfiles = NULL;
53 * db2_env - Database environment variable.
55 static DB_ENV db2_env;
60 * keyid's are 8 bytes, msb first. so start from the end. use 16
61 * bits, since that's enough to divide by any small number of db files.
63 unsigned char *keydata = (unsigned char *) key->data;
64 unsigned long keyidnum;
66 keyidnum = (keydata[KEYDB_KEYID_BYTES-2]<<8)|keydata[KEYDB_KEYID_BYTES-1];
67 return(db2_keydbfiles[keyidnum % db2_numdb]);
71 * initdb - Initialize the key database.
73 * This function should be called before any of the other functions in
74 * this file are called in order to allow the DB to be initialized ready
77 void initdb(bool readonly)
86 snprintf(buf, sizeof(buf) - 1, "%s/num_keydb", config.db_dir);
87 numdb = fopen(buf, "r");
89 if (fgets(buf, sizeof(buf), numdb) != NULL) {
90 db2_numdb = atoi(buf);
94 logthing(LOGTHING_ERROR, "Couldn't open num_keydb: %s",
98 memset(&db2_env, 0, sizeof(db2_env));
101 * Tunable param. Just using what pksd does for the moment. Bigger uses
102 * more memory but improves performance. Bigger than physical memory
105 db2_env.mp_size = 20 * 1024 * 1024;
107 ret = db_appinit(config.db_dir, NULL,
108 &db2_env, DB_INIT_MPOOL|DB_INIT_LOCK);
110 db2_keydbfiles = (DB **) malloc(sizeof (DB *) * db2_numdb);
111 memset(&keydbinfo, 0, sizeof(keydbinfo));
112 keydbinfo.db_pagesize = 8192;
113 for (i = 0; i < db2_numdb; i++) {
114 db2_keydbfiles[i] = NULL;
115 snprintf(keydbname, 19, "keydb%03d", i);
116 ret = db_open(keydbname, DB_HASH, DB_RDONLY, 0644,
117 &db2_env, &keydbinfo,
120 logthing(LOGTHING_CRITICAL,
121 "Error opening db file %d (errno %d)",
127 logthing(LOGTHING_CRITICAL, "Error initializing db (%d).",
134 * cleanupdb - De-initialize the key database.
136 * This function should be called upon program exit to allow the DB to
137 * cleanup after itself.
143 for (i = 0; i < db2_numdb; i++) {
144 if (db2_keydbfiles[i] != NULL) {
145 (*(db2_keydbfiles[i]->close))(db2_keydbfiles[i], 0);
146 db2_keydbfiles[i] = NULL;
150 db_appexit(&db2_env);
154 * starttrans - Start a transaction.
156 * Start a transaction. Intended to be used if we're about to perform many
157 * operations on the database to help speed it all up, or if we want
158 * something to only succeed if all relevant operations are successful.
160 bool starttrans(void)
166 * endtrans - End a transaction.
168 * Ends a transaction.
176 * fetch_key - Given a keyid fetch the key from storage.
177 * @keyid: The keyid to fetch.
178 * @publickey: A pointer to a structure to return the key in.
179 * @intrans: If we're already in a transaction.
181 * We use the hex representation of the keyid as the filename to fetch the
182 * key from. The key is stored in the file as a binary OpenPGP stream of
183 * packets, so we can just use read_openpgp_stream() to read the packets
184 * in and then parse_keys() to parse the packets into a publickey
187 int fetch_key(uint64_t keyid, struct openpgp_publickey **publickey,
190 struct openpgp_packet_list *packets = NULL;
193 char id[KEYDB_KEYID_BYTES];
194 struct buffer_ctx fetchbuf;
196 memset(&key, 0, sizeof(key));
197 memset(&data, 0, sizeof(data));
199 id[0] = (keyid >> 24) & 0xFF;
200 id[1] = (keyid >> 16) & 0xFF;
201 id[2] = (keyid >> 8) & 0xFF;
202 id[3] = keyid & 0xFF;
205 key.size = KEYDB_KEYID_BYTES;
207 ret = (*(keydb(&key)->get))(keydb(&key), NULL, &key, &data, 0);
209 fetchbuf.buffer = data.data;
211 fetchbuf.size = data.size;
212 read_openpgp_stream(buffer_fetchchar, &fetchbuf, &packets, 0);
213 parse_keys(packets, publickey);
214 free_packet_list(packets);
222 * fetch_key_text - Trys to find the keys that contain the supplied text.
223 * @search: The text to search for.
224 * @publickey: A pointer to a structure to return the key in.
226 * This function searches for the supplied text and returns the keys that
229 int fetch_key_text(const char *search, struct openpgp_publickey **publickey)
235 * store_key - Takes a key and stores it.
236 * @publickey: A pointer to the public key to store.
237 * @intrans: If we're already in a transaction.
238 * @update: If true the key exists and should be updated.
240 * Again we just use the hex representation of the keyid as the filename
241 * to store the key to. We flatten the public key to a list of OpenPGP
242 * packets and then use write_openpgp_stream() to write the stream out to
245 int store_key(struct openpgp_publickey *publickey, bool intrans, bool update)
251 * delete_key - Given a keyid delete the key from storage.
252 * @keyid: The keyid to delete.
253 * @intrans: If we're already in a transaction.
255 * This function deletes a public key from whatever storage mechanism we
256 * are using. Returns 0 if the key existed.
258 int delete_key(uint64_t keyid, bool intrans)
264 * iterate_keys - call a function once for each key in the db.
265 * @iterfunc: The function to call.
266 * @ctx: A context pointer
268 * Calls iterfunc once for each key in the database. ctx is passed
269 * unaltered to iterfunc. This function is intended to aid database dumps
270 * and statistic calculations.
272 * Returns the number of keys we iterated over.
274 int iterate_keys(void (*iterfunc)(void *ctx, struct openpgp_publickey *key),
281 * Include the basic keydb routines.
283 #define NEED_KEYID2UID 1
284 #define NEED_GETKEYSIGS 1
285 #define NEED_GETFULLKEYID 1
286 #define NEED_UPDATEKEYS 1