This repository has been archived on 2022-07-28. You can view files and clone it, but cannot push or open issues or pull requests.
md-cms/edit/password_protect.php

185 lines
5.3 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", __DIR__ . "/../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/theme.css") {
echo '<!DOCTYPE html>
<html id="loginPage">
<head>
<meta http-equiv="Content-Security-Policy" content="default-src \'none\'; script-src \'none\'; connect-src \'none\'; style-src \'self\'; font-src \'self\';" />
<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 ($loginInformation[$_POST['username']]['admin'] or count($loginInformation) == 1) {
$_SESSION['admin'] = true;
}
else $_SESSION['admin'] = false;
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
?>