~yolanda.robla/ubuntu/saucy/clamav/dep-8-tests

« back to all changes in this revision

Viewing changes to clamdscan/proto.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Tautschnig, Michael Tautschnig
  • Date: 2009-11-02 10:24:35 UTC
  • mfrom: (0.39.5 squeeze)
  • mto: (122.1.1 raring-security)
  • mto: This revision was merged to the branch mainline in revision 73.
  • Revision ID: james.westby@ubuntu.com-20091102102435-yzkn3jdvo4gank3q
Tags: 0.95.3+dfsg-1
[ Michael Tautschnig ]
* New upstream version
* Should fix clamd segfault on startup (closes: #537629)
* Updated info in clamd.conf man page (closes: #534443)
* Proper socket ownership setup, no chgrp in make_dir (closes: #553333)

Show diffs side-by-side

added added

removed removed

Lines of Context:
166
166
        }
167
167
    } else fd = 0;
168
168
 
169
 
    if(sendln(sockd, "zINSTREAM", 10)) return -1;
 
169
    if(sendln(sockd, "zINSTREAM", 10)) {
 
170
        close(fd);
 
171
        return -1;
 
172
    }
170
173
 
171
174
    while((len = read(fd, &buf[1], sizeof(buf) - sizeof(uint32_t))) > 0) {
172
175
        if((unsigned int)len > todo) len = todo;
238
241
/* Sends a proper scan request to clamd and parses its replies
239
242
 * This is used only in non IDSESSION mode
240
243
 * Returns the number of infected files or -1 on error */
241
 
int dsresult(int sockd, int scantype, const char *filename, int *printok) {
 
244
int dsresult(int sockd, int scantype, const char *filename, int *printok, int *files, int *errors) {
242
245
    int infected = 0, len, beenthere = 0;
243
246
    char *bol, *eol;
244
247
    struct RCVLN rcv;
 
248
    struct stat sb;
245
249
 
246
250
    recvlninit(&rcv, sockd);
247
251
 
270
274
 
271
275
    if(len <=0) {
272
276
        *printok = 0;
 
277
        if(errors)
 
278
            (*errors)++;
273
279
        return len;
274
280
    }
275
281
 
276
282
    while((len = recvln(&rcv, &bol, &eol))) {
277
283
        if(len == -1) return -1;
278
284
        beenthere = 1;
 
285
        if(files)
 
286
            (*files)++;
279
287
        if(!filename) logg("~%s\n", bol);
280
288
        if(len > 7) {
281
289
            char *colon = strrchr(bol, ':');
297
305
                    }
298
306
                }
299
307
            } else if(!memcmp(eol-7, " ERROR", 6)) {
 
308
                if(errors)
 
309
                    (*errors)++;
300
310
                *printok = 0;
301
311
                if(filename) {
302
312
                    if(scantype >= STREAM)
308
318
        }
309
319
    }
310
320
    if(!beenthere) {
311
 
        logg("~%s: no reply from clamd\n", filename ? filename : "STDIN");
312
 
        return -1;
 
321
        stat(filename, &sb);
 
322
        if(!S_ISDIR(sb.st_mode)) {
 
323
            logg("~%s: no reply from clamd\n", filename ? filename : "STDIN");
 
324
            return -1;
 
325
        }
313
326
    }
314
327
    return infected;
315
328
}
321
334
    int infected;
322
335
    int scantype;
323
336
    int printok;
 
337
    int files;
 
338
    int errors;
324
339
};
325
340
 
326
341
/* FTW callback for scanning in non IDSESSION mode
332
347
 
333
348
    switch(reason) {
334
349
    case error_stat:
335
 
        logg("^Can't access file %s\n", path);
 
350
        logg("!Can't access file %s\n", path);
 
351
        c->errors++;
336
352
        return CL_SUCCESS;
337
353
    case error_mem:
338
 
        logg("^Memory allocation failed in ftw\n");
 
354
        logg("!Memory allocation failed in ftw\n");
 
355
        c->errors++;
339
356
        return CL_EMEM;
340
357
    case warning_skipped_dir:
341
358
        logg("^Directory recursion limit reached\n");
342
359
    case warning_skipped_link:
343
360
        return CL_SUCCESS;
344
361
    case warning_skipped_special:
345
 
        logg("~%s: Not supported file type. ERROR\n", path);
 
362
        logg("!%s: Not supported file type\n", path);
 
363
        c->errors++;
346
364
        return CL_SUCCESS;
347
365
    case visit_directory_toplev:
348
366
        if(c->scantype >= STREAM)
357
375
        if(filename) free(filename);
358
376
        return CL_EOPEN;
359
377
    }
360
 
    ret = dsresult(sockd, c->scantype, f, &c->printok);
 
378
    ret = dsresult(sockd, c->scantype, f, &c->printok, &c->files, &c->errors);
361
379
    if(filename) free(filename);
362
380
    close(sockd);
363
381
    if(ret < 0) return CL_EOPEN;
375
393
    int ftw;
376
394
 
377
395
    cdata.infected = 0;
 
396
    cdata.files = 0;
 
397
    cdata.errors = 0;
378
398
    cdata.printok = printinfected^1;
379
399
    cdata.scantype = scantype;
380
400
    data.data = &cdata;
381
401
 
382
 
    ftw = cli_ftw(file, flags, maxlevel ? maxlevel : INT_MAX, serial_callback, &data);
 
402
    ftw = cli_ftw(file, flags, maxlevel ? maxlevel : INT_MAX, serial_callback, &data, NULL);
383
403
    *infected += cdata.infected;
384
404
 
385
 
    if(ftw == CL_SUCCESS || ftw == CL_BREAK) {
 
405
    if((cdata.errors < cdata.files) && (ftw == CL_SUCCESS || ftw == CL_BREAK)) {
386
406
        if(cdata.printok)
387
407
            logg("~%s: OK\n", file);
388
408
        return 0;
 
409
    } else if(!cdata.files) {
 
410
        logg("~%s: No files scanned\n", file);
389
411
    }
390
412
    return 1;
391
413
}
393
415
/* Used in IDSESSION mode */
394
416
struct client_parallel_data {
395
417
    int infected;
 
418
    int files;
 
419
    int errors;
396
420
    int scantype;
397
421
    int sockd;
398
422
    int lastid;
406
430
 
407
431
/* Sends a proper scan request to clamd and parses its replies
408
432
 * This is used only in IDSESSION mode
409
 
 * Returns 0 on success, 1 on hard failures */
 
433
 * Returns 0 on success, 1 on hard failures, 2 on len == 0 (bb#1717) */
410
434
static int dspresult(struct client_parallel_data *c) {
411
435
    const char *filename;
412
436
    char *bol, *eol;
419
443
    do {
420
444
        len = recvln(&rcv, &bol, &eol);
421
445
        if(len < 0) return 1;
422
 
        if(!len) return 0;
 
446
        if(!len) return 2;
423
447
        if((rid = atoi(bol))) {
424
448
            id = &c->ids;
425
449
            while(*id) {
445
469
                logg("~%s%s\n", filename, colon);
446
470
                if(action) action(filename);
447
471
            } else if(!memcmp(eol-7, " ERROR", 6)) {
 
472
                c->errors++;
448
473
                c->printok = 0;
449
474
                logg("~%s%s\n", filename, colon);
450
475
            }
467
492
 
468
493
    switch(reason) {
469
494
    case error_stat:
470
 
        logg("^Can't access file %s\n", path);
 
495
        logg("!Can't access file %s\n", path);
 
496
        c->errors++;
471
497
        return CL_SUCCESS;
472
498
    case error_mem:
473
 
        logg("^Memory allocation failed in ftw\n");
 
499
        logg("!Memory allocation failed in ftw\n");
 
500
        c->errors++;
474
501
        return CL_EMEM;
475
502
    case warning_skipped_dir:
476
503
        logg("^Directory recursion limit reached\n");
477
504
        return CL_SUCCESS;
478
505
    case warning_skipped_special:
479
 
        logg("~%s: Not supported file type. ERROR\n", path);
 
506
        logg("!%s: Not supported file type\n", path);
 
507
        c->errors++;
480
508
    case warning_skipped_link:
481
509
    case visit_directory_toplev:
482
510
        return CL_SUCCESS;
518
546
    cid->file = filename;
519
547
    cid->next = c->ids;
520
548
    c->ids = cid;
 
549
    c->files++;
521
550
 
522
551
    switch(c->scantype) {
523
552
#ifdef HAVE_FD_PASSING
531
560
    }
532
561
    if(res <= 0) {
533
562
        c->printok = 0;
 
563
        c->errors++;
534
564
        c->ids = cid->next;
535
565
        c->lastid--;
536
566
        free(cid);
556
586
    }
557
587
 
558
588
    cdata.infected = 0;
 
589
    cdata.files = 0;
 
590
    cdata.errors = 0;
559
591
    cdata.scantype = scantype;
560
592
    cdata.lastid = 0;
561
593
    cdata.ids = NULL;
562
594
    cdata.printok = printinfected^1;
563
595
    data.data = &cdata;
564
596
 
565
 
    ftw = cli_ftw(file, flags, maxlevel ? maxlevel : INT_MAX, parallel_callback, &data);
 
597
    ftw = cli_ftw(file, flags, maxlevel ? maxlevel : INT_MAX, parallel_callback, &data, NULL);
566
598
 
567
599
    if(ftw != CL_SUCCESS) {
568
600
        *infected += cdata.infected;
580
612
        logg("!Clamd closed the connection before scanning all files.\n");
581
613
        return 1;
582
614
    }
 
615
    if(cdata.errors == cdata.files)
 
616
        return 1;
583
617
    if(cdata.printok)
584
618
        logg("~%s: OK\n", file);
585
619
    return 0;