| /* |
| * 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 <common/base64.h> |
| #include <common/uri_auth.h> |
| |
| #include <types/stats.h> |
| #include <proto/log.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(struct 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)) { |
| 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)) |
| 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: |
| */ |