Browse code

Now detects eicar from http://www.webmail.us/testvirus

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

Nigel Horne authored on 2005/03/26 04:49:52
Showing 2 changed files
... ...
@@ -1,3 +1,8 @@
1
+Fri Mar 25 19:48:42 GMT 2005 (njh)
2
+----------------------------------
3
+  * libclamav:	Added TNEF (winmail.dat) decoding. Now finds eicar in test 14
4
+			from http://www.webmail.us/testvirus
5
+
1 6
 Fri Mar 25 18:58:29 CET 2005 (tk)
2 7
 ---------------------------------
3 8
   * freshclam: improve new database installation under w32 (thanks to Boguslaw
... ...
@@ -20,7 +20,7 @@
20 20
 #include "clamav-config.h"
21 21
 #endif
22 22
 
23
-static	char	const	rcsid[] = "$Id: tnef.c,v 1.5 2005/03/25 18:30:18 nigelhorne Exp $";
23
+static	char	const	rcsid[] = "$Id: tnef.c,v 1.6 2005/03/25 19:47:35 nigelhorne Exp $";
24 24
 
25 25
 #include <stdio.h>
26 26
 
... ...
@@ -28,8 +28,10 @@ static	char	const	rcsid[] = "$Id: tnef.c,v 1.5 2005/03/25 18:30:18 nigelhorne Ex
28 28
 #include "clamav.h"
29 29
 #include "others.h"
30 30
 #include "tnef.h"
31
+#include "blob.h"
31 32
 
32
-static	int	tnef_attachment(int desc);
33
+static	int	tnef_message(int desc);
34
+static	int	tnef_attachment(int desc, const char *dir, fileblob **fbref);
33 35
 
34 36
 /*
35 37
  * The algorithm will be based on kdepim/ktnef/lib/ktnefparser.cpp from
... ...
@@ -43,18 +45,22 @@ static	int	tnef_attachment(int desc);
43 43
 #define	LVL_ATTACHMENT	0x02
44 44
 
45 45
 #define	attMSGCLASS	0x8008
46
+#define	attBODY		0x800c
47
+#define	attATTACHDATA	0x800f	/* Attachment Data */
48
+#define	attATTACHTITLE	0x8010	/* Attachment File Name */
46 49
 #define	attDATEMODIFIED	0x8020
47 50
 #define	attTNEFVERSION	0x9006
48 51
 #define	attOEMCODEPAGE	0x9007
49 52
 
53
+/* FIXME: use stdio */
50 54
 int
51 55
 cli_tnef(const char *dir, int desc)
52 56
 {
53 57
 	uint32_t i32;
54 58
 	uint16_t i16;
55 59
 	uint8_t i8;
56
-
57
-	cli_warnmsg("TNEF not scanned yet - virus samples are welcome\n");
60
+	fileblob *fb;
61
+	int ret, alldone;
58 62
 
59 63
 	lseek(desc, 0L, SEEK_SET);
60 64
 
... ...
@@ -71,20 +77,26 @@ cli_tnef(const char *dir, int desc)
71 71
 	if(cli_readn(desc, &i16, sizeof(uint16_t)) != sizeof(uint16_t))
72 72
 		return CL_EIO;
73 73
 
74
-	for(;;) {
75
-		int alldone = 0;
74
+	fb = NULL;
75
+	ret = CL_CLEAN;
76
+	alldone = 0;
76 77
 
78
+	do {
77 79
 		switch(cli_readn(desc, &i8, sizeof(uint8_t))) {
78 80
 			case -1:
79 81
 				perror("read");
80
-				return CL_EIO;
82
+				ret = CL_EIO;
83
+				alldone = 1;
84
+				break;
81 85
 			case 0:
82 86
 				alldone = 1;
83 87
 				break;
84 88
 			case sizeof(uint8_t):
85 89
 				break;
86 90
 			default:
87
-				return CL_EIO;
91
+				ret = CL_EIO;
92
+				alldone = 1;
93
+				break;
88 94
 		}
89 95
 		if(alldone)
90 96
 			break;
... ...
@@ -93,35 +105,44 @@ cli_tnef(const char *dir, int desc)
93 93
 				/*cli_dbgmsg("TNEF - found message\n");*/
94 94
 				if(tnef_message(desc) != 0) {
95 95
 					cli_errmsg("Error reading TNEF message\n");
96
-					return CL_EFORMAT;
96
+					ret = CL_EFORMAT;
97
+					alldone = 1;
97 98
 				}
98 99
 				break;
99 100
 			case LVL_ATTACHMENT:
100 101
 				/*cli_dbgmsg("TNEF - found attachment\n");*/
101
-				if(tnef_attachment(desc) != 0) {
102
+				if(tnef_attachment(desc, dir, &fb) != 0) {
102 103
 					cli_errmsg("Error reading TNEF message\n");
103
-					return CL_EFORMAT;
104
+					ret = CL_EFORMAT;
105
+					alldone = 1;
104 106
 				}
105 107
 				break;
108
+			case 0:
109
+				break;
106 110
 			default:
107 111
 				cli_errmsg("TNEF - unknown level %d\n", (int)i8);
108
-				return CL_EFORMAT;
112
+				ret = CL_EFORMAT;
113
+				alldone = 1;
114
+				break;
109 115
 		}
110
-	}
116
+	} while(!alldone);
111 117
 
118
+	if(fb) {
119
+		fileblobDestroy(fb);
120
+		fb = NULL;
121
+	}
112 122
 	return CL_CLEAN;
113 123
 }
114 124
 
115
-/*
116
- * TODO: Debug mode only apart from attBODY?
117
- */
118 125
 static int
119 126
 tnef_message(int desc)
120 127
 {
121 128
 	uint32_t i32, length;
122 129
 	uint16_t i16, tag, type;
123 130
 	off_t offset;
131
+#if	CL_DEBUG
124 132
 	char *string;
133
+#endif
125 134
 
126 135
 	if(cli_readn(desc, &i32, sizeof(uint32_t)) != sizeof(uint32_t))
127 136
 		return -1;
... ...
@@ -142,6 +163,10 @@ tnef_message(int desc)
142 142
 	 * a lot of this stuff should be only discovered in debug mode...
143 143
 	 */
144 144
 	switch(tag) {
145
+		case attBODY:
146
+			cli_warnmsg("TNEF body not being scanned - report to bugs@clamav.net\n");
147
+			break;
148
+#if	CL_DEBUG
145 149
 		case attTNEFVERSION:
146 150
 			/*assert(length == sizeof(uint32_t))*/
147 151
 			if(cli_readn(desc, &i32, sizeof(uint32_t)) != sizeof(uint32_t))
... ...
@@ -166,8 +191,9 @@ tnef_message(int desc)
166 166
 			free(string);
167 167
 			break;
168 168
 		default:
169
-			cli_errmsg("TNEF - unsupported tag 0x%x type 0x%d length %u\n", tag, type, length);
169
+			cli_dbgmsg("TNEF - unsupported message tag 0x%x type 0x%d length %u\n", tag, type, length);
170 170
 			break;
171
+#endif
171 172
 	}
172 173
 
173 174
 	/*cli_dbgmsg("%lu %lu\n", offset + length, lseek(desc, 0L, SEEK_CUR));*/
... ...
@@ -182,7 +208,74 @@ tnef_message(int desc)
182 182
 }
183 183
 
184 184
 static int
185
-tnef_attachment(int desc)
185
+tnef_attachment(int desc, const char *dir, fileblob **fbref)
186 186
 {
187
+	uint32_t i32, length, todo;
188
+	uint16_t i16, tag, type;
189
+	off_t offset;
190
+	char *string;
191
+
192
+	if(cli_readn(desc, &i32, sizeof(uint32_t)) != sizeof(uint32_t))
193
+		return -1;
194
+
195
+	tag = i32 & 0xFFFF;
196
+	type = (i32 & 0xFFFF0000) >> 16;
197
+
198
+	if(cli_readn(desc, &i32, sizeof(uint32_t)) != sizeof(uint32_t))
199
+		return -1;
200
+
201
+	length = i32;
202
+
203
+	/*cli_dbgmsg("message tag 0x%x, type 0x%x, length %u\n", tag, type, length);*/
204
+
205
+	offset = lseek(desc, 0L, SEEK_CUR);
206
+
207
+	switch(tag) {
208
+		case attATTACHTITLE:
209
+			if(*fbref != NULL)
210
+				fileblobDestroy(*fbref);
211
+			*fbref = fileblobCreate();
212
+
213
+			if(*fbref == NULL)
214
+				return -1;
215
+			string = cli_malloc(length + 1);
216
+
217
+			if((unsigned int)cli_readn(desc, string, length) != length)
218
+				return -1;
219
+			string[length] = '\0';
220
+			cli_dbgmsg("TNEF filename %s\n", string);
221
+			fileblobSetFilename(*fbref, dir, string);
222
+			free(string);
223
+			break;
224
+		case attATTACHDATA:
225
+			if(*fbref == NULL) {
226
+				*fbref = fileblobCreate();
227
+
228
+				if(*fbref == NULL)
229
+					return -1;
230
+			}
231
+			/* FIXME: use stdio */
232
+			todo = length;
233
+			while(todo) {
234
+				unsigned char *c;
235
+
236
+				if(cli_readn(desc, &c, 1) != 1)
237
+					break;
238
+				fileblobAddData(*fbref, (const unsigned char *)&c, 1);
239
+			}
240
+			break;
241
+		default:
242
+			cli_dbgmsg("TNEF - unsupported attachment tag 0x%x type 0x%d length %u\n", tag, type, length);
243
+			break;
244
+	}
245
+
246
+	/*cli_dbgmsg("%lu %lu\n", offset + length, lseek(desc, 0L, SEEK_CUR));*/
247
+
248
+	lseek(desc, offset + length, SEEK_SET);	/* shouldn't be needed */
249
+
250
+	/* Checksum - TODO, verify */
251
+	if(cli_readn(desc, &i16, sizeof(uint16_t)) != sizeof(uint16_t))
252
+		return -1;
253
+
187 254
 	return 0;
188 255
 }