From 4fdc195b91e9b5f25c41d8c0b8275b766438b759 Mon Sep 17 00:00:00 2001 From: "adel.kalimullin" Date: Thu, 26 Dec 2024 17:24:42 +0300 Subject: [PATCH 01/11] SUPPORT-8836:fixes --- .../av/service/service/FileScanService.java | 88 +++++-------------- 1 file changed, 23 insertions(+), 65 deletions(-) diff --git a/src/main/java/ru/micord/av/service/service/FileScanService.java b/src/main/java/ru/micord/av/service/service/FileScanService.java index 33f4771..6ef6124 100644 --- a/src/main/java/ru/micord/av/service/service/FileScanService.java +++ b/src/main/java/ru/micord/av/service/service/FileScanService.java @@ -2,15 +2,9 @@ package ru.micord.av.service.service; import java.io.File; import java.io.IOException; -import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,16 +27,9 @@ public class FileScanService { public ScanResult scanFile(MultipartFile file) { File tempFile = null; - LocalDateTime startTime; - LocalDateTime stopTime; try { tempFile = saveFile(file); - startTime = LocalDateTime.now(); - String rawResult = runKeslScan(tempFile); - stopTime = LocalDateTime.now(); - return parseKeslResponse(rawResult, startTime, stopTime, tempFile, - file.getOriginalFilename() - ); + return runKeslScan(tempFile); } catch (Exception e) { throw new AvException("Error scanning file: " + file.getOriginalFilename(), e); @@ -69,64 +56,35 @@ public class FileScanService { return tempFile.toFile(); } - private String runKeslScan(File file) throws IOException, InterruptedException { + private ScanResult runKeslScan(File file) throws IOException, InterruptedException { ProcessBuilder processBuilder = new ProcessBuilder(KESL_CONTROL, KESL_SCAN, file.getAbsolutePath() ); processBuilder.redirectErrorStream(true); Process process = processBuilder.start(); - try (InputStream inputStream = process.getInputStream()) { - String result = new String(inputStream.readAllBytes()); - int exitCode = process.waitFor(); - if (exitCode != 0 && exitCode != 72) { - throw new AvException("KESL error, exit code: " + exitCode); - } - return result; - } - } - - private ScanResult parseKeslResponse(String rawResult, LocalDateTime startTime, - LocalDateTime stopTime, File file, String originalFilename) { - Map scanResults = new HashMap<>(); - List verdicts = new ArrayList<>(); - List threats = new ArrayList<>(); - String verdict = null; - - for (String line : rawResult.split("\n")) { - if (line.startsWith("Infected objects")) { - verdict = extractInteger(line) > 0 - ? ScanResult.Scan.VERDICT_INFECTED - : ScanResult.Scan.VERDICT_CLEAN; - if (ScanResult.Scan.VERDICT_INFECTED.equals(verdict)) - threats.add(new ScanResult.Scan.Threat("", file.getAbsolutePath())); - } - if (line.startsWith("Scan errors") && extractInteger(line) > 0) { - verdict = "error"; - } - } - if (verdict != null) { - scanResults.put(originalFilename, - new ScanResult.Scan(startTime.toString(), stopTime.toString(), - threats.toArray(new ScanResult.Scan.Threat[0]), verdict - ) + int exitCode = process.waitFor(); + if (exitCode == 0) { + return new ScanResult( + null, + null, + 100, + null, + "completed", + new String[] {ScanResult.Scan.VERDICT_CLEAN} ); - verdicts.add(verdict); } - return new ScanResult(startTime.toString(), stopTime.toString(), 100, scanResults, "completed", - verdicts.toArray(new String[0]) - ); - } - - private int extractInteger(String line) { - String[] parts = line.split(":"); - if (parts.length > 1) { - try { - return Integer.parseInt(parts[1].trim()); - } - catch (NumberFormatException e) { - throw new RuntimeException(e); - } + else if (exitCode == 72) { + return new ScanResult( + null, + null, + 100, + null, + "completed", + new String[] {ScanResult.Scan.VERDICT_INFECTED} + ); + } + else { + throw new AvException("KESL error, exit code: " + exitCode); } - return 0; } } From 384a97d629e4784870981ca5360cb503424d3166 Mon Sep 17 00:00:00 2001 From: "adel.kalimullin" Date: Fri, 27 Dec 2024 12:41:45 +0300 Subject: [PATCH 02/11] SUPPORT-8836:refactor --- .../controller/FileScanController.java | 8 +++--- .../micord/av/service/model/ScanResult.java | 17 ------------ .../av/service/service/FileScanService.java | 26 +++---------------- 3 files changed, 7 insertions(+), 44 deletions(-) delete mode 100644 src/main/java/ru/micord/av/service/model/ScanResult.java diff --git a/src/main/java/ru/micord/av/service/controller/FileScanController.java b/src/main/java/ru/micord/av/service/controller/FileScanController.java index dd7d0be..b0ec15f 100644 --- a/src/main/java/ru/micord/av/service/controller/FileScanController.java +++ b/src/main/java/ru/micord/av/service/controller/FileScanController.java @@ -9,7 +9,6 @@ import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.multipart.MultipartFile; -import ru.micord.av.service.model.ScanResult; import ru.micord.av.service.service.FileScanService; /** @@ -32,11 +31,10 @@ public class FileScanController { return ResponseEntity.badRequest().build(); } try { - ScanResult result = fileScanService.scanFile(file); - LOGGER.info("Scan result for file {}: status - {}, verdicts - {}", + int result = fileScanService.scanFile(file); + LOGGER.info("Scan result for file {}: exitCode - {}", file.getOriginalFilename(), - result.status(), - String.join(", ", result.verdicts())); + result); return ResponseEntity.ok(result); } catch (Exception e) { diff --git a/src/main/java/ru/micord/av/service/model/ScanResult.java b/src/main/java/ru/micord/av/service/model/ScanResult.java deleted file mode 100644 index 2f9196f..0000000 --- a/src/main/java/ru/micord/av/service/model/ScanResult.java +++ /dev/null @@ -1,17 +0,0 @@ -package ru.micord.av.service.model; - -import java.util.Map; - -/** - * @author Adel Kalimullin - */ -public record ScanResult(String completed, String created, Integer progress, - Map scan_result, String status, String[] verdicts) { - public record Scan(String started, String stopped, Threat[] threats, String verdict) { - public static final String VERDICT_CLEAN = "clean"; - public static final String VERDICT_INFECTED = "infected"; - - public record Threat(String name, String object) { - } - } -} \ No newline at end of file diff --git a/src/main/java/ru/micord/av/service/service/FileScanService.java b/src/main/java/ru/micord/av/service/service/FileScanService.java index 6ef6124..144d24d 100644 --- a/src/main/java/ru/micord/av/service/service/FileScanService.java +++ b/src/main/java/ru/micord/av/service/service/FileScanService.java @@ -12,7 +12,6 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import ru.micord.av.service.exception.AvException; -import ru.micord.av.service.model.ScanResult; /** * @author Adel Kalimullin @@ -25,7 +24,7 @@ public class FileScanService { @Value("${file.upload.directory}") private String uploadDirectory; - public ScanResult scanFile(MultipartFile file) { + public int scanFile(MultipartFile file) { File tempFile = null; try { tempFile = saveFile(file); @@ -56,32 +55,15 @@ public class FileScanService { return tempFile.toFile(); } - private ScanResult runKeslScan(File file) throws IOException, InterruptedException { + private int runKeslScan(File file) throws IOException, InterruptedException { ProcessBuilder processBuilder = new ProcessBuilder(KESL_CONTROL, KESL_SCAN, file.getAbsolutePath() ); processBuilder.redirectErrorStream(true); Process process = processBuilder.start(); int exitCode = process.waitFor(); - if (exitCode == 0) { - return new ScanResult( - null, - null, - 100, - null, - "completed", - new String[] {ScanResult.Scan.VERDICT_CLEAN} - ); - } - else if (exitCode == 72) { - return new ScanResult( - null, - null, - 100, - null, - "completed", - new String[] {ScanResult.Scan.VERDICT_INFECTED} - ); + if (exitCode == 0 || exitCode == 72) { + return exitCode; } else { throw new AvException("KESL error, exit code: " + exitCode); From 1a771c33f9baad751c3d393d89fc7526cdae1465 Mon Sep 17 00:00:00 2001 From: "adel.ka" Date: Tue, 31 Dec 2024 02:21:31 +0300 Subject: [PATCH 03/11] SUPPORT-8836:fixes --- .../av/service/service/FileScanService.java | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/main/java/ru/micord/av/service/service/FileScanService.java b/src/main/java/ru/micord/av/service/service/FileScanService.java index 144d24d..0f842b6 100644 --- a/src/main/java/ru/micord/av/service/service/FileScanService.java +++ b/src/main/java/ru/micord/av/service/service/FileScanService.java @@ -28,9 +28,9 @@ public class FileScanService { File tempFile = null; try { tempFile = saveFile(file); - return runKeslScan(tempFile); + return runKeslScan(tempFile, file.getOriginalFilename()); } - catch (Exception e) { + catch (IOException | InterruptedException e) { throw new AvException("Error scanning file: " + file.getOriginalFilename(), e); } finally { @@ -47,15 +47,14 @@ public class FileScanService { private File saveFile(MultipartFile file) throws IOException { Path uploadPath = Paths.get(uploadDirectory); - if (!Files.exists(uploadPath)) { - Files.createDirectories(uploadPath); - } - Path tempFile = Files.createTempFile(uploadPath, "kesl-upload-", ".tmp"); - file.transferTo(tempFile.toFile()); - return tempFile.toFile(); + Files.createDirectories(uploadPath); + Path tempFilePath = Files.createTempFile(uploadPath, "kesl-upload-", ".tmp"); + File tempFile = tempFilePath.toFile(); + file.transferTo(tempFile); + return tempFile; } - private int runKeslScan(File file) throws IOException, InterruptedException { + private int runKeslScan(File file, String originalFileName) throws IOException, InterruptedException { ProcessBuilder processBuilder = new ProcessBuilder(KESL_CONTROL, KESL_SCAN, file.getAbsolutePath() ); @@ -65,8 +64,6 @@ public class FileScanService { if (exitCode == 0 || exitCode == 72) { return exitCode; } - else { - throw new AvException("KESL error, exit code: " + exitCode); - } + throw new AvException("KESL error scanning file: " + originalFileName + ", exit code: " + exitCode); } } From 7a3e4b1d503eb38f6654aa067dc5062f383197b2 Mon Sep 17 00:00:00 2001 From: "adel.ka" Date: Tue, 31 Dec 2024 02:40:48 +0300 Subject: [PATCH 04/11] SUPPORT-8836:fixes --- .../java/ru/micord/av/service/service/FileScanService.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/ru/micord/av/service/service/FileScanService.java b/src/main/java/ru/micord/av/service/service/FileScanService.java index 0f842b6..c71f8d6 100644 --- a/src/main/java/ru/micord/av/service/service/FileScanService.java +++ b/src/main/java/ru/micord/av/service/service/FileScanService.java @@ -64,6 +64,7 @@ public class FileScanService { if (exitCode == 0 || exitCode == 72) { return exitCode; } - throw new AvException("KESL error scanning file: " + originalFileName + ", exit code: " + exitCode); + throw new AvException( + "KESL error scanning file: " + originalFileName + ", exit code: " + exitCode); } } From 1e4a9a234e51436e10caadfbca37e821a61dde82 Mon Sep 17 00:00:00 2001 From: "adel.ka" Date: Tue, 31 Dec 2024 03:07:39 +0300 Subject: [PATCH 05/11] SUPPORT-8836:fixes --- .../ru/micord/av/service/service/FileScanService.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/ru/micord/av/service/service/FileScanService.java b/src/main/java/ru/micord/av/service/service/FileScanService.java index c71f8d6..cb77634 100644 --- a/src/main/java/ru/micord/av/service/service/FileScanService.java +++ b/src/main/java/ru/micord/av/service/service/FileScanService.java @@ -61,10 +61,10 @@ public class FileScanService { processBuilder.redirectErrorStream(true); Process process = processBuilder.start(); int exitCode = process.waitFor(); - if (exitCode == 0 || exitCode == 72) { - return exitCode; + if (exitCode != 0 && exitCode != 72) { + throw new AvException( + "KESL error scanning file: " + originalFileName + ", exit code: " + exitCode); } - throw new AvException( - "KESL error scanning file: " + originalFileName + ", exit code: " + exitCode); + return exitCode; } } From c22fa63d150afdcf14b29d5f70fdf8eda55185d6 Mon Sep 17 00:00:00 2001 From: Alexandr Shalaginov Date: Fri, 10 Jan 2025 11:32:42 +0300 Subject: [PATCH 06/11] SUPPORT-8841: check if file is password protected --- README.md | 34 +++++++++++++++---- .../av/service/service/FileScanService.java | 32 ++++++++++++++--- src/main/resources/application.properties | 1 - src/main/resources/application.yaml | 8 +++++ 4 files changed, 62 insertions(+), 13 deletions(-) delete mode 100644 src/main/resources/application.properties create mode 100644 src/main/resources/application.yaml diff --git a/README.md b/README.md index a6561fc..de7ce7d 100644 --- a/README.md +++ b/README.md @@ -22,14 +22,34 @@ ## **Конфигурация и запуск** ### **1. Конфигурация параметров для сервиса** -Для корректного запуска сервиса добавьте следующие параметры в файл `application.properties`: -```properties -file.upload.directory=/tmp/uploaded_files # Путь для хранения временных файлов -spring.servlet.multipart.max-file-size=10MB # Максимальный размер загружаемого файла -spring.servlet.multipart.max-request-size=10MB # Максимальный размер запроса -server.port=8080 # Порт, на котором работает сервис +Для корректного запуска сервиса добавьте следующие параметры в файл `application.yaml`: +```yaml +file: + upload: + directory: '/tmp/uploaded_files' # Путь для хранения временных файлов +spring: + servlet: + multipart: + max-file-size: 10MB # Максимальный размер загружаемого файла + max-request-size: 10MB # Максимальный размер запроса +server: + port: 8080 # Порт, на котором работает сервис +``` +Если KESL использует русскую локализацию, то следует в файл `application.yaml` добавить следующий параметр: +```yaml +password: + protected: + result: + name: 'Объекты, защищенные паролем' +``` +Для английской локализации: +```yaml +password: + protected: + result: + name: 'Password-protected objects' ``` ### **2. Запуск JAR-файла с конфигурационным файлом** ```bash -java -jar app.jar --spring.config.location=file:/path/to/your/application.properties +java -jar app.jar --spring.config.location=file:/path/to/your/application.yaml ``` \ No newline at end of file diff --git a/src/main/java/ru/micord/av/service/service/FileScanService.java b/src/main/java/ru/micord/av/service/service/FileScanService.java index cb77634..ac5b9b6 100644 --- a/src/main/java/ru/micord/av/service/service/FileScanService.java +++ b/src/main/java/ru/micord/av/service/service/FileScanService.java @@ -2,6 +2,7 @@ package ru.micord.av.service.service; import java.io.File; import java.io.IOException; +import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -23,6 +24,8 @@ public class FileScanService { private static final Logger LOGGER = LoggerFactory.getLogger(FileScanService.class); @Value("${file.upload.directory}") private String uploadDirectory; + @Value("${password.protected.result.name:Объекты, защищенные паролем}") + private String passwordProtectedResultName; public int scanFile(MultipartFile file) { File tempFile = null; @@ -60,11 +63,30 @@ public class FileScanService { ); processBuilder.redirectErrorStream(true); Process process = processBuilder.start(); - int exitCode = process.waitFor(); - if (exitCode != 0 && exitCode != 72) { - throw new AvException( - "KESL error scanning file: " + originalFileName + ", exit code: " + exitCode); + + try (InputStream inputStream = process.getInputStream()) { + String result = new String(inputStream.readAllBytes()); + + int exitCode = process.waitFor(); + if (exitCode != 0 && exitCode != 72) { + throw new AvException( + "KESL error scanning file: " + originalFileName + ", exit code: " + exitCode); + } + checkScanResult(result, originalFileName); + + return exitCode; + } + } + + private void checkScanResult(String result, String originalFileName) { + for (String line : result.split("\n")) { + String[] lineParts = line.split(":"); + if (lineParts.length > 1) { + if (lineParts[0].startsWith(passwordProtectedResultName) + && Integer.parseInt(lineParts[1].trim()) > 0) { + throw new AvException("Detected password-protected file: " + originalFileName); + } + } } - return exitCode; } } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties deleted file mode 100644 index ee7a3e8..0000000 --- a/src/main/resources/application.properties +++ /dev/null @@ -1 +0,0 @@ -file.upload.directory = /tmp/uploaded_files diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml new file mode 100644 index 0000000..be42268 --- /dev/null +++ b/src/main/resources/application.yaml @@ -0,0 +1,8 @@ +file: + upload: + directory: '/tmp/uploaded_files' + +password: + protected: + result: + name: 'Объекты, защищенные паролем' \ No newline at end of file From f8482124ba4a64e320b7c402b0139924ca0da4ea Mon Sep 17 00:00:00 2001 From: Alexandr Shalaginov Date: Sat, 11 Jan 2025 11:35:50 +0300 Subject: [PATCH 07/11] SUPPORT-8841: add scan result logs --- .../java/ru/micord/av/service/service/FileScanService.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/ru/micord/av/service/service/FileScanService.java b/src/main/java/ru/micord/av/service/service/FileScanService.java index ac5b9b6..b6cfc9f 100644 --- a/src/main/java/ru/micord/av/service/service/FileScanService.java +++ b/src/main/java/ru/micord/av/service/service/FileScanService.java @@ -66,6 +66,7 @@ public class FileScanService { try (InputStream inputStream = process.getInputStream()) { String result = new String(inputStream.readAllBytes()); + LOGGER.info("File {} scanned with result: {}", originalFileName, result); int exitCode = process.waitFor(); if (exitCode != 0 && exitCode != 72) { @@ -79,6 +80,12 @@ public class FileScanService { } private void checkScanResult(String result, String originalFileName) { + if (!result.contains(passwordProtectedResultName)) { + LOGGER.warn("File scan result doesn't contains \"{}\", " + + "please check property \"password.protected.result.name\" is correct", + passwordProtectedResultName); + } + for (String line : result.split("\n")) { String[] lineParts = line.split(":"); if (lineParts.length > 1) { From f6fea26f850bc38cba639a98d1caa7904ecd04c0 Mon Sep 17 00:00:00 2001 From: Alexandr Shalaginov Date: Mon, 13 Jan 2025 08:18:08 +0300 Subject: [PATCH 08/11] SUPPORT-8841: change to exception --- .../ru/micord/av/service/service/FileScanService.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/ru/micord/av/service/service/FileScanService.java b/src/main/java/ru/micord/av/service/service/FileScanService.java index b6cfc9f..460f013 100644 --- a/src/main/java/ru/micord/av/service/service/FileScanService.java +++ b/src/main/java/ru/micord/av/service/service/FileScanService.java @@ -81,9 +81,11 @@ public class FileScanService { private void checkScanResult(String result, String originalFileName) { if (!result.contains(passwordProtectedResultName)) { - LOGGER.warn("File scan result doesn't contains \"{}\", " - + "please check property \"password.protected.result.name\" is correct", - passwordProtectedResultName); + throw new AvException(String.format( + "File scan result doesn't contains \"%s\", " + + "please check property \"password.protected.result.name\" is correct", + passwordProtectedResultName + )); } for (String line : result.split("\n")) { From deeaa0f561bcaad929ae88d760259b706351dafe Mon Sep 17 00:00:00 2001 From: Alexandr Shalaginov Date: Mon, 13 Jan 2025 13:06:23 +0300 Subject: [PATCH 09/11] SUPPORT-8841: move logging --- .../java/ru/micord/av/service/service/FileScanService.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/ru/micord/av/service/service/FileScanService.java b/src/main/java/ru/micord/av/service/service/FileScanService.java index 460f013..b5f548f 100644 --- a/src/main/java/ru/micord/av/service/service/FileScanService.java +++ b/src/main/java/ru/micord/av/service/service/FileScanService.java @@ -66,9 +66,10 @@ public class FileScanService { try (InputStream inputStream = process.getInputStream()) { String result = new String(inputStream.readAllBytes()); - LOGGER.info("File {} scanned with result: {}", originalFileName, result); int exitCode = process.waitFor(); + + LOGGER.info("File {} scanned with result: {}", originalFileName, result); if (exitCode != 0 && exitCode != 72) { throw new AvException( "KESL error scanning file: " + originalFileName + ", exit code: " + exitCode); From 9ef24f6094ff6509f02f03cc2edd0f70345f79df Mon Sep 17 00:00:00 2001 From: Alexandr Shalaginov Date: Tue, 14 Jan 2025 11:46:05 +0300 Subject: [PATCH 10/11] SUPPORT-8841: 1) add jar encoding utf8 2) change result log to debug --- README.md | 2 +- av-service.service | 2 +- src/main/java/ru/micord/av/service/service/FileScanService.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index de7ce7d..d63fdbf 100644 --- a/README.md +++ b/README.md @@ -51,5 +51,5 @@ password: ``` ### **2. Запуск JAR-файла с конфигурационным файлом** ```bash -java -jar app.jar --spring.config.location=file:/path/to/your/application.yaml +java -jar app.jar --spring.config.location=file:/path/to/your/application.yaml -Dfile.encoding=UTF8 ``` \ No newline at end of file diff --git a/av-service.service b/av-service.service index 100bb24..79be821 100644 --- a/av-service.service +++ b/av-service.service @@ -8,7 +8,7 @@ Type=simple Restart=on-failure User=root WorkingDirectory=/opt/av-service -ExecStart=/usr/bin/java -jar av-service.jar +ExecStart=/usr/bin/java -jar av-service.jar -Dfile.encoding=UTF8 [Install] WantedBy=multi-user.target diff --git a/src/main/java/ru/micord/av/service/service/FileScanService.java b/src/main/java/ru/micord/av/service/service/FileScanService.java index b5f548f..dbb2fcc 100644 --- a/src/main/java/ru/micord/av/service/service/FileScanService.java +++ b/src/main/java/ru/micord/av/service/service/FileScanService.java @@ -69,11 +69,11 @@ public class FileScanService { int exitCode = process.waitFor(); - LOGGER.info("File {} scanned with result: {}", originalFileName, result); if (exitCode != 0 && exitCode != 72) { throw new AvException( "KESL error scanning file: " + originalFileName + ", exit code: " + exitCode); } + LOGGER.debug("File {} scanned with result: {}", originalFileName, result); checkScanResult(result, originalFileName); return exitCode; From 15b200abbcfc9e5c5b6d100a6b526a84bce7afbf Mon Sep 17 00:00:00 2001 From: Alexandr Shalaginov Date: Tue, 14 Jan 2025 14:04:14 +0300 Subject: [PATCH 11/11] SUPPORT-8841: use zt-exec --- pom.xml | 6 +++ .../av/service/service/FileScanService.java | 41 +++++++++---------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/pom.xml b/pom.xml index 07262c6..376be50 100644 --- a/pom.xml +++ b/pom.xml @@ -22,6 +22,12 @@ spring-boot-starter-web + + org.zeroturnaround + zt-exec + 1.12 + + org.springframework.boot spring-boot-starter-test diff --git a/src/main/java/ru/micord/av/service/service/FileScanService.java b/src/main/java/ru/micord/av/service/service/FileScanService.java index dbb2fcc..250d769 100644 --- a/src/main/java/ru/micord/av/service/service/FileScanService.java +++ b/src/main/java/ru/micord/av/service/service/FileScanService.java @@ -2,16 +2,19 @@ package ru.micord.av.service.service; import java.io.File; import java.io.IOException; -import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.concurrent.TimeoutException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; +import org.zeroturnaround.exec.ProcessExecutor; +import org.zeroturnaround.exec.ProcessResult; +import org.zeroturnaround.exec.stream.slf4j.Slf4jStream; import ru.micord.av.service.exception.AvException; /** @@ -33,7 +36,7 @@ public class FileScanService { tempFile = saveFile(file); return runKeslScan(tempFile, file.getOriginalFilename()); } - catch (IOException | InterruptedException e) { + catch (IOException | InterruptedException | TimeoutException e) { throw new AvException("Error scanning file: " + file.getOriginalFilename(), e); } finally { @@ -57,27 +60,23 @@ public class FileScanService { return tempFile; } - private int runKeslScan(File file, String originalFileName) throws IOException, InterruptedException { - ProcessBuilder processBuilder = new ProcessBuilder(KESL_CONTROL, KESL_SCAN, - file.getAbsolutePath() - ); - processBuilder.redirectErrorStream(true); - Process process = processBuilder.start(); + private int runKeslScan(File file, String originalFileName) + throws IOException, InterruptedException, TimeoutException { + ProcessResult processResult = new ProcessExecutor() + .command(KESL_CONTROL, KESL_SCAN, file.getAbsolutePath()) + .redirectOutput(Slf4jStream.of(getClass()).asDebug()) + .readOutput(true) + .execute(); + String processOutput = processResult.outputUTF8(); + int exitCode = processResult.getExitValue(); - try (InputStream inputStream = process.getInputStream()) { - String result = new String(inputStream.readAllBytes()); - - int exitCode = process.waitFor(); - - if (exitCode != 0 && exitCode != 72) { - throw new AvException( - "KESL error scanning file: " + originalFileName + ", exit code: " + exitCode); - } - LOGGER.debug("File {} scanned with result: {}", originalFileName, result); - checkScanResult(result, originalFileName); - - return exitCode; + if (exitCode != 0 && exitCode != 72) { + throw new AvException( + "KESL error scanning file: " + originalFileName + ", exit code: " + exitCode); } + checkScanResult(processOutput, originalFileName); + + return exitCode; } private void checkScanResult(String result, String originalFileName) {