/*
 * User authentication & authorization
 *
 * Copyright 2010 Krzysztof Piotr Oledzki <ole@ans.pl>
 *
 * 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.
 *
 */

#ifdef CONFIG_HAP_CRYPT
/* This is to have crypt() defined on Linux */
#define _GNU_SOURCE

#ifdef NEED_CRYPT_H
/* some platforms such as Solaris need this */
#include <crypt.h>
#endif
#endif /* CONFIG_HAP_CRYPT */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <common/config.h>

#include <proto/acl.h>
#include <proto/log.h>

#include <types/auth.h>

struct userlist *userlist = NULL;    /* list of all existing userlists */

/* find targets for selected gropus. The function returns pointer to
 * the userlist struct ot NULL if name is NULL/empty or unresolvable.
 */

struct userlist *
auth_find_userlist(char *name)
{
	struct userlist *l;

	if (!name || !*name)
		return NULL;

	for (l = userlist; l; l = l->next)
		if (!strcmp(l->name, name))
			return l;

	return NULL;
}

/* find group_mask for selected gropus. The function returns 1 if OK or nothing to do,
 * 0 if case of unresolved groupname.
 * WARING: the function destroys the list (strtok), so it can only be used once.
 */

unsigned int
auth_resolve_groups(struct userlist *l, char *groups)
{

	char *group = NULL;
	unsigned int g, group_mask = 0;

	if (!groups || !*groups)
		return 0;

	while ((group = strtok(group?NULL:groups," "))) {
		for (g = 0; g < l->grpcnt; g++)
			if (!strcmp(l->groups[g], group))
				break;

		if (g == l->grpcnt) {
			Alert("No such group '%s' in userlist '%s'.\n",
				group, l->name);
			return 0;
		}

		group_mask |= (1 << g);
	}

	return group_mask;
}

struct req_acl_rule *
parse_auth_cond(const char **args, const char *file, int linenum, struct proxy *proxy)
{
	struct req_acl_rule *req_acl;
	int cur_arg;

	req_acl = (struct req_acl_rule*)calloc(1, sizeof(struct req_acl_rule));
	if (!req_acl) {
		Alert("parsing [%s:%d]: out of memory.\n", file, linenum);
		return NULL;
	}

	if (!*args[0]) {
		goto req_error_parsing;
	} else if (!strcmp(args[0], "allow")) {
		req_acl->action = PR_REQ_ACL_ACT_ALLOW;
		cur_arg = 1;
	} else if (!strcmp(args[0], "deny")) {
		req_acl->action = PR_REQ_ACL_ACT_DENY;
		cur_arg = 1;
	} else if (!strcmp(args[0], "auth")) {
		req_acl->action = PR_REQ_ACL_ACT_HTTP_AUTH;
		cur_arg = 1;

		while(*args[cur_arg]) {
			if (!strcmp(args[cur_arg], "realm")) {
				req_acl->http_auth.realm = strdup(args[cur_arg + 1]);
				cur_arg+=2;
				continue;
			} else
				break;
		}
	} else {
req_error_parsing:
		Alert("parsing [%s:%d]: %s '%s', expects 'allow', 'deny', 'auth'.\n",
			file, linenum, *args[1]?"unknown parameter":"missing keyword in", args[*args[1]?1:0]);
		return NULL;
	}

	if (strcmp(args[cur_arg], "if") == 0 || strcmp(args[cur_arg], "unless") == 0) {
		struct acl_cond *cond;

		if ((cond = build_acl_cond(file, linenum, proxy, args+cur_arg)) == NULL) {
			Alert("parsing [%s:%d] : error detected while parsing an 'http-request %s' condition.\n",
			      file, linenum, args[0]);
			return NULL;
		}
		req_acl->cond = cond;
	}
	else if (*args[cur_arg]) {
		Alert("parsing [%s:%d]: 'http-request %s' expects 'realm' for 'auth' or"
		      " either 'if' or 'unless' followed by a condition but found '%s'.\n",
		      file, linenum, args[0], args[cur_arg]);
		return NULL;
	}

	return req_acl;
}

void
userlist_free(struct userlist *ul)
{
	struct userlist *tul;
	struct auth_users *au, *tau;
	int i;

	while (ul) {
		au = ul->users;
		while (au) {
			tau = au;
			au = au->next;
			free(tau->user);
			free(tau->pass);
			free(tau);
		}

		tul = ul;
		ul = ul->next;

		for (i = 0; i < tul->grpcnt; i++)
			free(tul->groups[i]);

		free(tul->name);
		free(tul);
	};
}

void
req_acl_free(struct list *r) {
	struct req_acl_rule *tr, *pr;

	list_for_each_entry_safe(pr, tr, r, list) {
		LIST_DEL(&pr->list);
		if (pr->action == PR_REQ_ACL_ACT_HTTP_AUTH)
			free(pr->http_auth.realm);

		free(pr);
	}
}

/*
 * Authenticate and authorize user; return 1 if OK, 0 if case of error.
 */
int
check_user(struct userlist *ul, unsigned int group_mask, const char *user, const char *pass)
{

	struct auth_users *u;
	const char *ep;

#ifdef DEBUG_AUTH
	fprintf(stderr, "req: userlist=%s, user=%s, pass=%s, group_mask=%u\n",
		ul->name, user, pass, group_mask);
#endif

	for (u = ul->users; u; u = u->next)
		if (!strcmp(user, u->user))
			break;

	if (!u)
		return 0;

#ifdef DEBUG_AUTH
	fprintf(stderr, "cfg: user=%s, pass=%s, group_mask=%u, flags=%X",
		u->user, u->pass, u->group_mask, u->flags);
#endif

	/*
	 * if user matches but group does not,
	 * it makes no sens to check passwords
	 */
	if (group_mask && !(group_mask & u->u.group_mask))
		return 0;

	if (!(u->flags & AU_O_INSECURE)) {
#ifdef CONFIG_HAP_CRYPT
		ep = crypt(pass, u->pass);
#else
		return 0;
#endif
	} else
		ep = pass;

#ifdef DEBUG_AUTH
	fprintf(stderr, ", crypt=%s\n", ep);
#endif

	if (!strcmp(ep, u->pass))
		return 1;
	else
		return 0;
}

int
acl_match_auth(struct acl_test *test, struct acl_pattern *pattern)
{

	struct userlist *ul = test->ctx.a[0];
	char *user = test->ctx.a[1];
	char *pass = test->ctx.a[2];
	unsigned int group_mask;

	if (pattern)
		group_mask = pattern->val.group_mask;
	else
		group_mask = 0;

	if (check_user(ul, group_mask, user, pass))
		return ACL_PAT_PASS;
	else
		return ACL_PAT_FAIL;
}
