Browse code

freshclam: add new option TestDatabases

Tomasz Kojm authored on 2010/05/12 05:44:28
Showing 5 changed files
... ...
@@ -1,3 +1,7 @@
1
+Tue May 11 22:44:06 CEST 2010 (tk)
2
+----------------------------------
3
+ * freshclam: add new option TestDatabases
4
+
1 5
 Tue May 11 21:33:49 EEST 2010 (edwin)
2 6
 -------------------------------------
3 7
  * libclamav/filtering.c: fix handling of alternates and negated alternates (bb #2004)
... ...
@@ -96,6 +96,11 @@ With this option you can control scripted updates. It's highly recommended to ke
96 96
 .br .
97 97
 Default: enabled
98 98
 .TP 
99
+\fBTestDatabases BOOL\fR
100
+With this option enabled, freshclam will attempt to load new databases into memory to make sure they are properly handled by libclamav before replacing the old ones.
101
+.br .
102
+Default: enabled
103
+.TP 
99 104
 \fBCompressLocalDatabase BOOL\fR
100 105
 By default freshclam will keep the local databases (.cld) uncompressed to make their handling faster. With this option you can enable the compression; the change will take effect with the next database update.
101 106
 .br 
... ...
@@ -142,6 +142,12 @@ DatabaseMirror database.clamav.net
142 142
 # Default: 30
143 143
 #ReceiveTimeout 60
144 144
 
145
+# With this option enabled, freshclam will attempt to load new
146
+# databases into memory to make sure they are properly handled
147
+# by libclamav before replacing the old ones.
148
+# Default: yes
149
+#TestDatabases yes
150
+
145 151
 # When enabled freshclam will submit statistics to the ClamAV Project about
146 152
 # the latest virus detections in your environment. The ClamAV maintainers
147 153
 # will then use this data to determine what types of malware are the most
... ...
@@ -1467,14 +1467,15 @@ static int updatedb(const char *dbname, const char *hostname, char *ip, int *sig
1467 1467
 {
1468 1468
 	struct cl_cvd *current, *remote;
1469 1469
 	const struct optstruct *opt;
1470
-	unsigned int nodb = 0, currver = 0, newver = 0, port = 0, i, j;
1470
+	unsigned int nodb = 0, currver = 0, newver = 0, port = 0, i, j, newsigs = 0;
1471 1471
 	int ret, ims = -1;
1472
-	char *pt, cvdfile[32], localname[32], *tmpdir = NULL, *newfile, newdb[32], cwd[512];
1472
+	char *pt, cvdfile[32], localname[32], *tmpdir = NULL, *newfile, *newfile2, newdb[32], cwd[512];
1473 1473
 	char extradbinfo[64], *extradnsreply = NULL;
1474 1474
 	const char *proxy = NULL, *user = NULL, *pass = NULL, *uas = NULL;
1475 1475
 	unsigned int flevel = cl_retflevel(), remote_flevel = 0, maxattempts;
1476 1476
 	unsigned int can_whitelist = 0;
1477 1477
 	int ctimeout, rtimeout;
1478
+	struct cl_engine *engine;
1478 1479
 
1479 1480
 
1480 1481
     snprintf(cvdfile, sizeof(cvdfile), "%s.cvd", dbname);
... ...
@@ -1722,6 +1723,45 @@ static int updatedb(const char *dbname, const char *hostname, char *ip, int *sig
1722 1722
 	return 55; /* FIXME */
1723 1723
     }
1724 1724
 
1725
+    if(optget(opts, "TestDatabases")->enabled && strlen(newfile) > 4) {
1726
+	if(!(engine = cl_engine_new())) {
1727
+	    unlink(newfile);
1728
+	    free(newfile);
1729
+	    return 55;
1730
+	}
1731
+	newfile2 = strdup(newfile);
1732
+	if(!newfile2) {
1733
+	    unlink(newfile);
1734
+	    free(newfile);
1735
+	    cl_engine_free(engine);
1736
+	    return 55;
1737
+	}
1738
+	newfile2[strlen(newfile2) - 4] = '.';
1739
+	newfile2[strlen(newfile2) - 3] = 'c';
1740
+	newfile2[strlen(newfile2) - 2] = strstr(newdb, ".cld") ? 'l' : 'v';
1741
+	newfile2[strlen(newfile2) - 1] = 'd';
1742
+	if(rename(newfile, newfile2) == -1) {
1743
+	    logg("!Can't rename %s to %s: %s\n", newfile, newfile2, strerror(errno));
1744
+	    unlink(newfile);
1745
+	    free(newfile);
1746
+	    free(newfile2);
1747
+	    cl_engine_free(engine);
1748
+	    return 57;
1749
+	}
1750
+	free(newfile);
1751
+	newfile = newfile2;
1752
+	if((ret = cl_load(newfile, engine, &newsigs, CL_DB_PHISHING | CL_DB_PHISHING_URLS | CL_DB_BYTECODE | CL_DB_PUA)) != CL_SUCCESS) {
1753
+	    logg("!Failed to load new database: %s\n", cl_strerror(ret));
1754
+	    unlink(newfile);
1755
+	    free(newfile);
1756
+	    cl_engine_free(engine);
1757
+	    return 55;
1758
+	} else {
1759
+	    logg("*Properly loaded %u signatures from new %s\n", newsigs, newdb);
1760
+	}
1761
+	cl_engine_free(engine);
1762
+    }
1763
+
1725 1764
 #ifdef _WIN32
1726 1765
     if(!access(newdb, R_OK) && unlink(newdb)) {
1727 1766
 	logg("!Can't unlink %s. Please fix the problem manually and try again.\n", newdb);
... ...
@@ -350,6 +350,8 @@ const struct clam_option __clam_options[] = {
350 350
 
351 351
     { "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" },
352 352
 
353
+    { "TestDatabases", NULL, 0, TYPE_BOOL, MATCH_BOOL, 1, NULL, 0, OPT_FRESHCLAM, "With this option enabled, freshclam will attempt to load new\ndatabases into memory to make sure they are properly handled\nby libclamav before replacing the old ones.", "yes" },
354
+
353 355
     { "CompressLocalDatabase", NULL, 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_FRESHCLAM, "By default freshclam will keep the local databases (.cld) uncompressed to\nmake their handling faster. With this option you can enable the compression.\nThe change will take effect with the next database update.", "" },
354 356
 
355 357
     { "ExtraDatabase", NULL, 0, TYPE_STRING, NULL, -1, NULL, FLAG_MULTIPLE, OPT_FRESHCLAM, "Download additional database. This option can be used multiple times.", "dbname1\ndbname2" },