Browse code

freshclam: if all mirrors get blacklisted internally and freshclam is recent enough then attempt to whitelist them (bb#965)

git-svn: trunk@3963

Tomasz Kojm authored on 2008/07/16 21:22:56
Showing 3 changed files
... ...
@@ -1,3 +1,8 @@
1
+Wed Jul 16 13:56:21 CEST 2008 (tk)
2
+----------------------------------
3
+  * freshclam: if all mirrors get blacklisted internally and freshclam is
4
+	       recent enough then attempt to whitelist them (bb#965)
5
+
1 6
 Tue Jul 15 17:30:01 CEST 2008 (tk)
2 7
 ----------------------------------
3 8
   * libclamav, clamd: prune old lockdb code
... ...
@@ -181,9 +181,10 @@ static int getclientsock(const char *localip, int prot)
181 181
     return socketfd;
182 182
 }
183 183
 
184
-static int wwwconnect(const char *server, const char *proxy, int pport, char *ip, const char *localip, int ctimeout, struct mirdat *mdat, int logerr)
184
+static int wwwconnect(const char *server, const char *proxy, int pport, char *ip, const char *localip, int ctimeout, struct mirdat *mdat, int logerr, unsigned int can_whitelist)
185 185
 {
186 186
 	int socketfd, port, ret;
187
+	unsigned int ips = 0, ignored = 0;
187 188
 #ifdef SUPPORT_IPv6
188 189
 	struct addrinfo hints, *res = NULL, *rp, *loadbal_rp = NULL;
189 190
 	char port_s[6], loadbal_ipaddr[46];
... ...
@@ -241,6 +242,7 @@ static int wwwconnect(const char *server, const char *proxy, int pport, char *ip
241 241
     for(rp = res; rp; rp = rp->ai_next) {
242 242
 	    void *addr;
243 243
 
244
+	ips++;
244 245
 	if(rp->ai_family == AF_INET6)
245 246
 	    addr = &((struct sockaddr_in6 *) rp->ai_addr)->sin6_addr;
246 247
 	else
... ...
@@ -258,6 +260,7 @@ static int wwwconnect(const char *server, const char *proxy, int pport, char *ip
258 258
 	    else
259 259
 		logg("Ignoring mirror %s (has connected too many times with an outdated version)\n", ipaddr);
260 260
 
261
+	    ignored++;
261 262
 	    if(!loadbal || rp->ai_next)
262 263
 		continue;
263 264
 	}
... ...
@@ -341,11 +344,13 @@ static int wwwconnect(const char *server, const char *proxy, int pport, char *ip
341 341
 	ia = (unsigned char *) host->h_addr_list[i];
342 342
 	sprintf(ipaddr, "%u.%u.%u.%u", ia[0], ia[1], ia[2], ia[3]);
343 343
 
344
+	ips++;
344 345
 	if((ret = mirman_check(&((struct in_addr *) ia)->s_addr, AF_INET, mdat, NULL))) {
345 346
 	    if(ret == 1)
346 347
 		logg("Ignoring mirror %s (due to previous errors)\n", ipaddr);
347 348
 	    else
348 349
 		logg("Ignoring mirror %s (has connected too many times with an outdated version)\n", ipaddr);
350
+	    ignored++;
349 351
 	    continue;
350 352
 	}
351 353
 
... ...
@@ -380,6 +385,9 @@ static int wwwconnect(const char *server, const char *proxy, int pport, char *ip
380 380
     }
381 381
 #endif
382 382
 
383
+    if(can_whitelist && ips && (ips == ignored))
384
+	mirman_whitelist(mdat);
385
+
383 386
     return -2;
384 387
 }
385 388
 
... ...
@@ -459,7 +467,7 @@ static char *proxyauth(const char *user, const char *pass)
459 459
     return auth;
460 460
 }
461 461
 
462
-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)
462
+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)
463 463
 {
464 464
 	char cmd[512], head[513], buffer[FILEBUFF], ipaddr[46], *ch, *tmp;
465 465
 	int bread, cnt, sd;
... ...
@@ -523,9 +531,9 @@ static struct cl_cvd *remote_cvdhead(const char *file, const char *hostname, cha
523 523
     memset(ipaddr, 0, sizeof(ipaddr));
524 524
 
525 525
     if(ip[0]) /* use ip to connect */
526
-	sd = wwwconnect(ip, proxy, port, ipaddr, localip, ctimeout, mdat, logerr);
526
+	sd = wwwconnect(ip, proxy, port, ipaddr, localip, ctimeout, mdat, logerr, can_whitelist);
527 527
     else
528
-	sd = wwwconnect(hostname, proxy, port, ipaddr, localip, ctimeout, mdat, logerr);
528
+	sd = wwwconnect(hostname, proxy, port, ipaddr, localip, ctimeout, mdat, logerr, can_whitelist);
529 529
 
530 530
     if(sd < 0) {
531 531
 	return NULL;
... ...
@@ -626,7 +634,7 @@ static struct cl_cvd *remote_cvdhead(const char *file, const char *hostname, cha
626 626
     return cvd;
627 627
 }
628 628
 
629
-static int getfile(const char *srcfile, const char *destfile, const char *hostname, char *ip, const char *localip, const char *proxy, int port, const char *user, const char *pass, const char *uas, int ctimeout, int rtimeout, struct mirdat *mdat, int logerr)
629
+static int getfile(const char *srcfile, const char *destfile, const char *hostname, char *ip, const char *localip, const char *proxy, int port, const char *user, const char *pass, const char *uas, int ctimeout, int rtimeout, struct mirdat *mdat, int logerr, unsigned int can_whitelist)
630 630
 {
631 631
 	char cmd[512], buffer[FILEBUFF], *ch;
632 632
 	int bread, fd, totalsize = 0,  rot = 0, totaldownloaded = 0,
... ...
@@ -673,9 +681,9 @@ static int getfile(const char *srcfile, const char *destfile, const char *hostna
673 673
     memset(ipaddr, 0, sizeof(ipaddr));
674 674
 
675 675
     if(ip[0]) /* use ip to connect */
676
-	sd = wwwconnect(ip, proxy, port, ipaddr, localip, ctimeout, mdat, logerr);
676
+	sd = wwwconnect(ip, proxy, port, ipaddr, localip, ctimeout, mdat, logerr, can_whitelist);
677 677
     else
678
-	sd = wwwconnect(hostname, proxy, port, ipaddr, localip, ctimeout, mdat, logerr);
678
+	sd = wwwconnect(hostname, proxy, port, ipaddr, localip, ctimeout, mdat, logerr, can_whitelist);
679 679
 
680 680
     if(sd < 0) {
681 681
 	return 52;
... ...
@@ -804,14 +812,14 @@ static int getfile(const char *srcfile, const char *destfile, const char *hostna
804 804
     return 0;
805 805
 }
806 806
 
807
-static int getcvd(const char *cvdfile, const char *newfile, const char *hostname, char *ip, const char *localip, const char *proxy, int port, const char *user, const char *pass, const char *uas, int nodb, unsigned int newver, int ctimeout, int rtimeout, struct mirdat *mdat, int logerr)
807
+static int getcvd(const char *cvdfile, const char *newfile, const char *hostname, char *ip, const char *localip, const char *proxy, int port, const char *user, const char *pass, const char *uas, int nodb, unsigned int newver, int ctimeout, int rtimeout, struct mirdat *mdat, int logerr, unsigned int can_whitelist)
808 808
 {
809 809
 	struct cl_cvd *cvd;
810 810
 	int ret;
811 811
 
812 812
 
813 813
     logg("*Retrieving http://%s/%s\n", hostname, cvdfile);
814
-    if((ret = getfile(cvdfile, newfile, hostname, ip, localip, proxy, port, user, pass, uas, ctimeout, rtimeout, mdat, logerr))) {
814
+    if((ret = getfile(cvdfile, newfile, hostname, ip, localip, proxy, port, user, pass, uas, ctimeout, rtimeout, mdat, logerr, can_whitelist))) {
815 815
         logg("%cCan't download %s from %s\n", logerr ? '!' : '^', cvdfile, hostname);
816 816
         unlink(newfile);
817 817
         return ret;
... ...
@@ -875,7 +883,7 @@ static int chdir_tmp(const char *dbname, const char *tmpdir)
875 875
     return 0;
876 876
 }
877 877
 
878
-static int getpatch(const char *dbname, const char *tmpdir, int version, const char *hostname, char *ip, const char *localip, const char *proxy, int port, const char *user, const char *pass, const char *uas, int ctimeout, int rtimeout, struct mirdat *mdat, int logerr)
878
+static int getpatch(const char *dbname, const char *tmpdir, int version, const char *hostname, char *ip, const char *localip, const char *proxy, int port, const char *user, const char *pass, const char *uas, int ctimeout, int rtimeout, struct mirdat *mdat, int logerr, unsigned int can_whitelist)
879 879
 {
880 880
 	char *tempname, patch[32], olddir[512];
881 881
 	int ret, fd;
... ...
@@ -893,7 +901,7 @@ static int getpatch(const char *dbname, const char *tmpdir, int version, const c
893 893
     snprintf(patch, sizeof(patch), "%s-%d.cdiff", dbname, version);
894 894
 
895 895
     logg("*Retrieving http://%s/%s\n", hostname, patch);
896
-    if((ret = getfile(patch, tempname, hostname, ip, localip, proxy, port, user, pass, uas, ctimeout, rtimeout, mdat, logerr))) {
896
+    if((ret = getfile(patch, tempname, hostname, ip, localip, proxy, port, user, pass, uas, ctimeout, rtimeout, mdat, logerr, can_whitelist))) {
897 897
         logg("%cgetpatch: Can't download %s from %s\n", logerr ? '!' : '^', patch, hostname);
898 898
         unlink(tempname);
899 899
         free(tempname);
... ...
@@ -1096,7 +1104,8 @@ static int updatedb(const char *dbname, const char *hostname, char *ip, int *sig
1096 1096
 	int ret, ims = -1;
1097 1097
 	char *pt, cvdfile[32], localname[32], *tmpdir = NULL, *newfile, newdb[32], cwd[512];
1098 1098
 	const char *proxy = NULL, *user = NULL, *pass = NULL, *uas = NULL;
1099
-	unsigned int flevel = cl_retflevel(), maxattempts;
1099
+	unsigned int flevel = cl_retflevel(), remote_flevel = 0, maxattempts;
1100
+	unsigned int can_whitelist = 0;
1100 1101
 	int ctimeout, rtimeout;
1101 1102
 
1102 1103
 
... ...
@@ -1134,6 +1143,15 @@ static int updatedb(const char *dbname, const char *hostname, char *ip, int *sig
1134 1134
 	}
1135 1135
     }
1136 1136
 
1137
+    if(dnsreply) {
1138
+	if((pt = cli_strtok(dnsreply, 5, ":"))) {
1139
+	    remote_flevel = atoi(pt);
1140
+	    free(pt);
1141
+	    if(remote_flevel - flevel < 4)
1142
+		can_whitelist = 1;
1143
+	}
1144
+    }
1145
+
1137 1146
     /* Initialize proxy settings */
1138 1147
     if((cpt = cfgopt(copt, "HTTPProxyServer"))->enabled) {
1139 1148
 	proxy = cpt->strarg;
... ...
@@ -1166,7 +1184,7 @@ static int updatedb(const char *dbname, const char *hostname, char *ip, int *sig
1166 1166
 
1167 1167
     if(!nodb && !newver) {
1168 1168
 
1169
-	remote = remote_cvdhead(cvdfile, hostname, ip, localip, proxy, port, user, pass, uas, &ims, ctimeout, rtimeout, mdat, logerr);
1169
+	remote = remote_cvdhead(cvdfile, hostname, ip, localip, proxy, port, user, pass, uas, &ims, ctimeout, rtimeout, mdat, logerr, can_whitelist);
1170 1170
 
1171 1171
 	if(!nodb && !ims) {
1172 1172
 	    logg("%s is up to date (version: %d, sigs: %d, f-level: %d, builder: %s)\n", localname, current->version, current->sigs, current->fl, current->builder);
... ...
@@ -1231,7 +1249,7 @@ static int updatedb(const char *dbname, const char *hostname, char *ip, int *sig
1231 1231
     newfile = cli_gentemp(cwd);
1232 1232
 
1233 1233
     if(nodb) {
1234
-	ret = getcvd(cvdfile, newfile, hostname, ip, localip, proxy, port, user, pass, uas, nodb, newver, ctimeout, rtimeout, mdat, logerr);
1234
+	ret = getcvd(cvdfile, newfile, hostname, ip, localip, proxy, port, user, pass, uas, nodb, newver, ctimeout, rtimeout, mdat, logerr, can_whitelist);
1235 1235
 	if(ret) {
1236 1236
 	    memset(ip, 0, 16);
1237 1237
 	    free(newfile);
... ...
@@ -1249,7 +1267,7 @@ static int updatedb(const char *dbname, const char *hostname, char *ip, int *sig
1249 1249
 		    int llogerr = logerr;
1250 1250
 		if(logerr)
1251 1251
 		    llogerr = (j == maxattempts - 1);
1252
-		ret = getpatch(dbname, tmpdir, i, hostname, ip, localip, proxy, port, user, pass, uas, ctimeout, rtimeout, mdat, llogerr);
1252
+		ret = getpatch(dbname, tmpdir, i, hostname, ip, localip, proxy, port, user, pass, uas, ctimeout, rtimeout, mdat, llogerr, can_whitelist);
1253 1253
 		if(ret == 52 || ret == 58) {
1254 1254
 		    memset(ip, 0, 16);
1255 1255
 		    continue;
... ...
@@ -1265,7 +1283,7 @@ static int updatedb(const char *dbname, const char *hostname, char *ip, int *sig
1265 1265
 	    cli_rmdirs(tmpdir);
1266 1266
 	    free(tmpdir);
1267 1267
 	    logg("^Incremental update failed, trying to download %s\n", cvdfile);
1268
-	    ret = getcvd(cvdfile, newfile, hostname, ip, localip, proxy, port, user, pass, uas, 1, newver, ctimeout, rtimeout, mdat, logerr);
1268
+	    ret = getcvd(cvdfile, newfile, hostname, ip, localip, proxy, port, user, pass, uas, 1, newver, ctimeout, rtimeout, mdat, logerr, can_whitelist);
1269 1269
 	    if(ret) {
1270 1270
 		free(newfile);
1271 1271
 		return ret;
... ...
@@ -1404,11 +1422,6 @@ int downloadmanager(const struct cfgstruct *copt, const struct optstruct *opt, c
1404 1404
 		    }
1405 1405
 		}
1406 1406
 
1407
-	    } else {
1408
-		if(dnsreply) {
1409
-		    free(dnsreply);
1410
-		    dnsreply = NULL;
1411
-		}
1412 1407
 	    }
1413 1408
 	}
1414 1409
 
... ...
@@ -241,6 +241,15 @@ void mirman_list(const struct mirdat *mdat)
241 241
     }
242 242
 }
243 243
 
244
+void mirman_whitelist(struct mirdat *mdat)
245
+{
246
+	unsigned int i;
247
+
248
+    logg("Whitelisting all mirrors\n");
249
+    for(i = 0; i < mdat->num; i++)
250
+	mdat->mirtab[i].ignore = 0;
251
+}
252
+
244 253
 int mirman_write(const char *file, struct mirdat *mdat)
245 254
 {
246 255
 	int fd;