]> git.sommitrealweird.co.uk Git - onak.git/blob - onak.c
Relax asserts when cleaning up.
[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
11 #include <getopt.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <unistd.h>
16
17 #include "armor.h"
18 #include "charfuncs.h"
19 #include "cleankey.h"
20 #include "cleanup.h"
21 #include "keydb.h"
22 #include "keyid.h"
23 #include "keyindex.h"
24 #include "keystructs.h"
25 #include "log.h"
26 #include "mem.h"
27 #include "merge.h"
28 #include "onak-conf.h"
29 #include "parsekey.h"
30 #include "photoid.h"
31
32 void find_keys(char *search, uint64_t keyid, bool ishex,
33                 bool fingerprint, bool exact, bool verbose)
34 {
35         struct openpgp_publickey *publickey = NULL;
36         int count = 0;
37
38         if (ishex) {
39                 count = fetch_key(keyid, &publickey, false);
40         } else {
41                 count = fetch_key_text(search, &publickey);
42         }
43         if (publickey != NULL) {
44                 key_index(publickey, verbose, fingerprint, false);
45                 free_publickey(publickey);
46         } else if (count == 0) {
47                 puts("Key not found.");
48         } else {
49                 printf("Found %d keys, but maximum number to return is %d.\n",
50                                 count,
51                                 config.maxkeys);
52                 puts("Try again with a more specific search.");
53         }
54 }
55
56 void usage(void) {
57         puts("onak " VERSION " - an OpenPGP keyserver.\n");
58         puts("Usage:\n");
59         puts("\tonak [options] <command> <parameters>\n");
60         puts("\tCommands:\n");
61         puts("\tadd      - read armored OpenPGP keys from stdin and add to the"
62                 " keyserver");
63         puts("\tclean    - read armored OpenPGP keys from stdin, run the "
64                 " cleaning\n\t             routines against them and dump to"
65                 " stdout");
66         puts("\tdelete   - delete a given key from the keyserver");
67         puts("\tdump     - dump all the keys from the keyserver to a file or"
68                 " files\n\t           starting keydump*");
69         puts("\tget      - retrieves the key requested from the keyserver");
70         puts("\tgetphoto - retrieves the first photoid on the given key and"
71                 " dumps to\n\t           stdout");
72         puts("\tindex    - search for a key and list it");
73         puts("\tvindex   - search for a key and list it and its signatures");
74 }
75
76 int main(int argc, char *argv[])
77 {
78         struct openpgp_packet_list      *packets = NULL;
79         struct openpgp_packet_list      *list_end = NULL;
80         struct openpgp_publickey        *keys = NULL;
81         char                            *configfile = NULL;
82         int                              rc = EXIT_SUCCESS;
83         int                              result = 0;
84         char                            *search = NULL;
85         char                            *end = NULL;
86         uint64_t                         keyid = 0;
87         bool                             ishex = false;
88         bool                             verbose = false;
89         bool                             update = false;
90         bool                             binary = false;
91         bool                             fingerprint = false;
92         int                              optchar;
93
94         while ((optchar = getopt(argc, argv, "bc:fuv")) != -1 ) {
95                 switch (optchar) {
96                 case 'b': 
97                         binary = true;
98                         break;
99                 case 'c':
100                         configfile = strdup(optarg);
101                         break;
102                 case 'f': 
103                         fingerprint = true;
104                         break;
105                 case 'u': 
106                         update = true;
107                         break;
108                 case 'v': 
109                         verbose = true;
110                         setlogthreshold(LOGTHING_INFO);
111                         break;
112                 }
113         }
114
115         readconfig(configfile);
116         initlogthing("onak", config.logfile);
117         catchsignals();
118
119         if ((argc - optind) < 1) {
120                 usage();
121         } else if (!strcmp("dump", argv[optind])) {
122                 initdb(true);
123                 dumpdb("keydump");
124                 cleanupdb();
125         } else if (!strcmp("add", argv[optind])) {
126                 if (binary) {
127                         result = read_openpgp_stream(stdin_getchar, NULL,
128                                  &packets, 0);
129                         logthing(LOGTHING_INFO,
130                                         "read_openpgp_stream: %d", result);
131                 } else {
132                         dearmor_openpgp_stream(stdin_getchar, NULL, &packets);
133                 }
134                 if (packets != NULL) {
135                         result = parse_keys(packets, &keys);
136                         free_packet_list(packets);
137                         packets = NULL;
138                         logthing(LOGTHING_INFO, "Finished reading %d keys.",
139                                         result);
140
141                         result = cleankeys(keys);
142                         logthing(LOGTHING_INFO, "%d keys cleaned.",
143                                         result);
144
145                         initdb(false);
146                         logthing(LOGTHING_NOTICE, "Got %d new keys.",
147                                         update_keys(&keys));
148                         if (keys != NULL && update) {
149                                 flatten_publickey(keys,
150                                         &packets,
151                                         &list_end);
152                                 if (binary) {
153                                         write_openpgp_stream(stdout_putchar,
154                                                         NULL,
155                                                         packets);
156                                 } else {
157                                         armor_openpgp_stream(stdout_putchar,
158                                                 NULL,
159                                                 packets);
160                                 }
161                                 free_packet_list(packets);
162                                 packets = NULL;
163                         }
164                         cleanupdb();
165                 } else {
166                         rc = 1;
167                         logthing(LOGTHING_NOTICE, "No keys read.");
168                 }
169
170                 if (keys != NULL) {
171                         free_publickey(keys);
172                         keys = NULL;
173                 } else {
174                         rc = 1;
175                         logthing(LOGTHING_NOTICE, "No changes.");
176                 }
177         } else if (!strcmp("clean", argv[optind])) {
178                 if (binary) {
179                         result = read_openpgp_stream(stdin_getchar, NULL,
180                                  &packets, 0);
181                         logthing(LOGTHING_INFO,
182                                         "read_openpgp_stream: %d", result);
183                 } else {
184                         dearmor_openpgp_stream(stdin_getchar, NULL, &packets);
185                 }
186
187                 if (packets != NULL) {
188                         result = parse_keys(packets, &keys);
189                         free_packet_list(packets);
190                         packets = NULL;
191                         logthing(LOGTHING_INFO, "Finished reading %d keys.",
192                                         result);
193
194                         if (keys != NULL) {
195                                 result = cleankeys(keys);
196                                 logthing(LOGTHING_INFO, "%d keys cleaned.",
197                                                 result);
198
199                                 flatten_publickey(keys,
200                                         &packets,
201                                         &list_end);
202
203                                 if (binary) {
204                                         write_openpgp_stream(stdout_putchar,
205                                                         NULL,
206                                                         packets);
207                                 } else {
208                                         armor_openpgp_stream(stdout_putchar,
209                                                 NULL,
210                                                 packets);
211                                 }
212                                 free_packet_list(packets);
213                                 packets = NULL;
214                         }
215                 } else {
216                         rc = 1;
217                         logthing(LOGTHING_NOTICE, "No keys read.");
218                 }
219                 
220                 if (keys != NULL) {
221                         free_publickey(keys);
222                         keys = NULL;
223                 }
224         } else if ((argc - optind) == 2) {
225                 search = argv[optind+1];
226                 if (search != NULL) {
227                         keyid = strtoul(search, &end, 16);
228                         if (*search != 0 &&
229                                         end != NULL &&
230                                         *end == 0) {
231                                 ishex = true;
232                         }
233                 }
234                 initdb(false);
235                 if (!strcmp("index", argv[optind])) {
236                         find_keys(search, keyid, ishex, fingerprint,
237                                         false, false);
238                 } else if (!strcmp("vindex", argv[optind])) {
239                         find_keys(search, keyid, ishex, fingerprint,
240                                         false, true);
241                 } else if (!strcmp("getphoto", argv[optind])) {
242                         if (!ishex) {
243                                 puts("Can't get a key on uid text."
244                                         " You must supply a keyid.");
245                         } else if (fetch_key(keyid, &keys, false)) {
246                                 unsigned char *photo = NULL;
247                                 size_t         length = 0;
248
249                                 if (getphoto(keys, 0, &photo, &length)) {
250                                         fwrite(photo,
251                                                 1,
252                                                 length,
253                                                 stdout);
254                                 }
255                                 free_publickey(keys);
256                                 keys = NULL;
257                         } else {
258                                 puts("Key not found");
259                         }
260                 } else if (!strcmp("delete", argv[optind])) {
261                         delete_key(getfullkeyid(keyid), false);
262                 } else if (!strcmp("get", argv[optind])) {
263                         if (!ishex) {
264                                 puts("Can't get a key on uid text."
265                                         " You must supply a keyid.");
266                         } else if (fetch_key(keyid, &keys, false)) {
267                                 logthing(LOGTHING_INFO, "Got key.");
268                                 flatten_publickey(keys,
269                                                 &packets,
270                                                 &list_end);
271                                 free_publickey(keys);
272                                 armor_openpgp_stream(stdout_putchar,
273                                                 NULL,
274                                                 packets);
275                                 free_packet_list(packets);
276                                 packets = NULL;
277                         } else {
278                                 puts("Key not found");
279                         }
280                 }
281                 cleanupdb();
282         } else {
283                 usage();
284         }
285
286         cleanuplogthing();
287         cleanupconfig();
288
289         return rc;
290 }