‪TYPO3CMS  11.5
Maintenance.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\Container\ContainerInterface;
21 use Psr\Http\Message\ResponseInterface;
22 use Psr\Http\Message\ServerRequestInterface;
23 use Psr\Http\Server\MiddlewareInterface;
24 use Psr\Http\Server\RequestHandlerInterface;
25 use TYPO3\CMS\Core\Configuration\ConfigurationManager;
46 use TYPO3\CMS\Install\Service\SessionService;
47 
53 class ‪Maintenance implements MiddlewareInterface
54 {
58  protected ‪$packageManager;
59 
63  protected ‪$configurationManager;
64 
68  protected ‪$passwordHashFactory;
69 
73  private ‪$container;
74 
78  protected ‪$controllers = [
79  'icon' => IconController::class,
80  'layout' => LayoutController::class,
81  'login' => LoginController::class,
82  'maintenance' => MaintenanceController::class,
83  'settings' => SettingsController::class,
84  'upgrade' => UpgradeController::class,
85  'environment' => EnvironmentController::class,
86  ];
87 
88  public function ‪__construct(
90  ConfigurationManager ‪$configurationManager,
92  ContainerInterface ‪$container
93  ) {
94  $this->packageManager = ‪$packageManager;
95  $this->configurationManager = ‪$configurationManager;
96  $this->passwordHashFactory = ‪$passwordHashFactory;
97  $this->container = ‪$container;
98  }
99 
107  public function ‪process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
108  {
109  if (!$this->‪canHandleRequest($request)) {
110  return $handler->handle($request);
111  }
112 
113  $controllerName = $request->getQueryParams()['install']['controller'] ?? 'layout';
114  $actionName = $request->getParsedBody()['install']['action'] ?? $request->getQueryParams()['install']['action'] ?? 'init';
115 
116  if ($actionName === 'showEnableInstallToolFile' && ‪EnableFileService::isInstallToolEnableFilePermanent()) {
117  $actionName = 'showLogin';
118  }
119 
120  $action = $actionName . 'Action';
121 
122  // not session related actions
123  if ($actionName === 'init') {
124  $controller = $this->container->get(LayoutController::class);
125  return $controller->initAction($request);
126  }
127  if ($actionName === 'checkEnableInstallToolFile') {
128  return new JsonResponse([
129  'success' => $this->‪checkEnableInstallToolFile(),
130  ]);
131  }
132  if ($actionName === 'showEnableInstallToolFile') {
133  $controller = $this->container->get(LoginController::class);
134  return $controller->showEnableInstallToolFileAction($request);
135  }
136  if ($actionName === 'showLogin') {
137  if (!$this->‪checkEnableInstallToolFile()) {
138  throw new \RuntimeException('Not authorized', 1505564888);
139  }
140  $controller = $this->container->get(LoginController::class);
141  return $controller->showLoginAction($request);
142  }
143 
144  // session related actions
145  $session = new SessionService();
146 
147  // the backend user has an active session but the admin / maintainer
148  // rights have been revoked or the user was disabled or deleted in the meantime
149  if ($session->isAuthorizedBackendUserSession() && !$session->hasActiveBackendUserRoleAndSession()) {
150  // log out the user and destroy the session
151  $session->resetSession();
152  $session->destroySession();
153  $formProtection = ‪FormProtectionFactory::get(
154  InstallToolFormProtection::class
155  );
156  $formProtection->clean();
157 
158  return new HtmlResponse('', 403);
159  }
160 
161  if ($actionName === 'preAccessCheck') {
162  $response = new JsonResponse([
163  'installToolLocked' => !$this->‪checkEnableInstallToolFile(),
164  'isAuthorized' => $session->isAuthorized(),
165  ]);
166  } elseif ($actionName === 'checkLogin') {
167  if (!$this->‪checkEnableInstallToolFile() && !$session->isAuthorizedBackendUserSession()) {
168  throw new \RuntimeException('Not authorized', 1505563556);
169  }
170  if ($session->isAuthorized()) {
171  $session->refreshSession();
172  $response = new JsonResponse([
173  'success' => true,
174  ]);
175  } else {
176  // Session expired, log out user, start new session
177  $session->resetSession();
178  $session->startSession();
179  $response = new JsonResponse([
180  'success' => false,
181  ]);
182  }
183  } elseif ($actionName === 'login') {
184  $session->initializeSession();
185  if (!$this->‪checkEnableInstallToolFile()) {
186  throw new \RuntimeException('Not authorized', 1505567462);
187  }
188  $this->‪checkSessionToken($request, $session);
189  $this->‪checkSessionLifetime($session);
190  $password = $request->getParsedBody()['install']['password'] ?? null;
191  $authService = new AuthenticationService($session);
192  if ($authService->loginWithPassword($password, $request)) {
193  $response = new JsonResponse([
194  'success' => true,
195  ]);
196  } else {
197  if ($password === null || empty($password)) {
198  $messageQueue = (new FlashMessageQueue('install'))->enqueue(
199  new FlashMessage('Please enter the install tool password', '', ‪FlashMessage::ERROR)
200  );
201  } else {
202  $hashInstance = $this->passwordHashFactory->getDefaultHashInstance('BE');
203  $hashedPassword = $hashInstance->getHashedPassword($password);
204  $messageQueue = (new FlashMessageQueue('install'))->enqueue(
205  new FlashMessage(
206  'Given password does not match the install tool login password. Calculated hash: ' . $hashedPassword,
207  '',
209  )
210  );
211  }
212  $response = new JsonResponse([
213  'success' => false,
214  'status' => $messageQueue,
215  ]);
216  }
217  } elseif ($actionName === 'logout') {
220  }
221  $formProtection = ‪FormProtectionFactory::get(
222  InstallToolFormProtection::class
223  );
224  $formProtection->clean();
225  $session->destroySession();
226  $response = new JsonResponse([
227  'success' => true,
228  ]);
229  } else {
230  $enforceReferrerResponse = $this->‪enforceReferrer($request);
231  if ($enforceReferrerResponse instanceof ResponseInterface) {
232  return $enforceReferrerResponse;
233  }
234  $session->initializeSession();
235  if (
236  !$this->‪checkSessionToken($request, $session)
237  || !$this->‪checkSessionLifetime($session)
238  || !$session->isAuthorized()
239  ) {
240  return new HtmlResponse('', 403);
241  }
242  $session->refreshSession();
243  if (!array_key_exists($controllerName, $this->controllers)) {
244  throw new \RuntimeException(
245  'Unknown controller ' . $controllerName,
246  1505215756
247  );
248  }
249  $this->packageManager->recreatePackageStatesFileIfMissing();
250  $className = $this->controllers[$controllerName];
252  $controller = $this->container->get($className);
253  if (!method_exists($controller, $action)) {
254  throw new \RuntimeException(
255  'Unknown action method ' . $action . ' in controller ' . $controllerName,
256  1505216027
257  );
258  }
259  $response = $controller->$action($request);
260  }
261 
262  return $response;
263  }
264 
273  protected function ‪canHandleRequest(ServerRequestInterface $request): bool
274  {
275  $basicIntegrity = $this->‪checkIfEssentialConfigurationExists()
276  && !empty(‪$GLOBALS['TYPO3_CONF_VARS']['BE']['installToolPassword'])
278  if (!$basicIntegrity) {
279  return false;
280  }
281  return true;
282  }
283 
289  protected function ‪checkEnableInstallToolFile()
290  {
292  }
293 
301  protected function ‪checkSessionToken(ServerRequestInterface $request, SessionService $session): bool
302  {
303  $postValues = $request->getParsedBody()['install'] ?? null;
304  // no post data is there, so no token check necessary
305  if (empty($postValues)) {
306  return true;
307  }
308  $tokenOk = false;
309  // A token must be given as soon as there is POST data
310  if (isset($postValues['token'])) {
311  $formProtection = ‪FormProtectionFactory::get(
312  InstallToolFormProtection::class
313  );
314  $action = (string)$postValues['action'];
315  if ($action === '') {
316  throw new \RuntimeException(
317  'No POST action given for token check',
318  1369326593
319  );
320  }
321  $tokenOk = $formProtection->validateToken($postValues['token'], 'installTool', $action);
322  }
323  if (!$tokenOk) {
324  $session->resetSession();
325  $session->startSession();
326  }
327  return $tokenOk;
328  }
329 
337  protected function ‪checkSessionLifetime(SessionService $session): bool
338  {
339  $isExpired = $session->isExpired();
340  if ($isExpired) {
341  // Session expired, log out user, start new session
342  $session->resetSession();
343  $session->startSession();
344  }
345  return !$isExpired;
346  }
347 
353  protected function ‪checkIfEssentialConfigurationExists(): bool
354  {
355  return file_exists($this->configurationManager->getLocalConfigurationFileLocation());
356  }
357 
366  protected function ‪enforceReferrer(ServerRequestInterface $request): ?ResponseInterface
367  {
368  if (!(new Features())->isFeatureEnabled('security.backend.enforceReferrer')) {
369  return null;
370  }
371  return (new ReferrerEnforcer($request))->handle([
372  'flags' => ['refresh-always'],
373  'subject' => 'Install Tool',
374  ]);
375  }
376 }
‪TYPO3\CMS\Core\Http\Security\ReferrerEnforcer
Definition: ReferrerEnforcer.php:31
‪TYPO3\CMS\Install\Middleware\Maintenance\checkSessionLifetime
‪bool checkSessionLifetime(SessionService $session)
Definition: Maintenance.php:332
‪TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashFactory
Definition: PasswordHashFactory.php:27
‪TYPO3\CMS\Core\FormProtection\FormProtectionFactory\get
‪static TYPO3 CMS Core FormProtection AbstractFormProtection get($classNameOrType='default',... $constructorArguments)
Definition: FormProtectionFactory.php:73
‪TYPO3\CMS\Install\Middleware\Maintenance\$configurationManager
‪ConfigurationManager $configurationManager
Definition: Maintenance.php:61
‪TYPO3\CMS\Core\Package\FailsafePackageManager
Definition: FailsafePackageManager.php:27
‪TYPO3\CMS\Install\Middleware\Maintenance
Definition: Maintenance.php:54
‪TYPO3\CMS\Install\Controller\UpgradeController
Definition: UpgradeController.php:82
‪TYPO3\CMS\Install\Controller\EnvironmentController
Definition: EnvironmentController.php:53
‪TYPO3\CMS\Install\Service\EnableFileService
Definition: EnableFileService.php:26
‪TYPO3\CMS\Install\Middleware\Maintenance\canHandleRequest
‪bool canHandleRequest(ServerRequestInterface $request)
Definition: Maintenance.php:268
‪TYPO3\CMS\Install\Controller\IconController
Definition: IconController.php:32
‪TYPO3\CMS\Core\FormProtection\InstallToolFormProtection
Definition: InstallToolFormProtection.php:61
‪TYPO3\CMS\Install\Service\EnableFileService\checkInstallToolEnableFile
‪static bool checkInstallToolEnableFile()
Definition: EnableFileService.php:112
‪TYPO3\CMS\Install\Service\EnableFileService\removeInstallToolEnableFile
‪static bool removeInstallToolEnableFile()
Definition: EnableFileService.php:77
‪TYPO3\CMS\Install\Service\EnableFileService\installToolEnableFileExists
‪static bool installToolEnableFileExists()
Definition: EnableFileService.php:102
‪TYPO3\CMS\Install\Middleware\Maintenance\$packageManager
‪FailsafePackageManager $packageManager
Definition: Maintenance.php:57
‪TYPO3\CMS\Install\Controller\LoginController
Definition: LoginController.php:32
‪TYPO3\CMS\Core\Configuration\Features
Definition: Features.php:56
‪TYPO3\CMS\Install\Middleware\Maintenance\$container
‪ContainerInterface $container
Definition: Maintenance.php:69
‪TYPO3\CMS\Install\Service\EnableFileService\isInstallToolEnableFilePermanent
‪static bool isInstallToolEnableFilePermanent()
Definition: EnableFileService.php:132
‪TYPO3\CMS\Install\Service\EnableFileService\isFirstInstallAllowed
‪static bool isFirstInstallAllowed()
Definition: EnableFileService.php:45
‪TYPO3\CMS\Install\Middleware\Maintenance\$controllers
‪array $controllers
Definition: Maintenance.php:73
‪TYPO3\CMS\Install\Controller\LayoutController
Definition: LayoutController.php:42
‪TYPO3\CMS\Install\Middleware\Maintenance\$passwordHashFactory
‪PasswordHashFactory $passwordHashFactory
Definition: Maintenance.php:65
‪TYPO3\CMS\Core\Messaging\FlashMessage
Definition: FlashMessage.php:26
‪TYPO3\CMS\Core\FormProtection\FormProtectionFactory
Definition: FormProtectionFactory.php:48
‪TYPO3\CMS\Core\Http\JsonResponse
Definition: JsonResponse.php:28
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Install\Middleware\Maintenance\process
‪ResponseInterface process(ServerRequestInterface $request, RequestHandlerInterface $handler)
Definition: Maintenance.php:102
‪TYPO3\CMS\Install\Middleware\Maintenance\checkEnableInstallToolFile
‪bool checkEnableInstallToolFile()
Definition: Maintenance.php:284
‪TYPO3\CMS\Install\Controller\MaintenanceController
Definition: MaintenanceController.php:50
‪TYPO3\CMS\Install\Controller\AbstractController
Definition: AbstractController.php:31
‪TYPO3\CMS\Install\Middleware\Maintenance\checkIfEssentialConfigurationExists
‪bool checkIfEssentialConfigurationExists()
Definition: Maintenance.php:348
‪TYPO3\CMS\Install\Authentication\AuthenticationService
Definition: AuthenticationService.php:39
‪TYPO3\CMS\Install\Controller\SettingsController
Definition: SettingsController.php:48
‪TYPO3\CMS\Install\Middleware\Maintenance\__construct
‪__construct(FailsafePackageManager $packageManager, ConfigurationManager $configurationManager, PasswordHashFactory $passwordHashFactory, ContainerInterface $container)
Definition: Maintenance.php:83
‪TYPO3\CMS\Install\Middleware
Definition: Installer.php:18
‪TYPO3\CMS\Core\Messaging\FlashMessageQueue
Definition: FlashMessageQueue.php:29
‪TYPO3\CMS\Core\Messaging\AbstractMessage\ERROR
‪const ERROR
Definition: AbstractMessage.php:31
‪TYPO3\CMS\Install\Middleware\Maintenance\checkSessionToken
‪bool checkSessionToken(ServerRequestInterface $request, SessionService $session)
Definition: Maintenance.php:296
‪TYPO3\CMS\Core\Http\HtmlResponse
Definition: HtmlResponse.php:26
‪TYPO3\CMS\Install\Middleware\Maintenance\enforceReferrer
‪ResponseInterface null enforceReferrer(ServerRequestInterface $request)
Definition: Maintenance.php:361