diff options
Diffstat (limited to 'src/uri_auth.c')
-rw-r--r-- | src/uri_auth.c | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/src/uri_auth.c b/src/uri_auth.c new file mode 100644 index 0000000..db7e6c6 --- /dev/null +++ b/src/uri_auth.c @@ -0,0 +1,318 @@ +/* + * URI-based user authentication using the HTTP basic method. + * + * Copyright 2006-2007 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 <haproxy/api.h> +#include <haproxy/base64.h> +#include <haproxy/errors.h> +#include <haproxy/list.h> +#include <haproxy/stats-t.h> +#include <haproxy/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 = calloc(1, sizeof (*u))) == NULL) + goto out_u; + + LIST_INIT(&u->http_req_rules); + LIST_INIT(&u->admin_rules); + } 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 (root && !*root) + *root = u; + + return u; + + 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; + + free(u->uri_prefix); + u->uri_prefix = uri_copy; + u->uri_len = uri_len; + 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; + + 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 STAT_SHNODE flag enabled and + * <node> set as the name if it is not empty. + * Uses the pointer provided if not NULL and not initialized. + */ +struct uri_auth *stats_set_node(struct uri_auth **root, char *name) +{ + struct uri_auth *u; + char *node_copy = NULL; + + if (name && *name) { + node_copy = strdup(name); + if (node_copy == NULL) + goto out_realm; + } + + if ((u = stats_check_init_uri_auth(root)) == NULL) + goto out_u; + + if (!stats_set_flag(root, STAT_SHNODE)) + goto out_u; + + if (node_copy) { + free(u->node); + u->node = node_copy; + } + + return u; + + out_u: + free(node_copy); + out_realm: + return NULL; +} + +/* + * Returns a default uri_auth with STAT_SHDESC flag enabled and + * <description> set as the desc if it is not empty. + * Uses the pointer provided if not NULL and not initialized. + */ +struct uri_auth *stats_set_desc(struct uri_auth **root, char *desc) +{ + struct uri_auth *u; + char *desc_copy = NULL; + + if (desc && *desc) { + desc_copy = strdup(desc); + if (desc_copy == NULL) + goto out_realm; + } + + if ((u = stats_check_init_uri_auth(root)) == NULL) + goto out_u; + + if (!stats_set_flag(root, STAT_SHDESC)) + goto out_u; + + if (desc_copy) { + free(u->desc); + u->desc = desc_copy; + } + + return u; + + out_u: + free(desc_copy); + out_realm: + return NULL; +} + +/* + * Returns a default uri_auth with the <refresh> refresh interval. + * Uses the pointer provided if not NULL and not initialized. + */ +struct uri_auth *stats_set_refresh(struct uri_auth **root, int interval) +{ + struct uri_auth *u; + + if ((u = stats_check_init_uri_auth(root)) != NULL) + u->refresh = interval; + return u; +} + +/* + * Returns a default uri_auth with the <flag> set. + * Uses the pointer provided if not NULL and not initialized. + */ +struct uri_auth *stats_set_flag(struct uri_auth **root, int flag) +{ + struct uri_auth *u; + + if ((u = stats_check_init_uri_auth(root)) != NULL) + u->flags |= flag; + return u; +} + +/* + * 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 *user) +{ + struct uri_auth *u; + struct auth_users *newuser; + char *pass; + + pass = strchr(user, ':'); + if (pass) + *pass++ = '\0'; + else + pass = ""; + + if ((u = stats_check_init_uri_auth(root)) == NULL) + return NULL; + + if (!u->userlist) + u->userlist = calloc(1, sizeof(*u->userlist)); + + if (!u->userlist) + return NULL; + + if (!u->userlist->name) + u->userlist->name = strdup(".internal-stats-userlist"); + + if (!u->userlist->name) + return NULL; + + for (newuser = u->userlist->users; newuser; newuser = newuser->next) + if (strcmp(newuser->user, user) == 0) { + ha_warning("uri auth: ignoring duplicated user '%s'.\n", + user); + return u; + } + + newuser = calloc(1, sizeof(*newuser)); + if (!newuser) + return NULL; + + newuser->user = strdup(user); + if (!newuser->user) { + free(newuser); + return NULL; + } + + newuser->pass = strdup(pass); + if (!newuser->pass) { + free(newuser->user); + free(newuser); + return NULL; + } + + newuser->flags |= AU_O_INSECURE; + newuser->next = u->userlist->users; + u->userlist->users = newuser; + + return u; +} + +/* + * 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) == 0) + break; + scope_list = &old_scope->next; + } + + if (!old_scope) { + if ((new_name = strdup(scope)) == NULL) + goto out_u; + + if ((old_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; +} + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + */ |