diff --git a/MalwareMultiScan.Api/Controllers/DownloadController.cs b/MalwareMultiScan.Api/Controllers/DownloadController.cs new file mode 100644 index 0000000..8f4414b --- /dev/null +++ b/MalwareMultiScan.Api/Controllers/DownloadController.cs @@ -0,0 +1,31 @@ +using System.Threading.Tasks; +using MalwareMultiScan.Api.Services; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace MalwareMultiScan.Api.Controllers +{ + [Route("download")] + public class DownloadController : Controller + { + private readonly ScanResultsService _scanResultsService; + + public DownloadController(ScanResultsService scanResultsService) + { + _scanResultsService = scanResultsService; + } + + [HttpGet("{id}")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task Index(string id) + { + var fileStream = await _scanResultsService.ObtainFile(id); + + if (fileStream == null) + return NotFound(); + + return File(fileStream, "application/octet-stream"); + } + } +} \ No newline at end of file diff --git a/MalwareMultiScan.Api/Controllers/QueueController.cs b/MalwareMultiScan.Api/Controllers/QueueController.cs new file mode 100644 index 0000000..908751e --- /dev/null +++ b/MalwareMultiScan.Api/Controllers/QueueController.cs @@ -0,0 +1,15 @@ +using Microsoft.AspNetCore.Mvc; + +namespace MalwareMultiScan.Api.Controllers +{ + [ApiController] + [Route("queue")] + [Produces("application/json")] + public class QueueController : Controller + { + public IActionResult Index() + { + return Ok(); + } + } +} \ No newline at end of file diff --git a/MalwareMultiScan.Api/Controllers/ScanBackendsController.cs b/MalwareMultiScan.Api/Controllers/ScanBackendsController.cs new file mode 100644 index 0000000..c65e430 --- /dev/null +++ b/MalwareMultiScan.Api/Controllers/ScanBackendsController.cs @@ -0,0 +1,41 @@ +using System.Linq; +using System.Threading.Tasks; +using MalwareMultiScan.Api.Data.Configuration; +using MalwareMultiScan.Api.Data.Response; +using MalwareMultiScan.Api.Services; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace MalwareMultiScan.Api.Controllers +{ + [ApiController] + [Route("backends")] + [Produces("application/json")] + public class ScanBackendsController : Controller + { + private readonly ScanBackendService _scanBackendService; + + public ScanBackendsController(ScanBackendService scanBackendService) + { + _scanBackendService = scanBackendService; + } + + private async Task GetScanBackendResponse(ScanBackend backend) + { + return new ScanBackendResponse + { + Id = backend.Id, + Name = backend.Name, + Online = await _scanBackendService.Ping(backend) + }; + } + + [HttpGet] + [ProducesResponseType(typeof(ScanBackendResponse[]), StatusCodes.Status200OK)] + public async Task Index() + { + return Ok(await Task.WhenAll( + _scanBackendService.List.Select(GetScanBackendResponse).ToArray())); + } + } +} \ No newline at end of file diff --git a/MalwareMultiScan.Api/Controllers/ScanResultsController.cs b/MalwareMultiScan.Api/Controllers/ScanResultsController.cs new file mode 100644 index 0000000..2d8885a --- /dev/null +++ b/MalwareMultiScan.Api/Controllers/ScanResultsController.cs @@ -0,0 +1,31 @@ +using System.Threading.Tasks; +using MalwareMultiScan.Api.Services; +using MalwareMultiScan.Shared.Data.Responses; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; + +namespace MalwareMultiScan.Api.Controllers +{ + [ApiController] + [Route("results")] + [Produces("application/json")] + public class ScanResultsController : Controller + { + private readonly ScanResultsService _scanResultsService; + + public ScanResultsController(ScanResultsService scanResultsService) + { + _scanResultsService = scanResultsService; + } + + [HttpPost("{id}")] + [ProducesResponseType(StatusCodes.Status204NoContent)] + public async Task Index(string id, [FromBody] ResultResponse result) + { + await _scanResultsService.UpdateScanResultForBackend( + id, result.Backend, true, result.Success, result.Threats); + + return NoContent(); + } + } +} \ No newline at end of file diff --git a/MalwareMultiScan.Api/Data/Configuration/BackendConfiguration.cs b/MalwareMultiScan.Api/Data/Configuration/ScanBackend.cs similarity index 83% rename from MalwareMultiScan.Api/Data/Configuration/BackendConfiguration.cs rename to MalwareMultiScan.Api/Data/Configuration/ScanBackend.cs index 3524440..a2cb9ad 100644 --- a/MalwareMultiScan.Api/Data/Configuration/BackendConfiguration.cs +++ b/MalwareMultiScan.Api/Data/Configuration/ScanBackend.cs @@ -1,6 +1,6 @@ namespace MalwareMultiScan.Api.Data.Configuration { - public class BackendConfiguration + public class ScanBackend { public string Id { get; set; } public string Name { get; set; } diff --git a/MalwareMultiScan.Api/Data/Models/ScanRequest.cs b/MalwareMultiScan.Api/Data/Models/ScanRequest.cs deleted file mode 100644 index 23c9af3..0000000 --- a/MalwareMultiScan.Api/Data/Models/ScanRequest.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Collections.Generic; -using MongoDB.Bson; -using MongoDB.Bson.Serialization.Attributes; - -namespace MalwareMultiScan.Api.Data.Models -{ - public class ScanRequest - { - [BsonId] - [BsonRepresentation(BsonType.ObjectId)] - public string Id { get; set; } - - [BsonRepresentation(BsonType.ObjectId)] - public string FileId { get; set; } - - public Dictionary Results { get; set; } = - new Dictionary(); - } -} \ No newline at end of file diff --git a/MalwareMultiScan.Api/Data/Models/ScanResult.cs b/MalwareMultiScan.Api/Data/Models/ScanResult.cs new file mode 100644 index 0000000..c61369c --- /dev/null +++ b/MalwareMultiScan.Api/Data/Models/ScanResult.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; + +namespace MalwareMultiScan.Api.Data.Models +{ + public class ScanResult + { + [BsonId] + [BsonRepresentation(BsonType.ObjectId)] + public string Id { get; set; } + + public Dictionary Results { get; set; } = + new Dictionary(); + } +} \ No newline at end of file diff --git a/MalwareMultiScan.Api/Data/Models/ScanRequestEntry.cs b/MalwareMultiScan.Api/Data/Models/ScanResultEntry.cs similarity index 84% rename from MalwareMultiScan.Api/Data/Models/ScanRequestEntry.cs rename to MalwareMultiScan.Api/Data/Models/ScanResultEntry.cs index 87dccd8..dd3b536 100644 --- a/MalwareMultiScan.Api/Data/Models/ScanRequestEntry.cs +++ b/MalwareMultiScan.Api/Data/Models/ScanResultEntry.cs @@ -1,6 +1,6 @@ namespace MalwareMultiScan.Api.Data.Models { - public class ScanRequestEntry + public class ScanResultEntry { public bool Completed { get; set; } public bool Succeeded { get; set; } diff --git a/MalwareMultiScan.Api/Data/Response/ScanBackendResponse.cs b/MalwareMultiScan.Api/Data/Response/ScanBackendResponse.cs new file mode 100644 index 0000000..a7afe8f --- /dev/null +++ b/MalwareMultiScan.Api/Data/Response/ScanBackendResponse.cs @@ -0,0 +1,9 @@ +namespace MalwareMultiScan.Api.Data.Response +{ + public class ScanBackendResponse + { + public string Id { get; set; } + public string Name { get; set; } + public bool Online { get; set; } + } +} \ No newline at end of file diff --git a/MalwareMultiScan.Api/MalwareMultiScan.Api.csproj b/MalwareMultiScan.Api/MalwareMultiScan.Api.csproj index 8e7a9c3..b4895c0 100644 --- a/MalwareMultiScan.Api/MalwareMultiScan.Api.csproj +++ b/MalwareMultiScan.Api/MalwareMultiScan.Api.csproj @@ -4,10 +4,6 @@ netcoreapp3.1 - - - - Always @@ -24,5 +20,9 @@ <_ContentIncludedByDefault Remove="Properties\launchSettings.json" /> + + + + diff --git a/MalwareMultiScan.Api/Services/BackendConfigurationReader.cs b/MalwareMultiScan.Api/Services/BackendConfigurationReader.cs deleted file mode 100644 index b6a9b0a..0000000 --- a/MalwareMultiScan.Api/Services/BackendConfigurationReader.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.IO; -using MalwareMultiScan.Api.Data.Configuration; -using Microsoft.Extensions.Configuration; -using YamlDotNet.Serialization; -using YamlDotNet.Serialization.NamingConventions; - -namespace MalwareMultiScan.Api.Services -{ - public class BackendConfigurationReader - { - public BackendConfigurationReader(IConfiguration configuration) - { - var configurationPath = configuration.GetValue("BackendsConfiguration"); - - if (!File.Exists(configurationPath)) - throw new FileNotFoundException("Missing BackendsConfiguration YAML file", configurationPath); - - var configurationContent = File.ReadAllText(configurationPath); - - var deserializer = new DeserializerBuilder() - .WithNamingConvention(CamelCaseNamingConvention.Instance) - .Build(); - - Backends = deserializer.Deserialize(configurationContent); - } - - public BackendConfiguration[] Backends { get; } - } -} \ No newline at end of file diff --git a/MalwareMultiScan.Api/Services/ScanBackendService.cs b/MalwareMultiScan.Api/Services/ScanBackendService.cs new file mode 100644 index 0000000..f1ab944 --- /dev/null +++ b/MalwareMultiScan.Api/Services/ScanBackendService.cs @@ -0,0 +1,111 @@ +using System; +using System.IO; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using MalwareMultiScan.Api.Data.Configuration; +using MalwareMultiScan.Shared.Data.Requests; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using YamlDotNet.Serialization; +using YamlDotNet.Serialization.NamingConventions; + +namespace MalwareMultiScan.Api.Services +{ + public class ScanBackendService + { + private readonly IHttpClientFactory _httpClientFactory; + private readonly ILogger _logger; + + public ScanBackendService(IConfiguration configuration, IHttpClientFactory httpClientFactory, + ILogger logger) + { + _httpClientFactory = httpClientFactory; + _logger = logger; + var configurationPath = configuration.GetValue("BackendsConfiguration"); + + if (!File.Exists(configurationPath)) + throw new FileNotFoundException("Missing BackendsConfiguration YAML file", configurationPath); + + var configurationContent = File.ReadAllText(configurationPath); + + var deserializer = new DeserializerBuilder() + .WithNamingConvention(CamelCaseNamingConvention.Instance) + .Build(); + + List = deserializer.Deserialize(configurationContent); + } + + public ScanBackend[] List { get; } + + public async Task Ping(ScanBackend backend) + { + var cancellationTokenSource = new CancellationTokenSource( + TimeSpan.FromSeconds(1)); + + try + { + using var httpClient = _httpClientFactory.CreateClient(); + + var pingResponse = await httpClient.GetAsync( + new Uri(new Uri(backend.Endpoint), "/ping"), cancellationTokenSource.Token); + + pingResponse.EnsureSuccessStatusCode(); + } + catch (Exception exception) + { + _logger.LogError( + exception, $"Failed to ping {backend.Id}"); + + return false; + } + + return true; + } + + private async Task QueueScan(ScanBackend backend, string uri, HttpContent content) + { + var cancellationTokenSource = new CancellationTokenSource( + TimeSpan.FromSeconds(5)); + + using var httpClient = _httpClientFactory.CreateClient(); + + try + { + var response = await httpClient.PostAsync( + new Uri(new Uri(backend.Endpoint), uri), content, cancellationTokenSource.Token); + + response.EnsureSuccessStatusCode(); + } + catch (Exception exception) + { + _logger.LogError( + exception, $"Failed to initiate scan against {backend.Id}"); + + return false; + } + + return true; + } + + public async Task QueueFileScan( + ScanBackend backend, string fileName, Stream fileStream, string callbackUrl) + { + return await QueueScan(backend, "/scan/file", new MultipartFormDataContent + { + {new StringContent(callbackUrl), nameof(FileRequest.CallbackUrl)}, + {new StreamContent(fileStream), nameof(FileRequest.InputFile), fileName} + }); + } + + public async Task QueueUrlScan( + ScanBackend backend, string url, string callbackUrl) + { + return await QueueScan(backend, "/scan/url", new MultipartFormDataContent + { + {new StringContent(callbackUrl), nameof(UrlRequest.CallbackUrl)}, + {new StringContent(url), nameof(UrlRequest.InputUrl)} + }); + } + } +} \ No newline at end of file diff --git a/MalwareMultiScan.Api/Services/ScanRequestService.cs b/MalwareMultiScan.Api/Services/ScanRequestService.cs deleted file mode 100644 index 6813342..0000000 --- a/MalwareMultiScan.Api/Services/ScanRequestService.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System; -using System.IO; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; -using MalwareMultiScan.Api.Data.Models; -using Microsoft.Extensions.Logging; -using MongoDB.Driver; -using MongoDB.Driver.GridFS; - -namespace MalwareMultiScan.Api.Services -{ - public class ScanRequestService - { - private const string CollectionName = "ScanRequests"; - - private readonly GridFSBucket _bucket; - private readonly IMongoCollection _collection; - private readonly BackendConfigurationReader _configurationReader; - private readonly IHttpClientFactory _httpClientFactory; - private readonly ILogger _logger; - - public ScanRequestService(IMongoDatabase db, BackendConfigurationReader configurationReader, - IHttpClientFactory httpClientFactory, ILogger logger) - { - _configurationReader = configurationReader; - _httpClientFactory = httpClientFactory; - _logger = logger; - - _bucket = new GridFSBucket(db); - _collection = db.GetCollection(CollectionName); - } - - private async Task QueueScans(string requestId, string fileName, Stream fileStream) - { - foreach (var backend in _configurationReader.Backends) - { - var cancellationTokenSource = new CancellationTokenSource( - TimeSpan.FromSeconds(5)); - - using var httpClient = _httpClientFactory.CreateClient(); - - try - { - var endpointUri = new Uri( - new Uri(backend.Endpoint), "/scan/file"); - - var formContent = new MultipartFormDataContent - { - {new StringContent("value1"), "callbackUrl"}, - {new StreamContent(fileStream), "inputFile", fileName} - }; - - var response = await httpClient.PostAsync( - endpointUri, formContent, cancellationTokenSource.Token); - - response.EnsureSuccessStatusCode(); - - // TODO: update scan request - } - catch (Exception e) - { - _logger.LogError(e, - $"Failed to queue scanning job on {backend.Id} ({backend.Endpoint})"); - } - } - } - - public async Task InitializeNewRequest(string fileName, Stream fileStream, - CancellationToken cancellationToken = default) - { - var fileId = await _bucket.UploadFromStreamAsync(fileName, fileStream, - cancellationToken: cancellationToken); - - var scanRequest = new ScanRequest - { - FileId = fileId.ToString() - }; - - await _collection.InsertOneAsync(scanRequest, new InsertOneOptions - { - BypassDocumentValidation = false - }, cancellationToken); - - await QueueScans(scanRequest.Id, fileName, fileStream); - - return scanRequest.Id; - } - } -} \ No newline at end of file diff --git a/MalwareMultiScan.Api/Services/ScanResultsService.cs b/MalwareMultiScan.Api/Services/ScanResultsService.cs new file mode 100644 index 0000000..83de671 --- /dev/null +++ b/MalwareMultiScan.Api/Services/ScanResultsService.cs @@ -0,0 +1,97 @@ +using System; +using System.IO; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using MalwareMultiScan.Api.Data.Configuration; +using MalwareMultiScan.Api.Data.Models; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using MongoDB.Bson; +using MongoDB.Driver; +using MongoDB.Driver.GridFS; + +namespace MalwareMultiScan.Api.Services +{ + public class ScanResultsService + { + private const string CollectionName = "ScanResults"; + + private readonly IMongoCollection _collection; + private readonly GridFSBucket _bucket; + + private readonly ScanBackendService _scanBackendService; + + public ScanResultsService(IMongoDatabase db, ScanBackendService scanBackendService) + { + _scanBackendService = scanBackendService; + + _collection = db.GetCollection(CollectionName); + _bucket = new GridFSBucket(db); + } + + public async Task CreateScanResult() + { + var scanResult = new ScanResult(); + + await _collection.InsertOneAsync(scanResult); + + return scanResult; + } + + public async Task UpdateScanResultForBackend( + string resultId, string backendId, bool completed, bool succeeded, string[] threats = null) + { + var filterScanResult = Builders.Filter.Where(r => r.Id == resultId); + + var updateScanResult = Builders.Update.Set(r => r.Results[backendId], new ScanResultEntry + { + Completed = completed, + Succeeded = succeeded, + Threats = threats + }); + + await _collection.UpdateOneAsync(filterScanResult, updateScanResult); + } + + public async Task QueueFileScan(ScanResult result, string fileName, Stream fileStream, string callbackUrl) + { + foreach (var backend in _scanBackendService.List) + { + var queueResult = await _scanBackendService.QueueFileScan( + backend, fileName, fileStream, callbackUrl); + + await UpdateScanResultForBackend(result.Id, backend.Id, !queueResult, queueResult); + } + } + + public async Task QueueUrlScan(ScanResult result, string url, string callbackUrl) + { + foreach (var backend in _scanBackendService.List) + { + var queueResult = await _scanBackendService.QueueUrlScan( + backend, url, callbackUrl); + + await UpdateScanResultForBackend(result.Id, backend.Id, !queueResult, queueResult); + } + } + + public async Task StoreFile(string fileName, Stream fileStream) + { + var objectId = await _bucket.UploadFromStreamAsync(fileName, fileStream); + + return objectId.ToString(); + } + + public async Task ObtainFile(string id) + { + if (!ObjectId.TryParse(id, out var objectId)) + return null; + + return await _bucket.OpenDownloadStreamAsync(objectId, new GridFSDownloadOptions + { + Seekable = true + }); + } + } +} \ No newline at end of file diff --git a/MalwareMultiScan.Api/Startup.cs b/MalwareMultiScan.Api/Startup.cs index 7ed32be..12d3f37 100644 --- a/MalwareMultiScan.Api/Startup.cs +++ b/MalwareMultiScan.Api/Startup.cs @@ -18,8 +18,8 @@ namespace MalwareMultiScan.Api public void ConfigureServices(IServiceCollection services) { - services.AddSingleton(); - services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); services.AddSingleton( serviceProvider => diff --git a/MalwareMultiScan.Api/appsettings.json b/MalwareMultiScan.Api/appsettings.json index 62ff795..4ff2c96 100644 --- a/MalwareMultiScan.Api/appsettings.json +++ b/MalwareMultiScan.Api/appsettings.json @@ -14,5 +14,6 @@ "DatabaseName": "MalwareMultiScan", - "BackendsConfiguration": "backends.yaml" + "BackendsConfiguration": "backends.yaml", + "StoreFileUploads": true } diff --git a/MalwareMultiScan.Backends/Backends/Abstracts/AbstractScanBackend.cs b/MalwareMultiScan.Backends/Backends/Abstracts/AbstractScanBackend.cs index da66eb7..49633b2 100644 --- a/MalwareMultiScan.Backends/Backends/Abstracts/AbstractScanBackend.cs +++ b/MalwareMultiScan.Backends/Backends/Abstracts/AbstractScanBackend.cs @@ -12,8 +12,6 @@ namespace MalwareMultiScan.Backends.Backends.Abstracts { public virtual string Id => throw new NotImplementedException(); - public virtual DateTime DatabaseLastUpdate => throw new NotImplementedException(); - public virtual Task ScanAsync(string path, CancellationToken cancellationToken) { throw new NotImplementedException(); diff --git a/MalwareMultiScan.Backends/Backends/Implementations/ClamavScanBackend.cs b/MalwareMultiScan.Backends/Backends/Implementations/ClamavScanBackend.cs index 2d2de61..0ccb4d5 100644 --- a/MalwareMultiScan.Backends/Backends/Implementations/ClamavScanBackend.cs +++ b/MalwareMultiScan.Backends/Backends/Implementations/ClamavScanBackend.cs @@ -1,5 +1,3 @@ -using System; -using System.IO; using System.Text.RegularExpressions; using MalwareMultiScan.Backends.Backends.Abstracts; using Microsoft.Extensions.Logging; @@ -14,9 +12,6 @@ namespace MalwareMultiScan.Backends.Backends.Implementations public override string Id { get; } = "clamav"; - public override DateTime DatabaseLastUpdate => - File.GetLastWriteTime("/var/lib/clamav/daily.cvd"); - protected override string BackendPath { get; } = "/usr/bin/clamscan"; protected override Regex MatchRegex { get; } = diff --git a/MalwareMultiScan.Backends/Backends/Implementations/ComodoScanBackend.cs b/MalwareMultiScan.Backends/Backends/Implementations/ComodoScanBackend.cs index 6ef2bde..ac8b3a2 100644 --- a/MalwareMultiScan.Backends/Backends/Implementations/ComodoScanBackend.cs +++ b/MalwareMultiScan.Backends/Backends/Implementations/ComodoScanBackend.cs @@ -14,9 +14,6 @@ namespace MalwareMultiScan.Backends.Backends.Implementations public override string Id { get; } = "comodo"; - public override DateTime DatabaseLastUpdate => - File.GetLastWriteTime("/opt/COMODO/scanners/bases.cav"); - protected override string BackendPath { get; } = "/opt/COMODO/cmdscan"; protected override Regex MatchRegex { get; } = diff --git a/MalwareMultiScan.Backends/Backends/Implementations/DrWebScanBackend.cs b/MalwareMultiScan.Backends/Backends/Implementations/DrWebScanBackend.cs index b042b52..a98dcb6 100644 --- a/MalwareMultiScan.Backends/Backends/Implementations/DrWebScanBackend.cs +++ b/MalwareMultiScan.Backends/Backends/Implementations/DrWebScanBackend.cs @@ -1,5 +1,3 @@ -using System; -using System.IO; using System.Text.RegularExpressions; using MalwareMultiScan.Backends.Backends.Abstracts; using Microsoft.Extensions.Logging; @@ -14,9 +12,6 @@ namespace MalwareMultiScan.Backends.Backends.Implementations public override string Id { get; } = "drweb"; - public override DateTime DatabaseLastUpdate => - File.GetLastWriteTime("/var/opt/drweb.com/version/version.ini"); - protected override string BackendPath { get; } = "/usr/bin/drweb-ctl"; protected override Regex MatchRegex { get; } = diff --git a/MalwareMultiScan.Backends/Backends/Implementations/KesScanBackend.cs b/MalwareMultiScan.Backends/Backends/Implementations/KesScanBackend.cs index 6127780..2448351 100644 --- a/MalwareMultiScan.Backends/Backends/Implementations/KesScanBackend.cs +++ b/MalwareMultiScan.Backends/Backends/Implementations/KesScanBackend.cs @@ -1,5 +1,3 @@ -using System; -using System.IO; using System.Text.RegularExpressions; using MalwareMultiScan.Backends.Backends.Abstracts; using Microsoft.Extensions.Logging; @@ -14,9 +12,6 @@ namespace MalwareMultiScan.Backends.Backends.Implementations public override string Id { get; } = "kes"; - public override DateTime DatabaseLastUpdate => - File.GetLastWriteTime("/var/opt/kaspersky/kesl/common/updates/avbases/klsrl.dat"); - protected override string BackendPath { get; } = "/bin/bash"; protected override Regex MatchRegex { get; } = diff --git a/MalwareMultiScan.Backends/Backends/Implementations/McAffeeScanBackend.cs b/MalwareMultiScan.Backends/Backends/Implementations/McAffeeScanBackend.cs index 1791d8a..9c4d76a 100644 --- a/MalwareMultiScan.Backends/Backends/Implementations/McAffeeScanBackend.cs +++ b/MalwareMultiScan.Backends/Backends/Implementations/McAffeeScanBackend.cs @@ -1,5 +1,3 @@ -using System; -using System.IO; using System.Text.RegularExpressions; using MalwareMultiScan.Backends.Backends.Abstracts; using Microsoft.Extensions.Logging; @@ -14,9 +12,6 @@ namespace MalwareMultiScan.Backends.Backends.Implementations public override string Id { get; } = "mcafeee"; - public override DateTime DatabaseLastUpdate => - File.GetLastWriteTime("/usr/local/uvscan/avvscan.dat"); - protected override string BackendPath { get; } = "/usr/local/uvscan/uvscan"; protected override bool ThrowOnNonZeroExitCode { get; } = false; diff --git a/MalwareMultiScan.Backends/Backends/Implementations/SophosScanBackend.cs b/MalwareMultiScan.Backends/Backends/Implementations/SophosScanBackend.cs index 8c9cfe9..9b8cecd 100644 --- a/MalwareMultiScan.Backends/Backends/Implementations/SophosScanBackend.cs +++ b/MalwareMultiScan.Backends/Backends/Implementations/SophosScanBackend.cs @@ -1,5 +1,3 @@ -using System; -using System.IO; using System.Text.RegularExpressions; using MalwareMultiScan.Backends.Backends.Abstracts; using Microsoft.Extensions.Logging; @@ -14,9 +12,6 @@ namespace MalwareMultiScan.Backends.Backends.Implementations public override string Id { get; } = "sophos"; - public override DateTime DatabaseLastUpdate => - File.GetLastWriteTime("/opt/sophos-av/lib/sav/vdlsync.upd"); - protected override string BackendPath { get; } = "/opt/sophos-av/bin/savscan"; protected override bool ThrowOnNonZeroExitCode { get; } = false; diff --git a/MalwareMultiScan.Backends/Backends/Implementations/WindowsDefenderScanBackend.cs b/MalwareMultiScan.Backends/Backends/Implementations/WindowsDefenderScanBackend.cs index 2dd4129..8eb69b0 100644 --- a/MalwareMultiScan.Backends/Backends/Implementations/WindowsDefenderScanBackend.cs +++ b/MalwareMultiScan.Backends/Backends/Implementations/WindowsDefenderScanBackend.cs @@ -1,5 +1,3 @@ -using System; -using System.IO; using System.Text.RegularExpressions; using MalwareMultiScan.Backends.Backends.Abstracts; using Microsoft.Extensions.Logging; @@ -14,9 +12,6 @@ namespace MalwareMultiScan.Backends.Backends.Implementations public override string Id { get; } = "windows-defender"; - public override DateTime DatabaseLastUpdate => - File.GetLastWriteTime("/opt/engine/mpavbase.vdm"); - protected override string BackendPath { get; } = "/opt/mpclient"; protected override Regex MatchRegex { get; } = diff --git a/MalwareMultiScan.Shared/Data/Responses/ResultResponse.cs b/MalwareMultiScan.Shared/Data/Responses/ResultResponse.cs index 0d33c63..0f7542a 100644 --- a/MalwareMultiScan.Shared/Data/Responses/ResultResponse.cs +++ b/MalwareMultiScan.Shared/Data/Responses/ResultResponse.cs @@ -1,18 +1,17 @@ using System; +using System.ComponentModel.DataAnnotations; using System.Linq; namespace MalwareMultiScan.Shared.Data.Responses { public class ResultResponse { + [Required] public string Backend { get; set; } + [Required] public bool Success { get; set; } - - public DateTime? DatabaseLastUpdate { get; set; } - - public bool Detected => Threats?.Any() == true; - + public string[] Threats { get; set; } } } \ No newline at end of file diff --git a/MalwareMultiScan.Shared/Interfaces/IScanBackend.cs b/MalwareMultiScan.Shared/Interfaces/IScanBackend.cs index e10d3c5..dcf0411 100644 --- a/MalwareMultiScan.Shared/Interfaces/IScanBackend.cs +++ b/MalwareMultiScan.Shared/Interfaces/IScanBackend.cs @@ -10,8 +10,6 @@ namespace MalwareMultiScan.Shared.Interfaces { public string Id { get; } - public DateTime DatabaseLastUpdate { get; } - public Task ScanAsync(string path, CancellationToken cancellationToken); public Task ScanAsync(Uri uri, CancellationToken cancellationToken); public Task ScanAsync(IFormFile file, CancellationToken cancellationToken); diff --git a/MalwareMultiScan.Worker/Controllers/ScanController.cs b/MalwareMultiScan.Worker/Controllers/ScanController.cs index c41dadd..230e440 100644 --- a/MalwareMultiScan.Worker/Controllers/ScanController.cs +++ b/MalwareMultiScan.Worker/Controllers/ScanController.cs @@ -12,6 +12,15 @@ namespace MalwareMultiScan.Worker.Controllers [Produces("application/json")] public class ScanController : ControllerBase { + + [HttpGet] + [ProducesResponseType(StatusCodes.Status200OK)] + [Route("/ping")] + public IActionResult Ping() + { + return Ok("pong"); + } + [HttpPost] [ProducesResponseType(StatusCodes.Status202Accepted)] [ProducesResponseType(StatusCodes.Status400BadRequest)] diff --git a/MalwareMultiScan.Worker/Jobs/ScanJob.cs b/MalwareMultiScan.Worker/Jobs/ScanJob.cs index 9fa7c05..7dcf178 100644 --- a/MalwareMultiScan.Worker/Jobs/ScanJob.cs +++ b/MalwareMultiScan.Worker/Jobs/ScanJob.cs @@ -78,7 +78,6 @@ namespace MalwareMultiScan.Worker.Jobs { response.Success = true; response.Threats = await scanMethod(cancellationToken); - response.DatabaseLastUpdate = _backend.DatabaseLastUpdate; } catch (Exception exception) {