blob: fdbcef0018295684b4e23a6fe335633260d2ff31 [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);
Cyril Bonté474be412010-10-12 00:14:36 +020035 LIST_INIT(&u->admin_rules);
willy tarreau9e138862006-05-14 23:06:28 +020036 } else
37 u = *root;
38
39 if (!u->uri_prefix) {
40 u->uri_len = strlen(STATS_DEFAULT_URI);
41 if ((u->uri_prefix = strdup(STATS_DEFAULT_URI)) == NULL)
42 goto out_uri;
43 }
44
willy tarreau9e138862006-05-14 23:06:28 +020045 if (root && !*root)
46 *root = u;
47
48 return u;
49
willy tarreau9e138862006-05-14 23:06:28 +020050 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
Willy Tarreaua534fea2008-08-03 12:19:50 +020074 free(u->uri_prefix);
willy tarreau9e138862006-05-14 23:06:28 +020075 u->uri_prefix = uri_copy;
Willy Tarreaua534fea2008-08-03 12:19:50 +020076 u->uri_len = uri_len;
willy tarreau9e138862006-05-14 23:06:28 +020077 return u;
78
79 out_u:
80 free(uri_copy);
81 out_uri:
82 return NULL;
83}
84
85/*
86 * Returns a default uri_auth with <realm> set as the realm.
87 * Uses the pointer provided if not NULL and not initialized.
88 */
89struct uri_auth *stats_set_realm(struct uri_auth **root, char *realm)
90{
91 struct uri_auth *u;
92 char *realm_copy;
93
94 if ((realm_copy = strdup(realm)) == NULL)
95 goto out_realm;
96
97 if ((u = stats_check_init_uri_auth(root)) == NULL)
98 goto out_u;
99
Willy Tarreaua534fea2008-08-03 12:19:50 +0200100 free(u->auth_realm);
willy tarreau9e138862006-05-14 23:06:28 +0200101 u->auth_realm = realm_copy;
102 return u;
103
104 out_u:
105 free(realm_copy);
106 out_realm:
107 return NULL;
108}
109
110/*
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +0200111 * Returns a default uri_auth with ST_SHNODE flag enabled and
112 * <node> set as the name if it is not empty.
Willy Tarreau1d45b7c2009-08-16 10:29:18 +0200113 * Uses the pointer provided if not NULL and not initialized.
114 */
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +0200115struct uri_auth *stats_set_node(struct uri_auth **root, char *name)
Willy Tarreau1d45b7c2009-08-16 10:29:18 +0200116{
117 struct uri_auth *u;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +0200118 char *node_copy = NULL;
Willy Tarreau1d45b7c2009-08-16 10:29:18 +0200119
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +0200120 if (name && *name) {
121 node_copy = strdup(name);
122 if (node_copy == NULL)
123 goto out_realm;
124 }
Willy Tarreau1d45b7c2009-08-16 10:29:18 +0200125
126 if ((u = stats_check_init_uri_auth(root)) == NULL)
127 goto out_u;
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +0200128
129 if (!stats_set_flag(root, ST_SHNODE))
130 goto out_u;
131
132 if (node_copy) {
133 free(u->node);
134 u->node = node_copy;
135 }
136
137 return u;
138
139 out_u:
140 free(node_copy);
141 out_realm:
142 return NULL;
143}
144
145/*
146 * Returns a default uri_auth with ST_SHDESC flag enabled and
147 * <description> set as the desc if it is not empty.
148 * Uses the pointer provided if not NULL and not initialized.
149 */
150struct uri_auth *stats_set_desc(struct uri_auth **root, char *desc)
151{
152 struct uri_auth *u;
153 char *desc_copy = NULL;
154
155 if (desc && *desc) {
156 desc_copy = strdup(desc);
157 if (desc_copy == NULL)
158 goto out_realm;
159 }
Willy Tarreau1d45b7c2009-08-16 10:29:18 +0200160
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +0200161 if ((u = stats_check_init_uri_auth(root)) == NULL)
162 goto out_u;
163
164 if (!stats_set_flag(root, ST_SHDESC))
165 goto out_u;
166
167 if (desc_copy) {
168 free(u->desc);
169 u->desc = desc_copy;
170 }
171
Willy Tarreau1d45b7c2009-08-16 10:29:18 +0200172 return u;
173
174 out_u:
Krzysztof Piotr Oledzki48cb2ae2009-10-02 22:51:14 +0200175 free(desc_copy);
Willy Tarreau1d45b7c2009-08-16 10:29:18 +0200176 out_realm:
177 return NULL;
178}
179
180/*
Willy Tarreaubbd42122007-07-25 07:26:38 +0200181 * Returns a default uri_auth with the <refresh> refresh interval.
182 * Uses the pointer provided if not NULL and not initialized.
183 */
184struct uri_auth *stats_set_refresh(struct uri_auth **root, int interval)
185{
186 struct uri_auth *u;
187
188 if ((u = stats_check_init_uri_auth(root)) != NULL)
189 u->refresh = interval;
190 return u;
191}
192
193/*
Krzysztof Oledzkid9db9272007-10-15 10:05:11 +0200194 * Returns a default uri_auth with the <flag> set.
195 * Uses the pointer provided if not NULL and not initialized.
196 */
197struct uri_auth *stats_set_flag(struct uri_auth **root, int flag)
198{
199 struct uri_auth *u;
200
201 if ((u = stats_check_init_uri_auth(root)) != NULL)
202 u->flags |= flag;
203 return u;
204}
205
206/*
willy tarreau9e138862006-05-14 23:06:28 +0200207 * Returns a default uri_auth with a <user:passwd> entry added to the list of
208 * authorized users. If a matching entry is found, no update will be performed.
209 * Uses the pointer provided if not NULL and not initialized.
210 */
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +0100211struct uri_auth *stats_add_auth(struct uri_auth **root, char *user)
willy tarreau9e138862006-05-14 23:06:28 +0200212{
213 struct uri_auth *u;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +0100214 struct auth_users *newuser;
215 char *pass;
willy tarreau9e138862006-05-14 23:06:28 +0200216
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +0100217 pass = strchr(user, ':');
218 if (pass)
219 *pass++ = '\0';
220 else
221 pass = "";
willy tarreau9e138862006-05-14 23:06:28 +0200222
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +0100223 if ((u = stats_check_init_uri_auth(root)) == NULL)
224 return NULL;
willy tarreau9e138862006-05-14 23:06:28 +0200225
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +0100226 if (!u->userlist)
227 u->userlist = (struct userlist *)calloc(1, sizeof(struct userlist));
willy tarreau9e138862006-05-14 23:06:28 +0200228
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +0100229 if (!u->userlist)
230 return NULL;
willy tarreau9e138862006-05-14 23:06:28 +0200231
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +0100232 if (!u->userlist->name)
233 u->userlist->name = strdup(".internal-stats-userlist");
willy tarreau9e138862006-05-14 23:06:28 +0200234
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +0100235 if (!u->userlist->name)
236 return NULL;
willy tarreau9e138862006-05-14 23:06:28 +0200237
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +0100238 for (newuser = u->userlist->users; newuser; newuser = newuser->next)
239 if (!strcmp(newuser->user, user)) {
240 Warning("uri auth: ignoring duplicated user '%s'.\n",
241 user);
242 return u;
243 }
244
245 newuser = (struct auth_users *)calloc(1, sizeof(struct auth_users));
246 if (!newuser)
247 return NULL;
248
249 newuser->user = strdup(user);
250 newuser->pass = strdup(pass);
251 newuser->flags |= AU_O_INSECURE;
252
253 if (!newuser->user || !newuser->user)
254 return NULL;
255
256 newuser->next = u->userlist->users;
257 u->userlist->users = newuser;
258
259 return u;
willy tarreau9e138862006-05-14 23:06:28 +0200260}
261
willy tarreau1f431b52006-05-21 14:46:15 +0200262/*
263 * Returns a default uri_auth with a <scope> entry added to the list of
264 * allowed scopes. If a matching entry is found, no update will be performed.
265 * Uses the pointer provided if not NULL and not initialized.
266 */
267struct uri_auth *stats_add_scope(struct uri_auth **root, char *scope)
268{
269 struct uri_auth *u;
270 char *new_name;
271 struct stat_scope *old_scope, **scope_list;
272
273 if ((u = stats_check_init_uri_auth(root)) == NULL)
274 goto out;
275
276 scope_list = &u->scope;
277 while ((old_scope = *scope_list)) {
278 if (!strcmp(old_scope->px_id, scope))
279 break;
280 scope_list = &old_scope->next;
281 }
282
283 if (!old_scope) {
284 if ((new_name = strdup(scope)) == NULL)
285 goto out_u;
286
287 if ((old_scope = (struct stat_scope *)calloc(1, sizeof(*old_scope))) == NULL)
288 goto out_name;
289
290 old_scope->px_id = new_name;
291 old_scope->px_len = strlen(new_name);
292 *scope_list = old_scope;
293 }
294 return u;
295
296 out_name:
297 free(new_name);
298 out_u:
299 free(u);
300 out:
301 return NULL;
302}
303
Willy Tarreaubbd42122007-07-25 07:26:38 +0200304/*
305 * Local variables:
306 * c-indent-level: 8
307 * c-basic-offset: 8
308 * End:
309 */