/** * Test for PMA_langName * * @return void * @test */ public function testLangName() { $canonicalPath = "Servers/1/2test"; $this->assertEquals( "Servers_2test_name", PMA_langName($canonicalPath) ); $this->assertEquals( "returnsDefault", PMA_langName($canonicalPath, "name", "returnsDefault") ); $GLOBALS["strConfigServers_2test_name"] = "<a>msg</a>"; $this->assertEquals( "<a>msg</a>", PMA_langName($canonicalPath) ); $GLOBALS["strConfigServers_2test_desc"] = "<a>msg</a>"; $this->assertEquals( "<a>msg</a>", PMA_langName($canonicalPath, "desc") ); }
/** * Displays for for language selection * * @access public */ function PMA_select_language($use_fieldset = false, $show_doc = true) { if (count($GLOBALS['available_languages']) == 1) { // no use in switching languages, there is only one available return; } global $cfg, $lang; ?> <form method="post" action="index.php" target="_parent"> <?php $_form_params = array('db' => $GLOBALS['db'], 'table' => $GLOBALS['table']); echo PMA_generate_common_hidden_inputs($_form_params); // For non-English, display "Language" with emphasis because it's // not a proper word in the current language; we show it to help // people recognize the dialog $language_title = __('Language') . (__('Language') != 'Language' ? ' - <em>Language</em>' : ''); if ($show_doc) { $language_title .= PMA_CommonFunctions::getInstance()->showDocu('faq7_2'); } if ($use_fieldset) { echo '<fieldset><legend lang="en" dir="ltr">' . $language_title . '</legend>'; } else { echo '<bdo lang="en" dir="ltr"><label for="sel-lang">' . $language_title . ':</label></bdo>'; } ?> <select name="lang" class="autosubmit" lang="en" dir="ltr" id="sel-lang"> <?php uasort($GLOBALS['available_languages'], 'PMA_language_cmp'); foreach ($GLOBALS['available_languages'] as $id => $tmplang) { $lang_name = PMA_langName($tmplang); //Is current one active? if ($lang == $id) { $selected = ' selected="selected"'; } else { $selected = ''; } echo ' '; echo '<option value="' . $id . '"' . $selected . '>' . $lang_name . '</option>' . "\n"; } ?> </select> <?php if ($use_fieldset) { echo '</fieldset>'; } ?> </form> <?php }
/** * Returns HTML code for the language selector * * @param boolean $use_fieldset whether to use fieldset for selection * @param boolean $show_doc whether to show documentation links * * @return string * * @access public */ function PMA_getLanguageSelectorHtml($use_fieldset = false, $show_doc = true) { global $lang; $retval = ''; // Display language selection only if there // is more than one language to choose from if (count($GLOBALS['available_languages']) > 1) { $retval .= '<form method="get" action="index.php" class="disableAjax">'; $_form_params = array('db' => $GLOBALS['db'], 'table' => $GLOBALS['table']); $retval .= PMA_generate_common_hidden_inputs($_form_params); // For non-English, display "Language" with emphasis because it's // not a proper word in the current language; we show it to help // people recognize the dialog $language_title = __('Language') . (__('Language') != 'Language' ? ' - <em>Language</em>' : ''); if ($show_doc) { $language_title .= PMA_Util::showDocu('faq', 'faq7-2'); } if ($use_fieldset) { $retval .= '<fieldset><legend lang="en" dir="ltr">' . $language_title . '</legend>'; } else { $retval .= '<bdo lang="en" dir="ltr"><label for="sel-lang">' . $language_title . ': </label></bdo>'; } $retval .= '<select name="lang" class="autosubmit" lang="en"' . ' dir="ltr" id="sel-lang">'; uasort($GLOBALS['available_languages'], 'PMA_languageCmp'); foreach ($GLOBALS['available_languages'] as $id => $tmplang) { $lang_name = PMA_langName($tmplang); //Is current one active? if ($lang == $id) { $selected = ' selected="selected"'; } else { $selected = ''; } $retval .= '<option value="' . $id . '"' . $selected . '>'; $retval .= $lang_name; $retval .= '</option>'; } $retval .= '</select>'; if ($use_fieldset) { $retval .= '</fieldset>'; } $retval .= '</form>'; } return $retval; }
/** * Validates and saves form data to session * * @param array|string $forms array of form names * @param bool $allow_partial_save allows for partial form saving on * failed validation * * @return boolean true on success (no errors and all saved) */ public function save($forms, $allow_partial_save = true) { $result = true; $forms = (array) $forms; $values = array(); $to_save = array(); $is_setup_script = defined('PMA_SETUP'); if ($is_setup_script) { $this->_loadUserprefsInfo(); } $this->_errors = array(); foreach ($forms as $form_name) { /* @var $form Form */ if (isset($this->_forms[$form_name])) { $form = $this->_forms[$form_name]; } else { continue; } // get current server id $change_index = $form->index === 0 ? $this->_configFile->getServerCount() + 1 : false; // grab POST values foreach ($form->fields as $field => $system_path) { $work_path = array_search($system_path, $this->_systemPaths); $key = $this->_translatedPaths[$work_path]; $type = $form->getOptionType($field); // skip groups if ($type == 'group') { continue; } // ensure the value is set if (!isset($_POST[$key])) { // checkboxes aren't set by browsers if they're off if ($type == 'boolean') { $_POST[$key] = false; } else { $this->_errors[$form->name][] = sprintf(__('Missing data for %s'), '<i>' . PMA_langName($system_path) . '</i>'); $result = false; continue; } } // user preferences allow/disallow if ($is_setup_script && isset($this->_userprefsKeys[$system_path])) { if (isset($this->_userprefsDisallow[$system_path]) && isset($_POST[$key . '-userprefs-allow'])) { unset($this->_userprefsDisallow[$system_path]); } else { if (!isset($_POST[$key . '-userprefs-allow'])) { $this->_userprefsDisallow[$system_path] = true; } } } // cast variables to correct type switch ($type) { case 'double': settype($_POST[$key], 'float'); break; case 'boolean': case 'integer': if ($_POST[$key] !== '') { settype($_POST[$key], $type); } break; case 'select': $successfully_validated = $this->_validateSelect($_POST[$key], $form->getOptionValueList($system_path)); if (!$successfully_validated) { $this->_errors[$work_path][] = __('Incorrect value!'); $result = false; continue; } break; case 'string': case 'short_string': $_POST[$key] = trim($_POST[$key]); break; case 'array': // eliminate empty values and ensure we have an array $post_values = is_array($_POST[$key]) ? $_POST[$key] : explode("\n", $_POST[$key]); $_POST[$key] = array(); $this->_fillPostArrayParameters($post_values, $key); break; } // now we have value with proper type $values[$system_path] = $_POST[$key]; if ($change_index !== false) { $work_path = str_replace("Servers/{$form->index}/", "Servers/{$change_index}/", $work_path); } $to_save[$work_path] = $system_path; } } // save forms if (!$allow_partial_save && !empty($this->_errors)) { // don't look for non-critical errors $this->_validate(); return $result; } foreach ($to_save as $work_path => $path) { // TrustedProxies requires changes before saving if ($path == 'TrustedProxies') { $proxies = array(); $i = 0; foreach ($values[$path] as $value) { $matches = array(); $match = preg_match("/^(.+):(?:[ ]?)(\\w+)\$/", $value, $matches); if ($match) { // correct 'IP: HTTP header' pair $ip = trim($matches[1]); $proxies[$ip] = trim($matches[2]); } else { // save also incorrect values $proxies["-{$i}"] = $value; $i++; } } $values[$path] = $proxies; } $this->_configFile->set($work_path, $values[$path], $path); } if ($is_setup_script) { $this->_configFile->set('UserprefsDisallow', array_keys($this->_userprefsDisallow)); } // don't look for non-critical errors $this->_validate(); return $result; }
// // Display config file settings and load/save form // $form_display = new FormDisplay(); display_form_top('config.php'); display_fieldset_top('', '', null, array('class' => 'simple')); // Display language list $opts = array( 'doc' => $form_display->getDocLink('DefaultLang'), 'wiki' => $form_display->getWikiLink('DefaultLang'), 'values' => array(), 'values_escaped' => true); foreach ($all_languages as $each_lang_key => $each_lang) { $lang_name = PMA_langName($each_lang); $opts['values'][$each_lang_key] = $lang_name; } display_input('DefaultLang', __('Default language'), '', 'select', $cf->getValue('DefaultLang'), true, $opts); // Display server list $opts = array( 'doc' => $form_display->getDocLink('ServerDefault'), 'wiki' => $form_display->getWikiLink('ServerDefault'), 'values' => array(), 'values_disabled' => array()); if ($cf->getServerCount() > 0) { $opts['values']['0'] = __('let the user choose'); $opts['values']['-'] = '------------------------------'; if ($cf->getServerCount() == 1) {
/** * Check GZipDump configuration * * @param string $sGZipDumpWarn Warning for GZipDumpWarning * * @return void */ protected function performConfigChecksServerGZipdump($sGZipDumpWarn) { // // $cfg['GZipDump'] // requires zlib functions // if ($this->cfg->getValue('GZipDump') && (@(!function_exists('gzopen')) || @(!function_exists('gzencode')))) { PMA_messagesSet('error', 'GZipDump', PMA_lang(PMA_langName('GZipDump')), PMA_lang($sGZipDumpWarn, 'gzencode')); } }
/** * @dataProvider dataProvider * @return void */ function testLangName($test, $result) { $this->assertEquals($result, PMA_langName($test)); }
/** * Displays for for language selection * * @access public */ function PMA_select_language($use_fieldset = FALSE, $show_doc = TRUE) { global $cfg, $lang; ?> <form method="post" action="index.php" target="_parent"> <?php $_form_params = array('db' => $GLOBALS['db'], 'table' => $GLOBALS['table']); echo PMA_generate_common_hidden_inputs($_form_params); // For non-English, display "Language" with emphasis because it's // not a proper word in the current language; we show it to help // people recognize the dialog $language_title = __('Language') . (__('Language') != 'Language' ? ' - <em>Language</em>' : ''); if ($show_doc) { $language_title .= PMA_showDocu('faq7_2'); } if ($use_fieldset) { echo '<fieldset><legend xml:lang="en" dir="ltr">' . $language_title . '</legend>'; } else { echo '<bdo xml:lang="en" dir="ltr">' . $language_title . ':</bdo>'; } ?> <select name="lang" onchange="this.form.submit();" xml:lang="en" dir="ltr"> <?php uasort($GLOBALS['available_languages'], 'PMA_language_cmp'); foreach ($GLOBALS['available_languages'] as $id => $tmplang) { $lang_name = PMA_langName($tmplang); //Is current one active? if ($lang == $id) { $selected = ' selected="selected"'; } else { $selected = ''; } echo ' '; echo '<option value="' . $id . '"' . $selected . '>' . $lang_name . '</option>' . "\n"; } ?> </select> <?php if ($use_fieldset) { echo '</fieldset>'; } ?> <noscript> <?php if ($use_fieldset) { echo '<fieldset class="tblFooters">'; } ?> <input type="submit" value="Go" /> <?php if ($use_fieldset) { echo '</fieldset>'; } ?> </noscript> </form> <?php }
/** * Performs various compatibility, security and consistency checks on current config * * Outputs results to message list, must be called between PMA_messagesBegin() * and PMA_messagesEnd() * * @return void */ function PMA_performConfigChecks() { $cf = $GLOBALS['ConfigFile']; $blowfish_secret = $cf->get('blowfish_secret'); $blowfish_secret_set = false; $cookie_auth_used = false; $strAllowArbitraryServerWarning = __('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.'); $strAllowArbitraryServerWarning = sprintf($strAllowArbitraryServerWarning, '[a@?page=form&formset=Features#tab_Security]', '[/a]', '[a@?page=form&formset=Features#tab_Security]', '[/a]'); $strBlowfishSecretMsg = __('You didn\'t have blowfish secret set and have enabled cookie authentication, so a key was automatically generated for you. It is used to encrypt cookies; you don\'t need to remember it.'); $strBZipDumpWarning = __('%sBzip2 compression and decompression%s requires functions (%s) which are unavailable on this system.'); $strBZipDumpWarning = sprintf($strBZipDumpWarning, '[a@?page=form&formset=Features#tab_Import_export]', '[/a]', '%s'); $strDirectoryNotice = __('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.'); $strForceSSLNotice = __('This %soption%s should be enabled if your web server supports it.'); $strForceSSLNotice = sprintf($strForceSSLNotice, '[a@?page=form&formset=Features#tab_Security]', '[/a]'); $strGZipDumpWarning = __('%sGZip compression and decompression%s requires functions (%s) which are unavailable on this system.'); $strGZipDumpWarning = sprintf($strGZipDumpWarning, '[a@?page=form&formset=Features#tab_Import_export]', '[/a]', '%s'); $strLoginCookieValidityWarning = __('%sLogin cookie validity%s greater than %ssession.gc_maxlifetime%s may cause random session invalidation (currently session.gc_maxlifetime is %d).'); $strLoginCookieValidityWarning = sprintf($strLoginCookieValidityWarning, '[a@?page=form&formset=Features#tab_Security]', '[/a]', '[a@' . PMA_getPHPDocLink('session.configuration.php#ini.session.gc-maxlifetime') . ']', '[/a]', ini_get('session.gc_maxlifetime')); $strLoginCookieValidityWarning2 = __('%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.'); $strLoginCookieValidityWarning2 = sprintf($strLoginCookieValidityWarning2, '[a@?page=form&formset=Features#tab_Security]', '[/a]'); $strLoginCookieValidityWarning3 = __('If using cookie authentication and %sLogin cookie store%s is not 0, %sLogin cookie validity%s must be set to a value less or equal to it.'); $strLoginCookieValidityWarning3 = sprintf($strLoginCookieValidityWarning3, '[a@?page=form&formset=Features#tab_Security]', '[/a]', '[a@?page=form&formset=Features#tab_Security]', '[/a]'); $strSecurityInfoMsg = __('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.'); $strSecurityInfoMsg = sprintf($strSecurityInfoMsg, '[a@?page=servers&mode=edit&id=%1$d#tab_Server_config]', '[/a]', '[a@?page=form&formset=Features#tab_Security]', '[/a]'); $strServerAuthConfigMsg = __('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].'); $strServerAuthConfigMsg = sprintf($strServerAuthConfigMsg, '[a@?page=servers&mode=edit&id=%1$d#tab_Server]', '[/a]'); $strZipDumpExportWarning = __('%sZip compression%s requires functions (%s) which are unavailable on this system.'); $strZipDumpExportWarning = sprintf($strZipDumpExportWarning, '[a@?page=form&formset=Features#tab_Import_export]', '[/a]', '%s'); $strZipDumpImportWarning = __('%sZip decompression%s requires functions (%s) which are unavailable on this system.'); $strZipDumpImportWarning = sprintf($strZipDumpImportWarning, '[a@?page=form&formset=Features#tab_Import_export]', '[/a]', '%s'); for ($i = 1, $server_cnt = $cf->getServerCount(); $i <= $server_cnt; $i++) { $cookie_auth_server = $cf->getValue("Servers/{$i}/auth_type") == 'cookie'; $cookie_auth_used |= $cookie_auth_server; $server_name = $cf->getServerName($i); if ($server_name == 'localhost') { $server_name .= " [{$i}]"; } $server_name = htmlspecialchars($server_name); if ($cookie_auth_server && $blowfish_secret === null) { $blowfish_secret = uniqid('', true); $blowfish_secret_set = true; $cf->set('blowfish_secret', $blowfish_secret); } // // $cfg['Servers'][$i]['ssl'] // should be enabled if possible // if (!$cf->getValue("Servers/{$i}/ssl")) { $title = PMA_lang(PMA_langName('Servers/1/ssl')) . " ({$server_name})"; PMA_messagesSet('notice', "Servers/{$i}/ssl", $title, __('You should use SSL connections if your database server supports it.')); } // // $cfg['Servers'][$i]['extension'] // warn about using 'mysql' // if ($cf->getValue("Servers/{$i}/extension") == 'mysql') { $title = PMA_lang(PMA_langName('Servers/1/extension')) . " ({$server_name})"; PMA_messagesSet('notice', "Servers/{$i}/extension", $title, __('You should use mysqli for performance reasons.')); } // // $cfg['Servers'][$i]['auth_type'] // warn about full user credentials if 'auth_type' is 'config' // if ($cf->getValue("Servers/{$i}/auth_type") == 'config' && $cf->getValue("Servers/{$i}/user") != '' && $cf->getValue("Servers/{$i}/password") != '') { $title = PMA_lang(PMA_langName('Servers/1/auth_type')) . " ({$server_name})"; PMA_messagesSet('notice', "Servers/{$i}/auth_type", $title, PMA_lang($strServerAuthConfigMsg, $i) . ' ' . PMA_lang($strSecurityInfoMsg, $i)); } // // $cfg['Servers'][$i]['AllowRoot'] // $cfg['Servers'][$i]['AllowNoPassword'] // serious security flaw // if ($cf->getValue("Servers/{$i}/AllowRoot") && $cf->getValue("Servers/{$i}/AllowNoPassword")) { $title = PMA_lang(PMA_langName('Servers/1/AllowNoPassword')) . " ({$server_name})"; PMA_messagesSet('notice', "Servers/{$i}/AllowNoPassword", $title, __('You allow for connecting to the server without a password.') . ' ' . PMA_lang($strSecurityInfoMsg, $i)); } } // // $cfg['blowfish_secret'] // it's required for 'cookie' authentication // if ($cookie_auth_used) { if ($blowfish_secret_set) { // 'cookie' auth used, blowfish_secret was generated PMA_messagesSet('notice', 'blowfish_secret_created', PMA_lang(PMA_langName('blowfish_secret')), $strBlowfishSecretMsg); } else { $blowfish_warnings = array(); // check length if (strlen($blowfish_secret) < 8) { // too short key $blowfish_warnings[] = __('Key is too short, it should have at least 8 characters.'); } // check used characters $has_digits = (bool) preg_match('/\\d/', $blowfish_secret); $has_chars = (bool) preg_match('/\\S/', $blowfish_secret); $has_nonword = (bool) preg_match('/\\W/', $blowfish_secret); if (!$has_digits || !$has_chars || !$has_nonword) { $blowfish_warnings[] = PMA_lang(__('Key should contain letters, numbers [em]and[/em] special characters.')); } if (!empty($blowfish_warnings)) { PMA_messagesSet('error', 'blowfish_warnings' . count($blowfish_warnings), PMA_lang(PMA_langName('blowfish_secret')), implode('<br />', $blowfish_warnings)); } } } // // $cfg['ForceSSL'] // should be enabled if possible // if (!$cf->getValue('ForceSSL')) { PMA_messagesSet('notice', 'ForceSSL', PMA_lang(PMA_langName('ForceSSL')), PMA_lang($strForceSSLNotice)); } // // $cfg['AllowArbitraryServer'] // should be disabled // if ($cf->getValue('AllowArbitraryServer')) { PMA_messagesSet('notice', 'AllowArbitraryServer', PMA_lang(PMA_langName('AllowArbitraryServer')), PMA_lang($strAllowArbitraryServerWarning)); } // // $cfg['LoginCookieValidity'] // value greater than session.gc_maxlifetime will cause // random session invalidation after that time if ($cf->getValue('LoginCookieValidity') > ini_get('session.gc_maxlifetime')) { PMA_messagesSet('error', 'LoginCookieValidity', PMA_lang(PMA_langName('LoginCookieValidity')), PMA_lang($strLoginCookieValidityWarning)); } // // $cfg['LoginCookieValidity'] // should be at most 1800 (30 min) // if ($cf->getValue('LoginCookieValidity') > 1800) { PMA_messagesSet('notice', 'LoginCookieValidity', PMA_lang(PMA_langName('LoginCookieValidity')), PMA_lang($strLoginCookieValidityWarning2)); } // // $cfg['LoginCookieValidity'] // $cfg['LoginCookieStore'] // LoginCookieValidity must be less or equal to LoginCookieStore // if ($cf->getValue('LoginCookieStore') != 0 && $cf->getValue('LoginCookieValidity') > $cf->getValue('LoginCookieStore')) { PMA_messagesSet('error', 'LoginCookieValidity', PMA_lang(PMA_langName('LoginCookieValidity')), PMA_lang($strLoginCookieValidityWarning3)); } // // $cfg['SaveDir'] // should not be world-accessible // if ($cf->getValue('SaveDir') != '') { PMA_messagesSet('notice', 'SaveDir', PMA_lang(PMA_langName('SaveDir')), PMA_lang($strDirectoryNotice)); } // // $cfg['TempDir'] // should not be world-accessible // if ($cf->getValue('TempDir') != '') { PMA_messagesSet('notice', 'TempDir', PMA_lang(PMA_langName('TempDir')), PMA_lang($strDirectoryNotice)); } // // $cfg['GZipDump'] // requires zlib functions // if ($cf->getValue('GZipDump') && (@(!function_exists('gzopen')) || @(!function_exists('gzencode')))) { PMA_messagesSet('error', 'GZipDump', PMA_lang(PMA_langName('GZipDump')), PMA_lang($strGZipDumpWarning, 'gzencode')); } // // $cfg['BZipDump'] // requires bzip2 functions // if ($cf->getValue('BZipDump') && (!@function_exists('bzopen') || !@function_exists('bzcompress'))) { $functions = @function_exists('bzopen') ? '' : 'bzopen'; $functions .= @function_exists('bzcompress') ? '' : ($functions ? ', ' : '') . 'bzcompress'; PMA_messagesSet('error', 'BZipDump', PMA_lang(PMA_langName('BZipDump')), PMA_lang($strBZipDumpWarning, $functions)); } // // $cfg['ZipDump'] // requires zip_open in import // if ($cf->getValue('ZipDump') && !@function_exists('zip_open')) { PMA_messagesSet('error', 'ZipDump_import', PMA_lang(PMA_langName('ZipDump')), PMA_lang($strZipDumpImportWarning, 'zip_open')); } // // $cfg['ZipDump'] // requires gzcompress in export // if ($cf->getValue('ZipDump') && !@function_exists('gzcompress')) { PMA_messagesSet('error', 'ZipDump_export', PMA_lang(PMA_langName('ZipDump')), PMA_lang($strZipDumpExportWarning, 'gzcompress')); } }