Project

General

Profile

Feature #22245 » installToolPassword_secure__v0.diff

Administrator Admin, 2010-03-06 11:52

View differences:

t3lib/class.t3lib_install.php (working copy)
$line_array[] = $variable." = '".$this->slashValueForSingleDashes($value)."'; // ".$comment;
$this->touchedLine = -1;
}
if ($variable == '$typo_db_password') {
if (($variable == '$typo_db_password') || ($variable = '$TYPO3_CONF_VARS[\'BE\'][\'installToolPassword\']')) {
$this->messages[] = 'Updated ' . $variable;
} else {
$this->messages[] = $variable . " = '" . htmlspecialchars($value) . "'";
typo3/init.php (working copy)
$install_check->allowUpdateLocalConf = 1;
$install_check->init();
exit;
} elseif (!defined('TYPO3_enterInstallScript')) {
define('TYPO3_enterInstallScript', 0);
}
typo3/sysext/sv/ext_autoload.php (working copy)
*/
$extensionPath = t3lib_extMgm::extPath('sv');
return array(
'tx_sv_authbase' => $extensionPath . 'class.tx_sv_authbase.php',
'tx_sv_reports_serviceslist' => $extensionPath . 'reports/class.tx_sv_reports_serviceslist.php',
);
?>
typo3/sysext/saltedpasswords/ext_localconf.php (working copy)
'auth',
'tx_saltedpasswords_sv1',
array(
'title' => 'FE/BE Authentification salted',
'description' => 'Salting of passwords for Frontend and Backend',
'subtype' => 'authUserFE,authUserBE',
'title' => 'FE/BE/Install-Tool Authentification salted',
'description' => 'Salting of passwords for Frontend, Backend and Install Tool',
'subtype' => 'authUserFE,authUserBE,authInstallTool',
'available' => TRUE,
'priority' => 70, // must be higher than tx_sv_auth (50) and rsaauth (60) but lower than OpenID (75)
'quality' => 70,
typo3/sysext/saltedpasswords/sv1/class.tx_saltedpasswords_sv1.php (working copy)
// existing record is in format of Salted Hash password
if (is_object($this->objInstanceSaltedPW)) {
$validPasswd = $this->objInstanceSaltedPW->checkPassword($password,$user['password']);
$this->hashedPassword = $this->objInstanceSaltedPW->getHashedPassword($password);
// record is in format of Salted Hash password but authentication failed
// skip further authentication methods
......
*/
protected function updatePassword($uid, $updateFields) {
if (TYPO3_MODE === 'BE') {
$GLOBALS['TYPO3_DB']->exec_UPDATEquery( 'be_users', sprintf('uid = %u', $uid), $updateFields);
if (TYPO3_enterInstallScript) {
$this->pObj->updatePassword = $updateFields['password'];
} else {
$GLOBALS['TYPO3_DB']->exec_UPDATEquery( 'be_users', sprintf('uid = %u', $uid), $updateFields);
}
} else {
$GLOBALS['TYPO3_DB']->exec_UPDATEquery( 'fe_users', sprintf('uid = %u', $uid), $updateFields);
}
typo3/sysext/install/mod/class.tx_install.php (working copy)
*
*/
if (!(defined('TYPO3_enterInstallScript') && TYPO3_enterInstallScript)) die ('Access denied.');
// include requirements definition:
require_once(t3lib_extMgm::extPath('install') . 'requirements.php');
......
);
var $JSmessage = '';
// Will get set to the path of the ENABLE_INSTALL_TOOL file in constructor
var $enableInstallToolFile = '';
// Defines wheter log messages should get written for login attempts
var $writeAttemptLog = false;
var $writeDevLog = false;
// This variable gets set by service classes when the current password hash in localconf.php should get updated
// because of changes in encryption/hashing parameters
var $updatePassword = '';
// Getting set to the value of $TYPO3_CONF_VARS['BE']['loginSecurityLevel'] in the constructor
var $loginSecurityLevel = '';
var $security_level = '';
// The minimal number of characters required for a somewhat secure password
var $passwordMinChars = 5;
/**
* Constructor
*
......
// ****************************
// Initializing incoming vars.
// ****************************
$this->enableInstallToolFile = PATH_typo3conf . 'ENABLE_INSTALL_TOOL';
$this->INSTALL = t3lib_div::_GP('TYPO3_INSTALL');
$this->mode = t3lib_div::_GP('mode');
if ($this->mode !== '123') {
......
';
}
// The first one is for the login form hook of "rsaauth" extension, the second for salted password handling of "saltedpasswords"
$this->loginSecurityLevel = $GLOBALS['TYPO3_CONF_VARS']['BE']['loginSecurityLevel'];
$this->security_level = $GLOBALS['TYPO3_CONF_VARS']['BE']['loginSecurityLevel'];
// Retrieve the newPasswordHash value from previous call to the install tool and set it to a new random value
$this->newPasswordHash = $this->session->getNewPasswordHash();
$this->session->setNewPasswordHash();
if ($this->session->isAuthorized() || $this->checkPassword()) {
$this->passwordOK=1;
$this->session->refreshSession();
$enableInstallToolFile = PATH_typo3conf . 'ENABLE_INSTALL_TOOL';
if (is_file ($enableInstallToolFile)) {
if (is_file ($this->enableInstallToolFile)) {
// Extend the age of the ENABLE_INSTALL_TOOL file by one hour
@touch($enableInstallToolFile);
@touch($this->enableInstallToolFile);
}
if($this->redirect_url) {
......
function checkPassword() {
$p = t3lib_div::_GP('password');
if ($p && md5($p)==$GLOBALS['TYPO3_CONF_VARS']['BE']['installToolPassword']) {
// Perform password check
$passwordOk = false;
if (t3lib_extMgm::isLoaded('saltedpasswords') || t3lib_extMgm::isLoaded('rsaauth')) {
// Use the "saltedpasswords" and/or "rsaauth" system extension for more security by using password checking services
$altPass = t3lib_div::_GP('userident');
$p = $altPass ? $altPass : $p;
$passwordOk = $this->checkPasswordViaService($p);
$p = $this->hashedPassword;
} elseif ($p) {
// Perform plain md5 hashed password comparison
$this->hashedPassword = md5($p);
$passwordOk = ($this->hashedPassword == $GLOBALS['TYPO3_CONF_VARS']['BE']['installToolPassword']) ? true: false;
}
// If a new password should get set, and the correct hash value gets submitted
// set the new password in localconf.php and authenticate this session
$setNewSubmit = t3lib_div::_GP('setNewPassword');
if ($setNewSubmit && $this->hashedPassword) {
$currentKey = trim(t3lib_div::getUrl($this->enableInstallToolFile));
$storedKey = $this->newPasswordHash.':'.t3lib_div::getIndpEnv('REMOTE_ADDR');
if (!strcmp($storedKey, $currentKey)) {
// When the correct value was found in ENABLE_INSTALL_TOOL set the submitted (currently wrong) password as new one.
$this->setNewPassword($this->hashedPassword);
$passwordOk = true;
}
}
if ($passwordOk) {
$this->session->setAuthorized();
// Sending warning email
......
}
}
/**
* Returns true if submitted password is ok. Checks password by calling the auth service
*
* @return string The submitted password
* @return boolean Returns true if the submitted password was ok
*/
function checkPasswordViaService($password) {
$serviceChain='';
$authenticated = false;
// The submitted data
$loginData = array(
'uident' => $password,
'uident_text' => $password,
// As there are no users for the install tool we supply a dummy user name
'uname' => 'SYSTEM_InstallTool',
);
$authInfo = $_SERVER;
$tempuser = array(
'password' => $GLOBALS['TYPO3_CONF_VARS']['BE']['installToolPassword'],
'lockToDomain' => $GLOBALS['TYPO3_CONF_VARS']['BE']['installTool_lockToDomain'],
// As there are no users for the install tool we supply a uid of "0"
'uid' => 0,
);
while (is_object($serviceObj = t3lib_div::makeInstanceService('auth', 'authInstallTool', $serviceChain))) {
$serviceChain .= ',' . $serviceObj->getServiceKey();
$serviceObj->initAuth('authInstallTool', $loginData, $authInfo, $this);
$ret = $serviceObj->authUser($tempuser);
// Set the hash of the password which was used for login
$this->hashedPassword = $serviceObj->hashedPassword ? $serviceObj->hashedPassword : md5($serviceObj->login['uident_text'] ? $serviceObj->login['uident_text'] : $serviceObj->login['uident']);
if ($ret > 0) {
// if the service returns >=200 then no more checking is needed
// useful for IP checking without password
if (intval($ret) >= 200) {
$authenticated = true;
break;
} elseif (intval($ret) >= 100) {
// Just go on. User is still not authenticated but there's no reason to stop now.
} else {
$authenticated = true;
}
} else {
$authenticated = false;
break;
}
}
// Handle Password update to encrypted/salted passwords:
// The service classes found that the password has to get updated
// This is the case when parameters like hashing iterations or encryption/salting mechanisms have changed
if ($authenticated && $this->updatePassword) {
$this->setNewPassword($this->updatePassword);
}
return $authenticated;
}
/**
* Sets the submitted password as install tool password
*
* @return string The submitted password
* @return boolean Returns true if the submitted password was ok
*/
protected function setNewPassword($newPassword) {
$this->allowUpdateLocalConf = 1;
$lines = $this->writeToLocalconf_control();
$this->setValueInLocalconfFile($lines, '$TYPO3_CONF_VARS[\'BE\'][\'installToolPassword\']', $newPassword);
$this->writeToLocalconf_control($lines, false);
$this->allowUpdateLocalConf = 0;
// Restart session object because install-password has changed
$GLOBALS['TYPO3_CONF_VARS']['BE']['installToolPassword'] = $newPassword;
unset($this->session);
$this->session = t3lib_div::makeInstance('tx_install_session');
$this->session->startSession();
}
function getRsaFormTag($params = array()) {
$loginFormHook = t3lib_div::makeInstance('tx_rsaauth_loginformhook');
$content = '';
if ($altFormTag = $loginFormHook->getLoginFormTag($params, $this)) {
$content .= $loginFormHook->getLoginScripts(array(), $this);
$content .= $altFormTag;
// For compatibility with saltedpasswords system extension
$content .= '<input type="hidden" name="username" value="" />';
$content .= '<input type="hidden" name="userident" value="" />';
}
return $content;
}
/**
* [Describe function...]
*
* @return [type] ...
*/
function loginForm() {
$p = t3lib_div::_GP('password');
$redirect_url = $this->redirect_url ? $this->redirect_url : $this->action;
$this->messageFunc_nl2br=0;
$this->silent=0;
$passwordField = 'password';
$formName = 'passwordForm';
$content = '';
$formStart = '<form action="index.php" method="post" name="passwordForm">';
$content = '<form action="index.php" method="post" name="passwordForm">
<input type="password" name="password"><br />
if (t3lib_extMgm::isLoaded('rsaauth')) {
$rsaFormTag = $this->getRsaFormTag();
if ($rsaFormTag) {
// Use RSA encrypted login
$formStart = $rsaFormTag;
$passwordField = 'p_field';
$formName = 'loginform';
}
}
$content .= $formStart . '
<input type="password" name="' . $passwordField . '"><br />
<input type="hidden" name="redirect_url" value="'.htmlspecialchars($redirect_url).'">
<input type="submit" value="Log in"><br />
<input type="submit" name="loginButton" value="Log in"><br />
<br />
'.$this->fw('The Install Tool Password is <i>not</i> the admin password of TYPO3.<br />
If you don\'t know the current password, you can set a new one by setting the value of $TYPO3_CONF_VARS[\'BE\'][\'installToolPassword\'] in typo3conf/localconf.php to the md5() hash value of the password you desire.'.
($p ? '<br /><br />The password you just tried has this md5-value: <br /><br />'.md5($p) : '')
).'
'.$this->fw('The Install Tool Password is <i>not</i> the admin password of TYPO3.'.
(t3lib_div::_GP('setNewPassword') || t3lib_div::_GP('loginButton') ?
('<br /><br />If you don\'t know the current password, you can set a new one by filling in the new password in the above input field, then copy and paste the below value to the ENABLE_INSTALL_TOOL file and hit "Set new Password" button.
<br /><br />Copy and paste to ENABLE_INSTALL_TOOL<br />
<input type="text" name="setPasswordKey" value="' . $this->session->getNewPasswordHash() . ':' . t3lib_div::getIndpEnv('REMOTE_ADDR') . '" readonly="readonly" size="50" onclick="this.select();" />
<br /><br /><input type="submit" name="setNewPassword" value="Set new password" onclick="return checkNewPassword();" />') : '')).'
</form>
<script type="text/javascript">
<!--
document.passwordForm.password.focus();
function checkNewPassword() {
var currentPass = document.' . $formName . '.' . $passwordField . '.value;
if (currentPass.length < ' . $this->passwordMinChars . ') {
alert("The password must have at least ' . $this->passwordMinChars. ' characters!");
document.' . $formName . '.' . $passwordField . '.focus();
document.' . $formName . '.' . $passwordField . '.select();
return false;
}
return true;
}
document.' . $formName . '.' . $passwordField . '.focus();
//-->
</script>';
......
$doit=1;
if ($k=='BE' && $vk=='installToolPassword') {
if ($value) {
if (isset($_POST['installToolPassword_check']) && (!t3lib_div::_GP('installToolPassword_check') || strcmp(t3lib_div::_GP('installToolPassword_check'),$value))) {
$doit=0;
t3lib_div::debug('ERROR: The two passwords did not match! The password was not changed.');
if (($rsaPass = t3lib_div::_GP('userident')) && t3lib_extMgm::isLoaded('rsaauth')) {
$this->checkPasswordViaService($rsaPass);
$value = $this->hashedPassword;
} else {
if (isset($_POST['installToolPassword_check']) && (!t3lib_div::_GP('installToolPassword_check') || strcmp(t3lib_div::_GP('installToolPassword_check'),$value))) {
$doit=0;
t3lib_div::debug('ERROR: The two passwords did not match! The password was not changed.');
}
if (t3lib_div::_GP('installToolPassword_md5')) $value =md5($value);
}
if (t3lib_div::_GP('installToolPassword_md5')) $value =md5($value);
} else $doit=0;
}
......
* @return [type] ...
*/
function alterPasswordForm() {
$content = '<form action="'.$this->scriptSelf.'?TYPO3_INSTALL[type]=extConfig" method="post">
$formAction = $this->scriptSelf.'?TYPO3_INSTALL[type]=extConfig';
$passwordField = 'TYPO3_INSTALL[extConfig][BE][installToolPassword]';
$fomrStart = '<form action="' . $formAction . '" method="post" onsubmit="return comparePasswords();">';
if (t3lib_extMgm::isLoaded('rsaauth')) {
$rsaFormTag = $this->getRsaFormTag(array('formAction' => $formAction, 'formOnSubmit' => 'return comparePasswords() && tx_rsaauth_encrypt();'));
if ($rsaFormTag) {
// Use RSA encrypted login
$formStart = $rsaFormTag;
$formStart .= '<input type="hidden" name="' . $passwordField. '" value="1" />';
$passwordField = 'p_field';
$formName = 'loginform';
}
}
$content = '
<script type="text/javascript">
<!--
function comparePasswords() {
var pass1 = document.getElementById("changePassword1").value;
var pass2 = document.getElementById("changePassword2").value;
if (pass1.length < ' . $this->passwordMinChars . ') {
alert("The password must have at least ' . $this->passwordMinChars. ' characters!");
document.getElementById("changePassword2").value = "";
document.getElementById("changePassword1").value = "";
document.getElementById("changePassword1").focus();
return false;
}
if (pass1 != pass2) {
alert("The two passwords do not match");
document.getElementById("changePassword2").value = "";
document.getElementById("changePassword1").value = "";
document.getElementById("changePassword1").focus();
return false;
}
// Unset second value so no cleartext password gets transmitted
document.getElementById("changePassword2").value = "";
return true;
}
-->
</script>
' . $formStart . '
Enter new password:
<input type="password" name="TYPO3_INSTALL[extConfig][BE][installToolPassword]" /><br />Enter again:
<input type="password" name="installToolPassword_check" />
<input type="password" id="changePassword1" name="' . $passwordField . '" /><br />Enter again:
<input type="password" id="changePassword2" name="installToolPassword_check" />
<input type="hidden" name="installToolPassword_md5" value="1" />
<input type="submit" value="Set new password" /><br />
</form>';
return $content;
return $content;
}
/**
typo3/sysext/install/mod/class.tx_install_session.php (working copy)
}
/**
* Sets a random hash value in the session for retrieval upon next hit.
* This is used for allowing to set a new Install Tool Password when this
* value has been written to ENABLE_INSTALL_TOOL by an admin
*
* @return void
*/
public function setNewPasswordHash() {
$_SESSION['newPasswordHash'] = md5(serialize(microtime()).rand(0, 10000000));
}
/**
* Returns the stored hash value for comparison against the value from ENABLE_INSTALL_TOOL
*
* @return string The current temporary password hash
*/
public function getNewPasswordHash() {
return $_SESSION['newPasswordHash'];
}
/**
* Check if we have an already authorized session
*
* @return boolean True if this session has been authorized before (by a correct password)
typo3/sysext/rsaauth/hooks/class.tx_rsaauth_loginformhook.php (working copy)
*
* @return string Form tag
*/
public function getLoginFormTag(array $params, SC_index& $pObj) {
public function getLoginFormTag(array $params, &$pObj) {
$form = null;
if ($pObj->loginSecurityLevel == 'rsa') {
......
if (!is_null($backend)) {
// Add form tag
$form = '<form action="index.php" method="post" name="loginform" onsubmit="tx_rsaauth_encrypt();">';
$form = '<form action="' . ($params['formAction'] ? $params['formAction'] : 'index.php') . '" method="post" name="loginform" onsubmit="' . ($params['formOnSubmit'] ? $params['formOnSubmit'] : 'tx_rsaauth_encrypt();' ) . '">';
// Generate a new key pair
$keyPair = $backend->createNewKeyPair();
......
* @param SC_index $pObj Calling object
* @return string The code for the login form
*/
public function getLoginScripts(array $params, SC_index &$pObj) {
public function getLoginScripts(array $params, &$pObj) {
$content = '';
if ($pObj->loginSecurityLevel == 'rsa') {
typo3/sysext/rsaauth/ext_localconf.php (working copy)
'title' => 'RSA authentication',
'description' => 'Authenticates users by using encrypted passwords',
'subtype' => 'getUserBE,authUserBE,getUserFE,authUserFE',
'subtype' => 'getUserBE,authUserBE,getUserFE,authUserFE,authInstallTool',
'available' => TRUE,
'priority' => 60, // tx_svauth_sv1 has 50, t3sec_saltedpw has 55. This service must have higher priority!
(1-1/2)