git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@783 77e5149b-7576-45b1-b177-96237e5ba77b
Nigel Horne authored on 2004/08/23 05:20:14... | ... |
@@ -17,6 +17,9 @@ |
17 | 17 |
* |
18 | 18 |
* Change History: |
19 | 19 |
* $Log: mbox.c,v $ |
20 |
+ * Revision 1.111 2004/08/22 20:20:14 nigelhorne |
|
21 |
+ * Tidy |
|
22 |
+ * |
|
20 | 23 |
* Revision 1.110 2004/08/22 15:08:59 nigelhorne |
21 | 24 |
* messageExport |
22 | 25 |
* |
... | ... |
@@ -318,7 +321,7 @@ |
318 | 318 |
* Compilable under SCO; removed duplicate code with message.c |
319 | 319 |
* |
320 | 320 |
*/ |
321 |
-static char const rcsid[] = "$Id: mbox.c,v 1.110 2004/08/22 15:08:59 nigelhorne Exp $"; |
|
321 |
+static char const rcsid[] = "$Id: mbox.c,v 1.111 2004/08/22 20:20:14 nigelhorne Exp $"; |
|
322 | 322 |
|
323 | 323 |
#if HAVE_CONFIG_H |
324 | 324 |
#include "clamav-config.h" |
... | ... |
@@ -421,7 +424,7 @@ typedef enum { FALSE = 0, TRUE = 1 } bool; |
421 | 421 |
|
422 | 422 |
static message *parseEmailHeaders(const message *m, const table_t *rfc821Table); |
423 | 423 |
static int parseEmailHeader(message *m, const char *line, const table_t *rfc821Table); |
424 |
-static int parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, const char *dir, const table_t *rfc821Table, const table_t *subtypeTable, unsigned int options); |
|
424 |
+static int parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t *rfc821Table, const table_t *subtypeTable, unsigned int options); |
|
425 | 425 |
static int boundaryStart(const char *line, const char *boundary); |
426 | 426 |
static int endOfMessage(const char *line, const char *boundary); |
427 | 427 |
static int initialiseTables(table_t **rfc821Table, table_t **subtypeTable); |
... | ... |
@@ -430,7 +433,9 @@ static size_t strip(char *buf, int len); |
430 | 430 |
static bool continuationMarker(const char *line); |
431 | 431 |
static int parseMimeHeader(message *m, const char *cmd, const table_t *rfc821Table, const char *arg); |
432 | 432 |
static void saveTextPart(message *m, const char *dir); |
433 |
+#if 0 |
|
433 | 434 |
static bool saveFile(const blob *b, const char *dir); |
435 |
+#endif |
|
434 | 436 |
|
435 | 437 |
static void checkURLs(message *m, const char *dir); |
436 | 438 |
#ifdef WITH_CURL |
... | ... |
@@ -446,10 +451,6 @@ static void *getURL(struct arg *arg); |
446 | 446 |
#endif |
447 | 447 |
#endif |
448 | 448 |
|
449 |
- |
|
450 |
-/* Maximum number of attachments that we accept */ |
|
451 |
-#define MAX_ATTACHMENTS 10 |
|
452 |
- |
|
453 | 449 |
/* Maximum line length according to RFC821 */ |
454 | 450 |
#define LINE_LENGTH 1000 |
455 | 451 |
|
... | ... |
@@ -632,7 +633,7 @@ cli_mbox(const char *dir, int desc, unsigned int options) |
632 | 632 |
} |
633 | 633 |
messageDestroy(m); |
634 | 634 |
if(messageGetBody(body)) |
635 |
- if(!parseEmailBody(body, NULL, 0, NULL, dir, rfc821, subtype, options)) { |
|
635 |
+ if(!parseEmailBody(body, NULL, dir, rfc821, subtype, options)) { |
|
636 | 636 |
messageReset(body); |
637 | 637 |
m = body; |
638 | 638 |
continue; |
... | ... |
@@ -690,7 +691,7 @@ cli_mbox(const char *dir, int desc, unsigned int options) |
690 | 690 |
* Write out the last entry in the mailbox |
691 | 691 |
*/ |
692 | 692 |
if(messageGetBody(body)) |
693 |
- if(!parseEmailBody(body, NULL, 0, NULL, dir, rfc821, subtype, options)) |
|
693 |
+ if(!parseEmailBody(body, NULL, dir, rfc821, subtype, options)) |
|
694 | 694 |
retcode = -1; |
695 | 695 |
|
696 | 696 |
/* |
... | ... |
@@ -846,7 +847,6 @@ parseEmailHeader(message *m, const char *line, const table_t *rfc821) |
846 | 846 |
* any headers. First time of calling it'll be |
847 | 847 |
* the whole message. Later it'll be parts of a multipart message |
848 | 848 |
* textIn is the plain text message being built up so far |
849 |
- * blobsIn contains the array of attachments found so far |
|
850 | 849 |
* |
851 | 850 |
* Returns: |
852 | 851 |
* 0 for fail |
... | ... |
@@ -854,31 +854,23 @@ parseEmailHeader(message *m, const char *line, const table_t *rfc821) |
854 | 854 |
* 2 for success, attachments not saved |
855 | 855 |
*/ |
856 | 856 |
static int /* success or fail */ |
857 |
-parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, const char *dir, const table_t *rfc821Table, const table_t *subtypeTable, unsigned int options) |
|
857 |
+parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t *rfc821Table, const table_t *subtypeTable, unsigned int options) |
|
858 | 858 |
{ |
859 | 859 |
message **messages; /* parts of a multipart message */ |
860 | 860 |
int inhead, inMimeHead, i, rc = 1, htmltextPart, multiparts = 0; |
861 | 861 |
text *aText; |
862 |
- blob *blobList[MAX_ATTACHMENTS], **blobs; |
|
863 | 862 |
const char *cptr; |
864 | 863 |
message *mainMessage; |
864 |
+ fileblob *fb; |
|
865 | 865 |
|
866 |
- cli_dbgmsg("in parseEmailBody(nBlobs = %d)\n", nBlobs); |
|
867 |
- |
|
868 |
- /* Pre-assertions */ |
|
869 |
- if(nBlobs >= MAX_ATTACHMENTS) { |
|
870 |
- cli_warnmsg("Not all attachments will be scanned\n"); |
|
871 |
- /*return 2;*/ |
|
872 |
- } |
|
866 |
+ cli_dbgmsg("in parseEmailBody\n"); |
|
873 | 867 |
|
874 | 868 |
aText = textIn; |
875 |
- blobs = blobsIn; |
|
876 | 869 |
messages = NULL; |
877 | 870 |
mainMessage = messageIn; |
878 | 871 |
|
879 | 872 |
/* Anything left to be parsed? */ |
880 | 873 |
if(mainMessage && (messageGetBody(mainMessage) != NULL)) { |
881 |
- int numberOfAttachments = 0, numberOfNewAttachments; |
|
882 | 874 |
mime_type mimeType; |
883 | 875 |
const char *mimeSubtype; |
884 | 876 |
const text *t_line; |
... | ... |
@@ -1198,10 +1190,7 @@ parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, con |
1198 | 1198 |
cli_dbgmsg("No HTML code found to be scanned"); |
1199 | 1199 |
rc = 0; |
1200 | 1200 |
} else |
1201 |
- rc = parseEmailBody(aMessage, blobs, nBlobs, aText, dir, rfc821Table, subtypeTable, options); |
|
1202 |
- blobArrayDestroy(blobs, nBlobs); |
|
1203 |
- blobs = NULL; |
|
1204 |
- nBlobs = 0; |
|
1201 |
+ rc = parseEmailBody(aMessage, aText, dir, rfc821Table, subtypeTable, options); |
|
1205 | 1202 |
|
1206 | 1203 |
/* |
1207 | 1204 |
* Fixed based on an idea from Stephen White <stephen@earth.li> |
... | ... |
@@ -1238,19 +1227,15 @@ parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, con |
1238 | 1238 |
aMessage = messages[htmltextPart]; |
1239 | 1239 |
aText = textAddMessage(aText, aMessage); |
1240 | 1240 |
|
1241 |
- rc = parseEmailBody(NULL, blobs, nBlobs, aText, dir, rfc821Table, subtypeTable, options); |
|
1241 |
+ rc = parseEmailBody(NULL, aText, dir, rfc821Table, subtypeTable, options); |
|
1242 | 1242 |
|
1243 |
- if(rc == 1) { |
|
1243 |
+ if(rc == 1) |
|
1244 | 1244 |
/* |
1245 | 1245 |
* Alternative message has saved its |
1246 | 1246 |
* attachments, ensure we don't do |
1247 | 1247 |
* the same thing |
1248 | 1248 |
*/ |
1249 |
- blobArrayDestroy(blobs, nBlobs); |
|
1250 |
- blobs = NULL; |
|
1251 |
- nBlobs = 0; |
|
1252 | 1249 |
rc = 2; |
1253 |
- } |
|
1254 | 1250 |
/* |
1255 | 1251 |
* Fall through - some clients are broken and |
1256 | 1252 |
* say alternative instead of mixed. The Klez |
... | ... |
@@ -1285,7 +1270,7 @@ parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, con |
1285 | 1285 |
bool addAttachment = FALSE; |
1286 | 1286 |
bool addToText = FALSE; |
1287 | 1287 |
const char *dtype; |
1288 |
-#if 0 |
|
1288 |
+#ifndef SAVE_TO_DISC |
|
1289 | 1289 |
message *body; |
1290 | 1290 |
#endif |
1291 | 1291 |
|
... | ... |
@@ -1320,8 +1305,6 @@ parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, con |
1320 | 1320 |
if(mainMessage) { |
1321 | 1321 |
const text *u_line = uuencodeBegin(mainMessage); |
1322 | 1322 |
if(u_line) { |
1323 |
- fileblob *fb; |
|
1324 |
- |
|
1325 | 1323 |
cli_dbgmsg("Found uuencoded message in multipart/mixed mainMessage\n"); |
1326 | 1324 |
messageSetEncoding(mainMessage, "x-uuencode"); |
1327 | 1325 |
fb = messageToFileblob(mainMessage, dir); |
... | ... |
@@ -1432,7 +1415,7 @@ parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, con |
1432 | 1432 |
messageDestroy(messages[i]); |
1433 | 1433 |
messages[i] = NULL; |
1434 | 1434 |
if(body) { |
1435 |
- rc = parseEmailBody(body, blobs, nBlobs, NULL, dir, rfc821Table, subtypeTable, options); |
|
1435 |
+ rc = parseEmailBody(body, NULL, dir, rfc821Table, subtypeTable, options); |
|
1436 | 1436 |
messageDestroy(body); |
1437 | 1437 |
} |
1438 | 1438 |
#endif |
... | ... |
@@ -1449,13 +1432,13 @@ parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, con |
1449 | 1449 |
* The headers were parsed when reading in the |
1450 | 1450 |
* whole multipart section |
1451 | 1451 |
*/ |
1452 |
- rc = parseEmailBody(aMessage, blobs, nBlobs, aText, dir, rfc821Table, subtypeTable, options); |
|
1452 |
+ rc = parseEmailBody(aMessage, aText, dir, rfc821Table, subtypeTable, options); |
|
1453 | 1453 |
cli_dbgmsg("Finished recursion\n"); |
1454 | 1454 |
assert(aMessage == messages[i]); |
1455 | 1455 |
messageDestroy(messages[i]); |
1456 | 1456 |
messages[i] = NULL; |
1457 | 1457 |
} else { |
1458 |
- rc = parseEmailBody(NULL, blobs, nBlobs, NULL, dir, rfc821Table, subtypeTable, options); |
|
1458 |
+ rc = parseEmailBody(NULL, NULL, dir, rfc821Table, subtypeTable, options); |
|
1459 | 1459 |
if(mainMessage && (mainMessage != messageIn)) |
1460 | 1460 |
messageDestroy(mainMessage); |
1461 | 1461 |
mainMessage = NULL; |
... | ... |
@@ -1487,15 +1470,8 @@ parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, con |
1487 | 1487 |
|
1488 | 1488 |
if(addToText) |
1489 | 1489 |
aText = textAdd(aText, messageGetBody(aMessage)); |
1490 |
- else if(numberOfAttachments >= MAX_ATTACHMENTS) { |
|
1491 |
- cli_warnmsg("Not all attachments will be scanned\n"); |
|
1492 |
- /* |
|
1493 |
- * Try our best to save it |
|
1494 |
- * somewhere |
|
1495 |
- */ |
|
1496 |
- aText = textAdd(aText, messageGetBody(aMessage)); |
|
1497 |
- } else { |
|
1498 |
- fileblob *fb = messageToFileblob(aMessage, dir); |
|
1490 |
+ else { |
|
1491 |
+ fb = messageToFileblob(aMessage, dir); |
|
1499 | 1492 |
|
1500 | 1493 |
if(fb) |
1501 | 1494 |
fileblobDestroy(fb); |
... | ... |
@@ -1505,71 +1481,7 @@ parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, con |
1505 | 1505 |
messages[i] = NULL; |
1506 | 1506 |
} |
1507 | 1507 |
|
1508 |
- if(numberOfAttachments == 0) { |
|
1509 |
- /* No usable attachment was found */ |
|
1510 |
- rc = parseEmailBody(NULL, NULL, 0, aText, dir, rfc821Table, subtypeTable, options); |
|
1511 |
- break; |
|
1512 |
- } |
|
1513 |
- |
|
1514 |
- /* |
|
1515 |
- * Store any existing attachments at the end of |
|
1516 |
- * the list we've just built up |
|
1517 |
- */ |
|
1518 |
- numberOfNewAttachments = 0; |
|
1519 |
- for(i = 0; i < nBlobs; i++) { |
|
1520 |
- int j; |
|
1521 |
-#ifdef CL_DEBUG |
|
1522 |
- assert(blobs[i]->magic == BLOB); |
|
1523 |
-#endif |
|
1524 |
- /* |
|
1525 |
- * TODO: Now that fileblob is used |
|
1526 |
- * this checking doesn't happen, |
|
1527 |
- * need another means to save scanning |
|
1528 |
- * two attachments that are the same |
|
1529 |
- */ |
|
1530 |
- for(j = 0; j < numberOfAttachments; j++) |
|
1531 |
- if(blobcmp(blobs[i], blobList[j]) == 0) |
|
1532 |
- break; |
|
1533 |
- if(j >= numberOfAttachments) { |
|
1534 |
- assert(numberOfAttachments < MAX_ATTACHMENTS); |
|
1535 |
- cli_dbgmsg("Attaching %s to list of blobs\n", |
|
1536 |
- blobGetFilename(blobs[i])); |
|
1537 |
- blobClose(blobs[i]); |
|
1538 |
- blobList[numberOfAttachments++] = blobs[i]; |
|
1539 |
- numberOfNewAttachments++; |
|
1540 |
- } else { |
|
1541 |
- cli_warnmsg("Don't scan the same file twice as '%s' and '%s'\n", |
|
1542 |
- blobGetFilename(blobs[i]), |
|
1543 |
- blobGetFilename(blobList[j])); |
|
1544 |
- blobDestroy(blobs[i]); |
|
1545 |
- blobs[i] = NULL; |
|
1546 |
- } |
|
1547 |
- } |
|
1548 |
- |
|
1549 |
- /* |
|
1550 |
- * If we've found nothing new save what we have |
|
1551 |
- * and quit - that's this part all done. |
|
1552 |
- */ |
|
1553 |
- if(numberOfNewAttachments == 0) { |
|
1554 |
- rc = parseEmailBody(NULL, blobList, numberOfAttachments, NULL, dir, rfc821Table, subtypeTable, options); |
|
1555 |
- break; |
|
1556 |
- } |
|
1557 |
- /* |
|
1558 |
- * If there's only one part of the MULTIPART |
|
1559 |
- * we already have the body to decode so |
|
1560 |
- * there's no more work to do. |
|
1561 |
- * |
|
1562 |
- * This is mostly for the situation where |
|
1563 |
- * broken messages claim to be multipart |
|
1564 |
- * but aren't was causing us to go into |
|
1565 |
- * infinite recursion |
|
1566 |
- */ |
|
1567 |
- if(multiparts > 1) |
|
1568 |
- rc = parseEmailBody(mainMessage, blobList, numberOfAttachments, aText, dir, rfc821Table, subtypeTable, options); |
|
1569 |
- else if(numberOfAttachments == 1) { |
|
1570 |
- (void)saveFile(blobList[0], dir); |
|
1571 |
- blobDestroy(blobList[0]); |
|
1572 |
- } |
|
1508 |
+ /* rc = parseEmailBody(NULL, NULL, dir, rfc821Table, subtypeTable, options); */ |
|
1573 | 1509 |
break; |
1574 | 1510 |
case DIGEST: |
1575 | 1511 |
/* |
... | ... |
@@ -1592,10 +1504,7 @@ parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, con |
1592 | 1592 |
if(htmltextPart == -1) |
1593 | 1593 |
htmltextPart = 0; |
1594 | 1594 |
|
1595 |
- rc = parseEmailBody(messages[htmltextPart], blobs, nBlobs, aText, dir, rfc821Table, subtypeTable, options); |
|
1596 |
- blobArrayDestroy(blobs, nBlobs); |
|
1597 |
- blobs = NULL; |
|
1598 |
- nBlobs = 0; |
|
1595 |
+ rc = parseEmailBody(messages[htmltextPart], aText, dir, rfc821Table, subtypeTable, options); |
|
1599 | 1596 |
break; |
1600 | 1597 |
default: |
1601 | 1598 |
/* |
... | ... |
@@ -1612,9 +1521,6 @@ parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, con |
1612 | 1612 |
if(messages[i]) |
1613 | 1613 |
messageDestroy(messages[i]); |
1614 | 1614 |
|
1615 |
- if(blobs && (blobsIn == NULL)) |
|
1616 |
- puts("arraydestroy"); |
|
1617 |
- |
|
1618 | 1615 |
if(mainMessage && (mainMessage != messageIn)) |
1619 | 1616 |
messageDestroy(mainMessage); |
1620 | 1617 |
|
... | ... |
@@ -1650,7 +1556,7 @@ parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, con |
1650 | 1650 |
mainMessage = NULL; |
1651 | 1651 |
} |
1652 | 1652 |
if(messageGetBody(m)) |
1653 |
- rc = parseEmailBody(m, NULL, 0, NULL, dir, rfc821Table, subtypeTable, options); |
|
1653 |
+ rc = parseEmailBody(m, NULL, dir, rfc821Table, subtypeTable, options); |
|
1654 | 1654 |
|
1655 | 1655 |
messageDestroy(m); |
1656 | 1656 |
} |
... | ... |
@@ -1680,7 +1586,7 @@ parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, con |
1680 | 1680 |
/*if((strcasecmp(cptr, "octet-stream") == 0) || |
1681 | 1681 |
(strcasecmp(cptr, "x-msdownload") == 0)) {*/ |
1682 | 1682 |
{ |
1683 |
- fileblob *fb = messageToFileblob(mainMessage, dir); |
|
1683 |
+ fb = messageToFileblob(mainMessage, dir); |
|
1684 | 1684 |
|
1685 | 1685 |
if(fb) { |
1686 | 1686 |
cli_dbgmsg("Saving main message as attachment\n"); |
... | ... |
@@ -1706,152 +1612,127 @@ parseEmailBody(message *messageIn, blob **blobsIn, int nBlobs, text *textIn, con |
1706 | 1706 |
aText = NULL; |
1707 | 1707 |
} |
1708 | 1708 |
|
1709 |
- cli_dbgmsg("%d attachments found\n", nBlobs); |
|
1709 |
+ /* |
|
1710 |
+ * No attachments - scan the text portions, often files |
|
1711 |
+ * are hidden in HTML code |
|
1712 |
+ */ |
|
1713 |
+ cli_dbgmsg("%d multiparts found\n", multiparts); |
|
1714 |
+ for(i = 0; i < multiparts; i++) { |
|
1715 |
+ fb = messageToFileblob(messages[i], dir); |
|
1710 | 1716 |
|
1711 |
- if(nBlobs == 0) { |
|
1712 |
- fileblob *fb; |
|
1717 |
+ if(fb) { |
|
1718 |
+ cli_dbgmsg("Saving multipart %d, encoded with scheme %d\n", |
|
1719 |
+ i, messageGetEncoding(messages[i])); |
|
1713 | 1720 |
|
1721 |
+ fileblobDestroy(fb); |
|
1722 |
+ } |
|
1723 |
+ } |
|
1724 |
+ |
|
1725 |
+ if(mainMessage) { |
|
1714 | 1726 |
/* |
1715 |
- * No attachments - scan the text portions, often files |
|
1716 |
- * are hidden in HTML code |
|
1727 |
+ * Look for uu-encoded main file |
|
1717 | 1728 |
*/ |
1718 |
- cli_dbgmsg("%d multiparts found\n", multiparts); |
|
1719 |
- for(i = 0; i < multiparts; i++) { |
|
1720 |
- fb = messageToFileblob(messages[i], dir); |
|
1729 |
+ const text *t_line; |
|
1730 |
+ |
|
1731 |
+ if((t_line = uuencodeBegin(mainMessage)) != NULL) { |
|
1732 |
+ cli_dbgmsg("Found uuencoded file\n"); |
|
1721 | 1733 |
|
1722 |
- if(fb) { |
|
1723 |
- cli_dbgmsg("Saving multipart %d, encoded with scheme %d\n", |
|
1724 |
- i, messageGetEncoding(messages[i])); |
|
1734 |
+ /* |
|
1735 |
+ * Main part contains uuencoded section |
|
1736 |
+ */ |
|
1737 |
+ messageSetEncoding(mainMessage, "x-uuencode"); |
|
1725 | 1738 |
|
1739 |
+ if((fb = messageToFileblob(mainMessage, dir)) != NULL) { |
|
1740 |
+ if((cptr = fileblobGetFilename(fb)) != NULL) |
|
1741 |
+ cli_dbgmsg("Found uuencoded message %s\n", cptr); |
|
1726 | 1742 |
fileblobDestroy(fb); |
1727 | 1743 |
} |
1728 |
- } |
|
1729 |
- |
|
1730 |
- if(mainMessage) { |
|
1744 |
+ } else if((encodingLine(mainMessage) != NULL) && |
|
1745 |
+ ((t_line = bounceBegin(mainMessage)) != NULL)) { |
|
1746 |
+ const text *t; |
|
1747 |
+ static const char encoding[] = "Content-Transfer-Encoding"; |
|
1731 | 1748 |
/* |
1732 |
- * Look for uu-encoded main file |
|
1749 |
+ * Attempt to save the original (unbounced) |
|
1750 |
+ * message - clamscan will find that in the |
|
1751 |
+ * directory and call us again (with any luck) |
|
1752 |
+ * having found an e-mail message to handle |
|
1753 |
+ * |
|
1754 |
+ * This finds a lot of false positives, the |
|
1755 |
+ * search that an encoding line is in the |
|
1756 |
+ * bounce (i.e. it's after the bounce header) |
|
1757 |
+ * helps a bit, but at the expense of scanning |
|
1758 |
+ * the entire message. messageAddLine |
|
1759 |
+ * optimisation could help here, but needs |
|
1760 |
+ * careful thought, do it with line numbers |
|
1761 |
+ * would be best, since the current method in |
|
1762 |
+ * messageAddLine of checking encoding first |
|
1763 |
+ * must remain otherwise non bounce messages |
|
1764 |
+ * won't be scanned |
|
1733 | 1765 |
*/ |
1734 |
- const text *t_line; |
|
1766 |
+ for(t = t_line; t; t = t->t_next) { |
|
1767 |
+ const char *txt = lineGetData(t->t_line); |
|
1768 |
+ |
|
1769 |
+ if(txt && |
|
1770 |
+ (strncasecmp(txt, encoding, sizeof(encoding) - 1) == 0) && |
|
1771 |
+ (strstr(txt, "7bit") == NULL) && |
|
1772 |
+ (strstr(txt, "8bit") == NULL)) |
|
1773 |
+ break; |
|
1774 |
+ } |
|
1775 |
+ if(t && ((fb = fileblobCreate()) != NULL)) { |
|
1776 |
+ cli_dbgmsg("Found a bounce message\n"); |
|
1777 |
+ fileblobSetFilename(fb, dir, "bounce"); |
|
1778 |
+ fb = textToFileblob(t_line, fb); |
|
1779 |
+ fileblobDestroy(fb); |
|
1780 |
+ } |
|
1781 |
+ } else { |
|
1782 |
+ bool saveIt; |
|
1735 | 1783 |
|
1736 |
- if((t_line = uuencodeBegin(mainMessage)) != NULL) { |
|
1737 |
- cli_dbgmsg("Found uuencoded file\n"); |
|
1784 |
+ cli_dbgmsg("Not found uuencoded file\n"); |
|
1738 | 1785 |
|
1786 |
+ if(messageGetMimeType(mainMessage) == MESSAGE) |
|
1739 | 1787 |
/* |
1740 |
- * Main part contains uuencoded section |
|
1788 |
+ * Quick peek, if the encapsulated |
|
1789 |
+ * message has no |
|
1790 |
+ * content encoding statement don't |
|
1791 |
+ * bother saving to scan, it's safe |
|
1741 | 1792 |
*/ |
1742 |
- messageSetEncoding(mainMessage, "x-uuencode"); |
|
1743 |
- |
|
1744 |
- if((fb = messageToFileblob(mainMessage, dir)) != NULL) { |
|
1745 |
- if((cptr = fileblobGetFilename(fb)) != NULL) |
|
1746 |
- cli_dbgmsg("Found uuencoded message %s\n", cptr); |
|
1747 |
- fileblobDestroy(fb); |
|
1748 |
- } |
|
1749 |
- } else if((encodingLine(mainMessage) != NULL) && |
|
1750 |
- ((t_line = bounceBegin(mainMessage)) != NULL)) { |
|
1751 |
- const text *t; |
|
1752 |
- static const char encoding[] = "Content-Transfer-Encoding"; |
|
1793 |
+ saveIt = (encodingLine(mainMessage) != NULL); |
|
1794 |
+ else if((t_line = encodingLine(mainMessage)) != NULL) { |
|
1753 | 1795 |
/* |
1754 |
- * Attempt to save the original (unbounced) |
|
1755 |
- * message - clamscan will find that in the |
|
1756 |
- * directory and call us again (with any luck) |
|
1757 |
- * having found an e-mail message to handle |
|
1758 |
- * |
|
1759 |
- * This finds a lot of false positives, the |
|
1760 |
- * search that an encoding line is in the |
|
1761 |
- * bounce (i.e. it's after the bounce header) |
|
1762 |
- * helps a bit, but at the expense of scanning |
|
1763 |
- * the entire message. messageAddLine |
|
1764 |
- * optimisation could help here, but needs |
|
1765 |
- * careful thought, do it with line numbers |
|
1766 |
- * would be best, since the current method in |
|
1767 |
- * messageAddLine of checking encoding first |
|
1768 |
- * must remain otherwise non bounce messages |
|
1769 |
- * won't be scanned |
|
1796 |
+ * Some bounces include the message |
|
1797 |
+ * body without the headers. |
|
1798 |
+ * Unfortunately this generates a |
|
1799 |
+ * lot of false positives that a bounce |
|
1800 |
+ * has been found when it hasn't. |
|
1770 | 1801 |
*/ |
1771 |
- for(t = t_line; t; t = t->t_next) { |
|
1772 |
- const char *txt = lineGetData(t->t_line); |
|
1773 |
- |
|
1774 |
- if(txt && |
|
1775 |
- (strncasecmp(txt, encoding, sizeof(encoding) - 1) == 0) && |
|
1776 |
- (strstr(txt, "7bit") == NULL) && |
|
1777 |
- (strstr(txt, "8bit") == NULL)) |
|
1778 |
- break; |
|
1779 |
- } |
|
1780 |
- if(t && ((fb = fileblobCreate()) != NULL)) { |
|
1781 |
- cli_dbgmsg("Found a bounce message\n"); |
|
1802 |
+ if((fb = fileblobCreate()) != NULL) { |
|
1803 |
+ cli_dbgmsg("Found a bounce message with no header\n"); |
|
1782 | 1804 |
fileblobSetFilename(fb, dir, "bounce"); |
1783 |
- fb = textToFileblob(t_line, fb); |
|
1784 |
- fileblobDestroy(fb); |
|
1785 |
- } |
|
1786 |
- } else { |
|
1787 |
- bool saveIt; |
|
1788 |
- |
|
1789 |
- cli_dbgmsg("Not found uuencoded file\n"); |
|
1805 |
+ fileblobAddData(fb, "Received: by clamd\n", 19); |
|
1790 | 1806 |
|
1791 |
- if(messageGetMimeType(mainMessage) == MESSAGE) |
|
1792 |
- /* |
|
1793 |
- * Quick peek, if the encapsulated |
|
1794 |
- * message has no |
|
1795 |
- * content encoding statement don't |
|
1796 |
- * bother saving to scan, it's safe |
|
1797 |
- */ |
|
1798 |
- saveIt = (encodingLine(mainMessage) != NULL); |
|
1799 |
- else if((t_line = encodingLine(mainMessage)) != NULL) { |
|
1800 |
- /* |
|
1801 |
- * Some bounces include the message |
|
1802 |
- * body without the headers. |
|
1803 |
- * Unfortunately this generates a |
|
1804 |
- * lot of false positives that a bounce |
|
1805 |
- * has been found when it hasn't. |
|
1806 |
- * |
|
1807 |
- * TODO: use fileblobCreate here |
|
1808 |
- */ |
|
1809 |
- if((fb = fileblobCreate()) != NULL) { |
|
1810 |
- cli_dbgmsg("Found a bounce message with no header\n"); |
|
1811 |
- fileblobSetFilename(fb, dir, "bounce"); |
|
1812 |
- fileblobAddData(fb, "Received: by clamd\n", 19); |
|
1813 |
- |
|
1814 |
- fb = textToFileblob(t_line, fb); |
|
1815 |
- |
|
1816 |
- fileblobDestroy(fb); |
|
1817 |
- } |
|
1818 |
- saveIt = FALSE; |
|
1819 |
- } else |
|
1820 |
- /* |
|
1821 |
- * Save the entire text portion, |
|
1822 |
- * since it it may be an HTML file with |
|
1823 |
- * a JavaScript virus |
|
1824 |
- */ |
|
1825 |
- saveIt = TRUE; |
|
1807 |
+ fb = textToFileblob(t_line, fb); |
|
1826 | 1808 |
|
1827 |
- if(saveIt) { |
|
1828 |
- cli_dbgmsg("Saving text part to scan\n"); |
|
1829 |
- /* |
|
1830 |
- * TODO: May be better to save aText |
|
1831 |
- */ |
|
1832 |
- saveTextPart(mainMessage, dir); |
|
1809 |
+ fileblobDestroy(fb); |
|
1833 | 1810 |
} |
1834 |
- } |
|
1835 |
- } else |
|
1836 |
- rc = (multiparts) ? 1 : 2; /* anything saved? */ |
|
1837 |
- } else { |
|
1838 |
- short attachmentNumber; |
|
1839 |
- |
|
1840 |
- for(attachmentNumber = 0; attachmentNumber < nBlobs; attachmentNumber++) { |
|
1841 |
- blob *b = blobs[attachmentNumber]; |
|
1811 |
+ saveIt = FALSE; |
|
1812 |
+ } else |
|
1813 |
+ /* |
|
1814 |
+ * Save the entire text portion, |
|
1815 |
+ * since it it may be an HTML file with |
|
1816 |
+ * a JavaScript virus |
|
1817 |
+ */ |
|
1818 |
+ saveIt = TRUE; |
|
1842 | 1819 |
|
1843 |
- if(b) { |
|
1844 |
- if(!saveFile(b, dir)) |
|
1845 |
- break; |
|
1846 |
- blobDestroy(b); |
|
1847 |
- blobs[attachmentNumber] = NULL; |
|
1820 |
+ if(saveIt) { |
|
1821 |
+ cli_dbgmsg("Saving text part to scan\n"); |
|
1822 |
+ /* |
|
1823 |
+ * TODO: May be better to save aText |
|
1824 |
+ */ |
|
1825 |
+ saveTextPart(mainMessage, dir); |
|
1848 | 1826 |
} |
1849 | 1827 |
} |
1850 |
- } |
|
1851 |
- |
|
1852 |
- /* Already done */ |
|
1853 |
- if(blobs && (blobsIn == NULL)) |
|
1854 |
- blobArrayDestroy(blobs, nBlobs); |
|
1828 |
+ } else |
|
1829 |
+ rc = (multiparts) ? 1 : 2; /* anything saved? */ |
|
1855 | 1830 |
|
1856 | 1831 |
if(mainMessage && (mainMessage != messageIn)) |
1857 | 1832 |
messageDestroy(mainMessage); |
... | ... |
@@ -2184,6 +2065,7 @@ saveTextPart(message *m, const char *dir) |
2184 | 2184 |
} |
2185 | 2185 |
} |
2186 | 2186 |
|
2187 |
+#if 0 |
|
2187 | 2188 |
/* |
2188 | 2189 |
* Save some data as a unique file in the given directory. |
2189 | 2190 |
* |
... | ... |
@@ -2283,6 +2165,7 @@ saveFile(const blob *b, const char *dir) |
2283 | 2283 |
|
2284 | 2284 |
return (close(fd) >= 0); |
2285 | 2285 |
} |
2286 |
+#endif |
|
2286 | 2287 |
|
2287 | 2288 |
#ifdef FOLLOWURLS |
2288 | 2289 |
static void |