Skip to content
Snippets Groups Projects
Commit 5a0d86b9 authored by Demian Katz's avatar Demian Katz
Browse files

Updated installer to auto-configure security (resolving VUFIND-733; thanks to...

Updated installer to auto-configure security (resolving VUFIND-733; thanks to Kyle McGrogan for initial implementation).
parent f76ecfe7
No related merge requests found
...@@ -576,7 +576,7 @@ $staticRoutes = array( ...@@ -576,7 +576,7 @@ $staticRoutes = array(
'Cover/Show', 'Cover/Unavailable', 'Error/Unavailable', 'Help/Home', 'Cover/Show', 'Cover/Unavailable', 'Error/Unavailable', 'Help/Home',
'Install/Done', 'Install/FixBasicConfig', 'Install/FixCache', 'Install/Done', 'Install/FixBasicConfig', 'Install/FixCache',
'Install/FixDatabase', 'Install/FixDependencies', 'Install/FixILS', 'Install/FixDatabase', 'Install/FixDependencies', 'Install/FixILS',
'Install/FixSolr', 'Install/Home', 'Install/ShowSQL', 'Install/FixSolr', 'Install/Home', 'Install/ShowSQL', 'Install/FixSecurity',
'MyResearch/Account', 'MyResearch/CheckedOut', 'MyResearch/Delete', 'MyResearch/Account', 'MyResearch/CheckedOut', 'MyResearch/Delete',
'MyResearch/DeleteList', 'MyResearch/Edit', 'MyResearch/Email', 'MyResearch/DeleteList', 'MyResearch/Edit', 'MyResearch/Email',
'MyResearch/Export', 'MyResearch/Favorites', 'MyResearch/Fines', 'MyResearch/Export', 'MyResearch/Favorites', 'MyResearch/Fines',
......
...@@ -26,9 +26,12 @@ ...@@ -26,9 +26,12 @@
* @link http://vufind.org Main Site * @link http://vufind.org Main Site
*/ */
namespace VuFind\Controller; namespace VuFind\Controller;
use VuFind\Config\Reader as ConfigReader, VuFind\Config\Writer as ConfigWriter, use VuFind\Config\Reader as ConfigReader,
VuFind\Connection\Manager as ConnectionManager, VuFind\Db\AdapterFactory, VuFind\Config\Writer as ConfigWriter,
Zend\Mvc\MvcEvent; VuFind\Connection\Manager as ConnectionManager,
VuFind\Db\AdapterFactory,
Zend\Mvc\MvcEvent,
Zend\Crypt\Password\Bcrypt;
/** /**
* Class controls VuFind auto-configuration. * Class controls VuFind auto-configuration.
...@@ -234,7 +237,9 @@ class InstallController extends AbstractBase ...@@ -234,7 +237,9 @@ class InstallController extends AbstractBase
protected function checkDependencies() protected function checkDependencies()
{ {
$requiredFunctionsExist $requiredFunctionsExist
= function_exists('mb_substr') && is_callable('imagecreatefromstring'); = function_exists('mb_substr') && is_callable('imagecreatefromstring')
&& function_exists('mcrypt_module_open');
return array( return array(
'title' => 'Dependencies', 'title' => 'Dependencies',
'status' => $requiredFunctionsExist && $this->phpVersionIsNewEnough(), 'status' => $requiredFunctionsExist && $this->phpVersionIsNewEnough(),
...@@ -283,6 +288,17 @@ class InstallController extends AbstractBase ...@@ -283,6 +288,17 @@ class InstallController extends AbstractBase
$problems++; $problems++;
} }
// Is the mcrypt library missing?
if (!function_exists('mcrypt_module_open')) {
$msg
= "Your PHP installation appears to be missing the mcrypt plug-in."
." For better security support, it is recommended that you add this."
." For details on how to do this, see "
."http://vufind.org/wiki/installation "
."and look at the PHP installation instructions for your platform.";
}
return $this->createViewModel(array('problems' => $problems)); return $this->createViewModel(array('problems' => $problems));
} }
...@@ -545,6 +561,116 @@ class InstallController extends AbstractBase ...@@ -545,6 +561,116 @@ class InstallController extends AbstractBase
return $view; return $view;
} }
/**
* Check if Security configuration is set.
*
* @return array
*/
protected function checkSecurity()
{
// Are configuration settings missing?
$config = ConfigReader::getConfig();
if (!isset($config->Authentication->hash_passwords)
|| !$config->Authentication->hash_passwords
|| !isset($config->Authentication->encrypt_ils_password)
|| !$config->Authentication->encrypt_ils_password
) {
$status = false;
} else {
$status = true;
}
// If we're correctly configured, check that the data in the database is ok:
if ($status) {
try {
$rows = $this->getTable('user')->getInsecureRows();
$status = (count($rows) == 0);
} catch (\VuFind\Exception\PasswordSecurity $e) {
// Any security exception means we have a problem!
$status = false;
}
}
return array(
'title' => 'Security', 'status' => $status, 'fix' => 'fixsecurity'
);
}
/**
* Support method for fixsecurityAction(). Returns true if the configuration
* was modified, false otherwise.
*
* @param \Zend\Config\Config $config Existing VuFind configuration
* @param ConfigWriter $writer Config writer
*
* @return bool
*/
protected function fixSecurityConfiguration($config, $writer)
{
$changed = false;
if (!isset($config->Authentication->hash_passwords)
|| !$config->Authentication->hash_passwords
|| !isset($config->Authentication->encrypt_ils_password)
|| !$config->Authentication->encrypt_ils_password
) {
$writer->set('Authentication', 'hash_passwords', true);
$writer->set('Authentication', 'encrypt_ils_password', true);
$changed = true;
}
// Only rewrite encryption key if we don't already have one:
if (!isset($config->Authentication->ils_encryption_key)
|| empty($config->Authentication->ils_encryption_key)
) {
$enc_key = sha1(microtime(true).mt_rand(10000, 90000));
$writer->set('Authentication', 'ils_encryption_key', $enc_key);
$changed = true;
}
return $changed;
}
/**
* Display repair instructions for Security problems.
*
* @return mixed
*/
public function fixsecurityAction()
{
// First, set encryption/hashing to true, and set the key
$config = ConfigReader::getConfig();
$configPath = ConfigReader::getLocalConfigPath('config.ini', null, true);
$writer = new ConfigWriter($configPath);
if ($this->fixSecurityConfiguration($config, $writer)) {
// Problem writing? Show the user an error:
if (!$writer->save()) {
return $this->forwardTo('Install', 'fixbasicconfig');
}
// Success? Redirect to this action in order to reload the configuration:
return $this->redirect()->toRoute('install-fixsecurity');
}
// Now we want to loop through the database and update passwords (if
// necessary).
$rows = $this->getTable('user')->getInsecureRows();
if (count($rows) > 0) {
$bcrypt = new Bcrypt();
foreach ($rows as $row) {
if ($row->password != '') {
$row->pass_hash = $bcrypt->create($row->password);
$row->password = '';
}
if ($row->cat_password) {
$row->saveCredentials($row->cat_username, $row->cat_password);
} else {
$row->save();
}
}
}
return $this->redirect()->toRoute('install-home');
}
/** /**
* Disable auto-configuration. * Disable auto-configuration.
* *
......
...@@ -79,4 +79,18 @@ class User extends Gateway ...@@ -79,4 +79,18 @@ class User extends Gateway
return $row; return $row;
} }
/**
* Get user rows with insecure passwords and/or catalog passwords
*
* @return mixed
*/
public function getInsecureRows()
{
$callback = function ($select) {
$select->where
->notEqualTo('password', '')
->OR->isNotNull('cat_password');
};
return $this->select($callback);
}
} }
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment