git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@759 77e5149b-7576-45b1-b177-96237e5ba77b
Nigel Horne authored on 2004/08/17 17:31:58... | ... |
@@ -1,3 +1,7 @@ |
1 |
+Tue Aug 17 09:30:15 BST 2004 (njh) |
|
2 |
+---------------------------------- |
|
3 |
+ * libclamav/mbox.c: Scan fax-messages sent as e-mail (RFC3458) |
|
4 |
+ |
|
1 | 5 |
Mon Aug 16 22:13:31 CEST 2004 (acab) |
2 | 6 |
------------------------------------ |
3 | 7 |
* libclamav/pe.c: add support for FSG 1.31 and cli_malloc bugfix in |
... | ... |
@@ -17,6 +17,9 @@ |
17 | 17 |
* |
18 | 18 |
* Change History: |
19 | 19 |
* $Log: mbox.c,v $ |
20 |
+ * Revision 1.101 2004/08/17 08:28:32 nigelhorne |
|
21 |
+ * Support multitype/fax-message |
|
22 |
+ * |
|
20 | 23 |
* Revision 1.100 2004/08/12 10:36:09 nigelhorne |
21 | 24 |
* LIBCURL completed |
22 | 25 |
* |
... | ... |
@@ -288,7 +291,7 @@ |
288 | 288 |
* Compilable under SCO; removed duplicate code with message.c |
289 | 289 |
* |
290 | 290 |
*/ |
291 |
-static char const rcsid[] = "$Id: mbox.c,v 1.100 2004/08/12 10:36:09 nigelhorne Exp $"; |
|
291 |
+static char const rcsid[] = "$Id: mbox.c,v 1.101 2004/08/17 08:28:32 nigelhorne Exp $"; |
|
292 | 292 |
|
293 | 293 |
#if HAVE_CONFIG_H |
294 | 294 |
#include "clamav-config.h" |
... | ... |
@@ -364,14 +367,21 @@ static void print_trace(int use_syslog); |
364 | 364 |
typedef enum { FALSE = 0, TRUE = 1 } bool; |
365 | 365 |
|
366 | 366 |
#define SAVE_TO_DISC /* multipart/message are saved in a temporary file */ |
367 |
-/*#define CHECKURLS /* If an email contains URLs, check them */ |
|
368 |
-/*#define LIBCURL /* To build with LIBCURL: |
|
367 |
+#define CHECKURLS /* If an email contains URLs, check them */ |
|
368 |
+ |
|
369 |
+#ifdef CHECKURLS |
|
370 |
+#define LIBCURL /* To build with LIBCURL: |
|
369 | 371 |
* LDFLAGS=`curl-config --libs` ./configure ... |
370 | 372 |
*/ |
371 | 373 |
|
374 |
+#define MAX_URLS 10 /* |
|
375 |
+ * Maximum number of URLs scanned in a message |
|
376 |
+ * part |
|
377 |
+ */ |
|
372 | 378 |
#ifdef LIBCURL |
373 | 379 |
#include <curl/curl.h> |
374 | 380 |
#endif |
381 |
+#endif |
|
375 | 382 |
|
376 | 383 |
static message *parseEmailHeaders(message *m, const table_t *rfc821Table, bool destroy); |
377 | 384 |
static int parseEmailHeader(message *m, const char *line, const table_t *rfc821Table); |
... | ... |
@@ -416,6 +426,16 @@ static void getURL(const char *url, const char *dir, const char *filename); |
416 | 416 |
#define RELATED 10 /* RFC2387 */ |
417 | 417 |
#define REPORT 11 /* RFC1892 */ |
418 | 418 |
#define APPLEDOUBLE 12 /* Handling of this in only noddy for now */ |
419 |
+#define FAX MIXED /* |
|
420 |
+ * RFC3458 |
|
421 |
+ * Drafts stated to treat is as mixed if it is |
|
422 |
+ * not known. This disappeared in the final |
|
423 |
+ * version (except when talking about |
|
424 |
+ * voice-message), but it is good enough for us |
|
425 |
+ * since we do no validation of coversheet |
|
426 |
+ * presence etc. (which also has disappeared |
|
427 |
+ * in the final version) |
|
428 |
+ */ |
|
419 | 429 |
|
420 | 430 |
static const struct tableinit { |
421 | 431 |
const char *key; |
... | ... |
@@ -441,13 +461,13 @@ static const struct tableinit { |
441 | 441 |
{ "related", RELATED }, |
442 | 442 |
{ "report", REPORT }, |
443 | 443 |
{ "appledouble", APPLEDOUBLE }, |
444 |
+ { "fax-message", FAX }, |
|
444 | 445 |
{ NULL, 0 } |
445 | 446 |
}; |
446 | 447 |
|
447 | 448 |
#ifdef CL_THREAD_SAFE |
448 | 449 |
static pthread_mutex_t tables_mutex = PTHREAD_MUTEX_INITIALIZER; |
449 | 450 |
#endif |
450 |
-static table_t *rfc821Table, *subtypeTable; |
|
451 | 451 |
|
452 | 452 |
/* Maximum filenames under various systems */ |
453 | 453 |
#ifndef NAME_MAX /* e.g. Linux */ |
... | ... |
@@ -493,6 +513,7 @@ cli_mbox(const char *dir, int desc, unsigned int options) |
493 | 493 |
#ifdef CL_DEBUG |
494 | 494 |
void (*segv)(int); |
495 | 495 |
#endif |
496 |
+ static table_t *rfc821, *subtype; |
|
496 | 497 |
|
497 | 498 |
cli_dbgmsg("in mbox()\n"); |
498 | 499 |
|
... | ... |
@@ -516,12 +537,12 @@ cli_mbox(const char *dir, int desc, unsigned int options) |
516 | 516 |
#ifdef CL_THREAD_SAFE |
517 | 517 |
pthread_mutex_lock(&tables_mutex); |
518 | 518 |
#endif |
519 |
- if(rfc821Table == NULL) { |
|
520 |
- assert(subtypeTable == NULL); |
|
519 |
+ if(rfc821 == NULL) { |
|
520 |
+ assert(subtype == NULL); |
|
521 | 521 |
|
522 |
- if(initialiseTables(&rfc821Table, &subtypeTable) < 0) { |
|
523 |
- rfc821Table = NULL; |
|
524 |
- subtypeTable = NULL; |
|
522 |
+ if(initialiseTables(&rfc821, &subtype) < 0) { |
|
523 |
+ rfc821 = NULL; |
|
524 |
+ subtype = NULL; |
|
525 | 525 |
#ifdef CL_THREAD_SAFE |
526 | 526 |
pthread_mutex_unlock(&tables_mutex); |
527 | 527 |
#endif |
... | ... |
@@ -559,14 +580,14 @@ cli_mbox(const char *dir, int desc, unsigned int options) |
559 | 559 |
/* |
560 | 560 |
* End of a message in the mail box |
561 | 561 |
*/ |
562 |
- body = parseEmailHeaders(m, rfc821Table, TRUE); |
|
562 |
+ body = parseEmailHeaders(m, rfc821, TRUE); |
|
563 | 563 |
if(body == NULL) { |
564 | 564 |
messageReset(m); |
565 | 565 |
continue; |
566 | 566 |
} |
567 | 567 |
messageDestroy(m); |
568 | 568 |
if(messageGetBody(body)) |
569 |
- if(!parseEmailBody(body, NULL, 0, NULL, dir, rfc821Table, subtypeTable, options)) { |
|
569 |
+ if(!parseEmailBody(body, NULL, 0, NULL, dir, rfc821, subtype, options)) { |
|
570 | 570 |
messageReset(body); |
571 | 571 |
m = body; |
572 | 572 |
continue; |
... | ... |
@@ -619,14 +640,14 @@ cli_mbox(const char *dir, int desc, unsigned int options) |
619 | 619 |
|
620 | 620 |
retcode = 0; |
621 | 621 |
|
622 |
- body = parseEmailHeaders(m, rfc821Table, TRUE); |
|
622 |
+ body = parseEmailHeaders(m, rfc821, TRUE); |
|
623 | 623 |
messageDestroy(m); |
624 | 624 |
if(body) { |
625 | 625 |
/* |
626 | 626 |
* Write out the last entry in the mailbox |
627 | 627 |
*/ |
628 | 628 |
if(messageGetBody(body)) |
629 |
- if(!parseEmailBody(body, NULL, 0, NULL, dir, rfc821Table, subtypeTable, options)) |
|
629 |
+ if(!parseEmailBody(body, NULL, 0, NULL, dir, rfc821, subtype, options)) |
|
630 | 630 |
retcode = -1; |
631 | 631 |
|
632 | 632 |
/* |
... | ... |
@@ -659,7 +680,7 @@ cli_mbox(const char *dir, int desc, unsigned int options) |
659 | 659 |
* not be used again before it is destroyed, so we can trash it |
660 | 660 |
*/ |
661 | 661 |
static message * |
662 |
-parseEmailHeaders(message *m, const table_t *rfc821Table, bool destroy) |
|
662 |
+parseEmailHeaders(message *m, const table_t *rfc821, bool destroy) |
|
663 | 663 |
{ |
664 | 664 |
bool inHeader = TRUE; |
665 | 665 |
text *t; |
... | ... |
@@ -720,7 +741,7 @@ parseEmailHeaders(message *m, const table_t *rfc821Table, bool destroy) |
720 | 720 |
cli_dbgmsg("End of header information\n"); |
721 | 721 |
inHeader = FALSE; |
722 | 722 |
} else { |
723 |
- if((parseEmailHeader(ret, buffer, rfc821Table) >= 0) || |
|
723 |
+ if((parseEmailHeader(ret, buffer, rfc821) >= 0) || |
|
724 | 724 |
(strncasecmp(buffer, "From ", 5) == 0)) |
725 | 725 |
anyHeadersFound = TRUE; |
726 | 726 |
free(buffer); |
... | ... |
@@ -752,7 +773,7 @@ parseEmailHeaders(message *m, const table_t *rfc821Table, bool destroy) |
752 | 752 |
* Handle a header line of an email message |
753 | 753 |
*/ |
754 | 754 |
static int |
755 |
-parseEmailHeader(message *m, const char *line, const table_t *rfc821Table) |
|
755 |
+parseEmailHeader(message *m, const char *line, const table_t *rfc821) |
|
756 | 756 |
{ |
757 | 757 |
char *copy, *cmd; |
758 | 758 |
int ret = -1; |
... | ... |
@@ -783,7 +804,7 @@ parseEmailHeader(message *m, const char *line, const table_t *rfc821Table) |
783 | 783 |
* "multipart/mixed" and cmd to |
784 | 784 |
* be "Content-Type" |
785 | 785 |
*/ |
786 |
- ret = parseMimeHeader(m, cmd, rfc821Table, arg); |
|
786 |
+ ret = parseMimeHeader(m, cmd, rfc821, arg); |
|
787 | 787 |
} |
788 | 788 |
free(copy); |
789 | 789 |
|
... | ... |
@@ -1106,7 +1127,7 @@ parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, con |
1106 | 1106 |
} |
1107 | 1107 |
|
1108 | 1108 |
cli_dbgmsg("The message has %d parts\n", multiparts); |
1109 |
- cli_dbgmsg("Find out the multipart type(%s)\n", mimeSubtype); |
|
1109 |
+ cli_dbgmsg("Find out the multipart type (%s)\n", mimeSubtype); |
|
1110 | 1110 |
|
1111 | 1111 |
switch(tableFind(subtypeTable, mimeSubtype)) { |
1112 | 1112 |
case RELATED: |
... | ... |
@@ -1259,8 +1280,8 @@ parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, con |
1259 | 1259 |
break; |
1260 | 1260 |
case NOMIME: |
1261 | 1261 |
if(mainMessage) { |
1262 |
- const text *t_line = uuencodeBegin(mainMessage); |
|
1263 |
- if(t_line) { |
|
1262 |
+ const text *u_line = uuencodeBegin(mainMessage); |
|
1263 |
+ if(u_line) { |
|
1264 | 1264 |
blob *aBlob; |
1265 | 1265 |
|
1266 | 1266 |
cli_dbgmsg("Found uuencoded message in multipart/mixed mainMessage\n"); |
... | ... |
@@ -1291,12 +1312,12 @@ parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, con |
1291 | 1291 |
if(strcasecmp(dtype, "attachment") == 0) |
1292 | 1292 |
addAttachment = TRUE; |
1293 | 1293 |
else if((*dtype == '\0') || (strcasecmp(dtype, "inline") == 0)) { |
1294 |
- const text *t_line = uuencodeBegin(aMessage); |
|
1294 |
+ const text *u_line = uuencodeBegin(aMessage); |
|
1295 | 1295 |
|
1296 | 1296 |
if(mainMessage && (mainMessage != messageIn)) |
1297 | 1297 |
messageDestroy(mainMessage); |
1298 | 1298 |
mainMessage = NULL; |
1299 |
- if(t_line) { |
|
1299 |
+ if(u_line) { |
|
1300 | 1300 |
cli_dbgmsg("Found uuencoded message in multipart/mixed text portion\n"); |
1301 | 1301 |
messageSetEncoding(aMessage, "x-uuencode"); |
1302 | 1302 |
addAttachment = TRUE; |
... | ... |
@@ -2271,6 +2292,7 @@ checkURLs(message *m, const char *dir) |
2271 | 2271 |
char *ptr; |
2272 | 2272 |
size_t len; |
2273 | 2273 |
table_t *t; |
2274 |
+ int n; |
|
2274 | 2275 |
|
2275 | 2276 |
if(b == NULL) |
2276 | 2277 |
return; |
... | ... |
@@ -2285,6 +2307,7 @@ checkURLs(message *m, const char *dir) |
2285 | 2285 |
} |
2286 | 2286 |
|
2287 | 2287 |
t = tableCreate(); |
2288 |
+ n = 0; |
|
2288 | 2289 |
|
2289 | 2290 |
/* |
2290 | 2291 |
* cli_memstr(ptr, len, "<a href=", 8) |
... | ... |
@@ -2360,6 +2383,10 @@ checkURLs(message *m, const char *dir) |
2360 | 2360 |
(void)unlink(cmd); |
2361 | 2361 |
} |
2362 | 2362 |
#endif |
2363 |
+ if(++n > MAX_URLS) { |
|
2364 |
+ cli_warnmsg("Not all URLs will be scanned\n"); |
|
2365 |
+ break; |
|
2366 |
+ } |
|
2363 | 2367 |
} |
2364 | 2368 |
ptr++; |
2365 | 2369 |
len--; |
... | ... |
@@ -2422,6 +2449,9 @@ getURL(const char *url, const char *dir, const char *filename) |
2422 | 2422 |
/* These should be customisable */ |
2423 | 2423 |
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30); |
2424 | 2424 |
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10); |
2425 |
+#ifdef CURLOPT_MAXFILESIZE |
|
2426 |
+ curl_easy_setopt(curl, CURLOPT_MAXFILESIZE, 50*1024); |
|
2427 |
+#endif |
|
2425 | 2428 |
|
2426 | 2429 |
if(curl_easy_perform(curl) != CURLE_OK) { |
2427 | 2430 |
cli_warnmsg("URL %s failed to download\n", url); |