Mercurial > hg > nginx-quic
annotate src/http/modules/ngx_http_auth_basic_module.c @ 4664:356c91151658 stable-1.2
Merge of r4618: rewrite escaping fix (ticket #162).
The following code resulted in incorrect escaping of uri and possible
segfault:
location / {
rewrite ^(.*) $1?c=$1;
return 200 "$uri";
}
If there were arguments in a rewrite's replacement string, and length was
actually calculated (due to duplicate captures as in the example above,
or variables present), the is_args flag was set and incorrectly copied
after length calculation. This resulted in escaping applied to the uri part
of the replacement, resulting in incorrect escaping. Additionally, buffer
was allocated without escaping expected, thus this also resulted in buffer
overrun and possible segfault.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 04 Jun 2012 11:07:19 +0000 |
parents | d620f497c50f |
children | 4251e72b8bb4 05beaa2d87b3 |
rev | line source |
---|---|
503 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4412 | 4 * Copyright (C) Nginx, Inc. |
503 | 5 */ |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_http.h> | |
3922
9c057d5e1c27
"$apr1", "{PLAIN}", and "{SSHA}" password methods in auth basic module
Igor Sysoev <igor@sysoev.ru>
parents:
3887
diff
changeset
|
11 #include <ngx_crypt.h> |
503 | 12 |
13 | |
14 #define NGX_HTTP_AUTH_BUF_SIZE 2048 | |
15 | |
16 | |
17 typedef struct { | |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2571
diff
changeset
|
18 ngx_str_t passwd; |
503 | 19 } ngx_http_auth_basic_ctx_t; |
20 | |
21 | |
22 typedef struct { | |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2571
diff
changeset
|
23 ngx_str_t realm; |
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2571
diff
changeset
|
24 ngx_http_complex_value_t user_file; |
503 | 25 } ngx_http_auth_basic_loc_conf_t; |
26 | |
27 | |
28 static ngx_int_t ngx_http_auth_basic_handler(ngx_http_request_t *r); | |
29 static ngx_int_t ngx_http_auth_basic_crypt_handler(ngx_http_request_t *r, | |
30 ngx_http_auth_basic_ctx_t *ctx, ngx_str_t *passwd, ngx_str_t *realm); | |
31 static ngx_int_t ngx_http_auth_basic_set_realm(ngx_http_request_t *r, | |
32 ngx_str_t *realm); | |
33 static void ngx_http_auth_basic_close(ngx_file_t *file); | |
34 static void *ngx_http_auth_basic_create_loc_conf(ngx_conf_t *cf); | |
35 static char *ngx_http_auth_basic_merge_loc_conf(ngx_conf_t *cf, | |
36 void *parent, void *child); | |
681 | 37 static ngx_int_t ngx_http_auth_basic_init(ngx_conf_t *cf); |
503 | 38 static char *ngx_http_auth_basic(ngx_conf_t *cf, void *post, void *data); |
2567
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
39 static char *ngx_http_auth_basic_user_file(ngx_conf_t *cf, ngx_command_t *cmd, |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
40 void *conf); |
503 | 41 |
42 | |
43 static ngx_conf_post_handler_pt ngx_http_auth_basic_p = ngx_http_auth_basic; | |
44 | |
45 static ngx_command_t ngx_http_auth_basic_commands[] = { | |
46 | |
47 { ngx_string("auth_basic"), | |
631 | 48 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF |
49 |NGX_CONF_TAKE1, | |
503 | 50 ngx_conf_set_str_slot, |
51 NGX_HTTP_LOC_CONF_OFFSET, | |
52 offsetof(ngx_http_auth_basic_loc_conf_t, realm), | |
53 &ngx_http_auth_basic_p }, | |
54 | |
55 { ngx_string("auth_basic_user_file"), | |
631 | 56 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF |
57 |NGX_CONF_TAKE1, | |
2567
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
58 ngx_http_auth_basic_user_file, |
503 | 59 NGX_HTTP_LOC_CONF_OFFSET, |
60 offsetof(ngx_http_auth_basic_loc_conf_t, user_file), | |
61 NULL }, | |
62 | |
63 ngx_null_command | |
64 }; | |
65 | |
66 | |
667 | 67 static ngx_http_module_t ngx_http_auth_basic_module_ctx = { |
509 | 68 NULL, /* preconfiguration */ |
681 | 69 ngx_http_auth_basic_init, /* postconfiguration */ |
503 | 70 |
71 NULL, /* create main configuration */ | |
72 NULL, /* init main configuration */ | |
73 | |
74 NULL, /* create server configuration */ | |
75 NULL, /* merge server configuration */ | |
76 | |
77 ngx_http_auth_basic_create_loc_conf, /* create location configuration */ | |
78 ngx_http_auth_basic_merge_loc_conf /* merge location configuration */ | |
79 }; | |
80 | |
81 | |
82 ngx_module_t ngx_http_auth_basic_module = { | |
509 | 83 NGX_MODULE_V1, |
503 | 84 &ngx_http_auth_basic_module_ctx, /* module context */ |
85 ngx_http_auth_basic_commands, /* module directives */ | |
86 NGX_HTTP_MODULE, /* module type */ | |
541 | 87 NULL, /* init master */ |
681 | 88 NULL, /* init module */ |
541 | 89 NULL, /* init process */ |
90 NULL, /* init thread */ | |
91 NULL, /* exit thread */ | |
92 NULL, /* exit process */ | |
93 NULL, /* exit master */ | |
94 NGX_MODULE_V1_PADDING | |
503 | 95 }; |
96 | |
97 | |
98 static ngx_int_t | |
99 ngx_http_auth_basic_handler(ngx_http_request_t *r) | |
100 { | |
101 off_t offset; | |
102 ssize_t n; | |
103 ngx_fd_t fd; | |
539 | 104 ngx_int_t rc; |
2567
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
105 ngx_err_t err; |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
106 ngx_str_t pwd, user_file; |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
107 ngx_uint_t i, level, login, left, passwd; |
503 | 108 ngx_file_t file; |
109 ngx_http_auth_basic_ctx_t *ctx; | |
110 ngx_http_auth_basic_loc_conf_t *alcf; | |
111 u_char buf[NGX_HTTP_AUTH_BUF_SIZE]; | |
112 enum { | |
113 sw_login, | |
114 sw_passwd, | |
115 sw_skip | |
116 } state; | |
117 | |
118 alcf = ngx_http_get_module_loc_conf(r, ngx_http_auth_basic_module); | |
119 | |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2571
diff
changeset
|
120 if (alcf->realm.len == 0 || alcf->user_file.value.len == 0) { |
1786
adca43955f79
return NGX_DECLINED if access directives are not active,
Igor Sysoev <igor@sysoev.ru>
parents:
1352
diff
changeset
|
121 return NGX_DECLINED; |
503 | 122 } |
123 | |
124 ctx = ngx_http_get_module_ctx(r, ngx_http_auth_basic_module); | |
125 | |
126 if (ctx) { | |
127 return ngx_http_auth_basic_crypt_handler(r, ctx, &ctx->passwd, | |
128 &alcf->realm); | |
129 } | |
130 | |
539 | 131 rc = ngx_http_auth_basic_user(r); |
503 | 132 |
539 | 133 if (rc == NGX_DECLINED) { |
2523
7764f0fdd2a4
add auth basic failure logging
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
134 |
7764f0fdd2a4
add auth basic failure logging
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
135 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
7764f0fdd2a4
add auth basic failure logging
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
136 "no user/password was provided for basic authentication"); |
7764f0fdd2a4
add auth basic failure logging
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
137 |
503 | 138 return ngx_http_auth_basic_set_realm(r, &alcf->realm); |
139 } | |
140 | |
539 | 141 if (rc == NGX_ERROR) { |
503 | 142 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
143 } | |
144 | |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2571
diff
changeset
|
145 if (ngx_http_complex_value(r, &alcf->user_file, &user_file) != NGX_OK) { |
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2571
diff
changeset
|
146 return NGX_ERROR; |
2567
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
147 } |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
148 |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
149 fd = ngx_open_file(user_file.data, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0); |
503 | 150 |
151 if (fd == NGX_INVALID_FILE) { | |
2567
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
152 err = ngx_errno; |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
153 |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
154 if (err == NGX_ENOENT) { |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
155 level = NGX_LOG_ERR; |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
156 rc = NGX_HTTP_FORBIDDEN; |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
157 |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
158 } else { |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
159 level = NGX_LOG_CRIT; |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
160 rc = NGX_HTTP_INTERNAL_SERVER_ERROR; |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
161 } |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
162 |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
163 ngx_log_error(level, r->connection->log, err, |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
164 ngx_open_file_n " \"%s\" failed", user_file.data); |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
165 |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
166 return rc; |
503 | 167 } |
168 | |
169 ngx_memzero(&file, sizeof(ngx_file_t)); | |
170 | |
171 file.fd = fd; | |
2567
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
172 file.name = user_file; |
503 | 173 file.log = r->connection->log; |
174 | |
175 state = sw_login; | |
176 passwd = 0; | |
177 login = 0; | |
178 left = 0; | |
179 offset = 0; | |
180 | |
181 for ( ;; ) { | |
890
6356b34cf027
fix when last htpasswd line has no CR or LF
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
182 i = left; |
6356b34cf027
fix when last htpasswd line has no CR or LF
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
183 |
503 | 184 n = ngx_read_file(&file, buf + left, NGX_HTTP_AUTH_BUF_SIZE - left, |
185 offset); | |
186 | |
187 if (n == NGX_ERROR) { | |
188 ngx_http_auth_basic_close(&file); | |
189 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
190 } | |
191 | |
192 if (n == 0) { | |
193 break; | |
194 } | |
195 | |
196 for (i = left; i < left + n; i++) { | |
197 switch (state) { | |
198 | |
199 case sw_login: | |
2524
fd4ee75c6eee
name/password were ignored after odd empty lines
Igor Sysoev <igor@sysoev.ru>
parents:
2523
diff
changeset
|
200 if (login == 0) { |
fd4ee75c6eee
name/password were ignored after odd empty lines
Igor Sysoev <igor@sysoev.ru>
parents:
2523
diff
changeset
|
201 |
fd4ee75c6eee
name/password were ignored after odd empty lines
Igor Sysoev <igor@sysoev.ru>
parents:
2523
diff
changeset
|
202 if (buf[i] == '#' || buf[i] == CR) { |
fd4ee75c6eee
name/password were ignored after odd empty lines
Igor Sysoev <igor@sysoev.ru>
parents:
2523
diff
changeset
|
203 state = sw_skip; |
fd4ee75c6eee
name/password were ignored after odd empty lines
Igor Sysoev <igor@sysoev.ru>
parents:
2523
diff
changeset
|
204 break; |
fd4ee75c6eee
name/password were ignored after odd empty lines
Igor Sysoev <igor@sysoev.ru>
parents:
2523
diff
changeset
|
205 } |
fd4ee75c6eee
name/password were ignored after odd empty lines
Igor Sysoev <igor@sysoev.ru>
parents:
2523
diff
changeset
|
206 |
fd4ee75c6eee
name/password were ignored after odd empty lines
Igor Sysoev <igor@sysoev.ru>
parents:
2523
diff
changeset
|
207 if (buf[i] == LF) { |
fd4ee75c6eee
name/password were ignored after odd empty lines
Igor Sysoev <igor@sysoev.ru>
parents:
2523
diff
changeset
|
208 break; |
fd4ee75c6eee
name/password were ignored after odd empty lines
Igor Sysoev <igor@sysoev.ru>
parents:
2523
diff
changeset
|
209 } |
503 | 210 } |
211 | |
539 | 212 if (buf[i] != r->headers_in.user.data[login]) { |
503 | 213 state = sw_skip; |
214 break; | |
215 } | |
216 | |
539 | 217 if (login == r->headers_in.user.len) { |
503 | 218 state = sw_passwd; |
219 passwd = i + 1; | |
220 } | |
221 | |
222 login++; | |
223 | |
224 break; | |
225 | |
226 case sw_passwd: | |
227 if (buf[i] == LF || buf[i] == CR || buf[i] == ':') { | |
228 buf[i] = '\0'; | |
229 | |
230 ngx_http_auth_basic_close(&file); | |
231 | |
232 pwd.len = i - passwd; | |
233 pwd.data = &buf[passwd]; | |
234 | |
235 return ngx_http_auth_basic_crypt_handler(r, NULL, &pwd, | |
236 &alcf->realm); | |
237 } | |
238 | |
239 break; | |
240 | |
241 case sw_skip: | |
242 if (buf[i] == LF) { | |
243 state = sw_login; | |
244 login = 0; | |
245 } | |
246 | |
247 break; | |
248 } | |
249 } | |
250 | |
251 if (state == sw_passwd) { | |
252 left = left + n - passwd; | |
3887
e7798b5e990a
use memmove() in appropriate places
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
253 ngx_memmove(buf, &buf[passwd], left); |
503 | 254 passwd = 0; |
255 | |
256 } else { | |
257 left = 0; | |
258 } | |
259 | |
260 offset += n; | |
261 } | |
262 | |
263 ngx_http_auth_basic_close(&file); | |
264 | |
890
6356b34cf027
fix when last htpasswd line has no CR or LF
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
265 if (state == sw_passwd) { |
6356b34cf027
fix when last htpasswd line has no CR or LF
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
266 pwd.len = i - passwd; |
2049 | 267 pwd.data = ngx_pnalloc(r->pool, pwd.len + 1); |
890
6356b34cf027
fix when last htpasswd line has no CR or LF
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
268 if (pwd.data == NULL) { |
6356b34cf027
fix when last htpasswd line has no CR or LF
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
269 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
6356b34cf027
fix when last htpasswd line has no CR or LF
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
270 } |
6356b34cf027
fix when last htpasswd line has no CR or LF
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
271 |
6356b34cf027
fix when last htpasswd line has no CR or LF
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
272 ngx_cpystrn(pwd.data, &buf[passwd], pwd.len + 1); |
6356b34cf027
fix when last htpasswd line has no CR or LF
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
273 |
6356b34cf027
fix when last htpasswd line has no CR or LF
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
274 return ngx_http_auth_basic_crypt_handler(r, NULL, &pwd, &alcf->realm); |
6356b34cf027
fix when last htpasswd line has no CR or LF
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
275 } |
6356b34cf027
fix when last htpasswd line has no CR or LF
Igor Sysoev <igor@sysoev.ru>
parents:
681
diff
changeset
|
276 |
2523
7764f0fdd2a4
add auth basic failure logging
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
277 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
7764f0fdd2a4
add auth basic failure logging
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
278 "user \"%V\" was not found in \"%V\"", |
2567
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
279 &r->headers_in.user, &user_file); |
2523
7764f0fdd2a4
add auth basic failure logging
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
280 |
503 | 281 return ngx_http_auth_basic_set_realm(r, &alcf->realm); |
282 } | |
283 | |
284 | |
285 static ngx_int_t | |
286 ngx_http_auth_basic_crypt_handler(ngx_http_request_t *r, | |
287 ngx_http_auth_basic_ctx_t *ctx, ngx_str_t *passwd, ngx_str_t *realm) | |
288 { | |
289 ngx_int_t rc; | |
290 u_char *encrypted; | |
291 | |
292 rc = ngx_crypt(r->pool, r->headers_in.passwd.data, passwd->data, | |
293 &encrypted); | |
294 | |
295 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
2523
7764f0fdd2a4
add auth basic failure logging
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
296 "rc: %d user: \"%V\" salt: \"%s\"", |
7764f0fdd2a4
add auth basic failure logging
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
297 rc, &r->headers_in.user, passwd->data); |
503 | 298 |
299 if (rc == NGX_OK) { | |
300 if (ngx_strcmp(encrypted, passwd->data) == 0) { | |
301 return NGX_OK; | |
302 } | |
303 | |
304 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
305 "encrypted: \"%s\"", encrypted); | |
306 | |
2523
7764f0fdd2a4
add auth basic failure logging
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
307 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
7764f0fdd2a4
add auth basic failure logging
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
308 "user \"%V\": password mismatch", |
7764f0fdd2a4
add auth basic failure logging
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
309 &r->headers_in.user); |
7764f0fdd2a4
add auth basic failure logging
Igor Sysoev <igor@sysoev.ru>
parents:
2049
diff
changeset
|
310 |
503 | 311 return ngx_http_auth_basic_set_realm(r, realm); |
312 } | |
313 | |
314 if (rc == NGX_ERROR) { | |
315 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
316 } | |
317 | |
318 /* rc == NGX_AGAIN */ | |
319 | |
320 if (ctx == NULL) { | |
321 ctx = ngx_palloc(r->pool, sizeof(ngx_http_auth_basic_ctx_t)); | |
322 if (ctx == NULL) { | |
323 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
324 } | |
325 | |
326 ngx_http_set_ctx(r, ctx, ngx_http_auth_basic_module); | |
327 | |
328 ctx->passwd.len = passwd->len; | |
329 passwd->len++; | |
330 | |
331 ctx->passwd.data = ngx_pstrdup(r->pool, passwd); | |
332 if (ctx->passwd.data == NULL) { | |
333 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
334 } | |
335 | |
336 } | |
337 | |
338 /* TODO: add mutex event */ | |
339 | |
340 return rc; | |
341 } | |
342 | |
343 | |
344 static ngx_int_t | |
345 ngx_http_auth_basic_set_realm(ngx_http_request_t *r, ngx_str_t *realm) | |
346 { | |
347 r->headers_out.www_authenticate = ngx_list_push(&r->headers_out.headers); | |
348 if (r->headers_out.www_authenticate == NULL) { | |
349 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
350 } | |
351 | |
509 | 352 r->headers_out.www_authenticate->hash = 1; |
3516
dd1570b6f237
ngx_str_set() and ngx_str_null()
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
353 ngx_str_set(&r->headers_out.www_authenticate->key, "WWW-Authenticate"); |
503 | 354 r->headers_out.www_authenticate->value = *realm; |
355 | |
356 return NGX_HTTP_UNAUTHORIZED; | |
357 } | |
358 | |
359 static void | |
360 ngx_http_auth_basic_close(ngx_file_t *file) | |
361 { | |
362 if (ngx_close_file(file->fd) == NGX_FILE_ERROR) { | |
363 ngx_log_error(NGX_LOG_ALERT, file->log, ngx_errno, | |
364 ngx_close_file_n " \"%s\" failed", file->name.data); | |
365 } | |
366 } | |
367 | |
368 | |
369 static void * | |
370 ngx_http_auth_basic_create_loc_conf(ngx_conf_t *cf) | |
371 { | |
372 ngx_http_auth_basic_loc_conf_t *conf; | |
373 | |
374 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_auth_basic_loc_conf_t)); | |
375 if (conf == NULL) { | |
2912
c7d57b539248
return NULL instead of NGX_CONF_ERROR on a create conf failure
Igor Sysoev <igor@sysoev.ru>
parents:
2588
diff
changeset
|
376 return NULL; |
503 | 377 } |
378 | |
379 return conf; | |
380 } | |
381 | |
382 | |
383 static char * | |
384 ngx_http_auth_basic_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) | |
385 { | |
386 ngx_http_auth_basic_loc_conf_t *prev = parent; | |
387 ngx_http_auth_basic_loc_conf_t *conf = child; | |
388 | |
581 | 389 if (conf->realm.data == NULL) { |
503 | 390 conf->realm = prev->realm; |
391 } | |
392 | |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2571
diff
changeset
|
393 if (conf->user_file.value.len == 0) { |
503 | 394 conf->user_file = prev->user_file; |
395 } | |
396 | |
397 return NGX_CONF_OK; | |
398 } | |
399 | |
400 | |
401 static ngx_int_t | |
681 | 402 ngx_http_auth_basic_init(ngx_conf_t *cf) |
503 | 403 { |
404 ngx_http_handler_pt *h; | |
405 ngx_http_core_main_conf_t *cmcf; | |
406 | |
681 | 407 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); |
503 | 408 |
409 h = ngx_array_push(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers); | |
410 if (h == NULL) { | |
411 return NGX_ERROR; | |
412 } | |
413 | |
414 *h = ngx_http_auth_basic_handler; | |
415 | |
416 return NGX_OK; | |
417 } | |
418 | |
419 | |
420 static char * | |
421 ngx_http_auth_basic(ngx_conf_t *cf, void *post, void *data) | |
422 { | |
423 ngx_str_t *realm = data; | |
424 | |
581 | 425 size_t len; |
426 u_char *basic, *p; | |
427 | |
503 | 428 if (ngx_strcmp(realm->data, "off") == 0) { |
3516
dd1570b6f237
ngx_str_set() and ngx_str_null()
Igor Sysoev <igor@sysoev.ru>
parents:
2912
diff
changeset
|
429 ngx_str_set(realm, ""); |
583 | 430 return NGX_CONF_OK; |
503 | 431 } |
432 | |
581 | 433 len = sizeof("Basic realm=\"") - 1 + realm->len + 1; |
434 | |
2049 | 435 basic = ngx_pnalloc(cf->pool, len); |
581 | 436 if (basic == NULL) { |
437 return NGX_CONF_ERROR; | |
438 } | |
439 | |
440 p = ngx_cpymem(basic, "Basic realm=\"", sizeof("Basic realm=\"") - 1); | |
441 p = ngx_cpymem(p, realm->data, realm->len); | |
442 *p = '"'; | |
443 | |
444 realm->len = len; | |
445 realm->data = basic; | |
446 | |
503 | 447 return NGX_CONF_OK; |
448 } | |
2567
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
449 |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
450 |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
451 static char * |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
452 ngx_http_auth_basic_user_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
453 { |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
454 ngx_http_auth_basic_loc_conf_t *alcf = conf; |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
455 |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2571
diff
changeset
|
456 ngx_str_t *value; |
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2571
diff
changeset
|
457 ngx_http_compile_complex_value_t ccv; |
2567
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
458 |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2571
diff
changeset
|
459 if (alcf->user_file.value.len) { |
2567
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
460 return "is duplicate"; |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
461 } |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
462 |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
463 value = cf->args->elts; |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
464 |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2571
diff
changeset
|
465 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); |
2567
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
466 |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2571
diff
changeset
|
467 ccv.cf = cf; |
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2571
diff
changeset
|
468 ccv.value = &value[1]; |
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2571
diff
changeset
|
469 ccv.complex_value = &alcf->user_file; |
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2571
diff
changeset
|
470 ccv.zero = 1; |
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2571
diff
changeset
|
471 ccv.conf_prefix = 1; |
2567
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
472 |
2588
a6954ce88b80
use complex values in add_header, auth_basic_user_file,
Igor Sysoev <igor@sysoev.ru>
parents:
2571
diff
changeset
|
473 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
2567
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
474 return NGX_CONF_ERROR; |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
475 } |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
476 |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
477 return NGX_CONF_OK; |
f0f64973ba2f
auth_basic_user_file supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
2524
diff
changeset
|
478 } |