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