TYPO3 CMS  TYPO3_7-6
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 $objectManager = null;
30 
34  protected $session = null;
35 
39  protected $authenticationActions = [];
40 
44  protected function isInstallToolAvailable()
45  {
47  $installToolEnableService = $this->objectManager->get(\TYPO3\CMS\Install\Service\EnableFileService::class);
48  if ($installToolEnableService->isFirstInstallAllowed()) {
49  return true;
50  }
51  return $installToolEnableService->checkInstallToolEnableFile();
52  }
53 
63  protected function outputInstallToolNotEnabledMessageIfNeeded()
64  {
65  if (!$this->isInstallToolAvailable()) {
66  if (!EnableFileService::isFirstInstallAllowed() && !\TYPO3\CMS\Core\Core\Bootstrap::getInstance()->checkIfEssentialConfigurationExists()) {
68  $action = $this->objectManager->get(\TYPO3\CMS\Install\Controller\Action\Common\FirstInstallAction::class);
69  $action->setAction('firstInstall');
70  } else {
72  $action = $this->objectManager->get(\TYPO3\CMS\Install\Controller\Action\Common\InstallToolDisabledAction::class);
73  $action->setAction('installToolDisabled');
74  }
75  $action->setController('common');
76  $this->output($action->handle());
77  }
78  }
79 
86  protected function outputInstallToolPasswordNotSetMessageIfNeeded()
87  {
88  if (!$this->isInitialInstallationInProgress()
89  && (empty($GLOBALS['TYPO3_CONF_VARS']['BE']['installToolPassword']))
90  ) {
92  $action = $this->objectManager->get(\TYPO3\CMS\Install\Controller\Action\Common\InstallToolPasswordNotSetAction::class);
93  $action->setController('common');
94  $action->setAction('installToolPasswordNotSet');
95  $this->output($action->handle());
96  }
97  }
98 
105  protected function checkSessionToken()
106  {
107  $postValues = $this->getPostValues();
108  $tokenOk = false;
109  if (!empty($postValues)) {
110  // A token must be given as soon as there is POST data
111  if (isset($postValues['token'])) {
114  \TYPO3\CMS\Core\FormProtection\InstallToolFormProtection::class
115  );
116  $action = $this->getAction();
117  if ($action === '') {
118  throw new Exception(
119  'No POST action given for token check',
120  1369326593
121  );
122  }
123  $tokenOk = $formProtection->validateToken($postValues['token'], 'installTool', $action);
124  }
125  } else {
126  $tokenOk = true;
127  }
128 
129  $this->handleSessionTokenCheck($tokenOk);
130  }
131 
140  protected function handleSessionTokenCheck($tokenOk)
141  {
142  if (!$tokenOk) {
143  $this->session->resetSession();
144  $this->session->startSession();
145 
146  if ($this->isInitialInstallationInProgress()) {
147  $this->redirect();
148  } else {
150  $message = $this->objectManager->get(\TYPO3\CMS\Install\Status\ErrorStatus::class);
151  $message->setTitle('Invalid form token');
152  $message->setMessage(
153  'The form protection token was invalid. You have been logged out, please log in and try again.'
154  );
155  $this->output($this->loginForm($message));
156  }
157  }
158  }
159 
165  protected function checkSessionLifetime()
166  {
167  if ($this->session->isExpired()) {
168  // Session expired, log out user, start new session
169  $this->session->resetSession();
170  $this->session->startSession();
171 
172  $this->handleSessionLifeTimeExpired();
173  }
174  }
175 
182  protected function handleSessionLifeTimeExpired()
183  {
184  if ($this->isInitialInstallationInProgress()) {
185  $this->redirect();
186  } else {
188  $message = $this->objectManager->get(\TYPO3\CMS\Install\Status\ErrorStatus::class);
189  $message->setTitle('Session expired');
190  $message->setMessage(
191  'Your Install Tool session has expired. You have been logged out, please log in and try again.'
192  );
193  $this->output($this->loginForm($message));
194  }
195  }
196 
203  protected function loginForm(\TYPO3\CMS\Install\Status\StatusInterface $message = null)
204  {
206  $action = $this->objectManager->get(\TYPO3\CMS\Install\Controller\Action\Common\LoginForm::class);
207  $action->setController('common');
208  $action->setAction('login');
209  $action->setToken($this->generateTokenForAction('login'));
210  $action->setPostValues($this->getPostValues());
211  if ($message) {
212  $action->setMessages([$message]);
213  }
214  $content = $action->handle();
215  return $content;
216  }
217 
223  protected function loginIfRequested()
224  {
225  $action = $this->getAction();
226  $postValues = $this->getPostValues();
227  if ($action === 'login') {
228  $password = '';
229  $validPassword = false;
230  if (isset($postValues['values']['password'])) {
231  $password = $postValues['values']['password'];
232  $installToolPassword = $GLOBALS['TYPO3_CONF_VARS']['BE']['installToolPassword'];
233  $saltFactory = \TYPO3\CMS\Saltedpasswords\Salt\SaltFactory::getSaltingInstance($installToolPassword);
234  if (is_object($saltFactory)) {
235  $validPassword = $saltFactory->checkPassword($password, $installToolPassword);
236  } elseif (md5($password) === $installToolPassword) {
237  // Update install tool password
239  $configurationManager = $this->objectManager->get(\TYPO3\CMS\Core\Configuration\ConfigurationManager::class);
240  $configurationManager->setLocalConfigurationValueByPath(
241  'BE/installToolPassword',
242  $saltFactory->getHashedPassword($password)
243  );
244  $validPassword = true;
245  }
246  }
247  if ($validPassword) {
248  $this->session->setAuthorized();
249  $this->sendLoginSuccessfulMail();
250  $this->redirect();
251  } else {
253  $hashedPassword = $saltFactory->getHashedPassword($password);
255  $message = $this->objectManager->get(\TYPO3\CMS\Install\Status\ErrorStatus::class);
256  $message->setTitle('Login failed');
257  $message->setMessage('Given password does not match the install tool login password. ' .
258  'Calculated hash: ' . $hashedPassword);
259  $this->sendLoginFailedMail();
260  $this->output($this->loginForm($message));
261  }
262  }
263  }
264 
271  protected function outputLoginFormIfNotAuthorized()
272  {
273  if (!$this->session->isAuthorized()
274  && !$this->isInitialInstallationInProgress()
275  ) {
276  $this->output($this->loginForm());
277  } else {
278  $this->session->refreshSession();
279  }
280  }
281 
287  protected function sendLoginSuccessfulMail()
288  {
289  $warningEmailAddress = $GLOBALS['TYPO3_CONF_VARS']['BE']['warning_email_addr'];
290  if ($warningEmailAddress) {
292  $mailMessage = $this->objectManager->get(\TYPO3\CMS\Core\Mail\MailMessage::class);
293  $mailMessage
294  ->addTo($warningEmailAddress)
295  ->setSubject('Install Tool Login at \'' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] . '\'')
296  ->addFrom($this->getSenderEmailAddress(), $this->getSenderEmailName())
297  ->setBody('There has been an Install Tool login at TYPO3 site'
298  . ' \'' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] . '\''
299  . ' (' . GeneralUtility::getIndpEnv('HTTP_HOST') . ')'
300  . ' from remote address \'' . GeneralUtility::getIndpEnv('REMOTE_ADDR') . '\''
301  . ' (' . GeneralUtility::getIndpEnv('REMOTE_HOST') . ')')
302  ->send();
303  }
304  }
305 
311  protected function sendLoginFailedMail()
312  {
313  $formValues = GeneralUtility::_GP('install');
314  $warningEmailAddress = $GLOBALS['TYPO3_CONF_VARS']['BE']['warning_email_addr'];
315  if ($warningEmailAddress) {
317  $mailMessage = $this->objectManager->get(\TYPO3\CMS\Core\Mail\MailMessage::class);
318  $mailMessage
319  ->addTo($warningEmailAddress)
320  ->setSubject('Install Tool Login ATTEMPT at \'' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] . '\'')
321  ->addFrom($this->getSenderEmailAddress(), $this->getSenderEmailName())
322  ->setBody('There has been an Install Tool login attempt at TYPO3 site'
323  . ' \'' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] . '\''
324  . ' (' . GeneralUtility::getIndpEnv('HTTP_HOST') . ')'
325  . ' The last 5 characters of the MD5 hash of the password tried was \'' . substr(md5($formValues['password']), -5) . '\''
326  . ' remote address was \'' . GeneralUtility::getIndpEnv('REMOTE_ADDR') . '\''
327  . ' (' . GeneralUtility::getIndpEnv('REMOTE_HOST') . ')')
328  ->send();
329  }
330  }
331 
339  protected function generateTokenForAction($action = null)
340  {
341  if (!$action) {
342  $action = $this->getAction();
343  }
344  if ($action === '') {
345  throw new Exception(
346  'Token must have a valid action name',
347  1369326592
348  );
349  }
352  \TYPO3\CMS\Core\FormProtection\InstallToolFormProtection::class
353  );
354  return $formProtection->generateToken('installTool', $action);
355  }
356 
363  protected function isInitialInstallationInProgress()
364  {
366  $configurationManager = $this->objectManager->get(\TYPO3\CMS\Core\Configuration\ConfigurationManager::class);
367 
368  $localConfigurationFileLocation = $configurationManager->getLocalConfigurationFileLocation();
369  $localConfigurationFileExists = @is_file($localConfigurationFileLocation);
370  $result = false;
371  if (!$localConfigurationFileExists
372  || !empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['isInitialInstallationInProgress'])
373  ) {
374  $result = true;
375  }
376  return $result;
377  }
378 
386  protected function initializeSession()
387  {
389  $this->session = $this->objectManager->get(\TYPO3\CMS\Install\Service\SessionService::class);
390  if (!$this->session->hasSession()) {
391  $this->session->startSession();
392  }
393  }
394 
401  protected function addSessionMessages(array $messages)
402  {
403  foreach ($messages as $message) {
404  $this->session->addMessage($message);
405  }
406  }
407 
413  protected function initializeObjectManager()
414  {
416  $objectManager = GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\ObjectManager::class);
417  $this->objectManager = $objectManager;
418  }
419 
427  protected function loadBaseExtensions()
428  {
429  if ($this->isDbalEnabled()) {
430  require(\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('dbal') . 'ext_localconf.php');
431  }
432 
433  // @todo: Find out if this could be left out
434  require(\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('extbase') . 'ext_localconf.php');
435 
436  $cacheConfigurations = $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations'];
437 
438  $cacheConfigurationsWithCachesSetToNullBackend = [];
439  foreach ($cacheConfigurations as $cacheName => $cacheConfiguration) {
440  // cache_core is handled in bootstrap already
441  if (is_array($cacheConfiguration) && $cacheName !== 'cache_core') {
442  $cacheConfiguration['backend'] = NullBackend::class;
443  $cacheConfiguration['options'] = [];
444  }
445  $cacheConfigurationsWithCachesSetToNullBackend[$cacheName] = $cacheConfiguration;
446  }
447 
449  $cacheManager = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Cache\CacheManager::class);
450  $cacheManager->setCacheConfigurations($cacheConfigurationsWithCachesSetToNullBackend);
451  }
452 
458  protected function isDbalEnabled()
459  {
460  if (\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('adodb')
461  && \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('dbal')
462  ) {
463  return true;
464  }
465  return false;
466  }
467 
474  protected function validateAuthenticationAction($action)
475  {
476  if (!in_array($action, $this->authenticationActions)) {
477  throw new Exception(
478  $action . ' is not a valid authentication action',
479  1369345838
480  );
481  }
482  }
483 
490  protected function getAction()
491  {
492  $formValues = GeneralUtility::_GP('install');
493  $action = '';
494  if (isset($formValues['action'])) {
495  $action = $formValues['action'];
496  }
497  if ($action !== ''
498  && $action !== 'login'
499  && $action !== 'loginForm'
500  && $action !== 'logout'
501  && !in_array($action, $this->authenticationActions)
502  ) {
503  throw new Exception(
504  'Invalid action ' . $action,
505  1369325619
506  );
507  }
508  return $action;
509  }
510 
517  protected function getPostValues()
518  {
519  $postValues = GeneralUtility::_POST('install');
520  if (!is_array($postValues)) {
521  $postValues = [];
522  }
523  return $postValues;
524  }
525 
534  protected function redirect($controller = '', $action = '')
535  {
536  $getPostValues = GeneralUtility::_GP('install');
537 
538  $parameters = [];
539 
540  // Current redirect count
541  if (isset($getPostValues['redirectCount'])) {
542  $redirectCount = (int)$getPostValues['redirectCount'] + 1;
543  } else {
544  $redirectCount = 0;
545  }
546  if ($redirectCount >= 10) {
547  // Abort a redirect loop by throwing an exception. Calling this method
548  // some times in a row is ok, but break a loop if this happens too often.
549  throw new Exception\RedirectLoopException(
550  'Redirect loop aborted. If this message is shown again after a reload,' .
551  ' your setup is so weird that the install tool is unable to handle it.' .
552  ' Please make sure to remove the "install[redirectCount]" parameter from your request or' .
553  ' restart the install tool from the backend navigation.',
554  1380581244
555  );
556  }
557  $parameters[] = 'install[redirectCount]=' . $redirectCount;
558 
559  // Add context parameter in case this script was called within backend scope
560  $context = 'install[context]=standalone';
561  if (isset($getPostValues['context']) && $getPostValues['context'] === 'backend') {
562  $context = 'install[context]=backend';
563  }
564  $parameters[] = $context;
565 
566  // Add controller parameter
567  $controllerParameter = 'install[controller]=step';
568  if ((isset($getPostValues['controller']) && $getPostValues['controller'] === 'tool')
569  || $controller === 'tool'
570  ) {
571  $controllerParameter = 'install[controller]=tool';
572  }
573  $parameters[] = $controllerParameter;
574 
575  // Add action if specified
576  if ((string)$action !== '') {
577  $parameters[] = 'install[action]=' . $action;
578  }
579 
580  $redirectLocation = 'Install.php?' . implode('&', $parameters);
581 
583  $redirectLocation,
584  \TYPO3\CMS\Core\Utility\HttpUtility::HTTP_STATUS_303
585  );
586  }
587 
594  protected function output($content = '')
595  {
596  header('Content-Type: text/html; charset=utf-8');
597  header('Cache-Control: no-cache, must-revalidate');
598  header('Pragma: no-cache');
599  echo $content;
600  die;
601  }
602 
610  protected function getSenderEmailAddress()
611  {
612  return !empty($GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromAddress'])
613  ? $GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromAddress']
614  : 'no-reply@example.com';
615  }
616 
624  protected function getSenderEmailName()
625  {
626  return !empty($GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromName'])
627  ? $GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromName']
628  : 'TYPO3 CMS install tool';
629  }
630 }
static getSaltingInstance($saltedHash='', $mode=TYPO3_MODE)
Definition: SaltFactory.php:82
static redirect($url, $httpStatus=self::HTTP_STATUS_303)
Definition: HttpUtility.php:76
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']