-1

In fact with Mule ESB I use an SFTP connector to transfer files and a Java component that implements ClamAV to be able to analyze them. My concern is that I can not recover the file that is in the payload to pass to the scan method that expects an InputStream while the payload sends me a String. Has anyone ever used ClamAV with Mule ESB

Thank you

<flow name="ScanWithClamAvAndTransferFileOK">
        <sftp:inbound-endpoint connector-ref="SFTP" host="${sftp.host}" port="${sftp.port}" path="${sftp.path}" user="${sftp.user}" password="${sftp.password}" responseTimeout="30000" doc:name="Transfer file to SFTP Server"/>
        <component class="reporting.ClamAvTranformer" doc:name="Antivirus ClamAV"/>
        <file:outbound-endpoint path="/home/test" connector-ref="File" responseTimeout="10000" outputPattern="#[function:datestamp]-#[message.inboundProperties['originalFilename']]" doc:name="File"/>
    </flow>
public Object onCall(MuleEventContext eventContext) throws Exception {
        // TODO Auto-generated method stub
        MuleMessage message = eventContext.getMessage();
        byte[] reply = getReply((SftpInputStream) message.getPayload());
        return handleReply(reply);
    }

    private Object handleReply(byte[] reply) throws Exception{
        ResponseDTO response = new ResponseDTO();
        if (ClamAVClient.isCleanReply(reply)) {
            response.setResponseType("Scan réussi avec succès !");
        } else {
            response.setResponseType("Scan rejeté !");
            response.setMessage(byteToString(reply));
            //response.setResultType(ResultType.BUSINESS_FAULT.toString());
        }
        return response;
    }

    private byte[] getReply(InputStream stream) throws IllegalStateException{
        try {
            return clamAV.scan(stream);
        } catch (Exception e) {
            throw new IllegalStateException("Le fichier ne peut pas etre scanner, cause : "+e.getMessage(),e);
        }
    }

    private String byteToString(byte[] reply) throws Exception{
        return new String(reply, "UTF-8").trim();
    }

2 Answers2

0

The problem here (I guess) is that once ClamAV consumes the InputStream, there is nothing more to pass along. I have a similar use case, where a single InputStream is received, and this is to be scanned with ClamAV and passed to the database. This has been solved by "multicasting" the InputStream into two OutputStream, which is in turn read by two InputStreams, one going to the database, one to ClamAV. These two streams then need to both be read in order to continue the stream. If the virus-scan fails, the transaction will be aborted and rolled back, and whatever was sent to the database will be removed.

This approach might be a bit difficult in your case. An alternative could be to read the InputStream into a byte-array, and then create streams of this byte-array, one to send to ClamAV, and if it passes, one to pass along. Note that this will mean that the entire file will be held in memory, so make sure Mule has enough.

Tobb
  • 11,850
  • 6
  • 52
  • 77
0

In fact the problem is that I get to see the byte array in the buffer at the payload level but that I pass the object to Clamav scan method it returns an error saying that the object is null:

enter image description here

Here is the mistake I have:

ERROR 2019-07-04 10:51:30,873 [[reporting].ScanWithClamAvAndTransferFileOK.stage1.02] org.mule.exception.DefaultMessagingExceptionStrategy:

Message : java.lang.IllegalStateException: Le fichier ne peut pas etre scanner, cause : null. Component that caused exception is: DefaultJavaComponent{ScanWithClamAvAndTransferFileOK.component.853887645}.

See image:

enter image description here

Community
  • 1
  • 1