Browse code

add new features

git-svn: trunk@765

Tomasz Kojm authored on 2004/08/19 00:22:48
Showing 12 changed files
... ...
@@ -1,3 +1,16 @@
1
+Wed Aug 18 17:17:20 CEST 2004 (tk)
2
+----------------------------------
3
+  * clamscan: Scan mail files by default. Add new option --no-mail.
4
+  * clamd: Add new option MailFollowURLs. See documentation and source code
5
+	   for details. WARNING: This option may open your system to a DoS
6
+	   attack. Never use it on loaded servers.
7
+  * clamscan: Add new option --mail-follow-urls
8
+  * sigtool: Add new option --md5
9
+  * sigtool: Remove ability of automatic signature generation - inexperienced
10
+	     users should now use MD5 hashes (*.hdb databases) to create
11
+	     their own signatures
12
+  * docs: Update manual pages
13
+
1 14
 Wed Aug 18 15:24:00 BST 2004 (trog)
2 15
 -----------------------------------
3 16
   * libclamav/chmunpack.c: make sure we don't get filename collisions
... ...
@@ -327,6 +327,12 @@ int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *cop
327 327
     if(cfgopt(copt, "ScanMail")) {
328 328
 	logg("Mail files support enabled.\n");
329 329
 	options |= CL_MAIL;
330
+
331
+	if(cfgopt(copt, "MailFollowURLs")) {
332
+	    logg("Mail: URL scanning enabled.\n");
333
+	    options |= CL_MAILURL;
334
+	}
335
+
330 336
     } else {
331 337
 	logg("Mail files support disabled.\n");
332 338
     }
... ...
@@ -192,22 +192,24 @@ void help(void)
192 192
     mprintf("                          Clam AntiVirus Scanner "VERSION"\n");
193 193
     mprintf("                (C) 2002 - 2004 Tomasz Kojm <tkojm@clamav.net>\n\n");
194 194
 
195
-    mprintf("    --help                -h             Show help\n");
196
-    mprintf("    --version             -V             Print version number and exit\n");
195
+    mprintf("    --help                -h             Print this help screen\n");
196
+    mprintf("    --version             -V             Print version number\n");
197 197
     mprintf("    --verbose             -v             Be verbose\n");
198
-    mprintf("    --debug                              Enable debug messages\n");
199
-    mprintf("    --quiet                              Be quiet - only output error messages\n");
198
+    mprintf("    --debug                              Enable libclamav's debug messages\n");
199
+    mprintf("    --quiet                              Only output error messages\n");
200 200
     mprintf("    --stdout                             Write to stdout instead of stderr\n");
201
-    mprintf("                                         (this help is always written to stdout)\n");
201
+    mprintf("    --no-summary                         Disable summary at end of scanning\n");
202
+    mprintf("    --infected            -i             Only print infected files\n");
203
+    mprintf("    --bell                               Sound bell on virus detection\n");
204
+
202 205
     mprintf("\n");
203 206
     mprintf("    --tempdir=DIRECTORY                  Create temporary files in DIRECTORY\n");
204 207
     mprintf("    --leave-temps                        Do not remove temporary files\n");
205 208
     mprintf("    --database=FILE/DIR   -d FILE/DIR    Load virus database from FILE or load\n");
206 209
     mprintf("                                         all .cvd and .db[2] files from DIR\n");
207 210
     mprintf("    --log=FILE            -l FILE        Save scan report to FILE\n");
208
-    mprintf("    --recursive           -r             Scan directories recursively\n");
209
-    mprintf("    --infected            -i             Print infected files only\n");
210
-    mprintf("    --remove                             Remove infected files. Be careful.\n");
211
+    mprintf("    --recursive           -r             Scan subdirectories recursively\n");
212
+    mprintf("    --remove                             Remove infected files. Be careful!\n");
211 213
     mprintf("    --move=DIRECTORY                     Move infected files into DIRECTORY\n");
212 214
 #ifdef HAVE_REGEX_H
213 215
     mprintf("    --exclude=REGEX                      Don't scan file names matching REGEX\n");
... ...
@@ -216,16 +218,18 @@ void help(void)
216 216
     mprintf("    --exclude=PATT                       Don't scan file names containing PATT\n");
217 217
     mprintf("    --include=PATT                       Only scan file names containing PATT\n");
218 218
 #endif
219
-    mprintf("    --bell                               Sound bell on virus detection\n");
220
-    mprintf("    --no-summary                         Disable summary at end of scanning\n");
221
-    mprintf("    --mbox                -m             Treat stdin as a mailbox\n");
219
+
222 220
     mprintf("\n");
221
+    mprintf("    --no-mail                            Disable mail file support\n");
223 222
     mprintf("    --no-pe                              Disable PE analysis\n");
224 223
     mprintf("    --no-ole2                            Disable OLE2 support\n");
225 224
     mprintf("    --no-html                            Disable HTML support\n");
226 225
     mprintf("    --no-archive                         Disable libclamav archive support\n");
227 226
     mprintf("    --detect-broken                      Try to detect broken executable files\n");
228 227
     mprintf("    --block-encrypted                    Block encrypted archives\n");
228
+    mprintf("    --mail-follow-urls                   Download and scan URLs\n");
229
+
230
+    mprintf("\n");
229 231
     mprintf("    --max-space=#n                       Extract first #n kilobytes only\n");
230 232
     mprintf("    --max-files=#n                       Extract first #n files only\n");
231 233
     mprintf("    --max-recursion=#n                   Maximal recursion level\n");
... ...
@@ -237,9 +241,7 @@ void help(void)
237 237
     mprintf("    --lha[=FULLPATH]                     Enable support for .lha files\n");
238 238
     mprintf("    --jar[=FULLPATH]                     Enable support for .jar files\n");
239 239
     mprintf("    --tar[=FULLPATH]                     Enable support for .tar files\n");
240
-    mprintf("    --deb[=FULLPATH to ar]               Enable support for .deb files,\n");
241
-    mprintf("                                         implies --tgz , but doesn't conflict\n");
242
-    mprintf("                                         with --tgz=FULLPATH.\n");
240
+    mprintf("    --deb[=FULLPATH to ar]               Enable support for .deb files\n");
243 241
     mprintf("    --tgz[=FULLPATH]                     enable support for .tar.gz, .tgz files\n\n");
244 242
 
245 243
     exit(0);
... ...
@@ -48,7 +48,6 @@
48 48
 #include "manager.h"
49 49
 #include "treewalk.h"
50 50
 #include "shared.h"
51
-#include "mbox.h"
52 51
 #include "str.h"
53 52
 #include "strrcpy.h"
54 53
 #include "memory.h"
... ...
@@ -60,7 +59,6 @@
60 60
 dev_t procdev;
61 61
 #endif
62 62
 
63
-extern int cli_mbox(const char *dir, int desc, unsigned int options); /* FIXME */
64 63
 
65 64
 int scanmanager(const struct optstruct *opt)
66 65
 {
... ...
@@ -212,68 +210,7 @@ int scanmanager(const struct optstruct *opt)
212 212
 	    ret = scandirs(cwd, trie, user, opt, limits);
213 213
 
214 214
     } else if(!strcmp(opt->filename, "-")) { /* read data from stdin */
215
-	/*
216
-	 * njh@bandsman.co.uk: treat the input as a mailbox, the program
217
-	 * can then be used as a filter called when mail is received
218
-	 */
219
-	if(optc(opt, 'm')) {
220
-		const char *tmpdir;
221
-		char *dir;
222
-
223
-		/* njh@bandsman.co.uk: BeOS */
224
-#if !defined(C_CYGWIN) && !defined(C_BEOS)
225
-		if(!geteuid()) {
226
-		    if((user = getpwnam(UNPUSER)) == NULL) {
227
-			mprintf("@Can't get information about user %s\n", UNPUSER);
228
-			exit(60); /* this is critical problem, so we just exit here */
229
-		    }
230
-		}
231
-#endif
232
-
233
-		tmpdir = getenv("TMPDIR");
234
-
235
-		if(tmpdir == NULL)
236
-#ifdef P_tmpdir
237
-			tmpdir = P_tmpdir;
238
-#else
239
-			tmpdir = "/tmp";
240
-#endif
241
-
242
-		if(checkaccess(tmpdir, UNPUSER, W_OK) != 1) {
243
-			mprintf("@Can't write to the temporary directory.\n");
244
-			exit(64);
245
-		}
246
-		/* generate the temporary directory */
247
-
248
-		dir = cli_gentemp(tmpdir);
249
-		if(mkdir(dir, 0700)) {
250
-			mprintf("@Can't create the temporary directory %s\n", dir);
251
-			exit(63); /* critical */
252
-		}
253
-
254
-		if(user)
255
-			chown(dir, user->pw_uid, user->pw_gid);
256
-
257
-		/*
258
-		 * Extract the attachments into the temporary directory
259
-		 */
260
-		ret = cli_mbox(dir, 0, 0);
261
-
262
-		if(ret == 0) {
263
-			/* fix permissions of extracted files */
264
-			fixperms(dir);
265
-
266
-			if(ret == 0) /* execute successful */
267
-				ret = treewalk(dir, trie, user, opt, limits);
268
-
269
-			/* remove the directory - as clamav */
270
-			clamav_rmdirs(dir);
271
-
272
-			/* free dir - it's not necessary now */
273
-			free(dir);
274
-		}
275
-	} else
276
-	    ret = checkstdin(trie, limits);
215
+	ret = checkstdin(trie, limits);
277 216
 
278 217
     } else {
279 218
 	int x;
... ...
@@ -442,9 +379,15 @@ int scanfile(const char *filename, struct cl_node *root, const struct passwd *us
442 442
     else
443 443
 	options |= CL_HTML;
444 444
 
445
-    if(optc(opt, 'm'))
445
+    if(optl(opt, "no-mail")) {
446
+	options &= ~CL_MAIL;
447
+    } else {
446 448
 	options |= CL_MAIL;
447 449
 
450
+	if(optl(opt, "mail-follow-urls"))
451
+	    options |= CL_MAILURL;
452
+    }
453
+
448 454
     /* 
449 455
      * check the extension  - this is a special case, normally we don't need to
450 456
      * do this (libclamav detects archive by its magic string), but here we
... ...
@@ -94,7 +94,9 @@ int main(int argc, char **argv)
94 94
 	    {"no-pe", 0, 0, 0},
95 95
 	    {"no-ole2", 0, 0, 0},
96 96
 	    {"no-html", 0, 0, 0},
97
-	    {"mbox", 0, 0, 'm'},
97
+	    {"mbox", 0, 0, 'm'}, /* not used */
98
+	    {"no-mail", 0, 0, 0},
99
+	    {"mail-follow-urls", 0, 0, 0},
98 100
 	    {"unzip", 2, 0, 0},
99 101
 	    {"unrar", 2, 0, 0},
100 102
 	    {"unace", 2, 0, 0}, /* not used */
... ...
@@ -1,5 +1,5 @@
1 1
 .\" Manual page created by Tomasz Kojm, 20021001.
2
-.TH "clamav.conf" "5" "August 4, 2004" "Tomasz Kojm" "Clam AntiVirus"
2
+.TH "clamav.conf" "5" "August 18, 2004" "Tomasz Kojm" "Clam AntiVirus"
3 3
 .SH "NAME"
4 4
 .LP 
5 5
 \fBclamav.conf\fR \- a configuration file for Clam AntiVirus Daemon
... ...
@@ -125,8 +125,7 @@ Do internal checks every NUMBER seconds.
125 125
 Default: 3600
126 126
 .TP 
127 127
 \fBVirusEvent COMMAND\fR
128
-Execute the COMMAND when virus is found. In the command string %v and %f will be replaced by a virus name and an infected file name respectively.
129
-\fBSECURITY WARNING: Make sure the virus event command cannot be exploited eg. by using some special file name when %f is in use. Always use a full path to the command. Never delete/move files with this directive !
128
+Execute the COMMAND when virus is found. In the command string %v will be replaced by a virus name.
130 129
 \fR
131 130
 .br 
132 131
 Default: disabled.
... ...
@@ -180,7 +179,12 @@ Enables HTML detection and normalisation.
180 180
 Default: enabled.
181 181
 .TP 
182 182
 \fBScanMail\fR
183
-Enable scanning of Mbox, Maildir and raw mail files.
183
+Enable scanning of mail files.
184
+.br 
185
+Default: enabled.
186
+.TP 
187
+\fBMailFollowURLs\fR
188
+If an email contains URLs ClamAV can download and scan them. \fBWARNING: This option may open your system to a DoS attack. Never use it on loaded servers.\fR
184 189
 .br 
185 190
 Default: disabled.
186 191
 .TP 
... ...
@@ -1,5 +1,5 @@
1 1
 .\" Manual page created by Tomasz Kojm, 14/15 IV 2002
2
-.TH "clamscan" "1" "August 4, 2004" "Tomasz Kojm" "Clam AntiVirus"
2
+.TH "clamscan" "1" "August 18, 2004" "Tomasz Kojm" "Clam AntiVirus"
3 3
 .SH "NAME"
4 4
 .LP 
5 5
 clamscan \- scan files and directories against viruses
... ...
@@ -57,10 +57,6 @@ Don't scan file names containing PATT. It may be used multiple times.
57 57
 .TP 
58 58
 \fB\-\-include=PATT\fR
59 59
 Only scan file names containing PATT. It may be used multiple times.
60
-.TP 
61
-\fB\-\-mbox\fR
62
-Enable scanning of various mail file types (also treat stdin as a mailbox \- for backward compatibility).
63
-.TP 
64 60
 \fB\-i, \-\-infected\fR
65 61
 Only print infected files.
66 62
 .TP 
... ...
@@ -70,6 +66,9 @@ Remove infected files. \fBBe careful.\fR
70 70
 \fB\-\-move=DIRECTORY\fR
71 71
 Move infected files into DIRECTORY. Directory must be writeable for the 'clamav' user or unprivileged user running clamscan.
72 72
 .TP 
73
+\fB\-\-no\-mail\fR
74
+Disable scanning of mail files.
75
+.TP 
73 76
 \fB\-\-no\-pe\fR
74 77
 PE stands for Portable Executable \- it's an executable file format used in all 32\-bit versions of Windows operating systems. By default ClamAV performs deeper analysis of executable files and tries to decompress popular executable packers such as UPX. This option \fBdisables\fR PE support and is not recommended !
75 78
 .TP 
... ...
@@ -88,6 +87,9 @@ Mark broken executables as viruses (Broken.Executable).
88 88
 \fB\-\-block\-encrypted\fR
89 89
 Mark encrypted archives as viruses (Encrypted.Zip, Encrypted.RAR).
90 90
 .TP 
91
+\fB\-\-mail\-follow\-urls\fR
92
+If an email contains URLs ClamAV can download and scan them. \fBWARNING: This option may open your system to a DoS attack. Never use it on loaded servers.\fR
93
+.TP 
91 94
 \fB\-\-max\-files=#n\fR
92 95
 Extract first #n files from each archive. This option protects your system against DoS attacks (default: 500)
93 96
 .TP 
... ...
@@ -1,14 +1,15 @@
1 1
 .\" Manual page created by Tomasz Kojm, 20020629
2
-.TH "sigtool" "1" "July 22, 2004" "Tomasz Kojm" "Clam AntiVirus"
2
+.TH "sigtool" "1" "August 18, 2004" "Tomasz Kojm" "Clam AntiVirus"
3 3
 .SH "NAME"
4 4
 .LP 
5
-sigtool \- signature management tool
5
+sigtool \- signature and database management tool
6 6
 .SH "SYNOPSIS"
7 7
 .LP 
8 8
 sigtool [options]
9 9
 .SH "DESCRIPTION"
10 10
 .LP 
11
-sigtool can be used to generate a virus signature using an external anti\-virus scanner (see the official documentation for license issues!). It can also dump hexadecimal data and build and unpack CVD databases.
11
+sigtool can be used to generate MD5 checksums, convert data 
12
+into hexadecimal format, and build/unpack CVD databases. Also it can verify digital signatures of databases and list virus signature names.
12 13
 .SH "OPTIONS"
13 14
 .LP 
14 15
 
... ...
@@ -28,15 +29,8 @@ Write all messages to standard output (stdout), instead of standard error output
28 28
 \fB\-\-hex\-dump\fR
29 29
 Read data from stdin and write hex string to stdout.
30 30
 .TP 
31
-\fB\-c, \-\-command\fR
32
-Anti\-virus scanner command with options. Remember about quotes if the argument string contains white characters. Command should contain everything except infected file name.
33
-Make sure your commercial scanner's license does not disallow sigtool usage !
34
-.TP 
35
-\fB\-f, \-\-file\fR
36
-Infected file name.
37
-.TP 
38
-\fB\-s, \-\-string\fR
39
-Unique string from anti\-virus scanner's output when it detects the virus. In most cases it should be a virus name.
31
+\fB\-\-md5\fR
32
+Generate MD5 checksum from stdin.
40 33
 .TP 
41 34
 \fB\-i, \-\-info\fR
42 35
 Print a CVD information and verify MD5 and a digital signature.
... ...
@@ -55,11 +49,9 @@ Unpack a local CVD file to a current directory.
55 55
 .SH "EXAMPLES"
56 56
 .LP 
57 57
 .TP 
58
-(0) Generate hex string from testfile and save it to testfile.hex:
58
+Generate hex string from testfile and save it to testfile.hex:
59 59
 
60 60
 \fBcat testfile | sigtool \-\-hex\-dump > testfile.hex\fR
61
-.TP 
62
-(1) Please check clamdoc.pdf and signatures.pdf for more example of usage.
63 61
 .SH "CREDITS"
64 62
 Please check the full documentation for credits.
65 63
 .SH "AUTHOR"
... ...
@@ -160,8 +160,14 @@ ScanOLE2
160 160
 ## Mail files
161 161
 ##
162 162
 
163
-# Uncomment this option if you are going to scan mail files.
164
-#ScanMail
163
+# Enable internal e-mail scanner.
164
+ScanMail
165
+
166
+# If an email contains URLs ClamAV can download and scan them.
167
+# WARNING: This option may open your system to a DoS attack.
168
+#	   Never use it on loaded servers.
169
+#MailFollowURLs
170
+
165 171
 
166 172
 ##
167 173
 ## HTML
... ...
@@ -171,20 +177,18 @@ ScanOLE2
171 171
 # recommended and required to detect popular exploits.
172 172
 ScanHTML
173 173
 
174
+
174 175
 ##
175 176
 ## Archives
176 177
 ##
177 178
 
178
-
179 179
 # Comment this line to disable scanning of the archives.
180 180
 ScanArchive
181 181
 
182
-
183 182
 # By default the built-in RAR unpacker is disabled by default because the code
184 183
 # terribly leaks, however it's probably a good idea to enable it.
185 184
 #ScanRAR
186 185
 
187
-
188 186
 # Options below protect your system against Denial of Service attacks
189 187
 # with archive bombs.
190 188
 
... ...
@@ -65,6 +65,7 @@ struct cfgstruct *parsecfg(const char *cfgfile, int messages)
65 65
 	    {"ScanPE", OPT_NOARG},
66 66
 	    {"DetectBrokenExecutables", OPT_NOARG},
67 67
 	    {"ScanMail", OPT_NOARG},
68
+	    {"MailFollowURLs", OPT_NOARG},
68 69
 	    {"ScanHTML", OPT_NOARG},
69 70
 	    {"ScanOLE2", OPT_NOARG},
70 71
 	    {"ScanArchive", OPT_NOARG},
... ...
@@ -54,9 +54,7 @@ int main(int argc, char **argv)
54 54
 	    {"version", 0, 0, 'V'},
55 55
 	    {"tempdir", 1, 0, 0},
56 56
 	    {"hex-dump", 0, 0, 0},
57
-	    {"command", 1, 0, 'c'},
58
-	    {"string", 1, 0, 's'},
59
-	    {"file", 1, 0, 'f'},
57
+	    {"md5", 0, 0, 0},
60 58
 	    {"build", 1, 0, 'b'},
61 59
 	    {"server", 1, 0, 0},
62 60
 	    {"unpack", 1, 0, 'u'},
... ...
@@ -16,7 +16,6 @@
16 16
  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 17
  */
18 18
 
19
-/* some things may need to be tuned here (look at jmp variables) */
20 19
 
21 20
 #if HAVE_CONFIG_H
22 21
 #include "clamav-config.h"
... ...
@@ -67,115 +66,6 @@ int listdir(const char *dirname);
67 67
 void listsigs(struct optstruct *opt);
68 68
 int cli_rmdirs(const char *dirname); /* libclamav's internal */
69 69
 
70
-int scanfile(const char *cmd, const char *str, const char *file)
71
-{
72
-	FILE *pd;
73
-	char *command, buffer[LINE];
74
-
75
-
76
-    /* build the command */
77
-    command = (char *) mcalloc(strlen(cmd) + strlen(file) + 10, sizeof(char));
78
-    sprintf(command, "%s %s", cmd, file);
79
-
80
-    if((pd = popen(command, "r")) == NULL) {
81
-	mprintf("!popen() failed\n");
82
-	return 3;
83
-    }
84
-
85
-    while(fgets(buffer, LINE, pd)) {
86
-	if(strstr(buffer, str)) {
87
-	    free(command);
88
-            fclose(pd);
89
-	    return 1; /* found */
90
-	}
91
-    }
92
-
93
-    free(command);
94
-    fclose(pd);
95
-    return 0; /* substring not found */
96
-}
97
-
98
-char *cut(const char *file, long int start, long int end)
99
-{
100
-	char *fname = NULL, buffer[FILEBUFF];
101
-	int bytes, size, sum;
102
-	FILE *rd, *wd;
103
-
104
-
105
-    if((rd = fopen(file, "rb")) == NULL) {
106
-	mprintf("!File %s doesn't exist.\n", file);
107
-	exit(13);
108
-    }
109
-
110
-    if((fname = cli_gentemp(".")) == NULL) {
111
-	mprintf("!Can't generate temporary file name.\n");
112
-	exit(1);
113
-    }
114
-
115
-    if((wd = fopen(fname, "wb")) == NULL) {
116
-	mprintf("!Can't create temporary file %s\n", fname);
117
-	exit(14);
118
-    }
119
-
120
-    fseek(rd, start, SEEK_SET);
121
-
122
-    size = end - start;
123
-    sum = 0;
124
-
125
-    while((bytes = fread(buffer, 1, FILEBUFF, rd)) > 0) {
126
-	if(sum + bytes >= size) {
127
-	    fwrite(buffer, 1, size - sum, wd);
128
-	    break;
129
-	} else
130
-	    fwrite(buffer, 1, bytes, wd);
131
-
132
-	sum += bytes;
133
-    }
134
-
135
-    fclose(rd);
136
-    fclose(wd);
137
-
138
-    return fname;
139
-}
140
-
141
-char *change(const char *file, long int x)
142
-{
143
-	char *fname = NULL, buffer[FILEBUFF];
144
-	int bytes, ch;
145
-	FILE *rd, *wd;
146
-
147
-
148
-    if((rd = fopen(file, "rb")) == NULL) {
149
-	mprintf("!File %s doesn't exist.\n", file);
150
-	exit(13);
151
-    }
152
-
153
-    if((fname = cli_gentemp(".")) == NULL) {
154
-	mprintf("!Can't generate temporary file name.\n");
155
-	exit(1);
156
-    }
157
-
158
-    if((wd = fopen(fname, "wb+")) == NULL) {
159
-	mprintf("!Can't create temporary file %s\n", fname);
160
-	exit(14);
161
-    }
162
-
163
-    while((bytes = fread(buffer, 1, FILEBUFF, rd)) > 0)
164
-	fwrite(buffer, 1, bytes, wd);
165
-
166
-    fclose(rd);
167
-
168
-    if(x) { /* don't alter first character in the file */
169
-	fflush(wd);
170
-	fseek(wd, x, SEEK_SET);
171
-	ch = fgetc(wd);
172
-	fseek(wd, -1, SEEK_CUR);
173
-	fputc(++ch, wd);
174
-    }
175
-
176
-    fclose(wd);
177
-    return fname;
178
-}
179 70
 
180 71
 void sigtool(struct optstruct *opt)
181 72
 {
... ...
@@ -211,6 +101,12 @@ void sigtool(struct optstruct *opt)
211 211
 	    free(pt);
212 212
 	}
213 213
 
214
+    } else if(optl(opt, "md5")) {
215
+
216
+	char *md5 = cli_md5stream(stdin);
217
+	mprintf("%s\n", md5);
218
+	free(md5);
219
+
214 220
     } else if(optc(opt, 'b')) {
215 221
 	if(!optl(opt, "server")) {
216 222
 	    mprintf("!--server is required in this mode\n");
... ...
@@ -236,233 +132,11 @@ void sigtool(struct optstruct *opt)
236 236
 	listsigs(opt);
237 237
 
238 238
     } else {
239
-	    int jmp, lastjmp = 0, end, found = 0, exec = 0, pos, filesize,
240
-		maxsize = 0, ret;
241
-	    char *c, *s, *f, *tmp, *signame, *bsigname, *f2 = NULL;
242
-	    FILE *fd, *wd;
243
-
244
-	if(!optc(opt, 'c')) {
245
-	    mprintf("!--command, -c is required in this mode\n");
246
-	    exit(10);
247
-	} else if(!optc(opt, 's')) {
248
-	    mprintf("!--string, -s is required in this mode\n");
249
-	    exit(10);
250
-	} else if(!optc(opt, 'f')) {
251
-	    mprintf("!--file, -f is required in this mode\n");
252
-	    exit(10);
253
-	}
254
-
255
-	/* these are pointers to corresponding strings in option list */
256
-	c = getargc(opt, 'c');
257
-	s = getargc(opt, 's');
258
-	f = getargc(opt, 'f');
259
-
260
-	if(scanfile(c, s, f) != 1) {
261
-	    mprintf("!String %s not found in scanner's output.\n", s);
262
-	    mprintf("Please check it and try again.\n");
263
-	    mprintf("Does the scanner write to stdout ? It has to.\n");
264
-	    exit(11);
265
-	}
266
-
267
-	/* initial values */
268
-	filesize = end = fileinfo(f, 1);
269
-	jmp = end / 5 + 1;
270 239
 
271
-	/* find signature end */
272
-	while(1) {
273
-	    tmp = cut(f, 0, end);
274
-	    exec++;
275
-	    ret = scanfile(c, s, tmp);
276
-	    unlink(tmp);
277
-	    free(tmp);
278
-
279
-	    if(ret == 1) {
280
-
281
-		if(end >= jmp) {
282
-		    mprintf("Detected, decreasing end %d -> %d\n", end, end - jmp);
283
-		    end -= jmp;
284
-		} else
285
-		    end = 0;
286
-
287
-	    } else {
288
-		mprintf("Not detected at %d, moving forward.\n", end);
289
-		if(jmp == 1) {
290
-
291
-		    while(end <= filesize) {
292
-			tmp = cut(f, 0, end);
293
-			exec++;
294
-			if(scanfile(c, s, tmp) == 1) {
295
-			    mprintf(" *** Signature end found at %d\n", end);
296
-			    found = 1;
297
-			    f2 = strdup(tmp); /* remember this file */
298
-			    free(tmp);
299
-			    break;
300
-			} else {
301
-			    unlink(tmp);
302
-			    free(tmp);
303
-			    mprintf("Increasing end %d -> %d\n", end, end + 1);
304
-			}
305
-			end++;
306
-		    }
307
-
308
-		    if(found) break;
309
-		}
310
-
311
-		if(jmp)
312
-		    jmp--;
313
-		jmp = jmp/2 + 1;
314
-		end += jmp;
315
-		if(end > filesize)
316
-		    end = filesize;
317
-
318
-	    }
319
-
320
-	}
321
-
322
-	/* find signature start */
323
-	found = 0;
324
-	jmp = 50;
325
-	pos = end - jmp;
326
-
327
-	while(1) {
328
-
329
-	    tmp = change(f2, pos);
330
-	    if(scanfile(c, s, tmp) != 1) {
331
-		exec++;
332
-		unlink(tmp);
333
-		free(tmp);
334
-
335
-		if(pos >= jmp) {
336
-		    mprintf("Not detected, moving backward %d -> %d\n", pos, pos - jmp);
337
-		    pos -= jmp;
338
-		    maxsize += jmp;
339
-		} else {
340
-		    mprintf("Not detected, using the beginning of the file.\n");
341
-		    pos = 0;
342
-		    break;
343
-		}
344
-
345
-		if(maxsize > MAX_LENGTH) {
346
-		    mprintf("!Generated signature is too big.\n");
347
-		    unlink(f2);
348
-		    free(f2);
349
-		    exit(1);
350
-		}
351
-
352
-	    } else {
353
-		mprintf("Detected at %d, moving forward.\n", pos);
354
-		if(jmp == 1 && lastjmp == 1) {
355
-		    unlink(tmp);
356
-		    free(tmp);
357
-		    while(pos < end) {
358
-			tmp = change(f2, pos);
359
-			exec++;
360
-			ret = scanfile(c, s, tmp);
361
-			unlink(tmp);
362
-			free(tmp);
363
-			if(ret == 1) {
364
-			    mprintf("Moving forward %d -> %d\n", pos, pos + 1);
365
-			    pos++;
366
-
367
-			    if(end - pos < MIN_LENGTH) {
368
-				mprintf("!Generated signature is too small.\n");
369
-				unlink(f2);
370
-				free(f2);
371
-				exit(1);
372
-			    }
373
-
374
-			} else {
375
-			    mprintf(" *** Signature start found at %d\n", pos);
376
-			    found = 1;
377
-			    break;
378
-			}
379
-		    }
380
-
381
-		    if(pos >= end) {
382
-		        mprintf("!Can't generate a proper signature.\n");
383
-			unlink(f2);
384
-			free(f2);
385
-		        exit(1);
386
-		    }
387
-
388
-		    if(found)
389
-			break;
390
-		}
391
-
392
-		lastjmp = jmp;
393
-		if(jmp > 0)
394
-		    jmp--;
395
-		jmp = jmp/2 + 1;
396
-		pos += jmp;
397
-
398
-		if(pos >= end - 2 * jmp)
399
-		    pos = end - 2 * jmp;
400
-
401
-		unlink(tmp);
402
-		free(tmp);
403
-	    }
404
-
405
-	}
406
-
407
-	unlink(f2);
408
-	free(f2);
409
-	tmp = cut(f, pos, end);
410
-
411
-	mprintf("\nThe scanner was executed %d times.\n", exec);
412
-	mprintf("The signature length is %d (%d hex)\n", end - pos, 2 * (end - pos));
413
-
414
-	if(end - pos < MIN_LENGTH) {
415
-	    mprintf("\nWARNING: THE SIGNATURE IS TOO SMALL (PROBABLY ONLY A PART OF A REAL SIGNATURE).\n");
416
-	    mprintf("         PLEASE DON'T USE IT.\n\n");
417
-	}
418
-
419
-	if((fd = fopen(tmp, "rb")) == NULL) {
420
-	    mprintf("!Can't believe. Where is my signature, dude ?\n");
421
-	    exit(99);
422
-	}
423
-
424
-	signame = (char *) mcalloc(strlen(f) + 10, sizeof(char));
425
-	sprintf(signame, "%s.sig", f);
426
-	if(fileinfo(signame, 1) != -1) {
427
-	    mprintf("File %s exists.\n", signame);
428
-	    free(signame);
429
-	    signame = cli_gentemp(".");
430
-	}
431
-
432
-	bsigname = (char *) mcalloc(strlen(f) + 10, sizeof(char));
433
-	sprintf(bsigname, "%s.bsig", f);
434
-	if(fileinfo(bsigname, 1) != -1) {
435
-	    mprintf("File %s exists.\n", bsigname);
436
-	    free(bsigname);
437
-	    bsigname = cli_gentemp(".");
438
-	}
439
-
440
-	if((wd = fopen(signame, "wb")) == NULL) {
441
-	    mprintf("Can't write to %s\n", signame);
442
-	    unlink(tmp);
443
-	    free(tmp);
444
-	    exit(15);
445
-	}
446
-
447
-	mprintf("Saving signature in %s file.\n", signame);
448
-
449
-	while((bytes = fread(buffer, 1, FILEBUFF, fd)) > 0) {
450
-	    pt = cli_str2hex(buffer, bytes);
451
-	    fwrite(pt, 1, 2 * bytes, wd);
452
-	    free(pt);
453
-	}
454
-
455
-	mprintf("Saving binary signature in %s file.\n", bsigname);
456
-	rename(tmp, bsigname);
457
-
458
-	fclose(fd);
459
-	fclose(wd);
460
-	free(tmp);
461
-	free(signame);
462
-	free(bsigname);
240
+	help();
463 241
     }
464 242
 
465
-    /* free_opt(opt); */
243
+    free_opt(opt);
466 244
 }
467 245
 
468 246
 int countlines(const char *filename)
... ...
@@ -1040,12 +714,9 @@ void help(void)
1040 1040
     mprintf("    --quiet                                be quiet, output only error messages\n");
1041 1041
     mprintf("    --debug                                enable debug messages\n");
1042 1042
     mprintf("    --stdout                               write to stdout instead of stderr\n");
1043
-    mprintf("                                           (this help is always written to stdout)\n");
1044 1043
     mprintf("    --hex-dump                             convert data from stdin to a hex\n");
1045 1044
     mprintf("                                           string and print it on stdout\n");
1046
-    mprintf("    --command              -c              scanner command string, with options\n");
1047
-    mprintf("    --string               -s              'virus found' string in scan. output\n");
1048
-    mprintf("    --file                 -f              infected file\n");
1045
+    mprintf("    --md5                                  generate MD5 checksum from stdin\n");
1049 1046
     mprintf("    --info=FILE            -i FILE         print database information\n");
1050 1047
     mprintf("    --build=NAME           -b NAME         build a CVD file\n");
1051 1048
     mprintf("    --server=ADDR                          ClamAV Signing Service address\n");