git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@534 77e5149b-7576-45b1-b177-96237e5ba77b
Tomasz Kojm authored on 2004/05/02 04:33:05... | ... |
@@ -89,6 +89,7 @@ Thomas Lamy <Thomas.Lamy*in-online.net> |
89 | 89 |
Marty Lee <marty*maui.co.uk> |
90 | 90 |
Peter N Lewis <peter*stairways.com.au> |
91 | 91 |
David S. Madole <david*madole.net> |
92 |
+Joe Maimon <jmaimon*ttec.com> |
|
92 | 93 |
Andrey V. Malyshev <amal*krasn.ru> |
93 | 94 |
Everton da Silva Marques <everton*lab.ipaccess.diveo.net.br> |
94 | 95 |
Andrey J. Melnikoff <temnota*kmv.ru> |
... | ... |
@@ -1,3 +1,15 @@ |
1 |
+Sat May 1 21:29:29 CEST 2004 (tk) |
|
2 |
+---------------------------------- |
|
3 |
+ * clamd: stream scanner: |
|
4 |
+ + scan exactly up to StreamMaxLength (patch by Joe Maimon |
|
5 |
+ <jmaimon*ttec.com>) |
|
6 |
+ + fix description leak on ReadTimeout (patch by Maxim Dounin |
|
7 |
+ <mdounin@rambler-co.ru>) |
|
8 |
+ * contrib/trashscan: v. 0.12 (Trashware <trashware*gmx.de>) |
|
9 |
+ * libclamav: in block-encrypted mode scan a raw encrypted archive before |
|
10 |
+ marking it as encrypted (requested by Andy Fiddaman |
|
11 |
+ <clam*fiddaman.net>) |
|
12 |
+ |
|
1 | 13 |
Thu Apr 29 21:59:36 CEST 2004 (tk) |
2 | 14 |
---------------------------------- |
3 | 15 |
* libclamav: detect more mail file types |
... | ... |
@@ -194,7 +194,8 @@ int scan(const char *filename, unsigned long int *scanned, const struct cl_node |
194 | 194 |
|
195 | 195 |
int scanstream(int odesc, unsigned long int *scanned, const struct cl_node *root, const struct cl_limits *limits, int options, const struct cfgstruct *copt) |
196 | 196 |
{ |
197 |
- int ret, portscan = CL_DEFAULT_MAXPORTSCAN, sockfd, port, acceptd, tmpd, bread, retval, timeout; |
|
197 |
+ int ret, portscan = CL_DEFAULT_MAXPORTSCAN, sockfd, port, acceptd; |
|
198 |
+ int tmpd, bread, retval, timeout, btread; |
|
198 | 199 |
long int size = 0, maxsize = 0; |
199 | 200 |
short bound = 0; |
200 | 201 |
const char *virname; |
... | ... |
@@ -204,6 +205,7 @@ int scanstream(int odesc, unsigned long int *scanned, const struct cl_node *root |
204 | 204 |
struct cfgstruct *cpt; |
205 | 205 |
FILE *tmp = NULL; |
206 | 206 |
|
207 |
+ |
|
207 | 208 |
while(!bound && portscan--) { |
208 | 209 |
if((port = cl_rndnum(60000)) < 1024) |
209 | 210 |
port += 2139; |
... | ... |
@@ -231,35 +233,36 @@ int scanstream(int odesc, unsigned long int *scanned, const struct cl_node *root |
231 | 231 |
bound = 1; |
232 | 232 |
|
233 | 233 |
} |
234 |
- |
|
235 |
- if((cpt = cfgopt(copt, "ReadTimeout"))) { |
|
234 |
+ |
|
235 |
+ if((cpt = cfgopt(copt, "ReadTimeout"))) |
|
236 | 236 |
timeout = cpt->numarg; |
237 |
- } else { |
|
237 |
+ else |
|
238 | 238 |
timeout = CL_DEFAULT_SCANTIMEOUT; |
239 |
- } |
|
240 |
- if (timeout == 0) { |
|
239 |
+ |
|
240 |
+ if(timeout == 0) |
|
241 | 241 |
timeout = -1; |
242 |
- } |
|
243 | 242 |
|
244 | 243 |
if(!bound && !portscan) { |
245 | 244 |
logg("!ScanStream: Can't find any free port.\n"); |
246 | 245 |
mdprintf(odesc, "Can't find any free port ERROR\n"); |
246 |
+ close(sockfd); |
|
247 | 247 |
return -1; |
248 | 248 |
} else { |
249 | 249 |
listen(sockfd, 1); |
250 | 250 |
mdprintf(odesc, "PORT %d\n", port); |
251 | 251 |
} |
252 | 252 |
|
253 |
- retval = poll_fd(sockfd, timeout); |
|
254 |
- switch (retval) { |
|
255 |
- case 0: /* timeout */ |
|
256 |
- mdprintf(sockfd, "Accept timeout ERROR\n"); |
|
257 |
- logg("!ScanStream: accept timeout.\n"); |
|
258 |
- return -1; |
|
259 |
- case -1: |
|
260 |
- mdprintf(sockfd, "accept poll ERROR\n"); |
|
261 |
- logg("!ScanStream: accept poll failed.\n"); |
|
262 |
- return -1; |
|
253 |
+ switch(retval = poll_fd(sockfd, timeout)) { |
|
254 |
+ case 0: /* timeout */ |
|
255 |
+ mdprintf(odesc, "Accept timeout ERROR\n"); |
|
256 |
+ logg("!ScanStream: accept timeout.\n"); |
|
257 |
+ close(sockfd); |
|
258 |
+ return -1; |
|
259 |
+ case -1: |
|
260 |
+ mdprintf(odesc, "accept poll ERROR\n"); |
|
261 |
+ logg("!ScanStream: accept poll failed.\n"); |
|
262 |
+ close(sockfd); |
|
263 |
+ return -1; |
|
263 | 264 |
} |
264 | 265 |
|
265 | 266 |
if((acceptd = accept(sockfd, NULL, NULL)) == -1) { |
... | ... |
@@ -269,63 +272,63 @@ int scanstream(int odesc, unsigned long int *scanned, const struct cl_node *root |
269 | 269 |
return -1; |
270 | 270 |
} |
271 | 271 |
|
272 |
- |
|
273 | 272 |
logg("*Accepted connection on port %d, fd %d\n", port, acceptd); |
274 | 273 |
|
275 |
- /* StreamSaveToDisk is enforced, to ensure timeoute */ |
|
276 |
- /*if(cfgopt(copt, "StreamSaveToDisk")) { */ |
|
277 |
- if((tmp = tmpfile()) == NULL) { |
|
274 |
+ if((tmp = tmpfile()) == NULL) { |
|
275 |
+ shutdown(sockfd, 2); |
|
276 |
+ close(sockfd); |
|
277 |
+ close(acceptd); |
|
278 |
+ mdprintf(odesc, "Temporary file ERROR\n"); |
|
279 |
+ logg("!ScanStream: Can't create temporary file.\n"); |
|
280 |
+ return -1; |
|
281 |
+ } |
|
282 |
+ tmpd = fileno(tmp); |
|
283 |
+ |
|
284 |
+ if((cpt = cfgopt(copt, "StreamMaxLength"))) |
|
285 |
+ maxsize = cpt->numarg; |
|
286 |
+ |
|
287 |
+ btread = sizeof(buff); |
|
288 |
+ |
|
289 |
+ while((retval = poll_fd(acceptd, timeout)) == 1) { |
|
290 |
+ bread = read(acceptd, buff, btread); |
|
291 |
+ if(bread <= 0) |
|
292 |
+ break; |
|
293 |
+ size += bread; |
|
294 |
+ |
|
295 |
+ if(writen(tmpd, buff, bread) != bread) { |
|
278 | 296 |
shutdown(sockfd, 2); |
279 | 297 |
close(sockfd); |
280 | 298 |
close(acceptd); |
281 |
- mdprintf(odesc, "Temporary file ERROR\n"); |
|
282 |
- logg("!ScanStream: Can't create temporary file.\n"); |
|
299 |
+ mdprintf(odesc, "Temporary file -> write ERROR\n"); |
|
300 |
+ logg("!ScanStream: Can't write to temporary file.\n"); |
|
301 |
+ if(tmp) |
|
302 |
+ fclose(tmp); |
|
283 | 303 |
return -1; |
284 | 304 |
} |
285 |
- tmpd = fileno(tmp); |
|
286 | 305 |
|
287 |
- if((cpt = cfgopt(copt, "StreamMaxLength"))) |
|
288 |
- maxsize = cpt->numarg; |
|
306 |
+ if(maxsize && (size + btread >= maxsize)) { |
|
307 |
+ btread = (maxsize - size); /* only read up to max */ |
|
289 | 308 |
|
290 |
- while((retval = poll_fd(acceptd, timeout)) == 1) { |
|
291 |
- bread = read(acceptd, buff, sizeof(buff)); |
|
292 |
- if (bread <= 0) { |
|
293 |
- break; |
|
309 |
+ if(!btread) { |
|
310 |
+ logg("^ScanStream: Size limit reached ( max: %d)\n", maxsize); |
|
311 |
+ break; /* Scan what we have */ |
|
294 | 312 |
} |
295 |
- size += bread; |
|
296 |
- |
|
297 |
- if(maxsize && (size + sizeof(buff)) > maxsize) { |
|
298 |
- shutdown(sockfd, 2); |
|
299 |
- close(sockfd); |
|
300 |
- close(acceptd); |
|
301 |
- mdprintf(odesc, "Size exceeded ERROR\n"); |
|
302 |
- logg("^ScanStream: Size exceeded (stopped at %d, max: %d)\n", size, maxsize); |
|
303 |
- if(tmp) |
|
304 |
- fclose(tmp); |
|
305 |
- return -1; |
|
306 |
- } |
|
307 |
- |
|
308 |
- if(writen(tmpd, buff, bread) != bread) { |
|
309 |
- shutdown(sockfd, 2); |
|
310 |
- close(sockfd); |
|
311 |
- close(acceptd); |
|
312 |
- mdprintf(odesc, "Temporary file -> write ERROR\n"); |
|
313 |
- logg("!ScanStream: Can't write to temporary file.\n"); |
|
314 |
- if(tmp) |
|
315 |
- fclose(tmp); |
|
316 |
- return -1; |
|
317 |
- } |
|
318 |
- |
|
319 | 313 |
} |
314 |
+ } |
|
320 | 315 |
|
321 |
- lseek(tmpd, 0, SEEK_SET); |
|
322 |
- ret = cl_scandesc(tmpd, &virname, scanned, root, limits, options); |
|
323 |
- if(tmp) |
|
324 |
- fclose(tmp); |
|
316 |
+ switch(retval) { |
|
317 |
+ case 0: /* timeout */ |
|
318 |
+ mdprintf(odesc, "Accept timeout ERROR\n"); |
|
319 |
+ logg("!ScanStream: accept timeout.\n"); |
|
320 |
+ case -1: |
|
321 |
+ mdprintf(odesc, "accept poll ERROR\n"); |
|
322 |
+ logg("!ScanStream: accept poll failed.\n"); |
|
323 |
+ } |
|
325 | 324 |
|
326 |
- /* } else |
|
327 |
- ret = cl_scandesc(acceptd, &virname, scanned, root, limits, 0); |
|
328 |
- */ |
|
325 |
+ lseek(tmpd, 0, SEEK_SET); |
|
326 |
+ ret = cl_scandesc(tmpd, &virname, scanned, root, limits, options); |
|
327 |
+ if(tmp) |
|
328 |
+ fclose(tmp); |
|
329 | 329 |
|
330 | 330 |
close(acceptd); |
331 | 331 |
close(sockfd); |
... | ... |
@@ -76,10 +76,10 @@ static const struct cli_magic_s cli_magic[] = { |
76 | 76 |
{0, "PK\003\004", 4, "ZIP", CL_ZIPFILE}, |
77 | 77 |
{0, "\037\213", 2, "GZip", CL_GZFILE}, |
78 | 78 |
{0, "BZh", 3, "BZip", CL_BZFILE}, |
79 |
- {0, "From ", 5, "MBox", CL_MAILFILE}, |
|
80 | 79 |
|
81 | 80 |
/* Mail */ |
82 | 81 |
|
82 |
+ {0, "From ", 5, "MBox", CL_MAILFILE}, |
|
83 | 83 |
{0, "Received", 8, "Raw mail", CL_MAILFILE}, |
84 | 84 |
{0, "Return-Path: ", 13, "Maildir", CL_MAILFILE}, |
85 | 85 |
{0, "Return-path: ", 13, "Maildir", CL_MAILFILE}, |
... | ... |
@@ -107,20 +107,21 @@ static const struct cli_magic_s cli_magic[] = { |
107 | 107 |
|
108 | 108 |
{0, "\320\317\021\340\241\261\032\341", |
109 | 109 |
8, "OLE2 container", CL_OLE2FILE}, |
110 |
+ |
|
110 | 111 |
/* Ignored types */ |
111 | 112 |
|
112 | 113 |
{0, "\000\000\001\263", 4, "MPEG video stream", CL_DATAFILE}, |
113 | 114 |
{0, "\000\000\001\272", 4, "MPEG sys stream", CL_DATAFILE}, |
114 | 115 |
{0, "RIFF", 4, "RIFF", CL_DATAFILE}, |
115 |
- {0, "GIF87a", 6, "GIF (87a)", CL_DATAFILE}, |
|
116 |
- {0, "GIF89a", 6, "GIF (89a)", CL_DATAFILE}, |
|
117 |
- {0, "\x89PNG\r\n\x1a\n", 8, "PNG", CL_DATAFILE}, |
|
118 |
- {0, "\377\330\377\340", 4, "JPEG", CL_DATAFILE}, |
|
119 |
- {0, "\377\330\377\356", 4, "JPG", CL_DATAFILE}, |
|
116 |
+ {0, "GIF", 3, "GIF", CL_DATAFILE}, |
|
117 |
+ {0, "\x89PNG", 4, "PNG", CL_DATAFILE}, |
|
118 |
+ {0, "\377\330\377", 4, "JPEG", CL_DATAFILE}, |
|
119 |
+ {0, "BM", 2, "BMP", CL_DATAFILE}, |
|
120 | 120 |
{0, "OggS", 4, "Ogg Stream", CL_DATAFILE}, |
121 | 121 |
{0, "ID3", 3, "MP3", CL_DATAFILE}, |
122 | 122 |
{0, "\377\373\220", 3, "MP3", CL_DATAFILE}, |
123 | 123 |
{0, "\%PDF-", 5, "PDF document", CL_DATAFILE}, |
124 |
+ {0, "\%!PS-Adobe-", 11, "PostScript", CL_DATAFILE}, |
|
124 | 125 |
{0, "\060\046\262\165\216\146\317", 7, "WMA/WMV/ASF", CL_DATAFILE}, |
125 | 126 |
{0, ".RMF" , 4, "Real Media File", CL_DATAFILE}, |
126 | 127 |
|
... | ... |
@@ -146,8 +147,7 @@ cli_file_t cli_filetype(const char *buf, size_t buflen) |
146 | 146 |
static int cli_magic_scandesc(int desc, const char **virname, long int *scanned, const struct cl_node *root, const struct cl_limits *limits, int options, int *reclev); |
147 | 147 |
static int cli_scanfile(const char *filename, const char **virname, unsigned long int *scanned, const struct cl_node *root, const struct cl_limits *limits, int options, int *reclev); |
148 | 148 |
|
149 |
-static int cli_scandesc(int desc, const char **virname, long int *scanned, const struct |
|
150 |
-cl_node *root) |
|
149 |
+static int cli_scandesc(int desc, const char **virname, long int *scanned, const struct cl_node *root) |
|
151 | 150 |
{ |
152 | 151 |
char *buffer, *buff, *endbl, *pt; |
153 | 152 |
int bytes, buffsize, length, ret, *partcnt; |
... | ... |
@@ -242,7 +242,9 @@ static int cli_scanrar(int desc, const char **virname, long int *scanned, const |
242 | 242 |
if(DETECT_ENCRYPTED && (rarlist->item.Flags & 4)) { |
243 | 243 |
files++; |
244 | 244 |
cli_dbgmsg("Rar -> Encrypted files found in archive.\n"); |
245 |
- *virname = "Encrypted.RAR"; |
|
245 |
+ lseek(desc, 0, SEEK_SET); |
|
246 |
+ if(cli_scandesc(desc, virname, scanned, root) != CL_VIRUS) |
|
247 |
+ *virname = "Encrypted.RAR"; |
|
246 | 248 |
ret = CL_VIRUS; |
247 | 249 |
break; |
248 | 250 |
} |
... | ... |
@@ -411,7 +413,9 @@ static int cli_scanzip(int desc, const char **virname, long int *scanned, const |
411 | 411 |
if(DETECT_ENCRYPTED && (zdirent.d_flags & 1 )) { |
412 | 412 |
files++; |
413 | 413 |
cli_dbgmsg("Zip -> Encrypted files found in archive.\n"); |
414 |
- *virname = "Encrypted.Zip"; |
|
414 |
+ lseek(desc, 0, SEEK_SET); |
|
415 |
+ if(cli_scandesc(desc, virname, scanned, root) != CL_VIRUS) |
|
416 |
+ *virname = "Encrypted.Zip"; |
|
415 | 417 |
ret = CL_VIRUS; |
416 | 418 |
break; |
417 | 419 |
} |