Browse code

Some viruses in embedded messages were not being found

git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@158 77e5149b-7576-45b1-b177-96237e5ba77b

Nigel Horne authored on 2003/12/15 03:08:29
Showing 2 changed files
... ...
@@ -1,3 +1,7 @@
1
+Sun Dec 14 18:07:44 GMT 2003 (njh)
2
+----------------------------------
3
+  * libclamav: not all viruses were being found in embedded RFC822 messages
4
+
1 5
 Sat Dec 13 16:45:44 GMT 2003 (njh)
2 6
 ----------------------------------
3 7
   * libclamav: use new cl_chomp() and fixed memory leak
... ...
@@ -17,6 +17,9 @@
17 17
  *
18 18
  * Change History:
19 19
  * $Log: mbox.c,v $
20
+ * Revision 1.23  2003/12/14 18:07:01  nigelhorne
21
+ * Some viruses in embedded messages were not being found
22
+ *
20 23
  * Revision 1.22  2003/12/13 16:42:23  nigelhorne
21 24
  * call new cli_chomp
22 25
  *
... ...
@@ -57,7 +60,7 @@
57 57
  * Compilable under SCO; removed duplicate code with message.c
58 58
  *
59 59
  */
60
-static	char	const	rcsid[] = "$Id: mbox.c,v 1.22 2003/12/13 16:42:23 nigelhorne Exp $";
60
+static	char	const	rcsid[] = "$Id: mbox.c,v 1.23 2003/12/14 18:07:01 nigelhorne Exp $";
61 61
 
62 62
 #ifndef	CL_DEBUG
63 63
 /*#define	NDEBUG	/* map CLAMAV debug onto standard */
... ...
@@ -109,7 +112,7 @@ static	char	const	rcsid[] = "$Id: mbox.c,v 1.22 2003/12/13 16:42:23 nigelhorne E
109 109
 
110 110
 typedef enum    { FALSE = 0, TRUE = 1 } bool;
111 111
 
112
-static	void	parseEmailHeaders(message *m, table_t *rfc821Table);
112
+static	message	*parseEmailHeaders(const message *m, const table_t *rfc821Table);
113 113
 static	int	parseEmailBody(message *mainMessage, blob **blobsIn, int nBlobs, text *textIn, const char *dir, table_t *rfc821Table, table_t *subtypeTable);
114 114
 static	int	boundaryStart(const char *line, const char *boundary);
115 115
 static	int	endOfMessage(const char *line, const char *boundary);
... ...
@@ -342,12 +345,16 @@ cl_mbox(const char *dir, int desc)
342 342
 		/*
343 343
 		 * It's a single message, parse the headers then the body
344 344
 		 */
345
+		message *body;
346
+
345 347
 		do {
346 348
 			cli_chomp(buffer);
347 349
 			messageAddLine(m, buffer);
348 350
 		} while(fgets(buffer, sizeof(buffer), fd) != NULL);
349 351
 
350
-		parseEmailHeaders(m, rfc821Table);
352
+		body = parseEmailHeaders(m, rfc821Table);
353
+		messageDestroy(m);
354
+		m = body;
351 355
 	}
352 356
 
353 357
 	fclose(fd);
... ...
@@ -379,12 +386,16 @@ cl_mbox(const char *dir, int desc)
379 379
  * The given message contains a raw e-mail.
380 380
  *
381 381
  * This function parses the headers of m and sets the message's arguments
382
+ *
383
+ * Returns the message's body with the correct arguments set
382 384
  */
383
-static void
384
-parseEmailHeaders(message *m, table_t *rfc821Table)
385
+static message *
386
+parseEmailHeaders(const message *m, const table_t *rfc821Table)
385 387
 {
386 388
 	bool inContinuationHeader = FALSE;
389
+	bool inHeader = TRUE;
387 390
 	text *t, *msgText = messageToText(m);
391
+	message *ret = messageCreate();
388 392
 
389 393
 	t = msgText;
390 394
 	assert(t != NULL);
... ...
@@ -401,7 +412,7 @@ parseEmailHeaders(message *m, table_t *rfc821Table)
401 401
 		 * Section B.2 of RFC822 says TAB or SPACE means
402 402
 		 * a continuation of the previous entry.
403 403
 		 */
404
-		if((buffer[0] == '\t') || (buffer[0] == ' '))
404
+		if(inHeader && ((buffer[0] == '\t') || (buffer[0] == ' ')))
405 405
 			inContinuationHeader = TRUE;
406 406
 
407 407
 		if(inContinuationHeader) {
... ...
@@ -414,8 +425,8 @@ parseEmailHeaders(message *m, table_t *rfc821Table)
414 414
 			 * Add all the arguments on the line
415 415
 			 */
416 416
 			for(ptr = strtok_r(buffer, ";", &strptr); ptr; ptr = strtok_r(NULL, ":", &strptr))
417
-				messageAddArgument(m, ptr);
418
-		} else {
417
+				messageAddArgument(ret, ptr);
418
+		} else if(inHeader) {
419 419
 			cli_dbgmsg("Deal with header %s\n", buffer);
420 420
 
421 421
 			/*
... ...
@@ -423,26 +434,28 @@ parseEmailHeaders(message *m, table_t *rfc821Table)
423 423
 			 * the start of the text
424 424
 			 */
425 425
 			if(strstrip(buffer) == 0) {
426
-				free(buffer);
427 426
 				cli_dbgmsg("End of header information\n");
428
-				break;
427
+				inHeader = FALSE;
429 428
 			} else {
430 429
 				const bool isLastLine = !continuationMarker(buffer);
431 430
 				const char *cmd = strtok_r(buffer, " \t", &strptr);
432 431
 
433
-				if (cmd && *cmd) {
432
+				if(cmd && *cmd) {
434 433
 					const char *arg = strtok_r(NULL, "", &strptr);
435 434
 
436 435
 					if(arg)
437
-						if(parseMimeHeader(m, cmd, rfc821Table, arg) == CONTENT_TYPE)
436
+						if(parseMimeHeader(ret, cmd, rfc821Table, arg) == CONTENT_TYPE)
438 437
 							inContinuationHeader = !isLastLine;
439 438
 				}
440 439
 			}
441
-		}
440
+		} else
441
+			messageAddLine(ret, buffer);
442 442
 		free(buffer);
443 443
 	} while((t = t->t_next) != NULL);
444 444
 
445 445
 	textDestroy(msgText);
446
+
447
+	return ret;
446 448
 }
447 449
 
448 450
 /*
... ...
@@ -450,7 +463,8 @@ parseEmailHeaders(message *m, table_t *rfc821Table)
450 450
  *
451 451
  * This function parses the body of mainMessage and saves its attachments in dir
452 452
  *
453
- * mainMessage is the buffer to be parsed, it contains an e-mail's body. First
453
+ * mainMessage is the buffer to be parsed, it contains an e-mail's body, without
454
+ * any headers. First
454 455
  * time of calling it'll be
455 456
  *	the whole message. Later it'll be parts of a multipart message
456 457
  * textIn is the plain text message being built up so far
... ...
@@ -565,6 +579,10 @@ parseEmailBody(message *mainMessage, blob **blobsIn, int nBlobs, text *textIn, c
565 565
 			inhead = 1;
566 566
 			inMimeHead = 0;
567 567
 
568
+			/*
569
+			 * This looks like parseEmailHeaders() - maybe there's
570
+			 * some duplication of code to be cleaned up
571
+			 */
568 572
 			for(multiparts = 0; t_line && (multiparts < MAXALTERNATIVE); multiparts++) {
569 573
 				aMessage = messages[multiparts] = messageCreate();
570 574
 
... ...
@@ -574,10 +592,12 @@ parseEmailBody(message *mainMessage, blob **blobsIn, int nBlobs, text *textIn, c
574 574
 				while((t_line = t_line->t_next)) {
575 575
 					const char *line = t_line->t_text;
576 576
 
577
-					/*cli_dbgmsg("inMimeHead %d inhead %d boundary %s line %s\n",
578
-						inMimeHead, inhead, boundary, line);*/
577
+					/*cli_dbgmsg("inMimeHead %d inhead %d boundary %s line '%s' next '%s'\n",
578
+						inMimeHead, inhead, boundary, line, t_line->t_next ? t_line->t_next->t_text : "(null)");*/
579 579
 
580 580
 					if(inMimeHead) {
581
+						cli_dbgmsg("About to add mime Argument '%s'\n",
582
+							line);
581 583
 						while(isspace((int)*line))
582 584
 							line++;
583 585
 
... ...
@@ -585,8 +605,6 @@ parseEmailBody(message *mainMessage, blob **blobsIn, int nBlobs, text *textIn, c
585 585
 							inhead = inMimeHead = 0;
586 586
 							continue;
587 587
 						}
588
-						cli_dbgmsg("About to add mime Argument '%s'\n",
589
-							line);
590 588
 						/*
591 589
 						 * This may cause a trailing ';'
592 590
 						 * to be added if this test
... ...
@@ -705,6 +723,7 @@ parseEmailBody(message *mainMessage, blob **blobsIn, int nBlobs, text *textIn, c
705 705
 
706 706
 			switch(tableFind(subtypeTable, mimeSubtype)) {
707 707
 			case RELATED:
708
+				cli_dbgmsg("Multipart related handler\n");
708 709
 				/*
709 710
 				 * Have a look to see if there's HTML code
710 711
 				 * which will need scanning
... ...
@@ -811,9 +830,7 @@ parseEmailBody(message *mainMessage, blob **blobsIn, int nBlobs, text *textIn, c
811 811
 				if(aText)
812 812
 					mainMessage = NULL;
813 813
 
814
-#ifdef	CL_DEBUG
815 814
 				cli_dbgmsg("Mixed message with %d parts\n", multiparts);
816
-#endif
817 815
 				for(i = 0; i < multiparts; i++) {
818 816
 					bool addAttachment = FALSE;
819 817
 					bool addToText = FALSE;
... ...
@@ -827,10 +844,8 @@ parseEmailBody(message *mainMessage, blob **blobsIn, int nBlobs, text *textIn, c
827 827
 					dtype = messageGetDispositionType(aMessage);
828 828
 					cptr = messageGetMimeSubtype(aMessage);
829 829
 
830
-#ifdef	CL_DEBUG
831 830
 					cli_dbgmsg("Mixed message part %d is of type %d\n",
832 831
 						i, messageGetMimeType(aMessage));
833
-#endif
834 832
 
835 833
 					switch(messageGetMimeType(aMessage)) {
836 834
 					case APPLICATION:
... ...
@@ -1020,7 +1035,7 @@ parseEmailBody(message *mainMessage, blob **blobsIn, int nBlobs, text *textIn, c
1020 1020
 				 * ensure t is correctly freed
1021 1021
 				 */
1022 1022
 				text *t, *msgText = messageToText(mainMessage);
1023
-				message *m;
1023
+				message *m, *body;
1024 1024
 
1025 1025
 				t = msgText;
1026 1026
 				assert(t != NULL);
... ...
@@ -1040,7 +1055,10 @@ parseEmailBody(message *mainMessage, blob **blobsIn, int nBlobs, text *textIn, c
1040 1040
 
1041 1041
 				textDestroy(msgText);
1042 1042
 
1043
-				parseEmailHeaders(m, rfc821Table);
1043
+				body = parseEmailHeaders(m, rfc821Table);
1044
+
1045
+				messageDestroy(m);
1046
+				m = body;
1044 1047
 
1045 1048
 				messageClean(m);
1046 1049
 				if(messageGetBody(m))
... ...
@@ -1106,6 +1124,7 @@ parseEmailBody(message *mainMessage, blob **blobsIn, int nBlobs, text *textIn, c
1106 1106
 	}
1107 1107
 
1108 1108
 	cli_dbgmsg("%d attachments found\n", nBlobs);
1109
+	rc = 1;
1109 1110
 
1110 1111
 	if(nBlobs == 0) {
1111 1112
 		blob *b;
... ...
@@ -1114,19 +1133,14 @@ parseEmailBody(message *mainMessage, blob **blobsIn, int nBlobs, text *textIn, c
1114 1114
 		 * No attachments - scan the text portions, often files
1115 1115
 		 * are hidden in HTML code
1116 1116
 		 */
1117
-
1118
-#ifdef	CL_DEBUG
1119 1117
 		cli_dbgmsg("%d multiparts found\n", multiparts);
1120
-#endif
1121 1118
 		for(i = 0; i < multiparts; i++) {
1122 1119
 			b = messageToBlob(messages[i]);
1123 1120
 
1124 1121
 			assert(b != NULL);
1125 1122
 
1126
-#ifdef	CL_DEBUG
1127 1123
 			cli_dbgmsg("Saving multipart %d, encoded with scheme %d\n",
1128 1124
 				i, messageGetEncoding(messages[i]));
1129
-#endif
1130 1125
 
1131 1126
 			(void)saveFile(b, dir);
1132 1127
 
... ...
@@ -1171,7 +1185,8 @@ parseEmailBody(message *mainMessage, blob **blobsIn, int nBlobs, text *textIn, c
1171 1171
 					blobDestroy(b);
1172 1172
 				}
1173 1173
 			}
1174
-		}
1174
+		} else
1175
+			rc = (multiparts) ? 1 : 2;	/* anything saved? */
1175 1176
 	} else {
1176 1177
 		short attachmentNumber;
1177 1178
 
... ...
@@ -1194,9 +1209,9 @@ parseEmailBody(message *mainMessage, blob **blobsIn, int nBlobs, text *textIn, c
1194 1194
 	if(blobs && (blobsIn == NULL))
1195 1195
 		blobArrayDestroy(blobs, nBlobs);
1196 1196
 
1197
-	cli_dbgmsg("parseEmailBody() returning 1\n");
1197
+	cli_dbgmsg("parseEmailBody() returning %d\n", rc);
1198 1198
 
1199
-	return 1;
1199
+	return rc;
1200 1200
 }
1201 1201
 
1202 1202
 /*
... ...
@@ -1461,6 +1476,9 @@ parseMimeHeader(message *m, const char *cmd, const table_t *rfc821Table, const c
1461 1461
 	return type;
1462 1462
 }
1463 1463
 
1464
+/*
1465
+ * Save some data as a unique file in the given directory.
1466
+ */
1464 1467
 static bool
1465 1468
 saveFile(const blob *b, const char *dir)
1466 1469
 {