git-svn: trunk@3182
Nigel Horne authored on 2007/08/21 22:19:41... | ... |
@@ -271,8 +271,7 @@ need to restart sendmail after rebuilding sendmail.cf and starting clamd and |
271 | 271 |
clamav-milter. |
272 | 272 |
|
273 | 273 |
As with all software it is wise to ensure that clamav-milter has the least |
274 |
-privileges it needs to run. So don't run it as root and don't store the sockets |
|
275 |
-in a directory that can be written by everyone. For example ensure that /var/run |
|
274 |
+privileges it needs to run. So don't run it as root and don't store the sockets in a directory that can be written by everyone. For example ensure that /var/run |
|
276 | 275 |
is owned and writeable only by root and add entries for 'User' and |
277 | 276 |
'FixStaleSocket' in clamd.conf. |
278 | 277 |
|
... | ... |
@@ -295,6 +294,9 @@ appearing in a log file, you will need to increase the number of threads on |
295 | 295 |
your system (/proc/sys/kernel/threads-max), or decrease the value of |
296 | 296 |
--max-children. |
297 | 297 |
|
298 |
+Clamav-milter performs DNS look ups, if you wish to tweak its timeouts |
|
299 |
+see resolv.conf(5). |
|
300 |
+ |
|
298 | 301 |
2.7 Postfix |
299 | 302 |
|
300 | 303 |
Clamav-milter has only been designed to work with Sendmail. I understand that |
... | ... |
@@ -378,7 +380,8 @@ You will have to do a lot of fiddling if you want notifications to work, |
378 | 378 |
since clamav-milter calls sendmail to handle the notifications and sendmail |
379 | 379 |
will run of out the same jail. I've not disabled the notifications, but I |
380 | 380 |
may in the future - for the moment handling notifications in the jail is an |
381 |
-excercise for the reader. |
|
381 |
+excercise for the reader. I've put in a symbolic link to sendmail, but I |
|
382 |
+suspect it should be a real copy. |
|
382 | 383 |
|
383 | 384 |
mkdir /var/run/clamav-root |
384 | 385 |
chown clamav:clamav /var/run/clamav-root |
... | ... |
@@ -33,7 +33,7 @@ |
33 | 33 |
*/ |
34 | 34 |
static char const rcsid[] = "$Id: clamav-milter.c,v 1.312 2007/02/12 22:24:21 njh Exp $"; |
35 | 35 |
|
36 |
-#define CM_VERSION "devel-190807" |
|
36 |
+#define CM_VERSION "devel-20080820" |
|
37 | 37 |
|
38 | 38 |
#if HAVE_CONFIG_H |
39 | 39 |
#include "clamav-config.h" |
... | ... |
@@ -1185,6 +1185,12 @@ main(int argc, char **argv) |
1185 | 1185 |
cpt->strarg, (int)user->pw_uid, |
1186 | 1186 |
(int)user->pw_gid); |
1187 | 1187 |
|
1188 |
+ /* |
|
1189 |
+ * Note, some O/Ss (e.g. OpenBSD/Fedora Linux) FORCE |
|
1190 |
+ * you to run as root in black-hole-mode because |
|
1191 |
+ * /var/spool/mqueue is mode 700 owned by root! |
|
1192 |
+ * Flames to them, not to me, please. |
|
1193 |
+ */ |
|
1188 | 1194 |
if(black_hole_mode && (user->pw_uid != 0)) { |
1189 | 1195 |
int are_trusted; |
1190 | 1196 |
FILE *sendmail; |
... | ... |
@@ -1231,8 +1237,8 @@ main(int argc, char **argv) |
1231 | 1231 |
} |
1232 | 1232 |
} |
1233 | 1233 |
if(!are_trusted) { |
1234 |
- fprintf(stderr, _("%s: You cannot use black hole mode unless you are a TrustedUser\n"), |
|
1235 |
- argv[0]); |
|
1234 |
+ fprintf(stderr, _("%s: You cannot use black hole mode unless %s is a TrustedUser\n"), |
|
1235 |
+ argv[0], cpt->strarg); |
|
1236 | 1236 |
return EX_CONFIG; |
1237 | 1237 |
} |
1238 | 1238 |
} |
... | ... |
@@ -6413,39 +6419,87 @@ black_hole(const struct privdata *privdata) |
6413 | 6413 |
must_scan = (*to) ? 0 : 1; |
6414 | 6414 |
|
6415 | 6415 |
for(; *to; to++) { |
6416 |
+ pid_t pid, w; |
|
6417 |
+ int pv[2], status; |
|
6416 | 6418 |
FILE *sendmail; |
6417 |
- char cmd[128]; |
|
6419 |
+ char buf[BUFSIZ]; |
|
6418 | 6420 |
|
6419 |
- snprintf(cmd, sizeof(cmd) - 1, "%s -bv \"%s\"</dev/null 2>&1", |
|
6420 |
- SENDMAIL_BIN, *to); |
|
6421 |
+ cli_dbgmsg("Calling \"%s -bv %s\"\n", SENDMAIL_BIN, *to); |
|
6421 | 6422 |
|
6422 |
- cli_dbgmsg("Calling %s\n", cmd); |
|
6423 |
- sendmail = popen(cmd, "r"); |
|
6423 |
+ if(pipe(pv) < 0) { |
|
6424 |
+ perror("pipe"); |
|
6425 |
+ logg(_("!Can't create pipe\n")); |
|
6426 |
+ must_scan = 1; |
|
6427 |
+ break; |
|
6428 |
+ } |
|
6429 |
+ pid = fork(); |
|
6430 |
+ if(pid == 0) { |
|
6431 |
+ close(1); |
|
6432 |
+ close(pv[0]); |
|
6433 |
+ dup2(pv[1], 1); |
|
6434 |
+ close(pv[1]); |
|
6424 | 6435 |
|
6425 |
- if(sendmail) { |
|
6426 |
- char buf[BUFSIZ]; |
|
6436 |
+ /* |
|
6437 |
+ * Avoid calling popen() since *to isn't trusted |
|
6438 |
+ */ |
|
6439 |
+ execl(SENDMAIL_BIN, "sendmail", "-bv", *to, NULL); |
|
6440 |
+ perror(SENDMAIL_BIN); |
|
6441 |
+ logg("Can't execl %s\n", SENDMAIL_BIN); |
|
6442 |
+ _exit(errno ? errno : 1); |
|
6443 |
+ } |
|
6444 |
+ if(pid == -1) { |
|
6445 |
+ perror("fork"); |
|
6446 |
+ logg(_("!Can't fork\n")); |
|
6447 |
+ close(pv[0]); |
|
6448 |
+ close(pv[1]); |
|
6449 |
+ must_scan = 1; |
|
6450 |
+ break; |
|
6451 |
+ } |
|
6452 |
+ close(pv[1]); |
|
6453 |
+ sendmail = fdopen(pv[0], "r"); |
|
6427 | 6454 |
|
6428 |
- while(fgets(buf, sizeof(buf), sendmail) != NULL) { |
|
6429 |
- if(cli_chomp(buf) == 0) |
|
6430 |
- continue; |
|
6455 |
+ if(sendmail == NULL) { |
|
6456 |
+ logg("fdopen failed\n"); |
|
6457 |
+ close(pv[0]); |
|
6458 |
+ must_scan = 1; |
|
6459 |
+ break; |
|
6460 |
+ } |
|
6431 | 6461 |
|
6432 |
- cli_dbgmsg("sendmail output: %s\n", buf); |
|
6462 |
+ while(fgets(buf, sizeof(buf), sendmail) != NULL) { |
|
6463 |
+ if(cli_chomp(buf) == 0) |
|
6464 |
+ continue; |
|
6433 | 6465 |
|
6434 |
- if(strstr(buf, "... deliverable: mailer ")) { |
|
6435 |
- const char *p = strstr(buf, ", user "); |
|
6466 |
+ cli_dbgmsg("sendmail output: %s\n", buf); |
|
6436 | 6467 |
|
6437 |
- if(strcmp(&p[7], "/dev/null") != 0) { |
|
6438 |
- must_scan = 1; |
|
6439 |
- break; |
|
6440 |
- } |
|
6468 |
+ if(strstr(buf, "... deliverable: mailer ")) { |
|
6469 |
+ const char *p = strstr(buf, ", user "); |
|
6470 |
+ |
|
6471 |
+ if(strcmp(&p[7], "/dev/null") != 0) { |
|
6472 |
+ must_scan = 1; |
|
6473 |
+ break; |
|
6441 | 6474 |
} |
6442 | 6475 |
} |
6443 |
- if(pclose(sendmail) != 0) |
|
6476 |
+ } |
|
6477 |
+ fclose(sendmail); |
|
6478 |
+ |
|
6479 |
+ status = -1; |
|
6480 |
+ do |
|
6481 |
+ w = wait(&status); |
|
6482 |
+ while((w != pid) && (w != -1)); |
|
6483 |
+ |
|
6484 |
+ if(w == -1) |
|
6485 |
+ status = -1; |
|
6486 |
+ else |
|
6487 |
+ status = WEXITSTATUS(status); |
|
6488 |
+ |
|
6489 |
+ switch(status) { |
|
6490 |
+ case EX_NOUSER: |
|
6491 |
+ case EX_OK: |
|
6492 |
+ break; |
|
6493 |
+ default: |
|
6494 |
+ logg(_("^Can't execute '%s' to expand '%s' (error %d)\n"), |
|
6495 |
+ SENDMAIL_BIN, *to, WEXITSTATUS(status)); |
|
6444 | 6496 |
must_scan = 1; |
6445 |
- } else { |
|
6446 |
- logg(_("^Can't execute '%s' to expand '%s'"), |
|
6447 |
- cmd, *to); |
|
6448 |
- must_scan = 1; |
|
6449 | 6497 |
} |
6450 | 6498 |
if(must_scan) |
6451 | 6499 |
break; |
... | ... |
@@ -301,6 +301,7 @@ thrown away even if the message is clean. |
301 | 301 |
Enabling this stops these messages from being scanned |
302 | 302 |
(in practice clamav\-milter will discard |
303 | 303 |
these messages so the message doesn't go further down the milter call chain). |
304 |
+Only enable this if your site has many addresses aliased to /dev/null. |
|
304 | 305 |
.IP |
305 | 306 |
To enable this mode clamav-milter must have certain sendmail rights: |
306 | 307 |
it needs to run as a TrustedUser as defined by \fIsendmail\fR |
... | ... |
@@ -308,7 +309,10 @@ it needs to run as a TrustedUser as defined by \fIsendmail\fR |
308 | 308 |
by the use of the User directive in clamd.conf, |
309 | 309 |
the clamav user must be able read the mail queue (often /var/spool/mqueue), |
310 | 310 |
and AllowSupplementaryGroups must be enabled in clamd.conf. |
311 |
-Only enable this if your site has many addresses aliased to /dev/null. |
|
311 |
+Some operating systems set \fI/var/spool/mqueue\fR to be mode 700 forcing you to |
|
312 |
+run clamav-milter as root for black-hole-mode. |
|
313 |
+This is always unadvisable, it is better to have \fI/var/spool/mqueue\fR as |
|
314 |
+mode 750. |
|
312 | 315 |
.SH "BUGS" |
313 | 316 |
There is no support for IPv6. |
314 | 317 |
.SH "EXAMPLES" |
... | ... |
@@ -209,6 +209,7 @@ cli_pdf(const char *dir, int desc, const cli_ctx *ctx) |
209 | 209 |
xreflength = (size_t)(trailerstart - xrefstart); |
210 | 210 |
bytesleft -= xreflength; |
211 | 211 |
*/ |
212 |
+ *ctx->virname = NULL; |
|
212 | 213 |
|
213 | 214 |
/* |
214 | 215 |
* The body section consists of a sequence of indirect objects |
... | ... |
@@ -490,8 +491,15 @@ cli_pdf(const char *dir, int desc, const cli_ctx *ctx) |
490 | 490 |
if(is_flatedecode) { |
491 | 491 |
const int zstat = try_flatedecode((unsigned char *)tmpbuf, real_streamlen, real_streamlen, fout, ctx); |
492 | 492 |
|
493 |
- if(zstat != Z_OK) |
|
494 |
- rc = CL_EZIP; |
|
493 |
+ switch(zstat) { |
|
494 |
+ case Z_DATA_ERROR: |
|
495 |
+ rc = *ctx->virname ? CL_VIRUS : CL_EZIP; |
|
496 |
+ break; |
|
497 |
+ case Z_OK: |
|
498 |
+ break; |
|
499 |
+ default: |
|
500 |
+ rc = CL_EZIP; |
|
501 |
+ } |
|
495 | 502 |
} else |
496 | 503 |
cli_writen(fout, (const char *)streamstart, real_streamlen); |
497 | 504 |
} |
... | ... |
@@ -499,8 +507,15 @@ cli_pdf(const char *dir, int desc, const cli_ctx *ctx) |
499 | 499 |
} else if(is_flatedecode) { |
500 | 500 |
const int zstat = try_flatedecode((unsigned char *)streamstart, real_streamlen, calculated_streamlen, fout, ctx); |
501 | 501 |
|
502 |
- if(zstat != Z_OK) |
|
503 |
- rc = CL_EZIP; |
|
502 |
+ switch(zstat) { |
|
503 |
+ case Z_DATA_ERROR: |
|
504 |
+ rc = *ctx->virname ? CL_VIRUS : CL_EZIP; |
|
505 |
+ break; |
|
506 |
+ case Z_OK: |
|
507 |
+ break; |
|
508 |
+ default: |
|
509 |
+ rc = CL_EZIP; |
|
510 |
+ } |
|
504 | 511 |
} else { |
505 | 512 |
cli_dbgmsg("cli_pdf: writing %lu bytes from the stream\n", |
506 | 513 |
(unsigned long)real_streamlen); |
... | ... |
@@ -624,21 +639,14 @@ flatedecode(unsigned char *buf, off_t len, int fout, const cli_ctx *ctx) |
624 | 624 |
|
625 | 625 |
nbytes += cli_writen(fout, output, sizeof(output)); |
626 | 626 |
|
627 |
- /* |
|
628 |
- * BLOCKMAX is on if ArchiveBlockMax |
|
629 |
- * is set in clamd.conf |
|
630 |
- * |
|
631 |
- * Bug 608 Michael Brennen |
|
632 |
- * <michael@fishnet.us> |
|
633 |
- */ |
|
634 | 627 |
if(ctx->limits && |
635 | 628 |
ctx->limits->maxfilesize && |
636 |
- BLOCKMAX && |
|
637 | 629 |
(nbytes > (off_t) ctx->limits->maxfilesize)) { |
638 | 630 |
cli_dbgmsg("cli_pdf: flatedecode size exceeded (%lu)\n", |
639 | 631 |
(unsigned long)nbytes); |
640 | 632 |
inflateEnd(&stream); |
641 |
- *ctx->virname = "PDF.ExceededFileSize"; |
|
633 |
+ if(BLOCKMAX) |
|
634 |
+ *ctx->virname = "PDF.ExceededFileSize"; |
|
642 | 635 |
return Z_DATA_ERROR; |
643 | 636 |
} |
644 | 637 |
stream.next_out = output; |
... | ... |
@@ -672,11 +680,11 @@ flatedecode(unsigned char *buf, off_t len, int fout, const cli_ctx *ctx) |
672 | 672 |
|
673 | 673 |
if(ctx->limits && |
674 | 674 |
ctx->limits->maxratio && |
675 |
- BLOCKMAX && |
|
676 | 675 |
((stream.total_out / stream.total_in) > ctx->limits->maxratio)) { |
677 | 676 |
cli_dbgmsg("cli_pdf: flatedecode Max ratio reached\n"); |
678 | 677 |
inflateEnd(&stream); |
679 |
- *ctx->virname = "Oversized.PDF"; |
|
678 |
+ if(BLOCKMAX) |
|
679 |
+ *ctx->virname = "Oversized.PDF"; |
|
680 | 680 |
return Z_DATA_ERROR; |
681 | 681 |
} |
682 | 682 |
|