‪TYPO3CMS  10.4
BackendModuleController.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Psr\Http\Message\ResponseInterface;
21 use Psr\Http\Message\ServerRequestInterface;
34 use TYPO3\CMS\Install\Service\SessionService;
35 
47 {
48  protected const ‪FLAG_CONFIRMATION_REQUEST = 1;
49  protected const ‪FLAG_INSTALL_TOOL_PASSWORD = 2;
50  protected const ‪ALLOWED_ACTIONS = ['maintenance', 'settings', 'upgrade', 'environment'];
51 
55  protected ‪$sessionService;
56 
60  protected ‪$uriBuilder;
61 
62  public function ‪__construct()
63  {
64  $this->uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
65  }
66 
74  public function ‪backendUserConfirmationAction(ServerRequestInterface $request): ResponseInterface
75  {
76  $flags = (int)($request->getQueryParams()['flags'] ?? 0);
77  $targetController = (string)($request->getQueryParams()['targetController'] ?? '');
78  $targetHash = (string)($request->getQueryParams()['targetHash'] ?? '');
79  $expectedTargetHash = GeneralUtility::hmac($targetController, BackendModuleController::class);
80  $flagInstallToolPassword = (bool)($flags & self::FLAG_INSTALL_TOOL_PASSWORD);
81  $flagInvalidPassword = false;
82 
83  if (!in_array($targetController, self::ALLOWED_ACTIONS)
84  || !hash_equals($expectedTargetHash, $targetHash)) {
85  return new ‪HtmlResponse('', 403);
86  }
87  if ($flags & self::FLAG_CONFIRMATION_REQUEST) {
88  if ($flagInstallToolPassword && $this->‪verifyInstallToolPassword($request)) {
89  return $this->‪setAuthorizedAndRedirect($targetController);
90  }
91  if (!$flagInstallToolPassword && $this->‪verifyBackendUserPassword($request)) {
92  return $this->‪setAuthorizedAndRedirect($targetController);
93  }
94  $flagInvalidPassword = true;
95  }
96 
97  $view = GeneralUtility::makeInstance(StandaloneView::class);
98  $view->getTemplatePaths()->setTemplatePathAndFilename(
100  'install',
101  'Resources/Private/Templates/BackendModule/BackendUserConfirmation.html'
102  )
103  );
104  $view->assignMultiple([
105  'flagInvalidPassword' => $flagInvalidPassword,
106  'flagInstallToolPassword' => $flagInstallToolPassword,
107  'languageFileReference' => 'LLL:EXT:install/Resources/Private/Language/BackendModule.xlf',
108  'passwordModeUri' => $this->‪getBackendUserConfirmationUri([
109  'targetController' => $targetController,
110  'targetHash' => $targetHash,
111  // current flags, unset FLAG_CONFIRMATION_REQUEST, toggle FLAG_INSTALL_TOOL_PASSWORD
112  'flags' => $flags & ~self::FLAG_CONFIRMATION_REQUEST ^ self::FLAG_INSTALL_TOOL_PASSWORD,
113  ]),
114  'verifyUri' => $this->‪getBackendUserConfirmationUri([
115  'targetController' => $targetController,
116  'targetHash' => $targetHash,
117  // current flags, add FLAG_CONFIRMATION_REQUEST
118  'flags' => $flags | self::FLAG_CONFIRMATION_REQUEST,
119  ]),
120  'cancelUri' => '',
121  ]);
122  return new HtmlResponse($view->render());
123  }
124 
130  public function ‪maintenanceAction(): ResponseInterface
131  {
132  return $this->‪getBackendUserConfirmationRedirect('maintenance')
133  ?? $this->‪setAuthorizedAndRedirect('maintenance');
134  }
135 
141  public function ‪settingsAction(): ResponseInterface
142  {
143  return $this->‪getBackendUserConfirmationRedirect('settings')
144  ?? $this->‪setAuthorizedAndRedirect('settings');
145  }
146 
152  public function ‪upgradeAction(): ResponseInterface
153  {
154  return $this->‪getBackendUserConfirmationRedirect('upgrade')
155  ?? $this->‪setAuthorizedAndRedirect('upgrade');
156  }
157 
163  public function ‪environmentAction(): ResponseInterface
164  {
165  return $this->‪getBackendUserConfirmationRedirect('environment')
166  ?? $this->‪setAuthorizedAndRedirect('environment');
167  }
168 
175  protected function ‪getBackendUserConfirmationRedirect(string $targetController): ?ResponseInterface
176  {
177  if ($this->‪getSessionService()->isAuthorizedBackendUserSession()) {
178  return null;
179  }
180  if (‪Environment::getContext()->isDevelopment()) {
181  return null;
182  }
183  $redirectUri = $this->‪getBackendUserConfirmationUri([
184  'targetController' => $targetController,
185  'targetHash' => GeneralUtility::hmac($targetController, BackendModuleController::class),
186  ]);
187  return new RedirectResponse((string)$redirectUri, 403);
188  }
189 
190  protected function ‪getBackendUserConfirmationUri(array $parameters): ‪Uri
191  {
192  return $this->uriBuilder->buildUriFromRoute(
193  'install.backend-user-confirmation',
194  $parameters
195  );
196  }
197 
205  protected function ‪setAuthorizedAndRedirect(string $controller): ResponseInterface
206  {
207  $this->‪getSessionService()->setAuthorizedBackendSession($this->‪getBackendUser());
208  $redirectLocation = 'install.php?install[controller]=' . $controller . '&install[context]=backend';
209  return new RedirectResponse($redirectLocation, 303);
210  }
211 
218  protected function ‪verifyInstallToolPassword(ServerRequestInterface $request): bool
219  {
220  $parsedBody = $request->getParsedBody();
221  $password = $parsedBody['confirmationPassword'] ?? null;
222  $installToolPassword = ‪$GLOBALS['TYPO3_CONF_VARS']['BE']['installToolPassword'] ?? null;
223  if (!is_string($password) || empty($installToolPassword)) {
224  return false;
225  }
226 
227  try {
228  $hashFactory = GeneralUtility::makeInstance(PasswordHashFactory::class);
229  $hashInstance = $hashFactory->get($installToolPassword, 'BE');
230  return $hashInstance->checkPassword($password, $installToolPassword);
231  } catch (InvalidPasswordHashException $exception) {
232  return false;
233  }
234  }
235 
243  protected function ‪verifyBackendUserPassword(ServerRequestInterface $request): bool
244  {
245  $parsedBody = $request->getParsedBody();
246  $password = empty($parsedBody['confirmationPasswordInternal'])
247  ? ($parsedBody['confirmationPassword'] ?? null) // default field
248  : $parsedBody['confirmationPasswordInternal']; // filled e.g. by `ext:rsaauth`
249  if (!is_string($password)) {
250  return false;
251  }
252 
253  // clone current backend user object to avoid
254  // possible side effects for the real instance
255  $backendUser = clone $this->‪getBackendUser();
256  $loginData = [
257  'status' => 'sudo-mode',
258  'origin' => BackendModuleController::class,
259  'uname' => $backendUser->user['username'],
260  'uident' => $password,
261  ];
262  // currently there is no dedicated API to perform authentication
263  // that's why this process partially has to be simulated here
264  $loginData = $backendUser->‪processLoginData($loginData);
265  $authInfo = $backendUser->‪getAuthInfoArray();
266 
267  $authenticated = false;
269  foreach ($this->getAuthServices($backendUser, $loginData, $authInfo) as ‪$service) {
270  $ret = (int)‪$service->authUser($backendUser->user);
271  if ($ret <= 0) {
272  return false;
273  }
274  if ($ret >= 200) {
275  return true;
276  }
277  if ($ret < 100) {
278  $authenticated = true;
279  continue;
280  }
281  }
282  return $authenticated;
283  }
284 
293  protected function getAuthServices(BackendUserAuthentication $backendUser, array $loginData, array $authInfo): \Generator
294  {
295  $serviceChain = [];
296  $subType = 'authUserBE';
297  while (‪$service = GeneralUtility::makeInstanceService('auth', $subType, $serviceChain)) {
298  $serviceChain[] = ‪$service->getServiceKey();
299  if (!is_object(‪$service)) {
300  continue;
301  }
302  ‪$service->initAuth($subType, $loginData, $authInfo, $backendUser);
303  yield ‪$service;
304  }
305  }
306 
307  protected function ‪getBackendUser(): ‪BackendUserAuthentication
308  {
309  return ‪$GLOBALS['BE_USER'];
310  }
311 
318  protected function ‪getSessionService(): SessionService
319  {
320  if ($this->sessionService === null) {
321  $this->sessionService = new SessionService();
322  $this->sessionService->startSession();
323  }
325  }
326 
330  protected function ‪applyRsaAuthModules()
331  {
333  || !class_exists(\‪TYPO3\CMS\Rsaauth\RsaEncryptionEncoder::class)
334  ) {
335  return;
336  }
337  $rsaEncryptionEncoder = GeneralUtility::makeInstance(\‪TYPO3\CMS\Rsaauth\RsaEncryptionEncoder::class);
338  $rsaEncryptionEncoder->enableRsaEncryption(true);
339  }
340 }
‪TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashFactory
Definition: PasswordHashFactory.php:27
‪TYPO3\CMS\Install\Controller\BackendModuleController\ALLOWED_ACTIONS
‪const ALLOWED_ACTIONS
Definition: BackendModuleController.php:50
‪TYPO3\CMS\Core\Authentication\AbstractUserAuthentication\processLoginData
‪array processLoginData($loginData, $passwordTransmissionStrategy='')
Definition: AbstractUserAuthentication.php:1279
‪TYPO3\CMS\Install\Controller\BackendModuleController\getBackendUserConfirmationUri
‪getBackendUserConfirmationUri(array $parameters)
Definition: BackendModuleController.php:188
‪TYPO3\CMS\Install\Controller\BackendModuleController\verifyBackendUserPassword
‪bool verifyBackendUserPassword(ServerRequestInterface $request)
Definition: BackendModuleController.php:241
‪TYPO3\CMS\Install\Controller\BackendModuleController\maintenanceAction
‪ResponseInterface maintenanceAction()
Definition: BackendModuleController.php:128
‪TYPO3
‪TYPO3\CMS\Core\Crypto\PasswordHashing\InvalidPasswordHashException
Definition: InvalidPasswordHashException.php:26
‪TYPO3\CMS\Install\Controller\BackendModuleController\$uriBuilder
‪UriBuilder $uriBuilder
Definition: BackendModuleController.php:58
‪TYPO3\CMS\Core\Authentication\AbstractUserAuthentication\getAuthInfoArray
‪array getAuthInfoArray()
Definition: AbstractUserAuthentication.php:1340
‪TYPO3\CMS\Core\Authentication\AbstractAuthenticationService
Definition: AbstractAuthenticationService.php:29
‪TYPO3\CMS\Install\Controller\BackendModuleController\upgradeAction
‪ResponseInterface upgradeAction()
Definition: BackendModuleController.php:150
‪TYPO3\CMS\Install\Controller\BackendModuleController\settingsAction
‪ResponseInterface settingsAction()
Definition: BackendModuleController.php:139
‪TYPO3\CMS\Install\Controller\BackendModuleController\getBackendUser
‪getBackendUser()
Definition: BackendModuleController.php:305
‪TYPO3\CMS\Install\Controller\BackendModuleController\backendUserConfirmationAction
‪ResponseInterface backendUserConfirmationAction(ServerRequestInterface $request)
Definition: BackendModuleController.php:72
‪TYPO3\CMS\Core\Http\Uri
Definition: Uri.php:29
‪TYPO3\CMS\Core\Core\Environment\getContext
‪static ApplicationContext getContext()
Definition: Environment.php:133
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility
Definition: ExtensionManagementUtility.php:43
‪TYPO3\CMS\Install\Controller\BackendModuleController\getSessionService
‪SessionService getSessionService()
Definition: BackendModuleController.php:316
‪TYPO3\CMS\Install\Controller\BackendModuleController\FLAG_CONFIRMATION_REQUEST
‪const FLAG_CONFIRMATION_REQUEST
Definition: BackendModuleController.php:48
‪TYPO3\CMS\Install\Controller\BackendModuleController\applyRsaAuthModules
‪applyRsaAuthModules()
Definition: BackendModuleController.php:328
‪TYPO3\CMS\Install\Controller
Definition: AbstractController.php:18
‪TYPO3\CMS\Backend\Routing\UriBuilder
Definition: UriBuilder.php:38
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:62
‪TYPO3\CMS\Install\Controller\BackendModuleController\verifyInstallToolPassword
‪bool verifyInstallToolPassword(ServerRequestInterface $request)
Definition: BackendModuleController.php:216
‪TYPO3\CMS\Core\Http\RedirectResponse
Definition: RedirectResponse.php:28
‪TYPO3\CMS\Install\Controller\BackendModuleController\getBackendUserConfirmationRedirect
‪ResponseInterface null getBackendUserConfirmationRedirect(string $targetController)
Definition: BackendModuleController.php:173
‪TYPO3\CMS\Install\Controller\BackendModuleController\__construct
‪__construct()
Definition: BackendModuleController.php:60
‪TYPO3\CMS\Install\Controller\BackendModuleController\$service
‪yield $service
Definition: BackendModuleController.php:301
‪TYPO3\CMS\Install\Controller\BackendModuleController\FLAG_INSTALL_TOOL_PASSWORD
‪const FLAG_INSTALL_TOOL_PASSWORD
Definition: BackendModuleController.php:49
‪TYPO3\CMS\Install\Controller\BackendModuleController\$sessionService
‪SessionService $sessionService
Definition: BackendModuleController.php:54
‪TYPO3\CMS\Fluid\View\StandaloneView
Definition: StandaloneView.php:34
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:40
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\extPath
‪static string extPath($key, $script='')
Definition: ExtensionManagementUtility.php:127
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Install\Controller\BackendModuleController\environmentAction
‪ResponseInterface environmentAction()
Definition: BackendModuleController.php:161
‪TYPO3\CMS\Core\Utility\ExtensionManagementUtility\isLoaded
‪static bool isLoaded($key)
Definition: ExtensionManagementUtility.php:114
‪TYPO3\CMS\Install\Controller\BackendModuleController\setAuthorizedAndRedirect
‪ResponseInterface setAuthorizedAndRedirect(string $controller)
Definition: BackendModuleController.php:203
‪TYPO3\CMS\Core\Http\HtmlResponse
Definition: HtmlResponse.php:26
‪TYPO3\CMS\Install\Controller\BackendModuleController
Definition: BackendModuleController.php:47