mturk 2005/03/27 22:34:09 Modified: jk/native/common jk_uri_worker_map.c Log: Major uri worker mapping simplification. Sice we have wildchar matching it can be used for any use case except exact matching. Also added option to use 'double' mappings 'JkMount 'application|/*' will create two mappings at once: 'JkMount /applicantion' and 'JkMount /application/*'. Revision Changes Path 1.51 +60 -345 jakarta-tomcat-connectors/jk/native/common/jk_uri_worker_map.c Index: jk_uri_worker_map.c =================================================================== RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native/common/jk_uri_worker_map.c,v retrieving revision 1.50 retrieving revision 1.51 diff -u -r1.50 -r1.51 --- jk_uri_worker_map.c 21 Feb 2005 11:18:48 -0000 1.50 +++ jk_uri_worker_map.c 28 Mar 2005 06:34:09 -0000 1.51 @@ -74,63 +74,15 @@ return -1; } else if (exp[y] != '?') { - if (icase && tolower(str[x]) != tolower(exp[y])) + if (icase && (tolower(str[x]) != tolower(exp[y]))) return 1; else if (!icase && str[x] != exp[y]) return 1; } } return (str[x] != '\0'); -} - -/* - * We are now in a security nightmare, it maybe that somebody sent - * us a uri that looks like /top-secret.jsp. and the web server will - * fumble and return the jsp content. - * - * To solve that we will check for path info following the suffix, we - * will also check that the end of the uri is not ".suffix.", - * ".suffix/", or ".suffix ". - */ -static int check_security_fraud(jk_uri_worker_map_t *uw_map, const char *uri) -{ - unsigned i; - - for (i = 0; i < uw_map->size; i++) { - if (uw_map->maps[i]->match_type == MATCH_TYPE_SUFFIX) { - char *suffix_start; - for (suffix_start = strstr(uri, uw_map->maps[i]->suffix); - suffix_start; - suffix_start = - strstr(suffix_start + 1, uw_map->maps[i]->suffix)) { - - if ('.' != *(suffix_start - 1)) { - continue; - } - else { - char *after_suffix = - suffix_start + strlen(uw_map->maps[i]->suffix); - - if ((('.' == *after_suffix) || ('/' == *after_suffix) - || (' ' == *after_suffix)) - && (0 == - JK_STRNCMP(uw_map->maps[i]->context, uri, - uw_map->maps[i]->context_len))) { - /* - * Security violation !!! - * this is a fraud. - */ - return i; - } - } - } - } - } - - return -1; } - int uri_worker_map_alloc(jk_uri_worker_map_t **uw_map, jk_map_t *init_data, jk_logger_t *l) { @@ -249,8 +201,8 @@ match_type |= MATCH_TYPE_NO_MATCH; puri++; } - - /* Find if duplicate entry */ + + /* Find if duplicate entry */ for (i = 0; i < uw_map->size; i++) { uwr = uw_map->maps[i]; if (strcmp(uwr->uri, puri) == 0) { @@ -289,7 +241,7 @@ return JK_FALSE; } uwr->suffix = NULL; - + uri = jk_pool_strdup(&uw_map->p, puri); if (!uri || !worker) { jk_log(l, JK_LOG_ERROR, @@ -298,99 +250,28 @@ return JK_FALSE; } - if (uri[0] == '/') { - char *asterisk = strchr(uri, '*'); - - if ((asterisk && strchr(asterisk + 1, '*')) || + if (*uri == '/') { + if (strchr(uri, '*') || strchr(uri, '?')) { - uwr->uri = uri; - /* Lets check if we have multiple - * asterixes in the uri like: + /* Something like * /context/ * /user/ * + * /context/ *.suffix */ - uwr->context = uri; match_type |= MATCH_TYPE_WILDCHAR_PATH; jk_log(l, JK_LOG_DEBUG, - "wild chars path rule %s=%s was added", + "wildchar rule %s=%s was added", uri, worker); } - else if (asterisk) { - uwr->uri = jk_pool_strdup(&uw_map->p, uri); - - if (!uwr->uri) { - jk_log(l, JK_LOG_ERROR, - "can't alloc uri string"); - JK_TRACE_EXIT(l); - return JK_FALSE; - } - /* - * Now, lets check that the pattern is /context/asterisk.suffix - * or /context/asterisk - * we need to have a '/' then a '*' and the a '.' or a - * '/' then a '*' - */ - asterisk--; - if ('/' == asterisk[0]) { - if (0 == strncmp("/*/", uri, 3)) { - /* general context path */ - asterisk[1] = '\0'; - uwr->context = uri; - uwr->suffix = asterisk + 2; - match_type |= MATCH_TYPE_CONTEXT_PATH; - jk_log(l, JK_LOG_DEBUG, - "general context path rule %s*%s=%s was added", - uri, asterisk + 2, worker); - } - else if ('.' == asterisk[2]) { - /* suffix rule */ - asterisk[1] = asterisk[2] = '\0'; - uwr->context = uri; - uwr->suffix = asterisk + 3; - match_type |= MATCH_TYPE_SUFFIX; - jk_log(l, JK_LOG_DEBUG, - "suffix rule %s.%s=%s was added", - uri, asterisk + 3, worker); - } - else if ('\0' != asterisk[2]) { - /* general suffix rule */ - asterisk[1] = '\0'; - uwr->context = uri; - uwr->suffix = asterisk + 2; - match_type |= MATCH_TYPE_GENERAL_SUFFIX; - jk_log(l, JK_LOG_DEBUG, - "general suffix rule %s*%s=%s was added", - uri, asterisk + 2, worker); - } - else { - /* context based */ - asterisk[1] = '\0'; - uwr->context = uri; - match_type |= MATCH_TYPE_CONTEXT; - jk_log(l, JK_LOG_DEBUG, - "match rule %s=%s was added", uri, worker); - } - } - else { - /* Something like : JkMount /servlets/exampl* ajp13 */ - uwr->uri = uri; - uwr->context = uri; - match_type |= MATCH_TYPE_EXACT; - jk_log(l, JK_LOG_DEBUG, - "exact rule %s=%s was added", - uri, worker); - } - - } else { /* Something like: JkMount /login/j_security_check ajp13 */ - uwr->uri = uri; - uwr->context = uri; match_type |= MATCH_TYPE_EXACT; jk_log(l, JK_LOG_DEBUG, "exact rule %s=%s was added", uri, worker); } + uwr->uri = uri; + uwr->context = uri; uwr->worker_name = jk_pool_strdup(&uw_map->p, worker); uwr->context_len = strlen(uwr->context); } @@ -410,7 +291,7 @@ uwr->match_type = match_type; uw_map->maps[uw_map->size] = uwr; uw_map->size++; - if (match_type & MATCH_TYPE_NO_MATCH) { + if (match_type & MATCH_TYPE_NO_MATCH) { /* If we split the mappings this one will be calculated */ uw_map->nosize++; } @@ -491,34 +372,6 @@ return (s - str); } -#if 0 -/* deprecated */ -static void jk_no2slash(char *name) -{ - char *d, *s; - - s = d = name; - -#if defined(HAVE_UNC_PATHS) - /* Check for UNC names. Leave leading two slashes. */ - if (s[0] == '/' && s[1] == '/') - *d++ = *s++; -#endif - - while (*s) { - if ((*d++ = *s) == '/') { - do { - ++s; - } while (*s == '/'); - } - else { - ++s; - } - } - *d = '\0'; -} -#endif - static int is_nomap_match(jk_uri_worker_map_t *uw_map, const char *uri, const char* worker, jk_logger_t *l) @@ -533,7 +386,7 @@ /* Check only nomatch mappings */ if (!(uwr->match_type & MATCH_TYPE_NO_MATCH) || (uwr->match_type & MATCH_TYPE_DISABLED)) - continue; + continue; /* Check only mathing workers */ if (strcmp(uwr->worker_name, worker)) continue; @@ -547,79 +400,21 @@ #endif ) == 0) { jk_log(l, JK_LOG_DEBUG, - "Found a wildchar no match %s -> %s", + "Found a no match %s -> %s", uwr->worker_name, uwr->context); JK_TRACE_EXIT(l); return JK_TRUE; } } else if (JK_STRNCMP(uwr->context, uri, uwr->context_len) == 0) { - if (uwr->match_type & MATCH_TYPE_EXACT) { - if (strlen(uri) == uwr->context_len) { - if (JK_IS_DEBUG_LEVEL(l)) - jk_log(l, JK_LOG_DEBUG, - "Found an exact no match %s -> %s", - uwr->worker_name, uwr->context); - JK_TRACE_EXIT(l); - return JK_TRUE; - } - } - else if (uwr->match_type & MATCH_TYPE_CONTEXT) { + if (strlen(uri) == uwr->context_len) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, - "Found a context no match %s -> %s", - uwr->worker_name, uwr->context); + "Found an exact no match %s -> %s", + uwr->worker_name, uwr->context); JK_TRACE_EXIT(l); return JK_TRUE; } - else if (uwr->match_type & MATCH_TYPE_GENERAL_SUFFIX) { - int suffix_start = last_index_of(uri, uwr->suffix[0]); - if (suffix_start >= 0 - && 0 == JK_STRCMP(uri + suffix_start, uwr->suffix)) { - if (JK_IS_DEBUG_LEVEL(l)) - jk_log(l, JK_LOG_DEBUG, - "Found a general no suffix match for %s -> %s", - uwr->worker_name, uwr->uri); - JK_TRACE_EXIT(l); - return JK_TRUE; - } - } - else if (uwr->match_type & MATCH_TYPE_CONTEXT_PATH) { - char *suffix_path = NULL; - if (strlen(uri) > 1 - && (suffix_path = strchr(uri + 1, '/')) != NULL) { - if (0 == - JK_STRNCMP(suffix_path, uwr->suffix, - strlen(uwr->suffix))) { - jk_log(l, JK_LOG_DEBUG, - "Found a general context no match %s -> %s", - uwr->worker_name, uwr->context); - JK_TRACE_EXIT(l); - return JK_TRUE; - } - } - } - else { /* suffix match */ - size_t suffix_start = strlen(uri) - 1; - - for ( ; suffix_start > 0 && '.' != uri[suffix_start]; - suffix_start--) { - /* TODO: use while loop */ - } - if (uri[suffix_start] == '.') { - const char *suffix = uri + suffix_start + 1; - if (JK_STRCMP(suffix, uwr->suffix) == 0) { - if (uwr->match_type & MATCH_TYPE_NO_MATCH) { - if (JK_IS_DEBUG_LEVEL(l)) - jk_log(l, JK_LOG_DEBUG, - "Found a no suffix match for %s -> %s", - uwr->worker_name, uwr->uri); - JK_TRACE_EXIT(l); - return JK_TRUE; - } - } - } - } } } @@ -632,8 +427,6 @@ char *uri, jk_logger_t *l) { unsigned int i; - int best_match = -1; - size_t longest_match = 0; char *url_rewrite; char rewrite_char = ';'; const char *rv = NULL; @@ -653,19 +446,9 @@ url_rewrite = strstr(uri, JK_PATH_SESSION_IDENTIFIER); if (url_rewrite) { rewrite_char = *url_rewrite; - *url_rewrite = '\0'; + *url_rewrite = '\0'; } -#if 0 - /* XXX: Disable checking for two slashes. - * We should not interfere in the web server - * request processing. - * It is up to the web server or Tomcat to decide if - * the url is valid. - */ - jk_no2slash(uri); -#endif - if (uw_map->fname) uri_worker_map_update(uw_map, l); if (JK_IS_DEBUG_LEVEL(l)) @@ -677,11 +460,9 @@ /* Check for match types */ if ((uwr->match_type & MATCH_TYPE_DISABLED) || - (uwr->match_type & MATCH_TYPE_NO_MATCH) || - (uwr->context_len < longest_match)) { - /* can not be a best match anyway */ + (uwr->match_type & MATCH_TYPE_NO_MATCH)) continue; - } + if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Attempting to map context URI '%s'", uwr->uri); @@ -706,110 +487,18 @@ } } else if (JK_STRNCMP(uwr->context, uri, uwr->context_len) == 0) { - if (uwr->match_type & MATCH_TYPE_EXACT) { - if (strlen(uri) == uwr->context_len) { - if (JK_IS_DEBUG_LEVEL(l)) - jk_log(l, JK_LOG_DEBUG, - "Found an exact match %s -> %s", - uwr->worker_name, uwr->context); - JK_TRACE_EXIT(l); - rv = uwr->worker_name; - goto cleanup; - } - } - else if (uwr->match_type & MATCH_TYPE_CONTEXT) { - if (uwr->context_len > longest_match) { - if (JK_IS_DEBUG_LEVEL(l)) - jk_log(l, JK_LOG_DEBUG, - "Found a context match %s -> %s", - uwr->worker_name, uwr->context); - longest_match = uwr->context_len; - best_match = i; - } - } - else if (uwr->match_type & MATCH_TYPE_GENERAL_SUFFIX) { - int suffix_start = last_index_of(uri, uwr->suffix[0]); - if (suffix_start >= 0 - && 0 == strcmp(uri + suffix_start, uwr->suffix)) { - if (uwr->context_len >= longest_match) { - if (JK_IS_DEBUG_LEVEL(l)) - jk_log(l, JK_LOG_DEBUG, - "Found a general suffix match %s -> *%s", - uwr->worker_name, uwr->suffix); - longest_match = uwr->context_len; - best_match = i; - } - } - } - else if (uwr->match_type & MATCH_TYPE_CONTEXT_PATH) { - char *suffix_path = NULL; - if (strlen(uri) > 1 - && (suffix_path = strchr(uri + 1, '/')) != NULL) { - if (0 == - JK_STRNCMP(suffix_path, uwr->suffix, - strlen(uwr->suffix))) { - if (uwr->context_len >= longest_match) { - if (JK_IS_DEBUG_LEVEL(l)) - jk_log(l, JK_LOG_DEBUG, - "Found a general context path match %s -> *%s", - uwr->worker_name, uwr->suffix); - longest_match = uwr->context_len; - best_match = i; - } - } - } - } - else { /* suffix match */ - - size_t suffix_start = strlen(uri) - 1; - - for ( ; suffix_start > 0 && '.' != uri[suffix_start]; - suffix_start--) { - /* TODO: use while loop */ - } - if (uri[suffix_start] == '.') { - const char *suffix = uri + suffix_start + 1; - /* for WinXX, fix the JsP != jsp problems */ - if (JK_STRCMP(suffix, uwr->suffix) == 0) { - if (uwr->context_len >= longest_match) { - if (JK_IS_DEBUG_LEVEL(l)) - jk_log(l, JK_LOG_DEBUG, - "Found a suffix match %s -> *.%s", - uwr->worker_name, uwr->suffix); - longest_match = uwr->context_len; - best_match = i; - } - } - } + if (strlen(uri) == uwr->context_len) { + if (JK_IS_DEBUG_LEVEL(l)) + jk_log(l, JK_LOG_DEBUG, + "Found an exact match %s -> %s", + uwr->worker_name, uwr->context); + JK_TRACE_EXIT(l); + rv = uwr->worker_name; + goto cleanup; } } } - - if (best_match != -1) { - JK_TRACE_EXIT(l); - rv = uw_map->maps[best_match]->worker_name; - goto cleanup; - } - else { - /* - * We are now in a security nightmare, it maybe that somebody sent - * us a uri that looks like /top-secret.jsp. and the web server will - * fumble and return the jsp content. - * - * To solve that we will check for path info following the suffix, we - * will also check that the end of the uri is not .suffix. - */ - int fraud = check_security_fraud(uw_map, uri); - - if (fraud >= 0) { - jk_log(l, JK_LOG_EMERG, - "Found a security fraud in '%s'", - uri); - JK_TRACE_EXIT(l); - rv = uw_map->maps[fraud]->worker_name; - goto cleanup; - } - } + /* No matches found */ JK_TRACE_EXIT(l); cleanup: @@ -821,7 +510,6 @@ jk_log(l, JK_LOG_DEBUG, "Denying matching for worker %s by nomatch rule", rv); - JK_TRACE_EXIT(l); rv = NULL; } } @@ -837,11 +525,38 @@ jk_map_alloc(&map); if (jk_map_read_properties(map, uw_map->fname, &uw_map->modified)) { - int i; + int i; for (i = 0; i < jk_map_size(map); i++) { const char *u = jk_map_name_at(map, i); const char *w = jk_map_value_at(map, i); - if (!uri_worker_map_add(uw_map, u, w, l)) { + /* Multiple mappings like : + * /servlets-examples|/ * + * will create two mappings: + * /servlets-examples + * and: + * /servlets-examples/ * + */ + if (strchr(u, '|')) { + char *s, *r = strdup(u); + s = strchr(r, '|'); + *s = '\0'; + /* Add first mapping */ + if (!uri_worker_map_add(uw_map, r, w, l)) { + jk_log(l, JK_LOG_ERROR, + "invalid mapping rule %s->%s", r, w); + } + s++; + while (*s) + *(s - 1) = *s++; + *(s - 1) = '\0'; + /* add second mapping */ + if (!uri_worker_map_add(uw_map, r, w, l)) { + jk_log(l, JK_LOG_ERROR, + "invalid mapping rule %s->%s", r, w); + } + free(r); + } + else if (!uri_worker_map_add(uw_map, u, w, l)) { jk_log(l, JK_LOG_ERROR, "invalid mapping rule %s->%s", u, w); @@ -872,7 +587,7 @@ if (statbuf.st_mtime == uw_map->modified) { JK_LEAVE_CS(&(uw_map->cs), rc); return JK_TRUE; - } + } rc = uri_worker_map_load(uw_map, l); JK_LEAVE_CS(&(uw_map->cs), rc); jk_log(l, JK_LOG_INFO,
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]