/*
 * Modsecurity wrapper for haproxy
 *
 * This file contains the wrapper which sends data in ModSecurity
 * and returns the verdict.
 *
 * Copyright 2016 OZON, Thierry Fournier <thierry.fournier@ozon.io>
 *
 * 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; either version
 * 2 of the License, or (at your option) any later version.
 *
 */
#include <limits.h>
#include <stdio.h>
#include <stdarg.h>

#include <haproxy/hlua.h>
#include <haproxy/time.h>

#include <types/global.h>
#include <types/stream.h>

#include <haproxy/arg.h>
#include <proto/log.h>
#include <proto/spoe.h>

#include <api.h>

#include "modsec_wrapper.h"
#include "spoa.h"

static char host_name[60];

/* Note: The document and the code of "apr_table_make" considers
 * that this function doesn't fails. The Apache APR code says
 * other thing. If the system doesn't have any more memory, a
 * a segfault occurs :(. Be carrefull with this module.
 */

struct directory_config *modsec_config = NULL;
static server_rec *modsec_server = NULL;

struct apr_bucket_haproxy {
	apr_bucket_refcount refcount;
	char *buffer;
	size_t length;
};

static void haproxy_bucket_destroy(void *data)
{
	struct apr_bucket_haproxy *bucket = data;

	if (apr_bucket_shared_destroy(bucket))
		apr_bucket_free(bucket);
}

static apr_status_t haproxy_bucket_read(apr_bucket *bucket, const char **str,
                                        apr_size_t *len, apr_read_type_e block)
{
	struct apr_bucket_haproxy *data = bucket->data;

	if (bucket->start) {
		*str = NULL;
		*len = 0;
		return APR_SUCCESS;
	}

	*str = data->buffer;
	*len = data->length;
	bucket->start = 1; /* Just a flag to say that the read is started */

	return APR_SUCCESS;
}

static const apr_bucket_type_t apr_bucket_type_haproxy = {
	"HAProxy", 7, APR_BUCKET_DATA,
	haproxy_bucket_destroy,
	haproxy_bucket_read,
	apr_bucket_setaside_noop,
	apr_bucket_shared_split,
	apr_bucket_shared_copy
};

static char *chunk_strdup(struct request_rec *req, const char *str, size_t len)
{
	char *out;

	out = apr_pcalloc(req->pool, len + 1);
	if (!out)
		return NULL;
	memcpy(out, str, len);
	out[len] = '\0';
	return out;
}

static char *printf_dup(struct request_rec *req, char *fmt, ...)
{
	char *out;
	va_list ap;
	int len;

	va_start(ap, fmt);
	len = vsnprintf(NULL, 0, fmt, ap);
	va_end(ap);

	if (len == -1)
		return NULL;

	out = apr_pcalloc(req->pool, len + 1);
	if (!out)
		return NULL;

	va_start(ap, fmt);
	len = vsnprintf(out, len + 1, fmt, ap);
	va_end(ap);

	if (len == -1)
		return NULL;

	return out;
}

/* This function send logs. For now, it do nothing. */
static void modsec_log(void *obj, int level, char *str)
{
	LOG(&null_worker, "%s", str);
}

/* This function load the ModSecurity file. It returns -1 if the
 * initialisation fails.
 */
int modsecurity_load(const char *file)
{
	const char *msg;
	char cwd[128];

	/* Initialises modsecurity. */

	modsec_server = modsecInit();
	if (modsec_server == NULL) {
		LOG(&null_worker, "ModSecurity initialisation failed.\n");
		return -1;
	}

	modsecSetLogHook(NULL, modsec_log);

	gethostname(host_name, 60);
	modsec_server->server_hostname = host_name;

	modsecStartConfig();

	modsec_config = modsecGetDefaultConfig();
	if (modsec_config == NULL) {
		LOG(&null_worker, "ModSecurity default configuration initialisation failed.\n");
		return -1;
	}

	msg = modsecProcessConfig(modsec_config, file, getcwd(cwd, 128));
	if (msg != NULL) {
		LOG(&null_worker, "ModSecurity load configuration failed.\n");
		return -1;
	}

	modsecFinalizeConfig();

	modsecInitProcess();

	return 1;
}

struct modsec_hdr {
	const char *name;
	uint64_t name_len;
	const char *value;
	uint64_t value_len;
};

int modsecurity_process(struct worker *worker, struct modsecurity_parameters *params)
{
	struct conn_rec *cr;
	struct request_rec *req;
	struct apr_bucket_brigade *brigade;
	struct apr_bucket *link_bucket;
	struct apr_bucket_haproxy *data_bucket;
	struct apr_bucket *last_bucket;
	int i;
	long clength;
	char *err;
	int fail;
	const char *lang;
	char *name, *value;
	// int body_partial;
	struct timeval now;
	int ret;
	char *buf;
	char *end;
	const char *uniqueid;
	uint64_t uniqueid_len;
	const char *meth;
	uint64_t meth_len;
	const char *path;
	uint64_t path_len;
	const char *qs;
	uint64_t qs_len;
	const char *vers;
	uint64_t vers_len;
	const char *body;
	uint64_t body_len;
	uint64_t body_exposed_len;
	uint64_t hdr_nb;
	struct modsec_hdr hdrs[255];
	struct modsec_hdr hdr;
	int status;
	int return_code = -1;

	/* Decode uniqueid. */
	uniqueid = params->uniqueid.data.u.str.area;
	uniqueid_len = params->uniqueid.data.u.str.data;

	/* Decode method. */
	meth = params->method.data.u.str.area;
	meth_len = params->method.data.u.str.data;

	/* Decode path. */
	path = params->path.data.u.str.area;
	path_len = params->path.data.u.str.data;

	/* Decode query string. */
	qs = params->query.data.u.str.area;
	qs_len = params->query.data.u.str.data;

	/* Decode version. */
	vers = params->vers.data.u.str.area;
	vers_len = params->vers.data.u.str.data;

	/* Decode header binary block. */
	buf = params->hdrs_bin.data.u.str.area;
	end = buf + params->hdrs_bin.data.u.str.data;

	/* Decode each header. */
	hdr_nb = 0;
	while (1) {

		/* Initialise the storage struct. It is useless
		 * because the process fail if the struct is not
		 * fully filled. This init is just does in order
		 * to prevent bug after some improvements.
		 */
		memset(&hdr, 0, sizeof(hdr));

		/* Decode header name. */
		ret = decode_varint(&buf, end, &hdr.name_len);
		if (ret == -1)
			return -1;
		hdr.name = buf;
		buf += hdr.name_len;
		if (buf > end)
			return -1;

		/* Decode header value. */
		ret = decode_varint(&buf, end, &hdr.value_len);
		if (ret == -1)
			return -1;
		hdr.value = buf;
		buf += hdr.value_len;
		if (buf > end)
			return -1;

		/* Detect the end of the headers. */
		if (hdr.name_len == 0 && hdr.value_len == 0)
			break;

		/* Store the header. */
		if (hdr_nb < 255) {
			memcpy(&hdrs[hdr_nb], &hdr, sizeof(hdr));
			hdr_nb++;
		}
	}

	/* Decode body length. Note that the following control
	 * is just set for avoifing a gcc warning.
	 */
	body_exposed_len = (uint64_t)params->body_length.data.u.sint;
	if (body_exposed_len < 0)
		return -1;

	/* Decode body. */
	body = params->body.data.u.str.area;
	body_len = params->body.data.u.str.data;

	fail = 1;

	/* Init processing */

	cr = modsecNewConnection();
	req = modsecNewRequest(cr, modsec_config);

	/* Load request. */

	req->proxyreq = PROXYREQ_NONE;
	req->header_only = 0; /* May modified later */

	/* Copy header list. */

	for (i = 0; i < hdr_nb; i++) {
		name = chunk_strdup(req, hdrs[i].name, hdrs[i].name_len);
		if (!name) {
			errno = ENOMEM;
			goto fail;
		}
		value = chunk_strdup(req, hdrs[i].value, hdrs[i].value_len);
		if (!value) {
			errno = ENOMEM;
			goto fail;
		}
		apr_table_setn(req->headers_in, name, value);
	}

	/* Process special headers. */
	req->range = apr_table_get(req->headers_in, "Range");
	req->content_type = apr_table_get(req->headers_in, "Content-Type");
	req->content_encoding = apr_table_get(req->headers_in, "Content-Encoding");
	req->hostname = apr_table_get(req->headers_in, "Host");
	if (req->hostname != NULL) {
		req->parsed_uri.hostname = chunk_strdup(req, req->hostname, strlen(req->hostname));
	} else {
		req->parsed_uri.hostname = NULL;
	}

	lang = apr_table_get(req->headers_in, "Content-Languages");
	if (lang != NULL) {
		req->content_languages = apr_array_make(req->pool, 1, sizeof(const char *));
		*(const char **)apr_array_push(req->content_languages) = lang;
	}

	lang = apr_table_get(req->headers_in, "Content-Length");
	if (lang) {
		errno = 0;
		clength = strtol(lang, &err, 10);
		if (*err != '\0' || errno != 0 || clength < 0 || clength > INT_MAX) {
			errno = ERANGE;
			goto fail;
		}
		req->clength = clength;
	}

	/* Copy the first line of the request. */
	req->the_request = printf_dup(req, "%.*s %.*s%s%.*s %.*s",
	                              meth_len, meth,
	                              path_len, path,
	                              qs_len > 0 ? "?" : "",
	                              qs_len, qs,
	                              vers_len, vers);
	if (!req->the_request) {
		errno = ENOMEM;
		goto fail;
	}

	/* Copy the method. */
	req->method = chunk_strdup(req, meth, meth_len);
	if (!req->method) {
		errno = ENOMEM;
		goto fail;
	}

	/* Set the method number. */
	if (meth_len < 3) {
		errno = EINVAL;
		goto fail;
	}

	/* Detect the method */
	switch (meth_len) {
	case 3:
		if (strncmp(req->method, "GET", 3) == 0)
			req->method_number = M_GET;
		else if (strncmp(req->method, "PUT", 3) == 0)
			req->method_number = M_PUT;
		else {
			errno = EINVAL;
			goto fail;
		}
		break;
	case 4:
		if (strncmp(req->method, "POST", 4) == 0)
			req->method_number = M_POST;
		else if (strncmp(req->method, "HEAD", 4) == 0) {
			req->method_number = M_GET;
			req->header_only = 1;
		}
		else if (strncmp(req->method, "COPY", 4) == 0)
			req->method_number = M_COPY;
		else if (strncmp(req->method, "MOVE", 4) == 0)
			req->method_number = M_MOVE;
		else if (strncmp(req->method, "LOCK", 4) == 0)
			req->method_number = M_LOCK;
		else {
			errno = EINVAL;
			goto fail;
		}
		break;
	case 5:
		if (strncmp(req->method, "TRACE", 5) == 0)
			req->method_number = M_TRACE;
		else if (strncmp(req->method, "PATCH", 5) == 0)
			req->method_number = M_PATCH;
		else if (strncmp(req->method, "MKCOL", 5) == 0)
			req->method_number = M_MKCOL;
		else if (strncmp(req->method, "MERGE", 5) == 0)
			req->method_number = M_MERGE;
		else if (strncmp(req->method, "LABEL", 5) == 0)
			req->method_number = M_LABEL;
		else {
			errno = EINVAL;
			goto fail;
		}
		break;
	case 6:
		if (strncmp(req->method, "DELETE", 6) == 0)
			req->method_number = M_DELETE;
		else if (strncmp(req->method, "REPORT", 6) == 0)
			req->method_number = M_REPORT;
		else if (strncmp(req->method, "UPDATE", 6) == 0)
			req->method_number = M_UPDATE;
		else if (strncmp(req->method, "UNLOCK", 6) == 0)
			req->method_number = M_UNLOCK;
		else {
			errno = EINVAL;
			goto fail;
		}
		break;
	case 7:
		if (strncmp(req->method, "CHECKIN", 7) == 0)
			req->method_number = M_CHECKIN;
		else if (strncmp(req->method, "INVALID", 7) == 0)
			req->method_number = M_INVALID;
		else if (strncmp(req->method, "CONNECT", 7) == 0)
			req->method_number = M_CONNECT;
		else if (strncmp(req->method, "OPTIONS", 7) == 0)
			req->method_number = M_OPTIONS;
		else {
			errno = EINVAL;
			goto fail;
		}
		break;
	case 8:
		if (strncmp(req->method, "PROPFIND", 8) == 0)
			req->method_number = M_PROPFIND;
		else if (strncmp(req->method, "CHECKOUT", 8) == 0)
			req->method_number = M_CHECKOUT;
		else {
			errno = EINVAL;
			goto fail;
		}
		break;
	case 9:
		if (strncmp(req->method, "PROPPATCH", 9) == 0)
			req->method_number = M_PROPPATCH;
		else {
			errno = EINVAL;
			goto fail;
		}
		break;
	case 10:
		if (strncmp(req->method, "MKACTIVITY", 10) == 0)
			req->method_number = M_MKACTIVITY;
		else if (strncmp(req->method, "UNCHECKOUT", 10) == 0)
			req->method_number = M_UNCHECKOUT;
		else {
			errno = EINVAL;
			goto fail;
		}
		break;
	case 11:
		if (strncmp(req->method, "MKWORKSPACE", 11) == 0)
			req->method_number = M_MKWORKSPACE;
		else {
			errno = EINVAL;
			goto fail;
		}
		break;
	case 15:
		if (strncmp(req->method, "VERSION_CONTROL", 15) == 0)
			req->method_number = M_VERSION_CONTROL;
		else {
			errno = EINVAL;
			goto fail;
		}
		break;
	case 16:
		if (strncmp(req->method, "BASELINE_CONTROL", 16) == 0)
			req->method_number = M_BASELINE_CONTROL;
		else {
			errno = EINVAL;
			goto fail;
		}
		break;
	default:
		errno = EINVAL;
		goto fail;
	}

	/* Copy the protocol. */
	req->protocol = chunk_strdup(req, vers, vers_len);
	if (!req->protocol) {
		errno = ENOMEM;
		goto fail;
	}

	/* Compute the protocol number. */
	if (vers_len >= 8)
		req->proto_num = 1000 + !!(vers[7] == '1');

	/* The request time. */
	gettimeofday(&now, NULL);
	req->request_time = apr_time_make(now.tv_sec, now.tv_usec / 1000);

	/* No status line. */
	req->status_line = NULL;
	req->status = 0;

	/* Copy path. */
	req->parsed_uri.path = chunk_strdup(req, path, path_len);
	if (!req->parsed_uri.path) {
		errno = ENOMEM;
		goto fail;
	}

	/* Copy args (query string). */
	req->args = chunk_strdup(req, qs, qs_len);
	if (!req->args) {
		errno = ENOMEM;
		goto fail;
	}

	/* Set parsed_uri */

	req->parsed_uri.scheme = "http";

	if (req->hostname && req->parsed_uri.scheme && req->parsed_uri.path) {
		i = snprintf(NULL, 0, "%s://%s%s",
		             req->parsed_uri.scheme, req->hostname, req->parsed_uri.path);
		req->uri = apr_pcalloc(req->pool, i + 1);
		if (!req->uri) {
			errno = ENOMEM;
			goto fail;
		}
		i = snprintf(req->uri, i + 1, "%s://%s%s",
		             req->parsed_uri.scheme, req->hostname, req->parsed_uri.path);
	}

	req->filename = req->parsed_uri.path;

	/* Set unique id */

	apr_table_setn(req->subprocess_env, "UNIQUE_ID", chunk_strdup(req, uniqueid, uniqueid_len));

	/*
	 *
	 * Load body.
	 *
	 */

	/* Create an empty bucket brigade */
	brigade = apr_brigade_create(req->pool, req->connection->bucket_alloc);
	if (!brigade) {
		errno = ENOMEM;
		goto fail;
	}

	/* Stores HTTP body available data in a bucket */
	data_bucket = apr_bucket_alloc(sizeof(*data_bucket), req->connection->bucket_alloc);
	if (!data_bucket) {
		errno = ENOMEM;
		goto fail;
	}
	data_bucket->buffer = (char *)body;
	data_bucket->length = body_len;

	/* Create linked bucket */
	link_bucket = apr_bucket_alloc(sizeof(*link_bucket), req->connection->bucket_alloc);
	if (!link_bucket) {
		errno = ENOMEM;
		goto fail;
	}
	APR_BUCKET_INIT(link_bucket); /* link */
	link_bucket->free = apr_bucket_free;
	link_bucket->list = req->connection->bucket_alloc;
	link_bucket = apr_bucket_shared_make(link_bucket, data_bucket, 0, body_len);
	link_bucket->type = &apr_bucket_type_haproxy;

	/* Insert the bucket at the end of the brigade. */
	APR_BRIGADE_INSERT_TAIL(brigade, link_bucket);

	/* Insert the last bucket. */
	last_bucket = apr_bucket_eos_create(req->connection->bucket_alloc);
	APR_BRIGADE_INSERT_TAIL(brigade, last_bucket);

	/* Declares the bucket brigade in modsecurity */
	modsecSetBodyBrigade(req, brigade);

	/*
	 *
	 * Process analysis.
	 *
	 */

	/* Process request headers analysis. */
	status = modsecProcessRequestHeaders(req);
	if (status != DECLINED && status != DONE)
		return_code = status;

	/* Process request body analysis. */
	status = modsecProcessRequestBody(req);
	if (status != DECLINED && status != DONE)
		return_code = status;

	/* End processing. */

	fail = 0;
	if (return_code == -1)
		return_code = 0;

fail:

	modsecFinishRequest(req);
	modsecFinishConnection(cr);

	if (fail) {

		/* errno == ERANGE / ENOMEM / EINVAL */
		switch (errno) {
		case ERANGE: LOG(worker, "Invalid range");
		case ENOMEM: LOG(worker, "Out of memory error");
		case EINVAL: LOG(worker, "Invalid value");
		default:     LOG(worker, "Unknown error");
		}
	}

	return return_code;
}
