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