/* * URI-based user authentication using the HTTP basic method. * * Copyright 2006-2007 Willy Tarreau * * 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 #include #include #include #include /* * 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 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 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 set as the node name. * Uses the pointer provided if not NULL and not initialized. */ struct uri_auth *stats_set_node_name(struct uri_auth **root, char *name) { struct uri_auth *u; char *name_copy; if ((name_copy = strdup(name)) == NULL) goto out_realm; if ((u = stats_check_init_uri_auth(root)) == NULL) goto out_u; free(u->node_name); u->node_name = name_copy; return u; out_u: free(name_copy); out_realm: return NULL; } /* * Returns a default uri_auth with the 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 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 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 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; } /* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * End: */