diff --git a/lib/SimpleSAML/Configuration.php b/lib/SimpleSAML/Configuration.php index 2a52bf11cdb0683673d1c7034ce083347adbe459..62f25bff57e2f77017bdfef14b29cbc59de64032 100644 --- a/lib/SimpleSAML/Configuration.php +++ b/lib/SimpleSAML/Configuration.php @@ -113,13 +113,32 @@ class SimpleSAML_Configuration // the file initializes a variable named '$config' require($filename); + // check that $config exists + if (!isset($config)) { + throw new \SimpleSAML\Error\ConfigurationError( + '$config is not defined in the configuration file.', + $filename + ); + } + // check that $config is initialized to an array if (!is_array($config)) { - throw new Exception('Invalid configuration file: '.$filename); + throw new \SimpleSAML\Error\ConfigurationError( + '$config is not an array.', + $filename + ); + } + + // check that $config is not empty + if (empty($config)) { + throw new \SimpleSAML\Error\ConfigurationError( + '$config is empty.', + $filename + ); } } elseif ($required) { // file does not exist, but is required - throw new Exception('Missing configuration file: '.$filename); + throw new \SimpleSAML\Error\ConfigurationError('Missing configuration file', $filename); } else { // file does not exist, but is optional, so return an empty configuration object without saving it $cfg = new SimpleSAML_Configuration(array(), $filename); @@ -258,10 +277,17 @@ class SimpleSAML_Configuration } if ($instancename === 'simplesaml') { - return self::getConfig(); + try { + return self::getConfig(); + } catch (SimpleSAML\Error\ConfigurationError $e) { + throw \SimpleSAML\Error\CriticalConfigurationError::fromException($e); + } + } - throw new Exception('Configuration with name '.$instancename.' is not initialized.'); + throw new \SimpleSAML\Error\CriticalConfigurationError( + 'Configuration with name '.$instancename.' is not initialized.' + ); } @@ -407,7 +433,7 @@ class SimpleSAML_Configuration * * @return string The absolute path relative to the root of the website. * - * @throws SimpleSAML_Error_Exception If the format of 'baseurlpath' is incorrect. + * @throws SimpleSAML\Error\CriticalConfigurationError If the format of 'baseurlpath' is incorrect. */ public function getBaseURL() { @@ -428,11 +454,18 @@ class SimpleSAML_Configuration // local path only return $matches[1]; } else { - // invalid format - throw new SimpleSAML_Error_Exception( + /* + * Invalid 'baseurlpath'. We cannot recover from this, so throw a critical exception and try to be graceful + * with the configuration. Use a guessed base path instead of the one provided. + */ + $c = $this->toArray(); + $c['baseurlpath'] = SimpleSAML\Utils\HTTP::guessBasePath(); + throw new SimpleSAML\Error\CriticalConfigurationError( 'Incorrect format for option \'baseurlpath\'. Value is: "'. $this->getString('baseurlpath', 'simplesaml/').'". Valid format is in the form'. - ' [(http|https)://(hostname|fqdn)[:port]]/[path/to/simplesaml/].' + ' [(http|https)://(hostname|fqdn)[:port]]/[path/to/simplesaml/].', + $this->filename, + $c ); } } diff --git a/lib/SimpleSAML/Utils/HTTP.php b/lib/SimpleSAML/Utils/HTTP.php index a6097a5330b5dfd65b863ef59f96daf95b313ac8..5ebf7765ef4ac1035cd35b00390eda8da9e64b9e 100644 --- a/lib/SimpleSAML/Utils/HTTP.php +++ b/lib/SimpleSAML/Utils/HTTP.php @@ -539,7 +539,7 @@ class HTTP * https://idp.example.org/simplesaml/ * * @return string The absolute base URL for the SimpleSAMLphp installation. - * @throws \SimpleSAML_Error_Exception If 'baseurlpath' has an invalid format. + * @throws \SimpleSAML\Error\CriticalConfigurationError If 'baseurlpath' has an invalid format. * * @author Olav Morken, UNINETT AS <olav.morken@uninett.no> */ @@ -567,9 +567,17 @@ class HTTP return $protocol.$hostname.$port.$path; } else { - throw new \SimpleSAML_Error_Exception( + /* + * Invalid 'baseurlpath'. We cannot recover from this, so throw a critical exception and try to be graceful + * with the configuration. Use a guessed base path instead of the one provided. + */ + $c = $globalConfig->toArray(); + $c['baseurlpath'] = self::guessBasePath(); + throw new \SimpleSAML\Error\CriticalConfigurationError( 'Invalid value for \'baseurlpath\' in config.php. Valid format is in the form: '. - '[(http|https)://(hostname|fqdn)[:port]]/[path/to/simplesaml/]. It must end with a \'/\'.' + '[(http|https)://(hostname|fqdn)[:port]]/[path/to/simplesaml/]. It must end with a \'/\'.', + null, + $c ); } } diff --git a/tests/lib/SimpleSAML/ConfigurationTest.php b/tests/lib/SimpleSAML/ConfigurationTest.php index 5a0c7f3ec7847629b4c9e957dd5d43bb93483c85..076b8b067966ba48d6b04db31934c0d55b085aeb 100644 --- a/tests/lib/SimpleSAML/ConfigurationTest.php +++ b/tests/lib/SimpleSAML/ConfigurationTest.php @@ -14,6 +14,27 @@ class Test_SimpleSAML_Configuration extends PHPUnit_Framework_TestCase $this->assertTrue(is_string($c->getVersion())); } + /** + * Test that the default instance fails to load even if we previously loaded another instance. + * @expectedException \SimpleSAML\Error\CriticalConfigurationError + */ + public function testLoadDefaultInstance() + { + SimpleSAML_Configuration::loadFromArray(array('key' => 'value'), '', 'dummy'); + SimpleSAML_Configuration::getInstance(); + } + + + /** + * Test that after a \SimpleSAML\Error\CriticalConfigurationError exception, a basic, self-survival configuration + * is loaded. + */ + public function testCriticalConfigurationError() + { + $c = SimpleSAML_Configuration::getInstance(); + $this->assertNotEmpty($c->toArray()); + } + /** * Test SimpleSAML_Configuration::getValue() */ @@ -127,7 +148,7 @@ class Test_SimpleSAML_Configuration extends PHPUnit_Framework_TestCase /** * Test that SimpleSAML_Configuration::getBaseURL() fails if given a path without trailing slash - * @expectedException SimpleSAML_Error_Exception + * @expectedException \SimpleSAML\Error\CriticalConfigurationError */ public function testGetBaseURLError() { $c = SimpleSAML_Configuration::loadFromArray(array( @@ -861,19 +882,6 @@ class Test_SimpleSAML_Configuration extends PHPUnit_Framework_TestCase $c->getLocalizedString('opt'); } - - /** - * Test that the default instance fails to load even if we previously loaded another instance. - * @expectedException Exception - */ - public function testLoadDefaultInstance() - { - SimpleSAML_Configuration::loadFromArray(array('key' => 'value'), '', 'dummy'); - $c = SimpleSAML_Configuration::getInstance(); - var_dump($c); - } - - /** * Test that Configuration objects can be initialized from an array. * diff --git a/www/_include.php b/www/_include.php index f587766c726bcaf3d4f72678aa552796fcbc941c..4772fbb471668a94e09318615ec71b3baf72ee1a 100644 --- a/www/_include.php +++ b/www/_include.php @@ -83,10 +83,9 @@ set_error_handler('SimpleSAML_error_handler'); $configdir = SimpleSAML\Utils\Config::getConfigDir(); 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); + throw new \SimpleSAML\Error\CriticalConfigurationError( + 'You have not yet created the SimpleSAMLphp configuration files.' + ); } // set the timezone