Propòsit
Aquest mòdul permet l’escaneig d’arxius mitjançant el servei d’antivirus Centrals del CTTI.
Instal.lació i Configuració
Instal.lació
Per tal d’instal-lar el mòdul d’Antivirus es pot incloure automàticament a través de l’eina de suport al desenvolupament o bé afegir manualment en el pom.xml de l’aplicació la següent dependència:
<canigo.integration.antivirus.version>[2.4.0,2.5.0)</canigo.integration.antivirus.version>
<dependency>
<groupId>cat.gencat.ctti</groupId>
<artifactId>canigo.integration.antivirus</artifactId>
<version>${canigo.integration.antivirus.version}</version>
</dependency>
Configuració
La configuració es realitza automàticament a partir de la eina de suport al desenvolupament.
Ubicació proposada: <PROJECT_ROOT>/src/main/resources/config/props/antivirus.properties
Propietat | Requerit | Descripció |
---|---|---|
*.antivirus.remote | Sí | Paràmetre que indica si l’escaneig dels arxius es realitza de forma remota o no. Si fos de forma remota l’arxiu a escanejar s’ha de pujar abans al servidor d’antivirus centrals, procés que fa automàticament el mòdul. En cas de remote a fals s’enten que l’arxiu ja es troba pujat al servidor d’antivirus centrals. Valor per defecte: true |
*.antivirus.serverIp | Sí | IP del Host on es troba el Servidor d’antivirus Centrals. antivirus.intranet.gencat.cat per entorns productius preproduccio.antivirus.intranet.gencat.cat per entorns preproductius i d’altres |
*.antivirus.serverPort | Sí | Port del Host on es troba el Servidor d’antivirus Centrals. Valor per defecte: 1344 |
*.antivirus.numDayDBExpirationWarning | Sí | Número de dies que han de passar per que una definició de virus de la base de dades d’antivirus centrals es consideri caducada. Valor per defecte: 15 |
*.antivirus.failRetryTime | No | Mil·lisegons d’espera màxima per obrir la connexió al servidor d’antivirus. Valor per defecte: 30000 |
*.antivirus.readWriteTime | No | Mil·lisegons d’espera màxima per obtenir resposta d’una consulta al servidor d’antivirus. Valor per defecte: 3600000 |
Utilització del Mòdul
Per a utilizar aquest mòdul s’ha de demanar la següent llibreria enviant un correu a la bústia canigó oficina-tecnica.canigo.ctti@gencat.cat al no estar disponible a cap repositori públic Maven:
- Versió mòdul antivirus < 1.3.2: llibreria “sym-7.5.jar” configurant el pom.xml amb:
<dependency>
<groupId>sym</groupId>
<artifactId>sym</artifactId>
<version>7.5</version>
</dependency>
- Versió mòdul antivirus >= 1.3.2 i < 2.2.0: llibreria “scanengine-api-7.0.0.8.jar” configurant el pom.xml amb:
<dependency>
<groupId>com.symantec.scanengine.api</groupId>
<artifactId>scanengine-api</artifactId>
<version>7.0.0.8</version>
</dependency>
- Versió mòdul antivirus >= 2.2.0: llibreria “scanengine-api-7.9.2.jar” configurant el pom.xml amb:
<dependency>
<groupId>com.symantec.scanengine.api</groupId>
<artifactId>scanengine-api</artifactId>
<version>7.9.2</version>
</dependency>
Aquestes llibreries ja estan incorporades internament al SIC (Servei d’Integració Contínua) per a compilacions de releases d’aplicacions
Exemple d’ús
AntivirusServiceController.java
Endpoint de l’aplicació que publica el servei de l’antivirus
import java.io.InputStream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.sun.jersey.core.header.FormDataContentDisposition;
import com.sun.jersey.multipart.FormDataParam;
import cat.gencat.plantilla32.service.AntivirusService;
@RestController
@RequestMapping("/antivirus")
public class AntivirusServiceController {
@Autowired
AntivirusService antivirusService;
@PostMapping(consumes = {MediaType.MULTIPART_FORM_DATA_VALUE},
produces = { MediaType.APPLICATION_JSON_VALUE })
public String scan(@FormDataParam("file") InputStream inputStream,
@FormDataParam("file") FormDataContentDisposition fileDetail) {
return antivirusService.scan(inputStream);
}
}
AntivirusService.java
Classe java on es realitza la lògica de la operació i es crida al mòdul de l’antivirus
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.h2.util.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import cat.gencat.ctti.canigo.arch.integration.antivirus.Antivirus;
import cat.gencat.ctti.canigo.arch.integration.antivirus.ResultatEscaneig;
import cat.gencat.ctti.canigo.arch.integration.antivirus.beans.InfectionInfo;
import cat.gencat.ctti.canigo.arch.integration.antivirus.exceptions.AntivirusException;
@Service("antivirusService")
@Lazy
public class AntivirusService {
@Autowired
private Antivirus service;
private static final Logger log = LoggerFactory.getLogger(AntivirusService.class);
/**
* Escaneig de l'arxiu pujat al servidor
*
*/
public String scan(InputStream file){
String resultat = null;
String message = null;
log.info("AntivirusAction [scan] - Inici");
ResultatEscaneig res = null;
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
IOUtils.copy(file, out);
res = service.scan(out.toByteArray());
if (res != null) {
switch (res.getEstat()) {
case 0:
log.info("AntivirusAction [scan] - arxiu sense Virus");
resultat = "Arxiu sense Virus";
break;
case -1:
log.info("AntivirusAction [scan] - arxiu amb Virus!");
StringBuffer sb = new StringBuffer();
sb.append("Arxiu amb Virus!");
if(res.getArrayVirus()!=null){
for(InfectionInfo i : res.getArrayVirus()){
sb.append(i.getFileName() + " - " + i.getViolationName() + "; ");
}
resultat = sb.toString();
}
break;
case 1:
log.info("AntivirusAction [scan] - Warning");
resultat = res.getMissatge();
break;
default:
log.info("AntivirusAction [scan] - Error en el procés d'escaneig");
resultat = "S'ha produit un error";
}
}
message = "Resultat del escaneig: " + resultat;
log.info("AntivirusAction [scan] - Final");
} catch (AntivirusException ae) {
log.error("AntivirusException - Antivirus ("+ service.getClass()+"): " + service
+ " " + ae.getStackTrace());
message = "Resultat del escaneig(Error): " + ae.getMessage();
} catch (IOException e) {
log.error("AntivirusException - Antivirus ("+ service.getClass()+"): " + service
+ " " + e.getStackTrace());
message = "Resultat del escaneig(Error): " + e.getMessage();
}
return message;
}
}
Respostes servei antivirus
L’objecte cat.gencat.ctti.canigo.arch.integration.antivirus.ResultatEscaneig
és l’encarregat d’interpretar la informació de la resposta del servei de l’antivirus. Aquest objecte conté els mètodes:
-
int getEstat()
: Número enter que representa l’estat de finalització del procés d’escaneig.o STATUS_OK = 0
o STATUS_KO = -1
o STATUS_WARN = 1
-
String getMissatge()
: String que emmagatzemarà la informació de les amenaces trobades en el procés d’escaneig. Si no hi hagués cap el seu valor serà null -
List<InfectionInfo> getArrayVirus()
: Llistat d’objectes InfectionInfo. Aquests objectes representen cada amenaça detectada en l’escaneig. Cada objecte InfectionInfo disposa dels següents camps:o String violationId
o String violationName
o String threadCategory
o String fileName
o String disposition
El conjunt de dades que retornarà es pot resumir amb el següent quadre:
Cas | Estat | Missatge | ArrayVirus |
---|---|---|---|
KO | -1 | [string amb la informació del virus] | [LLista d’objetes de tipus InfectionInfo amb informació de les amenaces detectades] |
OK | 0 | null | null |
WARN (No s’ha pogut accedir al fitxer) | 1 | FILE_ACCESS_FAILED | null |
WARN(Error intern al servidor) | 1 | INTERNAL_SERVER_ERROR | null |
WARN(no hi ha llicència disponible) | 1 | NO_AV_LICENSE | null |
WARN(base de dades antivirus caducada) | 1 | Base de dades de la definició de l’antivirus caducada | null |