[TASK] Replace Space Indent into Tab indent (CGL Cleanup)
[Packages/TYPO3.CMS.git] / typo3 / sysext / saltedpasswords / classes / class.tx_saltedpasswords_emconfhelper.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) Steffen Ritter (info@rs-websystems.de)
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 // Make sure that we are executed only in TYPO3 context
28 if (!defined ('TYPO3_MODE')) die ('Access denied.');
29
30
31 /**
32 * class providing configuration checks for saltedpasswords.
33 *
34 * @author Steffen Ritter <info@rs-websystems.de>
35 *
36 * @since 2009-09-04
37 * @package TYPO3
38 * @subpackage tx_saltedpasswords
39 */
40 class tx_saltedpasswords_emconfhelper {
41 /**
42 * @var integer
43 */
44 protected $errorType = t3lib_FlashMessage::OK;
45
46 /**
47 * @var string
48 */
49 protected $header;
50
51 /**
52 * @var string
53 */
54 protected $preText;
55
56 /*
57 * @var array
58 */
59 protected $problems = array();
60
61 /**
62 * Set the error level if no higher level
63 * is set already
64 *
65 * @param string $level: one out of error, ok, warning, info
66 * @return void
67 */
68 private function setErrorLevel($level) {
69
70 switch ($level) {
71 case 'error':
72 $this->errorType = t3lib_FlashMessage::ERROR;
73 $this->header = 'Errors found in your configuration';
74 $this->preText = 'SaltedPasswords will not work until these problems have been resolved:<br />';
75 break;
76 case 'warning':
77 if ($this->errorType < t3lib_FlashMessage::ERROR) {
78 $this->errorType = t3lib_FlashMessage::WARNING;
79 $this->header = 'Warnings about your configuration';
80 $this->preText = 'SaltedPasswords might behave different than expected:<br />';
81 }
82 break;
83 case 'info':
84 if ($this->errorType < t3lib_FlashMessage::WARNING) {
85 $this->errorType = t3lib_FlashMessage::INFO;
86 $this->header = 'Additional information';
87 $this->preText = '<br />';
88 }
89 break;
90 case 'ok':
91 // TODO: Remove INFO condition as it has lower importance
92 if ($this->errorType < t3lib_FlashMessage::WARNING && $this->errorType != t3lib_FlashMessage::INFO) {
93 $this->errorType = t3lib_FlashMessage::OK;
94 $this->header = 'No errors were found';
95 $this->preText = 'SaltedPasswords has been configured correctly and works as expected.<br />';
96 }
97 break;
98 }
99 }
100
101 /**
102 * Renders the flash messages if problems have been found.
103 *
104 * @return string The flash message as HTML.
105 */
106 private function renderFlashMessage() {
107 $message = '';
108 // if there are problems, render them into an unordered list
109 if (count($this->problems) > 0) {
110 $message = <<< EOT
111 <ul>
112 <li>###PROBLEMS###</li>
113 </ul>
114 EOT;
115 $message = str_replace('###PROBLEMS###', implode('<br />&nbsp;</li><li>', $this->problems), $message);
116
117 if ($this->errorType > t3lib_FlashMessage::OK) {
118 $message .= <<< EOT
119 <br />
120 Note, that a wrong configuration might have impact on the security of
121 your TYPO3 installation and the usability of the backend.
122 EOT;
123 }
124 }
125
126 if (empty($message)) {
127 $this->setErrorLevel('ok');
128 }
129
130 $message = $this->preText . $message;
131 $flashMessage = t3lib_div::makeInstance('t3lib_FlashMessage', $message, $this->header, $this->errorType);
132
133 return $flashMessage->render();
134 }
135
136 /**
137 * Initializes this object.
138 *
139 * @return void
140 */
141 private function init() {
142 $requestSetup = $this->processPostData((array)$_REQUEST['data']);
143 $extConf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['saltedpasswords']);
144 $this->extConf['BE'] = array_merge((array)$extConf['BE.'], (array)$requestSetup['BE.']);
145 $this->extConf['FE'] = array_merge((array)$extConf['FE.'], (array)$requestSetup['FE.']);
146 $GLOBALS['LANG']->includeLLFile('EXT:saltedpasswords/locallang.xml');
147 }
148
149 /**
150 * Checks the backend configuration and shows a message if necessary.
151 *
152 * @param array $params: Field information to be rendered
153 * @param t3lib_tsStyleConfig $pObj: The calling parent object.
154 * @return string Messages as HTML if something needs to be reported
155 */
156 public function checkConfigurationBackend(array $params, t3lib_tsStyleConfig $pObj) {
157 $this->init();
158 $extConf = $this->extConf['BE'];
159
160 // the backend is called over SSL
161 $SSL = (($GLOBALS['TYPO3_CONF_VARS']['BE']['lockSSL'] > 0 ? TRUE : FALSE) && ($GLOBALS['TYPO3_CONF_VARS']['BE']['loginSecurityLevel'] != 'superchallenged'));
162 $rsaAuthLoaded = t3lib_extMgm::isLoaded('rsaauth');
163
164 if ($extConf['enabled']) {
165 // SSL configured?
166 if ($SSL) {
167 $this->setErrorLevel('ok');
168 $problems[] = 'The backend is configured to use SaltedPasswords over SSL.';
169 } elseif ($rsaAuthLoaded) {
170 if (trim($GLOBALS['TYPO3_CONF_VARS']['BE']['loginSecurityLevel']) === 'rsa') {
171 if ($this->isRsaAuthBackendAvailable()) {
172 $this->setErrorLevel('ok');
173 $problems[] = 'The backend is configured to use SaltedPasswords with RSA authentication.';
174 } else {
175 // this means that login would fail because rsaauth is not working properly
176 $this->setErrorLevel('error');
177 $problems[] = '<strong>Using the extension "rsaauth" is not possible, as no encryption backend ' .
178 'is available. Please install and configure the PHP extension "openssl". '.
179 'See <a href="http://php.net/manual/en/openssl.installation.php" target="_blank">PHP.net</a></strong>.';
180 }
181 } else {
182 // this means that we are not using saltedpasswords
183 $this->setErrorLevel('error');
184 $problems[] = 'The "rsaauth" extension is installed, but TYPO3 is not configured to use it during login.
185 Use the Install Tool to set the Login Security Level for the backend to "rsa"
186 ($TYPO3_CONF_VARS[\'BE\'][\'loginSecurityLevel\'])';
187
188 }
189 } else {
190 // this means that we are not using saltedpasswords
191 $this->setErrorLevel('error');
192 $problems[] = <<< EOT
193 Backend requirements for SaltedPasswords are not met, therefore the
194 authentication will not work even if it was explicitly enabled for backend
195 usage:<br />
196 <ul>
197 <li>Install the "rsaauth" extension and use the Install Tool to set the
198 Login Security Level for the backend to "rsa"
199 (\$TYPO3_CONF_VARS['BE']['loginSecurityLevel'])</li>
200
201 <li>If you have the option to use SSL, you can also configure your
202 backend for SSL usage:<br />
203 Use the Install Tool to set the Security-Level for the backend
204 to "normal" (\$TYPO3_CONF_VARS['BE']['loginSecurityLevel']) and
205 the SSL-locking option to a value greater than "0"
206 (see description - \$TYPO3_CONF_VARS['BE']['lockSSL'])</li>
207 </ul>
208 <br />
209 It is also possible to use "lockSSL" and "rsa" Login Security Level at the same
210 time.
211 EOT;
212 }
213
214 // only saltedpasswords as authsservice
215 if ($extConf['onlyAuthService']) {
216 // warn user that the combination with "forceSalted" may lock him out from Backend
217 if ($extConf['forceSalted']) {
218 $this->setErrorLevel('warning');
219 $problems[] = <<< EOT
220 SaltedPasswords has been configured to be the only authentication service for
221 the backend. Additionally, usage of salted passwords is enforced (forceSalted).
222 The result is that there is no chance to login with users not having a salted
223 password hash.<br />
224 <strong><i>WARNING:</i></strong> This may lock you out of the backend!
225 EOT;
226 } else {
227 // inform the user that things like openid won't work anymore
228 $this->setErrorLevel('info');
229 $problems[] = <<< EOT
230 SaltedPasswords has been configured to be the only authentication service for
231 the backend. This means that other services like "ipauth", "openid", etc. will
232 be ignored (except "rsauth", which is implicitely used).
233 EOT;
234 }
235 }
236 // forceSalted is set
237 if ($extConf['forceSalted'] && !$extConf['onlyAuthService']) {
238 $this->setErrorLevel('info');
239 $problems[] = <<< EOT
240 SaltedPasswords has been configured to enforce salted passwords (forceSalted).
241 <br />
242 This means that only passwords in the format of this extension will succeed for
243 login.<br />
244 <strong><i>IMPORTANT:</i></strong> This has the effect that passwords that are set from
245 the Install Tool will not work!
246 EOT;
247 }
248 // updatePasswd wont work with "forceSalted"
249 if ($extConf['updatePasswd'] && $extConf['forceSalted']) {
250 $this->setErrorLevel('error');
251 $problems[] = <<< EOT
252 SaltedPasswords is configured wrong and will not work as expected:<br />
253 It is not possible to set "updatePasswd" and "forceSalted" at the same time.
254 Please disable either one of them.
255 EOT;
256 }
257 // check if the configured hash-method is available on system
258 if (!$instance = tx_saltedpasswords_salts_factory::getSaltingInstance(NULL,'BE') || !$instance->isAvailable()) {
259 $this->setErrorLevel('error');
260 $problems[] = <<< EOT
261 The selected method for hashing your salted passwords is not available on this
262 system! Please check your configuration.
263 EOT;
264 }
265
266 } else {
267 // not enabled warning
268 $this->setErrorLevel('error');
269 $problems[] = 'SaltedPasswords has been disabled for backend users.';
270 }
271
272 $this->problems = $problems;
273
274 return $this->renderFlashMessage();
275 }
276
277 /**
278 * Checks if rsaauth is able to obtain a backend
279 *
280 * @return bool
281 */
282 protected function isRsaAuthBackendAvailable() {
283 /**
284 * Try to instantiate an RSAauth backend. If this does not work, it means that OpenSSL is not usable
285 * @var $rsaauthBackendFactory tx_rsaauth_backendfactory
286 */
287 $rsaauthBackendFactory = t3lib_div::makeInstance('tx_rsaauth_backendfactory');
288 $backend = $rsaauthBackendFactory->getBackend();
289 return $backend !== NULL;
290 }
291
292 /**
293 * Checks the frontend configuration and shows a message if necessary.
294 *
295 * @param array $params: Field information to be rendered
296 * @param t3lib_tsStyleConfig $pObj: The calling parent object.
297 * @return string Messages as HTML if something needs to be reported
298 */
299 public function checkConfigurationFrontend(array $params, t3lib_tsStyleConfig $pObj) {
300 $this->init();
301 $extConf = $this->extConf['FE'];
302
303 if ($extConf['enabled']) {
304 // inform the user if securityLevel in FE is challenged or blank --> extension won't work
305 if (!t3lib_div::inList('normal,rsa', $GLOBALS['TYPO3_CONF_VARS']['FE']['loginSecurityLevel'])) {
306 $this->setErrorLevel('info');
307 $problems[] = <<< EOT
308 <strong>IMPORTANT:</strong><br />
309 Frontend requirements for SaltedPasswords are not met, therefore the
310 authentication will not work even if it was explicitly enabled for frontend
311 usage:<br />
312 <ul>
313 <li>Install the "rsaauth" extension and use the Install Tool to set the
314 Login Security Level for the frontend to "rsa"
315 (\$TYPO3_CONF_VARS['FE']['loginSecurityLevel'])</li>
316
317 <li>Alternatively, use the Install Tool to set the Login Security Level
318 for the frontend to "normal"
319 (\$TYPO3_CONF_VARS['FE']['loginSecurityLevel'])</li>
320 </ul>
321 <br />
322 Make sure that the Login Security Level is not set to "" or "challenged"!
323 EOT;
324 } elseif (trim($GLOBALS['TYPO3_CONF_VARS']['FE']['loginSecurityLevel']) === 'rsa') {
325 if ($this->isRsaAuthBackendAvailable()) {
326 $this->setErrorLevel('ok');
327 $problems[] = 'The frontend is configured to use SaltedPasswords with RSA authentication.';
328 } else {
329 // this means that login would fail because rsaauth is not working properly
330 $this->setErrorLevel('error');
331 $problems[] = '<strong>Using the extension "rsaauth" is not possible, as no encryption backend ' .
332 'is available. Please install and configure the PHP extension "openssl". '.
333 'See <a href="http://php.net/manual/en/openssl.installation.php" target="_blank">PHP.net</a></strong>.';
334 }
335 }
336 // only saltedpasswords as authsservice
337 if ($extConf['onlyAuthService']) {
338 // warn user taht the combination with "forceSalted" may lock him out from frontend
339 if ($extConf['forceSalted']) {
340 $this->setErrorLevel('warning');
341 $problems[] = <<< EOT
342 SaltedPasswords has been configured to enforce salted passwords (forceSalted).
343 <br />
344 This means that only passwords in the format of this extension will succeed for
345 login.<br />
346 <strong><i>IMPORTANT:</i></strong> Because of this, it is not possible to login with
347 users not having a salted password hash (e.g. existing frontend users).
348 EOT;
349 } else {
350 // inform the user that things like openid won't work anymore
351 $this->setErrorLevel('info');
352 $problems[] = <<< EOT
353 SaltedPasswords has been configured to be the only authentication service for
354 frontend logins. This means that other services like "ipauth", "openid", etc.
355 will be ignored.
356 EOT;
357 }
358 }
359 // forceSalted is set
360 if ($extConf['forceSalted'] && !$extConf['onlyAuthService']) {
361 $this->setErrorLevel('warning');
362 $problems[] = <<< EOT
363 SaltedPasswords has been configured to enforce salted passwords (forceSalted).
364 <br />
365 This means that only passwords in the format of this extension will succeed for
366 login.<br />
367 <strong><i>IMPORTANT:</i></strong> This has the effect that passwords that were set
368 before SaltedPasswords was used will not work (in fact, they need to be
369 redefined).
370 EOT;
371 }
372 // updatePasswd wont work with "forceSalted"
373 if ($extConf['updatePasswd'] && $extConf['forceSalted']) {
374 $this->setErrorLevel('error');
375 $problems[] = <<< EOT
376 SaltedPasswords is configured wrong and will not work as expected:<br />
377 It is not possible to set "updatePasswd" and "forceSalted" at the same time.
378 Please disable either one of them.
379 EOT;
380 }
381
382 } else {
383 // not enabled warning
384 $this->setErrorLevel('info');
385 $problems[] = 'SaltedPasswords has been disabled for frontend users.';
386 }
387
388 $this->problems = $problems;
389
390 return $this->renderFlashMessage();
391 }
392
393 /**
394 * Renders a selector element that allows to select the hash method to be used.
395 *
396 * @param array $params: Field information to be rendered
397 * @param t3lib_tsStyleConfig $pObj: The calling parent object.
398 * @param string $disposal: The configuration disposal ('FE' or 'BE')
399 * @return string The HTML selector
400 */
401 protected function buildHashMethodSelector(array $params, t3lib_tsStyleConfig $pObj, $disposal) {
402 $this->init();
403 $fieldName = substr($params['fieldName'], 5, -1);
404 $unknownVariablePleaseRenameMe = '\'' . substr(md5($fieldName), 0, 10) . '\'';
405
406 $p_field = '';
407
408 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/saltedpasswords']['saltMethods'] as $class => $reference) {
409 $classInstance = t3lib_div::getUserObj($reference, 'tx_');
410
411 if ($classInstance instanceof tx_saltedpasswords_salts && $classInstance->isAvailable()) {
412 $sel = ($this->extConf[$disposal]['saltedPWHashingMethod'] == $class) ? ' selected="selected" ' : '';
413 $label = 'ext.saltedpasswords.title.' . $class;
414 $p_field .= '<option value="' . htmlspecialchars($class) . '"' . $sel . '>' . $GLOBALS['LANG']->getLL($label) . '</option>';
415 }
416 }
417
418 $p_field = '<select id="' . $fieldName . '" name="' . $params['fieldName'] . '" onChange="uFormUrl(' . $unknownVariablePleaseRenameMe . ')">' . $p_field . '</select>';
419
420 return $p_field;
421 }
422
423 /**
424 * Renders a selector element that allows to select the hash method to be used (frontend disposal).
425 *
426 * @param array $params: Field information to be rendered
427 * @param t3lib_tsStyleConfig $pObj: The calling parent object.
428 * @return string The HTML selector
429 */
430 public function buildHashMethodSelectorFE(array $params, t3lib_tsStyleConfig $pObj) {
431 return $this->buildHashMethodSelector($params, $pObj, 'FE');
432 }
433
434 /**
435 * Renders a selector element that allows to select the hash method to be used (backend disposal)
436 *
437 * @param array $params: Field information to be rendered
438 * @param t3lib_tsStyleConfig $pObj: The calling parent object.
439 * @return string The HTML selector
440 */
441 public function buildHashMethodSelectorBE(array $params, t3lib_tsStyleConfig $pObj) {
442 return $this->buildHashMethodSelector($params, $pObj, 'BE');
443 }
444
445 /**
446 * Processes the information submitted by the user using a POST request and
447 * transforms it to a TypoScript node notation.
448 *
449 * @param array $postArray: Incoming POST information
450 * @return array Processed and transformed POST information
451 */
452 private function processPostData(array $postArray = array()) {
453 foreach ($postArray as $key => $value) {
454 // TODO: Explain
455 $parts = explode('.', $key, 2);
456
457 if (count($parts)==2) {
458 // TODO: Explain
459 $value = $this->processPostData(array($parts[1] => $value));
460 $postArray[$parts[0].'.'] = array_merge((array)$postArray[$parts[0].'.'], $value);
461 } else {
462 // TODO: Explain
463 $postArray[$parts[0]] = $value;
464 }
465 }
466
467 return $postArray;
468 }
469 }
470 ?>