Mercurial > hg > nginx-vendor-current
comparison src/http/modules/ngx_http_auth_basic_module.c @ 694:88a1b4797f2e NGINX_1_3_10
nginx 1.3.10
*) Change: domain names specified in configuration file are now resolved
to IPv6 addresses as well as IPv4 ones.
*) Change: now if the "include" directive with mask is used on Unix
systems, included files are sorted in alphabetical order.
*) Change: the "add_header" directive adds headers to 201 responses.
*) Feature: the "geo" directive now supports IPv6 addresses in CIDR
notation.
*) Feature: the "flush" and "gzip" parameters of the "access_log"
directive.
*) Feature: variables support in the "auth_basic" directive.
*) Bugfix: nginx could not be built with the ngx_http_perl_module in
some cases.
*) Bugfix: a segmentation fault might occur in a worker process if the
ngx_http_xslt_module was used.
*) Bugfix: nginx could not be built on MacOSX in some cases.
Thanks to Piotr Sikora.
*) Bugfix: the "limit_rate" directive with high rates might result in
truncated responses on 32-bit platforms.
Thanks to Alexey Antropov.
*) Bugfix: a segmentation fault might occur in a worker process if the
"if" directive was used.
Thanks to Piotr Sikora.
*) Bugfix: a "100 Continue" response was issued with "413 Request Entity
Too Large" responses.
*) Bugfix: the "image_filter", "image_filter_jpeg_quality" and
"image_filter_sharpen" directives might be inherited incorrectly.
Thanks to Ian Babrou.
*) Bugfix: "crypt_r() failed" errors might appear if the "auth_basic"
directive was used on Linux.
*) Bugfix: in backup servers handling.
Thanks to Thomas Chen.
*) Bugfix: proxied HEAD requests might return incorrect response if the
"gzip" directive was used.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Tue, 25 Dec 2012 00:00:00 +0400 |
parents | d0f7a625f27c |
children |
comparison
equal
deleted
inserted
replaced
693:cfd4279acc6e | 694:88a1b4797f2e |
---|---|
18 ngx_str_t passwd; | 18 ngx_str_t passwd; |
19 } ngx_http_auth_basic_ctx_t; | 19 } ngx_http_auth_basic_ctx_t; |
20 | 20 |
21 | 21 |
22 typedef struct { | 22 typedef struct { |
23 ngx_str_t realm; | 23 ngx_http_complex_value_t *realm; |
24 ngx_http_complex_value_t user_file; | 24 ngx_http_complex_value_t user_file; |
25 } ngx_http_auth_basic_loc_conf_t; | 25 } ngx_http_auth_basic_loc_conf_t; |
26 | 26 |
27 | 27 |
28 static ngx_int_t ngx_http_auth_basic_handler(ngx_http_request_t *r); | 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, | 29 static ngx_int_t ngx_http_auth_basic_crypt_handler(ngx_http_request_t *r, |
33 static void ngx_http_auth_basic_close(ngx_file_t *file); | 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); | 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, | 35 static char *ngx_http_auth_basic_merge_loc_conf(ngx_conf_t *cf, |
36 void *parent, void *child); | 36 void *parent, void *child); |
37 static ngx_int_t ngx_http_auth_basic_init(ngx_conf_t *cf); | 37 static ngx_int_t ngx_http_auth_basic_init(ngx_conf_t *cf); |
38 static char *ngx_http_auth_basic(ngx_conf_t *cf, void *post, void *data); | |
39 static char *ngx_http_auth_basic_user_file(ngx_conf_t *cf, ngx_command_t *cmd, | 38 static char *ngx_http_auth_basic_user_file(ngx_conf_t *cf, ngx_command_t *cmd, |
40 void *conf); | 39 void *conf); |
41 | 40 |
42 | |
43 static ngx_conf_post_handler_pt ngx_http_auth_basic_p = ngx_http_auth_basic; | |
44 | 41 |
45 static ngx_command_t ngx_http_auth_basic_commands[] = { | 42 static ngx_command_t ngx_http_auth_basic_commands[] = { |
46 | 43 |
47 { ngx_string("auth_basic"), | 44 { ngx_string("auth_basic"), |
48 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF | 45 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF |
49 |NGX_CONF_TAKE1, | 46 |NGX_CONF_TAKE1, |
50 ngx_conf_set_str_slot, | 47 ngx_http_set_complex_value_slot, |
51 NGX_HTTP_LOC_CONF_OFFSET, | 48 NGX_HTTP_LOC_CONF_OFFSET, |
52 offsetof(ngx_http_auth_basic_loc_conf_t, realm), | 49 offsetof(ngx_http_auth_basic_loc_conf_t, realm), |
53 &ngx_http_auth_basic_p }, | 50 NULL }, |
54 | 51 |
55 { ngx_string("auth_basic_user_file"), | 52 { ngx_string("auth_basic_user_file"), |
56 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF | 53 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF |
57 |NGX_CONF_TAKE1, | 54 |NGX_CONF_TAKE1, |
58 ngx_http_auth_basic_user_file, | 55 ngx_http_auth_basic_user_file, |
101 off_t offset; | 98 off_t offset; |
102 ssize_t n; | 99 ssize_t n; |
103 ngx_fd_t fd; | 100 ngx_fd_t fd; |
104 ngx_int_t rc; | 101 ngx_int_t rc; |
105 ngx_err_t err; | 102 ngx_err_t err; |
106 ngx_str_t pwd, user_file; | 103 ngx_str_t pwd, realm, user_file; |
107 ngx_uint_t i, level, login, left, passwd; | 104 ngx_uint_t i, level, login, left, passwd; |
108 ngx_file_t file; | 105 ngx_file_t file; |
109 ngx_http_auth_basic_ctx_t *ctx; | 106 ngx_http_auth_basic_ctx_t *ctx; |
110 ngx_http_auth_basic_loc_conf_t *alcf; | 107 ngx_http_auth_basic_loc_conf_t *alcf; |
111 u_char buf[NGX_HTTP_AUTH_BUF_SIZE]; | 108 u_char buf[NGX_HTTP_AUTH_BUF_SIZE]; |
115 sw_skip | 112 sw_skip |
116 } state; | 113 } state; |
117 | 114 |
118 alcf = ngx_http_get_module_loc_conf(r, ngx_http_auth_basic_module); | 115 alcf = ngx_http_get_module_loc_conf(r, ngx_http_auth_basic_module); |
119 | 116 |
120 if (alcf->realm.len == 0 || alcf->user_file.value.len == 0) { | 117 if (alcf->realm == NULL || alcf->user_file.value.data == NULL) { |
118 return NGX_DECLINED; | |
119 } | |
120 | |
121 if (ngx_http_complex_value(r, alcf->realm, &realm) != NGX_OK) { | |
122 return NGX_ERROR; | |
123 } | |
124 | |
125 if (realm.len == 3 && ngx_strncmp(realm.data, "off", 3) == 0) { | |
121 return NGX_DECLINED; | 126 return NGX_DECLINED; |
122 } | 127 } |
123 | 128 |
124 ctx = ngx_http_get_module_ctx(r, ngx_http_auth_basic_module); | 129 ctx = ngx_http_get_module_ctx(r, ngx_http_auth_basic_module); |
125 | 130 |
126 if (ctx) { | 131 if (ctx) { |
127 return ngx_http_auth_basic_crypt_handler(r, ctx, &ctx->passwd, | 132 return ngx_http_auth_basic_crypt_handler(r, ctx, &ctx->passwd, |
128 &alcf->realm); | 133 &realm); |
129 } | 134 } |
130 | 135 |
131 rc = ngx_http_auth_basic_user(r); | 136 rc = ngx_http_auth_basic_user(r); |
132 | 137 |
133 if (rc == NGX_DECLINED) { | 138 if (rc == NGX_DECLINED) { |
134 | 139 |
135 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | 140 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
136 "no user/password was provided for basic authentication"); | 141 "no user/password was provided for basic authentication"); |
137 | 142 |
138 return ngx_http_auth_basic_set_realm(r, &alcf->realm); | 143 return ngx_http_auth_basic_set_realm(r, &realm); |
139 } | 144 } |
140 | 145 |
141 if (rc == NGX_ERROR) { | 146 if (rc == NGX_ERROR) { |
142 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 147 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
143 } | 148 } |
231 | 236 |
232 pwd.len = i - passwd; | 237 pwd.len = i - passwd; |
233 pwd.data = &buf[passwd]; | 238 pwd.data = &buf[passwd]; |
234 | 239 |
235 return ngx_http_auth_basic_crypt_handler(r, NULL, &pwd, | 240 return ngx_http_auth_basic_crypt_handler(r, NULL, &pwd, |
236 &alcf->realm); | 241 &realm); |
237 } | 242 } |
238 | 243 |
239 break; | 244 break; |
240 | 245 |
241 case sw_skip: | 246 case sw_skip: |
269 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 274 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
270 } | 275 } |
271 | 276 |
272 ngx_cpystrn(pwd.data, &buf[passwd], pwd.len + 1); | 277 ngx_cpystrn(pwd.data, &buf[passwd], pwd.len + 1); |
273 | 278 |
274 return ngx_http_auth_basic_crypt_handler(r, NULL, &pwd, &alcf->realm); | 279 return ngx_http_auth_basic_crypt_handler(r, NULL, &pwd, &realm); |
275 } | 280 } |
276 | 281 |
277 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | 282 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
278 "user \"%V\" was not found in \"%V\"", | 283 "user \"%V\" was not found in \"%V\"", |
279 &r->headers_in.user, &user_file); | 284 &r->headers_in.user, &user_file); |
280 | 285 |
281 return ngx_http_auth_basic_set_realm(r, &alcf->realm); | 286 return ngx_http_auth_basic_set_realm(r, &realm); |
282 } | 287 } |
283 | 288 |
284 | 289 |
285 static ngx_int_t | 290 static ngx_int_t |
286 ngx_http_auth_basic_crypt_handler(ngx_http_request_t *r, | 291 ngx_http_auth_basic_crypt_handler(ngx_http_request_t *r, |
342 | 347 |
343 | 348 |
344 static ngx_int_t | 349 static ngx_int_t |
345 ngx_http_auth_basic_set_realm(ngx_http_request_t *r, ngx_str_t *realm) | 350 ngx_http_auth_basic_set_realm(ngx_http_request_t *r, ngx_str_t *realm) |
346 { | 351 { |
352 size_t len; | |
353 u_char *basic, *p; | |
354 | |
347 r->headers_out.www_authenticate = ngx_list_push(&r->headers_out.headers); | 355 r->headers_out.www_authenticate = ngx_list_push(&r->headers_out.headers); |
348 if (r->headers_out.www_authenticate == NULL) { | 356 if (r->headers_out.www_authenticate == NULL) { |
349 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 357 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
350 } | 358 } |
351 | 359 |
360 len = sizeof("Basic realm=\"\"") - 1 + realm->len; | |
361 | |
362 basic = ngx_pnalloc(r->pool, len); | |
363 if (basic == NULL) { | |
364 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
365 } | |
366 | |
367 p = ngx_cpymem(basic, "Basic realm=\"", sizeof("Basic realm=\"") - 1); | |
368 p = ngx_cpymem(p, realm->data, realm->len); | |
369 *p = '"'; | |
370 | |
352 r->headers_out.www_authenticate->hash = 1; | 371 r->headers_out.www_authenticate->hash = 1; |
353 ngx_str_set(&r->headers_out.www_authenticate->key, "WWW-Authenticate"); | 372 ngx_str_set(&r->headers_out.www_authenticate->key, "WWW-Authenticate"); |
354 r->headers_out.www_authenticate->value = *realm; | 373 r->headers_out.www_authenticate->value.data = basic; |
374 r->headers_out.www_authenticate->value.len = len; | |
355 | 375 |
356 return NGX_HTTP_UNAUTHORIZED; | 376 return NGX_HTTP_UNAUTHORIZED; |
357 } | 377 } |
358 | 378 |
359 static void | 379 static void |
384 ngx_http_auth_basic_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) | 404 ngx_http_auth_basic_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) |
385 { | 405 { |
386 ngx_http_auth_basic_loc_conf_t *prev = parent; | 406 ngx_http_auth_basic_loc_conf_t *prev = parent; |
387 ngx_http_auth_basic_loc_conf_t *conf = child; | 407 ngx_http_auth_basic_loc_conf_t *conf = child; |
388 | 408 |
389 if (conf->realm.data == NULL) { | 409 if (conf->realm == NULL) { |
390 conf->realm = prev->realm; | 410 conf->realm = prev->realm; |
391 } | 411 } |
392 | 412 |
393 if (conf->user_file.value.len == 0) { | 413 if (conf->user_file.value.data == NULL) { |
394 conf->user_file = prev->user_file; | 414 conf->user_file = prev->user_file; |
395 } | 415 } |
396 | 416 |
397 return NGX_CONF_OK; | 417 return NGX_CONF_OK; |
398 } | 418 } |
416 return NGX_OK; | 436 return NGX_OK; |
417 } | 437 } |
418 | 438 |
419 | 439 |
420 static char * | 440 static char * |
421 ngx_http_auth_basic(ngx_conf_t *cf, void *post, void *data) | |
422 { | |
423 ngx_str_t *realm = data; | |
424 | |
425 size_t len; | |
426 u_char *basic, *p; | |
427 | |
428 if (ngx_strcmp(realm->data, "off") == 0) { | |
429 ngx_str_set(realm, ""); | |
430 return NGX_CONF_OK; | |
431 } | |
432 | |
433 len = sizeof("Basic realm=\"") - 1 + realm->len + 1; | |
434 | |
435 basic = ngx_pnalloc(cf->pool, len); | |
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 | |
447 return NGX_CONF_OK; | |
448 } | |
449 | |
450 | |
451 static char * | |
452 ngx_http_auth_basic_user_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 441 ngx_http_auth_basic_user_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
453 { | 442 { |
454 ngx_http_auth_basic_loc_conf_t *alcf = conf; | 443 ngx_http_auth_basic_loc_conf_t *alcf = conf; |
455 | 444 |
456 ngx_str_t *value; | 445 ngx_str_t *value; |
457 ngx_http_compile_complex_value_t ccv; | 446 ngx_http_compile_complex_value_t ccv; |
458 | 447 |
459 if (alcf->user_file.value.len) { | 448 if (alcf->user_file.value.data) { |
460 return "is duplicate"; | 449 return "is duplicate"; |
461 } | 450 } |
462 | 451 |
463 value = cf->args->elts; | 452 value = cf->args->elts; |
464 | 453 |