]> the.earth.li Git - onak.git/blob - gpgwww.c
Add subkey support to keydb_fs backend.
[onak.git] / gpgwww.c
1 /*
2  * gpgwww.c - www interface to path finder.
3  * 
4  * Jonathan McDowell <noodles@earth.li>
5  *
6  * Copyright 2001-2002 Project Purple.
7  */
8
9 #include <inttypes.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13
14 #include "armor.h"
15 #include "charfuncs.h"
16 #include "getcgi.h"
17 #include "hash.h"
18 #include "keydb.h"
19 #include "log.h"
20 #include "mem.h"
21 #include "onak-conf.h"
22 #include "parsekey.h"
23 #include "stats.h"
24
25 #define OP_UNKNOWN 0
26 #define OP_GET     1
27
28 int parsecgistuff(char **cgiparams, uint64_t *from, uint64_t *to)
29 {
30         int i = 0;
31         int op = OP_UNKNOWN;
32
33         if (cgiparams != NULL) {
34                 i = 0;
35                 while (cgiparams[i] != NULL) {
36                         if (!strcmp(cgiparams[i], "to")) {
37                                 *to = strtoul(cgiparams[i+1], NULL, 16);
38                         } else if (!strcmp(cgiparams[i], "from")) {
39                                 *from = strtoul(cgiparams[i+1], NULL, 16);
40                         } else if (!strcmp(cgiparams[i], "op")) {
41                                 if (!strcmp(cgiparams[i+1], "get")) {
42                                         op = OP_GET;
43                                 }
44                         }
45                         i += 2;
46                 }
47         }
48
49         return op;
50 }
51
52 int getkeyspath(uint64_t have, uint64_t want, int count)
53 {
54         struct openpgp_publickey *publickey = NULL;
55         struct openpgp_packet_list *packets = NULL;
56         struct openpgp_packet_list *list_end = NULL;
57         struct stats_key *keyinfoa, *keyinfob, *curkey;
58         uint64_t fullhave, fullwant;
59         int rec;
60         int pathlen = 0;
61
62         fullhave = getfullkeyid(have);
63         fullwant = getfullkeyid(want);
64
65         /*
66          * Make sure the keys we have and want are in the cache.
67          */
68         cached_getkeysigs(fullhave);
69         cached_getkeysigs(fullwant);
70
71         if ((keyinfoa = findinhash(fullhave)) == NULL) {
72                 return 1;
73         }
74         if ((keyinfob = findinhash(fullwant)) == NULL) {
75                 return 1;
76         }
77         
78         while (pathlen < count) {
79                 /*
80                  * Fill the tree info up.
81                  */
82                 initcolour(true);
83                 rec = findpath(keyinfoa, keyinfob);
84                 keyinfob->parent = 0;
85                 if (keyinfoa->colour == 0) {
86                         pathlen = count;
87                 } else {
88                         /*
89                          * Skip the first key, as the remote user will already
90                          * have it
91                          */
92                         curkey = findinhash(keyinfoa->parent);
93                         while (curkey != NULL && curkey->keyid != 0) {
94                                 if (curkey->keyid != fullwant && fetch_key(
95                                                 curkey->keyid,
96                                                         &publickey, false)) {
97                                         flatten_publickey(publickey,
98                                                         &packets,
99                                                         &list_end);
100                                         free_publickey(publickey);
101                                         publickey = NULL;
102                                 }
103                                 if (curkey != keyinfoa && curkey != keyinfob) {
104                                         curkey->disabled = true;
105                                 }
106                                 curkey = findinhash(curkey->parent);
107                         }
108                 }
109                 pathlen++;
110         }
111
112         /*
113          * Add the destination key to the list of returned keys.
114          */
115         if (fetch_key(fullwant, &publickey, false)) {
116                 flatten_publickey(publickey,
117                                 &packets,
118                                 &list_end);
119                 free_publickey(publickey);
120                 publickey = NULL;
121         }
122
123         armor_openpgp_stream(stdout_putchar, NULL, packets);
124         free_packet_list(packets);
125         packets = list_end = NULL;
126
127         return 0;
128 }
129
130 int main(int argc, char *argv[])
131 {
132         char     **cgiparams = NULL;    /* Our CGI parameter block */
133         uint64_t   from = 0, to = 0;
134         int        op = OP_UNKNOWN;
135
136         cgiparams = getcgivars(argc, argv);
137
138
139         op = parsecgistuff(cgiparams, &from, &to);
140         
141         if (op != OP_GET) {
142                 start_html("Experimental PGP key path finder results");
143         } else {
144                 puts("Content-Type: text/plain\n");
145         }
146
147         if (from == 0 || to == 0) {
148                 printf("Must pass from & to\n");
149                 puts("</HTML>");
150                 exit(1);
151         }
152
153         if (op != OP_GET) {
154                 printf("<P>Looking for path from 0x%llX to 0x%llX.\n",
155                                 from, to);
156                 printf("<A HREF=\"gpgwww?from=0x%08llX&to=0x%08llX\">"
157                                 "Find reverse path</A>\n",
158                                 to,
159                                 from);
160                 printf("<A HREF=\"gpgwww?from=0x%08llX&to=0x%08llX&op=get\">"
161                                 "Get all keys listed</A></P>\n",
162                                 from,
163                                 to);
164         }
165
166         readconfig(NULL);
167         initlogthing("gpgwww", config.logfile);
168         initdb(true);
169         inithash();
170         logthing(LOGTHING_NOTICE, "Looking for path from 0x%llX to 0x%llX.",
171                         from,
172                         to);
173         if (op == OP_GET) {
174                 getkeyspath(from, to, 3);
175         } else {
176                 dofindpath(from, to, true, 3);
177         }
178         destroyhash();
179         cleanupdb();
180         cleanuplogthing();
181         cleanupconfig();
182
183         if (op != OP_GET) {
184                 puts("<HR>");
185                 puts("Produced by gpgwww " VERSION ", part of onak. "
186                         "<A HREF=\"mailto:noodles-onak@earth.li\">"
187                         "Jonathan McDowell</A>");
188                 end_html();
189         }
190
191         cleanupcgi(cgiparams);
192         cgiparams = NULL;
193
194         return EXIT_SUCCESS;
195 }