"link", "key2" => array("link", "desc")), null for nothing, false for driver only, true for driver and server * @param string used after colon in title and heading, should be HTML escaped * @return null */ function page_header($title, $error = "", $breadcrumb = array(), $title2 = "") { global $LANG, $VERSION, $adminer, $drivers, $jush; page_headers(); if (is_ajax() && $error) { page_messages($error); exit; } $title_all = $title . ($title2 != "" ? ": $title2" : ""); $title_page = strip_tags($title_all . (SERVER != "" && SERVER != "localhost" ? h(" - " . SERVER) : "") . " - " . $adminer->name()); ?> <?php echo $title_page; ?> head()) { ?> css() as $css) { ?> time()) { // 86400 - 1 day in seconds $version = unserialize(file_get_contents($filename)); $_COOKIE["adminer_version"] = $version["version"]; // doesn't need to send to the browser } ?> > mixin(document.body, {onkeydown: bodyKeydown, onclick: bodyClick}); document.body.className = document.body.className.replace(/ nojs/, ' js'); var offlineMessage = ''; var thousandsSeparator = '';
' . $drivers[DRIVER] . ' » '; $link = substr(preg_replace('~\b(db|ns)=[^&]*&~', '', ME), 0, -1); $server = $adminer->serverName(SERVER); $server = ($server != "" ? $server : lang('Server')); if ($breadcrumb === false) { echo "$server\n"; } else { echo "$server » "; if ($_GET["ns"] != "" || (DB != "" && is_array($breadcrumb))) { echo '' . h(DB) . ' » '; } if (is_array($breadcrumb)) { if ($_GET["ns"] != "") { echo '' . h($_GET["ns"]) . ' » '; } foreach ($breadcrumb as $key => $val) { $desc = (is_array($val) ? $val[1] : h($val)); if ($desc != "") { echo "$desc » "; } } } echo "$title\n"; } } echo "

$title_all

\n"; echo "\n"; restart_session(); page_messages($error); $databases = &get_session("dbs"); if (DB != "" && $databases && !in_array(DB, $databases, true)) { $databases = null; } stop_session(); define("PAGE_HEADER", 1); } /** Send HTTP headers * @return null */ function page_headers() { global $adminer; header("Content-Type: text/html; charset=utf-8"); header("Cache-Control: no-cache"); header("X-Frame-Options: deny"); // ClickJacking protection in IE8, Safari 4, Chrome 2, Firefox 3.6.9 header("X-XSS-Protection: 0"); // prevents introducing XSS in IE8 by removing safe parts of the page header("X-Content-Type-Options: nosniff"); header("Referrer-Policy: origin-when-cross-origin"); foreach ($adminer->csp() as $csp) { $header = array(); foreach ($csp as $key => $val) { $header[] = "$key $val"; } header("Content-Security-Policy: " . implode("; ", $header)); } $adminer->headers(); } /** Get Content Security Policy headers * @return array of arrays with directive name in key, allowed sources in value */ function csp() { return array( array( "script-src" => "'self' 'unsafe-inline' 'nonce-" . get_nonce() . "' 'strict-dynamic'", // 'self' is a fallback for browsers not supporting 'strict-dynamic', 'unsafe-inline' is a fallback for browsers not supporting 'nonce-' "connect-src" => "'self' https://api.github.com/repos/adminerevo/adminerevo/releases/latest", "frame-src" => "'self'", "object-src" => "'none'", "base-uri" => "'none'", "form-action" => "'self'", ), ); } /** Get a CSP nonce * @return string Base64 value */ function get_nonce() { static $nonce; if (!$nonce) { $nonce = base64_encode(rand_string()); } return $nonce; } /** Print flash and error messages * @param string * @return null */ function page_messages($error) { $uri = preg_replace('~^[^?]*~', '', $_SERVER["REQUEST_URI"]); $messages = []; if (isset($_SESSION["messages"][$uri])) { $messages = $_SESSION["messages"][$uri]; } if (count($messages) > 0) { echo "
" . implode("
\n
", $messages) . "
" . script("messagesPrint();"); unset($_SESSION["messages"][$uri]); } if ($error) { echo "
$error
\n"; } } /** Print HTML footer * @param string "auth", "db", "ns" * @return null */ function page_footer($missing = "") { global $adminer, $token; ?>

\n"; }