$v) { if ($now - ($v['first'] ?? 0) > $lockoutSeconds * 2) { unset($attempts[$k]); } } $ipData = $attempts[$ip] ?? ['count' => 0, 'first' => $now]; $locked = ($ipData['count'] >= $maxAttempts) && ($now - $ipData['first'] < $lockoutSeconds); $TIMEOUT = 1800; if (!empty($_SESSION['freeloader_loggedin']) && isset($_SESSION['last_activity'])) { if (time() - $_SESSION['last_activity'] > $TIMEOUT) { session_unset(); session_destroy(); freeloader_bootstrap_session(); } } if (!empty($_SESSION['freeloader_loggedin'])) { $_SESSION['last_activity'] = time(); } $logged_in = !empty($_SESSION['freeloader_loggedin']); $error = null; if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['password'])) { if ($locked) { $error = 'Too many failed attempts. Please wait a few minutes and try again.'; } else { $password = $_POST['password'] ?? ''; $valid = false; // Bcrypt hash only (plaintext passwords are no longer accepted) if (!empty($FREELoader_PASSWORD_HASH)) { $valid = password_verify($password, $FREELoader_PASSWORD_HASH); } if ($valid) { session_regenerate_id(true); $_SESSION['freeloader_loggedin'] = true; $_SESSION['last_activity'] = time(); unset($attempts[$ip]); save_attempts($rateFile, $attempts); if (empty($_SESSION['freeloader_csrf'])) { $_SESSION['freeloader_csrf'] = bin2hex(random_bytes(32)); } header('Location: index.php'); exit; } if ($ipData['count'] === 0 || ($now - $ipData['first']) > $lockoutSeconds) { $ipData = ['count' => 1, 'first' => $now]; } else { $ipData['count']++; } $attempts[$ip] = $ipData; save_attempts($rateFile, $attempts); $error = 'Incorrect password.'; } } if (isset($_GET['logout'])) { session_unset(); session_destroy(); header('Location: index.php'); exit; } ?>
= htmlspecialchars($error) ?>
Account temporarily locked due to too many failed attempts.
[Logout]