Browse code

dynamic configuration support

git-svn: trunk@2603

Tomasz Kojm authored on 2007/01/10 05:06:51
Showing 10 changed files
... ...
@@ -1,3 +1,7 @@
1
+Tue Jan  9 21:04:03 CET 2007 (tk)
2
+---------------------------------
3
+  * libclamav: dynamic configuration support
4
+
1 5
 Mon Jan  8 22:41:21 CET 2007 (tk)
2 6
 ---------------------------------
3 7
   * libclamav/pe.h: add missing cltypes.h
... ...
@@ -158,6 +158,8 @@ libclamav_la_SOURCES = \
158 158
 	entitylist.h \
159 159
 	encoding_aliases.h \
160 160
 	hashtab.c \
161
-	hashtab.h
161
+	hashtab.h \
162
+	dconf.c \
163
+	dconf.h
162 164
 
163 165
 lib_LTLIBRARIES = libclamav.la
... ...
@@ -88,7 +88,7 @@ am_libclamav_la_OBJECTS = matcher-ac.lo matcher-bm.lo matcher-ncore.lo \
88 88
 	unrarppm.lo unrar20.lo unrarcmd.lo pdf.lo spin.lo yc.lo elf.lo \
89 89
 	sis.lo uuencode.lo pst.lo phishcheck.lo \
90 90
 	phish_domaincheck_db.lo phish_whitelist.lo regex_list.lo \
91
-	sha256.lo mspack.lo cab.lo entconv.lo hashtab.lo
91
+	sha256.lo mspack.lo cab.lo entconv.lo hashtab.lo dconf.lo
92 92
 libclamav_la_OBJECTS = $(am_libclamav_la_OBJECTS)
93 93
 DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
94 94
 depcomp = $(SHELL) $(top_srcdir)/depcomp
... ...
@@ -370,7 +370,9 @@ libclamav_la_SOURCES = \
370 370
 	entitylist.h \
371 371
 	encoding_aliases.h \
372 372
 	hashtab.c \
373
-	hashtab.h
373
+	hashtab.h \
374
+	dconf.c \
375
+	dconf.h
374 376
 
375 377
 lib_LTLIBRARIES = libclamav.la
376 378
 all: all-am
... ...
@@ -447,6 +449,7 @@ distclean-compile:
447 447
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cab.Plo@am__quote@
448 448
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chmunpack.Plo@am__quote@
449 449
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cvd.Plo@am__quote@
450
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dconf.Plo@am__quote@
450 451
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dsig.Plo@am__quote@
451 452
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf.Plo@am__quote@
452 453
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/entconv.Plo@am__quote@
... ...
@@ -186,6 +186,9 @@ struct cl_engine {
186 186
     void *whitelist_matcher;
187 187
     void *domainlist_matcher;
188 188
     void *phishcheck;
189
+
190
+    /* Dynamic configuration */
191
+    void *dconf;
189 192
 };
190 193
 
191 194
 struct cl_limits {
192 195
new file mode 100644
... ...
@@ -0,0 +1,316 @@
0
+/*
1
+ *  Copyright (C) 2007 Tomasz Kojm <tkojm@clamav.net>
2
+ *
3
+ *  This program is free software; you can redistribute it and/or modify
4
+ *  it under the terms of the GNU General Public License version 2 as
5
+ *  published by the Free Software Foundation.
6
+ *
7
+ *  This program is distributed in the hope that it will be useful,
8
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
+ *  GNU General Public License for more details.
11
+ *
12
+ *  You should have received a copy of the GNU General Public License
13
+ *  along with this program; if not, write to the Free Software
14
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
15
+ *  MA 02110-1301, USA.
16
+ */
17
+
18
+#if HAVE_CONFIG_H
19
+#include "clamav-config.h"
20
+#endif
21
+
22
+#include <stdio.h>
23
+#include <string.h>
24
+#include <stdlib.h>
25
+#include <ctype.h>
26
+
27
+#include "clamav.h"
28
+#include "cltypes.h"
29
+#include "dconf.h"
30
+#include "readdb.h"
31
+#include "str.h"
32
+#include "others.h"
33
+
34
+struct dconf_module {
35
+    const char	*mname;	    /* module name */
36
+    const char	*sname;	    /* submodule name */
37
+    uint32_t	bflag;	    /* bit flag */
38
+    uint8_t	state;	    /* default state (on/off) */
39
+};
40
+
41
+static struct dconf_module modules[] = {
42
+
43
+    { "PE",	    "PARITE",	    PE_CONF_PARITE,	    1 },
44
+    { "PE",	    "KRIZ",	    PE_CONF_KRIZ,	    1 },
45
+    { "PE",	    "MAGISTR",	    PE_CONF_MAGISTR,	    1 },
46
+    { "PE",	    "POLIPOS",	    PE_CONF_POLIPOS,	    1 },
47
+    { "PE",	    "MD5SECT",	    PE_CONF_MD5SECT,	    1 },
48
+    { "PE",	    "UPX",	    PE_CONF_UPX,	    1 },
49
+    { "PE",	    "FSG",	    PE_CONF_FSG,	    1 },
50
+    { "PE",	    "SUE",	    PE_CONF_SUE,	    0 },
51
+    { "PE",	    "PETITE",	    PE_CONF_PETITE,	    1 },
52
+    { "PE",	    "PESPIN",	    PE_CONF_PESPIN,	    1 },
53
+    { "PE",	    "YC",	    PE_CONF_YC,		    1 },
54
+    { "PE",	    "WWPACK",	    PE_CONF_WWPACK,	    1 },
55
+    { "PE",	    "NSPACK",	    PE_CONF_NSPACK,	    0 },
56
+
57
+    { "ELF",	    NULL,	    0x1,		    1 },
58
+
59
+    { "ARCHIVE",    "RAR",	    ARCH_CONF_RAR,	    1 },
60
+    { "ARCHIVE",    "ZIP",	    ARCH_CONF_ZIP,	    1 },
61
+    { "ARCHIVE",    "GZIP",	    ARCH_CONF_GZ,	    1 },
62
+    { "ARCHIVE",    "BZIP",	    ARCH_CONF_BZ,	    1 },
63
+    { "ARCHIVE",    "SZDD",	    ARCH_CONF_SZDD,	    1 },
64
+    { "ARCHIVE",    "CAB",	    ARCH_CONF_CAB,	    1 },
65
+    { "ARCHIVE",    "CHM",	    ARCH_CONF_CHM,	    1 },
66
+    { "ARCHIVE",    "OLE2",	    ARCH_CONF_OLE2,	    1 },
67
+    { "ARCHIVE",    "TAR",	    ARCH_CONF_TAR,	    1 },
68
+    { "ARCHIVE",    "BINHEX",	    ARCH_CONF_BINHEX,	    1 },
69
+    { "ARCHIVE",    "SIS",	    ARCH_CONF_SIS,	    1 },
70
+
71
+    { "DOCUMENT",   "HTML",	    DOC_CONF_HTML,	    1 },
72
+    { "DOCUMENT",   "RTF",	    DOC_CONF_RTF,	    1 },
73
+    { "DOCUMENT",   "PDF",	    DOC_CONF_PDF,	    1 },
74
+
75
+    { "MAIL",	    "MBOX",	    MAIL_CONF_MBOX,	    1 },
76
+    { "MAIL",	    "TNEF",	    MAIL_CONF_TNEF,	    1 },
77
+    { "MAIL",	    "PST",	    MAIL_CONF_PST,	    1 },
78
+
79
+    { "OTHER",	    "UUENCODED",    OTHER_CONF_UUENC,	    1 },
80
+    { "OTHER",	    "SCRENC",	    OTHER_CONF_SCRENC,	    1 },
81
+    { "OTHER",	    "RIFF",	    OTHER_CONF_RIFF,	    1 },
82
+    { "OTHER",	    "JPEG",	    OTHER_CONF_JPEG,	    1 },
83
+    { "OTHER",	    "CRYPTFF",	    OTHER_CONF_CRYPTFF,	    1 },
84
+
85
+    { NULL,	    NULL,	    0,			    0 }
86
+};
87
+
88
+struct cli_dconf *cli_dconf_init(void)
89
+{
90
+	unsigned int i;
91
+	struct cli_dconf *dconf;
92
+
93
+
94
+    dconf = (struct cli_dconf *) cli_calloc(sizeof(struct cli_dconf), 1);
95
+    if(!dconf)
96
+	return NULL;
97
+
98
+    for(i = 0; modules[i].mname; i++) {
99
+	if(!strcmp(modules[i].mname, "PE")) {
100
+	    if(modules[i].state)
101
+		dconf->pe |= modules[i].bflag;
102
+
103
+	} else if(!strcmp(modules[i].mname, "ELF")) {
104
+	    if(modules[i].state)
105
+		dconf->elf |= modules[i].bflag;
106
+
107
+	} else if(!strcmp(modules[i].mname, "ARCHIVE")) {
108
+	    if(modules[i].state)
109
+		dconf->archive |= modules[i].bflag;
110
+
111
+	} else if(!strcmp(modules[i].mname, "DOCUMENT")) {
112
+	    if(modules[i].state)
113
+		dconf->doc |= modules[i].bflag;
114
+
115
+	} else if(!strcmp(modules[i].mname, "MAIL")) {
116
+	    if(modules[i].state)
117
+		dconf->mail |= modules[i].bflag;
118
+
119
+	} else if(!strcmp(modules[i].mname, "OTHER")) {
120
+	    if(modules[i].state)
121
+		dconf->other |= modules[i].bflag;
122
+	}
123
+    }
124
+
125
+    return dconf;
126
+}
127
+
128
+void cli_dconf_print(struct cli_dconf *dconf)
129
+{
130
+	uint8_t pe = 0, elf = 0, arch = 0, doc = 0, mail = 0, other = 0;
131
+	unsigned int i;
132
+
133
+
134
+    cli_dbgmsg("Dynamic engine configuration settings:\n");
135
+    cli_dbgmsg("--------------------------------------\n");
136
+
137
+    for(i = 0; modules[i].mname; i++) {
138
+	if(!strcmp(modules[i].mname, "PE")) {
139
+	    if(!pe) {
140
+		cli_dbgmsg("Module PE: %s\n", dconf->pe ? "On" : "Off");
141
+		pe = 1;
142
+	    }
143
+	    if(dconf->pe)
144
+		cli_dbgmsg("   * Submodule %10s:\t%s\n", modules[i].sname, (dconf->pe & modules[i].bflag) ? "On" : "** Off **");
145
+	    else
146
+		continue;
147
+
148
+	} else if(!strcmp(modules[i].mname, "ELF")) {
149
+	    if(!elf) {
150
+		cli_dbgmsg("Module ELF: %s\n", dconf->elf ? "On" : "Off");
151
+		elf = 1;
152
+	    }
153
+
154
+	} else if(!strcmp(modules[i].mname, "ARCHIVE")) {
155
+	    if(!arch) {
156
+		cli_dbgmsg("Module ARCHIVE: %s\n", dconf->archive ? "On" : "Off");
157
+		arch = 1;
158
+	    }
159
+	    if(dconf->archive)
160
+		cli_dbgmsg("   * Submodule %10s:\t%s\n", modules[i].sname, (dconf->archive & modules[i].bflag) ? "On" : "** Off **");
161
+	    else
162
+		continue;
163
+
164
+	} else if(!strcmp(modules[i].mname, "DOCUMENT")) {
165
+	    if(!doc) {
166
+		cli_dbgmsg("Module DOCUMENT: %s\n", dconf->doc ? "On" : "Off");
167
+		doc = 1;
168
+	    }
169
+	    if(dconf->doc)
170
+		cli_dbgmsg("   * Submodule %10s:\t%s\n", modules[i].sname, (dconf->doc & modules[i].bflag) ? "On" : "** Off **");
171
+	    else
172
+		continue;
173
+
174
+	} else if(!strcmp(modules[i].mname, "MAIL")) {
175
+	    if(!mail) {
176
+		cli_dbgmsg("Module MAIL: %s\n", dconf->mail ? "On" : "Off");
177
+		mail = 1;
178
+	    }
179
+	    if(dconf->mail)
180
+		cli_dbgmsg("   * Submodule %10s:\t%s\n", modules[i].sname, (dconf->mail & modules[i].bflag) ? "On" : "** Off **");
181
+	    else
182
+		continue;
183
+
184
+	} else if(!strcmp(modules[i].mname, "OTHER")) {
185
+	    if(!other) {
186
+		cli_dbgmsg("Module OTHER: %s\n", dconf->other ? "On" : "Off");
187
+		other = 1;
188
+	    }
189
+	    if(dconf->other)
190
+		cli_dbgmsg("   * Submodule %10s:\t%s\n", modules[i].sname, (dconf->other & modules[i].bflag) ? "On" : "** Off **");
191
+	    else
192
+		continue;
193
+	}
194
+    }
195
+}
196
+
197
+static int chkflevel(const char *entry, int field)
198
+{
199
+	char *pt;
200
+
201
+
202
+    if((pt = cli_strtok(entry, field, ":"))) { /* min version */
203
+	if(!isdigit(*pt)) {
204
+	    free(pt);
205
+	    return 0;
206
+	}
207
+
208
+	if((unsigned int) atoi(pt) > cl_retflevel()) {
209
+	    free(pt);
210
+	    return 0;
211
+	}
212
+
213
+	free(pt);
214
+
215
+	if((pt = cli_strtok(entry, field + 1, ":"))) { /* max version */
216
+	    if(!isdigit(*pt)) {
217
+		free(pt);
218
+		return 0;
219
+	    }
220
+
221
+	    if((unsigned int) atoi(pt) < cl_retflevel()) {
222
+		free(pt);
223
+		return 0;
224
+	    }
225
+
226
+	    free(pt);
227
+	}
228
+    }
229
+
230
+    return 1;
231
+}
232
+
233
+int cli_dconf_load(FILE *fd, struct cl_engine **engine, unsigned int options)
234
+{
235
+	char buffer[FILEBUFF];
236
+	unsigned int line = 0;
237
+	int ret = 0;
238
+	struct cli_dconf *dconf;
239
+	uint32_t val;
240
+
241
+
242
+    if((ret = cli_initengine(engine, options))) {
243
+	cl_free(*engine);
244
+	return ret;
245
+    }
246
+
247
+    dconf = (struct cli_dconf *) (*engine)->dconf;
248
+
249
+    while(fgets(buffer, FILEBUFF, fd)) {
250
+	line++;
251
+	cli_chomp(buffer);
252
+
253
+	if(!strncmp(buffer, "PE:", 3) && chkflevel(buffer, 2)) {
254
+	    if(sscanf(buffer + 3, "0x%x", &val) == 1) {
255
+		dconf->pe = val;
256
+	    } else {
257
+		ret = CL_EMALFDB;
258
+		break;
259
+	    }
260
+	}
261
+
262
+	if(!strncmp(buffer, "ELF:", 4) && chkflevel(buffer, 2)) {
263
+	    if(sscanf(buffer + 4, "0x%x", &val) == 1) {
264
+		dconf->elf = val;
265
+	    } else {
266
+		ret = CL_EMALFDB;
267
+		break;
268
+	    }
269
+	}
270
+
271
+	if(!strncmp(buffer, "ARCHIVE:", 8) && chkflevel(buffer, 2)) {
272
+	    if(sscanf(buffer + 8, "0x%x", &val) == 1) {
273
+		dconf->archive = val;
274
+	    } else {
275
+		ret = CL_EMALFDB;
276
+		break;
277
+	    }
278
+	}
279
+
280
+	if(!strncmp(buffer, "DOCUMENT:", 9) && chkflevel(buffer, 2)) {
281
+	    if(sscanf(buffer + 9, "0x%x", &val) == 1) {
282
+		dconf->doc = val;
283
+	    } else {
284
+		ret = CL_EMALFDB;
285
+		break;
286
+	    }
287
+	}
288
+
289
+	if(!strncmp(buffer, "MAIL:", 5) && chkflevel(buffer, 2)) {
290
+	    if(sscanf(buffer + 5, "0x%x", &val) == 1) {
291
+		dconf->mail = val;
292
+	    } else {
293
+		ret = CL_EMALFDB;
294
+		break;
295
+	    }
296
+	}
297
+
298
+	if(!strncmp(buffer, "OTHER:", 6) && chkflevel(buffer, 2)) {
299
+	    if(sscanf(buffer + 6, "0x%x", &val) == 1) {
300
+		dconf->other = val;
301
+	    } else {
302
+		ret = CL_EMALFDB;
303
+		break;
304
+	    }
305
+	}
306
+    }
307
+
308
+    if(ret) {
309
+	cli_errmsg("Problem parsing configuration file at line %u\n", line);
310
+	cl_free(*engine);
311
+	return ret;
312
+    }
313
+
314
+    return CL_SUCCESS;
315
+}
0 316
new file mode 100644
... ...
@@ -0,0 +1,86 @@
0
+/*
1
+ *  Copyright (C) 2007 Tomasz Kojm <tkojm@clamav.net>
2
+ *
3
+ *  This program is free software; you can redistribute it and/or modify
4
+ *  it under the terms of the GNU General Public License version 2 as
5
+ *  published by the Free Software Foundation.
6
+ *
7
+ *  This program is distributed in the hope that it will be useful,
8
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
+ *  GNU General Public License for more details.
11
+ *
12
+ *  You should have received a copy of the GNU General Public License
13
+ *  along with this program; if not, write to the Free Software
14
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
15
+ *  MA 02110-1301, USA.
16
+ */
17
+
18
+#ifndef __DCONF_H
19
+#define __DCONF_H
20
+
21
+#include <stdio.h>
22
+
23
+#include "clamav.h"
24
+#include "cltypes.h"
25
+
26
+struct cli_dconf {
27
+    uint32_t pe;
28
+    uint32_t elf;
29
+    uint32_t archive;
30
+    uint32_t doc;
31
+    uint32_t mail;
32
+    uint32_t other;
33
+};
34
+
35
+/* PE flags */
36
+#define PE_CONF_PARITE	    0x1
37
+#define PE_CONF_KRIZ	    0x2
38
+#define PE_CONF_MAGISTR	    0x4
39
+#define PE_CONF_POLIPOS	    0x8
40
+#define PE_CONF_MD5SECT	    0x10
41
+#define PE_CONF_UPX	    0x20
42
+#define PE_CONF_FSG	    0x40
43
+#define PE_CONF_SUE	    0x80
44
+#define PE_CONF_PETITE	    0x100
45
+#define PE_CONF_PESPIN	    0x200
46
+#define PE_CONF_YC	    0x400
47
+#define PE_CONF_WWPACK	    0x800
48
+#define PE_CONF_NSPACK	    0x1000
49
+
50
+/* Archive flags */
51
+#define ARCH_CONF_RAR	    0x1
52
+#define ARCH_CONF_ZIP	    0x2
53
+#define ARCH_CONF_GZ	    0x4
54
+#define ARCH_CONF_BZ	    0x8
55
+#define ARCH_CONF_SZDD	    0x10
56
+#define ARCH_CONF_CAB	    0x20
57
+#define ARCH_CONF_CHM	    0x40
58
+#define ARCH_CONF_OLE2	    0x80
59
+#define ARCH_CONF_TAR	    0x100
60
+#define ARCH_CONF_BINHEX    0x200
61
+#define ARCH_CONF_SIS	    0x400
62
+
63
+/* Document flags */
64
+#define DOC_CONF_HTML	    0x1
65
+#define DOC_CONF_RTF	    0x2
66
+#define DOC_CONF_PDF	    0x4
67
+
68
+/* Mail flags */
69
+#define MAIL_CONF_MBOX	    0x1
70
+#define MAIL_CONF_TNEF	    0x2
71
+#define MAIL_CONF_PST	    0x4
72
+
73
+/* Other flags */
74
+#define OTHER_CONF_UUENC    0x1
75
+#define OTHER_CONF_SCRENC   0x2
76
+#define OTHER_CONF_RIFF	    0x4
77
+#define OTHER_CONF_JPEG	    0x8
78
+#define OTHER_CONF_CRYPTFF  0x10
79
+
80
+
81
+struct cli_dconf *cli_dconf_init(void);
82
+void cli_dconf_print(struct cli_dconf *dconf);
83
+int cli_dconf_load(FILE *fd, struct cl_engine **engine, unsigned int options);
84
+
85
+#endif
... ...
@@ -25,6 +25,7 @@
25 25
 #include "cltypes.h"
26 26
 
27 27
 #include "clamav.h"
28
+#include "dconf.h"
28 29
 
29 30
 /*
30 31
  * CLI_ISCONTAINED(buf1, size1, buf2, size2) checks if buf2 is contained
... ...
@@ -55,6 +56,7 @@ typedef struct {
55 55
     unsigned int options;
56 56
     unsigned int arec;
57 57
     unsigned int mrec;
58
+    struct cli_dconf *dconf;
58 59
 } cli_ctx;
59 60
 
60 61
 #define SCAN_ARCHIVE	    (ctx->options & CL_SCAN_ARCHIVE)
... ...
@@ -54,6 +54,8 @@
54 54
 #define	O_BINARY	0
55 55
 #endif
56 56
 
57
+#define DCONF ctx->dconf->pe
58
+
57 59
 #define IMAGE_DOS_SIGNATURE	    0x5a4d	    /* MZ */
58 60
 #define IMAGE_DOS_SIGNATURE_OLD	    0x4d5a          /* ZM */
59 61
 #define IMAGE_NT_SIGNATURE	    0x00004550
... ...
@@ -692,7 +694,11 @@ int cli_scanpe(int desc, cli_ctx *ctx)
692 692
 	    }
693 693
 	    
694 694
 	    /* check MD5 section sigs */
695
-	    md5_sect = ctx->engine->md5_sect;
695
+	    if(DCONF & PE_CONF_MD5SECT)
696
+		md5_sect = ctx->engine->md5_sect;
697
+	    else
698
+		md5_sect = NULL;
699
+
696 700
 	    while(md5_sect && md5_sect->size < exe_sections[i].rsz)
697 701
 	        md5_sect = md5_sect->next;
698 702
 
... ...
@@ -741,7 +747,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
741 741
 	        max = exe_sections[i].rva + exe_sections[i].rsz;
742 742
 	}
743 743
 
744
-	if(SCAN_ALGO && !strlen(sname)) {
744
+	if(SCAN_ALGO && (DCONF & PE_CONF_POLIPOS) && !strlen(sname)) {
745 745
 	    if(exe_sections[i].vsz > 40000 && exe_sections[i].vsz < 70000) {
746 746
 		if(EC32(section_hdr[i].Characteristics) == 0xe0000060) {
747 747
 		    polipos = i;
... ...
@@ -774,7 +780,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
774 774
     /* Attempt to detect some popular polymorphic viruses */
775 775
 
776 776
     /* W32.Parite.B */
777
-    if(SCAN_ALGO && !dll && ep == exe_sections[nsections - 1].raw) {
777
+    if(SCAN_ALGO && (DCONF & PE_CONF_PARITE) && !dll && ep == exe_sections[nsections - 1].raw) {
778 778
 	lseek(desc, ep, SEEK_SET);
779 779
 	if(cli_readn(desc, buff, 4096) == 4096) {
780 780
 		const char *pt = cli_memstr(buff, 4040, "\x47\x65\x74\x50\x72\x6f\x63\x41\x64\x64\x72\x65\x73\x73\x00", 15);
... ...
@@ -793,7 +799,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
793 793
     }
794 794
 
795 795
     /* Kriz */
796
-    if(SCAN_ALGO && CLI_ISCONTAINED(exe_sections[nsections - 1].raw, exe_sections[nsections - 1].rsz, ep, 0x0fd2)) {
796
+    if(SCAN_ALGO && (DCONF & PE_CONF_KRIZ) && CLI_ISCONTAINED(exe_sections[nsections - 1].raw, exe_sections[nsections - 1].rsz, ep, 0x0fd2)) {
797 797
 	cli_dbgmsg("in kriz\n");
798 798
 	lseek(desc, ep, SEEK_SET);
799 799
 	if(cli_readn(desc, buff, 200) == 200) {
... ...
@@ -855,7 +861,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
855 855
     }
856 856
 
857 857
     /* W32.Magistr.A/B */
858
-    if(SCAN_ALGO && !dll && (EC32(section_hdr[nsections - 1].Characteristics) & 0x80000000)) {
858
+    if(SCAN_ALGO && (DCONF & PE_CONF_MAGISTR) && !dll && (EC32(section_hdr[nsections - 1].Characteristics) & 0x80000000)) {
859 859
 	    uint32_t rsize, vsize, dam = 0;
860 860
 
861 861
 	vsize = exe_sections[nsections - 1].uvsz;
... ...
@@ -986,11 +992,9 @@ int cli_scanpe(int desc, cli_ctx *ctx)
986 986
 	}
987 987
     }
988 988
 
989
-
990
-#ifdef CL_EXPERIMENTAL
991 989
     /* SUE */
992 990
     
993
-    if(nsections > 2 && vep == exe_sections[nsections - 1].rva && exe_sections[nsections - 1].rsz > 0x350 && exe_sections[nsections - 1].rsz < 0x292+0x350+1000) {
991
+    if((DCONF & PE_CONF_SUE) && nsections > 2 && vep == exe_sections[nsections - 1].rva && exe_sections[nsections - 1].rsz > 0x350 && exe_sections[nsections - 1].rsz < 0x292+0x350+1000) {
994 992
   
995 993
       
996 994
       char *sue=buff+0x74;
... ...
@@ -1066,17 +1070,18 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1066 1066
       }
1067 1067
 
1068 1068
     }
1069
-#endif
1070 1069
 
1071 1070
     /* UPX & FSG support */
1072 1071
 
1073 1072
     /* try to find the first section with physical size == 0 */
1074 1073
     found = 0;
1075
-    for(i = 0; i < (unsigned int) nsections - 1; i++) {
1076
-	if(!section_hdr[i].SizeOfRawData && section_hdr[i].VirtualSize && section_hdr[i + 1].SizeOfRawData && section_hdr[i + 1].VirtualSize) {
1077
-	    found = 1;
1078
-	    cli_dbgmsg("UPX/FSG: empty section found - assuming compression\n");
1079
-	    break;
1074
+    if(DCONF & (PE_CONF_UPX | PE_CONF_FSG)) {
1075
+	for(i = 0; i < (unsigned int) nsections - 1; i++) {
1076
+	    if(!section_hdr[i].SizeOfRawData && section_hdr[i].VirtualSize && section_hdr[i + 1].SizeOfRawData && section_hdr[i + 1].VirtualSize) {
1077
+		found = 1;
1078
+		cli_dbgmsg("UPX/FSG: empty section found - assuming compression\n");
1079
+		break;
1080
+	    }
1080 1081
 	}
1081 1082
     }
1082 1083
 
... ...
@@ -1098,7 +1103,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1098 1098
 	    return CL_CLEAN;
1099 1099
 	}
1100 1100
 
1101
-	if(buff[0] == '\x87' && buff[1] == '\x25') {
1101
+	if((DCONF & PE_CONF_FSG) && buff[0] == '\x87' && buff[1] == '\x25') {
1102 1102
 
1103 1103
 	    /* FSG v2.0 support - thanks to aCaB ! */
1104 1104
 
... ...
@@ -1270,7 +1275,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1270 1270
 	    }
1271 1271
 	}
1272 1272
 
1273
- 	if(found && buff[0] == '\xbe' && cli_readint32(buff + 1) - EC32(optional_hdr32.ImageBase) < min) {
1273
+ 	if(found && (DCONF & PE_CONF_FSG) && buff[0] == '\xbe' && cli_readint32(buff + 1) - EC32(optional_hdr32.ImageBase) < min) {
1274 1274
 
1275 1275
 	    /* FSG support - v. 1.33 (thx trog for the many samples) */
1276 1276
 
... ...
@@ -1493,7 +1498,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1493 1493
 	}
1494 1494
 
1495 1495
 	/* FIXME: easy 2 hack */
1496
- 	if(found && buff[0] == '\xbb' && cli_readint32(buff + 1) - EC32(optional_hdr32.ImageBase) < min && buff[5] == '\xbf' && buff[10] == '\xbe' && vep >= exe_sections[i + 1].rva && vep - exe_sections[i + 1].rva > exe_sections[i + 1].rva - 0xe0 ) {
1496
+ 	if(found && (DCONF & PE_CONF_FSG) && buff[0] == '\xbb' && cli_readint32(buff + 1) - EC32(optional_hdr32.ImageBase) < min && buff[5] == '\xbf' && buff[10] == '\xbe' && vep >= exe_sections[i + 1].rva && vep - exe_sections[i + 1].rva > exe_sections[i + 1].rva - 0xe0 ) {
1497 1497
 
1498 1498
 	    /* FSG support - v. 1.31 */
1499 1499
 
... ...
@@ -1712,7 +1717,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1712 1712
 	}
1713 1713
 
1714 1714
 
1715
-	if(found) {
1715
+	if(found && (DCONF & PE_CONF_UPX)) {
1716 1716
 
1717 1717
 	    /* UPX support */
1718 1718
 
... ...
@@ -1938,7 +1943,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
1938 1938
 	    found = 1;
1939 1939
     }
1940 1940
 
1941
-    if(found) {
1941
+    if((DCONF & PE_CONF_PETITE) && found) {
1942 1942
 	cli_dbgmsg("Petite: v2.%d compression detected\n", found);
1943 1943
 
1944 1944
 	if(cli_readint32(buff + 0x80) == 0x163c988d) {
... ...
@@ -2029,7 +2034,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
2029 2029
 
2030 2030
     /* PESpin 1.1 */
2031 2031
 
2032
-    if(nsections > 1 &&
2032
+    if((DCONF & PE_CONF_PESPIN) && nsections > 1 &&
2033 2033
        vep >= EC32(section_hdr[nsections - 1].VirtualAddress) &&
2034 2034
        vep < EC32(section_hdr[nsections - 1].VirtualAddress) + EC32(section_hdr[nsections - 1].SizeOfRawData) - 0x3217 - 4 &&
2035 2035
        memcmp(buff+4, "\xe8\x00\x00\x00\x00\x8b\x1c\x24\x83\xc3", 10) == 0)  {
... ...
@@ -2127,7 +2132,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
2127 2127
 
2128 2128
     /* yC 1.3 */
2129 2129
 
2130
-    if(nsections > 1 &&
2130
+    if((DCONF & PE_CONF_YC) && nsections > 1 &&
2131 2131
        EC32(optional_hdr32.AddressOfEntryPoint) == EC32(section_hdr[nsections - 1].VirtualAddress) + 0x60 &&
2132 2132
        memcmp(buff, "\x55\x8B\xEC\x53\x56\x57\x60\xE8\x00\x00\x00\x00\x5D\x81\xED\x6C\x28\x40\x00\xB9\x5D\x34\x40\x00\x81\xE9\xC6\x28\x40\x00\x8B\xD5\x81\xC2\xC6\x28\x40\x00\x8D\x3A\x8B\xF7\x33\xC0\xEB\x04\x90\xEB\x01\xC2\xAC", 51) == 0)  {
2133 2133
 
... ...
@@ -2203,7 +2208,7 @@ int cli_scanpe(int desc, cli_ctx *ctx)
2203 2203
 
2204 2204
     /* WWPack */
2205 2205
 
2206
-    if(nsections > 1 &&
2206
+    if((DCONF & PE_CONF_WWPACK) && nsections > 1 &&
2207 2207
        exe_sections[nsections-1].raw>0x2b1 &&
2208 2208
        vep == exe_sections[nsections - 1].rva &&
2209 2209
        exe_sections[nsections - 1].rva + exe_sections[nsections - 1].rsz == max &&
... ...
@@ -2337,10 +2342,9 @@ int cli_scanpe(int desc, cli_ctx *ctx)
2337 2337
       }
2338 2338
     }
2339 2339
 
2340
-#ifdef CL_EXPERIMENTAL
2341 2340
     /* NsPack */
2342 2341
 
2343
-    while (1) {
2342
+    while (DCONF & PE_CONF_NSPACK) {
2344 2343
       uint32_t eprva = vep;
2345 2344
       uint32_t start_of_stuff, ssize, dsize, rep = ep;
2346 2345
       unsigned int nowinldr;
... ...
@@ -2452,7 +2456,6 @@ int cli_scanpe(int desc, cli_ctx *ctx)
2452 2452
       free(tempfile);
2453 2453
       break;
2454 2454
     }
2455
-#endif /* CL_EXPERIMENTAL - NsPack */
2456 2455
 
2457 2456
     /* to be continued ... */
2458 2457
 
... ...
@@ -48,6 +48,7 @@
48 48
 #include "others.h"
49 49
 #include "str.h"
50 50
 #include "defaults.h"
51
+#include "dconf.h"
51 52
 
52 53
 #ifdef CL_EXPERIMENTAL
53 54
 #include "phish_whitelist.h"
... ...
@@ -499,6 +500,12 @@ int cli_initengine(struct cl_engine **engine, unsigned int options)
499 499
 	    cli_errmsg("Can't allocate memory for roots!\n");
500 500
 	    return CL_EMEM;
501 501
 	}
502
+
503
+	(*engine)->dconf = cli_dconf_init();
504
+	if(!(*engine)->dconf) {
505
+	    cli_errmsg("Can't initialize dynamic configuration\n");
506
+	    return CL_EMEM;
507
+	}
502 508
     }
503 509
 
504 510
 #ifdef CL_EXPERIMENTAL
... ...
@@ -1159,6 +1166,9 @@ static int cli_load(const char *filename, struct cl_engine **engine, unsigned in
1159 1159
     } else if(cli_strbcasestr(filename, ".rmd")) {
1160 1160
 	ret = cli_loadmd(fd, engine, signo, 2, options);
1161 1161
 
1162
+    } else if(cli_strbcasestr(filename, ".cfg")) {
1163
+	ret = cli_dconf_load(fd, engine, options);
1164
+
1162 1165
     } else if(cli_strbcasestr(filename, ".ncdb")) {
1163 1166
 #ifdef HAVE_NCORE
1164 1167
 	if(options & CL_DB_NCORE)
... ...
@@ -1243,6 +1253,7 @@ static int cli_loaddbdir(const char *dirname, struct cl_engine **engine, unsigne
1243 1243
 	     cli_strbcasestr(dent->d_name, ".sdb")  ||
1244 1244
 	     cli_strbcasestr(dent->d_name, ".zmd")  ||
1245 1245
 	     cli_strbcasestr(dent->d_name, ".rmd")  ||
1246
+	     cli_strbcasestr(dent->d_name, ".cfg")  ||
1246 1247
 #ifdef CL_EXPERIMENTAL
1247 1248
 	     cli_strbcasestr(dent->d_name, ".pdb")  ||
1248 1249
 	     cli_strbcasestr(dent->d_name, ".wdb")  ||
... ...
@@ -1298,15 +1309,22 @@ int cl_load(const char *path, struct cl_engine **engine, unsigned int *signo, un
1298 1298
 
1299 1299
     switch(sb.st_mode & S_IFMT) {
1300 1300
 	case S_IFREG: 
1301
-	    return cli_load(path, engine, signo, options);
1301
+	    ret = cli_load(path, engine, signo, options);
1302
+	    break;
1302 1303
 
1303 1304
 	case S_IFDIR:
1304
-	    return cli_loaddbdir(path, engine, signo, options);
1305
+	    ret = cli_loaddbdir(path, engine, signo, options);
1306
+	    break;
1305 1307
 
1306 1308
 	default:
1307
-	    cli_errmsg("cl_load(): Not supported database file type\n");
1309
+	    cli_errmsg("cl_load(%s): Not supported database file type\n", path);
1308 1310
 	    return CL_EOPEN;
1309 1311
     }
1312
+
1313
+    if(ret == CL_SUCCESS)
1314
+	cli_dconf_print((*engine)->dconf);
1315
+
1316
+    return ret;
1310 1317
 }
1311 1318
 
1312 1319
 const char *cl_retdbdir(void)
... ...
@@ -1366,6 +1384,7 @@ int cl_statinidir(const char *dirname, struct cl_stat *dbstat)
1366 1366
 	    cli_strbcasestr(dent->d_name, ".sdb")  || 
1367 1367
 	    cli_strbcasestr(dent->d_name, ".zmd")  || 
1368 1368
 	    cli_strbcasestr(dent->d_name, ".rmd")  || 
1369
+	    cli_strbcasestr(dent->d_name, ".cfg")  ||
1369 1370
 #ifdef CL_EXPERIMENTAL
1370 1371
 	    cli_strbcasestr(dent->d_name, ".pdb")  ||
1371 1372
 	    cli_strbcasestr(dent->d_name, ".wdb")  ||
... ...
@@ -1452,6 +1471,7 @@ int cl_statchkdir(const struct cl_stat *dbstat)
1452 1452
 	    cli_strbcasestr(dent->d_name, ".sdb")  || 
1453 1453
 	    cli_strbcasestr(dent->d_name, ".zmd")  || 
1454 1454
 	    cli_strbcasestr(dent->d_name, ".rmd")  || 
1455
+	    cli_strbcasestr(dent->d_name, ".cfg")  ||
1455 1456
 #ifdef CL_EXPERIMENTAL
1456 1457
 	    cli_strbcasestr(dent->d_name, ".pdb")  ||
1457 1458
 	    cli_strbcasestr(dent->d_name, ".wdb")  ||
... ...
@@ -1563,16 +1583,19 @@ void cl_free(struct cl_engine *engine)
1563 1563
 	cli_ncore_unload(engine);
1564 1564
 #endif
1565 1565
 
1566
-    for(i = 0; i < CL_TARGET_TABLE_SIZE; i++) {
1567
-	if((root = engine->root[i])) {
1568
-	    cli_ac_free(root);
1569
-	    if(!engine->root[i]->ac_only)
1570
-		cli_bm_free(root);
1571
-	    free(root);
1566
+    if(engine->root) {
1567
+	for(i = 0; i < CL_TARGET_TABLE_SIZE; i++) {
1568
+	    if((root = engine->root[i])) {
1569
+		cli_ac_free(root);
1570
+		if(!engine->root[i]->ac_only)
1571
+		    cli_bm_free(root);
1572
+		free(root);
1573
+	    }
1572 1574
 	}
1575
+
1576
+	free(engine->root);
1573 1577
     }
1574 1578
 
1575
-    free(engine->root);
1576 1579
     if(engine->md5_hlist) {
1577 1580
 	for(i = 0; i < 256; i++) {
1578 1581
 	    md5pt = engine->md5_hlist[i];
... ...
@@ -1612,6 +1635,10 @@ void cl_free(struct cl_engine *engine)
1612 1612
 #ifdef CL_EXPERIMENTAL
1613 1613
     phishing_done(engine);
1614 1614
 #endif
1615
+
1616
+    if(engine->dconf)
1617
+	free(engine->dconf);
1618
+
1615 1619
     free(engine);
1616 1620
 }
1617 1621
 
... ...
@@ -52,8 +52,14 @@
52 52
 
53 53
 extern short cli_leavetemps_flag;
54 54
 
55
+#define DCONF_ARCH  ctx->dconf->archive
56
+#define DCONF_DOC   ctx->dconf->doc
57
+#define DCONF_MAIL  ctx->dconf->mail
58
+#define DCONF_OTHER ctx->dconf->other
59
+
55 60
 #include "clamav.h"
56 61
 #include "others.h"
62
+#include "dconf.h"
57 63
 #include "scanners.h"
58 64
 #include "matcher-ac.h"
59 65
 #include "matcher-bm.h"
... ...
@@ -1615,13 +1621,13 @@ static int cli_scanraw(int desc, cli_ctx *ctx, cli_file_t type)
1615 1615
 	ret == CL_TYPE_MAIL ? ctx->mrec++ : ctx->arec++;
1616 1616
 	switch(ret) {
1617 1617
 	    case CL_TYPE_HTML:
1618
-		if(SCAN_HTML && type == CL_TYPE_UNKNOWN_TEXT)
1618
+		if(SCAN_HTML && type == CL_TYPE_UNKNOWN_TEXT && (DCONF_DOC & DOC_CONF_HTML))
1619 1619
 		    if((nret = cli_scanhtml(desc, ctx)) == CL_VIRUS)
1620 1620
 			return CL_VIRUS;
1621 1621
 		break;
1622 1622
 
1623 1623
 	    case CL_TYPE_MAIL:
1624
-		if(SCAN_MAIL && type == CL_TYPE_UNKNOWN_TEXT)
1624
+		if(SCAN_MAIL && type == CL_TYPE_UNKNOWN_TEXT && (DCONF_MAIL & MAIL_CONF_MBOX))
1625 1625
 		    if((nret = cli_scanmail(desc, ctx)) == CL_VIRUS)
1626 1626
 			return CL_VIRUS;
1627 1627
 		break;
... ...
@@ -1634,15 +1640,15 @@ static int cli_scanraw(int desc, cli_ctx *ctx, cli_file_t type)
1634 1634
 			lastzip = lastrar = 0xdeadbeef;
1635 1635
 			fpt = ftoffset;
1636 1636
 			while(fpt) {
1637
-			    if(fpt->type == CL_TYPE_RARSFX) {
1637
+			    if(fpt->type == CL_TYPE_RARSFX && (DCONF_ARCH & ARCH_CONF_RAR)) {
1638 1638
 				cli_dbgmsg("RAR-SFX signature found at %d\n", fpt->offset);
1639 1639
 				if((nret = cli_scanrar(desc, ctx, fpt->offset, &lastrar)) == CL_VIRUS)
1640 1640
 				    break;
1641
-			    } else if(fpt->type == CL_TYPE_ZIPSFX) {
1641
+			    } else if(fpt->type == CL_TYPE_ZIPSFX && (DCONF_ARCH & ARCH_CONF_ZIP)) {
1642 1642
 				cli_dbgmsg("ZIP-SFX signature found at %d\n", fpt->offset);
1643 1643
 				if((nret = cli_scanzip(desc, ctx, fpt->offset, &lastzip)) == CL_VIRUS)
1644 1644
 				    break;
1645
-			    } else if(fpt->type == CL_TYPE_CABSFX) {
1645
+			    } else if(fpt->type == CL_TYPE_CABSFX && (DCONF_ARCH & ARCH_CONF_CAB)) {
1646 1646
 				cli_dbgmsg("CAB-SFX signature found at %d\n", fpt->offset);
1647 1647
 				if((nret = cli_scanmscab(desc, ctx, fpt->offset)) == CL_VIRUS)
1648 1648
 				    break;
... ...
@@ -1733,124 +1739,129 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
1733 1733
 
1734 1734
     switch(type) {
1735 1735
 	case CL_TYPE_RAR:
1736
-	    if(SCAN_ARCHIVE)
1736
+	    if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_RAR))
1737 1737
 		ret = cli_scanrar(desc, ctx, 0, NULL);
1738 1738
 	    break;
1739 1739
 
1740 1740
 	case CL_TYPE_ZIP:
1741
-	    if(SCAN_ARCHIVE)
1741
+	    if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ZIP))
1742 1742
 		ret = cli_scanzip(desc, ctx, 0, NULL);
1743 1743
 	    break;
1744 1744
 
1745 1745
 	case CL_TYPE_GZ:
1746
-	    if(SCAN_ARCHIVE)
1746
+	    if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_GZ))
1747 1747
 		ret = cli_scangzip(desc, ctx);
1748 1748
 	    break;
1749 1749
 
1750 1750
 	case CL_TYPE_BZ:
1751 1751
 #ifdef HAVE_BZLIB_H
1752
-	    if(SCAN_ARCHIVE)
1752
+	    if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_BZ))
1753 1753
 		ret = cli_scanbzip(desc, ctx);
1754 1754
 #endif
1755 1755
 	    break;
1756 1756
 
1757 1757
 	case CL_TYPE_MSSZDD:
1758
-	    if(SCAN_ARCHIVE)
1758
+	    if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_SZDD))
1759 1759
 		ret = cli_scanszdd(desc, ctx);
1760 1760
 	    break;
1761 1761
 
1762 1762
 	case CL_TYPE_MSCAB:
1763
-	    if(SCAN_ARCHIVE)
1763
+	    if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CAB))
1764 1764
 		ret = cli_scanmscab(desc, ctx, 0);
1765 1765
 	    break;
1766 1766
 
1767 1767
 	case CL_TYPE_HTML:
1768
-	    if(SCAN_HTML)
1768
+	    if(SCAN_HTML && (DCONF_DOC & DOC_CONF_HTML))
1769 1769
 		ret = cli_scanhtml(desc, ctx);
1770 1770
 	    break;
1771 1771
 
1772 1772
 	case CL_TYPE_HTML_UTF16:
1773
-	    if(SCAN_HTML)
1773
+	    if(SCAN_HTML && (DCONF_DOC & DOC_CONF_HTML))
1774 1774
 		ret = cli_scanhtml_utf16(desc, ctx);
1775 1775
 	    break;
1776 1776
 
1777 1777
 	case CL_TYPE_RTF:
1778
-	    ret = cli_scanrtf(desc, ctx);
1778
+	    if(DCONF_DOC & DOC_CONF_RTF)
1779
+		ret = cli_scanrtf(desc, ctx);
1779 1780
 	    break;
1780 1781
 
1781 1782
 	case CL_TYPE_MAIL:
1782
-	    if(SCAN_MAIL)
1783
+	    if(SCAN_MAIL && (DCONF_MAIL & MAIL_CONF_MBOX))
1783 1784
 		ret = cli_scanmail(desc, ctx);
1784 1785
 	    break;
1785 1786
 
1786 1787
 	case CL_TYPE_TNEF:
1787
-	    if(SCAN_MAIL)
1788
+	    if(SCAN_MAIL && (DCONF_MAIL & MAIL_CONF_TNEF))
1788 1789
 		ret = cli_scantnef(desc, ctx);
1789 1790
 	    break;
1790 1791
 
1791 1792
 	case CL_TYPE_UUENCODED:
1793
+	    if(DCONF_OTHER & OTHER_CONF_UUENC)
1792 1794
 		ret = cli_scanuuencoded(desc, ctx);
1793 1795
 	    break;
1794 1796
 
1795 1797
 	case CL_TYPE_PST:
1796
-	    if(SCAN_MAIL)
1798
+	    if(SCAN_MAIL && (DCONF_MAIL & MAIL_CONF_PST))
1797 1799
 		ret = cli_scanpst(desc, ctx);
1798 1800
 	    break;
1799 1801
 
1800 1802
 	case CL_TYPE_MSCHM:
1801
-	    if(SCAN_ARCHIVE)
1803
+	    if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CHM))
1802 1804
 		ret = cli_scanmschm(desc, ctx);
1803 1805
 	    break;
1804 1806
 
1805 1807
 	case CL_TYPE_MSOLE2:
1806
-	    if(SCAN_OLE2)
1808
+	    if(SCAN_OLE2 && (DCONF_ARCH & ARCH_CONF_OLE2))
1807 1809
 		ret = cli_scanole2(desc, ctx);
1808 1810
 	    break;
1809 1811
 
1810 1812
 	case CL_TYPE_POSIX_TAR:
1811
-	    if(SCAN_ARCHIVE)
1813
+	    if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_TAR))
1812 1814
 		ret = cli_scantar(desc, ctx, 1);
1813 1815
 	    break;
1814 1816
 
1815 1817
 	case CL_TYPE_OLD_TAR:
1816
-	    if(SCAN_ARCHIVE)
1818
+	    if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_TAR))
1817 1819
 		ret = cli_scantar(desc, ctx, 0);
1818 1820
 	    break;
1819 1821
 
1820 1822
 	case CL_TYPE_BINHEX:
1821
-	    if(SCAN_ARCHIVE)
1823
+	    if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_BINHEX))
1822 1824
 		ret = cli_scanbinhex(desc, ctx);
1823 1825
 	    break;
1824 1826
 
1825 1827
 	case CL_TYPE_SCRENC:
1826
-	    ret = cli_scanscrenc(desc, ctx);
1828
+	    if(DCONF_OTHER & OTHER_CONF_SCRENC)
1829
+		ret = cli_scanscrenc(desc, ctx);
1827 1830
 	    break;
1828 1831
 
1829 1832
 	case CL_TYPE_RIFF:
1830
-	    if(SCAN_ALGO)
1833
+	    if(SCAN_ALGO && (DCONF_OTHER & OTHER_CONF_RIFF))
1831 1834
 		ret = cli_scanriff(desc, ctx->virname);
1832 1835
 	    break;
1833 1836
 
1834 1837
 	case CL_TYPE_GRAPHICS:
1835
-	    if(SCAN_ALGO)
1838
+	    if(SCAN_ALGO && (DCONF_OTHER & OTHER_CONF_JPEG))
1836 1839
 		ret = cli_scanjpeg(desc, ctx->virname);
1837 1840
 	    break;
1838 1841
 
1839 1842
 	case CL_TYPE_PDF:
1840
-	    if(SCAN_ARCHIVE)    /* you may wish to change this line */
1843
+	    if(SCAN_ARCHIVE && (DCONF_DOC & DOC_CONF_PDF))    /* you may wish to change this line */
1841 1844
 		ret = cli_scanpdf(desc, ctx);
1842 1845
 	    break;
1843 1846
 
1844 1847
 	case CL_TYPE_CRYPTFF:
1845
-	    ret = cli_scancryptff(desc, ctx);
1848
+	    if(DCONF_OTHER & OTHER_CONF_CRYPTFF)
1849
+		ret = cli_scancryptff(desc, ctx);
1846 1850
 	    break;
1847 1851
 
1848 1852
 	case CL_TYPE_ELF:
1849
-	    if(SCAN_ELF)
1853
+	    if(SCAN_ELF && ctx->dconf->elf)
1850 1854
 		ret = cli_scanelf(desc, ctx);
1851 1855
 	    break;
1852 1856
 
1853 1857
 	case CL_TYPE_SIS:
1858
+	    if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_SIS))
1854 1859
 		ret = cli_scansis(desc, ctx);
1855 1860
 	    break;
1856 1861
 
... ...
@@ -1911,6 +1922,7 @@ int cl_scandesc(int desc, const char **virname, unsigned long int *scanned, cons
1911 1911
     ctx.limits = limits;
1912 1912
     ctx.scanned = scanned;
1913 1913
     ctx.options = options;
1914
+    ctx.dconf = (struct cli_dconf *) engine->dconf;
1914 1915
 
1915 1916
     return cli_magic_scandesc(desc, &ctx);
1916 1917
 }