/*
 * Mod Defender for HAProxy
 *
 * Copyright 2017 HAProxy Technologies, Dragan Dosen <ddosen@haproxy.com>
 *
 * Mod Defender
 * Copyright (c) 2017 Annihil (https://github.com/VultureProject/mod_defender)
 *
 * Parts of code based on Apache HTTP Server source
 * Copyright 2015 The Apache Software Foundation (http://www.apache.org/)
 *
 * 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
 * 3 of the License, or (at your option) any later version.
 *
 */
#include <limits.h>
#include <stdio.h>
#include <stdarg.h>

#include <common/defaults.h>
#include <common/standard.h>
#include <common/chunk.h>
#include <common/time.h>

#include <proto/spoe.h>

#include <http_core.h>
#include <http_main.h>
#include <http_log.h>
#include <http_request.h>

#include <apr_pools.h>
#include <apr_strings.h>

#include "spoa.h"
#include "standalone.h"
#include "defender.h"

#define DEFENDER_NAME "defender"
#define DEFENDER_INPUT_FILTER "DEFENDER_IN"
#define DEFENDER_DEFAULT_UNIQUE_ID "unique_id"
#define DEFENDER_BRIGADE_REQUEST "defender-brigade-request"

extern module AP_MODULE_DECLARE_DATA defender_module;

DECLARE_HOOK(int,post_config,(apr_pool_t *pconf,apr_pool_t *plog, apr_pool_t *ptemp,server_rec *s))
DECLARE_HOOK(int,fixups,(request_rec *r))
DECLARE_HOOK(int,header_parser,(request_rec *r))

char *defender_name = DEFENDER_NAME;
const char *defender_argv[] = { DEFENDER_NAME, NULL };
const char *defender_unknown_hostname = "";

void *defender_module_config = NULL;
static server_rec *server = NULL;
apr_pool_t *defender_pool = NULL;

char hostname[MAX_HOSTNAME_LEN];
char defender_cwd[MAXPATHLEN];

static apr_status_t defender_bucket_read(apr_bucket *b, const char **str,
                                         apr_size_t *len, apr_read_type_e block);
static void defender_bucket_destroy(void *data);

static const apr_bucket_type_t apr_bucket_type_defender = {
	"defender", 8, APR_BUCKET_DATA,
	defender_bucket_destroy,
	defender_bucket_read,
	apr_bucket_setaside_noop,
	apr_bucket_shared_split,
	apr_bucket_shared_copy
};

struct apr_bucket_defender {
	apr_bucket_refcount refcount;
	struct chunk buf;
};

static apr_status_t defender_bucket_read(apr_bucket *b, const char **str,
                                         apr_size_t *len, apr_read_type_e block)
{
	struct apr_bucket_defender *d = b->data;

	*str = d->buf.str;
	*len = d->buf.len;

	return APR_SUCCESS;
}

static void defender_bucket_destroy(void *data)
{
	struct apr_bucket_defender *d = data;

	if (apr_bucket_shared_destroy(d))
		apr_bucket_free(d);
}

static apr_bucket *defender_bucket_make(apr_bucket *b, const struct chunk *buf)
{
	struct apr_bucket_defender *d;

	d = apr_bucket_alloc(sizeof(*d), b->list);

	d->buf.str = buf->str;
	d->buf.len = buf->len;
	d->buf.size = 0;

	b = apr_bucket_shared_make(b, d, 0, buf->len);
	b->type = &apr_bucket_type_defender;
	return b;
}

static apr_bucket *defender_bucket_create(const struct chunk *buf,
                                          apr_bucket_alloc_t *list)
{
	apr_bucket *b = apr_bucket_alloc(sizeof(*b), list);

	APR_BUCKET_INIT(b);
	b->free = apr_bucket_free;
	b->list = list;
	return defender_bucket_make(b, buf);
}

static void defender_logger(int level, char *str)
{
	LOG(&null_worker, "%s", str);
}

static char *defender_strdup(apr_pool_t *pool, const char *src, uint64_t len)
{
	char *dst;

	if (!(dst = apr_pcalloc(pool, len + 1)))
		return NULL;

	memcpy(dst, src, len);
	dst[len] = '\0';

	return dst;
}

static char *defender_printf(apr_pool_t *pool, const char *fmt, ...)
{
	va_list argp;
	char *dst;
	int len;

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

	if (len < 0)
		return NULL;

	if (!(dst = apr_pcalloc(pool, len + 1)))
		return NULL;

	va_start(argp, fmt);
	len = vsnprintf(dst, len + 1, fmt, argp);
	va_end(argp);

	return dst;
}

static char *defender_addr2str(apr_pool_t *pool, struct sample *addr)
{
	sa_family_t family;
	const void *src;
	char *dst;

	switch (addr->data.type) {
	case SMP_T_IPV4:
		src = &addr->data.u.ipv4;
		family = AF_INET;
		break;
	case SMP_T_IPV6:
		src = &addr->data.u.ipv6;
		family = AF_INET6;
		break;
	default:
		return NULL;
	}

	if (!(dst = apr_pcalloc(pool, INET6_ADDRSTRLEN + 1)))
		return NULL;

	if (inet_ntop(family, src, dst, INET6_ADDRSTRLEN))
		return dst;

	return NULL;
}

static void defender_pre_config()
{
	apr_pool_t *ptemp = NULL;

	defender_module.module_index = 0;
	defender_module.register_hooks(defender_pool);

	apr_pool_create(&ptemp, defender_pool);
	run_ap_hook_post_config(defender_pool, defender_pool, ptemp, server);
	apr_pool_destroy(ptemp);
}

static const char *defender_read_config(const char *file)
{
	apr_pool_t *ptemp = NULL;
	const char *err;
	const char *fullname;

	defender_module_config = defender_module.create_dir_config(defender_pool, "/");
	if (defender_module_config == NULL) {
		return "cannot allocate space for the configuration structure";
	}

	apr_pool_create(&ptemp, defender_pool);

	fullname = ap_server_root_relative(ptemp, file);

	err = read_module_config(server, defender_module_config,
	                         defender_module.cmds,
	                         defender_pool, ptemp, fullname);

	apr_pool_destroy(ptemp);

    return err;
}

static void defender_post_config()
{
	apr_pool_t *ptemp = NULL;

	apr_pool_create(&ptemp, defender_pool);
	run_ap_hook_post_config(defender_pool, defender_pool, ptemp, server);
	apr_pool_destroy(ptemp);
}

static const char *defender_set_logger(const char *file)
{
	char *logname;

	logger = defender_logger;

	if (file == NULL)
		return NULL;

	logname = ap_server_root_relative(defender_pool, file);

	if (apr_file_open(&server->error_log, logname,
	                  APR_APPEND | APR_WRITE | APR_CREATE | APR_LARGEFILE,
	                  APR_OS_DEFAULT, defender_pool) != APR_SUCCESS) {
		return apr_pstrcat(defender_pool, "Cannot open log file, ",
		                   logname, NULL);
	}
	server->error_fname = logname;

	return NULL;
}

static apr_status_t defender_input_filter(ap_filter_t *f,
                                          apr_bucket_brigade *new_bb,
                                          ap_input_mode_t mode,
                                          apr_read_type_e block,
                                          apr_off_t readbytes)
{
	apr_bucket_brigade *bb = NULL;
	apr_bucket *b = NULL, *a = NULL;
	apr_status_t rv;

	bb = (apr_bucket_brigade *)apr_table_get(f->r->notes, DEFENDER_BRIGADE_REQUEST);

	if (bb == NULL || (bb && !APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(bb)))) {
		b = apr_bucket_eos_create(f->c->bucket_alloc);
		APR_BRIGADE_INSERT_TAIL(new_bb, b);
		if (bb == NULL)
			return APR_SUCCESS;
	}

	rv = apr_brigade_partition(bb, readbytes, &a);
	if (rv != APR_SUCCESS && rv != APR_INCOMPLETE)
		return rv;

	b = APR_BRIGADE_FIRST(bb);

	while (b != a) {
		if (APR_BUCKET_IS_EOS(b))
			ap_remove_input_filter(f);

		APR_BUCKET_REMOVE(b);
		APR_BRIGADE_INSERT_TAIL(new_bb, b);
		b = APR_BRIGADE_FIRST(bb);
	}

	return APR_SUCCESS;
}

static conn_rec *defender_create_conn()
{
	conn_rec *c = NULL;
	apr_pool_t *ptrans = NULL;

	apr_pool_create(&ptrans, defender_pool);

	c = apr_pcalloc(ptrans, sizeof(conn_rec));

	c->pool = ptrans;
	c->local_ip = "127.0.0.1";
	c->local_addr = server->addrs->host_addr;
	c->local_host = defender_name;
	c->client_addr = server->addrs->host_addr;
	c->remote_host = defender_name;

	c->id = 1;
	c->base_server = server;
	c->bucket_alloc = apr_bucket_alloc_create(ptrans);

	return c;
}

static request_rec *defender_create_request(conn_rec *conn)
{
	request_rec *r = NULL;
	apr_pool_t *p = NULL;
	struct ap_logconf *l;

	apr_pool_create(&p, conn->pool);

	r = apr_pcalloc(p, sizeof(request_rec));

	r->pool = p;
	r->connection = conn;
	r->server = conn->base_server;

	r->headers_in = apr_table_make(p, 25);
	r->headers_out = apr_table_make(p, 12);
	r->subprocess_env = apr_table_make(p, 25);
	r->err_headers_out = apr_table_make(p, 5);
	r->notes = apr_table_make(p, 5);

	r->request_config = apr_palloc(p, sizeof(void *));
	r->per_dir_config = apr_palloc(p, sizeof(void *));
	((void **)r->per_dir_config)[0] = defender_module_config;

	r->handler = defender_name;

	r->parsed_uri.scheme = "http";
	r->parsed_uri.is_initialized = 1;
	r->parsed_uri.port = 80;
	r->parsed_uri.port_str = "80";
	r->parsed_uri.fragment = "";

	r->input_filters = NULL;
	r->output_filters = NULL;

	l = apr_pcalloc(p, sizeof(struct ap_logconf));
	l->level = APLOG_DEBUG;
	r->log = l;

	return r;
}

static int defender_process_headers(request_rec *r)
{
	return run_ap_hook_header_parser(r);
}

static int defender_process_body(request_rec *r)
{
	ap_add_input_filter(DEFENDER_INPUT_FILTER, NULL, r, r->connection);
	return run_ap_hook_fixups(r);
}

int defender_init(const char *config_file, const char *log_file)
{
	apr_status_t rv;
	const char *msg;

	if (!config_file) {
		LOG(&null_worker, "Mod Defender configuration file not specified.\n");
		return 0;
	}

	apr_initialize();
	apr_pool_create(&defender_pool, NULL);
	apr_hook_global_pool = defender_pool;

	ap_server_root = getcwd(defender_cwd, APR_PATH_MAX);

	server = (server_rec *) apr_palloc(defender_pool, sizeof(server_rec));
	server->process = apr_palloc(defender_pool, sizeof(process_rec));
	server->process->argc = 1;
	server->process->argv = defender_argv;
	server->process->short_name = defender_name;
	server->process->pconf = defender_pool;
	server->process->pool = defender_pool;

	server->addrs = apr_palloc(defender_pool, sizeof(server_addr_rec));
	rv = apr_sockaddr_info_get(&server->addrs->host_addr,
	                           "127.0.0.1", APR_UNSPEC, 0, 0,
	                           defender_pool);
	if (rv != APR_SUCCESS) {
		LOG(&null_worker, "Mod Defender getaddrinfo failed.\n");
		return 0;
	}

	server->path = "/";
	server->pathlen = strlen(server->path);
	server->port = 0;
	server->server_admin = defender_name;
	server->server_scheme = "";
	server->error_fname = NULL;
	server->error_log = NULL;
	server->limit_req_line = DEFAULT_LIMIT_REQUEST_LINE;
	server->limit_req_fieldsize = DEFAULT_LIMIT_REQUEST_FIELDSIZE;
	server->limit_req_fields = DEFAULT_LIMIT_REQUEST_FIELDS;
	server->timeout = apr_time_from_sec(DEFAULT_TIMEOUT);

	memset(hostname, 0, sizeof(hostname));
	gethostname(hostname, sizeof(hostname) - 1);
	server->server_hostname = hostname;

	server->addrs->host_port = 0;
	server->names = server->wild_names = NULL;
	server->is_virtual = 0;

	server->lookup_defaults = NULL;
	server->module_config = NULL;

	msg = defender_set_logger(log_file);
	if (msg != NULL) {
		LOG(&null_worker, "Mod Defender init failed: %s\n", msg);
		return 0;
	}

	ap_register_input_filter(DEFENDER_INPUT_FILTER, defender_input_filter,
	                         NULL, AP_FTYPE_RESOURCE);

	defender_pre_config();

	msg = defender_read_config(config_file);
	if (msg != NULL) {
		LOG(&null_worker, "Mod Defender configuration failed: %s\n", msg);
		return 0;
	}

	defender_post_config();

	return 1;
}

int defender_process_request(struct worker *worker, struct defender_request *request)
{
	struct conn_rec *c = NULL;
	struct request_rec *r = NULL;

	struct apr_bucket_brigade *bb = NULL;
	struct apr_bucket *d = NULL, *e = NULL;

	struct chunk *method;
	struct chunk *path;
	struct chunk *query;
	struct chunk *version;
	struct chunk *body;

	struct defender_header hdr;
	char *hdr_ptr, *hdr_end;

	const char *ptr;

	int status = DECLINED;

	if (!(c = defender_create_conn()))
		goto out;

	if (!(r = defender_create_request(c)))
		goto out;

	/* request */
	r->request_time = apr_time_now();

	if (request->clientip.data.type != SMP_T_IPV4 &&
	    request->clientip.data.type != SMP_T_IPV6)
		goto out;

	if (!(r->useragent_ip = defender_addr2str(r->pool, &request->clientip)))
		goto out;

	if (request->id.data.u.str.str && request->id.data.u.str.len > 0) {
		apr_table_setn(r->subprocess_env, "UNIQUE_ID",
		               defender_strdup(r->pool, request->id.data.u.str.str,
		                               request->id.data.u.str.len));
	}
	else {
		apr_table_setn(r->subprocess_env, "UNIQUE_ID",
		               DEFENDER_DEFAULT_UNIQUE_ID);
	}

	method = &request->method.data.u.str;
	path = &request->path.data.u.str;
	query = &request->query.data.u.str;
	version = &request->version.data.u.str;

	r->method_number = lookup_builtin_method(method->str, method->len);
	if (!(r->method = defender_strdup(r->pool, method->str, method->len)))
		goto out;

	r->unparsed_uri = defender_printf(r->pool, "%.*s%s%.*s",
	                                  path->len, path->str,
	                                  query->len > 0 ? "?" : "",
	                                  query->len, query->str);
	if (!r->unparsed_uri)
		goto out;

	if (!(r->uri = defender_strdup(r->pool, path->str, path->len)))
		goto out;

	r->parsed_uri.path = r->filename = r->uri;

	if (!(r->args = defender_strdup(r->pool, query->str, query->len)))
		goto out;

	r->parsed_uri.query = r->args;

	r->protocol = defender_printf(r->pool, "%s%.*s",
	                              version->len > 0 ? "HTTP/" : "",
	                              version->len, version->str);
	if (!r->protocol)
		goto out;

	r->the_request = defender_printf(r->pool, "%.*s %s%s%s",
	                                 method->len, method->str,
	                                 r->unparsed_uri,
	                                 version->len > 0 ? " " : "",
	                                 r->protocol);
	if (!r->the_request)
		goto out;

	/* headers */
	if (request->headers.data.type != SMP_T_BIN)
		goto misc;

	hdr_ptr = request->headers.data.u.str.str;
	hdr_end = hdr_ptr + request->headers.data.u.str.len;

	while (1) {
		memset(&hdr, 0, sizeof(hdr));

		if (decode_varint(&hdr_ptr, hdr_end, &hdr.name.len) == -1)
			goto out;
		if (!(hdr.name.str = defender_strdup(r->pool, hdr_ptr, hdr.name.len)))
			goto out;

		hdr_ptr += hdr.name.len;
		if (hdr_ptr > hdr_end)
			goto out;

		if (decode_varint(&hdr_ptr, hdr_end, &hdr.value.len) == -1)
			goto out;
		if (!(hdr.value.str = defender_strdup(r->pool, hdr_ptr, hdr.value.len)))
			goto out;

		hdr_ptr += hdr.value.len;
		if (hdr_ptr > hdr_end)
			goto out;

		if (!hdr.name.len && !hdr.value.len)
			break;

		apr_table_setn(r->headers_in, hdr.name.str, hdr.value.str);
	}

misc:

	r->hostname = apr_table_get(r->headers_in, "Host");
	if (!r->hostname)
		r->hostname = defender_unknown_hostname;
	r->parsed_uri.hostname = (char *)r->hostname;

	r->content_type = apr_table_get(r->headers_in, "Content-Type");
	r->content_encoding = apr_table_get(r->headers_in, "Content-Encoding");
	ptr = apr_table_get(r->headers_in, "Content-Length");
	if (ptr)
		r->clength = strtol(ptr, NULL, 10);

	/* body */
	body = &request->body.data.u.str;

	bb = apr_brigade_create(r->pool, c->bucket_alloc);
	if (bb == NULL)
		goto out;

	d = defender_bucket_create(body, c->bucket_alloc);
	if (d == NULL)
		goto out;

	APR_BRIGADE_INSERT_TAIL(bb, d);

	e = apr_bucket_eos_create(c->bucket_alloc);
	APR_BRIGADE_INSERT_TAIL(bb, e);

	apr_table_setn(r->notes, DEFENDER_BRIGADE_REQUEST, (char *)bb);

	/* process */
	status = defender_process_headers(r);

	if (status == DECLINED)
		status = defender_process_body(r);

	apr_brigade_cleanup(bb);

	/* success */
	if (status == DECLINED)
		status = OK;

out:

	if (r && r->pool) {
		apr_table_clear(r->headers_in);
		apr_table_clear(r->headers_out);
		apr_table_clear(r->subprocess_env);
		apr_table_clear(r->err_headers_out);
		apr_table_clear(r->notes);
		apr_pool_destroy(r->pool);
	}

	if (c && c->pool) {
		apr_bucket_alloc_destroy(c->bucket_alloc);
		apr_pool_destroy(c->pool);
	}

	return status;
}
