diff --git a/wwwroot/inc/auth.php b/wwwroot/inc/auth.php index 9e92d1853..1d6e8c523 100644 --- a/wwwroot/inc/auth.php +++ b/wwwroot/inc/auth.php @@ -22,10 +22,10 @@ function assertHTTPCredentialsReceived() { if ( - ! isset ($_SERVER['PHP_AUTH_USER']) || - $_SERVER['PHP_AUTH_USER'] == '' || - ! isset ($_SERVER['PHP_AUTH_PW']) || - $_SERVER['PHP_AUTH_PW'] == '' + ! isset ($_SESSION['username']) || + $_SESSION['username'] == '' || + ! isset ($_POST['password']) || + $_POST['password'] == '' ) throw new RackTablesError ('', RackTablesError::NOT_AUTHENTICATED); } @@ -41,12 +41,144 @@ function assertHTTPCredentialsReceived() // Phase 1. Assert basic pre-requisites, short-circuit the logout request. if (! isset ($user_auth_src) || ! isset ($require_local_account)) throw new RackTablesError ('secret.php: either user_auth_src or require_local_account are missing', RackTablesError::MISCONFIGURED); + + startsession(); + if (isset ($_REQUEST['logout'])) { if (isset ($user_auth_src) && 'saml' == $user_auth_src) saml_logout (); - throw new RackTablesError ('', RackTablesError::NOT_AUTHENTICATED); // Reset browser credentials cache. + + if(isset($_SESSION['loggedin']) && ($_SESSION['loggedin'] == 1)) + { + unset($_SESSION['loggedin']); + unset($_SESSION['username']); + unset($_SESSION['userinfo']); + unset($_SESSION['auto_tags']); + unset($_SESSION['user_given_tags']); + unset($_SESSION['sessiontimeout']); + + echo << + + +RT logout + + +
+You have successfully logged out. +

Return to RackTables Login Page

+
+ +ENDLOGOUTPAGE; +exit; + } + else + { + throw new RackTablesError ('', RackTablesError::NOT_AUTHENTICATED); + } + } + + if (isset($_REQUEST['login'])) + { + + unset($_SESSION['loggedin']); + unset($_SESSION['username']); + unset($_SESSION['userinfo']); + unset($_SESSION['auto_tags']); + unset($_SESSION['user_given_tags']); + unset($_SESSION['sessiontimeout']); + + if(isset($_SESSION['msg'])) + $msg = $_SESSION['msg']; + else + $msg = ""; + + header ('Content-Type: text/html; charset=UTF-8'); + + echo << + + +RT login + + +
+
+$msg + + + + +
RackTables Login
Username:
Password:
+

+
+ +ENDLOGINFORM; + + if(isset($_SESSION['msg'])) + unset($_SESSION['msg']); +exit; + } + + // not logged in + if (!isset($_SESSION['loggedin']) or $_SESSION['loggedin'] != 1 ) + { + + if(!empty($_GET)) + $_SESSION['url'] = $_SERVER['REQUEST_URI']; + + // new login + if( + isset($_POST['username']) && + !empty($_POST['username']) && + isset($_POST['password']) && + !empty($_POST['password']) + ) + { + $_SESSION['username'] = $_POST['username']; + $remote_username = $_SESSION['username']; + } + else + throw new RackTablesError ('', RackTablesError::NOT_AUTHENTICATED); } + else + { + // already logged in + if(!isset($_SESSION['sessiontimeout']) || (time() - $_SESSION['sessiontimeout'] > 60*60)) // 1 Hour + { + if(!empty($_GET)) + $_SESSION['url'] = $_SERVER['REQUEST_URI']; + + $_SESSION['msg'] = "Session timed out!"; + unset($_SESSION['loggedin']); + unset($_SESSION['username']); + unset($_SESSION['userinfo']); + unset($_SESSION['auto_tags']); + unset($_SESSION['user_given_tags']); + unset($_SESSION['sessiontimeout']); + + // force login + throw new RackTablesError ('', RackTablesError::NOT_AUTHENTICATED); + } + + $remote_username = $_SESSION['username']; + + $userinfo = $_SESSION['userinfo']; + + $user_given_tags = $_SESSION['user_given_tags']; + $auto_tags = $_SESSION['auto_tags']; + + $remote_displayname = $_SESSION['displayname']; + + $_SESSION['sessiontimeout'] = time(); + + session_write_close(); + return; // success + } + + $_SESSION['sessiontimeout'] = time(); + // Phase 2. Do some method-specific processing, initialize $remote_username on success. switch (TRUE) { @@ -54,11 +186,11 @@ function assertHTTPCredentialsReceived() break; // skip this phase case 'database' == $user_auth_src: assertHTTPCredentialsReceived(); - $remote_username = $_SERVER['PHP_AUTH_USER']; + $remote_username = $_SESSION['username']; break; case 'ldap' == $user_auth_src: assertHTTPCredentialsReceived(); - $remote_username = $_SERVER['PHP_AUTH_USER']; + $remote_username = $_SESSION['username']; constructLDAPOptions(); break; case 'httpd' == $user_auth_src: @@ -90,12 +222,19 @@ function assertHTTPCredentialsReceived() switch (TRUE) { case isset ($script_mode) && $script_mode: + $_SESSION['loggedin'] = 1; return; // success // Just trust the server, because the password isn't known. case 'httpd' == $user_auth_src: $remote_displayname = $userinfo['user_realname'] != '' ? $userinfo['user_realname'] : $remote_username; + $_SESSION['userinfo'] = $userinfo; + $_SESSION['auto_tags'] = $auto_tags; + $_SESSION['user_given_tags'] = $user_given_tags; + $_SESSION['displayname'] = $remote_displayname; + $_SESSION['loggedin'] = 1; + session_write_close(); return; // success // When using LDAP, leave a mean to fix things. Admin user is always authenticated locally. case array_key_exists ('user_id', $userinfo) && $userinfo['user_id'] == 1: @@ -103,19 +242,44 @@ function assertHTTPCredentialsReceived() $remote_displayname = $userinfo['user_realname'] != '' ? $userinfo['user_realname'] : $remote_username; - if (authenticated_via_database ($userinfo, $_SERVER['PHP_AUTH_PW'])) + if (authenticated_via_database ($userinfo, $_POST['password'])) + { + $_SESSION['userinfo'] = $userinfo; + $_SESSION['auto_tags'] = $auto_tags; + $_SESSION['user_given_tags'] = $user_given_tags; + $_SESSION['displayname'] = $remote_displayname; + $_SESSION['loggedin'] = 1; + session_write_close(); return; // success + } + $_SESSION['msg'] = "Wrong Username or Password!"; break; // failure case 'ldap' == $user_auth_src: $ldap_dispname = ''; - if (! authenticated_via_ldap ($remote_username, $_SERVER['PHP_AUTH_PW'], $ldap_dispname)) + if (! authenticated_via_ldap ($remote_username, $_POST['password'], $ldap_dispname)) + { + $_SESSION['msg'] = "Wrong Username or Password!"; break; // failure + } $remote_displayname = $userinfo['user_realname'] != '' ? // local value is most preferred $userinfo['user_realname'] : ($ldap_dispname != '' ? $ldap_dispname : $remote_username); // then one from LDAP + + $_SESSION['userinfo'] = $userinfo; + $_SESSION['auto_tags'] = $auto_tags; + $_SESSION['user_given_tags'] = $user_given_tags; + $_SESSION['displayname'] = $remote_displayname; + $_SESSION['loggedin'] = 1; + session_write_close(); return; // success case 'saml' == $user_auth_src: $remote_displayname = $saml_dispname != '' ? $saml_dispname : $saml_username; + $_SESSION['userinfo'] = $userinfo; + $_SESSION['auto_tags'] = $auto_tags; + $_SESSION['user_given_tags'] = $user_given_tags; + $_SESSION['displayname'] = $remote_displayname; + $_SESSION['loggedin'] = 1; + session_write_close(); return; // success default: throw new RackTablesError ('Invalid authentication source!', RackTablesError::MISCONFIGURED); diff --git a/wwwroot/inc/exceptions.php b/wwwroot/inc/exceptions.php index a26a70c74..c59e260b7 100644 --- a/wwwroot/inc/exceptions.php +++ b/wwwroot/inc/exceptions.php @@ -135,9 +135,7 @@ public function dispatch() switch ($this->code) { case self::NOT_AUTHENTICATED: - header ('WWW-Authenticate: Basic realm="' . getConfigVar ('enterprise') . ' RackTables access"'); - header ('HTTP/1.1 401 Unauthorized'); - $this->genHTMLPage ('Not authenticated', '

This system requires authentication. You should use a username and a password.

'); + header('location: ?login'); break; case self::MISCONFIGURED: case self::INTERNAL: diff --git a/wwwroot/inc/init.php b/wwwroot/inc/init.php index 8be1b1554..c5543121d 100644 --- a/wwwroot/inc/init.php +++ b/wwwroot/inc/init.php @@ -121,6 +121,17 @@ // A successful call to authenticate() always generates autotags and somethimes // even given/implicit tags. It also sets remote_username and remote_displayname. authenticate(); + + if(isset($_SESSION['url'])) + { + startsession(); + $url = $_SESSION['url']; + unset($_SESSION['url']); + session_write_close(); + header("location: $url"); + exit; + } + // Authentication passed. // Note that we don't perform autorization here, so each 1st level page // has to do it in its way, e.g. by calling authorize() after fixContext(). diff --git a/wwwroot/inc/interface.php b/wwwroot/inc/interface.php index 0cbbb1667..cf788015e 100644 --- a/wwwroot/inc/interface.php +++ b/wwwroot/inc/interface.php @@ -90,7 +90,7 @@ function showLogoutURL () // add a trailing slash if the installation resides in a subdirectory if ($dirname != '/') $dirname .= '/'; - printf ('http%s://logout@%s%s?logout', $https, $_SERVER['SERVER_NAME'], $dirname); + printf ('http%s://%s%sindex.php?logout', $https, $_SERVER['SERVER_NAME'], $dirname); } $quick_links = NULL; // you can override this in your local.php, but first initialize it with getConfiguredQuickLinks()