2007-07-02 05:51:26 +00:00
< ? php
2025-03-05 11:28:53 +01:00
namespace Adminer ;
2010-04-21 12:01:32 +00:00
$connection = '' ;
2013-10-24 19:10:50 -07:00
$has_token = $_SESSION [ " token " ];
if ( ! $has_token ) {
2010-04-21 12:01:32 +00:00
$_SESSION [ " token " ] = rand ( 1 , 1e6 ); // defense against cross-site request forgery
}
2013-10-24 19:10:50 -07:00
$token = get_token (); ///< @var string CSRF protection
2010-04-21 12:01:32 +00:00
2010-05-07 16:31:14 +02:00
$permanent = array ();
if ( $_COOKIE [ " adminer_permanent " ]) {
foreach ( explode ( " " , $_COOKIE [ " adminer_permanent " ]) as $val ) {
list ( $key ) = explode ( " : " , $val );
$permanent [ $key ] = $val ;
}
}
2014-03-21 22:47:34 -07:00
function add_invalid_login () {
global $adminer ;
2025-03-16 20:49:52 +01:00
$base = get_temp_dir () . " /adminer.invalid " ;
// adminer.invalid may not be writable by us, try the files with random suffixes
foreach ( glob ( " $base * " ) ? : array ( $base ) as $filename ) {
$fp = file_open_lock ( $filename );
if ( $fp ) {
break ;
}
}
if ( ! $fp ) {
$fp = file_open_lock ( " $base - " . rand_string ());
}
2018-01-24 12:04:53 +01:00
if ( ! $fp ) {
return ;
2014-03-21 22:47:34 -07:00
}
$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 ] ++ ;
2018-01-24 12:04:53 +01:00
file_write_unlock ( $fp , serialize ( $invalids ));
2014-03-21 22:47:34 -07:00
}
2018-01-16 10:56:35 +01:00
function check_invalid_login () {
global $adminer ;
2025-03-16 20:49:52 +01:00
$invalids = array ();
foreach ( glob ( get_temp_dir () . " /adminer.invalid* " ) as $filename ) {
$fp = file_open_lock ( $filename );
if ( $fp ) {
$invalids = unserialize ( stream_get_contents ( $fp ));
file_unlock ( $fp );
break ;
}
}
2025-03-26 07:55:30 +01:00
$invalid = idx ( $invalids , $adminer -> bruteForceKey (), array ());
$next_attempt = ( $invalid [ 1 ] > 29 ? $invalid [ 0 ] - time () : 0 ); // allow 30 invalid attempts
2014-03-21 22:47:34 -07:00
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 )));
}
2018-01-16 10:56:35 +01:00
}
$auth = $_POST [ " auth " ];
if ( $auth ) {
2009-08-30 22:21:36 +00:00
session_regenerate_id (); // defense against session fixation
2014-04-21 09:45:15 -07:00
$vendor = $auth [ " driver " ];
2013-08-10 19:11:35 -07:00
$server = $auth [ " server " ];
$username = $auth [ " username " ];
2014-02-21 08:53:58 -08:00
$password = ( string ) $auth [ " password " ];
2013-08-10 19:11:35 -07:00
$db = $auth [ " db " ];
2014-04-21 09:45:15 -07:00
set_password ( $vendor , $server , $username , $password );
$_SESSION [ " db " ][ $vendor ][ $server ][ $username ][ $db ] = true ;
2013-10-24 22:40:05 -07:00
if ( $auth [ " permanent " ]) {
2025-03-16 18:05:52 +01:00
$key = implode ( " - " , array_map ( 'base64_encode' , array ( $vendor , $server , $username , $db )));
2013-06-11 11:02:17 +02:00
$private = $adminer -> permanentLogin ( true );
2013-08-10 19:11:35 -07:00
$permanent [ $key ] = " $key : " . base64_encode ( $private ? encrypt_string ( $password , $private ) : " " );
2010-05-07 16:31:14 +02:00
cookie ( " adminer_permanent " , implode ( " " , $permanent ));
2009-12-18 17:39:48 +00:00
}
2025-03-05 15:01:05 +01:00
if (
count ( $_POST ) == 1 // 1 - auth
2014-04-21 09:45:15 -07:00
|| DRIVER != $vendor
2013-08-10 19:11:35 -07:00
|| SERVER != $server
|| $_GET [ " username " ] !== $username // "0" == "00"
|| DB != $db
2010-04-21 12:01:32 +00:00
) {
2014-04-21 09:45:15 -07:00
redirect ( auth_url ( $vendor , $server , $username , $db ));
2009-08-30 22:21:36 +00:00
}
2025-02-21 13:53:18 +01:00
2021-02-07 14:23:41 +01:00
} elseif ( $_POST [ " logout " ] && ( ! $has_token || verify_token ())) {
foreach ( array ( " pwds " , " db " , " dbs " , " queries " ) as $key ) {
set_session ( $key , null );
2008-04-10 15:10:10 +00:00
}
2021-02-07 14:23:41 +01:00
unset_permanent ();
redirect ( substr ( preg_replace ( '~\b(username|db|ns)=[^&]*&~' , '' , ME ), 0 , - 1 ), lang ( 'Logout successful.' ) . ' ' . lang ( 'Thanks for using Adminer, consider <a href="https://www.adminer.org/en/donation/">donating</a>.' ));
2025-02-21 13:53:18 +01:00
2010-10-15 10:58:08 +02:00
} elseif ( $permanent && ! $_SESSION [ " pwds " ]) {
2010-05-07 16:31:14 +02:00
session_regenerate_id ();
2013-06-11 11:02:17 +02:00
$private = $adminer -> permanentLogin ();
2010-05-07 16:31:14 +02:00
foreach ( $permanent as $key => $val ) {
list (, $cipher ) = explode ( " : " , $val );
2013-07-05 08:28:37 -07:00
list ( $vendor , $server , $username , $db ) = array_map ( 'base64_decode' , explode ( " - " , $key ));
2013-08-10 19:06:21 -07:00
set_password ( $vendor , $server , $username , decrypt_string ( base64_decode ( $cipher ), $private ));
2013-07-05 08:28:37 -07:00
$_SESSION [ " db " ][ $vendor ][ $server ][ $username ][ $db ] = true ;
2009-12-18 17:39:48 +00:00
}
}
2012-09-08 20:54:02 -07:00
function unset_permanent () {
global $permanent ;
2012-09-08 21:29:16 -07:00
foreach ( $permanent as $key => $val ) {
2013-07-05 08:28:37 -07:00
list ( $vendor , $server , $username , $db ) = array_map ( 'base64_decode' , explode ( " - " , $key ));
if ( $vendor == DRIVER && $server == SERVER && $username == $_GET [ " username " ] && $db == DB ) {
2012-09-08 21:29:16 -07:00
unset ( $permanent [ $key ]);
}
2012-09-08 20:54:02 -07:00
}
2012-09-08 21:29:16 -07:00
cookie ( " adminer_permanent " , implode ( " " , $permanent ));
2012-09-08 20:54:02 -07:00
}
2025-03-22 21:04:58 +01:00
/** Render an error message and a login form
2015-02-07 10:40:51 -08:00
* @ param string plain text
2025-03-25 15:14:19 +01:00
* @ return never
2015-02-07 10:40:51 -08:00
*/
2014-03-21 22:47:34 -07:00
function auth_error ( $error ) {
global $adminer , $has_token ;
2009-10-06 15:33:48 +00:00
$session_name = session_name ();
2014-09-13 12:03:13 -07:00
if ( isset ( $_GET [ " username " ])) {
header ( " HTTP/1.1 403 Forbidden " ); // 401 requires sending WWW-Authenticate header
2013-10-24 19:10:50 -07:00
if (( $_COOKIE [ $session_name ] || $_GET [ $session_name ]) && ! $has_token ) {
2010-04-21 12:01:32 +00:00
$error = lang ( 'Session expired, please login again.' );
} else {
2018-02-20 23:10:05 +01:00
restart_session ();
2014-03-21 22:47:34 -07:00
add_invalid_login ();
2013-08-10 19:06:21 -07:00
$password = get_password ();
2012-05-13 23:54:07 -07:00
if ( $password !== null ) {
2013-06-11 11:02:17 +02:00
if ( $password === false ) {
2021-02-08 16:06:22 +01:00
$error .= ( $error ? '<br>' : '' ) . lang ( 'Master password expired. <a href="https://www.adminer.org/en/extension/"%s>Implement</a> %s method to make it permanent.' , target_blank (), '<code>permanentLogin()</code>' );
2013-06-11 11:02:17 +02:00
}
2013-08-10 19:06:21 -07:00
set_password ( DRIVER , SERVER , $_GET [ " username " ], null );
2010-04-21 12:01:32 +00:00
}
2012-09-08 20:54:02 -07:00
unset_permanent ();
2010-04-21 12:01:32 +00:00
}
}
2014-09-13 12:03:13 -07:00
if ( ! $_COOKIE [ $session_name ] && $_GET [ $session_name ] && ini_bool ( " session.use_only_cookies " )) {
$error = lang ( 'Session support must be enabled.' );
}
2013-08-11 09:26:18 -07:00
$params = session_get_cookie_params ();
2025-03-06 18:12:22 +01:00
cookie ( " adminer_key " , ( $_COOKIE [ " adminer_key " ] ? : rand_string ()), $params [ " lifetime " ]);
2010-04-21 12:01:32 +00:00
page_header ( lang ( 'Login' ), $error , null );
2012-05-14 02:16:10 -07:00
echo " <form action='' method='post'> \n " ;
2009-12-18 17:49:21 +00:00
echo " <div> " ;
2018-02-08 16:49:56 +01:00
if ( hidden_fields ( $_POST , array ( " auth " ))) { // expired session
echo " <p class='message'> " . lang ( 'The action will be performed after successful login with the same credentials.' ) . " \n " ;
}
2009-12-18 17:49:21 +00:00
echo " </div> \n " ;
2018-02-08 16:49:56 +01:00
$adminer -> loginForm ();
2009-12-18 17:49:21 +00:00
echo " </form> \n " ;
2007-07-02 05:51:26 +00:00
page_footer ( " auth " );
2014-03-21 22:47:34 -07:00
exit ;
2007-07-23 11:57:26 +00:00
}
2025-03-05 14:12:42 +01:00
if ( isset ( $_GET [ " username " ]) && ! class_exists ( 'Adminer\Db' )) {
2018-02-20 23:10:05 +01:00
unset ( $_SESSION [ " pwds " ][ DRIVER ]);
unset_permanent ();
2025-03-06 14:27:58 +01:00
page_header ( lang ( 'No extension' ), lang ( 'None of the supported PHP extensions (%s) are available.' , implode ( " , " , Driver :: $possibleDrivers )), false );
2018-02-20 23:10:05 +01:00
page_footer ( " auth " );
exit ;
}
2018-02-20 23:14:36 +01:00
stop_session ( true );
2018-02-20 23:10:05 +01:00
2019-05-14 09:07:51 +02:00
if ( isset ( $_GET [ " username " ]) && is_string ( get_password ())) {
2018-01-16 11:18:32 +01:00
list ( $host , $port ) = explode ( " : " , SERVER , 2 );
2021-01-12 21:32:04 +01:00
if ( preg_match ( '~^\s*([-+]?\d+)~' , $port , $match ) && ( $match [ 1 ] < 1024 || $match [ 1 ] > 65535 )) { // is_numeric('80#') would still connect to port 80
2018-01-24 18:21:18 +01:00
auth_error ( lang ( 'Connecting to privileged ports is not allowed.' ));
2018-01-16 11:18:32 +01:00
}
2018-01-16 10:56:35 +01:00
check_invalid_login ();
2025-03-07 12:03:29 +01:00
$connection = connect ( $adminer -> credentials ());
2025-03-08 05:37:01 +01:00
if ( is_object ( $connection )) {
$driver = new Driver ( $connection );
if ( $adminer -> operators === null ) {
$adminer -> operators = $driver -> operators ;
}
2025-03-25 06:15:09 +01:00
if ( $connection -> flavor ) {
2025-03-18 16:30:23 +01:00
save_settings ( array ( " vendor- " . DRIVER . " - " . SERVER => $drivers [ DRIVER ]));
2025-03-16 18:53:49 +01:00
}
2025-03-06 13:48:13 +01:00
}
2008-08-27 16:43:30 +00:00
}
2013-05-01 18:28:04 -07:00
2018-02-07 11:37:53 +01:00
$login = null ;
2016-06-01 09:57:17 -07:00
if ( ! is_object ( $connection ) || ( $login = $adminer -> login ( $_GET [ " username " ], get_password ())) !== true ) {
2025-02-21 14:29:22 +01:00
$error = ( is_string ( $connection ) ? nl_br ( h ( $connection )) : ( is_string ( $login ) ? $login : lang ( 'Invalid credentials.' )));
2018-09-13 16:08:57 +02:00
auth_error ( $error . ( preg_match ( '~^ | $~' , get_password ()) ? '<br>' . lang ( 'There is a space in the input password which might be the cause.' ) : '' ));
2007-07-02 05:51:26 +00:00
}
2009-11-20 17:29:35 +00:00
2021-02-07 14:23:41 +01:00
if ( $_POST [ " logout " ] && $has_token && ! verify_token ()) {
page_header ( lang ( 'Logout' ), lang ( 'Invalid CSRF token. Send the form again.' ));
page_footer ( " db " );
exit ;
}
2012-05-14 00:08:32 -07:00
if ( $auth && $_POST [ " token " ]) {
2010-04-21 12:01:32 +00:00
$_POST [ " token " ] = $token ; // reset token after explicit login
2010-02-24 11:59:25 +00:00
}
2013-04-01 18:45:26 -07:00
$error = '' ; ///< @var string
if ( $_POST ) {
2013-10-24 19:10:50 -07:00
if ( ! verify_token ()) {
2013-04-01 18:45:26 -07:00
$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 ' " )
2014-10-28 09:24:13 -07:00
: lang ( 'Invalid CSRF token. Send the form again.' ) . ' ' . lang ( 'If you did not send this request from Adminer then close this page.' )
2013-04-01 18:45:26 -07:00
);
}
2025-02-21 13:53:18 +01:00
2013-04-01 18:45:26 -07: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 06:12:13 -07:00
if ( isset ( $_GET [ " sql " ])) {
$error .= ' ' . lang ( 'You can upload a big SQL file via FTP and import it from server.' );
}
2013-04-01 18:45:26 -07:00
}