2 * keydb_keyd.c - Routines to talk to keyd backend.
4 * Copyright 2002-2004,2011 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.
25 #include <sys/socket.h>
26 #include <sys/types.h>
30 #include "charfuncs.h"
34 #include "keystructs.h"
37 #include "onak-conf.h"
41 * starttrans - Start a transaction.
43 * Start a transaction. Intended to be used if we're about to perform many
44 * operations on the database to help speed it all up, or if we want
45 * something to only succeed if all relevant operations are successful.
47 static bool keyd_starttrans(struct onak_dbctx *dbctx)
53 * endtrans - End a transaction.
57 static void keyd_endtrans(struct onak_dbctx *dbctx)
63 * fetch_key - Given a keyid fetch the key from storage.
64 * @keyid: The keyid to fetch.
65 * @publickey: A pointer to a structure to return the key in.
66 * @intrans: If we're already in a transaction.
68 * This function returns a public key from whatever storage mechanism we
71 * TODO: What about keyid collisions? Should we use fingerprint instead?
73 static int keyd_fetch_key_id(struct onak_dbctx *dbctx,
75 struct openpgp_publickey **publickey,
78 int keyd_fd = (intptr_t) dbctx->priv;
79 struct buffer_ctx keybuf;
80 struct openpgp_packet_list *packets = NULL;
81 uint32_t cmd = KEYD_CMD_GET_ID;
85 write(keyd_fd, &cmd, sizeof(cmd));
86 read(keyd_fd, &cmd, sizeof(cmd));
87 if (cmd == KEYD_REPLY_OK) {
88 write(keyd_fd, &keyid, sizeof(keyid));
90 read(keyd_fd, &keybuf.size, sizeof(keybuf.size));
91 if (keybuf.size > 0) {
92 keybuf.buffer = malloc(keybuf.size);
94 logthing(LOGTHING_TRACE,
95 "Getting %d bytes of key data.",
97 while (bytes >= 0 && count < keybuf.size) {
98 bytes = read(keyd_fd, &keybuf.buffer[count],
100 logthing(LOGTHING_TRACE,
101 "Read %d bytes.", bytes);
104 read_openpgp_stream(buffer_fetchchar, &keybuf,
106 parse_keys(packets, publickey);
107 free_packet_list(packets);
110 keybuf.buffer = NULL;
115 return (count > 0) ? 1 : 0;
118 static int keyd_fetch_key_fp(struct onak_dbctx *dbctx,
119 struct openpgp_fingerprint *fingerprint,
120 struct openpgp_publickey **publickey,
123 int keyd_fd = (intptr_t) dbctx->priv;
124 struct buffer_ctx keybuf;
125 struct openpgp_packet_list *packets = NULL;
126 uint32_t cmd = KEYD_CMD_GET_FP;
131 if (fingerprint->length > MAX_FINGERPRINT_LEN) {
135 write(keyd_fd, &cmd, sizeof(cmd));
136 read(keyd_fd, &cmd, sizeof(cmd));
137 if (cmd == KEYD_REPLY_OK) {
138 size = fingerprint->length;
139 write(keyd_fd, &size, sizeof(size));
140 write(keyd_fd, fingerprint->fp, size);
142 read(keyd_fd, &keybuf.size, sizeof(keybuf.size));
143 if (keybuf.size > 0) {
144 keybuf.buffer = malloc(keybuf.size);
146 logthing(LOGTHING_TRACE,
147 "Getting %d bytes of key data.",
149 while (bytes >= 0 && count < keybuf.size) {
150 bytes = read(keyd_fd, &keybuf.buffer[count],
151 keybuf.size - count);
152 logthing(LOGTHING_TRACE,
153 "Read %d bytes.", bytes);
156 read_openpgp_stream(buffer_fetchchar, &keybuf,
158 parse_keys(packets, publickey);
159 free_packet_list(packets);
162 keybuf.buffer = NULL;
167 return (count > 0) ? 1 : 0;
171 * delete_key - Given a keyid delete the key from storage.
172 * @keyid: The keyid to delete.
173 * @intrans: If we're already in a transaction.
175 * This function deletes a public key from whatever storage mechanism we
176 * are using. Returns 0 if the key existed.
178 static int keyd_delete_key(struct onak_dbctx *dbctx,
179 uint64_t keyid, bool intrans)
181 int keyd_fd = (intptr_t) dbctx->priv;
182 uint32_t cmd = KEYD_CMD_DELETE;
184 write(keyd_fd, &cmd, sizeof(cmd));
185 read(keyd_fd, &cmd, sizeof(cmd));
186 if (cmd == KEYD_REPLY_OK) {
187 write(keyd_fd, &keyid, sizeof(keyid));
194 * store_key - Takes a key and stores it.
195 * @publickey: A pointer to the public key to store.
196 * @intrans: If we're already in a transaction.
197 * @update: If true the key exists and should be updated.
199 * This function stores a public key in whatever storage mechanism we are
200 * using. intrans indicates if we're already in a transaction so don't
201 * need to start one. update indicates if the key already exists and is
202 * just being updated.
204 * TODO: Do we store multiple keys of the same id? Or only one and replace
207 static int keyd_store_key(struct onak_dbctx *dbctx,
208 struct openpgp_publickey *publickey, bool intrans,
211 int keyd_fd = (intptr_t) dbctx->priv;
212 struct buffer_ctx keybuf;
213 struct openpgp_packet_list *packets = NULL;
214 struct openpgp_packet_list *list_end = NULL;
215 struct openpgp_publickey *next = NULL;
216 uint32_t cmd = KEYD_CMD_STORE;
219 if (get_keyid(publickey, &keyid) != ONAK_E_OK) {
220 logthing(LOGTHING_ERROR, "Couldn't find key ID for key.");
225 keyd_delete_key(dbctx, keyid, false);
228 write(keyd_fd, &cmd, sizeof(cmd));
229 read(keyd_fd, &cmd, sizeof(cmd));
230 if (cmd == KEYD_REPLY_OK) {
233 keybuf.buffer = malloc(keybuf.size);
235 next = publickey->next;
236 publickey->next = NULL;
237 flatten_publickey(publickey,
240 publickey->next = next;
242 write_openpgp_stream(buffer_putchar, &keybuf, packets);
243 logthing(LOGTHING_TRACE, "Sending %d bytes.", keybuf.offset);
244 write(keyd_fd, &keybuf.offset, sizeof(keybuf.offset));
245 write(keyd_fd, keybuf.buffer, keybuf.offset);
247 free_packet_list(packets);
248 packets = list_end = NULL;
250 keybuf.buffer = NULL;
251 keybuf.size = keybuf.offset = 0;
258 * fetch_key_text - Trys to find the keys that contain the supplied text.
259 * @search: The text to search for.
260 * @publickey: A pointer to a structure to return the key in.
262 * This function searches for the supplied text and returns the keys that
265 static int keyd_fetch_key_text(struct onak_dbctx *dbctx,
267 struct openpgp_publickey **publickey)
269 int keyd_fd = (intptr_t) dbctx->priv;
270 struct buffer_ctx keybuf;
271 struct openpgp_packet_list *packets = NULL;
272 uint32_t cmd = KEYD_CMD_GET_TEXT;
276 write(keyd_fd, &cmd, sizeof(cmd));
277 read(keyd_fd, &cmd, sizeof(cmd));
278 if (cmd == KEYD_REPLY_OK) {
279 bytes = strlen(search);
280 write(keyd_fd, &bytes, sizeof(bytes));
281 write(keyd_fd, search, bytes);
283 read(keyd_fd, &keybuf.size, sizeof(keybuf.size));
284 if (keybuf.size > 0) {
285 keybuf.buffer = malloc(keybuf.size);
287 logthing(LOGTHING_TRACE,
288 "Getting %d bytes of key data.",
290 while (bytes >= 0 && count < keybuf.size) {
291 bytes = read(keyd_fd, &keybuf.buffer[count],
292 keybuf.size - count);
293 logthing(LOGTHING_TRACE,
294 "Read %d bytes.", bytes);
297 read_openpgp_stream(buffer_fetchchar, &keybuf,
299 parse_keys(packets, publickey);
300 free_packet_list(packets);
303 keybuf.buffer = NULL;
308 return (count > 0) ? 1 : 0;
313 static int keyd_fetch_key_skshash(struct onak_dbctx *dbctx,
314 const struct skshash *hash,
315 struct openpgp_publickey **publickey)
317 int keyd_fd = (intptr_t) dbctx->priv;
318 struct buffer_ctx keybuf;
319 struct openpgp_packet_list *packets = NULL;
320 uint32_t cmd = KEYD_CMD_GET_SKSHASH;
324 write(keyd_fd, &cmd, sizeof(cmd));
325 read(keyd_fd, &cmd, sizeof(cmd));
326 if (cmd == KEYD_REPLY_OK) {
327 write(keyd_fd, hash->hash, sizeof(hash->hash));
329 read(keyd_fd, &keybuf.size, sizeof(keybuf.size));
330 if (keybuf.size > 0) {
331 keybuf.buffer = malloc(keybuf.size);
333 logthing(LOGTHING_TRACE,
334 "Getting %d bytes of key data.",
336 while (bytes >= 0 && count < keybuf.size) {
337 bytes = read(keyd_fd, &keybuf.buffer[count],
338 keybuf.size - count);
339 logthing(LOGTHING_TRACE,
340 "Read %d bytes.", bytes);
343 read_openpgp_stream(buffer_fetchchar, &keybuf,
345 parse_keys(packets, publickey);
346 free_packet_list(packets);
349 keybuf.buffer = NULL;
354 return (count > 0) ? 1 : 0;
359 * getfullkeyid - Maps a 32bit key id to a 64bit one.
360 * @keyid: The 32bit keyid.
362 * This function maps a 32bit key id to the full 64bit one. It returns the
363 * full keyid. If the key isn't found a keyid of 0 is returned.
365 static uint64_t keyd_getfullkeyid(struct onak_dbctx *dbctx, uint64_t keyid)
367 int keyd_fd = (intptr_t) dbctx->priv;
368 uint32_t cmd = KEYD_CMD_GETFULLKEYID;
370 write(keyd_fd, &cmd, sizeof(cmd));
371 read(keyd_fd, &cmd, sizeof(cmd));
372 if (cmd == KEYD_REPLY_OK) {
373 write(keyd_fd, &keyid, sizeof(keyid));
374 read(keyd_fd, &cmd, sizeof(cmd));
375 if (cmd != sizeof(keyid)) {
378 read(keyd_fd, &keyid, sizeof(keyid));
385 * iterate_keys - call a function once for each key in the db.
386 * @iterfunc: The function to call.
387 * @ctx: A context pointer
389 * Calls iterfunc once for each key in the database. ctx is passed
390 * unaltered to iterfunc. This function is intended to aid database dumps
391 * and statistic calculations.
393 * Returns the number of keys we iterated over.
395 static int keyd_iterate_keys(struct onak_dbctx *dbctx,
396 void (*iterfunc)(void *ctx,
397 struct openpgp_publickey *key), void *ctx)
399 int keyd_fd = (intptr_t) dbctx->priv;
400 struct buffer_ctx keybuf;
401 struct openpgp_packet_list *packets = NULL;
402 struct openpgp_publickey *key = NULL;
403 uint32_t cmd = KEYD_CMD_KEYITER;
408 write(keyd_fd, &cmd, sizeof(cmd));
409 read(keyd_fd, &cmd, sizeof(cmd));
410 if (cmd == KEYD_REPLY_OK) {
412 read(keyd_fd, &keybuf.size, sizeof(keybuf.size));
413 while (keybuf.size > 0) {
414 keybuf.buffer = malloc(keybuf.size);
416 logthing(LOGTHING_TRACE,
417 "Getting %d bytes of key data.",
419 while (bytes >= 0 && count < keybuf.size) {
420 bytes = read(keyd_fd, &keybuf.buffer[count],
421 keybuf.size - count);
422 logthing(LOGTHING_TRACE,
423 "Read %d bytes.", bytes);
426 read_openpgp_stream(buffer_fetchchar, &keybuf,
428 parse_keys(packets, &key);
430 if (iterfunc != NULL && key != NULL) {
436 free_packet_list(packets);
439 keybuf.buffer = NULL;
440 keybuf.size = keybuf.offset = 0;
444 read(keyd_fd, &keybuf.size, sizeof(keybuf.size));
451 #define NEED_KEYID2UID 1
452 #define NEED_GETKEYSIGS 1
453 #define NEED_UPDATEKEYS 1
457 * cleanupdb - De-initialize the key database.
459 * This function should be called upon program exit to allow the DB to
460 * cleanup after itself.
462 static void keyd_cleanupdb(struct onak_dbctx *dbctx)
464 int keyd_fd = (intptr_t) dbctx->priv;
465 uint32_t cmd = KEYD_CMD_CLOSE;
467 if (write(keyd_fd, &cmd, sizeof(cmd)) != sizeof(cmd)) {
468 logthing(LOGTHING_CRITICAL,
469 "Couldn't send close cmd: %s (%d)",
474 if (read(keyd_fd, &cmd, sizeof(cmd)) != sizeof(cmd)) {
475 logthing(LOGTHING_CRITICAL,
476 "Couldn't read close cmd reply: %s (%d)",
479 } else if (cmd != KEYD_REPLY_OK) {
480 logthing(LOGTHING_CRITICAL,
481 "Got bad reply to KEYD_CMD_CLOSE: %d", cmd);
484 if (shutdown(keyd_fd, SHUT_RDWR) < 0) {
485 logthing(LOGTHING_NOTICE, "Error shutting down socket: %d",
488 if (close(keyd_fd) < 0) {
489 logthing(LOGTHING_NOTICE, "Error closing down socket: %d",
499 * initdb - Initialize the key database.
500 * @readonly: If we'll only be reading the DB, not writing to it.
502 * This function should be called before any of the other functions in
503 * this file are called in order to allow the DB to be initialized ready
506 struct onak_dbctx *keydb_keyd_init(bool readonly)
508 struct sockaddr_un sock;
509 uint32_t cmd = KEYD_CMD_UNKNOWN;
510 uint32_t reply = KEYD_REPLY_UNKNOWN_CMD;
513 struct onak_dbctx *dbctx;
515 dbctx = malloc(sizeof(*dbctx));
520 keyd_fd = socket(PF_UNIX, SOCK_STREAM, 0);
522 logthing(LOGTHING_CRITICAL,
523 "Couldn't open socket: %s (%d)",
529 sock.sun_family = AF_UNIX;
530 snprintf(sock.sun_path, sizeof(sock.sun_path) - 1, "%s/%s",
533 if (connect(keyd_fd, (struct sockaddr *) &sock, sizeof(sock)) < 0) {
534 logthing(LOGTHING_CRITICAL,
535 "Couldn't connect to socket %s: %s (%d)",
542 cmd = KEYD_CMD_VERSION;
543 if (write(keyd_fd, &cmd, sizeof(cmd)) != sizeof(cmd)) {
544 logthing(LOGTHING_CRITICAL,
545 "Couldn't write version cmd: %s (%d)",
549 count = read(keyd_fd, &reply, sizeof(reply));
550 if (count == sizeof(reply) && reply == KEYD_REPLY_OK) {
551 count = read(keyd_fd, &reply, sizeof(reply));
552 if (count != sizeof(reply) || reply != sizeof(reply)) {
553 logthing(LOGTHING_CRITICAL,
554 "Error! Unexpected keyd version "
556 reply, sizeof(reply));
560 count = read(keyd_fd, &reply, sizeof(reply));
561 if (count != sizeof(reply)) {
562 logthing(LOGTHING_CRITICAL,
563 "Error! Unexpected keyd version "
565 count, sizeof(reply));
568 logthing(LOGTHING_DEBUG,
569 "keyd protocol version %d",
571 if (reply != keyd_version) {
572 logthing(LOGTHING_CRITICAL,
573 "Error! keyd protocol version "
574 "mismatch. (us = %d, it = %d)",
575 keyd_version, reply);
580 dbctx->priv = (void *) (intptr_t) keyd_fd;
581 dbctx->cleanupdb = keyd_cleanupdb;
582 dbctx->starttrans = keyd_starttrans;
583 dbctx->endtrans = keyd_endtrans;
584 dbctx->fetch_key_id = keyd_fetch_key_id;
585 dbctx->fetch_key_fp = keyd_fetch_key_fp;
586 dbctx->fetch_key_text = keyd_fetch_key_text;
587 dbctx->fetch_key_skshash = keyd_fetch_key_skshash;
588 dbctx->store_key = keyd_store_key;
589 dbctx->update_keys = generic_update_keys;
590 dbctx->delete_key = keyd_delete_key;
591 dbctx->getkeysigs = generic_getkeysigs;
592 dbctx->cached_getkeysigs = generic_cached_getkeysigs;
593 dbctx->keyid2uid = generic_keyid2uid;
594 dbctx->getfullkeyid = keyd_getfullkeyid;
595 dbctx->iterate_keys = keyd_iterate_keys;