X-Git-Url: https://git.sommitrealweird.co.uk/onak.git/blobdiff_plain/870ceebb3ffd90a47102ff04c8f7779177573216..3cbcf9bd0186a4256c1f0d3f75e0540594bfca1d:/onak.c diff --git a/onak.c b/onak.c index 87b65e8..e6b9287 100644 --- a/onak.c +++ b/onak.c @@ -8,42 +8,30 @@ * Copyright 2002 Project Purple */ +#include +#include #include #include #include +#include +#include #include #include "armor.h" +#include "charfuncs.h" +#include "cleankey.h" +#include "cleanup.h" +#include "config.h" #include "keydb.h" #include "keyid.h" #include "keyindex.h" #include "keystructs.h" +#include "log.h" #include "mem.h" #include "merge.h" #include "onak-conf.h" #include "parsekey.h" - -int stdin_getchar(void *ctx, size_t count, unsigned char *c) -{ - int ic; - - do { - ic = getchar(); - *c = ic; - c++; - } while ((ic != EOF) && (--count > 0)); - return (ic == EOF); -} - -int stdout_putchar(void *ctx, size_t count, unsigned char *c) -{ - int i; - - for (i = 0; i < count; i++) { - putchar(c[i]); - } - return 0; -} +#include "photoid.h" void find_keys(char *search, uint64_t keyid, bool ishex, bool fingerprint, bool exact, bool verbose) @@ -52,9 +40,9 @@ void find_keys(char *search, uint64_t keyid, bool ishex, int count = 0; if (ishex) { - count = fetch_key(keyid, &publickey, false); + count = config.dbbackend->fetch_key(keyid, &publickey, false); } else { - count = fetch_key_text(search, &publickey); + count = config.dbbackend->fetch_key_text(search, &publickey); } if (publickey != NULL) { key_index(publickey, verbose, fingerprint, false); @@ -69,16 +57,59 @@ void find_keys(char *search, uint64_t keyid, bool ishex, } } +struct dump_ctx { + int count; + int maxcount; + int fd; + int filenum; + char *filebase; +}; + +void dump_func(void *ctx, struct openpgp_publickey *key) +{ + struct openpgp_packet_list *packets = NULL; + struct openpgp_packet_list *list_end = NULL; + struct dump_ctx *state; + char filename[1024]; + + state = (struct dump_ctx *) ctx; + + if (state->fd == -1 || state->count++ > state->maxcount) { + if (state->fd != -1) { + close(state->fd); + state->fd = -1; + } + snprintf(filename, 1023, state->filebase, state->filenum); + state->fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0640); + state->filenum++; + state->count = 0; + } + flatten_publickey(key, &packets, &list_end); + write_openpgp_stream(file_putchar, &state->fd, packets); + free_packet_list(packets); + packets = list_end = NULL; + + return; +} + void usage(void) { - puts("onak " VERSION " - an OpenPGP keyserver.\n"); + puts("onak " PACKAGE_VERSION " - an OpenPGP keyserver.\n"); puts("Usage:\n"); puts("\tonak [options] \n"); puts("\tCommands:\n"); - puts("\tadd - read armored OpenPGP keys from stdin and add to the keyserver"); - puts("\tdelete - delete a given key from the keyserver"); - puts("\tget - retrieves the key requested from the keyserver"); - puts("\tindex - search for a key and list it"); - puts("\tvindex - search for a key and list it and its signatures"); + puts("\tadd - read armored OpenPGP keys from stdin and add to the" + " keyserver"); + puts("\tclean - read armored OpenPGP keys from stdin, run the" + " cleaning\n\t routines against them and dump to" + " stdout"); + puts("\tdelete - delete a given key from the keyserver"); + puts("\tdump - dump all the keys from the keyserver to a file or" + " files\n\t starting keydump*"); + puts("\tget - retrieves the key requested from the keyserver"); + puts("\tgetphoto - retrieves the first photoid on the given key and" + " dumps to\n\t stdout"); + puts("\tindex - search for a key and list it"); + puts("\tvindex - search for a key and list it and its signatures"); } int main(int argc, char *argv[]) @@ -86,50 +117,103 @@ int main(int argc, char *argv[]) struct openpgp_packet_list *packets = NULL; struct openpgp_packet_list *list_end = NULL; struct openpgp_publickey *keys = NULL; + char *configfile = NULL; int rc = EXIT_SUCCESS; + int result = 0; char *search = NULL; char *end = NULL; uint64_t keyid = 0; bool ishex = false; bool verbose = false; + bool update = false; bool binary = false; + bool fingerprint = false; int optchar; + struct dump_ctx dumpstate; - - while ((optchar = getopt(argc, argv, "bv")) != -1 ) { + while ((optchar = getopt(argc, argv, "bc:fuv")) != -1 ) { switch (optchar) { case 'b': binary = true; break; + case 'c': + configfile = strdup(optarg); + break; + case 'f': + fingerprint = true; + break; + case 'u': + update = true; + break; case 'v': verbose = true; + setlogthreshold(LOGTHING_INFO); break; } } + readconfig(configfile); + initlogthing("onak", config.logfile); + catchsignals(); + if ((argc - optind) < 1) { usage(); + } else if (!strcmp("dump", argv[optind])) { + config.dbbackend->initdb(true); + dumpstate.count = dumpstate.filenum = 0; + dumpstate.maxcount = 100000; + dumpstate.fd = -1; + dumpstate.filebase = "keydump.%d.pgp"; + config.dbbackend->iterate_keys(dump_func, &dumpstate); + if (dumpstate.fd != -1) { + close(dumpstate.fd); + dumpstate.fd = -1; + } + config.dbbackend->cleanupdb(); } else if (!strcmp("add", argv[optind])) { if (binary) { - read_openpgp_stream(stdin_getchar, NULL, &packets); + result = read_openpgp_stream(stdin_getchar, NULL, + &packets, 0); + logthing(LOGTHING_INFO, + "read_openpgp_stream: %d", result); } else { dearmor_openpgp_stream(stdin_getchar, NULL, &packets); } if (packets != NULL) { - parse_keys(packets, &keys); + result = parse_keys(packets, &keys); free_packet_list(packets); packets = NULL; - if (verbose) { - fprintf(stderr, "Finished reading keys.\n"); + logthing(LOGTHING_INFO, "Finished reading %d keys.", + result); + + result = cleankeys(keys); + logthing(LOGTHING_INFO, "%d keys cleaned.", + result); + + config.dbbackend->initdb(false); + logthing(LOGTHING_NOTICE, "Got %d new keys.", + config.dbbackend->update_keys(&keys, + false)); + if (keys != NULL && update) { + flatten_publickey(keys, + &packets, + &list_end); + if (binary) { + write_openpgp_stream(stdout_putchar, + NULL, + packets); + } else { + armor_openpgp_stream(stdout_putchar, + NULL, + packets); + } + free_packet_list(packets); + packets = NULL; } - - initdb(); - fprintf(stderr, "Got %d new keys.\n", - update_keys(&keys, verbose)); - cleanupdb(); + config.dbbackend->cleanupdb(); } else { rc = 1; - fprintf(stderr, "No keys read.\n"); + logthing(LOGTHING_NOTICE, "No keys read."); } if (keys != NULL) { @@ -137,7 +221,54 @@ int main(int argc, char *argv[]) keys = NULL; } else { rc = 1; - fprintf(stderr, "No changes.\n"); + logthing(LOGTHING_NOTICE, "No changes."); + } + } else if (!strcmp("clean", argv[optind])) { + if (binary) { + result = read_openpgp_stream(stdin_getchar, NULL, + &packets, 0); + logthing(LOGTHING_INFO, + "read_openpgp_stream: %d", result); + } else { + dearmor_openpgp_stream(stdin_getchar, NULL, &packets); + } + + if (packets != NULL) { + result = parse_keys(packets, &keys); + free_packet_list(packets); + packets = NULL; + logthing(LOGTHING_INFO, "Finished reading %d keys.", + result); + + if (keys != NULL) { + result = cleankeys(keys); + logthing(LOGTHING_INFO, "%d keys cleaned.", + result); + + flatten_publickey(keys, + &packets, + &list_end); + + if (binary) { + write_openpgp_stream(stdout_putchar, + NULL, + packets); + } else { + armor_openpgp_stream(stdout_putchar, + NULL, + packets); + } + free_packet_list(packets); + packets = NULL; + } + } else { + rc = 1; + logthing(LOGTHING_NOTICE, "No keys read."); + } + + if (keys != NULL) { + free_publickey(keys); + keys = NULL; } } else if ((argc - optind) == 2) { search = argv[optind+1]; @@ -149,32 +280,70 @@ int main(int argc, char *argv[]) ishex = true; } } - initdb(); + config.dbbackend->initdb(false); if (!strcmp("index", argv[optind])) { - find_keys(search, keyid, ishex, false, false, false); + find_keys(search, keyid, ishex, fingerprint, + false, false); } else if (!strcmp("vindex", argv[optind])) { - find_keys(search, keyid, ishex, false, false, true); + find_keys(search, keyid, ishex, fingerprint, + false, true); + } else if (!strcmp("getphoto", argv[optind])) { + if (!ishex) { + puts("Can't get a key on uid text." + " You must supply a keyid."); + } else if (config.dbbackend->fetch_key(keyid, &keys, + false)) { + unsigned char *photo = NULL; + size_t length = 0; + + if (getphoto(keys, 0, &photo, &length)) { + fwrite(photo, + 1, + length, + stdout); + } + free_publickey(keys); + keys = NULL; + } else { + puts("Key not found"); + } } else if (!strcmp("delete", argv[optind])) { - delete_key(getfullkeyid(keyid), false); + config.dbbackend->delete_key( + config.dbbackend->getfullkeyid(keyid), + false); } else if (!strcmp("get", argv[optind])) { - if (fetch_key(keyid, &keys, false)) { - if (verbose) { - fprintf(stderr, "Got key.\n"); - } + if (!ishex) { + puts("Can't get a key on uid text." + " You must supply a keyid."); + } else if (config.dbbackend->fetch_key(keyid, &keys, + false)) { + logthing(LOGTHING_INFO, "Got key."); flatten_publickey(keys, &packets, &list_end); - armor_openpgp_stream(stdout_putchar, + free_publickey(keys); + if (binary) { + write_openpgp_stream(stdout_putchar, NULL, packets); + } else { + armor_openpgp_stream(stdout_putchar, + NULL, + packets); + } + free_packet_list(packets); + packets = NULL; } else { puts("Key not found"); } } - cleanupdb(); + config.dbbackend->cleanupdb(); } else { usage(); } + cleanuplogthing(); + cleanupconfig(); + return rc; }