static void write_error_response(PHTTP_FILTER_CONTEXT pfc,char *status,char * msg) { char crlf[3] = { (char)13, (char)10, '\0' }; char *ctype = "Content-Type:text/html\r\n\r\n"; DWORD len = strlen(msg); /* reject !!! */ pfc->ServerSupportFunction(pfc, SF_REQ_SEND_RESPONSE_HEADER, status, (DWORD)crlf, (DWORD)ctype); pfc->WriteClient(pfc, msg, &len, 0); }
void GetServerVariable(PHTTP_FILTER_CONTEXT pfc, LPSTR lpszVariable, dynabuf& s, DWORD size=80, bool bRequired=true) throw (bad_alloc, DWORD) { s.erase(); s.reserve(size); size=s.size(); while (!pfc->GetServerVariable(pfc,lpszVariable,s,&size)) { // Grumble. Check the error. DWORD e=GetLastError(); if (e==ERROR_INSUFFICIENT_BUFFER) s.reserve(size); else break; } if (bRequired && s.empty()) throw ERROR_NO_DATA; }
/* * OnPreprocHeaders(): */ static DWORD OnPreprocHeaders ( PHTTP_FILTER_CONTEXT pfc, PHTTP_FILTER_PREPROC_HEADERS pReqHeaders ) { if ( NULL == pfc || NULL == pReqHeaders) { SetLastError( ERROR_INVALID_PARAMETER); return SF_STATUS_REQ_ERROR; } DWORD IPLen; char RemoteIP[] = "0123:4567:89ab:cdef:0123:4567:89ab:cdef"; IPLen = sizeof(RemoteIP); if ( !pfc->GetServerVariable( pfc, "REMOTE_ADDR", (LPVOID) RemoteIP, &IPLen ) ) { return SF_STATUS_REQ_ERROR; } if ( pReqHeaders->AddHeader (pfc, (LPSTR) X_FORWARDED_FOR, (LPSTR) RemoteIP) ) { return SF_STATUS_REQ_NEXT_NOTIFICATION; } else { return SF_STATUS_REQ_ERROR; } }
DWORD WINAPI HttpFilterProc(PHTTP_FILTER_CONTEXT pfc, DWORD notificationType, LPVOID pvNotification) { char url[URL_SIZE]; char host[1024]; char port_buf[80]; int port = 0; unsigned long size; char query = 0; unsigned int query_index = 0; HTTP_FILTER_PREPROC_HEADERS *headers=NULL;; HTTP_FILTER_AUTH_COMPLETE_INFO *AuthComp=NULL;; if (g_is_iis5 < 0) { char version[1024]; size = sizeof(version); g_is_iis5 = 0; if (pfc->GetServerVariable(pfc, "SERVER_SOFTWARE", version, &size)) { LOG(("IIS version %s\n", version)); g_is_iis5 = atof(version + strlen("Microsoft-IIS/")) >= 5.0; } else { LOG(("Can't Get SERVER_SOFTWARE %d\n",GetLastError())); } } switch (notificationType) { case SF_NOTIFY_PREPROC_HEADERS: LOG(("HttpFilterProc: SF_NOTIFY_PREPROC_HEADERS\n")); if (g_is_iis5) break; headers = (HTTP_FILTER_PREPROC_HEADERS *) pvNotification; size = sizeof(host); host[0] = 0; pfc->GetServerVariable(pfc, "SERVER_NAME", host, &size); size = sizeof(port_buf); if (pfc->GetServerVariable(pfc, "SERVER_PORT", port_buf, &size) && size > 0) { port = atoi(port_buf); } size = sizeof(url); if (headers->GetHeader(pfc, "URL", url, &size) && size > 0) { url[size] = 0; for (query_index = 0; query_index < size; query_index++) { if (url[query_index] == '?') { query = url[query_index]; url[query_index] = 0; break; } } DWORD request_time = GetTickCount() / 1000; if (cse_match_request(g_config, host, port, url, 1, request_time) || g_config->enable_caucho_status && ! strcmp(url, "/caucho-status")) { char newurl[SCRIPT_URL_SIZE]; if (! pfc->pFilterContext) { pfc->pFilterContext = pfc->AllocMem(pfc, SCRIPT_URL_SIZE, 0); if (! pfc->pFilterContext) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return SF_STATUS_REQ_ERROR; } ((char *) pfc->pFilterContext)[0] = 0; } url[query_index] = query; strcpy(newurl, ISAPI_SCRIPT); strcat(newurl, url); headers->SetHeader(pfc, "URL", newurl); strcpy((char *) pfc->pFilterContext, url); ((char *) pfc->pFilterContext)[query_index] = 0; } } break; case SF_NOTIFY_AUTH_COMPLETE: LOG(("HttpFilterProc: SF_NOTIFY_AUTH_COMPLETE\n")); AuthComp = (HTTP_FILTER_AUTH_COMPLETE_INFO *) pvNotification; size = sizeof(host); host[0] = 0; pfc->GetServerVariable(pfc, "SERVER_NAME", host, &size); size = sizeof(port_buf); if (pfc->GetServerVariable(pfc, "SERVER_PORT", port_buf, &size) && size > 0) { port = atoi(port_buf); } size = sizeof(url); if (AuthComp->GetHeader(pfc, "URL", url, &size) && size > 0) { url[size] = 0; for (query_index = 0; query_index < size; query_index++) { if (url[query_index] == '?') { query = url[query_index]; url[query_index] = 0; break; } } DWORD request_time = GetTickCount() / 1000; if (cse_match_request(g_config, host, port, url, 1, request_time) || g_config->enable_caucho_status && ! strcmp(url, "/caucho-status")) { char newurl[SCRIPT_URL_SIZE]; if (! pfc->pFilterContext) { pfc->pFilterContext = pfc->AllocMem(pfc, SCRIPT_URL_SIZE, 0); if (! pfc->pFilterContext) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return SF_STATUS_REQ_ERROR; } ((char *) pfc->pFilterContext)[0] = 0; } url[query_index] = query; strcpy(newurl, ISAPI_SCRIPT); strcat(newurl, url); AuthComp->SetHeader(pfc, "URL", newurl); strcpy((char *) pfc->pFilterContext, url); ((char *) pfc->pFilterContext)[query_index] = 0; } } break; case SF_NOTIFY_LOG: LOG(("NOTIFY-LOG %p\n", pfc->pFilterContext)); if (pfc->pFilterContext && ((char *) pfc->pFilterContext)[0]) { char *pch = (char *) pfc->pFilterContext; LOG(("NOTIFY_LOG %s\n", pch ? pch : "null")); HTTP_FILTER_LOG *pLog = (HTTP_FILTER_LOG *) pvNotification; pLog->pszTarget = pch; } break; default: LOG(("Log %d\n", notificationType)); break; } return SF_STATUS_REQ_NEXT_NOTIFICATION; }
DWORD WINAPI HttpFilterProc(PHTTP_FILTER_CONTEXT pfc, DWORD dwNotificationType, LPVOID pvNotification) { jk_env_t *env=NULL; jk_uriEnv_t *uriEnv=NULL; if (!is_inited) { initialize_extension(); } /* 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 && is_mapread) { env = workerEnv->globalEnv->getEnv( workerEnv->globalEnv ); if (auth_notification_flags == dwNotificationType) { char uri[INTERNET_MAX_URL_LENGTH]; char snuri[INTERNET_MAX_URL_LENGTH]="/"; char Host[INTERNET_MAX_URL_LENGTH]; char Translate[INTERNET_MAX_URL_LENGTH]; char Port[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 szTranslate = sizeof(Translate); DWORD szPort = sizeof(Port); int nPort; #ifdef SF_NOTIFY_AUTH_COMPLETE if (auth_notification_flags == SF_NOTIFY_AUTH_COMPLETE) { 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 #endif { GetHeader=((PHTTP_FILTER_PREPROC_HEADERS)pvNotification)->GetHeader; SetHeader=((PHTTP_FILTER_PREPROC_HEADERS)pvNotification)->SetHeader; AddHeader=((PHTTP_FILTER_PREPROC_HEADERS)pvNotification)->AddHeader; } env->l->jkLog(env, env->l, JK_LOG_DEBUG, "HttpFilterProc started\n"); /* * 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)) { env->l->jkLog(env, env->l, JK_LOG_ERROR, "HttpFilterProc error while getting the url\n"); workerEnv->globalEnv->releaseEnv( workerEnv->globalEnv, env ); return SF_STATUS_REQ_ERROR; } if (strlen(uri)) { int rc; char *worker=0; query = strchr(uri, '?'); if (query) { *query++ = '\0'; } rc = jk_requtil_unescapeUrl(uri); jk_requtil_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'; } } nPort = atoi(Port); env->l->jkLog(env, env->l, JK_LOG_DEBUG, "In HttpFilterProc Virtual Host redirection of %s : %s\n", Host, Port); uriEnv = workerEnv->uriMap->mapUri(env, workerEnv->uriMap,Host, nPort, uri ); if( uriEnv!=NULL ) { char *forwardURI; /* This is a servlet, should redirect ... */ /* First check if the request was invalidated at decode */ if (rc == BAD_REQUEST) { env->l->jkLog(env, env->l, JK_LOG_ERROR, "HttpFilterProc [%s] contains one or more invalid escape sequences.\n", uri); write_error_response(pfc,"400 Bad Request", HTML_ERROR_400); workerEnv->globalEnv->releaseEnv( workerEnv->globalEnv, env ); return SF_STATUS_REQ_FINISHED; } else if(rc == BAD_PATH) { env->l->jkLog(env, env->l, JK_LOG_EMERG, "HttpFilterProc [%s] contains forbidden escape sequences.\n", uri); write_error_response(pfc,"403 Forbidden", HTML_ERROR_403); workerEnv->globalEnv->releaseEnv( workerEnv->globalEnv, env ); return SF_STATUS_REQ_FINISHED; } env->l->jkLog(env, env->l, JK_LOG_DEBUG, "HttpFilterProc [%s] is a servlet url - should redirect to %s\n", uri, uriEnv->workerName); /* get URI we should forward */ if( workerEnv->options == JK_OPT_FWDURICOMPATUNPARSED ){ /* get original unparsed URI */ GetHeader(pfc, "url", (LPVOID)uri, (LPDWORD)&sz); /* restore terminator for uri portion */ if (query) *(query - 1) = '\0'; env->l->jkLog(env, env->l, JK_LOG_DEBUG, "HttpFilterProc fowarding original URI [%s]\n",uri); forwardURI = uri; } else if( workerEnv->options == JK_OPT_FWDURIESCAPED ){ if (!jk_requtil_escapeUrl(uri,snuri,INTERNET_MAX_URL_LENGTH)) { env->l->jkLog(env, env->l, JK_LOG_ERROR, "HttpFilterProc [%s] re-encoding request exceeds maximum buffer size.\n", uri); write_error_response(pfc,"400 Bad Request", HTML_ERROR_400); workerEnv->globalEnv->releaseEnv( workerEnv->globalEnv, env ); return SF_STATUS_REQ_FINISHED; } env->l->jkLog(env, env->l, JK_LOG_DEBUG, "HttpFilterProc fowarding escaped URI [%s]\n",snuri); forwardURI = snuri; } else { forwardURI = uri; } if(!AddHeader(pfc, URI_HEADER_NAME, forwardURI) || ( (query != NULL && strlen(query) > 0) ? !AddHeader(pfc, QUERY_HEADER_NAME, query) : FALSE ) || !AddHeader(pfc, WORKER_HEADER_NAME, uriEnv->workerName) || !SetHeader(pfc, "url", extension_uri)) { env->l->jkLog(env, env->l, JK_LOG_ERROR, "HttpFilterProc error while adding request headers\n"); workerEnv->globalEnv->releaseEnv( workerEnv->globalEnv, env ); return SF_STATUS_REQ_ERROR; } /* Move Translate: header to a temporary header so * that the extension proc will be called. * This allows the servlet to handle 'Translate: f'. */ if(GetHeader(pfc, "Translate:", (LPVOID)Translate, (LPDWORD)&szTranslate) && Translate != NULL && szTranslate > 0) { if (!AddHeader(pfc, TOMCAT_TRANSLATE_HEADER_NAME, Translate)) { env->l->jkLog(env, env->l, JK_LOG_ERROR, "HttpFilterProc error while adding Tomcat-Translate headers\n"); workerEnv->globalEnv->releaseEnv( workerEnv->globalEnv, env ); return SF_STATUS_REQ_ERROR; } SetHeader(pfc, "Translate:", NULL); } } else { env->l->jkLog(env, env->l, JK_LOG_DEBUG, "HttpFilterProc [%s] is not a servlet url\n", uri); } /* * Check if somebody is feeding us with his own TOMCAT data headers. * We reject such postings ! */ env->l->jkLog(env, env->l, JK_LOG_DEBUG, "HttpFilterProc check if [%s] is pointing to the web-inf directory\n", uri); if(jk_requtil_uriIsWebInf(uri)) { env->l->jkLog(env, env->l, JK_LOG_EMERG, "HttpFilterProc [%s] points to the web-inf or meta-inf directory.\nSomebody try to hack into the site!!!\n", uri); write_error_response(pfc,"403 Forbidden", HTML_ERROR_403); workerEnv->globalEnv->releaseEnv( workerEnv->globalEnv, env ); return SF_STATUS_REQ_FINISHED; } } } workerEnv->globalEnv->releaseEnv( workerEnv->globalEnv, env ); } return SF_STATUS_REQ_NEXT_NOTIFICATION; }