/*
 * 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 <stdio.h>
#include <stdarg.h>

#include <haproxy/api.h>
#include <haproxy/chunk.h>
#include <haproxy/spoe.h>
#include <haproxy/time.h>
#include <haproxy/tools.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 buffer 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.area;
	*len = d->buf.data;

	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 buffer *buf)
{
	struct apr_bucket_defender *d;

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

	d->buf.area = buf->area;
	d->buf.data = buf->data;
	d->buf.size = 0;

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

static apr_bucket *defender_bucket_create(const struct buffer *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 buffer *method;
	struct buffer *path;
	struct buffer *query;
	struct buffer *version;
	struct buffer *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.area && request->id.data.u.str.data > 0) {
		apr_table_setn(r->subprocess_env, "UNIQUE_ID",
		               defender_strdup(r->pool, request->id.data.u.str.area,
		                               request->id.data.u.str.data));
	}
	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->area, method->data);
	if (!(r->method = defender_strdup(r->pool, method->area, method->data)))
		goto out;

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

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

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

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

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

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

	r->the_request = defender_printf(r->pool, "%.*s %s%s%s",
	                                 method->data, method->area,
	                                 r->unparsed_uri,
	                                 version->data > 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.area;
	hdr_end = hdr_ptr + request->headers.data.u.str.data;

	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;
}
