| Server IP : 188.114.96.3 / Your IP : 216.73.216.143 Web Server : Apache System : Linux sv058.home.net.pl 6.8.2 husak_dirty_pages_fix #1 SMP PREEMPT_DYNAMIC Tue Apr 2 22:06:51 CEST 2024 x86_64 User : ( 3194769) PHP Version : 8.5.12 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /test2.famaresto/inc/ |
Upload File : |
<?php
// Simple session auth (WP-like) without DB.
if (session_status() !== PHP_SESSION_ACTIVE) {
session_start();
}
function cms_data_dir(): string {
return dirname(__DIR__) . '/data';
}
function cms_users_file(): string {
return cms_data_dir() . '/users.json';
}
function cms_home_file(): string {
return cms_data_dir() . '/home.json';
}
function cms_ensure_data_dir(): void {
$dir = cms_data_dir();
if (!is_dir($dir)) {
@mkdir($dir, 0775, true);
}
}
function cms_load_json(string $file, array $fallback): array {
if (!is_file($file)) return $fallback;
$raw = @file_get_contents($file);
if ($raw === false || $raw === '') return $fallback;
$j = json_decode($raw, true);
return is_array($j) ? $j : $fallback;
}
function cms_save_json(string $file, array $data): bool {
cms_ensure_data_dir();
$json = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
if ($json === false) return false;
$tmp = $file . '.tmp';
if (@file_put_contents($tmp, $json, LOCK_EX) === false) return false;
return @rename($tmp, $file);
}
function cms_default_users(): array {
// default admin: change immediately
return [
'users' => [
[
'username' => 'admin',
'role' => 'admin',
'pass_hash' => password_hash('ZMIEŃ_TO_OD_RAZU', PASSWORD_DEFAULT),
'created_at' => date('c'),
]
]
];
}
function cms_load_users(): array {
$file = cms_users_file();
$data = cms_load_json($file, []);
if (!isset($data['users']) || !is_array($data['users']) || count($data['users']) === 0) {
$data = cms_default_users();
// attempt to persist
cms_save_json($file, $data);
}
return $data;
}
function cms_find_user(string $username): ?array {
$username = trim($username);
$data = cms_load_users();
foreach ($data['users'] as $u) {
if (isset($u['username']) && hash_equals((string)$u['username'], $username)) {
return $u;
}
}
return null;
}
// --- Legacy hash support (MD5 / htpasswd apr1 / crypt / {SHA}) + auto-upgrade ---
function cms_to64(int $v, int $n): string {
$itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
$s = '';
while ($n-- > 0) {
$s .= $itoa64[$v & 0x3f];
$v >>= 6;
}
return $s;
}
function cms_apr1_md5(string $password, string $salt): string {
$salt = substr($salt, 0, 8);
$len = strlen($password);
$text = $password . '$apr1$' . $salt;
$bin = pack('H32', md5($password . $salt . $password));
for ($i = $len; $i > 0; $i -= 16) {
$text .= substr($bin, 0, min(16, $i));
}
for ($i = $len; $i > 0; $i >>= 1) {
$text .= ($i & 1) ? chr(0) : $password[0];
}
$bin = pack('H32', md5($text));
for ($i = 0; $i < 1000; $i++) {
$new = ($i & 1) ? $password : $bin;
if ($i % 3) $new .= $salt;
if ($i % 7) $new .= $password;
$new .= ($i & 1) ? $bin : $password;
$bin = pack('H32', md5($new));
}
$tmp = '';
$tmp .= cms_to64((ord($bin[0]) << 16) | (ord($bin[6]) << 8) | ord($bin[12]), 4);
$tmp .= cms_to64((ord($bin[1]) << 16) | (ord($bin[7]) << 8) | ord($bin[13]), 4);
$tmp .= cms_to64((ord($bin[2]) << 16) | (ord($bin[8]) << 8) | ord($bin[14]), 4);
$tmp .= cms_to64((ord($bin[3]) << 16) | (ord($bin[9]) << 8) | ord($bin[15]), 4);
$tmp .= cms_to64((ord($bin[4]) << 16) | (ord($bin[10]) << 8) | ord($bin[5]), 4);
$tmp .= cms_to64(ord($bin[11]), 2);
return '$apr1$' . $salt . '$' . $tmp;
}
function cms_verify_apr1(string $password, string $stored): bool {
if (strpos($stored, '$apr1$') !== 0) return false;
$parts = explode('$', $stored);
if (count($parts) < 4) return false;
$salt = $parts[2] ?? '';
$calc = cms_apr1_md5($password, $salt);
return hash_equals($stored, $calc);
}
function cms_verify_password_any(string $password, array $u, bool &$needsUpgrade): bool {
$needsUpgrade = false;
// 1) Nowoczesny hash (bcrypt/argon)
if (isset($u['pass_hash']) && is_string($u['pass_hash']) && $u['pass_hash'] !== '') {
if (password_verify($password, $u['pass_hash'])) {
if (password_needs_rehash($u['pass_hash'], PASSWORD_DEFAULT)) $needsUpgrade = true;
return true;
}
}
// 2) Legacy MD5 hex: md5(password)
if (isset($u['pass_md5']) && is_string($u['pass_md5']) && preg_match('/^[a-f0-9]{32}$/i', $u['pass_md5'])) {
if (hash_equals(strtolower($u['pass_md5']), md5($password))) {
$needsUpgrade = true;
return true;
}
}
// 3) htpasswd $apr1$...
if (isset($u['pass_apr1']) && is_string($u['pass_apr1']) && strpos($u['pass_apr1'], '$apr1$') === 0) {
if (cms_verify_apr1($password, $u['pass_apr1'])) {
$needsUpgrade = true;
return true;
}
}
// 4) crypt() compatible ($1$, $5$, $6$, itp.)
if (isset($u['pass_crypt']) && is_string($u['pass_crypt']) && $u['pass_crypt'] !== '') {
$c = crypt($password, $u['pass_crypt']);
if (is_string($c) && hash_equals($u['pass_crypt'], $c)) {
$needsUpgrade = true;
return true;
}
}
// 5) htpasswd {SHA}...
if (isset($u['pass_sha1']) && is_string($u['pass_sha1']) && strpos($u['pass_sha1'], '{SHA}') === 0) {
$b64 = substr($u['pass_sha1'], 5);
$calc = base64_encode(sha1($password, true));
if (hash_equals($b64, $calc)) {
$needsUpgrade = true;
return true;
}
}
return false;
}
function cms_login(string $username, string $password): bool {
$username = trim($username);
if ($username === '') return false;
$data = cms_load_users();
if (!isset($data['users']) || !is_array($data['users'])) return false;
foreach ($data['users'] as $i => $u) {
if (!isset($u['username'])) continue;
if (!hash_equals((string)$u['username'], $username)) continue;
$needsUpgrade = false;
if (!cms_verify_password_any($password, $u, $needsUpgrade)) return false;
// zaloguj
$_SESSION['cms_user'] = [
'username' => (string)$u['username'],
'role' => (string)($u['role'] ?? 'editor'),
'login_at' => time(),
];
// upgrade hash na bezpieczny (po pierwszym udanym logowaniu)
if ($needsUpgrade) {
$u['pass_hash'] = password_hash($password, PASSWORD_DEFAULT);
unset($u['pass_md5'], $u['pass_apr1'], $u['pass_crypt'], $u['pass_sha1']);
$data['users'][$i] = $u;
cms_save_json(cms_users_file(), $data);
}
return true;
}
return false;
}
function cms_logout(): void {
unset($_SESSION['cms_user']);
}
function cms_current_user(): ?array {
return isset($_SESSION['cms_user']) && is_array($_SESSION['cms_user']) ? $_SESSION['cms_user'] : null;
}
function cms_is_logged_in(): bool {
return cms_current_user() !== null;
}
function cms_is_admin(): bool {
$u = cms_current_user();
return $u && (($u['role'] ?? '') === 'admin');
}
function cms_require_login(): void {
if (!cms_is_logged_in()) {
header('Location: /admin/login.php');
exit;
}
}
function cms_require_admin(): void {
cms_require_login();
if (!cms_is_admin()) {
http_response_code(403);
echo 'Brak uprawnień.';
exit;
}
}
function cms_csrf_token(): string {
if (empty($_SESSION['cms_csrf'])) {
$_SESSION['cms_csrf'] = bin2hex(random_bytes(16));
}
return $_SESSION['cms_csrf'];
}
function cms_check_csrf(?string $token): bool {
return is_string($token) && isset($_SESSION['cms_csrf']) && hash_equals($_SESSION['cms_csrf'], $token);
}
function cms_h(string $s): string {
return htmlspecialchars($s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}
function cms_sanitize_href(string $href): string {
$href = trim($href);
if ($href === '') return '';
if (preg_match('~^\s*javascript:~i', $href)) return '';
return $href;
}
function cms_layout_header(string $title): void {
header('Content-Type: text/html; charset=utf-8');
$user = cms_current_user();
$who = $user ? ('Zalogowany: ' . cms_h($user['username']) . ' (' . cms_h($user['role']) . ')') : '';
echo "<!doctype html><html lang=\"pl\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><title>".cms_h($title)."</title><style>
body{font-family:Arial,Helvetica,sans-serif;background:#f5f5ef;margin:0;padding:18px;}
.wrap{max-width:1000px;margin:0 auto;}
.top{display:flex;justify-content:space-between;gap:10px;align-items:center;margin-bottom:12px;flex-wrap:wrap;}
.card{background:#fff;border:1px solid #ddd;border-radius:12px;padding:14px;box-shadow:0 2px 6px rgba(0,0,0,.05)}
.nav a{display:inline-block;margin-right:10px;color:#0E5C93;text-decoration:none;font-weight:bold}
.nav a:hover{text-decoration:underline}
.muted{opacity:.75;font-size:12px}
.msg{margin:10px 0;padding:10px;border-radius:10px;background:#f0f7ff;border:1px solid #cfe6ff}
table{width:100%;border-collapse:collapse}
th,td{border-bottom:1px solid #eee;padding:8px;text-align:left;vertical-align:top}
input,textarea,select{width:100%;padding:8px;border:1px solid #ccc;border-radius:10px;font-size:14px}
textarea{min-height:90px;resize:vertical}
.rowbtn{padding:6px 10px;border-radius:999px;border:1px solid #aaa;background:#fff;cursor:pointer}
.btn{padding:10px 14px;border-radius:10px;border:1px solid #186D25;background:#186D25;color:#fff;cursor:pointer;font-weight:bold}
.btn.secondary{background:#444;border-color:#444}
.btn.danger{background:#9F0A05;border-color:#9F0A05}
.actions{display:flex;gap:10px;flex-wrap:wrap;margin-top:12px}
</style></head><body><div class=\"wrap\"><div class=\"top\"><div class=\"nav\">";
if (cms_is_logged_in()) {
echo "<a href=\"/admin/index.php\">Panel</a>";
echo "<a href=\"/admin/home.php\">Strona główna</a>";
echo "<a href=\"/admin/pages.php\">Strony</a>";
if (cms_is_admin()) {
echo "<a href=\"/admin/import.php\">Import treści</a>";
echo "<a href=\"/admin/users.php\">Użytkownicy</a>";
echo "<a href=\"/admin/import_users.php\">Import logowań</a>";
}
echo "<a href=\"/admin/logout.php\">Wyloguj</a>";
}
echo "</div><div class=\"muted\">$who</div></div>";
}
function cms_layout_footer(): void {
echo "</div></body></html>";
}