1 /*
2 * URI-based user authentication using the HTTP basic method.
3 *
4 * Copyright 2006-2007 Willy Tarreau <w@1wt.eu>
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
16 #include <common/base64.h>
17 #include <common/config.h>
18 #include <common/uri_auth.h>
19
20 #include <types/stats.h>
21 #include <proto/log.h>
22
23 /*
24 * Initializes a basic uri_auth structure header and returns a pointer to it.
25 * Uses the pointer provided if not NULL and not initialized.
26 */
stats_check_init_uri_auth(struct uri_auth ** root)27 struct uri_auth *stats_check_init_uri_auth(struct uri_auth **root)
28 {
29 struct uri_auth *u;
30
31 if (!root || !*root) {
32 if ((u = calloc(1, sizeof (*u))) == NULL)
33 goto out_u;
34
35 LIST_INIT(&u->http_req_rules);
36 LIST_INIT(&u->admin_rules);
37 } else
38 u = *root;
39
40 if (!u->uri_prefix) {
41 u->uri_len = strlen(STATS_DEFAULT_URI);
42 if ((u->uri_prefix = strdup(STATS_DEFAULT_URI)) == NULL)
43 goto out_uri;
44 }
45
46 if (root && !*root)
47 *root = u;
48
49 return u;
50
51 out_uri:
52 if (!root || !*root)
53 free(u);
54 out_u:
55 return NULL;
56 }
57
58 /*
59 * Returns a default uri_auth with <uri> set as the uri_prefix.
60 * Uses the pointer provided if not NULL and not initialized.
61 */
stats_set_uri(struct uri_auth ** root,char * uri)62 struct uri_auth *stats_set_uri(struct uri_auth **root, char *uri)
63 {
64 struct uri_auth *u;
65 char *uri_copy;
66 int uri_len;
67
68 uri_len = strlen(uri);
69 if ((uri_copy = strdup(uri)) == NULL)
70 goto out_uri;
71
72 if ((u = stats_check_init_uri_auth(root)) == NULL)
73 goto out_u;
74
75 free(u->uri_prefix);
76 u->uri_prefix = uri_copy;
77 u->uri_len = uri_len;
78 return u;
79
80 out_u:
81 free(uri_copy);
82 out_uri:
83 return NULL;
84 }
85
86 /*
87 * Returns a default uri_auth with <realm> set as the realm.
88 * Uses the pointer provided if not NULL and not initialized.
89 */
stats_set_realm(struct uri_auth ** root,char * realm)90 struct uri_auth *stats_set_realm(struct uri_auth **root, char *realm)
91 {
92 struct uri_auth *u;
93 char *realm_copy;
94
95 if ((realm_copy = strdup(realm)) == NULL)
96 goto out_realm;
97
98 if ((u = stats_check_init_uri_auth(root)) == NULL)
99 goto out_u;
100
101 free(u->auth_realm);
102 u->auth_realm = realm_copy;
103 return u;
104
105 out_u:
106 free(realm_copy);
107 out_realm:
108 return NULL;
109 }
110
111 /*
112 * Returns a default uri_auth with STAT_SHNODE flag enabled and
113 * <node> set as the name if it is not empty.
114 * Uses the pointer provided if not NULL and not initialized.
115 */
stats_set_node(struct uri_auth ** root,char * name)116 struct uri_auth *stats_set_node(struct uri_auth **root, char *name)
117 {
118 struct uri_auth *u;
119 char *node_copy = NULL;
120
121 if (name && *name) {
122 node_copy = strdup(name);
123 if (node_copy == NULL)
124 goto out_realm;
125 }
126
127 if ((u = stats_check_init_uri_auth(root)) == NULL)
128 goto out_u;
129
130 if (!stats_set_flag(root, STAT_SHNODE))
131 goto out_u;
132
133 if (node_copy) {
134 free(u->node);
135 u->node = node_copy;
136 }
137
138 return u;
139
140 out_u:
141 free(node_copy);
142 out_realm:
143 return NULL;
144 }
145
146 /*
147 * Returns a default uri_auth with STAT_SHDESC flag enabled and
148 * <description> set as the desc if it is not empty.
149 * Uses the pointer provided if not NULL and not initialized.
150 */
stats_set_desc(struct uri_auth ** root,char * desc)151 struct uri_auth *stats_set_desc(struct uri_auth **root, char *desc)
152 {
153 struct uri_auth *u;
154 char *desc_copy = NULL;
155
156 if (desc && *desc) {
157 desc_copy = strdup(desc);
158 if (desc_copy == NULL)
159 goto out_realm;
160 }
161
162 if ((u = stats_check_init_uri_auth(root)) == NULL)
163 goto out_u;
164
165 if (!stats_set_flag(root, STAT_SHDESC))
166 goto out_u;
167
168 if (desc_copy) {
169 free(u->desc);
170 u->desc = desc_copy;
171 }
172
173 return u;
174
175 out_u:
176 free(desc_copy);
177 out_realm:
178 return NULL;
179 }
180
181 /*
182 * Returns a default uri_auth with the <refresh> refresh interval.
183 * Uses the pointer provided if not NULL and not initialized.
184 */
stats_set_refresh(struct uri_auth ** root,int interval)185 struct uri_auth *stats_set_refresh(struct uri_auth **root, int interval)
186 {
187 struct uri_auth *u;
188
189 if ((u = stats_check_init_uri_auth(root)) != NULL)
190 u->refresh = interval;
191 return u;
192 }
193
194 /*
195 * Returns a default uri_auth with the <flag> set.
196 * Uses the pointer provided if not NULL and not initialized.
197 */
stats_set_flag(struct uri_auth ** root,int flag)198 struct uri_auth *stats_set_flag(struct uri_auth **root, int flag)
199 {
200 struct uri_auth *u;
201
202 if ((u = stats_check_init_uri_auth(root)) != NULL)
203 u->flags |= flag;
204 return u;
205 }
206
207 /*
208 * Returns a default uri_auth with a <user:passwd> entry added to the list of
209 * authorized users. If a matching entry is found, no update will be performed.
210 * Uses the pointer provided if not NULL and not initialized.
211 */
stats_add_auth(struct uri_auth ** root,char * user)212 struct uri_auth *stats_add_auth(struct uri_auth **root, char *user)
213 {
214 struct uri_auth *u;
215 struct auth_users *newuser;
216 char *pass;
217
218 pass = strchr(user, ':');
219 if (pass)
220 *pass++ = '\0';
221 else
222 pass = "";
223
224 if ((u = stats_check_init_uri_auth(root)) == NULL)
225 return NULL;
226
227 if (!u->userlist)
228 u->userlist = calloc(1, sizeof(struct userlist));
229
230 if (!u->userlist)
231 return NULL;
232
233 if (!u->userlist->name)
234 u->userlist->name = strdup(".internal-stats-userlist");
235
236 if (!u->userlist->name)
237 return NULL;
238
239 for (newuser = u->userlist->users; newuser; newuser = newuser->next)
240 if (!strcmp(newuser->user, user)) {
241 ha_warning("uri auth: ignoring duplicated user '%s'.\n",
242 user);
243 return u;
244 }
245
246 newuser = calloc(1, sizeof(*newuser));
247 if (!newuser)
248 return NULL;
249
250 newuser->user = strdup(user);
251 if (!newuser->user) {
252 free(newuser);
253 return NULL;
254 }
255
256 newuser->pass = strdup(pass);
257 if (!newuser->pass) {
258 free(newuser->user);
259 free(newuser);
260 return NULL;
261 }
262
263 newuser->flags |= AU_O_INSECURE;
264 newuser->next = u->userlist->users;
265 u->userlist->users = newuser;
266
267 return u;
268 }
269
270 /*
271 * Returns a default uri_auth with a <scope> entry added to the list of
272 * allowed scopes. If a matching entry is found, no update will be performed.
273 * Uses the pointer provided if not NULL and not initialized.
274 */
stats_add_scope(struct uri_auth ** root,char * scope)275 struct uri_auth *stats_add_scope(struct uri_auth **root, char *scope)
276 {
277 struct uri_auth *u;
278 char *new_name;
279 struct stat_scope *old_scope, **scope_list;
280
281 if ((u = stats_check_init_uri_auth(root)) == NULL)
282 goto out;
283
284 scope_list = &u->scope;
285 while ((old_scope = *scope_list)) {
286 if (!strcmp(old_scope->px_id, scope))
287 break;
288 scope_list = &old_scope->next;
289 }
290
291 if (!old_scope) {
292 if ((new_name = strdup(scope)) == NULL)
293 goto out_u;
294
295 if ((old_scope = calloc(1, sizeof(*old_scope))) == NULL)
296 goto out_name;
297
298 old_scope->px_id = new_name;
299 old_scope->px_len = strlen(new_name);
300 *scope_list = old_scope;
301 }
302 return u;
303
304 out_name:
305 free(new_name);
306 out_u:
307 free(u);
308 out:
309 return NULL;
310 }
311
312 /*
313 * Local variables:
314 * c-indent-level: 8
315 * c-basic-offset: 8
316 * End:
317 */
318