1174
1174
cli_dbgmsg("messageExport: numberOfEncTypes == %d\n", m->numberOfEncTypes);
1176
if((t_line = binhexBegin(m)) != NULL) {
1178
unsigned long newlen = 0L, len, dataforklen, resourceforklen, l;
1179
unsigned char *data;
1185
* HQX conversion table - illegal chars are 0xff
1187
const unsigned char hqxtbl[] = {
1188
/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f */
1189
/* 00-0f */ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1190
/* 10-1f */ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
1191
/* 20-2f */ 0xff,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0xff,0xff,
1192
/* 30-3f */ 0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0xff,0x14,0x15,0xff,0xff,0xff,0xff,0xff,0xff,
1193
/* 40-4f */ 0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0xff,
1194
/* 50-5f */ 0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0xff,0x2c,0x2d,0x2e,0x2f,0xff,0xff,0xff,0xff,
1195
/* 60-6f */ 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0xff,0x37,0x38,0x39,0x3a,0x3b,0x3c,0xff,0xff,
1196
/* 70-7f */ 0x3d,0x3e,0x3f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
1199
cli_dbgmsg("messageExport: decode binhex\n");
1201
* Decode BinHex4. First create a temporary blob which contains
1202
* the encoded message. Then decode that blob to the target
1203
* blob, free the temporary blob and return the target one
1205
* FIXME: EICAR isn't detected: should create 3 files in fork
1206
* format: .info, .data and .rsrc. This is needed for
1207
* position dependant detection such as EICAR
1211
while(((t_line = t_line->t_next) != NULL) &&
1212
(t_line->t_line == NULL))
1215
tmp = textToBlob(t_line, NULL,
1216
((m->numberOfEncTypes == 1) && (m->encodingTypes[0] == BINHEX)) ? destroy_text : 0);
1220
* FIXME: We've probably run out of memory during the
1223
cli_warnmsg("Couldn't start binhex parser\n");
1228
data = blobGetData(tmp);
1231
cli_warnmsg("Couldn't locate the binhex message that was claimed to be there\n");
1236
len = blobGetDataSize(tmp);
1238
if(data[0] == ':') {
1239
unsigned char *uptr;
1240
/* 7 bit (ala RFC1741) */
1243
* FIXME: this is dirty code, modification of the
1244
* contents of a member of the blob object should be
1245
* done through blob.c
1247
* Convert 7 bit data into 8 bit
1249
cli_dbgmsg("decode HQX7 message (%lu bytes)\n", len);
1251
uptr = cli_malloc(len);
1257
memcpy(uptr, data, len);
1261
* uptr now contains the encoded (7bit) data - len bytes long
1262
* data will contain the unencoded (8bit) data
1264
for(l = 1; l < len; l++) {
1265
unsigned char c = uptr[l];
1270
if((c == '\n') || (c == '\r'))
1273
if((c < 0x20) || (c > 0x7f) || (hqxtbl[c] == 0xff)) {
1274
cli_dbgmsg("Invalid HQX7 character '%c' (0x%02x)\n", c, c);
1281
* These masks probably aren't needed, but
1282
* they're here to verify the code is correct
1284
switch(bytenumber) {
1286
data[newlen] = (c << 2) & 0xFC;
1290
data[newlen++] |= (c >> 4) & 0x3;
1291
data[newlen] = (c << 4) & 0xF0;
1295
data[newlen++] |= (c >> 2) & 0xF;
1296
data[newlen] = (c << 6) & 0xC0;
1300
data[newlen++] |= c & 0x3F;
1306
cli_dbgmsg("decoded HQX7 message (now %lu bytes)\n", newlen);
1309
* Throw away the old encoded (7bit) data
1310
* data now points to the encoded (8bit) data - newlen bytes
1312
* The data array may contain repetitive characters
1316
cli_warnmsg("HQX8 messages not yet supported, extraction may fail - if you believe this file contains a virus, submit it to www.clamav.net\n");
1321
* Uncompress repetitive characters
1323
if(memchr(data, 0x90, newlen)) {
1324
blob *u = blobCreate(); /* uncompressed data */
1332
* Includes compression
1334
for(l = 0L; l < newlen; l++) {
1335
unsigned char c = data[l];
1338
* TODO: handle the case where the first byte
1341
blobAddData(u, &c, 1);
1343
if((l < (newlen - 1L)) && (data[l + 1] == 0x90)) {
1351
blobAddData(u, &c, 1);
1354
cli_dbgmsg("uncompress HQX7 at 0x%06lu: %d repetitive bytes\n", l, count);
1358
blobAddData(u, &c, 1);
1364
data = blobGetData(tmp);
1365
len = blobGetDataSize(tmp);
1366
cli_dbgmsg("Uncompressed %lu bytes to %lu\n", newlen, len);
1369
cli_dbgmsg("HQX7 message (%lu bytes) is not compressed\n",
1373
cli_dbgmsg("Discarding empty binHex attachment\n");
1380
* The blob tmp now contains the uncompressed data
1381
* of len bytes, i.e. the repetitive bytes have been removed
1387
* TODO: set filename argument in message as well
1395
filename = cli_malloc(byte + 1);
1396
if(filename == NULL) {
1401
memcpy(filename, &data[1], byte);
1402
filename[byte] = '\0';
1403
(*setFilename)(ret, dir, filename);
1404
/*ptr = cli_malloc(strlen(filename) + 6);*/
1405
ptr = cli_malloc(byte + 6);
1407
sprintf(ptr, "name=%s", filename);
1408
messageAddArgument(m, ptr);
1413
* skip over length, filename, version, type, creator and flags
1415
byte = 1 + byte + 1 + 4 + 4 + 2;
1418
* Set len to be the data fork length
1420
dataforklen = ((data[byte] << 24) & 0xFF000000) |
1421
((data[byte + 1] << 16) & 0xFF0000) |
1422
((data[byte + 2] << 8) & 0xFF00) |
1423
(data[byte + 3] & 0xFF);
1425
resourceforklen = ((data[byte + 4] << 24) & 0xFF000000) |
1426
((data[byte + 5] << 16) & 0xFF0000) |
1427
((data[byte + 6] << 8) & 0xFF00) |
1428
(data[byte + 7] & 0xFF);
1430
cli_dbgmsg("Filename = '%s', data fork length = %lu, resource fork length = %lu bytes\n",
1431
filename, dataforklen, resourceforklen);
1433
free((char *)filename);
1436
* Skip over data fork length, resource fork length and CRC
1440
l = blobGetDataSize(tmp) - byte;
1442
if(l < dataforklen) {
1443
cli_dbgmsg("Corrupt BinHex file, claims it is %lu bytes long in a message of %lu bytes\n",
1447
if(setCTX && m->ctx)
1448
(*setCTX)(ret, m->ctx);
1450
(*addData)(ret, &data[byte], dataforklen);
1457
if((m->numberOfEncTypes == 0) ||
1458
((m->numberOfEncTypes == 1) && (m->encodingTypes[0] == BINHEX))) {
1459
cli_dbgmsg("Finished exporting binhex file\n");
1464
1176
if(m->numberOfEncTypes == 0) {