'password_hash'|'sha256', 'hash' => string, 'salt' => string?] */ function admin_auth_config(): ?array { $path = getenv('ADMIN_AUTH_FILE'); if (!is_string($path) || $path === '') { $path = '/var/lib/sillylaird/admin_auth.php'; } if (!is_file($path) || !is_readable($path)) { return null; } $cfg = include $path; return is_array($cfg) ? $cfg : null; } function admin_password_ok(string $provided): bool { $cfg = admin_auth_config(); if ($cfg === null) { return false; } $hash = (string)($cfg['hash'] ?? ''); if ($hash === '') { return false; } $algo = strtolower((string)($cfg['algo'] ?? 'password_hash')); if ($algo === 'password_hash' || str_starts_with($hash, '$2y$') || str_starts_with($hash, '$2a$') || str_starts_with($hash, '$argon')) { return password_verify($provided, $hash); } // Legacy: sha256(password + salt) $salt = (string)($cfg['salt'] ?? ''); $computed = hash('sha256', $provided . $salt); return hash_equals($hash, $computed); } $error = ''; if ($_SERVER['REQUEST_METHOD'] === 'POST') { if (!proxy_rate_limit('admin_login', 5, 300)) { http_response_code(429); $error = 'Too many attempts. Try again in a few minutes.'; } else { $token = $_POST['csrf'] ?? ''; if (!is_string($token) || !hash_equals($_SESSION['csrf'], $token)) { $error = 'Bad request.'; } else { $provided = $_POST['password'] ?? ''; if (is_string($provided) && admin_password_ok($provided)) { session_regenerate_id(true); $_SESSION['admin'] = true; unset($_SESSION['csrf']); header('Location: ' . $dest); exit; } $error = 'Wrong password.'; usleep(random_int(150000, 400000)); } } } ?> Admin Login — SillyLaird

Admin Login