Browse code

freshclam: add new option PrivateMirror (bb#3058)

Tomasz Kojm authored on 2011/09/12 23:29:56
Showing 6 changed files
... ...
@@ -1,3 +1,7 @@
1
+Mon Sep 12 16:29:22 CEST 2011 (tk)
2
+----------------------------------
3
+ * freshclam: add new option PrivateMirror (bb#3058)
4
+
1 5
 Sun Aug 21 17:05:24 EEST 2011 (edwin)
2 6
 -------------------------------------
3 7
  * libclamav/pdf.c:  fix incorrect blocking of some encrypted PDF with empty user passwords. (bb #3364)
... ...
@@ -111,6 +111,11 @@ With this option you can provide custom sources (http:// or file://) for databas
111 111
 .br 
112 112
 Default: no custom URLs
113 113
 .TP 
114
+\fBPrivateMirror STR\fR
115
+This option allows you to easily point freshclam to private mirrors. If PrivateMirror is set, freshclam does not attempt to use DNS to determine whether its databases are out-of-date, instead it will use the If-Modified-Since request or directly check the headers of the remote database files. For each database, freshclam first attempts to download the CLD file. If that fails, it tries to download the CVD file. This option overrides DatabaseMirror, DNSDatabaseInfo and ScriptedUpdates. It can be used multiple times to provide fall-back mirrors.
116
+.br 
117
+Default: disabled
118
+.TP 
114 119
 \fBHTTPProxyServer STR\fR, \fBHTTPProxyPort NUMBER\fR
115 120
 Use given proxy server and TCP port for database downloads.
116 121
 .TP 
... ...
@@ -94,6 +94,19 @@ DatabaseMirror database.clamav.net
94 94
 #DatabaseCustomURL http://myserver.com/mysigs.ndb
95 95
 #DatabaseCustomURL file:///mnt/nfs/local.hdb
96 96
 
97
+# This option allows you to easily point freshclam to private mirrors.
98
+# If PrivateMirror is set, freshclam does not attempt to use DNS
99
+# to determine whether its databases are out-of-date, instead it will
100
+# use the If-Modified-Since request or directly check the headers of the
101
+# remote database files. For each database, freshclam first attempts
102
+# to download the CLD file. If that fails, it tries to download the
103
+# CVD file. This option overrides DatabaseMirror, DNSDatabaseInfo
104
+# and Scripted Updates. It can be used multiple times to provide
105
+# fall-back mirrors.
106
+# Default: disabled
107
+#PrivateMirror mirror1.mynetwork.com
108
+#PrivateMirror mirror2.mynetwork.com
109
+
97 110
 # Number of database checks per day.
98 111
 # Default: 12 (every two hours)
99 112
 #Checks 24
... ...
@@ -412,6 +412,51 @@ int main(int argc, char **argv)
412 412
 	return 0;
413 413
     }
414 414
 
415
+    if((opt = optget(opts, "PrivateMirror"))->enabled) {
416
+	    struct optstruct *dbm, *opth;
417
+
418
+	dbm = (struct optstruct *) optget(opts, "DatabaseMirror");
419
+	dbm->active = dbm->enabled = 1;
420
+	do {
421
+	    if(dbm->strarg)
422
+		free(dbm->strarg);
423
+	    dbm->strarg = strdup(opt->strarg);
424
+	    if(!dbm->strarg) {
425
+		logg("!strdup() failed\n");
426
+		optfree(opts);
427
+		return 75;
428
+	    }
429
+	    if(!dbm->nextarg) {
430
+		dbm->nextarg = (struct optstruct *) calloc(1, sizeof(struct optstruct));
431
+		if(!dbm->nextarg) {
432
+		    logg("!calloc() failed\n");
433
+		    optfree(opts);
434
+		    return 75;
435
+		}
436
+	    }
437
+	    opth = dbm;
438
+	    dbm = dbm->nextarg;
439
+	} while((opt = opt->nextarg));
440
+
441
+	opth->nextarg = NULL;
442
+	while(dbm) {
443
+	    free(dbm->name);
444
+	    free(dbm->cmd);
445
+	    free(dbm->strarg);
446
+	    opth = dbm;
447
+	    dbm = dbm->nextarg;
448
+	    free(opth);
449
+	}
450
+
451
+	/* disable DNS db checks */
452
+	opth = (struct optstruct *) optget(opts, "no-dns");
453
+	opth->active = opth->enabled = 1;
454
+
455
+	/* disable scripted updates */
456
+	opth = (struct optstruct *) optget(opts, "ScriptedUpdates");
457
+	opth->active = opth->enabled = 0;
458
+    }
459
+
415 460
     *updtmpdir = 0;
416 461
 
417 462
 #ifdef _WIN32
... ...
@@ -813,7 +813,7 @@ static struct cl_cvd *remote_cvdhead(const char *cvdfile, const char *localfile,
813 813
     }
814 814
 
815 815
     if((strstr(buffer, "HTTP/1.1 404")) != NULL || (strstr(buffer, "HTTP/1.0 404")) != NULL) { 
816
-	logg("%cCVD file not found on remote server\n", logerr ? '!' : '^');
816
+	logg("%c%s not found on remote server\n", logerr ? '!' : '^', cvdfile);
817 817
 	mirman_update(mdat->currip, mdat->af, mdat, 2);
818 818
 	return NULL;
819 819
     }
... ...
@@ -1558,8 +1558,8 @@ static int updatedb(const char *dbname, const char *hostname, char *ip, int *sig
1558 1558
 	struct cl_cvd *current, *remote;
1559 1559
 	const struct optstruct *opt;
1560 1560
 	unsigned int nodb = 0, currver = 0, newver = 0, port = 0, i, j;
1561
-	int ret, ims = -1;
1562
-	char *pt, cvdfile[32], localname[32], *tmpdir = NULL, *newfile, *newfile2, newdb[32];
1561
+	int ret, ims = -1, hascld = 0;
1562
+	char *pt, cvdfile[32], cldfile[32], localname[32], *tmpdir = NULL, *newfile, *newfile2, newdb[32];
1563 1563
 	char extradbinfo[64], *extradnsreply = NULL, squery[64];
1564 1564
 	const char *proxy = NULL, *user = NULL, *pass = NULL, *uas = NULL;
1565 1565
 	unsigned int flevel = cl_retflevel(), remote_flevel = 0, maxattempts;
... ...
@@ -1576,6 +1576,7 @@ static int updatedb(const char *dbname, const char *hostname, char *ip, int *sig
1576 1576
 	mirror_stats = 1;
1577 1577
 
1578 1578
     snprintf(cvdfile, sizeof(cvdfile), "%s.cvd", dbname);
1579
+    snprintf(cldfile, sizeof(cldfile), "%s.cld", dbname);
1579 1580
 
1580 1581
     if(!(current = currentdb(dbname, localname))) {
1581 1582
 	nodb = 1;
... ...
@@ -1688,8 +1689,14 @@ static int updatedb(const char *dbname, const char *hostname, char *ip, int *sig
1688 1688
     rtimeout = optget(opts, "ReceiveTimeout")->numarg;
1689 1689
 
1690 1690
     if(!nodb && !newver) {
1691
-
1692
-	remote = remote_cvdhead(cvdfile, localname, hostname, ip, localip, proxy, port, user, pass, uas, &ims, ctimeout, rtimeout, mdat, logerr, can_whitelist);
1691
+	if(optget(opts, "PrivateMirror")->enabled) {
1692
+	    remote = remote_cvdhead(cldfile, localname, hostname, ip, localip, proxy, port, user, pass, uas, &ims, ctimeout, rtimeout, mdat, logerr, can_whitelist);
1693
+	    if(remote)
1694
+		hascld = 1;
1695
+	    else
1696
+		remote = remote_cvdhead(cvdfile, localname, hostname, ip, localip, proxy, port, user, pass, uas, &ims, ctimeout, rtimeout, mdat, logerr, can_whitelist);
1697
+	} else
1698
+	    remote = remote_cvdhead(cvdfile, localname, hostname, ip, localip, proxy, port, user, pass, uas, &ims, ctimeout, rtimeout, mdat, logerr, can_whitelist);
1693 1699
 
1694 1700
 	if(!nodb && !ims) {
1695 1701
 	    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);
... ...
@@ -1759,7 +1766,15 @@ static int updatedb(const char *dbname, const char *hostname, char *ip, int *sig
1759 1759
 
1760 1760
     newfile = cli_gentemp(updtmpdir);
1761 1761
     if(nodb) {
1762
-	ret = getcvd(cvdfile, newfile, hostname, ip, localip, proxy, port, user, pass, uas, newver, ctimeout, rtimeout, mdat, logerr, can_whitelist, opts);
1762
+	if(optget(opts, "PrivateMirror")->enabled) {
1763
+	    ret = 0;
1764
+	    if(hascld)
1765
+		ret = getcvd(cldfile, newfile, hostname, ip, localip, proxy, port, user, pass, uas, newver, ctimeout, rtimeout, mdat, logerr, can_whitelist, opts);
1766
+	    if(ret || !hascld)
1767
+		ret = getcvd(cvdfile, newfile, hostname, ip, localip, proxy, port, user, pass, uas, newver, ctimeout, rtimeout, mdat, logerr, can_whitelist, opts);
1768
+	} else
1769
+	    ret = getcvd(cvdfile, newfile, hostname, ip, localip, proxy, port, user, pass, uas, newver, ctimeout, rtimeout, mdat, logerr, can_whitelist, opts);
1770
+
1763 1771
 	if(ret) {
1764 1772
 	    if(mirror_stats && strlen(ip)) {
1765 1773
 		snprintf(squery, sizeof(squery), "%s.%u.%u.%u.%u.%s.ping.clamav.net", dbname, 0, flevel, 0, w32, ip);
... ...
@@ -2166,7 +2181,7 @@ int downloadmanager(const struct optstruct *opts, const char *hostname, int loge
2166 2166
     if((opt = optget(opts, "LocalIPAddress"))->enabled)
2167 2167
 	localip = opt->strarg;
2168 2168
 
2169
-    if(optget(opts, "HTTPProxyServer")->enabled)
2169
+    if(optget(opts, "HTTPProxyServer")->enabled || optget(opts, "PrivateMirror")->enabled)
2170 2170
 	mirman_read("mirrors.dat", &mdat, 0);
2171 2171
     else
2172 2172
 	mirman_read("mirrors.dat", &mdat, 1);
... ...
@@ -371,6 +371,8 @@ const struct clam_option __clam_options[] = {
371 371
 
372 372
     { "DatabaseMirror", NULL, 0, TYPE_STRING, NULL, -1, NULL, FLAG_MULTIPLE, OPT_FRESHCLAM, "DatabaseMirror specifies to which mirror(s) freshclam should connect.\nYou should have at least two entries: db.XY.clamav.net (or db.XY.ipv6.clamav.net\nfor IPv6) and database.clamav.net (in this order). Please replace XY with your\ncountry code (see http://www.iana.org/cctld/cctld-whois.htm).\ndatabase.clamav.net is a round-robin record which points to our most reliable\nmirrors. It's used as a fall back in case db.XY.clamav.net is not working.", "db.XY.clamav.net\ndatabase.clamav.net" },
373 373
 
374
+    { "PrivateMirror", NULL, 0, TYPE_STRING, NULL, -1, NULL, FLAG_MULTIPLE, OPT_FRESHCLAM, "This option allows you to easily point freshclam to private mirrors.\nIf PrivateMirror is set, freshclam does not attempt to use DNS\nto determine whether its databases are out-of-date, instead it will\nuse the If-Modified-Since request or directly check the headers of the\nremote database files. For each database, freshclam first attempts\nto download the CLD file. If that fails, it tries to download the\nCVD file. This option overrides DatabaseMirror, DNSDatabaseInfo\nand Scripted Updates. It can be used multiple times to provide\nfall-back mirrors.", "mirror1.mynetwork.com\nmirror2.mynetwork.com" },
375
+
374 376
     { "MaxAttempts", NULL, 0, TYPE_NUMBER, MATCH_NUMBER, 3, NULL, 0, OPT_FRESHCLAM, "This option defines how many attempts freshclam should make before giving up.", "5" },
375 377
 
376 378
     { "ScriptedUpdates", NULL, 0, TYPE_BOOL, MATCH_BOOL, 1, NULL, 0, OPT_FRESHCLAM, "With this option you can control scripted updates. It's highly recommended to keep them enabled.", "yes" },