Browse code

Added --freshclam-monitor

git-svn: trunk@1730

Nigel Horne authored on 2005/10/01 01:01:59
Showing 3 changed files
... ...
@@ -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",