From: Jonathan McDowell Date: Sat, 3 Aug 2019 08:35:23 +0000 (+0100) Subject: Move CGI sources to their own subdirectory X-Git-Tag: onak-0.6.0~41 X-Git-Url: https://the.earth.li/gitweb/?p=onak.git;a=commitdiff_plain;h=3877403043acfbfa57497d3ba51a5ec2db1c77dc Move CGI sources to their own subdirectory Cleanup the code structure a bit by pulling those files only used for the HKP interface into their own directory. --- diff --git a/CGI b/CGI deleted file mode 100644 index 7e1980c..0000000 --- a/CGI +++ /dev/null @@ -1,12 +0,0 @@ - -/pks/lookup: - -op index | vindex | get required -search required -fingerprint boolean (true == on) -exact boolean - - -/pks/add: - -keytext for ADD. required diff --git a/CMakeLists.txt b/CMakeLists.txt index 6594a8b..4b28688 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -130,22 +130,31 @@ target_compile_definitions(libonak PRIVATE target_sources(libonak PRIVATE keydb_${DBTYPE}.c) target_link_libraries(libonak ${LIBONAK_LIBRARIES}) +# Build files that have substitutions in them +include_directories(${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}) +configure_file("${CMAKE_SOURCE_DIR}/build-config.h.in" + "${CMAKE_BINARY_DIR}/build-config.h" @ONLY) + +configure_file("${CMAKE_SOURCE_DIR}/onak.ini.in" + "${CMAKE_BINARY_DIR}/onak.ini" @ONLY) +install(FILES ${CMAKE_BINARY_DIR}/onak.ini + DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}) + +configure_file("${CMAKE_SOURCE_DIR}/onak-mail.pl.in" + "${CMAKE_BINARY_DIR}/onak-mail.pl" @ONLY) +install(PROGRAMS ${CMAKE_BINARY_DIR}/onak-mail.pl + DESTINATION ${CMAKE_INSTALL_LIBDIR}/onak/) +install(FILES onak-mail.pl.8 DESTINATION ${CMAKE_INSTALL_MANDIR}/man8/) + +# CGI directory +add_subdirectory(cgi) + # Executables start here # Swiss Army tool add_executable(onak onak.c) target_link_libraries(onak libonak) -# CGI -add_executable(add add.c) -target_link_libraries(add libonak) -add_executable(gpgwww gpgwww.c stats.c) -target_link_libraries(gpgwww libonak) -add_executable(hashquery hashquery.c) -target_link_libraries(hashquery libonak) -add_executable(lookup lookup.c) -target_link_libraries(lookup libonak) - # Tools that operate on the key DB add_executable(maxpath maxpath.c stats.c) target_link_libraries(maxpath libonak) @@ -163,22 +172,6 @@ target_link_libraries(stripkey libonak) install(TARGETS onak splitkeys RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) install(FILES onak.1 splitkeys.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1/) -# Build files that have substitutions in them -include_directories(${CMAKE_BINARY_DIR}) -configure_file("${CMAKE_SOURCE_DIR}/build-config.h.in" - "${CMAKE_BINARY_DIR}/build-config.h" @ONLY) - -configure_file("${CMAKE_SOURCE_DIR}/onak.ini.in" - "${CMAKE_BINARY_DIR}/onak.ini" @ONLY) -install(FILES ${CMAKE_BINARY_DIR}/onak.ini - DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}) - -configure_file("${CMAKE_SOURCE_DIR}/onak-mail.pl.in" - "${CMAKE_BINARY_DIR}/onak-mail.pl" @ONLY) -install(PROGRAMS ${CMAKE_BINARY_DIR}/onak-mail.pl - DESTINATION ${CMAKE_INSTALL_LIBDIR}/onak/) -install(FILES onak-mail.pl.8 DESTINATION ${CMAKE_INSTALL_MANDIR}/man8/) - # Basic unit tests enable_testing() add_test(NAME syntaxtest COMMAND perl -cw ${CMAKE_BINARY_DIR}/onak-mail.pl) diff --git a/add.c b/add.c deleted file mode 100644 index c3a54a7..0000000 --- a/add.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * add.c - CGI to add keys. - * - * Copyright 2002-2004,2007-2008 Jonathan McDowell - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ - -#include -#include -#include -#include - -#include "armor.h" -#include "cleankey.h" -#include "cleanup.h" -#include "charfuncs.h" -#include "getcgi.h" -#include "keydb.h" -#include "log.h" -#include "mem.h" -#include "onak-conf.h" -#include "parsekey.h" - -int main(int argc, char *argv[]) -{ - struct openpgp_packet_list *packets = NULL; - struct openpgp_publickey *keys = NULL; - char **params = NULL; - struct buffer_ctx ctx; - int count = 0; - int i; - struct onak_dbctx *dbctx; - - memset(&ctx, 0, sizeof(ctx)); - - params = getcgivars(argc, argv); - for (i = 0; params != NULL && params[i] != NULL; i += 2) { - if (!strcmp(params[i], "keytext")) { - ctx.buffer = params[i+1]; - ctx.size = strlen(ctx.buffer); - } else { - free(params[i+1]); - } - params[i+1] = NULL; - free(params[i]); - params[i] = NULL; - } - if (params != NULL) { - free(params); - params = NULL; - } - - start_html("onak : Add"); - if (ctx.buffer == NULL) { - puts("Error: No keytext to add supplied."); - end_html(); - } else { - readconfig(NULL); - initlogthing("add", config.logfile); - dearmor_openpgp_stream(buffer_fetchchar, - &ctx, - &packets); - if (packets != NULL) { - count = parse_keys(packets, &keys); - logthing(LOGTHING_NOTICE, "Received %d keys.", - count); - printf("Key block added to key server database.\n"); - printf(" New public keys added: %d\n", count); - end_html(); - if (stdout != NULL && fileno(stdout) != -1) { - fclose(stdout); - } - if (stderr != NULL && stderr != stdout && - fileno(stderr) != -1) { - fclose(stderr); - } - catchsignals(); - dbctx = config.dbinit(config.backend, false); - - count = cleankeys(&keys, config.clean_policies); - logthing(LOGTHING_INFO, "%d keys cleaned.", - count); - - count = dbctx->update_keys(dbctx, &keys, true); - logthing(LOGTHING_NOTICE, "Got %d new keys.", - count); - - if (keys != NULL) { - free_publickey(keys); - keys = NULL; - } - - dbctx->cleanupdb(dbctx); - } else { - puts("No OpenPGP packets found in input."); - end_html(); - } - cleanuplogthing(); - cleanupconfig(); - } - return (EXIT_SUCCESS); -} diff --git a/cgi/CGI b/cgi/CGI new file mode 100644 index 0000000..7e1980c --- /dev/null +++ b/cgi/CGI @@ -0,0 +1,12 @@ + +/pks/lookup: + +op index | vindex | get required +search required +fingerprint boolean (true == on) +exact boolean + + +/pks/add: + +keytext for ADD. required diff --git a/cgi/CMakeLists.txt b/cgi/CMakeLists.txt new file mode 100644 index 0000000..977f2a2 --- /dev/null +++ b/cgi/CMakeLists.txt @@ -0,0 +1,9 @@ +# CGI +add_executable(add add.c) +target_link_libraries(add libonak) +add_executable(gpgwww gpgwww.c ../stats.c) +target_link_libraries(gpgwww libonak) +add_executable(hashquery hashquery.c) +target_link_libraries(hashquery libonak) +add_executable(lookup lookup.c) +target_link_libraries(lookup libonak) diff --git a/cgi/add.c b/cgi/add.c new file mode 100644 index 0000000..c3a54a7 --- /dev/null +++ b/cgi/add.c @@ -0,0 +1,113 @@ +/* + * add.c - CGI to add keys. + * + * Copyright 2002-2004,2007-2008 Jonathan McDowell + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include +#include +#include +#include + +#include "armor.h" +#include "cleankey.h" +#include "cleanup.h" +#include "charfuncs.h" +#include "getcgi.h" +#include "keydb.h" +#include "log.h" +#include "mem.h" +#include "onak-conf.h" +#include "parsekey.h" + +int main(int argc, char *argv[]) +{ + struct openpgp_packet_list *packets = NULL; + struct openpgp_publickey *keys = NULL; + char **params = NULL; + struct buffer_ctx ctx; + int count = 0; + int i; + struct onak_dbctx *dbctx; + + memset(&ctx, 0, sizeof(ctx)); + + params = getcgivars(argc, argv); + for (i = 0; params != NULL && params[i] != NULL; i += 2) { + if (!strcmp(params[i], "keytext")) { + ctx.buffer = params[i+1]; + ctx.size = strlen(ctx.buffer); + } else { + free(params[i+1]); + } + params[i+1] = NULL; + free(params[i]); + params[i] = NULL; + } + if (params != NULL) { + free(params); + params = NULL; + } + + start_html("onak : Add"); + if (ctx.buffer == NULL) { + puts("Error: No keytext to add supplied."); + end_html(); + } else { + readconfig(NULL); + initlogthing("add", config.logfile); + dearmor_openpgp_stream(buffer_fetchchar, + &ctx, + &packets); + if (packets != NULL) { + count = parse_keys(packets, &keys); + logthing(LOGTHING_NOTICE, "Received %d keys.", + count); + printf("Key block added to key server database.\n"); + printf(" New public keys added: %d\n", count); + end_html(); + if (stdout != NULL && fileno(stdout) != -1) { + fclose(stdout); + } + if (stderr != NULL && stderr != stdout && + fileno(stderr) != -1) { + fclose(stderr); + } + catchsignals(); + dbctx = config.dbinit(config.backend, false); + + count = cleankeys(&keys, config.clean_policies); + logthing(LOGTHING_INFO, "%d keys cleaned.", + count); + + count = dbctx->update_keys(dbctx, &keys, true); + logthing(LOGTHING_NOTICE, "Got %d new keys.", + count); + + if (keys != NULL) { + free_publickey(keys); + keys = NULL; + } + + dbctx->cleanupdb(dbctx); + } else { + puts("No OpenPGP packets found in input."); + end_html(); + } + cleanuplogthing(); + cleanupconfig(); + } + return (EXIT_SUCCESS); +} diff --git a/cgi/gpgwww.c b/cgi/gpgwww.c new file mode 100644 index 0000000..0fc58fb --- /dev/null +++ b/cgi/gpgwww.c @@ -0,0 +1,209 @@ +/* + * gpgwww.c - www interface to path finder. + * + * Copyright 2001-2004 Jonathan McDowell + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include +#include +#include +#include + +#include "build-config.h" + +#include "armor.h" +#include "charfuncs.h" +#include "cleanup.h" +#include "getcgi.h" +#include "hash.h" +#include "keydb.h" +#include "log.h" +#include "mem.h" +#include "onak-conf.h" +#include "parsekey.h" +#include "stats.h" + +#define OP_UNKNOWN 0 +#define OP_GET 1 + +int parsecgistuff(char **cgiparams, uint64_t *from, uint64_t *to) +{ + int i = 0; + int op = OP_UNKNOWN; + + if (cgiparams != NULL) { + i = 0; + while (cgiparams[i] != NULL) { + if (!strcmp(cgiparams[i], "to")) { + *to = strtoul(cgiparams[i+1], NULL, 16); + } else if (!strcmp(cgiparams[i], "from")) { + *from = strtoul(cgiparams[i+1], NULL, 16); + } else if (!strcmp(cgiparams[i], "op")) { + if (!strcmp(cgiparams[i+1], "get")) { + op = OP_GET; + } + } + i += 2; + } + } + + return op; +} + +int getkeyspath(struct onak_dbctx *dbctx, + uint64_t have, uint64_t want, int count) +{ + struct openpgp_publickey *publickey = NULL; + struct openpgp_packet_list *packets = NULL; + struct openpgp_packet_list *list_end = NULL; + struct stats_key *keyinfoa, *keyinfob, *curkey; + int pathlen = 0; + + /* + * Make sure the keys we have and want are in the cache. + */ + dbctx->cached_getkeysigs(dbctx, have); + dbctx->cached_getkeysigs(dbctx, want); + + if ((keyinfoa = findinhash(have)) == NULL) { + return 1; + } + if ((keyinfob = findinhash(want)) == NULL) { + return 1; + } + + while ((!cleanup()) && (pathlen < count)) { + /* + * Fill the tree info up. + */ + initcolour(true); + findpath(dbctx, keyinfoa, keyinfob); + keyinfob->parent = 0; + if (keyinfoa->colour == 0) { + pathlen = count; + } else { + /* + * Skip the first key, as the remote user will already + * have it + */ + curkey = findinhash(keyinfoa->parent); + while (curkey != NULL && curkey->keyid != 0) { + if (curkey->keyid != want && + dbctx->fetch_key_id(dbctx, + curkey->keyid, + &publickey, false)) { + flatten_publickey(publickey, + &packets, + &list_end); + free_publickey(publickey); + publickey = NULL; + } + if (curkey != keyinfoa && curkey != keyinfob) { + curkey->disabled = true; + } + curkey = findinhash(curkey->parent); + } + } + pathlen++; + } + + /* + * Add the destination key to the list of returned keys. + */ + if (dbctx->fetch_key_id(dbctx, want, &publickey, false)) { + flatten_publickey(publickey, + &packets, + &list_end); + free_publickey(publickey); + publickey = NULL; + } + + armor_openpgp_stream(stdout_putchar, NULL, packets); + free_packet_list(packets); + packets = list_end = NULL; + + return 0; +} + +int main(int argc, char *argv[]) +{ + char **cgiparams = NULL; /* Our CGI parameter block */ + uint64_t from = 0, to = 0; + int op = OP_UNKNOWN; + struct onak_dbctx *dbctx; + + cgiparams = getcgivars(argc, argv); + + + op = parsecgistuff(cgiparams, &from, &to); + + if (op != OP_GET) { + start_html("Experimental PGP key path finder results"); + } else { + puts("Content-Type: text/plain\n"); + } + + if (from == 0 || to == 0) { + printf("Must pass from & to\n"); + puts(""); + exit(1); + } + + if (op != OP_GET) { + printf("

Looking for path from 0x%016" PRIX64" to 0x%016" + PRIX64 ".\n", + from, to); + printf("Find reverse path\n", + to, + from); + printf("" + "Get all keys listed

\n", + from, + to); + } + + readconfig(NULL); + initlogthing("gpgwww", config.logfile); + catchsignals(); + dbctx = config.dbinit(config.backend, true); + inithash(); + logthing(LOGTHING_NOTICE, "Looking for path from 0x%016" PRIX64 + " to 0x%016" + PRIX64, + from, + to); + if (op == OP_GET) { + getkeyspath(dbctx, from, to, 3); + } else { + dofindpath(dbctx, from, to, true, 3); + } + destroyhash(); + dbctx->cleanupdb(dbctx); + cleanuplogthing(); + cleanupconfig(); + + if (op != OP_GET) { + puts("
"); + puts("Produced by gpgwww " ONAK_VERSION ", part of onak. "); + end_html(); + } + + cleanupcgi(cgiparams); + cgiparams = NULL; + + return EXIT_SUCCESS; +} diff --git a/cgi/hashquery.c b/cgi/hashquery.c new file mode 100644 index 0000000..5c056a2 --- /dev/null +++ b/cgi/hashquery.c @@ -0,0 +1,128 @@ +/* + * hashquery.c - CGI to handle SKS style /pks/hashquery requests + * + * Copyright 2011 Jonathan McDowell + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include "charfuncs.h" +#include "cleanup.h" +#include "keydb.h" +#include "log.h" +#include "marshal.h" +#include "mem.h" +#include "onak-conf.h" + +void doerror(char *error) +{ + printf("Content-Type: text/plain\n\n"); + printf("%s", error); + cleanuplogthing(); + cleanupconfig(); + exit(EXIT_FAILURE); +} + +int main(int argc, char *argv[]) +{ + char *request_method; + int count, found, i; + uint8_t **hashes; + struct buffer_ctx cgipostbuf; + struct openpgp_publickey **keys; + struct onak_dbctx *dbctx; + + readconfig(NULL); + initlogthing("hashquery", config.logfile); + + request_method = getenv("REQUEST_METHOD"); + if (request_method == NULL || strcmp(request_method, "POST") != 0) { + doerror("hashquery must be a HTTP POST request.\n"); + } + + if (!(cgipostbuf.size = atoi(getenv("CONTENT_LENGTH")))) { + doerror("Must provide a content length.\n"); + } + + cgipostbuf.offset = 0; + cgipostbuf.buffer = malloc(cgipostbuf.size); + if (cgipostbuf.buffer == NULL) { + doerror("Couldn't allocate memory for query content.\n"); + } + + if (!fread(cgipostbuf.buffer, cgipostbuf.size, 1, stdin)) { + doerror("Couldn't read query.\n"); + } + + hashes = (uint8_t **) unmarshal_array(buffer_fetchchar, &cgipostbuf, + (void * (*)(int (*)(void *, size_t, void *), void *)) + unmarshal_skshash, &count); + + free(cgipostbuf.buffer); + cgipostbuf.buffer = NULL; + cgipostbuf.size = cgipostbuf.offset = 0; + + if (hashes == NULL) { + doerror("No hashes supplied.\n"); + } + + found = 0; + keys = calloc(sizeof(struct openpgp_publickey *), count); + if (keys == NULL) { + doerror("Couldn't allocate memory for reply.\n"); + } + + catchsignals(); + dbctx = config.dbinit(config.backend, false); + + if (dbctx->fetch_key_skshash == NULL) { + dbctx->cleanupdb(dbctx); + doerror("Can't fetch by skshash with this backend."); + } + + for (i = 0; i < count; i++) { + dbctx->fetch_key_skshash(dbctx, + (struct skshash *) hashes[i], &keys[found]); + if (keys[found] != NULL) { + found++; + } + free(hashes[i]); + hashes[i] = NULL; + } + free(hashes); + hashes = NULL; + + dbctx->cleanupdb(dbctx); + + puts("Content-Type: pgp/keys\n"); + marshal_array(stdout_putchar, NULL, + (void (*)(int (*)(void *, size_t, void *), + void *, const void *)) + marshal_publickey, (void **) keys, found); + printf("\n"); + + for (i = 0; i < found; i++) { + free_publickey(keys[i]); + } + free(keys); + + cleanuplogthing(); + cleanupconfig(); +} diff --git a/cgi/lookup.c b/cgi/lookup.c new file mode 100644 index 0000000..35c039b --- /dev/null +++ b/cgi/lookup.c @@ -0,0 +1,322 @@ +/* + * lookup.c - CGI to lookup keys. + * + * Copyright 2002-2005,2007-2009,2011 Jonathan McDowell + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include "build-config.h" + +#include "armor.h" +#include "charfuncs.h" +#include "cleankey.h" +#include "cleanup.h" +#include "getcgi.h" +#include "keydb.h" +#include "keyid.h" +#include "keyindex.h" +#include "log.h" +#include "mem.h" +#include "onak-conf.h" +#include "parsekey.h" +#include "photoid.h" + +#define OP_UNKNOWN 0 +#define OP_GET 1 +#define OP_INDEX 2 +#define OP_VINDEX 3 +#define OP_PHOTO 4 +#define OP_HGET 5 + +void find_keys(struct onak_dbctx *dbctx, + char *search, uint64_t keyid, + struct openpgp_fingerprint *fingerprint, + bool ishex, bool isfp, bool dispfp, bool skshash, + bool exact, bool verbose, bool mrhkp) +{ + struct openpgp_publickey *publickey = NULL; + int count = 0; + + if (ishex) { + count = dbctx->fetch_key_id(dbctx, keyid, &publickey, + false); + } else if (isfp) { + count = dbctx->fetch_key_fp(dbctx, fingerprint, &publickey, + false); + } else { + count = dbctx->fetch_key_text(dbctx, search, &publickey); + } + if (publickey != NULL) { + if (mrhkp) { + printf("info:1:%d\n", count); + mrkey_index(publickey); + } else { + key_index(dbctx, publickey, verbose, dispfp, + skshash, true); + } + free_publickey(publickey); + } else if (count == 0) { + if (mrhkp) { + puts("info:1:0"); + } else { + puts("Key not found."); + } + } else { + if (mrhkp) { + puts("info:1:0"); + } else { + printf("Found %d keys, but maximum number to return" + " is %d.\n", + count, + config.maxkeys); + puts("Try again with a more specific search."); + } + } +} + +static uint8_t hex2bin(char c) +{ + if (c >= '0' && c <= '9') { + return (c - '0'); + } else if (c >= 'a' && c <= 'f') { + return (c - 'a' + 10); + } else if (c >= 'A' && c <= 'F') { + return (c - 'A' + 10); + } + + return 255; +} + +int main(int argc, char *argv[]) +{ + char **params = NULL; + int op = OP_UNKNOWN; + int i, j; + int indx = 0; + bool dispfp = false; + bool skshash = false; + bool exact = false; + bool ishex = false; + bool isfp = false; + bool mrhkp = false; + uint64_t keyid = 0; + struct openpgp_fingerprint fingerprint; + char *search = NULL; + char *end = NULL; + struct openpgp_publickey *publickey = NULL; + struct openpgp_packet_list *packets = NULL; + struct openpgp_packet_list *list_end = NULL; + int result; + struct skshash hash; + struct onak_dbctx *dbctx; + + params = getcgivars(argc, argv); + for (i = 0; params != NULL && params[i] != NULL; i += 2) { + if (!strcmp(params[i], "op")) { + if (!strcmp(params[i+1], "get")) { + op = OP_GET; + } else if (!strcmp(params[i+1], "hget")) { + op = OP_HGET; + } else if (!strcmp(params[i+1], "index")) { + op = OP_INDEX; + } else if (!strcmp(params[i+1], "vindex")) { + op = OP_VINDEX; + } else if (!strcmp(params[i+1], "photo")) { + op = OP_PHOTO; + } + } else if (!strcmp(params[i], "search")) { + search = params[i+1]; + params[i+1] = NULL; + if (search != NULL && strlen(search) == 42 && + search[0] == '0' && search[1] == 'x') { + /* v4 fingerprint */ + fingerprint.length = 20; + for (j = 0; j < 20; j++) { + fingerprint.fp[j] = (hex2bin( + search[2 + j * 2]) + << 4) + + hex2bin(search[3 + j * 2]); + } + isfp = true; + } else if (search != NULL && strlen(search) == 66 && + search[0] == '0' && search[1] == 'x') { + /* v5 fingerprint */ + fingerprint.length = 32; + for (j = 0; j < 32; j++) { + fingerprint.fp[j] = (hex2bin( + search[2 + j * 2]) + << 4) + + hex2bin(search[3 + j * 2]); + } + isfp = true; + } else if (search != NULL) { + keyid = strtoull(search, &end, 16); + if (*search != 0 && + end != NULL && + *end == 0) { + ishex = true; + } + } + } else if (!strcmp(params[i], "idx")) { + indx = atoi(params[i+1]); + } else if (!strcmp(params[i], "fingerprint")) { + if (!strcmp(params[i+1], "on")) { + dispfp = true; + } + } else if (!strcmp(params[i], "hash")) { + if (!strcmp(params[i+1], "on")) { + skshash = true; + } + } else if (!strcmp(params[i], "exact")) { + if (!strcmp(params[i+1], "on")) { + exact = true; + } + } else if (!strcmp(params[i], "options")) { + /* + * TODO: We should be smarter about this; options may + * have several entries. For now mr is the only valid + * one though. + */ + if (!strcmp(params[i+1], "mr")) { + mrhkp = true; + } + } + free(params[i]); + params[i] = NULL; + if (params[i+1] != NULL) { + free(params[i+1]); + params[i+1] = NULL; + } + } + if (params != NULL) { + free(params); + params = NULL; + } + + if (mrhkp) { + puts("Content-Type: text/plain\n"); + } else if (op == OP_PHOTO) { + puts("Content-Type: image/jpeg\n"); + } else { + start_html("Lookup of key"); + } + + if (op == OP_UNKNOWN) { + puts("Error: No operation supplied."); + } else if (search == NULL) { + puts("Error: No key to search for supplied."); + } else { + readconfig(NULL); + initlogthing("lookup", config.logfile); + catchsignals(); + dbctx = config.dbinit(config.backend, false); + switch (op) { + case OP_GET: + case OP_HGET: + if (op == OP_HGET) { + parse_skshash(search, &hash); + result = dbctx->fetch_key_skshash(dbctx, + &hash, &publickey); + } else if (ishex) { + result = dbctx->fetch_key_id(dbctx, keyid, + &publickey, false); + } else if (isfp) { + result = dbctx->fetch_key_fp(dbctx, + &fingerprint, &publickey, false); + } else { + result = dbctx->fetch_key_text(dbctx, + search, + &publickey); + } + if (result) { + logthing(LOGTHING_NOTICE, + "Found %d key(s) for search %s", + result, + search); + puts("
");
+				cleankeys(&publickey, config.clean_policies);
+				flatten_publickey(publickey,
+							&packets,
+							&list_end);
+				armor_openpgp_stream(stdout_putchar,
+						NULL,
+						packets);
+				puts("
"); + } else { + logthing(LOGTHING_NOTICE, + "Failed to find key for search %s", + search); + puts("Key not found"); + } + break; + case OP_INDEX: + find_keys(dbctx, search, keyid, &fingerprint, + ishex, isfp, dispfp, skshash, + exact, false, mrhkp); + break; + case OP_VINDEX: + find_keys(dbctx, search, keyid, &fingerprint, + ishex, isfp, dispfp, skshash, + exact, true, mrhkp); + break; + case OP_PHOTO: + if (isfp) { + dbctx->fetch_key_fp(dbctx, &fingerprint, + &publickey, false); + } else { + dbctx->fetch_key_id(dbctx, keyid, + &publickey, false); + } + if (publickey != NULL) { + unsigned char *photo = NULL; + size_t length = 0; + + if (getphoto(publickey, indx, &photo, + &length) == ONAK_E_OK) { + fwrite(photo, + 1, + length, + stdout); + } + free_publickey(publickey); + publickey = NULL; + } + break; + default: + puts("Unknown operation!"); + } + dbctx->cleanupdb(dbctx); + cleanuplogthing(); + cleanupconfig(); + } + if (!mrhkp) { + puts("
"); + puts("Produced by onak " ONAK_VERSION ); + end_html(); + } + + if (search != NULL) { + free(search); + search = NULL; + } + + return (EXIT_SUCCESS); +} diff --git a/debian/onak.install b/debian/onak.install index a092913..f747b2d 100644 --- a/debian/onak.install +++ b/debian/onak.install @@ -1,2 +1,2 @@ obj-*/onak.ini etc -obj-*/add obj-*/lookup obj-*/gpgwww obj-*/hashquery usr/lib/cgi-bin/pks +obj-*/cgi/add obj-*/cgi/lookup obj-*/cgi/gpgwww obj-*/cgi/hashquery usr/lib/cgi-bin/pks diff --git a/gpgwww.c b/gpgwww.c deleted file mode 100644 index 0fc58fb..0000000 --- a/gpgwww.c +++ /dev/null @@ -1,209 +0,0 @@ -/* - * gpgwww.c - www interface to path finder. - * - * Copyright 2001-2004 Jonathan McDowell - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ - -#include -#include -#include -#include - -#include "build-config.h" - -#include "armor.h" -#include "charfuncs.h" -#include "cleanup.h" -#include "getcgi.h" -#include "hash.h" -#include "keydb.h" -#include "log.h" -#include "mem.h" -#include "onak-conf.h" -#include "parsekey.h" -#include "stats.h" - -#define OP_UNKNOWN 0 -#define OP_GET 1 - -int parsecgistuff(char **cgiparams, uint64_t *from, uint64_t *to) -{ - int i = 0; - int op = OP_UNKNOWN; - - if (cgiparams != NULL) { - i = 0; - while (cgiparams[i] != NULL) { - if (!strcmp(cgiparams[i], "to")) { - *to = strtoul(cgiparams[i+1], NULL, 16); - } else if (!strcmp(cgiparams[i], "from")) { - *from = strtoul(cgiparams[i+1], NULL, 16); - } else if (!strcmp(cgiparams[i], "op")) { - if (!strcmp(cgiparams[i+1], "get")) { - op = OP_GET; - } - } - i += 2; - } - } - - return op; -} - -int getkeyspath(struct onak_dbctx *dbctx, - uint64_t have, uint64_t want, int count) -{ - struct openpgp_publickey *publickey = NULL; - struct openpgp_packet_list *packets = NULL; - struct openpgp_packet_list *list_end = NULL; - struct stats_key *keyinfoa, *keyinfob, *curkey; - int pathlen = 0; - - /* - * Make sure the keys we have and want are in the cache. - */ - dbctx->cached_getkeysigs(dbctx, have); - dbctx->cached_getkeysigs(dbctx, want); - - if ((keyinfoa = findinhash(have)) == NULL) { - return 1; - } - if ((keyinfob = findinhash(want)) == NULL) { - return 1; - } - - while ((!cleanup()) && (pathlen < count)) { - /* - * Fill the tree info up. - */ - initcolour(true); - findpath(dbctx, keyinfoa, keyinfob); - keyinfob->parent = 0; - if (keyinfoa->colour == 0) { - pathlen = count; - } else { - /* - * Skip the first key, as the remote user will already - * have it - */ - curkey = findinhash(keyinfoa->parent); - while (curkey != NULL && curkey->keyid != 0) { - if (curkey->keyid != want && - dbctx->fetch_key_id(dbctx, - curkey->keyid, - &publickey, false)) { - flatten_publickey(publickey, - &packets, - &list_end); - free_publickey(publickey); - publickey = NULL; - } - if (curkey != keyinfoa && curkey != keyinfob) { - curkey->disabled = true; - } - curkey = findinhash(curkey->parent); - } - } - pathlen++; - } - - /* - * Add the destination key to the list of returned keys. - */ - if (dbctx->fetch_key_id(dbctx, want, &publickey, false)) { - flatten_publickey(publickey, - &packets, - &list_end); - free_publickey(publickey); - publickey = NULL; - } - - armor_openpgp_stream(stdout_putchar, NULL, packets); - free_packet_list(packets); - packets = list_end = NULL; - - return 0; -} - -int main(int argc, char *argv[]) -{ - char **cgiparams = NULL; /* Our CGI parameter block */ - uint64_t from = 0, to = 0; - int op = OP_UNKNOWN; - struct onak_dbctx *dbctx; - - cgiparams = getcgivars(argc, argv); - - - op = parsecgistuff(cgiparams, &from, &to); - - if (op != OP_GET) { - start_html("Experimental PGP key path finder results"); - } else { - puts("Content-Type: text/plain\n"); - } - - if (from == 0 || to == 0) { - printf("Must pass from & to\n"); - puts(""); - exit(1); - } - - if (op != OP_GET) { - printf("

Looking for path from 0x%016" PRIX64" to 0x%016" - PRIX64 ".\n", - from, to); - printf("Find reverse path\n", - to, - from); - printf("" - "Get all keys listed

\n", - from, - to); - } - - readconfig(NULL); - initlogthing("gpgwww", config.logfile); - catchsignals(); - dbctx = config.dbinit(config.backend, true); - inithash(); - logthing(LOGTHING_NOTICE, "Looking for path from 0x%016" PRIX64 - " to 0x%016" - PRIX64, - from, - to); - if (op == OP_GET) { - getkeyspath(dbctx, from, to, 3); - } else { - dofindpath(dbctx, from, to, true, 3); - } - destroyhash(); - dbctx->cleanupdb(dbctx); - cleanuplogthing(); - cleanupconfig(); - - if (op != OP_GET) { - puts("
"); - puts("Produced by gpgwww " ONAK_VERSION ", part of onak. "); - end_html(); - } - - cleanupcgi(cgiparams); - cgiparams = NULL; - - return EXIT_SUCCESS; -} diff --git a/hashquery.c b/hashquery.c deleted file mode 100644 index 5c056a2..0000000 --- a/hashquery.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * hashquery.c - CGI to handle SKS style /pks/hashquery requests - * - * Copyright 2011 Jonathan McDowell - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include - -#include "charfuncs.h" -#include "cleanup.h" -#include "keydb.h" -#include "log.h" -#include "marshal.h" -#include "mem.h" -#include "onak-conf.h" - -void doerror(char *error) -{ - printf("Content-Type: text/plain\n\n"); - printf("%s", error); - cleanuplogthing(); - cleanupconfig(); - exit(EXIT_FAILURE); -} - -int main(int argc, char *argv[]) -{ - char *request_method; - int count, found, i; - uint8_t **hashes; - struct buffer_ctx cgipostbuf; - struct openpgp_publickey **keys; - struct onak_dbctx *dbctx; - - readconfig(NULL); - initlogthing("hashquery", config.logfile); - - request_method = getenv("REQUEST_METHOD"); - if (request_method == NULL || strcmp(request_method, "POST") != 0) { - doerror("hashquery must be a HTTP POST request.\n"); - } - - if (!(cgipostbuf.size = atoi(getenv("CONTENT_LENGTH")))) { - doerror("Must provide a content length.\n"); - } - - cgipostbuf.offset = 0; - cgipostbuf.buffer = malloc(cgipostbuf.size); - if (cgipostbuf.buffer == NULL) { - doerror("Couldn't allocate memory for query content.\n"); - } - - if (!fread(cgipostbuf.buffer, cgipostbuf.size, 1, stdin)) { - doerror("Couldn't read query.\n"); - } - - hashes = (uint8_t **) unmarshal_array(buffer_fetchchar, &cgipostbuf, - (void * (*)(int (*)(void *, size_t, void *), void *)) - unmarshal_skshash, &count); - - free(cgipostbuf.buffer); - cgipostbuf.buffer = NULL; - cgipostbuf.size = cgipostbuf.offset = 0; - - if (hashes == NULL) { - doerror("No hashes supplied.\n"); - } - - found = 0; - keys = calloc(sizeof(struct openpgp_publickey *), count); - if (keys == NULL) { - doerror("Couldn't allocate memory for reply.\n"); - } - - catchsignals(); - dbctx = config.dbinit(config.backend, false); - - if (dbctx->fetch_key_skshash == NULL) { - dbctx->cleanupdb(dbctx); - doerror("Can't fetch by skshash with this backend."); - } - - for (i = 0; i < count; i++) { - dbctx->fetch_key_skshash(dbctx, - (struct skshash *) hashes[i], &keys[found]); - if (keys[found] != NULL) { - found++; - } - free(hashes[i]); - hashes[i] = NULL; - } - free(hashes); - hashes = NULL; - - dbctx->cleanupdb(dbctx); - - puts("Content-Type: pgp/keys\n"); - marshal_array(stdout_putchar, NULL, - (void (*)(int (*)(void *, size_t, void *), - void *, const void *)) - marshal_publickey, (void **) keys, found); - printf("\n"); - - for (i = 0; i < found; i++) { - free_publickey(keys[i]); - } - free(keys); - - cleanuplogthing(); - cleanupconfig(); -} diff --git a/lookup.c b/lookup.c deleted file mode 100644 index 35c039b..0000000 --- a/lookup.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - * lookup.c - CGI to lookup keys. - * - * Copyright 2002-2005,2007-2009,2011 Jonathan McDowell - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include - -#include "build-config.h" - -#include "armor.h" -#include "charfuncs.h" -#include "cleankey.h" -#include "cleanup.h" -#include "getcgi.h" -#include "keydb.h" -#include "keyid.h" -#include "keyindex.h" -#include "log.h" -#include "mem.h" -#include "onak-conf.h" -#include "parsekey.h" -#include "photoid.h" - -#define OP_UNKNOWN 0 -#define OP_GET 1 -#define OP_INDEX 2 -#define OP_VINDEX 3 -#define OP_PHOTO 4 -#define OP_HGET 5 - -void find_keys(struct onak_dbctx *dbctx, - char *search, uint64_t keyid, - struct openpgp_fingerprint *fingerprint, - bool ishex, bool isfp, bool dispfp, bool skshash, - bool exact, bool verbose, bool mrhkp) -{ - struct openpgp_publickey *publickey = NULL; - int count = 0; - - if (ishex) { - count = dbctx->fetch_key_id(dbctx, keyid, &publickey, - false); - } else if (isfp) { - count = dbctx->fetch_key_fp(dbctx, fingerprint, &publickey, - false); - } else { - count = dbctx->fetch_key_text(dbctx, search, &publickey); - } - if (publickey != NULL) { - if (mrhkp) { - printf("info:1:%d\n", count); - mrkey_index(publickey); - } else { - key_index(dbctx, publickey, verbose, dispfp, - skshash, true); - } - free_publickey(publickey); - } else if (count == 0) { - if (mrhkp) { - puts("info:1:0"); - } else { - puts("Key not found."); - } - } else { - if (mrhkp) { - puts("info:1:0"); - } else { - printf("Found %d keys, but maximum number to return" - " is %d.\n", - count, - config.maxkeys); - puts("Try again with a more specific search."); - } - } -} - -static uint8_t hex2bin(char c) -{ - if (c >= '0' && c <= '9') { - return (c - '0'); - } else if (c >= 'a' && c <= 'f') { - return (c - 'a' + 10); - } else if (c >= 'A' && c <= 'F') { - return (c - 'A' + 10); - } - - return 255; -} - -int main(int argc, char *argv[]) -{ - char **params = NULL; - int op = OP_UNKNOWN; - int i, j; - int indx = 0; - bool dispfp = false; - bool skshash = false; - bool exact = false; - bool ishex = false; - bool isfp = false; - bool mrhkp = false; - uint64_t keyid = 0; - struct openpgp_fingerprint fingerprint; - char *search = NULL; - char *end = NULL; - struct openpgp_publickey *publickey = NULL; - struct openpgp_packet_list *packets = NULL; - struct openpgp_packet_list *list_end = NULL; - int result; - struct skshash hash; - struct onak_dbctx *dbctx; - - params = getcgivars(argc, argv); - for (i = 0; params != NULL && params[i] != NULL; i += 2) { - if (!strcmp(params[i], "op")) { - if (!strcmp(params[i+1], "get")) { - op = OP_GET; - } else if (!strcmp(params[i+1], "hget")) { - op = OP_HGET; - } else if (!strcmp(params[i+1], "index")) { - op = OP_INDEX; - } else if (!strcmp(params[i+1], "vindex")) { - op = OP_VINDEX; - } else if (!strcmp(params[i+1], "photo")) { - op = OP_PHOTO; - } - } else if (!strcmp(params[i], "search")) { - search = params[i+1]; - params[i+1] = NULL; - if (search != NULL && strlen(search) == 42 && - search[0] == '0' && search[1] == 'x') { - /* v4 fingerprint */ - fingerprint.length = 20; - for (j = 0; j < 20; j++) { - fingerprint.fp[j] = (hex2bin( - search[2 + j * 2]) - << 4) + - hex2bin(search[3 + j * 2]); - } - isfp = true; - } else if (search != NULL && strlen(search) == 66 && - search[0] == '0' && search[1] == 'x') { - /* v5 fingerprint */ - fingerprint.length = 32; - for (j = 0; j < 32; j++) { - fingerprint.fp[j] = (hex2bin( - search[2 + j * 2]) - << 4) + - hex2bin(search[3 + j * 2]); - } - isfp = true; - } else if (search != NULL) { - keyid = strtoull(search, &end, 16); - if (*search != 0 && - end != NULL && - *end == 0) { - ishex = true; - } - } - } else if (!strcmp(params[i], "idx")) { - indx = atoi(params[i+1]); - } else if (!strcmp(params[i], "fingerprint")) { - if (!strcmp(params[i+1], "on")) { - dispfp = true; - } - } else if (!strcmp(params[i], "hash")) { - if (!strcmp(params[i+1], "on")) { - skshash = true; - } - } else if (!strcmp(params[i], "exact")) { - if (!strcmp(params[i+1], "on")) { - exact = true; - } - } else if (!strcmp(params[i], "options")) { - /* - * TODO: We should be smarter about this; options may - * have several entries. For now mr is the only valid - * one though. - */ - if (!strcmp(params[i+1], "mr")) { - mrhkp = true; - } - } - free(params[i]); - params[i] = NULL; - if (params[i+1] != NULL) { - free(params[i+1]); - params[i+1] = NULL; - } - } - if (params != NULL) { - free(params); - params = NULL; - } - - if (mrhkp) { - puts("Content-Type: text/plain\n"); - } else if (op == OP_PHOTO) { - puts("Content-Type: image/jpeg\n"); - } else { - start_html("Lookup of key"); - } - - if (op == OP_UNKNOWN) { - puts("Error: No operation supplied."); - } else if (search == NULL) { - puts("Error: No key to search for supplied."); - } else { - readconfig(NULL); - initlogthing("lookup", config.logfile); - catchsignals(); - dbctx = config.dbinit(config.backend, false); - switch (op) { - case OP_GET: - case OP_HGET: - if (op == OP_HGET) { - parse_skshash(search, &hash); - result = dbctx->fetch_key_skshash(dbctx, - &hash, &publickey); - } else if (ishex) { - result = dbctx->fetch_key_id(dbctx, keyid, - &publickey, false); - } else if (isfp) { - result = dbctx->fetch_key_fp(dbctx, - &fingerprint, &publickey, false); - } else { - result = dbctx->fetch_key_text(dbctx, - search, - &publickey); - } - if (result) { - logthing(LOGTHING_NOTICE, - "Found %d key(s) for search %s", - result, - search); - puts("
");
-				cleankeys(&publickey, config.clean_policies);
-				flatten_publickey(publickey,
-							&packets,
-							&list_end);
-				armor_openpgp_stream(stdout_putchar,
-						NULL,
-						packets);
-				puts("
"); - } else { - logthing(LOGTHING_NOTICE, - "Failed to find key for search %s", - search); - puts("Key not found"); - } - break; - case OP_INDEX: - find_keys(dbctx, search, keyid, &fingerprint, - ishex, isfp, dispfp, skshash, - exact, false, mrhkp); - break; - case OP_VINDEX: - find_keys(dbctx, search, keyid, &fingerprint, - ishex, isfp, dispfp, skshash, - exact, true, mrhkp); - break; - case OP_PHOTO: - if (isfp) { - dbctx->fetch_key_fp(dbctx, &fingerprint, - &publickey, false); - } else { - dbctx->fetch_key_id(dbctx, keyid, - &publickey, false); - } - if (publickey != NULL) { - unsigned char *photo = NULL; - size_t length = 0; - - if (getphoto(publickey, indx, &photo, - &length) == ONAK_E_OK) { - fwrite(photo, - 1, - length, - stdout); - } - free_publickey(publickey); - publickey = NULL; - } - break; - default: - puts("Unknown operation!"); - } - dbctx->cleanupdb(dbctx); - cleanuplogthing(); - cleanupconfig(); - } - if (!mrhkp) { - puts("
"); - puts("Produced by onak " ONAK_VERSION ); - end_html(); - } - - if (search != NULL) { - free(search); - search = NULL; - } - - return (EXIT_SUCCESS); -}