X-Git-Url: https://git.sommitrealweird.co.uk/onak.git/blobdiff_plain/677db9ffe0b9ea79bb52ffacc5ccb964e261093a..26d66979a4af09a16981527e6465bc73bd00f302:/keydb_keyd.c diff --git a/keydb_keyd.c b/keydb_keyd.c index dcdcb85..0f501fe 100644 --- a/keydb_keyd.c +++ b/keydb_keyd.c @@ -1,9 +1,20 @@ /* * keydb_keyd.c - Routines to talk to keyd backend. * - * Jonathan McDowell + * Copyright 2002-2004,2011 Jonathan McDowell * - * Copyright 2004 Project Purple + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include @@ -42,8 +53,8 @@ static int keyd_fd = -1; 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); @@ -76,18 +87,25 @@ static void keyd_initdb(bool readonly) errno); } else { count = read(keyd_fd, &reply, sizeof(reply)); - if (count == sizeof(reply)) { - if (reply == KEYD_REPLY_OK) { - count = read(keyd_fd, &reply, sizeof(reply)); - logthing(LOGTHING_DEBUG, - "keyd protocol version %d", - reply); - if (reply != keyd_version) { - logthing(LOGTHING_CRITICAL, - "Error! keyd protocol version " - "mismatch. (us = %d, it = %d)", + if (count == sizeof(reply) && reply == KEYD_REPLY_OK) { + count = read(keyd_fd, &reply, sizeof(reply)); + if (count != sizeof(reply) || reply != sizeof(reply)) { + logthing(LOGTHING_CRITICAL, + "Error! Unexpected keyd version " + "length: %d != %d", + reply, sizeof(reply)); + exit(EXIT_FAILURE); + } + + count = read(keyd_fd, &reply, sizeof(reply)); + logthing(LOGTHING_DEBUG, + "keyd protocol version %d", + reply); + if (reply != keyd_version) { + logthing(LOGTHING_CRITICAL, + "Error! keyd protocol version " + "mismatch. (us = %d, it = %d)", keyd_version, reply); - } } } } @@ -103,7 +121,7 @@ static void keyd_initdb(bool readonly) */ static void keyd_cleanupdb(void) { - int cmd = KEYD_CMD_CLOSE; + uint32_t cmd = KEYD_CMD_CLOSE; if (write(keyd_fd, &cmd, sizeof(cmd)) != sizeof(cmd)) { logthing(LOGTHING_CRITICAL, @@ -111,11 +129,25 @@ static void keyd_cleanupdb(void) strerror(errno), errno); } + + if (read(keyd_fd, &cmd, sizeof(cmd)) != sizeof(cmd)) { + logthing(LOGTHING_CRITICAL, + "Couldn't read close cmd reply: %s (%d)", + strerror(errno), + errno); + } else if (cmd != KEYD_REPLY_OK) { + logthing(LOGTHING_CRITICAL, + "Got bad reply to KEYD_CMD_CLOSE: %d", cmd); + } 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; @@ -160,7 +192,7 @@ static int keyd_fetch_key(uint64_t keyid, struct openpgp_publickey **publickey, { 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; @@ -207,7 +239,7 @@ static int keyd_fetch_key(uint64_t keyid, struct openpgp_publickey **publickey, */ static int keyd_delete_key(uint64_t keyid, bool intrans) { - int cmd = KEYD_CMD_DELETE; + uint32_t cmd = KEYD_CMD_DELETE; write(keyd_fd, &cmd, sizeof(cmd)); read(keyd_fd, &cmd, sizeof(cmd)); @@ -239,7 +271,7 @@ static int keyd_store_key(struct openpgp_publickey *publickey, bool intrans, 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); @@ -290,7 +322,7 @@ static int keyd_fetch_key_text(const char *search, { 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; @@ -331,6 +363,49 @@ static int keyd_fetch_key_text(const char *search, return 0; } +static int keyd_fetch_key_skshash(const struct skshash *hash, + struct openpgp_publickey **publickey) +{ + struct buffer_ctx keybuf; + struct openpgp_packet_list *packets = NULL; + uint32_t cmd = KEYD_CMD_GETSKSHASH; + ssize_t bytes = 0; + ssize_t count = 0; + + write(keyd_fd, &cmd, sizeof(cmd)); + read(keyd_fd, &cmd, sizeof(cmd)); + if (cmd == KEYD_REPLY_OK) { + write(keyd_fd, hash->hash, sizeof(hash->hash)); + keybuf.offset = 0; + read(keyd_fd, &keybuf.size, sizeof(keybuf.size)); + if (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, publickey); + free_packet_list(packets); + packets = NULL; + free(keybuf.buffer); + keybuf.buffer = NULL; + keybuf.size = 0; + } + } + + return (count > 0) ? 1 : 0; +} + + /** * getfullkeyid - Maps a 32bit key id to a 64bit one. * @keyid: The 32bit keyid. @@ -340,12 +415,16 @@ static int keyd_fetch_key_text(const char *search, */ 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)); if (cmd == KEYD_REPLY_OK) { write(keyd_fd, &keyid, sizeof(keyid)); + read(keyd_fd, &cmd, sizeof(cmd)); + if (cmd != sizeof(keyid)) { + return 0; + } read(keyd_fd, &keyid, sizeof(keyid)); } @@ -369,7 +448,7 @@ static int keyd_iterate_keys(void (*iterfunc)(void *ctx, struct buffer_ctx keybuf; struct openpgp_packet_list *packets = NULL; struct openpgp_publickey *key = NULL; - int cmd = KEYD_CMD_KEYITER; + uint32_t cmd = KEYD_CMD_KEYITER; ssize_t bytes = 0; ssize_t count = 0; int numkeys = 0; @@ -429,6 +508,7 @@ struct dbfuncs keydb_keyd_funcs = { .endtrans = keyd_endtrans, .fetch_key = keyd_fetch_key, .fetch_key_text = keyd_fetch_key_text, + .fetch_key_skshash = keyd_fetch_key_skshash, .store_key = keyd_store_key, .update_keys = generic_update_keys, .delete_key = keyd_delete_key,