KickJava   Java API By Example, From Geeks To Geeks.

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


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
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31
32 /**
33  * Connects to a clamd daemon, chats with it to pass it the email data and
34  * a response of virus or not in it.
35  * @author Jean-Francois POUX
36  */

37 public class ClamAVChat {
38
39     private String JavaDoc host;
40     private int port;
41     private byte[] toScan;
42
43     private Socket JavaDoc chat = null;
44     private Socket JavaDoc data = null;
45     private String JavaDoc virus = "";
46
47     private Log log = LogFactory.getLog(ClamAVChat.class);
48
49     private int connectionTimeout=90;
50     
51     public ClamAVChat(String JavaDoc host, int port, byte[] toScan, int connectionTimeout) {
52         this.host = host;
53         this.port = port;
54         this.toScan = toScan;
55         this.connectionTimeout=connectionTimeout;
56     }
57
58     /**
59      * check for viruses
60      * @return true if none found, false if found
61      */

62     public boolean doScan() {
63         chat = new Socket JavaDoc();
64         SocketAddress JavaDoc sockaddr = new InetSocketAddress JavaDoc(host, port);
65         try {
66             chat.setSoTimeout(connectionTimeout*1000);
67         } catch (SocketException JavaDoc e1) {
68         }
69
70         String JavaDoc responseValue = "";
71         try {
72             //First, try to connect to the clamd
73
chat.connect(sockaddr);
74             byte[] b = { 'S', 'T', 'R', 'E', 'A', 'M', '\n' };
75             chat.getOutputStream().write(b); // Write the initialisation command
76

77             // Now, read byte per byte until we find a LF.
78
byte[] rec = new byte[1];
79             while (true) {
80                 chat.getInputStream().read(rec);
81                 if (rec[0] == '\n')
82                     break;
83                 responseValue += new String JavaDoc(rec);
84             }
85             log.debug("response: " + responseValue);
86             
87             // In the response value, there's an integer. It's the TCP port that the clamd has allocated for us for data stream.
88
int dataPort = -1;
89             if (responseValue.contains(" "))
90                 dataPort = Integer.parseInt(responseValue.split(" ")[1]);
91
92             // Now, we connect to the data port obtained before.
93
data = new Socket JavaDoc();
94             SocketAddress JavaDoc sockaddrData = new InetSocketAddress JavaDoc(host, dataPort);
95             try {
96                 data.setSoTimeout(connectionTimeout*1000); // we leave 1m30 before closing connection is clamd does not issue a response.
97
} catch (SocketException JavaDoc e1) {
98             }
99             try {
100                 data.connect(sockaddrData);
101                 data.getOutputStream().write(toScan); // We write to the data stream the content of the mail
102
data.close(); // Then close the stream, so that clamd knows it's the end of the stream.
103
} catch (IOException JavaDoc e2) {
104
105             }
106             // Now that's we have send the body of the mail to clamd, we wait for the response on the chat stream.
107
responseValue = "";
108             while (true) {
109                 try {
110                     chat.getInputStream().read(rec);
111                 } catch (IOException JavaDoc e3) {
112                     break;
113                 }
114                 if (rec[0] == '\n')
115                     break;
116                 responseValue += new String JavaDoc(rec);
117             }
118             log.debug( "response: " + responseValue);
119
120         } catch (IOException JavaDoc e) {
121             log.debug("IO Error : " + e.getMessage());
122         } finally {
123             if (data != null) {
124                 try {
125                     data.close();
126                 } catch (IOException JavaDoc e3) {
127                 }
128             }
129
130             if (chat != null) {
131                 try {
132                     chat.close();
133                 } catch (IOException JavaDoc e3) {
134                 }
135             }
136         }
137
138         if (responseValue==null) {
139             log.error("response is null. Passing the mail anyway...");
140             return true;
141         }
142         
143         if (responseValue.contains("ERROR")) {
144             log.error("response is erroneous ("+responseValue+"). Passing the mail anyway...");
145         }
146         
147         if (responseValue.equals("stream: OK")) // clamd writes this if the stream we sent does not contains viruses.
148
return true;
149         
150         virus = responseValue; // Else there is an error, the response contains the name of the identified virus
151
return false;
152
153     }
154
155     public String JavaDoc getVirus() {
156         return virus;
157     }
158 }
Popular Tags