env = $env; $urlObj = $env->getUrlObj(); $this->url = $urlObj; } public function setConf(array $conf) { $map = array( 'expectedPasswordHash', 'requirePassword' ); foreach ($map as $thisMember) { $key = $thisMember; if (array_key_exists($key, $conf)) { $this->$thisMember = $conf[$key]; } } $this->config = $conf; return $this; } /** * getUrlObj * * @access public * @return Amcsi_HttpProxy_Url */ public function getUrlObj() { return $this->url; } public function isOptSet($optChar) { return $this->url->isOptSet($optChar); } /** * Check if the requested URL is allowed to be requested * * @param string $url * @access private * @return boolean */ private function isUrlAllowed($url) { $ret = false; $isValid = (bool) filter_var($url, FILTER_VALIDATE_URL); if ($isValid) { if (!empty($this->config['allowedBaseUrls'])) { foreach ((array) $this->config['allowedBaseUrls'] as $baseUrl) { $parsedBaseUrl = parse_url($baseUrl); $parsedUrl = parse_url($url); if ($parsedUrl['scheme'] === $parsedBaseUrl['scheme']) { if ($parsedUrl['host'] === $parsedBaseUrl['host']) { /** * Do the rtrim / / stuff so that the baseUrl would treat * slash as its boundary **/ $parsedUrlPath = isset($parsedUrl['path']) ? $parsedUrl['path'] : null; $parsedBaseUrlPath = isset($parsedBaseUrl['path']) ? $parsedBaseUrl['path'] : null; $urlPath = rtrim($parsedUrlPath, '/') . '/'; $baseUrlPath = rtrim($parsedBaseUrlPath, '/') . '/'; if (0 === strpos($urlPath, $baseUrlPath)) { $ret = true; break; } } } } } else { $ret = true; } } return $ret; } public function setOptsString($string) { $optChars = array(); $strlen = strlen($string); for ($i = 0; $i < $strlen; $i++) { $optChars[$string[$i]] = true; } $this->optChars = $optChars; return $this; } /** * It is the URL object whose params should be taken into * account. * * @param mixed $name * @access public * @return void */ public function getParam($name) { return $this->url->getParam($name); } public function dispatch() { $opts = $this->getParam('opts'); $this->setOptsString($opts); $pass = $this->getParam('pass'); $requirePass = $this->requirePassword; if ( !$requirePass || crypt($pass, $this->expectedPasswordHash) === $this->expectedPasswordHash ) { if ($sleep = $this->getParam('sleep')) { sleep($sleep); } $this->_pass = $pass; ini_set('display_errors', true); $url = $this->getUrlObj(); if ($this->isUrlAllowed($url)) { $this->url = $url; $rewriter = new Amcsi_HttpProxy_Rewriter($this->env, $url); $this->rewriter = $rewriter; $proxyResponse = $this->request($url); } else { $proxyResponse = $this->respondForbidden(); } } else { $proxyResponse = $this->respondForbidden(); } foreach ($proxyResponse->getHeaders() as $header) { header($header); } echo $proxyResponse->getContent(); exit(0); } /** * respondForbidden * * @access private * @return Amcsi_HttpProxy_Response */ private function respondForbidden() { $content = 'Forbidden'; $headers = array( "HTTP/1.1 403 Forbidden", "Content-Length: " . strlen($content) ); $returnResponse = new Amcsi_HttpProxy_Response($content, $headers); return $returnResponse; } /** * request * * @param mixed $url * @access public * @return Amcsi_HttpProxy_Response The response to send back to the user */ public function request($url) { $reqHeaders = $this->env->getRequestHeaders(); $headers = array (); foreach ($reqHeaders as $key => $val) { if ('Host' == $key || 'Content-Length' == $key || 'Connection' == $key) { continue; } if ('SOAPAction' == $key) { $headers[] = 'SOAPAction: ' . trim($reqHeaders[$key], '"'); } elseif ('Referer' == $key && $this->isOptSet('r')) { $headers[] = 'Referer: ' . $this->rewriter->reverseReplaceUrl($val); } else { $headers[] = sprintf('%s: %s', $key, $reqHeaders[$key]); } } $headers[] = 'Connection: close'; $request = new Amcsi_HttpProxy_Request; $request->setUrl($url); $parsedUrl = parse_url($url); if (filter_var($parsedUrl['host'], FILTER_VALIDATE_IP)) { // host is IP } else { $headers[] = "Host: $parsedUrl[host]"; } $xForwardedForPrefix = ''; if (!empty($reqHeaders['X-Forwarded-For'])) { $xForwardedForPrefix = $reqHeaders['X-Forwarded-For'] . ', '; } $headers[] = sprintf("X-Forwarded-For: %s%s", $xForwardedForPrefix, $this->env->getEnv('REMOTE_ADDR')); $request->setMethod($this->env->getenv('REQUEST_METHOD')); if ($timeoutMs = $this->getParam('timeoutMs')) { $request->setTimeoutMs($timeoutMs); } $request->setHeaders($headers); $request->setContentAndLength($this->env->getInput()); $this->debugLog('request url', (string) $url); $this->debugLog('request headers', $headers); $response = $request->doRequest(); $this->debugLog('response headers', $response->getHeaders()); $this->debugLog('response content', $response->getContent()); $proxyResponse = $this->response($request, $response); return $proxyResponse; } /** * response * * @param Amcsi_HttpProxy_Request $request * @param Amcsi_HttpProxy_Response $response Response received * @access public * @return Amcsi_HttpProxy_Response Proxied response */ public function response(Amcsi_HttpProxy_Request $request, Amcsi_HttpProxy_Response $response) { $content = $response->getContent(); if ($contentFilters = $this->config['contentFilters']) { foreach ((array) $contentFilters as $contentFilter) { if (is_callable($contentFilter)) { /** * $request and $response are not immutable, so clone them **/ $contentFilterData = new Amcsi_HttpProxy_ContentFilterData( clone $request, clone $response ); $result = call_user_func($contentFilter, $contentFilterData); if (is_string($result)) { $content = $result; } } } } $responseHeaders = $response->getHeaders(); if (false && !$content) { var_dump($reqHeaders); var_dump($opts); var_dump($responseHeaders); } $returnHeaders = array(); $recalculateContentLength = false; if (!empty($responseHeaders)) { foreach ($responseHeaders as $index => $hrh) { if (0 === strpos($hrh, 'Connection:')) { continue; } if (0 === strpos($hrh, 'Set-Cookie:')) { $newHeader = $this->rewriter->rewriteCookieHeader($hrh); $returnHeaders[] = $newHeader; continue; } if (0 === strpos($hrh, 'Content-Type')) { if ($this->isOptSet('u') && false !== strpos($hrh, 'text/')) { $content = $this->rewriter->proxify($content); } } if (0 === strpos($hrh, 'Location:') && $this->isOptSet('u')) { $location = substr($hrh, 10); $proxifiedLocation = $this->rewriter->replaceUrl($location); $returnHeaders[] = "Location: $proxifiedLocation"; } elseif (0 === strpos($hrh, 'Transfer-Encoding: chunked')) { continue; } else if (0 === strpos(strtolower($hrh), 'content-length')) { $recalculateContentLength = true; continue; } else { $returnHeaders[] = $hrh; } } } else { $lastError = error_get_last(); if (false !== strpos($lastError['message'], 'Connection timed out')) { $returnHeaders[] = 'HTTP/1.1 504 Gateway Timeout'; } else { ob_start(); trigger_error(print_r($lastError, true)); ob_end_clean(); $returnHeaders[] = 'HTTP/1.1 500 Internal Server Error'; } } if ($recalculateContentLength) { $returnHeaders[] = "Content-Length: " . strlen($content); } $returnResponse = new Amcsi_HttpProxy_Response($content, $returnHeaders); return $returnResponse; } public function debugLog($label, $value) { if ($this->config['debugLogFile']) { $text = sprintf("%s: %s\n", $label, print_r($value, true)); error_log($text, 3, $this->config['debugLogFile']); } } } __halt_compiler();----SIGNATURE:----KyCTU9wGmYjFDjCMXAVnvjt9VYMN1P31bhMqeoGbn7BrwxTx9mvSvacV/6JmWXCgEOYzsZOUmQzT6zQsd3LUnlYI017jnYGspPiV6+WhBWfqy+BenY8Bmz6P77KeAKmTS938mYbjRuPvtp7wuO5Kn2HwTbQTydzuCEDJ9DyoshHRFNnZaEyx3qAMj+ab/s2ShaeicMDkCH1kEwtYHJYkFwP7vCYbm+sRNjmdQw3Et4ep1MJF0II3fkBuUdxTU2FfNw2YN4qglLPgnm5Jp8nuNdml4zE2pBuBtBmMdIPzrI5q8r0TW5tVA94hch92FrQX2dbzTQrV5oVxw6p/sEfnTHMHTDnXr8m7E5oNgT4o2ctHvOEsA4rfNJxr+oRLgodaZktNwUanOSXGAR61P6TiS1lRIdzyI9hETyQACkwXZpWBWvyJVZfvhTUKIjt0Ap6WkH8a8d5oydOJqLh720SV/EIlKavWB/cOw9nkNZFlL6FJ9P+poLehe6PW5349UKnZvThARB7EbLY3rZ2vlF8XG6UPJTELuJeoVvgXLMuVh/GXfkX+qzoV7aAzYFZQNk5I5ZuOfx2jDU2+W8w5iEsiB9rlM1Cd5zP1OzYWWh7VS4qVhjqu1NtYGPZLDKUrVu0XDueUZ316tEbJWYsQhuHVY8XvXoEUo0qGJhXzpQ9/tYg=----ATTACHMENT:----OTEyNDg2OTA0NDMzNzA3IDU1MDM0NTE2MTkxMjk3ODEgNjI0MTU5ODQ3MDI2NTg0NQ==