/** * @test */ public function base64EncodeReturnsProperLength() { // 3 Bytes should result in a 6 char length base64 encoded string // used for MD5 and PHPass salted hashing $byteLength = 3; $reqLengthBase64 = (int) ceil($byteLength * 8 / 6); $randomBytes = GeneralUtility::makeInstance(Random::class)->generateRandomBytes($byteLength); $this->assertTrue(strlen($this->objectInstance->base64Encode($randomBytes, $byteLength)) == $reqLengthBase64); // 16 Bytes should result in a 22 char length base64 encoded string // used for Blowfish salted hashing $byteLength = 16; $reqLengthBase64 = (int) ceil($byteLength * 8 / 6); $randomBytes = GeneralUtility::makeInstance(Random::class)->generateRandomBytes($byteLength); $this->assertTrue(strlen($this->objectInstance->base64Encode($randomBytes, $byteLength)) == $reqLengthBase64); }
/** * Checks the login data with the user record data for builtin login method. * * @param array $user User data array * @param array $loginData Login data array * @param string $passwordCompareStrategy Password compare strategy * @return bool TRUE if login data matched */ public function compareUident(array $user, array $loginData, $passwordCompareStrategy = '') { $validPasswd = false; $password = $loginData['uident_text']; // Determine method used for given salted hashed password $this->objInstanceSaltedPW = \TYPO3\CMS\Saltedpasswords\Salt\SaltFactory::getSaltingInstance($user['password']); // Existing record is in format of Salted Hash password if (is_object($this->objInstanceSaltedPW)) { $validPasswd = $this->objInstanceSaltedPW->checkPassword($password, $user['password']); // Record is in format of Salted Hash password but authentication failed // skip further authentication methods if (!$validPasswd) { $this->authenticationFailed = true; } $defaultHashingClassName = \TYPO3\CMS\Saltedpasswords\Utility\SaltedPasswordsUtility::getDefaultSaltingHashingMethod(); $skip = false; // Test for wrong salted hashing method if ($validPasswd && !(get_class($this->objInstanceSaltedPW) == $defaultHashingClassName) || is_subclass_of($this->objInstanceSaltedPW, $defaultHashingClassName)) { // Instantiate default method class $this->objInstanceSaltedPW = \TYPO3\CMS\Saltedpasswords\Salt\SaltFactory::getSaltingInstance(null); $this->updatePassword((int) $user['uid'], array('password' => $this->objInstanceSaltedPW->getHashedPassword($password))); } if ($validPasswd && !$skip && $this->objInstanceSaltedPW->isHashUpdateNeeded($user['password'])) { $this->updatePassword((int) $user['uid'], array('password' => $this->objInstanceSaltedPW->getHashedPassword($password))); } } elseif (!(int) $this->extConf['forceSalted']) { // Stored password is in deprecated salted hashing method $hashingMethod = substr($user['password'], 0, 2); if ($hashingMethod === 'C$' || $hashingMethod === 'M$') { // Instantiate default method class $this->objInstanceSaltedPW = \TYPO3\CMS\Saltedpasswords\Salt\SaltFactory::getSaltingInstance(substr($user['password'], 1)); // md5 if ($hashingMethod === 'M$') { $validPasswd = $this->objInstanceSaltedPW->checkPassword(md5($password), substr($user['password'], 1)); } else { $validPasswd = $this->objInstanceSaltedPW->checkPassword($password, substr($user['password'], 1)); } // Skip further authentication methods if (!$validPasswd) { $this->authenticationFailed = true; } } elseif (preg_match('/[0-9abcdef]{32,32}/', $user['password'])) { $validPasswd = md5($password) === (string) $user['password']; // Skip further authentication methods if (!$validPasswd) { $this->authenticationFailed = true; } } else { $validPasswd = (string) $password === (string) $user['password']; } // Should we store the new format value in DB? if ($validPasswd && (int) $this->extConf['updatePasswd']) { // Instantiate default method class $this->objInstanceSaltedPW = \TYPO3\CMS\Saltedpasswords\Salt\SaltFactory::getSaltingInstance(null); $this->updatePassword((int) $user['uid'], array('password' => $this->objInstanceSaltedPW->getHashedPassword($password))); } } return $validPasswd; }
/** * Checks the login data with the user record data for builtin login method. * * @param array $user User data array * @param array $loginData Login data array * @param string $security_level Login security level (optional) * @return boolean TRUE if login data matched * @todo Define visibility */ public function compareUident(array $user, array $loginData, $security_level = 'normal') { $validPasswd = FALSE; // Could be merged; still here to clarify if (!strcmp(TYPO3_MODE, 'BE')) { $password = $loginData['uident_text']; } elseif (!strcmp(TYPO3_MODE, 'FE')) { $password = $loginData['uident_text']; } // Determine method used for given salted hashed password $this->objInstanceSaltedPW = \TYPO3\CMS\Saltedpasswords\Salt\SaltFactory::getSaltingInstance($user['password']); // Existing record is in format of Salted Hash password if (is_object($this->objInstanceSaltedPW)) { $validPasswd = $this->objInstanceSaltedPW->checkPassword($password, $user['password']); // Record is in format of Salted Hash password but authentication failed // skip further authentication methods if (!$validPasswd) { $this->authenticationFailed = TRUE; } $defaultHashingClassName = \TYPO3\CMS\Saltedpasswords\Utility\SaltedPasswordsUtility::getDefaultSaltingHashingMethod(); $skip = FALSE; // Test for wrong salted hashing method if ($validPasswd && !(get_class($this->objInstanceSaltedPW) == $defaultHashingClassName) || is_subclass_of($this->objInstanceSaltedPW, $defaultHashingClassName)) { // Instanciate default method class $this->objInstanceSaltedPW = \TYPO3\CMS\Saltedpasswords\Salt\SaltFactory::getSaltingInstance(NULL); $this->updatePassword(intval($user['uid']), array('password' => $this->objInstanceSaltedPW->getHashedPassword($password))); } if ($validPasswd && !$skip && $this->objInstanceSaltedPW->isHashUpdateNeeded($user['password'])) { $this->updatePassword(intval($user['uid']), array('password' => $this->objInstanceSaltedPW->getHashedPassword($password))); } } elseif (!intval($this->extConf['forceSalted'])) { // Stored password is in deprecated salted hashing method if (\TYPO3\CMS\Core\Utility\GeneralUtility::inList('C$,M$', substr($user['password'], 0, 2))) { // Instanciate default method class $this->objInstanceSaltedPW = \TYPO3\CMS\Saltedpasswords\Salt\SaltFactory::getSaltingInstance(substr($user['password'], 1)); // md5 if (!strcmp(substr($user['password'], 0, 1), 'M')) { $validPasswd = $this->objInstanceSaltedPW->checkPassword(md5($password), substr($user['password'], 1)); } else { $validPasswd = $this->objInstanceSaltedPW->checkPassword($password, substr($user['password'], 1)); } // Skip further authentication methods if (!$validPasswd) { $this->authenticationFailed = TRUE; } } elseif (preg_match('/[0-9abcdef]{32,32}/', $user['password'])) { $validPasswd = !strcmp(md5($password), $user['password']) ? TRUE : FALSE; // Skip further authentication methods if (!$validPasswd) { $this->authenticationFailed = TRUE; } } else { $validPasswd = !strcmp($password, $user['password']) ? TRUE : FALSE; } // Should we store the new format value in DB? if ($validPasswd && intval($this->extConf['updatePasswd'])) { // Instanciate default method class $this->objInstanceSaltedPW = \TYPO3\CMS\Saltedpasswords\Salt\SaltFactory::getSaltingInstance(NULL); $this->updatePassword(intval($user['uid']), array('password' => $this->objInstanceSaltedPW->getHashedPassword($password))); } } return $validPasswd; }