diff --git a/app/Livewire/Ui/Security/Modal/Fail2BanJailModal.php b/app/Livewire/Ui/Security/Modal/Fail2BanJailModal.php index e2de874..f4743ab 100644 --- a/app/Livewire/Ui/Security/Modal/Fail2BanJailModal.php +++ b/app/Livewire/Ui/Security/Modal/Fail2BanJailModal.php @@ -190,23 +190,62 @@ class Fail2BanJailModal extends ModalComponent $sqlite = $this->bin('sqlite3'); $db = $this->getDbFile(); - $q = sprintf( - "SELECT timeofban, expiretime - FROM bans - WHERE jail=%s AND ip=%s AND (expiretime=-1 OR expiretime>STRFTIME('%%s','now')) - ORDER BY timeofban DESC LIMIT 1", - $this->sql($jail), - $this->sql($ip) - ); + // 1) Spalten ermitteln + $cmdCols = "$sudo -n $sqlite -readonly ".escapeshellarg($db)." ".escapeshellarg("PRAGMA table_info(bans);"); + $colsRaw = trim((string)@shell_exec($cmdCols)); + if ($colsRaw === '') return null; + $hasExpire = strpos($colsRaw, "|expiretime|") !== false; + $hasBantime= strpos($colsRaw, "|bantime|") !== false; + + // 2) Query bauen nach Schema + if ($hasExpire) { + $q = sprintf( + "SELECT timeofban, expiretime FROM bans + WHERE jail=%s AND ip=%s + ORDER BY timeofban DESC LIMIT 1", + $this->sql($jail), $this->sql($ip) + ); + $cmd = "$sudo -n $sqlite -readonly ".escapeshellarg($db).' '.escapeshellarg($q); + $out = trim((string)@shell_exec($cmd)); + if ($out === '') return null; + [$timeofban, $expire] = array_map('intval', explode('|', $out)) + [null, null]; + return ['banned_at' => $timeofban ?: null, 'expire' => $expire ?? null]; + } + + if ($hasBantime) { + $q = sprintf( + "SELECT timeofban, bantime FROM bans + WHERE jail=%s AND ip=%s + ORDER BY timeofban DESC LIMIT 1", + $this->sql($jail), $this->sql($ip) + ); + $cmd = "$sudo -n $sqlite -readonly ".escapeshellarg($db).' '.escapeshellarg($q); + $out = trim((string)@shell_exec($cmd)); + if ($out === '') return null; + [$timeofban, $bantime] = array_map('intval', explode('|', $out)) + [null, null]; + $expire = ($timeofban && $bantime) ? ($timeofban + $bantime) : null; + return ['banned_at' => $timeofban ?: null, 'expire' => $expire]; + } + + // Fallback: nur timeofban vorhanden → aktuelles Jail-Bantime verwenden + $q = sprintf( + "SELECT timeofban FROM bans + WHERE jail=%s AND ip=%s + ORDER BY timeofban DESC LIMIT 1", + $this->sql($jail), $this->sql($ip) + ); $cmd = "$sudo -n $sqlite -readonly ".escapeshellarg($db).' '.escapeshellarg($q); $out = trim((string)@shell_exec($cmd)); if ($out === '') return null; - [$timeofban, $expire] = array_map('intval', explode('|', $out)) + [null, null]; - return ['banned_at' => $timeofban ?: null, 'expire' => $expire ?? null]; + $timeofban = (int)$out; + $bantime = $this->getBantime($jail); // aktuell konfiguriert (z. B. 3600) + $expire = $timeofban ? ($timeofban + max(0, $bantime)) : null; + + return ['banned_at' => $timeofban ?: null, 'expire' => $expire]; } - + private function isStillBanned(string $jail, string $ip): bool { // 1) Direkt: banip