blob: 84570efd26eb692f1b5f37f5d12e8783f17809b8 [file] [log] [blame]
willy tarreau9e138862006-05-14 23:06:28 +02001/*
2 * URI-based user authentication using the HTTP basic method.
3 *
4 * Copyright 2006 Willy Tarreau <willy@w.ods.org>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 */
12
13#include <stdlib.h>
14#include <string.h>
15#include <include/uri_auth.h>
16#include <include/base64.h>
17
18
19/*
20 * Initializes a basic uri_auth structure header and returns a pointer to it.
21 * Uses the pointer provided if not NULL and not initialized.
22 */
23struct uri_auth *stats_check_init_uri_auth(struct uri_auth **root)
24{
25 struct uri_auth *u;
26
27 if (!root || !*root) {
28 if ((u = (struct uri_auth *)calloc(1, sizeof (*u))) == NULL)
29 goto out_u;
30 } else
31 u = *root;
32
33 if (!u->uri_prefix) {
34 u->uri_len = strlen(STATS_DEFAULT_URI);
35 if ((u->uri_prefix = strdup(STATS_DEFAULT_URI)) == NULL)
36 goto out_uri;
37 }
38
39 if (!u->auth_realm)
40 if ((u->auth_realm = strdup(STATS_DEFAULT_REALM)) == NULL)
41 goto out_realm;
42
43 if (root && !*root)
44 *root = u;
45
46 return u;
47
48 out_realm:
49 free(u->uri_prefix);
50 out_uri:
51 if (!root || !*root)
52 free(u);
53 out_u:
54 return NULL;
55}
56
57/*
58 * Returns a default uri_auth with <uri> set as the uri_prefix.
59 * Uses the pointer provided if not NULL and not initialized.
60 */
61struct uri_auth *stats_set_uri(struct uri_auth **root, char *uri)
62{
63 struct uri_auth *u;
64 char *uri_copy;
65 int uri_len;
66
67 uri_len = strlen(uri);
68 if ((uri_copy = strdup(uri)) == NULL)
69 goto out_uri;
70
71 if ((u = stats_check_init_uri_auth(root)) == NULL)
72 goto out_u;
73
74 if (u->uri_prefix)
75 free(u->uri_prefix);
76
77 u->uri_len = uri_len;
78 u->uri_prefix = uri_copy;
79 return u;
80
81 out_u:
82 free(uri_copy);
83 out_uri:
84 return NULL;
85}
86
87/*
88 * Returns a default uri_auth with <realm> set as the realm.
89 * Uses the pointer provided if not NULL and not initialized.
90 */
91struct uri_auth *stats_set_realm(struct uri_auth **root, char *realm)
92{
93 struct uri_auth *u;
94 char *realm_copy;
95
96 if ((realm_copy = strdup(realm)) == NULL)
97 goto out_realm;
98
99 if ((u = stats_check_init_uri_auth(root)) == NULL)
100 goto out_u;
101
102 if (u->auth_realm)
103 free(u->auth_realm);
104
105 u->auth_realm = realm_copy;
106 return u;
107
108 out_u:
109 free(realm_copy);
110 out_realm:
111 return NULL;
112}
113
114/*
115 * Returns a default uri_auth with a <user:passwd> entry added to the list of
116 * authorized users. If a matching entry is found, no update will be performed.
117 * Uses the pointer provided if not NULL and not initialized.
118 */
119struct uri_auth *stats_add_auth(struct uri_auth **root, char *auth)
120{
121 struct uri_auth *u;
122 char *auth_base64;
123 int alen, blen;
124 struct user_auth *users, **ulist;
125
126 alen = strlen(auth);
127 blen = ((alen + 2) / 3) * 4;
128
129 if ((auth_base64 = (char *)calloc(1, blen + 1)) == NULL)
130 goto out_ubase64;
131
132 /* convert user:passwd to base64. It should return exactly blen */
133 if (a2base64(auth, alen, auth_base64, blen + 1) != blen)
134 goto out_base64;
135
136 if ((u = stats_check_init_uri_auth(root)) == NULL)
137 goto out_base64;
138
139 ulist = &u->users;
140 while ((users = *ulist)) {
141 if (!strcmp(users->user_pwd, auth_base64))
142 break;
143 ulist = &users->next;
144 }
145
146 if (!users) {
147 if ((users = (struct user_auth *)calloc(1, sizeof(*users))) == NULL)
148 goto out_u;
149 *ulist = users;
150 users->user_pwd = auth_base64;
151 users->user_len = blen;
152 }
153 return u;
154
155 out_u:
156 free(u);
157 out_base64:
158 free(auth_base64);
159 out_ubase64:
160 return NULL;
161}
162
willy tarreau1f431b52006-05-21 14:46:15 +0200163/*
164 * Returns a default uri_auth with a <scope> entry added to the list of
165 * allowed scopes. If a matching entry is found, no update will be performed.
166 * Uses the pointer provided if not NULL and not initialized.
167 */
168struct uri_auth *stats_add_scope(struct uri_auth **root, char *scope)
169{
170 struct uri_auth *u;
171 char *new_name;
172 struct stat_scope *old_scope, **scope_list;
173
174 if ((u = stats_check_init_uri_auth(root)) == NULL)
175 goto out;
176
177 scope_list = &u->scope;
178 while ((old_scope = *scope_list)) {
179 if (!strcmp(old_scope->px_id, scope))
180 break;
181 scope_list = &old_scope->next;
182 }
183
184 if (!old_scope) {
185 if ((new_name = strdup(scope)) == NULL)
186 goto out_u;
187
188 if ((old_scope = (struct stat_scope *)calloc(1, sizeof(*old_scope))) == NULL)
189 goto out_name;
190
191 old_scope->px_id = new_name;
192 old_scope->px_len = strlen(new_name);
193 *scope_list = old_scope;
194 }
195 return u;
196
197 out_name:
198 free(new_name);
199 out_u:
200 free(u);
201 out:
202 return NULL;
203}
204