1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
/*
* hashquery.c - CGI to handle SKS style /pks/hashquery requests
*
* Copyright 2011 Jonathan McDowell <noodles@earth.li>
*
* 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, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include "charfuncs.h"
#include "cleanup.h"
#include "keyid.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(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();
}
|