@@ -9,6 +9,7 @@ use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
@@ -67,27 +68,43 @@ class ScanDocumentForMalware implements ShouldBeUnique, ShouldQueue
|
||||
$disk = Storage::disk('local');
|
||||
$root = $disk->path('');
|
||||
$path = $disk->path($document->storage_key);
|
||||
$beforeHash = $this->fileHash($path);
|
||||
if ($beforeHash === null || ! hash_equals(trim($document->sha256), $beforeHash)) {
|
||||
$this->record($document, [
|
||||
'result' => 'inconclusive', 'reason_code' => 'file_hash_mismatch', 'engine' => 'ClamAV',
|
||||
'engine_version' => 'unknown', 'signatures_at' => null, 'duration_ms' => 0, 'detail' => null,
|
||||
], $startedAt, 'inconclusive');
|
||||
$temporary = null;
|
||||
try {
|
||||
if (($document->storage_encryption ?? null) === 'laravel') {
|
||||
$temporary = tempnam($root, 'scan-private-');
|
||||
if ($temporary === false) {
|
||||
throw new \RuntimeException('Private scan workspace unavailable');
|
||||
}
|
||||
chmod($temporary, 0600);
|
||||
file_put_contents($temporary, Crypt::decryptString($disk->get($document->storage_key)));
|
||||
$path = $temporary;
|
||||
}
|
||||
$beforeHash = $this->fileHash($path);
|
||||
if ($beforeHash === null || ! hash_equals(trim($document->sha256), $beforeHash)) {
|
||||
$this->record($document, [
|
||||
'result' => 'inconclusive', 'reason_code' => 'file_hash_mismatch', 'engine' => 'ClamAV',
|
||||
'engine_version' => 'unknown', 'signatures_at' => null, 'duration_ms' => 0, 'detail' => null,
|
||||
], $startedAt, 'inconclusive');
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
$result = $scanner->scan($path, (int) ($document->size_bytes ?? filesize($path)), $root);
|
||||
|
||||
$afterHash = $this->fileHash($path);
|
||||
if ($afterHash === null || ! hash_equals(trim($document->sha256), $afterHash)) {
|
||||
$result['result'] = 'inconclusive';
|
||||
$result['reason_code'] = 'file_changed_during_scan';
|
||||
$result['detail'] = null;
|
||||
}
|
||||
$result['file_sha256'] = $afterHash;
|
||||
|
||||
$this->record($document, $result, $startedAt, $result['result']);
|
||||
} finally {
|
||||
if (is_string($temporary) && is_file($temporary)) {
|
||||
unlink($temporary);
|
||||
}
|
||||
}
|
||||
|
||||
$result = $scanner->scan($path, (int) ($document->size_bytes ?? filesize($path)), $root);
|
||||
|
||||
$afterHash = $this->fileHash($path);
|
||||
if ($afterHash === null || ! hash_equals(trim($document->sha256), $afterHash)) {
|
||||
$result['result'] = 'inconclusive';
|
||||
$result['reason_code'] = 'file_changed_during_scan';
|
||||
$result['detail'] = null;
|
||||
}
|
||||
$result['file_sha256'] = $afterHash;
|
||||
|
||||
$this->record($document, $result, $startedAt, $result['result']);
|
||||
}
|
||||
|
||||
public function failed(Throwable $exception): void
|
||||
|
||||
Reference in New Issue
Block a user