git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@826 77e5149b-7576-45b1-b177-96237e5ba77b
Tomasz Kojm authored on 2004/09/05 06:09:20... | ... |
@@ -1,3 +1,7 @@ |
1 |
+Sat Sep 4 23:07:05 CEST 2004 (tk) |
|
2 |
+---------------------------------- |
|
3 |
+ * clamscan: add support for special files in stdin mode |
|
4 |
+ |
|
1 | 5 |
Sat Sep 4 17:46:39 CEST 2004 (tk) |
2 | 6 |
---------------------------------- |
3 | 7 |
* clamd: make output of VERSION compatible with clamd --version |
... | ... |
@@ -63,7 +63,7 @@ dev_t procdev; |
63 | 63 |
int scanmanager(const struct optstruct *opt) |
64 | 64 |
{ |
65 | 65 |
mode_t fmode; |
66 |
- int ret = 0, compression = 0, fmodeint; |
|
66 |
+ int ret = 0, compression = 0, fmodeint, options = 0; |
|
67 | 67 |
struct cl_node *trie = NULL; |
68 | 68 |
struct cl_limits *limits = NULL; |
69 | 69 |
struct passwd *user = NULL; |
... | ... |
@@ -160,6 +160,43 @@ int scanmanager(const struct optstruct *opt) |
160 | 160 |
else |
161 | 161 |
limits->maxratio = 200; |
162 | 162 |
|
163 |
+ /* set options */ |
|
164 |
+ |
|
165 |
+ if(optl(opt, "disable-archive") || optl(opt, "no-archive")) |
|
166 |
+ options &= ~CL_ARCHIVE; |
|
167 |
+ else |
|
168 |
+ options |= CL_ARCHIVE; |
|
169 |
+ |
|
170 |
+ if(optl(opt, "detect-broken")) |
|
171 |
+ options |= CL_BROKEN; |
|
172 |
+ |
|
173 |
+ if(optl(opt, "block-encrypted")) |
|
174 |
+ options |= CL_ENCRYPTED; |
|
175 |
+ |
|
176 |
+ if(optl(opt, "no-pe")) |
|
177 |
+ options &= ~CL_PE; |
|
178 |
+ else |
|
179 |
+ options |= CL_PE; |
|
180 |
+ |
|
181 |
+ if(optl(opt, "no-ole2")) |
|
182 |
+ options &= ~CL_OLE2; |
|
183 |
+ else |
|
184 |
+ options |= CL_OLE2; |
|
185 |
+ |
|
186 |
+ if(optl(opt, "no-html")) |
|
187 |
+ options &= ~CL_HTML; |
|
188 |
+ else |
|
189 |
+ options |= CL_HTML; |
|
190 |
+ |
|
191 |
+ if(optl(opt, "no-mail")) { |
|
192 |
+ options &= ~CL_MAIL; |
|
193 |
+ } else { |
|
194 |
+ options |= CL_MAIL; |
|
195 |
+ |
|
196 |
+ if(optl(opt, "mail-follow-urls")) |
|
197 |
+ options |= CL_MAILURL; |
|
198 |
+ } |
|
199 |
+ |
|
163 | 200 |
#ifdef C_LINUX |
164 | 201 |
if(stat("/proc", &sb) == -1) |
165 | 202 |
procdev = 0; |
... | ... |
@@ -175,10 +212,10 @@ int scanmanager(const struct optstruct *opt) |
175 | 175 |
mprintf("@Can't get absolute pathname of current working directory.\n"); |
176 | 176 |
ret = 57; |
177 | 177 |
} else |
178 |
- ret = scandirs(cwd, trie, user, opt, limits); |
|
178 |
+ ret = scandirs(cwd, trie, user, opt, limits, options); |
|
179 | 179 |
|
180 | 180 |
} else if(!strcmp(opt->filename, "-")) { /* read data from stdin */ |
181 |
- ret = checkstdin(trie, limits); |
|
181 |
+ ret = checkstdin(trie, limits, options); |
|
182 | 182 |
|
183 | 183 |
} else { |
184 | 184 |
int x; |
... | ... |
@@ -211,11 +248,11 @@ int scanmanager(const struct optstruct *opt) |
211 | 211 |
|
212 | 212 |
switch(fmode & S_IFMT) { |
213 | 213 |
case S_IFREG: |
214 |
- ret = scanfile(fullpath, trie, user, opt, limits); |
|
214 |
+ ret = scanfile(fullpath, trie, user, opt, limits, options); |
|
215 | 215 |
break; |
216 | 216 |
|
217 | 217 |
case S_IFDIR: |
218 |
- ret = scandirs(fullpath, trie, user, opt, limits); |
|
218 |
+ ret = scandirs(fullpath, trie, user, opt, limits, options); |
|
219 | 219 |
break; |
220 | 220 |
|
221 | 221 |
default: |
... | ... |
@@ -269,9 +306,9 @@ int match_regex(const char *filename, const char *pattern) |
269 | 269 |
#endif |
270 | 270 |
} |
271 | 271 |
|
272 |
-int scanfile(const char *filename, struct cl_node *root, const struct passwd *user, const struct optstruct *opt, const struct cl_limits *limits) |
|
272 |
+int scanfile(const char *filename, struct cl_node *root, const struct passwd *user, const struct optstruct *opt, const struct cl_limits *limits, int options) |
|
273 | 273 |
{ |
274 |
- int ret, options = 0, included; |
|
274 |
+ int ret, included; |
|
275 | 275 |
struct optnode *optnode; |
276 | 276 |
char *argument; |
277 | 277 |
#ifdef C_LINUX |
... | ... |
@@ -322,41 +359,6 @@ int scanfile(const char *filename, struct cl_node *root, const struct passwd *us |
322 | 322 |
return 0; |
323 | 323 |
} |
324 | 324 |
|
325 |
- if(optl(opt, "disable-archive") || optl(opt, "no-archive")) |
|
326 |
- options &= ~CL_ARCHIVE; |
|
327 |
- else |
|
328 |
- options |= CL_ARCHIVE; |
|
329 |
- |
|
330 |
- if(optl(opt, "detect-broken")) |
|
331 |
- options |= CL_BROKEN; |
|
332 |
- |
|
333 |
- if(optl(opt, "block-encrypted")) |
|
334 |
- options |= CL_ENCRYPTED; |
|
335 |
- |
|
336 |
- if(optl(opt, "no-pe")) |
|
337 |
- options &= ~CL_PE; |
|
338 |
- else |
|
339 |
- options |= CL_PE; |
|
340 |
- |
|
341 |
- if(optl(opt, "no-ole2")) |
|
342 |
- options &= ~CL_OLE2; |
|
343 |
- else |
|
344 |
- options |= CL_OLE2; |
|
345 |
- |
|
346 |
- if(optl(opt, "no-html")) |
|
347 |
- options &= ~CL_HTML; |
|
348 |
- else |
|
349 |
- options |= CL_HTML; |
|
350 |
- |
|
351 |
- if(optl(opt, "no-mail")) { |
|
352 |
- options &= ~CL_MAIL; |
|
353 |
- } else { |
|
354 |
- options |= CL_MAIL; |
|
355 |
- |
|
356 |
- if(optl(opt, "mail-follow-urls")) |
|
357 |
- options |= CL_MAILURL; |
|
358 |
- } |
|
359 |
- |
|
360 | 325 |
/* |
361 | 326 |
* check the extension - this is a special case, normally we don't need to |
362 | 327 |
* do this (libclamav detects archive by its magic string), but here we |
... | ... |
@@ -420,11 +422,11 @@ int scanfile(const char *filename, struct cl_node *root, const struct passwd *us |
420 | 420 |
return 0; |
421 | 421 |
} |
422 | 422 |
|
423 |
- return(scandenied(filename, root, user, opt, limits)); |
|
423 |
+ return(scandenied(filename, root, user, opt, limits, options)); |
|
424 | 424 |
} |
425 | 425 |
return 0; |
426 | 426 |
case 1: |
427 |
- return(scancompressed(filename, root, user, opt, limits)); |
|
427 |
+ return(scancompressed(filename, root, user, opt, limits, options)); |
|
428 | 428 |
} |
429 | 429 |
} |
430 | 430 |
|
... | ... |
@@ -452,7 +454,7 @@ int scanfile(const char *filename, struct cl_node *root, const struct passwd *us |
452 | 452 |
} |
453 | 453 |
|
454 | 454 |
/* it has guaranteed read access to the archive */ |
455 |
-int scancompressed(const char *filename, struct cl_node *root, const struct passwd *user, const struct optstruct *opt, const struct cl_limits *limits) |
|
455 |
+int scancompressed(const char *filename, struct cl_node *root, const struct passwd *user, const struct optstruct *opt, const struct cl_limits *limits, int options) |
|
456 | 456 |
{ |
457 | 457 |
int ret = 0; |
458 | 458 |
char *tmpdir, *gendir, *userprg; |
... | ... |
@@ -575,7 +577,7 @@ int scancompressed(const char *filename, struct cl_node *root, const struct pass |
575 | 575 |
fixperms(gendir); |
576 | 576 |
|
577 | 577 |
if(!ret) /* execute successful */ |
578 |
- ret = treewalk(gendir, root, user, opt, limits); |
|
578 |
+ ret = treewalk(gendir, root, user, opt, limits, options); |
|
579 | 579 |
|
580 | 580 |
/* remove the directory - as clamav */ |
581 | 581 |
clamav_rmdirs(gendir); |
... | ... |
@@ -658,7 +660,7 @@ int scancompressed(const char *filename, struct cl_node *root, const struct pass |
658 | 658 |
} |
659 | 659 |
} |
660 | 660 |
|
661 |
-int scandenied(const char *filename, struct cl_node *root, const struct passwd *user, const struct optstruct *opt, const struct cl_limits *limits) |
|
661 |
+int scandenied(const char *filename, struct cl_node *root, const struct passwd *user, const struct optstruct *opt, const struct cl_limits *limits, int options) |
|
662 | 662 |
{ |
663 | 663 |
char *tmpdir, *gendir, *tmpfile, *pt; |
664 | 664 |
struct stat statbuf; |
... | ... |
@@ -716,7 +718,7 @@ int scandenied(const char *filename, struct cl_node *root, const struct passwd * |
716 | 716 |
chown(tmpfile, user->pw_uid, user->pw_gid); |
717 | 717 |
} |
718 | 718 |
|
719 |
- if((ret = treewalk(gendir, root, user, opt, limits)) == 1) { |
|
719 |
+ if((ret = treewalk(gendir, root, user, opt, limits, options)) == 1) { |
|
720 | 720 |
logg("(Real infected archive: %s)\n", filename); |
721 | 721 |
mprintf("(Real infected archive: %s)\n", filename); |
722 | 722 |
|
... | ... |
@@ -742,9 +744,9 @@ int scandenied(const char *filename, struct cl_node *root, const struct passwd * |
742 | 742 |
return ret; |
743 | 743 |
} |
744 | 744 |
|
745 |
-int scandirs(const char *dirname, struct cl_node *root, const struct passwd *user, const struct optstruct *opt, const struct cl_limits *limits) |
|
745 |
+int scandirs(const char *dirname, struct cl_node *root, const struct passwd *user, const struct optstruct *opt, const struct cl_limits *limits, int options) |
|
746 | 746 |
{ |
747 |
- return treewalk(dirname, root, user, opt, limits); |
|
747 |
+ return treewalk(dirname, root, user, opt, limits, options); |
|
748 | 748 |
} |
749 | 749 |
|
750 | 750 |
int checkfile(const char *filename, const struct cl_node *root, const struct cl_limits *limits, int options) |
... | ... |
@@ -781,15 +783,44 @@ int checkfile(const char *filename, const struct cl_node *root, const struct cl_ |
781 | 781 |
return ret; |
782 | 782 |
} |
783 | 783 |
|
784 |
-int checkstdin(const struct cl_node *root, const struct cl_limits *limits) |
|
784 |
+int checkstdin(const struct cl_node *root, const struct cl_limits *limits, int options) |
|
785 | 785 |
{ |
786 | 786 |
int ret; |
787 |
- const char *virname; |
|
787 |
+ const char *virname, *tmpdir; |
|
788 |
+ char *file, buff[FILEBUFF]; |
|
789 |
+ FILE *fs; |
|
790 |
+ |
|
791 |
+ |
|
792 |
+ /* check write access */ |
|
793 |
+ tmpdir = getenv("TMPDIR"); |
|
794 |
+ |
|
795 |
+ if(tmpdir == NULL) |
|
796 |
+#ifdef P_tmpdir |
|
797 |
+ tmpdir = P_tmpdir; |
|
798 |
+#else |
|
799 |
+ tmpdir = "/tmp"; |
|
800 |
+#endif |
|
801 |
+ |
|
802 |
+ if(checkaccess(tmpdir, UNPUSER, W_OK) != 1) { |
|
803 |
+ mprintf("@Can't write to temporary directory.\n"); |
|
804 |
+ return 64; |
|
805 |
+ } |
|
806 |
+ |
|
807 |
+ file = cli_gentemp(tmpdir); |
|
808 |
+ |
|
809 |
+ if(!(fs = fopen(file, "wb"))) { |
|
810 |
+ mprintf("@Can't open %s for writing\n", file); |
|
811 |
+ return 63; |
|
812 |
+ } |
|
813 |
+ |
|
814 |
+ while((ret = fread(buff, 1, FILEBUFF, stdin))) |
|
815 |
+ fwrite(buff, 1, ret, fs); |
|
788 | 816 |
|
817 |
+ fclose(fs); |
|
789 | 818 |
|
790 | 819 |
claminfo.files++; |
791 | 820 |
|
792 |
- if((ret = cl_scandesc(0, &virname, &claminfo.blocks, root, limits, CL_RAW)) == CL_VIRUS) { |
|
821 |
+ if((ret = cl_scanfile(file, &virname, &claminfo.blocks, root, limits, options)) == CL_VIRUS) { |
|
793 | 822 |
mprintf("stdin: %s FOUND\n", virname); |
794 | 823 |
claminfo.ifiles++; |
795 | 824 |
|
... | ... |
@@ -803,6 +834,8 @@ int checkstdin(const struct cl_node *root, const struct cl_limits *limits) |
803 | 803 |
if(!printinfected) |
804 | 804 |
mprintf("stdin: %s\n", cl_strerror(ret)); |
805 | 805 |
|
806 |
+ unlink(file); |
|
807 |
+ free(file); |
|
806 | 808 |
return ret; |
807 | 809 |
} |
808 | 810 |
|
... | ... |
@@ -25,17 +25,17 @@ |
25 | 25 |
|
26 | 26 |
int scanmanager(const struct optstruct *opt); |
27 | 27 |
|
28 |
-int scanfile(const char *filename, struct cl_node *root, const struct passwd *user, const struct optstruct *opt, const struct cl_limits *limits); |
|
28 |
+int scanfile(const char *filename, struct cl_node *root, const struct passwd *user, const struct optstruct *opt, const struct cl_limits *limits, int options); |
|
29 | 29 |
|
30 |
-int scancompressed(const char *filename, struct cl_node *root, const struct passwd *user, const struct optstruct *opt, const struct cl_limits *limits); |
|
30 |
+int scancompressed(const char *filename, struct cl_node *root, const struct passwd *user, const struct optstruct *opt, const struct cl_limits *limits, int options); |
|
31 | 31 |
|
32 |
-int scandenied(const char *filename, struct cl_node *root, const struct passwd *user, const struct optstruct *opt, const struct cl_limits *limits); |
|
32 |
+int scandenied(const char *filename, struct cl_node *root, const struct passwd *user, const struct optstruct *opt, const struct cl_limits *limits, int options); |
|
33 | 33 |
|
34 |
-int scandirs(const char *dirname, struct cl_node *root, const struct passwd *user, const struct optstruct *opt, const struct cl_limits *limits); |
|
34 |
+int scandirs(const char *dirname, struct cl_node *root, const struct passwd *user, const struct optstruct *opt, const struct cl_limits *limits, int options); |
|
35 | 35 |
|
36 | 36 |
int checkfile(const char *filename, const struct cl_node *root, const struct cl_limits *limits, int compr); |
37 | 37 |
|
38 |
-int checkstdin(const struct cl_node *root, const struct cl_limits *limits); |
|
38 |
+int checkstdin(const struct cl_node *root, const struct cl_limits *limits, int options); |
|
39 | 39 |
|
40 | 40 |
#ifdef CLAMSCAN_THREADS |
41 | 41 |
int thr_exitno, thr_pid; |
... | ... |
@@ -45,7 +45,7 @@ |
45 | 45 |
* with some small changes. |
46 | 46 |
*/ |
47 | 47 |
|
48 |
-int treewalk(const char *dirname, struct cl_node *root, const struct passwd *user, const struct optstruct *opt, const struct cl_limits *limits) |
|
48 |
+int treewalk(const char *dirname, struct cl_node *root, const struct passwd *user, const struct optstruct *opt, const struct cl_limits *limits, int options) |
|
49 | 49 |
{ |
50 | 50 |
DIR *dd; |
51 | 51 |
struct dirent *dent; |
... | ... |
@@ -69,10 +69,10 @@ int treewalk(const char *dirname, struct cl_node *root, const struct passwd *use |
69 | 69 |
/* stat the file */ |
70 | 70 |
if(lstat(fname, &statbuf) != -1) { |
71 | 71 |
if(S_ISDIR(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode) && recursion) |
72 |
- treewalk(fname, root, user, opt, limits); |
|
72 |
+ treewalk(fname, root, user, opt, limits, options); |
|
73 | 73 |
else |
74 | 74 |
if(S_ISREG(statbuf.st_mode)) |
75 |
- scanret += scanfile(fname, root, user, opt, limits); |
|
75 |
+ scanret += scanfile(fname, root, user, opt, limits, options); |
|
76 | 76 |
} |
77 | 77 |
free(fname); |
78 | 78 |
} |
... | ... |
@@ -29,7 +29,7 @@ struct s_du { |
29 | 29 |
long int space; /* in kilobytes */ |
30 | 30 |
}; |
31 | 31 |
|
32 |
-int treewalk(const char *dirname, struct cl_node *root, const struct passwd *user, const struct optstruct *opt, const struct cl_limits *limits); |
|
32 |
+int treewalk(const char *dirname, struct cl_node *root, const struct passwd *user, const struct optstruct *opt, const struct cl_limits *limits, int options); |
|
33 | 33 |
|
34 | 34 |
int rmdirs(const char *dirname); |
35 | 35 |
int clamav_rmdirs(const char *dir); |