Browse code

Support multitype/fax-message

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
Showing 2 changed files
... ...
@@ -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);