diff --git a/www/_include.php b/www/_include.php index 8170a99daeee5818802e16bf77199e9c68b9c7c5..b6d81f1ab683e5c7e512eaf93e48c23afb79f4cb 100644 --- a/www/_include.php +++ b/www/_include.php @@ -1,89 +1,96 @@ <?php -/* Remove magic quotes. */ -if(get_magic_quotes_gpc()) { - foreach(array('_GET', '_POST', '_COOKIE', '_REQUEST') as $a) { - if (isset($$a) && is_array($$a)) { - foreach($$a as &$v) { - /* We don't use array-parameters anywhere. - * Ignore any that may appear. - */ - if(is_array($v)) { - continue; - } - /* Unescape the string. */ - $v = stripslashes($v); - } - } - } -} -if (get_magic_quotes_runtime()) { - set_magic_quotes_runtime(FALSE); +/** + * Disable magic quotes if they are enabled. + */ +function removeMagicQuotes() +{ + if (get_magic_quotes_gpc()) { + foreach (array('_GET', '_POST', '_COOKIE', '_REQUEST') as $a) { + if (isset($$a) && is_array($$a)) { + foreach ($$a as &$v) { + // we don't use array-parameters anywhere. Ignore any that may appear + if (is_array($v)) { + continue; + } + // unescape the string + $v = stripslashes($v); + } + } + } + } + if (get_magic_quotes_runtime()) { + set_magic_quotes_runtime(false); + } } +if (version_compare(PHP_VERSION, '5.4.0', '<')) { + removeMagicQuotes(); +} -/* Initialize the autoloader. */ -require_once(dirname(dirname(__FILE__)) . '/lib/_autoload.php'); +// initialize the autoloader +require_once(dirname(dirname(__FILE__)).'/lib/_autoload.php'); -/* Enable assertion handler for all pages. */ +// enable assertion handler for all pages SimpleSAML_Error_Assertion::installHandler(); -/* Show error page on unhandled exceptions. */ -function SimpleSAML_exception_handler(Exception $exception) { - - if ($exception instanceof SimpleSAML_Error_Error) { - $exception->show(); - } else { - $e = new SimpleSAML_Error_Error('UNHANDLEDEXCEPTION', $exception); - $e->show(); - } +// show error page on unhandled exceptions +function SimpleSAML_exception_handler(Exception $exception) +{ + if ($exception instanceof SimpleSAML_Error_Error) { + $exception->show(); + } else { + $e = new SimpleSAML_Error_Error('UNHANDLEDEXCEPTION', $exception); + $e->show(); + } } -set_exception_handler('SimpleSAML_exception_handler'); -/* Log full backtrace on errors and warnings. */ -function SimpleSAML_error_handler($errno, $errstr, $errfile = NULL, $errline = 0, $errcontext = NULL) { - - if (!class_exists('SimpleSAML_Logger')) { - /* We are probably logging a deprecation-warning during parsing. - * Unfortunately, the autoloader is disabled at this point, - * so we should stop here. - * - * See PHP bug: https://bugs.php.net/bug.php?id=47987 - */ - return FALSE; - } +set_exception_handler('SimpleSAML_exception_handler'); +// log full backtrace on errors and warnings +function SimpleSAML_error_handler($errno, $errstr, $errfile = null, $errline = 0, $errcontext = null) +{ + if (!class_exists('SimpleSAML_Logger')) { + /* We are probably logging a deprecation-warning during parsing. Unfortunately, the autoloader is disabled at + * this point, so we should stop here. + * + * See PHP bug: https://bugs.php.net/bug.php?id=47987 + */ + return false; + } - if ($errno & SimpleSAML_Utilities::$logMask || ! ($errno & error_reporting() )) { - /* Masked error. */ - return FALSE; - } + if ($errno & SimpleSAML_Utilities::$logMask || !($errno & error_reporting())) { + // masked error + return false; + } - static $limit = 5; - $limit -= 1; - if ($limit < 0) { - /* We have reached the limit in the number of backtraces we will log. */ - return FALSE; - } + static $limit = 5; + $limit -= 1; + if ($limit < 0) { + // we have reached the limit in the number of backtraces we will log + return false; + } - /* Show an error with a full backtrace. */ - $e = new SimpleSAML_Error_Exception('Error ' . $errno . ' - ' . $errstr); - $e->logError(); + // show an error with a full backtrace + $e = new SimpleSAML_Error_Exception('Error '.$errno.' - '.$errstr); + $e->logError(); - /* Resume normal error processing. */ - return FALSE; + // resume normal error processing + return false; } + set_error_handler('SimpleSAML_error_handler'); -$configdir = dirname(dirname(__FILE__)) . '/config'; -if (!file_exists($configdir . '/config.php')) { - header('Content-Type: text/plain'); - echo("You have not yet created the simpleSAMLphp configuration files.\n"); - echo("See: https://simplesamlphp.org/docs/devel/simplesamlphp-install-repo\n"); - exit(1); +$configdir = dirname(dirname(__FILE__)).'/config'; +if (!file_exists($configdir.'/config.php')) { + header('Content-Type: text/plain'); + echo("You have not yet created the simpleSAMLphp configuration files.\n"); + echo("See: https://simplesamlphp.org/docs/devel/simplesamlphp-install-repo\n"); + exit(1); } -/* Set the timezone. */ +// set the timezone SimpleSAML\Utils\Time::initTimezone(); -/* Disable XML external entity loading explicitly. */ + +// disable XML external entity loading explicitly libxml_disable_entity_loader(); diff --git a/www/authmemcookie.php b/www/authmemcookie.php index b6a1f92b20a36ec4ed54db8f6fadb56c5ac03890..02aedc49a70dc68b8d5d5d2ae05f56fab4944d0b 100644 --- a/www/authmemcookie.php +++ b/www/authmemcookie.php @@ -7,93 +7,91 @@ * The configuration for this script is stored in config/authmemcookie.php. * * The file extra/auth_memcookie.conf contains an example of how Auth Memcookie can be configured - * to use simpleSAMLphp. + * to use SimpleSAMLphp. */ require_once('_include.php'); try { - /* Load simpleSAMLphp configuration. */ - $globalConfig = SimpleSAML_Configuration::getInstance(); - - /* Check if this module is enabled. */ - if(!$globalConfig->getBoolean('enable.authmemcookie', FALSE)) { - throw new SimpleSAML_Error_Error('NOACCESS'); - } - - /* Load Auth MemCookie configuration. */ - $amc = SimpleSAML_AuthMemCookie::getInstance(); - - $sourceId = $amc->getAuthSource(); - $s = new SimpleSAML_Auth_Simple($sourceId); - - /* Check if the user is authorized. We attempt to authenticate the user if not. */ - $s->requireAuth(); - - /* Generate session id and save it in a cookie. */ - $sessionID = SimpleSAML\Utils\Random::generateID(); - - $cookieName = $amc->getCookieName(); - - $sessionHandler = SimpleSAML_SessionHandler::getSessionHandler(); - $sessionHandler->setCookie($cookieName, $sessionID); - - - /* Generate the authentication information. */ - - $attributes = $s->getAttributes(); - - $authData = array(); - - /* Username. */ - $usernameAttr = $amc->getUsernameAttr(); - if(!array_key_exists($usernameAttr, $attributes)) { - throw new Exception('The user doesn\'t have an attribute named \'' . $usernameAttr . - '\'. This attribute is expected to contain the username.'); - } - $authData['UserName'] = $attributes[$usernameAttr]; - - /* Groups. */ - $groupsAttr = $amc->getGroupsAttr(); - if($groupsAttr !== NULL) { - if(!array_key_exists($groupsAttr, $attributes)) { - throw new Exception('The user doesn\'t have an attribute named \'' . $groupsAttr . - '\'. This attribute is expected to contain the groups the user is a member of.'); - } - $authData['Groups'] = $attributes[$groupsAttr]; - } else { - $authData['Groups'] = array(); - } - - $authData['RemoteIP'] = $_SERVER['REMOTE_ADDR']; - - foreach($attributes as $n => $v) { - $authData['ATTR_' . $n] = $v; - } - - - /* Store the authentication data in the memcache server. */ - - $data = ''; - foreach($authData as $n => $v) { - if(is_array($v)) { - $v = implode(':', $v); - } - - $data .= $n . '=' . $v . "\r\n"; - } - - - $memcache = $amc->getMemcache(); - $expirationTime = $s->getAuthData('Expire'); - $memcache->set($sessionID, $data, 0, $expirationTime); - - /* Register logout handler. */ - $session = SimpleSAML_Session::getSessionFromRequest(); - $session->registerLogoutHandler($sourceId, 'SimpleSAML_AuthMemCookie', 'logoutHandler'); - - /* Redirect the user back to this page to signal that the login is completed. */ - \SimpleSAML\Utils\HTTP::redirectTrustedURL(\SimpleSAML\Utils\HTTP::getSelfURL()); -} catch(Exception $e) { - throw new SimpleSAML_Error_Error('CONFIG', $e); + // load SimpleSAMLphp configuration + $globalConfig = SimpleSAML_Configuration::getInstance(); + + // check if this module is enabled + if (!$globalConfig->getBoolean('enable.authmemcookie', false)) { + throw new SimpleSAML_Error_Error('NOACCESS'); + } + + // load Auth MemCookie configuration + $amc = SimpleSAML_AuthMemCookie::getInstance(); + + $sourceId = $amc->getAuthSource(); + $s = new SimpleSAML_Auth_Simple($sourceId); + + // check if the user is authorized. We attempt to authenticate the user if not + $s->requireAuth(); + + // generate session id and save it in a cookie + $sessionID = SimpleSAML\Utils\Random::generateID(); + + $cookieName = $amc->getCookieName(); + + $sessionHandler = SimpleSAML_SessionHandler::getSessionHandler(); + $sessionHandler->setCookie($cookieName, $sessionID); + + // generate the authentication information + $attributes = $s->getAttributes(); + + $authData = array(); + + // username + $usernameAttr = $amc->getUsernameAttr(); + if (!array_key_exists($usernameAttr, $attributes)) { + throw new Exception( + "The user doesn't have an attribute named '".$usernameAttr. + "'. This attribute is expected to contain the username." + ); + } + $authData['UserName'] = $attributes[$usernameAttr]; + + // groups + $groupsAttr = $amc->getGroupsAttr(); + if ($groupsAttr !== null) { + if (!array_key_exists($groupsAttr, $attributes)) { + throw new Exception( + "The user doesn't have an attribute named '".$groupsAttr. + "'. This attribute is expected to contain the groups the user is a member of." + ); + } + $authData['Groups'] = $attributes[$groupsAttr]; + } else { + $authData['Groups'] = array(); + } + + $authData['RemoteIP'] = $_SERVER['REMOTE_ADDR']; + + foreach ($attributes as $n => $v) { + $authData['ATTR_'.$n] = $v; + } + + // store the authentication data in the memcache server + $data = ''; + foreach ($authData as $n => $v) { + if (is_array($v)) { + $v = implode(':', $v); + } + $data .= $n.'='.$v."\r\n"; + } + + $memcache = $amc->getMemcache(); + $expirationTime = $s->getAuthData('Expire'); + $memcache->set($sessionID, $data, 0, $expirationTime); + + // register logout handler + $session = SimpleSAML_Session::getSessionFromRequest(); + $session->registerLogoutHandler($sourceId, 'SimpleSAML_AuthMemCookie', 'logoutHandler'); + + // redirect the user back to this page to signal that the login is completed + \SimpleSAML\Utils\HTTP::redirectTrustedURL(\SimpleSAML\Utils\HTTP::getSelfURL()); +} catch (Exception $e) { + throw new SimpleSAML_Error_Error('CONFIG', $e); } diff --git a/www/errorreport.php b/www/errorreport.php index 042f9a6131aad598a90f4795d67e938bfea19f23..723b3e7015eaa6552b5207286d8320ea5b775573 100644 --- a/www/errorreport.php +++ b/www/errorreport.php @@ -4,99 +4,117 @@ require_once('_include.php'); $config = SimpleSAML_Configuration::getInstance(); -/* This page will redirect to itself after processing a POST request and sending the email. */ -if($_SERVER['REQUEST_METHOD'] !== 'POST') { - /* The message has been sent. Show error report page. */ +// this page will redirect to itself after processing a POST request and sending the email +if ($_SERVER['REQUEST_METHOD'] !== 'POST') { + // the message has been sent. Show error report page - $t = new SimpleSAML_XHTML_Template($config, 'errorreport.php', 'errors'); - $t->show(); - exit; + $t = new SimpleSAML_XHTML_Template($config, 'errorreport.php', 'errors'); + $t->show(); + exit; } -$reportId = (string)$_REQUEST['reportId']; -$email = (string)$_REQUEST['email']; -$text = htmlspecialchars((string)$_REQUEST['text']); +$reportId = (string) $_REQUEST['reportId']; +$email = (string) $_REQUEST['email']; +$text = htmlspecialchars((string) $_REQUEST['text']); +$data = null; try { - $session = SimpleSAML_Session::getSessionFromRequest(); - $data = $session->getData('core:errorreport', $reportId); + $session = SimpleSAML_Session::getSessionFromRequest(); + $data = $session->getData('core:errorreport', $reportId); } catch (Exception $e) { - SimpleSAML_Logger::error('Error loading error report data: ' . var_export($e->getMessage(), TRUE)); + SimpleSAML_Logger::error('Error loading error report data: '.var_export($e->getMessage(), true)); } -if ($data === NULL) { - $data = array( - 'exceptionMsg' => 'not set', - 'exceptionTrace' => 'not set', - 'reportId' => $reportId, - 'trackId' => 'not set', - 'url' => 'not set', - 'version' => $config->getVersion(), - 'referer' => 'not set', - ); - - if (isset($session)) { - $data['trackId'] = $session->getTrackID(); - } +if ($data === null) { + $data = array( + 'exceptionMsg' => 'not set', + 'exceptionTrace' => 'not set', + 'reportId' => $reportId, + 'trackId' => 'not set', + 'url' => 'not set', + 'version' => $config->getVersion(), + 'referer' => 'not set', + ); + + if (isset($session)) { + $data['trackId'] = $session->getTrackID(); + } } foreach ($data as $k => $v) { - $data[$k] = htmlspecialchars($v); + $data[$k] = htmlspecialchars($v); } -/* Build the email message. */ - -$message = '<h1>SimpleSAMLphp Error Report</h1> +// build the email message +$message = <<<MESSAGE +<h1>SimpleSAMLphp Error Report</h1> <p>Message from user:</p> -<div class="box" style="background: yellow; color: #888; border: 1px solid #999900; padding: .4em; margin: .5em">' . htmlspecialchars($text) . '</div> +<div class="box" style="background: yellow; color: #888; border: 1px solid #999900; padding: .4em; margin: .5em"> + %s +</div> -<p>Exception: <strong>' . $data['exceptionMsg'] . '</strong></p> -<pre>' . $data['exceptionTrace'] . '</pre> +<p>Exception: <strong>%s</strong></p> +<pre>%s</pre> <p>URL:</p> -<pre><a href="' . $data['url'] . '">' . $data['url'] . '</a></pre> +<pre><a href="%s">%s</a></pre> <p>Host:</p> -<pre>' . htmlspecialchars(php_uname('n')) . '</pre> +<pre>%s</pre> <p>Directory:</p> -<pre>' . dirname(dirname(__FILE__)) . '</pre> +<pre>%s</pre> <p>Track ID:</p> -<pre>' . $data['trackId'] . '</pre> +<pre>%s</pre> -<p>Version: <tt>' . $data['version'] . '</tt></p> +<p>Version: <tt>%s</tt></p> -<p>Report ID: <tt>' . $data['reportId'] . '</tt></p> +<p>Report ID: <tt>%s</tt></p> -<p>Referer: <tt>' . $data['referer'] . '</tt></p> +<p>Referer: <tt>%s</tt></p> <hr /> -<div class="footer">This message was sent using simpleSAMLphp. Visit the <a href="http://simplesamlphp.org/">simpleSAMLphp homepage</a>.</div> - -'; - - -/* Add the email address of the submitter as the Reply-To address. */ +<div class="footer"> + This message was sent using SimpleSAMLphp. Visit the <a href="http://simplesamlphp.org/">SimpleSAMLphp homepage</a>. +</div> +MESSAGE; +$message = sprintf( + $message, + htmlspecialchars($text), + $data['exceptionMsg'], + $data['exceptionTrace'], + $data['url'], + $data['url'], + htmlspecialchars(php_uname('n')), + dirname(dirname(__FILE__)), + $data['trackId'], + $data['version'], + $data['reportId'], + $data['referer'] +); + +// add the email address of the submitter as the Reply-To address $email = trim($email); -/* Check that it looks like a valid email address. */ -if (!preg_match('/\s/', $email) && strpos($email, '@') !== FALSE) { - $replyto = $email; - $from = $email; + +// check that it looks like a valid email address +if (!preg_match('/\s/', $email) && strpos($email, '@') !== false) { + $replyto = $email; + $from = $email; } else { - $replyto = NULL; - $from = 'no-reply@simplesamlphp.org'; + $replyto = null; + $from = 'no-reply@simplesamlphp.org'; } -/* Send the email. */ +// send the email $toAddress = $config->getString('technicalcontact_email', 'na@example.org'); -if ($config->getBoolean('errorreporting', TRUE) && $toAddress !== 'na@example.org') { - $email = new SimpleSAML_XHTML_EMail($toAddress, 'simpleSAMLphp error report', $from); - $email->setBody($message); - $email->send(); - SimpleSAML_Logger::error('Report with id ' . $reportId . ' sent to <' . $toAddress . '>.'); +if ($config->getBoolean('errorreporting', true) && $toAddress !== 'na@example.org') { + $email = new SimpleSAML_XHTML_EMail($toAddress, 'SimpleSAMLphp error report', $from); + $email->setBody($message); + $email->send(); + SimpleSAML_Logger::error('Report with id '.$reportId.' sent to <'.$toAddress.'>.'); } -/* Redirect the user back to this page to clear the POST request. */ +// redirect the user back to this page to clear the POST request \SimpleSAML\Utils\HTTP::redirectTrustedURL(\SimpleSAML\Utils\HTTP::getSelfURLNoQuery()); diff --git a/www/logout.php b/www/logout.php index c361b29ec25326721834fcdc47c81268201089ac..220449af3eb27ae577ed8472fcfea48f9086b85b 100644 --- a/www/logout.php +++ b/www/logout.php @@ -4,17 +4,17 @@ require_once('_include.php'); $config = SimpleSAML_Configuration::getInstance(); -if(array_key_exists('link_href', $_REQUEST)) { - $link = (string)$_REQUEST['link_href']; - $link = \SimpleSAML\Utils\HTTP::normalizeURL($link); +if (array_key_exists('link_href', $_REQUEST)) { + $link = (string) $_REQUEST['link_href']; + $link = \SimpleSAML\Utils\HTTP::normalizeURL($link); } else { - $link = 'index.php'; + $link = 'index.php'; } -if(array_key_exists('link_text', $_REQUEST)) { - $text = $_REQUEST['link_text']; +if (array_key_exists('link_text', $_REQUEST)) { + $text = $_REQUEST['link_text']; } else { - $text = '{logout:default_link_text}'; + $text = '{logout:default_link_text}'; } $t = new SimpleSAML_XHTML_Template($config, 'logout.php'); @@ -22,5 +22,3 @@ $t->data['link'] = $link; $t->data['text'] = $text; $t->show(); exit(); - -?> \ No newline at end of file diff --git a/www/module.php b/www/module.php index 406191fb4d4b4091de6136abb652cca3ad712111..66baa3ddd89b846c0accb59d80692afa3216a864 100644 --- a/www/module.php +++ b/www/module.php @@ -6,179 +6,167 @@ * the RequestHandler in the module. * * @author Olav Morken, UNINETT AS. - * @package simpleSAMLphp + * @package SimpleSAMLphp */ require_once('_include.php'); -/* Index pages - filenames to attempt when accessing directories. */ +// index pages - file names to attempt when accessing directories $indexFiles = array('index.php', 'index.html', 'index.htm', 'index.txt'); -/* MIME types - key is file extension, value is MIME type. */ +// MIME types - key is file extension, value is MIME type $mimeTypes = array( - 'bmp' => 'image/x-ms-bmp', - 'css' => 'text/css', - 'gif' => 'image/gif', - 'htm' => 'text/html', - 'html' => 'text/html', - 'shtml' => 'text/html', - 'ico' => 'image/vnd.microsoft.icon', - 'jpe' => 'image/jpeg', - 'jpeg' => 'image/jpeg', - 'jpg' => 'image/jpeg', - 'js' => 'text/javascript', - 'pdf' => 'application/pdf', - 'png' => 'image/png', - 'svg' => 'image/svg+xml', - 'svgz' => 'image/svg+xml', - 'swf' => 'application/x-shockwave-flash', - 'swfl' => 'application/x-shockwave-flash', - 'txt' => 'text/plain', - 'xht' => 'application/xhtml+xml', - 'xhtml' => 'application/xhtml+xml', - ); + 'bmp' => 'image/x-ms-bmp', + 'css' => 'text/css', + 'gif' => 'image/gif', + 'htm' => 'text/html', + 'html' => 'text/html', + 'shtml' => 'text/html', + 'ico' => 'image/vnd.microsoft.icon', + 'jpe' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'js' => 'text/javascript', + 'pdf' => 'application/pdf', + 'png' => 'image/png', + 'svg' => 'image/svg+xml', + 'svgz' => 'image/svg+xml', + 'swf' => 'application/x-shockwave-flash', + 'swfl' => 'application/x-shockwave-flash', + 'txt' => 'text/plain', + 'xht' => 'application/xhtml+xml', + 'xhtml' => 'application/xhtml+xml', +); try { - if (empty($_SERVER['PATH_INFO'])) { - throw new SimpleSAML_Error_NotFound('No PATH_INFO to module.php'); - } - - $url = $_SERVER['PATH_INFO']; - assert('substr($url, 0, 1) === "/"'); - - /* Clear the PATH_INFO option, so that a script can detect whether it is called - * with anything following the '.php'-ending. - */ - unset($_SERVER['PATH_INFO']); - - $modEnd = strpos($url, '/', 1); - if ($modEnd === FALSE) { - /* The path must always be on the form /module/. */ - throw new SimpleSAML_Error_NotFound('The URL must at least contain a module name followed by a slash.'); - } - - $module = substr($url, 1, $modEnd - 1); - $url = substr($url, $modEnd + 1); - if ($url === FALSE) { - $url = ''; - } - - if (!SimpleSAML_Module::isModuleEnabled($module)) { - throw new SimpleSAML_Error_NotFound('The module \'' . $module . - '\' was either not found, or wasn\'t enabled.'); - } - - /* Make sure that the request isn't suspicious (contains references to current - * directory or parent directory or anything like that. Searching for './' in the - * URL will detect both '../' and './'. Searching for '\' will detect attempts to - * use Windows-style paths. - */ - if (strpos($url, '\\') !== FALSE) { - throw new SimpleSAML_Error_BadRequest('Requested URL contained a backslash.'); - } elseif (strpos($url, './') !== FALSE) { - throw new SimpleSAML_Error_BadRequest('Requested URL contained \'./\'.'); - } - - $moduleDir = SimpleSAML_Module::getModuleDir($module) . '/www/'; - - /* Check for '.php/' in the path, the presence of which indicates that another php-script - * should handle the request. - */ - for ($phpPos = strpos($url, '.php/'); $phpPos !== FALSE; $phpPos = strpos($url, '.php/', $phpPos + 1)) { - - $newURL = substr($url, 0, $phpPos + 4); - $param = substr($url, $phpPos + 4); - - if (is_file($moduleDir . $newURL)) { - /* $newPath points to a normal file. Point execution to that file, and - * save the remainder of the path in PATH_INFO. - */ - $url = $newURL; - $_SERVER['PATH_INFO'] = $param; - break; - } - } - - $path = $moduleDir . $url; - - if ($path[strlen($path)-1] === '/') { - /* Path ends with a slash - directory reference. Attempt to find index file - * in directory. - */ - foreach ($indexFiles as $if) { - if (file_exists($path . $if)) { - $path .= $if; - break; - } - } - } - - if (is_dir($path)) { - /* Path is a directory - maybe no index file was found in the previous step, or - * maybe the path didn't end with a slash. Either way, we don't do directory - * listings. - */ - throw new SimpleSAML_Error_NotFound('Directory listing not available.'); - } - - if (!file_exists($path)) { - /* File not found. */ - SimpleSAML_Logger::info('Could not find file \'' . $path . '\'.'); - throw new SimpleSAML_Error_NotFound('The URL wasn\'t found in the module.'); - } - - if (preg_match('#\.php$#D', $path)) { - /* PHP file - attempt to run it. */ - $_SERVER['SCRIPT_NAME'] .= '/' . $module . '/' . $url; - require($path); - exit(); - } - - /* Some other file type - attempt to serve it. */ - - /* Find MIME type for file, based on extension. */ - $contentType = NULL; - if (preg_match('#\.([^/\.]+)$#D', $path, $type)) { - $type = strtolower($type[1]); - if (array_key_exists($type, $mimeTypes)) { - $contentType = $mimeTypes[$type]; - } - } - - if ($contentType === NULL) { - /* We were unable to determine the MIME type from the file extension. Fall back - * to mime_content_type (if it exists). - */ - if (function_exists('mime_content_type')) { - $contentType = mime_content_type($path); - } else { - /* mime_content_type doesn't exist. Return a default MIME type. */ - SimpleSAML_Logger::warning('Unable to determine mime content type of file: ' . $path); - $contentType = 'application/octet-stream'; - } - } - - $contentLength = sprintf('%u', filesize($path)); /* Force filesize to an unsigned number. */ - - header('Content-Type: ' . $contentType); - header('Content-Length: ' . $contentLength); - header('Cache-Control: public,max-age=86400'); - header('Expires: ' . gmdate('D, j M Y H:i:s \G\M\T', time() + 10*60)); - header('Last-Modified: ' . gmdate('D, j M Y H:i:s \G\M\T', filemtime($path))); - - readfile($path); - exit(); - -} catch(SimpleSAML_Error_Error $e) { - - $e->show(); - -} catch(Exception $e) { - - $e = new SimpleSAML_Error_Error('UNHANDLEDEXCEPTION', $e); - $e->show(); - + if (empty($_SERVER['PATH_INFO'])) { + throw new SimpleSAML_Error_NotFound('No PATH_INFO to module.php'); + } + + $url = $_SERVER['PATH_INFO']; + assert('substr($url, 0, 1) === "/"'); + + /* clear the PATH_INFO option, so that a script can detect whether it is called with anything following the + *'.php'-ending. + */ + unset($_SERVER['PATH_INFO']); + + $modEnd = strpos($url, '/', 1); + if ($modEnd === false) { + // the path must always be on the form /module/ + throw new SimpleSAML_Error_NotFound('The URL must at least contain a module name followed by a slash.'); + } + + $module = substr($url, 1, $modEnd - 1); + $url = substr($url, $modEnd + 1); + if ($url === false) { + $url = ''; + } + + if (!SimpleSAML_Module::isModuleEnabled($module)) { + throw new SimpleSAML_Error_NotFound('The module \''.$module.'\' was either not found, or wasn\'t enabled.'); + } + + /* Make sure that the request isn't suspicious (contains references to current directory or parent directory or + * anything like that. Searching for './' in the URL will detect both '../' and './'. Searching for '\' will detect + * attempts to use Windows-style paths. + */ + if (strpos($url, '\\') !== false) { + throw new SimpleSAML_Error_BadRequest('Requested URL contained a backslash.'); + } elseif (strpos($url, './') !== false) { + throw new SimpleSAML_Error_BadRequest('Requested URL contained \'./\'.'); + } + + $moduleDir = SimpleSAML_Module::getModuleDir($module).'/www/'; + + // check for '.php/' in the path, the presence of which indicates that another php-script should handle the request + for ($phpPos = strpos($url, '.php/'); $phpPos !== false; $phpPos = strpos($url, '.php/', $phpPos + 1)) { + + $newURL = substr($url, 0, $phpPos + 4); + $param = substr($url, $phpPos + 4); + + if (is_file($moduleDir.$newURL)) { + /* $newPath points to a normal file. Point execution to that file, and + * save the remainder of the path in PATH_INFO. + */ + $url = $newURL; + $_SERVER['PATH_INFO'] = $param; + break; + } + } + + $path = $moduleDir.$url; + + if ($path[strlen($path) - 1] === '/') { + // path ends with a slash - directory reference. Attempt to find index file in directory + foreach ($indexFiles as $if) { + if (file_exists($path.$if)) { + $path .= $if; + break; + } + } + } + + if (is_dir($path)) { + /* Path is a directory - maybe no index file was found in the previous step, or maybe the path didn't end with + * a slash. Either way, we don't do directory listings. + */ + throw new SimpleSAML_Error_NotFound('Directory listing not available.'); + } + + if (!file_exists($path)) { + // file not found + SimpleSAML_Logger::info('Could not find file \''.$path.'\'.'); + throw new SimpleSAML_Error_NotFound('The URL wasn\'t found in the module.'); + } + + if (preg_match('#\.php$#D', $path)) { + // PHP file - attempt to run it + $_SERVER['SCRIPT_NAME'] .= '/'.$module.'/'.$url; + require($path); + exit(); + } + + // some other file type - attempt to serve it + + // find MIME type for file, based on extension + $contentType = null; + if (preg_match('#\.([^/\.]+)$#D', $path, $type)) { + $type = strtolower($type[1]); + if (array_key_exists($type, $mimeTypes)) { + $contentType = $mimeTypes[$type]; + } + } + + if ($contentType === null) { + /* We were unable to determine the MIME type from the file extension. Fall back to mime_content_type (if it + * exists). + */ + if (function_exists('mime_content_type')) { + $contentType = mime_content_type($path); + } else { + // mime_content_type doesn't exist. Return a default MIME type + SimpleSAML_Logger::warning('Unable to determine mime content type of file: '.$path); + $contentType = 'application/octet-stream'; + } + } + + $contentLength = sprintf('%u', filesize($path)); // force filesize to an unsigned number + + header('Content-Type: '.$contentType); + header('Content-Length: '.$contentLength); + header('Cache-Control: public,max-age=86400'); + header('Expires: '.gmdate('D, j M Y H:i:s \G\M\T', time() + 10 * 60)); + header('Last-Modified: '.gmdate('D, j M Y H:i:s \G\M\T', filemtime($path))); + + readfile($path); + exit(); +} catch (SimpleSAML_Error_Error $e) { + + $e->show(); +} catch (Exception $e) { + + $e = new SimpleSAML_Error_Error('UNHANDLEDEXCEPTION', $e); + $e->show(); } - -?> \ No newline at end of file