diff --git a/.gitignore b/.gitignore index 2afb1ac5..7362a623 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /adminer*.php /editor*.php /vendor/ +/.idea diff --git a/adminer/drivers/elastic.inc.php b/adminer/drivers/elastic.inc.php index f03098ec..c570c14e 100644 --- a/adminer/drivers/elastic.inc.php +++ b/adminer/drivers/elastic.inc.php @@ -8,64 +8,77 @@ if (isset($_GET["elastic"])) { class Min_DB { var $extension = "JSON", $server_info, $errno, $error, $_url, $_db; - /** Performs query - * @param string - * @param array - * @param string - * @return mixed + /** + * @param string $path + * @param array|null $content + * @param string $method + * @return array|false */ - function rootQuery($path, $content = array(), $method = 'GET') { + function rootQuery($path, array $content = null, $method = 'GET') { @ini_set('track_errors', 1); // @ - may be disabled $file = @file_get_contents("$this->_url/" . ltrim($path, '/'), false, stream_context_create(array('http' => array( 'method' => $method, - 'content' => $content === null ? $content : json_encode($content), - 'header' => 'Content-Type: application/json', - 'ignore_errors' => 1, // available since PHP 5.2.10 + 'content' => $content !== null ? json_encode($content) : null, + 'header' => $content !== null ? 'Content-Type: application/json' : [], + 'ignore_errors' => 1, + 'follow_location' => 0, + 'max_redirects' => 0, )))); - if (!$file) { - $this->error = error_get_last()['message']; - return $file; - } - if (!preg_match('~^HTTP/[0-9.]+ 2~i', $http_response_header[0])) { - $this->error = lang('Invalid credentials.') . " $http_response_header[0]"; + + if ($file === false) { + $this->error = lang('Invalid server or credentials.'); return false; } + $return = json_decode($file, true); if ($return === null) { - $this->errno = json_last_error(); - if (function_exists('json_last_error_msg')) { - $this->error = json_last_error_msg(); - } else { - $constants = get_defined_constants(true); - foreach ($constants['json'] as $name => $value) { - if ($value == $this->errno && preg_match('~^JSON_ERROR_~', $name)) { - $this->error = $name; - break; - } - } - } + $this->error = lang('Invalid server or credentials.'); + return false; } + + if (!preg_match('~^HTTP/[0-9.]+ 2~i', $http_response_header[0])) { + if (isset($return['error']['root_cause'][0]['type'])) { + $this->error = $return['error']['root_cause'][0]['type'] . ": " . $return['error']['root_cause'][0]['reason']; + } else { + $this->error = lang('Invalid server or credentials.'); + } + return false; + } + return $return; } /** Performs query relative to actual selected DB - * @param string - * @param array - * @param string - * @return mixed + * @param string $path + * @param array|null $content + * @param string $method + * @return array|false */ - function query($path, $content = array(), $method = 'GET') { + function query($path, array $content = null, $method = 'GET') { return $this->rootQuery(($this->_db != "" ? "$this->_db/" : "/") . ltrim($path, '/'), $content, $method); } + /** + * @param string $server + * @param string $username + * @param string $password + * @return bool + */ function connect($server, $username, $password) { - preg_match('~^(https?://)?(.*)~', $server, $match); - $this->_url = ($match[1] ? $match[1] : "http://") . "$username:$password@$match[2]"; + $this->_url = build_http_url($server, $username, $password, "localhost", 9200); + $return = $this->query(''); - if ($return) { - $this->server_info = $return['version']['number']; + if (!$return) { + return false; } - return (bool) $return; + + if (!isset($return['version']['number'])) { + $this->error = lang('Invalid server or credentials.'); + return false; + } + + $this->server_info = $return['version']['number']; + return true; } function select_db($database) { @@ -227,9 +240,6 @@ if (isset($_GET["elastic"])) { global $adminer; $connection = new Min_DB; list($server, $username, $password) = $adminer->credentials(); - if (strpos($server, '/') !== false || strpos($server, ':') !== false) { - return lang('Only hostname or IP address'); - } if ($password != "" && $connection->connect($server, $username, "")) { return lang('Database does not support password.'); } diff --git a/adminer/include/auth.inc.php b/adminer/include/auth.inc.php index 630e49e1..7080dd9e 100644 --- a/adminer/include/auth.inc.php +++ b/adminer/include/auth.inc.php @@ -15,6 +15,58 @@ if (isset($_COOKIE["adminer_permanent"]) && $_COOKIE["adminer_permanent"]) { } } +function validate_server_input() { + if (SERVER == "") { + return; + } + + $parts = parse_url(SERVER); + if (!$parts) { + auth_error(lang('Invalid server or credentials.')); + } + + // Check proper URL parts. + if (isset($parts['user']) || isset($parts['pass']) || isset($parts['query']) || isset($parts['fragment'])) { + auth_error(lang('Invalid server or credentials.')); + } + + // Allow only HTTP/S scheme. + if (isset($parts['scheme']) && !preg_match('~^(https?)$~i', $parts['scheme'])) { + auth_error(lang('Invalid server or credentials.')); + } + + // Allow only host without a path. Note that "localhost" is parsed as path. + $host = (isset($parts['host']) ? $parts['host'] : '') . (isset($parts['path']) ? $parts['path'] : ''); + if (strpos(rtrim($host, '/'), '/') !== false) { + auth_error(lang('Invalid server or credentials.')); + } + + // Check privileged ports. + if (isset($parts['port']) && ($parts['port'] < 1024 || $parts['port'] > 65535)) { + auth_error(lang('Connecting to privileged ports is not allowed.')); + } +} + +/** + * @param string $server + * @param string $username + * @param string $password + * @param string $defaultServer + * @param int|null $defaultPort + * @return string + */ +function build_http_url($server, $username, $password, $defaultServer, $defaultPort = null) { + if (!preg_match('~^(https?://)?([^:]*)(:\d+)?$~', rtrim($server, '/'), $matches)) { + $this->error = lang('Invalid server or credentials.'); + return false; + } + + return ($matches[1] ?: "http://") . + ($username !== "" || $password !== "" ? "$username:$password@" : "") . + ($matches[2] !== "" ? $matches[2] : $defaultServer) . + (isset($matches[3]) ? $matches[3] : ($defaultPort ? ":$defaultPort" : "")); +} + function add_invalid_login() { global $adminer; $fp = file_open_lock(get_temp_dir() . "/adminer.invalid"); @@ -60,7 +112,7 @@ $auth = (isset($_POST["auth"]) ? $_POST["auth"] : null); if ($auth) { session_regenerate_id(); // defense against session fixation $vendor = isset($auth["driver"]) ? $auth["driver"] : null; - $server = isset($auth["server"]) ? $auth["server"] : null; + $server = isset($auth["server"]) ? trim($auth["server"]) : null; $username = isset($auth["username"]) ? $auth["username"] : null; $password = isset($auth["password"]) ? (string) $auth["password"] : null; $db = isset($auth["db"]) ? $auth["db"] : null; @@ -86,7 +138,7 @@ if ($auth) { set_session($key, null); } unset_permanent(); - redirect(substr(preg_replace('~\b(username|db|ns)=[^&]*&~', '', ME), 0, -1), lang('Logout successful.') . '.'); + redirect(substr(preg_replace('~\b(username|db|ns)=[^&]*&~', '', ME), 0, -1), lang('Logout successful.')); } elseif ($permanent && !$_SESSION["pwds"]) { session_regenerate_id(); @@ -163,23 +215,16 @@ if (isset($_GET["username"]) && !class_exists("Min_DB")) { stop_session(true); if (isset($_GET["username"]) && is_string(get_password())) { - if (strpos(SERVER, ':') !== false) { - list($host, $port) = explode(":", SERVER, 2); - } else { - $host = SERVER; - $port = null; - } - if (preg_match('~^\s*([-+]?\d+)~', $port, $match) && ($match[1] < 1024 || $match[1] > 65535)) { // is_numeric('80#') would still connect to port 80 - auth_error(lang('Connecting to privileged ports is not allowed.')); - } + validate_server_input(); check_invalid_login(); + $connection = connect(); $driver = new Min_Driver($connection); } $login = null; if (!is_object($connection) || ($login = $adminer->login($_GET["username"], get_password())) !== true) { - $error = (is_string($connection) ? h($connection) : (is_string($login) ? $login : lang('Invalid credentials.'))); + $error = (is_string($connection) ? h($connection) : (is_string($login) ? $login : lang('Invalid server or credentials.'))); auth_error($error . (preg_match('~^ | $~', get_password()) ? '
' . lang('There is a space in the input password which might be the cause.') : '')); } diff --git a/adminer/lang/ar.inc.php b/adminer/lang/ar.inc.php index 0a717ffe..3c099f06 100644 --- a/adminer/lang/ar.inc.php +++ b/adminer/lang/ar.inc.php @@ -2,7 +2,7 @@ $translations = array( 'Login' => 'تسجيل الدخول', 'Logout successful.' => 'تم تسجيل الخروج بنجاح.', - 'Invalid credentials.' => 'بيانات الدخول غير صالحة.', + 'Invalid server or credentials.' => null, 'Server' => 'الخادم', 'Username' => 'اسم المستخدم', 'Password' => 'كلمة المرور', diff --git a/adminer/lang/bg.inc.php b/adminer/lang/bg.inc.php index 2ac82f51..2d4921a8 100644 --- a/adminer/lang/bg.inc.php +++ b/adminer/lang/bg.inc.php @@ -10,7 +10,7 @@ $translations = array( 'Logout' => 'Изход', 'Logged as: %s' => 'Текущ потребител: %s', 'Logout successful.' => 'Излизането е успешно.', - 'Invalid credentials.' => 'Невалидни потребителски данни.', + 'Invalid server or credentials.' => null, 'Too many unsuccessful logins, try again in %d minute(s).' => array('Прекалено много неуспешни опити за вход, опитайте пак след %d минута.', 'Прекалено много неуспешни опити за вход, опитайте пак след %d минути.'), 'Master password expired. Implement %s method to make it permanent.' => 'Главната парола вече е невалидна. Изберете %s метод, за да я направите постоянна.', 'Language' => 'Език', diff --git a/adminer/lang/bn.inc.php b/adminer/lang/bn.inc.php index 398b4ce0..7e281337 100644 --- a/adminer/lang/bn.inc.php +++ b/adminer/lang/bn.inc.php @@ -2,7 +2,7 @@ $translations = array( 'Login' => 'লগইন', 'Logout successful.' => 'সফলভাবে লগআউট হয়েছে।', - 'Invalid credentials.' => 'ভুল পাসওয়ার্ড।', + 'Invalid server or credentials.' => null, 'Server' => 'সার্ভার', 'Username' => 'ইউজারের নাম', 'Password' => 'পাসওয়ার্ড', diff --git a/adminer/lang/bs.inc.php b/adminer/lang/bs.inc.php index fd53c764..c7ddcab3 100644 --- a/adminer/lang/bs.inc.php +++ b/adminer/lang/bs.inc.php @@ -10,7 +10,7 @@ $translations = array( 'Logout' => 'Odjava', 'Logged as: %s' => 'Prijavi se kao: %s', 'Logout successful.' => 'Uspešna odjava.', - 'Invalid credentials.' => 'Nevažeće dozvole.', + 'Invalid server or credentials.' => null, 'Language' => 'Jezik', 'Invalid CSRF token. Send the form again.' => 'Nevažeći CSRF kod. Proslijedite ponovo formu.', 'No extension' => 'Bez dodataka', diff --git a/adminer/lang/ca.inc.php b/adminer/lang/ca.inc.php index 1cb3dcf0..2cbbda16 100644 --- a/adminer/lang/ca.inc.php +++ b/adminer/lang/ca.inc.php @@ -2,7 +2,7 @@ $translations = array( 'Login' => 'Inicia la sessió', 'Logout successful.' => 'Desconnexió correcta.', - 'Invalid credentials.' => 'Credencials invàlides.', + 'Invalid server or credentials.' => null, 'Server' => 'Servidor', 'Username' => 'Nom d\'usuari', 'Password' => 'Contrasenya', diff --git a/adminer/lang/cs.inc.php b/adminer/lang/cs.inc.php index e3ebbbee..d6e8e98f 100644 --- a/adminer/lang/cs.inc.php +++ b/adminer/lang/cs.inc.php @@ -10,7 +10,7 @@ $translations = array( 'Logout' => 'Odhlásit', 'Logged as: %s' => 'Přihlášen jako: %s', 'Logout successful.' => 'Odhlášení proběhlo v pořádku.', - 'Invalid credentials.' => 'Neplatné přihlašovací údaje.', + 'Invalid server or credentials.' => 'Neplatný server nebo přihlašovací údaje.', 'There is a space in the input password which might be the cause.' => 'Problém může být, že je v zadaném hesle mezera.', 'Adminer does not support accessing a database without a password, more information.' => 'Adminer nepodporuje přístup k databázi bez hesla, více informací.', 'Database does not support password.' => 'Databáze nepodporuje heslo.', diff --git a/adminer/lang/da.inc.php b/adminer/lang/da.inc.php index 10d31f6b..0746faef 100644 --- a/adminer/lang/da.inc.php +++ b/adminer/lang/da.inc.php @@ -9,7 +9,7 @@ $translations = array( 'Logout' => 'Log ud', 'Logged as: %s' => 'Logget ind som: %s', 'Logout successful.' => 'Log af vellykket.', - 'Invalid credentials.' => 'Ugyldige log ind oplysninger.', + 'Invalid server or credentials.' => null, 'Master password expired. Implement %s method to make it permanent.' => 'Master-kodeordet er udløbet. Implementer en metode for %s for at gøre det permanent.', 'Language' => 'Sprog', 'Invalid CSRF token. Send the form again.' => 'Ugyldigt CSRF-token - Genindsend formen.', diff --git a/adminer/lang/de.inc.php b/adminer/lang/de.inc.php index b5402dea..048762e0 100644 --- a/adminer/lang/de.inc.php +++ b/adminer/lang/de.inc.php @@ -2,7 +2,7 @@ $translations = array( 'Login' => 'Login', 'Logout successful.' => 'Abmeldung erfolgreich.', - 'Invalid credentials.' => 'Ungültige Anmelde-Informationen.', + 'Invalid server or credentials.' => 'Ungültige Server oder Anmelde-Informationen.', 'Server' => 'Server', 'Username' => 'Benutzer', 'Password' => 'Passwort', diff --git a/adminer/lang/el.inc.php b/adminer/lang/el.inc.php index b84a98d2..d6c25d51 100644 --- a/adminer/lang/el.inc.php +++ b/adminer/lang/el.inc.php @@ -10,7 +10,7 @@ $translations = array( 'Logout' => 'Αποσύνδεση', 'Logged as: %s' => 'Συνδεθήκατε ως %s', 'Logout successful.' => 'Αποσυνδεθήκατε με επιτυχία.', - 'Invalid credentials.' => 'Εσφαλμένα Διαπιστευτήρια.', + 'Invalid server or credentials.' => null, 'Too many unsuccessful logins, try again in %d minute(s).' => array('Επανειλημμένες ανεπιτυχείς προσπάθειες σύνδεσης, δοκιμάστε ξανά σε %s λεπτό.', 'Επανειλημμένες ανεπιτυχείς προσπάθειες σύνδεσης, δοκιμάστε ξανά σε %s λεπτά.'), 'Master password expired. Implement %s method to make it permanent.' => 'Έληξε ο Κύριος Κωδικός. Ενεργοποιήστε τη μέθοδο %s για να τον κάνετε μόνιμο.', 'Language' => 'Γλώσσα', diff --git a/adminer/lang/es.inc.php b/adminer/lang/es.inc.php index f6ea4311..f7976009 100644 --- a/adminer/lang/es.inc.php +++ b/adminer/lang/es.inc.php @@ -2,7 +2,7 @@ $translations = array( 'Login' => 'Login', 'Logout successful.' => 'Sesión finalizada con éxito.', - 'Invalid credentials.' => 'Usuario y/o clave de acceso incorrecta.', + 'Invalid server or credentials.' => null, 'Server' => 'Servidor', 'Username' => 'Usuario', 'Password' => 'Contraseña', diff --git a/adminer/lang/et.inc.php b/adminer/lang/et.inc.php index 002cf8e2..fe6ad6d3 100644 --- a/adminer/lang/et.inc.php +++ b/adminer/lang/et.inc.php @@ -2,7 +2,7 @@ $translations = array( 'Login' => 'Logi sisse', 'Logout successful.' => 'Väljalogimine õnnestus.', - 'Invalid credentials.' => 'Ebakorrektsed andmed.', + 'Invalid server or credentials.' => null, 'Server' => 'Server', 'Username' => 'Kasutajanimi', 'Password' => 'Parool', diff --git a/adminer/lang/fa.inc.php b/adminer/lang/fa.inc.php index e6a6eb95..c1a0654d 100644 --- a/adminer/lang/fa.inc.php +++ b/adminer/lang/fa.inc.php @@ -10,7 +10,7 @@ $translations = array( 'Logout' => 'خروج', 'Logged as: %s' => 'ورود به عنوان: %s', 'Logout successful.' => 'با موفقیت خارج شدید.', - 'Invalid credentials.' => 'اعتبار سنجی نامعتبر.', + 'Invalid server or credentials.' => null, 'Too many unsuccessful logins, try again in %d minute(s).' => array('ورودهای ناموفق بیش از حد، %d دقیقه دیگر تلاش نمایید.', 'ورودهای ناموفق بیش از حد، %d دقیقه دیگر تلاش نمایید.'), 'Master password expired. Implement %s method to make it permanent.' => 'رمز اصلی باطل شده است. روش %s را پیاده سازی کرده تا آن را دائمی سازید.', 'Language' => 'زبان', diff --git a/adminer/lang/fi.inc.php b/adminer/lang/fi.inc.php index 4e044672..a9e9f067 100644 --- a/adminer/lang/fi.inc.php +++ b/adminer/lang/fi.inc.php @@ -10,7 +10,7 @@ $translations = array( 'Logout' => 'Kirjaudu ulos', 'Logged as: %s' => 'Olet kirjautunut käyttäjänä: %s', 'Logout successful.' => 'Uloskirjautuminen onnistui.', - 'Invalid credentials.' => 'Virheelliset kirjautumistiedot.', + 'Invalid server or credentials.' => null, 'Too many unsuccessful logins, try again in %d minute(s).' => array('Liian monta epäonnistunutta sisäänkirjautumisyritystä, kokeile uudestaan %d minuutin kuluttua.', 'Liian monta epäonnistunutta sisäänkirjautumisyritystä, kokeile uudestaan %d minuutin kuluttua.'), 'Master password expired. Implement %s method to make it permanent.' => 'Master-salasana ei ole enää voimassa. Toteuta %s-metodi sen tekemiseksi pysyväksi.', 'Language' => 'Kieli', diff --git a/adminer/lang/fr.inc.php b/adminer/lang/fr.inc.php index 8d2d0393..eb6a85bd 100644 --- a/adminer/lang/fr.inc.php +++ b/adminer/lang/fr.inc.php @@ -2,7 +2,7 @@ $translations = array( 'Login' => 'Authentification', 'Logout successful.' => 'Au revoir !', - 'Invalid credentials.' => 'Authentification échouée.', + 'Invalid server or credentials.' => null, 'Server' => 'Serveur', 'Username' => 'Utilisateur', 'Password' => 'Mot de passe', diff --git a/adminer/lang/gl.inc.php b/adminer/lang/gl.inc.php index 55f1c1f5..5c864105 100644 --- a/adminer/lang/gl.inc.php +++ b/adminer/lang/gl.inc.php @@ -2,7 +2,7 @@ $translations = array( 'Login' => 'Conectar', 'Logout successful.' => 'Pechouse a sesión con éxito.', - 'Invalid credentials.' => 'Credenciais (usuario e/ou contrasinal) inválidos.', + 'Invalid server or credentials.' => null, 'Server' => 'Servidor', 'Username' => 'Usuario', 'Password' => 'Contrasinal', diff --git a/adminer/lang/he.inc.php b/adminer/lang/he.inc.php index 1a34a3e1..b80424fa 100644 --- a/adminer/lang/he.inc.php +++ b/adminer/lang/he.inc.php @@ -2,7 +2,7 @@ $translations = array( 'Login' => 'התחברות', 'Logout successful.' => 'ההתחברות הצליחה', - 'Invalid credentials.' => 'פרטי התחברות שגויים', + 'Invalid server or credentials.' => null, 'Server' => 'שרת', 'Username' => 'שם משתמש', 'Password' => 'סיסמה', diff --git a/adminer/lang/hu.inc.php b/adminer/lang/hu.inc.php index 72a6f911..6f546180 100644 --- a/adminer/lang/hu.inc.php +++ b/adminer/lang/hu.inc.php @@ -2,7 +2,7 @@ $translations = array( 'Login' => 'Belépés', 'Logout successful.' => 'Sikeres kilépés.', - 'Invalid credentials.' => 'Érvénytelen adatok.', + 'Invalid server or credentials.' => null, 'Server' => 'Szerver', 'Username' => 'Felhasználó', 'Password' => 'Jelszó', diff --git a/adminer/lang/id.inc.php b/adminer/lang/id.inc.php index 7f7b606c..903c1292 100644 --- a/adminer/lang/id.inc.php +++ b/adminer/lang/id.inc.php @@ -10,7 +10,7 @@ $translations = array( 'Logout' => 'Keluar', 'Logged as: %s' => 'Masuk sebagai: %s', 'Logout successful.' => 'Berhasil keluar.', - 'Invalid credentials.' => 'Akses tidak sah.', + 'Invalid server or credentials.' => null, 'Language' => 'Bahasa', 'Invalid CSRF token. Send the form again.' => 'Token CSRF tidak sah. Kirim ulang formulir.', 'No extension' => 'Ekstensi tidak ada', diff --git a/adminer/lang/it.inc.php b/adminer/lang/it.inc.php index ad3d0376..e28b3994 100644 --- a/adminer/lang/it.inc.php +++ b/adminer/lang/it.inc.php @@ -2,7 +2,7 @@ $translations = array( 'Login' => 'Autenticazione', 'Logout successful.' => 'Uscita effettuata con successo.', - 'Invalid credentials.' => 'Credenziali non valide.', + 'Invalid server or credentials.' => 'Server o credenziali non valide.', 'Server' => 'Server', 'Username' => 'Utente', 'Password' => 'Password', diff --git a/adminer/lang/ja.inc.php b/adminer/lang/ja.inc.php index b74cfefe..198a8f85 100644 --- a/adminer/lang/ja.inc.php +++ b/adminer/lang/ja.inc.php @@ -2,7 +2,7 @@ $translations = array( 'Login' => 'ログイン', 'Logout successful.' => 'ログアウト', - 'Invalid credentials.' => '不正なログイン', + 'Invalid server or credentials.' => null, 'Server' => 'サーバ', 'Username' => 'ユーザ名', 'Password' => 'パスワード', diff --git a/adminer/lang/ka.inc.php b/adminer/lang/ka.inc.php index b30428f3..5c916445 100644 --- a/adminer/lang/ka.inc.php +++ b/adminer/lang/ka.inc.php @@ -2,7 +2,7 @@ $translations = array( 'Login' => 'შესვლა', 'Logout successful.' => 'გამოხვედით სისტემიდან.', - 'Invalid credentials.' => 'არასწორი მომხმარებელი ან პაროლი.', + 'Invalid server or credentials.' => null, 'Server' => 'სერვერი', 'Username' => 'მომხმარებელი', 'Password' => 'პაროლი', diff --git a/adminer/lang/ko.inc.php b/adminer/lang/ko.inc.php index cf2592f1..809b64cb 100644 --- a/adminer/lang/ko.inc.php +++ b/adminer/lang/ko.inc.php @@ -121,7 +121,7 @@ $translations = array( 'Indexes have been altered.' => '색인을 변경했습니다.', 'Indexes' => '색인', 'Insert' => '삽입', - 'Invalid credentials.' => '잘못된 로그인', + 'Invalid server or credentials.' => null, 'Invalid CSRF token. Send the form again.' => '잘못된 CSRF 토큰입니다. 다시 보내주십시오.', 'Invalid database.' => '잘못된 데이터베이스입니다.', 'Invalid schema.' => '잘못된 스키마입니다.', diff --git a/adminer/lang/lt.inc.php b/adminer/lang/lt.inc.php index fd65ef10..f9beab19 100644 --- a/adminer/lang/lt.inc.php +++ b/adminer/lang/lt.inc.php @@ -10,7 +10,7 @@ $translations = array( 'Logout' => 'Atsijungti', 'Logged as: %s' => 'Prisijungęs kaip: %s', 'Logout successful.' => 'Jūs atsijungėte nuo sistemos.', - 'Invalid credentials.' => 'Neteisingi prisijungimo duomenys.', + 'Invalid server or credentials.' => null, 'Language' => 'Kalba', 'Invalid CSRF token. Send the form again.' => 'Neteisingas CSRF tokenas. Bandykite siųsti formos duomenis dar kartą.', 'No extension' => 'Nėra plėtiio', diff --git a/adminer/lang/lv.inc.php b/adminer/lang/lv.inc.php index dc139297..e2196689 100644 --- a/adminer/lang/lv.inc.php +++ b/adminer/lang/lv.inc.php @@ -2,7 +2,7 @@ $translations = array( 'Login' => 'Ieiet', 'Logout successful.' => 'Jūs veiksmīgi izgājāt no sistēmas.', - 'Invalid credentials.' => 'Nepareizs lietotāja vārds vai parole.', + 'Invalid server or credentials.' => null, 'Server' => 'Serveris', 'Username' => 'Lietotājs', 'Password' => 'Parole', diff --git a/adminer/lang/ms.inc.php b/adminer/lang/ms.inc.php index b1e43455..5c136697 100644 --- a/adminer/lang/ms.inc.php +++ b/adminer/lang/ms.inc.php @@ -10,7 +10,7 @@ $translations = array( 'Logout' => 'Log keluar', 'Logged as: %s' => 'Log masuk sebagai: %s', 'Logout successful.' => 'Log keluar berjaya.', - 'Invalid credentials.' => 'Akses tidak sah.', + 'Invalid server or credentials.' => null, 'Too many unsuccessful logins, try again in %d minute(s).' => 'Terlalu banyak percubaan log masuk yang gagal, sila cuba lagi dalam masa %d minit.', 'Master password expired. Implement %s method to make it permanent.' => 'Kata laluan utama telah luput. Gunakan cara %s untuk mengekalkannya.', 'Language' => 'Bahasa', diff --git a/adminer/lang/nl.inc.php b/adminer/lang/nl.inc.php index 0685f4d5..bbb64e99 100644 --- a/adminer/lang/nl.inc.php +++ b/adminer/lang/nl.inc.php @@ -2,7 +2,7 @@ $translations = array( 'Login' => 'Aanmelden', 'Logout successful.' => 'Successvol afgemeld.', - 'Invalid credentials.' => 'Ongeldige gebruikersgegevens.', + 'Invalid server or credentials.' => null, 'Server' => 'Server', 'Username' => 'Gebruikersnaam', 'Password' => 'Wachtwoord', diff --git a/adminer/lang/no.inc.php b/adminer/lang/no.inc.php index c2e09e91..9eeb03a6 100644 --- a/adminer/lang/no.inc.php +++ b/adminer/lang/no.inc.php @@ -9,7 +9,7 @@ $translations = array( 'Logout' => 'Logg ut', 'Logged as: %s' => 'Logget inn som: %s', 'Logout successful.' => 'Utlogging vellykket.', - 'Invalid credentials.' => 'Ugylding innloggingsinformasjon.', + 'Invalid server or credentials.' => null, 'Master password expired. Implement %s method to make it permanent.' => 'Master-passord er utløpt. Implementer en metode for %s for å gjøre det permanent.', 'Language' => 'Språk', 'Invalid CSRF token. Send the form again.' => 'Ugylding CSRF-token - Send inn skjemaet igjen.', diff --git a/adminer/lang/pl.inc.php b/adminer/lang/pl.inc.php index c7b089ed..8afe0f83 100644 --- a/adminer/lang/pl.inc.php +++ b/adminer/lang/pl.inc.php @@ -10,7 +10,7 @@ $translations = array( 'Logout' => 'Wyloguj', 'Logged as: %s' => 'Zalogowany jako: %s', 'Logout successful.' => 'Wylogowano pomyślnie.', - 'Invalid credentials.' => 'Nieprawidłowe dane logowania.', + 'Invalid credentials.' => 'Nieprawidłowy serwer lub dane logowania.', 'Too many unsuccessful logins, try again in %d minute(s).' => array('Za dużo nieudanych prób logowania, spróbuj ponownie za %d minutę.', 'Za dużo nieudanych prób logowania, spróbuj ponownie za %d minuty.', 'Za dużo nieudanych prób logowania, spróbuj ponownie za %d minut.'), 'Master password expired. Implement %s method to make it permanent.' => 'Ważność hasła głównego wygasła. Zaimplementuj własną metodę %s, aby ustawić je na stałe.', 'Language' => 'Język', diff --git a/adminer/lang/pt-br.inc.php b/adminer/lang/pt-br.inc.php index f9193132..c4adb33d 100644 --- a/adminer/lang/pt-br.inc.php +++ b/adminer/lang/pt-br.inc.php @@ -2,7 +2,7 @@ $translations = array( 'Login' => 'Entrar', 'Logout successful.' => 'Saída bem sucedida.', - 'Invalid credentials.' => 'Identificação inválida.', + 'Invalid server or credentials.' => null, 'Server' => 'Servidor', 'Username' => 'Usuário', 'Password' => 'Senha', diff --git a/adminer/lang/pt.inc.php b/adminer/lang/pt.inc.php index 9e702986..481df152 100644 --- a/adminer/lang/pt.inc.php +++ b/adminer/lang/pt.inc.php @@ -2,7 +2,7 @@ $translations = array( 'Login' => 'Entrar', 'Logout successful.' => 'Sessão terminada com sucesso.', - 'Invalid credentials.' => 'Identificação inválida.', + 'Invalid server or credentials.' => null, 'Server' => 'Servidor', 'Username' => 'Nome de utilizador', 'Password' => 'Senha', diff --git a/adminer/lang/ro.inc.php b/adminer/lang/ro.inc.php index bb2b74b9..91cd1ef6 100644 --- a/adminer/lang/ro.inc.php +++ b/adminer/lang/ro.inc.php @@ -2,7 +2,7 @@ $translations = array( 'Login' => 'Intră', 'Logout successful.' => 'Ați ieșit cu succes.', - 'Invalid credentials.' => 'Numele de utilizator sau parola este greșită.', + 'Invalid server or credentials.' => null, 'Server' => 'Server', 'Username' => 'Nume de utilizator', 'Password' => 'Parola', diff --git a/adminer/lang/ru.inc.php b/adminer/lang/ru.inc.php index 99b355e1..18cbb8bf 100644 --- a/adminer/lang/ru.inc.php +++ b/adminer/lang/ru.inc.php @@ -2,7 +2,7 @@ $translations = array( 'Login' => 'Войти', 'Logout successful.' => 'Вы успешно покинули систему.', - 'Invalid credentials.' => 'Неправильное имя пользователя или пароль.', + 'Invalid server or credentials.' => null, 'Server' => 'Сервер', 'Username' => 'Имя пользователя', 'Password' => 'Пароль', diff --git a/adminer/lang/sk.inc.php b/adminer/lang/sk.inc.php index c0463e0d..15e0d3a6 100644 --- a/adminer/lang/sk.inc.php +++ b/adminer/lang/sk.inc.php @@ -2,7 +2,7 @@ $translations = array( 'Login' => 'Prihlásiť sa', 'Logout successful.' => 'Odhlásenie prebehlo v poriadku.', - 'Invalid credentials.' => 'Neplatné prihlasovacie údaje.', + 'Invalid server or credentials.' => 'Neplatný server alebo prihlasovacie údaje.', 'Server' => 'Server', 'Username' => 'Používateľ', 'Password' => 'Heslo', @@ -70,7 +70,7 @@ $translations = array( 'Unable to select the table' => 'Tabuľku sa nepodarilo vypísať', 'Invalid CSRF token. Send the form again.' => 'Neplatný token CSRF. Odošlite formulár znova.', 'Comment' => 'Komentár', - 'Default values' => 'Východzie hodnoty', + 'Default values' => 'Predvolené hodnoty', '%d byte(s)' => array('%d bajt', '%d bajty', '%d bajtov'), 'No commands to execute.' => 'Žiadne príkazy na vykonanie.', 'Unable to upload a file.' => 'Súbor sa nepodarilo nahrať.', @@ -94,8 +94,8 @@ $translations = array( 'Add column' => 'Pridať stĺpec', 'Alter' => 'Zmeniť', 'Add foreign key' => 'Pridať cudzí kľúč', - 'ON DELETE' => 'ON DELETE', - 'ON UPDATE' => 'ON UPDATE', + 'ON DELETE' => 'Pri zmazaní', + 'ON UPDATE' => 'Pri aktualizácii', 'Index Type' => 'Typ indexu', 'Column (length)' => 'Stĺpec (dĺžka)', 'View has been dropped.' => 'Pohľad bol odstránený.', @@ -266,43 +266,43 @@ $translations = array( 'Edit all' => 'Upraviť všetko', 'HH:MM:SS' => 'HH:MM:SS', - 'Drop %s?' => null, - 'Tables have been optimized.' => null, - 'as a regular expression' => null, - 'Materialized view' => null, - 'Vacuum' => null, - 'Selected' => null, - 'overwrite' => null, - 'DB' => null, - 'File must be in UTF-8 encoding.' => null, - 'Modify' => null, - 'Load more data' => null, - 'Loading' => null, - 'Copy to clipboard' => null, - 'ATTACH queries are not supported.' => null, - 'Warnings' => null, - '%d / ' => array(), - 'Limit rows' => null, - 'Adminer does not support accessing a database without a password, more information.' => null, - 'Default value' => null, - 'Full table scan' => null, - 'Too many unsuccessful logins, try again in %d minute(s).' => array(), - 'Master password expired. Implement %s method to make it permanent.' => null, - 'The action will be performed after successful login with the same credentials.' => null, - 'Connecting to privileged ports is not allowed.' => null, - 'There is a space in the input password which might be the cause.' => null, - 'If you did not send this request from Adminer then close this page.' => null, - 'You can upload a big SQL file via FTP and import it from server.' => null, - 'Size' => null, - 'Compute' => null, - 'You are offline.' => null, - 'You have no privileges to update this table.' => null, - 'Saving' => null, - 'Unknown error.' => null, - 'Database does not support password.' => null, - 'Disable %s or enable %s or %s extensions.' => null, - 'yes' => null, - 'no' => null, + 'Drop %s?' => 'Odstrániť %s?', + 'Tables have been optimized.' => 'Tabuľky boli optimalizované.', + 'as a regular expression' => 'ako regulárny výraz', + 'Materialized view' => 'Materializovaný pohľad', + 'Vacuum' => 'Vyčistiť', + 'Selected' => 'Označené', + 'overwrite' => 'prepísať', + 'DB' => 'DB', + 'File must be in UTF-8 encoding.' => 'Súbor musí byť v kódovaní UTF-8.', + 'Modify' => 'Zmeniť', + 'Load more data' => 'Nahráť ďalšie dáta', + 'Loading' => 'Nahráva sa', + 'Copy to clipboard' => 'Kopírovať do schránky', + 'ATTACH queries are not supported.' => 'Dotazy ATTACH nie sú podporované.', + 'Warnings' => 'Varovania', + '%d / ' => '%d / ', + 'Limit rows' => 'Limit riadkov', + 'Adminer does not support accessing a database without a password, more information.' => 'Adminer nepodporuje prístup k databáze bez hesla, viac informácií.', + 'Default value' => 'Predvolená hodnota', + 'Full table scan' => 'Prechod celej tabuľky', + 'Too many unsuccessful logins, try again in %d minute(s).' => array('Príliš veľa pokusov o prihlásenie, skúste to znova za %d minutu.', 'Príliš veľa pokusov o prihlásenie, skúste to znova za %d minuty.', 'Príliš veľa pokusov o prihlásenie, skúste to znova za %d minút.'), + 'Master password expired. Implement %s method to make it permanent.' => 'Platnosť hlavného hesla vypršala. Implementujte metodu %s, aby platilo natrvalo.', + 'The action will be performed after successful login with the same credentials.' => 'Akcia sa vykoná po úspešnom prihlásení s rovnakými prihlasovacími údajmi.', + 'Connecting to privileged ports is not allowed.' => 'Pripojenie k privilegovaným portom nie je povolené.', + 'There is a space in the input password which might be the cause.' => 'V zadanom hesle je medzera, ktorá môže byť príčinou.', + 'If you did not send this request from Adminer then close this page.' => 'Pokiaľ ste tento požiadavok neodoslali z Adminera, zatvorte túto stránku.', + 'You can upload a big SQL file via FTP and import it from server.' => 'Veľký SQL soubor môžete nahrať pomocou FTP a importovať ho zo servera.', + 'Size' => 'Veľkosť', + 'Compute' => 'Spočítať', + 'You are offline.' => 'Ste offline.', + 'You have no privileges to update this table.' => 'Nemáte oprávnenie na aktualizáciu tejto tabuľky.', + 'Saving' => 'Ukladá sa', + 'Unknown error.' => 'Neznáma chyba.', + 'Database does not support password.' => 'Databáza nepodporuje heslo.', + 'Disable %s or enable %s or %s extensions.' => 'Zakážte %s alebo povoľte rozšírenie %s alebo %s.', + 'yes' => 'áno', + 'no' => 'nie', // 'Thanks for using Adminer, consider donating.' => null, ); diff --git a/adminer/lang/sl.inc.php b/adminer/lang/sl.inc.php index 4c88e4fa..2e3691e2 100644 --- a/adminer/lang/sl.inc.php +++ b/adminer/lang/sl.inc.php @@ -10,7 +10,7 @@ $translations = array( 'Logout' => 'Odjavi se', 'Logged as: %s' => 'Prijavljen kot: %s', 'Logout successful.' => 'Prijava uspešna.', - 'Invalid credentials.' => 'Neveljavne pravice.', + 'Invalid server or credentials.' => 'Neveljaven strežnik ali pravice.', 'Language' => 'Jezik', 'Invalid CSRF token. Send the form again.' => 'Neveljaven token CSRF. Pošljite formular še enkrat.', 'No extension' => 'Brez dodatkov', diff --git a/adminer/lang/sr.inc.php b/adminer/lang/sr.inc.php index f20094d1..22a6d417 100644 --- a/adminer/lang/sr.inc.php +++ b/adminer/lang/sr.inc.php @@ -10,7 +10,7 @@ $translations = array( 'Logout' => 'Одјава', 'Logged as: %s' => 'Пријави се као: %s', 'Logout successful.' => 'Успешна одјава.', - 'Invalid credentials.' => 'Неважеће дозволе.', + 'Invalid server or credentials.' => null, 'Language' => 'Језик', 'Invalid CSRF token. Send the form again.' => 'Неважећи CSRF код. Проследите поново форму.', 'No extension' => 'Без додатака', diff --git a/adminer/lang/sv.inc.php b/adminer/lang/sv.inc.php index 7231b5bc..0b360ee6 100644 --- a/adminer/lang/sv.inc.php +++ b/adminer/lang/sv.inc.php @@ -10,7 +10,7 @@ $translations = array( 'Logout' => 'Logga ut', 'Logged as: %s' => 'Inloggad som: %s', 'Logout successful.' => 'Du är nu utloggad.', - 'Invalid credentials.' => 'Ogiltiga inloggningsuppgifter.', + 'Invalid server or credentials.' => null, 'There is a space in the input password which might be the cause.' => 'Det finns ett mellanslag i lösenordet, vilket kan vara anledningen.', 'Adminer does not support accessing a database without a password, more information.' => 'Adminer tillåter inte att ansluta till en databas utan lösenord. Mer information.', 'Database does not support password.' => 'Databasen stödjer inte lösenord.', diff --git a/adminer/lang/ta.inc.php b/adminer/lang/ta.inc.php index 06dd515d..45c74466 100644 --- a/adminer/lang/ta.inc.php +++ b/adminer/lang/ta.inc.php @@ -2,7 +2,7 @@ $translations = array( 'Login' => 'நுழை', 'Logout successful.' => 'வெற்றிக‌ர‌மாய் வெளியேறியாயிற்று.', - 'Invalid credentials.' => 'ச‌ரியான‌ விப‌ர‌ங்க‌ள் இல்லை.', + 'Invalid server or credentials.' => null, 'Server' => 'வ‌ழ‌ங்கி (Server)', 'Username' => 'ப‌ய‌னாள‌ர் (User)', 'Password' => 'க‌ட‌வுச்சொல்', diff --git a/adminer/lang/th.inc.php b/adminer/lang/th.inc.php index 0c0dd808..e6591b65 100644 --- a/adminer/lang/th.inc.php +++ b/adminer/lang/th.inc.php @@ -2,7 +2,7 @@ $translations = array( 'Login' => 'เข้าสู่ระบบ', 'Logout successful.' => 'ออกจากระบบเรียบร้อยแล้ว.', - 'Invalid credentials.' => 'ข้อมูลไม่ถูกต้อง.', + 'Invalid server or credentials.' => null, 'Server' => 'เซอเวอร์', 'Username' => 'ชื่อผู้ใช้งาน', 'Password' => 'รหัสผ่าน', diff --git a/adminer/lang/tr.inc.php b/adminer/lang/tr.inc.php index f5d2669c..b37b6ba7 100644 --- a/adminer/lang/tr.inc.php +++ b/adminer/lang/tr.inc.php @@ -10,7 +10,7 @@ $translations = array( 'Logout' => 'Çıkış', 'Logged as: %s' => '%s olarak giriş yapıldı.', 'Logout successful.' => 'Oturum başarıyla sonlandı.', - 'Invalid credentials.' => 'Geçersiz kimlik bilgileri.', + 'Invalid server or credentials.' => null, 'Too many unsuccessful logins, try again in %d minute(s).' => array('Çok fazla oturum açma denemesi yapıldı.', '%d Dakika sonra tekrar deneyiniz.'), 'Master password expired. Implement %s method to make it permanent.' => 'Ana şifrenin süresi doldu. Kalıcı olması için %s medodunu kullanın.', 'Language' => 'Dil', diff --git a/adminer/lang/uk.inc.php b/adminer/lang/uk.inc.php index a2a1efe5..335832fd 100644 --- a/adminer/lang/uk.inc.php +++ b/adminer/lang/uk.inc.php @@ -10,7 +10,7 @@ $translations = array( 'Logout' => 'Вийти', 'Logged as: %s' => 'Ви увійшли як: %s', 'Logout successful.' => 'Ви вдало вийшли з системи.', - 'Invalid credentials.' => 'Неправильні дані входу.', + 'Invalid server or credentials.' => null, 'Language' => 'Мова', 'Invalid CSRF token. Send the form again.' => 'Недійсний CSRF токен. Надішліть форму ще раз.', 'No extension' => 'Нема розширень', diff --git a/adminer/lang/vi.inc.php b/adminer/lang/vi.inc.php index 8befb6bd..ab395c96 100644 --- a/adminer/lang/vi.inc.php +++ b/adminer/lang/vi.inc.php @@ -10,7 +10,7 @@ $translations = array( 'Logout' => 'Thoát', 'Logged as: %s' => 'Vào dưới tên: %s', 'Logout successful.' => 'Đã thoát xong.', - 'Invalid credentials.' => 'Tài khoản sai.', + 'Invalid server or credentials.' => null, 'Too many unsuccessful logins, try again in %d minute(s).' => 'Bạn gõ sai tài khoản quá nhiều lần, hãy thử lại sau %d phút nữa.', 'Master password expired. Implement %s method to make it permanent.' => 'Mật khẩu đã hết hạn. Thử cách làm để giữ cố định.', 'Language' => 'Ngôn ngữ', diff --git a/adminer/lang/xx.inc.php b/adminer/lang/xx.inc.php index a955fdbf..76bcc6f4 100644 --- a/adminer/lang/xx.inc.php +++ b/adminer/lang/xx.inc.php @@ -10,7 +10,7 @@ $translations = array( 'Logout' => 'Xx', 'Logged as: %s' => 'Xx: %s', 'Logout successful.' => 'Xx.', - 'Invalid credentials.' => 'Xx.', + 'Invalid server or credentials.' => 'Xx.', 'There is a space in the input password which might be the cause.' => 'Xx.', 'Adminer does not support accessing a database without a password, more information.' => 'Xx, xx.', 'Database does not support password.' => 'Xx.', diff --git a/adminer/lang/zh-tw.inc.php b/adminer/lang/zh-tw.inc.php index c7cbf580..01ebcda4 100644 --- a/adminer/lang/zh-tw.inc.php +++ b/adminer/lang/zh-tw.inc.php @@ -10,7 +10,7 @@ $translations = array( 'Logout' => '登出', 'Logged as: %s' => '登錄為: %s', 'Logout successful.' => '成功登出。', - 'Invalid credentials.' => '無效的憑證。', + 'Invalid server or credentials.' => null, 'There is a space in the input password which might be the cause.' => '您輸入的密碼中有一個空格,這可能是導致問題的原因。', 'Adminer does not support accessing a database without a password, more information.' => 'Adminer預設不支援訪問沒有密碼的資料庫,詳情見這裡.', 'Database does not support password.' => '資料庫不支援密碼。', diff --git a/adminer/lang/zh.inc.php b/adminer/lang/zh.inc.php index b66498f4..7892a1a3 100644 --- a/adminer/lang/zh.inc.php +++ b/adminer/lang/zh.inc.php @@ -10,7 +10,7 @@ $translations = array( 'Logout' => '登出', 'Logged as: %s' => '登录用户:%s', 'Logout successful.' => '成功登出。', - 'Invalid credentials.' => '无效凭据。', + 'Invalid server or credentials.' => null, 'There is a space in the input password which might be the cause.' => '您输入的密码中有一个空格,这可能是导致问题的原因。', 'Adminer does not support accessing a database without a password, more information.' => 'Adminer默认不支持访问没有密码的数据库,详情见这里.', 'Database does not support password.' => '数据库不支持密码。', diff --git a/adminer/static/favicon.ico b/adminer/static/favicon.ico index f59ca5cf..90866a8d 100644 Binary files a/adminer/static/favicon.ico and b/adminer/static/favicon.ico differ diff --git a/docs/assets/favicon.png b/docs/assets/favicon.png index c1b6febd..3e14723c 100644 Binary files a/docs/assets/favicon.png and b/docs/assets/favicon.png differ diff --git a/docs/index.md b/docs/index.md index 29458af4..75fc2efa 100644 --- a/docs/index.md +++ b/docs/index.md @@ -13,7 +13,8 @@ It is available for download as a single self-contained PHP file, making it easy to deploy anywhere.

-[Download](https://github.com/adminerevo/adminerevo){ .md-button .md-button--secondary target=\_blank } +[Download](https://download.adminerevo.org){ .md-button .md-button--primary target=\_blank } +[View Source](https://github.com/adminerevo/adminerevo){ .md-button .md-button--secondary target=\_blank }
diff --git a/plugins/drivers/clickhouse.php b/plugins/drivers/clickhouse.php index 60bb0b45..ff9eb688 100644 --- a/plugins/drivers/clickhouse.php +++ b/plugins/drivers/clickhouse.php @@ -8,56 +8,78 @@ if (isset($_GET["clickhouse"])) { var $extension = "JSON", $server_info, $errno, $_result, $error, $_url; var $_db = 'default'; + /** + * @param string $db + * @param string $query + * @return Min_Result|bool + */ function rootQuery($db, $query) { @ini_set('track_errors', 1); // @ - may be disabled $file = @file_get_contents("$this->_url/?database=$db", false, stream_context_create(array('http' => array( 'method' => 'POST', 'content' => $this->isQuerySelectLike($query) ? "$query FORMAT JSONCompact" : $query, 'header' => 'Content-type: application/x-www-form-urlencoded', - 'ignore_errors' => 1, // available since PHP 5.2.10 + 'ignore_errors' => 1, + 'follow_location' => 0, + 'max_redirects' => 0, )))); if ($file === false) { - $this->error = $php_errormsg; - return $file; - } - if (!preg_match('~^HTTP/[0-9.]+ 2~i', $http_response_header[0])) { - $this->error = lang('Invalid credentials.') . " $http_response_header[0]"; + $this->error = lang('Invalid server or credentials.'); return false; } - $return = json_decode($file, true); - if ($return === null) { - if (!$this->isQuerySelectLike($query) && $file === '') { - return true; - } - $this->errno = json_last_error(); - if (function_exists('json_last_error_msg')) { - $this->error = json_last_error_msg(); - } else { - $constants = get_defined_constants(true); - foreach ($constants['json'] as $name => $value) { - if ($value == $this->errno && preg_match('~^JSON_ERROR_~', $name)) { - $this->error = $name; - break; - } + if (!preg_match('~^HTTP/[0-9.]+ 2~i', $http_response_header[0])) { + foreach ($http_response_header as $header) { + if (preg_match('~^X-ClickHouse-Exception-Code:~i', $header)) { + $this->error = preg_replace('~\(version [^(]+\(.+$~', '', $file); + return false; } } + + $this->error = lang('Invalid server or credentials.'); + return false; } - return new Min_Result($return); + + if (!$this->isQuerySelectLike($query) && $file === '') { + return true; + } + + $return = json_decode($file, true); + if ($return === null) { + $this->error = lang('Invalid server or credentials.'); + return false; + } + + if (!isset($return['rows']) || !isset($return['data']) || !isset($return['meta'])) { + $this->error = lang('Invalid server or credentials.'); + return false; + } + + return new Min_Result($return['rows'], $return['data'], $return['meta']); } function isQuerySelectLike($query) { return (bool) preg_match('~^(select|show)~i', $query); } + /** + * @param string $query + * @return bool|Min_Result + */ function query($query) { return $this->rootQuery($this->_db, $query); } + /** + * @param string $server + * @param string $username + * @param string $password + * @return bool + */ function connect($server, $username, $password) { - preg_match('~^(https?://)?(.*)~', $server, $match); - $this->_url = ($match[1] ? $match[1] : "http://") . "$username:$password@$match[2]"; + $this->_url = build_http_url($server, $username, $password, "localhost", 8123); + $return = $this->query('SELECT 1'); return (bool) $return; } @@ -92,11 +114,17 @@ if (isset($_GET["clickhouse"])) { class Min_Result { var $num_rows, $_rows, $columns, $meta, $_offset = 0; - function __construct($result) { - $this->num_rows = $result['rows']; - $this->_rows = $result['data']; - $this->meta = $result['meta']; - $this->columns = array_column($this->meta, 'name'); + /** + * @param int $rows + * @param array[] $data + * @param array[] $meta + */ + function __construct($rows, array $data, array $meta) { + $this->num_rows = $rows; + $this->_rows = $data; + $this->meta = $meta; + $this->columns = array_column($meta, 'name'); + reset($this->_rows); } diff --git a/plugins/drivers/simpledb.php b/plugins/drivers/simpledb.php index 9fafe884..5decfd5b 100644 --- a/plugins/drivers/simpledb.php +++ b/plugins/drivers/simpledb.php @@ -6,13 +6,49 @@ if (isset($_GET["simpledb"])) { if (class_exists('SimpleXMLElement') && ini_bool('allow_url_fopen')) { class Min_DB { - var $extension = "SimpleXML", $server_info = '2009-04-15', $error, $timeout, $next, $affected_rows, $_result; + var $extension = "SimpleXML", $server_info = '2009-04-15', $error, $timeout, $next, $affected_rows, $_url, $_result; + + /** + * @param string $server + * @param string $password + * @return bool + */ + function connect($server, $password) { + if ($server == '' || $password == '') { + $this->error = lang('Invalid server or credentials.'); + return false; + } + + $parts = parse_url($server); + + if (!$parts || !isset($parts['host']) || !preg_match('~^sdb\.([a-z0-9-]+\.)?amazonaws\.com$~i', $parts['host']) || + isset($parts['port']) + ) { + $this->error = lang('Invalid server or credentials.'); + return false; + } + + $this->_url = build_http_url($server, '', '', ''); + + return (bool) $this->workaroundLoginRequest('ListDomains', ['MaxNumberOfDomains' => 1]); + } + + // FIXME: This is so wrong :-( Move sdb_request to Min_DB! + private function workaroundLoginRequest($action, $params = array()) { + global $connection; + + $connection = $this; + $result = sdb_request($action, $params); + $connection = null; + + return $result; + } function select_db($database) { return ($database == "domain"); } - function query($query, $unbuffered = false) { + function query($query) { $params = array('SelectExpression' => $query, 'ConsistentRead' => 'true'); if ($this->next) { $params['NextToken'] = $this->next; @@ -248,11 +284,15 @@ if (isset($_GET["simpledb"])) { function connect() { global $adminer; - list(, , $password) = $adminer->credentials(); - if ($password != "") { - return lang('Database does not support password.'); + + $connection = new Min_DB; + + list($server, , $password) = $adminer->credentials(); + if ($connection->connect($server, $password)) { + return $connection; } - return new Min_DB; + + return $connection->error; } function support($feature) { @@ -422,13 +462,16 @@ if (isset($_GET["simpledb"])) { $query = str_replace('%7E', '~', substr($query, 1)); $query .= "&Signature=" . urlencode(base64_encode(hmac('sha1', "POST\n" . preg_replace('~^https?://~', '', $host) . "\n/\n$query", $secret, true))); @ini_set('track_errors', 1); // @ - may be disabled - $file = @file_get_contents((preg_match('~^https?://~', $host) ? $host : "http://$host"), false, stream_context_create(array('http' => array( + + $file = @file_get_contents($connection->_url, false, stream_context_create(array('http' => array( 'method' => 'POST', // may not fit in URL with GET 'content' => $query, - 'ignore_errors' => 1, // available since PHP 5.2.10 + 'ignore_errors' => 1, + 'follow_location' => 0, + 'max_redirects' => 0, )))); if (!$file) { - $connection->error = $php_errormsg; + $connection->error = error_get_last()['message']; return false; } libxml_use_internal_errors(true);