~sircmpwn/himitsu

b69e36f064172050f8ed477d4e7dc582a6c365ad — Drew DeVault a month ago 17e0267
Implement command dispatch, query command
A himitsud/cmd.c => himitsud/cmd.c +65 -0
@@ 0,0 1,65 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "key.h"
#include "os.h"
#include "secstore.h"

static void
write_key(const struct hi_key *key, int out)
{
	char resp[] = "key ";
	write(out, resp, sizeof(resp) - 1);
	char *unparsed = hi_key_unparse(key, NULL, NULL);
	size_t l = strlen(unparsed);
	unparsed[l] = '\n';
	write(out, unparsed, l + 1);
	secure_clear_memory(unparsed, l + 1);
	free(unparsed);
}

static int
cmd_query(struct hi_secstore *secstore, int out, const char *args)
{
	struct hi_key *templ = NULL;
	if (args[0]) {
		templ = hi_key_parse(args);
		if (!templ) {
			char error[] = "error invalid key template\n";
			write(out, error, sizeof(error) - 1);
			return 1;
		}
	}
	struct hi_secstore_index *index = secstore->index;
	while (index) {
		if (templ && !hi_key_is_match(index->key, templ)) {
			continue;
		}
		write_key(index->key, out);
		index = index->next;
	}
	char end[] = "end\n";
	write(out, end, sizeof(end) - 1);
	hi_key_destroy(templ);
	return 0;
}

struct {
	char *name;
	int (*fn)(struct hi_secstore *, int, const char *);
} cmds[] = {
	{ "query", cmd_query },
};

int himitsu_run_command(struct hi_secstore *secstore,
		const char *name, const char *args, int outfd)
{
	for (size_t i = 0; i < sizeof(cmds) / sizeof(cmds[0]); ++i) {
		if (strcmp(cmds[i].name, name) == 0) {
			return cmds[i].fn(secstore, outfd, args);
		}
	}
	char error[] = "error unknown command\n";
	write(outfd, error, sizeof(error) - 1);
	return 1;
}

M himitsud/key.c => himitsud/key.c +8 -1
@@ 232,7 232,7 @@ hi_key_destroy(struct hi_key *key)
}

char *
hi_key_unparse(struct hi_key *key,
hi_key_unparse(const struct hi_key *key,
		hi_key_secret_resolver_t resolver, void *data)
{
	char *str;


@@ 288,3 288,10 @@ error:
	free(str);
	return NULL;
}

bool
hi_key_is_match(struct hi_key *ref, struct hi_key *templ)
{
	/* TODO */
	return true;
}

M himitsud/meson.build => himitsud/meson.build +1 -0
@@ 1,6 1,7 @@
executable('himitsud',
	files(
		'base64.c',
		'cmd.c',
		'key.c',
		'main.c',
		'secstore.c',

M himitsud/secstore.c => himitsud/secstore.c +1 -1
@@ 175,7 175,7 @@ error:

/* "Resolves" a secret key by returning its encrypted secret ID */
static const char *
hi_key_resolve_secret_id(struct hi_key *key, void *data)
hi_key_resolve_secret_id(const struct hi_key *key, void *data)
{
	assert(key->value);
	return key->value;

M himitsud/service.c => himitsud/service.c +19 -6
@@ 40,8 40,8 @@ client_hup(struct hi_service *service, struct hi_service_client *client)
static void
client_oom(struct hi_service *service, struct hi_service_client *client)
{
	char *error = "error out of memory\n";
	write(client->fd, error, sizeof(error) - 1);
	char error[] = "error out of memory\n";
	write(client->fd, error, sizeof(error));
	client_hup(service, client);
}



@@ 60,9 60,22 @@ client_errno(struct hi_service *service, struct hi_service_client *client)
static void
process_client_cmd(struct hi_service *service,
		struct hi_service_client *client,
		const char *cmd)
		char *cmd)
{
	fprintf(stderr, "client cmd: %s\n", cmd);
	char *name, *args;
	char *spc = strchr(cmd, ' ');
	if (spc == NULL) {
		name = cmd;
		args = "";
	} else {
		*spc = '\0';
		name = cmd;
		args = &spc[1];
	}
	if (himitsu_run_command(service->secstore,
				name, args, client->fd) != 0) {
		client_hup(service, client);
	}
}

static void


@@ 77,7 90,7 @@ client_readable(struct hi_service *service,
	if (client->bufsz - client->buflen < 1024) {
		size_t desired = client->bufsz + 4096;
		if (desired >= HISERVICE_MAX_BUFSZ) {
			char *error = "error exceeded max packet size\n";
			char error[] = "error exceeded max packet size\n";
			write(client->fd, error, sizeof(error) - 1);
			client_hup(service, client);
			return;


@@ 135,7 148,7 @@ accept_client(struct hi_service *service)
	}

	if (service->nfds >= sizeof(service->fds) / sizeof(service->fds[0])) {
		char *error = "error too many clients\n";
		char error[] = "error too many clients\n";
		write(clientfd, error, sizeof(error) - 1);
		close(clientfd);
		return;

M include/key.h => include/key.h +3 -2
@@ 21,7 21,8 @@ struct hi_key *hi_key_parse(const char *templ);
void hi_key_destroy(struct hi_key *key);

/** A function which, given a key, will return the secret value. */
typedef const char *(*hi_key_secret_resolver_t)(struct hi_key *key, void *data);
typedef const char *(*hi_key_secret_resolver_t)(
		const struct hi_key *key, void *data);

/**
 * Returns a key template for a given key. Must be freed by the caller. If


@@ 29,7 30,7 @@ typedef const char *(*hi_key_secret_resolver_t)(struct hi_key *key, void *data);
 * secret keys. In this case, it's the caller's responsibility to securely wipe
 * the memory when they're done with it.
 */
char *hi_key_unparse(struct hi_key *key,
char *hi_key_unparse(const struct hi_key *key,
		hi_key_secret_resolver_t resolver, void *data);

/** Returns true if the given key matches the given key template. */

M include/service.h => include/service.h +3 -0
@@ 30,4 30,7 @@ int himitsu_service_init(struct hi_service *service,
void himitsu_service_run(struct hi_service *service);
void himitsu_service_finish(struct hi_service *service);

int himitsu_run_command(struct hi_secstore *secstore,
		const char *name, const char *args, int outfd);

#endif