~louis/ubuntu/trusty/clamav/lp799623_fix_logrotate

« back to all changes in this revision

Viewing changes to libclamav/message.c

  • Committer: Bazaar Package Importer
  • Author(s): Scott Kitterman
  • Date: 2010-03-12 11:30:04 UTC
  • mfrom: (0.41.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20100312113004-b0fop4bkycszdd0z
Tags: 0.96~rc1+dfsg-0ubuntu1
* New upstream RC - FFE (LP: #537636):
  - Add OfficialDatabaseOnly option to clamav-base.postinst.in
  - Add LocalSocketGroup option to clamav-base.postinst.in
  - Add LocalSocketMode option to clamav-base.postinst.in
  - Add CrossFilesystems option to clamav-base.postinst.in
  - Add ClamukoScannerCount option to clamav-base.postinst.in
  - Add BytecodeSecurity opiton to clamav-base.postinst.in
  - Add DetectionStatsHostID option to clamav-freshclam.postinst.in
  - Add Bytecode option to clamav-freshclam.postinst.in
  - Add MilterSocketGroup option to clamav-milter.postinst.in
  - Add MilterSocketMode option to clamav-milter.postinst.in
  - Add ReportHostname option to clamav-milter.postinst.in
  - Bump libclamav SO version to 6.1.0 in libclamav6.install
  - Drop clamdmon from clamav.examples (no longer shipped by upstream)
  - Drop libclamav.a from libclamav-dev.install (not built by upstream)
  - Update SO version for lintian override for libclamav6
  - Add new Bytecode Testing Tool, usr/bin/clambc, to clamav.install
  - Add build-depends on python and python-setuptools for new test suite
  - Update debian/copyright for the embedded copy of llvm (using the system
    llvm is not currently feasible)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1173
1173
 
1174
1174
        cli_dbgmsg("messageExport: numberOfEncTypes == %d\n", m->numberOfEncTypes);
1175
1175
 
1176
 
        if((t_line = binhexBegin(m)) != NULL) {
1177
 
                unsigned char byte;
1178
 
                unsigned long newlen = 0L, len, dataforklen, resourceforklen, l;
1179
 
                unsigned char *data;
1180
 
                char *ptr;
1181
 
                int bytenumber;
1182
 
                blob *tmp;
1183
 
 
1184
 
                /*
1185
 
                 * HQX conversion table - illegal chars are 0xff
1186
 
                 */
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
1197
 
                };
1198
 
 
1199
 
                cli_dbgmsg("messageExport: decode binhex\n");
1200
 
                /*
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
1204
 
                 *
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
1208
 
                 *
1209
 
                 * See RFC1741
1210
 
                 */
1211
 
                while(((t_line = t_line->t_next) != NULL) &&
1212
 
                      (t_line->t_line == NULL))
1213
 
                        ;
1214
 
 
1215
 
                tmp = textToBlob(t_line, NULL,
1216
 
                        ((m->numberOfEncTypes == 1) && (m->encodingTypes[0] == BINHEX)) ? destroy_text : 0);
1217
 
 
1218
 
                if(tmp == NULL) {
1219
 
                        /*
1220
 
                         * FIXME: We've probably run out of memory during the
1221
 
                         * text to blob.
1222
 
                         */
1223
 
                        cli_warnmsg("Couldn't start binhex parser\n");
1224
 
                        (*destroy)(ret);
1225
 
                        return NULL;
1226
 
                }
1227
 
 
1228
 
                data = blobGetData(tmp);
1229
 
 
1230
 
                if(data == NULL) {
1231
 
                        cli_warnmsg("Couldn't locate the binhex message that was claimed to be there\n");
1232
 
                        blobDestroy(tmp);
1233
 
                        (*destroy)(ret);
1234
 
                        return NULL;
1235
 
                }
1236
 
                len = blobGetDataSize(tmp);
1237
 
 
1238
 
                if(data[0] == ':') {
1239
 
                        unsigned char *uptr;
1240
 
                        /* 7 bit (ala RFC1741) */
1241
 
 
1242
 
                        /*
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
1246
 
                         *
1247
 
                         * Convert 7 bit data into 8 bit
1248
 
                         */
1249
 
                        cli_dbgmsg("decode HQX7 message (%lu bytes)\n", len);
1250
 
 
1251
 
                        uptr = cli_malloc(len);
1252
 
                        if(uptr == NULL) {
1253
 
                                blobDestroy(tmp);
1254
 
                                (*destroy)(ret);
1255
 
                                return NULL;
1256
 
                        }
1257
 
                        memcpy(uptr, data, len);
1258
 
                        bytenumber = 0;
1259
 
 
1260
 
                        /*
1261
 
                         * uptr now contains the encoded (7bit) data - len bytes long
1262
 
                         * data will contain the unencoded (8bit) data
1263
 
                         */
1264
 
                        for(l = 1; l < len; l++) {
1265
 
                                unsigned char c = uptr[l];
1266
 
 
1267
 
                                if(c == ':')
1268
 
                                        break;
1269
 
 
1270
 
                                if((c == '\n') || (c == '\r'))
1271
 
                                        continue;
1272
 
 
1273
 
                                if((c < 0x20) || (c > 0x7f) || (hqxtbl[c] == 0xff)) {
1274
 
                                        cli_dbgmsg("Invalid HQX7 character '%c' (0x%02x)\n", c, c);
1275
 
                                        break;
1276
 
                                }
1277
 
                                c = hqxtbl[c];
1278
 
                                assert(c <= 63);
1279
 
 
1280
 
                                /*
1281
 
                                 * These masks probably aren't needed, but
1282
 
                                 * they're here to verify the code is correct
1283
 
                                 */
1284
 
                                switch(bytenumber) {
1285
 
                                        case 0:
1286
 
                                                data[newlen] = (c << 2) & 0xFC;
1287
 
                                                bytenumber = 1;
1288
 
                                                break;
1289
 
                                        case 1:
1290
 
                                                data[newlen++] |= (c >> 4) & 0x3;
1291
 
                                                data[newlen] = (c << 4) & 0xF0;
1292
 
                                                bytenumber = 2;
1293
 
                                                break;
1294
 
                                        case 2:
1295
 
                                                data[newlen++] |= (c >> 2) & 0xF;
1296
 
                                                data[newlen] = (c << 6) & 0xC0;
1297
 
                                                bytenumber = 3;
1298
 
                                                break;
1299
 
                                        case 3:
1300
 
                                                data[newlen++] |= c & 0x3F;
1301
 
                                                bytenumber = 0;
1302
 
                                                break;
1303
 
                                }
1304
 
                        }
1305
 
 
1306
 
                        cli_dbgmsg("decoded HQX7 message (now %lu bytes)\n", newlen);
1307
 
 
1308
 
                        /*
1309
 
                         * Throw away the old encoded (7bit) data
1310
 
                         * data now points to the encoded (8bit) data - newlen bytes
1311
 
                         *
1312
 
                         * The data array may contain repetitive characters
1313
 
                         */
1314
 
                        free(uptr);
1315
 
                } else {
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");
1317
 
                        newlen = len;
1318
 
                }
1319
 
 
1320
 
                /*
1321
 
                 * Uncompress repetitive characters
1322
 
                 */
1323
 
                if(memchr(data, 0x90, newlen)) {
1324
 
                        blob *u = blobCreate(); /* uncompressed data */
1325
 
 
1326
 
                        if(u == NULL) {
1327
 
                                (*destroy)(ret);
1328
 
                                blobDestroy(tmp);
1329
 
                                return NULL;
1330
 
                        }
1331
 
                        /*
1332
 
                         * Includes compression
1333
 
                         */
1334
 
                        for(l = 0L; l < newlen; l++) {
1335
 
                                unsigned char c = data[l];
1336
 
 
1337
 
                                /*
1338
 
                                 * TODO: handle the case where the first byte
1339
 
                                 * is 0x90
1340
 
                                 */
1341
 
                                blobAddData(u, &c, 1);
1342
 
 
1343
 
                                if((l < (newlen - 1L)) && (data[l + 1] == 0x90)) {
1344
 
                                        int count;
1345
 
 
1346
 
                                        l += 2;
1347
 
                                        count = data[l];
1348
 
 
1349
 
                                        if(count == 0) {
1350
 
                                                c = 0x90;
1351
 
                                                blobAddData(u, &c, 1);
1352
 
                                        } else {
1353
 
#ifdef  CL_DEBUG
1354
 
                                                cli_dbgmsg("uncompress HQX7 at 0x%06lu: %d repetitive bytes\n", l, count);
1355
 
#endif
1356
 
                                                blobGrow(u, count);
1357
 
                                                while(--count > 0)
1358
 
                                                        blobAddData(u, &c, 1);
1359
 
                                        }
1360
 
                                }
1361
 
                        }
1362
 
                        blobDestroy(tmp);
1363
 
                        tmp = u;
1364
 
                        data = blobGetData(tmp);
1365
 
                        len = blobGetDataSize(tmp);
1366
 
                        cli_dbgmsg("Uncompressed %lu bytes to %lu\n", newlen, len);
1367
 
                } else {
1368
 
                        len = newlen;
1369
 
                        cli_dbgmsg("HQX7 message (%lu bytes) is not compressed\n",
1370
 
                                len);
1371
 
                }
1372
 
                if(len == 0) {
1373
 
                        cli_dbgmsg("Discarding empty binHex attachment\n");
1374
 
                        (*destroy)(ret);
1375
 
                        blobDestroy(tmp);
1376
 
                        return NULL;
1377
 
                }
1378
 
 
1379
 
                /*
1380
 
                 * The blob tmp now contains the uncompressed data
1381
 
                 * of len bytes, i.e. the repetitive bytes have been removed
1382
 
                 */
1383
 
 
1384
 
                /*
1385
 
                 * Parse the header
1386
 
                 *
1387
 
                 * TODO: set filename argument in message as well
1388
 
                 */
1389
 
                byte = data[0];
1390
 
                if(byte >= len) {
1391
 
                        (*destroy)(ret);
1392
 
                        blobDestroy(tmp);
1393
 
                        return NULL;
1394
 
                }
1395
 
                filename = cli_malloc(byte + 1);
1396
 
                if(filename == NULL) {
1397
 
                        (*destroy)(ret);
1398
 
                        blobDestroy(tmp);
1399
 
                        return NULL;
1400
 
                }
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);
1406
 
                if(ptr) {
1407
 
                        sprintf(ptr, "name=%s", filename);
1408
 
                        messageAddArgument(m, ptr);
1409
 
                        free(ptr);
1410
 
                }
1411
 
 
1412
 
                /*
1413
 
                 * skip over length, filename, version, type, creator and flags
1414
 
                 */
1415
 
                byte = 1 + byte + 1 + 4 + 4 + 2;
1416
 
 
1417
 
                /*
1418
 
                 * Set len to be the data fork length
1419
 
                 */
1420
 
                dataforklen = ((data[byte] << 24) & 0xFF000000) |
1421
 
                        ((data[byte + 1] << 16) & 0xFF0000) |
1422
 
                        ((data[byte + 2] << 8) & 0xFF00) |
1423
 
                        (data[byte + 3] & 0xFF);
1424
 
 
1425
 
                resourceforklen = ((data[byte + 4] << 24) & 0xFF000000) |
1426
 
                        ((data[byte + 5] << 16) & 0xFF0000) |
1427
 
                        ((data[byte + 6] << 8) & 0xFF00) |
1428
 
                        (data[byte + 7] & 0xFF);
1429
 
 
1430
 
                cli_dbgmsg("Filename = '%s', data fork length = %lu, resource fork length = %lu bytes\n",
1431
 
                        filename, dataforklen, resourceforklen);
1432
 
 
1433
 
                free((char *)filename);
1434
 
 
1435
 
                /*
1436
 
                 * Skip over data fork length, resource fork length and CRC
1437
 
                 */
1438
 
                byte += 10;
1439
 
 
1440
 
                l = blobGetDataSize(tmp) - byte;
1441
 
 
1442
 
                if(l < dataforklen) {
1443
 
                        cli_dbgmsg("Corrupt BinHex file, claims it is %lu bytes long in a message of %lu bytes\n",
1444
 
                                dataforklen, l);
1445
 
                        dataforklen = l;
1446
 
                }
1447
 
                if(setCTX && m->ctx)
1448
 
                        (*setCTX)(ret, m->ctx);
1449
 
 
1450
 
                (*addData)(ret, &data[byte], dataforklen);
1451
 
 
1452
 
                blobDestroy(tmp);
1453
 
 
1454
 
                if(destroy_text)
1455
 
                        m->binhex = NULL;
1456
 
 
1457
 
                if((m->numberOfEncTypes == 0) ||
1458
 
                   ((m->numberOfEncTypes == 1) && (m->encodingTypes[0] == BINHEX))) {
1459
 
                        cli_dbgmsg("Finished exporting binhex file\n");
1460
 
                        return ret;
1461
 
                }
1462
 
        }
1463
 
 
1464
1176
        if(m->numberOfEncTypes == 0) {
1465
1177
                /*
1466
1178
                 * Fast copy
1711
1423
 
1712
1424
        cli_dbgmsg("messageSavePartial\n");
1713
1425
        time_val  = time(NULL);
1714
 
        snprintf(fullname, 1024, "%s/clamav-partial-%lu_%s-%u", dir, time_val, md5id, part);
 
1426
        snprintf(fullname, 1024, "%s"PATHSEP"clamav-partial-%lu_%s-%u", dir, time_val, md5id, part);
1715
1427
 
1716
1428
        fb = messageExport(m, fullname,
1717
1429
                (void *(*)(void))fileblobCreate,