/*
 * URI-based user authentication using the HTTP basic method.
 *
 * Copyright 2006 Willy Tarreau <w@1wt.eu>
 *
 * 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 <stdlib.h>
#include <string.h>

#include <common/base64.h>
#include <common/config.h>
#include <common/uri_auth.h>


/*
 * Initializes a basic uri_auth structure header and returns a pointer to it.
 * Uses the pointer provided if not NULL and not initialized.
 */
struct uri_auth *stats_check_init_uri_auth(struct uri_auth **root)
{
	struct uri_auth *u;

	if (!root || !*root) {
		if ((u = (struct uri_auth *)calloc(1, sizeof (*u))) == NULL)
			goto out_u;
	} else
		u = *root;

	if (!u->uri_prefix) {
		u->uri_len = strlen(STATS_DEFAULT_URI);
		if ((u->uri_prefix = strdup(STATS_DEFAULT_URI)) == NULL)
			goto out_uri;
	}

	if (!u->auth_realm)
		if ((u->auth_realm = strdup(STATS_DEFAULT_REALM)) == NULL)
			goto out_realm;

	if (root && !*root)
		*root = u;

	return u;

 out_realm:
	free(u->uri_prefix);
 out_uri:
	if (!root || !*root)
		free(u);
 out_u:
	return NULL;
}

/*
 * Returns a default uri_auth with <uri> set as the uri_prefix.
 * Uses the pointer provided if not NULL and not initialized.
 */
struct uri_auth *stats_set_uri(struct uri_auth **root, char *uri)
{
	struct uri_auth *u;
	char *uri_copy;
	int uri_len;

	uri_len  = strlen(uri);
	if ((uri_copy = strdup(uri)) == NULL)
		goto out_uri;
	
	if ((u = stats_check_init_uri_auth(root)) == NULL)
		goto out_u;
	
	if (u->uri_prefix)
		free(u->uri_prefix);

	u->uri_len = uri_len;
	u->uri_prefix = uri_copy;
	return u;

 out_u:
	free(uri_copy);
 out_uri:
	return NULL;
}

/*
 * Returns a default uri_auth with <realm> set as the realm.
 * Uses the pointer provided if not NULL and not initialized.
 */
struct uri_auth *stats_set_realm(struct uri_auth **root, char *realm)
{
	struct uri_auth *u;
	char *realm_copy;

	if ((realm_copy = strdup(realm)) == NULL)
		goto out_realm;
	
	if ((u = stats_check_init_uri_auth(root)) == NULL)
		goto out_u;
	
	if (u->auth_realm)
		free(u->auth_realm);

	u->auth_realm = realm_copy;
	return u;

 out_u:
	free(realm_copy);
 out_realm:
	return NULL;
}

/*
 * Returns a default uri_auth with a <user:passwd> entry added to the list of
 * authorized users. If a matching entry is found, no update will be performed.
 * Uses the pointer provided if not NULL and not initialized.
 */
struct uri_auth *stats_add_auth(struct uri_auth **root, char *auth)
{
	struct uri_auth *u;
	char *auth_base64;
	int alen, blen;
	struct user_auth *users, **ulist;

	alen = strlen(auth);
	blen = ((alen + 2) / 3) * 4;

	if ((auth_base64 = (char *)calloc(1, blen + 1)) == NULL)
		goto out_ubase64;

	/* convert user:passwd to base64. It should return exactly blen */
	if (a2base64(auth, alen, auth_base64, blen + 1) != blen)
		goto out_base64;

	if ((u = stats_check_init_uri_auth(root)) == NULL)
		goto out_base64;

	ulist = &u->users;
	while ((users = *ulist)) {
		if (!strcmp(users->user_pwd, auth_base64))
			break;
		ulist = &users->next;
	}

	if (!users) {
		if ((users = (struct user_auth *)calloc(1, sizeof(*users))) == NULL)
			goto out_u;
		*ulist = users;
		users->user_pwd = auth_base64;
		users->user_len = blen;
	}
	return u;

 out_u:
	free(u);
 out_base64:
	free(auth_base64);
 out_ubase64:
	return NULL;
}

/*
 * Returns a default uri_auth with a <scope> entry added to the list of
 * allowed scopes. If a matching entry is found, no update will be performed.
 * Uses the pointer provided if not NULL and not initialized.
 */
struct uri_auth *stats_add_scope(struct uri_auth **root, char *scope)
{
	struct uri_auth *u;
	char *new_name;
	struct stat_scope *old_scope, **scope_list;

	if ((u = stats_check_init_uri_auth(root)) == NULL)
		goto out;

	scope_list = &u->scope;
	while ((old_scope = *scope_list)) {
		if (!strcmp(old_scope->px_id, scope))
			break;
		scope_list = &old_scope->next;
	}

	if (!old_scope) {
		if ((new_name = strdup(scope)) == NULL)
			goto out_u;

		if ((old_scope = (struct stat_scope *)calloc(1, sizeof(*old_scope))) == NULL)
			goto out_name;

		old_scope->px_id = new_name;
		old_scope->px_len = strlen(new_name);
		*scope_list = old_scope;
	}
	return u;

 out_name:
	free(new_name);
 out_u:
	free(u);
 out:
	return NULL;
}

