Browse code

add support for special files in stdin mode

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
Showing 5 changed files
... ...
@@ -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);