~ubuntu-branches/ubuntu/raring/clamav/raring

« back to all changes in this revision

Viewing changes to libclamav/scanners.c

  • Committer: Bazaar Package Importer
  • Author(s): Stephen Gran
  • Date: 2008-09-05 17:25:34 UTC
  • mfrom: (0.35.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080905172534-yi3f8fkye1o7u1r3
* New upstream version (closes: #497662, #497773)
  - lots of new options for clamd.conf
  - fixes CVEs CVE-2008-3912, CVE-2008-3913, CVE-2008-3914, and
    CVE-2008-1389
* No longer supports --unzip option, so typo is gone (closes: #496276)
* Translations:
  - sv (thanks Martin Bagge <brother@bsnet.se>) (closes: #491760)

Show diffs side-by-side

added added

removed removed

Lines of Context:
90
90
#include "textnorm.h"
91
91
#include <zlib.h>
92
92
#include "unzip.h"
 
93
#include "dlp.h"
93
94
 
94
95
#ifdef HAVE_BZLIB_H
95
96
#include <bzlib.h>
130
131
#else
131
132
        while((dent = readdir(dd))) {
132
133
#endif
133
 
#if     (!defined(C_CYGWIN)) && (!defined(C_INTERIX)) && (!defined(C_WINDOWS))
 
134
#if     (!defined(C_INTERIX)) && (!defined(C_WINDOWS))
134
135
            if(dent->d_ino)
135
136
#endif
136
137
            {
238
239
        if(mdata->maxdepth && ctx->recursion > mdata->maxdepth)
239
240
            continue;
240
241
 
241
 
        /* TODO add support for regex */
242
 
        /*if(mdata->filename && !strstr(zdirent.d_name, mdata->filename))*/
243
 
        if(mdata->filename && strcmp((char *) metadata->filename, mdata->filename))
 
242
        if(mdata->filename && !cli_matchregex(metadata->filename, mdata->filename))
244
243
            continue;
245
244
 
246
245
        break; /* matched */
293
292
        if(!cli_leavetemps_flag)
294
293
            cli_rmdirs(dir);
295
294
        free(dir);
296
 
        if(ret == UNRAR_EMEM)
 
295
        if(ret == UNRAR_PASSWD) {
 
296
            cli_dbgmsg("RAR: Encrypted main header\n");
 
297
            if(DETECT_ENCRYPTED) {
 
298
                lseek(desc, 0, SEEK_SET);
 
299
                ret = cli_scandesc(desc, ctx, 0, 0, NULL, AC_SCAN_VIR);
 
300
                if(ret != CL_VIRUS)
 
301
                    *ctx->virname = "Encrypted.RAR";
 
302
                return CL_VIRUS;
 
303
            }
 
304
            return CL_CLEAN;
 
305
        } if(ret == UNRAR_EMEM) {
297
306
            return CL_EMEM;
298
 
        else
 
307
        } else {
299
308
            return CL_ERAR;
 
309
        }
300
310
    }
301
311
 
302
312
    do {
331
341
            rc = cli_magic_scandesc(rar_state.ofd,ctx);
332
342
            close(rar_state.ofd);
333
343
            if(!cli_leavetemps_flag) 
334
 
                unlink(rar_state.filename);
 
344
                if (cli_unlink(rar_state.filename)) ret = CL_EIO;
335
345
            if(rc == CL_VIRUS ) {
336
346
                cli_dbgmsg("RAR: infected with %s\n",*ctx->virname);
337
347
                ret = CL_VIRUS;
472
482
        cli_dbgmsg("GZip: Unable to malloc %u bytes.\n", FILEBUFF);
473
483
        gzclose(gd);
474
484
        close(fd);
475
 
        if(!cli_leavetemps_flag)
476
 
            unlink(tmpname);
477
 
        free(tmpname);  
 
485
        if(!cli_leavetemps_flag) {
 
486
            if(cli_unlink(tmpname)) {
 
487
                free(tmpname);
 
488
                return CL_EIO;
 
489
            }
 
490
        }
478
491
        return CL_EMEM;
479
492
    }
480
493
 
487
500
        if(cli_writen(fd, buff, bytes) != bytes) {
488
501
            cli_dbgmsg("GZip: Can't write to file.\n");
489
502
            close(fd);
490
 
            if(!cli_leavetemps_flag)
491
 
                unlink(tmpname);
 
503
            if(!cli_leavetemps_flag) {
 
504
                if (cli_unlink(tmpname)) {
 
505
                    free(tmpname);
 
506
                    gzclose(gd);
 
507
                    free(buff);
 
508
                    return CL_EIO;
 
509
                }
 
510
            }
492
511
            free(tmpname);      
493
512
            gzclose(gd);
494
513
            free(buff);
502
521
    if(ret == CL_VIRUS) {
503
522
        close(fd);
504
523
        if(!cli_leavetemps_flag)
505
 
            unlink(tmpname);
 
524
            if (cli_unlink(tmpname)) ret = CL_EIO;
506
525
        free(tmpname);  
507
526
        return ret;
508
527
    }
509
528
 
510
 
    if(fsync(fd) == -1) {
511
 
        cli_dbgmsg("GZip: Can't synchronise descriptor %d\n", fd);
512
 
        close(fd);
513
 
        if(!cli_leavetemps_flag)
514
 
            unlink(tmpname);
515
 
        free(tmpname);  
516
 
        return CL_EFSYNC;
517
 
    }
518
 
 
519
529
    lseek(fd, 0, SEEK_SET);
520
530
    if((ret = cli_magic_scandesc(fd, ctx)) == CL_VIRUS ) {
521
531
        cli_dbgmsg("GZip: Infected with %s\n", *ctx->virname);
522
532
        close(fd);
523
 
        if(!cli_leavetemps_flag)
524
 
            unlink(tmpname);
 
533
        if(!cli_leavetemps_flag) {
 
534
            if (cli_unlink(tmpname)) {
 
535
                free(tmpname);
 
536
                return CL_EIO;
 
537
            }
 
538
        }
525
539
        free(tmpname);  
526
540
        return CL_VIRUS;
527
541
    }
528
542
    close(fd);
529
543
    if(!cli_leavetemps_flag)
530
 
        unlink(tmpname);
 
544
        if (cli_unlink(tmpname)) ret = CL_EIO;
531
545
    free(tmpname);      
532
546
 
533
547
    return ret;
534
548
}
535
549
 
536
 
#ifdef HAVE_BZLIB_H
 
550
 
 
551
#ifndef HAVE_BZLIB_H
 
552
static int cli_scanbzip(int desc, cli_ctx *ctx) {
 
553
    cli_warnmsg("cli_scanbzip: bzip2 support not compiled in\n");
 
554
    return CL_CLEAN;
 
555
}
 
556
 
 
557
#else
537
558
 
538
559
#ifdef NOBZ2PREFIX
539
560
#define BZ2_bzReadOpen bzReadOpen
577
598
    if(!(buff = (char *) cli_malloc(FILEBUFF))) {
578
599
        cli_dbgmsg("Bzip: Unable to malloc %u bytes.\n", FILEBUFF);
579
600
        close(fd);
580
 
        if(!cli_leavetemps_flag)
581
 
            unlink(tmpname);
 
601
        if(!cli_leavetemps_flag) {
 
602
            if (cli_unlink(tmpname)) {
 
603
                free(tmpname);
 
604
                fclose(fs);
 
605
                BZ2_bzReadClose(&bzerror, bfd);
 
606
                return CL_EIO;
 
607
            }
 
608
        }
582
609
        free(tmpname);  
583
610
        fclose(fs);
584
611
        BZ2_bzReadClose(&bzerror, bfd);
595
622
            cli_dbgmsg("Bzip: Can't write to file.\n");
596
623
            BZ2_bzReadClose(&bzerror, bfd);
597
624
            close(fd);
598
 
            if(!cli_leavetemps_flag)
599
 
                unlink(tmpname);
 
625
            if(!cli_leavetemps_flag) {
 
626
                if (cli_unlink(tmpname)) {
 
627
                    free(tmpname);
 
628
                    free(buff);
 
629
                    fclose(fs);
 
630
                    return CL_EIO;
 
631
                }
 
632
            }
600
633
            free(tmpname);      
601
634
            free(buff);
602
635
            fclose(fs);
610
643
    if(ret == CL_VIRUS) {
611
644
        close(fd);
612
645
        if(!cli_leavetemps_flag)
613
 
            unlink(tmpname);
 
646
            if (cli_unlink(tmpname)) ret = CL_EIO;
614
647
        free(tmpname);  
615
648
        fclose(fs);
616
649
        return ret;
617
650
    }
618
651
 
619
 
    if(fsync(fd) == -1) {
620
 
        cli_dbgmsg("Bzip: Synchronisation failed for descriptor %d\n", fd);
621
 
        close(fd);
622
 
        if(!cli_leavetemps_flag)
623
 
            unlink(tmpname);
624
 
        free(tmpname);  
625
 
        fclose(fs);
626
 
        return CL_EFSYNC;
627
 
    }
628
 
 
629
652
    lseek(fd, 0, SEEK_SET);
630
653
    if((ret = cli_magic_scandesc(fd, ctx)) == CL_VIRUS ) {
631
654
        cli_dbgmsg("Bzip: Infected with %s\n", *ctx->virname);
632
655
    }
633
656
    close(fd);
634
657
    if(!cli_leavetemps_flag)
635
 
        unlink(tmpname);
 
658
        if (cli_unlink(tmpname)) ret = CL_EIO;
636
659
    free(tmpname);      
637
660
    fclose(fs);
638
661
 
659
682
    if(ret != CL_SUCCESS) { /* CL_VIRUS or some error */
660
683
        close(ofd);
661
684
        if(!cli_leavetemps_flag)
662
 
            unlink(tmpname);
 
685
            if (cli_unlink(tmpname)) ret = CL_EIO;
663
686
        free(tmpname);  
664
687
        return ret;
665
688
    }
669
692
    ret = cli_magic_scandesc(ofd, ctx);
670
693
    close(ofd);
671
694
    if(!cli_leavetemps_flag)
672
 
        unlink(tmpname);
 
695
        if (cli_unlink(tmpname)) ret = CL_EIO;
673
696
    free(tmpname);      
674
697
 
675
698
    return ret;
705
728
        else
706
729
            ret = cli_scanfile(tempname, ctx);
707
730
 
708
 
        if(!cli_leavetemps_flag)
709
 
            unlink(tempname);
 
731
        if(!cli_leavetemps_flag) {
 
732
            if (cli_unlink(tempname)) {
 
733
                free(tempname);
 
734
                ret = CL_EIO;
 
735
                break;
 
736
            }
 
737
        }
710
738
        free(tempname);
711
739
        if(ret == CL_VIRUS)
712
740
            break;
718
746
 
719
747
static int cli_vba_scandir(const char *dirname, cli_ctx *ctx, struct uniq *U)
720
748
{
721
 
    int ret = CL_CLEAN, i, j, fd, ofd, data_len;
 
749
    int ret = CL_CLEAN, i, j, fd, data_len;
722
750
        vba_project_t *vba_project;
723
751
        DIR *dd;
724
752
        struct dirent *dent;
731
759
        struct stat statbuf;
732
760
        char *fullname, vbaname[1024];
733
761
        unsigned char *data;
734
 
        uint32_t hash, hashcnt;
 
762
        char *hash;
 
763
        uint32_t hashcnt;
735
764
 
736
765
 
737
766
    cli_dbgmsg("VBADir: %s\n", dirname);
740
769
        if(!(vba_project = (vba_project_t *)cli_vba_readdir(dirname, U, hashcnt))) continue;
741
770
 
742
771
        for(i = 0; i < vba_project->count; i++) {
743
 
            for(j = 0; j < vba_project->colls[i]; j++) {
744
 
                snprintf(vbaname, 1024, "%s/%u_%u", vba_project->dir, vba_project->name[i], j);
 
772
            for(j = 0; (unsigned int)j < vba_project->colls[i]; j++) {
 
773
                snprintf(vbaname, 1024, "%s/%s_%u", vba_project->dir, vba_project->name[i], j);
745
774
                vbaname[sizeof(vbaname)-1] = '\0';
746
775
                fd = open(vbaname, O_RDONLY|O_BINARY);
747
776
                if(fd == -1) continue;
748
 
                cli_dbgmsg("VBADir: Decompress VBA project '%u_%u'\n", vba_project->name[i], j);
 
777
                cli_dbgmsg("VBADir: Decompress VBA project '%s_%u'\n", vba_project->name[i], j);
749
778
                data = (unsigned char *)cli_vba_inflate(fd, vba_project->offset[i], &data_len);
750
779
                close(fd);
751
780
 
752
781
                if(!data) {
753
 
                    cli_dbgmsg("VBADir: WARNING: VBA project '%u_%u' decompressed to NULL\n", vba_project->name[i], j);
 
782
                    cli_dbgmsg("VBADir: WARNING: VBA project '%s_%u' decompressed to NULL\n", vba_project->name[i], j);
754
783
                } else {
755
784
                    /* cli_dbgmsg("Project content:\n%s", data); */
756
785
                    if(ctx->scanned)
775
804
 
776
805
    if(ret == CL_CLEAN && (hashcnt = uniq_get(U, "powerpoint document", 19, &hash))) {
777
806
        while(hashcnt--) {
778
 
            snprintf(vbaname, 1024, "%s/%u_%u", dirname, hash, hashcnt);
 
807
            snprintf(vbaname, 1024, "%s/%s_%u", dirname, hash, hashcnt);
779
808
            vbaname[sizeof(vbaname)-1] = '\0';
780
809
            fd = open(vbaname, O_RDONLY|O_BINARY);
781
810
            if (fd == -1) continue;
793
822
 
794
823
    if (ret == CL_CLEAN && (hashcnt = uniq_get(U, "worddocument", 12, &hash))) {
795
824
        while(hashcnt--) {
796
 
            snprintf(vbaname, sizeof(vbaname), "%s/%u_%u", dirname, hash, hashcnt);
 
825
            snprintf(vbaname, sizeof(vbaname), "%s/%s_%u", dirname, hash, hashcnt);
797
826
            vbaname[sizeof(vbaname)-1] = '\0';
798
827
            fd = open(vbaname, O_RDONLY|O_BINARY);
799
828
            if (fd == -1) continue;
840
869
    /* Check directory for embedded OLE objects */
841
870
    hashcnt = uniq_get(U, "_1_ole10native", 14, &hash);
842
871
    while(hashcnt--) {
843
 
        snprintf(vbaname, sizeof(vbaname), "%s/%u_%u", dirname, hash, hashcnt);
 
872
        snprintf(vbaname, sizeof(vbaname), "%s/%s_%u", dirname, hash, hashcnt);
844
873
        vbaname[sizeof(vbaname)-1] = '\0';
845
874
 
846
875
        fd = open(vbaname, O_RDONLY|O_BINARY);
865
894
#else
866
895
        while((dent = readdir(dd))) {
867
896
#endif
868
 
#if     (!defined(C_CYGWIN)) && (!defined(C_INTERIX)) && (!defined(C_WINDOWS))
 
897
#if     (!defined(C_INTERIX)) && (!defined(C_WINDOWS))
869
898
            if(dent->d_ino)
870
899
#endif
871
900
            {
952
981
            }
953
982
    }
954
983
 
 
984
    if(ret == CL_CLEAN) {
 
985
            snprintf(fullname, 1024, "%s/javascript", tempname);
 
986
            fd = open(fullname, O_RDONLY|O_BINARY);
 
987
            if(fd >= 0) {
 
988
                    ret = cli_scandesc(fd, ctx, CL_TYPE_SCRIPT, 0, NULL, AC_SCAN_VIR);
 
989
                    close(fd);
 
990
            }
 
991
    }
 
992
 
955
993
    if (ret == CL_CLEAN) {
956
994
        snprintf(fullname, 1024, "%s/rfc2397", tempname);
957
995
        ret = cli_scandir(fullname, ctx, 0);
1062
1100
            if(write(fd, decoded, strlen(decoded)) == -1) {
1063
1101
                cli_errmsg("cli_scanhtml_utf16: Can't write to file %s\n", tempname);
1064
1102
                free(decoded);
1065
 
                unlink(tempname);
 
1103
                cli_unlink(tempname);
1066
1104
                free(tempname);
1067
1105
                close(fd);
1068
1106
                return CL_EIO;
1071
1109
        }
1072
1110
    }
1073
1111
 
1074
 
    fsync(fd);
1075
1112
    lseek(fd, 0, SEEK_SET);
1076
1113
    ret = cli_scanhtml(fd, ctx);
1077
1114
    close(fd);
1078
1115
 
1079
 
    if(!cli_leavetemps_flag)
1080
 
        unlink(tempname);
1081
 
    else
 
1116
    if(!cli_leavetemps_flag) {
 
1117
        if (cli_unlink(tempname)) ret = CL_EIO;
 
1118
    } else
1082
1119
        cli_dbgmsg("cli_scanhtml_utf16: Decoded HTML data saved in %s\n", tempname);
1083
1120
    free(tempname);
1084
1121
 
1366
1403
 
1367
1404
    free(dest);
1368
1405
 
1369
 
    if(fsync(ndesc) == -1) {
1370
 
        cli_errmsg("CryptFF: Can't fsync descriptor %d\n", ndesc);
1371
 
        close(ndesc);
1372
 
        free(tempfile);
1373
 
        return CL_EIO;
1374
 
    }
1375
 
 
1376
1406
    lseek(ndesc, 0, SEEK_SET);
1377
1407
 
1378
1408
    cli_dbgmsg("CryptFF: Scanning decrypted data\n");
1385
1415
    if(cli_leavetemps_flag)
1386
1416
        cli_dbgmsg("CryptFF: Decompressed data saved in %s\n", tempfile);
1387
1417
    else
1388
 
        unlink(tempfile);
 
1418
        if (cli_unlink(tempfile)) ret = CL_EIO;
1389
1419
 
1390
1420
    free(tempfile);
1391
1421
    return ret;
1503
1533
    return ret;
1504
1534
}
1505
1535
 
 
1536
static int cli_scan_structured(int desc, cli_ctx *ctx)
 
1537
{
 
1538
        char buf[8192];
 
1539
        int result = 0;
 
1540
        unsigned int cc_count = 0;
 
1541
        unsigned int ssn_count = 0;
 
1542
        int done = 0;
 
1543
        const struct cl_limits *lim = NULL;
 
1544
        int (*ccfunc)(const unsigned char *buffer, int length);
 
1545
        int (*ssnfunc)(const unsigned char *buffer, int length);
 
1546
 
 
1547
 
 
1548
    if(ctx == NULL || ctx->limits == NULL)
 
1549
        return CL_ENULLARG;
 
1550
 
 
1551
    lim = ctx->limits;
 
1552
 
 
1553
    if(lim->min_cc_count == 1)
 
1554
        ccfunc = dlp_has_cc;
 
1555
    else
 
1556
        ccfunc = dlp_get_cc_count;
 
1557
 
 
1558
    switch((ctx->options & CL_SCAN_STRUCTURED_SSN_NORMAL) | (ctx->options & CL_SCAN_STRUCTURED_SSN_STRIPPED)) {
 
1559
 
 
1560
        case (CL_SCAN_STRUCTURED_SSN_NORMAL | CL_SCAN_STRUCTURED_SSN_STRIPPED):
 
1561
            if(lim->min_ssn_count == 1)
 
1562
                ssnfunc = dlp_has_ssn;
 
1563
            else
 
1564
                ssnfunc = dlp_get_ssn_count;
 
1565
            break;
 
1566
 
 
1567
        case CL_SCAN_STRUCTURED_SSN_NORMAL:
 
1568
            if(lim->min_ssn_count == 1)
 
1569
                ssnfunc = dlp_has_normal_ssn;
 
1570
            else
 
1571
                ssnfunc = dlp_get_normal_ssn_count;
 
1572
            break;
 
1573
 
 
1574
        case CL_SCAN_STRUCTURED_SSN_STRIPPED:
 
1575
            if(lim->min_ssn_count == 1)
 
1576
                ssnfunc = dlp_has_stripped_ssn;
 
1577
            else
 
1578
                ssnfunc = dlp_get_stripped_ssn_count;
 
1579
            break;
 
1580
 
 
1581
        default:
 
1582
            ssnfunc = NULL;
 
1583
    }
 
1584
 
 
1585
    while(!done && ((result = cli_readn(desc, buf, 8191)) > 0)) {
 
1586
        if((cc_count += ccfunc((const unsigned char *)buf, result)) >= lim->min_cc_count)
 
1587
            done = 1;
 
1588
 
 
1589
        if(ssnfunc && ((ssn_count += ssnfunc((const unsigned char *)buf, result)) >= lim->min_ssn_count))
 
1590
            done = 1;
 
1591
    }
 
1592
 
 
1593
    if(cc_count != 0 && cc_count >= lim->min_cc_count) {
 
1594
        cli_dbgmsg("cli_scan_structured: %u credit card numbers detected\n", cc_count);
 
1595
        *ctx->virname = "Structured.CreditCardNumber";
 
1596
        return CL_VIRUS;
 
1597
    }
 
1598
 
 
1599
    if(ssn_count != 0 && ssn_count >= lim->min_ssn_count) {
 
1600
        cli_dbgmsg("cli_scan_structured: %u social security numbers detected\n", ssn_count);
 
1601
        *ctx->virname = "Structured.SSN";
 
1602
        return CL_VIRUS;
 
1603
    }
 
1604
 
 
1605
    return CL_CLEAN;
 
1606
}
 
1607
 
1506
1608
static int cli_scanembpe(int desc, cli_ctx *ctx)
1507
1609
{
1508
1610
        int fd, bytes, ret = CL_CLEAN;
1530
1632
        if(cli_writen(fd, buff, bytes) != bytes) {
1531
1633
            cli_dbgmsg("cli_scanembpe: Can't write to temporary file\n");
1532
1634
            close(fd);
1533
 
            if(!cli_leavetemps_flag)
1534
 
                unlink(tmpname);
 
1635
            if(!cli_leavetemps_flag) {
 
1636
                if (cli_unlink(tmpname)) {
 
1637
                    free(tmpname);
 
1638
                    return CL_EIO;
 
1639
                }
 
1640
            }
1535
1641
            free(tmpname);      
1536
1642
            return CL_EIO;
1537
1643
        }
1538
1644
    }
1539
1645
 
1540
 
    if(fsync(fd) == -1) {
1541
 
        cli_dbgmsg("cli_scanembpe: Can't synchronise descriptor %d\n", fd);
1542
 
        close(fd);
1543
 
        if(!cli_leavetemps_flag)
1544
 
            unlink(tmpname);
1545
 
        free(tmpname);  
1546
 
        return CL_EFSYNC;
1547
 
    }
1548
 
 
1549
1646
    ctx->recursion++;
1550
1647
    lseek(fd, 0, SEEK_SET);
1551
1648
    if((ret = cli_magic_scandesc(fd, ctx)) == CL_VIRUS) {
1552
1649
        cli_dbgmsg("cli_scanembpe: Infected with %s\n", *ctx->virname);
1553
1650
        close(fd);
1554
 
        if(!cli_leavetemps_flag)
1555
 
            unlink(tmpname);
 
1651
        if(!cli_leavetemps_flag) {
 
1652
            if (cli_unlink(tmpname)) {
 
1653
                free(tmpname);
 
1654
                return CL_EIO;
 
1655
            }
 
1656
        }
1556
1657
        free(tmpname);  
1557
1658
        return CL_VIRUS;
1558
1659
    }
1559
1660
    ctx->recursion--;
1560
1661
 
1561
1662
    close(fd);
1562
 
    if(!cli_leavetemps_flag)
1563
 
        unlink(tmpname);
 
1663
    if(!cli_leavetemps_flag) {
 
1664
        if (cli_unlink(tmpname)) {
 
1665
            free(tmpname);
 
1666
            return CL_EIO;
 
1667
        }
 
1668
    }
1564
1669
    free(tmpname);
1565
1670
 
1566
1671
    /* intentionally ignore possible errors from cli_magic_scandesc */
1805
1910
            break;
1806
1911
 
1807
1912
        case CL_TYPE_BZ:
1808
 
#ifdef HAVE_BZLIB_H
1809
1913
            if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_BZ))
1810
1914
                ret = cli_scanbzip(desc, ctx);
1811
 
#endif
1812
1915
            break;
1813
1916
        case CL_TYPE_ARJ:
1814
1917
            if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ARJ))
1934
2037
            ret = cli_check_mydoom_log(desc, ctx->virname);
1935
2038
            break;
1936
2039
 
 
2040
        case CL_TYPE_TEXT_ASCII:
 
2041
            if(SCAN_STRUCTURED && (DCONF_OTHER & OTHER_CONF_DLP))
 
2042
                /* TODO: consider calling this from cli_scanscript() for
 
2043
                 * a normalised text
 
2044
                 */
 
2045
                ret = cli_scan_structured(desc, ctx);
 
2046
            break;
 
2047
 
1937
2048
        default:
1938
2049
            break;
1939
2050
    }
1940
 
 
1941
2051
    ctx->recursion--;
1942
2052
 
 
2053
    if(ret == CL_VIRUS)
 
2054
        return CL_VIRUS;
 
2055
 
1943
2056
    if(type == CL_TYPE_ZIP && SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ZIP)) {
1944
2057
        if(sb.st_size > 1048576) {
1945
2058
            cli_dbgmsg("cli_magic_scandesc: Not checking for embedded PEs (zip file > 1 MB)\n");
1948
2061
    }
1949
2062
 
1950
2063
    /* CL_TYPE_HTML: raw HTML files are not scanned, unless safety measure activated via DCONF */
1951
 
    if(type != CL_TYPE_IGNORED && (type != CL_TYPE_HTML || !(DCONF_DOC & DOC_CONF_HTML_SKIPRAW)) && ret != CL_VIRUS && !ctx->engine->sdb) {
 
2064
    if(type != CL_TYPE_IGNORED && (type != CL_TYPE_HTML || !(DCONF_DOC & DOC_CONF_HTML_SKIPRAW)) && !ctx->engine->sdb) {
1952
2065
        if(cli_scanraw(desc, ctx, type, typercg, &dettype) == CL_VIRUS)
1953
2066
            return CL_VIRUS;
1954
2067
    }
1957
2070
    lseek(desc, 0, SEEK_SET);
1958
2071
    switch(type) {
1959
2072
        case CL_TYPE_TEXT_ASCII:
 
2073
        case CL_TYPE_TEXT_UTF16BE:
 
2074
        case CL_TYPE_TEXT_UTF16LE:
 
2075
        case CL_TYPE_TEXT_UTF8:
1960
2076
            if((DCONF_DOC & DOC_CONF_SCRIPT) && dettype != CL_TYPE_HTML)
1961
2077
                ret = cli_scanscript(desc, ctx);
1962
2078
            break;
2011
2127
    return rc;
2012
2128
}
2013
2129
 
 
2130
int cli_found_possibly_unwanted(cli_ctx* ctx)
 
2131
{
 
2132
        if(ctx->virname) {
 
2133
                cli_dbgmsg("found Possibly Unwanted: %s\n",*ctx->virname);
 
2134
                if(ctx->options & CL_SCAN_HEURISTIC_PRECEDENCE) {
 
2135
                        /* we found a heuristic match, don't scan further,
 
2136
                         * but consider it a virus. */
 
2137
                        cli_dbgmsg("cli_found_possibly_unwanted: CL_VIRUS\n");
 
2138
                        return CL_VIRUS;
 
2139
                }
 
2140
                /* heuristic scan isn't taking precedence, keep scanning.
 
2141
                 * If this is part of an archive, and 
 
2142
                 * we find a real malware we report that instead of the 
 
2143
                 * heuristic match */
 
2144
                ctx->found_possibly_unwanted = 1;
 
2145
        } else {
 
2146
                cli_warnmsg("cli_found_possibly_unwanted called, but virname is not set\n");
 
2147
        }
 
2148
        return CL_CLEAN;
 
2149
}
 
2150
 
2014
2151
static int cli_scanfile(const char *filename, cli_ctx *ctx)
2015
2152
{
2016
2153
        int fd, ret;