blob: cfe1f4c10d9c5fe8b16c36750c34f47b717021be [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) {
Vincent Bernat3c2f2f22016-04-03 13:48:42 +020031 if ((u = calloc(1, sizeof (*u))) == NULL)
willy tarreau9e138862006-05-14 23:06:28 +020032 goto out_u;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +010033
Willy Tarreauff011f22011-01-06 17:51:27 +010034 LIST_INIT(&u->http_req_rules);
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)
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200227 u->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
Vincent Bernat02779b62016-04-03 13:48:43 +0200245 newuser = calloc(1, sizeof(*newuser));
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +0100246 if (!newuser)
247 return NULL;
248
249 newuser->user = strdup(user);
Willy Tarreau0b291bd2013-01-24 02:26:43 +0100250 if (!newuser->user) {
251 free(newuser);
252 return NULL;
253 }
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +0100254
Willy Tarreau0b291bd2013-01-24 02:26:43 +0100255 newuser->pass = strdup(pass);
256 if (!newuser->pass) {
257 free(newuser->user);
258 free(newuser);
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +0100259 return NULL;
Willy Tarreau0b291bd2013-01-24 02:26:43 +0100260 }
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +0100261
Willy Tarreau0b291bd2013-01-24 02:26:43 +0100262 newuser->flags |= AU_O_INSECURE;
Krzysztof Piotr Oledzki8c8bd452010-01-29 19:29:32 +0100263 newuser->next = u->userlist->users;
264 u->userlist->users = newuser;
265
266 return u;
willy tarreau9e138862006-05-14 23:06:28 +0200267}
268
willy tarreau1f431b52006-05-21 14:46:15 +0200269/*
270 * Returns a default uri_auth with a <scope> entry added to the list of
271 * allowed scopes. If a matching entry is found, no update will be performed.
272 * Uses the pointer provided if not NULL and not initialized.
273 */
274struct uri_auth *stats_add_scope(struct uri_auth **root, char *scope)
275{
276 struct uri_auth *u;
277 char *new_name;
278 struct stat_scope *old_scope, **scope_list;
279
280 if ((u = stats_check_init_uri_auth(root)) == NULL)
281 goto out;
282
283 scope_list = &u->scope;
284 while ((old_scope = *scope_list)) {
285 if (!strcmp(old_scope->px_id, scope))
286 break;
287 scope_list = &old_scope->next;
288 }
289
290 if (!old_scope) {
291 if ((new_name = strdup(scope)) == NULL)
292 goto out_u;
293
Vincent Bernat3c2f2f22016-04-03 13:48:42 +0200294 if ((old_scope = calloc(1, sizeof(*old_scope))) == NULL)
willy tarreau1f431b52006-05-21 14:46:15 +0200295 goto out_name;
296
297 old_scope->px_id = new_name;
298 old_scope->px_len = strlen(new_name);
299 *scope_list = old_scope;
300 }
301 return u;
302
303 out_name:
304 free(new_name);
305 out_u:
306 free(u);
307 out:
308 return NULL;
309}
310
Willy Tarreaubbd42122007-07-25 07:26:38 +0200311/*
312 * Local variables:
313 * c-indent-level: 8
314 * c-basic-offset: 8
315 * End:
316 */