]> the.earth.li Git - onak.git/blob - gpgwww.c
Move to CMake over autoconf
[onak.git] / gpgwww.c
1 /*
2  * gpgwww.c - www interface to path finder.
3  *
4  * Copyright 2001-2004 Jonathan McDowell <noodles@earth.li>
5  *
6  * This program is free software: you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the Free
8  * Software Foundation; version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * this program.  If not, see <https://www.gnu.org/licenses/>.
17  */
18
19 #include <inttypes.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23
24 #include "build-config.h"
25
26 #include "armor.h"
27 #include "charfuncs.h"
28 #include "cleanup.h"
29 #include "getcgi.h"
30 #include "hash.h"
31 #include "keydb.h"
32 #include "log.h"
33 #include "mem.h"
34 #include "onak-conf.h"
35 #include "parsekey.h"
36 #include "stats.h"
37
38 #define OP_UNKNOWN 0
39 #define OP_GET     1
40
41 int parsecgistuff(char **cgiparams, uint64_t *from, uint64_t *to)
42 {
43         int i = 0;
44         int op = OP_UNKNOWN;
45
46         if (cgiparams != NULL) {
47                 i = 0;
48                 while (cgiparams[i] != NULL) {
49                         if (!strcmp(cgiparams[i], "to")) {
50                                 *to = strtoul(cgiparams[i+1], NULL, 16);
51                         } else if (!strcmp(cgiparams[i], "from")) {
52                                 *from = strtoul(cgiparams[i+1], NULL, 16);
53                         } else if (!strcmp(cgiparams[i], "op")) {
54                                 if (!strcmp(cgiparams[i+1], "get")) {
55                                         op = OP_GET;
56                                 }
57                         }
58                         i += 2;
59                 }
60         }
61
62         return op;
63 }
64
65 int getkeyspath(struct onak_dbctx *dbctx,
66                 uint64_t have, uint64_t want, int count)
67 {
68         struct openpgp_publickey *publickey = NULL;
69         struct openpgp_packet_list *packets = NULL;
70         struct openpgp_packet_list *list_end = NULL;
71         struct stats_key *keyinfoa, *keyinfob, *curkey;
72         uint64_t fullhave, fullwant;
73         int pathlen = 0;
74
75         fullhave = dbctx->getfullkeyid(dbctx, have);
76         fullwant = dbctx->getfullkeyid(dbctx, want);
77
78         /*
79          * Make sure the keys we have and want are in the cache.
80          */
81         dbctx->cached_getkeysigs(dbctx, fullhave);
82         dbctx->cached_getkeysigs(dbctx, fullwant);
83
84         if ((keyinfoa = findinhash(fullhave)) == NULL) {
85                 return 1;
86         }
87         if ((keyinfob = findinhash(fullwant)) == NULL) {
88                 return 1;
89         }
90         
91         while ((!cleanup()) && (pathlen < count)) {
92                 /*
93                  * Fill the tree info up.
94                  */
95                 initcolour(true);
96                 findpath(dbctx, keyinfoa, keyinfob);
97                 keyinfob->parent = 0;
98                 if (keyinfoa->colour == 0) {
99                         pathlen = count;
100                 } else {
101                         /*
102                          * Skip the first key, as the remote user will already
103                          * have it
104                          */
105                         curkey = findinhash(keyinfoa->parent);
106                         while (curkey != NULL && curkey->keyid != 0) {
107                                 if (curkey->keyid != fullwant &&
108                                                 dbctx->fetch_key_id(dbctx,
109                                                 curkey->keyid,
110                                                 &publickey, false)) {
111                                         flatten_publickey(publickey,
112                                                         &packets,
113                                                         &list_end);
114                                         free_publickey(publickey);
115                                         publickey = NULL;
116                                 }
117                                 if (curkey != keyinfoa && curkey != keyinfob) {
118                                         curkey->disabled = true;
119                                 }
120                                 curkey = findinhash(curkey->parent);
121                         }
122                 }
123                 pathlen++;
124         }
125
126         /*
127          * Add the destination key to the list of returned keys.
128          */
129         if (dbctx->fetch_key_id(dbctx, fullwant, &publickey, false)) {
130                 flatten_publickey(publickey,
131                                 &packets,
132                                 &list_end);
133                 free_publickey(publickey);
134                 publickey = NULL;
135         }
136
137         armor_openpgp_stream(stdout_putchar, NULL, packets);
138         free_packet_list(packets);
139         packets = list_end = NULL;
140
141         return 0;
142 }
143
144 int main(int argc, char *argv[])
145 {
146         char     **cgiparams = NULL;    /* Our CGI parameter block */
147         uint64_t   from = 0, to = 0;
148         int        op = OP_UNKNOWN;
149         struct onak_dbctx *dbctx;
150
151         cgiparams = getcgivars(argc, argv);
152
153
154         op = parsecgistuff(cgiparams, &from, &to);
155         
156         if (op != OP_GET) {
157                 start_html("Experimental PGP key path finder results");
158         } else {
159                 puts("Content-Type: text/plain\n");
160         }
161
162         if (from == 0 || to == 0) {
163                 printf("Must pass from & to\n");
164                 puts("</HTML>");
165                 exit(1);
166         }
167
168         if (op != OP_GET) {
169                 printf("<P>Looking for path from 0x%016" PRIX64" to 0x%016"
170                                 PRIX64 ".\n",
171                                 from, to);
172                 printf("<A HREF=\"gpgwww?from=0x%016" PRIX64 "&to=0x%016" PRIX64
173                                 "\">Find reverse path</A>\n",
174                                 to,
175                                 from);
176                 printf("<A HREF=\"gpgwww?from=0x%08" PRIX64 "&to=0x%08" PRIX64
177                                 "&op=get\">"
178                                 "Get all keys listed</A></P>\n",
179                                 from,
180                                 to);
181         }
182
183         readconfig(NULL);
184         initlogthing("gpgwww", config.logfile);
185         catchsignals();
186         dbctx = config.dbinit(config.backend, true);
187         inithash();
188         logthing(LOGTHING_NOTICE, "Looking for path from 0x%016" PRIX64
189                         " to 0x%016"
190                         PRIX64,
191                         from,
192                         to);
193         if (op == OP_GET) {
194                 getkeyspath(dbctx, from, to, 3);
195         } else {
196                 dofindpath(dbctx, from, to, true, 3);
197         }
198         destroyhash();
199         dbctx->cleanupdb(dbctx);
200         cleanuplogthing();
201         cleanupconfig();
202
203         if (op != OP_GET) {
204                 puts("<HR>");
205                 puts("Produced by gpgwww " ONAK_VERSION ", part of onak. ");
206                 end_html();
207         }
208
209         cleanupcgi(cgiparams);
210         cgiparams = NULL;
211
212         return EXIT_SUCCESS;
213 }