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