2 * lookup.c - CGI to lookup keys.
4 * Copyright 2002-2005,2007-2009,2011 Jonathan McDowell <noodles@earth.li>
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.
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
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/>.
26 #include "build-config.h"
29 #include "charfuncs.h"
38 #include "onak-conf.h"
49 void find_keys(struct onak_dbctx *dbctx,
50 char *search, uint64_t keyid,
51 struct openpgp_fingerprint *fingerprint,
52 bool ishex, bool isfp, bool dispfp, bool skshash,
53 bool exact, bool verbose, bool mrhkp)
55 struct openpgp_publickey *publickey = NULL;
59 count = dbctx->fetch_key_id(dbctx, keyid, &publickey,
62 count = dbctx->fetch_key_fp(dbctx, fingerprint, &publickey,
65 count = dbctx->fetch_key_text(dbctx, search, &publickey);
67 if (publickey != NULL) {
69 printf("info:1:%d\n", count);
70 mrkey_index(publickey);
72 key_index(dbctx, publickey, verbose, dispfp,
75 free_publickey(publickey);
76 } else if (count == 0) {
80 puts("Key not found.");
86 printf("Found %d keys, but maximum number to return"
90 puts("Try again with a more specific search.");
95 static uint8_t hex2bin(char c)
97 if (c >= '0' && c <= '9') {
99 } else if (c >= 'a' && c <= 'f') {
100 return (c - 'a' + 10);
101 } else if (c >= 'A' && c <= 'F') {
102 return (c - 'A' + 10);
108 int main(int argc, char *argv[])
110 char **params = NULL;
115 bool skshash = false;
121 struct openpgp_fingerprint fingerprint;
124 struct openpgp_publickey *publickey = NULL;
125 struct openpgp_packet_list *packets = NULL;
126 struct openpgp_packet_list *list_end = NULL;
129 struct onak_dbctx *dbctx;
131 params = getcgivars(argc, argv);
132 for (i = 0; params != NULL && params[i] != NULL; i += 2) {
133 if (!strcmp(params[i], "op")) {
134 if (!strcmp(params[i+1], "get")) {
136 } else if (!strcmp(params[i+1], "hget")) {
138 } else if (!strcmp(params[i+1], "index")) {
140 } else if (!strcmp(params[i+1], "vindex")) {
142 } else if (!strcmp(params[i+1], "photo")) {
145 } else if (!strcmp(params[i], "search")) {
146 search = params[i+1];
148 if (search != NULL && strlen(search) == 42 &&
149 search[0] == '0' && search[1] == 'x') {
151 fingerprint.length = 20;
152 for (j = 0; j < 20; j++) {
153 fingerprint.fp[j] = (hex2bin(
156 hex2bin(search[3 + j * 2]);
159 } else if (search != NULL && strlen(search) == 66 &&
160 search[0] == '0' && search[1] == 'x') {
162 fingerprint.length = 32;
163 for (j = 0; j < 32; j++) {
164 fingerprint.fp[j] = (hex2bin(
167 hex2bin(search[3 + j * 2]);
170 } else if (search != NULL) {
171 keyid = strtoull(search, &end, 16);
178 } else if (!strcmp(params[i], "idx")) {
179 indx = atoi(params[i+1]);
180 } else if (!strcmp(params[i], "fingerprint")) {
181 if (!strcmp(params[i+1], "on")) {
184 } else if (!strcmp(params[i], "hash")) {
185 if (!strcmp(params[i+1], "on")) {
188 } else if (!strcmp(params[i], "exact")) {
189 if (!strcmp(params[i+1], "on")) {
192 } else if (!strcmp(params[i], "options")) {
194 * TODO: We should be smarter about this; options may
195 * have several entries. For now mr is the only valid
198 if (!strcmp(params[i+1], "mr")) {
204 if (params[i+1] != NULL) {
209 if (params != NULL) {
215 puts("Content-Type: text/plain\n");
216 } else if (op == OP_PHOTO) {
217 puts("Content-Type: image/jpeg\n");
219 start_html("Lookup of key");
222 if (op == OP_UNKNOWN) {
223 puts("Error: No operation supplied.");
224 } else if (search == NULL) {
225 puts("Error: No key to search for supplied.");
228 initlogthing("lookup", config.logfile);
230 dbctx = config.dbinit(config.backend, false);
235 parse_skshash(search, &hash);
236 result = dbctx->fetch_key_skshash(dbctx,
239 result = dbctx->fetch_key_id(dbctx, keyid,
242 result = dbctx->fetch_key_fp(dbctx,
243 &fingerprint, &publickey, false);
245 result = dbctx->fetch_key_text(dbctx,
250 logthing(LOGTHING_NOTICE,
251 "Found %d key(s) for search %s",
255 cleankeys(dbctx, &publickey,
256 config.clean_policies);
257 flatten_publickey(publickey,
260 armor_openpgp_stream(stdout_putchar,
265 logthing(LOGTHING_NOTICE,
266 "Failed to find key for search %s",
268 puts("Key not found");
272 find_keys(dbctx, search, keyid, &fingerprint,
273 ishex, isfp, dispfp, skshash,
274 exact, false, mrhkp);
277 find_keys(dbctx, search, keyid, &fingerprint,
278 ishex, isfp, dispfp, skshash,
283 dbctx->fetch_key_fp(dbctx, &fingerprint,
286 dbctx->fetch_key_id(dbctx, keyid,
289 if (publickey != NULL) {
290 unsigned char *photo = NULL;
293 if (getphoto(publickey, indx, &photo,
294 &length) == ONAK_E_OK) {
300 free_publickey(publickey);
305 puts("Unknown operation!");
307 dbctx->cleanupdb(dbctx);
313 puts("Produced by onak " ONAK_VERSION );
317 if (search != NULL) {
322 return (EXIT_SUCCESS);