Browse code

libclamav: count .pdb entries as signatures freshclam, sigtool: add support for safebrowsing.cvd (bb#1056)

git-svn: trunk@4901

Tomasz Kojm authored on 2009/03/06 04:09:54
Showing 7 changed files
... ...
@@ -1,3 +1,8 @@
1
+Thu Mar  5 20:10:00 CET 2009 (tk)
2
+---------------------------------
3
+ * libclamav: count .pdb entries as signatures
4
+ * freshclam, sigtool: add support for safebrowsing.cvd (bb#1056)
5
+
1 6
 Thu Mar  5 16:43:46 CET 2009 (acab)
2 7
 -----------------------------------
3 8
  * libclamav/mpool.c: enable mmap poisoning (compile with --enable-debug)
... ...
@@ -1484,6 +1484,8 @@ static int updatedb(const char *dbname, const char *hostname, char *ip, int *sig
1484 1484
 	    field = 1;
1485 1485
 	} else if(!strcmp(dbname, "daily")) {
1486 1486
 	    field = 2;
1487
+	} else if(!strcmp(dbname, "safebrowsing")) {
1488
+	    field = 6;
1487 1489
 	} else {
1488 1490
 	    logg("!updatedb: Unknown database name (%s) passed.\n", dbname);
1489 1491
 	    cl_cvdfree(current);
... ...
@@ -1829,6 +1831,19 @@ int downloadmanager(const struct optstruct *opts, const char *hostname, const ch
1829 1829
     } else if(ret == 0)
1830 1830
 	updated = 1;
1831 1831
 
1832
+    /* if ipaddr[0] != 0 it will use it to connect to the web host */
1833
+    if(optget(opts, "SafeBrowsing")->enabled && (ret = updatedb("safebrowsing", hostname, ipaddr, &signo, opts, dnsreply, localip, outdated, &mdat, logerr)) > 50) {
1834
+	if(dnsreply)
1835
+	    free(dnsreply);
1836
+
1837
+	if(newver)
1838
+	    free(newver);
1839
+
1840
+	mirman_write("mirrors.dat", &mdat);
1841
+	return ret;
1842
+    } else if(ret == 0)
1843
+	updated = 1;
1844
+
1832 1845
     if(dnsreply)
1833 1846
 	free(dnsreply);
1834 1847
 
... ...
@@ -489,14 +489,14 @@ static int cli_loadwdb(FILE *fs, struct cl_engine *engine, unsigned int options,
489 489
 	}
490 490
     }
491 491
 
492
-    if((ret = load_regex_matcher(engine->whitelist_matcher, fs, options, 1, dbio))) {
492
+    if((ret = load_regex_matcher(engine->whitelist_matcher, fs, NULL, options, 1, dbio))) {
493 493
 	return ret;
494 494
     }
495 495
 
496 496
     return CL_SUCCESS;
497 497
 }
498 498
 
499
-static int cli_loadpdb(FILE *fs, struct cl_engine *engine, unsigned int options, struct cli_dbio *dbio)
499
+static int cli_loadpdb(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned int options, struct cli_dbio *dbio)
500 500
 {
501 501
 	int ret = 0;
502 502
 
... ...
@@ -510,7 +510,7 @@ static int cli_loadpdb(FILE *fs, struct cl_engine *engine, unsigned int options,
510 510
 	}
511 511
     }
512 512
 
513
-    if((ret = load_regex_matcher(engine->domainlist_matcher, fs, options, 0, dbio))) {
513
+    if((ret = load_regex_matcher(engine->domainlist_matcher, fs, signo, options, 0, dbio))) {
514 514
 	return ret;
515 515
     }
516 516
 
... ...
@@ -1516,7 +1516,7 @@ int cli_load(const char *filename, struct cl_engine *engine, unsigned int *signo
1516 1516
 	    skipped = 1;
1517 1517
     } else if(cli_strbcasestr(dbname, ".pdb")) {
1518 1518
 	if(options & CL_DB_PHISHING_URLS) {
1519
-	    ret = cli_loadpdb(fs, engine, options, dbio);
1519
+	    ret = cli_loadpdb(fs, engine, signo, options, dbio);
1520 1520
 	} else
1521 1521
 	    skipped = 1;
1522 1522
     } else if(cli_strbcasestr(dbname, ".ftm")) {
... ...
@@ -453,9 +453,9 @@ static int add_hash(struct regex_matcher *matcher, char* pattern, const char fl)
453 453
 
454 454
 
455 455
 /* Load patterns/regexes from file */
456
-int load_regex_matcher(struct regex_matcher* matcher,FILE* fd,unsigned int options,int is_whitelist,struct cli_dbio *dbio)
456
+int load_regex_matcher(struct regex_matcher* matcher,FILE* fd,unsigned int *signo,unsigned int options,int is_whitelist,struct cli_dbio *dbio)
457 457
 {
458
-	int rc,line=0;
458
+	int rc,line=0,entry=0;
459 459
 	char buffer[FILEBUFF];
460 460
 
461 461
 	assert(matcher);
... ...
@@ -502,13 +502,14 @@ int load_regex_matcher(struct regex_matcher* matcher,FILE* fd,unsigned int optio
502 502
 		size_t pattern_len;
503 503
 
504 504
 		cli_chomp(buffer);
505
+		line++;
505 506
 		if(!*buffer)
506 507
 			continue;/* skip empty lines */
507 508
 
508 509
 		if(functionality_level_check(buffer))
509 510
 			continue;
510 511
 
511
-		line++;
512
+		entry++;
512 513
 		pattern = strchr(buffer,':');
513 514
 		if(!pattern) {
514 515
 			cli_errmsg("Malformed regex list line %d\n",line);
... ...
@@ -550,6 +551,8 @@ int load_regex_matcher(struct regex_matcher* matcher,FILE* fd,unsigned int optio
550 550
 		}
551 551
 	}
552 552
 	matcher->list_loaded = 1;
553
+	if(signo)
554
+	    *signo += entry;
553 555
 
554 556
 	return CL_SUCCESS;
555 557
 }
... ...
@@ -66,7 +66,7 @@ int cli_build_regex_list(struct regex_matcher* matcher);
66 66
 int regex_list_add_pattern(struct regex_matcher *matcher, char *pattern);
67 67
 int regex_list_match(struct regex_matcher* matcher, char* real_url,const char* display_url,const struct pre_fixup_info* pre_fixup, int hostOnly,const char **info, int is_whitelist);
68 68
 int init_regex_list(struct regex_matcher* matcher);
69
-int load_regex_matcher(struct regex_matcher* matcher,FILE* fd,unsigned int options,int is_whitelist,struct cli_dbio *dbio);
69
+int load_regex_matcher(struct regex_matcher* matcher,FILE* fd,unsigned int *signo,unsigned int options,int is_whitelist,struct cli_dbio *dbio);
70 70
 void regex_list_cleanup(struct regex_matcher* matcher);
71 71
 void regex_list_done(struct regex_matcher* matcher);
72 72
 int is_regex_ok(struct regex_matcher* matcher);
... ...
@@ -98,6 +98,7 @@ const struct clam_option clam_options[] = {
98 98
     { NULL, "html-normalise", 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_SIGTOOL, "", "" },
99 99
     { NULL, "utf16-decode", 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_SIGTOOL, "", "" },
100 100
     { NULL, "build", 'b', TYPE_STRING, NULL, -1, NULL, 0, OPT_SIGTOOL, "", "" },
101
+    { NULL, "no-cdiff", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_SIGTOOL, "", "" },
101 102
     { NULL, "server", 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_SIGTOOL, "", "" },
102 103
     { NULL, "unpack", 'u', TYPE_STRING, NULL, -1, NULL, 0, OPT_SIGTOOL, "", "" },
103 104
     { NULL, "unpack-current", 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_SIGTOOL, "", "" },
... ...
@@ -349,6 +350,8 @@ const struct clam_option clam_options[] = {
349 349
 
350 350
     { "DetectionStatsCountry", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_FRESHCLAM, "Country of origin of malware/detection statistics (for statistical\npurposes only). The statistics collector at ClamAV.net will look up\nyour IP address to determine the geographical origin of the malware\nreported by your installation. If this installation is mainly used to\nscan data which comes from a different location, please enable this\noption and enter a two-letter code (see http://www.iana.org/domains/root/db/)\nof the country of origin.", "country-code" },
351 351
 
352
+    { "SafeBrowsing", NULL, 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_FRESHCLAM, "FIXME", "yes" },
353
+
352 354
     /* Deprecated options */
353 355
 
354 356
     { "MailMaxRecursion", NULL, 0, TYPE_NUMBER, NULL, -1, NULL, 0, OPT_CLAMD | OPT_DEPRECATED, "", "" },
... ...
@@ -95,12 +95,26 @@ static const struct dblist_s {
95 95
     { "main.zmd",   1 },    { "daily.zmd",  1 },
96 96
     { "main.rmd",   1 },    { "daily.rmd",  1 },
97 97
     { "main.fp",    0 },    { "daily.fp",   0 },
98
-    { "main.pdb",   0 },    { "daily.pdb",  0 },
99
-    { "main.wdb",   0 },    { "daily.wdb",  0 },
98
+    { "main.pdb",   1 },    { "daily.pdb",  1 },    { "safebrowsing.pdb", 1 },
99
+    { "main.wdb",   0 },    { "daily.wdb",  0 },    { "safebrowsing.wdb", 0 },
100 100
 
101 101
     { NULL,	    0 }
102 102
 };
103 103
 
104
+static const char *getdbname(const char *str)
105
+{
106
+    if(strstr(str, "main"))
107
+	return "main";
108
+    else if(strstr(str, "daily"))
109
+	return "daily";
110
+    else if(strstr(str, "safebrowsing"))
111
+	return "safebrowsing";
112
+    else {
113
+	mprintf("!getdbname: Can't extract db name\n");
114
+	return "UNKNOWN";
115
+    }
116
+}
117
+
104 118
 static int hexdump(void)
105 119
 {
106 120
 	char buffer[FILEBUFF], *pt;
... ...
@@ -559,7 +573,7 @@ static int build(const struct optstruct *opts)
559 559
 	return -1;
560 560
     }
561 561
 
562
-    dbname = strstr(optget(opts, "build")->strarg, "main") ? "main" : "daily";
562
+    dbname = getdbname(optget(opts, "build")->strarg);
563 563
 
564 564
     if(!(engine = cl_engine_new())) {
565 565
 	mprintf("!build: Can't initialize antivirus engine\n");
... ...
@@ -803,6 +817,11 @@ static int build(const struct optstruct *opts)
803 803
 
804 804
     mprintf("Created %s\n", newcvd);
805 805
 
806
+    if(optget(opts, "no-cdiff")->enabled) {
807
+	mprintf("Skipping .cdiff creation\n");
808
+	return 0;
809
+    }
810
+
806 811
     /* generate patch */
807 812
     if(!(pt = cli_gentemp(NULL))) {
808 813
 	mprintf("!build: Can't generate temporary name\n");
... ...
@@ -852,11 +871,7 @@ static int build(const struct optstruct *opts)
852 852
 	return -1;
853 853
     }
854 854
 
855
-    if(!strcmp(dbname, "main"))
856
-	snprintf(patch, sizeof(patch), "main-%u.script", version);
857
-    else
858
-	snprintf(patch, sizeof(patch), "daily-%u.script", version);
859
-
855
+    snprintf(patch, sizeof(patch), "%s-%u.script", dbname, version);
860 856
     ret = diffdirs(olddb, pt, patch);
861 857
 
862 858
     cli_rmdirs(pt);
... ...
@@ -1239,15 +1254,12 @@ static int vbadump(const struct optstruct *opts)
1239 1239
 
1240 1240
 static int comparemd5(const char *dbname)
1241 1241
 {
1242
-	char info[16], buff[256], *md5, *pt;
1242
+	char info[32], buff[256], *md5, *pt;
1243 1243
 	FILE *fh;
1244 1244
 	int ret = 0;
1245 1245
 
1246 1246
 
1247
-    if(strstr(dbname, "main"))
1248
-	strcpy(info, "main.info");
1249
-    else
1250
-	strcpy(info, "daily.info");
1247
+    snprintf(info, sizeof(info), "%s.info", getdbname(dbname));
1251 1248
 
1252 1249
     if(!(fh = fopen(info, "r"))) {
1253 1250
 	mprintf("!verifydiff: Can't open %s\n", info);
... ...
@@ -1731,11 +1743,7 @@ static int makediff(const struct optstruct *opts)
1731 1731
 	return -1;
1732 1732
     }
1733 1733
 
1734
-    if(strstr(opts->filename[0], "main"))
1735
-	snprintf(name, sizeof(name), "main-%u.script", newver);
1736
-    else
1737
-	snprintf(name, sizeof(name), "daily-%u.script", newver);
1738
-
1734
+    snprintf(name, sizeof(name), "%s-%u.script", getdbname(opts->filename[0]), newver);
1739 1735
     ret = diffdirs(odir, ndir, name);
1740 1736
 
1741 1737
     cli_rmdirs(odir);
... ...
@@ -1781,6 +1789,7 @@ static void help(void)
1781 1781
     mprintf("    --utf16-decode=FILE                    decode UTF16 encoded files\n");
1782 1782
     mprintf("    --info=FILE            -i FILE         print database information\n");
1783 1783
     mprintf("    --build=NAME [cvd] -b NAME             build a CVD file\n");
1784
+    mprintf("    --no-cdiff                             Don't generate .cdiff file\n");
1784 1785
     mprintf("    --server=ADDR                          ClamAV Signing Service address\n");
1785 1786
     mprintf("    --unpack=FILE          -u FILE         Unpack a CVD/CLD file\n");
1786 1787
     mprintf("    --unpack-current=SHORTNAME             Unpack local CVD/CLD into cwd\n");