📄 jk_isapi_plugin.c
字号:
static char *stristr(const char *s, const char *find){ char c, sc; size_t len; if ((c = tolower((unsigned char)(*find++))) != 0) { len = strlen(find); do { do { if ((sc = tolower((unsigned char)(*s++))) == 0) return (NULL); } while (sc != c); } while (strnicmp(s, find, len) != 0); s--; } return ((char *)s);}static int uri_is_web_inf(const char *uri){ if (stristr(uri, "web-inf")) { return JK_TRUE; } if (stristr(uri, "meta-inf")) { return JK_TRUE; } return JK_FALSE;}static void write_error_response(PHTTP_FILTER_CONTEXT pfc, char *status, char *msg){ DWORD len = (DWORD)strlen(msg); /* reject !!! */ pfc->AddResponseHeaders(pfc, CONTENT_TYPE, 0); pfc->ServerSupportFunction(pfc, SF_REQ_SEND_RESPONSE_HEADER, status, 0, 0); pfc->WriteClient(pfc, msg, &len, 0);}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 int num_of_headers){ static char crlf[3] = { (char)13, (char)10, '\0' }; JK_TRACE_ENTER(logger); if (status < 100 || status > 1000) { jk_log(logger, JK_LOG_ERROR, "invalid status %d", status); JK_TRACE_EXIT(logger); return JK_FALSE; } if (s && s->ws_private) { isapi_private_data_t *p = s->ws_private; if (!p->request_started) { size_t len_of_status; char *status_str; char *headers_str; p->request_started = JK_TRUE; /* * Create the status line */ if (!reason) { reason = status_reason(status); } status_str = (char *)_alloca((6 + strlen(reason)) * sizeof(char)); sprintf(status_str, "%d %s", status, reason); len_of_status = strlen(status_str); /* * Create response headers string */ if (num_of_headers) { size_t i, len_of_headers; for (i = 0, len_of_headers = 0; i < num_of_headers; i++) { len_of_headers += strlen(header_names[i]); len_of_headers += strlen(header_values[i]); len_of_headers += 4; /* extra for colon, space and crlf */ } len_of_headers += 3; /* crlf and terminating null char */ headers_str = (char *)_alloca(len_of_headers * sizeof(char)); headers_str[0] = '\0'; for (i = 0; i < num_of_headers; i++) { strcat(headers_str, header_names[i]); strcat(headers_str, ": "); strcat(headers_str, header_values[i]); strcat(headers_str, crlf); } strcat(headers_str, crlf); } else { headers_str = crlf; } if (!p->lpEcb->ServerSupportFunction(p->lpEcb->ConnID, HSE_REQ_SEND_RESPONSE_HEADER, status_str, (LPDWORD) &len_of_status, (LPDWORD) headers_str)) { jk_log(logger, JK_LOG_ERROR, "HSE_REQ_SEND_RESPONSE_HEADER failed"); JK_TRACE_EXIT(logger); return JK_FALSE; } } JK_TRACE_EXIT(logger); return JK_TRUE; } JK_LOG_NULL_PARAMS(logger); JK_TRACE_EXIT(logger); return JK_FALSE;}static int JK_METHOD read(jk_ws_service_t *s, void *b, unsigned int l, unsigned int *a){ JK_TRACE_ENTER(logger); if (s && s->ws_private && b && a) { isapi_private_data_t *p = s->ws_private; *a = 0; if (l) { char *buf = b; DWORD already_read = p->lpEcb->cbAvailable - p->bytes_read_so_far; if (already_read >= l) { memcpy(buf, p->lpEcb->lpbData + p->bytes_read_so_far, l); p->bytes_read_so_far += l; *a = l; } else { /* * Try to copy what we already have */ if (already_read > 0) { memcpy(buf, p->lpEcb->lpbData + p->bytes_read_so_far, already_read); buf += already_read; l -= already_read; p->bytes_read_so_far = p->lpEcb->cbAvailable; *a = already_read; } /* * Now try to read from the client ... */ if (p->lpEcb->ReadClient(p->lpEcb->ConnID, buf, (LPDWORD)&l)) { *a += l; } else { jk_log(logger, JK_LOG_ERROR, "ReadClient failed with %08x", GetLastError()); JK_TRACE_EXIT(logger); return JK_FALSE; } } } JK_TRACE_EXIT(logger); return JK_TRUE; } JK_LOG_NULL_PARAMS(logger); JK_TRACE_EXIT(logger); return JK_FALSE;}static int JK_METHOD write(jk_ws_service_t *s, const void *b, unsigned int l){ JK_TRACE_ENTER(logger); if (s && s->ws_private && b) { isapi_private_data_t *p = s->ws_private; if (l) { unsigned int written = 0; char *buf = (char *)b; if (!p->request_started) { start_response(s, 200, NULL, NULL, NULL, 0); } while (written < l) { DWORD try_to_write = l - written; if (!p->lpEcb->WriteClient(p->lpEcb->ConnID, buf + written, &try_to_write, 0)) { jk_log(logger, JK_LOG_ERROR, "WriteClient failed with %08x", GetLastError()); JK_TRACE_EXIT(logger); return JK_FALSE; } written += try_to_write; } } JK_TRACE_EXIT(logger); return JK_TRUE; } JK_LOG_NULL_PARAMS(logger); JK_TRACE_EXIT(logger); return JK_FALSE;}BOOL WINAPI GetFilterVersion(PHTTP_FILTER_VERSION pVer){ ULONG http_filter_revision = HTTP_FILTER_REVISION; pVer->dwFilterVersion = pVer->dwServerFilterVersion; if (pVer->dwFilterVersion > http_filter_revision) { pVer->dwFilterVersion = http_filter_revision; } pVer->dwFlags = SF_NOTIFY_ORDER_HIGH | SF_NOTIFY_SECURE_PORT | SF_NOTIFY_NONSECURE_PORT | SF_NOTIFY_PREPROC_HEADERS | SF_NOTIFY_LOG | SF_NOTIFY_AUTH_COMPLETE; strcpy(pVer->lpszFilterDesc, VERSION_STRING); if (!is_inited) { return initialize_extension(); } return TRUE;}DWORD WINAPI HttpFilterProc(PHTTP_FILTER_CONTEXT pfc, DWORD dwNotificationType, LPVOID pvNotification){ /* Initialise jk */ if (is_inited && !is_mapread) { char serverName[MAX_SERVERNAME]; DWORD dwLen = sizeof(serverName); if (pfc->GetServerVariable(pfc, SERVER_NAME, serverName, &dwLen)) { if (dwLen > 0) serverName[dwLen - 1] = '\0'; if (init_jk(serverName)) is_mapread = JK_TRUE; } /* If we can't read the map we become dormant */ if (!is_mapread) is_inited = JK_FALSE; } if (is_inited && (iis5 < 0)) { char serverSoftware[256]; DWORD dwLen = sizeof(serverSoftware); iis5 = 0; if (pfc-> GetServerVariable(pfc, SERVER_SOFTWARE, serverSoftware, &dwLen)) { iis5 = (atof(serverSoftware + 14) >= 5.0); if (iis5) { jk_log(logger, JK_LOG_DEBUG, "Detected IIS >= 5.0"); } else { jk_log(logger, JK_LOG_DEBUG, "Detected IIS < 5.0"); } } } if (is_inited && (((SF_NOTIFY_PREPROC_HEADERS == dwNotificationType) && !iis5) || ((SF_NOTIFY_AUTH_COMPLETE == dwNotificationType) && iis5) ) ) { char uri[INTERNET_MAX_URL_LENGTH]; char snuri[INTERNET_MAX_URL_LENGTH] = "/"; char Host[INTERNET_MAX_URL_LENGTH] = ""; char Port[INTERNET_MAX_URL_LENGTH] = ""; char Translate[INTERNET_MAX_URL_LENGTH]; BOOL(WINAPI * GetHeader) (struct _HTTP_FILTER_CONTEXT * pfc, LPSTR lpszName, LPVOID lpvBuffer, LPDWORD lpdwSize); BOOL(WINAPI * SetHeader) (struct _HTTP_FILTER_CONTEXT * pfc, LPSTR lpszName, LPSTR lpszValue); BOOL(WINAPI * AddHeader) (struct _HTTP_FILTER_CONTEXT * pfc, LPSTR lpszName, LPSTR lpszValue); char *query; DWORD sz = sizeof(uri); DWORD szHost = sizeof(Host); DWORD szPort = sizeof(Port); DWORD szTranslate = sizeof(Translate); if (iis5) { GetHeader = ((PHTTP_FILTER_AUTH_COMPLETE_INFO) pvNotification)->GetHeader; SetHeader = ((PHTTP_FILTER_AUTH_COMPLETE_INFO) pvNotification)->SetHeader; AddHeader = ((PHTTP_FILTER_AUTH_COMPLETE_INFO) pvNotification)->AddHeader; } else { GetHeader = ((PHTTP_FILTER_PREPROC_HEADERS) pvNotification)->GetHeader; SetHeader = ((PHTTP_FILTER_PREPROC_HEADERS) pvNotification)->SetHeader; AddHeader = ((PHTTP_FILTER_PREPROC_HEADERS) pvNotification)->AddHeader; } if (JK_IS_DEBUG_LEVEL(logger)) jk_log(logger, JK_LOG_DEBUG, "Filter started"); /* * Just in case somebody set these headers in the request! */ SetHeader(pfc, URI_HEADER_NAME, NULL); SetHeader(pfc, QUERY_HEADER_NAME, NULL); SetHeader(pfc, WORKER_HEADER_NAME, NULL); SetHeader(pfc, TOMCAT_TRANSLATE_HEADER_NAME, NULL); if (!GetHeader(pfc, "url", (LPVOID) uri, (LPDWORD) & sz)) { jk_log(logger, JK_LOG_ERROR, "error while getting the url"); return SF_STATUS_REQ_ERROR; } if (strlen(uri)) { int rc; const char *worker = NULL; query = strchr(uri, '?'); if (query) { *query++ = '\0'; } rc = unescape_url(uri); if (rc == BAD_REQUEST) { jk_log(logger, JK_LOG_ERROR, "[%s] contains one or more invalid escape sequences.", uri); write_error_response(pfc, "400 Bad Request", HTML_ERROR_400); return SF_STATUS_REQ_FINISHED; } else if (rc == BAD_PATH) { jk_log(logger, JK_LOG_EMERG, "[%s] contains forbidden escape sequences.", uri); write_error_response(pfc, "404 Not Found", HTML_ERROR_404); return SF_STATUS_REQ_FINISHED; } getparents(uri); if (pfc-> GetServerVariable(pfc, SERVER_NAME, (LPVOID) Host, (LPDWORD) & szHost)) { if (szHost > 0) { Host[szHost - 1] = '\0'; } } Port[0] = '\0'; if (pfc-> GetServerVariable(pfc, "SERVER_PORT", (LPVOID) Port, (LPDWORD) & szPort)) { if (szPort > 0) { Port[szPort - 1] = '\0'; } } szPort = atoi(Port); if (szPort != 80 && szPort != 443 && szHost > 0) { strcat(Host, ":"); strcat(Host, Port); } if (szHost > 0) { strcat(snuri, Host); strcat(snuri, uri); if (JK_IS_DEBUG_LEVEL(logger)) jk_log(logger, JK_LOG_DEBUG, "Virtual Host redirection of %s", snuri); worker = map_uri_to_worker(uw_map, snuri, logger); } if (!worker) { if (JK_IS_DEBUG_LEVEL(logger)) jk_log(logger, JK_LOG_DEBUG, "Default redirection of %s", uri); worker = map_uri_to_worker(uw_map, uri, logger); } /* * Check if somebody is feading us with his own TOMCAT data headers. * We reject such postings ! */ if (JK_IS_DEBUG_LEVEL(logger)) jk_log(logger, JK_LOG_DEBUG, "check if [%s] is points to the web-inf directory", uri); if (uri_is_web_inf(uri)) { jk_log(logger, JK_LOG_EMERG, "[%s] points to the web-inf or meta-inf directory.\nSomebody try to hack into the site!!!", uri); write_error_response(pfc, "404 Not Found", HTML_ERROR_404);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -