/* strongSwan VICI protocol implementation for NHRP
 * Copyright (c) 2014-2015 Timo Teräs
 *
 * This file is free software: you may copy, redistribute and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 */

#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>

#include "thread.h"
#include "zbuf.h"
#include "log.h"
#include "nhrpd.h"

#include "vici.h"

#define ERRNO_IO_RETRY(EN) (((EN) == EAGAIN) || ((EN) == EWOULDBLOCK) || ((EN) == EINTR))

struct blob {
	char *ptr;
	int len;
};

static int blob_equal(const struct blob *b, const char *str)
{
	if (b->len != (int) strlen(str)) return 0;
	return memcmp(b->ptr, str, b->len) == 0;
}

static int blob2buf(const struct blob *b, char *buf, size_t n)
{
	if (b->len >= (int) n) return 0;
	memcpy(buf, b->ptr, b->len);
	buf[b->len] = 0;
	return 1;
}

struct vici_conn {
	struct thread *t_reconnect, *t_read, *t_write;
	struct zbuf ibuf;
	struct zbuf_queue obuf;
	int fd;
	uint8_t ibuf_data[VICI_MAX_MSGLEN];
};

struct vici_message_ctx {
	const char *sections[8];
	int nsections;
};

static int vici_reconnect(struct thread *t);
static void vici_submit_request(struct vici_conn *vici, const char *name, ...);

static void vici_zbuf_puts(struct zbuf *obuf, const char *str)
{
	size_t len = strlen(str);
	zbuf_put8(obuf, len);
	zbuf_put(obuf, str, len);
}

static void vici_connection_error(struct vici_conn *vici)
{
	nhrp_vc_reset();

	THREAD_OFF(vici->t_read);
	THREAD_OFF(vici->t_write);
	zbuf_reset(&vici->ibuf);
	zbufq_reset(&vici->obuf);

	close(vici->fd);
	vici->fd = -1;
	THREAD_TIMER_ON(master, vici->t_reconnect, vici_reconnect, vici, 2);
}

static void vici_parse_message(
	struct vici_conn *vici, struct zbuf *msg,
	void (*parser)(struct vici_message_ctx *ctx, enum vici_type_t msgtype, const struct blob *key, const struct blob *val),
	struct vici_message_ctx *ctx)
{
	uint8_t *type;
	struct blob key;
	struct blob val;

	while ((type = zbuf_may_pull(msg, uint8_t)) != NULL) {
		switch (*type) {
		case VICI_SECTION_START:
			key.len = zbuf_get8(msg);
			key.ptr = zbuf_pulln(msg, key.len);
			debugf(NHRP_DEBUG_VICI, "VICI: Section start '%.*s'", key.len, key.ptr);
			parser(ctx, *type, &key, NULL);
			ctx->nsections++;
			break;
		case VICI_SECTION_END:
			debugf(NHRP_DEBUG_VICI, "VICI: Section end");
			parser(ctx, *type, NULL, NULL);
			ctx->nsections--;
			break;
		case VICI_KEY_VALUE:
			key.len = zbuf_get8(msg);
			key.ptr = zbuf_pulln(msg, key.len);
			val.len = zbuf_get_be16(msg);
			val.ptr = zbuf_pulln(msg, val.len);
			debugf(NHRP_DEBUG_VICI, "VICI: Key '%.*s'='%.*s'", key.len, key.ptr, val.len, val.ptr);
			parser(ctx, *type, &key, &val);
			break;
		case VICI_LIST_START:
			key.len = zbuf_get8(msg);
			key.ptr = zbuf_pulln(msg, key.len);
			debugf(NHRP_DEBUG_VICI, "VICI: List start '%.*s'", key.len, key.ptr);
			break;
		case VICI_LIST_ITEM:
			val.len = zbuf_get_be16(msg);
			val.ptr = zbuf_pulln(msg, val.len);
			debugf(NHRP_DEBUG_VICI, "VICI: List item: '%.*s'", val.len, val.ptr);
			parser(ctx, *type, &key, &val);
			break;
		case VICI_LIST_END:
			debugf(NHRP_DEBUG_VICI, "VICI: List end");
			break;
		default:
			debugf(NHRP_DEBUG_VICI, "VICI: Unsupported message component type %d", *type);
			return;
		}
	}
}

struct handle_sa_ctx {
	struct vici_message_ctx msgctx;
	int event;
	int child_ok;
	int kill_ikesa;
	uint32_t child_uniqueid, ike_uniqueid;
	struct {
		union sockunion host;
		struct blob id, cert;
	} local, remote;
};

static void parse_sa_message(
	struct vici_message_ctx *ctx,
	enum vici_type_t msgtype,
	const struct blob *key, const struct blob *val)
{
	struct handle_sa_ctx *sactx = container_of(ctx, struct handle_sa_ctx, msgctx);
	struct nhrp_vc *vc;
	char buf[512];

	switch (msgtype) {
	case VICI_SECTION_START:
		if (ctx->nsections == 3) {
			/* Begin of child-sa section, reset child vars */
			sactx->child_uniqueid = 0;
			sactx->child_ok = 0;
		}
		break;
	case VICI_SECTION_END:
		if (ctx->nsections == 3) {
			/* End of child-sa section, update nhrp_vc */
			int up = sactx->child_ok || sactx->event == 1;
			if (up) {
				vc = nhrp_vc_get(&sactx->local.host, &sactx->remote.host, up);
				if (vc) {
					blob2buf(&sactx->local.id, vc->local.id, sizeof(vc->local.id));
					if (blob2buf(&sactx->local.cert, (char*)vc->local.cert, sizeof(vc->local.cert)))
						vc->local.certlen = sactx->local.cert.len;
					blob2buf(&sactx->remote.id, vc->remote.id, sizeof(vc->remote.id));
					if (blob2buf(&sactx->remote.cert, (char*)vc->remote.cert, sizeof(vc->remote.cert)))
						vc->remote.certlen = sactx->remote.cert.len;
					sactx->kill_ikesa |= nhrp_vc_ipsec_updown(sactx->child_uniqueid, vc);
				}
			} else {
				nhrp_vc_ipsec_updown(sactx->child_uniqueid, 0);
			}
		}
		break;
	default:
		switch (key->ptr[0]) {
		case 'l':
			if (blob_equal(key, "local-host") && ctx->nsections == 1) {
				if (blob2buf(val, buf, sizeof(buf)))
					str2sockunion(buf, &sactx->local.host);
			} else if (blob_equal(key, "local-id") && ctx->nsections == 1) {
				sactx->local.id = *val;
			} else if (blob_equal(key, "local-cert-data") && ctx->nsections == 1) {
				sactx->local.cert = *val;
			}
			break;
		case 'r':
			if (blob_equal(key, "remote-host") && ctx->nsections == 1) {
				if (blob2buf(val, buf, sizeof(buf)))
					str2sockunion(buf, &sactx->remote.host);
			} else if (blob_equal(key, "remote-id") && ctx->nsections == 1) {
				sactx->remote.id = *val;
			} else if (blob_equal(key, "remote-cert-data") && ctx->nsections == 1) {
				sactx->remote.cert = *val;
			}
			break;
		case 'u':
			if (blob_equal(key, "uniqueid") && blob2buf(val, buf, sizeof(buf))) {
				if (ctx->nsections == 3)
					sactx->child_uniqueid = strtoul(buf, NULL, 0);
				else if (ctx->nsections == 1)
					sactx->ike_uniqueid = strtoul(buf, NULL, 0);
			}
			break;
		case 's':
			if (blob_equal(key, "state") && ctx->nsections == 3) {
				sactx->child_ok =
					(sactx->event == 0 &&
					 (blob_equal(val, "INSTALLED") ||
					  blob_equal(val, "REKEYED")));
			}
			break;
		}
		break;
	}
}

static void vici_recv_sa(struct vici_conn *vici, struct zbuf *msg, int event)
{
	char buf[32];
	struct handle_sa_ctx ctx = {
		.event = event,
	};

	vici_parse_message(vici, msg, parse_sa_message, &ctx.msgctx);

	if (ctx.kill_ikesa && ctx.ike_uniqueid) {
		debugf(NHRP_DEBUG_COMMON, "VICI: Deleting IKE_SA %u", ctx.ike_uniqueid);
		snprintf(buf, sizeof buf, "%u", ctx.ike_uniqueid);
		vici_submit_request(
			vici, "terminate",
			VICI_KEY_VALUE, "ike-id", strlen(buf), buf,
			VICI_END);
	}
}

static void vici_recv_message(struct vici_conn *vici, struct zbuf *msg)
{
	uint32_t msglen;
	uint8_t msgtype;
	struct blob name;

	msglen = zbuf_get_be32(msg);
	msgtype = zbuf_get8(msg);
	debugf(NHRP_DEBUG_VICI, "VICI: Message %d, %d bytes", msgtype, msglen);

	switch (msgtype) {
	case VICI_EVENT:
		name.len = zbuf_get8(msg);
		name.ptr = zbuf_pulln(msg, name.len);

		debugf(NHRP_DEBUG_VICI, "VICI: Event '%.*s'", name.len, name.ptr);
		if (blob_equal(&name, "list-sa") ||
		    blob_equal(&name, "child-updown") ||
		    blob_equal(&name, "child-rekey"))
			vici_recv_sa(vici, msg, 0);
		else if (blob_equal(&name, "child-state-installed") ||
			 blob_equal(&name, "child-state-rekeyed"))
			vici_recv_sa(vici, msg, 1);
		else if (blob_equal(&name, "child-state-destroying"))
			vici_recv_sa(vici, msg, 2);
		break;
	case VICI_EVENT_UNKNOWN:
		zlog_err("VICI: StrongSwan does not support mandatory events (unpatched?)");
		break;
	case VICI_EVENT_CONFIRM:
	case VICI_CMD_RESPONSE:
		break;
	default:
		zlog_notice("VICI: Unrecognized message type %d", msgtype);
		break;
	}
}

static int vici_read(struct thread *t)
{
	struct vici_conn *vici = THREAD_ARG(t);
	struct zbuf *ibuf = &vici->ibuf;
	struct zbuf pktbuf;

	vici->t_read = NULL;
	if (zbuf_read(ibuf, vici->fd, (size_t) -1) < 0) {
		vici_connection_error(vici);
		return 0;
	}

	/* Process all messages in buffer */
	do {
		uint32_t *hdrlen = zbuf_may_pull(ibuf, uint32_t);
		if (!hdrlen)
			break;
		if (!zbuf_may_pulln(ibuf, ntohl(*hdrlen))) {
			zbuf_reset_head(ibuf, hdrlen);
			break;
		}

		/* Handle packet */
		zbuf_init(&pktbuf, hdrlen, htonl(*hdrlen)+4, htonl(*hdrlen)+4);
		vici_recv_message(vici, &pktbuf);
	} while (1);

	THREAD_READ_ON(master, vici->t_read, vici_read, vici, vici->fd);
	return 0;
}

static int vici_write(struct thread *t)
{
	struct vici_conn *vici = THREAD_ARG(t);
	int r;

	vici->t_write = NULL;
	r = zbufq_write(&vici->obuf, vici->fd);
	if (r > 0) {
		THREAD_WRITE_ON(master, vici->t_write, vici_write, vici, vici->fd);
	} else if (r < 0) {
		vici_connection_error(vici);
	}

	return 0;
}

static void vici_submit(struct vici_conn *vici, struct zbuf *obuf)
{
	if (vici->fd < 0) {
		zbuf_free(obuf);
		return;
	}

	zbufq_queue(&vici->obuf, obuf);
	THREAD_WRITE_ON(master, vici->t_write, vici_write, vici, vici->fd);
}

static void vici_submit_request(struct vici_conn *vici, const char *name, ...)
{
	struct zbuf *obuf;
	uint32_t *hdrlen;
	va_list va;
	size_t len;
	int type;

	obuf = zbuf_alloc(256);
	if (!obuf) return;

	hdrlen = zbuf_push(obuf, uint32_t);
	zbuf_put8(obuf, VICI_CMD_REQUEST);
	vici_zbuf_puts(obuf, name);

	va_start(va, name);
	for (type = va_arg(va, int); type != VICI_END; type = va_arg(va, int)) {
		zbuf_put8(obuf, type);
		switch (type) {
		case VICI_KEY_VALUE:
			vici_zbuf_puts(obuf, va_arg(va, const char *));
			len = va_arg(va, size_t);
			zbuf_put_be16(obuf, len);
			zbuf_put(obuf, va_arg(va, void *), len);
			break;
		case VICI_END:
			break;
		default:
			break;
		}
	}
	va_end(va);
	*hdrlen = htonl(zbuf_used(obuf) - 4);
	vici_submit(vici, obuf);
}

static void vici_register_event(struct vici_conn *vici, const char *name)
{
	struct zbuf *obuf;
	uint32_t *hdrlen;
	uint8_t namelen;

	namelen = strlen(name);
	obuf = zbuf_alloc(4 + 1 + 1 + namelen);
	if (!obuf) return;

	hdrlen = zbuf_push(obuf, uint32_t);
	zbuf_put8(obuf, VICI_EVENT_REGISTER);
	zbuf_put8(obuf, namelen);
	zbuf_put(obuf, name, namelen);
	*hdrlen = htonl(zbuf_used(obuf) - 4);

	vici_submit(vici, obuf);
}

static int vici_reconnect(struct thread *t)
{
	struct vici_conn *vici = THREAD_ARG(t);
	int fd;

	vici->t_reconnect = NULL;
	if (vici->fd >= 0) return 0;

	fd = sock_open_unix("/var/run/charon.vici");
	if (fd < 0) {
		zlog_warn("%s: failure connecting VICI socket: %s",
			__PRETTY_FUNCTION__, strerror(errno));
		THREAD_TIMER_ON(master, vici->t_reconnect, vici_reconnect, vici, 2);
		return 0;
	}

	debugf(NHRP_DEBUG_COMMON, "VICI: Connected");
	vici->fd = fd;
	THREAD_READ_ON(master, vici->t_read, vici_read, vici, vici->fd);

	/* Send event subscribtions */
	//vici_register_event(vici, "child-updown");
	//vici_register_event(vici, "child-rekey");
	vici_register_event(vici, "child-state-installed");
	vici_register_event(vici, "child-state-rekeyed");
	vici_register_event(vici, "child-state-destroying");
	vici_register_event(vici, "list-sa");
	vici_submit_request(vici, "list-sas", VICI_END);

	return 0;
}

static struct vici_conn vici_connection;

void vici_init(void)
{
	struct vici_conn *vici = &vici_connection;

	vici->fd = -1;
	zbuf_init(&vici->ibuf, vici->ibuf_data, sizeof(vici->ibuf_data), 0);
	zbufq_init(&vici->obuf);
	THREAD_TIMER_MSEC_ON(master, vici->t_reconnect, vici_reconnect, vici, 10);
}

void vici_terminate(void)
{
}

void vici_request_vc(const char *profile, union sockunion *src, union sockunion *dst, int prio)
{
	struct vici_conn *vici = &vici_connection;
	char buf[2][SU_ADDRSTRLEN];

	sockunion2str(src, buf[0], sizeof buf[0]);
	sockunion2str(dst, buf[1], sizeof buf[1]);

	vici_submit_request(
		vici, "initiate",
		VICI_KEY_VALUE, "child", strlen(profile), profile,
		VICI_KEY_VALUE, "timeout", 2, "-1",
		VICI_KEY_VALUE, "async", 1, "1",
		VICI_KEY_VALUE, "init-limits", 1, prio ? "0" : "1",
		VICI_KEY_VALUE, "my-host", strlen(buf[0]), buf[0],
		VICI_KEY_VALUE, "other-host", strlen(buf[1]), buf[1],
		VICI_END);
}

int sock_open_unix(const char *path)
{
	int ret, fd;
	struct sockaddr_un addr;

	fd = socket(AF_UNIX, SOCK_STREAM, 0);
	if (fd < 0)
		return -1;

	memset(&addr, 0, sizeof (struct sockaddr_un));
	addr.sun_family = AF_UNIX;
	strncpy(addr.sun_path, path, strlen (path));

	ret = connect(fd, (struct sockaddr *) &addr, sizeof(addr.sun_family) + strlen(addr.sun_path));
	if (ret < 0) {
		close(fd);
		return -1;
	}

	fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);

	return fd;
}
