📄 jk_isapi_plugin.c
字号:
/* ========================================================================= * * * * The Apache Software License, Version 1.1 * * * * Copyright (c) 1999-2001 The Apache Software Foundation. * * All rights reserved. * * * * ========================================================================= * * * * Redistribution and use in source and binary forms, with or without modi- * * fication, are permitted provided that the following conditions are met: * * * * 1. Redistributions of source code must retain the above copyright notice * * notice, this list of conditions and the following disclaimer. * * * * 2. Redistributions in binary form must reproduce the above copyright * * notice, this list of conditions and the following disclaimer in the * * documentation and/or other materials provided with the distribution. * * * * 3. The end-user documentation included with the redistribution, if any, * * must include the following acknowlegement: * * * * "This product includes software developed by the Apache Software * * Foundation <http://www.apache.org/>." * * * * Alternately, this acknowlegement may appear in the software itself, if * * and wherever such third-party acknowlegements normally appear. * * * * 4. The names "The Jakarta Project", "Jk", and "Apache Software * * Foundation" must not be used to endorse or promote products derived * * from this software without prior written permission. For written * * permission, please contact <apache@apache.org>. * * * * 5. Products derived from this software may not be called "Apache" nor may * * "Apache" appear in their names without prior written permission of the * * Apache Software Foundation. * * * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES * * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * * THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY * * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * * POSSIBILITY OF SUCH DAMAGE. * * * * ========================================================================= * * * * This software consists of voluntary contributions made by many indivi- * * duals on behalf of the Apache Software Foundation. For more information * * on the Apache Software Foundation, please see <http://www.apache.org/>. * * * * ========================================================================= *//*************************************************************************** * Description: ISAPI plugin for IIS/PWS * * Author: Gal Shachor <shachor@il.ibm.com> * * Author: Larry Isaacs <larryi@apache.org> * * Author: Ignacio J. Ortega <nacho@apache.org> * * Version: $Revision: 1.18 $ * ***************************************************************************/// This define is needed to include wincrypt,h, needed to get client certificates#define _WIN32_WINNT 0x0400#include <httpext.h>#include <httpfilt.h>#include <wininet.h>#include "jk_global.h"#include "jk_util.h"#include "jk_map.h"#include "jk_pool.h"#include "jk_service.h"#include "jk_worker.h"#include "jk_uri_worker_map.h"#define VERSION_STRING "Jakarta/ISAPI/" JK_VERSTRING#define DEFAULT_WORKER_NAME ("ajp13")/* * We use special headers to pass values from the filter to the * extension. These values are: * * 1. The real URI before redirection took place * 2. The name of the worker to be used. * 3. The contents of the Translate header, if any * */#define URI_HEADER_NAME ("TOMCATURI:")#define QUERY_HEADER_NAME ("TOMCATQUERY:")#define WORKER_HEADER_NAME ("TOMCATWORKER:")#define TOMCAT_TRANSLATE_HEADER_NAME ("TOMCATTRANSLATE:")#define CONTENT_LENGTH ("CONTENT_LENGTH:")#define HTTP_URI_HEADER_NAME ("HTTP_TOMCATURI")#define HTTP_QUERY_HEADER_NAME ("HTTP_TOMCATQUERY")#define HTTP_WORKER_HEADER_NAME ("HTTP_TOMCATWORKER")#define REGISTRY_LOCATION ("Software\\Apache Software Foundation\\Jakarta Isapi Redirector\\1.0")#define EXTENSION_URI_TAG ("extension_uri")#define URI_SELECT_TAG ("uri_select")#define URI_SELECT_PARSED_VERB ("parsed")#define URI_SELECT_UNPARSED_VERB ("unparsed")#define URI_SELECT_ESCAPED_VERB ("escaped")#define BAD_REQUEST -1#define BAD_PATH -2#define MAX_SERVERNAME 128#define GET_SERVER_VARIABLE_VALUE(name, place) { \ (place) = NULL; \ huge_buf_sz = sizeof(huge_buf); \ if (get_server_value(private_data->lpEcb, \ (name), \ huge_buf, \ huge_buf_sz, \ "")) { \ (place) = jk_pool_strdup(&private_data->p, huge_buf); \ } \}\#define GET_SERVER_VARIABLE_VALUE_INT(name, place, def) { \ huge_buf_sz = sizeof(huge_buf); \ if (get_server_value(private_data->lpEcb, \ (name), \ huge_buf, \ huge_buf_sz, \ "")) { \ (place) = atoi(huge_buf); \ if (0 == (place)) { \ (place) = def; \ } \ } else { \ (place) = def; \ } \}\static char ini_file_name[MAX_PATH];static int using_ini_file = JK_FALSE;static int is_inited = JK_FALSE;static int is_mapread = JK_FALSE;static int iis5 = -1;static jk_uri_worker_map_t *uw_map = NULL; static jk_logger_t *logger = NULL; static char *SERVER_NAME = "SERVER_NAME";static char *SERVER_SOFTWARE = "SERVER_SOFTWARE";static char extension_uri[INTERNET_MAX_URL_LENGTH] = "/jakarta/isapi_redirect.dll";static char log_file[MAX_PATH * 2];static int log_level = JK_LOG_EMERG_LEVEL;static char worker_file[MAX_PATH * 2];static char worker_mount_file[MAX_PATH * 2];#define URI_SELECT_OPT_PARSED 0#define URI_SELECT_OPT_UNPARSED 1#define URI_SELECT_OPT_ESCAPED 2static int uri_select_option = URI_SELECT_OPT_PARSED;static jk_worker_env_t worker_env;struct isapi_private_data { jk_pool_t p; int request_started; unsigned bytes_read_so_far; LPEXTENSION_CONTROL_BLOCK lpEcb;};typedef struct isapi_private_data isapi_private_data_t;static int JK_METHOD start_response(jk_ws_service_t *s, int status, const char *reason, const char * const *header_names, const char * const *header_values, unsigned num_of_headers);static int JK_METHOD read(jk_ws_service_t *s, void *b, unsigned l, unsigned *a);static int JK_METHOD write(jk_ws_service_t *s, const void *b, unsigned l);static int init_ws_service(isapi_private_data_t *private_data, jk_ws_service_t *s, char **worker_name);static int init_jk(char *serverName);static int initialize_extension(void);static int read_registry_init_data(void);static int get_registry_config_parameter(HKEY hkey, const char *tag, char *b, DWORD sz);static int get_server_value(LPEXTENSION_CONTROL_BLOCK lpEcb, char *name, char *buf, DWORD bufsz, char *def_val);static int base64_encode_cert_len(int len);static int base64_encode_cert(char *encoded, const unsigned char *string, int len);static char x2c(const char *what){ register char digit; digit = ((what[0] >= 'A') ? ((what[0] & 0xdf) - 'A') + 10 : (what[0] - '0')); digit *= 16; digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A') + 10 : (what[1] - '0')); return (digit);}static int unescape_url(char *url){ register int x, y, badesc, badpath; badesc = 0; badpath = 0; for (x = 0, y = 0; url[y]; ++x, ++y) { if (url[y] != '%') url[x] = url[y]; else { if (!isxdigit(url[y + 1]) || !isxdigit(url[y + 2])) { badesc = 1; url[x] = '%'; } else { url[x] = x2c(&url[y + 1]); y += 2; if (url[x] == '/' || url[x] == '\0') badpath = 1; } } } url[x] = '\0'; if (badesc) return BAD_REQUEST; else if (badpath) return BAD_PATH; else return 0;}static void getparents(char *name){ int l, w; /* Four paseses, as per RFC 1808 */ /* a) remove ./ path segments */ for (l = 0, w = 0; name[l] != '\0';) { if (name[l] == '.' && name[l + 1] == '/' && (l == 0 || name[l - 1] == '/')) l += 2; else name[w++] = name[l++]; } /* b) remove trailing . path, segment */ if (w == 1 && name[0] == '.') w--; else if (w > 1 && name[w - 1] == '.' && name[w - 2] == '/') w--; name[w] = '\0'; /* c) remove all xx/../ segments. (including leading ../ and /../) */ l = 0; while (name[l] != '\0') { if (name[l] == '.' && name[l + 1] == '.' && name[l + 2] == '/' && (l == 0 || name[l - 1] == '/')) { register int m = l + 3, n; l = l - 2; if (l >= 0) { while (l >= 0 && name[l] != '/') l--; l++; } else l = 0; n = l; while ((name[n] = name[m])) (++n, ++m); } else ++l; } /* d) remove trailing xx/.. segment. */ if (l == 2 && name[0] == '.' && name[1] == '.') name[0] = '\0'; else if (l > 2 && name[l - 1] == '.' && name[l - 2] == '.' && name[l - 3] == '/') { l = l - 4; if (l >= 0) { while (l >= 0 && name[l] != '/') l--; l++; } else l = 0; name[l] = '\0'; }}/* Apache code to escape a URL */#define T_OS_ESCAPE_PATH (4)static const unsigned char test_char_table[256] = { 0,14,14,14,14,14,14,14,14,14,15,14,14,14,14,14,14,14,14,14, 14,14,14,14,14,14,14,14,14,14,14,14,14,0,7,6,1,6,1,1, 9,9,1,0,8,0,0,10,0,0,0,0,0,0,0,0,0,0,8,15, 15,8,15,15,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,15,15,15,7,0,7,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,15,7,15,1,14,6,6,6,6,6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6 };#define TEST_CHAR(c, f) (test_char_table[(unsigned)(c)] & (f))static const char c2x_table[] = "0123456789abcdef";static unsigned char *c2x(unsigned what, unsigned char *where){ *where++ = '%'; *where++ = c2x_table[what >> 4]; *where++ = c2x_table[what & 0xf]; return where;}static int escape_url(const char *path, char *dest, int destsize){ const unsigned char *s = (const unsigned char *)path; unsigned char *d = (unsigned char *)dest; unsigned char *e = dest + destsize - 1; unsigned char *ee = dest + destsize - 3; unsigned c; while ((c = *s)) { if (TEST_CHAR(c, T_OS_ESCAPE_PATH)) { if (d >= ee ) return JK_FALSE; d = c2x(c, d); } else { if (d >= e ) return JK_FALSE; *d++ = c; } ++s; } *d = '\0'; return JK_TRUE;}static int uri_is_web_inf(char *uri){ char *c = uri; while(*c) { *c = tolower(*c); c++; } if(strstr(uri, "web-inf")) { return JK_TRUE; } if(strstr(uri, "meta-inf")) { return JK_TRUE; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -