adminerevo/adminer/include/auth.inc.php

198 lines
6.5 KiB
PHP
Raw Normal View History

<?php
$connection = '';
2013-10-25 02:10:50 +00:00
$has_token = $_SESSION["token"];
if (!$has_token) {
$_SESSION["token"] = rand(1, 1e6); // defense against cross-site request forgery
}
2013-10-25 02:10:50 +00:00
$token = get_token(); ///< @var string CSRF protection
2010-05-07 14:31:14 +00:00
$permanent = array();
if ($_COOKIE["adminer_permanent"]) {
foreach (explode(" ", $_COOKIE["adminer_permanent"]) as $val) {
list($key) = explode(":", $val);
$permanent[$key] = $val;
}
}
function add_invalid_login() {
global $adminer;
$filename = get_temp_dir() . "/adminer.invalid";
$fp = @fopen($filename, "r+"); // @ - may not exist
if (!$fp) { // c+ is available since PHP 5.2.6
2014-03-25 16:35:49 +00:00
$fp = @fopen($filename, "w"); // @ - may not be writable
if (!$fp) {
return;
}
}
flock($fp, LOCK_EX);
$invalids = unserialize(stream_get_contents($fp));
$time = time();
if ($invalids) {
foreach ($invalids as $ip => $val) {
if ($val[0] < $time) {
unset($invalids[$ip]);
}
}
}
$invalid = &$invalids[$adminer->bruteForceKey()];
if (!$invalid) {
$invalid = array($time + 30*60, 0); // active for 30 minutes
}
$invalid[1]++;
$serialized = serialize($invalids);
rewind($fp);
fwrite($fp, $serialized);
ftruncate($fp, strlen($serialized));
flock($fp, LOCK_UN);
fclose($fp);
}
2012-05-14 07:08:32 +00:00
$auth = $_POST["auth"];
if ($auth) {
$invalids = unserialize(@file_get_contents(get_temp_dir() . "/adminer.invalid")); // @ - may not exist
$invalid = $invalids[$adminer->bruteForceKey()];
$next_attempt = ($invalid[1] > 30 ? $invalid[0] - time() : 0); // allow 30 invalid attempts
if ($next_attempt > 0) { //! do the same with permanent login
auth_error(lang('Too many unsuccessful logins, try again in %d minute(s).', ceil($next_attempt / 60)));
}
session_regenerate_id(); // defense against session fixation
2013-08-11 02:11:35 +00:00
$driver = $auth["driver"];
$server = $auth["server"];
$username = $auth["username"];
$password = (string) $auth["password"];
2013-08-11 02:11:35 +00:00
$db = $auth["db"];
set_password($driver, $server, $username, $password);
$_SESSION["db"][$driver][$server][$username][$db] = true;
2013-10-25 05:40:05 +00:00
if ($auth["permanent"]) {
2013-08-11 02:11:35 +00:00
$key = base64_encode($driver) . "-" . base64_encode($server) . "-" . base64_encode($username) . "-" . base64_encode($db);
$private = $adminer->permanentLogin(true);
2013-08-11 02:11:35 +00:00
$permanent[$key] = "$key:" . base64_encode($private ? encrypt_string($password, $private) : "");
2010-05-07 14:31:14 +00:00
cookie("adminer_permanent", implode(" ", $permanent));
}
2012-05-14 07:08:32 +00:00
if (count($_POST) == 1 // 1 - auth
2013-08-11 02:11:35 +00:00
|| DRIVER != $driver
|| SERVER != $server
|| $_GET["username"] !== $username // "0" == "00"
|| DB != $db
) {
2013-08-11 02:11:35 +00:00
redirect(auth_url($driver, $server, $username, $db));
}
2013-05-02 01:28:04 +00:00
} elseif ($_POST["logout"]) {
2013-10-25 02:10:50 +00:00
if ($has_token && !verify_token()) {
page_header(lang('Logout'), lang('Invalid CSRF token. Send the form again.'));
page_footer("db");
exit;
} else {
2012-09-09 04:29:16 +00:00
foreach (array("pwds", "db", "dbs", "queries") as $key) {
set_session($key, null);
}
unset_permanent();
2013-07-03 17:34:19 +00:00
redirect(substr(preg_replace('~\b(username|db|ns)=[^&]*&~', '', ME), 0, -1), lang('Logout successful.'));
}
2013-05-02 01:28:04 +00:00
} elseif ($permanent && !$_SESSION["pwds"]) {
2010-05-07 14:31:14 +00:00
session_regenerate_id();
$private = $adminer->permanentLogin();
2010-05-07 14:31:14 +00:00
foreach ($permanent as $key => $val) {
list(, $cipher) = explode(":", $val);
2013-07-05 15:28:37 +00:00
list($vendor, $server, $username, $db) = array_map('base64_decode', explode("-", $key));
set_password($vendor, $server, $username, decrypt_string(base64_decode($cipher), $private));
2013-07-05 15:28:37 +00:00
$_SESSION["db"][$vendor][$server][$username][$db] = true;
}
}
function unset_permanent() {
global $permanent;
2012-09-09 04:29:16 +00:00
foreach ($permanent as $key => $val) {
2013-07-05 15:28:37 +00:00
list($vendor, $server, $username, $db) = array_map('base64_decode', explode("-", $key));
if ($vendor == DRIVER && $server == SERVER && $username == $_GET["username"] && $db == DB) {
2012-09-09 04:29:16 +00:00
unset($permanent[$key]);
}
}
2012-09-09 04:29:16 +00:00
cookie("adminer_permanent", implode(" ", $permanent));
}
function auth_error($error) {
global $adminer, $has_token;
$session_name = session_name();
if (!$_COOKIE[$session_name] && $_GET[$session_name] && ini_bool("session.use_only_cookies")) {
$error = lang('Session support must be enabled.');
} elseif (isset($_GET["username"])) {
2013-10-25 02:10:50 +00:00
if (($_COOKIE[$session_name] || $_GET[$session_name]) && !$has_token) {
$error = lang('Session expired, please login again.');
} else {
add_invalid_login();
$password = get_password();
2012-05-14 06:54:07 +00:00
if ($password !== null) {
if ($password === false) {
2013-06-11 12:56:54 +00:00
$error .= '<br>' . lang('Master password expired. <a href="http://www.adminer.org/en/extension/" target="_blank">Implement</a> %s method to make it permanent.', '<code>permanentLogin()</code>');
}
set_password(DRIVER, SERVER, $_GET["username"], null);
}
unset_permanent();
}
}
$params = session_get_cookie_params();
cookie("adminer_key", ($_COOKIE["adminer_key"] ? $_COOKIE["adminer_key"] : rand_string()), $params["lifetime"]);
page_header(lang('Login'), $error, null);
echo "<form action='' method='post'>\n";
$adminer->loginForm();
echo "<div>";
2012-05-14 07:08:32 +00:00
hidden_fields($_POST, array("auth")); // expired session
echo "</div>\n";
echo "</form>\n";
page_footer("auth");
exit;
}
if (isset($_GET["username"])) {
if (!class_exists("Min_DB")) {
unset($_SESSION["pwds"][DRIVER]);
unset_permanent();
2010-11-03 23:12:01 +00:00
page_header(lang('No extension'), lang('None of the supported PHP extensions (%s) are available.', implode(", ", $possible_drivers)), false);
page_footer("auth");
exit;
}
$connection = connect();
}
2013-05-02 01:28:04 +00:00
2014-02-08 03:35:26 +00:00
$driver = new Min_Driver($connection);
2014-01-10 19:16:36 +00:00
if (!is_object($connection) || !$adminer->login($_GET["username"], get_password())) {
auth_error((is_string($connection) ? $connection : lang('Invalid credentials.')));
}
2012-05-14 07:08:32 +00:00
if ($auth && $_POST["token"]) {
$_POST["token"] = $token; // reset token after explicit login
}
$error = ''; ///< @var string
if ($_POST) {
2013-10-25 02:10:50 +00:00
if (!verify_token()) {
$ini = "max_input_vars";
$max_vars = ini_get($ini);
if (extension_loaded("suhosin")) {
foreach (array("suhosin.request.max_vars", "suhosin.post.max_vars") as $key) {
$val = ini_get($key);
if ($val && (!$max_vars || $val < $max_vars)) {
$ini = $key;
$max_vars = $val;
}
}
}
$error = (!$_POST["token"] && $max_vars
? lang('Maximum number of allowed fields exceeded. Please increase %s.', "'$ini'")
: lang('Invalid CSRF token. Send the form again.')
);
}
2013-05-02 01:28:04 +00:00
} elseif ($_SERVER["REQUEST_METHOD"] == "POST") {
// posted form with no data means that post_max_size exceeded because Adminer always sends token at least
$error = lang('Too big POST data. Reduce the data or increase the %s configuration directive.', "'post_max_size'");
2013-06-24 13:12:13 +00:00
if (isset($_GET["sql"])) {
$error .= ' ' . lang('You can upload a big SQL file via FTP and import it from server.');
}
}