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... | ... |
@@ -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 |
} |