diff options
author | Bob Beck <beck@cvs.openbsd.org> | 2004-02-27 18:25:50 +0000 |
---|---|---|
committer | Bob Beck <beck@cvs.openbsd.org> | 2004-02-27 18:25:50 +0000 |
commit | b87c0c466568c6ab2c7197dca4afd243ffea29c0 (patch) | |
tree | 3b77597b4f2c83ae5ba42bf557b2a21662aeabf5 /libexec | |
parent | da7f8b89a47685233a7ef1260405a539372b447a (diff) |
make spamlogd watch the destination of outbound smtp connections,
so that replies to mail sent out do not get greylisting delays.
ok millert@
Diffstat (limited to 'libexec')
-rw-r--r-- | libexec/spamlogd/spamlogd.8 | 38 | ||||
-rw-r--r-- | libexec/spamlogd/spamlogd.c | 112 |
2 files changed, 113 insertions, 37 deletions
diff --git a/libexec/spamlogd/spamlogd.8 b/libexec/spamlogd/spamlogd.8 index 61e411efb2a..faf0f35407a 100644 --- a/libexec/spamlogd/spamlogd.8 +++ b/libexec/spamlogd/spamlogd.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: spamlogd.8,v 1.1 2004/02/26 07:28:55 beck Exp $ +.\" $OpenBSD: spamlogd.8,v 1.2 2004/02/27 18:25:49 beck Exp $ .\" .\" Copyright (c) 2004 Bob Beck. All rights reserved. .\" @@ -22,6 +22,7 @@ .Nd spamd whitelist updating daemon .Sh SYNOPSIS .Nm spamlogd +.Op Fl I .Op Fl i Ar interface .Sh DESCRIPTION .Nm @@ -38,16 +39,35 @@ updates the whitelist entries whenever a connection to port 25 is logged to the .Xr pflog 4 -interface. +interface. The source addresses of inbound connections are whitelisted +when seen by +.Nm +to ensure that their entries in +.Pa /var/db/spamd +do not expire if the connecting host continues to send legitimate mail. +The destination addresses of outbound connections are whitelisted +when seen by +.Nm +so that replies to outbound mail may be received without initial +greylisting delays (see GREYLISTING in +.Xr spamd 8 ). .Pp The options are as follows: .Bl -tag -width Ds +.It Fl I +Specify that +.Nm +is only to whitelist inbound smtp connections. +By default +.Nm +will whitelist the source of inbound smtp connections, and the +target of outbound smtp connections. .It Fl i Ar interface Specify a network interface on which packets must arrive. The default is to watch for connections logged from any interfaces. .El .Pp -It is important to be sure to log any connections to your real +It is important to be sure to log any connections to and from your real MTA in order for .Nm to update the whitelist entries. @@ -59,7 +79,19 @@ $EXT_IF = "fxp0" $MAILHOSTS = "{129.128.11.10, 129.128.11.43}" pass in log on $EXT_IF inet proto tcp to $MAILHOSTS \e port smtp keep state +pass out log on $EXT_IF inet proto tcp from $MAILHOSTS \e + to any port smtp keep state .Ed +.Pp +.Nm +sends log messages to +.Xr syslogd 8 +using +.Em facility +daemon. +.Nm +will log each connection it sees at level +.Em LOG_DEBUG . .Sh FILES /var/db/spamd .Sh SEE ALSO diff --git a/libexec/spamlogd/spamlogd.c b/libexec/spamlogd/spamlogd.c index f93ed313d9e..a25676caccc 100644 --- a/libexec/spamlogd/spamlogd.c +++ b/libexec/spamlogd/spamlogd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: spamlogd.c,v 1.2 2004/02/26 08:18:56 deraadt Exp $ */ +/* $OpenBSD: spamlogd.c,v 1.3 2004/02/27 18:25:49 beck Exp $ */ /* * Copyright (c) 2004 Bob Beck. All rights reserved. @@ -34,6 +34,7 @@ #include <pwd.h> #include <stdio.h> #include <stdlib.h> +#include <syslog.h> #include <string.h> #include <time.h> #include <unistd.h> @@ -45,15 +46,12 @@ extern struct passwd *pw; extern FILE * grey; extern int debug; +struct syslog_data sdata = SYSLOG_DATA_INIT; size_t whitecount, whitealloc; char **whitelist; +int inbound; /* do we only whitelist inbound smtp? */ int pfdev; -DB *db; -DBT dbk, dbd; -BTREEINFO btreeinfo; - - /* borrowed from dhartmei.. */ static int address_valid_v4(const char *a) @@ -71,9 +69,12 @@ address_valid_v4(const char *a) int dbupdate(char *dbname, char *ip) { - struct gdata gd; - time_t now; - int r; + BTREEINFO btreeinfo; + DBT dbk, dbd; + DB *db; + struct gdata gd; + time_t now; + int r; now = time(NULL); memset(&btreeinfo, 0, sizeof(btreeinfo)); @@ -81,7 +82,7 @@ dbupdate(char *dbname, char *ip) if (db == NULL) return(-1); if (!address_valid_v4(ip)) { - warnx("invalid ip address %s\n", ip); + syslog_r(LOG_NOTICE, &sdata, "invalid ip address %s", ip); goto bad; } memset(&dbk, 0, sizeof(dbk)); @@ -91,7 +92,7 @@ dbupdate(char *dbname, char *ip) /* add or update whitelist entry */ r = db->get(db, &dbk, &dbd, 0); if (r == -1) { - warn("db->get failed"); + syslog_r(LOG_NOTICE, &sdata, "db->get failed (%m)"); goto bad; } if (r) { @@ -109,7 +110,7 @@ dbupdate(char *dbname, char *ip) dbd.data = &gd; r = db->put(db, &dbk, &dbd, 0); if (r) { - warn("db->put failed"); + syslog_r(LOG_NOTICE, &sdata, "db->put failed (%m)"); goto bad; } } else { @@ -129,7 +130,7 @@ dbupdate(char *dbname, char *ip) dbd.data = &gd; r = db->put(db, &dbk, &dbd, 0); if (r) { - warn("db->put failed"); + syslog_r(LOG_NOTICE, &sdata, "db->put failed (%m)"); goto bad; } } @@ -147,13 +148,13 @@ dbupdate(char *dbname, char *ip) static int usage(void) { - fprintf(stderr, "usage: spamlogd [-i netif]\n"); + fprintf(stderr, "usage: spamlogd [-I] [-i netif]\n"); exit(1); } -char *targv[19] = { +char *targv[17] = { "tcpdump", "-l", "-n", "-e", "-i", "pflog0", "-q", - "-t", "inbound", "and", "port", "25", "and", "action", "pass", + "-t", "port", "25", "and", "action", "pass", NULL, NULL, NULL, NULL }; @@ -166,14 +167,18 @@ main(int argc, char **argv) pid_t pid; FILE *f; - while ((ch = getopt(argc, argv, "i:")) != -1) { + + while ((ch = getopt(argc, argv, "i:I")) != -1) { switch (ch) { case 'i': - if (targv[17]) /* may only set once */ + if (targv[15]) /* may only set once */ usage(); - targv[15] = "and"; - targv[16] = "on"; - targv[17] = optarg; + targv[13] = "and"; + targv[14] = "on"; + targv[15] = optarg; + break; + case 'I': + inbound = 1; break; default: usage(); @@ -207,31 +212,70 @@ main(int argc, char **argv) f = fdopen(p[0], "r"); if (f == NULL) err(1, "fdopen"); + tzset(); + openlog_r("spamlogd", LOG_PID | LOG_NDELAY, LOG_DAEMON, &sdata); + lbuf = NULL; while ((buf = fgetln(f, &len))) { - char *cp; + char *cp = NULL; + char buf2[len + 1]; if (buf[len - 1] == '\n') buf[len - 1] = '\0'; else { - if ((lbuf = (char *)malloc(len + 1)) == NULL) - err(1, NULL); + if ((lbuf = (char *)malloc(len + 1)) == NULL) { + syslog_r(LOG_ERR, &sdata, "malloc failed"); + exit(1); + } memcpy(lbuf, buf, len); lbuf[len] = '\0'; buf = lbuf; } - if ((cp = (strchr(buf, '>'))) != NULL) { - /* XXX replace this grot with an sscanf */ - while (*cp != '.' && cp >= buf) { - *cp = '\0'; - cp--; + + if (!inbound && strstr(buf, "pass out") != NULL) { + /* + * this is outbound traffic - we whitelist + * the destination address, because we assume + * that a reply may come to this outgoing mail + * we are sending. + */ + if ((cp = (strchr(buf, '>'))) != NULL) { + if (sscanf(cp, "> %s", buf2) == 1) { + cp = strrchr(buf2, '.'); + if (cp != NULL) { + *cp = '\0'; + cp = buf2; + syslog_r(LOG_DEBUG, &sdata, + "outbound %s\n", cp); + } + } + else + cp = NULL; + } + + } else { + /* + * this is inbound traffic - we whitelist + * the source address, because this is + * traffic presumably to our real MTA + */ + if ((cp = (strchr(buf, '>'))) != NULL) { + while (*cp != '.' && cp >= buf) { + *cp = '\0'; + cp--; + } + *cp ='\0'; + while (*cp != ' ' && cp >= buf) + cp--; + cp++; + syslog_r(LOG_DEBUG, &sdata, + "inbound %s\n", cp); + } - *cp ='\0'; - while (*cp != ' ' && cp >= buf) - cp--; - cp++; - dbupdate(PATH_SPAMD_DB, cp); } + if (cp != NULL) + dbupdate(PATH_SPAMD_DB, cp); + if (lbuf != NULL) { free(lbuf); lbuf = NULL; |