Changeset 173

Show
Ignore:
Timestamp:
01/08/08 21:19:15 (1 year ago)
Author:
jfp
Message:

change clamav filter to use libclamav

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/jsmtpd/src/org/jsmtpd/plugins/filters/ClamAV/ClamAVFilter.java

    r140 r173  
    2121package org.jsmtpd.plugins.filters.ClamAV; 
    2222 
    23 import java.io.IOException; 
    24 import java.net.InetSocketAddress; 
    25 import java.net.Socket; 
    26 import java.net.SocketAddress; 
    27 import java.net.SocketException; 
     23import java.io.ByteArrayInputStream; 
    2824import java.util.LinkedList; 
    29  
     25import net.taldius.clamav.ClamAVScanner; 
     26import net.taldius.clamav.ClamAVScannerFactory; 
     27import net.taldius.clamav.ScannerException; 
    3028import org.apache.commons.logging.Log; 
    3129import org.apache.commons.logging.LogFactory; 
     
    3735 
    3836/** 
    39  
    4037 *  
    4138 * This plugin is a client to the ClamAV antivirus 
    4239 * daemon.<br> 
    4340 *  
     41 * It uses libclamav, available at http://dev.taldius.net/libclamav/ 
    4442 *  
    45  * It connects to a remote daemon (via TCP), passes 
    46  * it the stream to check. Any virus detection  
    47  * makes the filter fail and drop the mail. 
    48  * It generates a new mail to inform the sender.<br> 
    49  *  
    50  * You need to set up a ClamAV daemon, by example 
    51  * on your favourite Linux distro : 
    52  * apt-get install clamav-daemon should do the job 
    53  * chose a port number to bind it to and edit the 
    54  * clamav daemon config file clamd.conf :<br><br> 
    55  * TCPSocket xxx<br> 
    56  * where xxx is your port number 
    57  * <br><br> 
    58  * you should read http://www.clamav.net/doc/ 
    59  * to get info on ClamAV 
    60  * <br> 
    61  * <br><br> 
    62  * 7/3/2005<br> 
    63  * changed Email type, so adapted here 
    6443 * @author Jean-Francois POUX 
    6544 */ 
    6645public class ClamAVFilter implements IFilter { 
    6746 
    68     private String clamdHost; 
    69     private int clamdPort; 
    70     private int socketTimeout; 
    7147    private Log log = LogFactory.getLog(ClamAVFilter.class); 
    72     private int connectionTimeout=90; 
    7348    /** 
    7449     * Will cause a virus detection to automaticly break the chain 
     
    7954 
    8055    public boolean doFilter(Email input) throws FilterTreeFailureException { 
    81         /** 
    82          * Connect to clamd 
    83          * send STREAM 
    84          * read the socket 
    85          * connect to this socket 
    86          * send the email data as bytes 
    87          * close the stream socket 
    88          * read the response 
    89          */ 
    9056        log.debug("Starting ClamAV Scan of "+input.getDiskName()); 
    9157        long time = System.currentTimeMillis(); 
    92         ClamAVChat chat = new ClamAVChat(clamdHost, clamdPort, input.getDataAsByte(), connectionTimeout); 
    93         boolean response =chat.doScan(); 
    94         log.debug("Scanned "+input.getDiskName()+ ", "+input.getSize()+" octs in "+(System.currentTimeMillis()-time)+" ms"); 
    95         if ( response == true) { 
    96             return true; 
    97         } 
     58         
     59        ClamAVScanner scanner = ClamAVScannerFactory.getScanner(); 
     60        ByteArrayInputStream is = new ByteArrayInputStream (input.getDataAsByte()); 
     61         
     62        boolean response; 
     63                try { 
     64                        response = scanner.performScan(is); 
     65                         
     66                        log.debug("Scanned "+input.getDiskName()+ ", "+input.getSize()+" octs in "+(System.currentTimeMillis()-time)+" ms"); 
     67                if ( response == true) { 
     68                    return true; 
     69                } 
    9870 
    99         if (failOnError) { 
    100             if (!input.getFrom().toString().equals("<>")) // is it an internal mail already ? 
    101             { 
    102                 LinkedList<String> messages = new LinkedList<String>(); 
    103                 messages.add(""); 
    104                 messages.add("Hello, this is the Jsmtpd mailer daemon"); 
    105                 messages.add(""); 
    106                 messages.add("I'm affraid I can't deliver your email to " + input.getRcptAsString()); 
    107                 messages.add(""); 
    108                 messages.add(getPluginName() + " has detected the virus : " + chat.getVirus()); 
    109                 messages.add(""); 
    110                 messages.add("This is a fatal error, giving up"); 
    111                 Email error = Email.createInternalMail(input.getFrom(), "Mailer-daemon error, virus found", messages, input); 
    112                 QueueService.getInstance().queueMail(error); 
    113             } 
    114             throw new FilterTreeFailureException(); 
    115         } 
     71                if (failOnError) { 
     72                    if (!input.getFrom().toString().equals("<>")) // is it an internal mail already ? 
     73                    { 
     74                        LinkedList<String> messages = new LinkedList<String>(); 
     75                        messages.add(""); 
     76                        messages.add("Hello, this is the Jsmtpd mailer daemon"); 
     77                        messages.add(""); 
     78                        messages.add("I'm affraid I can't deliver your email to " + input.getRcptAsString()); 
     79                        messages.add(""); 
     80                        messages.add(getPluginName() + " has detected the virus : " + scanner.getMessage()); 
     81                        messages.add(""); 
     82                        messages.add("This is a fatal error, giving up"); 
     83                        Email error = Email.createInternalMail(input.getFrom(), "Mailer-daemon error, virus found", messages, input); 
     84                        QueueService.getInstance().queueMail(error); 
     85                    } 
     86                    throw new FilterTreeFailureException(); 
     87                } 
     88                         
     89                } catch (ScannerException e) { 
     90                        log.error("Failed to scan "+input.getDiskName(),e); 
     91                        return failOnError; 
     92                } 
    11693        return false; 
    11794    } 
    11895 
    119     /* (non-Javadoc) 
    120      * @see jsmtpd.common.IGenericPlugin#getPluginName() 
    121      */ 
    12296    public String getPluginName() { 
    123  
    12497        return "Jsmtpd-ClamAV antivirus filter"; 
    12598    } 
    12699 
    127     /* (non-Javadoc) 
    128      * @see jsmtpd.common.IGenericPlugin#initPlugin() 
    129      */ 
    130100    public void initPlugin() throws PluginInitException { 
    131         /** 
    132          * Read config 
    133          * connect to tcp port 
    134          * check answer of pong 
    135          */ 
    136         log.debug(getPluginName() + " initing"); 
    137  
    138         Socket sock = new Socket(); 
    139         SocketAddress sockaddr = new InetSocketAddress(clamdHost, clamdPort); 
    140         try { 
    141             sock.setSoTimeout(socketTimeout * 1000); 
    142         } catch (SocketException e1) { 
    143             e1.printStackTrace(); 
    144         } 
    145  
    146         try { 
    147             sock.connect(sockaddr); 
    148             byte[] b = { 'P', 'I', 'N', 'G', '\n' }; 
    149             sock.getOutputStream().write(b); 
    150             byte[] c = new byte[4]; 
    151             sock.getInputStream().read(c); 
    152             String d = new String(c); 
    153             if (!d.equals("PONG")) 
    154                 throw new PluginInitException(); 
    155              
    156         } catch (IOException e2) { 
    157             throw new PluginInitException(); 
    158         } 
    159         try { 
    160             if (sock!=null) 
    161             sock.close(); 
    162         } catch (Exception e3) { 
    163  
    164         } 
    165101        log.debug(getPluginName() + " initialized"); 
    166102    } 
     
    171107 
    172108    public void setClamdHost(String host) { 
    173         clamdHost = host
     109       ClamAVScannerFactory.setClamdHost(host)
    174110    } 
    175111 
    176112    public void setClamdPort(int port) { 
    177         clamdPort = port; 
    178     } 
    179  
    180     public void setSocketTimeout(int time) { 
    181         socketTimeout = time; 
     113        ClamAVScannerFactory.setClamdPort(port); 
    182114    } 
    183115 
     
    185117        failOnError = pa; 
    186118    } 
     119     
    187120    public void setConnectionTimeout(int connectionTimeout) { 
    188         this.connectionTimeout = connectionTimeout
     121       ClamAVScannerFactory.setConnectionTimeout(connectionTimeout*1000)
    189122    } 
    190123}