mailwolt/app/Livewire/Ui/Security/ClamavManager.php

161 lines
5.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
namespace App\Livewire\Ui\Security;
use Livewire\Attributes\Layout;
use Livewire\Attributes\Title;
use Livewire\Component;
#[Layout('layouts.dvx')]
#[Title('Virenschutz · Mailwolt')]
class ClamavManager extends Component
{
public bool $installed = false;
public bool $running = false;
public bool $enabled = false;
public string $dbDate = '—';
public string $dbVersion = '—';
public ?int $ramMb = null;
public string $lastError = '';
public string $lastSuccess = '';
public bool $installing = false;
public bool $starting = false;
public function mount(): void
{
$this->refresh();
}
public function refresh(): void
{
$this->lastError = '';
$this->lastSuccess = '';
$this->starting = false;
$this->running = $this->serviceActive();
$this->enabled = $this->serviceEnabled();
$this->installed = true;
$this->ramMb = $this->running ? $this->readRamMb() : null;
[$this->dbDate, $this->dbVersion] = $this->readDbInfo();
}
public function pollStatus(): void
{
if (!$this->starting) return;
$this->running = $this->serviceActive();
$this->enabled = $this->serviceEnabled();
if ($this->running) {
$this->starting = false;
$this->lastSuccess = 'ClamAV wurde aktiviert und läuft.';
$this->ramMb = $this->readRamMb();
}
}
public function install(): void
{
$this->installing = true;
$out = [];
@exec('sudo -n /usr/local/sbin/mailwolt-clamav install 2>&1', $out, $rc);
$this->installing = false;
if ($rc !== 0) {
$this->lastError = implode(' ', $out) ?: 'Installation fehlgeschlagen.';
} else {
$this->dispatch('toast', type: 'success', badge: 'ClamAV',
title: 'Installiert', text: 'ClamAV wurde installiert. Sie können ihn jetzt aktivieren.');
}
$this->refresh();
}
public function enable(): void
{
$this->lastError = $this->lastSuccess = '';
// Im Hintergrund starten systemctl start kann 30-60s dauern (DB-Laden)
shell_exec('nohup sudo -n /usr/local/sbin/mailwolt-clamav enable > /tmp/mw-clamav-start.log 2>&1 &');
$this->starting = true;
$this->enabled = true; // systemctl enable ist sofort wirksam
}
public function disable(): void
{
[$ok, $msg] = $this->runCmd('disable');
if ($ok) $this->lastSuccess = 'ClamAV wurde gestoppt und deaktiviert.';
else $this->lastError = $msg;
$this->running = $this->serviceActive();
$this->enabled = $this->serviceEnabled();
}
public function updateDb(): void
{
[$ok, $msg] = $this->runCmd('freshclam');
if ($ok) $this->lastSuccess = 'Virensignaturen wurden aktualisiert.';
else $this->lastError = $msg;
[$this->dbDate, $this->dbVersion] = $this->readDbInfo();
}
private function runCmd(string $action): array
{
$out = []; $rc = null;
exec('sudo -n /usr/local/sbin/mailwolt-clamav ' . escapeshellarg($action) . ' 2>&1', $out, $rc);
\Log::info('ClamAV ' . $action, ['rc' => $rc, 'out' => $out]);
$msg = implode(' ', $out) ?: 'Unbekannter Fehler (rc=' . $rc . ')';
return [$rc === 0, $msg];
}
private function serviceActive(): bool
{
$exit = null;
@exec('systemctl is-active --quiet clamav-daemon 2>/dev/null', $_, $exit);
return $exit === 0;
}
private function serviceEnabled(): bool
{
$exit = null;
@exec('systemctl is-enabled --quiet clamav-daemon 2>/dev/null', $_, $exit);
return $exit === 0;
}
private function readRamMb(): ?int
{
$out = [];
@exec("ps -C clamd -o rss= 2>/dev/null", $out);
$kb = array_sum(array_map('intval', array_filter($out)));
return $kb > 0 ? (int) round($kb / 1024) : null;
}
private function readDbInfo(): array
{
$paths = [
'/var/lib/clamav/main.cvd',
'/var/lib/clamav/main.cld',
'/var/lib/clamav/daily.cvd',
'/var/lib/clamav/daily.cld',
];
$latest = 0;
foreach ($paths as $p) {
if (@file_exists($p)) {
$mtime = @filemtime($p);
if ($mtime > $latest) $latest = $mtime;
}
}
if ($latest === 0) return ['—', '—'];
$date = date('d.m.Y H:i', $latest);
$ver = '—';
$out = [];
@exec('sigtool --info /var/lib/clamav/daily.cld 2>/dev/null | grep "^Version:" | head -1', $out);
if (empty($out)) {
@exec('sigtool --info /var/lib/clamav/daily.cvd 2>/dev/null | grep "^Version:" | head -1', $out);
}
if (!empty($out[0])) {
$ver = trim(str_replace('Version:', '', $out[0]));
}
return [$date, $ver];
}
public function render()
{
return view('livewire.ui.security.clamav-manager');
}
}