KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jsmtpd > plugins > filters > ClamAV > ClamAVFilter


1 /*
2  *
3  * Jsmtpd, Java SMTP daemon
4  * Copyright (C) 2005 Jean-Francois POUX, jf.poux@laposte.net
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  *
20  */

21 package org.jsmtpd.plugins.filters.ClamAV;
22
23 import java.io.IOException JavaDoc;
24 import java.net.InetSocketAddress JavaDoc;
25 import java.net.Socket JavaDoc;
26 import java.net.SocketAddress JavaDoc;
27 import java.net.SocketException JavaDoc;
28 import java.util.LinkedList JavaDoc;
29
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.jsmtpd.core.common.PluginInitException;
33 import org.jsmtpd.core.common.filter.FilterTreeFailureException;
34 import org.jsmtpd.core.common.filter.IFilter;
35 import org.jsmtpd.core.mail.Email;
36 import org.jsmtpd.core.send.QueueService;
37
38 /**
39
40  *
41  * This plugin is a client to the ClamAV antivirus
42  * daemon.<br>
43  *
44  *
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
64  * @author Jean-Francois POUX
65  */

66 public class ClamAVFilter implements IFilter {
67
68     private String JavaDoc clamdHost;
69     private int clamdPort;
70     private int socketTimeout;
71     private Log log = LogFactory.getLog(ClamAVFilter.class);
72     private int connectionTimeout=90;
73     /**
74      * Will cause a virus detection to automaticly break the chain
75      * and generate an error message to the sender
76      */

77     private boolean failOnError = false;
78
79
80     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          */

90         log.debug("Starting ClamAV Scan of "+input.getDiskName());
91         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         }
98
99         if (failOnError) {
100             if (!input.getFrom().toString().equals("<>")) // is it an internal mail already ?
101
{
102                 LinkedList JavaDoc<String JavaDoc> messages = new LinkedList JavaDoc<String JavaDoc>();
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         }
116         return false;
117     }
118
119     /* (non-Javadoc)
120      * @see jsmtpd.common.IGenericPlugin#getPluginName()
121      */

122     public String JavaDoc getPluginName() {
123
124         return "Jsmtpd-ClamAV antivirus filter";
125     }
126
127     /* (non-Javadoc)
128      * @see jsmtpd.common.IGenericPlugin#initPlugin()
129      */

130     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 JavaDoc sock = new Socket JavaDoc();
139         SocketAddress JavaDoc sockaddr = new InetSocketAddress JavaDoc(clamdHost, clamdPort);
140         try {
141             sock.setSoTimeout(socketTimeout * 1000);
142         } catch (SocketException JavaDoc 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 JavaDoc d = new String JavaDoc(c);
153             if (!d.equals("PONG"))
154                 throw new PluginInitException();
155             
156         } catch (IOException JavaDoc e2) {
157             throw new PluginInitException();
158         }
159         try {
160             if (sock!=null)
161             sock.close();
162         } catch (Exception JavaDoc e3) {
163
164         }
165         log.debug(getPluginName() + " initialized");
166     }
167
168     public void shutdownPlugin() {
169
170     }
171
172     public void setClamdHost(String JavaDoc host) {
173         clamdHost = host;
174     }
175
176     public void setClamdPort(int port) {
177         clamdPort = port;
178     }
179
180     public void setSocketTimeout(int time) {
181         socketTimeout = time;
182     }
183
184     public void setFailOnError(boolean pa) {
185         failOnError = pa;
186     }
187     public void setConnectionTimeout(int connectionTimeout) {
188         this.connectionTimeout = connectionTimeout;
189     }
190 }
Popular Tags