diff -bur lighttpd-1.4.19-old/src/mod_access.c lighttpd-1.4.19/src/mod_access.c --- lighttpd-1.4.19-old/src/mod_access.c 2007-06-15 15:46:17.000000000 +0100 +++ lighttpd-1.4.19/src/mod_access.c 2008-06-05 16:10:15.000000000 +0100 @@ -10,6 +10,7 @@ typedef struct { array *access_deny; + array *access_allow; } plugin_config; typedef struct { @@ -41,6 +42,7 @@ plugin_config *s = p->config_storage[i]; array_free(s->access_deny); + array_free(s->access_allow); free(s); } @@ -58,6 +60,7 @@ config_values_t cv[] = { { "url.access-deny", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, + { "url.access-allow", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } }; @@ -68,8 +71,10 @@ s = calloc(1, sizeof(plugin_config)); s->access_deny = array_init(); + s->access_allow = array_init(); cv[0].destination = s->access_deny; + cv[1].destination = s->access_allow; p->config_storage[i] = s; @@ -88,6 +93,7 @@ plugin_config *s = p->config_storage[0]; PATCH(access_deny); + PATCH(access_allow); /* skip the first, the global context */ for (i = 1; i < srv->config_context->used; i++) { @@ -104,6 +110,9 @@ if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.access-deny"))) { PATCH(access_deny); } + if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.access-allow"))) { + PATCH(access_allow); + } } } @@ -136,6 +145,41 @@ "-- mod_access_uri_handler called"); } + for (k = 0; k < p->conf.access_allow->used; k++) { + data_string *ds = (data_string *)p->conf.access_allow->data[k]; + int ct_len = ds->value->used - 1; + int allowed = 0; + + + if (ct_len > s_len) continue; + if (ds->value->used == 0) continue; + + /* if we have a case-insensitive FS we have to lower-case the URI here too */ + + if (con->conf.force_lowercase_filenames) { + if (0 == strncasecmp(con->uri.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) { + allowed = 1; + } + } else { + if (0 == strncmp(con->uri.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) { + allowed = 1; + } + } + + if (allowed) { + return HANDLER_GO_ON; + } + + } + + if (k > 0) { /* have access_allow but none matched */ + con->http_status = 403; + if (con->conf.log_request_handling) + log_error_write(srv, __FILE__, __LINE__, "sb", + "url denied as failed to match any from access_allow"); + return HANDLER_FINISHED; + } + for (k = 0; k < p->conf.access_deny->used; k++) { data_string *ds = (data_string *)p->conf.access_deny->data[k]; int ct_len = ds->value->used - 1;