Skip to content
Snippets Groups Projects
Commit 790016bd authored by Olav Morken's avatar Olav Morken
Browse files

Added configuration checker.

git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@624 44740490-163a-0410-bde0-09ae8108e29a
parent 949448f0
No related branches found
No related tags found
No related merge requests found
......@@ -828,6 +828,14 @@ $lang = array(
'hr' => 'Izvorna vrijednost administratorske zaporke (auth.adminpassword) u konfiguraciji nije promjenjena, molimo promjenite zaporku.',
'hu' => 'Még nem lett megváltoztatva a karbantartói jelszó (auth.adminpassword) a konfigurációs fájlban, kérjük, változtassa meg most! ',
),
'title_READCONFIGTEMPLATES' => array (
'en' => 'Error reading config-templates directory',
'no' => 'Feil ved lesing av config-templates katalogen',
),
'descr_READCONFIGTEMPLATES' => array (
'en' => 'An error occured while simpleSAMLphp was attempting to find the available files in the config-templates directory.',
'no' => 'En feil oppstod mens simpleSAMLphp prøvde å finne tilgjengelige filer i config-templates katalogen.',
),
);
......
......@@ -481,6 +481,10 @@ $lang = array(
'hr' => 'Održavanje i konfiguriranje simpleSAMLphp-a',
'hu' => 'SimpleSAMLphp karbantartása és beállítása',
),
'link_configcheck' => array (
'no' => 'simpleSAMLphp konfigurasjonskontroll',
'en' => 'simpleSAMLphp configuraction check',
),
);
......
<?php
$this->data['header'] = 'Configuration check';
if(array_key_exists('file', $this->data)) {
$this->data['header'] .= ' - ' . htmlspecialchars($this->data['file']);
}
$this->includeAtTemplateBase('includes/header.php');
?>
<div id="content">
<h2><?php echo $this->data['header']; ?></h2>
<?php
if(array_key_exists('files', $this->data)) {
/* File list. */
echo('<p>Select configuration file to check:</p>');
echo('<ul>');
foreach($this->data['files'] as $file) {
$fileName = htmlspecialchars($file['name']);
if($file['available']) {
$fileUrl = htmlspecialchars($this->data['url'] . '?file=' . urlencode($file['name']));
echo('<li><a href="' . $fileUrl . '">' . $fileName . '</a></li>');
} else {
$reason = htmlspecialchars($file['reason']);
echo('<li>' . $fileName . ' - ' . $reason . '</li>');
}
}
echo('</ul>');
} else {
/* File details. */
$notices = $this->data['notices'];
$missing = $this->data['missing'];
$superfluous = $this->data['superfluous'];
if(count($notices) > 0) {
echo('<h3>Notices</h3>');
echo('<ul>');
foreach($notices as $i) {
$type = $i['type'];
if($type === 'error') {
$image = 'bomb.png';
} elseif($type === 'warning') {
$image = 'caution.png';
}
$imageUrl = '/' . $this->data['baseurlpath'] . 'resources/icons/' . $image;
echo('<p>');
echo('<img style="display: inline; float: left; width: 1.7em; height: 1.7em;" src="' . htmlspecialchars($imageUrl) . '" alt="' . htmlspecialchars($type) . '" />');
echo(htmlspecialchars($i['message']));
echo('</p>');
}
echo('</ul>');
}
if(count($missing) > 0) {
echo('<h3>Options missing from config file</h3>');
echo('<ul>');
foreach($missing as $i) {
echo('<li>' . htmlspecialchars($i) . '</li>');
}
echo('</ul>');
}
if(count($superfluous) > 0) {
echo('<h3>Superfluous options in config file</h3>');
echo('<ul>');
foreach($superfluous as $i) {
echo('<li>' . htmlspecialchars($i) . '</li>');
}
echo('</ul>');
}
if(count($notices) === 0 && count($missing) === 0 && count($superfluous) === 0) {
echo('<p>No errors found.</p>');
}
echo('<p><a href="' . htmlspecialchars($this->data['url']) . '">Go back to the file list</a></p>');
}
$this->includeAtTemplateBase('includes/footer.php');
?>
<?php
require_once('../_include.php');
/* A list of notices which will be shown to the user - only used during file verification. */
$notices = array();
/**
* This function adds a warning to the list of notices.
*
* @param $message The warning message.
*/
function warning($message) {
global $notices;
$notices[] = array(
'type' => 'warning',
'message' => $message,
);
}
/**
* This function adds an error to the list of notices.
*
* @param $message The error message.
*/
function error($message) {
global $notices;
$notices[] = array(
'type' => 'error',
'message' => $message,
);
}
/**
* Load a config file
*
* This function loads a configuration file. If the file isn't a standard configuration file
* it will return NULL. Parse errors will result in FALSE being returned.
*
* @param $file Full path to the configuration file.
* @return The array with the configuration values if successfull. NULL if $file isn't a standard
* configuration file. FALSE if there was an parse error.
*/
function loadConfigFile($file) {
assert('file_exists($file)');
/* Cache of loaded configuration files - to avoid loading and parsing the same file twice. */
static $cache = array();
/* Check for file in cache. */
if(array_key_exists($file, $cache)) {
return $cache[$file];
}
/* Load the file. */
$data = file_get_contents($file);
/* Set $config to a known value. This is used to detect whether $file updates the $config variable. */
$config = FALSE;
/* Strip out the php start and end tags. */
$matches = array();
if(!preg_match('/\s*<\?php(.*)\?>\s*/s', $data, $matches)) {
/* File doesn't start with <?php and end with ?>. */
return FALSE;
}
$data = $matches[1];
/* Process the file. */
$res = eval($data);
if($res === FALSE) {
/* Parse error in file. */
return FALSE;
}
if($config === FALSE) {
/* $config not updated - this is not a standard config file. */
$cache[$file] = NULL;
return NULL;
}
$cache[$file] = $config;
return $config;
}
/**
* Determine whether the specified configuration file can be checked.
*
* @return TRUE if it can be checked, of a string with the reason if it can't be checked.
*/
function canCheckFile($file) {
global $configFiles;
global $configDir;
global $configTemplateDir;
if(!in_array($file, $configFiles)) {
return 'not in the list of available config files';
}
if(!file_exists($configDir . $file)) {
return 'not added to config directory';
}
$configTemplateData = loadConfigFile($configTemplateDir . $file);
if($configTemplateData === FALSE) {
return 'parse error in template file';
}
if($configTemplateData === NULL) {
return 'not a standard configuration file';
}
$configData = loadConfigFile($configDir . $file);
if($configData === FALSE) {
return 'parse error in configuration file';
}
if($configData === NULL) {
return 'invalid configuration file - $config not defined in file';
}
return TRUE;
}
/**
* Does some checks on config.php
*
* @param $config The configuration data.
*/
function validate_config($config, &$errors, &$warnings) {
if($config['auth.adminpassword'] === '123') {
error('auth.adminpassword should be changed from the default value.');
}
if($config['technicalcontact_email'] === 'na') {
warning('technicalcontact_email should be set to a email address users can contact for support.');
}
}
/* Load configuration and session information. */
$config = SimpleSAML_Configuration::getInstance();
$session = SimpleSAML_Session::getInstance();
/* Check if the user is logged in with admin access. */
if (!$session->isValid('login-admin') ) {
SimpleSAML_Utilities::redirect('/' . $config->getBaseURL() . 'auth/login-admin.php',
array('RelayState' => SimpleSAML_Utilities::selfURL())
);
}
/* Find config directories. */
$configDir = $config->getBaseDir() . 'config/';
$configTemplateDir = $config->getBaseDir() . 'config-templates/';
/* Find all available configuration files. */
$configFiles = array();
$dirHandle = opendir($configTemplateDir);
if($dirHandle === FALSE) {
SimpleSAML_Utilities::fatalError($session->getTrackId(), 'READCONFIGTEMPLATES');
}
while(($configFile = readdir($dirHandle)) !== FALSE) {
/* We are only interrested in .php-files in the directory. */
if(substr($configFile, -4) !== '.php') {
continue;
}
$configFiles[] = $configFile;
}
closedir($dirHandle);
if(array_key_exists('file', $_GET)) {
/* The user has selected a file. */
$file = $_GET['file'];
/* Can we check this file? */
if(canCheckFile($file) !== TRUE) {
$file = NULL;
}
} else {
/* The user needs to select a file. */
$file = NULL;
}
/* Initialize template page. */
$et = new SimpleSAML_XHTML_Template($config, 'admin-config.php');
$et->data['url'] = SimpleSAML_Utilities::selfURLNoQuery();
if($file === NULL) {
/* No file selected by user - find and show list of available config files. */
$files = array();
foreach($configFiles as $configFile) {
$canCheck = canCheckFile($configFile);
if($canCheck === TRUE) {
$available = TRUE;
$reason = '';
} else {
$available = FALSE;
$reason = $canCheck;
}
$files[] = array(
'name' => $configFile,
'available' => $available,
'reason' => $reason,
);
}
/* Show page. */
$et->data['files'] = $files;
$et->show();
/* We are done - exit. */
exit();
}
/* User has selected a configuration file. */
$et->data['file'] = $file;
/* If the code reaches this point, parse errors and such in $file should be handled. */
/* Load the configuration. */
$templateData = loadConfigFile($configTemplateDir . $file);
$configData = loadConfigFile($configDir . $file);
/* Check if we have a validation function for this config file, and use it if we do. */
$funcName = 'validate_' . substr($file, 0, -4);
if(is_callable($funcName)) {
call_user_func($funcName, $configData);
}
$et->data['notices'] = $notices;
/* Find keys in the template file which are missing in the config file. */
$missing = array();
foreach($templateData as $key => $value) {
if(!array_key_exists($key, $configData)) {
$missing[] = $key;
}
}
$et->data['missing'] = $missing;
/* Find keys in the config file which are missing in the template file. */
$superfluous = array();
foreach($configData as $key => $value) {
if(!array_key_exists($key, $templateData)) {
$superfluous[] = $key;
}
}
$et->data['superfluous'] = $superfluous;
$et->show();
?>
\ No newline at end of file
......@@ -48,6 +48,11 @@ $links[] = array(
'href' => 'admin/phpinfo.php',
'text' => 'link_phpinfo');
$links[] = array(
'href' => 'admin/config.php',
'text' => 'link_configcheck',
);
$linksmeta = array();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment