Browse code

shared/optparser.c, clamconf/clamconf.c: add --generate-config

git-svn: trunk@4664

Tomasz Kojm authored on 2009/01/30 04:03:59
Showing 4 changed files
... ...
@@ -1,3 +1,7 @@
1
+Thu Jan 29 20:27:45 CET 2009 (tk)
2
+---------------------------------
3
+ * shared/optparser.c, clamconf/clamconf.c: add --generate-config
4
+
1 5
 Thu Jan 29 18:36:51 EET 2009 (edwin)
2 6
 ------------------------------------
3 7
  * libclamav/scanners.c: raise scanscript limit
... ...
@@ -28,13 +28,15 @@
28 28
 #include "shared/optparser.h"
29 29
 #include "shared/misc.h"
30 30
 
31
+#include "libclamav/str.h"
32
+
31 33
 static struct _cfgfile {
32 34
     const char *name;
33 35
     int tool;
34 36
 } cfgfile[] = {
35 37
     { "clamd.conf",	    OPT_CLAMD	    },
36 38
     { "freshclam.conf",	    OPT_FRESHCLAM   },
37
-    { "clamav-milter.conf", OPT_MILTER	    },
39
+    /* TODO: { "clamav-milter.conf", OPT_MILTER	    }, */
38 40
     { NULL,		    0		    }
39 41
 };
40 42
 
... ...
@@ -88,16 +90,99 @@ static void printopts(struct optstruct *opts, int nondef)
88 88
     }
89 89
 }
90 90
 
91
+static int printconf(const char *name)
92
+{
93
+	int i, j, tool = 0, tokens_count;
94
+	char buffer[1025];
95
+	const char *tokens[128];
96
+	const struct clam_option *cpt;
97
+
98
+    for(i = 0; cfgfile[i].name; i++) {
99
+	if(!strcmp(name, cfgfile[i].name)) {
100
+	    tool = cfgfile[i].tool;
101
+	    break;
102
+	}
103
+    }
104
+    if(!tool) {
105
+	printf("ERROR: Unknown config file\nAvailable options:");
106
+	for(i = 0; cfgfile[i].name; i++)
107
+	    printf(" %s", cfgfile[i].name);
108
+	printf("\n");
109
+	return 1;
110
+    }
111
+
112
+    printf("##\n## %s - automatically generated by clamconf "VERSION"\n##\n", name);
113
+    printf("\n# Comment out or remove the line below.\nExample\n");
114
+
115
+    for(i = 0; clam_options[i].owner; i++) {
116
+	cpt = &clam_options[i];
117
+	if(cpt->name && (cpt->owner & tool) && !(cpt->owner & OPT_DEPRECATED) && !(cpt->flags & 4)) {
118
+	    strncpy(buffer, cpt->description, 1024);
119
+	    buffer[1024] = 0;
120
+	    tokens_count = cli_strtokenize(buffer, '\n', 128, tokens);
121
+	    printf("\n");
122
+	    for(j = 0; j < tokens_count; j++)
123
+		printf("# %s\n", tokens[j]);
124
+
125
+	    switch(cpt->argtype) {
126
+		case TYPE_STRING:
127
+		    if(cpt->strarg)
128
+			printf("# Default: %s\n", cpt->strarg);
129
+		    else
130
+			printf("# Default: disabled\n");
131
+		    break;
132
+
133
+		case TYPE_NUMBER:
134
+		    if(cpt->numarg != -1)
135
+			printf("# Default: %d\n", cpt->numarg);
136
+		    else
137
+			printf("# Default: disabled\n");
138
+		    break;
139
+
140
+		case TYPE_SIZE:
141
+		    if(cpt->numarg != -1)
142
+			printf("# Default: %d\n", cpt->numarg);
143
+		    else
144
+			printf("# Default: disabled\n");
145
+		    break;
146
+
147
+		case TYPE_BOOL:
148
+		    if(cpt->numarg != -1)
149
+			printf("# Default: %s\n", cpt->numarg ? "yes" : "no");
150
+		    else
151
+			printf("# Default: disabled\n");
152
+		    break;
153
+
154
+		default:
155
+		    printf("!!! %s: UNKNOWN INTERNAL TYPE !!!\n", cpt->name);
156
+	    }
157
+
158
+	    if(cpt->suggested && strchr(cpt->suggested, '\n')) {
159
+		strncpy(buffer, cpt->suggested, 1024);
160
+		buffer[1024] = 0;
161
+		tokens_count = cli_strtokenize(buffer, '\n', 128, tokens);
162
+		for(j = 0; j < tokens_count; j++)
163
+		    printf("#%s %s\n", cpt->name, tokens[j]);
164
+	    } else {
165
+		printf("#%s %s\n", cpt->name, cpt->suggested ? cpt->suggested : "ARG");
166
+	    }
167
+	}
168
+    }
169
+
170
+    return 0;
171
+}
172
+
91 173
 static void help(void)
92 174
 {
93 175
     printf("\n");
94 176
     printf("           Clam AntiVirus: Configuration Tool %s\n", get_version());
95 177
     printf("           (C) 2009 Sourcefire, Inc.\n\n");
96 178
 
97
-    printf("    --help               -h         Show help\n");
98
-    printf("    --version            -V         Show version\n");
99
-    printf("    --config-dir=DIR     -c DIR     Read configuration files from DIR\n");
100
-    printf("    --non-default        -n         Only display non-default settings\n");
179
+    printf("    --help                 -h         Show help\n");
180
+    printf("    --version              -V         Show version\n");
181
+    printf("    --config-dir=DIR       -c DIR     Read configuration files from DIR\n");
182
+    printf("    --non-default          -n         Only display non-default settings\n");
183
+    printf("    --generate-config=NAME -g NAME    Generate example config file\n");
101 184
     printf("\n");
102 185
     return;
103 186
 }
... ...
@@ -107,6 +192,7 @@ int main(int argc, char **argv)
107 107
 	const char *dir;
108 108
 	char path[512];
109 109
 	struct optstruct *opts, *toolopts;
110
+	const struct optstruct *opt;
110 111
 	unsigned int i, j;
111 112
 
112 113
 
... ...
@@ -128,6 +214,12 @@ int main(int argc, char **argv)
128 128
 	return 0;
129 129
     }
130 130
 
131
+    if((opt = optget(opts, "generate-config"))->enabled) {
132
+	printconf(opt->strarg);
133
+	optfree(opts);
134
+	return 0;
135
+    }
136
+
131 137
     printf("ClamAV engine version: %s\n", get_version());
132 138
     /* TODO: db information */
133 139
 
... ...
@@ -23,6 +23,9 @@ Search for configuration files clamd.conf and freshclam.conf in DIR.
23 23
 .TP 
24 24
 \fB\-n, \-\-non\-default\fR
25 25
 Only print non-default settings.
26
+.TP 
27
+\fB\-g CONFIG_NAME, \-\-generate\-config=CONFIG_NAME\fR
28
+Generate example configuration file.
26 29
 .SH "CREDITS"
27 30
 The idea of this tool is based on Postfix's postconf. clamconf was created under pressure from Tomasz Papszun ;-)
28 31
 .SH "AUTHOR"
... ...
@@ -54,6 +54,7 @@
54 54
 
55 55
 #define FLAG_MULTIPLE	1 /* option can be used multiple times */
56 56
 #define FLAG_REQUIRED	2 /* arg is required, even if there's a default value */
57
+#define FLAG_HIDDEN	4 /* don't print in clamconf --generate-config */
57 58
 
58 59
 const struct clam_option clam_options[] = {
59 60
     /* name,   longopt, sopt, argtype, regex, num, str, mul, owner, description, suggested */
... ...
@@ -109,6 +110,7 @@ const struct clam_option clam_options[] = {
109 109
 
110 110
     { NULL, "config-dir", 'c', TYPE_STRING, NULL, 0, CONFDIR, FLAG_REQUIRED, OPT_CLAMCONF, "", "" },
111 111
     { NULL, "non-default", 'n', TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMCONF, "", "" },
112
+    { NULL, "generate-config", 'g', TYPE_STRING, NULL, -1, NULL, 0, OPT_CLAMCONF, "", "" },
112 113
 
113 114
     /* cmdline only - deprecated */
114 115
     { NULL, "http-proxy", 0, TYPE_STRING, NULL, 0, NULL, 0, OPT_FRESHCLAM | OPT_DEPRECATED, "", "" },
... ...
@@ -184,9 +186,9 @@ const struct clam_option clam_options[] = {
184 184
 
185 185
     { "ReadTimeout", NULL, 0, TYPE_NUMBER, MATCH_NUMBER, 120, NULL, 0, OPT_CLAMD | OPT_MILTER, "This option specifies the time (in seconds) after which clamd should\ntimeout if a client doesn't provide any data.", "120" },
186 186
 
187
-    { "IdleTimeout", NULL, 0, TYPE_NUMBER, MATCH_NUMBER, 30, NULL, 0, OPT_CLAMD, "This option specifies how long (in seconds) the process should wait for a new job.", "60" },
187
+    { "IdleTimeout", NULL, 0, TYPE_NUMBER, MATCH_NUMBER, 30, NULL, 0, OPT_CLAMD, "This option specifies how long (in seconds) the process should wait\nfor a new job.", "60" },
188 188
 
189
-    { "ExcludePath", NULL, 0, TYPE_STRING, NULL, -1, NULL, FLAG_MULTIPLE, OPT_CLAMD, "Don't scan files/directories whose names match the provided\nregular expression. This option can be specified multiple times.", "^/proc/" },
189
+    { "ExcludePath", NULL, 0, TYPE_STRING, NULL, -1, NULL, FLAG_MULTIPLE, OPT_CLAMD, "Don't scan files/directories whose names match the provided\nregular expression. This option can be specified multiple times.", "^/proc/\n^/sys/" },
190 190
 
191 191
     { "MaxDirectoryRecursion", "max-dir-recursion", 0, TYPE_NUMBER, MATCH_NUMBER, 15, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "Maximum depth the directories are scanned at.", "15" },
192 192
 
... ...
@@ -214,9 +216,9 @@ const struct clam_option clam_options[] = {
214 214
 
215 215
     { "DetectPUA", "detect-pua", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "Detect Potentially Unwanted Applications.", "yes" },
216 216
 
217
-    { "ExcludePUA", "exclude-pua", 0, TYPE_STRING, NULL, -1, NULL, FLAG_MULTIPLE, OPT_CLAMD | OPT_CLAMSCAN, "Exclude a specific PUA category. This directive can be used multiple times.\nSee http://www.clamav.net/support/pua for the complete list of PUA\ncategories.", "NetTool" },
217
+    { "ExcludePUA", "exclude-pua", 0, TYPE_STRING, NULL, -1, NULL, FLAG_MULTIPLE, OPT_CLAMD | OPT_CLAMSCAN, "Exclude a specific PUA category. This directive can be used multiple times.\nSee http://www.clamav.net/support/pua for the complete list of PUA\ncategories.", "NetTool\nPWTool" },
218 218
 
219
-    { "IncludePUA", "include-pua", 0, TYPE_STRING, NULL, -1, NULL, FLAG_MULTIPLE, OPT_CLAMD | OPT_CLAMSCAN, "Only include a specific PUA category. This directive can be used multiple\ntimes.", "Spy" },
219
+    { "IncludePUA", "include-pua", 0, TYPE_STRING, NULL, -1, NULL, FLAG_MULTIPLE, OPT_CLAMD | OPT_CLAMSCAN, "Only include a specific PUA category. This directive can be used multiple\ntimes.", "Spy\nScanner\nRAT" },
220 220
 
221 221
     { "AlgorithmicDetection", "algorithmic-detection", 0, TYPE_BOOL, MATCH_BOOL, 1, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "In some cases (eg. complex malware, exploits in graphic files, and others),\nClamAV uses special algorithms to provide accurate detection. This option\ncontrols the algorithmic detection.", "yes" },
222 222
 
... ...
@@ -262,13 +264,13 @@ const struct clam_option clam_options[] = {
262 262
 
263 263
     { "ArchiveBlockEncrypted", "block-encrypted", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "Mark encrypted archives as viruses (Encrypted.Zip, Encrypted.RAR).", "no" },
264 264
 
265
-    { "MaxScanSize", "max-scansize", 0, TYPE_SIZE, MATCH_SIZE, CLI_DEFAULT_MAXSCANSIZE, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "This option sets the maximum amount of data to be scanned for each input file.\nArchives and other containers are recursively extracted and scanned up to this\nvalue.\nThe value of 0 disables the limit.\nWARNING: disabling this limit or setting it too high may result in severe damage.", "100M" },
265
+    { "MaxScanSize", "max-scansize", 0, TYPE_SIZE, MATCH_SIZE, CLI_DEFAULT_MAXSCANSIZE, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "This option sets the maximum amount of data to be scanned for each input file.\nArchives and other containers are recursively extracted and scanned up to this\nvalue.\nThe value of 0 disables the limit.\nWARNING: disabling this limit or setting it too high may result in severe\ndamage.", "100M" },
266 266
 
267
-    { "MaxFileSize", "max-filesize", 0, TYPE_SIZE, MATCH_SIZE, CLI_DEFAULT_MAXFILESIZE, NULL, 0, OPT_CLAMD | OPT_MILTER | OPT_CLAMSCAN, "Files larger than this limit won't be scanned. Affects the input file itself\nas well as files contained inside it (when the input file is an archive, a\ndocument or some other kind of container).\nThe value of 0 disables the limit.\nWARNING: disabling this limit or setting it too high may result in severe damage to the system.", "25M" },
267
+    { "MaxFileSize", "max-filesize", 0, TYPE_SIZE, MATCH_SIZE, CLI_DEFAULT_MAXFILESIZE, NULL, 0, OPT_CLAMD | OPT_MILTER | OPT_CLAMSCAN, "Files larger than this limit won't be scanned. Affects the input file itself\nas well as files contained inside it (when the input file is an archive, a\ndocument or some other kind of container).\nThe value of 0 disables the limit.\nWARNING: disabling this limit or setting it too high may result in severe\ndamage to the system.", "25M" },
268 268
 
269
-    { "MaxRecursion", "max-recursion", 0, TYPE_NUMBER, MATCH_NUMBER, CLI_DEFAULT_MAXRECLEVEL, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "Nested archives are scanned recursively, e.g. if a Zip archive contains a RAR\nfile, all files within it will also be scanned. This option specifies how\ndeeply the process should be continued.\nThe value of 0 disables the limit.\nWARNING: disabling this limit or setting it too high may result in severe damage to the system.", "16" },
269
+    { "MaxRecursion", "max-recursion", 0, TYPE_NUMBER, MATCH_NUMBER, CLI_DEFAULT_MAXRECLEVEL, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "Nested archives are scanned recursively, e.g. if a Zip archive contains a RAR\nfile, all files within it will also be scanned. This option specifies how\ndeeply the process should be continued.\nThe value of 0 disables the limit.\nWARNING: disabling this limit or setting it too high may result in severe\ndamage to the system.", "16" },
270 270
 
271
-    { "MaxFiles", "max-files", 0, TYPE_NUMBER, MATCH_NUMBER, CLI_DEFAULT_MAXFILES, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "Number of files to be scanned within an archive, a document, or any other\ncontainer file.\nThe value of 0 disables the limit.\nWARNING: disabling this limit or setting it too high may result in severe damage to the system.", "10000" },
271
+    { "MaxFiles", "max-files", 0, TYPE_NUMBER, MATCH_NUMBER, CLI_DEFAULT_MAXFILES, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "Number of files to be scanned within an archive, a document, or any other\ncontainer file.\nThe value of 0 disables the limit.\nWARNING: disabling this limit or setting it too high may result in severe\ndamage to the system.", "10000" },
272 272
 
273 273
     { "ClamukoScanOnAccess", NULL, 0, TYPE_BOOL, MATCH_BOOL, -1, NULL, 0, OPT_CLAMD, "This option enables Clamuko. Dazuko needs to be already configured and\nrunning.", "no" },
274 274
 
... ...
@@ -278,16 +280,16 @@ const struct clam_option clam_options[] = {
278 278
 
279 279
     { "ClamukoScanOnExec", NULL, 0, TYPE_BOOL, MATCH_BOOL, -1, NULL, 0, OPT_CLAMD, "Scan files when they get executed by the system.", "yes" },
280 280
 
281
-    { "ClamukoIncludePath", NULL, 0, TYPE_STRING, NULL, -1, NULL, FLAG_MULTIPLE, OPT_CLAMD, "This option specifies a directory (together will all files and directories\ninside this directory) which should be scanned on-access. This option can\nbe used multiple times.", "/home" },
281
+    { "ClamukoIncludePath", NULL, 0, TYPE_STRING, NULL, -1, NULL, FLAG_MULTIPLE, OPT_CLAMD, "This option specifies a directory (together will all files and directories\ninside this directory) which should be scanned on-access. This option can\nbe used multiple times.", "/home\n/students" },
282 282
 
283
-    { "ClamukoExcludePath", NULL, 0, TYPE_STRING, NULL, -1, NULL, FLAG_MULTIPLE, OPT_CLAMD, "This option allows excluding directories from on-access scanning. It can be used multiple times.", "/home/bofh" },
283
+    { "ClamukoExcludePath", NULL, 0, TYPE_STRING, NULL, -1, NULL, FLAG_MULTIPLE, OPT_CLAMD, "This option allows excluding directories from on-access scanning. It can\nbe used multiple times.", "/home/bofh\n/root" },
284 284
 
285 285
     { "ClamukoMaxFileSize", NULL, 0, TYPE_SIZE, MATCH_SIZE, 5242880, NULL, 0, OPT_CLAMD, "Files larger than this value will not be scanned.", "5M" },
286 286
 
287 287
     /* FIXME: mark these as private and don't output into clamd.conf/man */
288
-    { "DevACOnly", "dev-ac-only", 0, TYPE_BOOL, MATCH_BOOL, -1, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "", "" },
288
+    { "DevACOnly", "dev-ac-only", 0, TYPE_BOOL, MATCH_BOOL, -1, NULL, FLAG_HIDDEN, OPT_CLAMD | OPT_CLAMSCAN, "", "" },
289 289
 
290
-    { "DevACDepth", "dev-ac-depth", 0, TYPE_NUMBER, MATCH_NUMBER, -1, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "", "" },
290
+    { "DevACDepth", "dev-ac-depth", 0, TYPE_NUMBER, MATCH_NUMBER, -1, NULL, FLAG_HIDDEN, OPT_CLAMD | OPT_CLAMSCAN, "", "" },
291 291
 
292 292
     /* Freshclam-only entries */
293 293
 
... ...
@@ -300,11 +302,7 @@ const struct clam_option clam_options[] = {
300 300
 
301 301
     { "DNSDatabaseInfo", NULL, 0, TYPE_STRING, NULL, -1, "current.cvd.clamav.net", FLAG_REQUIRED, OPT_FRESHCLAM, "Use DNS to verify the virus database version. Freshclam uses DNS TXT records\nto verify the versions of the database and software itself. With this\ndirective you can change the database verification domain.\nWARNING: Please don't change it unless you're configuring freshclam to use\nyour own database verification domain.", "current.cvd.clamav.net" },
302 302
 
303
-    /* FIXME: - add an inactive entry for db.XY.clamav.net for freshclam.conf
304
-     * purposes
305
-     * - 
306
-     */
307
-    { "DatabaseMirror", NULL, 0, TYPE_STRING, NULL, -1, NULL, FLAG_MULTIPLE, OPT_FRESHCLAM, "FIXME", "" },
303
+    { "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 and\ndatabase.clamav.net (in this order). Please replace XY with your country\ncode (see http://www.iana.org/cctld/cctld-whois.htm). database.clamav.net\nis a round-robin record which points to our most reliable mirrors. It's used\nas a fall back in case db.XY.clamav.net is not working.", "db.XY.clamav.net\ndatabase.clamav.net" },
308 304
 
309 305
     { "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" },
310 306
 
... ...
@@ -337,9 +335,9 @@ const struct clam_option clam_options[] = {
337 337
 
338 338
     { "ReceiveTimeout", NULL, 0, TYPE_NUMBER, MATCH_NUMBER, 30, NULL, 0, OPT_FRESHCLAM, "Timeout in seconds when reading from database server.", "30" },
339 339
 
340
-    { "SubmitDetectionStats", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_FRESHCLAM, "", "" },
340
+    { "SubmitDetectionStats", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_FRESHCLAM, "When enabled freshclam will submit statistics to the ClamAV Project about\nthe latest virus detections in your environment. The ClamAV maintainers\nwill then use this data to determine what types of malware are the most\ndetected in the field and in what geographic area they are.\nThis feature requires LogTime and LogFile to be enabled in clamd.conf.", "/path/to/clamd.conf" },
341 341
 
342
-    { "DetectionStatsCountry", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_FRESHCLAM, "When enabled freshclam will submit statistics to the ClamAV Project about\nthe latest virus detections in your environment. The ClamAV maintainers\nwill then use this data to determine what types of malware are the most\ndetected in the field and in what geographic area they are.\nThis feature requires LogTime and LogFile to be enabled in clamd.conf.", "/path/to/clamd.conf" },
342
+    { "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" },
343 343
 
344 344
     /* Deprecated options */
345 345