1 package org.eparapher.core.tools;
2
3 import java.io.BufferedReader;
4 import java.io.BufferedWriter;
5 import java.io.IOException;
6 import java.io.InputStreamReader;
7 import java.io.OutputStreamWriter;
8 import java.io.PrintWriter;
9 import java.net.Socket;
10 import java.net.UnknownHostException;
11
12 import org.apache.log4j.Logger;
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 public final class ClamavUtils {
36
37
38 private static final long serialVersionUID = -721510070948622509L;
39
40
41 private static final String LOGGER_ROOTNAME = ClamavUtils.class.getName();
42
43
44 private int port = 0;
45
46
47 private String server = null;
48
49
50 private Socket skt = null;
51
52
53
54
55
56
57
58
59
60
61 public static final String COMMANDE_PING = "PING";
62
63
64 public static final String COMMANDE_RELOAD = "RELOAD";
65
66
67 public static final String COMMANDE_SCAN = "SCAN";
68
69
70 public static final String COMMANDE_SHUTDOWN = "SHUTDOWN";
71
72
73 public static final String COMMANDE_VERSION = "VERSION";
74
75
76
77
78
79
80 public static final byte CODE_RETOUR_FICHIER_SAIN = 0;
81
82
83 public static final byte CODE_RETOUR_FICHIER_VEROLE = 1;
84
85
86 public static final byte CODE_RETOUR_FICHIER_NON_TRAITE = 2;
87
88
89 public static final byte CODE_RETOUR_ERREUR_SCAN = 3;
90
91
92
93
94
95
96 private static final String CLAMAV_REPONSE_OK = "OK";
97
98
99 private static final String CLAMAV_REPONSE_FOUND = "FOUND";
100
101
102 private static final String REPONSE_PING = "PONG";
103
104
105
106
107
108
109
110
111
112
113
114 public ClamavUtils(final String pServeur, final int pPort) {
115
116 this.server = pServeur;
117 this.port = pPort;
118 }
119
120
121
122
123
124
125 private Boolean connect() {
126
127 final Logger logger = Logger.getLogger(LOGGER_ROOTNAME + "#connect");
128 if (logger.isDebugEnabled()) {
129 logger.debug("Connecting to ClamAV server " + server + ":" + port );
130 }
131
132
133 Boolean retour = Boolean.FALSE;
134
135 try {
136
137
138 skt = new Socket(server, port);
139
140
141 retour = isConnected();
142
143 if (logger.isDebugEnabled()) {
144 if (retour) {
145 logger.debug("connexion to ClamAV is [OK]");
146 } else {
147 logger.debug("connexion to ClamAV is [KO]");
148 }
149 }
150
151 } catch (UnknownHostException uhe) {
152 logger.error("Bad IP address : " + uhe.getMessage());
153
154 } catch (IOException ioe) {
155 logger.error("input/output error : " + ioe.getMessage());
156 }
157
158 return retour;
159 }
160
161
162
163
164 private void disconnect() {
165
166 final Logger logger = Logger.getLogger(LOGGER_ROOTNAME + "#disconnect");
167 if (logger.isDebugEnabled()) {
168 logger.debug("tentative de deconnexion du serveur [" + server + "] sur le port [" + port + "]");
169 }
170
171
172 try {
173
174 if (isConnected()) {
175 skt.close();
176
177 if (skt.isClosed()) {
178 logger.debug("deconnexion du serveur [OK]");
179 } else {
180 logger.debug("deconnexion du serveur [KO]");
181 }
182 }
183
184 } catch (IOException ioe) {
185 logger.error("erreur d'entree/sortie a la fermeture du socket [" + ioe.getMessage() + "]");
186 }
187
188 }
189
190
191
192
193
194
195 private Boolean isConnected() {
196 return new Boolean(skt.isConnected());
197 }
198
199
200
201
202
203
204
205 public String sendCommand(final String pCommande) {
206
207 final Logger logger = Logger.getLogger(LOGGER_ROOTNAME + "#sendCommand");
208
209
210 String retour = null;
211
212
213 if (!isEmptyString(pCommande)) {
214
215 if (logger.isDebugEnabled()) {
216 logger.debug("envoi de la commande [" + pCommande + "]");
217 }
218
219
220 if (connect()) {
221
222
223 PrintWriter out = null;
224 BufferedReader in = null;
225
226 try {
227
228
229 out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(skt.getOutputStream())), Boolean.TRUE);
230 out.println(pCommande);
231
232
233 in = new BufferedReader(new InputStreamReader(skt.getInputStream()));
234 retour = in.readLine();
235
236 if (logger.isDebugEnabled()) {
237 logger.debug("reponse de la commande [" + retour + "]");
238 }
239
240 } catch (IOException ioe) {
241 logger.error("IOException sur l'envoi de la commande ou la reception du resultat [" + ioe.getMessage() + "]");
242
243 } finally {
244
245
246 try {
247 in.close();
248 logger.debug("fermeture des ressources du flux d'entree [OK]");
249
250 } catch (IOException ioe) {
251 logger.error("IOException a la fermeture du flux d'entree [" + ioe.getMessage() + "]");
252 }
253
254
255 out.close();
256 logger.debug("fermeture des ressources du flux de sortie [OK]");
257
258
259 disconnect();
260 }
261
262 } else {
263 logger.debug("pas de connexion");
264 }
265
266 } else {
267 logger.debug("la commande est vide");
268 }
269
270 return retour;
271 }
272
273
274 private boolean isEmptyString(String str) {
275 if (str == null)
276 return true;
277 if (str.equals(""))
278 return true;
279 return false;
280 }
281
282
283
284
285
286
287
288 public byte scanFile(final String pFile) {
289
290 final Logger logger = Logger.getLogger(LOGGER_ROOTNAME + "#scanFile");
291
292
293 byte retour = -1;
294
295
296 if (!isEmptyString(pFile)) {
297
298
299 String command = COMMANDE_SCAN + " " + pFile;
300
301
302 String result = sendCommand(command);
303 if (result != null) {
304
305
306 int pos = result.lastIndexOf(":") + 2;
307 result = result.substring(pos);
308
309
310 if (result.equals(CLAMAV_REPONSE_OK)) {
311 retour = CODE_RETOUR_FICHIER_SAIN;
312
313 } else if (result.contains(CLAMAV_REPONSE_FOUND)) {
314 retour = CODE_RETOUR_FICHIER_VEROLE;
315
316 } else {
317 retour = CODE_RETOUR_ERREUR_SCAN;
318 }
319
320 } else {
321 retour = CODE_RETOUR_ERREUR_SCAN;
322 }
323
324 } else {
325 retour = CODE_RETOUR_FICHIER_NON_TRAITE;
326 logger.error("aucun fichier a verifier");
327 }
328
329 if (logger.isDebugEnabled()) {
330 logger.debug("code de retour [" + retour + "]");
331 }
332
333 return retour;
334 }
335
336
337
338
339
340
341 public Boolean ping() {
342
343 final Logger logger = Logger.getLogger(LOGGER_ROOTNAME + "#ping");
344
345
346 Boolean retour = null;
347
348
349 String command = COMMANDE_PING;
350
351
352 String result = sendCommand(command);
353 if (result != null) {
354
355
356 retour = new Boolean(result.equals(REPONSE_PING));
357 if (logger.isDebugEnabled()) {
358 logger.debug("ping [" + retour + "]");
359 }
360
361 } else {
362
363 if (logger.isDebugEnabled()) {
364 logger.debug("ping [error]");
365 }
366 }
367
368 return retour;
369 }
370
371
372
373
374
375
376 public String getVersion() {
377
378 final Logger logger = Logger.getLogger(LOGGER_ROOTNAME + "#getVersion");
379
380
381 String retour = null;
382
383
384 String command = COMMANDE_VERSION;
385
386
387 retour = sendCommand(command);
388 if (retour != null) {
389
390 if (logger.isDebugEnabled()) {
391 logger.debug("version de ClamAV [" + retour + "]");
392 }
393
394 } else {
395
396 if (logger.isDebugEnabled()) {
397 logger.debug("version de ClamAV [error]");
398 }
399 }
400
401 return retour;
402 }
403
404 }
405