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);
}
Beispiel #2
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;
}
Beispiel #3
0
/*
* 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;
	}
}
Beispiel #4
0
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;
}