diff --git a/clamav-devel/ChangeLog b/clamav-devel/ChangeLog index 04867ee85..fa192bf1c 100644 --- a/clamav-devel/ChangeLog +++ b/clamav-devel/ChangeLog @@ -1,3 +1,7 @@ +Fri Sep 30 17:00:49 BST 2005 (njh) +---------------------------------- + * clamav-milter: Added --freshclam-monitor + Mon Sep 26 19:40:14 CEST 2005 (tk) ---------------------------------- * libclamav/matcher.c: cl_build: cli_addtypesigs was corrupting AC trie in diff --git a/clamav-devel/clamav-milter/clamav-milter.c b/clamav-devel/clamav-milter/clamav-milter.c index c7df45a83..6a0237479 100644 --- a/clamav-devel/clamav-milter/clamav-milter.c +++ b/clamav-devel/clamav-milter/clamav-milter.c @@ -22,9 +22,9 @@ * * For installation instructions see the file INSTALL that came with this file */ -static char const rcsid[] = "$Id: clamav-milter.c,v 1.219 2005/08/24 19:02:11 nigelhorne Exp $"; +static char const rcsid[] = "$Id: clamav-milter.c,v 1.220 2005/09/30 16:01:57 nigelhorne Exp $"; -#define CM_VERSION "devel-240805" +#define CM_VERSION "devel-300905" #if HAVE_CONFIG_H #include "clamav-config.h" @@ -129,6 +129,9 @@ typedef unsigned int in_addr_t; #define VERSION_LENGTH 128 +/* DO NOT ENABLE THIS, it is for my research only */ +/*#define REPORT_PHISHING "reportphishing@antiphishing.org"*/ + /*#define SESSION /* * Keep one command connection open to clamd, otherwise a new * command connection is created for each new email @@ -374,6 +377,11 @@ static pthread_mutex_t n_children_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t n_children_cond = PTHREAD_COND_INITIALIZER; static volatile unsigned int n_children = 0; static unsigned int max_children = 0; +static unsigned int freshclam_monitor = 10; /* + * how often, in + * seconds, to scan for + * database updates + */ static int child_timeout = 300; /* number of seconds to wait for * a child to die. Set to 0 to * wait forever @@ -477,6 +485,7 @@ help(void) puts(_("\t--dont-scan-on-error\t-d\tPass e-mails through unscanned if a system error occurs.")); puts(_("\t--dont-wait\t\t\tAsk remote end to resend if max-children exceeded.")); puts(_("\t--external\t\t-e\tUse an external scanner (usually clamd).")); + puts(_("\t--freshclam-monitor=SECS\t-M SECS\tHow often to check for database update.")); puts(_("\t--from=EMAIL\t\t-a EMAIL\tError messages come from here.")); puts(_("\t--force-scan\t\t-f\tForce scan all messages (overrides (-o and -l).")); puts(_("\t--help\t\t\t-h\tThis message.")); @@ -569,9 +578,9 @@ main(int argc, char **argv) for(;;) { int opt_index = 0; #ifdef CL_DEBUG - const char *args = "a:AbB:c:CdDefF:lLm:nNop:PqQ:hHs:St:T:U:VwW:x:0:"; + const char *args = "a:AbB:c:CdDefF:lLm:M:nNop:PqQ:hHs:St:T:U:VwW:x:0:"; #else - const char *args = "a:AbB:c:CdDefF:lLm:nNop:PqQ:hHs:St:T:U:VwW:0:"; + const char *args = "a:AbB:c:CdDefF:lLm:M:nNop:PqQ:hHs:St:T:U:VwW:0:"; #endif static struct option long_options[] = { @@ -650,6 +659,12 @@ main(int argc, char **argv) { "max-children", 1, NULL, 'm' }, + { + "freshclam-monitor", 1, NULL, 'M' + }, + { + "sendmail-cf", 1, NULL, '0' + }, { "server", 1, NULL, 's' }, @@ -671,9 +686,6 @@ main(int argc, char **argv) { "version", 0, NULL, 'V' }, - { - "sendmail-cf", 1, NULL, '0' - }, #ifdef CL_DEBUG { "debug-level", 1, NULL, 'x' @@ -747,6 +759,9 @@ main(int argc, char **argv) case 'm': /* maximum number of children */ max_children = atoi(optarg); break; + case 'M': /* how often to monitor for freshclam */ + freshclam_monitor = atoi(optarg); + break; case 'n': /* don't add X-Virus-Scanned */ nflag++; smfilter.xxfi_flags &= ~(SMFIF_ADDHDRS|SMFIF_CHGHDRS); @@ -815,9 +830,9 @@ main(int argc, char **argv) #endif default: #ifdef CL_DEBUG - 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]); + 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]); #else - 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]); + 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]); #endif return EX_USAGE; } @@ -1088,6 +1103,10 @@ main(int argc, char **argv) fprintf(stderr, _("%s: --max-children must be given if --external is not given\n"), argv[0]); return EX_CONFIG; } + if(freshclam_monitor <= 0) { + fprintf(stderr, _("%s: --freshclam_monitor must be at least one second\n"), argv[0]); + return EX_CONFIG; + } #if 0 if(child_timeout) { 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) * Patch from Damian Menscher to * ensure it wakes up when a child goes away */ - do + do { + if(use_syslog) + /* LOG_INFO */ + syslog(LOG_NOTICE, + _("n_children %u: waiting %d seconds for some to exit"), + n_children, child_timeout); + if(child_timeout == 0) { pthread_cond_wait(&n_children_cond, &n_children_mutex); rc = 0; @@ -2246,7 +2271,7 @@ clamfi_envfrom(SMFICTX *ctx, char **argv) rc = pthread_cond_timedwait(&n_children_cond, &n_children_mutex, &timeout); } - while((n_children >= max_children) && (rc != ETIMEDOUT)); + } while((n_children >= max_children) && (rc != ETIMEDOUT)); } n_children++; @@ -2805,6 +2830,10 @@ clamfi_eom(SMFICTX *ctx) smfi_addheader(ctx, "X-Virus-Scanned", buf); } + /* + * TODO: it would be useful to add a header if mbox.c/FOLLOWURLS was + * exceeded + */ if(strstr(mess, "ERROR") != NULL) { if(strstr(mess, "Size limit reached") != NULL) { /* @@ -2827,7 +2856,7 @@ clamfi_eom(SMFICTX *ctx) rc = cl_error; } else if((ptr = strstr(mess, "FOUND")) != NULL) { /* - * Fixme: This will give false positives if the + * FIXME: This will give false positives if the * word "FOUND" is in the email, e.g. the * quarantine directory is /tmp/VIRUSES-FOUND */ @@ -3029,6 +3058,42 @@ clamfi_eom(SMFICTX *ctx) privdata->filename = NULL; } +#ifdef REPORT_PHISHING + if((quarantine == NULL) && (!advisory) && + (strstr(virusname, "Phishing") != NULL)) { + for(to = privdata->to; *to; to++) { + smfi_delrcpt(ctx, *to); + smfi_addheader(ctx, "X-Original-To", *to); + free(*to); + } + free(privdata->to); + privdata->to = NULL; + if(smfi_addrcpt(ctx, REPORT_PHISHING) == MI_FAILURE) { + /* It's a remote site */ + if(privdata->filename) { + char cmd[128]; + + snprintf(cmd, sizeof(cmd), "rmail %s < %s", REPORT_PHISHING, privdata->filename); + if(system(cmd) == 0) + if(use_syslog) + syslog(LOG_INFO, _("Reported phishing to %s"), REPORT_PHISHING); + + } + if(use_syslog) + syslog(LOG_ERR, _("Can't set anti-phish header")); + else + cli_warnmsg(_("Can't set anti-phish header\n")); + rc = (privdata->discard) ? SMFIS_DISCARD : SMFIS_REJECT; + } else { + setsubject(ctx, "Phishing attempt trapped and redirected"); + + if(use_syslog) + syslog(LOG_DEBUG, "Redirected phish to %s", REPORT_PHISHING); + cli_dbgmsg("Redirected phish to %s\n", REPORT_PHISHING); + } + } else +#endif + if(quarantine) { for(to = privdata->to; *to; to++) { smfi_delrcpt(ctx, *to); @@ -3048,10 +3113,17 @@ clamfi_eom(SMFICTX *ctx) cli_warnmsg(_("Can't set quarantine user %s\n"), quarantine); rc = (privdata->discard) ? SMFIS_DISCARD : SMFIS_REJECT; } else { +#ifdef REPORT_PHISHING + if(strstr(virusname, "Phishing") != NULL) { + (void)smfi_addrcpt(ctx, REPORT_PHISHING); + setsubject(ctx, "Blocked Phishing Attempt"); + } else +#endif + setsubject(ctx, virusname); + if(use_syslog) syslog(LOG_DEBUG, "Redirected virus to %s", quarantine); cli_dbgmsg("Redirected virus to %s\n", quarantine); - setsubject(ctx, virusname); } } else if(advisory) setsubject(ctx, virusname); @@ -4420,7 +4492,7 @@ watchdog(void *a) gettimeofday(&tp, NULL); - ts.tv_sec = tp.tv_sec + readTimeout - 1; + ts.tv_sec = tp.tv_sec + freshclam_monitor; ts.tv_nsec = tp.tv_usec * 1000; cli_dbgmsg("watchdog sleeps\n"); pthread_mutex_lock(&watchdog_mutex); @@ -4572,7 +4644,7 @@ watchdog(void *a) gettimeofday(&tp, NULL); - ts.tv_sec = tp.tv_sec + readTimeout - 1; + ts.tv_sec = tp.tv_sec + freshclam_monitor; ts.tv_nsec = tp.tv_usec * 1000; cli_dbgmsg("watchdog sleeps\n"); pthread_mutex_lock(&watchdog_mutex); diff --git a/clamav-devel/docs/man/clamav-milter.8 b/clamav-devel/docs/man/clamav-milter.8 index 26de07d72..144c1c80f 100644 --- a/clamav-devel/docs/man/clamav-milter.8 +++ b/clamav-devel/docs/man/clamav-milter.8 @@ -106,6 +106,15 @@ the scanning. Also scan messages sent from LAN. You probably want this especially if your LAN is populated by machines running Windows or DOS. .TP +\fB-M, \-\-freshclam-monitor\fR +When not running in external mode, this option tells clamav\-milter how +often to check that the virus database has been updated, probably by +freshclam(1). +The option takes one parameter, which is a number in seconds. +The default is 300 seconds. +The checking cannot be disabled, a value less than or equal to zero will be +rejected. +.TP \fB-n, \-\-noxheader\fR Usually clamav\-milter adds headings to messages that are scanned. The headers are of the form "X-Virus-Scanned: version",