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