/*
 * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com>
 * All rights reserved
 *
 * "THE BEER-WARE LICENSE" (Revision 42):
 * Sergey Lyubka wrote this file.  As long as you retain this notice you
 * can do whatever you want with this stuff. If we meet some day, and you think
 * this stuff is worth it, you can buy me a beer in return.
 */

#include "shttpd_defs.h"
#include "wsmand-daemon.h"

/*
 * Configuration parameters setters
 */
static void
set_int(struct shttpd_ctx *ctx, void *ptr, const char *string)
{
	ctx = NULL;	/* Unused */
	* (int *) ptr = atoi(string);
}

static void
set_str(struct shttpd_ctx *ctx, void *ptr, const char *string)
{
	ctx = NULL;	/* Unused */
	* (char **) ptr = strdup(string);
}

static void
set_log_file(struct shttpd_ctx *ctx, void *ptr, const char *string)
{
	FILE	**fp = ptr;
	ctx = NULL;

	if ((*fp = fopen(string, "a")) == NULL)
		elog(E_FATAL, NULL, "cannot open log file %s: %s",
		    string, strerror(errno));
}

static int isbyte(int n) { return (n >= 0 && n <= 255); }

static void
set_acl(struct shttpd_ctx *ctx, void *ptr, const char *s)
{
	struct llhead	*head = ptr;
	struct acl	*acl;
	char		flag;
	int		len, a, b, c, d, n, mask;

	ctx = NULL;

	FOR_EACH_WORD_IN_LIST(s, len) {

		mask = 32;

		if (sscanf(s, "%c%d.%d.%d.%d%n",&flag,&a,&b,&c,&d,&n) != 5) {
			elog(E_FATAL, NULL, "[%s]: subnet must be "
			    "[+|-]x.x.x.x[/x]", s);
		} else if (flag != '+' && flag != '-') {
			elog(E_FATAL, NULL, "flag must be + or -: [%s]", s);
		} else if (!isbyte(a)||!isbyte(b)||!isbyte(c)||!isbyte(d)) {
			elog(E_FATAL, NULL, "bad ip address: [%s]", s);
		} else	if ((acl = malloc(sizeof(*acl))) == NULL) {
			elog(E_FATAL, NULL, "%s", "cannot malloc subnet");
		} else if (sscanf(s + n, "/%d", &mask) == 0) {
			/* Do nothing, no mask specified */
		} else if (mask < 0 || mask > 32) {
			elog(E_FATAL, NULL, "bad subnet mask: %d [%s]", n, s);
		}

		acl->ip = (a << 24) | (b << 16) | (c << 8) | d;
		acl->mask = mask ? 0xffffffffU << (32 - mask) : 0;
		acl->flag = flag;
		LL_TAIL(head, &acl->link);
	}
}

#ifndef NO_SSL
/*
 * Dynamically load SSL library. Set up ctx->ssl_ctx pointer.
 */
static void
set_ssl(struct shttpd_ctx *ctx, void *arg, const char *pem)
{
	SSL_CTX		*CTX;
	void		*lib;
	struct ssl_func	*fp;
        char *ssl_disabled_protocols = wsmand_options_get_ssl_disabled_protocols();

	arg = NULL;	/* Unused */

	/* Load SSL library dynamically */
	if ((lib = dlopen(SSL_LIB, RTLD_LAZY)) == NULL) {
		elog(E_FATAL, NULL, "set_ssl: cannot load %s", SSL_LIB);
                ctx->ssl_ctx = NULL;
                return;
        }

	for (fp = ssl_sw; fp->name != NULL; fp++) {
		if ((fp->ptr.v_void = dlsym(lib, fp->name)) == NULL) {
                        elog(E_FATAL, NULL,"set_ssl: cannot find %s", fp->name);
                  ctx->ssl_ctx = NULL;
                  return;
                }
        }

	/* Initialize SSL crap */
	static int ssl_library_initialized = 0;
	if(!ssl_library_initialized) {
		debug("Initialize SSL");
		SSL_library_init();
		ssl_library_initialized = 1;
	}
	if ((CTX = SSL_CTX_new(SSLv23_server_method())) == NULL) {
		elog(E_FATAL, NULL, "SSL_CTX_new error");
        }
        else if (wsmand_options_get_ssl_cert_file() && SSL_CTX_use_certificate_file(CTX, wsmand_options_get_ssl_cert_file(),SSL_FILETYPE_PEM) == 0) {
		elog(E_FATAL, NULL, "cannot open %s : %s", pem, strerror(errno));
                SSL_CTX_free(CTX);
                CTX = NULL;
        }
	else if (wsmand_options_get_ssl_key_file() && SSL_CTX_use_PrivateKey_file(CTX, wsmand_options_get_ssl_key_file(), SSL_FILETYPE_PEM) == 0) {
		elog(E_FATAL, NULL, "cannot open %s : %s", pem, strerror(errno));
                SSL_CTX_free(CTX);
                CTX = NULL;
        }
	while (ssl_disabled_protocols) {
          struct ctx_opts_t {
            char *name;
            long opt;
          } protocols[] = {
            { "SSLv2", SSL_OP_NO_SSLv2 },
            { "SSLv3", SSL_OP_NO_SSLv3 },
            { "TLSv1", SSL_OP_NO_TLSv1 },
# if OPENSSL_VERSION_NUMBER >= 0x10001000L
            { "TLSv1_1", SSL_OP_NO_TLSv1_1 },
            { "TLSv1_2", SSL_OP_NO_TLSv1_2 },
# endif
            { NULL, 0 }
          };
          char *blank_ptr;
          int idx;
          if (*ssl_disabled_protocols == 0)
            break;
          blank_ptr = strchr(ssl_disabled_protocols, ' ');
          if (blank_ptr == NULL)
            blank_ptr = ssl_disabled_protocols + strlen(ssl_disabled_protocols);
          for (idx = 0; protocols[idx].name ; ++idx) {
            if (strncasecmp(protocols[idx].name, ssl_disabled_protocols, blank_ptr-ssl_disabled_protocols) == 0) {
              debug("SSL: disable %s protocol", protocols[idx].name);
              SSL_CTX_ctrl(CTX, SSL_CTRL_OPTIONS, protocols[idx].opt, NULL);                      
              break;
            }
          }
          if (*blank_ptr == 0)
            break;
          ssl_disabled_protocols = blank_ptr + 1;          
        }

	ctx->ssl_ctx = CTX;
}
#endif /* NO_SSL */

static void
set_mime(struct shttpd_ctx *ctx, void *arg, const char *string)
{
	arg = NULL;
	set_mime_types(ctx, string);
}

#define	OFS(x)	offsetof(struct shttpd_ctx, x)
#define BOOL_OPT	"0|1"
const struct opt options[] = {
	{'d', "document_root", "Web root directory", set_str,
		OFS(document_root), "directory", NULL, OPT_DIR},
	{'i', "index_files", "Index files", set_str, OFS(index_files),
		"file_list", INDEX_FILES, OPT_ADVANCED},
	{'p', "listen_ports", "Listening ports", set_str,
		OFS(ports), "ports", LISTENING_PORTS, OPT_ADVANCED},
	{'D', "list_directories", "Directory listing", set_int,
		OFS(dirlist), BOOL_OPT, "1", OPT_BOOL | OPT_ADVANCED},
#ifndef NO_CGI
	{'c', "cgi_extensions", "CGI extensions", set_str,
		OFS(cgi_extensions), "ext_list", CGI_EXT, OPT_ADVANCED},
	{'C', "cgi_interpreter", "CGI interpreter", set_str,
		OFS(cgi_interpreter), "file", NULL, OPT_FILE | OPT_ADVANCED},
	{'V', "cgi_envvar", "CGI envir variables", set_str,
		OFS(cgi_vars), "X=Y,....", NULL, OPT_ADVANCED},
#endif /* NO_CGI */
#if !defined(NO_SSI)
	{'S', "ssi_extensions", "SSI extensions", set_str,
		OFS(ssi_extensions), "ext_list", SSI_EXT, OPT_ADVANCED},
#endif /* NO_SSI */
	{'N', "auth_realm", "Authentication realm", set_str,
		OFS(auth_realm), "auth_realm", REALM, OPT_ADVANCED},
	{'l', "access_log", "Access log file", set_log_file,
		OFS(access_log), "file", NULL, OPT_FILE | OPT_ADVANCED},
	{'e', "error_log", "Error log file", set_log_file,
		OFS(error_log), "file", NULL, OPT_FILE | OPT_ADVANCED},
	{'m', "mime_types", "Mime types file", set_mime,
		OFS(mime_file), "file", NULL, OPT_FILE | OPT_ADVANCED},
	{'P', "global_htpasswd", "Global passwords file", set_str,
		OFS(global_passwd_file), "file", NULL, OPT_FILE | OPT_ADVANCED},
#ifndef NO_SSL
	{'s', "ssl_certificate", "SSL certificate file", set_ssl,
		OFS(ssl_ctx), "pem_file", NULL, OPT_FILE | OPT_ADVANCED},
#endif /* NO_SSL */
	{'U', "put_auth", "PUT,DELETE auth file",set_str,
		OFS(put_auth_file), "file", NULL, OPT_FILE | OPT_ADVANCED},
	{'a', "aliases", "Aliases", set_str,
		OFS(aliases), "X=Y,...", NULL, OPT_ADVANCED},
	{'b', "io_buf_size", "IO buffer size", set_int, OFS(io_buf_size),
		"bytes", DFLT_IO_SIZ, OPT_INT | OPT_ADVANCED},
	{'x', "acl", "Allow/deny IP addresses/subnets", set_acl,
		OFS(acl), "acl_list", NULL, OPT_ADVANCED},
#ifdef _WIN32
	{'B', "auto_start", "Autostart with Windows", set_int,
		OFS(auto_start), BOOL_OPT, "1", OPT_BOOL},
#else
	{'I', "inetd_mode", "Inetd mode", set_int,
		OFS(inetd_mode), BOOL_OPT, NULL, OPT_BOOL	},
	{'u', "runtime_uid", "Run as user", set_str,
		OFS(uid), "user_name", NULL, 0		},
#endif /* _WIN32 */
	{0,   NULL, NULL, NULL, 0, NULL, NULL, 0	}
};

static const struct opt *
find_option(int sw, const char *name)
{
	const struct opt	*opt;

	for (opt = options; opt->sw != 0; opt++)
		if (sw == opt->sw || (name && strcmp(opt->name, name) == 0))
			return (opt);

	return (NULL);
}

static void
set_option(const struct opt *opt, const char *val, char **tmpvars)
{
	tmpvars += opt - options;

	if (*tmpvars != NULL)
		free(*tmpvars);

	*tmpvars = strdup(val);
}

/*
 * Initialize shttpd context
 */
static void
initialize_context(struct shttpd_ctx *ctx, const char *config_file,
		int argc, char *argv[], char **tmpvars)
{
	char			line[FILENAME_MAX], root[FILENAME_MAX],
					var[sizeof(line)], val[sizeof(line)];
	const char		*arg;
	size_t			i;
	const struct opt	*opt;
	FILE 			*fp;
	struct tm		*tm;

	current_time = time(NULL);
	tm = localtime(&current_time);
	tz_offset = 0;
#if 0
	tm->tm_gmtoff - 3600 * (tm->tm_isdst > 0 ? 1 : 0);
#endif

	(void) memset(ctx, 0, sizeof(*ctx));

	ctx->start_time = current_time;
	InitializeCriticalSection(&ctx->mutex);

	LL_INIT(&ctx->connections);
	LL_INIT(&ctx->mime_types);
	LL_INIT(&ctx->registered_uris);
	LL_INIT(&ctx->uri_auths);
	LL_INIT(&ctx->error_handlers);
	LL_INIT(&ctx->acl);

#if !defined(NO_SSI)
	LL_INIT(&ctx->ssi_funcs);
#endif /* NO_SSI */

	/* First pass: set the defaults */
	for (opt = options; opt->sw != 0; opt++)
		if (tmpvars[opt - options] == NULL && opt->def != NULL)
			tmpvars[opt - options] = strdup(opt->def);

	/* Second pass: load config file  */
	if (config_file != NULL && (fp = fopen(config_file, "r")) != NULL) {
		DBG(("init_ctx: config file %s", config_file));

		/* Loop through the lines in config file */
		while (fgets(line, sizeof(line), fp) != NULL) {

			/* Skip comments and empty lines */
			if (line[0] == '#' || line[0] == '\n')
				continue;

			/* Trim trailing newline character */
			line[strlen(line) - 1] = '\0';

			if (sscanf(line, "%s %[^#\n]", var, val) != 2)
				elog(E_FATAL,0,"init_ctx: bad line: [%s]",line);

			if ((opt = find_option(0, var)) == NULL)
				elog(E_FATAL, NULL,
				    "set_option: unknown variable [%s]", var);
			set_option(opt, val, tmpvars);
		}
		(void) fclose(fp);
	}

	/* Third pass: process command line args */
	for (i = 1; i < (size_t) argc && argv[i][0] == '-'; i++)
		if ((opt = find_option(argv[i][1], NULL)) != NULL) {
			arg = argv[i][2] ? &argv[i][2] : argv[++i];

			if (arg == NULL)
				usage(argv[0]);

			set_option(opt, arg, tmpvars);
		} else {
			usage(argv[0]);
		}

	/* Call setters functions now */
	for (i = 0; i < NELEMS(options); i++)
		if (tmpvars[i] != NULL) {
			options[i].setter(ctx,
			    ((char *) ctx) + options[i].ofs, tmpvars[i]);
			free(tmpvars[i]);
		}

	/* If document_root is not set, set it to current directory */
	if (ctx->document_root == NULL) {
		(void) my_getcwd(root, sizeof(root));
		ctx->document_root = strdup(root);
	}

#ifdef _WIN32
	{WSADATA data;	WSAStartup(MAKEWORD(2,2), &data);}
#endif /* _WIN32 */

	DBG(("init_ctx: initialized context %p", (void *) ctx));
}

/*
 * Show usage string and exit.
 */
void
usage(const char *prog)
{
	const struct opt	*opt;

	(void) fprintf(stderr,
	    "SHTTPD version %s (c) Sergey Lyubka\n"
	    "usage: %s [OPTIONS] [config_file]\n"
	    "Note: config line keyword for every option is in the "
	    "round brackets\n", VERSION, prog);

#if !defined(NO_AUTH)
	(void) fprintf(stderr, "-A <htpasswd_file> <realm> <user> <passwd>\n");
#endif /* NO_AUTH */

	for (opt = options; opt->name != NULL; opt++)
		(void) fprintf(stderr, "-%c <%s>\t\t%s (%s)\n",
		    opt->sw, opt->arg, opt->desc, opt->name);

	exit(EXIT_FAILURE);
}

struct shttpd_ctx *
init_from_argc_argv(const char *config_file, int argc, char *argv[])
{
	struct shttpd_ctx	*ctx;
	char			*tmpvars[NELEMS(options)];
	size_t			i;

	/* Initialize all temporary holders to NULL */
	for (i = 0; i < NELEMS(tmpvars); i++)
		tmpvars[i] = NULL;

	if ((ctx = malloc(sizeof(*ctx))) != NULL)
		initialize_context(ctx, config_file, argc, argv, tmpvars);

	return (ctx);
}

struct shttpd_ctx *
shttpd_init(const char *config_file, ...)
{
	struct shttpd_ctx	*ctx;
	va_list			ap;
	const char		*opt_name, *opt_value;
	char			*tmpvars[NELEMS(options)];
	const struct opt	*opt;
	size_t			i;

	elog(E_LOG, NULL, "Initializing http server");
	/* Initialize all temporary holders to NULL */
	for (i = 0; i < NELEMS(tmpvars); i++)
		tmpvars[i] = NULL;

	if ((ctx = malloc(sizeof(*ctx))) != NULL) {

		va_start(ap, config_file);
		while ((opt_name = va_arg(ap, const char *)) != NULL) {
			opt_value = va_arg(ap, const char *);

			if ((opt = find_option(0, opt_name)) == NULL)
				elog(E_FATAL, NULL, "shttpd_init: "
				    "unknown variable [%s]", opt_name);
			set_option(opt, opt_value, tmpvars);
		}
		va_end(ap);

		initialize_context(ctx, config_file, 0, NULL, tmpvars);
	}

	return (ctx);
}
