1<?php 2namespace TYPO3\CMS\Install\Report; 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 17use TYPO3\CMS\Core\Core\Environment; 18use TYPO3\CMS\Core\Crypto\PasswordHashing\InvalidPasswordHashException; 19use TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashFactory; 20use TYPO3\CMS\Core\Utility\GeneralUtility; 21use TYPO3\CMS\Install\Service\EnableFileService; 22use TYPO3\CMS\Install\SystemEnvironment\ServerResponse\ServerResponseCheck; 23use TYPO3\CMS\Reports\Status; 24 25/** 26 * Provides an status report of the security of the install tool 27 * @internal This class is only meant to be used within EXT:install and is not part of the TYPO3 Core API. 28 */ 29class SecurityStatusReport implements \TYPO3\CMS\Reports\StatusProviderInterface 30{ 31 /** 32 * Compiles a collection of system status checks as a status report. 33 * 34 * @return Status[] 35 */ 36 public function getStatus() 37 { 38 $this->executeAdminCommand(); 39 return [ 40 'installToolPassword' => $this->getInstallToolPasswordStatus(), 41 'installToolProtection' => $this->getInstallToolProtectionStatus(), 42 'serverResponseStatus' => GeneralUtility::makeInstance(ServerResponseCheck::class)->asStatus(), 43 ]; 44 } 45 46 /** 47 * Checks whether the Install Tool password is set to its default value. 48 * 49 * @return Status An object representing the security of the install tool password 50 */ 51 protected function getInstallToolPasswordStatus() 52 { 53 // @todo @deprecated: This should be removed in TYPO3 v10.0 when install tool allows proper hashes only 54 $value = $GLOBALS['LANG']->getLL('status_ok'); 55 $message = ''; 56 $severity = Status::OK; 57 $isDefaultPassword = false; 58 $installToolPassword = $GLOBALS['TYPO3_CONF_VARS']['BE']['installToolPassword']; 59 $hashInstance = null; 60 $hashFactory = GeneralUtility::makeInstance(PasswordHashFactory::class); 61 try { 62 $hashInstance = $hashFactory->get($installToolPassword, 'BE'); 63 } catch (InvalidPasswordHashException $e) { 64 // $hashInstance stays null 65 $value = $GLOBALS['LANG']->getLL('status_wrongValue'); 66 $message = $e->getMessage(); 67 $severity = Status::ERROR; 68 } 69 if ($installToolPassword !== '' && $hashInstance !== null) { 70 $isDefaultPassword = $hashInstance->checkPassword('joh316', $installToolPassword); 71 } elseif ($installToolPassword === 'bacb98acf97e0b6112b1d1b650b84971') { 72 // using MD5 of legacy default password 'joh316' 73 $isDefaultPassword = true; 74 } 75 if ($isDefaultPassword) { 76 $value = $GLOBALS['LANG']->getLL('status_insecure'); 77 $severity = Status::ERROR; 78 /** @var \TYPO3\CMS\Backend\Routing\UriBuilder $uriBuilder */ 79 $uriBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Routing\UriBuilder::class); 80 $changeInstallToolPasswordUrl = (string)$uriBuilder->buildUriFromRoute('tools_toolssettings'); 81 $message = sprintf( 82 $GLOBALS['LANG']->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:warning.installtool_default_password'), 83 '<a href="' . htmlspecialchars($changeInstallToolPasswordUrl) . '">', 84 '</a>' 85 ); 86 } 87 return GeneralUtility::makeInstance( 88 Status::class, 89 $GLOBALS['LANG']->sL('LLL:EXT:install/Resources/Private/Language/Report/locallang.xlf:status_installToolPassword'), 90 $value, 91 $message, 92 $severity 93 ); 94 } 95 96 /** 97 * Checks for the existence of the ENABLE_INSTALL_TOOL file. 98 * 99 * @return Status An object representing whether ENABLE_INSTALL_TOOL exists 100 */ 101 protected function getInstallToolProtectionStatus() 102 { 103 $enableInstallToolFile = Environment::getPublicPath() . '/' . EnableFileService::INSTALL_TOOL_ENABLE_FILE_PATH; 104 $value = $GLOBALS['LANG']->getLL('status_disabled'); 105 $message = ''; 106 $severity = Status::OK; 107 if (EnableFileService::installToolEnableFileExists()) { 108 if (EnableFileService::isInstallToolEnableFilePermanent()) { 109 $severity = Status::WARNING; 110 $disableInstallToolUrl = GeneralUtility::getIndpEnv('TYPO3_REQUEST_URL') . '&adminCmd=remove_ENABLE_INSTALL_TOOL'; 111 $value = $GLOBALS['LANG']->sL('LLL:EXT:install/Resources/Private/Language/Report/locallang.xlf:status_enabledPermanently'); 112 $message = sprintf( 113 $GLOBALS['LANG']->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:warning.install_enabled'), 114 '<code style="white-space: nowrap;">' . $enableInstallToolFile . '</code>' 115 ); 116 $message .= ' <a href="' . htmlspecialchars($disableInstallToolUrl) . '">' . 117 $GLOBALS['LANG']->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:warning.install_enabled_cmd') . '</a>'; 118 } else { 119 if (EnableFileService::installToolEnableFileLifetimeExpired()) { 120 EnableFileService::removeInstallToolEnableFile(); 121 } else { 122 $severity = Status::NOTICE; 123 $disableInstallToolUrl = GeneralUtility::getIndpEnv('TYPO3_REQUEST_URL') . '&adminCmd=remove_ENABLE_INSTALL_TOOL'; 124 $value = $GLOBALS['LANG']->sL('LLL:EXT:install/Resources/Private/Language/Report/locallang.xlf:status_enabledTemporarily'); 125 $message = sprintf( 126 $GLOBALS['LANG']->sL('LLL:EXT:install/Resources/Private/Language/Report/locallang.xlf:status_installEnabledTemporarily'), 127 '<code style="white-space: nowrap;">' . $enableInstallToolFile . '</code>', 128 floor((@filemtime($enableInstallToolFile) + EnableFileService::INSTALL_TOOL_ENABLE_FILE_LIFETIME - time()) / 60) 129 ); 130 $message .= ' <a href="' . htmlspecialchars($disableInstallToolUrl) . '">' . 131 $GLOBALS['LANG']->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:warning.install_enabled_cmd') . '</a>'; 132 } 133 } 134 } 135 return GeneralUtility::makeInstance( 136 Status::class, 137 $GLOBALS['LANG']->sL('LLL:EXT:install/Resources/Private/Language/Report/locallang.xlf:status_installTool'), 138 $value, 139 $message, 140 $severity 141 ); 142 } 143 144 /** 145 * Executes commands like removing the Install Tool enable file. 146 */ 147 protected function executeAdminCommand() 148 { 149 $command = GeneralUtility::_GET('adminCmd'); 150 switch ($command) { 151 case 'remove_ENABLE_INSTALL_TOOL': 152 EnableFileService::removeInstallToolEnableFile(); 153 break; 154 default: 155 // Do nothing 156 } 157 } 158} 159