Mercurial > hg > nginx
comparison src/http/modules/ngx_http_auth_basic_module.c @ 4948:d03712b6914b
The "auth_basic" directive gained support of variables.
author | Ruslan Ermilov <ru@nginx.com> |
---|---|
date | Mon, 10 Dec 2012 13:11:11 +0000 |
parents | 4251e72b8bb4 |
children | c37f34bda5ea |
comparison
equal
deleted
inserted
replaced
4947:4251e72b8bb4 | 4948:d03712b6914b |
---|---|
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.data == NULL) { | 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.data == NULL) { | 413 if (conf->user_file.value.data == NULL) { |
394 conf->user_file = prev->user_file; | 414 conf->user_file = prev->user_file; |
412 } | 432 } |
413 | 433 |
414 *h = ngx_http_auth_basic_handler; | 434 *h = ngx_http_auth_basic_handler; |
415 | 435 |
416 return NGX_OK; | 436 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 | |
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 } | 437 } |
449 | 438 |
450 | 439 |
451 static char * | 440 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) |