cscvs to tla changeset 125
[onak.git] / onak.c
1 /*
2  * onak.c - An OpenPGP keyserver.
3  *
4  * This is the main swiss army knife binary.
5  *
6  * Jonathan McDowell <noodles@earth.li>
7  * 
8  * Copyright 2002 Project Purple
9  *
10  * $Id: onak.c,v 1.20 2004/05/27 01:25:37 noodles Exp $
11  */
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <unistd.h>
17
18 #include "armor.h"
19 #include "charfuncs.h"
20 #include "keydb.h"
21 #include "keyid.h"
22 #include "keyindex.h"
23 #include "keystructs.h"
24 #include "log.h"
25 #include "mem.h"
26 #include "merge.h"
27 #include "onak-conf.h"
28 #include "parsekey.h"
29 #include "photoid.h"
30
31 void find_keys(char *search, uint64_t keyid, bool ishex,
32                 bool fingerprint, bool exact, bool verbose)
33 {
34         struct openpgp_publickey *publickey = NULL;
35         int count = 0;
36
37         if (ishex) {
38                 count = fetch_key(keyid, &publickey, false);
39         } else {
40                 count = fetch_key_text(search, &publickey);
41         }
42         if (publickey != NULL) {
43                 key_index(publickey, verbose, fingerprint, false);
44                 free_publickey(publickey);
45         } else if (count == 0) {
46                 puts("Key not found.");
47         } else {
48                 printf("Found %d keys, but maximum number to return is %d.\n",
49                                 count,
50                                 config.maxkeys);
51                 puts("Try again with a more specific search.");
52         }
53 }
54
55 void usage(void) {
56         puts("onak " VERSION " - an OpenPGP keyserver.\n");
57         puts("Usage:\n");
58         puts("\tonak [options] <command> <parameters>\n");
59         puts("\tCommands:\n");
60         puts("\tadd    - read armored OpenPGP keys from stdin and add to the"
61                 " keyserver");
62         puts("\tdelete - delete a given key from the keyserver");
63         puts("\tdump   - dump all the keys from the keyserver to a file or"
64                 " files\n\t         starting keydump*");
65         puts("\tget    - retrieves the key requested from the keyserver");
66         puts("\tindex  - search for a key and list it");
67         puts("\tvindex - search for a key and list it and its signatures");
68 }
69
70 int main(int argc, char *argv[])
71 {
72         struct openpgp_packet_list      *packets = NULL;
73         struct openpgp_packet_list      *list_end = NULL;
74         struct openpgp_publickey        *keys = NULL;
75         char                            *configfile = NULL;
76         int                              rc = EXIT_SUCCESS;
77         int                              result = 0;
78         char                            *search = NULL;
79         char                            *end = NULL;
80         uint64_t                         keyid = 0;
81         bool                             ishex = false;
82         bool                             verbose = false;
83         bool                             update = false;
84         bool                             binary = false;
85         bool                             fingerprint = false;
86         int                              optchar;
87
88         while ((optchar = getopt(argc, argv, "bc:fuv")) != -1 ) {
89                 switch (optchar) {
90                 case 'b': 
91                         binary = true;
92                         break;
93                 case 'c':
94                         configfile = strdup(optarg);
95                         break;
96                 case 'f': 
97                         fingerprint = true;
98                         break;
99                 case 'u': 
100                         update = true;
101                         break;
102                 case 'v': 
103                         verbose = true;
104                         setlogthreshold(LOGTHING_INFO);
105                         break;
106                 }
107         }
108
109         readconfig(configfile);
110         initlogthing("onak", config.logfile);
111
112         if ((argc - optind) < 1) {
113                 usage();
114         } else if (!strcmp("dump", argv[optind])) {
115                 initdb(true);
116                 dumpdb("keydump");
117                 cleanupdb();
118         } else if (!strcmp("add", argv[optind])) {
119                 if (binary) {
120                         result = read_openpgp_stream(stdin_getchar, NULL,
121                                  &packets, 0);
122                         logthing(LOGTHING_INFO,
123                                         "read_openpgp_stream: %d", result);
124                 } else {
125                         dearmor_openpgp_stream(stdin_getchar, NULL, &packets);
126                 }
127                 if (packets != NULL) {
128                         result = parse_keys(packets, &keys);
129                         free_packet_list(packets);
130                         packets = NULL;
131                         logthing(LOGTHING_INFO, "Finished reading %d keys.",
132                                         result);
133
134                         initdb(false);
135                         logthing(LOGTHING_NOTICE, "Got %d new keys.",
136                                         update_keys(&keys));
137                         if (keys != NULL && update) {
138                                 flatten_publickey(keys,
139                                         &packets,
140                                         &list_end);
141                                 armor_openpgp_stream(stdout_putchar,
142                                         NULL,
143                                         packets);
144                                 free_packet_list(packets);
145                                 packets = NULL;
146                         }
147                         cleanupdb();
148                 } else {
149                         rc = 1;
150                         logthing(LOGTHING_NOTICE, "No keys read.");
151                 }
152
153                 if (keys != NULL) {
154                         free_publickey(keys);
155                         keys = NULL;
156                 } else {
157                         rc = 1;
158                         logthing(LOGTHING_NOTICE, "No changes.");
159                 }
160         } else if ((argc - optind) == 2) {
161                 search = argv[optind+1];
162                 if (search != NULL) {
163                         keyid = strtoul(search, &end, 16);
164                         if (*search != 0 &&
165                                         end != NULL &&
166                                         *end == 0) {
167                                 ishex = true;
168                         }
169                 }
170                 initdb(false);
171                 if (!strcmp("index", argv[optind])) {
172                         find_keys(search, keyid, ishex, fingerprint,
173                                         false, false);
174                 } else if (!strcmp("vindex", argv[optind])) {
175                         find_keys(search, keyid, ishex, fingerprint,
176                                         false, true);
177                 } else if (!strcmp("getphoto", argv[optind])) {
178                         if (!ishex) {
179                                 puts("Can't get a key on uid text."
180                                         " You must supply a keyid.");
181                         } else if (fetch_key(keyid, &keys, false)) {
182                                 struct openpgp_packet *photo = NULL;
183                                 FILE *photof = NULL;
184                                 photo = getphoto(keys, 0);
185                                 if (photo != NULL) {
186                                         photof = fopen("keyphoto.jpg", "w");
187                                         fwrite(photo->data+19,
188                                                         1,
189                                                         (photo->length - 19),
190                                                         photof);
191                                         fclose(photof);
192                                 }
193                                 free_publickey(keys);
194                                 keys = NULL;
195                         } else {
196                                 puts("Key not found");
197                         }
198                 } else if (!strcmp("delete", argv[optind])) {
199                         delete_key(getfullkeyid(keyid), false);
200                 } else if (!strcmp("get", argv[optind])) {
201                         if (!ishex) {
202                                 puts("Can't get a key on uid text."
203                                         " You must supply a keyid.");
204                         } else if (fetch_key(keyid, &keys, false)) {
205                                 logthing(LOGTHING_INFO, "Got key.");
206                                 flatten_publickey(keys,
207                                                 &packets,
208                                                 &list_end);
209                                 free_publickey(keys);
210                                 armor_openpgp_stream(stdout_putchar,
211                                                 NULL,
212                                                 packets);
213                                 free_packet_list(packets);
214                                 packets = NULL;
215                         } else {
216                                 puts("Key not found");
217                         }
218                 }
219                 cleanupdb();
220         } else {
221                 usage();
222         }
223
224         cleanuplogthing();
225         cleanupconfig();
226
227         return rc;
228 }