2 /* vim: set expandtab sw=4 ts=4 sts=4: */
4 * Server config checks management
10 * Performs various compatibility, security and consistency checks on current config
12 * Outputs results to message list, must be called between PMA_messagesBegin()
13 * and PMA_messagesEnd()
17 class ServerConfigChecks
20 * @var ConfigFile configurations being checked
27 * @param ConfigFile $cfg Configuration
29 public function __construct(ConfigFile
$cfg)
35 * Perform config checks
39 public function performConfigChecks()
41 $blowfishSecret = $this->cfg
->get('blowfish_secret');
42 $blowfishSecretSet = false;
43 $cookieAuthUsed = false;
46 $sAllowArbitraryServerWarn, $sBlowfishSecretMsg,
47 $sBZipDumpWarn, $sDirectoryNotice, $sForceSSLNotice,
48 $sGZipDumpWarn, $sLoginCookieValidityWarn,
49 $sLoginCookieValidityWarn2, $sLoginCookieValidityWarn3,
50 $sSecurityInfoMsg, $sSrvAuthCfgMsg, $sZipDumpExportWarn,
52 ) = self
::defineMessages();
54 list($cookieAuthUsed, $blowfishSecret, $blowfishSecretSet)
55 = $this->performConfigChecksServers(
56 $cookieAuthUsed, $blowfishSecret, $sSrvAuthCfgMsg,
57 $sSecurityInfoMsg, $blowfishSecretSet
60 $this->performConfigChecksCookieAuthUsed(
61 $cookieAuthUsed, $blowfishSecretSet, $sBlowfishSecretMsg,
67 // should be enabled if possible
69 if (!$this->cfg
->getValue('ForceSSL')) {
73 PMA_lang(PMA_langName('ForceSSL')),
74 PMA_lang($sForceSSLNotice)
79 // $cfg['AllowArbitraryServer']
82 if ($this->cfg
->getValue('AllowArbitraryServer')) {
85 'AllowArbitraryServer',
86 PMA_lang(PMA_langName('AllowArbitraryServer')),
87 PMA_lang($sAllowArbitraryServerWarn)
91 $this->performConfigChecksLoginCookie(
92 $sLoginCookieValidityWarn, $sLoginCookieValidityWarn2,
93 $sLoginCookieValidityWarn3
98 // should not be world-accessible
100 if ($this->cfg
->getValue('SaveDir') != '') {
104 PMA_lang(PMA_langName('SaveDir')),
105 PMA_lang($sDirectoryNotice)
111 // should not be world-accessible
113 if ($this->cfg
->getValue('TempDir') != '') {
117 PMA_lang(PMA_langName('TempDir')),
118 PMA_lang($sDirectoryNotice)
122 $this->performConfigChecksZips(
123 $sGZipDumpWarn, $sBZipDumpWarn, $sZipDumpImportWarn,
129 * Check config of servers
131 * @param boolean $cookieAuthUsed Cookie auth is used
132 * @param string $blowfishSecret Blowfish secret
133 * @param string $sServerAuthCfgMsg Message for server auth config
134 * @param string $sSecurityInfoMsg Message for security information
135 * @param boolean $blowfishSecretSet Blowfish secret set
139 protected function performConfigChecksServers(
140 $cookieAuthUsed, $blowfishSecret, $sServerAuthCfgMsg,
141 $sSecurityInfoMsg, $blowfishSecretSet
143 $serverCnt = $this->cfg
->getServerCount();
144 for ($i = 1; $i <= $serverCnt; $i++
) {
146 = ($this->cfg
->getValue("Servers/$i/auth_type") == 'cookie');
147 $cookieAuthUsed |
= $cookieAuthServer;
148 $serverName = $this->performConfigChecksServersGetServerName(
149 $this->cfg
->getServerName($i), $i
151 $serverName = htmlspecialchars($serverName);
153 list($blowfishSecret, $blowfishSecretSet)
154 = $this->performConfigChecksServersSetBlowfishSecret(
155 $blowfishSecret, $cookieAuthServer, $blowfishSecretSet
159 // $cfg['Servers'][$i]['ssl']
160 // should be enabled if possible
162 if (!$this->cfg
->getValue("Servers/$i/ssl")) {
163 $title = PMA_lang(PMA_langName('Servers/1/ssl')) . " ($serverName)";
168 __('You should use SSL connections if your database server supports it.')
173 // $cfg['Servers'][$i]['auth_type']
174 // warn about full user credentials if 'auth_type' is 'config'
176 if ($this->cfg
->getValue("Servers/$i/auth_type") == 'config'
177 && $this->cfg
->getValue("Servers/$i/user") != ''
178 && $this->cfg
->getValue("Servers/$i/password") != ''
180 $title = PMA_lang(PMA_langName('Servers/1/auth_type'))
184 "Servers/$i/auth_type",
186 PMA_lang($sServerAuthCfgMsg, $i) . ' '
187 . PMA_lang($sSecurityInfoMsg, $i)
192 // $cfg['Servers'][$i]['AllowRoot']
193 // $cfg['Servers'][$i]['AllowNoPassword']
194 // serious security flaw
196 if ($this->cfg
->getValue("Servers/$i/AllowRoot")
197 && $this->cfg
->getValue("Servers/$i/AllowNoPassword")
199 $title = PMA_lang(PMA_langName('Servers/1/AllowNoPassword'))
203 "Servers/$i/AllowNoPassword",
205 __('You allow for connecting to the server without a password.') . ' '
206 . PMA_lang($sSecurityInfoMsg, $i)
210 return array($cookieAuthUsed, $blowfishSecret, $blowfishSecretSet);
214 * Set blowfish secret
216 * @param string $blowfishSecret Blowfish secret
217 * @param boolean $cookieAuthServer Cookie auth is used
218 * @param boolean $blowfishSecretSet Blowfish secret set
222 protected function performConfigChecksServersSetBlowfishSecret(
223 $blowfishSecret, $cookieAuthServer, $blowfishSecretSet
225 if ($cookieAuthServer && $blowfishSecret === null) {
226 $blowfishSecret = uniqid('', true);
227 $blowfishSecretSet = true;
228 $this->cfg
->set('blowfish_secret', $blowfishSecret);
229 return array($blowfishSecret, $blowfishSecretSet);
231 return array($blowfishSecret, $blowfishSecretSet);
237 * @param string $serverName Server name
238 * @param int $serverId Server id
240 * @return string Server name
242 protected function performConfigChecksServersGetServerName(
243 $serverName, $serverId
245 if ($serverName == 'localhost') {
246 $serverName .= " [$serverId]";
253 * Perform config checks for zip part.
255 * @param string $sGZipDumpWarning Gzip dump warning
256 * @param string $sBZipDumpWarning Bzip dump warning
257 * @param string $sZipDumpImportWarn Zip dump import warning
258 * @param string $sZipDumpExportWarn Zip dump export warning
262 protected function performConfigChecksZips(
263 $sGZipDumpWarning, $sBZipDumpWarning, $sZipDumpImportWarn,
266 $this->performConfigChecksServerGZipdump($sGZipDumpWarning);
267 $this->performConfigChecksServerBZipdump($sBZipDumpWarning);
268 $this->performConfigChecksServersZipdump(
269 $sZipDumpImportWarn, $sZipDumpExportWarn
274 * Perform config checks for zip part.
276 * @param string $sZipDumpImportWarn Zip dump import warning
277 * @param string $sZipDumpExportWarn Zip dump export warning
281 protected function performConfigChecksServersZipdump(
282 $sZipDumpImportWarn, $sZipDumpExportWarn
286 // requires zip_open in import
288 if ($this->cfg
->getValue('ZipDump') && !@function_exists
('zip_open')) {
292 PMA_lang(PMA_langName('ZipDump')),
293 PMA_lang($sZipDumpImportWarn, 'zip_open')
299 // requires gzcompress in export
301 if ($this->cfg
->getValue('ZipDump') && !@function_exists
('gzcompress')) {
305 PMA_lang(PMA_langName('ZipDump')),
306 PMA_lang($sZipDumpExportWarn, 'gzcompress')
312 * Check config of servers
314 * @param boolean $cookieAuthUsed Cookie auth is used
315 * @param boolean $blowfishSecretSet Blowfish secret set
316 * @param string $sBlowfishSecretMsg Blowfish secret message
317 * @param string $blowfishSecret Blowfish secret
321 protected function performConfigChecksCookieAuthUsed(
322 $cookieAuthUsed, $blowfishSecretSet, $sBlowfishSecretMsg,
326 // $cfg['blowfish_secret']
327 // it's required for 'cookie' authentication
329 if ($cookieAuthUsed) {
330 if ($blowfishSecretSet) {
331 // 'cookie' auth used, blowfish_secret was generated
334 'blowfish_secret_created',
335 PMA_lang(PMA_langName('blowfish_secret')),
336 PMA_lang($sBlowfishSecretMsg)
339 $blowfishWarnings = array();
341 if (strlen($blowfishSecret) < 8) {
343 $blowfishWarnings[] = __('Key is too short, it should have at least 8 characters.');
345 // check used characters
346 $hasDigits = (bool)preg_match('/\d/', $blowfishSecret);
347 $hasChars = (bool)preg_match('/\S/', $blowfishSecret);
348 $hasNonword = (bool)preg_match('/\W/', $blowfishSecret);
349 if (!$hasDigits ||
!$hasChars ||
!$hasNonword) {
350 $blowfishWarnings[] = PMA_lang(__('Key should contain letters, numbers [em]and[/em] special characters.'));
352 if (!empty($blowfishWarnings)) {
355 'blowfish_warnings' . count($blowfishWarnings),
356 PMA_lang(PMA_langName('blowfish_secret')),
357 implode('<br />', $blowfishWarnings)
365 * Define all messages
369 protected static function defineMessages()
371 $sAllowArbitraryServerWarn = __('This %soption%s should be disabled as it allows attackers to bruteforce login to any MySQL server. If you feel this is necessary, use %strusted proxies list%s. However, IP-based protection may not be reliable if your IP belongs to an ISP where thousands of users, including you, are connected to.');
372 $sAllowArbitraryServerWarn = sprintf(
373 $sAllowArbitraryServerWarn,
374 '[a@?page=form&formset=Features#tab_Security]',
375 '[/a]', '[a@?page=form&formset=Features#tab_Security]',
378 $sBlowfishSecretMsg = __('You didn\'t have blowfish secret set and have enabled [kbd]cookie[/kbd] authentication, so a key was automatically generated for you. It is used to encrypt cookies; you don\'t need to remember it.');
379 $sBZipDumpWarning = __('%sBzip2 compression and decompression%s requires functions (%s) which are unavailable on this system.');
380 $sBZipDumpWarning = sprintf(
382 '[a@?page=form&formset=Features#tab_Import_export]',
385 $sDirectoryNotice = __('This value should be double checked to ensure that this directory is neither world accessible nor readable or writable by other users on your server.');
386 $sForceSSLNotice = __('This %soption%s should be enabled if your web server supports it.');
387 $sForceSSLNotice = sprintf(
389 '[a@?page=form&formset=Features#tab_Security]',
392 $sGZipDumpWarning = __('%sGZip compression and decompression%s requires functions (%s) which are unavailable on this system.');
393 $sGZipDumpWarning = sprintf(
395 '[a@?page=form&formset=Features#tab_Import_export]',
399 $sLoginCookieValidityWarn = __('%sLogin cookie validity%s greater than %ssession.gc_maxlifetime%s may cause random session invalidation (currently session.gc_maxlifetime is %d).');
400 $sLoginCookieValidityWarn = sprintf(
401 $sLoginCookieValidityWarn,
402 '[a@?page=form&formset=Features#tab_Security]',
404 '[a@' . PMA_getPHPDocLink(
405 'session.configuration.php#ini.session.gc-maxlifetime'
408 ini_get('session.gc_maxlifetime')
410 $sLoginCookieValidityWarn2 = __('%sLogin cookie validity%s should be set to 1800 seconds (30 minutes) at most. Values larger than 1800 may pose a security risk such as impersonation.');
411 $sLoginCookieValidityWarn2 = sprintf(
412 $sLoginCookieValidityWarn2,
413 '[a@?page=form&formset=Features#tab_Security]',
416 $sLoginCookieValidityWarn3 = __('If using [kbd]cookie[/kbd] authentication and %sLogin cookie store%s is not 0, %sLogin cookie validity%s must be set to a value less or equal to it.');
417 $sLoginCookieValidityWarn3 = sprintf(
418 $sLoginCookieValidityWarn3,
419 '[a@?page=form&formset=Features#tab_Security]',
420 '[/a]', '[a@?page=form&formset=Features#tab_Security]',
423 $sSecurityInfoMsg = __('If you feel this is necessary, use additional protection settings - %shost authentication%s settings and %strusted proxies list%s. However, IP-based protection may not be reliable if your IP belongs to an ISP where thousands of users, including you, are connected to.');
424 $sSecurityInfoMsg = sprintf(
426 '[a@?page=servers&mode=edit&id=%1$d#tab_Server_config]',
428 '[a@?page=form&formset=Features#tab_Security]',
431 $sServerAuthConfigMsg = __('You set the [kbd]config[/kbd] authentication type and included username and password for auto-login, which is not a desirable option for live hosts. Anyone who knows or guesses your phpMyAdmin URL can directly access your phpMyAdmin panel. Set %sauthentication type%s to [kbd]cookie[/kbd] or [kbd]http[/kbd].');
432 $sServerAuthConfigMsg = sprintf(
433 $sServerAuthConfigMsg,
434 '[a@?page=servers&mode=edit&id=%1$d#tab_Server]',
437 $sZipDumpExportWarn = __('%sZip compression%s requires functions (%s) which are unavailable on this system.');
438 $sZipDumpExportWarn = sprintf(
440 '[a@?page=form&formset=Features#tab_Import_export]',
444 $sZipDumpImportWarn = __('%sZip decompression%s requires functions (%s) which are unavailable on this system.');
445 $sZipDumpImportWarn = sprintf(
447 '[a@?page=form&formset=Features#tab_Import_export]',
452 $sAllowArbitraryServerWarn, $sBlowfishSecretMsg, $sBZipDumpWarning,
453 $sDirectoryNotice, $sForceSSLNotice, $sGZipDumpWarning,
454 $sLoginCookieValidityWarn, $sLoginCookieValidityWarn2,
455 $sLoginCookieValidityWarn3, $sSecurityInfoMsg, $sServerAuthConfigMsg,
456 $sZipDumpExportWarn, $sZipDumpImportWarn
461 * Check configuration for login cookie
463 * @param string $sLoginCookieValidityWarn Warning 1 for login cookie validity
464 * @param string $sLoginCookieValidityWarn2 Warning 2 for login cookie validity
465 * @param string $sLoginCookieValidityWarn3 Warning 3 for login cookie validity
469 protected function performConfigChecksLoginCookie(
470 $sLoginCookieValidityWarn, $sLoginCookieValidityWarn2,
471 $sLoginCookieValidityWarn3
474 // $cfg['LoginCookieValidity']
475 // value greater than session.gc_maxlifetime will cause
476 // random session invalidation after that time
477 $loginCookieValidity = $this->cfg
->getValue('LoginCookieValidity');
478 if ($loginCookieValidity > ini_get('session.gc_maxlifetime')
482 'LoginCookieValidity',
483 PMA_lang(PMA_langName('LoginCookieValidity')),
484 PMA_lang($sLoginCookieValidityWarn)
489 // $cfg['LoginCookieValidity']
490 // should be at most 1800 (30 min)
492 if ($loginCookieValidity > 1800) {
495 'LoginCookieValidity',
496 PMA_lang(PMA_langName('LoginCookieValidity')),
497 PMA_lang($sLoginCookieValidityWarn2)
502 // $cfg['LoginCookieValidity']
503 // $cfg['LoginCookieStore']
504 // LoginCookieValidity must be less or equal to LoginCookieStore
506 if (($this->cfg
->getValue('LoginCookieStore') != 0)
507 && ($loginCookieValidity > $this->cfg
->getValue('LoginCookieStore'))
511 'LoginCookieValidity',
512 PMA_lang(PMA_langName('LoginCookieValidity')),
513 PMA_lang($sLoginCookieValidityWarn3)
519 * Check GZipDump configuration
521 * @param string $sBZipDumpWarn Warning for BZipDumpWarning
525 protected function performConfigChecksServerBZipdump($sBZipDumpWarn)
529 // requires bzip2 functions
531 if ($this->cfg
->getValue('BZipDump')
532 && (!@function_exists
('bzopen') ||
!@function_exists
('bzcompress'))
534 $functions = @function_exists
('bzopen')
537 $functions .= @function_exists
('bzcompress')
539 : ($functions ?
', ' : '') . 'bzcompress';
543 PMA_lang(PMA_langName('BZipDump')),
544 PMA_lang($sBZipDumpWarn, $functions)
550 * Check GZipDump configuration
552 * @param string $sGZipDumpWarn Warning for GZipDumpWarning
556 protected function performConfigChecksServerGZipdump($sGZipDumpWarn)
560 // requires zlib functions
562 if ($this->cfg
->getValue('GZipDump')
563 && (@!function_exists('gzopen') ||
@!function_exists('gzencode'))
568 PMA_lang(PMA_langName('GZipDump')),
569 PMA_lang($sGZipDumpWarn, 'gzencode')