]> the.earth.li Git - onak.git/blob - onak.c
Add subkey support to keydb_fs backend.
[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 "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("\tclean    - read armored OpenPGP keys from stdin, run the "
63                 " cleaning\n\t             routines against them and dump to"
64                 " stdout");
65         puts("\tdelete   - delete a given key from the keyserver");
66         puts("\tdump     - dump all the keys from the keyserver to a file or"
67                 " files\n\t           starting keydump*");
68         puts("\tget      - retrieves the key requested from the keyserver");
69         puts("\tgetphoto - retrieves the first photoid on the given key and"
70                 " dumps to\n\t           stdout");
71         puts("\tindex    - search for a key and list it");
72         puts("\tvindex   - search for a key and list it and its signatures");
73 }
74
75 int main(int argc, char *argv[])
76 {
77         struct openpgp_packet_list      *packets = NULL;
78         struct openpgp_packet_list      *list_end = NULL;
79         struct openpgp_publickey        *keys = NULL;
80         char                            *configfile = NULL;
81         int                              rc = EXIT_SUCCESS;
82         int                              result = 0;
83         char                            *search = NULL;
84         char                            *end = NULL;
85         uint64_t                         keyid = 0;
86         bool                             ishex = false;
87         bool                             verbose = false;
88         bool                             update = false;
89         bool                             binary = false;
90         bool                             fingerprint = false;
91         int                              optchar;
92
93         while ((optchar = getopt(argc, argv, "bc:fuv")) != -1 ) {
94                 switch (optchar) {
95                 case 'b': 
96                         binary = true;
97                         break;
98                 case 'c':
99                         configfile = strdup(optarg);
100                         break;
101                 case 'f': 
102                         fingerprint = true;
103                         break;
104                 case 'u': 
105                         update = true;
106                         break;
107                 case 'v': 
108                         verbose = true;
109                         setlogthreshold(LOGTHING_INFO);
110                         break;
111                 }
112         }
113
114         readconfig(configfile);
115         initlogthing("onak", config.logfile);
116
117         if ((argc - optind) < 1) {
118                 usage();
119         } else if (!strcmp("dump", argv[optind])) {
120                 initdb(true);
121                 dumpdb("keydump");
122                 cleanupdb();
123         } else if (!strcmp("add", argv[optind])) {
124                 if (binary) {
125                         result = read_openpgp_stream(stdin_getchar, NULL,
126                                  &packets, 0);
127                         logthing(LOGTHING_INFO,
128                                         "read_openpgp_stream: %d", result);
129                 } else {
130                         dearmor_openpgp_stream(stdin_getchar, NULL, &packets);
131                 }
132                 if (packets != NULL) {
133                         result = parse_keys(packets, &keys);
134                         free_packet_list(packets);
135                         packets = NULL;
136                         logthing(LOGTHING_INFO, "Finished reading %d keys.",
137                                         result);
138
139                         result = cleankeys(keys);
140                         logthing(LOGTHING_INFO, "%d keys cleaned.",
141                                         result);
142
143                         initdb(false);
144                         logthing(LOGTHING_NOTICE, "Got %d new keys.",
145                                         update_keys(&keys));
146                         if (keys != NULL && update) {
147                                 flatten_publickey(keys,
148                                         &packets,
149                                         &list_end);
150                                 if (binary) {
151                                         write_openpgp_stream(stdout_putchar,
152                                                         NULL,
153                                                         packets);
154                                 } else {
155                                         armor_openpgp_stream(stdout_putchar,
156                                                 NULL,
157                                                 packets);
158                                 }
159                                 free_packet_list(packets);
160                                 packets = NULL;
161                         }
162                         cleanupdb();
163                 } else {
164                         rc = 1;
165                         logthing(LOGTHING_NOTICE, "No keys read.");
166                 }
167
168                 if (keys != NULL) {
169                         free_publickey(keys);
170                         keys = NULL;
171                 } else {
172                         rc = 1;
173                         logthing(LOGTHING_NOTICE, "No changes.");
174                 }
175         } else if (!strcmp("clean", argv[optind])) {
176                 if (binary) {
177                         result = read_openpgp_stream(stdin_getchar, NULL,
178                                  &packets, 0);
179                         logthing(LOGTHING_INFO,
180                                         "read_openpgp_stream: %d", result);
181                 } else {
182                         dearmor_openpgp_stream(stdin_getchar, NULL, &packets);
183                 }
184
185                 if (packets != NULL) {
186                         result = parse_keys(packets, &keys);
187                         free_packet_list(packets);
188                         packets = NULL;
189                         logthing(LOGTHING_INFO, "Finished reading %d keys.",
190                                         result);
191
192                         if (keys != NULL) {
193                                 result = cleankeys(keys);
194                                 logthing(LOGTHING_INFO, "%d keys cleaned.",
195                                                 result);
196
197                                 flatten_publickey(keys,
198                                         &packets,
199                                         &list_end);
200
201                                 if (binary) {
202                                         write_openpgp_stream(stdout_putchar,
203                                                         NULL,
204                                                         packets);
205                                 } else {
206                                         armor_openpgp_stream(stdout_putchar,
207                                                 NULL,
208                                                 packets);
209                                 }
210                                 free_packet_list(packets);
211                                 packets = NULL;
212                         }
213                 } else {
214                         rc = 1;
215                         logthing(LOGTHING_NOTICE, "No keys read.");
216                 }
217                 
218                 if (keys != NULL) {
219                         free_publickey(keys);
220                         keys = NULL;
221                 }
222         } else if ((argc - optind) == 2) {
223                 search = argv[optind+1];
224                 if (search != NULL) {
225                         keyid = strtoul(search, &end, 16);
226                         if (*search != 0 &&
227                                         end != NULL &&
228                                         *end == 0) {
229                                 ishex = true;
230                         }
231                 }
232                 initdb(false);
233                 if (!strcmp("index", argv[optind])) {
234                         find_keys(search, keyid, ishex, fingerprint,
235                                         false, false);
236                 } else if (!strcmp("vindex", argv[optind])) {
237                         find_keys(search, keyid, ishex, fingerprint,
238                                         false, true);
239                 } else if (!strcmp("getphoto", argv[optind])) {
240                         if (!ishex) {
241                                 puts("Can't get a key on uid text."
242                                         " You must supply a keyid.");
243                         } else if (fetch_key(keyid, &keys, false)) {
244                                 unsigned char *photo = NULL;
245                                 size_t         length = 0;
246
247                                 if (getphoto(keys, 0, &photo, &length)) {
248                                         fwrite(photo,
249                                                 1,
250                                                 length,
251                                                 stdout);
252                                 }
253                                 free_publickey(keys);
254                                 keys = NULL;
255                         } else {
256                                 puts("Key not found");
257                         }
258                 } else if (!strcmp("delete", argv[optind])) {
259                         delete_key(getfullkeyid(keyid), false);
260                 } else if (!strcmp("get", argv[optind])) {
261                         if (!ishex) {
262                                 puts("Can't get a key on uid text."
263                                         " You must supply a keyid.");
264                         } else if (fetch_key(keyid, &keys, false)) {
265                                 logthing(LOGTHING_INFO, "Got key.");
266                                 flatten_publickey(keys,
267                                                 &packets,
268                                                 &list_end);
269                                 free_publickey(keys);
270                                 armor_openpgp_stream(stdout_putchar,
271                                                 NULL,
272                                                 packets);
273                                 free_packet_list(packets);
274                                 packets = NULL;
275                         } else {
276                                 puts("Key not found");
277                         }
278                 }
279                 cleanupdb();
280         } else {
281                 usage();
282         }
283
284         cleanuplogthing();
285         cleanupconfig();
286
287         return rc;
288 }