Commit 67594662 authored by Marc Egger's avatar Marc Egger
Browse files

References #11798 : use official password hashing API instead of hack

parent f9bcc6fe
Pipeline #4813 passed with stages
in 4 minutes and 14 seconds
......@@ -127,7 +127,7 @@ For QFQ variables and FormElements:
+------------------+------+-------+-----------------------------------------------------------------------------------------+
| Name | Form | Query | Pattern |
+==================+======+=======+=========================================================================================+
| **alnumx** | Form | Query | [A-Za-z][0-9]@-_.,;: /() ÀÈÌÒÙàèìòùÁÉÍÓÚÝáéíóúýÂÊÎÔÛâêîôûÃÑÕãñõÄËÏÖÜŸäëïöüÿçß |
| **alnumx** | Form | Query | [A-Za-z][0-9]@-_.,;: /() ÀÈÌÒÙàèìòùÁÉÍÓÚÝáéíóúýÂÊÎÔÛâêîôûÃÑÕãñõÄËÏÖÜŸäëïöüÿçß |
+------------------+------+-------+-----------------------------------------------------------------------------------------+
| **digit** | Form | Query | [0-9] |
+------------------+------+-------+-----------------------------------------------------------------------------------------+
......
......@@ -498,8 +498,6 @@ const SYSTEM_DB_NAME_DATA = 'dbNameData';
const SYSTEM_DB_NAME_QFQ = 'dbNameQfq';
const SYSTEM_DB_NAME_T3 = 'dbNameT3';
const SYSTEM_PW_HASHING_CLASS = 'passwordHashingClassName';
const SYSTEM_QFQ_LOG_PATHFILENAME = 'qfqLog'; // absolute or relative to app
const SYSTEM_MAIL_LOG_PATHFILENAME = 'mailLog'; // absolute or relative to app
......
......@@ -42,7 +42,7 @@ class Config {
*/
public static function get(string $key)
{
self::readConfig();
self::readConfig(); // only reads once
return self::$config[$key] ?? null;
}
......@@ -57,7 +57,7 @@ class Config {
*/
public static function getConfigArray($PhpUnitOverloadCwdToConfigFile = ''): array
{
self::readConfig($PhpUnitOverloadCwdToConfigFile);
self::readConfig($PhpUnitOverloadCwdToConfigFile); // only reads once, except if argument !=''
return self::$config;
}
......@@ -73,6 +73,7 @@ class Config {
private static function readConfig($PhpUnitOverloadCwdToConfigFile = '') {
if (self::$config !== null && $PhpUnitOverloadCwdToConfigFile === '') {
// only read once, except phpUnit
return;
}
......@@ -203,9 +204,6 @@ class Config {
// Typo3 version >=9
$configT3qfq = $GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS'][EXT_KEY];
$configT3qfq[SYSTEM_DB_NAME_T3] = self::getDbName($GLOBALS['TYPO3_CONF_VARS']['DB']);
// Typo3 version >=10
$configT3qfq[SYSTEM_PW_HASHING_CLASS] = $GLOBALS['TYPO3_CONF_VARS']['BE']['passwordHashing']['className'] ?? null;
// NOTE: This does not use the official API to access Typo3 password hashing. Here is the official API: https://docs.typo3.org/m/typo3/reference-coreapi/master/en-us/ApiOverview/PasswordHashing/
} elseif (isset($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf'][EXT_KEY])) {
// Typo3 version <=8
......@@ -218,9 +216,6 @@ class Config {
if (isset($configT3['EXTENSIONS'][EXT_KEY])) {
// Typo3 version >=9
$configT3qfq = $configT3['EXTENSIONS'][EXT_KEY];
// Typo3 version >=10
$configT3qfq[SYSTEM_PW_HASHING_CLASS] = $configT3['BE']['passwordHashing']['className'] ?? null;
// NOTE: This does not use the official API to access Typo3 password hashing. Here is the official API: https://docs.typo3.org/m/typo3/reference-coreapi/master/en-us/ApiOverview/PasswordHashing/
} else {
// Typo3 version <=8
$configT3qfq = unserialize($configT3['EXT']['extConf'][EXT_KEY]);
......
......@@ -10,7 +10,6 @@ namespace IMATHUZH\Qfq\Core\Typo3;
use IMATHUZH\Qfq\Core\Helper\Path;
use IMATHUZH\Qfq\Core\Helper\Support;
use IMATHUZH\Qfq\Core\Store\Config;
/**
......@@ -41,14 +40,9 @@ class T3Handler {
/**
* Convert a cleartext password to a hash. Respects if 'salted passwords' are enabled.
* NOTE: This does not use the official API to access Typo3 password hashing. Here is the official API: https://docs.typo3.org/m/typo3/reference-coreapi/master/en-us/ApiOverview/PasswordHashing/
* Legacy code (Typo3 version <=8) based on https://docs.typo3.org/typo3cms/extensions/saltedpasswords/8.7/DevelopersGuide/Index.html
*
* @param string $newPassword
* @return string
* @throws \CodeException
* @throws \UserFormException
* @throws \UserReportException
*/
public static function getHash($newPassword) {
......@@ -57,16 +51,18 @@ class T3Handler {
$saltedPassword = null;
$t3Hasher = self::getT3HashingInstance(); //implements interface: TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashInterface
if (!is_null($t3Hasher)) {
if (class_exists('\TYPO3\CMS\Core\Utility\GeneralUtility')
&& class_exists('\TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashFactory')) {
// Typo3 version >=9
$saltedPassword = $t3Hasher->getHashedPassword($newPassword);
// NOTE: This does not use the official API to access Typo3 password hashing. Here is the official API: https://docs.typo3.org/m/typo3/reference-coreapi/master/en-us/ApiOverview/PasswordHashing/
$hashInstance = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashFactory::class)
->getDefaultHashInstance('FE');
$saltedPassword = $hashInstance->getHashedPassword($newPassword);
} elseif (class_exists('\TYPO3\CMS\Saltedpasswords\Utility\SaltedPasswordsUtility') && class_exists('\TYPO3\CMS\Saltedpasswords\Salt\SaltFactory')) {
// Typo3 version <=8
// Legacy code based on https://docs.typo3.org/typo3cms/extensions/saltedpasswords/8.7/DevelopersGuide/Index.html
if (\TYPO3\CMS\Saltedpasswords\Utility\SaltedPasswordsUtility::isUsageEnabled('FE')) {
$objSalt = \TYPO3\CMS\Saltedpasswords\Salt\SaltFactory::getSaltingInstance(NULL);
if (is_object($objSalt)) {
......@@ -89,15 +85,10 @@ class T3Handler {
/**
* Check if the salted password corresponds to the password.
* NOTE: This does not use the official API to access Typo3 password hashing. Here is the official API: https://docs.typo3.org/m/typo3/reference-coreapi/master/en-us/ApiOverview/PasswordHashing/
* Legacy code (Typo3 version <=8) based on https://docs.typo3.org/typo3cms/extensions/saltedpasswords/8.7/DevelopersGuide/Index.html
*
* @param string $saltedPassword
* @param string $password
* @return bool
* @throws \CodeException
* @throws \UserFormException
* @throws \UserReportException
*/
public static function checkPassword($saltedPassword, $password) {
......@@ -106,17 +97,18 @@ class T3Handler {
// Restore T3 ErrorHandler. T3 throws exceptions - those should be handled by T3!
restore_error_handler();
$t3Hasher = self::getT3HashingInstance(); //implements interface: TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashInterface
if (!is_null($t3Hasher)) {
if (class_exists('\TYPO3\CMS\Core\Utility\GeneralUtility')
&& class_exists('\TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashFactory')) {
// Typo3 version >=9
$success = $t3Hasher->checkPassword($password, $saltedPassword);
// NOTE: This does not use the official API to access Typo3 password hashing. Here is the official API: https://docs.typo3.org/m/typo3/reference-coreapi/master/en-us/ApiOverview/PasswordHashing/
$success = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashFactory::class)
->get($saltedPassword, 'FE') # or getDefaultHashInstance($mode)
->checkPassword($password, $saltedPassword);
} elseif (class_exists('\TYPO3\CMS\Saltedpasswords\Utility\SaltedPasswordsUtility') && class_exists('\TYPO3\CMS\Saltedpasswords\Salt\SaltFactory')) {
// Typo3 version <=8
// Legacy code based on https://docs.typo3.org/typo3cms/extensions/saltedpasswords/8.7/DevelopersGuide/Index.html
if (\TYPO3\CMS\Saltedpasswords\Utility\SaltedPasswordsUtility::isUsageEnabled('FE')) {
$objSalt2 = \TYPO3\CMS\Saltedpasswords\Salt\SaltFactory::getSaltingInstance($saltedPassword);
if (is_object($objSalt2)) {
......@@ -137,26 +129,6 @@ class T3Handler {
return $success;
}
/**
* Return an instance of the Typo3 password hashing class as configured in LocalConfiguration.php
* Returns object which implements interface: TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashInterface
* NOTE: This does not use the official API to access Typo3 password hashing. Here is the official API: https://docs.typo3.org/m/typo3/reference-coreapi/master/en-us/ApiOverview/PasswordHashing/
*
* @return mixed|null
* @throws \CodeException
* @throws \UserFormException
* @throws \UserReportException
*/
public static function getT3HashingInstance()
{
self::t3AutoloadIfNotRunning();
$hashingClass = Config::get(SYSTEM_PW_HASHING_CLASS);
if(!is_string($hashingClass) || !class_exists($hashingClass)) {
return null;
}
return new $hashingClass;
}
/**
* Load Typo3 autoloader if Typo3 is not instantiated
*
......
Supports Markdown
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