/** * @param \HTRouter\Request $request * @return int */ public function authenticateDigestUser(\HTRouter\Request $request) { /** * @var $plugin \HTRouter\AuthModule */ $plugin = $this->_container->getConfig()->get("AuthType"); if (!$plugin || !$plugin instanceof \HTRouter\AuthModule || $plugin->getName() != "Digest") { return \HTRouter::STATUS_DECLINED; } // Set our handler type $request->setAuthType($this->getName()); // Not yet available return \HTRouter::STATUS_DECLINED; }
function matchHeaders(\HTRouter\Request $request) { foreach ($this->getConfig()->get("SetEnvIf", array()) as $entry) { $val = ""; switch (strtolower($entry->attribute)) { case "remote_host": $val = $_SERVER['REMOTE_HOST']; break; case "remote_addr": $val = $_SERVER['REMOTE_ADDR']; break; case "server_addr": $val = $_SERVER['SERVER_ADDR']; break; case "request_method": $val = $_SERVER['REQUEST_METHOD']; break; case "request_protocol": $val = $_SERVER['REQUEST_PROTOCOL']; break; case "request_uri": $val = $_SERVER['REQUEST_URI']; break; default: // Match all headers until we find a match $tmp = array_merge($request->getInHeaders(), $this->getRouter()->getEnvironment()); foreach ($tmp as $header => $value) { if ($entry->attribute_is_regex) { // Match against regex $regex = "/" . $entry->attribute . "/"; if (preg_match($regex, $header)) { // Match! $val = $value; break; } } else { // Match direct if (strcmp($entry->attribute, $header) == 0) { // Match! $val = $value; break; } } } break; } // Found a correct value, not check against the actual regex $regex = "/" . $entry->regex . "/"; if ($entry->nocase) { $regex .= "i"; } if (preg_match($regex, $val)) { $this->_addMatch($request, $entry); } } // All done. Proceed to next module return \HTRouter::STATUS_DECLINED; }
/** * These functions should return true|false or something to make sure we can continue with our stuff? * * @param \HTRouter\Request $request * @return bool * @throws \LogicException */ public function checkAccess(\HTRouter\Request $request) { // The way we parse things depends on the "order" switch ($this->getConfig()->get("AccessOrder")) { case self::ALLOW_THEN_DENY: $result = false; if ($this->_findAllowDeny($this->getConfig()->get("AccessAllow"))) { $result = \HTRouter::STATUS_OK; } if ($this->_findAllowDeny($this->getConfig()->get("AccessDeny"))) { $result = \HTRouter::STATUS_HTTP_FORBIDDEN; } break; case self::DENY_THEN_ALLOW: $result = \HTRouter::STATUS_OK; if ($this->_findAllowDeny($this->getConfig()->get("AccessDeny"))) { $result = \HTRouter::STATUS_HTTP_FORBIDDEN; } if ($this->_findAllowDeny($this->getConfig()->get("AccessAllow"))) { $result = \HTRouter::STATUS_OK; } break; case self::MUTUAL_FAILURE: if ($this->_findAllowDeny($this->getConfig()->get("AccessAllow")) and !$this->_findAllowDeny($this->getConfig()->get("AccessDeny"))) { $result = \HTRouter::STATUS_OK; } else { $result = \HTRouter::STATUS_HTTP_FORBIDDEN; } break; default: throw new \LogicException("Unknown order"); break; } // Not ok. Now we need to check if "satisfy any" already got a satisfaction if ($result == \HTRouter::STATUS_HTTP_FORBIDDEN && ($this->getConfig()->get("Satisfy") == "any" || count($this->getConfig()->get("Requires", array()) == 0))) { // Check if there is at least one require line in the htaccess. If found, it means that // we still have to possibility that we can be authorized $this->getLogger()->log(\HTRouter\Logger::ERRORLEVEL_ERROR, "Access denied for " . $request->getFilename() . " / " . $request->getUri()); } // Return what we need to return return $result; }
public function checkUserAccess(\HTRouter\Request $request) { // Any will do, and we are already authenticated through the "allow/deny" rules. No Need to check this. // @TODO: This code must be moved to HTRouter::_run() if ($this->getConfig()->get("Satisfy") == "any" && $request->getAuthorized()) { return \HTRouter\AuthModule::AUTHZ_GRANTED; } $requires = $this->getConfig()->get("Require"); foreach ($requires as $require) { if (strtolower($require) == "valid-user") { // Set the authorized user inside the request $user = $request->getAuthUser(); $request->setAuthUser($user); $request->setAuthorized(true); return \HTRouter\AuthModule::AUTHZ_GRANTED; } // Check if it starts with 'user' $users = explode(" ", $require); $tmp = array_shift($users); if ($tmp != "user") { continue; } // Parse all users on this line to check if it matches against the currently authenticated user foreach ($users as $user) { if ($user == $request->getAuthUser()) { // Set the authorized user inside the request $request->setAuthUser($user); $request->setAuthorized(true); return \HTRouter\AuthModule::AUTHZ_GRANTED; } } } // If the module is authorative we should deny access. This will stop other modules from trying to match.. if ($this->getConfig()->get("AuthzUserAuthoritative") == "on") { return \HTRouter\AuthModule::AUTHZ_DENIED; } // Nothing that matches found, and w return \HTRouter\AuthModule::AUTHZ_NOT_FOUND; }
public function dirFixups(\HTRouter\Request $request) { $filename = $request->getFilename(); if (empty($filename) || is_dir($request->getDocumentRoot() . $filename)) { return $this->_fixup_dir($request); } elseif (!empty($filename) && !file_exists($request->getDocumentRoot() . $filename) && @filetype($request->getDocumentRoot() . $filename) == "unknown") { // @TODO: This must be different FILE_NOT_EXIST return $this->_fixup_dflt($request); } return \HTRouter::STATUS_DECLINED; }
function findUriOnDisk(\HTRouter\Request $request, $url) { return $request->getUri(); }
/** * Returns either int or array[2] with user/pass * * @param $request * @return array|int */ function _getBasicAuth(\HTRouter\Request $request) { // Parse authentication request $auth = $request->getInHeaders("Authorization"); if (!$auth) { return \HTRouter::STATUS_HTTP_UNAUTHORIZED; } list($auth_scheme, $auth_params) = explode(" ", $auth, 2); if (strtolower($auth_scheme) != "basic") { return \HTRouter::STATUS_HTTP_UNAUTHORIZED; } // Split user/pass $auth_params = base64_decode($auth_params); return explode(":", $auth_params, 2); }
/** * Outputs an error message generated from the current request. * * @param HTRouter\Request $request */ protected function _print_error(\HTRouter\Request $request) { echo <<<EOH <html> <head> <title>HTRouter error code: {$request->getStatus()} - {$request->getStatusLine()} </title> </head> <body> <h1>{$request->getStatus()} - {$request->getStatusLine()}</h1> <table> <tr><td>Uri</td><td>:</td><td>{$request->getUri()}<td></tr> <tr><td>DocRoot</td><td>:</td><td>{$request->getDocumentRoot()}<td></tr> <tr><td>Filename</td><td>:</td><td>{$request->getFilename()}<td></tr> </table> </body> </html> EOH; }
function fixUp(\HTRouter\Request $request) { if ($this->getConfig()->get("RewriteEngine") == false) { return \HTRouter::STATUS_DECLINED; } // Temp save $oldFilename = $request->getFilename(); if (!$request->getFilename()) { $request->setFilename($request->getUri()); } $ruleStatus = $this->_applyRewrites(); if ($ruleStatus) { if ($ruleStatus == self::ACTION_STATUS) { $n = $request->getStatus(); $request->setStatus(\HTROUTER::STATUS_HTTP_OK); return $n; } if (($skip = $this->_is_absolute_url($request->getFilename())) > 0) { if ($ruleStatus == self::ACTION_NOESCAPE) { $request->setFilename(urlencode($request->getFilename(), $skip)); } // Add query string if needed if ($request->getArgs()) { if ($ruleStatus == self::ACTION_NOESCAPE) { $request->setFilename($request->getFilename() . "?" . $request->getQueryString()); } else { $request->setFilename($request->getFilename() . "?" . urlencode($request->getQueryString())); } } // Is this a redirect? if ($request->getStatus() >= 300 && $request->getStatus() < 400) { $n = $request->getStatus(); $request->setStatus(\HTRouter::STATUS_HTTP_OK); } else { // No redirect, but we need to redir anyway.. $n = \HTRouter::STATUS_HTTP_MOVED_TEMPORARILY; } // The filename is the URI to redirect.. strange, I know... $request->appendOutHeaders("Location", $request->getFilename()); return $n; } elseif (substr($request->getFilename(), 0, 12) == "passthrough:") { // Starts with passthrough? Let's pass $request->setUri(substr($request->getFilename(), 13)); return \HTRouter::STATUS_DECLINED; } else { // Local path if ($oldFilename == $request->getFilename()) { // Rewrite to the same name. Prevent deadlocks return \HTRouter::STATUS_HTTP_OK; } } } else { $request->getFilename($oldFilename); return \HTRouter::STATUS_DECLINED; } return \HTRouter::STATUS_DECLINED; }
/** * @static * @param $string * @param \HTRouter\Request $request * @param array $ruleMatches * @param array $condMatches * @return mixed * @throws \RuntimeException */ public static function expandSubstitutions($string, \HTRouter\Request $request, $ruleMatches = array(), $condMatches = array()) { // Do backref matching on rewriterule ($1-$9) preg_match_all('|\\$([1-9])|', $string, $matches); foreach ($matches[1] as $index) { if (!isset($ruleMatches[$index - 1])) { throw new \RuntimeException("Want to match index {$index}, but nothing found in rule to match"); } $string = str_replace("\${$index}", $ruleMatches[$index - 1], $string); } // Do backref matching on the last rewritecond (%1-%9) preg_match_all('|\\%([1-9])|', $string, $matches); foreach ($matches[1] as $index) { if (!isset($condMatches[$index - 1])) { throw new \RuntimeException("Want to match index {$index}, but nothing found in condition to match"); } $string = str_replace("%{$index}", $condMatches[$index - 1], $string); } // Do variable substitution $string = str_replace("%{HTTP_USER_AGENT}", $request->getServerVar("HTTP_USER_AGENT"), $string); $string = str_replace("%{HTTP_REFERER}", $request->getServerVar("HTTP_REFERER"), $string); $string = str_replace("%{HTTP_COOKIE}", $request->getServerVar("HTTP_COOKIE"), $string); $string = str_replace("%{HTTP_FORWARDED}", $request->getServerVar("HTTP_FORWARDED"), $string); $string = str_replace("%{HTTP_HOST}", $request->getServerVar("HTTP_HOST"), $string); $string = str_replace("%{HTTP_PROXY_CONNECTION}", $request->getServerVar("HTTP_PROXY_CONNECTION"), $string); $string = str_replace("%{HTTP_ACCEPT}", $request->getServerVar("HTTP_ACCEPT"), $string); $string = str_replace("%{REMOTE_ADDR}", $request->getServerVar("REMOTE_ADDR"), $string); $string = str_replace("%{REMOTE_HOST}", $request->getServerVar("REMOTE_HOST"), $string); $string = str_replace("%{REMOTE_PORT}", $request->getServerVar("REMOTE_PORT"), $string); $string = str_replace("%{REMOTE_USER}", $request->getAuthUser(), $string); $string = str_replace("%{REMOTE_IDENT}", "", $string); // We don't support identing! $string = str_replace("%{REQUEST_METHOD}", $request->getMethod(), $string); $string = str_replace("%{SCRIPT_FILENAME}", $request->getFilename(), $string); $string = str_replace("%{PATH_INFO}", $request->getPathInfo(), $string); $string = str_replace("%{QUERY_STRING}", $request->getQueryString(), $string); if ($request->getAuthType()) { $string = str_replace("%{AUTH_TYPE}", $request->getAuthType()->getName(), $string); // Returns either Basic or Digest } else { $string = str_replace("%{AUTH_TYPE}", "", $string); } $string = str_replace("%{DOCUMENT_ROOT}", $request->getDocumentRoot(), $string); $string = str_replace("%{SERVER_ADMIN}", $request->getServerVar("SERVER_ADMIN"), $string); $string = str_replace("%{SERVER_NAME}", $request->getServerVar("SERVER_NAME"), $string); $string = str_replace("%{SERVER_ADDR}", $request->getServerVar("SERVER_ADDR"), $string); $string = str_replace("%{SERVER_PORT}", $request->getServerVar("SERVER_PORT"), $string); $string = str_replace("%{SERVER_PROTOCOL}", $request->getServerVar("SERVER_PROTOCOL"), $string); $router = \HTRouter::getInstance(); $string = str_replace("%{SERVER_SOFTWARE}", $router->getServerSoftware(), $string); // Non-deterministic, but it won't change over the course of a request, even if the seconds have changed! $string = str_replace("%{TIME_YEAR}", date("Y"), $string); // 2011 $string = str_replace("%{TIME_MON}", date("m"), $string); // 01-12 $string = str_replace("%{TIME_DAY}", date("d"), $string); // 01-31 $string = str_replace("%{TIME_HOUR}", date("H"), $string); // 00-23 $string = str_replace("%{TIME_MIN}", date("i"), $string); // 00-59 $string = str_replace("%{TIME_SEC}", date("s"), $string); // 00-59 $string = str_replace("%{TIME_WDAY}", date("w"), $string); // 0-6 (sun-sat) $string = str_replace("%{TIME}", date("YmdHis"), $string); // %04d%02d%02d%02d%02d%02d $string = str_replace("%{API_VERSION}", $router->getServerApi(), $string); //$string = str_replace("%{THE_REQUEST}", $request->getTheRequest(), $string); // "GET /dir HTTP/1.1" $string = str_replace("%{REQUEST_URI}", $request->getUri(), $string); $string = str_replace("%{REQUEST_FILENAME}", $request->getServerVar("SCRIPT_FILENAME"), $string); $string = str_replace("%{IS_SUBREQ}", $request->isSubRequest() ? "true" : "false", $string); $string = str_replace("%{HTTPS}", $request->isHttps() ? "on" : "off", $string); return $string; }
public function translateName(\HTRouter\Request $request) { // Need an (absolute) url $uri = $request->getUri(); if (empty($uri) || $uri[0] != '/') { return \HTRouter::STATUS_DECLINED; } // check if name matches one of the redirects foreach ($this->getConfig()->get("Redirects", array()) as $redirect) { // @TODO: Check if this is OK? $pos = strpos($request->getUri(), $redirect->urlpath); if ($pos === 0) { $url = $redirect->url . substr($request->getUri(), strlen($redirect->urlpath)); $qs = $request->getQueryString(); if (!empty($qs)) { $url .= '?' . $qs; } $request->appendOutHeaders("Location", $url); return $redirect->http_status; } } return \HTRouter::STATUS_DECLINED; }
/** * ap_directory_walk is really difficult since it needs to be highly optimized. Since we don't need that * optimization and we don't need much of the functionality, I've used some artistic freedom in creating * this method. * * @param \HTRouter\Request $request * @return int */ protected function _directoryWalk(\HTRouter\Request $request) { // No filename found to start from? $fn = $request->getFilename(); if (empty($fn)) { $utils = new \HTrouter\Utils(); $path = $utils->findUriOnDisk($request, $request->getUri()); $request->setFilename($path); return \HTRouter::STATUS_OK; } // get htaccess name from config or constant $config = $this->getRouterConfig("global"); if (isset($config['htaccessfilename'])) { $htaccessFilename = $config['htaccessfilename']; } else { $htaccessFilename = \HTRouter::HTACCESS_FILE; } /* Create an array with the following paths: * * / * /wwwroot * /wwwroot/router * /wwwroot/router/public * * So we can do a simple iteration without worrying about stuff. Easier to reverse the process if needed. */ if ($fn[strlen($fn) - 1] == '/') { // THis is a "directory" (ie: /dir/, so filename is the dirname) $dirname = $fn; } else { // This might be a directory, we should check to see if the file is a directory, if so, it's a dir if (is_dir($request->getDocumentRoot() . $fn)) { $dirname = $fn; } else { // A file, so get the dirname $dirname = dirname($fn); } } $path = explode("/", $dirname); if (empty($path[count($path) - 1])) { array_pop($path); } $dirs = array(); while (count($path) > 0) { $dirs[] = $request->getDocumentRoot() . join("/", $path); array_pop($path); } $dirs = array_unique($dirs); // Just in case... // Iterate directories and find htaccess files foreach ($dirs as $dir) { $htaccessPath = $dir . "/" . $htaccessFilename; if (is_readable($htaccessPath)) { // Read HTACCESS and merge information $newConfig = $this->_readHTAccess($request, $htaccessPath); // Merge together with current request foreach ($this->getRouter()->getModules() as $module) { /** * @var $module \HTRouter\Module */ $module->mergeConfigs($this->getConfig(), $newConfig); } } } return \HTRouter::STATUS_OK; }