diff --git a/dev/install/install.php5 b/dev/install/install.php5 index 2785867f7..d57431947 100755 --- a/dev/install/install.php5 +++ b/dev/install/install.php5 @@ -1494,6 +1494,8 @@ HTML; if($base != '.') $baseClause = "RewriteBase '$base'\n"; else $baseClause = ""; + if(strpos(strtolower(php_sapi_name()), "cgi") !== false) $cgiClause = "RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]\n"; + else $cgiClause = ""; $modulePath = FRAMEWORK_NAME; $rewrite = <<When using CGI/FastCGI with Apache, you will have to add the `RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]` rewrite rule to your `.htaccess` file| | `SS_SEND_ALL_EMAILS_TO`| If you set this define, all emails will be redirected to this address.| | `SS_SEND_ALL_EMAILS_FROM`| If you set this define, all emails will be send from this address.| | `SS_ERROR_LOG` | | diff --git a/security/BasicAuth.php b/security/BasicAuth.php index 4ad895ea1..43fa47691 100644 --- a/security/BasicAuth.php +++ b/security/BasicAuth.php @@ -1,13 +1,13 @@ basicAuthEnabled}. - * + * * @package framework * @subpackage security */ @@ -17,15 +17,15 @@ class BasicAuth { * @var Boolean Flag set by {@link self::protect_entire_site()} */ private static $entire_site_protected = false; - + /** * @config * @var String|array Holds a {@link Permission} code that is required - * when calling {@link protect_site_if_necessary()}. Set this value through + * when calling {@link protect_site_if_necessary()}. Set this value through * {@link protect_entire_site()}. */ private static $entire_site_protected_code = 'ADMIN'; - + /** * @config * @var String Message that shows in the authentication box. @@ -35,31 +35,39 @@ class BasicAuth { /** * Require basic authentication. Will request a username and password if none is given. - * + * * Used by {@link Controller::init()}. - * + * * @throws SS_HTTPResponse_Exception - * + * * @param string $realm * @param string|array $permissionCode Optional * @param boolean $tryUsingSessionLogin If true, then the method with authenticate against the * session log-in if those credentials are disabled. - * @return Member $member + * @return Member $member */ public static function requireLogin($realm, $permissionCode = null, $tryUsingSessionLogin = true) { $isRunningTests = (class_exists('SapphireTest', false) && SapphireTest::is_running_test()); if(!Security::database_is_ready() || (Director::is_cli() && !$isRunningTests)) return true; - + + $matches = array(); + if (isset($_SERVER['HTTP_AUTHORIZATION']) && + preg_match('/Basic\s+(.*)$/i', $_SERVER['HTTP_AUTHORIZATION'], $matches)) { + list($name, $password) = explode(':', base64_decode($matches[1])); + $_SERVER['PHP_AUTH_USER'] = strip_tags($name); + $_SERVER['PHP_AUTH_PW'] = strip_tags($password); + } + $member = null; if(isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) { $member = MemberAuthenticator::authenticate(array( - 'Email' => $_SERVER['PHP_AUTH_USER'], + 'Email' => $_SERVER['PHP_AUTH_USER'], 'Password' => $_SERVER['PHP_AUTH_PW'], ), null); } - + if(!$member && $tryUsingSessionLogin) $member = Member::currentUser(); - + // If we've failed the authentication mechanism, then show the login form if(!$member) { $response = new SS_HTTPResponse(null, 401); @@ -70,13 +78,13 @@ class BasicAuth { } else { $response->setBody(_t('BasicAuth.ENTERINFO', "Please enter a username and password.")); } - + // Exception is caught by RequestHandler->handleRequest() and will halt further execution $e = new SS_HTTPResponse_Exception(null, 401); $e->setResponse($response); throw $e; } - + if($permissionCode && !Permission::checkMember($member->ID, $permissionCode)) { $response = new SS_HTTPResponse(null, 401); $response->addHeader('WWW-Authenticate', "Basic realm=\"$realm\""); @@ -84,28 +92,28 @@ class BasicAuth { if(isset($_SERVER['PHP_AUTH_USER'])) { $response->setBody(_t('BasicAuth.ERRORNOTADMIN', "That user is not an administrator.")); } - + // Exception is caught by RequestHandler->handleRequest() and will halt further execution $e = new SS_HTTPResponse_Exception(null, 401); $e->setResponse($response); throw $e; } - + return $member; } - + /** * Enable protection of the entire site with basic authentication. - * + * * This log-in uses the Member database for authentication, but doesn't interfere with the * regular log-in form. This can be useful for test sites, where you want to hide the site * away from prying eyes, but still be able to test the regular log-in features of the site. - * + * * If you are including conf/ConfigureFromEnv.php in your _config.php file, you can also enable * this feature by adding this line to your _ss_environment.php: - * + * * define('SS_USE_BASIC_AUTH', true); - * + * * @param boolean $protect Set this to false to disable protection. * @param String $code {@link Permission} code that is required from the user. * Defaults to "ADMIN". Set to NULL to just require a valid login, regardless @@ -116,11 +124,11 @@ class BasicAuth { Config::inst()->update('BasicAuth', 'entire_site_protected_code', $code); Config::inst()->update('BasicAuth', 'entire_site_protected_message', $message); } - + /** * Call {@link BasicAuth::requireLogin()} if {@link BasicAuth::protect_entire_site()} has been called. * This is a helper function used by {@link Controller::init()}. - * + * * If you want to enabled protection (rather than enforcing it), * please use {@link protect_entire_site()}. */