📄 jk_isapi_plugin.c
字号:
/*
* Find the first occurrence of find in s.
*/
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);
return SF_STATUS_REQ_FINISHED;
}
if (worker) {
char *forwardURI;
/* This is a servlet, should redirect ... */
jk_log(logger, JK_LOG_DEBUG,
"[%s] is a servlet url - should redirect to %s",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -