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