config.h
config.h.in
add
+hashquery
lookup
onak
gpgwww
prefix ?= @prefix@
exec_prefix ?= @exec_prefix@
-PROGS = add lookup gpgwww onak splitkeys onak-mail.pl stripkey
-CORE_OBJS = armor.o charfuncs.o decodekey.o getcgi.o hash.o \
+PROGS = add lookup hashquery gpgwww onak splitkeys onak-mail.pl stripkey
+CORE_OBJS = armor.o charfuncs.o decodekey.o getcgi.o hash.o marshal.o \
keyid.o keyindex.o ll.o mem.o onak-conf.o parsekey.o sha1.o md5.o \
log.o photoid.o wordlist.o cleanup.o merge.o sendsync.o keyarray.o
SRCS = armor.c parsekey.c merge.c keyid.c md5.c sha1.c main.c getcgi.c mem.c \
keyindex.c stats.c lookup.c add.c keydb_$(DBTYPE).c ll.c hash.c \
gpgwww.c onak-conf.c charfuncs.c sendsync.c log.c photoid.c \
- wordlist.c cleankey.c cleanup.c keyarray.c \
+ wordlist.c cleankey.c cleanup.c keyarray.c hashquery.c marshal.c \
$(foreach be,@BACKENDS@,keydb_$(be).c)
PROGS_LDFLAGS_EXTRA =
$(CC) $(LDFLAGS) -o gpgwww gpgwww.o $(OBJS) $(LIBS) \
$(PROGS_LDFLAGS_EXTRA)
+hashquery: hashquery.o $(CORE_OBJS) $(KEYDB_OBJ)
+ $(CC) $(LDFLAGS) -o hashquery hashquery.o $(CORE_OBJS) \
+ $(KEYDB_OBJ) $(LIBS) $(PROGS_LDFLAGS_EXTRA)
+
lookup: lookup.o cleankey.o $(CORE_OBJS) $(KEYDB_OBJ)
$(CC) $(LDFLAGS) -o lookup lookup.o cleankey.o $(CORE_OBJS) \
$(KEYDB_OBJ) $(LIBS) $(PROGS_LDFLAGS_EXTRA)
+onak (0.4.0-1+bzr) unstable; urgency=low
+
+ * Development build
+
+ -- Jonathan McDowell <noodles@earth.li> Sun, 24 Apr 2011 16:42:15 -0700
+
onak (0.4.0-1) unstable; urgency=low
* Only seed empty database for if we're using default config
--- /dev/null
+/*
+ * hashquery.c - CGI to handle SKS style /pks/hashquery requests
+ *
+ * Copyright 2011 Jonathan McDowell <noodles@earth.li>
+ */
+
+#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;
+
+ 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");
+ }
+
+ if (config.dbbackend->fetch_key_skshash == NULL) {
+ doerror("Can't fetch by skshash with this backend.");
+ }
+
+ catchsignals();
+ config.dbbackend->initdb(false);
+
+ for (i = 0; i < count; i++) {
+ config.dbbackend->fetch_key_skshash(
+ (struct skshash *) hashes[i], &keys[found]);
+ if (keys[found] != NULL) {
+ found++;
+ }
+ free(hashes[i]);
+ hashes[i] = NULL;
+ }
+ free(hashes);
+ hashes = NULL;
+
+ config.dbbackend->cleanupdb();
+
+ 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();
+}
--- /dev/null
+/*
+ * marshal.c - SKS compatible marshalling routines
+ *
+ * Copyright 2011 Jonathan McDowell <noodles@earth.li>
+ */
+
+#include <arpa/inet.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "charfuncs.h"
+#include "keyid.h"
+#include "keystructs.h"
+#include "mem.h"
+#include "parsekey.h"
+
+void marshal_publickey(int (*putchar_func)(void *ctx, size_t count,
+ void *c),
+ void *ctx,
+ const struct openpgp_publickey *key)
+{
+ uint32_t len;
+ struct openpgp_packet_list *packets = NULL, *list_end = NULL;
+ struct buffer_ctx buf;
+
+ buf.buffer = calloc(1, 1024);
+ buf.size = 1024;
+ buf.offset = 0;
+
+ flatten_publickey((struct openpgp_publickey *) key, &packets,
+ &list_end);
+ write_openpgp_stream(buffer_putchar, &buf, packets);
+
+ len = htonl(buf.offset);
+
+ putchar_func(ctx, sizeof(len), &len);
+ putchar_func(ctx, buf.offset, buf.buffer);
+
+ free_packet_list(packets);
+}
+
+void marshal_skshash(int (*putchar_func)(void *ctx, size_t count,
+ void *c),
+ void *ctx,
+ const struct skshash *hash)
+{
+ uint32_t len;
+
+ len = htonl(sizeof(hash->hash));
+
+ putchar_func(ctx, sizeof(len), &len);
+ putchar_func(ctx, sizeof(hash->hash), (void *) hash->hash);
+}
+
+struct skshash *unmarshal_skshash(int (*getchar_func)(void *ctx, size_t count,
+ void *c),
+ void *ctx)
+{
+ uint32_t len;
+ struct skshash *hash;
+
+ if (getchar_func(ctx, sizeof(len), &len)) {
+ return NULL;
+ }
+ len = ntohl(len);
+ if (len > sizeof(struct skshash)) {
+ return NULL;
+ }
+ hash = calloc(sizeof(struct skshash), 1);
+ if (getchar_func(ctx, len, hash->hash)) {
+ free(hash);
+ return NULL;
+ }
+
+ return hash;
+}
+
+void marshal_string(int (*putchar_func)(void *ctx, size_t count,
+ void *c),
+ void *ctx,
+ const char *string)
+{
+ uint32_t len, nlen;
+
+ len = strlen(string);
+ nlen = htonl(len);
+
+ putchar_func(ctx, sizeof(nlen), &nlen);
+ putchar_func(ctx, len, &string);
+}
+
+char *unmarshal_string(int (*getchar_func)(void *ctx, size_t count,
+ void *c),
+ void *ctx)
+{
+ uint32_t len;
+ char *string;
+
+ if (getchar_func(ctx, sizeof(len), &len)) {
+ return NULL;
+ }
+ len = ntohl(len);
+ string = malloc(len + 1);
+ if (getchar_func(ctx, len, string)) {
+ free(string);
+ return NULL;
+ }
+
+ string[len] = 0;
+ return string;
+}
+
+void marshal_array(int (*putchar_func)(void *ctx, size_t count,
+ void *c),
+ void *ctx,
+ void (*marshal_func)(int
+ (*putchar_func)(void *ctx,
+ size_t count, void *c),
+ void *ctx, const void *item),
+ void **array,
+ int size)
+{
+ uint32_t len;
+ int i;
+
+ len = htonl(size);
+
+ putchar_func(ctx, sizeof(len), &len);
+
+ for (i = 0; i < size; i++) {
+ marshal_func(putchar_func, ctx, array[i]);
+ }
+}
+
+void **unmarshal_array(int (*getchar_func)(void *ctx, size_t count,
+ void *c),
+ void *ctx,
+ void *(*unmarshal_func)(int
+ (*getchar_func)(void *ctx,
+ size_t count, void *c),
+ void *ctx),
+ int *size)
+{
+ uint32_t len;
+ void **array;
+ int i;
+
+ if (getchar_func(ctx, sizeof(len), &len)) {
+ return NULL;
+ }
+ *size = ntohl(len);
+ array = malloc(*size * sizeof(void *));
+ for (i = 0; i < *size; i++) {
+ array[i] = unmarshal_func(getchar_func, ctx);
+ }
+
+ return array;
+}
--- /dev/null
+/*
+ * marshal.h - SKS compatible marshalling routines
+ *
+ * Copyright 2011 Jonathan McDowell <noodles@earth.li>
+ */
+
+#ifndef __MARSHAL_H__
+#define __MARSHAL_H__
+
+#include "keyid.h"
+#include "keystructs.h"
+
+/**
+ * marshal_publickey - Output an OpenPGP key as a byte stream
+ * @putchar_func: The function to put the next character to the stream
+ * @ctx: A pointer to the context structure for putchar_func.
+ * @key: The key to output.
+ *
+ * Takes an OpenPGP key and marshals it to a byte stream - writes
+ * a 32 bit size of the forthcoming data in network byte order and
+ * then the flattened byte representation of the key.
+ */
+void marshal_publickey(int (*putchar_func)(void *ctx, size_t count,
+ void *c),
+ void *ctx,
+ const struct openpgp_publickey *key);
+
+/**
+ * unmarshal_publickey - Turn a byte stream into an OpenPGP key
+ * @getchar_func: The function to get the next character from the stream
+ * @ctx: A pointer to the context structure for getchar_func.
+ *
+ * Returns an OpenPGP structure which is the unmarshalled result of
+ * the input byte stream - ie the inverse of marshal_publickey.
+ */
+struct openpgp_publickey *unmarshal_publickey(int (*getchar_func)(void *ctx,
+ size_t count,
+ void *c),
+ void *ctx);
+
+/**
+ * marshal_skshash - Output an SKS hash as a byte stream
+ * @putchar_func: The function to put the next character to the stream
+ * @ctx: A pointer to the context structure for putchar_func.
+ * @hash: The hash to output.
+ *
+ * Takes an SKS hash and marshals it to a byte stream - writes
+ * a 32 bit size of the forthcoming data (16 bytes) in network byte order
+ * and then the byte representation of the hash.
+ */
+void marshal_skshash(int (*putchar_func)(void *ctx, size_t count,
+ void *c),
+ void *ctx,
+ const struct skshash *hash);
+
+/**
+ * unmarshal_skshash - Turn a byte stream into an SKS hash structure
+ * @getchar_func: The function to get the next character from the stream
+ * @ctx: A pointer to the context structure for getchar_func.
+ *
+ * Returns an SKS hash structure which is the unmarshalled result of
+ * the input byte stream - ie the inverse of marshal_skshash.
+ */
+struct skshash *unmarshal_skshash(int (*getchar_func)(void *ctx, size_t count,
+ void *c),
+ void *ctx);
+
+/**
+ * marshal_string - Output a string as a byte stream
+ * @putchar_func: The function to put the next character to the stream
+ * @ctx: A pointer to the context structure for putchar_func.
+ * @string: The string to output.
+ *
+ * Takes a string and marshals it to a byte stream - writes a 32 bit size
+ * of the forthcoming data in network byte order and then the string.
+ */
+void marshal_string(int (*putchar_func)(void *ctx, size_t count,
+ void *c),
+ void *ctx,
+ const char *string);
+
+/**
+ * unmarshal_string - Turn a byte stream into a string
+ * @getchar_func: The function to get the next character from the stream
+ * @ctx: A pointer to the context structure for getchar_func.
+ *
+ * Returns a string which is the unmarshalled result of the input byte
+ * stream - ie the inverse of marshal_string.
+ */
+char *unmarshal_string(int (*getchar_func)(void *ctx, size_t count,
+ void *c),
+ void *ctx);
+
+/**
+ * marshal_array - Outputs an array as a byte stream
+ * @putchar_func: The function to put the next character to the stream
+ * @ctx: A pointer to the context structure for putchar_func.
+ * @marshal_func: The function to use to marshal each array element.
+ * @array: A pointer to the array to marshal
+ * @size:: The number of elements in the array.
+ *
+ * Takes an array and marshals it into a byte stream. Outputs a 32 bit
+ * count of the elements in the array in network byte order and then
+ * calls marshal_func for each element in the array to provide the
+ * marshalled contents.
+ */
+void marshal_array(int (*putchar_func)(void *ctx, size_t count,
+ void *c),
+ void *ctx,
+ void (*marshal_func)(int
+ (*putchar_func)(void *ctx,
+ size_t count, void *c),
+ void *ctx, const void *item),
+ void **array,
+ int size);
+
+/**
+ * unmarshal_array - Turn a byte stream into an array of elements
+ * @getchar_func: The function to get the next character from the stream
+ * @ctx: A pointer to the context structure for getchar_func.
+ * @unmarshal_func: The function to use to unmarshal each array element.
+ * @size: A pointer to where to store the number of elements unmarshalled
+ *
+ * Takes a byte stream and unmarshals it into an array of elements,
+ * as determined by the supplied unmarshal_func function. ie the reverse
+ * of marshal_array.
+ */
+void **unmarshal_array(int (*getchar_func)(void *ctx, size_t count,
+ void *c),
+ void *ctx,
+ void *(*unmarshal_func)(int
+ (*getchar_func)(void *ctx,
+ size_t count, void *c),
+ void *ctx),
+ int *size);
+
+#endif /* __MARSHAL_H__ */