diff --git a/contrib/blocklist/Makefile b/contrib/blocklist/Makefile --- a/contrib/blocklist/Makefile +++ b/contrib/blocklist/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.2 2015/01/22 17:49:41 christos Exp $ +# $NetBSD: Makefile,v 1.1.1.1 2020/06/15 01:52:52 christos Exp $ SUBDIR = lib .WAIT include bin etc libexec diff --git a/contrib/blocklist/Makefile.inc b/contrib/blocklist/Makefile.inc --- a/contrib/blocklist/Makefile.inc +++ b/contrib/blocklist/Makefile.inc @@ -1,10 +1,11 @@ -# $NetBSD: Makefile.inc,v 1.3 2015/01/23 03:57:22 christos Exp $ +# $NetBSD: Makefile.inc,v 1.3 2025/02/11 17:48:30 christos Exp $ WARNS=6 .if !defined(LIB) -LDADD+= -lblacklist -DPADD+= ${LIBBLACKLIST} +LDADD+= -lblocklist +DPADD+= ${LIBBLOCKLIST} .endif CPPFLAGS+= -I${.CURDIR}/../include CPPFLAGS+=-DHAVE_STRUCT_SOCKADDR_SA_LEN -DHAVE_UTIL_H -DHAVE_DB_H +CPPFLAGS+=-DHAVE_SYS_CDEFS_H diff --git a/contrib/blocklist/README b/contrib/blocklist/README --- a/contrib/blocklist/README +++ b/contrib/blocklist/README @@ -1,21 +1,21 @@ -# $NetBSD: README,v 1.8 2017/04/13 17:59:34 christos Exp $ +# $NetBSD: README,v 1.3 2024/02/09 00:53:30 wiz Exp $ This package contains library that can be used by network daemons to communicate with a packet filter via a daemon to enforce opening and closing ports dynamically based on policy. -The interface to the packet filter is in libexec/blacklistd-helper +The interface to the packet filter is in libexec/blocklistd-helper (this is currently designed for npf) and the configuration file -(inspired from inetd.conf) is in etc/blacklistd.conf. +(inspired from inetd.conf) is in etc/blocklistd.conf. -On NetBSD you can find an example npf.conf and blacklistd.conf in -/usr/share/examples/blacklistd; you need to adjust the interface +On NetBSD you can find an example npf.conf and blocklistd.conf in +/usr/share/examples/blocklistd; you need to adjust the interface in npf.conf and copy both files to /etc; then you just enable -blacklistd=YES in /etc/rc.conf, start it up, and you are all set. +blocklistd=YES in /etc/rc.conf, start it up, and you are all set. -There is also a startup file in etc/rc.d/blacklistd +There is also a startup file in etc/rc.d/blocklistd -Patches to various daemons to add blacklisting capabilitiers are in the +Patches to various daemons to add blocklisting capabilities are in the "diff" directory: - OpenSSH: diff/ssh.diff [tcp socket example] - Bind: diff/named.diff [both tcp and udp] @@ -23,21 +23,21 @@ These patches have been applied to NetBSD-current. -The network daemon (for example sshd) communicates to blacklistd, via -a unix socket like syslog. The library calls are simple and everything +The network daemon (for example sshd) communicates to blocklistd, via +a Unix socket like syslog. The library calls are simple and everything is handled by the library. In the simplest form the only thing the daemon needs to do is to call: - blacklist(action, acceptedfd, message); + blocklist(action, acceptedfd, message); Where: - action = 0 -> successful login clear blacklist state + action = 0 -> successful login clear blocklist state 1 -> failed login, add to the failed count acceptedfd -> the file descriptor where the server is connected to the remote client. It is used to determine the listening socket, and the remote address. This allows any program to - contact the blacklist daemon, since the verification + contact the blocklist daemon, since the verification if the program has access to the listening socket is done by virtue that the port number is retrieved from the kernel. @@ -46,13 +46,13 @@ Unfortunately there is no way to get information about the "peer" from a udp socket, because there is no connection and that information is kept with the server. In that case the daemon can provide the -peer information to blacklistd via: +peer information to blocklistd via: - blacklist_sa(action, acceptedfd, sockaddr, sockaddr_len, message); + blocklist_sa(action, acceptedfd, sockaddr, sockaddr_len, message); The configuration file contains entries of the form: -# Blacklist rule +# Blocklist rule # host/Port type protocol owner name nfail disable 192.168.1.1:ssh stream tcp * -int 10 1m 8.8.8.8:ssh stream tcp * -ext 6 60m @@ -60,18 +60,18 @@ http stream tcp * * 6 60m Here note that owner is * because the connection is done from the -child ssh socket which runs with user privs. We treat ipv4 connections +child ssh socket which runs with user privs. We treat IPv4 connections differently by maintaining two different rules one for the external interface and one from the internal We also register for both tcp and tcp6 since those are different listening sockets and addresses; -we don't bother with ipv6 and separate rules. We use nfail = 6, +we don't bother with IPv6 and separate rules. We use nfail = 6, because ssh allows 3 password attempts per connection, and this will let us have 2 connections before blocking. Finally we block for an hour; we could block forever too by specifying * in the duration column. -blacklistd and the library use syslog(3) to report errors. The -blacklist filter state is persisted automatically in /var/db/blacklistd.db +blocklistd and the library use syslog(3) to report errors. The +blocklist filter state is persisted automatically in /var/db/blocklistd.db so that if the daemon is restarted, it remembers what connections is currently handling. To start from a fresh state (if you restart npf too for example), you can use -f. To watch the daemon at work, @@ -80,27 +80,27 @@ The current control file is designed for npf, and it uses the dynamic rule feature. You need to create a dynamic rule in your /etc/npf.conf on the group referring to the interface you want to block -called blacklistd as follows: +called blocklistd as follows: ext_if=bge0 int_if=sk0 group "external" on $ext_if { ... - ruleset "blacklistd-ext" - ruleset "blacklistd" + ruleset "blocklistd-ext" + ruleset "blocklistd" ... } group "internal" on $int_if { ... - ruleset "blacklistd-int" + ruleset "blocklistd-int" ... } -You can use 'blacklistctl dump -a' to list all the current entries +You can use 'blocklistctl dump -a' to list all the current entries in the database; the ones that have nfail / where urrent ->= otal, should have an id assosiated with them; this means that +>= otal, should have an id associated with them; this means that there is a packet filter rule added for that entry. For npf, you can examine the packet filter dynamic rule entries using 'npfctl rule list'. The number of current entries can exceed diff --git a/contrib/blocklist/TODO b/contrib/blocklist/TODO --- a/contrib/blocklist/TODO +++ b/contrib/blocklist/TODO @@ -1,4 +1,4 @@ -# $NetBSD: TODO,v 1.7 2015/01/23 21:34:01 christos Exp $ +# $NetBSD: TODO,v 1.3 2025/02/05 20:22:26 christos Exp $ - don't poll periodically, find the next timeout - use the socket also for commands? Or separate socket? @@ -17,5 +17,48 @@ -n block unblock -- do we need an api in blacklistctl to perform maintenance -- fix the blacklistctl output to be more user friendly +- do we need an api in blocklistctl to perform maintenance +- fix the blocklistctl output to be more user friendly + +- figure out some way to do distributed operation securely (perhaps with + a helper daemon that authenticates local sockets and then communicates + local DB changes to the central server over a secure channel -- + perhaps blocklistd-helper can have a back-end that can send updates to + a central server) + +- add "blocklistd -l" to enable filter logging on all rules by default + +- add some new options in the config file + + "/all" - block both TCP and UDP (on the proto field?) + + "/log" - enable filter logging (if not the default) (on the name field?) + "/nolog"- disable filter logging (if not the default) (on the name field?) + + The latter two probably require a new parameter for blocklistd-helper. + +- "blocklistd -f" should (also?) be a blocklistctl function!?!?! + +- if blocklistd was started with '-r' then a SIGHUP should also do a + "control flush $rulename" and then re-add all the filter rules? + +- should/could /etc/rc.conf.d/ipfilter be created with the following? + + reload_postcmd=blocklistd_reload + start_postcmd=blocklistd_start + stop_precmd=blocklistd_stop + blocklistd_reload () + { + /etc/rc.d/blocklistd reload # IFF SIGHUP does flush/re-add + # /etc/rc.d/blocklistd restart + } + blocklistd_stop () + { + /etc/rc.d/blocklistd stop + } + blocklistd_start () + { + /etc/rc.d/blocklistd start + } + + or is there a better way? diff --git a/contrib/blocklist/bin/Makefile b/contrib/blocklist/bin/Makefile --- a/contrib/blocklist/bin/Makefile +++ b/contrib/blocklist/bin/Makefile @@ -1,12 +1,12 @@ -# $NetBSD: Makefile,v 1.11 2015/01/27 19:40:36 christos Exp $ +# $NetBSD: Makefile,v 1.1.1.1 2020/06/15 01:52:52 christos Exp $ BINDIR=/sbin -PROGS=blacklistd blacklistctl -MAN.blacklistd=blacklistd.8 blacklistd.conf.5 -MAN.blacklistctl=blacklistctl.8 -SRCS.blacklistd = blacklistd.c conf.c run.c state.c support.c internal.c -SRCS.blacklistctl = blacklistctl.c conf.c state.c support.c internal.c +PROGS=blocklistd blocklistctl +MAN.blocklistd=blocklistd.8 blocklistd.conf.5 +MAN.blocklistctl=blocklistctl.8 +SRCS.blocklistd = blocklistd.c conf.c run.c state.c support.c internal.c +SRCS.blocklistctl = blocklistctl.c conf.c state.c support.c internal.c DBG=-g LDADD+=-lutil diff --git a/contrib/blocklist/bin/blacklistctl.8 b/contrib/blocklist/bin/blocklistctl.8 rename from contrib/blocklist/bin/blacklistctl.8 rename to contrib/blocklist/bin/blocklistctl.8 --- a/contrib/blocklist/bin/blacklistctl.8 +++ b/contrib/blocklist/bin/blocklistctl.8 @@ -1,4 +1,4 @@ -.\" $NetBSD: blacklistctl.8,v 1.9 2016/06/08 12:48:37 wiz Exp $ +.\" $NetBSD: blocklistctl.8,v 1.4 2025/02/07 01:35:38 kre Exp $ .\" .\" Copyright (c) 2015 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -27,27 +27,43 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd June 7, 2016 -.Dt BLACKLISTCTL 8 +.Dd January 27, 2025 +.Dt BLOCKLISTCTL 8 .Os .Sh NAME -.Nm blacklistctl -.Nd display and change the state of blacklistd +.Nm blocklistctl +.Nd display and change the state of the blocklistd database .Sh SYNOPSIS .Nm .Cm dump .Op Fl abdnrw +.Op Fl D Ar dbname .Sh DESCRIPTION .Nm -is a program used to display the state of -.Xr blacklistd 8 +is a program used to display and change the state of the +.Xr blocklistd 8 +database. +The following sub-commands are supported: +.Ss dump .Pp -The following options are available: +The following options are available for the +.Cm dump +sub-command: .Bl -tag -width indent .It Fl a -Show all database entries, by default it shows only the embryonic ones. +Show all database entries, by default it shows only the active ones. +Inactive entries will be shown with a last-access (or, with +.Fl r , +the remaining) time of +.Ql never . .It Fl b Show only the blocked entries. +.It Fl D Ar dbname +Specify the location of the +.Ic blocklistd +database file to use. +The default is +.Pa /var/db/blocklistd.db . .It Fl d Increase debugging level. .It Fl n @@ -59,18 +75,47 @@ .Fl w flag, makes the display wide enough for IPv6 addresses. .El +.Pp +The output of the +.Cm dump +sub-command consists of a header (unless +.Fl n +was given) and one line for each record in the database, where each line +has the following columns: +.Bl -tag -width indent +.It Ql address/ma:port +The remote address, mask, and local port number of the client connection +associated with the database entry. +.It Ql id +column will show the identifier for the packet filter rule associated +with the database entry, though this may only be the word +.Ql OK +for packet filters which do not creat a unique identifier for each rule. +.It Ql nfail +The number of +.Em failures +reported for the client on the noted port, as well as the number of +failures allowed before blocking (or, with +.Fl a , +an asterisk +.Aq * ) +.It So last access Sc | So remaining time Sc +The last time a the client was reported as attempting access, or, with +.Fl r , +the time remaining before the rule blocking the client will be removed. +.El .Sh SEE ALSO -.Xr blacklistd 8 +.Xr blocklistd 8 .Sh NOTES Sometimes the reported number of failed attempts can exceed the number of attempts that -.Xr blacklistd 8 +.Xr blocklistd 8 is configured to block. This can happen either because the rule has been removed manually, or because there were more attempts in flight while the rule block was being added. This condition is normal; in that case -.Xr blacklistd 8 +.Xr blocklistd 8 will first attempt to remove the existing rule, and then it will re-add it to make sure that there is only one rule active. .Sh HISTORY diff --git a/contrib/blocklist/bin/blacklistctl.c b/contrib/blocklist/bin/blocklistctl.c rename from contrib/blocklist/bin/blacklistctl.c rename to contrib/blocklist/bin/blocklistctl.c --- a/contrib/blocklist/bin/blacklistctl.c +++ b/contrib/blocklist/bin/blocklistctl.c @@ -1,4 +1,4 @@ -/* $NetBSD: blacklistctl.c,v 1.23 2018/05/24 19:21:01 christos Exp $ */ +/* $NetBSD: blocklistctl.c,v 1.4 2025/02/11 17:48:30 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -32,8 +32,10 @@ #include "config.h" #endif +#ifdef HAVE_SYS_CDEFS_H #include -__RCSID("$NetBSD: blacklistctl.c,v 1.23 2018/05/24 19:21:01 christos Exp $"); +#endif +__RCSID("$NetBSD: blocklistctl.c,v 1.4 2025/02/11 17:48:30 christos Exp $"); #include #include @@ -63,7 +65,8 @@ warnx("Missing/unknown command"); else if (c != '?') warnx("Unknown option `%c'", (char)c); - fprintf(stderr, "Usage: %s dump [-abdnrw]\n", getprogname()); + fprintf(stderr, + "Usage: %s dump [-abdnrw] [-D dbname]\n", getprogname()); exit(EXIT_FAILURE); } diff --git a/contrib/blocklist/bin/blacklistd.8 b/contrib/blocklist/bin/blocklistd.8 rename from contrib/blocklist/bin/blacklistd.8 rename to contrib/blocklist/bin/blocklistd.8 --- a/contrib/blocklist/bin/blacklistd.8 +++ b/contrib/blocklist/bin/blocklistd.8 @@ -1,4 +1,4 @@ -.\" $NetBSD: blacklistd.8,v 1.23 2020/04/21 13:57:12 christos Exp $ +.\" $NetBSD: blocklistd.8,v 1.8 2025/02/25 22:13:34 christos Exp $ .\" .\" Copyright (c) 2015 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -27,11 +27,11 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd April 21, 2020 -.Dt BLACKLISTD 8 +.Dd February 25, 2025 +.Dt BLOCKLISTD 8 .Os .Sh NAME -.Nm blacklistd +.Nm blocklistd .Nd block and release ports on demand to avoid DoS abuse .Sh SYNOPSIS .Nm @@ -53,22 +53,35 @@ attempts. If no such file is specified, then it only listens to the socket path specified by -.Ar sockspath +.Ar sockpath or if that is not specified to -.Pa /var/run/blacklistd.sock . +.Pa /var/run/blocklistd.sock . Each notification contains an (action, port, protocol, address, owner) tuple that identifies the remote connection and the action. -This tuple is consulted against entries in -.Ar configfile -with syntax specified in -.Xr blacklistd.conf 5 . +This tuple is consulted against entries from the +.Ar configfile , +with the syntax specified in +.Xr blocklistd.conf 5 . If an entry is matched, a state entry is created for that tuple. Each entry contains a number of tries limit and a duration. .Pp +If +.Ar configfile +is a directory, or a directory exists with the same name as +.Ar configfile +with +.Qq .d +appended to it, each file in the directory will be read as configuration file. +If +.Ar configfile +exists as a file it will be processed before the contents of the +.Ar configfile Ns .d +directory if that also exists. +.Pp The way .Nm does configuration entry matching is by having the client side pass the -file descriptor associated with the connection the client wants to blacklist +file descriptor associated with the connection the client wants to blocklist as well as passing socket credentials. .Pp The file descriptor is used to retrieve information (address and port) @@ -116,7 +129,7 @@ The .Ar rulename argument can be set from the command line (default -.Dv blacklistd ) . +.Dv blocklistd ) . The script could print a numerical id to stdout as a handle for the rule that can be used later to remove that connection, but that is not required as all information to remove the rule is @@ -152,8 +165,8 @@ .It Fl C Ar controlprog Use .Ar controlprog -to communicate with the packet filter, usually -.Pa /usr/libexec/blacklistd-helper . +to communicate with the packet filter, instead of the default, which is +.Pa /usr/libexec/blocklistd-helper . The following arguments are passed to the control program: .Bl -tag -width protocol .It action @@ -161,7 +174,7 @@ .Dv add , .Dv rem , or -.Dv flush +.Dv flush ; to add, remove or flush a firewall rule. .It name The rule name. @@ -183,13 +196,17 @@ The add command is expected to return the rule identifier string to stdout. .El .It Fl c Ar configuration -The name of the configuration file to read, usually -.Pa /etc/blacklistd.conf . +The name of the configuration file to read. +The default when +.Fl c +is not given is +.Pa /etc/blocklistd.conf . .It Fl D Ar dbfile The Berkeley DB file where .Nm -stores its state, usually -.Pa /var/db/blacklistd.db . +stores its state. +It defaults to +.Pa /var/db/blocklistd.db . .It Fl d Normally, .Nm @@ -203,14 +220,14 @@ .Bd -literal -offset indent control flush .Ed -.It Fl P Ar sockspathsfile +.It Fl P Ar sockpathsfile A file containing a list of pathnames, one per line that .Nm will create sockets to listen to. This is useful for chrooted environments. .It Fl R Ar rulename Specify the default rule name for the packet filter rules, usually -.Dv blacklistd . +.Dv blocklistd . .It Fl r Re-read the firewall rules from the internal database, then remove and re-add them. @@ -256,19 +273,21 @@ to decrease the internal debugging level by 1. .El .Sh FILES -.Bl -tag -width /usr/libexec/blacklistd-helper -compact -.It Pa /usr/libexec/blacklistd-helper +.Bl -tag -width /usr/libexec/blocklistd-helper -compact +.It Pa /usr/libexec/blocklistd-helper Shell script invoked to interface with the packet filter. -.It Pa /etc/blacklistd.conf +.It Pa /etc/blocklistd.conf Configuration file. -.It Pa /var/db/blacklistd.db +.It Pa /var/db/blocklistd.db Database of current connection entries. -.It Pa /var/run/blacklistd.sock +.It Pa /var/run/blocklistd.sock Socket to receive connection notifications. .El .Sh SEE ALSO -.Xr blacklistd.conf 5 , -.Xr blacklistctl 8 , +.Xr blocklistd.conf 5 , +.Xr blocklistctl 8 , +.Xr ipf 8 , +.Xr ipfw 8 , .Xr pfctl 8 , .Xr syslogd 8 .Sh HISTORY diff --git a/contrib/blocklist/bin/blacklistd.c b/contrib/blocklist/bin/blocklistd.c rename from contrib/blocklist/bin/blacklistd.c rename to contrib/blocklist/bin/blocklistd.c --- a/contrib/blocklist/bin/blacklistd.c +++ b/contrib/blocklist/bin/blocklistd.c @@ -1,4 +1,4 @@ -/* $NetBSD: blacklistd.c,v 1.38 2019/02/27 02:20:18 christos Exp $ */ +/* $NetBSD: blocklistd.c,v 1.10 2025/03/26 17:09:35 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -31,8 +31,11 @@ #ifdef HAVE_CONFIG_H #include "config.h" #endif + +#ifdef HAVE_SYS_CDEFS_H #include -__RCSID("$NetBSD: blacklistd.c,v 1.38 2019/02/27 02:20:18 christos Exp $"); +#endif +__RCSID("$NetBSD: blocklistd.c,v 1.10 2025/03/26 17:09:35 christos Exp $"); #include #include @@ -175,6 +178,8 @@ struct dbinfo dbi; struct timespec ts; + memset(&dbi, 0, sizeof(dbi)); + memset(&c, 0, sizeof(c)); if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { (*lfun)(LOG_ERR, "clock_gettime failed (%m)"); return; @@ -188,10 +193,11 @@ if (getremoteaddress(bi, &rss, &rsl) == -1) goto out; - if (debug) { + if (debug || bi->bi_msg[0]) { sockaddr_snprintf(rbuf, sizeof(rbuf), "%a:%p", (void *)&rss); - (*lfun)(LOG_DEBUG, "processing type=%d fd=%d remote=%s msg=%s" - " uid=%lu gid=%lu", bi->bi_type, bi->bi_fd, rbuf, + (*lfun)(bi->bi_msg[0] ? LOG_INFO : LOG_DEBUG, + "processing type=%d fd=%d remote=%s msg=%s uid=%lu gid=%lu", + bi->bi_type, bi->bi_fd, rbuf, bi->bi_msg, (unsigned long)bi->bi_uid, (unsigned long)bi->bi_gid); } @@ -216,16 +222,19 @@ switch (bi->bi_type) { case BL_ABUSE: /* - * If the application has signaled abusive behavior, - * set the number of fails to be one less than the - * configured limit. Fallthrough to the normal BL_ADD - * processing, which will increment the failure count - * to the threshhold, and block the abusive address. + * If the application has signaled abusive behavior, set the + * number of fails to be two less than the configured limit. + * Fall through to the normal BL_ADD and BL_BADUSER processing, + * which will increment the failure count to the threshhold, and + * block the abusive address. */ if (c.c_nfail != -1) - dbi.count = c.c_nfail - 1; + dbi.count = c.c_nfail - 2; /*FALLTHROUGH*/ case BL_ADD: + dbi.count++; /* will become += 2 */ + /*FALLTHROUGH*/ + case BL_BADUSER: dbi.count++; dbi.last = ts.tv_sec; if (c.c_nfail != -1 && dbi.count >= c.c_nfail) { @@ -254,9 +263,6 @@ dbi.count = 0; dbi.last = 0; break; - case BL_BADUSER: - /* ignore for now */ - break; default: (*lfun)(LOG_ERR, "unknown message %d", bi->bi_type); } @@ -334,7 +340,7 @@ addfd(struct pollfd **pfdp, bl_t **blp, size_t *nfd, size_t *maxfd, const char *path) { - bl_t bl = bl_create(true, path, vflag ? vdlog : vsyslog); + bl_t bl = bl_create(true, path, vflag ? vdlog : vsyslog_r); if (bl == NULL || !bl_isconnected(bl)) exit(EXIT_FAILURE); if (*nfd >= *maxfd) { @@ -395,15 +401,25 @@ static void rules_restore(void) { + DB *db; struct conf c; struct dbinfo dbi; unsigned int f; - for (f = 1; state_iterate(state, &c, &dbi, f) == 1; f = 0) { + db = state_open(dbfile, O_RDONLY, 0); + if (db == NULL) { + (*lfun)(LOG_ERR, "Can't open `%s' to restore state (%m)", + dbfile); + return; + } + for (f = 1; state_iterate(db, &c, &dbi, f) == 1; f = 0) { if (dbi.id[0] == '\0') continue; (void)run_change("add", &c, dbi.id, sizeof(dbi.id)); + state_put(state, &c, &dbi); } + state_close(db); + state_sync(state); } int diff --git a/contrib/blocklist/bin/blacklistd.conf.5 b/contrib/blocklist/bin/blocklistd.conf.5 rename from contrib/blocklist/bin/blacklistd.conf.5 rename to contrib/blocklist/bin/blocklistd.conf.5 --- a/contrib/blocklist/bin/blacklistd.conf.5 +++ b/contrib/blocklist/bin/blocklistd.conf.5 @@ -1,6 +1,6 @@ -.\" $NetBSD: blacklistd.conf.5,v 1.9 2019/11/06 20:33:30 para Exp $ +.\" $NetBSD: blocklistd.conf.5,v 1.7 2025/02/11 17:47:05 christos Exp $ .\" -.\" Copyright (c) 2015 The NetBSD Foundation, Inc. +.\" Copyright (c) 2015, 2025 The NetBSD Foundation, Inc. .\" All rights reserved. .\" .\" This code is derived from software contributed to The NetBSD Foundation @@ -27,17 +27,17 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd May 18, 2020 -.Dt BLACKLISTD.CONF 5 +.Dd February 5, 2025 +.Dt BLOCKLISTD.CONF 5 .Os .Sh NAME -.Nm blacklistd.conf -.Nd configuration file format for blacklistd +.Nm blocklistd.conf +.Nd configuration file format for blocklistd .Sh DESCRIPTION The .Nm file contains configuration entries for -.Xr blacklistd 8 +.Xr blocklistd 8 in a fashion similar to .Xr inetd.conf 5 . Only one entry per line is permitted. @@ -48,34 +48,34 @@ at the beginning of a line. .Pp There are two kinds of configuration lines, -.Va local +.Va [local] and -.Va remote . +.Va [remote] . By default, configuration lines are -.Va local , +.Va [local] , i.e. the address specified refers to the addresses on the local machine. To switch to between -.Va local +.Va [local] and -.Va remote +.Va [remote] configuration lines you can specify the stanzas: .Dq [local] and .Dq [remote] . .Pp On -.Va local +.Va [local] and -.Va remote +.Va [remote] lines .Dq * means use the default, or wildcard match. In addition, for -.Va remote +.Va [remote] lines .Dq = means use the values from the matched -.Va local +.Va [local] configuration line. .Pp The first four fields, @@ -85,9 +85,9 @@ and .Va owner are used to match the -.Va local +.Va [local] or -.Va remote +.Va [remote] addresses, whereas the last 3 fields .Va name , .Va nfail , @@ -110,8 +110,8 @@ can be an IPv4 address in numeric format, an IPv6 address in numeric format and enclosed by square brackets, or an interface name. Mask modifiers are not allowed on interfaces because interfaces -can have multiple addresses in different protocols where the mask has a different -size. +can have multiple addresses in different protocols where the mask has a +different size. .Pp The .Dv mask @@ -143,8 +143,8 @@ field, is the name of the packet filter rule to be used. If the .Va name -starts with a -.Dq - , +starts with a hyphen +.Pq Dq - , then the default rulename is prepended to the given name. If the .Dv name @@ -160,13 +160,13 @@ defaulting to .Dq * meaning never, and the last field -.Va disable +.Va duration specifies the amount of time since the last access that the blocking rule should be active, defaulting to .Dq * meaning forever. The default unit for -.Va disable +.Va duration is seconds, but one can specify suffixes for different units, such as .Dq m for minutes @@ -176,28 +176,34 @@ for days. .Pp Matching is done first by checking the -.Va local +.Va [local] rules individually, in the order of the most specific to the least specific. -If a match is found, then the -.Va remote +If a match is found, then the matching +.Va [remote] rules are applied. The .Va name , .Va nfail , and -.Va disable +.Va duration fields can be altered by the -.Va remote +.Va [remote] rule that matched. .Pp The -.Va remote +.Va [remote] rules can be used for allowing specific addresses, changing the mask -size, the rule that the packet filter uses, the number of failed attempts, -or the block duration. +size (via +.Va name ) , +the rule that the packet filter uses (also via +.Va name ) , +the number of failed attempts (via +.Va nfail ) , +or the duration to block (via +.Va duration ) . .Sh FILES -.Bl -tag -width /etc/blacklistd.conf -compact -.It Pa /etc/blacklistd.conf +.Bl -tag -width /etc/blocklistd.conf -compact +.It Pa /etc/blocklistd.conf Configuration file. .El .Sh EXAMPLES @@ -209,13 +215,15 @@ [remote] # Never block 1.2.3.4 1.2.3.4:ssh * * * * * * -# For addresses coming from 8.8.0.0/16 block whole /24 networks instead of +# Never block the example IPv6 subnet either +[2001:db8::]/32:ssh * * * * * * +# For addresses coming from 8.8.0.0/16 block whole /24 networks instead # individual hosts, but keep the rest of the blocking parameters the same. 8.8.0.0/16:ssh * * * /24 = = .Ed .Sh SEE ALSO -.Xr blacklistctl 8 , -.Xr blacklistd 8 +.Xr blocklistctl 8 , +.Xr blocklistd 8 .Sh HISTORY .Nm first appeared in diff --git a/contrib/blocklist/bin/conf.h b/contrib/blocklist/bin/conf.h --- a/contrib/blocklist/bin/conf.h +++ b/contrib/blocklist/bin/conf.h @@ -1,4 +1,4 @@ -/* $NetBSD: conf.h,v 1.6 2015/01/27 19:40:36 christos Exp $ */ +/* $NetBSD: conf.h,v 1.2 2025/02/05 20:09:33 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -34,6 +34,7 @@ #include struct conf { + size_t c_lineno; struct sockaddr_storage c_ss; int c_lmask; int c_port; diff --git a/contrib/blocklist/bin/conf.c b/contrib/blocklist/bin/conf.c --- a/contrib/blocklist/bin/conf.c +++ b/contrib/blocklist/bin/conf.c @@ -1,4 +1,4 @@ -/* $NetBSD: conf.c,v 1.24 2016/04/04 15:52:56 christos Exp $ */ +/* $NetBSD: conf.c,v 1.10 2025/02/11 17:48:30 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -32,8 +32,10 @@ #include "config.h" #endif +#ifdef HAVE_SYS_CDEFS_H #include -__RCSID("$NetBSD: conf.c,v 1.24 2016/04/04 15:52:56 christos Exp $"); +#endif +__RCSID("$NetBSD: conf.c,v 1.10 2025/02/11 17:48:30 christos Exp $"); #include #ifdef HAVE_LIBUTIL_H @@ -58,6 +60,7 @@ #include #include #include +#include #include "bl.h" #include "internal.h" @@ -261,7 +264,7 @@ if (debug) (*lfun)(LOG_DEBUG, "%s: host6 %s", __func__, p); if (strcmp(p, "*") != 0) { - if (inet_pton(AF_INET6, p, &sin6->sin6_addr) == -1) + if (inet_pton(AF_INET6, p, &sin6->sin6_addr) != 1) goto out; sin6->sin6_family = AF_INET6; #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN @@ -269,6 +272,8 @@ #endif port = &sin6->sin6_port; } + if (!*pstr) + pstr = "*"; } else if (pstr != p || strchr(p, '.') || conf_is_interface(p)) { if (pstr == p) pstr = "*"; @@ -311,7 +316,7 @@ *port = htons((in_port_t)c->c_port); return 0; out: - (*lfun)(LOG_ERR, "%s: %s, %zu: Bad address [%s]", __func__, f, l, pstr); + (*lfun)(LOG_ERR, "%s: %s, %zu: Bad address [%s]", __func__, f, l, p); return -1; out1: (*lfun)(LOG_ERR, "%s: %s, %zu: Can't specify mask %d with " @@ -407,6 +412,8 @@ { int e; + c->c_lineno = l; + while (*p && isspace((unsigned char)*p)) p++; @@ -471,7 +478,6 @@ uint32_t m; int omask = mask; - len >>= 2; switch (mask) { case FSTAR: if (memcmp(v1, v2, len) == 0) @@ -485,7 +491,7 @@ break; } - for (size_t i = 0; i < len; i++) { + for (size_t i = 0; i < (len >> 2); i++) { if (mask > 32) { m = htonl((uint32_t)~0); mask -= 32; @@ -501,7 +507,6 @@ out: if (debug > 1) { char b1[256], b2[256]; - len <<= 2; blhexdump(b1, sizeof(b1), "a1", v1, len); blhexdump(b2, sizeof(b2), "a2", v2, len); (*lfun)(LOG_DEBUG, "%s: %s != %s [0x%x]", __func__, @@ -690,6 +695,25 @@ static int conf_eq(const struct conf *c1, const struct conf *c2) +{ + if (!conf_addr_eq(&c1->c_ss, &c2->c_ss, FSTAR)) + return 0; + +#define CMP(a, b, f) \ + if ((a)->f != (b)->f) \ + return 0; + + CMP(c1, c2, c_port); + CMP(c1, c2, c_proto); + CMP(c1, c2, c_family); + CMP(c1, c2, c_uid); +#undef CMP + + return 1; +} + +static int +conf_match(const struct conf *c1, const struct conf *c2) { if (!conf_addr_eq(&c1->c_ss, &c2->c_ss, c2->c_lmask)) @@ -953,13 +977,54 @@ } static void -confset_replace(struct confset *dc, struct confset *sc) +confset_merge(struct confset *dc, struct confset *sc) { - struct confset tc; - tc = *dc; - *dc = *sc; - confset_init(sc); - confset_free(&tc); + size_t i, j; + char buf[BUFSIZ]; + + /* Check each rule of the src confset (sc) */ + for (i = 0; i < sc->cs_n; i++) { + /* Compare to each rule in the dest confset (dc) */ + for (j = 0; j < dc->cs_n; j++) { + if (conf_eq(&dc->cs_c[j], &sc->cs_c[i])) { + break; + } + } + + if (j == dc->cs_n) { + /* This is a new rule to add to the dest confset. */ + if (confset_full(dc) && confset_grow(dc) == -1) + return; + + *confset_get(dc) = sc->cs_c[i]; + confset_add(dc); + continue; + } + + /* We had a match above. */ + /* + * Check whether the rule from the src confset is more + * restrictive than the existing one. Adjust the + * existing rule if necessary. + */ + if (sc->cs_c[i].c_nfail == dc->cs_c[j].c_nfail && + sc->cs_c[i].c_duration && dc->cs_c[j].c_duration) { + (*lfun)(LOG_DEBUG, "skipping existing rule: %s", + conf_print(buf, sizeof (buf), "", "\t", &sc->cs_c[i])); + continue; + } + + if (sc->cs_c[i].c_nfail < dc->cs_c[j].c_nfail) + dc->cs_c[j].c_nfail = sc->cs_c[i].c_nfail; + + if (sc->cs_c[i].c_duration > dc->cs_c[j].c_duration) + dc->cs_c[j].c_duration = sc->cs_c[i].c_duration; + + (*lfun)(LOG_DEBUG, "adjusted existing rule: %s", + conf_print(buf, sizeof (buf), "", "\t", &dc->cs_c[j])); + } + + confset_free(sc); } static void @@ -990,7 +1055,7 @@ if (debug) (*lfun)(LOG_DEBUG, "%s", conf_print(buf, sizeof(buf), "check:\t", "", &cs->cs_c[i])); - if (conf_eq(c, &cs->cs_c[i])) { + if (conf_match(c, &cs->cs_c[i])) { if (debug) (*lfun)(LOG_DEBUG, "%s", conf_print(buf, sizeof(buf), @@ -1160,21 +1225,14 @@ return cr; } - -void -conf_parse(const char *f) +static void +conf_parsefile(FILE *fp, const char *config_file) { - FILE *fp; char *line; size_t lineno, len; struct confset lc, rc, *cs; - if ((fp = fopen(f, "r")) == NULL) { - (*lfun)(LOG_ERR, "%s: Cannot open `%s' (%m)", __func__, f); - return; - } - - lineno = 1; + lineno = 0; confset_init(&rc); confset_init(&lc); @@ -1197,23 +1255,103 @@ if (confset_grow(cs) == -1) { confset_free(&lc); confset_free(&rc); - fclose(fp); free(line); return; } } - if (conf_parseline(f, lineno, line, confset_get(cs), + if (conf_parseline(config_file, lineno, line, confset_get(cs), cs == &lc) == -1) continue; confset_add(cs); } - fclose(fp); - confset_sort(&lc); - confset_sort(&rc); + confset_merge(&rconf, &rc); + confset_merge(&lconf, &lc); +} + + +static void +conf_parsedir(DIR *dir, const char *config_path) +{ + long path_max; + struct dirent *dent; + char *path; + FILE *fp; + + if ((path_max = pathconf(config_path, _PC_PATH_MAX)) == -1) + path_max = 2048; + + if ((path = malloc((size_t)path_max)) == NULL) { + (*lfun)(LOG_ERR, "%s: Failed to allocate memory for path (%m)", + __func__); + return; + } + + while ((dent = readdir(dir)) != NULL) { + if (strcmp(dent->d_name, ".") == 0 || + strcmp(dent->d_name, "..") == 0) + continue; + + (void) snprintf(path, (size_t)path_max, "%s/%s", config_path, + dent->d_name); + if ((fp = fopen(path, "r")) == NULL) { + (*lfun)(LOG_ERR, "%s: Cannot open `%s' (%m)", __func__, + path); + continue; + } + conf_parsefile(fp, path); + fclose(fp); + } + + free(path); +} + +void +conf_parse(const char *config_path) +{ + char *path; + DIR *dir; + FILE *fp; + + if ((dir = opendir(config_path)) != NULL) { + /* + * If config_path is a directory, parse the configuration files + * in the directory. Then we're done here. + */ + conf_parsedir(dir, config_path); + closedir(dir); + goto out; + } else if ((fp = fopen(config_path, "r")) != NULL) { + /* If config_path is a file, parse it. */ + conf_parsefile(fp, config_path); + fclose(fp); + } + + /* + * Append ".d" to config_path, and if that is a directory, parse the + * configuration files in the directory. + */ + if (asprintf(&path, "%s.d", config_path) < 0) { + (*lfun)(LOG_ERR, "%s: Failed to allocate memory for path (%m)", + __func__); + goto out; + } + + if ((dir = opendir(path)) != NULL) { + conf_parsedir(dir, path); + closedir(dir); + } + free(path); + +out: + if (dir == NULL && fp == NULL) { + (*lfun)(LOG_ERR, "%s: Cannot open `%s' (%m)", __func__, + config_path); + return; + } - confset_replace(&rconf, &rc); - confset_replace(&lconf, &lc); + confset_sort(&lconf); + confset_sort(&rconf); if (debug) { confset_list(&lconf, "local", "target"); diff --git a/contrib/blocklist/bin/internal.h b/contrib/blocklist/bin/internal.h --- a/contrib/blocklist/bin/internal.h +++ b/contrib/blocklist/bin/internal.h @@ -1,4 +1,4 @@ -/* $NetBSD: internal.h,v 1.14 2016/04/04 15:52:56 christos Exp $ */ +/* $NetBSD: internal.h,v 1.1.1.1 2020/06/15 01:52:53 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -32,13 +32,13 @@ #define _INTERNAL_H #ifndef _PATH_BLCONF -#define _PATH_BLCONF "/etc/blacklistd.conf" +#define _PATH_BLCONF "/etc/blocklistd.conf" #endif #ifndef _PATH_BLCONTROL -#define _PATH_BLCONTROL "/libexec/blacklistd-helper" +#define _PATH_BLCONTROL "/usr/libexec/blocklistd-helper" #endif #ifndef _PATH_BLSTATE -#define _PATH_BLSTATE "/var/db/blacklistd.db" +#define _PATH_BLSTATE "/var/db/blocklistd.db" #endif extern struct confset rconf, lconf; diff --git a/contrib/blocklist/bin/internal.c b/contrib/blocklist/bin/internal.c --- a/contrib/blocklist/bin/internal.c +++ b/contrib/blocklist/bin/internal.c @@ -1,4 +1,4 @@ -/* $NetBSD: internal.c,v 1.5 2015/01/27 19:40:37 christos Exp $ */ +/* $NetBSD: internal.c,v 1.2 2025/02/11 17:48:30 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -32,8 +32,10 @@ #include "config.h" #endif +#ifdef HAVE_SYS_CDEFS_H #include -__RCSID("$NetBSD: internal.c,v 1.5 2015/01/27 19:40:37 christos Exp $"); +#endif +__RCSID("$NetBSD: internal.c,v 1.2 2025/02/11 17:48:30 christos Exp $"); #include #include @@ -41,7 +43,7 @@ #include "internal.h" int debug; -const char *rulename = "blacklistd"; +const char *rulename = "blocklistd"; const char *controlprog = _PATH_BLCONTROL; struct confset lconf, rconf; struct ifaddrs *ifas; diff --git a/contrib/blocklist/bin/run.h b/contrib/blocklist/bin/run.h --- a/contrib/blocklist/bin/run.h +++ b/contrib/blocklist/bin/run.h @@ -1,4 +1,4 @@ -/* $NetBSD: run.h,v 1.5 2015/01/27 19:40:37 christos Exp $ */ +/* $NetBSD: run.h,v 1.1.1.1 2020/06/15 01:52:53 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. diff --git a/contrib/blocklist/bin/run.c b/contrib/blocklist/bin/run.c --- a/contrib/blocklist/bin/run.c +++ b/contrib/blocklist/bin/run.c @@ -1,4 +1,4 @@ -/* $NetBSD: run.c,v 1.14 2016/04/04 15:52:56 christos Exp $ */ +/* $NetBSD: run.c,v 1.3 2025/02/11 17:48:30 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -32,8 +32,10 @@ #include "config.h" #endif +#ifdef HAVE_SYS_CDEFS_H #include -__RCSID("$NetBSD: run.c,v 1.14 2016/04/04 15:52:56 christos Exp $"); +#endif +__RCSID("$NetBSD: run.c,v 1.3 2025/02/11 17:48:30 christos Exp $"); #include #ifdef HAVE_LIBUTIL_H @@ -131,7 +133,8 @@ prname = "udp"; break; default: - (*lfun)(LOG_ERR, "%s: bad protocol %d", __func__, c->c_proto); + (*lfun)(LOG_ERR, "%s: bad protocol %d (line %zu)", __func__, + c->c_proto, c->c_lineno); return -1; } diff --git a/contrib/blocklist/bin/state.h b/contrib/blocklist/bin/state.h --- a/contrib/blocklist/bin/state.h +++ b/contrib/blocklist/bin/state.h @@ -1,4 +1,4 @@ -/* $NetBSD: state.h,v 1.5 2015/01/27 19:40:37 christos Exp $ */ +/* $NetBSD: state.h,v 1.1.1.1 2020/06/15 01:52:53 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. diff --git a/contrib/blocklist/bin/state.c b/contrib/blocklist/bin/state.c --- a/contrib/blocklist/bin/state.c +++ b/contrib/blocklist/bin/state.c @@ -1,4 +1,4 @@ -/* $NetBSD: state.c,v 1.19 2016/09/26 19:43:43 christos Exp $ */ +/* $NetBSD: state.c,v 1.2 2025/02/11 17:48:30 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -32,8 +32,10 @@ #include "config.h" #endif +#ifdef HAVE_SYS_CDEFS_H #include -__RCSID("$NetBSD: state.c,v 1.19 2016/09/26 19:43:43 christos Exp $"); +#endif +__RCSID("$NetBSD: state.c,v 1.2 2025/02/11 17:48:30 christos Exp $"); #include #include diff --git a/contrib/blocklist/bin/support.h b/contrib/blocklist/bin/support.h --- a/contrib/blocklist/bin/support.h +++ b/contrib/blocklist/bin/support.h @@ -1,4 +1,4 @@ -/* $NetBSD: support.h,v 1.7 2016/04/04 15:52:56 christos Exp $ */ +/* $NetBSD: support.h,v 1.2 2024/08/02 17:11:55 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -34,8 +34,9 @@ __BEGIN_DECLS const char *fmttime(char *, size_t, time_t); const char *fmtydhms(char *, size_t, time_t); -void vdlog(int, const char *, va_list) - __attribute__((__format__(__printf__, 2, 0))); +struct syslog_data; +void vdlog(int, struct syslog_data *, const char *, va_list) + __attribute__((__format__(__printf__, 3, 0))); void dlog(int, const char *, ...) __attribute__((__format__(__printf__, 2, 3))); ssize_t blhexdump(char *, size_t, const char *, const void *, size_t); diff --git a/contrib/blocklist/bin/support.c b/contrib/blocklist/bin/support.c --- a/contrib/blocklist/bin/support.c +++ b/contrib/blocklist/bin/support.c @@ -1,4 +1,4 @@ -/* $NetBSD: support.c,v 1.9 2018/09/18 22:12:19 christos Exp $ */ +/* $NetBSD: support.c,v 1.3 2025/02/11 17:48:30 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -32,8 +32,10 @@ #include "config.h" #endif +#ifdef HAVE_SYS_CDEFS_H #include -__RCSID("$NetBSD: support.c,v 1.9 2018/09/18 22:12:19 christos Exp $"); +#endif +__RCSID("$NetBSD: support.c,v 1.3 2025/02/11 17:48:30 christos Exp $"); #include #include @@ -66,7 +68,8 @@ } void -vdlog(int level __unused, const char *fmt, va_list ap) +vdlog(int level __unused, struct syslog_data *sd __unused, + const char *fmt, va_list ap) { char buf[BUFSIZ]; @@ -81,7 +84,7 @@ va_list ap; va_start(ap, fmt); - vdlog(level, fmt, ap); + vdlog(level, NULL, fmt, ap); va_end(ap); } diff --git a/contrib/blocklist/diff/ftpd.diff b/contrib/blocklist/diff/ftpd.diff --- a/contrib/blocklist/diff/ftpd.diff +++ b/contrib/blocklist/diff/ftpd.diff @@ -2,17 +2,17 @@ +++ pfilter.c 2015-01-23 17:12:02.000000000 -0500 @@ -0,0 +1,24 @@ +#include -+#include ++#include + +#include "pfilter.h" + -+static struct blacklist *blstate; ++static struct blocklist *blstate; + +void +pfilter_open(void) +{ + if (blstate == NULL) -+ blstate = blacklist_open(); ++ blstate = blocklist_open(); +} + +void @@ -23,7 +23,7 @@ + if (blstate == NULL) + return; + -+ blacklist_r(blstate, what, 0, msg); ++ blocklist_r(blstate, what, 0, msg); +} --- /dev/null 2015-01-23 17:30:40.000000000 -0500 +++ pfilter.h 2015-01-23 17:07:25.000000000 -0500 @@ -42,8 +42,8 @@ MLINKS= ftpusers.5 ftpchroot.5 +SRCS+= pfilter.c -+LDADD+= -lblacklist -+DPADD+= ${LIBBLACKLIST} ++LDADD+= -lblocklist ++DPADD+= ${LIBBLOCKLIST} + .if defined(NO_INTERNAL_LS) CPPFLAGS+=-DNO_INTERNAL_LS diff --git a/contrib/blocklist/diff/named.diff b/contrib/blocklist/diff/named.diff --- a/contrib/blocklist/diff/named.diff +++ b/contrib/blocklist/diff/named.diff @@ -8,17 +8,17 @@ +#include +#include + -+#include ++#include + +#include "pfilter.h" + -+static struct blacklist *blstate; ++static struct blocklist *blstate; + +void +pfilter_open(void) +{ + if (blstate == NULL) -+ blstate = blacklist_open(); ++ blstate = blocklist_open(); +} + +#define TCP_CLIENT(c) (((c)->attributes & NS_CLIENTATTR_TCP) != 0) @@ -39,7 +39,7 @@ + } + if (socket == NULL) + return; -+ blacklist_sa_r(blstate, ++ blocklist_sa_r(blstate, + res != ISC_R_SUCCESS, isc_socket_getfd(socket), + &client->peeraddr.type.sa, client->peeraddr.length, msg); +} @@ -63,8 +63,8 @@ + pfilter.c tkeyconf.c tsigconf.c \ update.c xfrout.c zoneconf.c ${SRCS_UNIX} -+LDADD+=-lblacklist -+DPADD+=${LIBBLACKLIST} ++LDADD+=-lblocklist ++DPADD+=${LIBBLOCKLIST} .include Index: dist/bin/named/client.c =================================================================== diff --git a/contrib/blocklist/diff/postfix.diff b/contrib/blocklist/diff/postfix.diff new file mode 100644 --- /dev/null +++ b/contrib/blocklist/diff/postfix.diff @@ -0,0 +1,98 @@ +Index: dist/src/smtpd/pfilter.c +=================================================================== +RCS file: dist/src/smtpd/pfilter.c +diff -N dist/src/smtpd/pfilter.c +--- /dev/null 1 Jan 1970 00:00:00 -0000 ++++ dist/src/smtpd/pfilter.c 1 Feb 2018 03:29:09 -0000 +@@ -0,0 +1,19 @@ ++#include "pfilter.h" ++#include /* for NULL */ ++#include ++ ++static struct blocklist *blstate; ++ ++void ++pfilter_notify(int a, int fd) ++{ ++ if (blstate == NULL) ++ blstate = blocklist_open(); ++ if (blstate == NULL) ++ return; ++ (void)blocklist_r(blstate, a, fd, "smtpd"); ++ if (a == 0) { ++ blocklist_close(blstate); ++ blstate = NULL; ++ } ++} +Index: dist/src/smtpd/pfilter.h +=================================================================== +RCS file: dist/src/smtpd/pfilter.h +diff -N dist/src/smtpd/pfilter.h +--- /dev/null 1 Jan 1970 00:00:00 -0000 ++++ dist/src/smtpd/pfilter.h 1 Feb 2018 03:29:09 -0000 +@@ -0,0 +1,2 @@ ++ ++void pfilter_notify(int, int); +Index: dist/src/smtpd/smtpd.c +=================================================================== +RCS file: /cvsroot/src/external/ibm-public/postfix/dist/src/smtpd/smtpd.c,v +retrieving revision 1.14 +diff -u -r1.14 smtpd.c +--- dist/src/smtpd/smtpd.c 14 Feb 2017 01:16:48 -0000 1.14 ++++ dist/src/smtpd/smtpd.c 1 Feb 2018 03:29:09 -0000 +@@ -1197,6 +1197,8 @@ + #include + #include + ++#include "pfilter.h" ++ + /* + * Tunable parameters. Make sure that there is some bound on the length of + * an SMTP command, so that the mail system stays in control even when a +@@ -5048,6 +5050,7 @@ + if (state->error_count >= var_smtpd_hard_erlim) { + state->reason = REASON_ERROR_LIMIT; + state->error_mask |= MAIL_ERROR_PROTOCOL; ++ pfilter_notify(1, vstream_fileno(state->client)); + smtpd_chat_reply(state, "421 4.7.0 %s Error: too many errors", + var_myhostname); + break; +Index: libexec/smtpd/Makefile +=================================================================== +RCS file: /cvsroot/src/external/ibm-public/postfix/libexec/smtpd/Makefile,v +retrieving revision 1.6 +diff -u -r1.6 Makefile +--- libexec/smtpd/Makefile 21 May 2017 15:28:40 -0000 1.6 ++++ libexec/smtpd/Makefile 1 Feb 2018 03:29:09 -0000 +@@ -13,11 +13,14 @@ + SRCS= smtpd.c smtpd_token.c smtpd_check.c smtpd_chat.c smtpd_state.c \ + smtpd_peer.c smtpd_sasl_proto.c smtpd_sasl_glue.c smtpd_proxy.c \ + smtpd_xforward.c smtpd_dsn_fix.c smtpd_milter.c smtpd_resolve.c \ +- smtpd_expand.c smtpd_haproxy.c ++ smtpd_expand.c smtpd_haproxy.c pfilter.c + + DPADD+= ${LIBPMASTER} ${LIBPMILTER} ${LIBPGLOBAL} ${LIBPDNS} ${LIBPXSASL} + LDADD+= ${LIBPMASTER} ${LIBPMILTER} ${LIBPGLOBAL} ${LIBPDNS} ${LIBPXSASL} + ++DPADD+= ${LIBBLOCKLIST} ++LDADD+= -lblocklist ++ + DPADD+= ${LIBPTLS} ${LIBSSL} ${LIBCRYPTO} + LDADD+= ${LIBPTLS} -lssl -lcrypto + +Index: dist/src/smtpd/smtpd.c +=================================================================== +RCS file: /cvsroot/src/external/ibm-public/postfix/dist/src/smtpd/smtpd.c,v +retrieving revision 1.17 +diff -u -u -r1.17 smtpd.c +--- dist/src/smtpd/smtpd.c 18 Mar 2020 19:05:20 -0000 1.17 ++++ dist/src/smtpd/smtpd.c 25 Sep 2020 12:51:52 -0000 +@@ -5795,6 +5795,8 @@ + || strcmp(state->reason, REASON_LOST_CONNECTION)) { + msg_info("%s after %s from %s", + state->reason, state->where, state->namaddr); ++ if (strcmp(state->where, SMTPD_CMD_AUTH) == 0) ++ pfilter_notify(1, vstream_fileno(state->client)); + } + } + diff --git a/contrib/blocklist/diff/proftpd.diff b/contrib/blocklist/diff/proftpd.diff --- a/contrib/blocklist/diff/proftpd.diff +++ b/contrib/blocklist/diff/proftpd.diff @@ -1,12 +1,12 @@ --- Make.rules.in.orig 2015-05-27 20:25:54.000000000 -0400 +++ Make.rules.in 2016-01-25 21:48:47.000000000 -0500 @@ -110,3 +110,8 @@ - + FTPWHO_OBJS=ftpwho.o scoreboard.o misc.o BUILD_FTPWHO_OBJS=utils/ftpwho.o utils/scoreboard.o utils/misc.o + -+CPPFLAGS+=-DHAVE_BLACKLIST -+LIBS+=-lblacklist ++CPPFLAGS+=-DHAVE_BLOCKLIST ++LIBS+=-lblocklist +OBJS+= pfilter.o +BUILD_OBJS+= src/pfilter.o --- /dev/null 2016-01-22 17:30:55.000000000 -0500 @@ -84,25 +84,25 @@ +#include "pfilter.h" +#include "conf.h" +#include "privs.h" -+#ifdef HAVE_BLACKLIST -+#include ++#ifdef HAVE_BLOCKLIST ++#include +#endif + -+static struct blacklist *blstate; ++static struct blocklist *blstate; + +void +pfilter_init(void) +{ -+#ifdef HAVE_BLACKLIST ++#ifdef HAVE_BLOCKLIST + if (blstate == NULL) -+ blstate = blacklist_open(); ++ blstate = blocklist_open(); +#endif +} + +void +pfilter_notify(int a) +{ -+#ifdef HAVE_BLACKLIST ++#ifdef HAVE_BLOCKLIST + conn_t *c = session.c; + int fd; + @@ -119,6 +119,6 @@ + pfilter_init(); + if (blstate == NULL) + return; -+ (void)blacklist_r(blstate, a, fd, "proftpd"); ++ (void)blocklist_r(blstate, a, fd, "proftpd"); +#endif +} diff --git a/contrib/blocklist/diff/ssh.diff b/contrib/blocklist/diff/ssh.diff --- a/contrib/blocklist/diff/ssh.diff +++ b/contrib/blocklist/diff/ssh.diff @@ -7,14 +7,14 @@ +#include "packet.h" +#include "log.h" +#include "pfilter.h" -+#include ++#include + -+static struct blacklist *blstate; ++static struct blocklist *blstate; + +void +pfilter_init(void) +{ -+ blstate = blacklist_open(); ++ blstate = blocklist_open(); +} + +void @@ -27,9 +27,9 @@ + return; + // XXX: 3? + fd = packet_connection_is_on_socket() ? packet_get_connection_in() : 3; -+ (void)blacklist_r(blstate, a, fd, "ssh"); ++ (void)blocklist_r(blstate, a, fd, "ssh"); + if (a == 0) { -+ blacklist_close(blstate); ++ blocklist_close(blstate); + blstate = NULL; + } +} @@ -60,8 +60,8 @@ LDADD+= -lwrap DPADD+= ${LIBWRAP} + -+LDADD+= -lblacklist -+DPADD+= ${LIBBLACKLIST} ++LDADD+= -lblocklist ++DPADD+= ${LIBBLOCKLIST} diff -ru openssh-7.7p1/auth-pam.c dist/auth-pam.c --- openssh-7.7p1/auth-pam.c 2018-04-02 01:38:28.000000000 -0400 +++ dist/auth-pam.c 2018-05-23 11:56:22.206661484 -0400 diff --git a/contrib/blocklist/etc/Makefile b/contrib/blocklist/etc/Makefile --- a/contrib/blocklist/etc/Makefile +++ b/contrib/blocklist/etc/Makefile @@ -1,10 +1,10 @@ -# $NetBSD: Makefile,v 1.3 2015/01/26 00:18:40 christos Exp $ +# $NetBSD: Makefile,v 1.2 2025/02/05 20:24:26 christos Exp $ -SUBDIR=rc.d +SUBDIR= rc.d -FILESDIR= /usr/share/examples/blacklist -FILESMODE= 644 -FILES= blacklistd.conf npf.conf +FILESDIR= /usr/share/examples/blocklist +FILESMODE= 644 +FILES= blocklistd.conf ipf.conf npf.conf .include .include diff --git a/contrib/blocklist/etc/blacklistd.conf b/contrib/blocklist/etc/blocklistd.conf rename from contrib/blocklist/etc/blacklistd.conf rename to contrib/blocklist/etc/blocklistd.conf --- a/contrib/blocklist/etc/blacklistd.conf +++ b/contrib/blocklist/etc/blocklistd.conf @@ -1,5 +1,5 @@ -# Blacklist rule -# adr/mask:port type proto owner name nfail disable +# Blocklist rule +# adr/mask:port type proto owner name nfail duration [local] ssh stream * * * 3 6h ftp stream * * * 3 6h @@ -7,8 +7,9 @@ #6161 stream tcp6 christos * 2 10m * * * * * 3 60 -# adr/mask:port type proto owner name nfail disable +# adr/mask:port type proto owner name nfail duration [remote] #129.168.0.0/16 * * * = * * +#[2001:db8::]/32:ssh * * * = * * #6161 = = = =/24 = = #* stream tcp * = = = diff --git a/contrib/blocklist/etc/ipf.conf b/contrib/blocklist/etc/ipf.conf new file mode 100644 --- /dev/null +++ b/contrib/blocklist/etc/ipf.conf @@ -0,0 +1,45 @@ +#======================================== +# +# subsection for abuse blocking +# +#======================================== +# +# This section should be included early in the main /etc/ipf.conf file, right +# after any basic generic accounting ("count") rules, and any cleanup rules to +# block invalid fragments, invalid options (e.g. "ssrr"), etc. +# +# Note these will not actually block anything since they don't include the +# "quick" flag, and are thus part of a last-match group. They simply set up a +# group such that any connection logging rule further below won't also match if +# one of the rules in the group matches, no matter when or where the subsequent +# matching rule is added. I.e. all rules in the group are checked for a match +# (and a possible "first match" with "quick") before any subsequent rules +# further below are used. Note group rules can be added at any time, including +# at runtime after all other rules have been added -- they will still belong to +# the group and once added will be checked as part of the group. +# +# head of "blocklistd" group: +# +# The "blocklistd" group will be used by blocklistd(8). +# +block in proto tcp/udp from any to any head blocklistd +# +# head of "attackers" group to block all attackers: +# +# The "attackers" group is intended to be used for manually maintained rules +# e.g. as could be added like this: +# +# echo 'block return-rst in log quick proto tcp from 118.136.0.0/15 to any flags S/SAFR group attackers' >> /etc/ipf.conf +# /etc/rc.d/ipfliter reload +# +# Note the choice in this example is to return RST packets for blocked SYN +# packets to help the other end close. This is not necessary, but it better +# mimics what the kernel does by default, thus perhaps hiding the fact a +# firewall is present. +# +# XXX This example still allows UDP services, but we would need to duplicate +# each rule with "proto udp" (and without "flags blah") due to IPF parsing +# limitations.... +# +block in proto tcp/udp from any to any head attackers +# diff --git a/contrib/blocklist/etc/npf.conf b/contrib/blocklist/etc/npf.conf --- a/contrib/blocklist/etc/npf.conf +++ b/contrib/blocklist/etc/npf.conf @@ -1,4 +1,4 @@ -# Transparent firewall example for blacklistd +# Transparent firewall example for blocklistd $ext_if = "bnx0" @@ -6,7 +6,7 @@ alg "icmp" group "external" on $ext_if { - ruleset "blacklistd" + ruleset "blocklistd" pass final all } diff --git a/contrib/blocklist/etc/rc.d/Makefile b/contrib/blocklist/etc/rc.d/Makefile --- a/contrib/blocklist/etc/rc.d/Makefile +++ b/contrib/blocklist/etc/rc.d/Makefile @@ -1,6 +1,6 @@ -# $NetBSD: Makefile,v 1.1 2015/01/22 17:49:41 christos Exp $ +# $NetBSD: Makefile,v 1.1.1.1 2020/06/15 01:52:53 christos Exp $ -SCRIPTS=blacklistd +SCRIPTS=blocklistd SCRIPTSDIR=/etc/rc.d .include diff --git a/contrib/blocklist/etc/rc.d/blacklistd b/contrib/blocklist/etc/rc.d/blocklistd rename from contrib/blocklist/etc/rc.d/blacklistd rename to contrib/blocklist/etc/rc.d/blocklistd --- a/contrib/blocklist/etc/rc.d/blacklistd +++ b/contrib/blocklist/etc/rc.d/blocklistd @@ -1,15 +1,15 @@ #!/bin/sh # -# $NetBSD: blacklistd,v 1.2 2016/10/17 22:47:16 christos Exp $ +# $NetBSD: blocklistd,v 1.2 2021/03/07 00:46:39 christos Exp $ # -# PROVIDE: blacklistd -# REQUIRE: npf +# PROVIDE: blocklistd +# REQUIRE: npf pf ipfilter # BEFORE: SERVERS $_rc_subr_loaded . /etc/rc.subr -name="blacklistd" +name="blocklistd" rcvar=$name command="/sbin/${name}" pidfile="/var/run/${name}.pid" @@ -18,17 +18,17 @@ extra_commands="reload" _sockfile="/var/run/${name}.sockets" -_sockname="blacklistd.sock" +_sockname="blocklistd.sock" -blacklistd_precmd() +blocklistd_precmd() { - # Create default list of blacklistd sockets to watch + # Create default list of blocklistd sockets to watch # ( umask 022 ; > $_sockfile ) # Find /etc/rc.d scripts with "chrootdir" rcorder(8) keyword, # and if $${app}_chrootdir is a directory, add appropriate - # blacklistd socket to list of sockets to watch. + # blocklistd socket to list of sockets to watch. # for _lr in $(rcorder -k chrootdir /etc/rc.d/*); do ( @@ -42,8 +42,8 @@ done # If other sockets have been provided, change run_rc_command()'s - # internal copy of $blacklistd_flags to force use of specific - # blacklistd sockets. + # internal copy of $blocklistd_flags to force use of specific + # blocklistd sockets. # if [ -s $_sockfile ]; then echo "/var/run/${_sockname}" >> $_sockfile diff --git a/contrib/blocklist/include/Makefile b/contrib/blocklist/include/Makefile --- a/contrib/blocklist/include/Makefile +++ b/contrib/blocklist/include/Makefile @@ -1,10 +1,10 @@ -# $NetBSD: Makefile,v 1.1 2015/01/21 16:16:00 christos Exp $ +# $NetBSD: Makefile,v 1.1.1.1 2020/06/15 01:52:53 christos Exp $ # Doing a make includes builds /usr/include NOOBJ= # defined -INCS= blacklist.h +INCS= blocklist.h INCSDIR= /usr/include .include diff --git a/contrib/blocklist/include/bl.h b/contrib/blocklist/include/bl.h --- a/contrib/blocklist/include/bl.h +++ b/contrib/blocklist/include/bl.h @@ -1,4 +1,4 @@ -/* $NetBSD: bl.h,v 1.13 2016/03/11 17:16:40 christos Exp $ */ +/* $NetBSD: bl.h,v 1.2 2024/08/02 17:11:55 christos Exp $ */ /*- * Copyright (c) 2014 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ #include #include #include -#include "blacklist.h" +#include "blocklist.h" typedef enum { BL_INVALID, @@ -58,14 +58,15 @@ #define bi_cred bi_u._bi_cred #ifndef _PATH_BLSOCK -#define _PATH_BLSOCK "/var/run/blacklistd.sock" +#define _PATH_BLSOCK "/var/run/blocklistd.sock" #endif __BEGIN_DECLS -typedef struct blacklist *bl_t; +typedef struct blocklist *bl_t; -bl_t bl_create(bool, const char *, void (*)(int, const char *, va_list)); +bl_t bl_create(bool, const char *, + void (*)(int, struct syslog_data *, const char *, va_list)); void bl_destroy(bl_t); int bl_send(bl_t, bl_type_t, int, const struct sockaddr *, socklen_t, const char *); diff --git a/contrib/blocklist/include/blacklist.h b/contrib/blocklist/include/blocklist.h rename from contrib/blocklist/include/blacklist.h rename to contrib/blocklist/include/blocklist.h --- a/contrib/blocklist/include/blacklist.h +++ b/contrib/blocklist/include/blocklist.h @@ -1,4 +1,4 @@ -/* $NetBSD: blacklist.h,v 1.3 2015/01/23 18:48:56 christos Exp $ */ +/* $NetBSD: blocklist.h,v 1.4 2025/02/11 17:42:17 christos Exp $ */ /*- * Copyright (c) 2014 The NetBSD Foundation, Inc. @@ -28,28 +28,38 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef _BLACKLIST_H -#define _BLACKLIST_H +#ifndef _BLOCKLIST_H +#define _BLOCKLIST_H #include +#include -__BEGIN_DECLS -struct blacklist *blacklist_open(void); -void blacklist_close(struct blacklist *); -int blacklist(int, int, const char *); -int blacklist_r(struct blacklist *, int, int, const char *); -int blacklist_sa(int, int, const struct sockaddr *, socklen_t, const char *); -int blacklist_sa_r(struct blacklist *, int, int, +#if defined(__cplusplus) +extern "C" { +#endif + +struct syslog_data; +struct blocklist *blocklist_open(void); +struct blocklist *blocklist_open2( + void (*)(int, struct syslog_data *, const char *, va_list)); +void blocklist_close(struct blocklist *); +int blocklist(int, int, const char *); +int blocklist_r(struct blocklist *, int, int, const char *); +int blocklist_sa(int, int, const struct sockaddr *, socklen_t, const char *); +int blocklist_sa_r(struct blocklist *, int, int, const struct sockaddr *, socklen_t, const char *); -__END_DECLS + +#if defined(__cplusplus) +} +#endif /* action values for user applications */ -#define BLACKLIST_API_ENUM 1 +#define BLOCKLIST_API_ENUM 1 enum { - BLACKLIST_AUTH_OK = 0, - BLACKLIST_AUTH_FAIL, - BLACKLIST_ABUSIVE_BEHAVIOR, - BLACKLIST_BAD_USER + BLOCKLIST_AUTH_OK = 0, + BLOCKLIST_AUTH_FAIL, + BLOCKLIST_ABUSIVE_BEHAVIOR, + BLOCKLIST_BAD_USER }; -#endif /* _BLACKLIST_H */ +#endif /* _BLOCKLIST_H */ diff --git a/contrib/blocklist/lib/Makefile b/contrib/blocklist/lib/Makefile --- a/contrib/blocklist/lib/Makefile +++ b/contrib/blocklist/lib/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.7 2019/03/08 20:40:05 christos Exp $ +# $NetBSD: Makefile,v 1.1.1.1 2020/06/15 01:52:53 christos Exp $ .include @@ -6,14 +6,14 @@ CPPFLAGS+=-D_REENTRANT #LIBDPLIBS+=pthread ${NETBSDSRCDIR}/lib/libpthread -LIB=blacklist -SRCS=bl.c blacklist.c -MAN=libblacklist.3 -MLINKS+=libblacklist.3 blacklist_open.3 -MLINKS+=libblacklist.3 blacklist_close.3 -MLINKS+=libblacklist.3 blacklist.3 -MLINKS+=libblacklist.3 blacklist_r.3 -MLINKS+=libblacklist.3 blacklist_sa.3 -MLINKS+=libblacklist.3 blacklist_sa_r.3 +LIB=blocklist +SRCS=bl.c blocklist.c +MAN=libblocklist.3 +MLINKS+=libblocklist.3 blocklist_open.3 +MLINKS+=libblocklist.3 blocklist_close.3 +MLINKS+=libblocklist.3 blocklist.3 +MLINKS+=libblocklist.3 blocklist_r.3 +MLINKS+=libblocklist.3 blocklist_sa.3 +MLINKS+=libblocklist.3 blocklist_sa_r.3 .include diff --git a/contrib/blocklist/lib/bl.c b/contrib/blocklist/lib/bl.c --- a/contrib/blocklist/lib/bl.c +++ b/contrib/blocklist/lib/bl.c @@ -1,4 +1,4 @@ -/* $NetBSD: bl.c,v 1.28 2016/07/29 17:13:09 christos Exp $ */ +/* $NetBSD: bl.c,v 1.9 2025/03/30 01:53:59 christos Exp $ */ /*- * Copyright (c) 2014 The NetBSD Foundation, Inc. @@ -32,8 +32,10 @@ #include "config.h" #endif +#ifdef HAVE_SYS_CDEFS_H #include -__RCSID("$NetBSD: bl.c,v 1.28 2016/07/29 17:13:09 christos Exp $"); +#endif +__RCSID("$NetBSD: bl.c,v 1.9 2025/03/30 01:53:59 christos Exp $"); #include #include @@ -57,6 +59,10 @@ #include #endif +#if defined(SO_RECVUCRED) +#include +#endif + #include "bl.h" typedef struct { @@ -68,7 +74,7 @@ char bl_data[]; } bl_message_t; -struct blacklist { +struct blocklist { #ifdef _REENTRANT pthread_mutex_t b_mutex; # define BL_INIT(b) pthread_mutex_init(&b->b_mutex, NULL) @@ -82,7 +88,8 @@ int b_fd; int b_connected; struct sockaddr_un b_sun; - void (*b_fun)(int, const char *, va_list); + struct syslog_data b_syslog_data; + void (*b_fun)(int, struct syslog_data *, const char *, va_list); bl_info_t b_info; }; @@ -115,14 +122,16 @@ } static void -bl_log(void (*fun)(int, const char *, va_list), int level, - const char *fmt, ...) +bl_log(bl_t b, int level, const char *fmt, ...) { va_list ap; int serrno = errno; + if (b->b_fun == NULL) + return; + va_start(ap, fmt); - (*fun)(level, fmt, ap); + (*b->b_fun)(level, &b->b_syslog_data, fmt, ap); va_end(ap); errno = serrno; } @@ -152,7 +161,7 @@ b->b_fd = socket(PF_LOCAL, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK|SOCK_NOSIGPIPE, 0); if (b->b_fd == -1) { - bl_log(b->b_fun, LOG_ERR, "%s: socket failed (%s)", + bl_log(b, LOG_ERR, "%s: socket failed (%s)", __func__, strerror(errno)); BL_UNLOCK(b); return -1; @@ -186,7 +195,7 @@ rv = connect(b->b_fd, (const void *)sun, (socklen_t)sizeof(*sun)); if (rv == 0) { if (srv) { - bl_log(b->b_fun, LOG_ERR, + bl_log(b, LOG_ERR, "%s: another daemon is handling `%s'", __func__, sun->sun_path); goto out; @@ -199,7 +208,7 @@ * and only log once. */ if (b->b_connected != 1) { - bl_log(b->b_fun, LOG_DEBUG, + bl_log(b, LOG_DEBUG, "%s: connect failed for `%s' (%s)", __func__, sun->sun_path, strerror(errno)); b->b_connected = 1; @@ -207,8 +216,7 @@ BL_UNLOCK(b); return -1; } - bl_log(b->b_fun, LOG_DEBUG, "Connected to blacklist server", - __func__); + bl_log(b, LOG_DEBUG, "Connected to blocklist server", __func__); } if (srv) { @@ -219,8 +227,7 @@ (void)umask(om); errno = serrno; if (rv == -1) { - bl_log(b->b_fun, LOG_ERR, - "%s: bind failed for `%s' (%s)", + bl_log(b, LOG_ERR, "%s: bind failed for `%s' (%s)", __func__, sun->sun_path, strerror(errno)); goto out; } @@ -231,8 +238,8 @@ #if defined(LOCAL_CREDS) #define CRED_LEVEL 0 #define CRED_NAME LOCAL_CREDS -#define CRED_SC_UID sc_euid -#define CRED_SC_GID sc_egid +#define CRED_SC_UID(x) (x)->sc_euid +#define CRED_SC_GID(x) (x)->sc_egid #define CRED_MESSAGE SCM_CREDS #define CRED_SIZE SOCKCREDSIZE(NGROUPS_MAX) #define CRED_TYPE struct sockcred @@ -240,12 +247,21 @@ #elif defined(SO_PASSCRED) #define CRED_LEVEL SOL_SOCKET #define CRED_NAME SO_PASSCRED -#define CRED_SC_UID uid -#define CRED_SC_GID gid +#define CRED_SC_UID(x) (x)->uid +#define CRED_SC_GID(x) (x)->gid #define CRED_MESSAGE SCM_CREDENTIALS #define CRED_SIZE sizeof(struct ucred) #define CRED_TYPE struct ucred #define GOT_CRED 2 +#elif defined(SO_RECVUCRED) +#define CRED_LEVEL SOL_SOCKET +#define CRED_NAME SO_RECVUCRED +#define CRED_SC_UID(x) ucred_geteuid(x) +#define CRED_SC_GID(x) ucred_getegid(x) +#define CRED_MESSAGE SCM_UCRED +#define CRED_SIZE ucred_size() +#define CRED_TYPE ucred_t +#define GOT_CRED 2 #else #define GOT_CRED 0 /* @@ -259,7 +275,7 @@ #ifdef CRED_LEVEL if (setsockopt(b->b_fd, CRED_LEVEL, CRED_NAME, &one, (socklen_t)sizeof(one)) == -1) { - bl_log(b->b_fun, LOG_ERR, "%s: setsockopt %s " + bl_log(b, LOG_ERR, "%s: setsockopt %s " "failed (%s)", __func__, __STRING(CRED_NAME), strerror(errno)); goto out; @@ -275,12 +291,15 @@ } bl_t -bl_create(bool srv, const char *path, void (*fun)(int, const char *, va_list)) +bl_create(bool srv, const char *path, + void (*fun)(int, struct syslog_data *, const char *, va_list)) { + static struct syslog_data sd = SYSLOG_DATA_INIT; bl_t b = calloc(1, sizeof(*b)); if (b == NULL) - goto out; - b->b_fun = fun == NULL ? vsyslog : fun; + return NULL; + b->b_fun = fun; + b->b_syslog_data = sd; b->b_fd = -1; b->b_connected = -1; BL_INIT(b); @@ -295,11 +314,6 @@ bl_init(b, srv); return b; -out: - free(b); - bl_log(fun, LOG_ERR, "%s: malloc failed (%s)", __func__, - strerror(errno)); - return NULL; } void @@ -327,7 +341,7 @@ family = AF_INET6; break; default: - bl_log(b->b_fun, LOG_ERR, "%s: invalid socket len %u (%s)", + bl_log(b, LOG_ERR, "%s: invalid socket len %u (%s)", __func__, (unsigned)slen, ctx); errno = EINVAL; return -1; @@ -336,7 +350,7 @@ memcpy(ss, sa, slen); if (ss->ss_family != family) { - bl_log(b->b_fun, LOG_INFO, + bl_log(b, LOG_INFO, "%s: correcting socket family %d to %d (%s)", __func__, ss->ss_family, family, ctx); ss->ss_family = family; @@ -344,7 +358,7 @@ #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN if (ss->ss_len != slen) { - bl_log(b->b_fun, LOG_INFO, + bl_log(b, LOG_INFO, "%s: correcting socket len %u to %u (%s)", __func__, ss->ss_len, (unsigned)slen, ctx); ss->ss_len = (uint8_t)slen; @@ -424,10 +438,11 @@ union { char ctrl[CMSG_SPACE(sizeof(int)) + CMSG_SPACE(CRED_SIZE)]; uint32_t fd; - CRED_TYPE sc; } ua; struct cmsghdr *cmsg; +#if GOT_CRED != 0 CRED_TYPE *sc; +#endif union { bl_message_t bl; char buf[512]; @@ -450,18 +465,18 @@ msg.msg_flags = 0; msg.msg_control = ua.ctrl; - msg.msg_controllen = sizeof(ua.ctrl) + 100; + msg.msg_controllen = sizeof(ua.ctrl); rlen = recvmsg(b->b_fd, &msg, 0); if (rlen == -1) { - bl_log(b->b_fun, LOG_ERR, "%s: recvmsg failed (%s)", __func__, + bl_log(b, LOG_ERR, "%s: recvmsg failed (%s)", __func__, strerror(errno)); return NULL; } for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { if (cmsg->cmsg_level != SOL_SOCKET) { - bl_log(b->b_fun, LOG_ERR, + bl_log(b, LOG_ERR, "%s: unexpected cmsg_level %d", __func__, cmsg->cmsg_level); continue; @@ -469,10 +484,15 @@ switch (cmsg->cmsg_type) { case SCM_RIGHTS: if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) { - bl_log(b->b_fun, LOG_ERR, + int *fd = (void *)CMSG_DATA(cmsg); + size_t len = cmsg->cmsg_len / sizeof(int); + bl_log(b, LOG_ERR, "%s: unexpected cmsg_len %d != %zu", __func__, cmsg->cmsg_len, - CMSG_LEN(2 * sizeof(int))); + CMSG_LEN(sizeof(int))); + + for (size_t i = 0; i < len; i++) + (void)close(fd[i]); continue; } memcpy(&bi->bi_fd, CMSG_DATA(cmsg), sizeof(bi->bi_fd)); @@ -481,13 +501,13 @@ #ifdef CRED_MESSAGE case CRED_MESSAGE: sc = (void *)CMSG_DATA(cmsg); - bi->bi_uid = sc->CRED_SC_UID; - bi->bi_gid = sc->CRED_SC_GID; + bi->bi_uid = CRED_SC_UID(sc); + bi->bi_gid = CRED_SC_GID(sc); got |= GOT_CRED; break; #endif default: - bl_log(b->b_fun, LOG_ERR, + bl_log(b, LOG_ERR, "%s: unexpected cmsg_type %d", __func__, cmsg->cmsg_type); continue; @@ -496,7 +516,7 @@ } if (got != (GOT_CRED|GOT_FD)) { - bl_log(b->b_fun, LOG_ERR, "message missing %s %s", + bl_log(b, LOG_ERR, "message missing %s %s", #if GOT_CRED != 0 (got & GOT_CRED) == 0 ? "cred" : #endif @@ -506,13 +526,13 @@ rem = (size_t)rlen; if (rem < sizeof(ub.bl)) { - bl_log(b->b_fun, LOG_ERR, "message too short %zd", rlen); + bl_log(b, LOG_ERR, "message too short %zd", rlen); return NULL; } rem -= sizeof(ub.bl); if (ub.bl.bl_version != BL_VERSION) { - bl_log(b->b_fun, LOG_ERR, "bad version %d", ub.bl.bl_version); + bl_log(b, LOG_ERR, "bad version %d", ub.bl.bl_version); return NULL; } @@ -523,10 +543,12 @@ bi->bi_uid = -1; bi->bi_gid = -1; #endif - rem = MIN(sizeof(bi->bi_msg), rem); if (rem == 0) bi->bi_msg[0] = '\0'; - else - strlcpy(bi->bi_msg, ub.bl.bl_data, rem); + else { + rem = MIN(sizeof(bi->bi_msg) - 1, rem); + memcpy(bi->bi_msg, ub.bl.bl_data, rem); + bi->bi_msg[rem] = '\0'; + } return bi; } diff --git a/contrib/blocklist/lib/blacklist.c b/contrib/blocklist/lib/blocklist.c rename from contrib/blocklist/lib/blacklist.c rename to contrib/blocklist/lib/blocklist.c --- a/contrib/blocklist/lib/blacklist.c +++ b/contrib/blocklist/lib/blocklist.c @@ -1,4 +1,4 @@ -/* $NetBSD: blacklist.c,v 1.5 2015/01/22 16:19:53 christos Exp $ */ +/* $NetBSD: blocklist.c,v 1.4 2025/02/11 17:48:30 christos Exp $ */ /*- * Copyright (c) 2014 The NetBSD Foundation, Inc. @@ -32,8 +32,10 @@ #include "config.h" #endif +#ifdef HAVE_SYS_CDEFS_H #include -__RCSID("$NetBSD: blacklist.c,v 1.5 2015/01/22 16:19:53 christos Exp $"); +#endif +__RCSID("$NetBSD: blocklist.c,v 1.4 2025/02/11 17:48:30 christos Exp $"); #include #include @@ -45,36 +47,36 @@ #include int -blacklist_sa(int action, int rfd, const struct sockaddr *sa, socklen_t salen, +blocklist_sa(int action, int rfd, const struct sockaddr *sa, socklen_t salen, const char *msg) { - struct blacklist *bl; + struct blocklist *bl; int rv; - if ((bl = blacklist_open()) == NULL) + if ((bl = blocklist_open()) == NULL) return -1; - rv = blacklist_sa_r(bl, action, rfd, sa, salen, msg); - blacklist_close(bl); + rv = blocklist_sa_r(bl, action, rfd, sa, salen, msg); + blocklist_close(bl); return rv; } int -blacklist_sa_r(struct blacklist *bl, int action, int rfd, +blocklist_sa_r(struct blocklist *bl, int action, int rfd, const struct sockaddr *sa, socklen_t slen, const char *msg) { bl_type_t internal_action; /* internal values are not the same as user application values */ switch (action) { - case BLACKLIST_AUTH_FAIL: + case BLOCKLIST_AUTH_FAIL: internal_action = BL_ADD; break; - case BLACKLIST_AUTH_OK: + case BLOCKLIST_AUTH_OK: internal_action = BL_DELETE; break; - case BLACKLIST_ABUSIVE_BEHAVIOR: + case BLOCKLIST_ABUSIVE_BEHAVIOR: internal_action = BL_ABUSE; break; - case BLACKLIST_BAD_USER: + case BLOCKLIST_BAD_USER: internal_action = BL_BADUSER; break; default: @@ -85,24 +87,31 @@ } int -blacklist(int action, int rfd, const char *msg) +blocklist(int action, int rfd, const char *msg) { - return blacklist_sa(action, rfd, NULL, 0, msg); + return blocklist_sa(action, rfd, NULL, 0, msg); } int -blacklist_r(struct blacklist *bl, int action, int rfd, const char *msg) +blocklist_r(struct blocklist *bl, int action, int rfd, const char *msg) { - return blacklist_sa_r(bl, action, rfd, NULL, 0, msg); + return blocklist_sa_r(bl, action, rfd, NULL, 0, msg); +} + +struct blocklist * +blocklist_open(void) { + return bl_create(false, NULL, vsyslog_r); } -struct blacklist * -blacklist_open(void) { - return bl_create(false, NULL, vsyslog); +struct blocklist * +blocklist_open2( + void (*logger)(int, struct syslog_data *, const char *, va_list)) +{ + return bl_create(false, NULL, logger); } void -blacklist_close(struct blacklist *bl) +blocklist_close(struct blocklist *bl) { bl_destroy(bl); } diff --git a/contrib/blocklist/lib/libblacklist.3 b/contrib/blocklist/lib/libblocklist.3 rename from contrib/blocklist/lib/libblacklist.3 rename to contrib/blocklist/lib/libblocklist.3 --- a/contrib/blocklist/lib/libblacklist.3 +++ b/contrib/blocklist/lib/libblocklist.3 @@ -1,4 +1,4 @@ -.\" $NetBSD: libblacklist.3,v 1.10 2020/03/30 15:47:15 christos Exp $ +.\" $NetBSD: libblocklist.3,v 1.7 2025/02/05 20:14:30 christos Exp $ .\" .\" Copyright (c) 2015 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -27,55 +27,71 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd March 30, 2020 -.Dt LIBBLACKLIST 3 +.Dd February 5, 2025 +.Dt LIBBLOCKLIST 3 .Os .Sh NAME -.Nm blacklist_open , -.Nm blacklist_close , -.Nm blacklist_r , -.Nm blacklist , -.Nm blacklist_sa , -.Nm blacklist_sa_r -.Nd Blacklistd notification library +.Nm blocklist_open , +.Nm blocklist_open2 , +.Nm blocklist_close , +.Nm blocklist_r , +.Nm blocklist , +.Nm blocklist_sa , +.Nm blocklist_sa_r +.Nd Blocklistd notification library .Sh LIBRARY -.Lb libblacklist +.Lb libblocklist .Sh SYNOPSIS -.In blacklist.h -.Ft struct blacklist * -.Fn blacklist_open "void" +.In blocklist.h +.Ft struct blocklist * +.Fn blocklist_open "void" +.Ft struct blocklist * +.Fn blocklist_open2 "void (*logger)(int, struct syslog_data *, va_list)" .Ft void -.Fn blacklist_close "struct blacklist *cookie" +.Fn blocklist_close "struct blocklist *cookie" .Ft int -.Fn blacklist "int action" "int fd" "const char *msg" +.Fn blocklist "int action" "int fd" "const char *msg" .Ft int -.Fn blacklist_r "struct blacklist *cookie" "int action" "int fd" "const char *msg" +.Fn blocklist_r "struct blocklist *cookie" "int action" "int fd" "const char *msg" .Ft int -.Fn blacklist_sa "int action" "int fd" "const struct sockaddr *sa" "socklen_t salen" "const char *msg" +.Fn blocklist_sa "int action" "int fd" "const struct sockaddr *sa" "socklen_t salen" "const char *msg" .Ft int -.Fn blacklist_sa_r "struct blacklist *cookie" "int action" "int fd" "const struct sockaddr *sa" "socklen_t salen" "const char *msg" +.Fn blocklist_sa_r "struct blocklist *cookie" "int action" "int fd" "const struct sockaddr *sa" "socklen_t salen" "const char *msg" .Sh DESCRIPTION These functions can be used by daemons to notify -.Xr blacklistd 8 -about successful and failed remote connections so that blacklistd can +.Xr blocklistd 8 +about successful and failed remote connections so that blocklistd can block or release port access to prevent Denial of Service attacks. .Pp The function -.Fn blacklist_open +.Fn blocklist_open creates the necessary state to communicate with -.Xr blacklistd 8 +.Xr blocklistd 8 and returns a pointer to it, or .Dv NULL on failure. .Pp +The function +.Fn blocklist_open2 +is similar to +.Fn blocklist_open +but allows a +.Fa logger +to be specified. +If the +.Fa logger +is +.Dv NULL , +then no logging is performed. +.Pp The -.Fn blacklist_close +.Fn blocklist_close function frees all memory and resources used. .Pp The -.Fn blacklist +.Fn blocklist function sends a message to -.Xr blacklistd 8 , +.Xr blocklistd 8 , with an integer .Ar action argument specifying the type of notification, @@ -89,37 +105,31 @@ The .Ar action parameter can take these values: -.Bl -tag -width ".Va BLACKLIST_ABUSIVE_BEHAVIOR" -.It Va BLACKLIST_AUTH_FAIL +.Bl -tag -width ".Dv BLOCKLIST_ABUSIVE_BEHAVIOR" +.It Va BLOCKLIST_BAD_USER +The sending daemon has determined the username presented for +authentication is invalid. +This is considered as one failure count. +.It Va BLOCKLIST_AUTH_FAIL There was an unsuccessful authentication attempt. -.It Va BLACKLIST_AUTH_OK -A user successfully authenticated. -.It Va BLACKLIST_ABUSIVE_BEHAVIOR -The sending daemon has detected abusive behavior -from the remote system. -The remote address should -be blocked as soon as possible. -.It Va BLACKLIST_BAD_USER -The sending daemon has determined the username -presented for authentication is invalid. -The -.Xr blacklistd 8 -daemon compares the username to a configured list of forbidden -usernames and -blocks the address immediately if a forbidden username matches. -(The -.Ar BLACKLIST_BAD_USER -support is not currently available.) +This is considered as two failure counts together. +.It Va BLOCKLIST_ABUSIVE_BEHAVIOR +The sending daemon has detected abusive behavior from the remote system. +This is considered as a total immediate failure. +The remote address will be blocked as soon as possible. +.It Va BLOCKLIST_AUTH_OK +A valid user successfully authenticated. +Any entry for the remote address will be removed as soon as possible. .El .Pp The -.Fn blacklist_r -function is more efficient because it keeps the blacklist state around. +.Fn blocklist_r +function is more efficient because it keeps the blocklist state around. .Pp The -.Fn blacklist_sa +.Fn blocklist_sa and -.Fn blacklist_sa_r +.Fn blocklist_sa_r functions can be used with unconnected sockets, where .Xr getpeername 2 will not work, the server will pass the peer name in the message. @@ -127,7 +137,7 @@ In all cases the file descriptor passed in the .Fa fd argument must be pointing to a valid socket so that -.Xr blacklistd 8 +.Xr blocklistd 8 can establish ownership of the local endpoint using .Xr getsockname 2 . @@ -141,7 +151,7 @@ state and specify a custom logging function. .Sh RETURN VALUES The function -.Fn blacklist_open +.Fn blocklist_open returns a cookie on success and .Dv NULL on failure setting @@ -149,10 +159,10 @@ to an appropriate value. .Pp The functions -.Fn blacklist , -.Fn blacklist_sa , +.Fn blocklist , +.Fn blocklist_sa , and -.Fn blacklist_sa_r +.Fn blocklist_sa_r return .Dv 0 on success and @@ -161,7 +171,7 @@ .Dv errno to an appropriate value. .Sh SEE ALSO -.Xr blacklistd.conf 5 , -.Xr blacklistd 8 +.Xr blocklistd.conf 5 , +.Xr blocklistd 8 .Sh AUTHORS .An Christos Zoulas diff --git a/contrib/blocklist/lib/shlib_version b/contrib/blocklist/lib/shlib_version --- a/contrib/blocklist/lib/shlib_version +++ b/contrib/blocklist/lib/shlib_version @@ -1,2 +1,2 @@ major=0 -minor=0 +minor=1 diff --git a/contrib/blocklist/libexec/Makefile b/contrib/blocklist/libexec/Makefile --- a/contrib/blocklist/libexec/Makefile +++ b/contrib/blocklist/libexec/Makefile @@ -1,6 +1,6 @@ -# $NetBSD: Makefile,v 1.1 2015/01/22 17:49:41 christos Exp $ +# $NetBSD: Makefile,v 1.1.1.1 2020/06/15 01:52:53 christos Exp $ -SCRIPTS= blacklistd-helper +SCRIPTS= blocklistd-helper SCRIPTSDIR= /libexec .include diff --git a/contrib/blocklist/libexec/blacklistd-helper b/contrib/blocklist/libexec/blacklistd-helper deleted file mode 100644 --- a/contrib/blocklist/libexec/blacklistd-helper +++ /dev/null @@ -1,134 +0,0 @@ -#!/bin/sh -#echo "run $@" 1>&2 -#set -x -# $1 command -# $2 rulename -# $3 protocol -# $4 address -# $5 mask -# $6 port -# $7 id - -pf= -if [ -f "/etc/ipfw-blacklist.rc" ]; then - pf="ipfw" - . /etc/ipfw-blacklist.rc - ipfw_offset=${ipfw_offset:-2000} -fi - -if [ -z "$pf" ]; then - for f in npf pf ipf; do - if [ -f "/etc/$f.conf" ]; then - pf="$f" - break - fi - done -fi - -if [ -z "$pf" ]; then - echo "$0: Unsupported packet filter" 1>&2 - exit 1 -fi - -if [ -n "$3" ]; then - proto="proto $3" -fi - -if [ -n "$6" ]; then - port="port $6" -fi - -addr="$4" -mask="$5" -case "$4" in -::ffff:*.*.*.*) - if [ "$5" = 128 ]; then - mask=32 - addr=${4#::ffff:} - fi;; -esac - -case "$1" in -add) - case "$pf" in - ipf) - /sbin/ipfstat -io | /sbin/ipf -I -f - >/dev/null 2>&1 - echo block in quick $proto from $addr/$mask to \ - any port=$6 head port$6 | \ - /sbin/ipf -I -f - -s >/dev/null 2>&1 && echo OK - ;; - ipfw) - # use $ipfw_offset+$port for rule number - rule=$(($ipfw_offset + $6)) - tname="port$6" - /sbin/ipfw table $tname create type addr 2>/dev/null - /sbin/ipfw -q table $tname add "$addr/$mask" - # if rule number $rule does not already exist, create it - /sbin/ipfw show $rule >/dev/null 2>&1 || \ - /sbin/ipfw add $rule drop $3 from \ - table"("$tname")" to any dst-port $6 >/dev/null && \ - echo OK - ;; - npf) - /sbin/npfctl rule "$2" add block in final $proto from \ - "$addr/$mask" to any $port - ;; - pf) - # if the filtering rule does not exist, create it - /sbin/pfctl -a "$2/$6" -sr 2>/dev/null | \ - grep -q "" || \ - echo "block in quick $proto from to any $port" | \ - /sbin/pfctl -a "$2/$6" -f - - # insert $ip/$mask into per-protocol/port anchored table - /sbin/pfctl -qa "$2/$6" -t "port$6" -T add "$addr/$mask" && \ - /sbin/pfctl -qk "$addr" && echo OK - ;; - esac - ;; -rem) - case "$pf" in - ipf) - /sbin/ipfstat -io | /sbin/ipf -I -f - >/dev/null 2>&1 - echo block in quick $proto from $addr/$mask to \ - any port=$6 head port$6 | \ - /sbin/ipf -I -r -f - -s >/dev/null 2>&1 && echo OK - ;; - ipfw) - /sbin/ipfw table "port$6" delete "$addr/$mask" 2>/dev/null && \ - echo OK - ;; - npf) - /sbin/npfctl rule "$2" rem-id "$7" - ;; - pf) - /sbin/pfctl -qa "$2/$6" -t "port$6" -T delete "$addr/$mask" && \ - echo OK - ;; - esac - ;; -flush) - case "$pf" in - ipf) - /sbin/ipf -Z -I -Fi -s > /dev/null && echo OK - ;; - ipfw) - /sbin/ipfw table "port$6" flush 2>/dev/null && echo OK - ;; - npf) - /sbin/npfctl rule "$2" flush - ;; - pf) - # dynamically determine which anchors exist - for anchor in $(/sbin/pfctl -a "$2" -s Anchors); do - /sbin/pfctl -a $anchor -t "port${anchor##*/}" -T flush - /sbin/pfctl -a $anchor -F rules - done - echo OK - ;; - esac - ;; -*) - echo "$0: Unknown command '$1'" 1>&2 - exit 1 - ;; -esac diff --git a/contrib/blocklist/libexec/blocklistd-helper b/contrib/blocklist/libexec/blocklistd-helper new file mode 100755 --- /dev/null +++ b/contrib/blocklist/libexec/blocklistd-helper @@ -0,0 +1,272 @@ +#!/bin/sh +#echo "run $@" 1>&2 +#set -x +# $1 command +# $2 rulename +# $3 protocol +# $4 address +# $5 mask +# $6 port +# $7 id + +pf= +if [ -f "/etc/ipfw-blocklist.rc" ]; then + pf="ipfw" + . /etc/ipfw-blocklist.rc + ipfw_offset=${ipfw_offset:-2000} +fi + +if [ -z "$pf" ]; then + for f in npf pf ipfilter ipfw; do + if [ -x /etc/rc.d/$f ]; then + if /etc/rc.d/$f status >/dev/null 2>&1; then + pf="$f" + break + fi + elif [ -f "/etc/$f.conf" ]; then + # xxx assume a config file means it can be enabled -- + # and the first one wins! + pf="$f" + break + fi + done +fi + +if [ -z "$pf" -a -x "/sbin/iptables" ]; then + pf="iptables" +fi + +if [ -z "$pf" ]; then + echo "$0: Unsupported packet filter" 1>&2 + exit 1 +fi + +flags= +if [ -n "$3" ]; then + raw_proto="$3" + proto="proto $3" + if [ $3 = "tcp" ]; then + flags="flags S/SAFR" + fi +fi + +if [ -n "$6" ]; then + raw_port="$6" + port="port $6" +fi + +addr="$4" +mask="$5" +case "$4" in +::ffff:*.*.*.*) + if [ "$5" = 128 ]; then + mask=32 + addr=${4#::ffff:} + fi;; +esac + +case "$1" in +add) + case "$pf" in + ipfilter) + # N.B.: If you reload /etc/ipf.conf then you need to stop and + # restart blocklistd (and make sure blocklistd_flags="-r"). + # This should normally already be implemented in + # /etc/rc.d/ipfilter, but if then not add the following lines to + # the end of the ipfilter_reload() function: + # + # if checkyesnox blocklistd; then + # /etc/rc.d/blocklistd restart + # fi + # + # XXX we assume the following rule is present in /etc/ipf.conf: + # (should we check? -- it probably cannot be added dynamically) + # + # block in proto tcp/udp from any to any head blocklistd + # + # where "blocklistd" is the default rulename (i.e. "$2") + # + # This rule can come before any rule that logs connections, + # etc., and should be followed by final rules such as: + # + # # log all as-yet unblocked incoming TCP connection + # # attempts + # log in proto tcp from any to any flags S/SAFR + # # last "pass" match wins for all non-blocked packets + # pass in all + # pass out all + # + # I.e. a "pass" rule which will be the final match and override + # the "block". This way the rules added by blocklistd will + # actually block packets, and prevent logging of them as + # connections, because they include the "quick" flag. + # + # N.b.: $port is not included/used in rules -- abusers are cut + # off completely from all services! + # + # Note RST packets are not returned for blocked SYN packets of + # active attacks, so the port will not appear to be closed. + # This will probably give away the fact that a firewall has been + # triggered to block connections, but it prevents generating + # extra outbound traffic, and it may also slow down the attacker + # somewhat. + # + # Note also that we don't block all packets, just new attempts + # to open connections (see $flags above). This allows us to do + # counterespionage against the attacker (or continue to make use + # of any other services that might be on the same subnet as the + # supposed attacker). However it does not kill any active + # connections -- we rely on the reporting daemon to do its own + # protection and cleanup. + # + # N.B.: The rule generated here must exactly match the + # corresponding rule generated for the "rem" command below! + # + echo block in log quick $proto \ + from $addr/$mask to any $flags group $2 | \ + /sbin/ipf -A -f - >/dev/null 2>&1 && echo OK + ;; + + ipfw) + # use $ipfw_offset+$port for rule number + rule=$(($ipfw_offset + $6)) + tname="port$6" + /sbin/ipfw table $tname create type addr 2>/dev/null + /sbin/ipfw -q table $tname add "$addr/$mask" + # if rule number $rule does not already exist, create it + /sbin/ipfw show $rule >/dev/null 2>&1 || \ + /sbin/ipfw add $rule drop $3 from \ + table"("$tname")" to any dst-port $6 >/dev/null && \ + echo OK + ;; + + iptables) + if ! /sbin/iptables --list "$2" >/dev/null 2>&1; then + /sbin/iptables --new-chain "$2" + fi + /sbin/iptables --append INPUT --proto "$raw_proto" \ + --dport "$raw_port" --jump "$2" + /sbin/iptables --append "$2" --proto "$raw_proto" \ + --source "$addr/$mask" --dport "$raw_port" --jump DROP + echo OK + ;; + + npf) + /sbin/npfctl rule "$2" add block in final $proto from \ + "$addr/$mask" to any $port + ;; + + pf) + # if the filtering rule does not exist, create it + /sbin/pfctl -a "$2/$6" -sr 2>/dev/null | \ + grep -q "" || \ + echo "block in quick $proto from to any $port" | \ + /sbin/pfctl -a "$2/$6" -f - + # insert $ip/$mask into per-protocol/port anchored table + /sbin/pfctl -qa "$2/$6" -t "port$6" -T add "$addr/$mask" && \ + /sbin/pfctl -qk "$addr" && echo OK + ;; + + esac + ;; +rem) + case "$pf" in + ipfilter) + # N.B.: The rule generated here must exactly match the + # corresponding rule generated for the "add" command above! + # + echo block in log quick $proto \ + from $addr/$mask to any $flags group $2 | \ + /sbin/ipf -A -r -f - >/dev/null 2>&1 && echo OK + ;; + + ipfw) + /sbin/ipfw table "port$6" delete "$addr/$mask" 2>/dev/null && \ + echo OK + ;; + + iptables) + if /sbin/iptables --list "$2" >/dev/null 2>&1; then + /sbin/iptables --delete "$2" --proto "$raw_proto" \ + --source "$addr/$mask" --dport "$raw_port" \ + --jump DROP + fi + echo OK + ;; + + npf) + /sbin/npfctl rule "$2" rem-id "$7" + ;; + + pf) + /sbin/pfctl -qa "$2/$6" -t "port$6" -T delete "$addr/$mask" && \ + echo OK + ;; + + esac + ;; +flush) + case "$pf" in + ipfilter) + # + # N.B. WARNING: This is obviously not reentrant! + # + # First we flush all the rules from the inactive set, then we + # reload the ones that do not belong to the group "$2", and + # finally we swap the active and inactive rule sets. + # + /sbin/ipf -I -F a + # + # "ipf -I -F a" also flushes active accounting rules! + # + # Note that accounting rule groups are unique to accounting + # rules and have nothing to do with filter rules, though of + # course theoretically one could use the same group name for + # them too. + # + # In theory anyone using any such accounting rules should have a + # wrapper /etc/rc.conf.d/blocklistd script (and corresponding + # /etc/rc.conf.d/ipfilter script) that will record and + # consolidate the values accumulated by such accounting rules + # before they are flushed, since otherwise their counts will be + # lost forever. + # + /usr/sbin/ipfstat -io | fgrep -v "group $2" | \ + /sbin/ipf -I -f - >/dev/null 2>&1 + # + # This MUST be done last and separately as "-s" is executed + # _while_ the command arguments are being processed! + # + /sbin/ipf -s && echo OK + ;; + + ipfw) + /sbin/ipfw table "port$6" flush 2>/dev/null && echo OK + ;; + + iptables) + if /sbin/iptables --list "$2" >/dev/null 2>&1; then + /sbin/iptables --flush "$2" + fi + echo OK + ;; + + npf) + /sbin/npfctl rule "$2" flush + ;; + + pf) + # dynamically determine which anchors exist + for anchor in $(/sbin/pfctl -a "$2" -s Anchors 2> /dev/null); do + /sbin/pfctl -a "$anchor" -t "port${anchor##*/}" -T flush + /sbin/pfctl -a "$anchor" -F rules + done + echo OK + ;; + esac + ;; +*) + echo "$0: Unknown command '$1'" 1>&2 + exit 1 + ;; +esac diff --git a/contrib/blocklist/port/Makefile.am b/contrib/blocklist/port/Makefile.am --- a/contrib/blocklist/port/Makefile.am +++ b/contrib/blocklist/port/Makefile.am @@ -1,25 +1,39 @@ # ACLOCAL_AMFLAGS = -I m4 -lib_LTLIBRARIES = libblacklist.la -include_HEADERS = ../include/blacklist.h +lib_LTLIBRARIES = libblocklist.la +include_HEADERS = $(srcdir)/../include/blocklist.h -bin_PROGRAMS = blacklistd blacklistctl srvtest cltest +exampledir = $(datarootdir)/examples +example_DATA = $(srcdir)/../etc/blocklistd.conf $(srcdir)/../etc/npf.conf $(srcdir)/../etc/ipf.conf -VPATH = ../bin:../lib:../test:../include +sbin_PROGRAMS = blocklistd blocklistctl +noinst_PROGRAMS = srvtest cltest +libexec_SCRIPTS = $(srcdir)/../libexec/blocklistd-helper -AM_CPPFLAGS = -I../include -DDOT="." +man5_MANS = $(srcdir)/../bin/blocklistd.conf.5 +man8_MANS = $(srcdir)/../bin/blocklistd.8 $(srcdir)/../bin/blocklistctl.8 + +VPATH = $(srcdir)/../port:$(srcdir)/../bin:$(srcdir)/../lib:$(srcdir)/../test:$(srcdir)/../include + +AM_CPPFLAGS = -I$(srcdir)/../include -DDOT="." +AM_CPPFLAGS += -D_PATH_BLCONF=\"$(sysconfdir)/blocklistd.conf\" +AM_CPPFLAGS += -D_PATH_BLCONTROL=\"$(libexecdir)/blocklistd-helper\" +AM_CPPFLAGS += -D_PATH_BLSOCK=\"$(runstatedir)/blocklistd.sock\" +AM_CPPFLAGS += -D_PATH_BLSTATE=\"$(localstatedir)/db/blocklistd.db\" +AM_CPPFLAGS += -std=c99 -D_POSIX_C_SOURCE=200809L -D__EXTENSIONS__ +AM_CPPFLAGS += -D__BSD_VISIBLE=1 AM_CFLAGS = @WARNINGS@ -libblacklist_la_SOURCES = bl.c blacklist.c -libblacklist_la_LDFLAGS = -no-undefined -version-info 0:0:0 -libblacklist_la_LIBADD = $(LTLIBOBJS) +libblocklist_la_SOURCES = bl.c blocklist.c +libblocklist_la_LDFLAGS = -no-undefined -version-info 0:0:0 +libblocklist_la_LIBADD = $(LTLIBOBJS) SRCS = internal.c support.c run.c conf.c state.c -blacklistd_SOURCES = blacklistd.c ${SRCS} -blacklistd_LDADD = libblacklist.la -blacklistctl_SOURCES = blacklistctl.c ${SRCS} -blacklistctl_LDADD = libblacklist.la +blocklistd_SOURCES = blocklistd.c ${SRCS} +blocklistd_LDADD = libblocklist.la +blocklistctl_SOURCES = blocklistctl.c ${SRCS} +blocklistctl_LDADD = libblocklist.la srvtest_SOURCES = srvtest.c ${SRCS} -srvtest_LDADD = libblacklist.la +srvtest_LDADD = libblocklist.la cltest_SOURCES = cltest.c ${SRCS} -cltest_LDADD = libblacklist.la +cltest_LDADD = libblocklist.la diff --git a/contrib/blocklist/port/_strtoi.h b/contrib/blocklist/port/_strtoi.h --- a/contrib/blocklist/port/_strtoi.h +++ b/contrib/blocklist/port/_strtoi.h @@ -1,4 +1,4 @@ -/* $NetBSD: _strtoi.h,v 1.1 2015/01/22 02:15:59 christos Exp $ */ +/* $NetBSD: _strtoi.h,v 1.1.1.1 2020/06/15 01:52:53 christos Exp $ */ /*- * Copyright (c) 1990, 1993 diff --git a/contrib/blocklist/port/configure.ac b/contrib/blocklist/port/configure.ac --- a/contrib/blocklist/port/configure.ac +++ b/contrib/blocklist/port/configure.ac @@ -1,5 +1,5 @@ dnl Process this file with autoconf to produce a configure script. -AC_INIT([blacklistd],[0.1],[christos@netbsd.com]) +AC_INIT([blocklistd],[0.1],[christos@netbsd.com]) AM_INIT_AUTOMAKE([subdir-objects foreign]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) @@ -7,9 +7,10 @@ AC_CONFIG_MACRO_DIR([m4]) AC_SUBST(WARNINGS) +AC_SUBST(LINK_NTOA) dnl Checks for programs. -AC_PROG_CC_STDC +AC_PROG_CC AC_USE_SYSTEM_EXTENSIONS AM_PROG_CC_C_O AC_C_BIGENDIAN @@ -18,18 +19,19 @@ LT_INIT([disable-static pic-only]) gl_VISIBILITY dnl Checks for headers -AC_HEADER_STDC AC_HEADER_MAJOR AC_HEADER_SYS_WAIT AC_CHECK_HEADERS(stdint.h fcntl.h stdint.h inttypes.h unistd.h) AC_CHECK_HEADERS(sys/un.h sys/socket.h limits.h) AC_CHECK_HEADERS(arpa/inet.h getopt.h err.h) AC_CHECK_HEADERS(sys/types.h util.h sys/time.h time.h) -AC_CHECK_HEADERS(netatalk/at.h net/if_dl.h db.h db_185.h) +AC_CHECK_HEADERS(netatalk/at.h db.h db_185.h) +AC_CHECK_HEADERS(sys/cdefs.h) AC_CHECK_LIB(rt, clock_gettime) AC_CHECK_LIB(db, __db185_open) AC_CHECK_LIB(util, pidfile) AC_CHECK_LIB(util, sockaddr_snprintf) +AC_SEARCH_LIBS(__xnet_connect, socket) AH_BOTTOM([ #ifndef __NetBSD__ @@ -82,7 +84,7 @@ AC_CHECK_FUNCS(strerror) dnl Provide implementation of some required functions if necessary -AC_REPLACE_FUNCS(strtoi sockaddr_snprintf popenve clock_gettime strlcpy strlcat getprogname fparseln fgetln pidfile) +AC_REPLACE_FUNCS(strtoi sockaddr_snprintf popenve clock_gettime strlcpy strlcat getprogname fparseln fgetln pidfile vsyslog_r) dnl See if we are cross-compiling AM_CONDITIONAL(IS_CROSS_COMPILE, test "$cross_compiling" = yes) diff --git a/contrib/blocklist/port/fgetln.c b/contrib/blocklist/port/fgetln.c --- a/contrib/blocklist/port/fgetln.c +++ b/contrib/blocklist/port/fgetln.c @@ -1,4 +1,4 @@ -/* $NetBSD: fgetln.c,v 1.1 2015/01/22 03:48:07 christos Exp $ */ +/* $NetBSD: fgetln.c,v 1.1.1.1 2020/06/15 01:52:54 christos Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. diff --git a/contrib/blocklist/port/fparseln.c b/contrib/blocklist/port/fparseln.c --- a/contrib/blocklist/port/fparseln.c +++ b/contrib/blocklist/port/fparseln.c @@ -1,4 +1,4 @@ -/* $NetBSD: fparseln.c,v 1.1 2015/01/22 03:48:07 christos Exp $ */ +/* $NetBSD: fparseln.c,v 1.2 2025/02/11 17:48:30 christos Exp $ */ /* * Copyright (c) 1997 Christos Zoulas. All rights reserved. @@ -27,9 +27,11 @@ #include "config.h" #endif +#ifdef HAVE_SYS_CDEFS_H #include +#endif #if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: fparseln.c,v 1.1 2015/01/22 03:48:07 christos Exp $"); +__RCSID("$NetBSD: fparseln.c,v 1.2 2025/02/11 17:48:30 christos Exp $"); #endif /* LIBC_SCCS and not lint */ #include diff --git a/contrib/blocklist/port/pidfile.c b/contrib/blocklist/port/pidfile.c --- a/contrib/blocklist/port/pidfile.c +++ b/contrib/blocklist/port/pidfile.c @@ -1,4 +1,4 @@ -/* $NetBSD: pidfile.c,v 1.2 2016/04/05 12:28:57 christos Exp $ */ +/* $NetBSD: pidfile.c,v 1.2 2025/02/11 17:48:30 christos Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -32,9 +32,11 @@ #include "config.h" #endif +#ifdef HAVE_SYS_CDEFS_H #include +#endif #if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: pidfile.c,v 1.2 2016/04/05 12:28:57 christos Exp $"); +__RCSID("$NetBSD: pidfile.c,v 1.2 2025/02/11 17:48:30 christos Exp $"); #endif #include diff --git a/contrib/blocklist/port/popenve.c b/contrib/blocklist/port/popenve.c --- a/contrib/blocklist/port/popenve.c +++ b/contrib/blocklist/port/popenve.c @@ -1,4 +1,4 @@ -/* $NetBSD: popenve.c,v 1.2 2015/01/22 03:10:50 christos Exp $ */ +/* $NetBSD: popenve.c,v 1.2 2025/02/11 17:48:30 christos Exp $ */ /* * Copyright (c) 1988, 1993 @@ -36,12 +36,14 @@ #include "config.h" #endif +#ifdef HAVE_SYS_CDEFS_H #include +#endif #if defined(LIBC_SCCS) && !defined(lint) #if 0 static char sccsid[] = "@(#)popen.c 8.3 (Berkeley) 5/3/95"; #else -__RCSID("$NetBSD: popenve.c,v 1.2 2015/01/22 03:10:50 christos Exp $"); +__RCSID("$NetBSD: popenve.c,v 1.2 2025/02/11 17:48:30 christos Exp $"); #endif #endif /* LIBC_SCCS and not lint */ diff --git a/contrib/blocklist/port/port.h b/contrib/blocklist/port/port.h --- a/contrib/blocklist/port/port.h +++ b/contrib/blocklist/port/port.h @@ -1,6 +1,7 @@ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif +#include #include #include #include @@ -15,6 +16,22 @@ #define __dead __attribute__((__noreturn__)) #endif +#ifndef __BEGIN_DECLS +#define __BEGIN_DECLS +#endif + +#ifndef __END_DECLS +#define __END_DECLS +#endif + +#ifndef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#ifndef MAX +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + #ifndef __RCSID #define __RCSID(a) #endif @@ -27,6 +44,10 @@ #define __arraycount(a) (sizeof(a) / sizeof(a[0])) #endif +#ifndef __STRING +#define __STRING(x) #x +#endif + #ifndef HAVE_STRLCPY size_t strlcpy(char *, const char *, size_t); #endif @@ -78,9 +99,10 @@ #define CLOCK_REALTIME 0 #endif -#if !defined(__FreeBSD__) -#define _PATH_BLCONF "conf" -#define _PATH_BLCONTROL "control" -#define _PATH_BLSOCK "blacklistd.sock" -#define _PATH_BLSTATE "blacklistd.db" +#ifndef HAVE_VSYSLOG_R +#define SYSLOG_DATA_INIT { 0 } +struct syslog_data { + int dummy; +}; +void vsyslog_r(int, struct syslog_data *, const char *, va_list); #endif diff --git a/contrib/blocklist/port/sockaddr_snprintf.c b/contrib/blocklist/port/sockaddr_snprintf.c --- a/contrib/blocklist/port/sockaddr_snprintf.c +++ b/contrib/blocklist/port/sockaddr_snprintf.c @@ -1,4 +1,4 @@ -/* $NetBSD: sockaddr_snprintf.c,v 1.11 2016/06/01 22:57:51 christos Exp $ */ +/* $NetBSD: sockaddr_snprintf.c,v 1.2 2025/02/11 17:48:30 christos Exp $ */ /*- * Copyright (c) 2004 The NetBSD Foundation, Inc. @@ -32,9 +32,11 @@ #include "config.h" #endif +#ifdef HAVE_SYS_CDEFS_H #include +#endif #if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: sockaddr_snprintf.c,v 1.11 2016/06/01 22:57:51 christos Exp $"); +__RCSID("$NetBSD: sockaddr_snprintf.c,v 1.2 2025/02/11 17:48:30 christos Exp $"); #endif /* LIBC_SCCS and not lint */ #include diff --git a/contrib/blocklist/port/strlcat.c b/contrib/blocklist/port/strlcat.c --- a/contrib/blocklist/port/strlcat.c +++ b/contrib/blocklist/port/strlcat.c @@ -1,4 +1,4 @@ -/* $NetBSD: strlcat.c,v 1.2 2015/01/22 03:48:07 christos Exp $ */ +/* $NetBSD: strlcat.c,v 1.2 2025/02/11 17:48:30 christos Exp $ */ /* $OpenBSD: strlcat.c,v 1.10 2003/04/12 21:56:39 millert Exp $ */ /* @@ -22,9 +22,12 @@ #include "config.h" #endif +#ifdef HAVE_SYS_CDEFS_H #include +#endif + #if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: strlcat.c,v 1.2 2015/01/22 03:48:07 christos Exp $"); +__RCSID("$NetBSD: strlcat.c,v 1.2 2025/02/11 17:48:30 christos Exp $"); #endif /* LIBC_SCCS and not lint */ #ifdef _LIBC diff --git a/contrib/blocklist/port/strlcpy.c b/contrib/blocklist/port/strlcpy.c --- a/contrib/blocklist/port/strlcpy.c +++ b/contrib/blocklist/port/strlcpy.c @@ -1,4 +1,4 @@ -/* $NetBSD: strlcpy.c,v 1.2 2015/01/22 03:48:07 christos Exp $ */ +/* $NetBSD: strlcpy.c,v 1.2 2025/02/11 17:48:30 christos Exp $ */ /* $OpenBSD: strlcpy.c,v 1.7 2003/04/12 21:56:39 millert Exp $ */ /* @@ -22,9 +22,12 @@ #include "config.h" #endif +#ifdef HAVE_SYS_CDEFS_H #include +#endif + #if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: strlcpy.c,v 1.2 2015/01/22 03:48:07 christos Exp $"); +__RCSID("$NetBSD: strlcpy.c,v 1.2 2025/02/11 17:48:30 christos Exp $"); #endif /* LIBC_SCCS and not lint */ #ifdef _LIBC diff --git a/contrib/blocklist/port/strtoi.c b/contrib/blocklist/port/strtoi.c --- a/contrib/blocklist/port/strtoi.c +++ b/contrib/blocklist/port/strtoi.c @@ -1,4 +1,4 @@ -/* $NetBSD: strtoi.c,v 1.3 2015/01/22 03:10:50 christos Exp $ */ +/* $NetBSD: strtoi.c,v 1.2 2025/02/11 17:48:31 christos Exp $ */ /*- * Copyright (c) 2005 The DragonFly Project. All rights reserved. @@ -33,8 +33,10 @@ #include "config.h" #endif +#ifdef HAVE_SYS_CDEFS_H #include -__RCSID("$NetBSD: strtoi.c,v 1.3 2015/01/22 03:10:50 christos Exp $"); +#endif +__RCSID("$NetBSD: strtoi.c,v 1.2 2025/02/11 17:48:31 christos Exp $"); #if defined(_KERNEL) #include diff --git a/contrib/blocklist/port/vsyslog_r.c b/contrib/blocklist/port/vsyslog_r.c new file mode 100644 --- /dev/null +++ b/contrib/blocklist/port/vsyslog_r.c @@ -0,0 +1,13 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +void +vsyslog_r(int priority, struct syslog_data *sd __unused, const char *fmt, va_list ap) +{ + vsyslog(priority, fmt, ap); +} + diff --git a/contrib/blocklist/test/Makefile b/contrib/blocklist/test/Makefile --- a/contrib/blocklist/test/Makefile +++ b/contrib/blocklist/test/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.3 2015/05/30 22:40:38 christos Exp $ +# $NetBSD: Makefile,v 1.1.1.1 2020/06/15 01:52:54 christos Exp $ MKMAN=no diff --git a/contrib/blocklist/test/cltest.c b/contrib/blocklist/test/cltest.c --- a/contrib/blocklist/test/cltest.c +++ b/contrib/blocklist/test/cltest.c @@ -1,4 +1,4 @@ -/* $NetBSD: cltest.c,v 1.6 2015/01/22 05:44:28 christos Exp $ */ +/* $NetBSD: cltest.c,v 1.2 2025/02/11 17:48:31 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -32,8 +32,10 @@ #include "config.h" #endif +#ifdef HAVE_SYS_CDEFS_H #include -__RCSID("$NetBSD: cltest.c,v 1.6 2015/01/22 05:44:28 christos Exp $"); +#endif +__RCSID("$NetBSD: cltest.c,v 1.2 2025/02/11 17:48:31 christos Exp $"); #include #include diff --git a/contrib/blocklist/test/srvtest.c b/contrib/blocklist/test/srvtest.c --- a/contrib/blocklist/test/srvtest.c +++ b/contrib/blocklist/test/srvtest.c @@ -1,4 +1,4 @@ -/* $NetBSD: srvtest.c,v 1.10 2015/05/30 22:40:38 christos Exp $ */ +/* $NetBSD: srvtest.c,v 1.2 2025/02/11 17:43:16 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -32,8 +32,10 @@ #include "config.h" #endif +#ifdef HAVE_SYS_CDEFS_H #include -__RCSID("$NetBSD: srvtest.c,v 1.10 2015/05/30 22:40:38 christos Exp $"); +#endif +__RCSID("$NetBSD: srvtest.c,v 1.2 2025/02/11 17:43:16 christos Exp $"); #include #include @@ -48,7 +50,7 @@ #include #include -#include "blacklist.h" +#include "blocklist.h" #ifdef BLDEBUG #include "bl.h" static void *b; @@ -71,9 +73,9 @@ buffer[sizeof(buffer) - 1] = '\0'; printf("%s: sending %d %s\n", getprogname(), afd, buffer); #ifdef BLDEBUG - blacklist_r(b, 1, afd, buffer); + blocklist_r(b, 1, afd, buffer); #else - blacklist(1, afd, buffer); + blocklist(1, afd, buffer); #endif exit(0); } @@ -95,7 +97,7 @@ err(1, "recvfrom"); buffer[sizeof(buffer) - 1] = '\0'; printf("%s: sending %d %s\n", getprogname(), afd, buffer); - blacklist_sa(1, afd, (void *)&ss, slen, buffer); + blocklist_sa(1, afd, (void *)&ss, slen, buffer); exit(0); } static int @@ -167,7 +169,11 @@ usage(int c) { warnx("Unknown option `%c'", (char)c); - fprintf(stderr, "Usage: %s [-u] [-p ]\n", getprogname()); + fprintf(stderr, "Usage: %s [-u] [-p ]" +#ifdef BLDEBUG + " [-s ]" +#endif + "\n", getprogname()); exit(EXIT_FAILURE); } @@ -182,14 +188,16 @@ struct pollfd pfd[NUMFD]; int type = SOCK_STREAM, c; in_port_t port = 6161; - - signal(SIGCHLD, SIG_IGN); - #ifdef BLDEBUG - b = bl_create(false, "blsock", vsyslog); + char *sockpath = "blsock"; + const char *optstr = "up:s:"; +#else + const char *optstr = "up:"; #endif - while ((c = getopt(argc, argv, "up:")) != -1) + signal(SIGCHLD, SIG_IGN); + + while ((c = getopt(argc, argv, optstr)) != -1) switch (c) { case 'u': type = SOCK_DGRAM; @@ -197,10 +205,20 @@ case 'p': port = (in_port_t)atoi(optarg); break; +#ifdef BLDEBUG + case 's': + sockpath = (char *)optarg; + break; +#endif default: usage(c); } +#ifdef BLDEBUG + b = bl_create(false, sockpath, vsyslog_r); +#endif + + pfd[0].fd = cr(AF_INET, type, port); pfd[0].events = POLLIN; #if NUMFD > 1