From d9fb5b538c7c7222c29be018b3c2a9680a181f70 Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Mon, 20 Sep 2004 14:32:11 +0000 Subject: [PATCH 01/16] Hard error when db version is < 4. Fix configure.ac so we hard error if our version is less than 4. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index a3468aa..e0a7e84 100644 --- a/configure.ac +++ b/configure.ac @@ -21,7 +21,7 @@ then set `eval $ac_cpp conftest.c | egrep '^ *[[0-9]] *'`; v="$1"; vv="$2" AC_MSG_RESULT($v.$vv) if test "$v" -ne 4; then - AC_MSG_RESULT([ * onak requires libdb version 4]) + AC_MSG_ERROR([ * onak requires libdb version 4]) fi for db in "db-$v.$vv" "db$v.$vv" "db-$v" "db$v" "db"; do AC_MSG_CHECKING(for db_create in lib$db) -- 2.39.2 From bdada0eacc11f6cfbf3256556d86282a0124ab26 Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Mon, 20 Sep 2004 14:33:18 +0000 Subject: [PATCH 02/16] Add assert for invalid armor parameters. Add an assert if we had a NULL string to the armor_putchar function. Brett spotted this while doing evil things. --- armor.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/armor.c b/armor.c index 6bb77d8..bb0085e 100644 --- a/armor.c +++ b/armor.c @@ -188,6 +188,8 @@ static int armor_putchar(void *ctx, size_t count, unsigned char *c) { int i; + log_assert(c != NULL); + for (i = 0; i < count; i++) { armor_putchar_int(ctx, c[i]); } -- 2.39.2 From a8ef501f8a174ef7eb96baa1803e1ad58e703831 Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Tue, 21 Sep 2004 13:07:38 +0000 Subject: [PATCH 03/16] Compile warning cleanup; add missed include file. cleanup.c uses functions prototyped in string.h, so include it. --- cleanup.c | 1 + 1 file changed, 1 insertion(+) diff --git a/cleanup.c b/cleanup.c index 32b997a..3a33e60 100644 --- a/cleanup.c +++ b/cleanup.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "cleanup.h" #include "keydb.h" -- 2.39.2 From c8d06ad9146d939718dec9ee01b39e4e7012ef23 Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Wed, 22 Sep 2004 09:28:13 +0000 Subject: [PATCH 04/16] Make cleanup.c compile cleanly under c99. Change cleanup.c so the signal bits all compile cleanly under C99 with -DBSD_SOURCE=1. --- cleanup.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/cleanup.c b/cleanup.c index 3a33e60..ecb3322 100644 --- a/cleanup.c +++ b/cleanup.c @@ -65,17 +65,13 @@ void sig_cleanup(int signal) */ void catchsignals(void) { - struct sigaction alarmh; - logthing(LOGTHING_INFO, "Catching signals"); - memset(&alarmh, 0, sizeof(alarmh)); - alarmh.sa_handler = sig_cleanup; - sigaction(SIGALRM, &alarmh, NULL); - sigaction(SIGPIPE, &alarmh, NULL); - sigaction(SIGTERM, &alarmh, NULL); - sigaction(SIGINT, &alarmh, NULL); - sigaction(SIGHUP, &alarmh, NULL); + signal(SIGALRM, &sig_cleanup); + signal(SIGPIPE, &sig_cleanup); + signal(SIGTERM, &sig_cleanup); + signal(SIGINT, &sig_cleanup); + signal(SIGHUP, &sig_cleanup); return; } -- 2.39.2 From d7c1eb353d72c8c1955a7dfb842227a18149cb98 Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Thu, 23 Sep 2004 12:21:08 +0000 Subject: [PATCH 05/16] Fix transaction around id32 updating in DB4 backend. For some reason we finished our transaction before we wrote the id32db details. Fix this so we do it afterwards instead. --- keydb_db4.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/keydb_db4.c b/keydb_db4.c index 0d7b46b..0163ed5 100644 --- a/keydb_db4.c +++ b/keydb_db4.c @@ -638,10 +638,6 @@ int store_key(struct openpgp_publickey *publickey, bool intrans, bool update) uids = NULL; } - if (!intrans) { - endtrans(); - } - /* * Write the truncated 32 bit keyid so we can lookup the full id for * queries. @@ -704,6 +700,10 @@ int store_key(struct openpgp_publickey *publickey, bool intrans, bool update) } } + if (!intrans) { + endtrans(); + } + return deadlock ? -1 : 0 ; } -- 2.39.2 From 63d00390a7c0507abd8099821d86602e9256c43b Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Thu, 23 Sep 2004 15:20:16 +0000 Subject: [PATCH 06/16] Fix sixdegrees to initialise the logging infrastructure. sixdegrees wasn't initialising the logging infrastructure, so would log to stderr rather than the log file for example. Fix this. --- sixdegrees.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sixdegrees.c b/sixdegrees.c index 0dd324f..b78397f 100644 --- a/sixdegrees.c +++ b/sixdegrees.c @@ -13,6 +13,7 @@ #include "keydb.h" #include "keystructs.h" #include "ll.h" +#include "log.h" #include "onak-conf.h" #include "stats.h" @@ -125,6 +126,7 @@ int main(int argc, char *argv[]) } readconfig(NULL); + initlogthing("sixdegrees", config.logfile); initdb(true); inithash(); sixdegrees(getfullkeyid(keyid)); -- 2.39.2 From 168d9233fd2efadcb50f76e57f960fb875383fbb Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Sat, 25 Sep 2004 09:05:04 +0000 Subject: [PATCH 07/16] Fix maxpath to initialise the logging infrastructure. maxpath wasn't initialising the logging infrastructure, so would log to stderr rather than the log file for example. Fix this. --- maxpath.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/maxpath.c b/maxpath.c index dfee16c..191ce8a 100644 --- a/maxpath.c +++ b/maxpath.c @@ -14,6 +14,7 @@ #include "hash.h" #include "keydb.h" #include "ll.h" +#include "log.h" #include "onak-conf.h" #include "stats.h" @@ -70,6 +71,7 @@ void findmaxpath(unsigned long max) int main(int argc, char *argv[]) { readconfig(NULL); + initlogthing("maxpath", config.logfile); initdb(true); inithash(); findmaxpath(30); @@ -77,6 +79,7 @@ int main(int argc, char *argv[]) findmaxpath(30); destroyhash(); cleanupdb(); + cleanuplogthing(); cleanupconfig(); return EXIT_SUCCESS; -- 2.39.2 From 23817f46df40d242f476a82f677bd8aa22f22aca Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Sat, 25 Sep 2004 09:05:56 +0000 Subject: [PATCH 08/16] Cleanup logging in sixdegrees.c When we've finished in sixdegrees, remember to shut the logging infrastructure down. --- sixdegrees.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sixdegrees.c b/sixdegrees.c index b78397f..d7d650f 100644 --- a/sixdegrees.c +++ b/sixdegrees.c @@ -132,6 +132,7 @@ int main(int argc, char *argv[]) sixdegrees(getfullkeyid(keyid)); destroyhash(); cleanupdb(); + cleanuplogthing(); cleanupconfig(); return 0; -- 2.39.2 From 848a41ea337ecee39f3eaf9d091a316d07ec8e9d Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Sat, 25 Sep 2004 09:26:31 +0000 Subject: [PATCH 09/16] Update version to indicate arch build. Update the version in autoconf and debian/changelog to indicate that any build is from arch rather than a released tarball (ie add +arch). --- configure.ac | 2 +- debian/changelog | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index e0a7e84..1b9e633 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ AC_PREREQ(2.50) -AC_INIT([onak],[0.3.0],[noodles-onak@earth.li]) +AC_INIT([onak],[0.3.0+arch],[noodles-onak@earth.li]) AC_CONFIG_SRCDIR(onak.c) AC_CONFIG_HEADER(config.h) diff --git a/debian/changelog b/debian/changelog index ce3836a..132dbca 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +onak (0.3.0+arch-1) unstable; urgency=low + + * arch snapshot + + -- Jonathan McDowell Fri, 24 Sep 2004 19:35:48 +0100 + onak (0.3.0-1) unstable; urgency=low * Initial Release. (closes: #254425) -- 2.39.2 From 66748d60571a5ebbbc0f0cb84c061f9c62f5aef7 Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Sat, 25 Sep 2004 09:34:55 +0000 Subject: [PATCH 10/16] Add keyd backend (persistant database access over Unix socket) Add keyd, which runs in the background and talks to the real database and then communicates with the various onak programs over a Unix socket. --- Makefile.in | 33 +++-- configure.ac | 4 + keyd.c | 317 ++++++++++++++++++++++++++++++++++++++++++++ keyd.h | 33 +++++ keydb_keyd.c | 361 +++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 738 insertions(+), 10 deletions(-) create mode 100644 keyd.c create mode 100644 keyd.h create mode 100644 keydb_keyd.c diff --git a/Makefile.in b/Makefile.in index 334ec29..cd6620e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -16,19 +16,32 @@ prefix ?= @prefix@ exec_prefix ?= @exec_prefix@ PROGS = add lookup gpgwww onak splitkeys onak-mail.pl stripkey -CORE_OBJS = armor.o charfuncs.o decodekey.o getcgi.o hash.o keydb_$(DBTYPE).o \ +CORE_OBJS = armor.o charfuncs.o decodekey.o getcgi.o hash.o \ keyid.o keyindex.o ll.o mem.o onak-conf.o parsekey.o sha1.o md5.o \ log.o photoid.o wordlist.o cleanup.o -OBJS = merge.o stats.o sendsync.o cleankey.o $(CORE_OBJS) SRCS = armor.c parsekey.c merge.c keyid.c md5.c sha1.c main.c getcgi.c mem.c \ keyindex.c stats.c lookup.c add.c keydb_$(DBTYPE).c ll.c hash.c \ gpgwww.c onak-conf.c charfuncs.c sendsync.c log.c photoid.c \ wordlist.c cleankey.c cleanup.c +ifeq (x@KEYD@, xyes) +PROGS += keyd +KEYDB_OBJ = keydb_keyd.o +SRCS += keyd.c keydb_keyd.c +else +KEYDB_OBJ = keydb_$(DBTYPE).o +endif + +OBJS = merge.o stats.o sendsync.o cleankey.o $(CORE_OBJS) $(KEYDB_OBJ) + all: .depend $(PROGS) testparse maxpath sixdegrees splitkeys onak.conf -splitkeys: splitkeys.o $(CORE_OBJS) - $(CC) $(LDFLAGS) -o splitkeys splitkeys.o $(CORE_OBJS) $(LIBS) +keyd: keyd.o $(CORE_OBJS) keydb_$(DBTYPE).o + $(CC) $(LDFLAGS) -o keyd keyd.o $(CORE_OBJS) keydb_$(DBTYPE).o $(LIBS) + +splitkeys: splitkeys.o $(CORE_OBJS) $(KEYDB_OBJ) + $(CC) $(LDFLAGS) -o splitkeys splitkeys.o $(CORE_OBJS) $(KEYDB_OBJ) \ + $(LIBS) testparse: main.o $(OBJS) $(CC) $(LDFLAGS) -o testparse main.o $(OBJS) $(LIBS) @@ -45,17 +58,17 @@ stripkey: stripkey.o $(OBJS) gpgwww: gpgwww.o $(OBJS) $(CC) $(LDFLAGS) -o gpgwww gpgwww.o $(OBJS) $(LIBS) -lookup: lookup.o cleankey.o merge.o $(CORE_OBJS) +lookup: lookup.o cleankey.o merge.o $(CORE_OBJS) $(KEYDB_OBJ) $(CC) $(LDFLAGS) -o lookup lookup.o cleankey.o merge.o $(CORE_OBJS) \ - $(LIBS) + $(KEYDB_OBJ) $(LIBS) -add: add.o cleankey.o merge.o sendsync.o $(CORE_OBJS) +add: add.o cleankey.o merge.o sendsync.o $(CORE_OBJS) $(KEYDB_OBJ) $(CC) $(LDFLAGS) -o add add.o cleankey.o merge.o sendsync.o \ - $(CORE_OBJS) $(LIBS) + $(CORE_OBJS) $(KEYDB_OBJ) $(LIBS) -onak: onak.o merge.o cleankey.o $(CORE_OBJS) +onak: onak.o merge.o cleankey.o $(CORE_OBJS) $(KEYDB_OBJ) $(CC) $(LDFLAGS) -o onak onak.o merge.o cleankey.o \ - $(CORE_OBJS) $(LIBS) + $(CORE_OBJS) $(KEYDB_OBJ) $(LIBS) onak-conf.o: onak-conf.c onak-conf.h $(CC) $(CFLAGS) -DCONFIGFILE=\"@sysconfdir@/onak.conf\" -c onak-conf.c diff --git a/configure.ac b/configure.ac index 1b9e633..7b6bce6 100644 --- a/configure.ac +++ b/configure.ac @@ -9,6 +9,8 @@ AC_C_BIGENDIAN AC_ARG_ENABLE(backend,AC_HELP_STRING([--enable-backend=],[Choose the backend database to use. Defaults to db4.]), [], [enable_backend="db4"]) +AC_ARG_ENABLE(keyd,AC_HELP_STRING([--enable-keyd],[Use keyd as the DB backend.]), [], []) + AC_MSG_CHECKING([which key database backend to use]) AC_MSG_RESULT([$enable_backend]) AC_CHECK_FILE([$srcdir/keydb_$enable_backend.c], ,AC_MSG_ERROR([non existent key database backend $enable_backend])) @@ -46,6 +48,8 @@ fi AC_SUBST(DBTYPE, $enable_backend) +AC_SUBST(KEYD, $enable_keyd) + AC_CONFIG_FILES(Makefile) AC_OUTPUT diff --git a/keyd.c b/keyd.c new file mode 100644 index 0000000..7b6226e --- /dev/null +++ b/keyd.c @@ -0,0 +1,317 @@ +/* + * keyd.c - key retrieval daemon + * + * Jonathan McDowell + * + * Copyright 2004 Project Purple + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "charfuncs.h" +#include "cleanup.h" +#include "keyd.h" +#include "keydb.h" +#include "keystructs.h" +#include "log.h" +#include "mem.h" +#include "onak-conf.h" +#include "parsekey.h" + +int sock_init(const char *sockname) +{ + struct sockaddr_un sock; + int fd = -1; + int ret = -1; + + fd = socket(PF_UNIX, SOCK_STREAM, 0); + if (fd != -1) { + ret = fcntl(fd, F_SETFD, 1); + } + + if (ret != -1) { + sock.sun_family = AF_UNIX; + strncpy(sock.sun_path, sockname, sizeof(sock.sun_path) - 1); + unlink(sockname); + ret = bind(fd, (struct sockaddr *) &sock, sizeof(sock)); + } + + if (ret != -1) { + ret = listen(fd, 5); + } + + return fd; +} + +int sock_do(int fd) +{ + int cmd = KEYD_CMD_UNKNOWN; + ssize_t bytes = 0; + ssize_t count = 0; + int ret = 0; + uint64_t keyid = 0; + char *search = NULL; + struct openpgp_publickey *key = NULL; + struct openpgp_packet_list *packets = NULL; + struct openpgp_packet_list *list_end = NULL; + struct buffer_ctx storebuf; + + /* + * Get the command from the client. + */ + bytes = read(fd, &cmd, sizeof(cmd)); + + logthing(LOGTHING_DEBUG, "Read %d bytes, command: %d", bytes, cmd); + + if (bytes != sizeof(cmd)) { + ret = 1; + } + + if (ret == 0) { + switch (cmd) { + case KEYD_CMD_VERSION: + cmd = KEYD_REPLY_OK; + write(fd, &cmd, sizeof(cmd)); + write(fd, &keyd_version, sizeof(keyd_version)); + break; + case KEYD_CMD_GET: + cmd = KEYD_REPLY_OK; + write(fd, &cmd, sizeof(cmd)); + bytes = read(fd, &keyid, sizeof(keyid)); + if (bytes != sizeof(keyid)) { + ret = 1; + } + storebuf.offset = 0; + if (ret == 0) { + logthing(LOGTHING_INFO, + "Fetching 0x%llX, result: %d", + keyid, + fetch_key(keyid, &key, false)); + if (key != NULL) { + storebuf.size = 8192; + storebuf.buffer = malloc(8192); + + flatten_publickey(key, + &packets, + &list_end); + write_openpgp_stream(buffer_putchar, + &storebuf, + packets); + logthing(LOGTHING_TRACE, + "Sending %d bytes.", + storebuf.offset); + write(fd, &storebuf.offset, + sizeof(storebuf.offset)); + write(fd, storebuf.buffer, + storebuf.offset); + + free(storebuf.buffer); + storebuf.buffer = NULL; + storebuf.size = storebuf.offset = 0; + free_packet_list(packets); + packets = list_end = NULL; + free_publickey(key); + key = NULL; + } else { + write(fd, &storebuf.offset, + sizeof(storebuf.offset)); + } + } + break; + case KEYD_CMD_GETTEXT: + cmd = KEYD_REPLY_OK; + write(fd, &cmd, sizeof(cmd)); + bytes = read(fd, &count, sizeof(count)); + if (bytes != sizeof(count)) { + ret = 1; + } + storebuf.offset = 0; + if (ret == 0) { + search = malloc(count+1); + read(fd, search, count); + search[count] = 0; + logthing(LOGTHING_INFO, + "Fetching %s, result: %d", + search, + fetch_key_text(search, &key)); + if (key != NULL) { + storebuf.size = 8192; + storebuf.buffer = malloc(8192); + + flatten_publickey(key, + &packets, + &list_end); + write_openpgp_stream(buffer_putchar, + &storebuf, + packets); + logthing(LOGTHING_TRACE, + "Sending %d bytes.", + storebuf.offset); + write(fd, &storebuf.offset, + sizeof(storebuf.offset)); + write(fd, storebuf.buffer, + storebuf.offset); + + free(storebuf.buffer); + storebuf.buffer = NULL; + storebuf.size = storebuf.offset = 0; + free_packet_list(packets); + packets = list_end = NULL; + free_publickey(key); + key = NULL; + } else { + write(fd, &storebuf.offset, + sizeof(storebuf.offset)); + } + } + break; + case KEYD_CMD_STORE: + cmd = KEYD_REPLY_OK; + write(fd, &cmd, sizeof(cmd)); + storebuf.offset = 0; + bytes = read(fd, &storebuf.size, + sizeof(storebuf.size)); + logthing(LOGTHING_TRACE, "Reading %d bytes.", + storebuf.size); + if (bytes != sizeof(storebuf.size)) { + ret = 1; + } + if (ret == 0 && storebuf.size > 0) { + storebuf.buffer = malloc(storebuf.size); + bytes = count = 0; + while (bytes >= 0 && count < storebuf.size) { + bytes = read(fd, + &storebuf.buffer[count], + storebuf.size - count); + logthing(LOGTHING_TRACE, + "Read %d bytes.", + bytes); + count += bytes; + } + read_openpgp_stream(buffer_fetchchar, + &storebuf, + &packets, + 0); + parse_keys(packets, &key); + store_key(key, false, false); + free_packet_list(packets); + packets = NULL; + free_publickey(key); + key = NULL; + free(storebuf.buffer); + storebuf.buffer = NULL; + storebuf.size = storebuf.offset = 0; + } + break; + case KEYD_CMD_DELETE: + cmd = KEYD_REPLY_OK; + write(fd, &cmd, sizeof(cmd)); + bytes = read(fd, &keyid, sizeof(keyid)); + if (bytes != sizeof(keyid)) { + ret = 1; + } + if (ret == 0) { + logthing(LOGTHING_INFO, + "Deleting 0x%llX, result: %d", + keyid, + delete_key(keyid, false)); + } + break; + case KEYD_CMD_GETFULLKEYID: + cmd = KEYD_REPLY_OK; + write(fd, &cmd, sizeof(cmd)); + bytes = read(fd, &keyid, sizeof(keyid)); + if (bytes != sizeof(keyid)) { + ret = 1; + } + if (ret == 0) { + keyid = getfullkeyid(keyid); + write(fd, &keyid, sizeof(keyid)); + } + break; + case KEYD_CMD_CLOSE: + ret = 1; + break; + case KEYD_CMD_QUIT: + trytocleanup(); + break; + default: + logthing(LOGTHING_ERROR, "Got unknown command: %d", + cmd); + cmd = KEYD_REPLY_UNKNOWN_CMD; + write(fd, &cmd, sizeof(cmd)); + } + } + + return(ret); +} + +int sock_close(int fd) +{ + return shutdown(fd, SHUT_RDWR); +} + +int sock_accept(int fd) +{ + struct sockaddr_un sock; + socklen_t socklen; + int srv = -1; + int ret = -1; + + socklen = sizeof(sock); + srv = accept(fd, (struct sockaddr *) &sock, &socklen); + if (srv != -1) { + ret = fcntl(srv, F_SETFD, 1); + } + + if (ret != -1) { + while (!sock_do(srv)) ; + sock_close(srv); + } + + return 1; +} + +int main(int argc, char *argv[]) +{ + int fd = -1; + fd_set rfds; + char sockname[1024]; + + readconfig(NULL); + initlogthing("keyd", config.logfile); + + catchsignals(); + + snprintf(sockname, 1023, "%s/%s", config.db_dir, KEYD_SOCKET); + fd = sock_init(sockname); + + if (fd != -1) { + FD_ZERO(&rfds); + FD_SET(fd, &rfds); + + initdb(false); + + logthing(LOGTHING_NOTICE, "Accepting connections."); + while (!cleanup() && select(fd + 1, &rfds, NULL, NULL, NULL) != -1) { + logthing(LOGTHING_INFO, "Accepted connection."); + sock_accept(fd); + FD_SET(fd, &rfds); + } + cleanupdb(); + sock_close(fd); + unlink(sockname); + } + + cleanuplogthing(); + cleanupconfig(); + + return(EXIT_SUCCESS); +} diff --git a/keyd.h b/keyd.h new file mode 100644 index 0000000..7497cb4 --- /dev/null +++ b/keyd.h @@ -0,0 +1,33 @@ +/* + * keyd.h - Public API for keyd. + * + * Jonathan McDowell + * + * Copyright 2004 Project Purple + */ + +#ifndef __KEYD_H__ +#define __KEYD_H__ + +#define KEYD_SOCKET "keyd.sock" + +enum keyd_ops { + KEYD_CMD_UNKNOWN = 0, + KEYD_CMD_VERSION = 1, + KEYD_CMD_GET, + KEYD_CMD_STORE, + KEYD_CMD_DELETE, + KEYD_CMD_GETTEXT, + KEYD_CMD_GETFULLKEYID, + KEYD_CMD_CLOSE, + KEYD_CMD_QUIT +}; + +enum keyd_reply { + KEYD_REPLY_OK = 0, + KEYD_REPLY_UNKNOWN_CMD = 1 +}; + +static int keyd_version = 1; + +#endif /* __KEYD_H__ */ diff --git a/keydb_keyd.c b/keydb_keyd.c new file mode 100644 index 0000000..10716ee --- /dev/null +++ b/keydb_keyd.c @@ -0,0 +1,361 @@ +/* + * keydb_keyd.c - Routines to talk to keyd backend. + * + * Jonathan McDowell + * + * Copyright 2004 Project Purple + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "charfuncs.h" +#include "keyd.h" +#include "keydb.h" +#include "keyid.h" +#include "keystructs.h" +#include "log.h" +#include "mem.h" +#include "onak-conf.h" +#include "parsekey.h" + +/** + * keyd_fd - our file descriptor for the socket connection to keyd. + */ +static int keyd_fd = -1; + +/** + * initdb - Initialize the key database. + * @readonly: If we'll only be reading the DB, not writing to it. + * + * This function should be called before any of the other functions in + * this file are called in order to allow the DB to be initialized ready + * for access. + */ +void initdb(bool readonly) +{ + struct sockaddr_un sock; + int cmd = KEYD_CMD_UNKNOWN; + int reply = KEYD_REPLY_UNKNOWN_CMD; + ssize_t count; + + keyd_fd = socket(PF_UNIX, SOCK_STREAM, 0); + if (keyd_fd < 0) { + logthing(LOGTHING_CRITICAL, + "Couldn't open socket: %s (%d)", + strerror(errno), + errno); + exit(EXIT_FAILURE); + } + + sock.sun_family = AF_UNIX; + snprintf(sock.sun_path, sizeof(sock.sun_path) - 1, "%s/%s", + config.db_dir, + KEYD_SOCKET); + if (connect(keyd_fd, (struct sockaddr *) &sock, sizeof(sock)) < 0) { + logthing(LOGTHING_CRITICAL, + "Couldn't connect to socket %s: %s (%d)", + sock.sun_path, + strerror(errno), + errno); + exit(EXIT_FAILURE); + } + + cmd = KEYD_CMD_VERSION; + if (write(keyd_fd, &cmd, sizeof(cmd)) != sizeof(cmd)) { + logthing(LOGTHING_CRITICAL, + "Couldn't write version cmd: %s (%d)", + strerror(errno), + 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)", + keyd_version, reply); + } + } + } + } + + return; +} + +/** + * cleanupdb - De-initialize the key database. + * + * This function should be called upon program exit to allow the DB to + * cleanup after itself. + */ +void cleanupdb(void) +{ + if (shutdown(keyd_fd, SHUT_RDWR) < 0) { + logthing(LOGTHING_NOTICE, "Error shutting down socket: %d", + errno); + } + keyd_fd = -1; + + return; +} + + +/** + * starttrans - Start a transaction. + * + * Start a transaction. Intended to be used if we're about to perform many + * 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) +{ + return true; +} + +/** + * endtrans - End a transaction. + * + * Ends a transaction. + */ +void endtrans(void) +{ + return; +} + +/** + * fetch_key - Given a keyid fetch the key from storage. + * @keyid: The keyid to fetch. + * @publickey: A pointer to a structure to return the key in. + * @intrans: If we're already in a transaction. + * + * This function returns a public key from whatever storage mechanism we + * are using. + * + * TODO: What about keyid collisions? Should we use fingerprint instead? + */ +int 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; + 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, &keyid, sizeof(keyid)); + 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; +} + +/** + * store_key - Takes a key and stores it. + * @publickey: A pointer to the public key to store. + * @intrans: If we're already in a transaction. + * @update: If true the key exists and should be updated. + * + * This function stores a public key in whatever storage mechanism we are + * using. intrans indicates if we're already in a transaction so don't + * need to start one. update indicates if the key already exists and is + * just being updated. + * + * 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) +{ + 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; + uint64_t keyid; + + keyid = get_keyid(publickey); + + if (update) { + delete_key(keyid, false); + } + + write(keyd_fd, &cmd, sizeof(cmd)); + read(keyd_fd, &cmd, sizeof(cmd)); + if (cmd == KEYD_REPLY_OK) { + keybuf.offset = 0; + keybuf.size = 8192; + keybuf.buffer = malloc(keybuf.size); + + next = publickey->next; + publickey->next = NULL; + flatten_publickey(publickey, + &packets, + &list_end); + publickey->next = next; + + write_openpgp_stream(buffer_putchar, &keybuf, packets); + logthing(LOGTHING_TRACE, "Sending %d bytes.", keybuf.offset); + write(keyd_fd, &keybuf.offset, sizeof(keybuf.offset)); + write(keyd_fd, keybuf.buffer, keybuf.offset); + + free_packet_list(packets); + packets = list_end = NULL; + free(keybuf.buffer); + keybuf.buffer = NULL; + keybuf.size = keybuf.offset = 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. + * @publickey: A pointer to a structure to return the key in. + * + * 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) +{ + struct buffer_ctx keybuf; + struct openpgp_packet_list *packets = NULL; + int cmd = KEYD_CMD_GETTEXT; + 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) { + bytes = strlen(search); + write(keyd_fd, &bytes, sizeof(bytes)); + write(keyd_fd, search, bytes); + 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; + + return 0; +} + +/** + * getfullkeyid - Maps a 32bit key id to a 64bit one. + * @keyid: The 32bit keyid. + * + * 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) +{ + int 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, &keyid, sizeof(keyid)); + } + + return keyid; +} + +/** + * dumpdb - dump the key database + * @filenamebase: The base filename to use for the dump. + * + * 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. + */ +int dumpdb(char *filenamebase) +{ + return 0; +} + +#define NEED_KEYID2UID 1 +#define NEED_GETKEYSIGS 1 +#include "keydb.c" -- 2.39.2 From a57a146ebc3f15f1ba2dfe8ecb9b59702fb8f799 Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Sat, 25 Sep 2004 09:36:21 +0000 Subject: [PATCH 11/16] Move update_keys to keydb rather than merge. Move update_keys to the database backends, as in some senses it makes more sense there - we have multiple DB calls and this is the main thing that needs transactions, so by moving it here we should be able to hide them from the rest of the code. --- Makefile.in | 16 ++++++------ keydb.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++- keydb.h | 14 ++++++++++- keydb_db2.c | 1 + keydb_db4.c | 1 + keydb_file.c | 1 + keydb_fs.c | 1 + keydb_keyd.c | 1 + keydb_pg.c | 1 + merge.c | 67 +------------------------------------------------ merge.h | 14 +---------- 11 files changed, 98 insertions(+), 89 deletions(-) diff --git a/Makefile.in b/Makefile.in index cd6620e..896711c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -18,7 +18,7 @@ exec_prefix ?= @exec_prefix@ PROGS = add lookup gpgwww onak splitkeys onak-mail.pl stripkey CORE_OBJS = armor.o charfuncs.o decodekey.o getcgi.o hash.o \ keyid.o keyindex.o ll.o mem.o onak-conf.o parsekey.o sha1.o md5.o \ - log.o photoid.o wordlist.o cleanup.o + log.o photoid.o wordlist.o cleanup.o merge.o SRCS = armor.c parsekey.c merge.c keyid.c md5.c sha1.c main.c getcgi.c mem.c \ keyindex.c stats.c lookup.c add.c keydb_$(DBTYPE).c ll.c hash.c \ gpgwww.c onak-conf.c charfuncs.c sendsync.c log.c photoid.c \ @@ -32,7 +32,7 @@ else KEYDB_OBJ = keydb_$(DBTYPE).o endif -OBJS = merge.o stats.o sendsync.o cleankey.o $(CORE_OBJS) $(KEYDB_OBJ) +OBJS = stats.o sendsync.o cleankey.o $(CORE_OBJS) $(KEYDB_OBJ) all: .depend $(PROGS) testparse maxpath sixdegrees splitkeys onak.conf @@ -58,16 +58,16 @@ stripkey: stripkey.o $(OBJS) gpgwww: gpgwww.o $(OBJS) $(CC) $(LDFLAGS) -o gpgwww gpgwww.o $(OBJS) $(LIBS) -lookup: lookup.o cleankey.o merge.o $(CORE_OBJS) $(KEYDB_OBJ) - $(CC) $(LDFLAGS) -o lookup lookup.o cleankey.o merge.o $(CORE_OBJS) \ +lookup: lookup.o cleankey.o $(CORE_OBJS) $(KEYDB_OBJ) + $(CC) $(LDFLAGS) -o lookup lookup.o cleankey.o $(CORE_OBJS) \ $(KEYDB_OBJ) $(LIBS) -add: add.o cleankey.o merge.o sendsync.o $(CORE_OBJS) $(KEYDB_OBJ) - $(CC) $(LDFLAGS) -o add add.o cleankey.o merge.o sendsync.o \ +add: add.o cleankey.o sendsync.o $(CORE_OBJS) $(KEYDB_OBJ) + $(CC) $(LDFLAGS) -o add add.o cleankey.o sendsync.o \ $(CORE_OBJS) $(KEYDB_OBJ) $(LIBS) -onak: onak.o merge.o cleankey.o $(CORE_OBJS) $(KEYDB_OBJ) - $(CC) $(LDFLAGS) -o onak onak.o merge.o cleankey.o \ +onak: onak.o cleankey.o $(CORE_OBJS) $(KEYDB_OBJ) + $(CC) $(LDFLAGS) -o onak onak.o cleankey.o \ $(CORE_OBJS) $(KEYDB_OBJ) $(LIBS) onak-conf.o: onak-conf.c onak-conf.h diff --git a/keydb.c b/keydb.c index 2b419ca..1621782 100644 --- a/keydb.c +++ b/keydb.c @@ -3,7 +3,7 @@ * * Jonathan McDowell * - * Copyright 2002 Project Purple + * Copyright 2002-2004 Project Purple */ /** @@ -22,6 +22,7 @@ #include "keyid.h" #include "keystructs.h" #include "mem.h" +#include "merge.h" #include "parsekey.h" #ifdef NEED_KEYID2UID @@ -150,3 +151,70 @@ uint64_t getfullkeyid(uint64_t keyid) return keyid; } #endif + +#ifdef NEED_UPDATEKEYS +/** + * update_keys - Takes a list of public keys and updates them in the DB. + * @keys: The keys to update in the DB. + * + * Takes a list of keys and adds them to the database, merging them with + * the key in the database if it's already present there. The key list is + * update to contain the minimum set of updates required to get from what + * we had before to what we have now (ie the set of data that was added to + * the DB). Returns the number of entirely new keys added. + */ +int update_keys(struct openpgp_publickey **keys) +{ + struct openpgp_publickey *curkey = NULL; + struct openpgp_publickey *oldkey = NULL; + struct openpgp_publickey *prev = NULL; + int newkeys = 0; + bool intrans; + + for (curkey = *keys; curkey != NULL; curkey = curkey->next) { + intrans = starttrans(); + logthing(LOGTHING_INFO, + "Fetching key 0x%llX, result: %d", + get_keyid(curkey), + fetch_key(get_keyid(curkey), &oldkey, intrans)); + + /* + * If we already have the key stored in the DB then merge it + * with the new one that's been supplied. Otherwise the key + * we've just got is the one that goes in the DB and also the + * one that we send out. + */ + if (oldkey != NULL) { + merge_keys(oldkey, curkey); + if (curkey->revocations == NULL && + curkey->uids == NULL && + curkey->subkeys == NULL) { + if (prev == NULL) { + *keys = curkey->next; + } else { + prev->next = curkey->next; + curkey->next = NULL; + free_publickey(curkey); + curkey = prev; + } + } else { + prev = curkey; + logthing(LOGTHING_INFO, + "Merged key; storing updated key."); + store_key(oldkey, intrans, true); + } + free_publickey(oldkey); + oldkey = NULL; + } else { + logthing(LOGTHING_INFO, + "Storing completely new key."); + store_key(curkey, intrans, false); + newkeys++; + } + endtrans(); + intrans = false; + } + + return newkeys; +} +#endif /* NEED_UPDATEKEYS */ diff --git a/keydb.h b/keydb.h index ae87ce3..b484831 100644 --- a/keydb.h +++ b/keydb.h @@ -3,7 +3,7 @@ * * Jonathan McDowell * - * Copyright 2002 Project Purple + * Copyright 2002-2004 Project Purple */ #ifndef __KEYDB_H__ @@ -97,6 +97,18 @@ int delete_key(uint64_t keyid, bool intrans); */ int fetch_key_text(const char *search, struct openpgp_publickey **publickey); +/** + * update_keys - Takes a list of public keys and updates them in the DB. + * @keys: The keys to update in the DB. + * + * Takes a list of keys and adds them to the database, merging them with + * the key in the database if it's already present there. The key list is + * update to contain the minimum set of updates required to get from what + * we had before to what we have now (ie the set of data that was added to + * the DB). Returns the number of entirely new keys added. + */ +int update_keys(struct openpgp_publickey **keys); + /** * keyid2uid - Takes a keyid and returns the primary UID for it. * @keyid: The keyid to lookup. diff --git a/keydb_db2.c b/keydb_db2.c index 6a1e2e8..020ee83 100644 --- a/keydb_db2.c +++ b/keydb_db2.c @@ -271,4 +271,5 @@ int dumpdb(char *filenamebase) #define NEED_KEYID2UID 1 #define NEED_GETKEYSIGS 1 #define NEED_GETFULLKEYID 1 +#define NEED_UPDATEKEYS 1 #include "keydb.c" diff --git a/keydb_db4.c b/keydb_db4.c index 0163ed5..7f8e498 100644 --- a/keydb_db4.c +++ b/keydb_db4.c @@ -1032,4 +1032,5 @@ uint64_t getfullkeyid(uint64_t keyid) */ #define NEED_GETKEYSIGS 1 #define NEED_KEYID2UID 1 +#define NEED_UPDATEKEYS 1 #include "keydb.c" diff --git a/keydb_file.c b/keydb_file.c index 4a4322b..81cb22a 100644 --- a/keydb_file.c +++ b/keydb_file.c @@ -188,4 +188,5 @@ int dumpdb(char *filenamebase) #define NEED_KEYID2UID 1 #define NEED_GETKEYSIGS 1 #define NEED_GETFULLKEYID 1 +#define NEED_UPDATEKEYS 1 #include "keydb.c" diff --git a/keydb_fs.c b/keydb_fs.c index 33fe51a..73d9758 100644 --- a/keydb_fs.c +++ b/keydb_fs.c @@ -537,4 +537,5 @@ uint64_t getfullkeyid(uint64_t keyid) */ #define NEED_KEYID2UID 1 #define NEED_GETKEYSIGS 1 +#define NEED_UPDATEKEYS 1 #include "keydb.c" diff --git a/keydb_keyd.c b/keydb_keyd.c index 10716ee..0399bc3 100644 --- a/keydb_keyd.c +++ b/keydb_keyd.c @@ -358,4 +358,5 @@ int dumpdb(char *filenamebase) #define NEED_KEYID2UID 1 #define NEED_GETKEYSIGS 1 +#define NEED_UPDATEKEYS 1 #include "keydb.c" diff --git a/keydb_pg.c b/keydb_pg.c index dd7cbfd..88682af 100644 --- a/keydb_pg.c +++ b/keydb_pg.c @@ -586,4 +586,5 @@ int dumpdb(char *filenamebase) * Include the basic keydb routines. */ #define NEED_GETFULLKEYID 1 +#define NEED_UPDATEKEYS 1 #include "keydb.c" diff --git a/merge.c b/merge.c index d2d2beb..95abbba 100644 --- a/merge.c +++ b/merge.c @@ -3,7 +3,7 @@ * * Jonathan McDowell * - * Copyright 2002 Project Purple + * Copyright 2002-2004 Project Purple */ #include @@ -352,68 +352,3 @@ int merge_keys(struct openpgp_publickey *a, struct openpgp_publickey *b) return rc; } - -/** - * update_keys - Takes a list of public keys and updates them in the DB. - * @keys: The keys to update in the DB. - * - * Takes a list of keys and adds them to the database, merging them with - * the key in the database if it's already present there. The key list is - * update to contain the minimum set of updates required to get from what - * we had before to what we have now (ie the set of data that was added to - * the DB). Returns the number of entirely new keys added. - */ -int update_keys(struct openpgp_publickey **keys) -{ - struct openpgp_publickey *curkey = NULL; - struct openpgp_publickey *oldkey = NULL; - struct openpgp_publickey *prev = NULL; - int newkeys = 0; - bool intrans; - - for (curkey = *keys; curkey != NULL; curkey = curkey->next) { - intrans = starttrans(); - logthing(LOGTHING_INFO, - "Fetching key 0x%llX, result: %d", - get_keyid(curkey), - fetch_key(get_keyid(curkey), &oldkey, intrans)); - - /* - * If we already have the key stored in the DB then merge it - * with the new one that's been supplied. Otherwise the key - * we've just got is the one that goes in the DB and also the - * one that we send out. - */ - if (oldkey != NULL) { - merge_keys(oldkey, curkey); - if (curkey->revocations == NULL && - curkey->uids == NULL && - curkey->subkeys == NULL) { - if (prev == NULL) { - *keys = curkey->next; - } else { - prev->next = curkey->next; - curkey->next = NULL; - free_publickey(curkey); - curkey = prev; - } - } else { - prev = curkey; - logthing(LOGTHING_INFO, - "Merged key; storing updated key."); - store_key(oldkey, intrans, true); - } - free_publickey(oldkey); - oldkey = NULL; - } else { - logthing(LOGTHING_INFO, - "Storing completely new key."); - store_key(curkey, intrans, false); - newkeys++; - } - endtrans(); - intrans = false; - } - - return newkeys; -} diff --git a/merge.h b/merge.h index bbefcc3..cabbc18 100644 --- a/merge.h +++ b/merge.h @@ -3,7 +3,7 @@ * * Jonathan McDowell * - * Copyright 2002 Project Purple + * Copyright 2002-2004 Project Purple */ #ifndef __MERGE_H__ @@ -25,18 +25,6 @@ */ int merge_keys(struct openpgp_publickey *a, struct openpgp_publickey *b); -/** - * update_keys - Takes a list of public keys and updates them in the DB. - * @keys: The keys to update in the DB. - * - * Takes a list of keys and adds them to the database, merging them with - * the key in the database if it's already present there. The key list is - * update to contain the minimum set of updates required to get from what - * we had before to what we have now (ie the set of data that was added to - * the DB). Returns the number of entirely new keys added. - */ -int update_keys(struct openpgp_publickey **keys); - /** * get_signed_packet - Gets a signed packet from a list. * @packet_list: The list of packets to look in. -- 2.39.2 From f42ab5050f79833030453b21d69f4f3be9fcd0d0 Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Mon, 27 Sep 2004 22:22:25 +0000 Subject: [PATCH 12/16] Add key iteration functionality to keydb backends. Add a function to the keydb backends which will call a given function once for every contained in the db. Currently implemented for db4, keyd, file and pg backends. --- keyd.c | 51 ++++++++++++++++++++++++++++++++++++++++ keyd.h | 3 ++- keydb.h | 14 +++++++++++ keydb_db2.c | 18 +++++++++++++- keydb_db4.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++ keydb_file.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++- keydb_fs.c | 17 ++++++++++++++ keydb_keyd.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++ keydb_pg.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++- 9 files changed, 355 insertions(+), 4 deletions(-) diff --git a/keyd.c b/keyd.c index 7b6226e..f8f5d4a 100644 --- a/keyd.c +++ b/keyd.c @@ -19,12 +19,56 @@ #include "cleanup.h" #include "keyd.h" #include "keydb.h" +#include "keyid.h" #include "keystructs.h" #include "log.h" #include "mem.h" #include "onak-conf.h" #include "parsekey.h" +void iteratefunc(void *ctx, struct openpgp_publickey *key) +{ + struct openpgp_packet_list *packets = NULL; + struct openpgp_packet_list *list_end = NULL; + struct buffer_ctx storebuf; + int ret = 0; + int fd = (int) ctx; + + if (key != NULL) { + storebuf.offset = 0; + storebuf.size = 8192; + storebuf.buffer = malloc(8192); + + logthing(LOGTHING_TRACE, + "Iterating over 0x%016llX.", + get_keyid(key)); + + flatten_publickey(key, + &packets, + &list_end); + write_openpgp_stream(buffer_putchar, + &storebuf, + packets); + logthing(LOGTHING_TRACE, + "Sending %d bytes.", + storebuf.offset); + ret = write(fd, &storebuf.offset, + sizeof(storebuf.offset)); + if (ret != 0) { + write(fd, storebuf.buffer, + storebuf.offset); + } + + free(storebuf.buffer); + storebuf.buffer = NULL; + storebuf.size = storebuf.offset = 0; + free_packet_list(packets); + packets = list_end = NULL; + } + + return; +} + int sock_init(const char *sockname) { struct sockaddr_un sock; @@ -236,6 +280,13 @@ int sock_do(int fd) write(fd, &keyid, sizeof(keyid)); } break; + case KEYD_CMD_KEYITER: + cmd = KEYD_REPLY_OK; + write(fd, &cmd, sizeof(cmd)); + iterate_keys(iteratefunc, (void *) fd); + bytes = 0; + write(fd, &bytes, sizeof(bytes)); + break; case KEYD_CMD_CLOSE: ret = 1; break; diff --git a/keyd.h b/keyd.h index 7497cb4..3bc252a 100644 --- a/keyd.h +++ b/keyd.h @@ -19,6 +19,7 @@ enum keyd_ops { KEYD_CMD_DELETE, KEYD_CMD_GETTEXT, KEYD_CMD_GETFULLKEYID, + KEYD_CMD_KEYITER, KEYD_CMD_CLOSE, KEYD_CMD_QUIT }; @@ -28,6 +29,6 @@ enum keyd_reply { KEYD_REPLY_UNKNOWN_CMD = 1 }; -static int keyd_version = 1; +static int keyd_version = 2; #endif /* __KEYD_H__ */ diff --git a/keydb.h b/keydb.h index b484831..ca2a823 100644 --- a/keydb.h +++ b/keydb.h @@ -159,4 +159,18 @@ uint64_t getfullkeyid(uint64_t keyid); */ int dumpdb(char *filenamebase); +/** + * iterate_keys - call a function once for each key in the db. + * @iterfunc: The function to call. + * @ctx: A context pointer + * + * 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 iterate_keys(void (*iterfunc)(void *ctx, struct openpgp_publickey *key), + void *ctx); + #endif /* __KEYDB_H__ */ diff --git a/keydb_db2.c b/keydb_db2.c index 020ee83..f9ca04b 100644 --- a/keydb_db2.c +++ b/keydb_db2.c @@ -3,7 +3,7 @@ * * Jonathan McDowell * - * Copyright 2002 Project Purple + * Copyright 2002-2004 Project Purple */ #include @@ -264,6 +264,22 @@ int dumpdb(char *filenamebase) return 0; } +/** + * iterate_keys - call a function once for each key in the db. + * @iterfunc: The function to call. + * @ctx: A context pointer + * + * 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 iterate_keys(void (*iterfunc)(void *ctx, struct openpgp_publickey *key), + void *ctx) +{ + return 0; +} /* * Include the basic keydb routines. diff --git a/keydb_db4.c b/keydb_db4.c index 7f8e498..de2215c 100644 --- a/keydb_db4.c +++ b/keydb_db4.c @@ -978,6 +978,72 @@ int dumpdb(char *filenamebase) return 0; } +/** + * iterate_keys - call a function once for each key in the db. + * @iterfunc: The function to call. + * @ctx: A context pointer + * + * 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 iterate_keys(void (*iterfunc)(void *ctx, struct openpgp_publickey *key), + void *ctx) +{ + DBT dbkey, data; + DBC *cursor = NULL; + int ret = 0; + int i = 0; + int numkeys = 0; + struct buffer_ctx fetchbuf; + struct openpgp_packet_list *packets = NULL; + struct openpgp_publickey *key = NULL; + + for (i = 0; i < numdbs; i++) { + ret = dbconns[i]->cursor(dbconns[i], + NULL, + &cursor, + 0); /* flags */ + + memset(&dbkey, 0, sizeof(dbkey)); + memset(&data, 0, sizeof(data)); + ret = cursor->c_get(cursor, &dbkey, &data, DB_NEXT); + while (ret == 0) { + fetchbuf.buffer = data.data; + fetchbuf.offset = 0; + fetchbuf.size = data.size; + read_openpgp_stream(buffer_fetchchar, &fetchbuf, + &packets, 0); + parse_keys(packets, &key); + + iterfunc(ctx, key); + + free_publickey(key); + key = NULL; + free_packet_list(packets); + packets = NULL; + + memset(&dbkey, 0, sizeof(dbkey)); + memset(&data, 0, sizeof(data)); + ret = cursor->c_get(cursor, &dbkey, &data, + DB_NEXT); + numkeys++; + } + if (ret != DB_NOTFOUND) { + logthing(LOGTHING_ERROR, + "Problem reading key: %s", + db_strerror(ret)); + } + + ret = cursor->c_close(cursor); + cursor = NULL; + } + + return numkeys; +} + /** * getfullkeyid - Maps a 32bit key id to a 64bit one. * @keyid: The 32bit keyid. diff --git a/keydb_file.c b/keydb_file.c index 81cb22a..1ef81b4 100644 --- a/keydb_file.c +++ b/keydb_file.c @@ -3,11 +3,12 @@ * * Jonathan McDowell * - * Copyright 2002 Project Purple + * Copyright 2002-2004 Project Purple */ #include #include +#include #include #include #include @@ -20,6 +21,7 @@ #include "keyid.h" #include "keystructs.h" #include "ll.h" +#include "log.h" #include "mem.h" #include "onak-conf.h" #include "parsekey.h" @@ -167,6 +169,66 @@ int fetch_key_text(const char *search, struct openpgp_publickey **publickey) return 0; } +/** + * iterate_keys - call a function once for each key in the db. + * @iterfunc: The function to call. + * @ctx: A context pointer + * + * 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 iterate_keys(void (*iterfunc)(void *ctx, struct openpgp_publickey *key), + void *ctx) +{ + int numkeys = 0; + struct openpgp_packet_list *packets = NULL; + struct openpgp_publickey *key = NULL; + DIR *dir; + char keyfile[1024]; + int fd = -1; + struct dirent *curfile = NULL; + + dir = opendir(config.db_dir); + + if (dir != NULL) { + while ((curfile = readdir(dir)) != NULL) { + if (curfile->d_name[0] == '0' && + curfile->d_name[1] == 'x') { + snprintf(keyfile, 1023, "%s/%s", + config.db_dir, + curfile->d_name); + fd = open(keyfile, O_RDONLY); + + if (fd > -1) { + read_openpgp_stream(file_fetchchar, + &fd, + &packets, + 0); + parse_keys(packets, &key); + + iterfunc(ctx, key); + + free_publickey(key); + key = NULL; + free_packet_list(packets); + packets = NULL; + close(fd); + } + numkeys++; + } + } + + closedir(dir); + dir = NULL; + } + + return numkeys; +} + + /** * dumpdb - dump the key database * @filenamebase: The base filename to use for the dump. diff --git a/keydb_fs.c b/keydb_fs.c index 73d9758..1c5d14c 100644 --- a/keydb_fs.c +++ b/keydb_fs.c @@ -532,6 +532,23 @@ uint64_t getfullkeyid(uint64_t keyid) return ret; } +/** + * iterate_keys - call a function once for each key in the db. + * @iterfunc: The function to call. + * @ctx: A context pointer + * + * 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 iterate_keys(void (*iterfunc)(void *ctx, struct openpgp_publickey *key), + void *ctx) +{ + return 0; +} + /* * Include the basic keydb routines. */ diff --git a/keydb_keyd.c b/keydb_keyd.c index 0399bc3..fac5548 100644 --- a/keydb_keyd.c +++ b/keydb_keyd.c @@ -356,6 +356,71 @@ int dumpdb(char *filenamebase) return 0; } +/** + * iterate_keys - call a function once for each key in the db. + * @iterfunc: The function to call. + * @ctx: A context pointer + * + * 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 iterate_keys(void (*iterfunc)(void *ctx, struct openpgp_publickey *key), + void *ctx) +{ + struct buffer_ctx keybuf; + struct openpgp_packet_list *packets = NULL; + struct openpgp_publickey *key = NULL; + int 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 diff --git a/keydb_pg.c b/keydb_pg.c index 88682af..afdbb23 100644 --- a/keydb_pg.c +++ b/keydb_pg.c @@ -3,7 +3,7 @@ * * Jonathan McDowell * - * Copyright 2002 Project Purple + * Copyright 2002-2004 Project Purple */ #include @@ -582,6 +582,65 @@ int dumpdb(char *filenamebase) return 0; } +/** + * iterate_keys - call a function once for each key in the db. + * @iterfunc: The function to call. + * @ctx: A context pointer + * + * 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 iterate_keys(void (*iterfunc)(void *ctx, struct openpgp_publickey *key), + void *ctx) +{ + struct openpgp_packet_list *packets = NULL; + struct openpgp_publickey *key = NULL; + PGresult *result = NULL; + char *oids = NULL; + char statement[1024]; + int fd = -1; + int i = 0; + int numkeys = 0; + Oid key_oid; + + result = PQexec(dbconn, "SELECT keydata FROM onak_keys;"); + + if (PQresultStatus(result) == PGRES_TUPLES_OK) { + numkeys = PQntuples(result); + for (i = 0; i < numkeys; i++) { + oids = PQgetvalue(result, i, 0); + key_oid = (Oid) atoi(oids); + + fd = lo_open(dbconn, key_oid, INV_READ); + if (fd < 0) { + logthing(LOGTHING_ERROR, + "Can't open large object."); + } else { + read_openpgp_stream(keydb_fetchchar, &fd, + &packets, 0); + parse_keys(packets, key); + lo_close(dbconn, fd); + + iterfunc(ctx, key); + + free_publickey(key); + key = NULL; + free_packet_list(packets); + packets = NULL; + } + } + } else if (PQresultStatus(result) != PGRES_TUPLES_OK) { + logthing(LOGTHING_ERROR, "Problem retrieving key from DB."); + } + + PQclear(result); + + return (numkeys); +} + /* * Include the basic keydb routines. */ -- 2.39.2 From 535ab6abb5d606afdbd9c50699fd861b301ba600 Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Mon, 27 Sep 2004 22:34:47 +0000 Subject: [PATCH 13/16] Make Makefile cleanup keyd and backend db .o files. We weren't cleaning up keyd.o and keydb_$(DBTYPE).o with "make clean" when keyd was enabled; fix this. --- Makefile.in | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile.in b/Makefile.in index 896711c..cab1f82 100644 --- a/Makefile.in +++ b/Makefile.in @@ -83,9 +83,12 @@ onak.conf: onak.conf.in < onak.conf.in > onak.conf clean: - $(RM) -f $(PROGS) $(OBJS) Makefile.bak testparse maxpath *.core core \ + $(RM) $(PROGS) $(OBJS) Makefile.bak testparse maxpath *.core core \ gpgwww.o add.o lookup.o main.o maxpath.o onak.o sixdegrees \ sixdegrees.o splitkeys.o stripkey.o onak.conf +ifeq (x@KEYD@, xyes) + $(RM) keyd.o keydb_$(DBTYPE).o +endif distclean: clean $(RM) -f Makefile .depend config.{log,status,h} -- 2.39.2 From 99c35bb21639a4d9e4d3da7434960525d2113ac2 Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Tue, 28 Sep 2004 11:02:18 +0000 Subject: [PATCH 14/16] Change buffer_put/fetchchar functions to use memcpy. We used an inefficient loop to copy data in the buffer character functions; change them to use memcpy. --- charfuncs.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/charfuncs.c b/charfuncs.c index c8a140f..778df1c 100644 --- a/charfuncs.c +++ b/charfuncs.c @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -22,12 +23,11 @@ int buffer_fetchchar(void *ctx, size_t count, unsigned char *c) { struct buffer_ctx *buf = NULL; - size_t i; buf = (struct buffer_ctx *) ctx; - for (i = 0; i < count; i++) { - c[i] = buf->buffer[buf->offset++]; - } + + memcpy(c, &buf->buffer[buf->offset], count); + buf->offset += count; return (((buf->offset) == (buf->size)) ? 1 : 0); } @@ -46,7 +46,6 @@ int buffer_putchar(void *ctx, size_t count, unsigned char *c) { struct buffer_ctx *buf = NULL; size_t newsize = 0; - size_t i; buf = (struct buffer_ctx *) ctx; @@ -57,11 +56,10 @@ int buffer_putchar(void *ctx, size_t count, unsigned char *c) buf->buffer = realloc(buf->buffer, newsize); buf->size = newsize; } - - for (i = 0; i < count; i++) { - buf->buffer[buf->offset++] = c[i]; - } + memcpy(&buf->buffer[buf->offset], c, count); + buf->offset += count; + return 1; } -- 2.39.2 From 082ed75922ea5dde7779e76db20991f595f0d541 Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Tue, 28 Sep 2004 17:17:43 +0000 Subject: [PATCH 15/16] Remove ancient gprof output. onak.gprof is no longer relevant; remove it. --- onak.gprof | 295 ----------------------------------------------------- 1 file changed, 295 deletions(-) delete mode 100644 onak.gprof diff --git a/onak.gprof b/onak.gprof deleted file mode 100644 index 0e8b40b..0000000 --- a/onak.gprof +++ /dev/null @@ -1,295 +0,0 @@ -Flat profile: - -Each sample counts as 0.01 seconds. - % cumulative self self total - time seconds seconds calls us/call us/call name - 44.57 0.41 0.41 44208 9.27 14.02 transform - 22.83 0.62 0.21 9902592 0.02 0.02 rol - 9.78 0.71 0.09 31610 2.85 19.66 sha1_write - 7.61 0.78 0.07 33623 2.08 2.08 stdin_getchar - 2.17 0.80 0.02 6937 2.88 106.67 get_keyid - 2.17 0.82 0.02 1690 11.83 17.75 write_openpgp_stream - 2.17 0.84 0.02 Letext - 1.09 0.85 0.01 30179 0.33 0.33 keydb_putchar - 1.09 0.86 0.01 17848 0.56 0.56 packet_dup - 1.09 0.87 0.01 6322 1.58 35.26 sha1_final - 1.09 0.88 0.01 1690 5.92 8.88 flatten_publickey - 1.09 0.89 0.01 1690 5.92 5.92 keyuids - 1.09 0.90 0.01 1690 5.92 262.98 store_key - 1.09 0.91 0.01 1 10000.00 10000.00 free_publickey - 1.09 0.92 0.01 1 10000.00 815000.00 update_keys - 0.00 0.92 0.00 17848 0.00 0.00 free_packet - 0.00 0.92 0.00 6322 0.00 0.00 sha1_init - 0.00 0.92 0.00 6322 0.00 0.00 sha1_read - 0.00 0.92 0.00 3438 0.00 0.00 free_packet_list - 0.00 0.92 0.00 3227 0.00 0.00 free_signedpacket_list - 0.00 0.92 0.00 1690 0.00 0.00 endtrans - 0.00 0.92 0.00 1690 0.00 0.00 fetch_key - 0.00 0.92 0.00 1690 0.00 0.00 spsize - 0.00 0.92 0.00 1690 0.00 0.00 starttrans - 0.00 0.92 0.00 1 0.00 0.00 cleanupdb - 0.00 0.92 0.00 1 0.00 0.00 initdb - 0.00 0.92 0.00 1 0.00 5000.00 parse_keys - 0.00 0.92 0.00 1 0.00 70000.00 read_openpgp_stream - - % the percentage of the total running time of the -time program used by this function. - -cumulative a running sum of the number of seconds accounted - seconds for by this function and those listed above it. - - self the number of seconds accounted for by this -seconds function alone. This is the major sort for this - listing. - -calls the number of times this function was invoked, if - this function is profiled, else blank. - - self the average number of milliseconds spent in this -ms/call function per call, if this function is profiled, - else blank. - - total the average number of milliseconds spent in this -ms/call function and its descendents per call, if this - function is profiled, else blank. - -name the name of the function. This is the minor sort - for this listing. The index shows the location of - the function in the gprof listing. If the index is - in parenthesis it shows where it would appear in - the gprof listing if it were to be printed. - - Call graph (explanation follows) - - -granularity: each sample hit covers 4 byte(s) for 1.09% of 0.92 seconds - -index % time self children called name - -[1] 97.8 0.00 0.90 main [1] - 0.01 0.81 1/1 update_keys [2] - 0.00 0.07 1/1 read_openpgp_stream [10] - 0.01 0.00 1/1 free_publickey [17] - 0.00 0.01 1/1 parse_keys [18] - 0.00 0.00 1/3438 free_packet_list [22] - 0.00 0.00 1/1 initdb [29] - 0.00 0.00 1/1 cleanupdb [28] ------------------------------------------------ - 0.01 0.81 1/1 main [1] -[2] 88.6 0.01 0.81 1 update_keys [2] - 0.01 0.43 1690/1690 store_key [6] - 0.01 0.35 3380/6937 get_keyid [3] - 0.00 0.00 1690/1690 starttrans [27] - 0.00 0.00 1690/1690 fetch_key [25] - 0.00 0.00 1690/1690 endtrans [24] ------------------------------------------------ - 0.01 0.35 3380/6937 update_keys [2] - 0.01 0.37 3557/6937 store_key [6] -[3] 80.4 0.02 0.72 6937 get_keyid [3] - 0.07 0.43 25288/31610 sha1_write [4] - 0.01 0.21 6322/6322 sha1_final [7] - 0.00 0.00 6322/6322 sha1_init [20] - 0.00 0.00 6322/6322 sha1_read [21] ------------------------------------------------ - 18966 sha1_write [4] - 0.02 0.11 6322/31610 sha1_final [7] - 0.07 0.43 25288/31610 get_keyid [3] -[4] 67.5 0.09 0.53 31610+18966 sha1_write [4] - 0.35 0.18 37886/44208 transform [5] - 18966 sha1_write [4] ------------------------------------------------ - 0.06 0.03 6322/44208 sha1_final [7] - 0.35 0.18 37886/44208 sha1_write [4] -[5] 67.4 0.41 0.21 44208 transform [5] - 0.21 0.00 9902592/9902592 rol [8] ------------------------------------------------ - 0.01 0.43 1690/1690 update_keys [2] -[6] 48.3 0.01 0.43 1690 store_key [6] - 0.01 0.37 3557/6937 get_keyid [3] - 0.02 0.01 1690/1690 write_openpgp_stream [11] - 0.01 0.01 1690/1690 flatten_publickey [13] - 0.01 0.00 1690/1690 keyuids [16] ------------------------------------------------ - 0.01 0.21 6322/6322 get_keyid [3] -[7] 24.2 0.01 0.21 6322 sha1_final [7] - 0.02 0.11 6322/31610 sha1_write [4] - 0.06 0.03 6322/44208 transform [5] ------------------------------------------------ - 0.21 0.00 9902592/9902592 transform [5] -[8] 22.8 0.21 0.00 9902592 rol [8] ------------------------------------------------ - 0.07 0.00 33623/33623 read_openpgp_stream [10] -[9] 7.6 0.07 0.00 33623 stdin_getchar [9] ------------------------------------------------ - 0.00 0.07 1/1 main [1] -[10] 7.6 0.00 0.07 1 read_openpgp_stream [10] - 0.07 0.00 33623/33623 stdin_getchar [9] ------------------------------------------------ - 0.02 0.01 1690/1690 store_key [6] -[11] 3.3 0.02 0.01 1690 write_openpgp_stream [11] - 0.01 0.00 30179/30179 keydb_putchar [14] ------------------------------------------------ - -[12] 2.2 0.02 0.00 Letext [12] ------------------------------------------------ - 0.01 0.01 1690/1690 store_key [6] -[13] 1.6 0.01 0.01 1690 flatten_publickey [13] - 0.01 0.00 8924/17848 packet_dup [15] ------------------------------------------------ - 0.01 0.00 30179/30179 write_openpgp_stream [11] -[14] 1.1 0.01 0.00 30179 keydb_putchar [14] ------------------------------------------------ - 0.01 0.00 8924/17848 parse_keys [18] - 0.01 0.00 8924/17848 flatten_publickey [13] -[15] 1.1 0.01 0.00 17848 packet_dup [15] ------------------------------------------------ - 0.01 0.00 1690/1690 store_key [6] -[16] 1.1 0.01 0.00 1690 keyuids [16] - 0.00 0.00 1690/1690 spsize [26] ------------------------------------------------ - 0.01 0.00 1/1 main [1] -[17] 1.1 0.01 0.00 1 free_publickey [17] - 0.00 0.00 3227/3227 free_signedpacket_list [23] - 0.00 0.00 1690/17848 free_packet [19] - 0.00 0.00 41/3438 free_packet_list [22] ------------------------------------------------ - 0.00 0.01 1/1 main [1] -[18] 0.5 0.00 0.01 1 parse_keys [18] - 0.01 0.00 8924/17848 packet_dup [15] ------------------------------------------------ - 0.00 0.00 1690/17848 free_publickey [17] - 0.00 0.00 3410/17848 free_signedpacket_list [23] - 0.00 0.00 12748/17848 free_packet_list [22] -[19] 0.0 0.00 0.00 17848 free_packet [19] ------------------------------------------------ - 0.00 0.00 6322/6322 get_keyid [3] -[20] 0.0 0.00 0.00 6322 sha1_init [20] ------------------------------------------------ - 0.00 0.00 6322/6322 get_keyid [3] -[21] 0.0 0.00 0.00 6322 sha1_read [21] ------------------------------------------------ - 0.00 0.00 1/3438 main [1] - 0.00 0.00 41/3438 free_publickey [17] - 0.00 0.00 3396/3438 free_signedpacket_list [23] -[22] 0.0 0.00 0.00 3438 free_packet_list [22] - 0.00 0.00 12748/17848 free_packet [19] ------------------------------------------------ - 0.00 0.00 3227/3227 free_publickey [17] -[23] 0.0 0.00 0.00 3227 free_signedpacket_list [23] - 0.00 0.00 3410/17848 free_packet [19] - 0.00 0.00 3396/3438 free_packet_list [22] ------------------------------------------------ - 0.00 0.00 1690/1690 update_keys [2] -[24] 0.0 0.00 0.00 1690 endtrans [24] ------------------------------------------------ - 0.00 0.00 1690/1690 update_keys [2] -[25] 0.0 0.00 0.00 1690 fetch_key [25] ------------------------------------------------ - 0.00 0.00 1690/1690 keyuids [16] -[26] 0.0 0.00 0.00 1690 spsize [26] ------------------------------------------------ - 0.00 0.00 1690/1690 update_keys [2] -[27] 0.0 0.00 0.00 1690 starttrans [27] ------------------------------------------------ - 0.00 0.00 1/1 main [1] -[28] 0.0 0.00 0.00 1 cleanupdb [28] ------------------------------------------------ - 0.00 0.00 1/1 main [1] -[29] 0.0 0.00 0.00 1 initdb [29] ------------------------------------------------ - - This table describes the call tree of the program, and was sorted by - the total amount of time spent in each function and its children. - - Each entry in this table consists of several lines. The line with the - index number at the left hand margin lists the current function. - The lines above it list the functions that called this function, - and the lines below it list the functions this one called. - This line lists: - index A unique number given to each element of the table. - Index numbers are sorted numerically. - The index number is printed next to every function name so - it is easier to look up where the function in the table. - - % time This is the percentage of the `total' time that was spent - in this function and its children. Note that due to - different viewpoints, functions excluded by options, etc, - these numbers will NOT add up to 100%. - - self This is the total amount of time spent in this function. - - children This is the total amount of time propagated into this - function by its children. - - called This is the number of times the function was called. - If the function called itself recursively, the number - only includes non-recursive calls, and is followed by - a `+' and the number of recursive calls. - - name The name of the current function. The index number is - printed after it. If the function is a member of a - cycle, the cycle number is printed between the - function's name and the index number. - - - For the function's parents, the fields have the following meanings: - - self This is the amount of time that was propagated directly - from the function into this parent. - - children This is the amount of time that was propagated from - the function's children into this parent. - - called This is the number of times this parent called the - function `/' the total number of times the function - was called. Recursive calls to the function are not - included in the number after the `/'. - - name This is the name of the parent. The parent's index - number is printed after it. If the parent is a - member of a cycle, the cycle number is printed between - the name and the index number. - - If the parents of the function cannot be determined, the word - `' is printed in the `name' field, and all the other - fields are blank. - - For the function's children, the fields have the following meanings: - - self This is the amount of time that was propagated directly - from the child into the function. - - children This is the amount of time that was propagated from the - child's children to the function. - - called This is the number of times the function called - this child `/' the total number of times the child - was called. Recursive calls by the child are not - listed in the number after the `/'. - - name This is the name of the child. The child's index - number is printed after it. If the child is a - member of a cycle, the cycle number is printed - between the name and the index number. - - If there are any cycles (circles) in the call graph, there is an - entry for the cycle-as-a-whole. This entry shows who called the - cycle (as parents) and the members of the cycle (as children.) - The `+' recursive calls entry shows the number of function calls that - were internal to the cycle, and the calls entry for each member shows, - for that member, how many times it was called from other members of - the cycle. - - -Index by function name - - [12] Letext (bithelp.h) [29] initdb [4] sha1_write - [28] cleanupdb [14] keydb_putchar (keydb_pg.c) [26] spsize - [24] endtrans [16] keyuids [27] starttrans - [25] fetch_key [15] packet_dup [9] stdin_getchar - [13] flatten_publickey [18] parse_keys [6] store_key - [19] free_packet [10] read_openpgp_stream [5] transform (sha.c) - [22] free_packet_list [8] rol (bithelp.h) [2] update_keys - [17] free_publickey [7] sha1_final [11] write_openpgp_stream - [23] free_signedpacket_list [20] sha1_init - [3] get_keyid [21] sha1_read -- 2.39.2 From fd58db2034c6781399583384055ce69fc300b26b Mon Sep 17 00:00:00 2001 From: Jonathan McDowell Date: Sat, 16 Oct 2004 20:11:22 +0000 Subject: [PATCH 16/16] Move mailsync functionality to the database backends. Move the sending of key sync mails to the DB backend. --- Makefile.in | 8 ++++---- add.c | 5 +++-- keydb.c | 7 ++++++- keydb.h | 6 +++++- onak.c | 2 +- 5 files changed, 19 insertions(+), 9 deletions(-) diff --git a/Makefile.in b/Makefile.in index cab1f82..d9459c8 100644 --- a/Makefile.in +++ b/Makefile.in @@ -18,7 +18,7 @@ exec_prefix ?= @exec_prefix@ PROGS = add lookup gpgwww onak splitkeys onak-mail.pl stripkey CORE_OBJS = armor.o charfuncs.o decodekey.o getcgi.o hash.o \ keyid.o keyindex.o ll.o mem.o onak-conf.o parsekey.o sha1.o md5.o \ - log.o photoid.o wordlist.o cleanup.o merge.o + log.o photoid.o wordlist.o cleanup.o merge.o sendsync.o SRCS = armor.c parsekey.c merge.c keyid.c md5.c sha1.c main.c getcgi.c mem.c \ keyindex.c stats.c lookup.c add.c keydb_$(DBTYPE).c ll.c hash.c \ gpgwww.c onak-conf.c charfuncs.c sendsync.c log.c photoid.c \ @@ -32,7 +32,7 @@ else KEYDB_OBJ = keydb_$(DBTYPE).o endif -OBJS = stats.o sendsync.o cleankey.o $(CORE_OBJS) $(KEYDB_OBJ) +OBJS = stats.o cleankey.o $(CORE_OBJS) $(KEYDB_OBJ) all: .depend $(PROGS) testparse maxpath sixdegrees splitkeys onak.conf @@ -62,8 +62,8 @@ lookup: lookup.o cleankey.o $(CORE_OBJS) $(KEYDB_OBJ) $(CC) $(LDFLAGS) -o lookup lookup.o cleankey.o $(CORE_OBJS) \ $(KEYDB_OBJ) $(LIBS) -add: add.o cleankey.o sendsync.o $(CORE_OBJS) $(KEYDB_OBJ) - $(CC) $(LDFLAGS) -o add add.o cleankey.o sendsync.o \ +add: add.o cleankey.o $(CORE_OBJS) $(KEYDB_OBJ) + $(CC) $(LDFLAGS) -o add add.o cleankey.o \ $(CORE_OBJS) $(KEYDB_OBJ) $(LIBS) onak: onak.o cleankey.o $(CORE_OBJS) $(KEYDB_OBJ) diff --git a/add.c b/add.c index 189444e..46f5ecf 100644 --- a/add.c +++ b/add.c @@ -78,14 +78,15 @@ int main(int argc, char *argv[]) logthing(LOGTHING_INFO, "%d keys cleaned.", count); - count = update_keys(&keys); + count = update_keys(&keys, true); logthing(LOGTHING_NOTICE, "Got %d new keys.", count); + if (keys != NULL) { - sendkeysync(keys); free_publickey(keys); keys = NULL; } + cleanupdb(); } else { puts("No OpenPGP packets found in input."); diff --git a/keydb.c b/keydb.c index 1621782..b8bd316 100644 --- a/keydb.c +++ b/keydb.c @@ -156,6 +156,7 @@ uint64_t getfullkeyid(uint64_t keyid) /** * update_keys - Takes a list of public keys and updates them in the DB. * @keys: The keys to update in the DB. + * @sendsync: Should we send a sync mail to our peers. * * Takes a list of keys and adds them to the database, merging them with * the key in the database if it's already present there. The key list is @@ -163,7 +164,7 @@ uint64_t getfullkeyid(uint64_t keyid) * we had before to what we have now (ie the set of data that was added to * the DB). Returns the number of entirely new keys added. */ -int update_keys(struct openpgp_publickey **keys) +int update_keys(struct openpgp_publickey **keys, bool sendsync) { struct openpgp_publickey *curkey = NULL; struct openpgp_publickey *oldkey = NULL; @@ -215,6 +216,10 @@ int update_keys(struct openpgp_publickey **keys) intrans = false; } + if (sendsync && keys != NULL) { + sendkeysync(keys); + } + return newkeys; } #endif /* NEED_UPDATEKEYS */ diff --git a/keydb.h b/keydb.h index ca2a823..98cf34d 100644 --- a/keydb.h +++ b/keydb.h @@ -100,14 +100,18 @@ int fetch_key_text(const char *search, struct openpgp_publickey **publickey); /** * update_keys - Takes a list of public keys and updates them in the DB. * @keys: The keys to update in the DB. + * @sendsync: If we should send a keysync mail. * * Takes a list of keys and adds them to the database, merging them with * the key in the database if it's already present there. The key list is * update to contain the minimum set of updates required to get from what * we had before to what we have now (ie the set of data that was added to * the DB). Returns the number of entirely new keys added. + * + * If sendsync is true then we send out a keysync mail to our sync peers + * with the update. */ -int update_keys(struct openpgp_publickey **keys); +int update_keys(struct openpgp_publickey **keys, bool sendsync); /** * keyid2uid - Takes a keyid and returns the primary UID for it. diff --git a/onak.c b/onak.c index 7bd8919..e79e565 100644 --- a/onak.c +++ b/onak.c @@ -145,7 +145,7 @@ int main(int argc, char *argv[]) initdb(false); logthing(LOGTHING_NOTICE, "Got %d new keys.", - update_keys(&keys)); + update_keys(&keys, false)); if (keys != NULL && update) { flatten_publickey(keys, &packets, -- 2.39.2