Browse code

Some uuencoded viruses were getting through

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

Nigel Horne authored on 2005/01/01 21:54:54
Showing 2 changed files
... ...
@@ -1,3 +1,7 @@
1
+Sat Jan  1 12:54:04 GMT 2005 (njh)
2
+----------------------------------
3
+  * libclamav/message.c:	Some uuencoded viruses were getting through
4
+
1 5
 Thu Dec 30 14:06:03 GMT 2004 (njh)
2 6
 ----------------------------------
3 7
   * contrib/init/NetBSD2.0:	Added startup and shutdown scripts for NetBSD2.0
... ...
@@ -17,6 +17,9 @@
17 17
  *
18 18
  * Change History:
19 19
  * $Log: message.c,v $
20
+ * Revision 1.135  2005/01/01 12:52:58  nigelhorne
21
+ * Some uuencoded viruses were getting through
22
+ *
20 23
  * Revision 1.134  2004/12/19 23:19:54  nigelhorne
21 24
  * Tidy
22 25
  *
... ...
@@ -399,7 +402,7 @@
399 399
  * uuencodebegin() no longer static
400 400
  *
401 401
  */
402
-static	char	const	rcsid[] = "$Id: message.c,v 1.134 2004/12/19 23:19:54 nigelhorne Exp $";
402
+static	char	const	rcsid[] = "$Id: message.c,v 1.135 2005/01/01 12:52:58 nigelhorne Exp $";
403 403
 
404 404
 #if HAVE_CONFIG_H
405 405
 #include "clamav-config.h"
... ...
@@ -484,6 +487,7 @@ static	const	struct	encoding_map {
484 484
 	{	"x-binhex",		BINHEX		},
485 485
 	{	"us-ascii",		NOENCODING	},	/* incorrect */
486 486
 	{	"x-uue",		UUENCODE	},	/* incorrect */
487
+	{	"uuencode",		UUENCODE	},	/* incorrect */
487 488
 	{	NULL,			NOENCODING	}
488 489
 };
489 490
 
... ...
@@ -1042,6 +1046,8 @@ messageSetEncoding(message *m, const char *enctype)
1042 1042
 	while((*enctype == '\t') || (*enctype == ' '))
1043 1043
 		enctype++;
1044 1044
 
1045
+	cli_dbgmsg("messageSetEncoding: '%s'\n", enctype);
1046
+
1045 1047
 	if(strcasecmp(enctype, "8 bit") == 0) {
1046 1048
 		cli_dbgmsg("Broken content-transfer-encoding: '8 bit' changed to '8bit'\n");
1047 1049
 		enctype = "8bit";
... ...
@@ -1378,8 +1384,8 @@ messageExport(message *m, const char *dir, void *(*create)(void), void (*destroy
1378 1378
 
1379 1379
 	if((t_line = binhexBegin(m)) != NULL) {
1380 1380
 		unsigned char byte;
1381
-		unsigned long len, l, newlen = 0L;
1382
-		unsigned char *uptr, *data;
1381
+		unsigned long newlen = 0L, len, l;
1382
+		unsigned char *data;
1383 1383
 		char *ptr;
1384 1384
 		int bytenumber;
1385 1385
 		blob *tmp;
... ...
@@ -1400,13 +1406,6 @@ messageExport(message *m, const char *dir, void *(*create)(void), void (*destroy
1400 1400
 		/* 70-7f */	0x3d,0x3e,0x3f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
1401 1401
 		};
1402 1402
 
1403
-		tmp = blobCreate();
1404
-
1405
-		if(tmp == NULL) {
1406
-			(*destroy)(ret);
1407
-			return NULL;
1408
-		}
1409
-
1410 1403
 		/*
1411 1404
 		 * Decode BinHex4. First create a temporary blob which contains
1412 1405
 		 * the encoded message. Then decode that blob to the target
... ...
@@ -1414,106 +1413,107 @@ messageExport(message *m, const char *dir, void *(*create)(void), void (*destroy
1414 1414
 		 *
1415 1415
 		 * See RFC1741
1416 1416
 		 */
1417
-		while((t_line = t_line->t_next) != NULL)
1418
-			if(t_line->t_line) {
1419
-				const char *d = lineGetData(t_line->t_line);
1420
-				blobAddData(tmp, (unsigned char *)d, strlen(d));
1421
-			}
1417
+		while(((t_line = t_line->t_next) != NULL) &&
1418
+		      (t_line->t_line == NULL))
1419
+			;
1422 1420
 
1423
-		data = blobGetData(tmp);
1424
-
1425
-		if(data == NULL) {
1426
-			cli_warnmsg("Couldn't locate the binhex message that was claimed to be there\n");
1427
-			blobDestroy(tmp);
1428
-			(*destroy)(ret);
1429
-			return NULL;
1430
-		}
1431
-		if(data[0] != ':') {
1432
-			/*
1433
-			 * TODO: Need an example of this before I can be
1434
-			 * sure it works
1435
-			 * Possibly data[0] = '#'
1436
-			 */
1437
-			cli_warnmsg("8 bit binhex code is not yet supported\n");
1438
-			blobDestroy(tmp);
1421
+		tmp = textToBlob(t_line, NULL);
1422
+		if(tmp == NULL) {
1439 1423
 			(*destroy)(ret);
1440 1424
 			return NULL;
1441 1425
 		}
1442 1426
 
1443
-		len = blobGetDataSize(tmp);
1444
-
1445
-		/*
1446
-		 * FIXME: this is dirty code, modification of the contents
1447
-		 * of a member of the blob object should be done through blob.c
1448
-		 *
1449
-		 * Convert 7 bit data into 8 bit
1450
-		 */
1451
-		cli_dbgmsg("decode HQX7 message (%lu bytes)\n", len);
1427
+		data = blobGetData(tmp);
1452 1428
 
1453
-		uptr = cli_malloc(len);
1454
-		if(uptr == NULL) {
1429
+		if(data == NULL) {
1430
+			cli_warnmsg("Couldn't locate the binhex message that was claimed to be there\n");
1455 1431
 			blobDestroy(tmp);
1456 1432
 			(*destroy)(ret);
1457 1433
 			return NULL;
1458 1434
 		}
1459
-		memcpy(uptr, data, len);
1460
-		bytenumber = 0;
1461
-
1462
-		/*
1463
-		 * uptr now contains the encoded (7bit) data - len bytes long
1464
-		 * data will contain the unencoded (8bit) data
1465
-		 */
1466
-		for(l = 1; l < len; l++) {
1467
-			unsigned char c = uptr[l];
1435
+		len = blobGetDataSize(tmp);
1468 1436
 
1469
-			if(c == ':')
1470
-				break;
1437
+		if(data[0] == ':') {
1438
+			unsigned char *uptr;
1439
+			/* 7 bit (ala RFC1741) */
1471 1440
 
1472
-			if((c == '\n') || (c == '\r'))
1473
-				continue;
1441
+			/*
1442
+			 * FIXME: this is dirty code, modification of the
1443
+			 * contents of a member of the blob object should be
1444
+			 * done through blob.c
1445
+			 *
1446
+			 * Convert 7 bit data into 8 bit
1447
+			 */
1448
+			cli_dbgmsg("decode HQX7 message (%lu bytes)\n", len);
1474 1449
 
1475
-			if((c < 0x20) || (c > 0x7f) || (hqxtbl[c] == 0xff)) {
1476
-				cli_warnmsg("Invalid HQX7 character '%c' (0x%02x)\n", c, c);
1477
-				break;
1450
+			uptr = cli_malloc(len);
1451
+			if(uptr == NULL) {
1452
+				blobDestroy(tmp);
1453
+				(*destroy)(ret);
1454
+				return NULL;
1478 1455
 			}
1479
-			c = hqxtbl[c];
1480
-			assert(c <= 63);
1456
+			memcpy(uptr, data, len);
1457
+			bytenumber = 0;
1481 1458
 
1482 1459
 			/*
1483
-			 * These masks probably aren't needed, but
1484
-			 * they're here to verify the code is correct
1460
+			 * uptr now contains the encoded (7bit) data - len bytes long
1461
+			 * data will contain the unencoded (8bit) data
1485 1462
 			 */
1486
-			switch(bytenumber) {
1487
-				case 0:
1488
-					data[newlen] = (c << 2) & 0xFC;
1489
-					bytenumber = 1;
1490
-					break;
1491
-				case 1:
1492
-					data[newlen++] |= (c >> 4) & 0x3;
1493
-					data[newlen] = (c << 4) & 0xF0;
1494
-					bytenumber = 2;
1495
-					break;
1496
-				case 2:
1497
-					data[newlen++] |= (c >> 2) & 0xF;
1498
-					data[newlen] = (c << 6) & 0xC0;
1499
-					bytenumber = 3;
1463
+			for(l = 1; l < len; l++) {
1464
+				unsigned char c = uptr[l];
1465
+
1466
+				if(c == ':')
1500 1467
 					break;
1501
-				case 3:
1502
-					data[newlen++] |= c & 0x3F;
1503
-					bytenumber = 0;
1468
+
1469
+				if((c == '\n') || (c == '\r'))
1470
+					continue;
1471
+
1472
+				if((c < 0x20) || (c > 0x7f) || (hqxtbl[c] == 0xff)) {
1473
+					cli_warnmsg("Invalid HQX7 character '%c' (0x%02x)\n", c, c);
1504 1474
 					break;
1475
+				}
1476
+				c = hqxtbl[c];
1477
+				assert(c <= 63);
1478
+
1479
+				/*
1480
+				 * These masks probably aren't needed, but
1481
+				 * they're here to verify the code is correct
1482
+				 */
1483
+				switch(bytenumber) {
1484
+					case 0:
1485
+						data[newlen] = (c << 2) & 0xFC;
1486
+						bytenumber = 1;
1487
+						break;
1488
+					case 1:
1489
+						data[newlen++] |= (c >> 4) & 0x3;
1490
+						data[newlen] = (c << 4) & 0xF0;
1491
+						bytenumber = 2;
1492
+						break;
1493
+					case 2:
1494
+						data[newlen++] |= (c >> 2) & 0xF;
1495
+						data[newlen] = (c << 6) & 0xC0;
1496
+						bytenumber = 3;
1497
+						break;
1498
+					case 3:
1499
+						data[newlen++] |= c & 0x3F;
1500
+						bytenumber = 0;
1501
+						break;
1502
+				}
1505 1503
 			}
1506
-		}
1507 1504
 
1508
-		cli_dbgmsg("decoded HQX7 message (now %lu bytes)\n", newlen);
1505
+			cli_dbgmsg("decoded HQX7 message (now %lu bytes)\n", newlen);
1509 1506
 
1510
-		/*
1511
-		 * Throw away the old encoded (7bit) data
1512
-		 * data now points to the encoded (8bit) data - newlen bytes
1513
-		 *
1514
-		 * The data array may contain repetitive characters
1515
-		 */
1516
-		free(uptr);
1507
+			/*
1508
+			 * Throw away the old encoded (7bit) data
1509
+			 * data now points to the encoded (8bit) data - newlen bytes
1510
+			 *
1511
+			 * The data array may contain repetitive characters
1512
+			 */
1513
+			free(uptr);
1514
+		} else {
1515
+			cli_warnmsg("HQX8 messages not yet supported - send to bugs@clamav.net\n", len);
1516
+			newlen = len;
1517
+		}
1517 1518
 
1518 1519
 		/*
1519 1520
 		 * Uncompress repetitive characters
... ...
@@ -1700,7 +1700,7 @@ messageExport(message *m, const char *dir, void *(*create)(void), void (*destroy
1700 1700
 		/*
1701 1701
 		 * Find the filename to decode
1702 1702
 		 */
1703
-		if((enctype == UUENCODE) || ((enctype == NOENCODING) && (i == 0) && uuencodeBegin(m))) {
1703
+		if((enctype == UUENCODE) || uuencodeBegin(m)) {
1704 1704
 			t_line = uuencodeBegin(m);
1705 1705
 
1706 1706
 			if(t_line == NULL) {