]> git.sommitrealweird.co.uk Git - onak.git/blobdiff - keydb_keyd.c
Explicitly use 32 bits for keyd socket commands
[onak.git] / keydb_keyd.c
index 10716ee0c5504c1b15742236146adc8cf31bbc9c..e5d46a335a4b1ea17d3a13bf3c39a04d22de0666 100644 (file)
@@ -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.
  */
  *     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;
 {
        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);
        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.
  */
  *     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 (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;
        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.
  */
  *     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;
 }
 {
        return true;
 }
@@ -130,7 +143,7 @@ bool starttrans(void)
  *
  *     Ends a transaction.
  */
  *
  *     Ends a transaction.
  */
-void endtrans(void)
+static void keyd_endtrans(void)
 {
        return;
 }
 {
        return;
 }
@@ -146,12 +159,12 @@ void endtrans(void)
  *
  *      TODO: What about keyid collisions? Should we use fingerprint instead?
  */
  *
  *      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;
                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;
 
        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;
 }
 
        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.
 /**
  *     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?
  */
  *     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;
 {
        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) {
        uint64_t                    keyid;
 
        keyid = get_keyid(publickey);
        
        if (update) {
-               delete_key(keyid, false);
+               keyd_delete_key(keyid, false);
        }
 
        write(keyd_fd, &cmd, sizeof(cmd));
        }
 
        write(keyd_fd, &cmd, sizeof(cmd));
@@ -246,27 +281,6 @@ int store_key(struct openpgp_publickey *publickey, bool intrans, bool update)
        return 0;
 }
 
        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.
 /**
  *     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.
  */
  *     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;
 {
        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;
 
        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.
  */
  *     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));
 
        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_KEYID2UID 1
 #define NEED_GETKEYSIGS 1
+#define NEED_UPDATEKEYS 1
 #include "keydb.c"
 #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,
+};