ClamAVScan - antivirus scan mailet using ClamAV's CLAMD daemon

ClamAVScan does an antivirus scan check using the ClamAV daemon CLAMD (see

It interacts directly with the daemon using the "stream" method, which should have the lowest possible overhead. I've done tests getting less than 2.5 seconds of CPU per megabyte scanned on a 1.5 GHz CPU.

The CLAMD daemon will typically reside on localhost, but could reside on a different host. It may also consist on a set of multiple daemons, each residing on a different server and on different IP number. In such case a DNS host name with multiple IP adresses (round-robin load sharing) is supported by the mailet (but on the same port number).

ClamAV runs on Linux, but there are ports to other OS too. I have ClamAVScan working on Windows XP and 2k using ClamAV For Windows (see

Initialization parameters

The init parameters are as follows:


The actions performed are as follows:

ClamAV configuration notes

The following parameters are required in clamav.conf:

A James config.xml example

Here follows an example of config.xml definitions deploying CLAMD on localhost, and handling the infected messages:


<!-- Do an antivirus scan -->
<mailet match="All" class="ClamAVScan" onMailetException="ignore"/>

<!-- If infected go to virus processor -->
<mailet match="HasMailAttributeWithValue=org.apache.james.infected, true" class="ToProcessor">
   <processor> virus </processor>

<!-- Check attachment extensions for possible viruses -->
<mailet match="AttachmentFileNameIs=-d -z *.exe *.com *.bat *.cmd *.pif *.scr *.vbs *.avi *.mp3 *.mpeg *.shs" class="ToProcessor" onMatchException="noMatch">
   <processor> bad-extensions </processor>


<!-- Messages containing viruses -->
<processor name="virus">

   <!-- To avoid a loop while bouncing -->
   <mailet match="All" class="SetMailAttribute">
      <org.apache.james.infected>true, bouncing</org.apache.james.infected>

   <mailet match="SMTPAuthSuccessful" class="Bounce">
      <notice>Warning: We were unable to deliver the message below because it was found infected by virus(es).</notice>
   <mailet match="All" class="ToRepository">
   <mailet match="All" class="Null"/>


The reason for the onMailetException="ignore" entry in the ClamAVScan mailet "call" is to avoid losing the message if an Exception is unlikely thrown, but it is just my choice, as I have a "second line" defense blocking "bad extensions" with an "AttachmentFileNameIs=" call.

ClamAVScan (last edited 2009-09-20 22:58:32 by localhost)