TYPO3 CMS  TYPO3_8-7
AbstractController.php
Go to the documentation of this file.
1 <?php
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
20 
25 {
29  protected $session = null;
30 
34  protected $authenticationActions = [];
35 
39  protected function isInstallToolAvailable()
40  {
42  $installToolEnableService = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Service\EnableFileService::class);
43  if ($installToolEnableService->isFirstInstallAllowed()) {
44  return true;
45  }
46  return $installToolEnableService->checkInstallToolEnableFile();
47  }
48 
56  protected function outputInstallToolNotEnabledMessageIfNeeded()
57  {
58  if (!$this->isInstallToolAvailable()) {
59  if (!EnableFileService::isFirstInstallAllowed() && !\TYPO3\CMS\Core\Core\Bootstrap::getInstance()->checkIfEssentialConfigurationExists()) {
61  $action = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Controller\Action\Common\FirstInstallAction::class);
62  $action->setAction('firstInstall');
63  } else {
65  $action = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Controller\Action\Common\InstallToolDisabledAction::class);
66  $action->setAction('installToolDisabled');
67  }
68  $action->setController('common');
69  $this->output($action->handle());
70  }
71  }
72 
79  protected function outputInstallToolPasswordNotSetMessageIfNeeded()
80  {
81  if (!$this->isInitialInstallationInProgress()
82  && (empty($GLOBALS['TYPO3_CONF_VARS']['BE']['installToolPassword']))
83  ) {
85  $action = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Controller\Action\Common\InstallToolPasswordNotSetAction::class);
86  $action->setController('common');
87  $action->setAction('installToolPasswordNotSet');
88  $this->output($action->handle());
89  }
90  }
91 
97  protected function checkSessionToken()
98  {
99  $postValues = $this->getPostValues();
100  $tokenOk = false;
101  if (!empty($postValues)) {
102  // A token must be given as soon as there is POST data
103  if (isset($postValues['token'])) {
106  \TYPO3\CMS\Core\FormProtection\InstallToolFormProtection::class
107  );
108  $action = $this->getAction();
109  if ($action === '') {
110  throw new Exception(
111  'No POST action given for token check',
112  1369326593
113  );
114  }
115  $tokenOk = $formProtection->validateToken($postValues['token'], 'installTool', $action);
116  }
117  } else {
118  $tokenOk = true;
119  }
120 
121  $this->handleSessionTokenCheck($tokenOk);
122  }
123 
131  protected function handleSessionTokenCheck($tokenOk)
132  {
133  if (!$tokenOk) {
134  $this->session->resetSession();
135  $this->session->startSession();
136 
137  if ($this->isInitialInstallationInProgress()) {
138  $this->redirect();
139  } else {
141  $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\ErrorStatus::class);
142  $message->setTitle('Invalid form token');
143  $message->setMessage(
144  'The form protection token was invalid. You have been logged out, please log in and try again.'
145  );
146  $this->output($this->loginForm($message));
147  }
148  }
149  }
150 
154  protected function checkSessionLifetime()
155  {
156  if ($this->session->isExpired()) {
157  // Session expired, log out user, start new session
158  $this->session->resetSession();
159  $this->session->startSession();
160 
161  $this->handleSessionLifeTimeExpired();
162  }
163  }
164 
169  protected function handleSessionLifeTimeExpired()
170  {
171  if ($this->isInitialInstallationInProgress()) {
172  $this->redirect();
173  } else {
175  $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\ErrorStatus::class);
176  $message->setTitle('Session expired');
177  $message->setMessage(
178  'Your Install Tool session has expired. You have been logged out, please log in and try again.'
179  );
180  $this->output($this->loginForm($message));
181  }
182  }
183 
190  protected function loginForm(\TYPO3\CMS\Install\Status\StatusInterface $message = null)
191  {
193  $action = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Controller\Action\Common\LoginForm::class);
194  $action->setController('common');
195  $action->setAction('login');
196  $action->setToken($this->generateTokenForAction('login'));
197  $action->setPostValues($this->getPostValues());
198  if ($message) {
199  $action->setMessages([$message]);
200  }
201  $content = $action->handle();
202  return $content;
203  }
204 
208  protected function loginIfRequested()
209  {
210  $action = $this->getAction();
211  $postValues = $this->getPostValues();
212  if ($action === 'login') {
213  $password = '';
214  $validPassword = false;
215  if (isset($postValues['values']['password']) && $postValues['values']['password'] !== '') {
216  $password = $postValues['values']['password'];
217  $installToolPassword = $GLOBALS['TYPO3_CONF_VARS']['BE']['installToolPassword'];
218  $saltFactory = \TYPO3\CMS\Saltedpasswords\Salt\SaltFactory::getSaltingInstance($installToolPassword);
219  if (is_object($saltFactory)) {
220  $validPassword = $saltFactory->checkPassword($password, $installToolPassword);
221  } elseif (md5($password) === $installToolPassword) {
222  // Update install tool password
225  $configurationManager = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Configuration\ConfigurationManager::class);
226  $configurationManager->setLocalConfigurationValueByPath(
227  'BE/installToolPassword',
228  $saltFactory->getHashedPassword($password)
229  );
230  $validPassword = true;
231  }
232  }
233  if ($validPassword) {
234  $this->session->setAuthorized();
235  $this->sendLoginSuccessfulMail();
236  $this->redirect();
237  } else {
238  if (!isset($postValues['values']['password']) || $postValues['values']['password'] === '') {
239  $messageText = 'Please enter the install tool password';
240  } else {
242  $hashedPassword = $saltFactory->getHashedPassword($password);
243  $messageText = 'Given password does not match the install tool login password. ' .
244  'Calculated hash: ' . $hashedPassword;
245  }
247  $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\ErrorStatus::class);
248  $message->setTitle('Login failed');
249  $message->setMessage($messageText);
250  $this->sendLoginFailedMail();
251  $this->output($this->loginForm($message));
252  }
253  }
254  }
255 
260  protected function outputLoginFormIfNotAuthorized()
261  {
262  if (!$this->session->isAuthorized()
263  && !$this->isInitialInstallationInProgress()
264  ) {
265  $this->output($this->loginForm());
266  } else {
267  $this->session->refreshSession();
268  }
269  }
270 
274  protected function sendLoginSuccessfulMail()
275  {
276  $warningEmailAddress = $GLOBALS['TYPO3_CONF_VARS']['BE']['warning_email_addr'];
277  if ($warningEmailAddress) {
279  $mailMessage = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Mail\MailMessage::class);
280  $mailMessage
281  ->addTo($warningEmailAddress)
282  ->setSubject('Install Tool Login at \'' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] . '\'')
283  ->addFrom($this->getSenderEmailAddress(), $this->getSenderEmailName())
284  ->setBody('There has been an Install Tool login at TYPO3 site'
285  . ' \'' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] . '\''
286  . ' (' . GeneralUtility::getIndpEnv('HTTP_HOST') . ')'
287  . ' from remote address \'' . GeneralUtility::getIndpEnv('REMOTE_ADDR') . '\''
288  . ' (' . GeneralUtility::getIndpEnv('REMOTE_HOST') . ')')
289  ->send();
290  }
291  }
292 
296  protected function sendLoginFailedMail()
297  {
298  $formValues = GeneralUtility::_GP('install');
299  $warningEmailAddress = $GLOBALS['TYPO3_CONF_VARS']['BE']['warning_email_addr'];
300  if ($warningEmailAddress) {
302  $mailMessage = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Mail\MailMessage::class);
303  $mailMessage
304  ->addTo($warningEmailAddress)
305  ->setSubject('Install Tool Login ATTEMPT at \'' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] . '\'')
306  ->addFrom($this->getSenderEmailAddress(), $this->getSenderEmailName())
307  ->setBody('There has been an Install Tool login attempt at TYPO3 site'
308  . ' \'' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] . '\''
309  . ' (' . GeneralUtility::getIndpEnv('HTTP_HOST') . ')'
310  . ' The last 5 characters of the MD5 hash of the password tried was \'' . substr(md5($formValues['password']), -5) . '\''
311  . ' remote address was \'' . GeneralUtility::getIndpEnv('REMOTE_ADDR') . '\''
312  . ' (' . GeneralUtility::getIndpEnv('REMOTE_HOST') . ')')
313  ->send();
314  }
315  }
316 
324  protected function generateTokenForAction($action = null)
325  {
326  if (!$action) {
327  $action = $this->getAction();
328  }
329  if ($action === '') {
330  throw new Exception(
331  'Token must have a valid action name',
332  1369326592
333  );
334  }
337  \TYPO3\CMS\Core\FormProtection\InstallToolFormProtection::class
338  );
339  return $formProtection->generateToken('installTool', $action);
340  }
341 
348  protected function isInitialInstallationInProgress()
349  {
351  $configurationManager = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Configuration\ConfigurationManager::class);
352 
353  $localConfigurationFileLocation = $configurationManager->getLocalConfigurationFileLocation();
354  $localConfigurationFileExists = @is_file($localConfigurationFileLocation);
355  $result = false;
356  if (!$localConfigurationFileExists
357  || !empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['isInitialInstallationInProgress'])
358  ) {
359  $result = true;
360  }
361  return $result;
362  }
363 
369  protected function initializeSession()
370  {
372  $this->session = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Service\SessionService::class);
373  if (!$this->session->hasSession()) {
374  $this->session->startSession();
375  }
376  }
377 
384  protected function addSessionMessages(array $messages)
385  {
386  foreach ($messages as $message) {
387  $this->session->addMessage($message);
388  }
389  }
390 
395  protected function loadBaseExtensions()
396  {
397  // @todo: Find out if this could be left out
398  require(\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('extbase') . 'ext_localconf.php');
399 
400  $cacheConfigurations = $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations'];
401 
402  $cacheConfigurationsWithCachesSetToNullBackend = [];
403  foreach ($cacheConfigurations as $cacheName => $cacheConfiguration) {
404  // cache_core is handled in bootstrap already
405  if (is_array($cacheConfiguration) && $cacheName !== 'cache_core') {
406  $cacheConfiguration['backend'] = NullBackend::class;
407  $cacheConfiguration['options'] = [];
408  }
409  $cacheConfigurationsWithCachesSetToNullBackend[$cacheName] = $cacheConfiguration;
410  }
412  $cacheManager = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Cache\CacheManager::class);
413  $cacheManager->setCacheConfigurations($cacheConfigurationsWithCachesSetToNullBackend);
414  }
415 
422  protected function validateAuthenticationAction($action)
423  {
424  if (!in_array($action, $this->authenticationActions)) {
425  throw new Exception(
426  $action . ' is not a valid authentication action',
427  1369345838
428  );
429  }
430  }
431 
438  protected function getAction()
439  {
440  $formValues = GeneralUtility::_GP('install');
441  $action = '';
442  if (isset($formValues['action'])) {
443  $action = $formValues['action'];
444  }
445  if ($action !== ''
446  && $action !== 'login'
447  && $action !== 'loginForm'
448  && $action !== 'logout'
449  && !in_array($action, $this->authenticationActions)
450  ) {
451  throw new Exception(
452  'Invalid action ' . $action,
453  1369325619
454  );
455  }
456  return $action;
457  }
458 
465  protected function getPostValues()
466  {
467  $postValues = GeneralUtility::_POST('install');
468  if (!is_array($postValues)) {
469  $postValues = [];
470  }
471  return $postValues;
472  }
473 
482  protected function redirect($controller = '', $action = '')
483  {
484  $getPostValues = GeneralUtility::_GP('install');
485 
486  $parameters = [];
487 
488  // Current redirect count
489  if (isset($getPostValues['redirectCount'])) {
490  $redirectCount = (int)$getPostValues['redirectCount'] + 1;
491  } else {
492  $redirectCount = 0;
493  }
494  if ($redirectCount >= 10) {
495  // Abort a redirect loop by throwing an exception. Calling this method
496  // some times in a row is ok, but break a loop if this happens too often.
497  throw new Exception\RedirectLoopException(
498  'Redirect loop aborted. If this message is shown again after a reload,' .
499  ' your setup is so weird that the install tool is unable to handle it.' .
500  ' Please make sure to remove the "install[redirectCount]" parameter from your request or' .
501  ' restart the install tool from the backend navigation.',
502  1380581244
503  );
504  }
505  $parameters[] = 'install[redirectCount]=' . $redirectCount;
506 
507  // Add context parameter in case this script was called within backend scope
508  $context = 'install[context]=standalone';
509  if (isset($getPostValues['context']) && $getPostValues['context'] === 'backend') {
510  $context = 'install[context]=backend';
511  }
512  $parameters[] = $context;
513 
514  // Add controller parameter
515  $controllerParameter = 'install[controller]=step';
516  if ((isset($getPostValues['controller']) && $getPostValues['controller'] === 'tool')
517  || $controller === 'tool'
518  ) {
519  $controllerParameter = 'install[controller]=tool';
520  }
521  $parameters[] = $controllerParameter;
522 
523  // Add action if specified
524  if ((string)$action !== '') {
525  $parameters[] = 'install[action]=' . $action;
526  }
527 
528  $redirectLocation = GeneralUtility::getIndpEnv('TYPO3_REQUEST_SCRIPT') . '?' . implode('&', $parameters);
529 
531  $redirectLocation,
532  \TYPO3\CMS\Core\Utility\HttpUtility::HTTP_STATUS_303
533  );
534  }
535 
542  protected function output($content = '')
543  {
544  header('Content-Type: text/html; charset=utf-8');
545  header('Cache-Control: no-cache, must-revalidate');
546  header('Pragma: no-cache');
547  echo $content;
548  die;
549  }
550 
558  protected function getSenderEmailAddress()
559  {
560  return !empty($GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromAddress'])
561  ? $GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromAddress']
562  : 'no-reply@example.com';
563  }
564 
572  protected function getSenderEmailName()
573  {
574  return !empty($GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromName'])
575  ? $GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromName']
576  : 'TYPO3 CMS install tool';
577  }
578 }
static getSaltingInstance($saltedHash='', $mode=TYPO3_MODE)
Definition: SaltFactory.php:83
static makeInstance($className,... $constructorArguments)
static get($classNameOrType='default',... $constructorArguments)
static redirect($url, $httpStatus=self::HTTP_STATUS_303)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']