git-svn: trunk@2051
Nigel Horne authored on 2006/06/29 01:06:07... | ... |
@@ -16,7 +16,7 @@ |
16 | 16 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
17 | 17 |
* MA 02110-1301, USA. |
18 | 18 |
*/ |
19 |
-static char const rcsid[] = "$Id: mbox.c,v 1.311 2006/06/07 12:28:49 njh Exp $"; |
|
19 |
+static char const rcsid[] = "$Id: mbox.c,v 1.312 2006/06/28 16:06:07 njh Exp $"; |
|
20 | 20 |
|
21 | 21 |
#if HAVE_CONFIG_H |
22 | 22 |
#include "clamav-config.h" |
... | ... |
@@ -98,7 +98,7 @@ typedef enum { FALSE = 0, TRUE = 1 } bool; |
98 | 98 |
#define SAVE_TO_DISC /* multipart/message are saved in a temporary file */ |
99 | 99 |
|
100 | 100 |
/* |
101 |
- * Code does exist to run FOLLORURLS on systems without libcurl, however that |
|
101 |
+ * Code does exist to run FOLLOWURLS on systems without libcurl, however that |
|
102 | 102 |
* is not recommended so it is not compiled by default |
103 | 103 |
* |
104 | 104 |
* On Solaris, when using the GNU C compiler, the clamAV build system uses the |
... | ... |
@@ -138,6 +138,23 @@ typedef enum { FALSE = 0, TRUE = 1 } bool; |
138 | 138 |
* Needs curl >= 7.11 (I've heard that 7.9 can cause crashes and I have seen |
139 | 139 |
* 7.10 segfault, later versions can be flakey as well) |
140 | 140 |
* untested) |
141 |
+ * |
|
142 |
+ * Even 7.15 crashes, valgrind shows this: |
|
143 |
+ * ==2835== Warning: client switching stacks? SP change: 0xBEB0FD2C --> 0xD0678F0 |
|
144 |
+* ==2835== to suppress, use: --max-stackframe=1314225092 or greater |
|
145 |
+ |
|
146 |
+ * ==2835== Invalid write of size 4 |
|
147 |
+ * ==2835== at 0x40F67BD: Curl_resolv (in /usr/lib/libcurl.so.3.0.0) |
|
148 |
+ * ==2835== Address 0xD0678F4 is on thread 1's stack |
|
149 |
+ * ==2835== Can't extend stack to 0xD067390 during signal delivery for thread 1: |
|
150 |
+ * ==2835== no stack segment |
|
151 |
+ * ==2835== |
|
152 |
+ * ==2835== Process terminating with default action of signal 11 (SIGSEGV) |
|
153 |
+ * ==2835== Access not within mapped region at address 0xD067390 |
|
154 |
+ * ==2835== at 0x40F67BD: Curl_resolv (in /usr/lib/libcurl.so.3.0.0) |
|
155 |
+ * |
|
156 |
+ * This bug has been reported upstream, however they claim that the bug |
|
157 |
+ * does not exist :-( |
|
141 | 158 |
*/ |
142 | 159 |
#if (LIBCURL_VERSION_NUM < 0x070B00) |
143 | 160 |
#undef WITH_CURL /* also undef FOLLOWURLS? */ |
... | ... |
@@ -191,6 +208,7 @@ static int rfc1341(message *m, const char *dir); |
191 | 191 |
static bool usefulHeader(int commandNumber, const char *cmd); |
192 | 192 |
static char *getline_from_mbox(char *buffer, size_t len, FILE *fin); |
193 | 193 |
static bool isBounceStart(const char *line); |
194 |
+static bool binhexMessage(const char *dir, message *message); |
|
194 | 195 |
|
195 | 196 |
static void checkURLs(message *m, const char *dir); |
196 | 197 |
#ifdef WITH_CURL |
... | ... |
@@ -368,6 +386,8 @@ static void free_map(void); |
368 | 368 |
* TODO: Add support for systems without mmap() |
369 | 369 |
* |
370 | 370 |
* TODO: partial_dir fall through |
371 |
+ * |
|
372 |
+ * FIXME: Some EICAR gets through |
|
371 | 373 |
*/ |
372 | 374 |
int |
373 | 375 |
cli_mbox(const char *dir, int desc, cli_ctx *ctx) |
... | ... |
@@ -1953,9 +1973,8 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t |
1953 | 1953 |
cli_dbgmsg("Changing message/rfc822-headers to text/rfc822-headers\n"); |
1954 | 1954 |
mimeType = NOMIME; |
1955 | 1955 |
messageSetMimeSubtype(mainMessage, ""); |
1956 |
- } |
|
1957 |
- |
|
1958 |
- cli_dbgmsg("mimeType = %d\n", mimeType); |
|
1956 |
+ } else |
|
1957 |
+ cli_dbgmsg("mimeType = %d\n", mimeType); |
|
1959 | 1958 |
|
1960 | 1959 |
switch(mimeType) { |
1961 | 1960 |
case NOMIME: |
... | ... |
@@ -2011,12 +2030,10 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t |
2011 | 2011 |
* TODO: check yEnc |
2012 | 2012 |
*/ |
2013 | 2013 |
if(binhexBegin(mainMessage) == t_line) { |
2014 |
- if(messageGetEncoding(mainMessage) == NOENCODING) { |
|
2015 |
- messageSetEncoding(mainMessage, "x-binhex"); |
|
2016 |
- fb = messageToFileblob(mainMessage, dir); |
|
2017 |
- |
|
2018 |
- if(fb) |
|
2019 |
- fileblobDestroy(fb); |
|
2014 |
+ if(binhexMessage(dir, mainMessage)) { |
|
2015 |
+ /* virus found */ |
|
2016 |
+ rc = 3; |
|
2017 |
+ break; |
|
2020 | 2018 |
} |
2021 | 2019 |
} else if(encodingLine(mainMessage) == t_line->t_next) { |
2022 | 2020 |
/* |
... | ... |
@@ -2505,15 +2522,10 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t |
2505 | 2505 |
if(mainMessage) { |
2506 | 2506 |
if(binhexBegin(aMessage)) { |
2507 | 2507 |
cli_dbgmsg("Found binhex message in multipart/mixed mainMessage\n"); |
2508 |
- messageSetEncoding(mainMessage, "x-bunhex"); |
|
2509 |
- fb = messageToFileblob(mainMessage, dir); |
|
2510 | 2508 |
|
2511 |
- if(fb) { |
|
2512 |
- if(fileblobContainsVirus(fb)) { |
|
2513 |
- infected = TRUE; |
|
2514 |
- rc = 3; |
|
2515 |
- } |
|
2516 |
- fileblobDestroy(fb); |
|
2509 |
+ if(binhexMessage(dir, mainMessage)) { |
|
2510 |
+ infected = TRUE; |
|
2511 |
+ rc = 3; |
|
2517 | 2512 |
} |
2518 | 2513 |
} |
2519 | 2514 |
if(mainMessage != messageIn) |
... | ... |
@@ -2522,15 +2534,9 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t |
2522 | 2522 |
} else if(aMessage) { |
2523 | 2523 |
if(binhexBegin(aMessage)) { |
2524 | 2524 |
cli_dbgmsg("Found binhex message in multipart/mixed non mime part\n"); |
2525 |
- messageSetEncoding(aMessage, "x-binhex"); |
|
2526 |
- fb = messageToFileblob(aMessage, dir); |
|
2527 |
- |
|
2528 |
- if(fb) { |
|
2529 |
- if(fileblobContainsVirus(fb)) { |
|
2530 |
- infected = TRUE; |
|
2531 |
- rc = 3; |
|
2532 |
- } |
|
2533 |
- fileblobDestroy(fb); |
|
2525 |
+ if(binhexMessage(dir, aMessage)) { |
|
2526 |
+ infected = TRUE; |
|
2527 |
+ rc = 3; |
|
2534 | 2528 |
} |
2535 | 2529 |
assert(aMessage == messages[i]); |
2536 | 2530 |
messageReset(messages[i]); |
... | ... |
@@ -3006,7 +3012,7 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t |
3006 | 3006 |
} |
3007 | 3007 |
} |
3008 | 3008 |
|
3009 |
- if(mainMessage) { |
|
3009 |
+ if(mainMessage && (rc != 3)) { |
|
3010 | 3010 |
/* |
3011 | 3011 |
* Look for uu-encoded main file |
3012 | 3012 |
*/ |
... | ... |
@@ -3112,7 +3118,7 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t |
3112 | 3112 |
/* |
3113 | 3113 |
* Save the entire text portion, |
3114 | 3114 |
* since it it may be an HTML file with |
3115 |
- * a JavaScript virus |
|
3115 |
+ * a JavaScript virus or a phish |
|
3116 | 3116 |
*/ |
3117 | 3117 |
saveIt = TRUE; |
3118 | 3118 |
else |
... | ... |
@@ -3141,8 +3147,8 @@ parseEmailBody(message *messageIn, text *textIn, const char *dir, const table_t |
3141 | 3141 |
if(messages) |
3142 | 3142 |
free(messages); |
3143 | 3143 |
|
3144 |
- if((rc == CL_SUCCESS) && infected) |
|
3145 |
- rc = CL_VIRUS; |
|
3144 |
+ if((rc != 0) && infected) |
|
3145 |
+ rc = 3; |
|
3146 | 3146 |
|
3147 | 3147 |
cli_dbgmsg("parseEmailBody() returning %d\n", rc); |
3148 | 3148 |
|
... | ... |
@@ -4475,3 +4481,31 @@ isBounceStart(const char *line) |
4475 | 4475 |
} |
4476 | 4476 |
return TRUE; |
4477 | 4477 |
} |
4478 |
+ |
|
4479 |
+/* |
|
4480 |
+ * Extract a binhexEncoded message, return if it's found to be infected as we |
|
4481 |
+ * extract it |
|
4482 |
+ */ |
|
4483 |
+static bool |
|
4484 |
+binhexMessage(const char *dir, message *m) |
|
4485 |
+{ |
|
4486 |
+ bool infected = FALSE; |
|
4487 |
+ fileblob *fb; |
|
4488 |
+ |
|
4489 |
+ if(messageGetEncoding(m) == NOENCODING) |
|
4490 |
+ messageSetEncoding(m, "x-binhex"); |
|
4491 |
+ |
|
4492 |
+ fb = messageToFileblob(m, dir); |
|
4493 |
+ |
|
4494 |
+ if(fb) { |
|
4495 |
+ if(fileblobContainsVirus(fb)) |
|
4496 |
+ infected = TRUE; |
|
4497 |
+ |
|
4498 |
+ cli_dbgmsg("Binhex file decoded to %s\n", |
|
4499 |
+ fileblobGetFilename(fb)); |
|
4500 |
+ fileblobDestroy(fb); |
|
4501 |
+ } else |
|
4502 |
+ cli_errmsg("Couldn't decode binhex file to %s\n", dir); |
|
4503 |
+ |
|
4504 |
+ return infected; |
|
4505 |
+} |