Browse code

add support for signature whitelisting with daily.ign/local.ign (bb#779)

git-svn: trunk@3601

Tomasz Kojm authored on 2008/02/09 04:32:45
Showing 4 changed files
... ...
@@ -1,3 +1,8 @@
1
+Fri Feb  8 20:16:45 CET 2008 (tk)
2
+---------------------------------
3
+  * libclamac/readdb.c: add support for signature whitelisting with
4
+			daily.ign/local.ign (bb#779)
5
+
1 6
 Fri Feb  8 14:20:55 EET 2008 (edwin)
2 7
 ------------------------------------
3 8
   * configure.in:
... ...
@@ -136,6 +136,9 @@ struct cl_engine {
136 136
 
137 137
     /* Filetype definitions */
138 138
     void *ftypes;
139
+
140
+    /* Ignored signatures */
141
+    void *ignored;
139 142
 };
140 143
 
141 144
 struct cl_limits {
... ...
@@ -76,6 +76,17 @@
76 76
 static pthread_mutex_t cli_ref_mutex = PTHREAD_MUTEX_INITIALIZER;
77 77
 #endif
78 78
 
79
+struct cli_ignsig {
80
+    char *dbname, *signame;
81
+    unsigned int line;
82
+    struct cli_ignsig *next;
83
+};
84
+
85
+struct cli_ignored {
86
+    struct hashset hs;
87
+    struct cli_ignsig *list;
88
+};
89
+
79 90
 /* Prototypes for old public functions just to shut up some gcc warnings;
80 91
  * to be removed in 1.0
81 92
  */
... ...
@@ -378,10 +389,32 @@ char *cli_dbgets(char *buff, unsigned int size, FILE *fs, gzFile *gzs, unsigned
378 378
     }
379 379
 }
380 380
 
381
-static int cli_loaddb(FILE *fs, struct cl_engine **engine, unsigned int *signo, unsigned int options, gzFile *gzs, unsigned int gzrsize)
381
+static int cli_chkign(const struct cli_ignored *ignored, const char *dbname, unsigned int line, const char *signame)
382
+{
383
+	struct cli_ignsig *pt;
384
+
385
+    if(!ignored || !dbname || !signame)
386
+	return 0;
387
+
388
+    if(hashset_contains(&ignored->hs, line)) {
389
+	pt = ignored->list;
390
+	while(pt) {
391
+	    if(pt->line == line && !strcmp(pt->dbname, dbname) && !strcmp(pt->signame, signame)) {
392
+		cli_dbgmsg("Skipping signature %s @ %s:%u\n", signame, dbname, line);
393
+		return 1;
394
+	    }
395
+	    pt = pt->next;
396
+	}
397
+    }
398
+
399
+    return 0;
400
+}
401
+
402
+static int cli_loaddb(FILE *fs, struct cl_engine **engine, unsigned int *signo, unsigned int options, gzFile *gzs, unsigned int gzrsize, const char *dbname)
382 403
 {
383 404
 	char buffer[FILEBUFF], *pt, *start;
384
-	int line = 0, ret = 0;
405
+	unsigned int line = 0, sigs = 0;
406
+	int ret = 0;
385 407
 	struct cli_matcher *root;
386 408
 
387 409
 
... ...
@@ -411,12 +444,16 @@ static int cli_loaddb(FILE *fs, struct cl_engine **engine, unsigned int *signo,
411 411
 	start = buffer;
412 412
 	*pt++ = 0;
413 413
 
414
+	if((*engine)->ignored && cli_chkign((*engine)->ignored, dbname, line, start))
415
+	    continue;
416
+
414 417
 	if(*pt == '=') continue;
415 418
 
416 419
 	if((ret = cli_parse_add(root, start, pt, 0, NULL, 0))) {
417 420
 	    ret = CL_EMALFDB;
418 421
 	    break;
419 422
 	}
423
+	sigs++;
420 424
     }
421 425
 
422 426
     if(!line) {
... ...
@@ -432,7 +469,7 @@ static int cli_loaddb(FILE *fs, struct cl_engine **engine, unsigned int *signo,
432 432
     }
433 433
 
434 434
     if(signo)
435
-	*signo += line;
435
+	*signo += sigs;
436 436
 
437 437
     return CL_SUCCESS;
438 438
 }
... ...
@@ -498,7 +535,7 @@ static int cli_loadpdb(FILE *fs, struct cl_engine **engine, unsigned int options
498 498
 }
499 499
 
500 500
 #define NDB_TOKENS 6
501
-static int cli_loadndb(FILE *fs, struct cl_engine **engine, unsigned int *signo, unsigned short sdb, unsigned int options, gzFile *gzs, unsigned int gzrsize)
501
+static int cli_loadndb(FILE *fs, struct cl_engine **engine, unsigned int *signo, unsigned short sdb, unsigned int options, gzFile *gzs, unsigned int gzrsize, const char *dbname)
502 502
 {
503 503
 	const char *tokens[NDB_TOKENS];
504 504
 	char buffer[FILEBUFF];
... ...
@@ -529,7 +566,6 @@ static int cli_loadndb(FILE *fs, struct cl_engine **engine, unsigned int *signo,
529 529
 	    if(!strncmp(buffer, "HTML.Phishing", 13) || !strncmp(buffer, "Email.Phishing", 14))
530 530
 		continue;
531 531
 
532
-	sigs++;
533 532
 	cli_chomp(buffer);
534 533
 
535 534
 	cli_strtokenize(buffer, ':', NDB_TOKENS, tokens);
... ...
@@ -539,6 +575,9 @@ static int cli_loadndb(FILE *fs, struct cl_engine **engine, unsigned int *signo,
539 539
 	    break;
540 540
 	}
541 541
 
542
+	if((*engine)->ignored && cli_chkign((*engine)->ignored, dbname, line, virname))
543
+	    continue;
544
+
542 545
 	if((pt = tokens[4])) { /* min version */
543 546
 	    if(!isdigit(*pt)) {
544 547
 		ret = CL_EMALFDB;
... ...
@@ -547,7 +586,6 @@ static int cli_loadndb(FILE *fs, struct cl_engine **engine, unsigned int *signo,
547 547
 
548 548
 	    if((unsigned int) atoi(pt) > cl_retflevel()) {
549 549
 		cli_dbgmsg("Signature for %s not loaded (required f-level: %d)\n", virname, atoi(pt));
550
-		sigs--;
551 550
 		continue;
552 551
 	    }
553 552
 
... ...
@@ -559,7 +597,6 @@ static int cli_loadndb(FILE *fs, struct cl_engine **engine, unsigned int *signo,
559 559
 		}
560 560
 
561 561
 		if((unsigned int) atoi(pt) < cl_retflevel()) {
562
-		    sigs--;
563 562
 		    continue;
564 563
 		}
565 564
 
... ...
@@ -574,7 +611,6 @@ static int cli_loadndb(FILE *fs, struct cl_engine **engine, unsigned int *signo,
574 574
 
575 575
 	if(target >= CLI_MTARGETS) {
576 576
 	    cli_dbgmsg("Not supported target type in signature for %s\n", virname);
577
-	    sigs--;
578 577
 	    continue;
579 578
 	}
580 579
 
... ...
@@ -596,7 +632,7 @@ static int cli_loadndb(FILE *fs, struct cl_engine **engine, unsigned int *signo,
596 596
 	    ret = CL_EMALFDB;
597 597
 	    break;
598 598
 	}
599
-
599
+	sigs++;
600 600
     }
601 601
 
602 602
     if(!line) {
... ...
@@ -715,6 +751,100 @@ static int cli_loadft(FILE *fs, struct cl_engine **engine, unsigned int options,
715 715
     return CL_SUCCESS;
716 716
 }
717 717
 
718
+static int cli_loadign(FILE *fs, struct cl_engine **engine, unsigned int options, gzFile *gzs, unsigned int gzrsize)
719
+{
720
+	char buffer[FILEBUFF], *pt;
721
+	unsigned int line = 0;
722
+	struct cli_ignsig *new, *last = NULL;
723
+	struct cli_ignored *ignored;
724
+	int ret;
725
+
726
+
727
+    if((ret = cli_initengine(engine, options))) {
728
+	cl_free(*engine);
729
+	return ret;
730
+    }
731
+
732
+    if(!(ignored = (*engine)->ignored)) {
733
+	ignored = (*engine)->ignored = (struct cli_ignored *) cli_calloc(sizeof(struct cli_ignored), 1);
734
+	if(!ignored || hashset_init(&ignored->hs, 64, 50)) {
735
+	    cl_free(*engine);
736
+	    return CL_EMEM;
737
+	}
738
+    }
739
+
740
+    while(cli_dbgets(buffer, FILEBUFF, fs, gzs, &gzrsize)) {
741
+	line++;
742
+	cli_chomp(buffer);
743
+
744
+	new = (struct cli_ignsig *) cli_calloc(1, sizeof(struct cli_ignsig));
745
+	if(!new) {
746
+	    ret = CL_EMEM;
747
+	    break;
748
+	}
749
+
750
+	if(!(new->dbname = cli_strtok(buffer, 0, ":"))) {
751
+	    free(new);
752
+	    ret = CL_EMALFDB;
753
+	    break;
754
+	}
755
+
756
+	if(!(pt = cli_strtok(buffer, 1, ":"))) {
757
+	    free(new->dbname);
758
+	    free(new);
759
+	    ret = CL_EMALFDB;
760
+	    break;
761
+	} else {
762
+	    new->line = atoi(pt);
763
+	    free(pt);
764
+	}
765
+
766
+	if((ret = hashset_addkey(&ignored->hs, new->line)))
767
+	    break;
768
+
769
+	if(!(new->signame = cli_strtok(buffer, 2, ":"))) {
770
+	    free(new->dbname);
771
+	    free(new);
772
+	    ret = CL_EMALFDB;
773
+	    break;
774
+	}
775
+
776
+	if(!last) {
777
+	    last = ignored->list = new;
778
+	} else {
779
+	    last->next = new;
780
+	    last = new;
781
+	}
782
+    }
783
+
784
+    if(ret) {
785
+	cli_errmsg("cli_loadign: Problem parsing database at line %u\n", line);
786
+	cl_free(*engine);
787
+	return ret;
788
+    }
789
+
790
+    return CL_SUCCESS;
791
+}
792
+
793
+static void cli_freeign(struct cl_engine *engine)
794
+{
795
+	struct cli_ignsig *pt;
796
+	struct cli_ignored *ignored;
797
+
798
+    if((ignored = engine->ignored)) {
799
+	while(ignored->list) {
800
+	    pt = ignored->list;
801
+	    ignored->list = ignored->list->next;
802
+	    free(pt->dbname);
803
+	    free(pt->signame);
804
+	    free(pt);
805
+	}
806
+	hashset_destroy(&ignored->hs);
807
+	free(engine->ignored);
808
+	engine->ignored = NULL;
809
+    }
810
+}
811
+
718 812
 static int scomp(const void *a, const void *b)
719 813
 {
720 814
     return *(const uint32_t *)a - *(const uint32_t *)b;
... ...
@@ -757,11 +887,11 @@ static int cli_md5db_init(struct cl_engine **engine, unsigned int mode)
757 757
     else			    \
758 758
 	db = (*engine)->md5_fp;
759 759
 
760
-static int cli_loadmd5(FILE *fs, struct cl_engine **engine, unsigned int *signo, unsigned int mode, unsigned int options, gzFile *gzs, unsigned int gzrsize)
760
+static int cli_loadmd5(FILE *fs, struct cl_engine **engine, unsigned int *signo, unsigned int mode, unsigned int options, gzFile *gzs, unsigned int gzrsize, const char *dbname)
761 761
 {
762 762
 	char buffer[FILEBUFF], *pt;
763 763
 	int ret = CL_SUCCESS;
764
-	unsigned int size_field = 1, md5_field = 0, line = 0;
764
+	unsigned int size_field = 1, md5_field = 0, line = 0, sigs = 0;
765 765
 	uint32_t size;
766 766
 	struct cli_bm_patt *new;
767 767
 	struct cli_matcher *db = NULL;
... ...
@@ -818,6 +948,13 @@ static int cli_loadmd5(FILE *fs, struct cl_engine **engine, unsigned int *signo,
818 818
 	    break;
819 819
 	}
820 820
 
821
+	if((*engine)->ignored && cli_chkign((*engine)->ignored, dbname, line, new->virname)) {
822
+	    free(new->virname);
823
+	    free(new->pattern);
824
+	    free(new);
825
+	    continue;
826
+	}
827
+
821 828
 	MD5_DB;
822 829
 	if(!db && (ret = cli_md5db_init(engine, mode))) {
823 830
 	    free(new->pattern);
... ...
@@ -842,6 +979,8 @@ static int cli_loadmd5(FILE *fs, struct cl_engine **engine, unsigned int *signo,
842 842
 	    }
843 843
 	    hashset_addkey(&db->md5_sizes_hs, size);
844 844
 	}
845
+
846
+	sigs++;
845 847
     }
846 848
 
847 849
     if(!line) {
... ...
@@ -857,15 +996,16 @@ static int cli_loadmd5(FILE *fs, struct cl_engine **engine, unsigned int *signo,
857 857
     }
858 858
 
859 859
     if(signo)
860
-	*signo += line;
860
+	*signo += sigs;
861 861
 
862 862
     return CL_SUCCESS;
863 863
 }
864 864
 
865
-static int cli_loadmd(FILE *fs, struct cl_engine **engine, unsigned int *signo, int type, unsigned int options, gzFile *gzs, unsigned int gzrsize)
865
+static int cli_loadmd(FILE *fs, struct cl_engine **engine, unsigned int *signo, int type, unsigned int options, gzFile *gzs, unsigned int gzrsize, const char *dbname)
866 866
 {
867 867
 	char buffer[FILEBUFF], *pt;
868
-	int line = 0, comments = 0, ret = 0, crc;
868
+	unsigned int line = 0, sigs = 0;
869
+	int ret, crc;
869 870
 	struct cli_meta_node *new;
870 871
 
871 872
 
... ...
@@ -876,10 +1016,8 @@ static int cli_loadmd(FILE *fs, struct cl_engine **engine, unsigned int *signo,
876 876
 
877 877
     while(cli_dbgets(buffer, FILEBUFF, fs, gzs, &gzrsize)) {
878 878
 	line++;
879
-	if(buffer[0] == '#') {
880
-	    comments++;
879
+	if(buffer[0] == '#')
881 880
 	    continue;
882
-	}
883 881
 
884 882
 	cli_chomp(buffer);
885 883
 
... ...
@@ -895,6 +1033,12 @@ static int cli_loadmd(FILE *fs, struct cl_engine **engine, unsigned int *signo,
895 895
 	    break;
896 896
 	}
897 897
 
898
+	if((*engine)->ignored && cli_chkign((*engine)->ignored, dbname, line, new->virname)) {
899
+	    free(new->virname);
900
+	    free(new);
901
+	    continue;
902
+	}
903
+
898 904
 	if(!(pt = cli_strtok(buffer, 1, ":"))) {
899 905
 	    free(new->virname);
900 906
 	    free(new);
... ...
@@ -1014,6 +1158,8 @@ static int cli_loadmd(FILE *fs, struct cl_engine **engine, unsigned int *signo,
1014 1014
 	    new->next = (*engine)->rar_mlist;
1015 1015
 	    (*engine)->rar_mlist = new;
1016 1016
 	}
1017
+
1018
+	sigs++;
1017 1019
     }
1018 1020
 
1019 1021
     if(!line) {
... ...
@@ -1029,7 +1175,7 @@ static int cli_loadmd(FILE *fs, struct cl_engine **engine, unsigned int *signo,
1029 1029
     }
1030 1030
 
1031 1031
     if(signo)
1032
-	*signo += (line - comments);
1032
+	*signo += sigs;
1033 1033
 
1034 1034
     return CL_SUCCESS;
1035 1035
 }
... ...
@@ -1041,6 +1187,7 @@ int cli_load(const char *filename, struct cl_engine **engine, unsigned int *sign
1041 1041
 	FILE *fs = NULL;
1042 1042
 	int ret = CL_SUCCESS;
1043 1043
 	uint8_t skipped = 0;
1044
+	const char *dbname;
1044 1045
 
1045 1046
 
1046 1047
     if(!gzs && (fs = fopen(filename, "rb")) == NULL) {
... ...
@@ -1048,83 +1195,97 @@ int cli_load(const char *filename, struct cl_engine **engine, unsigned int *sign
1048 1048
 	return CL_EOPEN;
1049 1049
     }
1050 1050
 
1051
-    if(cli_strbcasestr(filename, ".db")) {
1052
-	ret = cli_loaddb(fs, engine, signo, options, gzs, gzrsize);
1051
+/*
1052
+#ifdef C_WINDOWS
1053
+    if((dbname = strrchr(filename, '\\')))
1054
+#else
1055
+*/
1056
+    if((dbname = strrchr(filename, '/')))
1057
+/*#endif */
1058
+	dbname++;
1059
+    else
1060
+	dbname = filename;
1053 1061
 
1054
-    } else if(cli_strbcasestr(filename, ".cvd")) {
1062
+    if(cli_strbcasestr(dbname, ".db")) {
1063
+	ret = cli_loaddb(fs, engine, signo, options, gzs, gzrsize, dbname);
1064
+
1065
+    } else if(cli_strbcasestr(dbname, ".cvd")) {
1055 1066
 	    int warn = 0;
1056 1067
 
1057
-	if(strstr(filename, "daily.cvd"))
1068
+	if(!strcmp(dbname, "daily.cvd"))
1058 1069
 	    warn = 1;
1059 1070
 
1060 1071
 	ret = cli_cvdload(fs, engine, signo, warn, options, 0);
1061 1072
 
1062
-    } else if(cli_strbcasestr(filename, ".cld")) {
1073
+    } else if(cli_strbcasestr(dbname, ".cld")) {
1063 1074
 	    int warn = 0;
1064 1075
 
1065
-	if(strstr(filename, "daily.cld"))
1076
+	if(!strcmp(dbname, "daily.cld"))
1066 1077
 	    warn = 1;
1067 1078
 
1068 1079
 	ret = cli_cvdload(fs, engine, signo, warn, options | CL_DB_CVDNOTMP, 1);
1069 1080
 
1070
-    } else if(cli_strbcasestr(filename, ".hdb")) {
1071
-	ret = cli_loadmd5(fs, engine, signo, MD5_HDB, options, gzs, gzrsize);
1081
+    } else if(cli_strbcasestr(dbname, ".hdb")) {
1082
+	ret = cli_loadmd5(fs, engine, signo, MD5_HDB, options, gzs, gzrsize, dbname);
1072 1083
 
1073
-    } else if(cli_strbcasestr(filename, ".hdu")) {
1084
+    } else if(cli_strbcasestr(dbname, ".hdu")) {
1074 1085
 	if(options & CL_DB_PUA)
1075
-	    ret = cli_loadmd5(fs, engine, signo, MD5_HDB, options, gzs, gzrsize);
1086
+	    ret = cli_loadmd5(fs, engine, signo, MD5_HDB, options, gzs, gzrsize, dbname);
1076 1087
 	else
1077 1088
 	    skipped = 1;
1078 1089
 
1079
-    } else if(cli_strbcasestr(filename, ".fp")) {
1080
-	ret = cli_loadmd5(fs, engine, signo, MD5_FP, options, gzs, gzrsize);
1090
+    } else if(cli_strbcasestr(dbname, ".fp")) {
1091
+	ret = cli_loadmd5(fs, engine, signo, MD5_FP, options, gzs, gzrsize, dbname);
1081 1092
 
1082
-    } else if(cli_strbcasestr(filename, ".mdb")) {
1083
-	ret = cli_loadmd5(fs, engine, signo, MD5_MDB, options, gzs, gzrsize);
1093
+    } else if(cli_strbcasestr(dbname, ".mdb")) {
1094
+	ret = cli_loadmd5(fs, engine, signo, MD5_MDB, options, gzs, gzrsize, dbname);
1084 1095
 
1085
-    } else if(cli_strbcasestr(filename, ".mdu")) {
1096
+    } else if(cli_strbcasestr(dbname, ".mdu")) {
1086 1097
 	if(options & CL_DB_PUA)
1087
-	    ret = cli_loadmd5(fs, engine, signo, MD5_MDB, options, gzs, gzrsize);
1098
+	    ret = cli_loadmd5(fs, engine, signo, MD5_MDB, options, gzs, gzrsize, dbname);
1088 1099
 	else
1089 1100
 	    skipped = 1;
1090 1101
 
1091
-    } else if(cli_strbcasestr(filename, ".ndb")) {
1092
-	ret = cli_loadndb(fs, engine, signo, 0, options, gzs, gzrsize);
1102
+    } else if(cli_strbcasestr(dbname, ".ndb")) {
1103
+	ret = cli_loadndb(fs, engine, signo, 0, options, gzs, gzrsize, dbname);
1093 1104
 
1094
-    } else if(cli_strbcasestr(filename, ".ndu")) {
1105
+    } else if(cli_strbcasestr(dbname, ".ndu")) {
1095 1106
 	if(!(options & CL_DB_PUA))
1096 1107
 	    skipped = 1;
1097 1108
 	else
1098
-	    ret = cli_loadndb(fs, engine, signo, 0, options, gzs, gzrsize);
1109
+	    ret = cli_loadndb(fs, engine, signo, 0, options, gzs, gzrsize, dbname);
1099 1110
 
1100
-    } else if(cli_strbcasestr(filename, ".sdb")) {
1101
-	ret = cli_loadndb(fs, engine, signo, 1, options, gzs, gzrsize);
1111
+    } else if(cli_strbcasestr(dbname, ".sdb")) {
1112
+	ret = cli_loadndb(fs, engine, signo, 1, options, gzs, gzrsize, dbname);
1102 1113
 
1103
-    } else if(cli_strbcasestr(filename, ".zmd")) {
1104
-	ret = cli_loadmd(fs, engine, signo, 1, options, gzs, gzrsize);
1114
+    } else if(cli_strbcasestr(dbname, ".zmd")) {
1115
+	ret = cli_loadmd(fs, engine, signo, 1, options, gzs, gzrsize, dbname);
1105 1116
 
1106
-    } else if(cli_strbcasestr(filename, ".rmd")) {
1107
-	ret = cli_loadmd(fs, engine, signo, 2, options, gzs, gzrsize);
1117
+    } else if(cli_strbcasestr(dbname, ".rmd")) {
1118
+	ret = cli_loadmd(fs, engine, signo, 2, options, gzs, gzrsize, dbname);
1108 1119
 
1109
-    } else if(cli_strbcasestr(filename, ".cfg")) {
1120
+    } else if(cli_strbcasestr(dbname, ".cfg")) {
1110 1121
 	ret = cli_dconf_load(fs, engine, options, gzs, gzrsize);
1111 1122
 
1112
-    } else if(cli_strbcasestr(filename, ".wdb")) {
1123
+    } else if(cli_strbcasestr(dbname, ".wdb")) {
1113 1124
 	if(options & CL_DB_PHISHING_URLS) {
1114 1125
 	    ret = cli_loadwdb(fs, engine, options, gzs, gzrsize);
1115 1126
 	} else
1116 1127
 	    skipped = 1;
1117
-    } else if(cli_strbcasestr(filename, ".pdb")) {
1128
+    } else if(cli_strbcasestr(dbname, ".pdb")) {
1118 1129
 	if(options & CL_DB_PHISHING_URLS) {
1119 1130
 	    ret = cli_loadpdb(fs, engine, options, gzs, gzrsize);
1120 1131
 	} else
1121 1132
 	    skipped = 1;
1122
-    } else if(cli_strbcasestr(filename, ".ft")) {
1133
+    } else if(cli_strbcasestr(dbname, ".ft")) {
1123 1134
 	ret = cli_loadft(fs, engine, options, 0, gzs, gzrsize);
1124 1135
 
1136
+    } else if(cli_strbcasestr(dbname, ".ign")) {
1137
+	ret = cli_loadign(fs, engine, options, gzs, gzrsize);
1138
+
1125 1139
     } else {
1126 1140
 	cli_dbgmsg("cli_load: unknown extension - assuming old database format\n");
1127
-	ret = cli_loaddb(fs, engine, signo, options, gzs, gzrsize);
1141
+	ret = cli_loaddb(fs, engine, signo, options, gzs, gzrsize, dbname);
1128 1142
     }
1129 1143
 
1130 1144
     if(ret) {
... ...
@@ -1156,23 +1317,41 @@ static int cli_loaddbdir(const char *dirname, struct cl_engine **engine, unsigne
1156 1156
 	    char b[offsetof(struct dirent, d_name) + NAME_MAX + 1];
1157 1157
 	} result;
1158 1158
 #endif
1159
-	struct stat sb;
1160 1159
 	char *dbfile;
1161 1160
 	int ret = CL_ESUPPORT;
1162 1161
 
1163 1162
 
1164 1163
     cli_dbgmsg("Loading databases from %s\n", dirname);
1165
-
1166
-    /* check for and load daily.cfg */
1167
-    dbfile = (char *) cli_malloc(strlen(dirname) + 11);
1164
+    dbfile = (char *) cli_malloc(strlen(dirname) + 20);
1168 1165
     if(!dbfile)
1169 1166
 	return CL_EMEM;
1167
+
1168
+    /* try to load local.ign and daily.cvd/daily.ign first */
1169
+    sprintf(dbfile, "%s/local.ign", dirname);
1170
+    if(!access(dbfile, R_OK) && (ret = cli_load(dbfile, engine, signo, options, NULL, 0))) {
1171
+	free(dbfile);
1172
+	return ret;
1173
+    }
1174
+
1175
+    sprintf(dbfile, "%s/daily.cld", dirname);
1176
+    if(access(dbfile, R_OK))
1177
+	sprintf(dbfile, "%s/daily.cvd", dirname);
1178
+    if(!access(dbfile, R_OK) && (ret = cli_load(dbfile, engine, signo, options, NULL, 0))) {
1179
+	free(dbfile);
1180
+	return ret;
1181
+    }
1182
+
1183
+    sprintf(dbfile, "%s/daily.ign", dirname);
1184
+    if(!access(dbfile, R_OK) && (ret = cli_load(dbfile, engine, signo, options, NULL, 0))) {
1185
+	free(dbfile);
1186
+	return ret;
1187
+    }
1188
+
1189
+    /* check for and load daily.cfg */
1170 1190
     sprintf(dbfile, "%s/daily.cfg", dirname);
1171
-    if(stat(dbfile, &sb) != -1) {
1172
-	if((ret = cli_load(dbfile, engine, signo, options, NULL, 0))) {
1173
-	    free(dbfile);
1174
-	    return ret;
1175
-	}
1191
+    if(!access(dbfile, R_OK) && (ret = cli_load(dbfile, engine, signo, options, NULL, 0))) {
1192
+	free(dbfile);
1193
+	return ret;
1176 1194
     }
1177 1195
     free(dbfile);
1178 1196
 
... ...
@@ -1192,7 +1371,7 @@ static int cli_loaddbdir(const char *dirname, struct cl_engine **engine, unsigne
1192 1192
 	if(dent->d_ino)
1193 1193
 #endif
1194 1194
 	{
1195
-	    if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..") && CLI_DBEXT(dent->d_name)) {
1195
+	    if(strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..") && strcmp(dent->d_name, "daily.cvd") && strcmp(dent->d_name, "daily.cld") && strcmp(dent->d_name, "daily.ign") && strcmp(dent->d_name, "daily.cfg") && strcmp(dent->d_name, "local.ign") && CLI_DBEXT(dent->d_name)) {
1196 1196
 
1197 1197
 		dbfile = (char *) cli_malloc(strlen(dent->d_name) + strlen(dirname) + 2);
1198 1198
 
... ...
@@ -1551,6 +1730,7 @@ void cl_free(struct cl_engine *engine)
1551 1551
 	free(engine->dconf);
1552 1552
 
1553 1553
     cli_ftfree(engine->ftypes);
1554
+    cli_freeign(engine);
1554 1555
     free(engine);
1555 1556
 }
1556 1557
 
... ...
@@ -1589,7 +1769,7 @@ int cl_build(struct cl_engine *engine)
1589 1589
     }
1590 1590
 
1591 1591
     cli_md5db_build(engine->md5_mdb);
1592
-
1592
+    cli_freeign(engine);
1593 1593
     cli_dconf_print(engine->dconf);
1594 1594
 
1595 1595
     return CL_SUCCESS;
... ...
@@ -43,6 +43,7 @@
43 43
 	cli_strbcasestr(ext, ".pdb")   ||	\
44 44
 	cli_strbcasestr(ext, ".wdb")   ||	\
45 45
 	cli_strbcasestr(ext, ".ft")    ||	\
46
+	cli_strbcasestr(ext, ".ign")   ||	\
46 47
 	cli_strbcasestr(ext, ".cvd")   ||	\
47 48
 	cli_strbcasestr(ext, ".cld")		\
48 49
     )