/** * Checks RSA configuration and creates warnings if necessary. * * @param array $warnings Warnings * @return void * @see t3lib_BEfunc::displayWarningMessages() */ public function displayWarningMessages_postProcess(array &$warnings) { $backend = tx_rsaauth_backendfactory::getBackend(); if ($backend instanceof tx_rsaauth_cmdline_backend) { // Not using the PHP extension! $warnings['rsaauth_cmdline'] = $GLOBALS['LANG']->sL('LLL:EXT:rsaauth/hooks/locallang.xml:hook_using_cmdline'); // Check the path $extconf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['rsaauth']); $path = trim($extconf['temporaryDirectory']); if ($path == '') { // Path is empty $warnings['rsaauth'] = $GLOBALS['LANG']->sL('LLL:EXT:rsaauth/hooks/locallang.xml:hook_empty_directory'); } elseif (!t3lib_div::isAbsPath($path)) { // Path is not absolute $warnings['rsaauth'] = $GLOBALS['LANG']->sL('LLL:EXT:rsaauth/hooks/locallang.xml:hook_directory_not_absolute'); } elseif (!@is_dir($path)) { // Path does not represent a directory $warnings['rsaauth'] = $GLOBALS['LANG']->sL('LLL:EXT:rsaauth/hooks/locallang.xml:hook_directory_not_exist'); } elseif (!@is_writable($path)) { // Directory is not writable $warnings['rsaauth'] = $GLOBALS['LANG']->sL('LLL:EXT:rsaauth/hooks/locallang.xml:hook_directory_not_writable'); } elseif (substr($path, 0, strlen(PATH_site)) == PATH_site) { // Directory is inside the site root $warnings['rsaauth'] = $GLOBALS['LANG']->sL('LLL:EXT:rsaauth/hooks/locallang.xml:hook_directory_inside_siteroot'); } } }
/** * 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; }
/** * Obtains a backend. This function will return a non-abstract class, which * is derieved from the tx_rsaauth_abstract_backend. Applications should * not use anoy methods that are not declared in the tx_rsaauth_abstract_backend. * * @return tx_rsaauth_abstract_backend A backend */ public static function getBackend() { if (!self::$initialized) { // Backend does not exist yet. Create it. foreach (self::$availableBackends as $backend) { $backendObject = t3lib_div::getUserObj($backend); // Check that it is derieved from the proper base class if ($backendObject instanceof tx_rsaauth_abstract_backend) { /* @var $backendObject tx_rsaauth_abstract_backend */ if ($backendObject->isAvailable()) { // The backend is available, save it and stop the loop self::$selectedBackend = $backendObject; self::$initialized = true; break; } // Attempt to force destruction of the object unset($backend); } } } return self::$selectedBackend; }
/** * 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; }
/** * Initializes the service. * * @return boolean */ public function init() { $available = parent::init(); if ($available) { // Get the backend $this->backend = tx_rsaauth_backendfactory::getBackend(); if (is_null($this->backend)) { $available = false; } } return $available; }
/** * Decrypts the password for auto-login on confirmation or invitation acceptation * * @param array $dataArray: table row containing the password to be decrypted * @param array $row: incoming data containing the auto-login private key * @return void */ public function decryptPasswordForAutoLogin(array &$dataArray, array $row) { if (isset($row['auto_login_key'])) { $privateKey = $row['auto_login_key']; if ($privateKey !== '') { $password = $dataArray['tx_srfeuserregister_password']; if ($password != '') { $backend = tx_rsaauth_backendfactory::getBackend(); if (is_object($backend) && $backend->isAvailable()) { $decryptedPassword = $backend->decrypt($privateKey, $password); if ($decryptedPassword) { $dataArray['password'] = $decryptedPassword; } else { // Failed to decrypt auto login password $message = $GLOBALS['TSFE']->sL('LLL:EXT:' . $this->extKey . '/pi1/locallang.xml:internal_decrypt_auto_login_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 } } } } }
/** * 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; }