diff options
author | Robin Appelman <robin@icewind.nl> | 2020-03-17 16:46:08 +0300 |
---|---|---|
committer | Robin Appelman <robin@icewind.nl> | 2020-08-31 16:00:46 +0300 |
commit | 7033a6ba7c69f691b197742f5047331b9c7351dd (patch) | |
tree | 46de0643b3f6f638bc033451b71c8deef42cf873 /lib | |
parent | 8725da5d28ce37dd965631f1c4405df8922b00bf (diff) |
test the connection to the av when saving settings
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Controller/SettingsController.php | 31 | ||||
-rw-r--r-- | lib/Scanner/ExternalKaspersky.php | 1 | ||||
-rw-r--r-- | lib/Scanner/IScanner.php | 12 | ||||
-rw-r--r-- | lib/Scanner/ScannerBase.php | 100 | ||||
-rw-r--r-- | lib/Scanner/ScannerFactory.php | 65 |
5 files changed, 116 insertions, 93 deletions
diff --git a/lib/Controller/SettingsController.php b/lib/Controller/SettingsController.php index 6a25688..44ffb69 100644 --- a/lib/Controller/SettingsController.php +++ b/lib/Controller/SettingsController.php @@ -8,6 +8,8 @@ namespace OCA\Files_Antivirus\Controller; +use OCA\Files_Antivirus\Scanner\ScannerFactory; +use OCA\Files_Antivirus\Status; use \OCP\AppFramework\Controller; use \OCP\IRequest; use \OCP\IL10N; @@ -22,17 +24,20 @@ class SettingsController extends Controller { * @var AppConfig */ private $settings; - + /** * @var IL10N */ private $l10n; - - public function __construct($appName, IRequest $request, AppConfig $appconfig, IL10N $l10n) { + + private $scannerFactory; + + public function __construct($appName, IRequest $request, AppConfig $appconfig, IL10N $l10n, ScannerFactory $scannerFactory) { parent::__construct($appName, $request); $this->settings = $appconfig; $this->l10n = $l10n; + $this->scannerFactory = $scannerFactory; } /** @@ -59,14 +64,22 @@ class SettingsController extends Controller { $this->settings->setAvInfectedAction($avInfectedAction); $this->settings->setAvStreamMaxLength($avStreamMaxLength); $this->settings->setAvMaxFileSize($avMaxFileSize); - + + try { + $scanner = $this->scannerFactory->getScanner(); + $result = $scanner->scanString("dummy scan content"); + $success = $result->getNumericStatus() == Status::SCANRESULT_CLEAN; + $message = $success ? $this->l10n->t('Saved') : 'unexpected scan results for test content'; + } catch (\Exception $e) { + $message = $e->getMessage(); + $success = false; + } + return new JSONResponse( ['data' => - ['message' => - $this->l10n->t('Saved') - ], - 'status' => 'success', - 'settings' => $this->settings->getAllValues() + ['message' => $message], + 'status' => $success ? 'success' : 'error', + 'settings' => $this->settings->getAllValues(), ] ); } diff --git a/lib/Scanner/ExternalKaspersky.php b/lib/Scanner/ExternalKaspersky.php index aab5084..1850475 100644 --- a/lib/Scanner/ExternalKaspersky.php +++ b/lib/Scanner/ExternalKaspersky.php @@ -61,6 +61,7 @@ class ExternalKaspersky extends ScannerBase { 'X-KAV-Timeout' => '60000', 'X-KAV-ProtocolVersion' => '1', ], + 'connect_timeout' => 5, ])->getBody(); $this->logger->debug( diff --git a/lib/Scanner/IScanner.php b/lib/Scanner/IScanner.php index 5244c5c..a270187 100644 --- a/lib/Scanner/IScanner.php +++ b/lib/Scanner/IScanner.php @@ -33,7 +33,7 @@ interface IScanner { * @param Item $item * @return Status */ - public function scan(Item $item); + public function scan(Item $item): Status; /** * Async scan - new portion of data is available @@ -47,10 +47,18 @@ interface IScanner { * * @return Status */ - public function completeAsyncScan(); + public function completeAsyncScan(): Status; /** * Open write handle. etc */ public function initScanner(); + + /** + * Scan a chunk of data synchronously + * + * @param string $data + * @return Status + */ + public function scanString(string $data): Status; } diff --git a/lib/Scanner/ScannerBase.php b/lib/Scanner/ScannerBase.php index e23dec3..5bd91ca 100644 --- a/lib/Scanner/ScannerBase.php +++ b/lib/Scanner/ScannerBase.php @@ -1,25 +1,25 @@ <?php /** -* ownCloud - files_antivirus -* -* @author Manuel Deglado -* @copyright 2012 Manuel Deglado manuel.delgado@ucr.ac.cr -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE -* License as published by the Free Software Foundation; either -* version 3 of the License, or any later version. -* -* This library is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU AFFERO GENERAL PUBLIC LICENSE for more details. -* -* You should have received a copy of the GNU Affero General Public -* License along with this library. If not, see <http://www.gnu.org/licenses/>. -* -*/ + * ownCloud - files_antivirus + * + * @author Manuel Deglado + * @copyright 2012 Manuel Deglado manuel.delgado@ucr.ac.cr + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ namespace OCA\Files_Antivirus\Scanner; @@ -30,9 +30,10 @@ use OCA\Files_Antivirus\StatusFactory; use OCP\ILogger; abstract class ScannerBase implements IScanner { - + /** * Scan result + * * @var Status */ protected $status; @@ -40,6 +41,7 @@ abstract class ScannerBase implements IScanner { /** * If scanning was done part by part * the first detected infected part is stored here + * * @var Status */ protected $infectedStatus; @@ -87,11 +89,11 @@ abstract class ScannerBase implements IScanner { abstract protected function shutdownScanner(); - public function getStatus(){ - if ($this->infectedStatus instanceof Status){ + public function getStatus() { + if ($this->infectedStatus instanceof Status) { return $this->infectedStatus; } - if ($this->status instanceof Status){ + if ($this->status instanceof Status) { return $this->status; } return $this->statusFactory->newStatus(); @@ -99,43 +101,55 @@ abstract class ScannerBase implements IScanner { /** * Synchronous scan + * * @param Item $item * @return Status */ - public function scan(Item $item) { + public function scan(Item $item): Status { $this->initScanner(); while (false !== ($chunk = $item->fread())) { $this->writeChunk($chunk); } - + + $this->shutdownScanner(); + return $this->getStatus(); + } + + public function scanString(string $data): Status { + $this->initScanner(); + + $this->writeChunk($data); + $this->shutdownScanner(); return $this->getStatus(); } - + /** * Async scan - new portion of data is available + * * @param string $data */ - public function onAsyncData($data){ + public function onAsyncData($data) { $this->writeChunk($data); } - + /** * Async scan - resource is closed + * * @return Status */ - public function completeAsyncScan(){ + public function completeAsyncScan(): Status { $this->shutdownScanner(); return $this->getStatus(); } - + /** * Open write handle. etc */ - public function initScanner(){ + public function initScanner() { $this->byteCount = 0; - if ($this->status instanceof Status && $this->status->getNumericStatus() === Status::SCANRESULT_INFECTED){ + if ($this->status instanceof Status && $this->status->getNumericStatus() === Status::SCANRESULT_INFECTED) { $this->infectedStatus = clone $this->status; } $this->status = $this->statusFactory->newStatus(); @@ -144,7 +158,7 @@ abstract class ScannerBase implements IScanner { /** * @param string $chunk */ - protected function writeChunk($chunk){ + protected function writeChunk($chunk) { $this->fwrite( $this->prepareChunk($chunk) ); @@ -153,14 +167,14 @@ abstract class ScannerBase implements IScanner { /** * @param string $data */ - final protected function fwrite($data){ - if ($this->isAborted){ + final protected function fwrite($data) { + if ($this->isAborted) { return; } $dataLength = strlen($data); $streamSizeLimit = (int)$this->appConfig->getAvStreamMaxLength(); - if ($this->byteCount + $dataLength > $streamSizeLimit){ + if ($this->byteCount + $dataLength > $streamSizeLimit) { \OC::$server->getLogger()->debug( 'reinit scanner', ['app' => 'files_antivirus'] @@ -171,7 +185,7 @@ abstract class ScannerBase implements IScanner { $isReopenSuccessful = true; } - if (!$isReopenSuccessful || !$this->writeRaw($data)){ + if (!$isReopenSuccessful || !$this->writeRaw($data)) { if (!$this->isLogUsed) { $this->isLogUsed = true; \OC::$server->getLogger()->warning( @@ -188,7 +202,7 @@ abstract class ScannerBase implements IScanner { /** * @return bool */ - protected function retry(){ + protected function retry() { $this->initScanner(); if (!is_null($this->lastChunk)) { return $this->writeRaw($this->lastChunk); @@ -200,10 +214,10 @@ abstract class ScannerBase implements IScanner { * @param $data * @return bool */ - protected function writeRaw($data){ + protected function writeRaw($data) { $dataLength = strlen($data); $bytesWritten = @fwrite($this->getWriteHandle(), $data); - if ($bytesWritten === $dataLength){ + if ($bytesWritten === $dataLength) { $this->byteCount += $bytesWritten; $this->lastChunk = $data; return true; @@ -213,18 +227,20 @@ abstract class ScannerBase implements IScanner { /** * Get a resource to write data into + * * @return resource */ - protected function getWriteHandle(){ + protected function getWriteHandle() { return $this->writeHandle; } /** * Prepare chunk (if required) + * * @param string $data * @return string */ - protected function prepareChunk($data){ + protected function prepareChunk($data) { return $data; } } diff --git a/lib/Scanner/ScannerFactory.php b/lib/Scanner/ScannerFactory.php index 2e39942..59e7c63 100644 --- a/lib/Scanner/ScannerFactory.php +++ b/lib/Scanner/ScannerFactory.php @@ -9,54 +9,39 @@ namespace OCA\Files_Antivirus\Scanner; use OCA\Files_Antivirus\AppConfig; -use OCP\ILogger; use OCP\IServerContainer; -class ScannerFactory{ - - /** @var AppConfig */ +class ScannerFactory { protected $appConfig; - - /** @var ILogger */ - protected $logger; - - /** @var string */ - protected $scannerClass; - private $serverContainer; - - public function __construct(AppConfig $appConfig, ILogger $logger, IServerContainer $serverContainer){ - $this->appConfig = $appConfig; - $this->logger = $logger; - $this->serverContainer = $serverContainer; - try { - $avMode = $appConfig->getAvMode(); - switch($avMode) { - case 'daemon': - case 'socket': - $this->scannerClass = ExternalClam::class; - break; - case 'executable': - $this->scannerClass = LocalClam::class; - break; - case 'kaspersky': - $this->scannerClass = ExternalKaspersky::class; - break; - default: - $this->logger->warning('Application is misconfigured. Please check the settings at the admin page. Invalid mode: ' . $avMode); - break; - } - } catch (\Exception $e){ - $logger->logException($e); - } + public function __construct(AppConfig $appConfig, IServerContainer $serverContainer) { + $this->appConfig = $appConfig; + $this->serverContainer = $serverContainer; } - + /** - * Produce a scanner instance + * Produce a scanner instance + * * @return IScanner */ - public function getScanner(){ - return $this->serverContainer->query($this->scannerClass); + public function getScanner() { + $avMode = $this->appConfig->getAvMode(); + switch ($avMode) { + case 'daemon': + case 'socket': + $scannerClass = ExternalClam::class; + break; + case 'executable': + $scannerClass = LocalClam::class; + break; + case 'kaspersky': + $scannerClass = ExternalKaspersky::class; + break; + default: + throw new \InvalidArgumentException('Application is misconfigured. Please check the settings at the admin page. Invalid mode: ' . $avMode); + } + + return $this->serverContainer->query($scannerClass); } } |