git-svn: trunk@765
Tomasz Kojm authored on 2004/08/19 00:22:48... | ... |
@@ -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"); |