| 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 : /polana/admin/ |
Upload File : |
<?php
declare(strict_types=1);
/** POLANA V18.9 — minimal backup SMTP sender fix. Admin-only and reversible. */
require_once dirname(__DIR__) . '/includes/polana_backup_v182.php';
require_admin_role();
header('X-Robots-Tag: noindex, nofollow', true);
header('Cache-Control: no-store, private', true);
header('X-Content-Type-Options: nosniff', true);
function pbk189_target(): string { return dirname(__DIR__) . '/includes/polana_backup_v182.php'; }
function pbk189_patch_dir(): string { return pbk_private() . '/patch-v189-smtp'; }
function pbk189_state_file(): string { return pbk189_patch_dir() . '/state.json'; }
function pbk189_old(): string {
return '$from = smtp_clean_email(setting(\'smtp_from_email\')); $to = smtp_clean_email($to);';
}
function pbk189_new(): string {
return '$from = smtp_clean_email(filter_var($user, FILTER_VALIDATE_EMAIL) ? $user : setting(\'smtp_from_email\')); $to = smtp_clean_email($to);';
}
function pbk189_inspect(string $source): string {
$start = strpos($source, 'function pbk_send_attachment(');
$stop = $start === false ? false : strpos($source, 'function pbk_status_path(', $start);
if ($start === false || $stop === false || $stop <= $start) return 'unknown';
$segment = substr($source, $start, $stop - $start);
if (substr_count($segment, pbk189_new()) === 1) return 'installed';
if (substr_count($segment, pbk189_old()) === 1 && strpos($source, 'V18.3') !== false) return 'supported';
return 'unknown';
}
function pbk189_write_atomic(string $target, string $source): void {
$tmp = dirname($target) . '/.polana189-' . bin2hex(random_bytes(8)) . '.tmp';
$f = @fopen($tmp, 'x+b');
if ($f === false) throw new RuntimeException('Brak uprawnień zapisu do includes/. Instalator niczego nie zmienił.');
try {
if (fwrite($f, $source) !== strlen($source)) throw new RuntimeException('Niepełny zapis pliku.');
fflush($f);
} finally { fclose($f); }
$mode = @fileperms($target);
@chmod($tmp, $mode !== false ? ($mode & 0777) : 0644);
if (!@rename($tmp, $target)) { @unlink($tmp); throw new RuntimeException('Nie można atomowo podmienić biblioteki.'); }
if (function_exists('opcache_invalidate')) @opcache_invalidate($target, true);
}
function pbk189_write_state(array $state): void {
$filename = pbk189_state_file();
$data = json_encode($state, JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
$temp = $filename . '.' . bin2hex(random_bytes(4)) . '.tmp';
if (@file_put_contents($temp, $data, LOCK_EX) !== strlen($data)) throw new RuntimeException('Nie zapisano metadanych rollbacku.');
@chmod($temp, 0600);
if (!@rename($temp, $filename)) { @unlink($temp); throw new RuntimeException('Nie zapisano metadanych rollbacku.'); }
}
function pbk189_install(): string {
$target = pbk189_target();
$current = @file_get_contents($target);
if (!is_string($current)) throw new RuntimeException('Nie można odczytać biblioteki backupu.');
if (pbk189_inspect($current) === 'installed') return 'Poprawka jest już obecna w bibliotece. Nie wykonano zmian.';
if (pbk189_inspect($current) !== 'supported') throw new RuntimeException('Nieznana wersja biblioteki — niczego nie nadpisano. Prześlij aktualny plik do porównania.');
$dir = pbk189_patch_dir();
if (!is_dir($dir) && !@mkdir($dir, 0700)) throw new RuntimeException('Nie można utworzyć prywatnego katalogu rollbacku.');
@chmod($dir, 0700);
if (is_file(pbk189_state_file())) throw new RuntimeException('Istnieje poprzedni stan poprawki. Najpierw rozstrzygnij rollback; bez nadpisywania starej kopii.');
$backupName = 'backup-' . date('Ymd-His') . '-' . bin2hex(random_bytes(5)) . '.php.txt';
$backupPath = $dir . '/' . $backupName;
$handle = @fopen($backupPath, 'x+b');
if ($handle === false) throw new RuntimeException('Brak możliwości wykonania kopii oryginalnej biblioteki.');
try { if (fwrite($handle, $current) !== strlen($current)) throw new RuntimeException('Niepełna kopia przed poprawką.'); }
finally { fclose($handle); }
@chmod($backupPath, 0600);
$modified = str_replace(pbk189_old(), pbk189_new(), $current, $n);
if ($n !== 1 || pbk189_inspect($modified) !== 'installed') throw new RuntimeException('Błąd weryfikacji patcha. Oryginał bez zmian.');
if (hash_file('sha256', $backupPath) !== hash('sha256', $current)) throw new RuntimeException('Kopia przed poprawką nie przeszła SHA-256. Oryginał bez zmian.');
// State is persisted first; a crash before replacing the target will result in a safe no-op rollback refusal.
pbk189_write_state(['backup' => $backupName, 'before' => hash('sha256', $current), 'after' => hash('sha256', $modified), 'created' => date(DATE_ATOM)]);
pbk189_write_atomic($target, $modified);
if (hash_file('sha256', $target) !== hash('sha256', $modified)) throw new RuntimeException('Niepotwierdzony zapis biblioteki. Przejdź do rollbacku.');
return 'Poprawka zainstalowana. SMTP nadawca backupów = konto smtp_username (jeżeli jest adresem e-mail).';
}
function pbk189_rollback(): string {
$stateRaw = @file_get_contents(pbk189_state_file());
$state = is_string($stateRaw) ? json_decode($stateRaw, true) : null;
if (!is_array($state)) throw new RuntimeException('Brak zapisanej kopii do rollbacku.');
$backupName = (string)($state['backup'] ?? '');
if (!preg_match('/^backup-[0-9]{8}-[0-9]{6}-[a-f0-9]{10}\.php\.txt$/', $backupName)) throw new RuntimeException('Nieprawidłowa nazwa backupu.');
$original = @file_get_contents(pbk189_patch_dir() . '/' . $backupName);
if (!is_string($original) || hash('sha256', $original) !== ($state['before'] ?? null)) throw new RuntimeException('Niepoprawny plik rollbacku.');
$target = pbk189_target();
$current = @file_get_contents($target);
if (!is_string($current) || hash('sha256', $current) !== ($state['after'] ?? null)) throw new RuntimeException('Biblioteka została zmieniona po instalacji. Wstrzymano rollback, aby nie nadpisać nowszego kodu.');
pbk189_write_atomic($target, $original);
if (hash_file('sha256', $target) !== $state['before']) throw new RuntimeException('Nie udało się potwierdzić rollbacku.');
@rename(pbk189_state_file(), pbk189_patch_dir() . '/rolled-back-' . date('Ymd-His') . '.json');
return 'Rollback wykonany i zweryfikowany SHA-256. Ustawienia, dane SQL i klucz szyfrowania bez zmian.';
}
$message = ''; $error = ''; $status = 'unknown';
try {
$source = @file_get_contents(pbk189_target());
if (!is_string($source)) throw new RuntimeException('Brak dostępu do biblioteki backupu.');
$status = pbk189_inspect($source);
if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'POST') {
verify_csrf();
$action = (string)($_POST['action'] ?? '');
if ($action === 'install') $message = pbk189_install();
elseif ($action === 'rollback') $message = pbk189_rollback();
else throw new RuntimeException('Nieznana operacja.');
clearstatcache(true, pbk189_target());
$status = pbk189_inspect((string)file_get_contents(pbk189_target()));
}
} catch (Throwable $e) { $error = $e->getMessage(); }
function pbk189_e(string $s): string { return htmlspecialchars($s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); }
render_admin_header('POLANA V18.9 — Naprawa SMTP backupów');
?>
<style>
.p189{max-width:760px;margin:24px auto 80px;padding:0 16px;color:#27372f}.p189 article{background:#fff;border:1px solid #ccd8ce;border-radius:16px;padding:24px;margin:18px 0}.p189 button{border:0;border-radius:10px;background:#254834;color:white;padding:11px 16px;font:inherit;cursor:pointer}.p189 button[disabled]{opacity:.45;cursor:default}.p189 .secondary{background:#eef3ef;color:#254834}.p189 .err{background:#ffe9e7;padding:12px}.p189 .ok{background:#e9f7e8;padding:12px}.p189 small{color:#657267}
</style>
<div class="p189">
<h1>POLANA V18.9 — Naprawa SMTP backupów</h1>
<p>Rozwiązuje błąd SMTP 553, gdy konto logowania SMTP to <code>[email protected]</code>, a globalny nadawca ustawiony jest na <code>[email protected]</code>.</p>
<p>Zmiana dotyczy <b>wyłącznie biblioteki wysyłki zaszyfrowanych backupów SQL</b>. Nie zmienia SMTP dla rezerwacji, bazy danych, kalendarza, Google Drive, klucza i archiwów.</p>
<?php if ($message !== ''): ?><div class="ok"><?=pbk189_e($message)?></div><?php endif; ?>
<?php if ($error !== ''): ?><div class="err"><?=pbk189_e($error)?></div><?php endif; ?>
<article><h2>Wykryty stan: <?=pbk189_e($status === 'supported' ? 'wersja V18.3 — gotowa' : ($status === 'installed' ? 'poprawka obecna' : 'nieznana wersja — bez zmian'))?></h2>
<form method="post"><?=csrf_field()?><input type="hidden" name="action" value="install"><button type="submit" <?= $status !== 'supported' ? 'disabled' : '' ?>>Backup kodu i naprawa nadawcy SMTP</button></form>
<p><small>Przed modyfikacją tworzona jest kopia biblioteki poza WWW. Przy innej wersji lub braku uprawnień zapis zostanie wstrzymany.</small></p></article>
<article><h2>Cofnięcie zmiany</h2><form method="post"><?=csrf_field()?><input type="hidden" name="action" value="rollback"><button type="submit" class="secondary">Rollback V18.9</button></form><p><small>Rollback nie nadpisze biblioteki, jeśli została zmieniona po instalacji.</small></p></article>
<p>Po instalacji otwórz <a href="/admin/polana-backup-automat.php">Automatyczne kopie</a>, kliknij <b>Test: wykonaj SQL teraz</b>. Jeżeli dzisiejszy zaszyfrowany backup istnieje i jest poprawny, biblioteka użyje go ponownie i spróbuje wysłać e-mail.</p>
</div>
<?php render_admin_footer(); ?>