[TASK] Use name-resolution instead of strings where possible: 9
[Packages/TYPO3.CMS.git] / typo3 / sysext / saltedpasswords / Classes / Salt / SaltFactory.php
1 <?php
2 namespace TYPO3\CMS\Saltedpasswords\Salt;
3
4 /**
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 /**
18 * Class that implements Blowfish salted hashing based on PHP's
19 * crypt() function.
20 *
21 * @author Marcus Krause <marcus#exp2009@t3sec.info>
22 */
23 class SaltFactory {
24
25 /**
26 * An instance of the salted hashing method.
27 * This member is set in the getSaltingInstance() function.
28 *
29 * @var \TYPO3\CMS\Saltedpasswords\Salt\AbstractSalt
30 */
31 static protected $instance = NULL;
32
33 /**
34 * Returns list of all registered hashing methods. Used eg. in
35 * extension configuration to select the default hashing method.
36 *
37 * @return array
38 */
39 static public function getRegisteredSaltedHashingMethods() {
40 $saltMethods = static::getDefaultSaltMethods();
41 if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/saltedpasswords']['saltMethods'])) {
42 $configuredMethods = (array)$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/saltedpasswords']['saltMethods'];
43 if (count($configuredMethods) > 0) {
44 if (isset($configuredMethods[0])) {
45 // ensure the key of the array is not numeric, but a class name
46 foreach ($configuredMethods as $method) {
47 $saltMethods[$method] = $method;
48 }
49 } else {
50 $saltMethods = array_merge($saltMethods, $configuredMethods);
51 }
52 }
53 }
54 return $saltMethods;
55 }
56
57 /**
58 * Returns an array with default salt method class names.
59 *
60 * @return array
61 */
62 static protected function getDefaultSaltMethods() {
63 return array(
64 \TYPO3\CMS\Saltedpasswords\Salt\Md5Salt::class => \TYPO3\CMS\Saltedpasswords\Salt\Md5Salt::class,
65 \TYPO3\CMS\Saltedpasswords\Salt\BlowfishSalt::class => \TYPO3\CMS\Saltedpasswords\Salt\BlowfishSalt::class,
66 \TYPO3\CMS\Saltedpasswords\Salt\PhpassSalt::class => \TYPO3\CMS\Saltedpasswords\Salt\PhpassSalt::class
67 );
68 }
69
70
71 /**
72 * Obtains a salting hashing method instance.
73 *
74 * This function will return an instance of a class that implements
75 * \TYPO3\CMS\Saltedpasswords\Salt\SaltInterface
76 *
77 * Use parameter NULL to reset the factory!
78 *
79 * @param string|NULL $saltedHash Salted hashed password to determine the type of used method from or NULL to reset to the default type
80 * @param string $mode The TYPO3 mode (FE or BE) saltedpasswords shall be used for
81 * @return SaltInterface An instance of salting hash method class
82 */
83 static public function getSaltingInstance($saltedHash = '', $mode = TYPO3_MODE) {
84 // Creating new instance when
85 // * no instance existing
86 // * a salted hash given to determine salted hashing method from
87 // * a NULL parameter given to reset instance back to default method
88 if (!is_object(self::$instance) || !empty($saltedHash) || $saltedHash === NULL) {
89 // Determine method by checking the given hash
90 if (!empty($saltedHash)) {
91 $result = self::determineSaltingHashingMethod($saltedHash, $mode);
92 if (!$result) {
93 self::$instance = NULL;
94 }
95 } else {
96 $classNameToUse = \TYPO3\CMS\Saltedpasswords\Utility\SaltedPasswordsUtility::getDefaultSaltingHashingMethod($mode);
97 $availableClasses = static::getRegisteredSaltedHashingMethods();
98 self::$instance = \TYPO3\CMS\Core\Utility\GeneralUtility::getUserObj($availableClasses[$classNameToUse]);
99 }
100 }
101 return self::$instance;
102 }
103
104 /**
105 * Method tries to determine the salting hashing method used for given salt.
106 *
107 * Method implicitly sets the instance of the found method object in the class property when found.
108 *
109 * @param string $saltedHash
110 * @param string $mode (optional) The TYPO3 mode (FE or BE) saltedpasswords shall be used for
111 * @return bool TRUE, if salting hashing method has been found, otherwise FALSE
112 */
113 static public function determineSaltingHashingMethod($saltedHash, $mode = TYPO3_MODE) {
114 $registeredMethods = static::getRegisteredSaltedHashingMethods();
115 $defaultClassName = \TYPO3\CMS\Saltedpasswords\Utility\SaltedPasswordsUtility::getDefaultSaltingHashingMethod($mode);
116 $defaultReference = $registeredMethods[$defaultClassName];
117 unset($registeredMethods[$defaultClassName]);
118 // place the default method first in the order
119 $registeredMethods = array($defaultClassName => $defaultReference) + $registeredMethods;
120 $methodFound = FALSE;
121 foreach ($registeredMethods as $method) {
122 $objectInstance = \TYPO3\CMS\Core\Utility\GeneralUtility::getUserObj($method);
123 if ($objectInstance instanceof SaltInterface) {
124 $methodFound = $objectInstance->isValidSaltedPW($saltedHash);
125 if ($methodFound) {
126 self::$instance = $objectInstance;
127 break;
128 }
129 }
130 }
131 return $methodFound;
132 }
133
134 /**
135 * Method sets a custom salting hashing method class.
136 *
137 * @param string $resource Object resource to use (e.g. \TYPO3\CMS\Saltedpasswords\Salt\BlowfishSalt::class)
138 * @return \TYPO3\CMS\Saltedpasswords\Salt\AbstractSalt An instance of salting hashing method object
139 */
140 static public function setPreferredHashingMethod($resource) {
141 self::$instance = NULL;
142 $objectInstance = \TYPO3\CMS\Core\Utility\GeneralUtility::getUserObj($resource);
143 if (is_object($objectInstance) && is_subclass_of($objectInstance, \TYPO3\CMS\Saltedpasswords\Salt\AbstractSalt::class)) {
144 self::$instance = $objectInstance;
145 }
146 return self::$instance;
147 }
148 }