~ubuntu-branches/ubuntu/saucy/clamav/saucy-backports

« back to all changes in this revision

Viewing changes to libclamav/xar.c

  • Committer: Package Import Robot
  • Author(s): Scott Kitterman
  • Date: 2014-07-15 01:08:10 UTC
  • mfrom: (0.35.47 sid)
  • Revision ID: package-import@ubuntu.com-20140715010810-ru66ek4fun2iseba
Tags: 0.98.4+dfsg-2~ubuntu13.10.1
No-change backport to saucy (LP: #1341962)

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
#include "clamav-config.h"
23
23
#endif
24
24
 
 
25
#include <openssl/ssl.h>
 
26
#include <openssl/err.h>
 
27
#include "libclamav/crypto.h"
 
28
 
25
29
#include <errno.h>
26
30
#include "xar.h"
27
31
#include "fmap.h"
36
40
#include "scanners.h"
37
41
#include "inflate64.h"
38
42
#include "lzma_iface.h"
39
 
#include "sha1.h"
40
 
#include "md5.h"
41
43
 
42
44
/*
43
45
   xar_cleanup_temp_file - cleanup after cli_gentempfd
50
52
static int xar_cleanup_temp_file(cli_ctx *ctx, int fd, char * tmpname)
51
53
{
52
54
    int rc = CL_SUCCESS;
53
 
    close(fd);
54
 
    if(!ctx->engine->keeptmp) {
55
 
        if (cli_unlink(tmpname)) {
56
 
            cli_errmsg("cli_scanxar: error unlinking tmpfile %s\n", tmpname); 
57
 
            rc = CL_EUNLINK;
 
55
    if (fd > -1)
 
56
        close(fd);
 
57
    if (tmpname != NULL) {
 
58
        if (!ctx->engine->keeptmp) {
 
59
            if (cli_unlink(tmpname)) {
 
60
                cli_dbgmsg("cli_scanxar: error unlinking tmpfile %s\n", tmpname); 
 
61
                rc = CL_EUNLINK;
 
62
            }
58
63
        }
 
64
        free(tmpname);
59
65
    }
60
 
    free(tmpname);
61
66
    return rc;
62
67
}
63
68
 
76
81
        if (numstr) {
77
82
            *value = atol((const char *)numstr);
78
83
            if (*value < 0) {
79
 
                cli_errmsg("cli_scanxar: XML element value %li\n", *value);
 
84
                cli_dbgmsg("cli_scanxar: XML element value %li\n", *value);
80
85
                return CL_EFORMAT;
81
86
            }
82
87
            return CL_SUCCESS;
83
88
        }
84
89
    }
85
 
    cli_errmsg("cli_scanxar: No text for XML element\n");
 
90
    cli_dbgmsg("cli_scanxar: No text for XML element\n");
86
91
    return CL_EFORMAT;
87
92
}
88
93
 
101
106
 
102
107
    *hash = XAR_CKSUM_NONE;
103
108
    if (style == NULL) {
104
 
        cli_errmsg("cli_scaxar: xmlTextReaderGetAttribute no style attribute "
 
109
        cli_dbgmsg("cli_scaxar: xmlTextReaderGetAttribute no style attribute "
105
110
                   "for checksum element\n");
106
111
    } else {
107
112
        cli_dbgmsg("cli_scanxar: checksum algorithm is %s.\n", style);        
114
119
            *hash = XAR_CKSUM_OTHER;
115
120
        }
116
121
    }
 
122
    if (style != NULL)
 
123
        xmlFree(style);
117
124
 
118
125
    if (xmlTextReaderRead(reader) == 1 && xmlTextReaderNodeType(reader) == XML_READER_TYPE_TEXT) {
119
126
        xmlval = xmlTextReaderConstValue(reader);
122
129
            cli_dbgmsg("cli_scanxar: checksum value is %s.\n", *cksum);
123
130
        } else {
124
131
            *cksum = NULL;
125
 
            cli_errmsg("cli_scanxar: xmlTextReaderConstValue() returns NULL for checksum value.\n");           
 
132
            cli_dbgmsg("cli_scanxar: xmlTextReaderConstValue() returns NULL for checksum value.\n");           
126
133
        }
127
134
    }
128
135
    else
129
 
        cli_errmsg("cli_scanxar: No text for XML checksum element.\n");
 
136
        cli_dbgmsg("cli_scanxar: No text for XML checksum element.\n");
130
137
}
131
138
 
132
139
/*
191
198
                       xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT) {
192
199
                xmlChar * style = xmlTextReaderGetAttribute(reader, (const xmlChar *)"style");
193
200
                if (style == NULL) {
194
 
                    cli_errmsg("cli_scaxar: xmlTextReaderGetAttribute no style attribute "
 
201
                    cli_dbgmsg("cli_scaxar: xmlTextReaderGetAttribute no style attribute "
195
202
                               "for encoding element\n");
196
203
                    *encoding = CL_TYPE_ANY;
197
204
                } else if (xmlStrEqual(style, (const xmlChar *)"application/x-gzip")) {
210
217
                    cli_dbgmsg("cli_scanxar: encoding = application/x-xz.\n");
211
218
                    *encoding = CL_TYPE_XZ;
212
219
                } else {
213
 
                    cli_errmsg("cli_scaxar: unknown style value=%s for encoding element\n", style);
 
220
                    cli_dbgmsg("cli_scaxar: unknown style value=%s for encoding element\n", style);
214
221
                    *encoding = CL_TYPE_ANY;
215
222
                }
 
223
                if (style != NULL)
 
224
                    xmlFree(style);
216
225
 
217
226
           } else if (indata && xmlStrEqual(name, (const xmlChar *)"data") &&
218
227
                       xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) {
272
281
    while (xmlTextReaderRead(reader) == 1) {
273
282
        name = xmlTextReaderConstLocalName(reader);
274
283
        if (name == NULL) {
275
 
            cli_errmsg("cli_scanxar: xmlTextReaderConstLocalName() no name.\n");
 
284
            cli_dbgmsg("cli_scanxar: xmlTextReaderConstLocalName() no name.\n");
276
285
            rc = CL_EFORMAT;
277
286
            break;
278
287
        }
283
292
            xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT) {
284
293
            subdoc = xmlTextReaderReadInnerXml(reader);
285
294
            if (subdoc == NULL) {
286
 
                cli_errmsg("cli_scanxar: no content in subdoc element.\n");
 
295
                cli_dbgmsg("cli_scanxar: no content in subdoc element.\n");
287
296
                xmlTextReaderNext(reader);
288
297
                continue;
289
298
            }
290
 
            //            printf("subdoc:\n%s\n", subdoc);
291
299
            subdoc_len = xmlStrlen(subdoc);
292
300
            cli_dbgmsg("cli_scanxar: in-memory scan of xml subdocument, len %i.\n", subdoc_len);
293
301
            rc = cli_mem_scandesc(subdoc, subdoc_len, ctx);
297
305
            /* make a file to leave if --leave-temps in effect */
298
306
            if(ctx->engine->keeptmp) {
299
307
                if ((rc = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &fd)) != CL_SUCCESS) {
300
 
                    cli_errmsg("cli_scanxar: Can't create temporary file for subdocument.\n");
 
308
                    cli_dbgmsg("cli_scanxar: Can't create temporary file for subdocument.\n");
301
309
                } else {
302
310
                    cli_dbgmsg("cli_scanxar: Writing subdoc to temp file %s.\n", tmpname);
303
311
                    if (cli_writen(fd, subdoc, subdoc_len) < 0) {
304
 
                        cli_errmsg("cli_scanxar: cli_writen error writing subdoc temporary file.\n");
 
312
                        cli_dbgmsg("cli_scanxar: cli_writen error writing subdoc temporary file.\n");
305
313
                        rc = CL_EWRITE;
306
314
                    }
307
315
                    rc = xar_cleanup_temp_file(ctx, fd, tmpname);
317
325
    return rc;
318
326
}
319
327
 
320
 
static void * xar_hash_init(int hash, SHA1Context *sc, cli_md5_ctx *mc)
 
328
static void * xar_hash_init(int hash, void **sc, void **mc)
321
329
{
322
330
    if (!sc && !mc)
323
331
        return NULL;
324
332
    switch (hash) {
325
333
    case XAR_CKSUM_SHA1:
326
 
        SHA1Init(sc);
327
 
        return sc;
 
334
        *sc = cl_hash_init("sha1");
 
335
        if (!(*sc)) {
 
336
            return NULL;
 
337
        }
 
338
 
 
339
        return *sc;
328
340
    case XAR_CKSUM_MD5:
329
 
        cli_md5_init(mc);
330
 
        return mc;
 
341
        *mc = cl_hash_init("md5");
 
342
        if (!(*mc)) {
 
343
            return NULL;
 
344
        }
 
345
 
 
346
        return *mc;
331
347
    case XAR_CKSUM_OTHER:
332
348
    case XAR_CKSUM_NONE:
333
349
    default:
335
351
    }
336
352
}
337
353
 
338
 
static void xar_hash_update(void * hash_ctx, const void * data, unsigned long size, int hash)
 
354
static void xar_hash_update(void * hash_ctx, void * data, unsigned long size, int hash)
339
355
{
340
356
    if (!hash_ctx || !data || !size)
341
357
        return;
 
358
 
342
359
    switch (hash) {
343
 
    case XAR_CKSUM_SHA1:
344
 
        SHA1Update(hash_ctx, data, size);
345
 
        return;
346
 
    case XAR_CKSUM_MD5:
347
 
        if (0 == cli_md5_update(hash_ctx, data, size)) {
348
 
            cli_errmsg("cli_scanxar: cli_md5_update invalid return.\n");
349
 
            return;
350
 
        }
351
 
        return;
 
360
    case XAR_CKSUM_NONE:
352
361
    case XAR_CKSUM_OTHER:
353
 
    case XAR_CKSUM_NONE:
354
 
    default:
355
362
        return;
356
363
    }
 
364
 
 
365
    cl_update_hash(hash_ctx, data, size);
357
366
}
358
367
 
359
368
static void xar_hash_final(void * hash_ctx, void * result, int hash)
360
369
{
361
 
    
362
370
    if (!hash_ctx || !result)
363
371
        return;
 
372
 
364
373
    switch (hash) {
365
 
    case XAR_CKSUM_SHA1:
366
 
        SHA1Final(hash_ctx, result);
367
 
        return;
368
 
    case XAR_CKSUM_MD5:
369
 
        cli_md5_final(result, hash_ctx);
370
 
        return;
371
374
    case XAR_CKSUM_OTHER:
372
375
    case XAR_CKSUM_NONE:
373
 
    default:
374
376
        return;
375
377
    }
 
378
 
 
379
    cl_finish_hash(hash_ctx, result);
376
380
}
377
381
 
378
382
static int xar_hash_check(int hash, const void * result, const void * expected)
409
413
{
410
414
    int rc = CL_SUCCESS;
411
415
    unsigned int cksum_fails = 0;
 
416
    unsigned int extract_errors = 0;
412
417
#if HAVE_LIBXML2
413
418
    int fd = -1;
414
419
    struct xar_header hdr;
423
428
 
424
429
    /* retrieve xar header */
425
430
    if (fmap_readn(*ctx->fmap, &hdr, 0, sizeof(hdr)) != sizeof(hdr)) {
426
 
        cli_errmsg("cli_scanxar: Invalid header, too short.\n");
 
431
        cli_dbgmsg("cli_scanxar: Invalid header, too short.\n");
427
432
        return CL_EFORMAT;
428
433
    }
429
434
    hdr.magic = be32_to_host(hdr.magic);
432
437
        cli_dbgmsg("cli_scanxar: Matched magic\n");
433
438
    }
434
439
    else {
435
 
        cli_errmsg("cli_scanxar: Invalid magic\n");
 
440
        cli_dbgmsg("cli_scanxar: Invalid magic\n");
436
441
        return CL_EFORMAT;
437
442
    }
438
443
    hdr.size = be16_to_host(hdr.size);
451
456
    /* Uncompress TOC */
452
457
    strm.next_in = (unsigned char *)fmap_need_off_once(*ctx->fmap, hdr.size, hdr.toc_length_compressed);
453
458
    if (strm.next_in == NULL) {
454
 
        cli_errmsg("cli_scanxar: fmap_need_off_once fails on TOC.\n");
455
 
        return CL_EFORMAT;
 
459
        cli_dbgmsg("cli_scanxar: fmap_need_off_once fails on TOC.\n");
 
460
        return CL_EREAD;
456
461
    }
457
462
    strm.avail_in = hdr.toc_length_compressed; 
458
463
    toc = cli_malloc(hdr.toc_length_decompressed+1);
459
464
    if (toc == NULL) {
460
 
        cli_errmsg("cli_scanxar: cli_malloc fails on TOC decompress buffer.\n");
 
465
        cli_dbgmsg("cli_scanxar: cli_malloc fails on TOC decompress buffer.\n");
461
466
        return CL_EMEM;
462
467
    }
463
468
    toc[hdr.toc_length_decompressed] = '\0';
465
470
    strm.next_out = (unsigned char *)toc;
466
471
    rc = inflateInit(&strm);
467
472
    if (rc != Z_OK) {
468
 
        cli_errmsg("cli_scanxar:inflateInit error %i \n", rc);
 
473
        cli_dbgmsg("cli_scanxar:inflateInit error %i \n", rc);
469
474
        rc = CL_EFORMAT;
470
475
        goto exit_toc;
471
476
    }    
472
477
    rc = inflate(&strm, Z_SYNC_FLUSH);
473
478
    if (rc != Z_OK && rc != Z_STREAM_END) {
474
 
        cli_errmsg("cli_scanxar:inflate error %i \n", rc);
 
479
        cli_dbgmsg("cli_scanxar:inflate error %i \n", rc);
475
480
        rc = CL_EFORMAT;
476
481
        goto exit_toc;
477
482
    }
478
483
    rc = inflateEnd(&strm);
479
484
    if (rc != Z_OK) {
480
 
        cli_errmsg("cli_scanxar:inflateEnd error %i \n", rc);
 
485
        cli_dbgmsg("cli_scanxar:inflateEnd error %i \n", rc);
481
486
        rc = CL_EFORMAT;
482
487
        goto exit_toc;
483
488
    }
498
503
    /* make a file to leave if --leave-temps in effect */
499
504
    if(ctx->engine->keeptmp) {
500
505
        if ((rc = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &fd)) != CL_SUCCESS) {
501
 
            cli_errmsg("cli_scanxar: Can't create temporary file for TOC.\n");
 
506
            cli_dbgmsg("cli_scanxar: Can't create temporary file for TOC.\n");
502
507
            goto exit_toc;
503
508
        }
504
509
        if (cli_writen(fd, toc, hdr.toc_length_decompressed) < 0) {
505
 
            cli_errmsg("cli_scanxar: cli_writen error writing TOC.\n");
 
510
            cli_dbgmsg("cli_scanxar: cli_writen error writing TOC.\n");
506
511
            rc = CL_EWRITE;
507
512
            xar_cleanup_temp_file(ctx, fd, tmpname);
508
513
            goto exit_toc;
514
519
 
515
520
    reader = xmlReaderForMemory(toc, hdr.toc_length_decompressed, "noname.xml", NULL, 0);
516
521
    if (reader == NULL) {
517
 
        cli_errmsg("cli_scanxar: xmlReaderForMemory error for TOC\n");
 
522
        cli_dbgmsg("cli_scanxar: xmlReaderForMemory error for TOC\n");
518
523
        goto exit_toc;
519
524
    }
520
525
 
521
526
    rc = xar_scan_subdocuments(reader, ctx);
522
527
    if (rc != CL_SUCCESS) {
523
 
        cli_errmsg("xar_scan_subdocuments returns %i.\n", rc);
 
528
        cli_dbgmsg("xar_scan_subdocuments returns %i.\n", rc);
524
529
        goto exit_reader;
525
530
    }
526
531
 
531
536
                                                       &a_cksum, &a_hash, &e_cksum, &e_hash))) {
532
537
        int do_extract_cksum = 1;
533
538
        unsigned char * blockp;
534
 
        SHA1Context a_sc, e_sc;
535
 
        cli_md5_ctx a_mc, e_mc;
 
539
        void *a_sc, *e_sc;
 
540
        void *a_mc, *e_mc;
536
541
        void *a_hash_ctx, *e_hash_ctx;
537
542
        char result[SHA1_HASH_SIZE];
538
543
        char * expected;
547
552
        at = offset + hdr.toc_length_compressed + hdr.size;
548
553
 
549
554
        if ((rc = cli_gentempfd(ctx->engine->tmpdir, &tmpname, &fd)) != CL_SUCCESS) {
550
 
            cli_errmsg("cli_scanxar: Can't generate temporary file.\n");
 
555
            cli_dbgmsg("cli_scanxar: Can't generate temporary file.\n");
551
556
            goto exit_reader;
552
557
        }
553
558
 
564
569
            /* inflate gzip directly because file segments do not contain magic */
565
570
            memset(&strm, 0, sizeof(strm));
566
571
            if ((rc = inflateInit(&strm)) != Z_OK) {
567
 
                cli_errmsg("cli_scanxar: InflateInit failed: %d\n", rc);
 
572
                cli_dbgmsg("cli_scanxar: InflateInit failed: %d\n", rc);
568
573
                rc = CL_EFORMAT;
569
 
                goto exit_tmpfile;
 
574
                extract_errors++;
 
575
                break;
570
576
            }
571
577
            
572
578
            while (at < map->len && at < offset+hdr.toc_length_compressed+hdr.size+length) {
574
580
                void * next_in;
575
581
                unsigned int bytes = MIN(map->len - at, map->pgsz);
576
582
                bytes = MIN(length, bytes);
577
 
                //cli_dbgmsg("cli_scanxar: fmap %u bytes\n", bytes);
578
583
                if(!(strm.next_in = next_in = (void*)fmap_need_off_once(map, at, bytes))) {
579
584
                    cli_dbgmsg("cli_scanxar: Can't read %u bytes @ %lu.\n", bytes, (long unsigned)at);
580
585
                    inflateEnd(&strm);
588
593
                    unsigned char buff[FILEBUFF];
589
594
                    strm.avail_out = sizeof(buff);
590
595
                    strm.next_out = buff;
591
 
                    //cli_dbgmsg("cli_scanxar: inflating.....\n");
592
596
                    inf = inflate(&strm, Z_SYNC_FLUSH);
593
597
                    if (inf != Z_OK && inf != Z_STREAM_END && inf != Z_BUF_ERROR) {
594
 
                        cli_errmsg("cli_scanxar: inflate error %i %s.\n", inf, strm.msg?strm.msg:"");
595
 
                        at = map->len;
 
598
                        cli_dbgmsg("cli_scanxar: inflate error %i %s.\n", inf, strm.msg?strm.msg:"");
596
599
                        rc = CL_EFORMAT;
597
 
                        goto exit_tmpfile;
 
600
                        extract_errors++;
 
601
                        break;
598
602
                    }
599
603
 
600
604
                    bytes = sizeof(buff) - strm.avail_out;
602
606
                    xar_hash_update(e_hash_ctx, buff, bytes, e_hash);
603
607
                   
604
608
                    if (cli_writen(fd, buff, bytes) < 0) {
605
 
                        cli_errmsg("cli_scanxar: cli_writen error file %s.\n", tmpname);
 
609
                        cli_dbgmsg("cli_scanxar: cli_writen error file %s.\n", tmpname);
606
610
                        inflateEnd(&strm);
607
611
                        rc = CL_EWRITE;
608
612
                        goto exit_tmpfile;
616
620
                    }
617
621
                } while (strm.avail_out == 0);
618
622
 
 
623
                if (rc != CL_SUCCESS)
 
624
                    break;
 
625
 
619
626
                avail_in -= strm.avail_in;
620
627
                xar_hash_update(a_hash_ctx, next_in, avail_in, a_hash);
621
628
            }
622
 
            
 
629
 
623
630
            inflateEnd(&strm);
624
631
            break;
625
632
        case CL_TYPE_7Z:
631
638
                unsigned long in_remaining = length;
632
639
                unsigned long out_size = 0;
633
640
                unsigned char * buff = __lzma_wrap_alloc(NULL, CLI_LZMA_OBUF_SIZE);
 
641
                int lret;
634
642
                
635
643
                memset(&lz, 0, sizeof(lz));
636
644
                if (buff == NULL) {
637
 
                    cli_errmsg("cli_scanxar: memory request for lzma decompression buffer fails.\n");
 
645
                    cli_dbgmsg("cli_scanxar: memory request for lzma decompression buffer fails.\n");
638
646
                    rc = CL_EMEM;
639
647
                    goto exit_tmpfile;
640
648
                    
644
652
                if (blockp == NULL) {
645
653
                    char errbuff[128];
646
654
                    cli_strerror(errno, errbuff, sizeof(errbuff));
647
 
                    cli_errmsg("cli_scanxar: Can't read %li bytes @ %li, errno:%s.\n",
 
655
                    cli_dbgmsg("cli_scanxar: Can't read %li bytes @ %li, errno:%s.\n",
648
656
                               length, at, errbuff);
649
657
                    rc = CL_EREAD;
650
658
                    __lzma_wrap_free(NULL, buff);
656
664
 
657
665
                xar_hash_update(a_hash_ctx, blockp, CLI_LZMA_HDR_SIZE, a_hash);
658
666
 
659
 
                rc = cli_LzmaInit(&lz, 0);
660
 
                if (rc != LZMA_RESULT_OK) {
661
 
                    cli_errmsg("cli_scanxar: cli_LzmaInit() fails: %i.\n", rc);
 
667
                lret = cli_LzmaInit(&lz, 0);
 
668
                if (lret != LZMA_RESULT_OK) {
 
669
                    cli_dbgmsg("cli_scanxar: cli_LzmaInit() fails: %i.\n", lret);
662
670
                    rc = CL_EFORMAT;
663
671
                    __lzma_wrap_free(NULL, buff);
664
 
                    goto exit_tmpfile;
 
672
                    extract_errors++;
 
673
                    break;
665
674
                }
666
 
                
 
675
 
667
676
                at += CLI_LZMA_HDR_SIZE;
668
677
                in_remaining -= CLI_LZMA_HDR_SIZE;
669
678
                while (at < map->len && at < offset+hdr.toc_length_compressed+hdr.size+length) {
679
688
                    if (lz.next_in == NULL) {
680
689
                        char errbuff[128];
681
690
                        cli_strerror(errno, errbuff, sizeof(errbuff));
682
 
                        cli_errmsg("cli_scanxar: Can't read %li bytes @ %li, errno: %s.\n",
 
691
                        cli_dbgmsg("cli_scanxar: Can't read %li bytes @ %li, errno: %s.\n",
683
692
                                   length, at, errbuff);
684
693
                        rc = CL_EREAD;
685
694
                        __lzma_wrap_free(NULL, buff);
687
696
                        goto exit_tmpfile;
688
697
                    }
689
698
 
690
 
                    rc = cli_LzmaDecode(&lz);
691
 
                    if (rc != LZMA_RESULT_OK && rc != LZMA_STREAM_END) {
692
 
                        cli_errmsg("cli_scanxar: cli_LzmaDecode() fails: %i.\n", rc);
 
699
                    lret = cli_LzmaDecode(&lz);
 
700
                    if (lret != LZMA_RESULT_OK && lret != LZMA_STREAM_END) {
 
701
                        cli_dbgmsg("cli_scanxar: cli_LzmaDecode() fails: %i.\n", lret);
693
702
                        rc = CL_EFORMAT;
694
 
                        __lzma_wrap_free(NULL, buff);
695
 
                        cli_LzmaShutdown(&lz);
696
 
                        goto exit_tmpfile;
 
703
                        extract_errors++;
 
704
                        break;
697
705
                    }
698
706
 
699
707
                    in_consumed = avail_in - lz.avail_in;
712
720
                    /* cli_dbgmsg("Writing %li bytes to LZMA decompress temp file, " */
713
721
                    /*            "consumed %li of %li available compressed bytes.\n", */
714
722
                    /*            avail_out, in_consumed, avail_in); */
715
 
                    
 
723
 
716
724
                    if (cli_writen(fd, buff, avail_out) < 0) {
717
725
                        cli_dbgmsg("cli_scanxar: cli_writen error writing lzma temp file for %li bytes.\n",
718
726
                                   avail_out);
721
729
                        rc = CL_EWRITE;
722
730
                        goto exit_tmpfile;
723
731
                    }
724
 
                    
 
732
 
725
733
                    /* Check file size limitation. */
726
734
                    out_size += avail_out;
727
735
                    if (cli_checklimits("cli_scanxar", ctx, out_size, 0, 0) != CL_CLEAN) {
728
736
                        break;
729
737
                    }
730
 
                    
731
 
                    if (rc == LZMA_STREAM_END)
 
738
 
 
739
                    if (lret == LZMA_STREAM_END)
732
740
                        break;
733
741
                }
734
742
 
735
 
                
736
743
                cli_LzmaShutdown(&lz);
737
744
                __lzma_wrap_free(NULL, buff);
738
745
            }
754
761
                if (!(blockp = (void*)fmap_need_off_once(map, at, length))) {
755
762
                    char errbuff[128];
756
763
                    cli_strerror(errno, errbuff, sizeof(errbuff));
757
 
                    cli_errmsg("cli_scanxar: Can't read %li bytes @ %li, errno:%s.\n",
 
764
                    cli_dbgmsg("cli_scanxar: Can't read %li bytes @ %li, errno:%s.\n",
758
765
                               length, at, errbuff);
759
766
                    rc = CL_EREAD;
760
767
                    goto exit_tmpfile;
771
778
            }          
772
779
        }
773
780
 
774
 
        xar_hash_final(a_hash_ctx, result, a_hash);
 
781
        if (rc == CL_SUCCESS) {
 
782
            xar_hash_final(a_hash_ctx, result, a_hash);
 
783
            if (a_cksum != NULL) {
 
784
                expected = cli_hex2str((char *)a_cksum);
 
785
                if (xar_hash_check(a_hash, result, expected) != 0) {
 
786
                    cli_dbgmsg("cli_scanxar: archived-checksum missing or mismatch.\n");
 
787
                    cksum_fails++;
 
788
                } else {
 
789
                    cli_dbgmsg("cli_scanxar: archived-checksum matched.\n");                
 
790
                }
 
791
                free(expected);
 
792
            }
 
793
            if (e_cksum != NULL) {
 
794
                if (do_extract_cksum) {
 
795
                    xar_hash_final(e_hash_ctx, result, e_hash);
 
796
                    expected = cli_hex2str((char *)e_cksum);
 
797
                    if (xar_hash_check(e_hash, result, expected) != 0) {
 
798
                        cli_dbgmsg("cli_scanxar: extracted-checksum missing or mismatch.\n");
 
799
                        cksum_fails++;
 
800
                    } else {
 
801
                        cli_dbgmsg("cli_scanxar: extracted-checksum matched.\n");                
 
802
                    }
 
803
                    free(expected);
 
804
                }
 
805
            }
 
806
        
 
807
            rc = cli_magic_scandesc(fd, ctx);
 
808
            if (rc != CL_SUCCESS) {
 
809
                if (rc == CL_VIRUS) {
 
810
                    cli_dbgmsg("cli_scanxar: Infected with %s\n", cli_get_last_virus(ctx));
 
811
                    if (!SCAN_ALL)
 
812
                        goto exit_tmpfile;
 
813
                } else if (rc != CL_BREAK) {
 
814
                    cli_dbgmsg("cli_scanxar: cli_magic_scandesc error %i\n", rc);
 
815
                    goto exit_tmpfile;
 
816
                }
 
817
            }
 
818
        }
 
819
        
775
820
        if (a_cksum != NULL) {
776
 
            expected = cli_hex2str((char *)a_cksum);
777
 
            if (xar_hash_check(a_hash, result, expected) != 0) {
778
 
                cli_dbgmsg("cli_scanxar: archived-checksum missing or mismatch.\n");
779
 
                cksum_fails++;
780
 
            } else {
781
 
                cli_dbgmsg("cli_scanxar: archived-checksum matched.\n");                
782
 
            }
783
 
            free(expected);
784
821
            xmlFree(a_cksum);
785
822
            a_cksum = NULL;
786
823
        }
787
824
        if (e_cksum != NULL) {
788
 
            if (do_extract_cksum) {
789
 
                xar_hash_final(e_hash_ctx, result, e_hash);
790
 
                expected = cli_hex2str((char *)e_cksum);
791
 
                if (xar_hash_check(e_hash, result, expected) != 0) {
792
 
                    cli_dbgmsg("cli_scanxar: extracted-checksum missing or mismatch.\n");
793
 
                    cksum_fails++;
794
 
                } else {
795
 
                    cli_dbgmsg("cli_scanxar: extracted-checksum matched.\n");                
796
 
                }
797
 
                free(expected);
798
 
            }
799
825
            xmlFree(e_cksum);
800
826
            e_cksum = NULL;
801
827
        }
802
 
        
803
 
        rc = cli_magic_scandesc(fd, ctx);
804
 
        if (rc != CL_SUCCESS) {
805
 
            if (rc == CL_VIRUS) {
806
 
                cli_dbgmsg("cli_scanxar: Infected with %s\n", cli_get_last_virus(ctx));
807
 
                if (!SCAN_ALL)
808
 
                    goto exit_tmpfile;
809
 
            } else if (rc != CL_BREAK) {
810
 
                cli_errmsg("cli_scanxar: cli_magic_scandesc error %i\n", rc);
811
 
                goto exit_tmpfile;
812
 
            }
813
 
        }
814
 
   }
 
828
    }
815
829
 
816
830
 exit_tmpfile:
817
831
    xar_cleanup_temp_file(ctx, fd, tmpname);
 
832
 
 
833
 exit_reader:
818
834
    if (a_cksum != NULL)
819
835
        xmlFree(a_cksum);   
820
836
    if (e_cksum != NULL)
821
837
        xmlFree(e_cksum);
822
 
 
823
 
 exit_reader:
824
838
    xmlTextReaderClose(reader);
825
839
    xmlFreeTextReader(reader);
826
840
 
831
845
#else
832
846
    cli_dbgmsg("cli_scanxar: can't scan xar files, need libxml2.\n");
833
847
#endif
834
 
    if (cksum_fails != 0)
835
 
        cli_warnmsg("cli_scanxar: %u checksums missing, mismatched, or unsupported - use --debug for more info.\n", cksum_fails);
 
848
    if (cksum_fails + extract_errors != 0) {
 
849
        cli_warnmsg("cli_scanxar: %u checksum errors and %u extraction errors, use --debug for more info.\n",
 
850
                    cksum_fails, extract_errors);
 
851
    }
836
852
 
837
853
    return rc;
838
854
}