diff -urNp lighttpd-1.4.8/src/mod_auth.c lighttpd-1.4.8-new/src/mod_auth.c --- lighttpd-1.4.8/src/mod_auth.c 2005-11-15 03:29:48.000000000 -0700 +++ lighttpd-1.4.8-new/src/mod_auth.c 2006-01-04 16:32:03.000000000 -0700 @@ -168,13 +168,14 @@ static int mod_auth_patch_connection(ser } #undef PATCH -static handler_t mod_auth_uri_handler(server *srv, connection *con, void *p_d) { +static handler_t mod_auth_subrequest_handler(server *srv, connection *con, void *p_d) { size_t k; int auth_required = 0, auth_satisfied = 0; char *http_authorization = NULL; data_string *ds; mod_auth_plugin_data *p = p_d; array *req; + buffer *url; /* select the right config */ mod_auth_patch_connection(srv, con, p); @@ -193,11 +194,38 @@ static handler_t mod_auth_uri_handler(se /* search auth-directives for path */ for (k = 0; k < p->conf.auth_require->used; k++) { + data_string *use_physical; if (p->conf.auth_require->data[k]->key->used == 0) continue; - - if (0 == strncmp(con->uri.path->ptr, p->conf.auth_require->data[k]->key->ptr, p->conf.auth_require->data[k]->key->used - 1)) { - auth_required = 1; - break; + + req = ((data_array *)(p->conf.auth_require->data[k]))->value; + use_physical = (data_string *)array_get_element(req, "use_physical"); + if (con->physical.path != NULL && con->physical.path->ptr != NULL && use_physical != NULL && + use_physical->value->ptr != NULL && strcmp(use_physical->value->ptr, "yes") == 0) + { + char resolved_path[PATH_MAX]; + + if (realpath(con->physical.path->ptr, resolved_path) == NULL) continue; + if (strncmp(resolved_path, p->conf.auth_require->data[k]->key->ptr, + p->conf.auth_require->data[k]->key->used - 1) == 0) + { + auth_required = 1; + url = buffer_init(); + buffer_copy_string(url, p->conf.auth_require->data[k]->key->ptr); + break; + } + } + else if (0 == strncmp(con->uri.path->ptr, p->conf.auth_require->data[k]->key->ptr, p->conf.auth_require->data[k]->key->used - 1)) + { + data_string *authority; + authority = (data_string *)array_get_element(req, "authority"); + if (authority == NULL || authority->value->ptr == NULL || + strcmp(authority->value->ptr, con->uri.authority->ptr) == 0) + { + auth_required = 1; + url = buffer_init(); + buffer_copy_string(url, con->uri.path->ptr); + break; + } } } @@ -226,16 +254,17 @@ static handler_t mod_auth_uri_handler(se (0 == strncmp(http_authorization, "Basic", auth_type_len))) { if (0 == strcmp(method->value->ptr, "basic")) { - auth_satisfied = http_auth_basic_check(srv, con, p, req, con->uri.path, auth_realm+1); + auth_satisfied = http_auth_basic_check(srv, con, p, req, url, auth_realm+1); } } else if ((auth_type_len == 6) && (0 == strncmp(http_authorization, "Digest", auth_type_len))) { if (0 == strcmp(method->value->ptr, "digest")) { - if (-1 == (auth_satisfied = http_auth_digest_check(srv, con, p, req, con->uri.path, auth_realm+1))) { + if (-1 == (auth_satisfied = http_auth_digest_check(srv, con, p, req, url, auth_realm+1))) { con->http_status = 400; /* a field was missing */ + buffer_free(url); return HANDLER_FINISHED; } } @@ -274,6 +303,7 @@ static handler_t mod_auth_uri_handler(se } else { /* evil */ } + buffer_free(url); return HANDLER_FINISHED; } else { /* the REMOTE_USER header */ @@ -281,6 +311,7 @@ static handler_t mod_auth_uri_handler(se buffer_copy_string_buffer(con->authed_user, p->auth_user); } + buffer_free(url); return HANDLER_GO_ON; } @@ -384,7 +415,7 @@ SETDEFAULTS_FUNC(mod_auth_set_defaults) for (n = 0; n < da->value->used; n++) { size_t m; data_array *da_file = (data_array *)da->value->data[n]; - const char *method, *realm, *require; + const char *method, *realm, *require, *authority, *use_physical; if (da->value->data[n]->type != TYPE_ARRAY) { log_error_write(srv, __FILE__, __LINE__, "sssbs", @@ -393,7 +424,7 @@ SETDEFAULTS_FUNC(mod_auth_set_defaults) return HANDLER_ERROR; } - method = realm = require = NULL; + method = realm = require = authority = use_physical = NULL; for (m = 0; m < da_file->value->used; m++) { if (da_file->value->data[m]->type == TYPE_STRING) { @@ -403,6 +434,10 @@ SETDEFAULTS_FUNC(mod_auth_set_defaults) realm = ((data_string *)(da_file->value->data[m]))->value->ptr; } else if (0 == strcmp(da_file->value->data[m]->key->ptr, "require")) { require = ((data_string *)(da_file->value->data[m]))->value->ptr; + } else if (0 == strcmp(da_file->value->data[m]->key->ptr, "authority")) { + authority = ((data_string *)(da_file->value->data[m]))->value->ptr; + } else if (0 == strcmp(da_file->value->data[m]->key->ptr, "use_physical")) { + use_physical = ((data_string *)(da_file->value->data[m]))->value->ptr; } else { log_error_write(srv, __FILE__, __LINE__, "sssbs", "unexpected type for key: ", "auth.require", "[", da_file->value->data[m]->key, "](string)"); return HANDLER_ERROR; @@ -462,6 +497,26 @@ SETDEFAULTS_FUNC(mod_auth_set_defaults) buffer_copy_string(ds->value, require); array_insert_unique(a->value, (data_unset *)ds); + + if (authority) + { + ds = data_string_init(); + + buffer_copy_string(ds->key, "authority"); + buffer_copy_string(ds->value, authority); + + array_insert_unique(a->value, (data_unset *)ds); + } + + if (use_physical) + { + ds = data_string_init(); + + buffer_copy_string(ds->key, "use_physical"); + buffer_copy_string(ds->value, use_physical); + + array_insert_unique(a->value, (data_unset *)ds); + } array_insert_unique(s->auth_require, (data_unset *)a); } @@ -609,7 +664,7 @@ int mod_auth_plugin_init(plugin *p) { p->name = buffer_init_string("auth"); p->init = mod_auth_init; p->set_defaults = mod_auth_set_defaults; - p->handle_uri_clean = mod_auth_uri_handler; + p->handle_subrequest_start = mod_auth_subrequest_handler; p->cleanup = mod_auth_free; p->data = NULL;