git-svn-id: file:///var/lib/svn/clamav-devel/branches/clamav-0.94@4456 77e5149b-7576-45b1-b177-96237e5ba77b
Tomasz Kojm authored on 2008/11/22 07:39:38... | ... |
@@ -1,3 +1,8 @@ |
1 |
+Fri Nov 21 23:40:19 CET 2008 (tk) |
|
2 |
+--------------------------------- |
|
3 |
+ * freshclam/manager.c: add support for http proxy in SubmitDetectionStats |
|
4 |
+ (bb#1284) |
|
5 |
+ |
|
1 | 6 |
Thu Nov 20 21:53:39 EET 2008 (edwin) |
2 | 7 |
------------------------------------ |
3 | 8 |
* configure, m4/lib-link.m4: more multiarch dir fixes (bb #1277) |
... | ... |
@@ -462,10 +462,78 @@ static const char *readbline(int fd, char *buf, int bufsize, int filesize, int * |
462 | 462 |
} |
463 | 463 |
} |
464 | 464 |
|
465 |
+static unsigned int fmt_base64(char *dest, const char *src, unsigned int len) |
|
466 |
+{ |
|
467 |
+ unsigned short bits = 0,temp = 0; |
|
468 |
+ unsigned long written = 0; |
|
469 |
+ unsigned int i; |
|
470 |
+ const char base64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; |
|
471 |
+ |
|
472 |
+ |
|
473 |
+ for(i = 0; i < len; i++) { |
|
474 |
+ temp <<= 8; |
|
475 |
+ temp += src[i]; |
|
476 |
+ bits += 8; |
|
477 |
+ while(bits > 6) { |
|
478 |
+ dest[written] = base64[((temp >> (bits - 6)) & 63)]; |
|
479 |
+ written++; |
|
480 |
+ bits -= 6; |
|
481 |
+ } |
|
482 |
+ } |
|
483 |
+ |
|
484 |
+ if(bits) { |
|
485 |
+ temp <<= (6 - bits); |
|
486 |
+ dest[written] = base64[temp & 63]; |
|
487 |
+ written++; |
|
488 |
+ } |
|
489 |
+ |
|
490 |
+ while(written & 3) { |
|
491 |
+ dest[written] = '='; |
|
492 |
+ written++; |
|
493 |
+ } |
|
494 |
+ |
|
495 |
+ return written; |
|
496 |
+} |
|
497 |
+ |
|
498 |
+static char *proxyauth(const char *user, const char *pass) |
|
499 |
+{ |
|
500 |
+ int len; |
|
501 |
+ char *buf, *userpass, *auth; |
|
502 |
+ |
|
503 |
+ |
|
504 |
+ userpass = malloc(strlen(user) + strlen(pass) + 2); |
|
505 |
+ if(!userpass) { |
|
506 |
+ logg("!proxyauth: Can't allocate memory for 'userpass'\n"); |
|
507 |
+ return NULL; |
|
508 |
+ } |
|
509 |
+ sprintf(userpass, "%s:%s", user, pass); |
|
510 |
+ |
|
511 |
+ buf = malloc((strlen(pass) + strlen(user)) * 2 + 4); |
|
512 |
+ if(!buf) { |
|
513 |
+ logg("!proxyauth: Can't allocate memory for 'buf'\n"); |
|
514 |
+ free(userpass); |
|
515 |
+ return NULL; |
|
516 |
+ } |
|
517 |
+ |
|
518 |
+ len = fmt_base64(buf, userpass, strlen(userpass)); |
|
519 |
+ free(userpass); |
|
520 |
+ buf[len] = '\0'; |
|
521 |
+ auth = malloc(strlen(buf) + 30); |
|
522 |
+ if(!auth) { |
|
523 |
+ free(buf); |
|
524 |
+ logg("!proxyauth: Can't allocate memory for 'authorization'\n"); |
|
525 |
+ return NULL; |
|
526 |
+ } |
|
527 |
+ |
|
528 |
+ sprintf(auth, "Proxy-Authorization: Basic %s\r\n", buf); |
|
529 |
+ free(buf); |
|
530 |
+ |
|
531 |
+ return auth; |
|
532 |
+} |
|
533 |
+ |
|
465 | 534 |
/* |
466 | 535 |
* TODO: |
467 | 536 |
* - strptime() is most likely not portable enough |
468 |
- * - proxy support |
|
469 | 537 |
*/ |
470 | 538 |
int submitstats(const char *clamdcfg, const struct cfgstruct *copt) |
471 | 539 |
{ |
... | ... |
@@ -474,14 +542,14 @@ int submitstats(const char *clamdcfg, const struct cfgstruct *copt) |
474 | 474 |
char query[SUBMIT_MIN_ENTRIES * 256]; |
475 | 475 |
char buff[512], statsdat[512], newstatsdat[512], uastr[128]; |
476 | 476 |
char logfile[256], fbuff[FILEBUFF]; |
477 |
- char *pt, *pt2; |
|
478 |
- const char *line, *country = NULL; |
|
477 |
+ char *pt, *pt2, *auth = NULL; |
|
478 |
+ const char *line, *country = NULL, *user, *proxy = NULL; |
|
479 | 479 |
struct cfgstruct *clamdopt; |
480 | 480 |
const struct cfgstruct *cpt; |
481 | 481 |
struct stat sb; |
482 | 482 |
struct tm tms; |
483 | 483 |
time_t epoch; |
484 |
- unsigned int qcnt, entries, submitted = 0, permfail = 0; |
|
484 |
+ unsigned int qcnt, entries, submitted = 0, permfail = 0, port = 0; |
|
485 | 485 |
|
486 | 486 |
|
487 | 487 |
if((cpt = cfgopt(copt, "DetectionStatsCountry"))->enabled) { |
... | ... |
@@ -558,6 +626,31 @@ int submitstats(const char *clamdcfg, const struct cfgstruct *copt) |
558 | 558 |
snprintf(uastr, sizeof(uastr), PACKAGE"/%s (OS: "TARGET_OS_TYPE", ARCH: "TARGET_ARCH_TYPE", CPU: "TARGET_CPU_TYPE")%s%s", get_version(), country ? ":" : "", country ? country : ""); |
559 | 559 |
uastr[sizeof(uastr) - 1] = 0; |
560 | 560 |
|
561 |
+ if((cpt = cfgopt(copt, "HTTPProxyServer"))->enabled) { |
|
562 |
+ proxy = cpt->strarg; |
|
563 |
+ if(!strncasecmp(proxy, "http://", 7)) |
|
564 |
+ proxy += 7; |
|
565 |
+ |
|
566 |
+ if((cpt = cfgopt(copt, "HTTPProxyUsername"))->enabled) { |
|
567 |
+ user = cpt->strarg; |
|
568 |
+ if(!(cpt = cfgopt(copt, "HTTPProxyPassword"))->enabled) { |
|
569 |
+ logg("!SubmitDetectionStats: HTTPProxyUsername requires HTTPProxyPassword\n"); |
|
570 |
+ close(fd); |
|
571 |
+ return 56; |
|
572 |
+ } |
|
573 |
+ auth = proxyauth(user, cpt->strarg); |
|
574 |
+ if(!auth) { |
|
575 |
+ close(fd); |
|
576 |
+ return 56; |
|
577 |
+ } |
|
578 |
+ } |
|
579 |
+ |
|
580 |
+ if((cpt = cfgopt(copt, "HTTPProxyPort"))->enabled) |
|
581 |
+ port = cpt->numarg; |
|
582 |
+ |
|
583 |
+ logg("*Connecting via %s\n", proxy); |
|
584 |
+ } |
|
585 |
+ |
|
561 | 586 |
ret = 0; |
562 | 587 |
memset(query, 0, sizeof(query)); |
563 | 588 |
qcnt = 0; |
... | ... |
@@ -609,7 +702,7 @@ int submitstats(const char *clamdcfg, const struct cfgstruct *copt) |
609 | 609 |
entries++; |
610 | 610 |
|
611 | 611 |
if(entries == SUBMIT_MIN_ENTRIES) { |
612 |
- sd = wwwconnect("stats.clamav.net", NULL, 0, NULL, cfgopt(copt, "LocalIPAddress")->strarg, cfgopt(copt, "ConnectTimeout")->numarg, NULL, 0, 0); |
|
612 |
+ sd = wwwconnect("stats.clamav.net", proxy, port, NULL, cfgopt(copt, "LocalIPAddress")->strarg, cfgopt(copt, "ConnectTimeout")->numarg, NULL, 0, 0); |
|
613 | 613 |
if(sd == -1) { |
614 | 614 |
logg("!SubmitDetectionStats: Can't connect to server\n"); |
615 | 615 |
ret = 52; |
... | ... |
@@ -618,13 +711,13 @@ int submitstats(const char *clamdcfg, const struct cfgstruct *copt) |
618 | 618 |
|
619 | 619 |
query[sizeof(query) - 1] = 0; |
620 | 620 |
snprintf(post, sizeof(post), |
621 |
- "POST /submit.php HTTP/1.0\r\n" |
|
622 |
- "Host: stats.clamav.net\r\n" |
|
621 |
+ "POST http://stats.clamav.net/submit.php HTTP/1.0\r\n" |
|
622 |
+ "Host: stats.clamav.net\r\n%s" |
|
623 | 623 |
"Content-Type: application/x-www-form-urlencoded\r\n" |
624 | 624 |
"User-Agent: %s\r\n" |
625 | 625 |
"Content-Length: %u\r\n\n" |
626 | 626 |
"%s", |
627 |
- uastr, (unsigned int) strlen(query), query); |
|
627 |
+ auth ? auth : "", uastr, (unsigned int) strlen(query), query); |
|
628 | 628 |
|
629 | 629 |
if(send(sd, post, strlen(post), 0) < 0) { |
630 | 630 |
logg("!SubmitDetectionStats: Can't write to socket\n"); |
... | ... |
@@ -691,6 +784,8 @@ int submitstats(const char *clamdcfg, const struct cfgstruct *copt) |
691 | 691 |
} while((line = readbline(fd, fbuff, FILEBUFF, sb.st_size, &lread))); |
692 | 692 |
|
693 | 693 |
close(fd); |
694 |
+ if(auth) |
|
695 |
+ free(auth); |
|
694 | 696 |
|
695 | 697 |
if(submitted || permfail) { |
696 | 698 |
if((fd = open("stats.dat", O_WRONLY | O_CREAT | O_TRUNC, 0600)) == -1) { |
... | ... |
@@ -720,75 +815,6 @@ static int Rfc2822DateTime(char *buf, time_t mtime) |
720 | 720 |
return strftime(buf, 36, "%a, %d %b %Y %X GMT", gmt); |
721 | 721 |
} |
722 | 722 |
|
723 |
-static unsigned int fmt_base64(char *dest, const char *src, unsigned int len) |
|
724 |
-{ |
|
725 |
- unsigned short bits = 0,temp = 0; |
|
726 |
- unsigned long written = 0; |
|
727 |
- unsigned int i; |
|
728 |
- const char base64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; |
|
729 |
- |
|
730 |
- |
|
731 |
- for(i = 0; i < len; i++) { |
|
732 |
- temp <<= 8; |
|
733 |
- temp += src[i]; |
|
734 |
- bits += 8; |
|
735 |
- while(bits > 6) { |
|
736 |
- dest[written] = base64[((temp >> (bits - 6)) & 63)]; |
|
737 |
- written++; |
|
738 |
- bits -= 6; |
|
739 |
- } |
|
740 |
- } |
|
741 |
- |
|
742 |
- if(bits) { |
|
743 |
- temp <<= (6 - bits); |
|
744 |
- dest[written] = base64[temp & 63]; |
|
745 |
- written++; |
|
746 |
- } |
|
747 |
- |
|
748 |
- while(written & 3) { |
|
749 |
- dest[written] = '='; |
|
750 |
- written++; |
|
751 |
- } |
|
752 |
- |
|
753 |
- return written; |
|
754 |
-} |
|
755 |
- |
|
756 |
-static char *proxyauth(const char *user, const char *pass) |
|
757 |
-{ |
|
758 |
- int len; |
|
759 |
- char *buf, *userpass, *auth; |
|
760 |
- |
|
761 |
- |
|
762 |
- userpass = malloc(strlen(user) + strlen(pass) + 2); |
|
763 |
- if(!userpass) { |
|
764 |
- logg("!proxyauth: Can't allocate memory for 'userpass'\n"); |
|
765 |
- return NULL; |
|
766 |
- } |
|
767 |
- sprintf(userpass, "%s:%s", user, pass); |
|
768 |
- |
|
769 |
- buf = malloc((strlen(pass) + strlen(user)) * 2 + 4); |
|
770 |
- if(!buf) { |
|
771 |
- logg("!proxyauth: Can't allocate memory for 'buf'\n"); |
|
772 |
- free(userpass); |
|
773 |
- return NULL; |
|
774 |
- } |
|
775 |
- |
|
776 |
- len = fmt_base64(buf, userpass, strlen(userpass)); |
|
777 |
- free(userpass); |
|
778 |
- buf[len] = '\0'; |
|
779 |
- auth = malloc(strlen(buf) + 30); |
|
780 |
- if(!auth) { |
|
781 |
- free(buf); |
|
782 |
- logg("!proxyauth: Can't allocate memory for 'authorization'\n"); |
|
783 |
- return NULL; |
|
784 |
- } |
|
785 |
- |
|
786 |
- sprintf(auth, "Proxy-Authorization: Basic %s\r\n", buf); |
|
787 |
- free(buf); |
|
788 |
- |
|
789 |
- return auth; |
|
790 |
-} |
|
791 |
- |
|
792 | 723 |
static struct cl_cvd *remote_cvdhead(const char *file, const char *hostname, char *ip, const char *localip, const char *proxy, int port, const char *user, const char *pass, const char *uas, int *ims, int ctimeout, int rtimeout, struct mirdat *mdat, int logerr, unsigned int can_whitelist) |
793 | 724 |
{ |
794 | 725 |
char cmd[512], head[513], buffer[FILEBUFF], ipaddr[46], *ch, *tmp; |