180 lines
5.0 KiB
PHP
180 lines
5.0 KiB
PHP
|
<?PHP
|
||
|
/**
|
||
|
* Login script
|
||
|
*
|
||
|
* @author Joshua Ramon Enslin <joshua@jrenslin.de>
|
||
|
*/
|
||
|
|
||
|
// Load settings
|
||
|
|
||
|
// Demand HTTPS
|
||
|
if (!isset($_SERVER['HTTPS']) or $_SERVER['HTTPS'] != 'on') header("Location: ../");
|
||
|
|
||
|
// Get available login information
|
||
|
|
||
|
$loginInformation = json_decode(file_get_contents(__DIR__ . '/../data/users.json'), True);
|
||
|
define("loginLogFile", "/../data/logins.csv");
|
||
|
|
||
|
/**
|
||
|
* Function for printing the login page
|
||
|
*
|
||
|
* @param string $error_msg Error message to print. Optional.
|
||
|
* @param string $cssFile CSS file.
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
function showLoginPasswordProtect($error_msg = "", $cssFile = "themes/default/default.css") {
|
||
|
|
||
|
echo '<!DOCTYPE html>
|
||
|
<html id="loginPage">
|
||
|
<head>
|
||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
|
<meta http-equiv="content-type" content="text/html;charset=utf-8">
|
||
|
<meta charset="UTF-8">
|
||
|
<title>Log In</title>
|
||
|
<link rel="stylesheet" type="text/css" href="' . $cssFile . '">
|
||
|
</head>
|
||
|
<body>
|
||
|
<h1>Log In</h1>';
|
||
|
if ($error_msg) echo '<p id="errorMsg">'.$error_msg.'</p>';
|
||
|
echo '
|
||
|
<form action="" method="POST">
|
||
|
<input type="text" name="username" placeholder="Username" required autofocus />
|
||
|
<input type="password" name="password" placeholder="Password" required />
|
||
|
<button type="submit">Submit</button>
|
||
|
</form>
|
||
|
</body>
|
||
|
</html>
|
||
|
';
|
||
|
|
||
|
die();
|
||
|
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Logout function: Unsets all relevant session variables.
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
function logout() {
|
||
|
$loginVariables = array("username", "userlevel", "userLastLogin", "userLang");
|
||
|
foreach ($loginVariables as $var) {
|
||
|
if (isset($_SESSION[$var])) unset($_SESSION[$var]);
|
||
|
}
|
||
|
header("Location: ../");
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Function for Logging logins.
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
function logLogin() {
|
||
|
file_put_contents(loginLogFile, $_SESSION['username'].'|'.date("Y-m-d H:i:s").PHP_EOL, FILE_APPEND | LOCK_EX);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Prevent brute force attacks
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
function preventBruteForce() {
|
||
|
|
||
|
if (!isset($_SESSION['loginattempt'])) $_SESSION['loginattempt'] = array();
|
||
|
|
||
|
$_SESSION['loginattempt'][] = date("Y-m-d H:i:s");
|
||
|
|
||
|
if (count($_SESSION['loginattempt']) > 3) {
|
||
|
|
||
|
$secondtolastattempt = strtotime($_SESSION['loginattempt'][count($_SESSION['loginattempt']) - 3]);
|
||
|
$lastattempt = strtotime($_SESSION['loginattempt'][count($_SESSION['loginattempt']) - 2]);
|
||
|
|
||
|
$logindelay = (intval(count($_SESSION['loginattempt'])) * 20);
|
||
|
$sincelastlogin = strtotime(date("Y-m-d H:i:s")) - $lastattempt;
|
||
|
|
||
|
if ($sincelastlogin < $logindelay) showLoginPasswordProtect("You failed logging in too often, try again in $logindelay seconds.");
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Check for validity of username / password combination.
|
||
|
*
|
||
|
* @param mixed[] $loginInformation Array containing all login information.
|
||
|
* @param string $username Username to check.
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
function checkLoginValidity(array $loginInformation, $username) {
|
||
|
if (!isset($loginInformation[$username])) showLoginPasswordProtect("Incorrect username");
|
||
|
}
|
||
|
|
||
|
// Main part of the script
|
||
|
|
||
|
if (isset($_GET['logout'])) logout(); // Log out if so requested
|
||
|
|
||
|
// Check for expiry
|
||
|
|
||
|
else if (isset($_SESSION['username'])) {
|
||
|
|
||
|
checkLoginValidity($loginInformation, $_SESSION["username"]);
|
||
|
|
||
|
// Check for expiry of login
|
||
|
if (isset($_SESSION["userLastLogin"]) and strtotime(date("Y-m-d H:i:s")) - strtotime($_SESSION["userLastLogin"]) > 3600) logout();
|
||
|
|
||
|
// Renew last login time
|
||
|
$_SESSION["userLastLogin"] = date("Y-m-d H:i:s");
|
||
|
|
||
|
}
|
||
|
|
||
|
// If the corresponding POST vars are set, check for
|
||
|
|
||
|
else if (isset($_SERVER['PHP_AUTH_USER']) and isset($_SERVER['PHP_AUTH_PW'])) {
|
||
|
|
||
|
preventBruteForce();
|
||
|
checkLoginValidity($loginInformation, $_SERVER['PHP_AUTH_USER']);
|
||
|
|
||
|
if (password_verify($loginInformation[$_SERVER['PHP_AUTH_USER']]['password'], $_SERVER['PHP_AUTH_PW'])) showLoginPasswordProtect("Incorrect password");
|
||
|
|
||
|
// Set username
|
||
|
$_SESSION["username"] = $_SERVER['PHP_AUTH_USER'];
|
||
|
|
||
|
// Set last access time
|
||
|
$_SESSION["userLastLogin"] = date("Y-m-d H:i:s");
|
||
|
|
||
|
if (isset($_SESSION['loginattempt'])) unset($_SESSION['loginattempt']);
|
||
|
|
||
|
// Log login time
|
||
|
logLogin();
|
||
|
|
||
|
}
|
||
|
else if (isset($_POST['username']) and isset($_POST['password'])) {
|
||
|
|
||
|
preventBruteForce();
|
||
|
checkLoginValidity($loginInformation, $_POST['username']);
|
||
|
if (password_verify($loginInformation[$_POST['username']]['password'], $_POST['username'])) showLoginPasswordProtect("Incorrect password");
|
||
|
|
||
|
// Set username
|
||
|
$_SESSION["username"] = $_POST['username'];
|
||
|
|
||
|
// Set last access time
|
||
|
$_SESSION["userLastLogin"] = date("Y-m-d H:i:s");
|
||
|
|
||
|
if (isset($_SESSION['loginattempt'])) unset($_SESSION['loginattempt']);
|
||
|
|
||
|
// Log login time
|
||
|
logLogin();
|
||
|
|
||
|
}
|
||
|
|
||
|
// If nothing happens, offer login page
|
||
|
|
||
|
else showLoginPasswordProtect();
|
||
|
|
||
|
// End script
|
||
|
|
||
|
unset($loginInformation); // Unset array containing login information
|
||
|
|
||
|
?>
|