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

« back to all changes in this revision

Viewing changes to freshclam/manager.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:
30
30
 * fails on Solaris because it would require a c99 compiler,
31
31
 * 500 fails completely on Solaris, and FreeBSD, and w/o _XOPEN_SOURCE
32
32
 * strptime is not defined on Linux */
33
 
#define _GNU_SOURCE
34
33
#define __EXTENSIONS
35
34
 
36
35
#include <stdio.h>
61
60
#include <errno.h>
62
61
#include <zlib.h>
63
62
 
 
63
#include <openssl/ssl.h>
 
64
#include <openssl/err.h>
 
65
#include "libclamav/crypto.h"
 
66
 
64
67
#include "target.h"
65
68
 
66
69
#include "freshclamcodes.h"
629
632
    return auth;
630
633
}
631
634
 
632
 
#if BUILD_CLAMD
633
 
int
634
 
submitstats (const char *clamdcfg, const struct optstruct *opts)
635
 
{
636
 
    int sd, clamsockd, bread, cnt, ret;
637
 
    char post[SUBMIT_MIN_ENTRIES * 256 + 512];
638
 
    char query[SUBMIT_MIN_ENTRIES * 256];
639
 
    char uastr[128], *line;
640
 
    char *pt, *auth = NULL;
641
 
    const char *country = NULL, *user, *proxy = NULL, *hostid = NULL;
642
 
    const struct optstruct *opt;
643
 
    unsigned int qcnt, entries, submitted = 0, permfail = 0, port = 0;
644
 
    struct RCVLN rcv;
645
 
    const char *tokens[5];
646
 
 
647
 
 
648
 
    if ((opt = optget (opts, "DetectionStatsCountry"))->enabled)
649
 
    {
650
 
        if (strlen (opt->strarg) != 2 || !isalpha (opt->strarg[0])
651
 
            || !isalpha (opt->strarg[1]))
652
 
        {
653
 
            logg ("!SubmitDetectionStats: DetectionStatsCountry requires a two-letter country code\n");
654
 
            return FCE_CONFIG;
655
 
        }
656
 
        country = opt->strarg;
657
 
    }
658
 
 
659
 
    if ((opt = optget (opts, "DetectionStatsHostID"))->enabled)
660
 
    {
661
 
        if (strlen (opt->strarg) != 32)
662
 
        {
663
 
            logg ("!SubmitDetectionStats: The unique ID must be 32 characters long\n");
664
 
            return FCE_CONFIG;
665
 
        }
666
 
        hostid = opt->strarg;
667
 
    }
668
 
 
669
 
    if ((opt = optget (opts, "HTTPUserAgent"))->enabled)
670
 
        strncpy (uastr, opt->strarg, sizeof (uastr));
671
 
    else
672
 
        snprintf (uastr, sizeof (uastr),
673
 
                  PACKAGE "/%s (OS: " TARGET_OS_TYPE ", ARCH: "
674
 
                  TARGET_ARCH_TYPE ", CPU: " TARGET_CPU_TYPE "):%s:%s",
675
 
                  get_version (), country ? country : "",
676
 
                  hostid ? hostid : "");
677
 
    uastr[sizeof (uastr) - 1] = 0;
678
 
 
679
 
    if ((opt = optget (opts, "HTTPProxyServer"))->enabled)
680
 
    {
681
 
        proxy = opt->strarg;
682
 
        if (!strncasecmp (proxy, "http://", 7))
683
 
            proxy += 7;
684
 
 
685
 
        if ((opt = optget (opts, "HTTPProxyUsername"))->enabled)
686
 
        {
687
 
            user = opt->strarg;
688
 
            if (!(opt = optget (opts, "HTTPProxyPassword"))->enabled)
689
 
            {
690
 
                logg ("!SubmitDetectionStats: HTTPProxyUsername requires HTTPProxyPassword\n");
691
 
                return FCE_CONFIG;
692
 
            }
693
 
            auth = proxyauth (user, opt->strarg);
694
 
            if (!auth)
695
 
                return FCE_CONFIG;
696
 
        }
697
 
 
698
 
        if ((opt = optget (opts, "HTTPProxyPort"))->enabled)
699
 
            port = opt->numarg;
700
 
 
701
 
        logg ("*Connecting via %s\n", proxy);
702
 
    }
703
 
 
704
 
    if ((clamsockd = clamd_connect (clamdcfg, "SubmitDetectionStats")) < 0){
705
 
        if(auth){
706
 
            free(auth);
707
 
        }    
708
 
        return FCE_CONNECTION;
709
 
    }   
710
 
 
711
 
    recvlninit (&rcv, clamsockd);
712
 
    if (sendln (clamsockd, "zDETSTATS", 10))
713
 
    {
714
 
        if(auth){
715
 
            free(auth);
716
 
        }    
717
 
        closesocket (clamsockd);
718
 
        return FCE_CONNECTION;
719
 
    }
720
 
 
721
 
    ret = 0;
722
 
    memset (query, 0, sizeof (query));
723
 
    qcnt = 0;
724
 
    entries = 0;
725
 
    while (recvln (&rcv, &line, NULL) > 0)
726
 
    {
727
 
        if (cli_strtokenize (line, ':', 5, tokens) != 5)
728
 
        {
729
 
            logg ("!SubmitDetectionStats: Invalid data format\n");
730
 
            ret = FCE_CONNECTION;
731
 
            break;
732
 
        }
733
 
 
734
 
        qcnt +=
735
 
            snprintf (&query[qcnt], sizeof (query) - qcnt,
736
 
                      "ts[]=%s&fname[]=%s&virus[]=%s(%s:%s)&", tokens[0],
737
 
                      tokens[4], tokens[3], tokens[1], tokens[2]);
738
 
        entries++;
739
 
 
740
 
        if (entries == SUBMIT_MIN_ENTRIES)
741
 
        {
742
 
            sd = wwwconnect ("stats.clamav.net", proxy, port, NULL,
743
 
                             optget (opts, "LocalIPAddress")->strarg,
744
 
                             optget (opts, "ConnectTimeout")->numarg, NULL, 0,
745
 
                             0, 1);
746
 
            if (sd < 0)
747
 
            {
748
 
                logg ("!SubmitDetectionStats: Can't connect to server\n");
749
 
                ret = FCE_CONNECTION;
750
 
                break;
751
 
            }
752
 
            query[sizeof (query) - 1] = 0;
753
 
            if (mdprintf (sd,
754
 
                          "POST http://stats.clamav.net/submit.php HTTP/1.0\r\n"
755
 
                          "Host: stats.clamav.net\r\n%s%s%s%s"
756
 
                          "Content-Type: application/x-www-form-urlencoded\r\n"
757
 
                          "User-Agent: %s\r\n"
758
 
                          "Connection: Close\r\n"
759
 
                          "Content-Length: %u\r\n\r\n"
760
 
                          "%s",
761
 
                          auth ? auth : "", hostid ? "X-HostID: " : "",
762
 
                          hostid ? hostid : "", hostid ? "\r\n" : "", uastr,
763
 
                          (unsigned int) strlen (query), query) < 0)
764
 
            {
765
 
                logg ("!SubmitDetectionStats: Can't write to socket\n");
766
 
                ret = FCE_CONNECTION;
767
 
                closesocket (sd);
768
 
                break;
769
 
            }
770
 
 
771
 
            pt = post;
772
 
            cnt = sizeof (post) - 1;
773
 
#ifdef SO_ERROR
774
 
            while ((bread =
775
 
                    wait_recv (sd, pt, cnt, 0,
776
 
                               optget (opts, "ReceiveTimeout")->numarg)) > 0)
777
 
            {
778
 
#else
779
 
            while ((bread = recv (sd, pt, cnt, 0)) > 0)
780
 
            {
781
 
#endif
782
 
                pt += bread;
783
 
                cnt -= bread;
784
 
                if (cnt <= 0)
785
 
                    break;
786
 
            }
787
 
            *pt = 0;
788
 
            closesocket (sd);
789
 
 
790
 
            if (bread < 0)
791
 
            {
792
 
                logg ("!SubmitDetectionStats: Can't read from socket\n");
793
 
                ret = FCE_CONNECTION;
794
 
                break;
795
 
            }
796
 
 
797
 
            if (strstr (post, "SUBMIT_OK"))
798
 
            {
799
 
                submitted += entries;
800
 
                if (submitted + SUBMIT_MIN_ENTRIES > SUBMIT_MAX_ENTRIES)
801
 
                    break;
802
 
                qcnt = 0;
803
 
                entries = 0;
804
 
                memset (query, 0, sizeof (query));
805
 
                continue;
806
 
            }
807
 
 
808
 
            ret = FCE_CONNECTION;
809
 
            if ((pt = strstr (post, "SUBMIT_PERMANENT_FAILURE")))
810
 
            {
811
 
                if (!submitted)
812
 
                {
813
 
                    permfail = 1;
814
 
                    if ((pt + 32 <= post + sizeof (post)) && pt[24] == ':')
815
 
                        logg ("!SubmitDetectionStats: Remote server reported permanent failure: %s\n", &pt[25]);
816
 
                    else
817
 
                        logg ("!SubmitDetectionStats: Remote server reported permanent failure\n");
818
 
                }
819
 
            }
820
 
            else if ((pt = strstr (post, "SUBMIT_TEMPORARY_FAILURE")))
821
 
            {
822
 
                if (!submitted)
823
 
                {
824
 
                    if ((pt + 32 <= post + sizeof (post)) && pt[24] == ':')
825
 
                        logg ("!SubmitDetectionStats: Remote server reported temporary failure: %s\n", &pt[25]);
826
 
                    else
827
 
                        logg ("!SubmitDetectionStats: Remote server reported temporary failure\n");
828
 
                }
829
 
            }
830
 
            else
831
 
            {
832
 
                if (!submitted)
833
 
                    logg ("!SubmitDetectionStats: Incorrect answer from server\n");
834
 
            }
835
 
 
836
 
            break;
837
 
        }
838
 
    }
839
 
    closesocket (clamsockd);
840
 
    if (auth)
841
 
        free (auth);
842
 
 
843
 
    if (ret == 0)
844
 
    {
845
 
        if (!submitted)
846
 
        {
847
 
            logg ("SubmitDetectionStats: Not enough recent data for submission\n");
848
 
        }
849
 
        else
850
 
        {
851
 
            logg ("SubmitDetectionStats: Submitted %u records\n", submitted);
852
 
            if ((clamsockd =
853
 
                 clamd_connect (clamdcfg, "SubmitDetectionStats")) != -1)
854
 
            {
855
 
                sendln (clamsockd, "DETSTATSCLEAR", 14);
856
 
                recv (clamsockd, query, sizeof (query), 0);
857
 
                closesocket (clamsockd);
858
 
            }
859
 
        }
860
 
    }
861
 
    return ret;
862
 
}
863
 
#else
864
 
int
865
 
submitstats (const char *clamdcfg, const struct optstruct *opts)
866
 
{
867
 
    logg ("clamd not built, no statistics");
868
 
    return FCE_CONNECTION;
869
 
}
870
 
#endif
871
 
 
872
635
static int
873
636
Rfc2822DateTime (char *buf, time_t mtime)
874
637
{
1784
1547
    {
1785
1548
        return FCE_TESTFAIL;
1786
1549
    }
 
1550
    cl_engine_set_clcb_stats_submit(engine, NULL);
1787
1551
 
1788
1552
    if ((ret =
1789
1553
         cl_load (newfile, engine, &newsigs,