/** * Authenticates a user. The function decrypts the password, runs evaluations * on it and passes to the parent authentication service. * * @param array $userRecord User record * @return int Code that shows if user is really authenticated. * @see t3lib_userAuth::checkAuthentication() */ public function authUser(array $userRecord) { $result = 100; if ($this->pObj->security_level == 'rsa') { $storage = tx_rsaauth_storagefactory::getStorage(); /* @var $storage tx_rsaauth_abstract_storage */ // Set failure status by default $result = -1; // Preprocess the password $password = $this->login['uident']; $key = $storage->get(); if ($key != null && substr($password, 0, 4) == 'rsa:') { // Decode password and pass to parent $decryptedPassword = $this->backend->decrypt($key, substr($password, 4)); if ($decryptedPassword != null) { // Run the password through the eval function $decryptedPassword = $this->runPasswordEvaluations($decryptedPassword); if ($decryptedPassword != null) { $this->login['uident'] = $decryptedPassword; if (parent::authUser($userRecord)) { $result = 200; } } } // Reset the password to its original value $this->login['uident'] = $password; // Remove the key $storage->put(null); } } return $result; }
/** * Hooks to the felogin extension to provide additional code for FE login * * @return array 0 => onSubmit function, 1 => extra fields and required files */ public function loginFormHook() { $result = array(0 => '', 1 => ''); if ($GLOBALS['TYPO3_CONF_VARS']['FE']['loginSecurityLevel'] == 'rsa') { $backend = tx_rsaauth_backendfactory::getBackend(); if ($backend) { $result[0] = 'tx_rsaauth_feencrypt(this);'; $javascriptPath = t3lib_extMgm::siteRelPath('rsaauth') . 'resources/'; $files = array('jsbn/jsbn.js', 'jsbn/prng4.js', 'jsbn/rng.js', 'jsbn/rsa.js', 'jsbn/base64.js', 'rsaauth_min.js'); foreach ($files as $file) { $result[1] .= '<script type="text/javascript" src="' . t3lib_div::getIndpEnv('TYPO3_SITE_URL') . $javascriptPath . $file . '"></script>'; } // Generate a new key pair $keyPair = $backend->createNewKeyPair(); // Save private key $storage = tx_rsaauth_storagefactory::getStorage(); /* @var $storage tx_rsaauth_abstract_storage */ $storage->put($keyPair->getPrivateKey()); // Add RSA hidden fields $result[1] .= '<input type="hidden" id="rsa_n" name="n" value="' . htmlspecialchars($keyPair->getPublicKeyModulus()) . '" />'; $result[1] .= '<input type="hidden" id="rsa_e" name="e" value="' . sprintf('%x', $keyPair->getExponent()) . '" />'; } } return $result; }
/** * Adds RSA-specific JavaScript and returns a form tag * * @return string Form tag */ public function getLoginFormTag(array $params, SC_index &$pObj) { $form = null; if ($pObj->loginSecurityLevel == 'rsa') { // If we can get the backend, we can proceed $backend = tx_rsaauth_backendfactory::getBackend(); if (!is_null($backend)) { // Add form tag $form = '<form action="index.php" method="post" name="loginform" onsubmit="tx_rsaauth_encrypt();">'; // Generate a new key pair $keyPair = $backend->createNewKeyPair(); // Save private key $storage = tx_rsaauth_storagefactory::getStorage(); /* @var $storage tx_rsaauth_abstract_storage */ $storage->put($keyPair->getPrivateKey()); // Add RSA hidden fields $form .= '<input type="hidden" id="rsa_n" name="n" value="' . htmlspecialchars($keyPair->getPublicKeyModulus()) . '" />'; $form .= '<input type="hidden" id="rsa_e" name="e" value="' . sprintf('%x', $keyPair->getExponent()) . '" />'; } } return $form; }
/** * Sets the preffered storage to the factory. This method can be called from * another extension or ext_localconf.php * * @param string $preferredStorage Preffered storage * @return void */ public static function setPreferredStorage($preferredStorage) { self::$preferredStorage = $preferredStorage; }
/** * Method adds a further authUser method. * * Will return one of following authentication status codes: * - 0 - authentication failure * - 100 - just go on. User is not authenticated but there is still no reason to stop * - 200 - the service was able to authenticate the user * * @param array Array containing FE user data of the logged user. * @return integer authentication statuscode, one of 0,100 and 200 */ public function authUser(array $user) { $OK = 100; $validPasswd = FALSE; if ($this->pObj->security_level == 'rsa' && t3lib_extMgm::isLoaded('rsaauth')) { require_once t3lib_extMgm::extPath('rsaauth') . 'sv1/backends/class.tx_rsaauth_backendfactory.php'; require_once t3lib_extMgm::extPath('rsaauth') . 'sv1/storage/class.tx_rsaauth_storagefactory.php'; $backend = tx_rsaauth_backendfactory::getBackend(); $storage = tx_rsaauth_storagefactory::getStorage(); // Preprocess the password $password = $this->login['uident']; $key = $storage->get(); if ($key != NULL && substr($password, 0, 4) == 'rsa:') { // Decode password and pass to parent $decryptedPassword = $backend->decrypt($key, substr($password, 4)); $this->login['uident_text'] = $decryptedPassword; } } if ($this->login['uident'] && $this->login['uname']) { if (!empty($this->login['uident_text'])) { $validPasswd = $this->compareUident($user, $this->login); } if (!$validPasswd && (intval($this->extConf['onlyAuthService']) || $this->authenticationFailed)) { // Failed login attempt (wrong password) - no delegation to further services $this->writeLog(TYPO3_MODE . ' Authentication failed - wrong password for username \'%s\'', $this->login['uname']); $OK = 0; } else { if (!$validPasswd) { // Failed login attempt (wrong password) $this->writeLog("Login-attempt from %s, username '%s', password not accepted!", $this->authInfo['REMOTE_ADDR'], $this->login['uname']); } else { if ($validPasswd && $user['lockToDomain'] && strcasecmp($user['lockToDomain'], $this->authInfo['HTTP_HOST'])) { // Lock domain didn't match, so error: $this->writeLog("Login-attempt from %s, username '%s', locked domain '%s' did not match '%s'!", $this->authInfo['REMOTE_ADDR'], $this->login['uname'], $user['lockToDomain'], $this->authInfo['HTTP_HOST']); $OK = 0; } else { if ($validPasswd) { $this->writeLog(TYPO3_MODE . ' Authentication successful for username \'%s\'', $this->login['uname']); $OK = 200; } } } } } return $OK; }
/** * Decrypts fields that were encrypted for transmission * * @param array $row: incoming data array that may contain encrypted fields * @return boolean TRUE if decryption was successful */ public function decryptIncomingFields(array &$row) { $success = TRUE; $fields = array('password', 'password_again'); $incomingFieldSet = FALSE; foreach ($fields as $field) { if (isset($row[$field])) { $incomingFieldSet = TRUE; break; } } if ($incomingFieldSet) { switch ($this->getTransmissionSecurityLevel()) { case 'rsa': // Get services from rsaauth // Can't simply use the authentication service because we have two fields to decrypt $backend = tx_rsaauth_backendfactory::getBackend(); $storage = tx_rsaauth_storagefactory::getStorage(); /* @var $storage tx_rsaauth_abstract_storage */ if (is_object($backend) && is_object($storage)) { $key = $storage->get(); if ($key != NULL) { foreach ($fields as $field) { if (isset($row[$field]) && $row[$field] != '') { if (substr($row[$field], 0, 4) == 'rsa:') { // Decode password $result = $backend->decrypt($key, substr($row[$field], 4)); if ($result) { $row[$field] = $result; } else { // RSA auth service failed to process incoming password // May happen if the key is wrong // May happen if multiple instance of rsaauth on same page $success = FALSE; $message = $GLOBALS['TSFE']->sL('LLL:EXT:' . $this->extKey . '/pi1/locallang.xml:internal_rsaauth_process_incoming_password_failed'); t3lib_div::sysLog($message, $this->extKey, t3lib_div::SYSLOG_SEVERITY_ERROR); } } } } // Remove the key $storage->put(NULL); } else { // RSA auth service failed to retrieve private key // May happen if the key was already removed $success = FALSE; $message = $GLOBALS['TSFE']->sL('LLL:EXT:' . $this->extKey . '/pi1/locallang.xml:internal_rsaauth_retrieve_private_key_failed'); t3lib_div::sysLog($message, $this->extKey, t3lib_div::SYSLOG_SEVERITY_ERROR); } } else { // Required RSA auth backend not available // Should not happen: checked in tx_srfeuserregister_pi1_base::checkRequirements $success = FALSE; $message = $GLOBALS['TSFE']->sL('LLL:EXT:' . $this->extKey . '/pi1/locallang.xml:internal_rsaauth_backend_not_available'); t3lib_div::sysLog($message, $this->extKey, t3lib_div::SYSLOG_SEVERITY_ERROR); } break; case 'normal': default: // Nothing to decrypt break; } } return $success; }
protected function checkRequirements() { $content = ''; // Check if all required extensions are available if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->extKey]['constraints']['depends'])) { $requiredExtensions = array_diff(array_keys($GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->extKey]['constraints']['depends']), array('php', 'typo3')); foreach ($requiredExtensions as $requiredExtension) { if (!t3lib_extMgm::isLoaded($requiredExtension)) { $message = sprintf($GLOBALS['TSFE']->sL('LLL:EXT:' . $this->extKey . '/pi1/locallang.xml:internal_required_extension_missing'), $requiredExtension); t3lib_div::sysLog($message, $this->extKey, t3lib_div::SYSLOG_SEVERITY_ERROR); $content .= sprintf($GLOBALS['TSFE']->sL('LLL:EXT:' . $this->extKey . '/pi1/locallang.xml:internal_check_requirements_frontend'), $message); } } } // Check if front end login security level is correctly set $supportedTransmissionSecurityLevels = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF'][$this->extKey]['loginSecurityLevels']; if (!in_array($GLOBALS['TYPO3_CONF_VARS']['FE']['loginSecurityLevel'], $supportedTransmissionSecurityLevels)) { $message = $GLOBALS['TSFE']->sL('LLL:EXT:' . $this->extKey . '/pi1/locallang.xml:internal_login_security_level'); t3lib_div::sysLog($message, $this->extKey, t3lib_div::SYSLOG_SEVERITY_ERROR); $content .= sprintf($GLOBALS['TSFE']->sL('LLL:EXT:' . $this->extKey . '/pi1/locallang.xml:internal_check_requirements_frontend'), $message); } else { // Check if salted passwords are enabled in front end if (t3lib_extMgm::isLoaded('saltedpasswords')) { if (!tx_saltedpasswords_div::isUsageEnabled('FE')) { $message = $GLOBALS['TSFE']->sL('LLL:EXT:' . $this->extKey . '/pi1/locallang.xml:internal_salted_passwords_disabled'); t3lib_div::sysLog($message, $this->extKey, t3lib_div::SYSLOG_SEVERITY_ERROR); $content .= sprintf($GLOBALS['TSFE']->sL('LLL:EXT:' . $this->extKey . '/pi1/locallang.xml:internal_check_requirements_frontend'), $message); } else { // Check if we can get a salting instance $objSalt = tx_saltedpasswords_salts_factory::getSaltingInstance(NULL); if (!is_object($objSalt)) { // Could not get a salting instance from saltedpasswords $message = $GLOBALS['TSFE']->sL('LLL:EXT:' . $this->extKey . '/pi1/locallang.xml:internal_salted_passwords_no_instance'); t3lib_div::sysLog($message, $this->extKey, t3lib_div::SYSLOG_SEVERITY_ERROR); $content .= sprintf($GLOBALS['TSFE']->sL('LLL:EXT:' . $this->extKey . '/pi1/locallang.xml:internal_check_requirements_frontend'), $message); } } } // Check if we can get a backend from rsaauth if (t3lib_extMgm::isLoaded('rsaauth')) { // rsaauth in TYPO3 4.5 misses autoload if (!class_exists('tx_rsaauth_backendfactory')) { require_once t3lib_extMgm::extPath('rsaauth') . 'sv1/backends/class.tx_rsaauth_backendfactory.php'; require_once t3lib_extMgm::extPath('rsaauth') . 'sv1/storage/class.tx_rsaauth_storagefactory.php'; } $backend = tx_rsaauth_backendfactory::getBackend(); $storage = tx_rsaauth_storagefactory::getStorage(); if (!is_object($backend) || !$backend->isAvailable() || !is_object($storage)) { // Required RSA auth backend not available $message = $GLOBALS['TSFE']->sL('LLL:EXT:' . $this->extKey . '/pi1/locallang.xml:internal_rsaauth_backend_not_available'); t3lib_div::sysLog($message, $this->extKey, t3lib_div::SYSLOG_SEVERITY_ERROR); $content .= sprintf($GLOBALS['TSFE']->sL('LLL:EXT:' . $this->extKey . '/pi1/locallang.xml:internal_check_requirements_frontend'), $message); } } } return $content; }