[TASK] EXT:reports Minor typo in HTML
[Packages/TYPO3.CMS.git] / typo3 / sysext / reports / Classes / Report / Status / SecurityStatus.php
1 <?php
2 namespace TYPO3\CMS\Reports\Report\Status;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2009-2011 Ingo Renner <ingo@typo3.org>
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 *
19 * This script is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * This copyright notice MUST APPEAR in all copies of the script!
25 ***************************************************************/
26 /**
27 * Performs several checks about the system's health
28 *
29 * @author Ingo Renner <ingo@typo3.org>
30 */
31 class SecurityStatus implements \TYPO3\CMS\Reports\StatusProviderInterface {
32
33 /**
34 * Determines the Install Tool's status, mainly concerning its protection.
35 *
36 * @return array List of statuses
37 * @see typo3/sysext/reports/interfaces/tx_reports_StatusProvider::getStatus()
38 */
39 public function getStatus() {
40 $this->executeAdminCommand();
41 $statuses = array(
42 'adminUserAccount' => $this->getAdminAccountStatus(),
43 'encryptionKeyEmpty' => $this->getEncryptionKeyStatus(),
44 'fileDenyPattern' => $this->getFileDenyPatternStatus(),
45 'htaccessUpload' => $this->getHtaccessUploadStatus(),
46 'installToolEnabled' => $this->getInstallToolProtectionStatus(),
47 'installToolPassword' => $this->getInstallToolPasswordStatus(),
48 'saltedpasswords' => $this->getSaltedPasswordsStatus()
49 );
50 return $statuses;
51 }
52
53 /**
54 * Checks whether a an BE user account named admin with default password exists.
55 *
56 * @return \TYPO3\CMS\Reports\Status An tx_reports_reports_status_Status object representing whether a default admin account exists
57 */
58 protected function getAdminAccountStatus() {
59 $value = $GLOBALS['LANG']->getLL('status_ok');
60 $message = '';
61 $severity = \TYPO3\CMS\Reports\Status::OK;
62 $whereClause = 'username = ' . $GLOBALS['TYPO3_DB']->fullQuoteStr('admin', 'be_users') . \TYPO3\CMS\Backend\Utility\BackendUtility::deleteClause('be_users');
63 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('uid, username, password', 'be_users', $whereClause);
64 if ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
65 $secure = TRUE;
66 // Check against salted password
67 if (\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('saltedpasswords')) {
68 if (\TYPO3\CMS\Saltedpasswords\Utility\SaltedPasswordsUtility::isUsageEnabled('BE')) {
69 /** @var $saltingObject \TYPO3\CMS\Saltedpasswords\Salt\SaltInterface */
70 $saltingObject = \TYPO3\CMS\Saltedpasswords\Salt\SaltFactory::getSaltingInstance($row['password']);
71 if (is_object($saltingObject)) {
72 if ($saltingObject->checkPassword('password', $row['password'])) {
73 $secure = FALSE;
74 }
75 }
76 }
77 }
78 // Check against plain MD5
79 if ($row['password'] === '5f4dcc3b5aa765d61d8327deb882cf99') {
80 $secure = FALSE;
81 }
82 if (!$secure) {
83 $value = $GLOBALS['LANG']->getLL('status_insecure');
84 $severity = \TYPO3\CMS\Reports\Status::ERROR;
85 $editUserAccountUrl = 'alt_doc.php?returnUrl=mod.php?M=tools_txreportsM1&edit[be_users][' . $row['uid'] . ']=edit';
86 $message = sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:warning.backend_admin'), '<a href="' . $editUserAccountUrl . '">', '</a>');
87 }
88 }
89 $GLOBALS['TYPO3_DB']->sql_free_result($res);
90 return \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Reports\\Status', $GLOBALS['LANG']->getLL('status_adminUserAccount'), $value, $message, $severity);
91 }
92
93 /**
94 * Checks whether the encryption key is empty.
95 *
96 * @return \TYPO3\CMS\Reports\Status An tx_reports_reports_status_Status object representing whether the encryption key is empty or not
97 */
98 protected function getEncryptionKeyStatus() {
99 $value = $GLOBALS['LANG']->getLL('status_ok');
100 $message = '';
101 $severity = \TYPO3\CMS\Reports\Status::OK;
102 if (empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'])) {
103 $value = $GLOBALS['LANG']->getLL('status_insecure');
104 $severity = \TYPO3\CMS\Reports\Status::ERROR;
105 $url = 'install/index.php?redirect_url=index.php' . urlencode('?TYPO3_INSTALL[type]=config#set_encryptionKey');
106 $message = sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:warning.install_encryption'), '<a href="' . $url . '">', '</a>');
107 }
108 return \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Reports\\Status', $GLOBALS['LANG']->getLL('status_encryptionKey'), $value, $message, $severity);
109 }
110
111 /**
112 * Checks if fileDenyPattern was changed which is dangerous on Apache
113 *
114 * @return \TYPO3\CMS\Reports\Status An tx_reports_reports_status_Status object representing whether the file deny pattern has changed
115 */
116 protected function getFileDenyPatternStatus() {
117 $value = $GLOBALS['LANG']->getLL('status_ok');
118 $message = '';
119 $severity = \TYPO3\CMS\Reports\Status::OK;
120 $defaultParts = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode('|', FILE_DENY_PATTERN_DEFAULT, TRUE);
121 $givenParts = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode('|', $GLOBALS['TYPO3_CONF_VARS']['BE']['fileDenyPattern'], TRUE);
122 $result = array_intersect($defaultParts, $givenParts);
123 if ($defaultParts !== $result) {
124 $value = $GLOBALS['LANG']->getLL('status_insecure');
125 $severity = \TYPO3\CMS\Reports\Status::ERROR;
126 $url = 'install/index.php?redirect_url=index.php' . urlencode('?TYPO3_INSTALL[type]=config#set_encryptionKey');
127 $message = sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:warning.file_deny_pattern_partsNotPresent'), '<br /><pre>' . htmlspecialchars(FILE_DENY_PATTERN_DEFAULT) . '</pre><br />');
128 }
129 return \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Reports\\Status', $GLOBALS['LANG']->getLL('status_fileDenyPattern'), $value, $message, $severity);
130 }
131
132 /**
133 * Checks if fileDenyPattern allows to upload .htaccess files which is
134 * dangerous on Apache.
135 *
136 * @return \TYPO3\CMS\Reports\Status An tx_reports_reports_status_Status object representing whether it's possible to upload .htaccess files
137 */
138 protected function getHtaccessUploadStatus() {
139 $value = $GLOBALS['LANG']->getLL('status_ok');
140 $message = '';
141 $severity = \TYPO3\CMS\Reports\Status::OK;
142 if ($GLOBALS['TYPO3_CONF_VARS']['BE']['fileDenyPattern'] != FILE_DENY_PATTERN_DEFAULT && \TYPO3\CMS\Core\Utility\GeneralUtility::verifyFilenameAgainstDenyPattern('.htaccess')) {
143 $value = $GLOBALS['LANG']->getLL('status_insecure');
144 $severity = \TYPO3\CMS\Reports\Status::ERROR;
145 $message = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:warning.file_deny_htaccess');
146 }
147 return \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Reports\\Status', $GLOBALS['LANG']->getLL('status_htaccessUploadProtection'), $value, $message, $severity);
148 }
149
150 /**
151 * Checks whether memcached is configured, if that's the case we asume it's also used.
152 *
153 * @return boolean TRUE if memcached is used, FALSE otherwise.
154 */
155 protected function isMemcachedUsed() {
156 $memcachedUsed = FALSE;
157 $memcachedServers = $this->getConfiguredMemcachedServers();
158 if (count($memcachedServers)) {
159 $memcachedUsed = TRUE;
160 }
161 return $memcachedUsed;
162 }
163
164 /**
165 * Executes commands like removing the Install Tool enable file.
166 *
167 * @return void
168 */
169 protected function executeAdminCommand() {
170 $command = \TYPO3\CMS\Core\Utility\GeneralUtility::_GET('adminCmd');
171 switch ($command) {
172 case 'remove_ENABLE_INSTALL_TOOL':
173 unlink(PATH_site . 'typo3conf/ENABLE_INSTALL_TOOL');
174 break;
175 }
176 }
177
178 /**
179 * Checks whether the Install Tool password is set to its default value.
180 *
181 * @return \TYPO3\CMS\Reports\Status An tx_reports_reports_status_Status object representing the security of the install tool password
182 */
183 protected function getInstallToolPasswordStatus() {
184 $value = $GLOBALS['LANG']->getLL('status_ok');
185 $message = '';
186 $severity = \TYPO3\CMS\Reports\Status::OK;
187 if ($GLOBALS['TYPO3_CONF_VARS']['BE']['installToolPassword'] == md5('joh316')) {
188 $value = $GLOBALS['LANG']->getLL('status_insecure');
189 $severity = \TYPO3\CMS\Reports\Status::ERROR;
190 $changeInstallToolPasswordUrl = 'mod.php?M=tools_install';
191 $message = sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:warning.install_password'), '<a href="' . $changeInstallToolPasswordUrl . '">', '</a>');
192 }
193 return \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Reports\\Status', $GLOBALS['LANG']->getLL('status_installToolPassword'), $value, $message, $severity);
194 }
195
196 /**
197 * Checks whether the Install Tool password is set to its default value.
198 *
199 * @return \TYPO3\CMS\Reports\Status An tx_reports_reports_status_Status object representing the security of the saltedpassswords extension
200 */
201 protected function getSaltedPasswordsStatus() {
202 $value = $GLOBALS['LANG']->getLL('status_ok');
203 $message = '';
204 $severity = \TYPO3\CMS\Reports\Status::OK;
205 if (!\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLoaded('saltedpasswords')) {
206 $value = $GLOBALS['LANG']->getLL('status_insecure');
207 $severity = \TYPO3\CMS\Reports\Status::ERROR;
208 $message .= $GLOBALS['LANG']->getLL('status_saltedPasswords_notInstalled');
209 } else {
210 /** @var \TYPO3\CMS\Saltedpasswords\Utility\ExtensionManagerConfigurationUtility $configCheck */
211 $configCheck = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Saltedpasswords\\Utility\\ExtensionManagerConfigurationUtility');
212 $message = '<p>' . $GLOBALS['LANG']->getLL('status_saltedPasswords_infoText') . '</p>';
213 $messageDetail = '';
214 $flashMessage = $configCheck->checkConfigurationBackend(array(), new \TYPO3\CMS\Core\TypoScript\ConfigurationForm());
215 if (strpos($flashMessage, 'message-error') !== FALSE) {
216 $value = $GLOBALS['LANG']->getLL('status_insecure');
217 $severity = \TYPO3\CMS\Reports\Status::ERROR;
218 $messageDetail .= $flashMessage;
219 }
220 if (strpos($flashMessage, 'message-warning') !== FALSE) {
221 $severity = \TYPO3\CMS\Reports\Status::WARNING;
222 $messageDetail .= $flashMessage;
223 }
224 if (strpos($flashMessage, 'message-information') !== FALSE) {
225 $messageDetail .= $flashMessage;
226 }
227 $unsecureUserCount = \TYPO3\CMS\Saltedpasswords\Utility\SaltedPasswordsUtility::getNumberOfBackendUsersWithInsecurePassword();
228 if ($unsecureUserCount > 0) {
229 $value = $GLOBALS['LANG']->getLL('status_insecure');
230 $severity = \TYPO3\CMS\Reports\Status::ERROR;
231 $messageDetail .= '<div class="typo3-message message-warning">' . $GLOBALS['LANG']->getLL('status_saltedPasswords_notAllPasswordsHashed') . '</div>';
232 }
233 $message .= $messageDetail;
234 if (empty($messageDetail)) {
235 $message = '';
236 }
237 }
238 return \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Reports\\Status', $GLOBALS['LANG']->getLL('status_saltedPasswords'), $value, $message, $severity);
239 }
240
241 /**
242 * Checks for the existance of the ENABLE_INSTALL_TOOL file.
243 *
244 * @return \TYPO3\CMS\Reports\Status An tx_reports_reports_status_Status object representing whether ENABLE_INSTALL_TOOL exists
245 */
246 protected function getInstallToolProtectionStatus() {
247 $enableInstallToolFile = PATH_site . 'typo3conf/ENABLE_INSTALL_TOOL';
248 $value = $GLOBALS['LANG']->getLL('status_disabled');
249 $message = '';
250 $severity = \TYPO3\CMS\Reports\Status::OK;
251 $enableInstallToolFileExists = is_file($enableInstallToolFile);
252 if ($enableInstallToolFileExists) {
253 if (trim(file_get_contents($enableInstallToolFile)) === 'KEEP_FILE') {
254 $severity = \TYPO3\CMS\Reports\Status::WARNING;
255 $disableInstallToolUrl = \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_REQUEST_URL') . '&amp;adminCmd=remove_ENABLE_INSTALL_TOOL';
256 $value = $GLOBALS['LANG']->getLL('status_enabledPermanently');
257 $message = sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:warning.install_enabled'), '<span style="white-space: nowrap;">' . $enableInstallToolFile . '</span>');
258 $message .= ' <a href="' . $disableInstallToolUrl . '">' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:warning.install_enabled_cmd') . '</a>';
259 } else {
260 $enableInstallToolFileTtl = filemtime($enableInstallToolFile) + 3600 - time();
261 if ($enableInstallToolFileTtl <= 0) {
262 unlink($enableInstallToolFile);
263 } else {
264 $severity = \TYPO3\CMS\Reports\Status::NOTICE;
265 $disableInstallToolUrl = \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_REQUEST_URL') . '&amp;adminCmd=remove_ENABLE_INSTALL_TOOL';
266 $value = $GLOBALS['LANG']->getLL('status_enabledTemporarily');
267 $message = sprintf($GLOBALS['LANG']->getLL('status_installEnabledTemporarily'), '<span style="white-space: nowrap;">' . $enableInstallToolFile . '</span>', floor($enableInstallToolFileTtl / 60));
268 $message .= ' <a href="' . $disableInstallToolUrl . '">' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:warning.install_enabled_cmd') . '</a>';
269 }
270 }
271 }
272 return \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Reports\\Status', $GLOBALS['LANG']->getLL('status_installTool'), $value, $message, $severity);
273 }
274
275 }
276
277
278 ?>