On Thu, Mar 07, 2013 at 12:04:22PM -0800, Constantine A. Murenin wrote:
> On 2013-W10-3 15:46 -0700, Bob Beck wrote:
> > > Yes, one could log stuff into different pflog interfaces, but I don't
> > > understand why pf.conf `pass in ... log ... port smtp ...` is effectively
> > > redefined to mean `add <spamd-white>` when spamlogd is running,
> >
> > http://www.openbsd.org/cgi-bin/man.cgi?query=spamlogd
> >
> > and RTFM for the first two sentences - and it's pretty darn clear.
> >
> > Those of us that whitelist blocks of addresses (and log them) like
> > this behaviour to track what mailservers we are seeing like the
> > current behavior.
>
> Point taken; this should be optional.
> Index: spamlogd.8
> ===================================================================
> RCS file: /cvs/OpenBSD-CVS/src/libexec/spamlogd/spamlogd.8,v
> retrieving revision 1.17
> diff -u -d -p -8 -r1.17 spamlogd.8
> --- spamlogd.8 4 Mar 2011 21:01:49 -0000 1.17
> +++ spamlogd.8 7 Mar 2013 19:41:24 -0000
> @@ -17,17 +17,17 @@
> .Dd $Mdocdate: March 4 2011 $
> .Dt SPAMLOGD 8
> .Os
> .Sh NAME
> .Nm spamlogd
> .Nd spamd whitelist updating daemon
> .Sh SYNOPSIS
> .Nm spamlogd
> -.Op Fl DI
> +.Op Fl DIU
> .Op Fl i Ar interface
> .Op Fl l Ar pflog_interface
> .Op Fl W Ar whiteexp
> .Op Fl Y Ar synctarget
> .Sh DESCRIPTION
> .Nm
> manipulates the
> .Xr spamd 8
> @@ -73,16 +73,32 @@ target of outbound SMTP connections.
> Specify a network interface on which packets must arrive.
> The default is to watch for connections logged from all interfaces.
> .It Fl l Ar pflog_interface
> Specify a
> .Xr pflog 4
> interface to listen for connection notifications.
> The default is to watch for connections logged on
> .Dq pflog0 .
> +.It Fl U
> +Specify that for inbound SMTP connections,
> +.Nm
> +is only to update existing
> +.Pa /var/db/spamd
> +entries, without adding any new ones.
> +By default
> +.Nm
> +will whitelist the source of all inbound SMTP connections that are logged.
> +This option is needed if connections redirected to
> +.Xr spamd 8
> +are logged,
> +and no distinct
> +.Xr pflog 4
> +interface is configured for
> +.Nm .
> .It Fl W Ar whiteexp
> Adjust the time for
> .Ar whiteexp
> in hours.
> The default is 864 hours (approximately 36 days); maximum is 2160 hours
> (approximately 90 days).
> .It Fl Y Ar synctarget
> Add a target to receive synchronisation messages; see
> Index: spamlogd.c
> ===================================================================
> RCS file: /cvs/OpenBSD-CVS/src/libexec/spamlogd/spamlogd.c,v
> retrieving revision 1.21
> diff -u -d -p -8 -r1.21 spamlogd.c
> --- spamlogd.c 18 Mar 2011 22:37:06 -0000 1.21
> +++ spamlogd.c 7 Mar 2013 19:46:44 -0000
> @@ -63,29 +63,30 @@
> int debug = 1;
> int greylist = 1;
> FILE *grey = NULL;
>
> u_short sync_port;
> int syncsend;
> u_int8_t flag_debug = 0;
> u_int8_t flag_inbound = 0;
> +u_int8_t flag_updateonly = 0;
> char *networkif = NULL;
> char *pflogif = "pflog0";
> char errbuf[PCAP_ERRBUF_SIZE];
> pcap_t *hpcap = NULL;
> struct syslog_data sdata = SYSLOG_DATA_INIT;
> time_t whiteexp = WHITEEXP;
> extern char *__progname;
>
> void logmsg(int , const char *, ...);
> void sighandler_close(int);
> int init_pcap(void);
> void logpkt_handler(u_char *, const struct pcap_pkthdr *, const u_char
*);
> -int dbupdate(char *, char *);
> +int dbupdate(char *, char *, int);
> void usage(void);
>
> void
> logmsg(int pri, const char *msg, ...)
> {
> va_list ap;
> va_start(ap, msg);
>
> @@ -187,22 +188,22 @@ logpkt_handler(u_char *user, const struc
> sizeof(ipstraddr));
> }
>
> if (ipstraddr[0] != '\0') {
> if (hdr->dir == PF_IN)
> logmsg(LOG_DEBUG,"inbound %s", ipstraddr);
> else
> logmsg(LOG_DEBUG,"outbound %s", ipstraddr);
> - dbupdate(PATH_SPAMD_DB, ipstraddr);
> + dbupdate(PATH_SPAMD_DB, ipstraddr, hdr->dir == PF_IN);
> }
> }
>
> int
> -dbupdate(char *dbname, char *ip)
> +dbupdate(char *dbname, char *ip, int inbound)
> {
> HASHINFO hashinfo;
> DBT dbk, dbd;
> DB *db;
> struct gdata gd;
> time_t now;
> int r;
> struct in_addr ia;
> @@ -227,16 +228,20 @@ dbupdate(char *dbname, char *ip)
> /* add or update whitelist entry */
> r = db->get(db, &dbk, &dbd, 0);
> if (r == -1) {
> logmsg(LOG_NOTICE, "db->get failed (%m)");
> goto bad;
> }
>
> if (r) {
> + if (inbound && flag_updateonly) {
> + logmsg(LOG_DEBUG,"ignoring %s", ip);
> + goto bad;
> + }
> /* new entry */
> memset(&gd, 0, sizeof(gd));
> gd.first = now;
> gd.bcount = 1;
> gd.pass = now;
> gd.expire = now + whiteexp;
> memset(&dbk, 0, sizeof(dbk));
> dbk.size = strlen(ip);
> @@ -280,17 +285,17 @@ dbupdate(char *dbname, char *ip)
> db = NULL;
> return (-1);
> }
>
> void
> usage(void)
> {
> fprintf(stderr,
> - "usage: %s [-DI] [-i interface] [-l pflog_interface] "
> + "usage: %s [-DIU] [-i interface] [-l pflog_interface] "
> "[-W whiteexp] [-Y synctarget]\n",
> __progname);
> exit(1);
> }
>
> int
> main(int argc, char **argv)
> {
> @@ -302,23 +307,26 @@ main(int argc, char **argv)
> char *sync_iface = NULL;
> char *sync_baddr = NULL;
> const char *errstr;
>
> if ((ent = getservbyname("spamd-sync", "udp")) == NULL)
> errx(1, "Can't find service \"spamd-sync\" in /etc/services");
> sync_port = ntohs(ent->s_port);
>
> - while ((ch = getopt(argc, argv, "DIi:l:W:Y:")) != -1) {
> + while ((ch = getopt(argc, argv, "DIUi:l:W:Y:")) != -1) {
> switch (ch) {
> case 'D':
> flag_debug = 1;
> break;
> case 'I':
> flag_inbound = 1;
> + break;
> + case 'U':
> + flag_updateonly = 1;
> break;
> case 'i':
> networkif = optarg;
> break;
> case 'l':
> pflogif = optarg;
> break;
> case 'W':