634
submitstats (const char *clamdcfg, const struct optstruct *opts)
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;
645
const char *tokens[5];
648
if ((opt = optget (opts, "DetectionStatsCountry"))->enabled)
650
if (strlen (opt->strarg) != 2 || !isalpha (opt->strarg[0])
651
|| !isalpha (opt->strarg[1]))
653
logg ("!SubmitDetectionStats: DetectionStatsCountry requires a two-letter country code\n");
656
country = opt->strarg;
659
if ((opt = optget (opts, "DetectionStatsHostID"))->enabled)
661
if (strlen (opt->strarg) != 32)
663
logg ("!SubmitDetectionStats: The unique ID must be 32 characters long\n");
666
hostid = opt->strarg;
669
if ((opt = optget (opts, "HTTPUserAgent"))->enabled)
670
strncpy (uastr, opt->strarg, sizeof (uastr));
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;
679
if ((opt = optget (opts, "HTTPProxyServer"))->enabled)
682
if (!strncasecmp (proxy, "http://", 7))
685
if ((opt = optget (opts, "HTTPProxyUsername"))->enabled)
688
if (!(opt = optget (opts, "HTTPProxyPassword"))->enabled)
690
logg ("!SubmitDetectionStats: HTTPProxyUsername requires HTTPProxyPassword\n");
693
auth = proxyauth (user, opt->strarg);
698
if ((opt = optget (opts, "HTTPProxyPort"))->enabled)
701
logg ("*Connecting via %s\n", proxy);
704
if ((clamsockd = clamd_connect (clamdcfg, "SubmitDetectionStats")) < 0){
708
return FCE_CONNECTION;
711
recvlninit (&rcv, clamsockd);
712
if (sendln (clamsockd, "zDETSTATS", 10))
717
closesocket (clamsockd);
718
return FCE_CONNECTION;
722
memset (query, 0, sizeof (query));
725
while (recvln (&rcv, &line, NULL) > 0)
727
if (cli_strtokenize (line, ':', 5, tokens) != 5)
729
logg ("!SubmitDetectionStats: Invalid data format\n");
730
ret = FCE_CONNECTION;
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]);
740
if (entries == SUBMIT_MIN_ENTRIES)
742
sd = wwwconnect ("stats.clamav.net", proxy, port, NULL,
743
optget (opts, "LocalIPAddress")->strarg,
744
optget (opts, "ConnectTimeout")->numarg, NULL, 0,
748
logg ("!SubmitDetectionStats: Can't connect to server\n");
749
ret = FCE_CONNECTION;
752
query[sizeof (query) - 1] = 0;
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"
758
"Connection: Close\r\n"
759
"Content-Length: %u\r\n\r\n"
761
auth ? auth : "", hostid ? "X-HostID: " : "",
762
hostid ? hostid : "", hostid ? "\r\n" : "", uastr,
763
(unsigned int) strlen (query), query) < 0)
765
logg ("!SubmitDetectionStats: Can't write to socket\n");
766
ret = FCE_CONNECTION;
772
cnt = sizeof (post) - 1;
775
wait_recv (sd, pt, cnt, 0,
776
optget (opts, "ReceiveTimeout")->numarg)) > 0)
779
while ((bread = recv (sd, pt, cnt, 0)) > 0)
792
logg ("!SubmitDetectionStats: Can't read from socket\n");
793
ret = FCE_CONNECTION;
797
if (strstr (post, "SUBMIT_OK"))
799
submitted += entries;
800
if (submitted + SUBMIT_MIN_ENTRIES > SUBMIT_MAX_ENTRIES)
804
memset (query, 0, sizeof (query));
808
ret = FCE_CONNECTION;
809
if ((pt = strstr (post, "SUBMIT_PERMANENT_FAILURE")))
814
if ((pt + 32 <= post + sizeof (post)) && pt[24] == ':')
815
logg ("!SubmitDetectionStats: Remote server reported permanent failure: %s\n", &pt[25]);
817
logg ("!SubmitDetectionStats: Remote server reported permanent failure\n");
820
else if ((pt = strstr (post, "SUBMIT_TEMPORARY_FAILURE")))
824
if ((pt + 32 <= post + sizeof (post)) && pt[24] == ':')
825
logg ("!SubmitDetectionStats: Remote server reported temporary failure: %s\n", &pt[25]);
827
logg ("!SubmitDetectionStats: Remote server reported temporary failure\n");
833
logg ("!SubmitDetectionStats: Incorrect answer from server\n");
839
closesocket (clamsockd);
847
logg ("SubmitDetectionStats: Not enough recent data for submission\n");
851
logg ("SubmitDetectionStats: Submitted %u records\n", submitted);
853
clamd_connect (clamdcfg, "SubmitDetectionStats")) != -1)
855
sendln (clamsockd, "DETSTATSCLEAR", 14);
856
recv (clamsockd, query, sizeof (query), 0);
857
closesocket (clamsockd);
865
submitstats (const char *clamdcfg, const struct optstruct *opts)
867
logg ("clamd not built, no statistics");
868
return FCE_CONNECTION;
873
636
Rfc2822DateTime (char *buf, time_t mtime)