blob: 6b2ca2aa39493dce0c11c5554c984adaba97c595 [file] [log] [blame]
willy tarreau9e138862006-05-14 23:06:28 +02001/*
2 * URI-based user authentication using the HTTP basic method.
3 *
Willy Tarreaubbd42122007-07-25 07:26:38 +02004 * Copyright 2006-2007 Willy Tarreau <w@1wt.eu>
willy tarreau9e138862006-05-14 23:06:28 +02005 *
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>
Willy Tarreaubaaee002006-06-26 02:48:02 +020015
Willy Tarreau2dd0d472006-06-29 17:53:05 +020016#include <common/base64.h>
Willy Tarreaue3ba5f02006-06-29 18:54:54 +020017#include <common/config.h>
Willy Tarreau2dd0d472006-06-29 17:53:05 +020018#include <common/uri_auth.h>
willy tarreau9e138862006-05-14 23:06:28 +020019
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +010020#include <proto/log.h>
willy tarreau9e138862006-05-14 23:06:28 +020021
22/*
23 * Initializes a basic uri_auth structure header and returns a pointer to it.
24 * Uses the pointer provided if not NULL and not initialized.
25 */
26struct uri_auth *stats_check_init_uri_auth(struct uri_auth **root)
27{
28 struct uri_auth *u;
29
30 if (!root || !*root) {
31 if ((u = (struct uri_auth *)calloc(1, sizeof (*u))) == NULL)
32 goto out_u;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +010033
34 LIST_INIT(&u->req_acl);
willy tarreau9e138862006-05-14 23:06:28 +020035 } else
36 u = *root;
37
38 if (!u->uri_prefix) {
39 u->uri_len = strlen(STATS_DEFAULT_URI);
40 if ((u->uri_prefix = strdup(STATS_DEFAULT_URI)) == NULL)
41 goto out_uri;
42 }
43
willy tarreau9e138862006-05-14 23:06:28 +020044 if (root && !*root)
45 *root = u;
46
47 return u;
48
willy tarreau9e138862006-05-14 23:06:28 +020049 out_uri:
50 if (!root || !*root)
51 free(u);
52 out_u:
53 return NULL;
54}
55
56/*
57 * Returns a default uri_auth with <uri> set as the uri_prefix.
58 * Uses the pointer provided if not NULL and not initialized.
59 */
60struct uri_auth *stats_set_uri(struct uri_auth **root, char *uri)
61{
62 struct uri_auth *u;
63 char *uri_copy;
64 int uri_len;
65
66 uri_len = strlen(uri);
67 if ((uri_copy = strdup(uri)) == NULL)
68 goto out_uri;
69
70 if ((u = stats_check_init_uri_auth(root)) == NULL)
71 goto out_u;
72
Willy Tarreaua534fea2008-08-03 12:19:50 +020073 free(u->uri_prefix);
willy tarreau9e138862006-05-14 23:06:28 +020074 u->uri_prefix = uri_copy;
Willy Tarreaua534fea2008-08-03 12:19:50 +020075 u->uri_len = uri_len;
willy tarreau9e138862006-05-14 23:06:28 +020076 return u;
77
78 out_u:
79 free(uri_copy);
80 out_uri:
81 return NULL;
82}
83
84/*
85 * Returns a default uri_auth with <realm> set as the realm.
86 * Uses the pointer provided if not NULL and not initialized.
87 */
88struct uri_auth *stats_set_realm(struct uri_auth **root, char *realm)
89{
90 struct uri_auth *u;
91 char *realm_copy;
92
93 if ((realm_copy = strdup(realm)) == NULL)
94 goto out_realm;
95
96 if ((u = stats_check_init_uri_auth(root)) == NULL)
97 goto out_u;
98
Willy Tarreaua534fea2008-08-03 12:19:50 +020099 free(u->auth_realm);
willy tarreau9e138862006-05-14 23:06:28 +0200100 u->auth_realm = realm_copy;
101 return u;
102
103 out_u:
104 free(realm_copy);
105 out_realm:
106 return NULL;
107}
108
109/*
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +0200110 * Returns a default uri_auth with ST_SHNODE flag enabled and
111 * <node> set as the name if it is not empty.
Willy Tarreau1d45b7c2009-08-16 10:29:18 +0200112 * Uses the pointer provided if not NULL and not initialized.
113 */
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +0200114struct uri_auth *stats_set_node(struct uri_auth **root, char *name)
Willy Tarreau1d45b7c2009-08-16 10:29:18 +0200115{
116 struct uri_auth *u;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +0200117 char *node_copy = NULL;
Willy Tarreau1d45b7c2009-08-16 10:29:18 +0200118
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +0200119 if (name && *name) {
120 node_copy = strdup(name);
121 if (node_copy == NULL)
122 goto out_realm;
123 }
Willy Tarreau1d45b7c2009-08-16 10:29:18 +0200124
125 if ((u = stats_check_init_uri_auth(root)) == NULL)
126 goto out_u;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +0200127
128 if (!stats_set_flag(root, ST_SHNODE))
129 goto out_u;
130
131 if (node_copy) {
132 free(u->node);
133 u->node = node_copy;
134 }
135
136 return u;
137
138 out_u:
139 free(node_copy);
140 out_realm:
141 return NULL;
142}
143
144/*
145 * Returns a default uri_auth with ST_SHDESC flag enabled and
146 * <description> set as the desc if it is not empty.
147 * Uses the pointer provided if not NULL and not initialized.
148 */
149struct uri_auth *stats_set_desc(struct uri_auth **root, char *desc)
150{
151 struct uri_auth *u;
152 char *desc_copy = NULL;
153
154 if (desc && *desc) {
155 desc_copy = strdup(desc);
156 if (desc_copy == NULL)
157 goto out_realm;
158 }
Willy Tarreau1d45b7c2009-08-16 10:29:18 +0200159
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +0200160 if ((u = stats_check_init_uri_auth(root)) == NULL)
161 goto out_u;
162
163 if (!stats_set_flag(root, ST_SHDESC))
164 goto out_u;
165
166 if (desc_copy) {
167 free(u->desc);
168 u->desc = desc_copy;
169 }
170
Willy Tarreau1d45b7c2009-08-16 10:29:18 +0200171 return u;
172
173 out_u:
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +0200174 free(desc_copy);
Willy Tarreau1d45b7c2009-08-16 10:29:18 +0200175 out_realm:
176 return NULL;
177}
178
179/*
Willy Tarreaubbd42122007-07-25 07:26:38 +0200180 * Returns a default uri_auth with the <refresh> refresh interval.
181 * Uses the pointer provided if not NULL and not initialized.
182 */
183struct uri_auth *stats_set_refresh(struct uri_auth **root, int interval)
184{
185 struct uri_auth *u;
186
187 if ((u = stats_check_init_uri_auth(root)) != NULL)
188 u->refresh = interval;
189 return u;
190}
191
192/*
Krzysztof Oledzkid9db9272007-10-15 10:05:11 +0200193 * Returns a default uri_auth with the <flag> set.
194 * Uses the pointer provided if not NULL and not initialized.
195 */
196struct uri_auth *stats_set_flag(struct uri_auth **root, int flag)
197{
198 struct uri_auth *u;
199
200 if ((u = stats_check_init_uri_auth(root)) != NULL)
201 u->flags |= flag;
202 return u;
203}
204
205/*
willy tarreau9e138862006-05-14 23:06:28 +0200206 * Returns a default uri_auth with a <user:passwd> entry added to the list of
207 * authorized users. If a matching entry is found, no update will be performed.
208 * Uses the pointer provided if not NULL and not initialized.
209 */
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +0100210struct uri_auth *stats_add_auth(struct uri_auth **root, char *user)
willy tarreau9e138862006-05-14 23:06:28 +0200211{
212 struct uri_auth *u;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +0100213 struct auth_users *newuser;
214 char *pass;
willy tarreau9e138862006-05-14 23:06:28 +0200215
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +0100216 pass = strchr(user, ':');
217 if (pass)
218 *pass++ = '\0';
219 else
220 pass = "";
willy tarreau9e138862006-05-14 23:06:28 +0200221
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +0100222 if ((u = stats_check_init_uri_auth(root)) == NULL)
223 return NULL;
willy tarreau9e138862006-05-14 23:06:28 +0200224
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +0100225 if (!u->userlist)
226 u->userlist = (struct userlist *)calloc(1, sizeof(struct userlist));
willy tarreau9e138862006-05-14 23:06:28 +0200227
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +0100228 if (!u->userlist)
229 return NULL;
willy tarreau9e138862006-05-14 23:06:28 +0200230
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +0100231 if (!u->userlist->name)
232 u->userlist->name = strdup(".internal-stats-userlist");
willy tarreau9e138862006-05-14 23:06:28 +0200233
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +0100234 if (!u->userlist->name)
235 return NULL;
willy tarreau9e138862006-05-14 23:06:28 +0200236
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +0100237 for (newuser = u->userlist->users; newuser; newuser = newuser->next)
238 if (!strcmp(newuser->user, user)) {
239 Warning("uri auth: ignoring duplicated user '%s'.\n",
240 user);
241 return u;
242 }
243
244 newuser = (struct auth_users *)calloc(1, sizeof(struct auth_users));
245 if (!newuser)
246 return NULL;
247
248 newuser->user = strdup(user);
249 newuser->pass = strdup(pass);
250 newuser->flags |= AU_O_INSECURE;
251
252 if (!newuser->user || !newuser->user)
253 return NULL;
254
255 newuser->next = u->userlist->users;
256 u->userlist->users = newuser;
257
258 return u;
willy tarreau9e138862006-05-14 23:06:28 +0200259}
260
willy tarreau1f431b52006-05-21 14:46:15 +0200261/*
262 * Returns a default uri_auth with a <scope> entry added to the list of
263 * allowed scopes. If a matching entry is found, no update will be performed.
264 * Uses the pointer provided if not NULL and not initialized.
265 */
266struct uri_auth *stats_add_scope(struct uri_auth **root, char *scope)
267{
268 struct uri_auth *u;
269 char *new_name;
270 struct stat_scope *old_scope, **scope_list;
271
272 if ((u = stats_check_init_uri_auth(root)) == NULL)
273 goto out;
274
275 scope_list = &u->scope;
276 while ((old_scope = *scope_list)) {
277 if (!strcmp(old_scope->px_id, scope))
278 break;
279 scope_list = &old_scope->next;
280 }
281
282 if (!old_scope) {
283 if ((new_name = strdup(scope)) == NULL)
284 goto out_u;
285
286 if ((old_scope = (struct stat_scope *)calloc(1, sizeof(*old_scope))) == NULL)
287 goto out_name;
288
289 old_scope->px_id = new_name;
290 old_scope->px_len = strlen(new_name);
291 *scope_list = old_scope;
292 }
293 return u;
294
295 out_name:
296 free(new_name);
297 out_u:
298 free(u);
299 out:
300 return NULL;
301}
302
Willy Tarreaubbd42122007-07-25 07:26:38 +0200303/*
304 * Local variables:
305 * c-indent-level: 8
306 * c-basic-offset: 8
307 * End:
308 */