X-Git-Url: https://git.sommitrealweird.co.uk/onak.git/blobdiff_plain/66748d60571a5ebbbc0f0cb84c061f9c62f5aef7..59e5def499b3e9ae3587ebae2bef8794a1df34ea:/keydb_keyd.c?ds=sidebyside diff --git a/keydb_keyd.c b/keydb_keyd.c index 10716ee..e5d46a3 100644 --- a/keydb_keyd.c +++ b/keydb_keyd.c @@ -39,11 +39,11 @@ static int keyd_fd = -1; * this file are called in order to allow the DB to be initialized ready * for access. */ -void initdb(bool readonly) +static void keyd_initdb(bool readonly) { struct sockaddr_un sock; - int cmd = KEYD_CMD_UNKNOWN; - int reply = KEYD_REPLY_UNKNOWN_CMD; + uint32_t cmd = KEYD_CMD_UNKNOWN; + uint32_t reply = KEYD_REPLY_UNKNOWN_CMD; ssize_t count; keyd_fd = socket(PF_UNIX, SOCK_STREAM, 0); @@ -101,12 +101,25 @@ void initdb(bool readonly) * This function should be called upon program exit to allow the DB to * cleanup after itself. */ -void cleanupdb(void) +static void keyd_cleanupdb(void) { + uint32_t cmd = KEYD_CMD_CLOSE; + + if (write(keyd_fd, &cmd, sizeof(cmd)) != sizeof(cmd)) { + logthing(LOGTHING_CRITICAL, + "Couldn't send close cmd: %s (%d)", + strerror(errno), + errno); + } + if (shutdown(keyd_fd, SHUT_RDWR) < 0) { logthing(LOGTHING_NOTICE, "Error shutting down socket: %d", errno); } + if (close(keyd_fd) < 0) { + logthing(LOGTHING_NOTICE, "Error closing down socket: %d", + errno); + } keyd_fd = -1; return; @@ -120,7 +133,7 @@ void cleanupdb(void) * operations on the database to help speed it all up, or if we want * something to only succeed if all relevant operations are successful. */ -bool starttrans(void) +static bool keyd_starttrans(void) { return true; } @@ -130,7 +143,7 @@ bool starttrans(void) * * Ends a transaction. */ -void endtrans(void) +static void keyd_endtrans(void) { return; } @@ -146,12 +159,12 @@ void endtrans(void) * * TODO: What about keyid collisions? Should we use fingerprint instead? */ -int fetch_key(uint64_t keyid, struct openpgp_publickey **publickey, +static int keyd_fetch_key(uint64_t keyid, struct openpgp_publickey **publickey, bool intrans) { struct buffer_ctx keybuf; struct openpgp_packet_list *packets = NULL; - int cmd = KEYD_CMD_GET; + uint32_t cmd = KEYD_CMD_GET; ssize_t bytes = 0; ssize_t count = 0; @@ -188,6 +201,27 @@ int fetch_key(uint64_t keyid, struct openpgp_publickey **publickey, return (count > 0) ? 1 : 0; } +/** +* delete_key - Given a keyid delete the key from storage. +* @keyid: The keyid to delete. +* @intrans: If we're already in a transaction. +* +* This function deletes a public key from whatever storage mechanism we +* are using. Returns 0 if the key existed. +*/ +static int keyd_delete_key(uint64_t keyid, bool intrans) +{ + uint32_t cmd = KEYD_CMD_DELETE; + + write(keyd_fd, &cmd, sizeof(cmd)); + read(keyd_fd, &cmd, sizeof(cmd)); + if (cmd == KEYD_REPLY_OK) { + write(keyd_fd, &keyid, sizeof(keyid)); + } + + return 0; +} + /** * store_key - Takes a key and stores it. * @publickey: A pointer to the public key to store. @@ -202,19 +236,20 @@ int fetch_key(uint64_t keyid, struct openpgp_publickey **publickey, * TODO: Do we store multiple keys of the same id? Or only one and replace * it? */ -int store_key(struct openpgp_publickey *publickey, bool intrans, bool update) +static int keyd_store_key(struct openpgp_publickey *publickey, bool intrans, + bool update) { struct buffer_ctx keybuf; struct openpgp_packet_list *packets = NULL; struct openpgp_packet_list *list_end = NULL; struct openpgp_publickey *next = NULL; - int cmd = KEYD_CMD_STORE; + uint32_t cmd = KEYD_CMD_STORE; uint64_t keyid; keyid = get_keyid(publickey); if (update) { - delete_key(keyid, false); + keyd_delete_key(keyid, false); } write(keyd_fd, &cmd, sizeof(cmd)); @@ -246,27 +281,6 @@ int store_key(struct openpgp_publickey *publickey, bool intrans, bool update) return 0; } -/** - * delete_key - Given a keyid delete the key from storage. - * @keyid: The keyid to delete. - * @intrans: If we're already in a transaction. - * - * This function deletes a public key from whatever storage mechanism we - * are using. Returns 0 if the key existed. - */ -int delete_key(uint64_t keyid, bool intrans) -{ - int cmd = KEYD_CMD_DELETE; - - write(keyd_fd, &cmd, sizeof(cmd)); - read(keyd_fd, &cmd, sizeof(cmd)); - if (cmd == KEYD_REPLY_OK) { - write(keyd_fd, &keyid, sizeof(keyid)); - } - - return 0; -} - /** * fetch_key_text - Trys to find the keys that contain the supplied text. * @search: The text to search for. @@ -275,11 +289,12 @@ int delete_key(uint64_t keyid, bool intrans) * This function searches for the supplied text and returns the keys that * contain it. */ -int fetch_key_text(const char *search, struct openpgp_publickey **publickey) +static int keyd_fetch_key_text(const char *search, + struct openpgp_publickey **publickey) { struct buffer_ctx keybuf; struct openpgp_packet_list *packets = NULL; - int cmd = KEYD_CMD_GETTEXT; + uint32_t cmd = KEYD_CMD_GETTEXT; ssize_t bytes = 0; ssize_t count = 0; @@ -327,9 +342,9 @@ int fetch_key_text(const char *search, struct openpgp_publickey **publickey) * This function maps a 32bit key id to the full 64bit one. It returns the * full keyid. If the key isn't found a keyid of 0 is returned. */ -uint64_t getfullkeyid(uint64_t keyid) +static uint64_t keyd_getfullkeyid(uint64_t keyid) { - int cmd = KEYD_CMD_GETFULLKEYID; + uint32_t cmd = KEYD_CMD_GETFULLKEYID; write(keyd_fd, &cmd, sizeof(cmd)); read(keyd_fd, &cmd, sizeof(cmd)); @@ -342,20 +357,88 @@ uint64_t getfullkeyid(uint64_t keyid) } /** - * dumpdb - dump the key database - * @filenamebase: The base filename to use for the dump. + * iterate_keys - call a function once for each key in the db. + * @iterfunc: The function to call. + * @ctx: A context pointer * - * Dumps the database into one or more files, which contain pure OpenPGP - * that can be reimported into onak or gpg. filenamebase provides a base - * file name for the dump; several files may be created, all of which will - * begin with this string and then have a unique number and a .pgp - * extension. + * Calls iterfunc once for each key in the database. ctx is passed + * unaltered to iterfunc. This function is intended to aid database dumps + * and statistic calculations. + * + * Returns the number of keys we iterated over. */ -int dumpdb(char *filenamebase) +static int keyd_iterate_keys(void (*iterfunc)(void *ctx, + struct openpgp_publickey *key), void *ctx) { - return 0; + struct buffer_ctx keybuf; + struct openpgp_packet_list *packets = NULL; + struct openpgp_publickey *key = NULL; + uint32_t cmd = KEYD_CMD_KEYITER; + ssize_t bytes = 0; + ssize_t count = 0; + int numkeys = 0; + + write(keyd_fd, &cmd, sizeof(cmd)); + read(keyd_fd, &cmd, sizeof(cmd)); + if (cmd == KEYD_REPLY_OK) { + keybuf.offset = 0; + read(keyd_fd, &keybuf.size, sizeof(keybuf.size)); + while (keybuf.size > 0) { + keybuf.buffer = malloc(keybuf.size); + bytes = count = 0; + logthing(LOGTHING_TRACE, + "Getting %d bytes of key data.", + keybuf.size); + while (bytes >= 0 && count < keybuf.size) { + bytes = read(keyd_fd, &keybuf.buffer[count], + keybuf.size - count); + logthing(LOGTHING_TRACE, + "Read %d bytes.", bytes); + count += bytes; + } + read_openpgp_stream(buffer_fetchchar, &keybuf, + &packets, 0); + parse_keys(packets, &key); + + if (iterfunc != NULL && key != NULL) { + iterfunc(ctx, key); + } + + free_publickey(key); + key = NULL; + free_packet_list(packets); + packets = NULL; + free(keybuf.buffer); + keybuf.buffer = NULL; + keybuf.size = keybuf.offset = 0; + + numkeys++; + + read(keyd_fd, &keybuf.size, sizeof(keybuf.size)); + } + } + + return numkeys; } #define NEED_KEYID2UID 1 #define NEED_GETKEYSIGS 1 +#define NEED_UPDATEKEYS 1 #include "keydb.c" + +struct dbfuncs keydb_keyd_funcs = { + .initdb = keyd_initdb, + .cleanupdb = keyd_cleanupdb, + .starttrans = keyd_starttrans, + .endtrans = keyd_endtrans, + .fetch_key = keyd_fetch_key, + .fetch_key_text = keyd_fetch_key_text, + .store_key = keyd_store_key, + .update_keys = generic_update_keys, + .delete_key = keyd_delete_key, + .getkeysigs = generic_getkeysigs, + .cached_getkeysigs = generic_cached_getkeysigs, + .keyid2uid = generic_keyid2uid, + .getfullkeyid = keyd_getfullkeyid, + .iterate_keys = keyd_iterate_keys, +};