git-svn: trunk@2710
Nigel Horne authored on 2007/02/13 00:02:48... | ... |
@@ -1,3 +1,7 @@ |
1 |
+Mon Feb 12 15:02:13 GMT 2007 (njh) |
|
2 |
+---------------------------------- |
|
3 |
+ * clamav-milter/clamav-milter.c: Allow From addresses to be whitelisted |
|
4 |
+ |
|
1 | 5 |
Mon Feb 12 14:58:57 CET 2007 (tk) |
2 | 6 |
--------------------------------- |
3 | 7 |
* docs/signatures.pdf: fix some typos (bb#285), thanks to Aeriana |
... | ... |
@@ -24,9 +24,9 @@ |
24 | 24 |
* |
25 | 25 |
* For installation instructions see the file INSTALL that came with this file |
26 | 26 |
*/ |
27 |
-static char const rcsid[] = "$Id: clamav-milter.c,v 1.310 2007/01/17 20:50:10 njh Exp $"; |
|
27 |
+static char const rcsid[] = "$Id: clamav-milter.c,v 1.311 2007/02/12 15:01:50 njh Exp $"; |
|
28 | 28 |
|
29 |
-#define CM_VERSION "devel-170107" |
|
29 |
+#define CM_VERSION "devel-120207" |
|
30 | 30 |
|
31 | 31 |
#if HAVE_CONFIG_H |
32 | 32 |
#include "clamav-config.h" |
... | ... |
@@ -48,9 +48,11 @@ static char const rcsid[] = "$Id: clamav-milter.c,v 1.310 2007/01/17 20:50:10 nj |
48 | 48 |
|
49 | 49 |
#include <stdio.h> |
50 | 50 |
#include <sysexits.h> |
51 |
+#ifdef HAVE_SYS_STAT_H |
|
51 | 52 |
#include <sys/stat.h> |
53 |
+#endif |
|
52 | 54 |
#include <syslog.h> |
53 |
-#if HAVE_STDINT_H |
|
55 |
+#if HAVE_STDLIB_H |
|
54 | 56 |
#include <stdlib.h> |
55 | 57 |
#endif |
56 | 58 |
#if HAVE_MEMORY_H |
... | ... |
@@ -90,6 +92,7 @@ static char const rcsid[] = "$Id: clamav-milter.c,v 1.310 2007/01/17 20:50:10 nj |
90 | 90 |
#ifdef HAVE_UNISTD_H |
91 | 91 |
#include <unistd.h> |
92 | 92 |
#endif |
93 |
+#include <ctype.h> |
|
93 | 94 |
|
94 | 95 |
#if HAVE_MMAP |
95 | 96 |
#if HAVE_SYS_MMAN_H |
... | ... |
@@ -177,8 +180,9 @@ typedef unsigned int in_addr_t; |
177 | 177 |
* sockets is better |
178 | 178 |
* TODO: Test with IPv6 |
179 | 179 |
* TODO: Load balancing, allow local machine to talk via UNIX domain socket. |
180 |
- * TODO: allow each line in the whitelist file to specify a quarantine email |
|
180 |
+ * TODO: allow each To: line in the whitelist file to specify a quarantine email |
|
181 | 181 |
* address |
182 |
+ * TODO: optionally use zlib to compress data sent to remote hosts |
|
182 | 183 |
*/ |
183 | 184 |
|
184 | 185 |
struct header_node_t { |
... | ... |
@@ -211,7 +215,7 @@ static struct cidr_net { /* don't make this const because of -I flag */ |
211 | 211 |
{ PACKADDR(192, 168, 0, 0), MAKEMASK(16) }, /* 192.168.0.0/16 */ |
212 | 212 |
{ PACKADDR( 10, 0, 0, 0), MAKEMASK(24) }, /* 10.0.0.0/24 */ |
213 | 213 |
{ PACKADDR(172, 16, 0, 0), MAKEMASK(20) }, /* 172.16.0.0/20 */ |
214 |
- { PACKADDR(169, 254, 0, 0), MAKEMASK(16) }, /* 169.254.0.0/16 */ |
|
214 |
+ { PACKADDR(169, 254, 0, 0), MAKEMASK(16) }, /* 169.254.0.0/16 */ |
|
215 | 215 |
{ 0, 0 }, /* space to put one more via -I addr */ |
216 | 216 |
{ 0, 0 } |
217 | 217 |
}; |
... | ... |
@@ -526,7 +530,7 @@ static void print_trace(void); |
526 | 526 |
#endif |
527 | 527 |
|
528 | 528 |
static int verifyIncomingSocketName(const char *sockName); |
529 |
-static int isWhitelisted(const char *emailaddress); |
|
529 |
+static int isWhitelisted(const char *emailaddress, int to); |
|
530 | 530 |
static int isBlacklisted(const char *ip_address); |
531 | 531 |
static void mx(void); |
532 | 532 |
#ifdef HAVE_RESOLV_H |
... | ... |
@@ -2613,6 +2617,11 @@ clamfi_envfrom(SMFICTX *ctx, char **argv) |
2613 | 2613 |
|
2614 | 2614 |
logg("*clamfi_envfrom: %s\n", argv[0]); |
2615 | 2615 |
|
2616 |
+ if(isWhitelisted(argv[0], 0)) { |
|
2617 |
+ logg(_("*clamfi_envfrom: ignoring whitelisted message")); |
|
2618 |
+ return SMFIS_ACCEPT; |
|
2619 |
+ } |
|
2620 |
+ |
|
2616 | 2621 |
if(strcmp(argv[0], "<>") == 0) { |
2617 | 2622 |
mailaddr = smfi_getsymval(ctx, "{mail_addr}"); |
2618 | 2623 |
if(mailaddr == NULL) |
... | ... |
@@ -2838,7 +2847,7 @@ clamfi_eoh(SMFICTX *ctx) |
2838 | 2838 |
#if 0 |
2839 | 2839 |
/* Mailing lists often say our own posts are from us */ |
2840 | 2840 |
if(detect_forged_local_address && privdata->from && |
2841 |
- (!privdata->sender) && !isWhitelisted(privdata->from)) { |
|
2841 |
+ (!privdata->sender) && !isWhitelisted(privdata->from, 1)) { |
|
2842 | 2842 |
char me[MAXHOSTNAMELEN + 1]; |
2843 | 2843 |
const char *ptr; |
2844 | 2844 |
|
... | ... |
@@ -2887,7 +2896,7 @@ clamfi_eoh(SMFICTX *ctx) |
2887 | 2887 |
* ENDFOR |
2888 | 2888 |
*/ |
2889 | 2889 |
for(to = privdata->to; *to; to++) |
2890 |
- if(!isWhitelisted(*to)) |
|
2890 |
+ if(!isWhitelisted(*to, 1)) |
|
2891 | 2891 |
/* |
2892 | 2892 |
* This recipient is not on the whitelist, |
2893 | 2893 |
* no need to check any further |
... | ... |
@@ -2898,11 +2907,7 @@ clamfi_eoh(SMFICTX *ctx) |
2898 | 2898 |
* Didn't find a recipient who is not on the white list, so all |
2899 | 2899 |
* must be on the white list, so just accept the e-mail |
2900 | 2900 |
*/ |
2901 |
- if(use_syslog) |
|
2902 |
- syslog(LOG_NOTICE, _("clamfi_eoh: ignoring whitelisted message")); |
|
2903 |
-#ifdef CL_DEBUG |
|
2904 |
- cli_dbgmsg(_("clamfi_eoh: ignoring whitelisted message\n")); |
|
2905 |
-#endif |
|
2901 |
+ logg(_("*clamfi_enveoh: ignoring whitelisted message")); |
|
2906 | 2902 |
clamfi_cleanup(ctx); |
2907 | 2903 |
|
2908 | 2904 |
return SMFIS_ACCEPT; |
... | ... |
@@ -5546,9 +5551,10 @@ verifyIncomingSocketName(const char *sockName) |
5546 | 5546 |
* to that domain are to be whitelisted |
5547 | 5547 |
*/ |
5548 | 5548 |
static int |
5549 |
-isWhitelisted(const char *emailaddress) |
|
5549 |
+isWhitelisted(const char *emailaddress, int to) |
|
5550 | 5550 |
{ |
5551 |
- static table_t *whitelist; /* never freed */ |
|
5551 |
+ static table_t *to_whitelist, *from_whitelist; /* never freed */ |
|
5552 |
+ table_t *table; |
|
5552 | 5553 |
|
5553 | 5554 |
cli_dbgmsg("isWhitelisted %s\n", emailaddress); |
5554 | 5555 |
|
... | ... |
@@ -5558,7 +5564,7 @@ isWhitelisted(const char *emailaddress) |
5558 | 5558 |
if(quarantine && (strcasecmp(quarantine, emailaddress) == 0)) |
5559 | 5559 |
return 1; |
5560 | 5560 |
|
5561 |
- if((whitelist == NULL) && whitelistFile) { |
|
5561 |
+ if((to_whitelist == NULL) && whitelistFile) { |
|
5562 | 5562 |
FILE *fin; |
5563 | 5563 |
char buf[BUFSIZ + 1]; |
5564 | 5564 |
|
... | ... |
@@ -5571,16 +5577,26 @@ isWhitelisted(const char *emailaddress) |
5571 | 5571 |
whitelistFile); |
5572 | 5572 |
return 0; |
5573 | 5573 |
} |
5574 |
- whitelist = tableCreate(); |
|
5574 |
+ to_whitelist = tableCreate(); |
|
5575 |
+ from_whitelist = tableCreate(); |
|
5575 | 5576 |
|
5576 |
- if(whitelist == NULL) { |
|
5577 |
+ if((to_whitelist == NULL) || (from_whitelist == NULL)) { |
|
5577 | 5578 |
if(use_syslog) |
5578 | 5579 |
syslog(LOG_ERR, _("Can't create whitelist table")); |
5580 |
+ if(to_whitelist) { |
|
5581 |
+ tableDestroy(to_whitelist); |
|
5582 |
+ to_whitelist = NULL; |
|
5583 |
+ } else { |
|
5584 |
+ tableDestroy(from_whitelist); |
|
5585 |
+ from_whitelist = NULL; |
|
5586 |
+ } |
|
5579 | 5587 |
fclose(fin); |
5580 | 5588 |
return 0; |
5581 | 5589 |
} |
5582 | 5590 |
|
5583 | 5591 |
while(fgets(buf, sizeof(buf), fin) != NULL) { |
5592 |
+ const char *ptr; |
|
5593 |
+ |
|
5584 | 5594 |
/* comment line? */ |
5585 | 5595 |
switch(buf[0]) { |
5586 | 5596 |
case '#': |
... | ... |
@@ -5588,12 +5604,33 @@ isWhitelisted(const char *emailaddress) |
5588 | 5588 |
case ':': |
5589 | 5589 |
continue; |
5590 | 5590 |
} |
5591 |
- if(cli_chomp(buf) > 0) |
|
5592 |
- (void)tableInsert(whitelist, buf, 1); |
|
5591 |
+ if(cli_chomp(buf) > 0) { |
|
5592 |
+ if((ptr = strchr(buf, ':')) != NULL) { |
|
5593 |
+ do |
|
5594 |
+ ptr++; |
|
5595 |
+ while(*ptr && isspace(*ptr)); |
|
5596 |
+ |
|
5597 |
+ if(*ptr == '\0') { |
|
5598 |
+ logg("*Ignoring bad line '%s'\n", |
|
5599 |
+ buf); |
|
5600 |
+ continue; |
|
5601 |
+ } |
|
5602 |
+ } else |
|
5603 |
+ ptr = buf; |
|
5604 |
+ |
|
5605 |
+ if(strncasecmp(buf, "From:", 5) == 0) |
|
5606 |
+ table = from_whitelist; |
|
5607 |
+ else |
|
5608 |
+ table = to_whitelist; |
|
5609 |
+ |
|
5610 |
+ (void)tableInsert(table, ptr, 1); |
|
5611 |
+ } |
|
5593 | 5612 |
} |
5594 | 5613 |
fclose(fin); |
5595 | 5614 |
} |
5596 |
- if(whitelist && (tableFind(whitelist, emailaddress) == 1)) |
|
5615 |
+ table = (to) ? to_whitelist : from_whitelist; |
|
5616 |
+ |
|
5617 |
+ if(table && (tableFind(table, emailaddress) == 1)) |
|
5597 | 5618 |
/* |
5598 | 5619 |
* This recipient is on the whitelist |
5599 | 5620 |
*/ |
... | ... |
@@ -269,11 +269,16 @@ local domain. |
269 | 269 |
.TP |
270 | 270 |
\fB\-\-whitelist-file=FILE, \-W file\fR |
271 | 271 |
This option specifies a file which contains a list of e-mail addresses. |
272 |
-E-mails sent to these addresses will NOT be checked. |
|
272 |
+E-mails sent to or from these addresses will NOT be checked. |
|
273 | 273 |
While this is not an Anti-Virus function, it is quite useful for some systems. |
274 |
-The address given to the \-\-quarantine directive is always white-listed. |
|
274 |
+The address given to the \-\-quarantine directive is always whitelisted. |
|
275 |
+.IP |
|
275 | 276 |
The file consists of a list of addresses, each address on a line enclosed |
276 | 277 |
in angle brackets (e.g. <foo@bar.com>). |
278 |
+Optionally each line can start with the string \fITo:\fR or \fIFrom:\fR |
|
279 |
+indicating if it is the sender or recipient that is to be whitelisted. If the |
|
280 |
+field is missing, the default is \fITo\fR. |
|
281 |
+Lines starting with #, : or ! are ignored. |
|
277 | 282 |
.TP |
278 | 283 |
\fB\-\-sendmail-cf=FILE\fR |
279 | 284 |
When starting, clamav\-milter runs some sanity checks against the sendmail.cf |