81f1aad18d9f23e16d7f989cab43cb11e2b79ddf
[Packages/TYPO3.CMS.git] / typo3 / sysext / rsaauth / sv1 / class.tx_rsaauth_sv1.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2009-2011 Dmitry Dulepov <dmitry@typo3.org>
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 *
17 * This script is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * This copyright notice MUST APPEAR in all copies of the script!
23 ***************************************************************/
24
25 require_once(t3lib_extMgm::extPath('sv') . 'class.tx_sv_auth.php');
26 require_once(t3lib_extMgm::extPath('rsaauth') . 'sv1/backends/class.tx_rsaauth_backendfactory.php');
27 require_once(t3lib_extMgm::extPath('rsaauth') . 'sv1/storage/class.tx_rsaauth_storagefactory.php');
28
29 // Include backends
30
31 /**
32 * Service "RSA authentication" for the "rsaauth" extension. This service will
33 * authenticate a user using hos password encoded with one time public key. It
34 * uses the standard TYPO3 service to do all dirty work. Firsts, it will decode
35 * the password and then pass it to the parent service ('sv'). This ensures that it
36 * always works, even if other TYPO3 internals change.
37 *
38 * @author Dmitry Dulepov <dmitry@typo3.org>
39 * @package TYPO3
40 * @subpackage tx_rsaauth
41 */
42 class tx_rsaauth_sv1 extends tx_sv_auth {
43
44 /**
45 * An RSA backend.
46 *
47 * @var tx_rsaauth_abstract_backend
48 */
49 protected $backend = NULL;
50
51 /**
52 * Standard extension key for the service
53 *
54 * @var string
55 */
56 public $extKey = 'rsaauth'; // The extension key.
57
58 /**
59 * Standard prefix id for the service
60 *
61 * @var string
62 */
63 public $prefixId = 'tx_rsaauth_sv1'; // Same as class name
64
65 /**
66 * Standard relative path for the service
67 *
68 * @var string
69 */
70 public $scriptRelPath = 'sv1/class.tx_rsaauth_sv1.php'; // Path to this script relative to the extension dir.
71
72 /**
73 * Authenticates a user. The function decrypts the password, runs evaluations
74 * on it and passes to the parent authentication service.
75 *
76 * @param array $userRecord User record
77 * @return int Code that shows if user is really authenticated.
78 * @see t3lib_userAuth::checkAuthentication()
79 */
80 public function authUser(array $userRecord) {
81 $result = 100;
82
83 if ($this->pObj->security_level == 'rsa') {
84
85 $storage = tx_rsaauth_storagefactory::getStorage();
86 /* @var $storage tx_rsaauth_abstract_storage */
87
88 // Set failure status by default
89 $result = -1;
90
91 // Preprocess the password
92 $password = $this->login['uident'];
93 $key = $storage->get();
94 if ($key != NULL && substr($password, 0, 4) == 'rsa:') {
95 // Decode password and pass to parent
96 $decryptedPassword = $this->backend->decrypt($key, substr($password, 4));
97 if ($decryptedPassword != NULL) {
98 // Run the password through the eval function
99 $decryptedPassword = $this->runPasswordEvaluations($decryptedPassword);
100 if ($decryptedPassword != NULL) {
101 $this->login['uident'] = $decryptedPassword;
102 if (parent::authUser($userRecord)) {
103 $result = 200;
104 }
105 }
106 }
107 // Reset the password to its original value
108 $this->login['uident'] = $password;
109 // Remove the key
110 $storage->put(NULL);
111 }
112 }
113 return $result;
114 }
115
116 /**
117 * Initializes the service.
118 *
119 * @return boolean
120 */
121 public function init() {
122 $available = parent::init();
123 if ($available) {
124 // Get the backend
125 $this->backend = tx_rsaauth_backendfactory::getBackend();
126 if (is_null($this->backend)) {
127 $available = FALSE;
128 }
129 }
130
131 return $available;
132 }
133
134 /**
135 * Runs password evaluations. This is necessary because other extensions can
136 * modify the way the password is stored in the database. We check for all
137 * evaluations for the password column and run those.
138 *
139 * Notes:
140 * - we call t3lib_TCEmain::checkValue_input_Eval() but it is risky: if a hook
141 * relies on BE_USER, it will fail. No hook should do this, so we risk it.
142 * - we cannot use t3lib_TCEmain::checkValue_input_Eval() for running all
143 * evaluations because it does not create md5 hashes.
144 *
145 * @param string $password Evaluated password
146 * @return void
147 * @see t3lib_TCEmain::checkValue_input_Eval()
148 */
149 protected function runPasswordEvaluations($password) {
150 $table = $this->pObj->user_table;
151 t3lib_div::loadTCA($table);
152 $conf = &$GLOBALS['TCA'][$table]['columns'][$this->pObj->userident_column]['config'];
153 $evaluations = $conf['eval'];
154 if ($evaluations) {
155 $tce = NULL;
156 foreach (t3lib_div::trimExplode(',', $evaluations, TRUE) as $evaluation) {
157 switch ($evaluation) {
158 case 'md5':
159 $password = md5($password);
160 break;
161 case 'upper':
162 // We do not pass this to TCEmain because TCEmain will use objects unavailable in FE
163 $csConvObj = (TYPO3_MODE == 'BE' ? $GLOBALS['LANG']->csConvObj : $GLOBALS['TSFE']->csConvObj);
164 $charset = (TYPO3_MODE == 'BE' ? $GLOBALS['LANG']->charSet : $GLOBALS['TSFE']->metaCharset);
165 $password = $csConvObj->conv_case($charset, $password, 'toUpper');
166 break;
167 case 'lower':
168 // We do not pass this to TCEmain because TCEmain will use objects unavailable in FE
169 $csConvObj = (TYPO3_MODE == 'BE' ? $GLOBALS['LANG']->csConvObj : $GLOBALS['TSFE']->csConvObj);
170 $charset = (TYPO3_MODE == 'BE' ? $GLOBALS['LANG']->charSet : $GLOBALS['TSFE']->metaCharset);
171 $password = $csConvObj->conv_case($charset, $password, 'toLower');
172 break;
173 case 'password':
174 case 'required':
175 // Do nothing!
176 break;
177 default:
178 // We must run these evaluations through TCEmain to avoid
179 // code duplication and ensure that any custom evaluations
180 // are called in a proper context
181 if ($tce == NULL) {
182 /* @var $tce t3lib_TCEmain */
183 $tce = t3lib_div::makeInstance('t3lib_TCEmain');
184 }
185 $result = $tce->checkValue_input_Eval($password, array($evaluation), $conf['is_in']);
186 if (!isset($result['value'])) {
187 // Failure!!!
188 return NULL;
189 }
190 $password = $result['value'];
191 }
192 }
193 }
194 return $password;
195 }
196 }
197
198 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/rsaauth/sv1/class.tx_rsaauth_sv1.php'])) {
199 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/rsaauth/sv1/class.tx_rsaauth_sv1.php']);
200 }
201
202 ?>