git-svn: trunk@1730
Nigel Horne authored on 2005/10/01 01:01:59... | ... |
@@ -1,3 +1,7 @@ |
1 |
+Fri Sep 30 17:00:49 BST 2005 (njh) |
|
2 |
+---------------------------------- |
|
3 |
+ * clamav-milter: Added --freshclam-monitor |
|
4 |
+ |
|
1 | 5 |
Mon Sep 26 19:40:14 CEST 2005 (tk) |
2 | 6 |
---------------------------------- |
3 | 7 |
* libclamav/matcher.c: cl_build: cli_addtypesigs was corrupting AC trie in |
... | ... |
@@ -22,9 +22,9 @@ |
22 | 22 |
* |
23 | 23 |
* For installation instructions see the file INSTALL that came with this file |
24 | 24 |
*/ |
25 |
-static char const rcsid[] = "$Id: clamav-milter.c,v 1.219 2005/08/24 19:02:11 nigelhorne Exp $"; |
|
25 |
+static char const rcsid[] = "$Id: clamav-milter.c,v 1.220 2005/09/30 16:01:57 nigelhorne Exp $"; |
|
26 | 26 |
|
27 |
-#define CM_VERSION "devel-240805" |
|
27 |
+#define CM_VERSION "devel-300905" |
|
28 | 28 |
|
29 | 29 |
#if HAVE_CONFIG_H |
30 | 30 |
#include "clamav-config.h" |
... | ... |
@@ -129,6 +129,9 @@ typedef unsigned int in_addr_t; |
129 | 129 |
|
130 | 130 |
#define VERSION_LENGTH 128 |
131 | 131 |
|
132 |
+/* DO NOT ENABLE THIS, it is for my research only */ |
|
133 |
+/*#define REPORT_PHISHING "reportphishing@antiphishing.org"*/ |
|
134 |
+ |
|
132 | 135 |
/*#define SESSION /* |
133 | 136 |
* Keep one command connection open to clamd, otherwise a new |
134 | 137 |
* command connection is created for each new email |
... | ... |
@@ -374,6 +377,11 @@ static pthread_mutex_t n_children_mutex = PTHREAD_MUTEX_INITIALIZER; |
374 | 374 |
static pthread_cond_t n_children_cond = PTHREAD_COND_INITIALIZER; |
375 | 375 |
static volatile unsigned int n_children = 0; |
376 | 376 |
static unsigned int max_children = 0; |
377 |
+static unsigned int freshclam_monitor = 10; /* |
|
378 |
+ * how often, in |
|
379 |
+ * seconds, to scan for |
|
380 |
+ * database updates |
|
381 |
+ */ |
|
377 | 382 |
static int child_timeout = 300; /* number of seconds to wait for |
378 | 383 |
* a child to die. Set to 0 to |
379 | 384 |
* wait forever |
... | ... |
@@ -477,6 +485,7 @@ help(void) |
477 | 477 |
puts(_("\t--dont-scan-on-error\t-d\tPass e-mails through unscanned if a system error occurs.")); |
478 | 478 |
puts(_("\t--dont-wait\t\t\tAsk remote end to resend if max-children exceeded.")); |
479 | 479 |
puts(_("\t--external\t\t-e\tUse an external scanner (usually clamd).")); |
480 |
+ puts(_("\t--freshclam-monitor=SECS\t-M SECS\tHow often to check for database update.")); |
|
480 | 481 |
puts(_("\t--from=EMAIL\t\t-a EMAIL\tError messages come from here.")); |
481 | 482 |
puts(_("\t--force-scan\t\t-f\tForce scan all messages (overrides (-o and -l).")); |
482 | 483 |
puts(_("\t--help\t\t\t-h\tThis message.")); |
... | ... |
@@ -569,9 +578,9 @@ main(int argc, char **argv) |
569 | 569 |
for(;;) { |
570 | 570 |
int opt_index = 0; |
571 | 571 |
#ifdef CL_DEBUG |
572 |
- const char *args = "a:AbB:c:CdDefF:lLm:nNop:PqQ:hHs:St:T:U:VwW:x:0:"; |
|
572 |
+ const char *args = "a:AbB:c:CdDefF:lLm:M:nNop:PqQ:hHs:St:T:U:VwW:x:0:"; |
|
573 | 573 |
#else |
574 |
- const char *args = "a:AbB:c:CdDefF:lLm:nNop:PqQ:hHs:St:T:U:VwW:0:"; |
|
574 |
+ const char *args = "a:AbB:c:CdDefF:lLm:M:nNop:PqQ:hHs:St:T:U:VwW:0:"; |
|
575 | 575 |
#endif |
576 | 576 |
|
577 | 577 |
static struct option long_options[] = { |
... | ... |
@@ -650,6 +659,12 @@ main(int argc, char **argv) |
650 | 650 |
{ |
651 | 651 |
"max-children", 1, NULL, 'm' |
652 | 652 |
}, |
653 |
+ { |
|
654 |
+ "freshclam-monitor", 1, NULL, 'M' |
|
655 |
+ }, |
|
656 |
+ { |
|
657 |
+ "sendmail-cf", 1, NULL, '0' |
|
658 |
+ }, |
|
653 | 659 |
{ |
654 | 660 |
"server", 1, NULL, 's' |
655 | 661 |
}, |
... | ... |
@@ -671,9 +686,6 @@ main(int argc, char **argv) |
671 | 671 |
{ |
672 | 672 |
"version", 0, NULL, 'V' |
673 | 673 |
}, |
674 |
- { |
|
675 |
- "sendmail-cf", 1, NULL, '0' |
|
676 |
- }, |
|
677 | 674 |
#ifdef CL_DEBUG |
678 | 675 |
{ |
679 | 676 |
"debug-level", 1, NULL, 'x' |
... | ... |
@@ -747,6 +759,9 @@ main(int argc, char **argv) |
747 | 747 |
case 'm': /* maximum number of children */ |
748 | 748 |
max_children = atoi(optarg); |
749 | 749 |
break; |
750 |
+ case 'M': /* how often to monitor for freshclam */ |
|
751 |
+ freshclam_monitor = atoi(optarg); |
|
752 |
+ break; |
|
750 | 753 |
case 'n': /* don't add X-Virus-Scanned */ |
751 | 754 |
nflag++; |
752 | 755 |
smfilter.xxfi_flags &= ~(SMFIF_ADDHDRS|SMFIF_CHGHDRS); |
... | ... |
@@ -815,9 +830,9 @@ main(int argc, char **argv) |
815 | 815 |
#endif |
816 | 816 |
default: |
817 | 817 |
#ifdef CL_DEBUG |
818 |
- fprintf(stderr, "Usage: %s [-b] [-c FILE] [-F FILE] [--max-children=num] [-e] [-l] [-o] [-p address] [-P] [-q] [-Q USER] [-s SERVER] [-S] [-x#] [-U PATH] socket-addr\n", argv[0]); |
|
818 |
+ fprintf(stderr, "Usage: %s [-b] [-c FILE] [-F FILE] [--max-children=num] [-e] [-l] [-o] [-p address] [-P] [-q] [-Q USER] [-s SERVER] [-S] [-x#] [-U PATH] [-M#] socket-addr\n", argv[0]); |
|
819 | 819 |
#else |
820 |
- fprintf(stderr, "Usage: %s [-b] [-c FILE] [-F FILE] [--max-children=num] [-e] [-l] [-o] [-p address] [-P] [-q] [-Q USER] [-s SERVER] [-S] [-U PATH] socket-addr\n", argv[0]); |
|
820 |
+ fprintf(stderr, "Usage: %s [-b] [-c FILE] [-F FILE] [--max-children=num] [-e] [-l] [-o] [-p address] [-P] [-q] [-Q USER] [-s SERVER] [-S] [-U PATH] [-M#] socket-addr\n", argv[0]); |
|
821 | 821 |
#endif |
822 | 822 |
return EX_USAGE; |
823 | 823 |
} |
... | ... |
@@ -1088,6 +1103,10 @@ main(int argc, char **argv) |
1088 | 1088 |
fprintf(stderr, _("%s: --max-children must be given if --external is not given\n"), argv[0]); |
1089 | 1089 |
return EX_CONFIG; |
1090 | 1090 |
} |
1091 |
+ if(freshclam_monitor <= 0) { |
|
1092 |
+ fprintf(stderr, _("%s: --freshclam_monitor must be at least one second\n"), argv[0]); |
|
1093 |
+ return EX_CONFIG; |
|
1094 |
+ } |
|
1091 | 1095 |
#if 0 |
1092 | 1096 |
if(child_timeout) { |
1093 | 1097 |
fprintf(stderr, _("%s: --timeout must not be given if --external is not given\n"), argv[0]); |
... | ... |
@@ -2232,7 +2251,13 @@ clamfi_envfrom(SMFICTX *ctx, char **argv) |
2232 | 2232 |
* Patch from Damian Menscher <menscher@uiuc.edu> to |
2233 | 2233 |
* ensure it wakes up when a child goes away |
2234 | 2234 |
*/ |
2235 |
- do |
|
2235 |
+ do { |
|
2236 |
+ if(use_syslog) |
|
2237 |
+ /* LOG_INFO */ |
|
2238 |
+ syslog(LOG_NOTICE, |
|
2239 |
+ _("n_children %u: waiting %d seconds for some to exit"), |
|
2240 |
+ n_children, child_timeout); |
|
2241 |
+ |
|
2236 | 2242 |
if(child_timeout == 0) { |
2237 | 2243 |
pthread_cond_wait(&n_children_cond, &n_children_mutex); |
2238 | 2244 |
rc = 0; |
... | ... |
@@ -2246,7 +2271,7 @@ clamfi_envfrom(SMFICTX *ctx, char **argv) |
2246 | 2246 |
|
2247 | 2247 |
rc = pthread_cond_timedwait(&n_children_cond, &n_children_mutex, &timeout); |
2248 | 2248 |
} |
2249 |
- while((n_children >= max_children) && (rc != ETIMEDOUT)); |
|
2249 |
+ } while((n_children >= max_children) && (rc != ETIMEDOUT)); |
|
2250 | 2250 |
} |
2251 | 2251 |
n_children++; |
2252 | 2252 |
|
... | ... |
@@ -2805,6 +2830,10 @@ clamfi_eom(SMFICTX *ctx) |
2805 | 2805 |
smfi_addheader(ctx, "X-Virus-Scanned", buf); |
2806 | 2806 |
} |
2807 | 2807 |
|
2808 |
+ /* |
|
2809 |
+ * TODO: it would be useful to add a header if mbox.c/FOLLOWURLS was |
|
2810 |
+ * exceeded |
|
2811 |
+ */ |
|
2808 | 2812 |
if(strstr(mess, "ERROR") != NULL) { |
2809 | 2813 |
if(strstr(mess, "Size limit reached") != NULL) { |
2810 | 2814 |
/* |
... | ... |
@@ -2827,7 +2856,7 @@ clamfi_eom(SMFICTX *ctx) |
2827 | 2827 |
rc = cl_error; |
2828 | 2828 |
} else if((ptr = strstr(mess, "FOUND")) != NULL) { |
2829 | 2829 |
/* |
2830 |
- * Fixme: This will give false positives if the |
|
2830 |
+ * FIXME: This will give false positives if the |
|
2831 | 2831 |
* word "FOUND" is in the email, e.g. the |
2832 | 2832 |
* quarantine directory is /tmp/VIRUSES-FOUND |
2833 | 2833 |
*/ |
... | ... |
@@ -3029,6 +3058,42 @@ clamfi_eom(SMFICTX *ctx) |
3029 | 3029 |
privdata->filename = NULL; |
3030 | 3030 |
} |
3031 | 3031 |
|
3032 |
+#ifdef REPORT_PHISHING |
|
3033 |
+ if((quarantine == NULL) && (!advisory) && |
|
3034 |
+ (strstr(virusname, "Phishing") != NULL)) { |
|
3035 |
+ for(to = privdata->to; *to; to++) { |
|
3036 |
+ smfi_delrcpt(ctx, *to); |
|
3037 |
+ smfi_addheader(ctx, "X-Original-To", *to); |
|
3038 |
+ free(*to); |
|
3039 |
+ } |
|
3040 |
+ free(privdata->to); |
|
3041 |
+ privdata->to = NULL; |
|
3042 |
+ if(smfi_addrcpt(ctx, REPORT_PHISHING) == MI_FAILURE) { |
|
3043 |
+ /* It's a remote site */ |
|
3044 |
+ if(privdata->filename) { |
|
3045 |
+ char cmd[128]; |
|
3046 |
+ |
|
3047 |
+ snprintf(cmd, sizeof(cmd), "rmail %s < %s", REPORT_PHISHING, privdata->filename); |
|
3048 |
+ if(system(cmd) == 0) |
|
3049 |
+ if(use_syslog) |
|
3050 |
+ syslog(LOG_INFO, _("Reported phishing to %s"), REPORT_PHISHING); |
|
3051 |
+ |
|
3052 |
+ } |
|
3053 |
+ if(use_syslog) |
|
3054 |
+ syslog(LOG_ERR, _("Can't set anti-phish header")); |
|
3055 |
+ else |
|
3056 |
+ cli_warnmsg(_("Can't set anti-phish header\n")); |
|
3057 |
+ rc = (privdata->discard) ? SMFIS_DISCARD : SMFIS_REJECT; |
|
3058 |
+ } else { |
|
3059 |
+ setsubject(ctx, "Phishing attempt trapped and redirected"); |
|
3060 |
+ |
|
3061 |
+ if(use_syslog) |
|
3062 |
+ syslog(LOG_DEBUG, "Redirected phish to %s", REPORT_PHISHING); |
|
3063 |
+ cli_dbgmsg("Redirected phish to %s\n", REPORT_PHISHING); |
|
3064 |
+ } |
|
3065 |
+ } else |
|
3066 |
+#endif |
|
3067 |
+ |
|
3032 | 3068 |
if(quarantine) { |
3033 | 3069 |
for(to = privdata->to; *to; to++) { |
3034 | 3070 |
smfi_delrcpt(ctx, *to); |
... | ... |
@@ -3048,10 +3113,17 @@ clamfi_eom(SMFICTX *ctx) |
3048 | 3048 |
cli_warnmsg(_("Can't set quarantine user %s\n"), quarantine); |
3049 | 3049 |
rc = (privdata->discard) ? SMFIS_DISCARD : SMFIS_REJECT; |
3050 | 3050 |
} else { |
3051 |
+#ifdef REPORT_PHISHING |
|
3052 |
+ if(strstr(virusname, "Phishing") != NULL) { |
|
3053 |
+ (void)smfi_addrcpt(ctx, REPORT_PHISHING); |
|
3054 |
+ setsubject(ctx, "Blocked Phishing Attempt"); |
|
3055 |
+ } else |
|
3056 |
+#endif |
|
3057 |
+ setsubject(ctx, virusname); |
|
3058 |
+ |
|
3051 | 3059 |
if(use_syslog) |
3052 | 3060 |
syslog(LOG_DEBUG, "Redirected virus to %s", quarantine); |
3053 | 3061 |
cli_dbgmsg("Redirected virus to %s\n", quarantine); |
3054 |
- setsubject(ctx, virusname); |
|
3055 | 3062 |
} |
3056 | 3063 |
} else if(advisory) |
3057 | 3064 |
setsubject(ctx, virusname); |
... | ... |
@@ -4420,7 +4492,7 @@ watchdog(void *a) |
4420 | 4420 |
|
4421 | 4421 |
gettimeofday(&tp, NULL); |
4422 | 4422 |
|
4423 |
- ts.tv_sec = tp.tv_sec + readTimeout - 1; |
|
4423 |
+ ts.tv_sec = tp.tv_sec + freshclam_monitor; |
|
4424 | 4424 |
ts.tv_nsec = tp.tv_usec * 1000; |
4425 | 4425 |
cli_dbgmsg("watchdog sleeps\n"); |
4426 | 4426 |
pthread_mutex_lock(&watchdog_mutex); |
... | ... |
@@ -4572,7 +4644,7 @@ watchdog(void *a) |
4572 | 4572 |
|
4573 | 4573 |
gettimeofday(&tp, NULL); |
4574 | 4574 |
|
4575 |
- ts.tv_sec = tp.tv_sec + readTimeout - 1; |
|
4575 |
+ ts.tv_sec = tp.tv_sec + freshclam_monitor; |
|
4576 | 4576 |
ts.tv_nsec = tp.tv_usec * 1000; |
4577 | 4577 |
cli_dbgmsg("watchdog sleeps\n"); |
4578 | 4578 |
pthread_mutex_lock(&watchdog_mutex); |
... | ... |
@@ -106,6 +106,15 @@ the scanning. |
106 | 106 |
Also scan messages sent from LAN. You probably want this especially if |
107 | 107 |
your LAN is populated by machines running Windows or DOS. |
108 | 108 |
.TP |
109 |
+\fB-M, \-\-freshclam-monitor\fR |
|
110 |
+When not running in external mode, this option tells clamav\-milter how |
|
111 |
+often to check that the virus database has been updated, probably by |
|
112 |
+freshclam(1). |
|
113 |
+The option takes one parameter, which is a number in seconds. |
|
114 |
+The default is 300 seconds. |
|
115 |
+The checking cannot be disabled, a value less than or equal to zero will be |
|
116 |
+rejected. |
|
117 |
+.TP |
|
109 | 118 |
\fB-n, \-\-noxheader\fR |
110 | 119 |
Usually clamav\-milter adds headings to messages that are scanned. |
111 | 120 |
The headers are of the form "X-Virus-Scanned: version", |