Annotation of embedaddon/lighttpd/src/mod_access.c, revision 1.1.1.3
1.1.1.3 ! misho 1: #include "first.h"
! 2:
1.1 misho 3: #include "base.h"
4: #include "log.h"
5: #include "buffer.h"
6:
7: #include "plugin.h"
8:
9: #include <ctype.h>
10: #include <stdlib.h>
11: #include <string.h>
12:
13: typedef struct {
1.1.1.3 ! misho 14: array *access_allow;
1.1 misho 15: array *access_deny;
16: } plugin_config;
17:
18: typedef struct {
19: PLUGIN_DATA;
20:
21: plugin_config **config_storage;
22:
23: plugin_config conf;
24: } plugin_data;
25:
26: INIT_FUNC(mod_access_init) {
27: plugin_data *p;
28:
29: p = calloc(1, sizeof(*p));
30:
31: return p;
32: }
33:
34: FREE_FUNC(mod_access_free) {
35: plugin_data *p = p_d;
36:
37: UNUSED(srv);
38:
39: if (!p) return HANDLER_GO_ON;
40:
41: if (p->config_storage) {
42: size_t i;
43: for (i = 0; i < srv->config_context->used; i++) {
44: plugin_config *s = p->config_storage[i];
45:
1.1.1.3 ! misho 46: if (NULL == s) continue;
! 47:
! 48: array_free(s->access_allow);
1.1 misho 49: array_free(s->access_deny);
50:
51: free(s);
52: }
53: free(p->config_storage);
54: }
55:
56: free(p);
57:
58: return HANDLER_GO_ON;
59: }
60:
61: SETDEFAULTS_FUNC(mod_access_set_defaults) {
62: plugin_data *p = p_d;
63: size_t i = 0;
64:
65: config_values_t cv[] = {
66: { "url.access-deny", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },
1.1.1.3 ! misho 67: { "url.access-allow", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },
1.1 misho 68: { NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
69: };
70:
1.1.1.2 misho 71: p->config_storage = calloc(1, srv->config_context->used * sizeof(plugin_config *));
1.1 misho 72:
73: for (i = 0; i < srv->config_context->used; i++) {
1.1.1.3 ! misho 74: data_config const* config = (data_config const*)srv->config_context->data[i];
1.1 misho 75: plugin_config *s;
76:
77: s = calloc(1, sizeof(plugin_config));
78: s->access_deny = array_init();
1.1.1.3 ! misho 79: s->access_allow = array_init();
1.1 misho 80:
81: cv[0].destination = s->access_deny;
1.1.1.3 ! misho 82: cv[1].destination = s->access_allow;
1.1 misho 83:
84: p->config_storage[i] = s;
85:
1.1.1.3 ! misho 86: if (0 != config_insert_values_global(srv, config->value, cv, i == 0 ? T_CONFIG_SCOPE_SERVER : T_CONFIG_SCOPE_CONNECTION)) {
1.1 misho 87: return HANDLER_ERROR;
88: }
89: }
90:
91: return HANDLER_GO_ON;
92: }
93:
94: #define PATCH(x) \
95: p->conf.x = s->x;
96: static int mod_access_patch_connection(server *srv, connection *con, plugin_data *p) {
97: size_t i, j;
98: plugin_config *s = p->config_storage[0];
99:
1.1.1.3 ! misho 100: PATCH(access_allow);
1.1 misho 101: PATCH(access_deny);
102:
103: /* skip the first, the global context */
104: for (i = 1; i < srv->config_context->used; i++) {
105: data_config *dc = (data_config *)srv->config_context->data[i];
106: s = p->config_storage[i];
107:
108: /* condition didn't match */
109: if (!config_check_cond(srv, con, dc)) continue;
110:
111: /* merge config */
112: for (j = 0; j < dc->value->used; j++) {
113: data_unset *du = dc->value->data[j];
114:
115: if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.access-deny"))) {
116: PATCH(access_deny);
1.1.1.3 ! misho 117: } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("url.access-allow"))) {
! 118: PATCH(access_allow);
1.1 misho 119: }
120: }
121: }
122:
123: return 0;
124: }
125: #undef PATCH
126:
127: /**
128: * URI handler
129: *
130: * we will get called twice:
131: * - after the clean up of the URL and
132: * - after the pathinfo checks are done
133: *
134: * this handles the issue of trailing slashes
135: */
136: URIHANDLER_FUNC(mod_access_uri_handler) {
137: plugin_data *p = p_d;
138: int s_len;
139: size_t k;
140:
1.1.1.3 ! misho 141: if (buffer_is_empty(con->uri.path)) return HANDLER_GO_ON;
1.1 misho 142:
143: mod_access_patch_connection(srv, con, p);
144:
1.1.1.3 ! misho 145: s_len = buffer_string_length(con->uri.path);
1.1 misho 146:
147: if (con->conf.log_request_handling) {
1.1.1.3 ! misho 148: log_error_write(srv, __FILE__, __LINE__, "s",
1.1 misho 149: "-- mod_access_uri_handler called");
150: }
151:
1.1.1.3 ! misho 152: for (k = 0; k < p->conf.access_allow->used; ++k) {
! 153: data_string *ds = (data_string *)p->conf.access_allow->data[k];
! 154: int ct_len = buffer_string_length(ds->value);
! 155: int allowed = 0;
! 156:
! 157: if (ct_len > s_len) continue;
! 158: if (buffer_is_empty(ds->value)) continue;
! 159:
! 160: /* if we have a case-insensitive FS we have to lower-case the URI here too */
! 161:
! 162: if (con->conf.force_lowercase_filenames) {
! 163: if (0 == strncasecmp(con->uri.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) {
! 164: allowed = 1;
! 165: }
! 166: } else {
! 167: if (0 == strncmp(con->uri.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) {
! 168: allowed = 1;
! 169: }
! 170: }
! 171:
! 172: if (allowed) {
! 173: return HANDLER_GO_ON;
! 174: }
! 175: }
! 176:
! 177: if (k > 0) { /* have access_allow but none matched */
! 178: con->http_status = 403;
! 179: con->mode = DIRECT;
! 180:
! 181: if (con->conf.log_request_handling) {
! 182: log_error_write(srv, __FILE__, __LINE__, "sb",
! 183: "url denied as failed to match any from access_allow", con->uri.path);
! 184: }
! 185:
! 186: return HANDLER_FINISHED;
! 187: }
! 188:
1.1 misho 189: for (k = 0; k < p->conf.access_deny->used; k++) {
190: data_string *ds = (data_string *)p->conf.access_deny->data[k];
1.1.1.3 ! misho 191: int ct_len = buffer_string_length(ds->value);
1.1 misho 192: int denied = 0;
193:
194:
195: if (ct_len > s_len) continue;
1.1.1.3 ! misho 196: if (buffer_is_empty(ds->value)) continue;
1.1 misho 197:
198: /* if we have a case-insensitive FS we have to lower-case the URI here too */
199:
200: if (con->conf.force_lowercase_filenames) {
201: if (0 == strncasecmp(con->uri.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) {
202: denied = 1;
203: }
204: } else {
205: if (0 == strncmp(con->uri.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) {
206: denied = 1;
207: }
208: }
209:
210: if (denied) {
211: con->http_status = 403;
212: con->mode = DIRECT;
213:
214: if (con->conf.log_request_handling) {
215: log_error_write(srv, __FILE__, __LINE__, "sb",
216: "url denied as we match:", ds->value);
217: }
218:
219: return HANDLER_FINISHED;
220: }
221: }
222:
223: /* not found */
224: return HANDLER_GO_ON;
225: }
226:
227:
228: int mod_access_plugin_init(plugin *p);
229: int mod_access_plugin_init(plugin *p) {
230: p->version = LIGHTTPD_VERSION_ID;
231: p->name = buffer_init_string("access");
232:
233: p->init = mod_access_init;
234: p->set_defaults = mod_access_set_defaults;
235: p->handle_uri_clean = mod_access_uri_handler;
236: p->handle_subrequest_start = mod_access_uri_handler;
237: p->cleanup = mod_access_free;
238:
239: p->data = NULL;
240:
241: return 0;
242: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>