2  * onak.c - An OpenPGP keyserver.
 
   4  * This is the main swiss army knife binary.
 
   6  * Jonathan McDowell <noodles@earth.li>
 
   8  * Copyright 2002 Project Purple
 
  16 #include <sys/types.h>
 
  21 #include "charfuncs.h"
 
  28 #include "keystructs.h"
 
  32 #include "onak-conf.h"
 
  36 void find_keys(char *search, uint64_t keyid, bool ishex,
 
  37                 bool fingerprint, bool exact, bool verbose)
 
  39         struct openpgp_publickey *publickey = NULL;
 
  43                 count = config.dbbackend->fetch_key(keyid, &publickey, false);
 
  45                 count = config.dbbackend->fetch_key_text(search, &publickey);
 
  47         if (publickey != NULL) {
 
  48                 key_index(publickey, verbose, fingerprint, false);
 
  49                 free_publickey(publickey);
 
  50         } else if (count == 0) {
 
  51                 puts("Key not found.");
 
  53                 printf("Found %d keys, but maximum number to return is %d.\n",
 
  56                 puts("Try again with a more specific search.");
 
  68 void dump_func(void *ctx, struct openpgp_publickey *key)
 
  70         struct openpgp_packet_list *packets = NULL;
 
  71         struct openpgp_packet_list *list_end = NULL;
 
  72         struct dump_ctx *state;
 
  75         state = (struct dump_ctx *) ctx;
 
  77         if (state->fd == -1 || state->count > state->maxcount) {
 
  78                 if (state->fd != -1) {
 
  82                 snprintf(filename, 1023, state->filebase, state->filenum);
 
  83                 state->fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0640);
 
  87         flatten_publickey(key, &packets, &list_end);
 
  88         write_openpgp_stream(file_putchar, &state->fd, packets);
 
  89         free_packet_list(packets);
 
  90         packets = list_end = NULL;
 
  96         puts("onak " PACKAGE_VERSION " - an OpenPGP keyserver.\n");
 
  98         puts("\tonak [options] <command> <parameters>\n");
 
  99         puts("\tCommands:\n");
 
 100         puts("\tadd      - read armored OpenPGP keys from stdin and add to the"
 
 102         puts("\tclean    - read armored OpenPGP keys from stdin, run the"
 
 103                 " cleaning\n\t             routines against them and dump to"
 
 105         puts("\tdelete   - delete a given key from the keyserver");
 
 106         puts("\tdump     - dump all the keys from the keyserver to a file or"
 
 107                 " files\n\t           starting keydump*");
 
 108         puts("\tget      - retrieves the key requested from the keyserver");
 
 109         puts("\tgetphoto - retrieves the first photoid on the given key and"
 
 110                 " dumps to\n\t           stdout");
 
 111         puts("\tindex    - search for a key and list it");
 
 112         puts("\tvindex   - search for a key and list it and its signatures");
 
 115 int main(int argc, char *argv[])
 
 117         struct openpgp_packet_list      *packets = NULL;
 
 118         struct openpgp_packet_list      *list_end = NULL;
 
 119         struct openpgp_publickey        *keys = NULL;
 
 120         char                            *configfile = NULL;
 
 121         int                              rc = EXIT_SUCCESS;
 
 127         bool                             verbose = false;
 
 130         bool                             fingerprint = false;
 
 132         struct dump_ctx                  dumpstate;
 
 134         while ((optchar = getopt(argc, argv, "bc:fuv")) != -1 ) {
 
 140                         configfile = strdup(optarg);
 
 150                         setlogthreshold(LOGTHING_INFO);
 
 155         readconfig(configfile);
 
 156         initlogthing("onak", config.logfile);
 
 159         if ((argc - optind) < 1) {
 
 161         } else if (!strcmp("dump", argv[optind])) {
 
 162                 config.dbbackend->initdb(true);
 
 163                 dumpstate.count = dumpstate.filenum = 0;
 
 164                 dumpstate.maxcount = 1000000;
 
 166                 dumpstate.filebase = "keydump.%d.pgp";
 
 167                 config.dbbackend->iterate_keys(dump_func, &dumpstate);
 
 168                 if (dumpstate.fd != -1) {
 
 172                 config.dbbackend->cleanupdb();
 
 173         } else if (!strcmp("add", argv[optind])) {
 
 175                         result = read_openpgp_stream(stdin_getchar, NULL,
 
 177                         logthing(LOGTHING_INFO,
 
 178                                         "read_openpgp_stream: %d", result);
 
 180                         dearmor_openpgp_stream(stdin_getchar, NULL, &packets);
 
 182                 if (packets != NULL) {
 
 183                         result = parse_keys(packets, &keys);
 
 184                         free_packet_list(packets);
 
 186                         logthing(LOGTHING_INFO, "Finished reading %d keys.",
 
 189                         result = cleankeys(keys);
 
 190                         logthing(LOGTHING_INFO, "%d keys cleaned.",
 
 193                         config.dbbackend->initdb(false);
 
 194                         logthing(LOGTHING_NOTICE, "Got %d new keys.",
 
 195                                         config.dbbackend->update_keys(&keys,
 
 197                         if (keys != NULL && update) {
 
 198                                 flatten_publickey(keys,
 
 202                                         write_openpgp_stream(stdout_putchar,
 
 206                                         armor_openpgp_stream(stdout_putchar,
 
 210                                 free_packet_list(packets);
 
 213                         config.dbbackend->cleanupdb();
 
 216                         logthing(LOGTHING_NOTICE, "No keys read.");
 
 220                         free_publickey(keys);
 
 224                         logthing(LOGTHING_NOTICE, "No changes.");
 
 226         } else if (!strcmp("clean", argv[optind])) {
 
 228                         result = read_openpgp_stream(stdin_getchar, NULL,
 
 230                         logthing(LOGTHING_INFO,
 
 231                                         "read_openpgp_stream: %d", result);
 
 233                         dearmor_openpgp_stream(stdin_getchar, NULL, &packets);
 
 236                 if (packets != NULL) {
 
 237                         result = parse_keys(packets, &keys);
 
 238                         free_packet_list(packets);
 
 240                         logthing(LOGTHING_INFO, "Finished reading %d keys.",
 
 244                                 result = cleankeys(keys);
 
 245                                 logthing(LOGTHING_INFO, "%d keys cleaned.",
 
 248                                 flatten_publickey(keys,
 
 253                                         write_openpgp_stream(stdout_putchar,
 
 257                                         armor_openpgp_stream(stdout_putchar,
 
 261                                 free_packet_list(packets);
 
 266                         logthing(LOGTHING_NOTICE, "No keys read.");
 
 270                         free_publickey(keys);
 
 273         } else if ((argc - optind) == 2) {
 
 274                 search = argv[optind+1];
 
 275                 if (search != NULL) {
 
 276                         keyid = strtoul(search, &end, 16);
 
 283                 config.dbbackend->initdb(false);
 
 284                 if (!strcmp("index", argv[optind])) {
 
 285                         find_keys(search, keyid, ishex, fingerprint,
 
 287                 } else if (!strcmp("vindex", argv[optind])) {
 
 288                         find_keys(search, keyid, ishex, fingerprint,
 
 290                 } else if (!strcmp("getphoto", argv[optind])) {
 
 292                                 puts("Can't get a key on uid text."
 
 293                                         " You must supply a keyid.");
 
 294                         } else if (config.dbbackend->fetch_key(keyid, &keys,
 
 296                                 unsigned char *photo = NULL;
 
 299                                 if (getphoto(keys, 0, &photo, &length)) {
 
 305                                 free_publickey(keys);
 
 308                                 puts("Key not found");
 
 310                 } else if (!strcmp("delete", argv[optind])) {
 
 311                         config.dbbackend->delete_key(
 
 312                                         config.dbbackend->getfullkeyid(keyid),
 
 314                 } else if (!strcmp("get", argv[optind])) {
 
 316                                 puts("Can't get a key on uid text."
 
 317                                         " You must supply a keyid.");
 
 318                         } else if (config.dbbackend->fetch_key(keyid, &keys,
 
 320                                 logthing(LOGTHING_INFO, "Got key.");
 
 321                                 flatten_publickey(keys,
 
 324                                 free_publickey(keys);
 
 325                                 armor_openpgp_stream(stdout_putchar,
 
 328                                 free_packet_list(packets);
 
 331                                 puts("Key not found");
 
 334                 config.dbbackend->cleanupdb();