diff --git a/UPDATING b/UPDATING index 4c4e8033a6d..277e70c7bd6 100644 --- a/UPDATING +++ b/UPDATING @@ -1,5 +1,21 @@ Updating Information for MidnightBSD users. +20260922: + blacklistd has been renamed to blocklistd, following upstream. + The library is now libblocklist(3) with blocklist_*() functions, + the daemon and control program are blocklistd(8) and + blocklistctl(8), the configuration file is /etc/blocklistd.conf, + the rc.conf knobs are blocklistd_enable and blocklistd_flags, and + the sshd_config option is UseBlocklist. The build options are + WITH[OUT]_BLOCKLIST and WITH[OUT]_BLOCKLIST_SUPPORT. + + The old names keep working for now: libblacklist, blacklistd, + blacklistctl, /etc/blacklistd.conf, the blacklistd rc script and + the old build options are all still provided, but they warn on + use and will be removed in a future release. Move your + configuration to the new names. Note that the last column of the + configuration file, formerly "disable", is now "duration". + 20260922: tcsh 6.24.16 (from 6.21.00). Adds $'...' strings with \x, \u, \U and \c escapes, the :Q modifier, $?<, jobs -Z, CLICOLOR_FORCE and diff --git a/contrib/blacklist/TODO b/contrib/blacklist/TODO deleted file mode 100644 index 9925020d54b..00000000000 --- a/contrib/blacklist/TODO +++ /dev/null @@ -1,21 +0,0 @@ -# $NetBSD: TODO,v 1.7 2015/01/23 21:34:01 christos Exp $ - -- don't poll periodically, find the next timeout -- use the socket also for commands? Or separate socket? -- add functionality to the control program. Should it change the database - directly, or talk to the daemon to have it do it? -- perhaps handle interfaces too instead of addresses for dynamic ip? - ? What to do with multiple addresses? -- perhaps rate limit against DoS -- perhaps instead of scanning the list have a sparse map by port? -- do we want to use libnpf directly for efficiency? -- add more daemons ftpd? -- do we care about the db state becoming too large? -- instead of a yes = bump one, no = return to 0 interface, do we want - to have something more flexible like? - +n - -n - block - unblock -- do we need an api in blacklistctl to perform maintenance -- fix the blacklistctl output to be more user friendly diff --git a/contrib/blacklist/bin/Makefile b/contrib/blacklist/bin/Makefile deleted file mode 100644 index 280c72fd3af..00000000000 --- a/contrib/blacklist/bin/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -# $NetBSD: Makefile,v 1.11 2015/01/27 19:40:36 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 -DBG=-g - -LDADD+=-lutil -DPADD+=${LIBUTIL} - -.include diff --git a/contrib/blacklist/diff/named.diff b/contrib/blacklist/diff/named.diff deleted file mode 100644 index fcd97ba7ec1..00000000000 --- a/contrib/blacklist/diff/named.diff +++ /dev/null @@ -1,216 +0,0 @@ ---- /dev/null 2015-01-22 01:48:00.000000000 -0500 -+++ dist/bin/named/pfilter.c 2015-01-22 01:35:16.000000000 -0500 -@@ -0,0 +1,42 @@ -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "pfilter.h" -+ -+static struct blacklist *blstate; -+ -+void -+pfilter_open(void) -+{ -+ if (blstate == NULL) -+ blstate = blacklist_open(); -+} -+ -+#define TCP_CLIENT(c) (((c)->attributes & NS_CLIENTATTR_TCP) != 0) -+ -+void -+pfilter_notify(isc_result_t res, ns_client_t *client, const char *msg) -+{ -+ isc_socket_t *socket; -+ -+ pfilter_open(); -+ -+ if (TCP_CLIENT(client)) -+ socket = client->tcpsocket; -+ else { -+ socket = client->udpsocket; -+ if (!client->peeraddr_valid) -+ return; -+ } -+ if (socket == NULL) -+ return; -+ blacklist_sa_r(blstate, -+ res != ISC_R_SUCCESS, isc_socket_getfd(socket), -+ &client->peeraddr.type.sa, client->peeraddr.length, msg); -+} ---- /dev/null 2015-01-22 01:48:00.000000000 -0500 -+++ dist/bin/named/pfilter.h 2015-01-22 01:16:56.000000000 -0500 -@@ -0,0 +1,2 @@ -+void pfilter_open(void); -+void pfilter_notify(isc_result_t, ns_client_t *, const char *); -Index: bin/named/Makefile -=================================================================== -RCS file: /cvsroot/src/external/bsd/bind/bin/named/Makefile,v -retrieving revision 1.8 -diff -u -u -r1.8 Makefile ---- bin/named/Makefile 31 Dec 2013 20:23:12 -0000 1.8 -+++ bin/named/Makefile 23 Jan 2015 21:37:09 -0000 -@@ -33,7 +33,9 @@ - lwaddr.c lwdclient.c lwderror.c \ - lwdgabn.c lwdgnba.c lwdgrbn.c lwdnoop.c lwresd.c lwsearch.c \ - main.c notify.c query.c server.c sortlist.c statschannel.c \ -- tkeyconf.c tsigconf.c \ -+ pfilter.c tkeyconf.c tsigconf.c \ - update.c xfrout.c zoneconf.c ${SRCS_UNIX} - -+LDADD+=-lblacklist -+DPADD+=${LIBBLACKLIST} - .include -Index: dist/bin/named/client.c -=================================================================== -RCS file: /cvsroot/src/external/bsd/bind/dist/bin/named/client.c,v -retrieving revision 1.11 -diff -u -u -r1.11 client.c ---- dist/bin/named/client.c 10 Dec 2014 04:37:51 -0000 1.11 -+++ dist/bin/named/client.c 23 Jan 2015 21:37:09 -0000 -@@ -65,6 +65,8 @@ - #include - #include - -+#include "pfilter.h" -+ - /*** - *** Client - ***/ -@@ -3101,6 +3103,7 @@ - result = ns_client_checkaclsilent(client, sockaddr ? &netaddr : NULL, - acl, default_allow); - -+ pfilter_notify(result, client, opname); - if (result == ISC_R_SUCCESS) - ns_client_log(client, DNS_LOGCATEGORY_SECURITY, - NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), -Index: dist/bin/named/main.c -=================================================================== -RCS file: /cvsroot/src/external/bsd/bind/dist/bin/named/main.c,v -retrieving revision 1.15 -diff -u -u -r1.15 main.c ---- dist/bin/named/main.c 10 Dec 2014 04:37:51 -0000 1.15 -+++ dist/bin/named/main.c 23 Jan 2015 21:37:09 -0000 -@@ -83,6 +83,9 @@ - #ifdef HAVE_LIBXML2 - #include - #endif -+ -+#include "pfilter.h" -+ - /* - * Include header files for database drivers here. - */ -@@ -1206,6 +1209,8 @@ - - parse_command_line(argc, argv); - -+ pfilter_open(); -+ - /* - * Warn about common configuration error. - */ -Index: dist/bin/named/query.c -=================================================================== -RCS file: /cvsroot/src/external/bsd/bind/dist/bin/named/query.c,v -retrieving revision 1.17 -diff -u -u -r1.17 query.c ---- dist/bin/named/query.c 10 Dec 2014 04:37:52 -0000 1.17 -+++ dist/bin/named/query.c 23 Jan 2015 21:37:09 -0000 -@@ -65,6 +65,8 @@ - #include - #include - -+#include "pfilter.h" -+ - #if 0 - /* - * It has been recommended that DNS64 be changed to return excluded -@@ -762,6 +764,8 @@ - } - - result = ns_client_checkaclsilent(client, NULL, queryacl, ISC_TRUE); -+ if (result != ISC_R_SUCCESS) -+ pfilter_notify(result, client, "validatezonedb"); - if ((options & DNS_GETDB_NOLOG) == 0) { - char msg[NS_CLIENT_ACLMSGSIZE("query")]; - if (result == ISC_R_SUCCESS) { -@@ -1026,6 +1030,8 @@ - result = ns_client_checkaclsilent(client, NULL, - client->view->cacheacl, - ISC_TRUE); -+ if (result == ISC_R_SUCCESS) -+ pfilter_notify(result, client, "cachedb"); - if (result == ISC_R_SUCCESS) { - /* - * We were allowed by the "allow-query-cache" ACL. -Index: dist/bin/named/update.c -=================================================================== -RCS file: /cvsroot/src/external/bsd/bind/dist/bin/named/update.c,v -retrieving revision 1.9 -diff -u -u -r1.9 update.c ---- dist/bin/named/update.c 10 Dec 2014 04:37:52 -0000 1.9 -+++ dist/bin/named/update.c 23 Jan 2015 21:37:09 -0000 -@@ -59,6 +59,8 @@ - #include - #include - -+#include "pfilter.h" -+ - /*! \file - * \brief - * This module implements dynamic update as in RFC2136. -@@ -307,6 +309,7 @@ - - result = ns_client_checkaclsilent(client, NULL, queryacl, ISC_TRUE); - if (result != ISC_R_SUCCESS) { -+ pfilter_notify(result, client, "queryacl"); - dns_name_format(zonename, namebuf, sizeof(namebuf)); - dns_rdataclass_format(client->view->rdclass, classbuf, - sizeof(classbuf)); -@@ -324,6 +327,7 @@ - sizeof(classbuf)); - - result = DNS_R_REFUSED; -+ pfilter_notify(result, client, "updateacl"); - ns_client_log(client, NS_LOGCATEGORY_UPDATE_SECURITY, - NS_LOGMODULE_UPDATE, ISC_LOG_INFO, - "update '%s/%s' denied", namebuf, classbuf); -@@ -362,6 +366,7 @@ - msg = "disabled"; - } else { - result = ns_client_checkaclsilent(client, NULL, acl, ISC_FALSE); -+ pfilter_notify(result, client, "updateacl"); - if (result == ISC_R_SUCCESS) { - level = ISC_LOG_DEBUG(3); - msg = "approved"; -Index: dist/bin/named/xfrout.c -=================================================================== -RCS file: /cvsroot/src/external/bsd/bind/dist/bin/named/xfrout.c,v -retrieving revision 1.7 -diff -u -u -r1.7 xfrout.c ---- dist/bin/named/xfrout.c 10 Dec 2014 04:37:52 -0000 1.7 -+++ dist/bin/named/xfrout.c 23 Jan 2015 21:37:09 -0000 -@@ -54,6 +54,8 @@ - #include - #include - -+#include "pfilter.h" -+ - /*! \file - * \brief - * Outgoing AXFR and IXFR. -@@ -822,6 +824,7 @@ - &client->peeraddr, - &db); - -+ pfilter_notify(result, client, "zonexfr"); - if (result == ISC_R_NOPERM) { - char _buf1[DNS_NAME_FORMATSIZE]; - char _buf2[DNS_RDATACLASS_FORMATSIZE]; diff --git a/contrib/blacklist/etc/Makefile b/contrib/blacklist/etc/Makefile deleted file mode 100644 index 669528ddca8..00000000000 --- a/contrib/blacklist/etc/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# $NetBSD: Makefile,v 1.3 2015/01/26 00:18:40 christos Exp $ - -SUBDIR=rc.d - -FILESDIR= /usr/share/examples/blacklist -FILESMODE= 644 -FILES= blacklistd.conf npf.conf - -.include -.include diff --git a/contrib/blacklist/etc/rc.d/Makefile b/contrib/blacklist/etc/rc.d/Makefile deleted file mode 100644 index e863d0853a0..00000000000 --- a/contrib/blacklist/etc/rc.d/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# $NetBSD: Makefile,v 1.1 2015/01/22 17:49:41 christos Exp $ - -SCRIPTS=blacklistd -SCRIPTSDIR=/etc/rc.d - -.include diff --git a/contrib/blacklist/lib/Makefile b/contrib/blacklist/lib/Makefile deleted file mode 100644 index 4f1ab7717a9..00000000000 --- a/contrib/blacklist/lib/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# $NetBSD: Makefile,v 1.7 2019/03/08 20:40:05 christos Exp $ - -.include - -USE_SHLIBDIR= yes - -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 - -.include diff --git a/contrib/blacklist/libexec/Makefile b/contrib/blacklist/libexec/Makefile deleted file mode 100644 index 6537080bf46..00000000000 --- a/contrib/blacklist/libexec/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# $NetBSD: Makefile,v 1.1 2015/01/22 17:49:41 christos Exp $ - -SCRIPTS= blacklistd-helper -SCRIPTSDIR= /libexec - -.include diff --git a/contrib/blacklist/port/Makefile.am b/contrib/blacklist/port/Makefile.am deleted file mode 100644 index 43bf6c94b42..00000000000 --- a/contrib/blacklist/port/Makefile.am +++ /dev/null @@ -1,25 +0,0 @@ -# -ACLOCAL_AMFLAGS = -I m4 -lib_LTLIBRARIES = libblacklist.la -include_HEADERS = ../include/blacklist.h - -bin_PROGRAMS = blacklistd blacklistctl srvtest cltest - -VPATH = ../bin:../lib:../test:../include - -AM_CPPFLAGS = -I../include -DDOT="." -AM_CFLAGS = @WARNINGS@ - -libblacklist_la_SOURCES = bl.c blacklist.c -libblacklist_la_LDFLAGS = -no-undefined -version-info 0:0:0 -libblacklist_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 -srvtest_SOURCES = srvtest.c ${SRCS} -srvtest_LDADD = libblacklist.la -cltest_SOURCES = cltest.c ${SRCS} -cltest_LDADD = libblacklist.la diff --git a/contrib/blocklist/MIDNIGHTBSD-upgrade b/contrib/blocklist/MIDNIGHTBSD-upgrade new file mode 100644 index 00000000000..8fe004fdc91 --- /dev/null +++ b/contrib/blocklist/MIDNIGHTBSD-upgrade @@ -0,0 +1,38 @@ +blocklist (formerly blacklist) from https://github.com/zoulasc/blocklist + +Vendor branch: vendor/blocklist, tagged vendor/blocklist/YYYYMMDD after +the upstream commit date. Upstream has no releases; import HEAD. + +To import a new snapshot: + + 1) git clone https://github.com/zoulasc/blocklist.git and note the + commit hash and date. + 2) In this repository: + git fetch HEAD + c=$(git commit-tree FETCH_HEAD^{tree} -p vendor/blocklist \ + -m "Import blocklist YYYY-MM-DD (shorthash)") + git branch -f vendor/blocklist $c + git tag vendor/blocklist/YYYYMMDD $c + 3) On master: + git merge -X subtree=contrib/blocklist vendor/blocklist + 4) Re-run sh midnightbsd-changes.sh in contrib/blocklist and check + that nothing else changed with + git diff vendor/blocklist HEAD:contrib/blocklist + 5) If source files were added or removed, update lib/libblocklist, + usr.sbin/blocklistd and usr.sbin/blocklistctl. + 6) Build world and test sshd(8) and fingerd(8) integration. + +Files that are not upstream: + + bin/blacklistctl.c bin/blacklistd.c bin/old_internal.[ch] + include/blacklist.h include/old_bl.h lib/blacklist.c lib/old_bl.c + bin/blacklistctl.8 bin/blacklistd.8 bin/blacklistd.conf.5 lib/libblacklist.3 + Compatibility sources for the old blacklist names, taken from + FreeBSD. They build lib/libblacklist, usr.sbin/blacklistd and + usr.sbin/blacklistctl so existing configurations keep working + with a warning. + port/config.h + Wrapper that pulls in port/port.h; upstream generates this with + autoconf. + midnightbsd-changes.sh MIDNIGHTBSD-upgrade + This file and the change script. diff --git a/contrib/blacklist/Makefile b/contrib/blocklist/Makefile similarity index 51% rename from contrib/blacklist/Makefile rename to contrib/blocklist/Makefile index da4411d0ca7..899746d0143 100644 --- a/contrib/blacklist/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/blacklist/Makefile.inc b/contrib/blocklist/Makefile.inc similarity index 50% rename from contrib/blacklist/Makefile.inc rename to contrib/blocklist/Makefile.inc index 85c82783cd3..b22d4a80124 100644 --- a/contrib/blacklist/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/blacklist/README b/contrib/blocklist/README similarity index 68% rename from contrib/blacklist/README rename to contrib/blocklist/README index 7da3317a77f..4b34138e01e 100644 --- a/contrib/blacklist/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 @@ Patches to various daemons to add blacklisting capabilitiers are in the 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 @@ Where: 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 @@ ssh stream tcp6 * * 6 60m 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 @@ you can use -d. 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 new file mode 100644 index 00000000000..d67111bd513 --- /dev/null +++ b/contrib/blocklist/TODO @@ -0,0 +1,64 @@ +# $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? +- add functionality to the control program. Should it change the database + directly, or talk to the daemon to have it do it? +- perhaps handle interfaces too instead of addresses for dynamic ip? + ? What to do with multiple addresses? +- perhaps rate limit against DoS +- perhaps instead of scanning the list have a sparse map by port? +- do we want to use libnpf directly for efficiency? +- add more daemons ftpd? +- do we care about the db state becoming too large? +- instead of a yes = bump one, no = return to 0 interface, do we want + to have something more flexible like? + +n + -n + block + unblock +- 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 new file mode 100644 index 00000000000..1856e2524f3 --- /dev/null +++ b/contrib/blocklist/bin/Makefile @@ -0,0 +1,15 @@ +# $NetBSD: Makefile,v 1.1.1.1 2020/06/15 01:52:52 christos Exp $ + +BINDIR=/sbin + +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 +DPADD+=${LIBUTIL} + +.include diff --git a/contrib/blacklist/bin/blacklistctl.8 b/contrib/blocklist/bin/blacklistctl.8 similarity index 61% rename from contrib/blacklist/bin/blacklistctl.8 rename to contrib/blocklist/bin/blacklistctl.8 index 7c652111774..08f1d1b9e5a 100644 --- a/contrib/blacklist/bin/blacklistctl.8 +++ b/contrib/blocklist/bin/blacklistctl.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,42 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd June 7, 2016 +.Dd January 27, 2025 .Dt BLACKLISTCTL 8 .Os .Sh NAME .Nm blacklistctl -.Nd display and change the state of blacklistd +.Nd display and change the state of the blacklistd 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 +is a program used to display and change the state of the .Xr blacklistd 8 -.Pp -The following options are available: +database. +The following sub-commands are supported: +.Ss dump +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 blacklistd +database file to use. +The default is +.Pa /var/db/blocklistd.db . .It Fl d Increase debugging level. .It Fl n @@ -59,9 +74,43 @@ Normally the width of addresses is good for IPv4, the .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 create 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 .Sh NOTES +The +.Nm +program has been renamed to +.Xr blocklistctl 8 . +.Pp Sometimes the reported number of failed attempts can exceed the number of attempts that .Xr blacklistd 8 diff --git a/contrib/blacklist/bin/blacklistctl.c b/contrib/blocklist/bin/blacklistctl.c similarity index 92% rename from contrib/blacklist/bin/blacklistctl.c rename to contrib/blocklist/bin/blacklistctl.c index aebbf72acc5..6298a08b10b 100644 --- a/contrib/blacklist/bin/blacklistctl.c +++ b/contrib/blocklist/bin/blacklistctl.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 @@ -53,7 +55,7 @@ __RCSID("$NetBSD: blacklistctl.c,v 1.23 2018/05/24 19:21:01 christos Exp $"); #include "conf.h" #include "state.h" -#include "internal.h" +#include "old_internal.h" #include "support.h" static __dead void @@ -61,9 +63,10 @@ usage(int c) { if (c == 0) warnx("Missing/unknown command"); - else + 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); } @@ -123,7 +126,6 @@ main(int argc, char *argv[]) break; default: usage(o); - break; } db = state_open(dbname, O_RDONLY, 0); diff --git a/contrib/blacklist/bin/blacklistd.8 b/contrib/blocklist/bin/blacklistd.8 similarity index 73% rename from contrib/blacklist/bin/blacklistd.8 rename to contrib/blocklist/bin/blacklistd.8 index ec7f8b429d9..9ca886e9c4d 100644 --- a/contrib/blacklist/bin/blacklistd.8 +++ b/contrib/blocklist/bin/blacklistd.8 @@ -1,4 +1,4 @@ -.\" $NetBSD: blacklistd.8,v 1.18 2016/07/30 06:09:29 dholland 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,7 +27,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd October 5, 2018 +.Dd February 25, 2025 .Dt BLACKLISTD 8 .Os .Sh NAME @@ -53,18 +53,67 @@ for notifications from other daemons about successful or failed connection 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 +This tuple is consulted against entries from the +.Ar configfile , +with the syntax specified in .Xr blacklistd.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 +as well as passing socket credentials. +.Pp +The file descriptor is used to retrieve information (address and port) +about the remote side with +.Xr getpeername 2 +and the local side with +.Xr getsockname 2 . +.Pp +By examining the port of the local side, +.Nm +can determine if the client program +.Dq owns +the port. +By examining the optional address portion on the local side, it can match +interfaces. +By examining the remote address, it can match specific allow or deny rules. +.Pp +Finally +.Nm +can examine the socket credentials to match the user in the configuration file. +.Pp +While this works well for TCP sockets, it cannot be relied on for unbound +UDP sockets. +It is also less meaningful when it comes to connections using non-privileged +ports. +On the other hand, if we receive a request that has a local endpoint indicating +a UDP privileged port, we can presume that the client was privileged to be +able to acquire that port. +.Pp +Once an entry is matched +.Nm +can perform various actions. If the action is .Dq add and the number of tries limit is reached, then a @@ -87,10 +136,10 @@ that is not required as all information to remove the rule is kept. .Pp If the action is -.Dq remove +.Dq rem Then the same control script is invoked as: .Bd -literal -offset indent -control remove
+control rem
.Ed .Pp where @@ -116,7 +165,7 @@ The following options are available: .It Fl C Ar controlprog Use .Ar controlprog -to communicate with the packet filter, usually +to communicate with the packet filter, instead of the default, which is .Pa /usr/libexec/blacklistd-helper . The following arguments are passed to the control program: .Bl -tag -width protocol @@ -125,7 +174,7 @@ The action to perform: .Dv add , .Dv rem , or -.Dv flush +.Dv flush ; to add, remove or flush a firewall rule. .It name The rule name. @@ -147,13 +196,17 @@ identifier of the rule to be removed. 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 +The name of the configuration file to read. +The default when +.Fl c +is not given is .Pa /etc/blacklistd.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 @@ -167,7 +220,7 @@ are deleted by invoking the control script as: .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. @@ -202,19 +255,19 @@ instead of .Nm deals with the following signals: .Bl -tag -width "USR2" -.It HUP +.It Dv HUP Receipt of this signal causes .Nm to re-read the configuration file. -.It INT, TERM & QUIT +.It Dv INT , Dv TERM & Dv QUIT These signals tell .Nm to exit in an orderly fashion. -.It USR1 +.It Dv USR1 This signal tells .Nm to increase the internal debugging level by 1. -.It USR2 +.It Dv USR2 This signal tells .Nm to decrease the internal debugging level by 1. @@ -225,16 +278,23 @@ to decrease the internal debugging level by 1. Shell script invoked to interface with the packet filter. .It Pa /etc/blacklistd.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 ipf 8 , +.Xr ipfw 8 , .Xr pfctl 8 , .Xr syslogd 8 +.Sh NOTES +The +.Nm +daemon has been renamed to +.Xr blocklistd 8 . .Sh HISTORY .Nm first appeared in diff --git a/contrib/blacklist/bin/blacklistd.c b/contrib/blocklist/bin/blacklistd.c similarity index 89% rename from contrib/blacklist/bin/blacklistd.c rename to contrib/blocklist/bin/blacklistd.c index ebfcc6e840b..01eb662c83f 100644 --- a/contrib/blacklist/bin/blacklistd.c +++ b/contrib/blocklist/bin/blacklistd.c @@ -1,4 +1,4 @@ -/* $NetBSD: blacklistd.c,v 1.38 2019/02/27 02:20:18 christos Exp $ */ +/* $NetBSD: blocklistd.c,v 1.15 2026/02/07 14:32:04 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.15 2026/02/07 14:32:04 christos Exp $"); #include #include @@ -64,8 +67,8 @@ __RCSID("$NetBSD: blacklistd.c,v 1.38 2019/02/27 02:20:18 christos Exp $"); #include #include -#include "bl.h" -#include "internal.h" +#include "old_bl.h" +#include "old_internal.h" #include "conf.h" #include "run.h" #include "state.h" @@ -105,7 +108,7 @@ sigdone(int n __unused) static __dead void usage(int c) { - if (c) + if (c != '?') warnx("Unknown option `%c'", (char)c); fprintf(stderr, "Usage: %s [-vdfr] [-c ] [-R ] " "[-P ] [-C ] [-D ] " @@ -175,6 +178,8 @@ process(bl_t bl) 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,12 @@ process(bl_t bl) 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); } @@ -220,7 +227,7 @@ process(bl_t bl) * 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. + * to the threshold, and block the abusive address. */ if (c.c_nfail != -1) dbi.count = c.c_nfail - 1; @@ -228,24 +235,19 @@ process(bl_t bl) case BL_ADD: dbi.count++; dbi.last = ts.tv_sec; - if (dbi.id[0]) { + if (c.c_nfail != -1 && dbi.count >= c.c_nfail) { /* - * We should not be getting this since the rule - * should have blocked the address. A possible - * explanation is that someone removed that rule, - * and another would be that we got another attempt - * before we added the rule. In anycase, we remove - * and re-add the rule because we don't want to add - * it twice, because then we'd lose track of it. + * No point in re-adding the rule. + * It might exist already due to latency in processing + * and removing the rule is the wrong thing to do as + * it allows a window to attack again. */ - (*lfun)(LOG_DEBUG, "rule exists %s", dbi.id); - (void)run_change("rem", &c, dbi.id, 0); - dbi.id[0] = '\0'; - } - if (c.c_nfail != -1 && dbi.count >= c.c_nfail) { - int res = run_change("add", &c, dbi.id, sizeof(dbi.id)); - if (res == -1) - goto out; + if (dbi.id[0] == '\0') { + int res = run_change("add", &c, + dbi.id, sizeof(dbi.id)); + if (res == -1) + goto out; + } sockaddr_snprintf(rbuf, sizeof(rbuf), "%a", (void *)&rss); (*lfun)(LOG_INFO, @@ -330,8 +332,8 @@ update(void) (*lfun)(LOG_INFO, "released %s/%d:%d after %d seconds", buf, c.c_lmask, c.c_port, c.c_duration); } - state_del(state, &c); - goto again; + if (state_del(state, &c) == 0) + goto again; } } @@ -339,7 +341,7 @@ static void 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) { @@ -400,15 +402,25 @@ rules_flush(void) 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 @@ -459,9 +471,9 @@ main(int argc, char *argv[]) void *p = reallocarray(blsock, maxblsock, sizeof(*blsock)); if (p == NULL) - err(EXIT_FAILURE, - "Can't allocate memory for %zu sockets", - maxblsock); + err(EXIT_FAILURE, "Can't allocate " + "memory for %zu sockets", + maxblsock); blsock = p; } blsock[nblsock++] = optarg; @@ -479,7 +491,7 @@ main(int argc, char *argv[]) argc -= optind; if (argc) - usage(0); + usage('?'); signal(SIGHUP, sighup); signal(SIGINT, sigdone); diff --git a/contrib/blacklist/bin/blacklistd.conf.5 b/contrib/blocklist/bin/blacklistd.conf.5 similarity index 84% rename from contrib/blacklist/bin/blacklistd.conf.5 rename to contrib/blocklist/bin/blacklistd.conf.5 index d79da702c85..d4ca6785d5b 100644 --- a/contrib/blacklist/bin/blacklistd.conf.5 +++ b/contrib/blocklist/bin/blacklistd.conf.5 @@ -1,6 +1,6 @@ -.\" $NetBSD: blacklistd.conf.5,v 1.7 2017/06/07 13:50:57 wiz Exp $ +.\" $NetBSD: blocklistd.conf.5,v 1.9 2026/01/13 21:38:18 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 @@ -48,34 +48,34 @@ Comments are denoted by a 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 @@ The first four fields, 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 @@ The 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 @@ The 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 @@ field contains the number of failed attempts before access is blocked, 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,25 +176,31 @@ for hours and 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 -rules can be used for whitelisting specific addresses, changing the mask -size, the rule that the packet filter uses, the number of failed attempts, -or the block duration. +.Va [remote] +rules can be used for allowing specific addresses, changing the mask +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 @@ -209,13 +215,20 @@ bnx0:ssh * * * * 3 6h [remote] # Never block 1.2.3.4 1.2.3.4:ssh * * * * * * -# For addresses coming from 8.8.0.0/16 block class C networks instead +# 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 +.Sh NOTES +The +.Nm +file has been renamed to +.Xr blocklistd.conf 8 . .Sh HISTORY .Nm first appeared in diff --git a/contrib/blocklist/bin/blocklistctl.8 b/contrib/blocklist/bin/blocklistctl.8 new file mode 100644 index 00000000000..d241f284447 --- /dev/null +++ b/contrib/blocklist/bin/blocklistctl.8 @@ -0,0 +1,134 @@ +.\" $NetBSD: blocklistctl.8,v 1.6 2025/10/26 13:49:22 christos Exp $ +.\" +.\" Copyright (c) 2015 The NetBSD Foundation, Inc. +.\" All rights reserved. +.\" +.\" This code is derived from software contributed to The NetBSD Foundation +.\" by Christos Zoulas. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd October 25, 2025 +.Dt BLOCKLISTCTL 8 +.Os +.Sh NAME +.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 and change the state of the +.Xr blocklistd 8 +database. +The following sub-commands are supported: +.Ss dump +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 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 +Don't display a header. +.It Fl r +Show the remaining blocked time instead of the last activity time. +.It Fl w +Normally the width of addresses is good for IPv4, the +.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 rulename +The packet filter rule name associated with the database entry, +usually +.Dv blocklistd . +.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 create 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 blocklistd 8 +.Sh NOTES +Sometimes the reported number of failed attempts can exceed the number +of attempts that +.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 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 +.Nm +first appeared in +.Nx 7 . +.Fx +support for +.Nm +was implemented in +.Fx 11 . +.Sh AUTHORS +.An Christos Zoulas diff --git a/contrib/blocklist/bin/blocklistctl.c b/contrib/blocklist/bin/blocklistctl.c new file mode 100644 index 00000000000..b43d8b8aaab --- /dev/null +++ b/contrib/blocklist/bin/blocklistctl.c @@ -0,0 +1,170 @@ +/* $NetBSD: blocklistctl.c,v 1.5 2025/10/25 16:56:10 christos Exp $ */ + +/*- + * Copyright (c) 2015 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_SYS_CDEFS_H +#include +#endif +__RCSID("$NetBSD: blocklistctl.c,v 1.5 2025/10/25 16:56:10 christos Exp $"); + +#include +#include +#ifdef HAVE_LIBUTIL_H +#include +#endif +#ifdef HAVE_UTIL_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include + +#include "conf.h" +#include "state.h" +#include "internal.h" +#include "support.h" + +static __dead void +usage(int c) +{ + if (c == 0) + warnx("Missing/unknown command"); + else if (c != '?') + warnx("Unknown option `%c'", (char)c); + fprintf(stderr, + "Usage: %s dump [-abdnrw] [-D dbname]\n", getprogname()); + exit(EXIT_FAILURE); +} + +static const char * +star(char *buf, size_t len, int val) +{ + if (val == -1) + return "*"; + snprintf(buf, len, "%d", val); + return buf; +} + +int +main(int argc, char *argv[]) +{ + const char *dbname = _PATH_BLSTATE; + DB *db; + struct conf c; + struct dbinfo dbi; + unsigned int i; + struct timespec ts; + int all, blocked, remain, wide, noheader; + int o; + + noheader = wide = blocked = all = remain = 0; + lfun = dlog; + + if (argc == 1 || strcmp(argv[1], "dump") != 0) + usage(0); + + argc--; + argv++; + + while ((o = getopt(argc, argv, "abD:dnrw")) != -1) + switch (o) { + case 'a': + all = 1; + blocked = 0; + break; + case 'b': + blocked = 1; + break; + case 'D': + dbname = optarg; + break; + case 'd': + debug++; + break; + case 'n': + noheader = 1; + break; + case 'r': + remain = 1; + break; + case 'w': + wide = 1; + break; + default: + usage(o); + } + + db = state_open(dbname, O_RDONLY, 0); + if (db == NULL) + err(EXIT_FAILURE, "Can't open `%s'", dbname); + + clock_gettime(CLOCK_REALTIME, &ts); + wide = wide ? 8 * 4 + 7 : 4 * 3 + 3; + if (!noheader) + printf("rulename\t%*.*s/ma:port\tid\tnfail\t%s\n", wide, wide, + "address", remain ? "remaining time" : "last access"); + for (i = 1; state_iterate(db, &c, &dbi, i) != 0; i = 0) { + char buf[BUFSIZ]; + char mbuf[64], pbuf[64]; + if (!all) { + if (blocked) { + if (c.c_nfail == -1 || dbi.count < c.c_nfail) + continue; + } else { + if (dbi.count >= c.c_nfail) + continue; + } + } + sockaddr_snprintf(buf, sizeof(buf), "%a", (void *)&c.c_ss); + printf("%s\t%*.*s/%s:%s\t", c.c_name, wide, wide, buf, + star(mbuf, sizeof(mbuf), c.c_lmask), + star(pbuf, sizeof(pbuf), c.c_port)); + if (c.c_duration == -1) { + strlcpy(buf, "never", sizeof(buf)); + } else { + if (remain) + fmtydhms(buf, sizeof(buf), + c.c_duration - (ts.tv_sec - dbi.last)); + else + fmttime(buf, sizeof(buf), dbi.last); + } + printf("%s\t%d/%s\t%-s\n", dbi.id, dbi.count, + star(mbuf, sizeof(mbuf), c.c_nfail), buf); + } + state_close(db); + return EXIT_SUCCESS; +} diff --git a/contrib/blocklist/bin/blocklistd.8 b/contrib/blocklist/bin/blocklistd.8 new file mode 100644 index 00000000000..e0b9fb482cb --- /dev/null +++ b/contrib/blocklist/bin/blocklistd.8 @@ -0,0 +1,303 @@ +.\" $NetBSD: blocklistd.8,v 1.8 2025/02/25 22:13:34 christos Exp $ +.\" +.\" Copyright (c) 2015 The NetBSD Foundation, Inc. +.\" All rights reserved. +.\" +.\" This code is derived from software contributed to The NetBSD Foundation +.\" by Christos Zoulas. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd February 25, 2025 +.Dt BLOCKLISTD 8 +.Os +.Sh NAME +.Nm blocklistd +.Nd block and release ports on demand to avoid DoS abuse +.Sh SYNOPSIS +.Nm +.Op Fl dfrv +.Op Fl C Ar controlprog +.Op Fl c Ar configfile +.Op Fl D Ar dbfile +.Op Fl P Ar sockpathsfile +.Op Fl R Ar rulename +.Op Fl s Ar sockpath +.Op Fl t Ar timeout +.Sh DESCRIPTION +.Nm +is a daemon similar to +.Xr syslogd 8 +that listens to sockets at paths specified in the +.Ar sockpathsfile +for notifications from other daemons about successful or failed connection +attempts. +If no such file is specified, then it only listens to the socket path +specified by +.Ar sockpath +or if that is not specified to +.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 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 blocklist +as well as passing socket credentials. +.Pp +The file descriptor is used to retrieve information (address and port) +about the remote side with +.Xr getpeername 2 +and the local side with +.Xr getsockname 2 . +.Pp +By examining the port of the local side, +.Nm +can determine if the client program +.Dq owns +the port. +By examining the optional address portion on the local side, it can match +interfaces. +By examining the remote address, it can match specific allow or deny rules. +.Pp +Finally +.Nm +can examine the socket credentials to match the user in the configuration file. +.Pp +While this works well for TCP sockets, it cannot be relied on for unbound +UDP sockets. +It is also less meaningful when it comes to connections using non-privileged +ports. +On the other hand, if we receive a request that has a local endpoint indicating +a UDP privileged port, we can presume that the client was privileged to be +able to acquire that port. +.Pp +Once an entry is matched +.Nm +can perform various actions. +If the action is +.Dq add +and the number of tries limit is reached, then a +control script +.Ar controlprog +is invoked with arguments: +.Bd -literal -offset indent +control add
+.Ed +.Pp +and should invoke a packet filter command to block the connection +specified by the arguments. +The +.Ar rulename +argument can be set from the command line (default +.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 +kept. +.Pp +If the action is +.Dq rem +Then the same control script is invoked as: +.Bd -literal -offset indent +control rem
+.Ed +.Pp +where +.Ar id +is the number returned from the +.Dq add +action. +.Pp +.Nm +maintains a database of known connections in +.Ar dbfile . +On startup it reads entries from that file, and updates its internal state. +.Pp +.Nm +checks the list of active entries every +.Ar timeout +seconds (default +.Dv 15 ) +and removes entries and block rules using the control program as necessary. +.Pp +The following options are available: +.Bl -tag -width indent +.It Fl C Ar controlprog +Use +.Ar controlprog +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 +The action to perform: +.Dv add , +.Dv rem , +or +.Dv flush ; +to add, remove or flush a firewall rule. +.It name +The rule name. +.It protocol +The optional protocol name (can be empty): +.Dv tcp , +.Dv tcp6 , +.Dv udp , +.Dv udp6 . +.It address +The IPv4 or IPv6 numeric address to be blocked or released. +.It mask +The numeric mask to be applied to the blocked or released address +.It port +The optional numeric port to be blocked (can be empty). +.It id +For packet filters that support removal of rules by rule identifier, the +identifier of the rule to be removed. +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. +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. +It defaults to +.Pa /var/db/blocklistd.db . +.It Fl d +Normally, +.Nm +disassociates itself from the terminal unless the +.Fl d +flag is specified, in which case it stays in the foreground. +.It Fl f +Truncate the state database and flush all the rules named +.Ar rulename +are deleted by invoking the control script as: +.Bd -literal -offset indent +control flush +.Ed +.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 blocklistd . +.It Fl r +Re-read the firewall rules from the internal database, then +remove and re-add them. +This helps for packet filters that do not retain state across reboots. +.It Fl s Ar sockpath +Add +.Ar sockpath +to the list of Unix sockets +.Nm +listens to. +.It Fl t Ar timeout +The interval in seconds +.Nm +polls the state file to update the rules. +.It Fl v +Cause +.Nm +to print +diagnostic messages to +.Dv stdout +instead of +.Xr syslogd 8 . +.El +.Sh SIGNAL HANDLING +.Nm +deals with the following signals: +.Bl -tag -width "USR2" +.It Dv HUP +Receipt of this signal causes +.Nm +to re-read the configuration file. +.It Dv INT , Dv TERM & Dv QUIT +These signals tell +.Nm +to exit in an orderly fashion. +.It Dv USR1 +This signal tells +.Nm +to increase the internal debugging level by 1. +.It Dv USR2 +This signal tells +.Nm +to decrease the internal debugging level by 1. +.El +.Sh FILES +.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/blocklistd.conf +Configuration file. +.It Pa /var/db/blocklistd.db +Database of current connection entries. +.It Pa /var/run/blocklistd.sock +Socket to receive connection notifications. +.El +.Sh SEE ALSO +.Xr blocklistd.conf 5 , +.Xr blocklistctl 8 , +.Xr ipf 8 , +.Xr ipfw 8 , +.Xr pfctl 8 , +.Xr syslogd 8 +.Sh HISTORY +.Nm +first appeared in +.Nx 7 . +.Fx +support for +.Nm +was implemented in +.Fx 11 . +.Sh AUTHORS +.An Christos Zoulas diff --git a/contrib/blocklist/bin/blocklistd.c b/contrib/blocklist/bin/blocklistd.c new file mode 100644 index 00000000000..231d6477835 --- /dev/null +++ b/contrib/blocklist/bin/blocklistd.c @@ -0,0 +1,594 @@ +/* $NetBSD: blocklistd.c,v 1.15 2026/02/07 14:32:04 christos Exp $ */ + +/*- + * Copyright (c) 2015 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_SYS_CDEFS_H +#include +#endif +__RCSID("$NetBSD: blocklistd.c,v 1.15 2026/02/07 14:32:04 christos Exp $"); + +#include +#include +#include + +#ifdef HAVE_LIBUTIL_H +#include +#endif +#ifdef HAVE_UTIL_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bl.h" +#include "internal.h" +#include "conf.h" +#include "run.h" +#include "state.h" +#include "support.h" + +static const char *configfile = _PATH_BLCONF; +static DB *state; +static const char *dbfile = _PATH_BLSTATE; +static sig_atomic_t readconf; +static sig_atomic_t done; +static int vflag; + +static void +sigusr1(int n __unused) +{ + debug++; +} + +static void +sigusr2(int n __unused) +{ + debug--; +} + +static void +sighup(int n __unused) +{ + readconf++; +} + +static void +sigdone(int n __unused) +{ + done++; +} + +static __dead void +usage(int c) +{ + if (c != '?') + warnx("Unknown option `%c'", (char)c); + fprintf(stderr, "Usage: %s [-vdfr] [-c ] [-R ] " + "[-P ] [-C ] [-D ] " + "[-s ] [-t ]\n", getprogname()); + exit(EXIT_FAILURE); +} + +static int +getremoteaddress(bl_info_t *bi, struct sockaddr_storage *rss, socklen_t *rsl) +{ + *rsl = sizeof(*rss); + memset(rss, 0, *rsl); + + if (getpeername(bi->bi_fd, (void *)rss, rsl) != -1) + return 0; + + if (errno != ENOTCONN) { + (*lfun)(LOG_ERR, "getpeername failed (%m)"); + return -1; + } + + if (bi->bi_slen == 0) { + (*lfun)(LOG_ERR, "unconnected socket with no peer in message"); + return -1; + } + + switch (bi->bi_ss.ss_family) { + case AF_INET: + *rsl = sizeof(struct sockaddr_in); + break; + case AF_INET6: + *rsl = sizeof(struct sockaddr_in6); + break; + default: + (*lfun)(LOG_ERR, "bad client passed socket family %u", + (unsigned)bi->bi_ss.ss_family); + return -1; + } + + if (*rsl != bi->bi_slen) { + (*lfun)(LOG_ERR, "bad client passed socket length %u != %u", + (unsigned)*rsl, (unsigned)bi->bi_slen); + return -1; + } + + memcpy(rss, &bi->bi_ss, *rsl); + +#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN + if (*rsl != rss->ss_len) { + (*lfun)(LOG_ERR, + "bad client passed socket internal length %u != %u", + (unsigned)*rsl, (unsigned)rss->ss_len); + return -1; + } +#endif + return 0; +} + +static void +process(bl_t bl) +{ + struct sockaddr_storage rss; + socklen_t rsl; + char rbuf[BUFSIZ]; + bl_info_t *bi; + struct conf c; + 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; + } + + if ((bi = bl_recv(bl)) == NULL) { + (*lfun)(LOG_ERR, "no message (%m)"); + return; + } + + if (getremoteaddress(bi, &rss, &rsl) == -1) + goto out; + + if (debug || bi->bi_msg[0]) { + sockaddr_snprintf(rbuf, sizeof(rbuf), "%a:%p", (void *)&rss); + (*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); + } + + if (conf_find(bi->bi_fd, bi->bi_uid, &rss, &c) == NULL) { + (*lfun)(LOG_DEBUG, "no rule matched"); + goto out; + } + + + if (state_get(state, &c, &dbi) == -1) + goto out; + + if (debug) { + char b1[128], b2[128]; + (*lfun)(LOG_DEBUG, "%s: initial db state for %s: count=%d/%d " + "last=%s now=%s", __func__, rbuf, dbi.count, c.c_nfail, + fmttime(b1, sizeof(b1), dbi.last), + fmttime(b2, sizeof(b2), ts.tv_sec)); + } + + switch (bi->bi_type) { + case BL_ABUSE: + /* + * 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 threshold, and + * block the abusive address. + */ + if (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) { + /* + * No point in re-adding the rule. + * It might exist already due to latency in processing + * and removing the rule is the wrong thing to do as + * it allows a window to attack again. + */ + if (dbi.id[0] == '\0') { + int res = run_change("add", &c, + dbi.id, sizeof(dbi.id)); + if (res == -1) + goto out; + } + sockaddr_snprintf(rbuf, sizeof(rbuf), "%a", + (void *)&rss); + (*lfun)(LOG_INFO, + "blocked %s/%d:%d for %d seconds", + rbuf, c.c_lmask, c.c_port, c.c_duration); + } + break; + case BL_DELETE: + if (dbi.last == 0) + goto out; + dbi.count = 0; + dbi.last = 0; + break; + default: + (*lfun)(LOG_ERR, "unknown message %d", bi->bi_type); + } + state_put(state, &c, &dbi); + +out: + close(bi->bi_fd); + + if (debug) { + char b1[128], b2[128]; + (*lfun)(LOG_DEBUG, "%s: final db state for %s: count=%d/%d " + "last=%s now=%s", __func__, rbuf, dbi.count, c.c_nfail, + fmttime(b1, sizeof(b1), dbi.last), + fmttime(b2, sizeof(b2), ts.tv_sec)); + } +} + +static void +update_interfaces(void) +{ + struct ifaddrs *oifas, *nifas; + + if (getifaddrs(&nifas) == -1) + return; + + oifas = ifas; + ifas = nifas; + + if (oifas) + freeifaddrs(oifas); +} + +static void +update(void) +{ + struct timespec ts; + struct conf c; + struct dbinfo dbi; + unsigned int f, n; + char buf[128]; + void *ss = &c.c_ss; + + if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { + (*lfun)(LOG_ERR, "clock_gettime failed (%m)"); + return; + } + +again: + for (n = 0, f = 1; state_iterate(state, &c, &dbi, f) == 1; + f = 0, n++) + { + time_t when = c.c_duration + dbi.last; + if (debug > 1) { + char b1[64], b2[64]; + sockaddr_snprintf(buf, sizeof(buf), "%a:%p", ss); + (*lfun)(LOG_DEBUG, "%s:[%u] %s count=%d duration=%d " + "last=%s " "now=%s", __func__, n, buf, dbi.count, + c.c_duration, fmttime(b1, sizeof(b1), dbi.last), + fmttime(b2, sizeof(b2), ts.tv_sec)); + } + if (c.c_duration == -1 || when >= ts.tv_sec) + continue; + if (dbi.id[0]) { + run_change("rem", &c, dbi.id, 0); + sockaddr_snprintf(buf, sizeof(buf), "%a", ss); + (*lfun)(LOG_INFO, "released %s/%d:%d after %d seconds", + buf, c.c_lmask, c.c_port, c.c_duration); + } + if (state_del(state, &c) == 0) + goto again; + } +} + +static void +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_r); + if (bl == NULL || !bl_isconnected(bl)) + exit(EXIT_FAILURE); + if (*nfd >= *maxfd) { + *maxfd += 10; + *blp = reallocarray(*blp, *maxfd, sizeof(**blp)); + if (*blp == NULL) + err(EXIT_FAILURE, "malloc"); + *pfdp = reallocarray(*pfdp, *maxfd, sizeof(**pfdp)); + if (*pfdp == NULL) + err(EXIT_FAILURE, "malloc"); + } + + (*pfdp)[*nfd].fd = bl_getfd(bl); + (*pfdp)[*nfd].events = POLLIN; + (*blp)[*nfd] = bl; + *nfd += 1; +} + +static void +uniqueadd(struct conf ***listp, size_t *nlist, size_t *mlist, struct conf *c) +{ + struct conf **list = *listp; + + if (c->c_name[0] == '\0') + return; + for (size_t i = 0; i < *nlist; i++) { + if (strcmp(list[i]->c_name, c->c_name) == 0) + return; + } + if (*nlist == *mlist) { + *mlist += 10; + void *p = reallocarray(*listp, *mlist, sizeof(*list)); + if (p == NULL) + err(EXIT_FAILURE, "Can't allocate for rule list"); + list = *listp = p; + } + list[(*nlist)++] = c; +} + +static void +rules_flush(void) +{ + struct conf **list; + size_t nlist, mlist; + + list = NULL; + mlist = nlist = 0; + for (size_t i = 0; i < rconf.cs_n; i++) + uniqueadd(&list, &nlist, &mlist, &rconf.cs_c[i]); + for (size_t i = 0; i < lconf.cs_n; i++) + uniqueadd(&list, &nlist, &mlist, &lconf.cs_c[i]); + + for (size_t i = 0; i < nlist; i++) + run_flush(list[i]); + free(list); +} + +static void +rules_restore(void) +{ + DB *db; + struct conf c; + struct dbinfo dbi; + unsigned int f; + + 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 +main(int argc, char *argv[]) +{ + int c, tout, flags, flush, restore, ret; + const char *spath, **blsock; + size_t nblsock, maxblsock; + + setprogname(argv[0]); + + spath = NULL; + blsock = NULL; + maxblsock = nblsock = 0; + flush = 0; + restore = 0; + tout = 0; + flags = O_RDWR|O_EXCL|O_CLOEXEC; + while ((c = getopt(argc, argv, "C:c:D:dfP:rR:s:t:v")) != -1) { + switch (c) { + case 'C': + controlprog = optarg; + break; + case 'c': + configfile = optarg; + break; + case 'D': + dbfile = optarg; + break; + case 'd': + debug++; + break; + case 'f': + flush++; + break; + case 'P': + spath = optarg; + break; + case 'R': + rulename = optarg; + break; + case 'r': + restore++; + break; + case 's': + if (nblsock >= maxblsock) { + maxblsock += 10; + void *p = reallocarray(blsock, maxblsock, + sizeof(*blsock)); + if (p == NULL) + err(EXIT_FAILURE, "Can't allocate " + "memory for %zu sockets", + maxblsock); + blsock = p; + } + blsock[nblsock++] = optarg; + break; + case 't': + tout = atoi(optarg) * 1000; + break; + case 'v': + vflag++; + break; + default: + usage(c); + } + } + + argc -= optind; + if (argc) + usage('?'); + + signal(SIGHUP, sighup); + signal(SIGINT, sigdone); + signal(SIGQUIT, sigdone); + signal(SIGTERM, sigdone); + signal(SIGUSR1, sigusr1); + signal(SIGUSR2, sigusr2); + + openlog(getprogname(), LOG_PID, LOG_DAEMON); + + if (debug) { + lfun = dlog; + if (tout == 0) + tout = 5000; + } else { + if (tout == 0) + tout = 15000; + } + + update_interfaces(); + conf_parse(configfile); + if (flush) { + rules_flush(); + if (!restore) + flags |= O_TRUNC; + } + + struct pollfd *pfd = NULL; + bl_t *bl = NULL; + size_t nfd = 0; + size_t maxfd = 0; + + for (size_t i = 0; i < nblsock; i++) + addfd(&pfd, &bl, &nfd, &maxfd, blsock[i]); + free(blsock); + + if (spath) { + FILE *fp = fopen(spath, "r"); + char *line; + if (fp == NULL) + err(EXIT_FAILURE, "Can't open `%s'", spath); + for (; (line = fparseln(fp, NULL, NULL, NULL, 0)) != NULL; + free(line)) + addfd(&pfd, &bl, &nfd, &maxfd, line); + fclose(fp); + } + if (nfd == 0) + addfd(&pfd, &bl, &nfd, &maxfd, _PATH_BLSOCK); + + state = state_open(dbfile, flags, 0600); + if (state == NULL) + state = state_open(dbfile, flags | O_CREAT, 0600); + else { + if (restore) { + if (!flush) + rules_flush(); + rules_restore(); + } + } + if (state == NULL) + exit(EXIT_FAILURE); + + if (!debug) { + if (daemon(0, 0) == -1) + err(EXIT_FAILURE, "daemon failed"); + if (pidfile(NULL) == -1) + err(EXIT_FAILURE, "Can't create pidfile"); + } + + for (size_t t = 0; !done; t++) { + if (readconf) { + readconf = 0; + conf_parse(configfile); + } + ret = poll(pfd, (nfds_t)nfd, tout); + if (debug) + (*lfun)(LOG_DEBUG, "received %d from poll()", ret); + switch (ret) { + case -1: + if (errno == EINTR) + continue; + (*lfun)(LOG_ERR, "poll (%m)"); + exit(EXIT_FAILURE); + case 0: + state_sync(state); + break; + default: + for (size_t i = 0; i < nfd; i++) + if (pfd[i].revents & POLLIN) + process(bl[i]); + } + if (t % 100 == 0) + state_sync(state); + if (t % 10000 == 0) + update_interfaces(); + update(); + } + state_close(state); + exit(EXIT_SUCCESS); +} diff --git a/contrib/blocklist/bin/blocklistd.conf.5 b/contrib/blocklist/bin/blocklistd.conf.5 new file mode 100644 index 00000000000..cff8b33302e --- /dev/null +++ b/contrib/blocklist/bin/blocklistd.conf.5 @@ -0,0 +1,237 @@ +.\" $NetBSD: blocklistd.conf.5,v 1.9 2026/01/13 21:38:18 christos Exp $ +.\" +.\" Copyright (c) 2015, 2025 The NetBSD Foundation, Inc. +.\" All rights reserved. +.\" +.\" This code is derived from software contributed to The NetBSD Foundation +.\" by Christos Zoulas. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd January 13, 2026 +.Dt BLOCKLISTD.CONF 5 +.Os +.Sh NAME +.Nm blocklistd.conf +.Nd configuration file format for blocklistd +.Sh DESCRIPTION +The +.Nm +file contains configuration entries for +.Xr blocklistd 8 +in a fashion similar to +.Xr inetd.conf 5 . +Only one entry per line is permitted. +Every entry must have all fields populated. +Each field can be separated by a tab or a space. +Comments are denoted by a +.Dq # +at the beginning of a line. +.Pp +There are two kinds of configuration lines, +.Va [local] +and +.Va [remote] . +By default, configuration lines are +.Va [local] , +i.e. the address specified refers to the addresses on the local machine. +To switch to between +.Va [local] +and +.Va [remote] +configuration lines you can specify the stanzas: +.Dq [local] +and +.Dq [remote] . +.Pp +On +.Va [local] +and +.Va [remote] +lines +.Dq * +means use the default, or wildcard match. +In addition, for +.Va [remote] +lines +.Dq = +means use the values from the matched +.Va [local] +configuration line. +.Pp +The first four fields, +.Va location , +.Va type , +.Va proto , +and +.Va owner +are used to match the +.Va [local] +or +.Va [remote] +addresses, whereas the last 3 fields +.Va name , +.Va nfail , +and +.Va disable +are used to modify the filtering action. +.Pp +The first field denotes the +.Va location +as an address, mask, and port. +The syntax for the +.Va location +is: +.Bd -literal -offset indent + [
|[/]:] +.Ed +.Pp +The +.Dv address +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. +.Pp +The +.Dv mask +is always numeric, but the +.Dv port +can be either numeric or symbolic. +.Pp +The second field is the socket +.Va type : +.Dv stream , +.Dv dgram , +or numeric. +The third field is the +.Va protocol : +.Dv tcp , +.Dv udp , +.Dv tcp6 , +.Dv udp6 , +or numeric. +The fourth field is the effective user +.Va ( owner ) +of the daemon process reporting the event, +either as a username or a userid. +.Pp +The rest of the fields control the behavior of the filter. +.Pp +The +.Va name +field, is the name of the packet filter rule to be used. +If the +.Va name +starts with a hyphen +.Pq Dq - , +then the default rulename is prepended to the given name. +If the +.Dv name +contains a +.Dq / , +the remaining portion of the name is interpreted as the mask to be +applied to the address specified in the rule, causing a single rule violation to +block the entire subnet for the configured prefix. +.Pp +The +.Va nfail +field contains the number of failed attempts before access is blocked, +defaulting to +.Dq * +meaning never, and the last field +.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 duration +is seconds, but one can specify suffixes for different units, such as +.Dq m +for minutes +.Dq h +for hours and +.Dq d +for days. +.Pp +Matching is done first by checking the +.Va [local] +rules individually, in the order of the most specific to the least specific. +If a match is found, then the matching +.Va [remote] +rules are applied. +The +.Va name , +.Va nfail , +and +.Va duration +fields can be altered by the +.Va [remote] +rule that matched. +.Pp +The +.Va [remote] +rules can be used for allowing specific addresses, changing the mask +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/blocklistd.conf -compact +.It Pa /etc/blocklistd.conf +Configuration file. +.El +.Sh EXAMPLES +.Bd -literal -offset 8n +# Block ssh, after 3 attempts for 6 hours on the bnx0 interface +[local] +# location type proto owner name nfail duration +bnx0:ssh * * * * 3 6h +[remote] +# Never block 1.2.3.4 +1.2.3.4:ssh * * * * * * +# 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 blocklistctl 8 , +.Xr blocklistd 8 +.Sh HISTORY +.Nm +first appeared in +.Nx 7 . +.Fx +support for +.Nm +was implemented in +.Fx 11 . +.Sh AUTHORS +.An Christos Zoulas diff --git a/contrib/blacklist/bin/conf.c b/contrib/blocklist/bin/conf.c similarity index 79% rename from contrib/blacklist/bin/conf.c rename to contrib/blocklist/bin/conf.c index 5fc614d794b..f469e28235c 100644 --- a/contrib/blacklist/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 @@ -46,6 +48,7 @@ __RCSID("$NetBSD: conf.c,v 1.24 2016/04/04 15:52:56 christos Exp $"); #include #include #include +#include #include #include #include @@ -55,7 +58,9 @@ __RCSID("$NetBSD: conf.c,v 1.24 2016/04/04 15:52:56 christos Exp $"); #include #include #include +#include #include +#include #include "bl.h" #include "internal.h" @@ -259,7 +264,7 @@ conf_gethostport(const char *f, size_t l, bool local, struct conf *c, 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 @@ -267,6 +272,8 @@ conf_gethostport(const char *f, size_t l, bool local, struct conf *c, #endif port = &sin6->sin6_port; } + if (!*pstr) + pstr = "*"; } else if (pstr != p || strchr(p, '.') || conf_is_interface(p)) { if (pstr == p) pstr = "*"; @@ -309,7 +316,7 @@ conf_gethostport(const char *f, size_t l, bool local, struct conf *c, *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 " @@ -373,6 +380,7 @@ conf_getname(const char *f, size_t l, bool local, struct conf *c, strlcpy(c->c_name, rulename, CONFNAMESZ); return 0; } + if (strcmp(p, "=") == 0) { if (local) goto out; @@ -404,6 +412,8 @@ conf_parseline(const char *f, size_t l, char *p, struct conf *c, bool local) { int e; + c->c_lineno = l; + while (*p && isspace((unsigned char)*p)) p++; @@ -468,14 +478,12 @@ conf_amask_eq(const void *v1, const void *v2, size_t len, int mask) uint32_t m; int omask = mask; - len >>= 2; switch (mask) { case FSTAR: if (memcmp(v1, v2, len) == 0) return 1; goto out; case FEQUAL: - (*lfun)(LOG_CRIT, "%s: Internal error: bad mask %d", __func__, mask); abort(); @@ -483,7 +491,7 @@ conf_amask_eq(const void *v1, const void *v2, size_t len, int mask) 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; @@ -499,7 +507,6 @@ conf_amask_eq(const void *v1, const void *v2, size_t len, int mask) 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__, @@ -688,6 +695,25 @@ conf_addr_eq(const struct sockaddr_storage *s1, 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)) @@ -951,13 +977,54 @@ confset_free(struct confset *cs) } 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 @@ -988,7 +1055,7 @@ confset_match(const struct confset *cs, struct conf *c, 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), @@ -1000,32 +1067,72 @@ confset_match(const struct confset *cs, struct conf *c, return i; } -const struct conf * -conf_find(int fd, uid_t uid, const struct sockaddr_storage *rss, - struct conf *cr) +#ifdef AF_ROUTE +static int +conf_route_perm(int fd) { +#if defined(RTM_IFANNOUNCE) && defined(SA_SIZE) + /* + * Send a routing message that is not supported to check for access + * We expect EOPNOTSUPP for having access, since we are sending a + * request the system does not understand and EACCES if we don't have + * access. + */ + static struct sockaddr_in sin = { +#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN + .sin_len = sizeof(sin), +#endif + .sin_family = AF_INET, + }; + char buf[4096]; + struct rt_msghdr *rtm = (void *)buf; + char *cp = (char *)(rtm + 1); + size_t l; + +#define NEXTADDR(s) \ + l = SA_SIZE(sizeof(*s)); memmove(cp, s, l); cp += l; + memset(buf, 0, sizeof(buf)); + rtm->rtm_type = RTM_IFANNOUNCE; + rtm->rtm_flags = 0; + rtm->rtm_addrs = RTA_DST|RTA_GATEWAY; + rtm->rtm_version = RTM_VERSION; + rtm->rtm_seq = 666; + NEXTADDR(&sin); + NEXTADDR(&sin); + rtm->rtm_msglen = (u_short)((char *)cp - (char *)rtm); + if (write(fd, rtm, rtm->rtm_msglen) != -1) { + (*lfun)(LOG_ERR, "Writing to routing socket succeeded!"); + return 0; + } + switch (errno) { + case EACCES: + return 0; + case EOPNOTSUPP: + return 1; + default: + (*lfun)(LOG_ERR, + "Unexpected error writing to routing socket (%m)"); + return 0; + } +#else + return 0; +#endif +} +#endif + +static int +conf_handle_inet(int fd, const void *lss, struct conf *cr) { - int proto; - socklen_t slen; - struct sockaddr_storage lss; - size_t i; char buf[BUFSIZ]; + int proto; + socklen_t slen = sizeof(proto); - memset(cr, 0, sizeof(*cr)); - slen = sizeof(lss); - memset(&lss, 0, slen); - if (getsockname(fd, (void *)&lss, &slen) == -1) { - (*lfun)(LOG_ERR, "getsockname failed (%m)"); - return NULL; - } - - slen = sizeof(proto); if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &proto, &slen) == -1) { (*lfun)(LOG_ERR, "getsockopt failed (%m)"); - return NULL; + return -1; } if (debug) { - sockaddr_snprintf(buf, sizeof(buf), "%a:%p", (void *)&lss); + sockaddr_snprintf(buf, sizeof(buf), "%a:%p", lss); (*lfun)(LOG_DEBUG, "listening socket: %s", buf); } @@ -1038,16 +1145,51 @@ conf_find(int fd, uid_t uid, const struct sockaddr_storage *rss, break; default: (*lfun)(LOG_ERR, "unsupported protocol %d", proto); + return -1; + } + return 0; +} + +const struct conf * +conf_find(int fd, uid_t uid, const struct sockaddr_storage *rss, + struct conf *cr) +{ + socklen_t slen; + struct sockaddr_storage lss; + size_t i; + char buf[BUFSIZ]; + + memset(cr, 0, sizeof(*cr)); + slen = sizeof(lss); + memset(&lss, 0, slen); + if (getsockname(fd, (void *)&lss, &slen) == -1) { + (*lfun)(LOG_ERR, "getsockname failed (%m)"); return NULL; } switch (lss.ss_family) { case AF_INET: cr->c_port = ntohs(((struct sockaddr_in *)&lss)->sin_port); + if (conf_handle_inet(fd, &lss, cr) == -1) + return NULL; break; case AF_INET6: cr->c_port = ntohs(((struct sockaddr_in6 *)&lss)->sin6_port); + if (conf_handle_inet(fd, &lss, cr) == -1) + return NULL; + break; +#ifdef AF_ROUTE + case AF_ROUTE: + if (!conf_route_perm(fd)) { + (*lfun)(LOG_ERR, + "permission denied to routing socket (%m)"); + return NULL; + } + cr->c_proto = FSTAR; + cr->c_port = FSTAR; + memcpy(&lss, rss, sizeof(lss)); break; +#endif default: (*lfun)(LOG_ERR, "unsupported family %d", lss.ss_family); return NULL; @@ -1083,21 +1225,14 @@ conf_find(int fd, uid_t uid, const struct sockaddr_storage *rss, 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); @@ -1120,23 +1255,103 @@ conf_parse(const char *f) 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/blacklist/bin/conf.h b/contrib/blocklist/bin/conf.h similarity index 96% rename from contrib/blacklist/bin/conf.h rename to contrib/blocklist/bin/conf.h index 03f1942e3e3..8e4cd3a41fa 100644 --- a/contrib/blacklist/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/blacklist/bin/internal.c b/contrib/blocklist/bin/internal.c similarity index 90% rename from contrib/blacklist/bin/internal.c rename to contrib/blocklist/bin/internal.c index 5c039e4dc5d..625de55928d 100644 --- a/contrib/blacklist/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 @@ __RCSID("$NetBSD: internal.c,v 1.5 2015/01/27 19:40:37 christos Exp $"); #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/blacklist/bin/internal.h b/contrib/blocklist/bin/internal.h similarity index 90% rename from contrib/blacklist/bin/internal.h rename to contrib/blocklist/bin/internal.h index 5a40e49fbbd..553320e7afd 100644 --- a/contrib/blacklist/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/old_internal.c b/contrib/blocklist/bin/old_internal.c new file mode 100644 index 00000000000..79093cc8b8a --- /dev/null +++ b/contrib/blocklist/bin/old_internal.c @@ -0,0 +1,50 @@ +/* $NetBSD: internal.c,v 1.2 2025/02/11 17:48:30 christos Exp $ */ + +/*- + * Copyright (c) 2015 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_SYS_CDEFS_H +#include +#endif +__RCSID("$NetBSD: internal.c,v 1.2 2025/02/11 17:48:30 christos Exp $"); + +#include +#include +#include "conf.h" +#include "old_internal.h" + +int debug; +const char *rulename = "blacklistd"; +const char *controlprog = _PATH_BLCONTROL; +struct confset lconf, rconf; +struct ifaddrs *ifas; +void (*lfun)(int, const char *, ...) = syslog; diff --git a/contrib/blocklist/bin/old_internal.h b/contrib/blocklist/bin/old_internal.h new file mode 100644 index 00000000000..becee563e81 --- /dev/null +++ b/contrib/blocklist/bin/old_internal.h @@ -0,0 +1,58 @@ +/* $NetBSD: internal.h,v 1.1.1.1 2020/06/15 01:52:53 christos Exp $ */ + +/*- + * Copyright (c) 2015 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _OLD_INTERNAL_H +#define _OLD_INTERNAL_H + +#ifndef _PATH_BLCONF +#define _PATH_BLCONF "/etc/blacklistd.conf" +#endif +#ifndef _PATH_BLCONTROL +#define _PATH_BLCONTROL "/usr/libexec/blacklistd-helper" +#endif +#ifndef _PATH_BLSTATE +/* We want the new name, the old one would be incompatible after 24932b6 */ +#define _PATH_BLSTATE "/var/db/blocklistd.db" +#endif + +extern struct confset rconf, lconf; +extern int debug; +extern const char *rulename; +extern const char *controlprog; +extern struct ifaddrs *ifas; + +#if !defined(__syslog_attribute__) && !defined(__syslog__) +#define __syslog__ __printf__ +#endif + +extern void (*lfun)(int, const char *, ...) + __attribute__((__format__(__syslog__, 2, 3))); + +#endif /* _OLD_INTERNAL_H */ diff --git a/contrib/blacklist/bin/run.c b/contrib/blocklist/bin/run.c similarity index 93% rename from contrib/blacklist/bin/run.c rename to contrib/blocklist/bin/run.c index e11f8b28e2e..90071291811 100644 --- a/contrib/blacklist/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.4 2026/02/07 14:29:09 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.4 2026/02/07 14:29:09 christos Exp $"); #include #ifdef HAVE_LIBUTIL_H @@ -132,7 +134,8 @@ run_change(const char *how, const struct conf *c, char *id, size_t len) 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/blacklist/bin/run.h b/contrib/blocklist/bin/run.h similarity index 96% rename from contrib/blacklist/bin/run.h rename to contrib/blocklist/bin/run.h index bafc3e55469..da21906e0db 100644 --- a/contrib/blacklist/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/blacklist/bin/state.c b/contrib/blocklist/bin/state.c similarity index 96% rename from contrib/blacklist/bin/state.c rename to contrib/blocklist/bin/state.c index f2622c82c25..bb93904f348 100644 --- a/contrib/blacklist/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.3 2025/10/25 18:43:51 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.3 2025/10/25 18:43:51 christos Exp $"); #include #include @@ -129,7 +131,7 @@ state_del(DB *db, const struct conf *c) (*lfun)(LOG_DEBUG, "%s: returns %d", __func__, rv); (*db->sync)(db, 0); } - return 0; + return rv; default: (*lfun)(LOG_ERR, "%s: failed (%m)", __func__); return -1; diff --git a/contrib/blacklist/bin/state.h b/contrib/blocklist/bin/state.h similarity index 96% rename from contrib/blacklist/bin/state.h rename to contrib/blocklist/bin/state.h index 2e9257006e8..48f63a41ef3 100644 --- a/contrib/blacklist/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/blacklist/bin/support.c b/contrib/blocklist/bin/support.c similarity index 92% rename from contrib/blacklist/bin/support.c rename to contrib/blocklist/bin/support.c index 3e14fcbdc68..66d6ccce7db 100644 --- a/contrib/blacklist/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.4 2026/02/07 14:29:58 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.4 2026/02/07 14:29:58 christos Exp $"); #include #include @@ -66,7 +68,8 @@ expandm(char *buf, size_t len, const char *fmt) } 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 @@ dlog(int level, const char *fmt, ...) va_list ap; va_start(ap, fmt); - vdlog(level, fmt, ap); + vdlog(level, NULL, fmt, ap); va_end(ap); } diff --git a/contrib/blacklist/bin/support.h b/contrib/blocklist/bin/support.h similarity index 90% rename from contrib/blacklist/bin/support.h rename to contrib/blocklist/bin/support.h index 899649ce831..bb865cb8fe6 100644 --- a/contrib/blacklist/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/blacklist/diff/ftpd.diff b/contrib/blocklist/diff/ftpd.diff similarity index 92% rename from contrib/blacklist/diff/ftpd.diff rename to contrib/blocklist/diff/ftpd.diff index d28577f3ef5..37b43dae229 100644 --- a/contrib/blacklist/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 @@ diff -u -p -u -r1.63 Makefile 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 new file mode 100644 index 00000000000..75ebc74bde7 --- /dev/null +++ b/contrib/blocklist/diff/named.diff @@ -0,0 +1,161 @@ +Index: bin/named/Makefile +=================================================================== +RCS file: /cvsroot/src/external/mpl/bind/bin/named/Makefile,v +retrieving revision 1.6 +diff -u -p -u -r1.6 Makefile +--- bin/named/Makefile 21 Feb 2024 22:50:56 -0000 1.6 ++++ bin/named/Makefile 9 Apr 2026 15:53:58 -0000 +@@ -47,5 +47,7 @@ CLEANFILES+= xsl.c + + main.o: ${VERSIONFILE} + ++LDADD+=-lblocklist ++DPADD+=${LIBBLOCKLIST} + + .include +Index: dist/bin/named/main.c +=================================================================== +RCS file: /cvsroot/src/external/mpl/bind/dist/bin/named/main.c,v +retrieving revision 1.22 +diff -u -p -u -r1.22 main.c +--- dist/bin/named/main.c 8 Apr 2026 00:15:44 -0000 1.22 ++++ dist/bin/named/main.c 9 Apr 2026 15:53:59 -0000 +@@ -54,6 +54,8 @@ + + #include + ++#include "ns/pfilter.h" ++ + #ifdef HAVE_GPERFTOOLS_PROFILER + #include + #endif /* ifdef HAVE_GPERFTOOLS_PROFILER */ +@@ -1554,6 +1556,9 @@ main(int argc, char *argv[]) { + + parse_command_line(argc, argv); + ++ // Should we have a command line flag? ++ pfilter_enable(); ++ + #ifdef ENABLE_AFL + if (named_g_fuzz_type != isc_fuzz_none) { + named_fuzz_setup(); +Index: dist/lib/ns/client.c +=================================================================== +RCS file: /cvsroot/src/external/mpl/bind/dist/lib/ns/client.c,v +retrieving revision 1.27 +diff -u -p -u -r1.27 client.c +--- dist/lib/ns/client.c 8 Apr 2026 00:16:16 -0000 1.27 ++++ dist/lib/ns/client.c 9 Apr 2026 15:54:00 -0000 +@@ -66,6 +66,8 @@ + #include + #include + ++#include "pfilter.h" ++ + /*** + *** Client + ***/ +@@ -2703,6 +2705,7 @@ ns_client_checkacl(ns_client_t *client, + ns_client_log(client, DNS_LOGCATEGORY_SECURITY, + NS_LOGMODULE_CLIENT, log_level, "%s denied", + opname); ++ pfilter_notify(result, client, opname); + } + return result; + } +Index: dist/lib/ns/xfrout.c +=================================================================== +RCS file: /cvsroot/src/external/mpl/bind/dist/lib/ns/xfrout.c,v +retrieving revision 1.16 +diff -u -p -u -r1.16 xfrout.c +--- dist/lib/ns/xfrout.c 29 Jan 2026 18:37:56 -0000 1.16 ++++ dist/lib/ns/xfrout.c 9 Apr 2026 15:54:00 -0000 +@@ -48,6 +48,8 @@ + #include + #include + ++#include "pfilter.h" ++ + /*! \file + * \brief + * Outgoing AXFR and IXFR. +@@ -826,6 +828,7 @@ ns_xfr_start(ns_client_t *client, dns_rd + ISC_LOG_ERROR, + "zone transfer '%s/%s' denied", + _buf1, _buf2); ++ pfilter_notify(result, client, "zonexfr"); + goto cleanup; + } + if (result != ISC_R_SUCCESS) { +Index: include/ns/pfilter.h +=================================================================== +RCS file: /cvsroot/src/external/mpl/bind/include/ns/pfilter.h,v +retrieving revision 1.1 +diff -u -p -u -r1.1 pfilter.h +--- include/ns/pfilter.h 26 Jan 2025 16:30:19 -0000 1.1 ++++ include/ns/pfilter.h 9 Apr 2026 15:54:00 -0000 +@@ -1,2 +1,3 @@ + void pfilter_enable(void); +-void pfilter_notify(isc_result_t, ns_client_t *, const char *); ++struct ns_client; ++void pfilter_notify(isc_result_t, struct ns_client *, const char *); +Index: include/ns/pfilter.h +=================================================================== +RCS file: include/ns/pfilter.h +diff -N include/ns/pfilter.h +--- /dev/null 1 Jan 1970 00:00:00 -0000 ++++ include/ns/pfilter.h 9 Apr 2026 15:54:52 -0000 1.2 +@@ -0,0 +1,3 @@ ++void pfilter_enable(void); ++struct ns_client; ++void pfilter_notify(isc_result_t, struct ns_client *, const char *); +Index: lib/libns/pfilter.c +=================================================================== +RCS file: lib/libns/pfilter.c +diff -N lib/libns/pfilter.c +--- /dev/null 1 Jan 1970 00:00:00 -0000 ++++ lib/libns/pfilter.c 26 Jan 2025 16:30:19 -0000 1.1 +@@ -0,0 +1,43 @@ ++ ++#include ++#include ++#include ++ ++#include ++ ++#include ++ ++static struct blocklist *blstate; ++static int blenable; ++ ++void ++pfilter_enable(void) { ++ blenable = 1; ++} ++ ++#define TCP_CLIENT(c) (((c)->attributes & NS_CLIENTATTR_TCP) != 0) ++ ++void ++pfilter_notify(isc_result_t res, ns_client_t *client, const char *msg) ++{ ++ int fd; ++ ++ if (!blenable) ++ return; ++ ++ if (blstate == NULL) ++ blstate = blocklist_open(); ++ ++ if (blstate == NULL) ++ return; ++ ++ if (!TCP_CLIENT(client) && !client->peeraddr_valid) ++ return; ++ ++ if ((fd = isc_nmhandle_getfd(client->handle)) == -1) ++ return; ++ ++ blocklist_sa_r(blstate, ++ res != ISC_R_SUCCESS, fd, ++ &client->peeraddr.type.sa, client->peeraddr.length, msg); ++} diff --git a/contrib/blocklist/diff/postfix.diff b/contrib/blocklist/diff/postfix.diff new file mode 100644 index 00000000000..6f14389515c --- /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/blacklist/diff/proftpd.diff b/contrib/blocklist/diff/proftpd.diff similarity index 91% rename from contrib/blacklist/diff/proftpd.diff rename to contrib/blocklist/diff/proftpd.diff index 455b7cd60c6..e8d2cc5e9e0 100644 --- a/contrib/blacklist/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/blacklist/diff/ssh.diff b/contrib/blocklist/diff/ssh.diff similarity index 94% rename from contrib/blacklist/diff/ssh.diff rename to contrib/blocklist/diff/ssh.diff index 9427fc8ddb3..17300bb5dc8 100644 --- a/contrib/blacklist/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 @@ diff -u -u -r1.10 Makefile 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 new file mode 100644 index 00000000000..f4f2dc79f85 --- /dev/null +++ b/contrib/blocklist/etc/Makefile @@ -0,0 +1,10 @@ +# $NetBSD: Makefile,v 1.2 2025/02/05 20:24:26 christos Exp $ + +SUBDIR= rc.d + +FILESDIR= /usr/share/examples/blocklist +FILESMODE= 644 +FILES= blocklistd.conf ipf.conf npf.conf + +.include +.include diff --git a/contrib/blacklist/etc/blacklistd.conf b/contrib/blocklist/etc/blocklistd.conf similarity index 50% rename from contrib/blacklist/etc/blacklistd.conf rename to contrib/blocklist/etc/blocklistd.conf index f061b004ad3..49eb99a4107 100644 --- a/contrib/blacklist/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 @@ domain * * named * 3 12h #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 * * * = * * +#192.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 index 00000000000..f6bec74238d --- /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/blacklist/etc/npf.conf b/contrib/blocklist/etc/npf.conf similarity index 65% rename from contrib/blacklist/etc/npf.conf rename to contrib/blocklist/etc/npf.conf index 42d56044ad6..b1c33f2738f 100644 --- a/contrib/blacklist/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 @@ set bpf.jit on; 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 new file mode 100644 index 00000000000..9e214984f7c --- /dev/null +++ b/contrib/blocklist/etc/rc.d/Makefile @@ -0,0 +1,6 @@ +# $NetBSD: Makefile,v 1.1.1.1 2020/06/15 01:52:53 christos Exp $ + +SCRIPTS=blocklistd +SCRIPTSDIR=/etc/rc.d + +.include diff --git a/contrib/blacklist/etc/rc.d/blacklistd b/contrib/blocklist/etc/rc.d/blocklistd similarity index 71% rename from contrib/blacklist/etc/rc.d/blacklistd rename to contrib/blocklist/etc/rc.d/blocklistd index 278a6742e63..89871ebda4a 100644 --- a/contrib/blacklist/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 @@ start_precmd="${name}_precmd" 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 @@ blacklistd_precmd() 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/blacklist/include/Makefile b/contrib/blocklist/include/Makefile similarity index 57% rename from contrib/blacklist/include/Makefile rename to contrib/blocklist/include/Makefile index 6854907be25..b7ce1eca278 100644 --- a/contrib/blacklist/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/blacklist/include/bl.h b/contrib/blocklist/include/bl.h similarity index 89% rename from contrib/blacklist/include/bl.h rename to contrib/blocklist/include/bl.h index 8f366de912f..c7ed517d7a6 100644 --- a/contrib/blacklist/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 @@ typedef struct { #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/blacklist/include/blacklist.h b/contrib/blocklist/include/blacklist.h similarity index 88% rename from contrib/blacklist/include/blacklist.h rename to contrib/blocklist/include/blacklist.h index 2f5c8ba0986..f97cf34c4bc 100644 --- a/contrib/blacklist/include/blacklist.h +++ b/contrib/blocklist/include/blacklist.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. @@ -32,16 +32,26 @@ #define _BLACKLIST_H #include +#include -__BEGIN_DECLS +#if defined(__cplusplus) +extern "C" { +#endif + +struct syslog_data; struct blacklist *blacklist_open(void); +struct blacklist *blacklist_open2( + void (*)(int, struct syslog_data *, const char *, va_list)); 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, const struct sockaddr *, socklen_t, const char *); -__END_DECLS + +#if defined(__cplusplus) +} +#endif /* action values for user applications */ #define BLACKLIST_API_ENUM 1 diff --git a/contrib/blocklist/include/blocklist.h b/contrib/blocklist/include/blocklist.h new file mode 100644 index 00000000000..f09e5139079 --- /dev/null +++ b/contrib/blocklist/include/blocklist.h @@ -0,0 +1,65 @@ +/* $NetBSD: blocklist.h,v 1.4 2025/02/11 17:42:17 christos Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _BLOCKLIST_H +#define _BLOCKLIST_H + +#include +#include + +#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 *); + +#if defined(__cplusplus) +} +#endif + +/* action values for user applications */ +#define BLOCKLIST_API_ENUM 1 +enum { + BLOCKLIST_AUTH_OK = 0, + BLOCKLIST_AUTH_FAIL, + BLOCKLIST_ABUSIVE_BEHAVIOR, + BLOCKLIST_BAD_USER +}; + +#endif /* _BLOCKLIST_H */ diff --git a/contrib/blocklist/include/old_bl.h b/contrib/blocklist/include/old_bl.h new file mode 100644 index 00000000000..1ab64a4d9b6 --- /dev/null +++ b/contrib/blocklist/include/old_bl.h @@ -0,0 +1,80 @@ +/* $NetBSD: bl.h,v 1.2 2024/08/02 17:11:55 christos Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _OLD_BL_H +#define _OLD_BL_H + +#include +#include +#include +#include +#include "blacklist.h" + +typedef enum { + BL_INVALID, + BL_ADD, + BL_DELETE, + BL_ABUSE, + BL_BADUSER +} bl_type_t; + +typedef struct { + bl_type_t bi_type; + int bi_fd; + uid_t bi_uid; + gid_t bi_gid; + socklen_t bi_slen; + struct sockaddr_storage bi_ss; + char bi_msg[1024]; +} bl_info_t; + +#define bi_cred bi_u._bi_cred + +/* We want the new name */ +#ifndef _PATH_BLSOCK +#define _PATH_BLSOCK "/var/run/blocklistd.sock" +#endif + +__BEGIN_DECLS + +typedef struct blacklist *bl_t; + +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 *); +int bl_getfd(bl_t); +bl_info_t *bl_recv(bl_t); +bool bl_isconnected(bl_t); + +__END_DECLS + +#endif /* _OLD_BL_H */ diff --git a/contrib/blocklist/lib/Makefile b/contrib/blocklist/lib/Makefile new file mode 100644 index 00000000000..147f311c478 --- /dev/null +++ b/contrib/blocklist/lib/Makefile @@ -0,0 +1,19 @@ +# $NetBSD: Makefile,v 1.1.1.1 2020/06/15 01:52:53 christos Exp $ + +.include + +USE_SHLIBDIR= yes + +CPPFLAGS+=-D_REENTRANT +#LIBDPLIBS+=pthread ${NETBSDSRCDIR}/lib/libpthread +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/blacklist/lib/bl.c b/contrib/blocklist/lib/bl.c similarity index 82% rename from contrib/blacklist/lib/bl.c rename to contrib/blocklist/lib/bl.c index a3aa4ef1f9f..80396ed12b2 100644 --- a/contrib/blacklist/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 @@ __RCSID("$NetBSD: bl.c,v 1.28 2016/07/29 17:13:09 christos Exp $"); #include #endif +#if defined(SO_RECVUCRED) +#include +#endif + #include "bl.h" typedef struct { @@ -68,7 +74,7 @@ typedef struct { 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 @@ struct blacklist { 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 @@ bl_reset(bl_t b, bool locked) } 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 @@ bl_init(bl_t b, bool srv) 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 @@ bl_init(bl_t b, bool srv) 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 @@ bl_init(bl_t b, bool srv) * 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_init(bl_t b, bool srv) 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 @@ bl_init(bl_t b, bool srv) (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 @@ bl_init(bl_t b, bool srv) #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 @@ bl_init(bl_t b, bool srv) #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 @@ bl_init(bl_t b, bool srv) #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_init(bl_t b, bool srv) } 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_create(bool srv, const char *path, void (*fun)(int, const char *, va_list)) 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 @@ bl_getsock(bl_t b, struct sockaddr_storage *ss, const struct sockaddr *sa, 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 @@ bl_getsock(bl_t b, struct sockaddr_storage *ss, const struct sockaddr *sa, 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 @@ bl_getsock(bl_t b, struct sockaddr_storage *ss, const struct sockaddr *sa, #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 @@ bl_recv(bl_t b) 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 @@ bl_recv(bl_t b) 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 @@ bl_recv(bl_t b) 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 @@ bl_recv(bl_t b) #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,24 +516,23 @@ bl_recv(bl_t b) } 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 "", (got & GOT_FD) == 0 ? "fd" : ""); - return NULL; } 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; } @@ -524,10 +543,12 @@ bl_recv(bl_t b) 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/blacklist/lib/blacklist.c b/contrib/blocklist/lib/blacklist.c similarity index 88% rename from contrib/blacklist/lib/blacklist.c rename to contrib/blocklist/lib/blacklist.c index ba376c3daf0..12e5f83e09a 100644 --- a/contrib/blacklist/lib/blacklist.c +++ b/contrib/blocklist/lib/blacklist.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,11 +32,13 @@ #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 +#include #include #include @@ -98,7 +100,14 @@ blacklist_r(struct blacklist *bl, int action, int rfd, const char *msg) struct blacklist * blacklist_open(void) { - return bl_create(false, NULL, vsyslog); + return bl_create(false, NULL, vsyslog_r); +} + +struct blacklist * +blacklist_open2( + void (*logger)(int, struct syslog_data *, const char *, va_list)) +{ + return bl_create(false, NULL, logger); } void diff --git a/contrib/blocklist/lib/blocklist.c b/contrib/blocklist/lib/blocklist.c new file mode 100644 index 00000000000..139fc434262 --- /dev/null +++ b/contrib/blocklist/lib/blocklist.c @@ -0,0 +1,117 @@ +/* $NetBSD: blocklist.c,v 1.4 2025/02/11 17:48:30 christos Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_SYS_CDEFS_H +#include +#endif +__RCSID("$NetBSD: blocklist.c,v 1.4 2025/02/11 17:48:30 christos Exp $"); + +#include +#include + +#include +#include +#include +#include +#include + +int +blocklist_sa(int action, int rfd, const struct sockaddr *sa, socklen_t salen, + const char *msg) +{ + struct blocklist *bl; + int rv; + if ((bl = blocklist_open()) == NULL) + return -1; + rv = blocklist_sa_r(bl, action, rfd, sa, salen, msg); + blocklist_close(bl); + return rv; +} + +int +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 BLOCKLIST_AUTH_FAIL: + internal_action = BL_ADD; + break; + case BLOCKLIST_AUTH_OK: + internal_action = BL_DELETE; + break; + case BLOCKLIST_ABUSIVE_BEHAVIOR: + internal_action = BL_ABUSE; + break; + case BLOCKLIST_BAD_USER: + internal_action = BL_BADUSER; + break; + default: + internal_action = BL_INVALID; + break; + } + return bl_send(bl, internal_action, rfd, sa, slen, msg); +} + +int +blocklist(int action, int rfd, const char *msg) +{ + return blocklist_sa(action, rfd, NULL, 0, msg); +} + +int +blocklist_r(struct blocklist *bl, int action, int rfd, const char *msg) +{ + return blocklist_sa_r(bl, action, rfd, NULL, 0, msg); +} + +struct blocklist * +blocklist_open(void) { + return bl_create(false, NULL, vsyslog_r); +} + +struct blocklist * +blocklist_open2( + void (*logger)(int, struct syslog_data *, const char *, va_list)) +{ + return bl_create(false, NULL, logger); +} + +void +blocklist_close(struct blocklist *bl) +{ + bl_destroy(bl); +} diff --git a/contrib/blacklist/lib/libblacklist.3 b/contrib/blocklist/lib/libblacklist.3 similarity index 82% rename from contrib/blacklist/lib/libblacklist.3 rename to contrib/blocklist/lib/libblacklist.3 index aaf809469e6..5bc093c38f7 100644 --- a/contrib/blacklist/lib/libblacklist.3 +++ b/contrib/blocklist/lib/libblacklist.3 @@ -1,4 +1,4 @@ -.\" $NetBSD: libblacklist.3,v 1.8 2017/10/22 10:31:57 abhinav 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,11 +27,12 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd May 5, 2017 +.Dd February 5, 2025 .Dt LIBBLACKLIST 3 .Os .Sh NAME .Nm blacklist_open , +.Nm blacklist_open2 , .Nm blacklist_close , .Nm blacklist_r , .Nm blacklist , @@ -44,6 +45,8 @@ .In blacklist.h .Ft struct blacklist * .Fn blacklist_open "void" +.Ft struct blacklist * +.Fn blacklist_open2 "void (*logger)(int, struct syslog_data *, va_list)" .Ft void .Fn blacklist_close "struct blacklist *cookie" .Ft int @@ -68,6 +71,19 @@ and returns a pointer to it, or .Dv NULL on failure. .Pp +The function +.Fn blacklist_open2 +is similar to +.Fn blacklist_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 function frees all memory and resources used. @@ -89,24 +105,26 @@ argument. The .Ar action parameter can take these values: -.Bl -tag -width ".Va BLACKLIST_ABUSIVE_BEHAVIOR" -.It Va BLACKLIST_AUTH_FAIL +.Bl -tag -width ".Dv BLACKLIST_ABUSIVE_BEHAVIOR" +.It Dv BLACKLIST_AUTH_FAIL There was an unsuccessful authentication attempt. -.It Va BLACKLIST_AUTH_OK +.It Dv BLACKLIST_AUTH_OK A user successfully authenticated. -.It Va BLACKLIST_ABUSIVE_BEHAVIOR +.It Dv BLACKLIST_ABUSIVE_BEHAVIOR The sending daemon has detected abusive behavior -from the remote system. The remote address should +from the remote system. +The remote address should be blocked as soon as possible. -.It Va BLACKLIST_BAD_USER +.It Dv BLACKLIST_BAD_USER The sending daemon has determined the username -presented for authentication is invalid. The +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 +.Dv BLACKLIST_BAD_USER support is not currently available.) .El .Pp @@ -122,6 +140,14 @@ functions can be used with unconnected sockets, where .Xr getpeername 2 will not work, the server will pass the peer name in the message. .Pp +In all cases the file descriptor passed in the +.Fa fd +argument must be pointing to a valid socket so that +.Xr blacklistd 8 +can establish ownership of the local endpoint +using +.Xr getsockname 2 . +.Pp By default, .Xr syslogd 8 is used for message logging. @@ -150,6 +176,11 @@ on success and on failure setting .Dv errno to an appropriate value. +.Sh NOTES +The +.Lb libblacklist +has been renamed to +.Xr libblocklist 3 . .Sh SEE ALSO .Xr blacklistd.conf 5 , .Xr blacklistd 8 diff --git a/contrib/blocklist/lib/libblocklist.3 b/contrib/blocklist/lib/libblocklist.3 new file mode 100644 index 00000000000..7a016625a04 --- /dev/null +++ b/contrib/blocklist/lib/libblocklist.3 @@ -0,0 +1,177 @@ +.\" $NetBSD: libblocklist.3,v 1.7 2025/02/05 20:14:30 christos Exp $ +.\" +.\" Copyright (c) 2015 The NetBSD Foundation, Inc. +.\" All rights reserved. +.\" +.\" This code is derived from software contributed to The NetBSD Foundation +.\" by Christos Zoulas. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS +.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd February 5, 2025 +.Dt LIBBLOCKLIST 3 +.Os +.Sh NAME +.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 libblocklist +.Sh SYNOPSIS +.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 blocklist_close "struct blocklist *cookie" +.Ft int +.Fn blocklist "int action" "int fd" "const char *msg" +.Ft int +.Fn blocklist_r "struct blocklist *cookie" "int action" "int fd" "const char *msg" +.Ft int +.Fn blocklist_sa "int action" "int fd" "const struct sockaddr *sa" "socklen_t salen" "const char *msg" +.Ft int +.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 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 blocklist_open +creates the necessary state to communicate with +.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 blocklist_close +function frees all memory and resources used. +.Pp +The +.Fn blocklist +function sends a message to +.Xr blocklistd 8 , +with an integer +.Ar action +argument specifying the type of notification, +a file descriptor +.Ar fd +specifying the accepted file descriptor connected to the client, +and an optional message in the +.Ar msg +argument. +.Pp +The +.Ar action +parameter can take these values: +.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. +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 blocklist_r +function is more efficient because it keeps the blocklist state around. +.Pp +The +.Fn blocklist_sa +and +.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. +.Pp +In all cases the file descriptor passed in the +.Fa fd +argument must be pointing to a valid socket so that +.Xr blocklistd 8 +can establish ownership of the local endpoint +using +.Xr getsockname 2 . +.Pp +By default, +.Xr syslogd 8 +is used for message logging. +The internal +.Fn bl_create +function can be used to create the required internal +state and specify a custom logging function. +.Sh RETURN VALUES +The function +.Fn blocklist_open +returns a cookie on success and +.Dv NULL +on failure setting +.Dv errno +to an appropriate value. +.Pp +The functions +.Fn blocklist , +.Fn blocklist_sa , +and +.Fn blocklist_sa_r +return +.Dv 0 +on success and +.Dv \-1 +on failure setting +.Dv errno +to an appropriate value. +.Sh SEE ALSO +.Xr blocklistd.conf 5 , +.Xr blocklistd 8 +.Sh AUTHORS +.An Christos Zoulas diff --git a/contrib/blocklist/lib/old_bl.c b/contrib/blocklist/lib/old_bl.c new file mode 100644 index 00000000000..ffbbd3f620a --- /dev/null +++ b/contrib/blocklist/lib/old_bl.c @@ -0,0 +1,554 @@ +/* $NetBSD: bl.c,v 1.9 2025/03/30 01:53:59 christos Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_SYS_CDEFS_H +#include +#endif +__RCSID("$NetBSD: bl.c,v 1.9 2025/03/30 01:53:59 christos Exp $"); + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef _REENTRANT +#include +#endif + +#if defined(SO_RECVUCRED) +#include +#endif + +#include "old_bl.h" + +typedef struct { + uint32_t bl_len; + uint32_t bl_version; + uint32_t bl_type; + uint32_t bl_salen; + struct sockaddr_storage bl_ss; + char bl_data[]; +} bl_message_t; + +struct blacklist { +#ifdef _REENTRANT + pthread_mutex_t b_mutex; +# define BL_INIT(b) pthread_mutex_init(&b->b_mutex, NULL) +# define BL_LOCK(b) pthread_mutex_lock(&b->b_mutex) +# define BL_UNLOCK(b) pthread_mutex_unlock(&b->b_mutex) +#else +# define BL_INIT(b) do {} while(/*CONSTCOND*/0) +# define BL_LOCK(b) BL_INIT(b) +# define BL_UNLOCK(b) BL_INIT(b) +#endif + int b_fd; + int b_connected; + struct sockaddr_un b_sun; + struct syslog_data b_syslog_data; + void (*b_fun)(int, struct syslog_data *, const char *, va_list); + bl_info_t b_info; +}; + +#define BL_VERSION 1 + +bool +bl_isconnected(bl_t b) +{ + return b->b_connected == 0; +} + +int +bl_getfd(bl_t b) +{ + return b->b_fd; +} + +static void +bl_reset(bl_t b, bool locked) +{ + int serrno = errno; + if (!locked) + BL_LOCK(b); + close(b->b_fd); + errno = serrno; + b->b_fd = -1; + b->b_connected = -1; + if (!locked) + BL_UNLOCK(b); +} + +static void +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); + (*b->b_fun)(level, &b->b_syslog_data, fmt, ap); + va_end(ap); + errno = serrno; +} + +static int +bl_init(bl_t b, bool srv) +{ + static int one = 1; + /* AF_UNIX address of local logger */ + mode_t om; + int rv, serrno; + struct sockaddr_un *sun = &b->b_sun; + +#ifndef SOCK_NONBLOCK +#define SOCK_NONBLOCK 0 +#endif +#ifndef SOCK_CLOEXEC +#define SOCK_CLOEXEC 0 +#endif +#ifndef SOCK_NOSIGPIPE +#define SOCK_NOSIGPIPE 0 +#endif + + BL_LOCK(b); + + if (b->b_fd == -1) { + b->b_fd = socket(PF_LOCAL, + SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK|SOCK_NOSIGPIPE, 0); + if (b->b_fd == -1) { + bl_log(b, LOG_ERR, "%s: socket failed (%s)", + __func__, strerror(errno)); + BL_UNLOCK(b); + return -1; + } +#if SOCK_CLOEXEC == 0 + fcntl(b->b_fd, F_SETFD, FD_CLOEXEC); +#endif +#if SOCK_NONBLOCK == 0 + fcntl(b->b_fd, F_SETFL, fcntl(b->b_fd, F_GETFL) | O_NONBLOCK); +#endif +#if SOCK_NOSIGPIPE == 0 +#ifdef SO_NOSIGPIPE + int o = 1; + setsockopt(b->b_fd, SOL_SOCKET, SO_NOSIGPIPE, &o, sizeof(o)); +#else + signal(SIGPIPE, SIG_IGN); +#endif +#endif + } + + if (bl_isconnected(b)) { + BL_UNLOCK(b); + return 0; + } + + /* + * We try to connect anyway even when we are a server to verify + * that no other server is listening to the socket. If we succeed + * to connect and we are a server, someone else owns it. + */ + rv = connect(b->b_fd, (const void *)sun, (socklen_t)sizeof(*sun)); + if (rv == 0) { + if (srv) { + bl_log(b, LOG_ERR, + "%s: another daemon is handling `%s'", + __func__, sun->sun_path); + goto out; + } + } else { + if (!srv) { + /* + * If the daemon is not running, we just try a + * connect, so leave the socket alone until it does + * and only log once. + */ + if (b->b_connected != 1) { + bl_log(b, LOG_DEBUG, + "%s: connect failed for `%s' (%s)", + __func__, sun->sun_path, strerror(errno)); + b->b_connected = 1; + } + BL_UNLOCK(b); + return -1; + } + bl_log(b, LOG_DEBUG, "Connected to blacklist server", __func__); + } + + if (srv) { + (void)unlink(sun->sun_path); + om = umask(0); + rv = bind(b->b_fd, (const void *)sun, (socklen_t)sizeof(*sun)); + serrno = errno; + (void)umask(om); + errno = serrno; + if (rv == -1) { + bl_log(b, LOG_ERR, "%s: bind failed for `%s' (%s)", + __func__, sun->sun_path, strerror(errno)); + goto out; + } + } + + b->b_connected = 0; +#define GOT_FD 1 +#if defined(LOCAL_CREDS) +#define CRED_LEVEL 0 +#define CRED_NAME LOCAL_CREDS +#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 +#define GOT_CRED 2 +#elif defined(SO_PASSCRED) +#define CRED_LEVEL SOL_SOCKET +#define CRED_NAME SO_PASSCRED +#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 +/* + * getpeereid() and LOCAL_PEERCRED don't help here + * because we are not a stream socket! + */ +#define CRED_SIZE 0 +#define CRED_TYPE void * __unused +#endif + +#ifdef CRED_LEVEL + if (setsockopt(b->b_fd, CRED_LEVEL, CRED_NAME, + &one, (socklen_t)sizeof(one)) == -1) { + bl_log(b, LOG_ERR, "%s: setsockopt %s " + "failed (%s)", __func__, __STRING(CRED_NAME), + strerror(errno)); + goto out; + } +#endif + + BL_UNLOCK(b); + return 0; +out: + bl_reset(b, true); + BL_UNLOCK(b); + return -1; +} + +bl_t +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) + return NULL; + b->b_fun = fun; + b->b_syslog_data = sd; + b->b_fd = -1; + b->b_connected = -1; + BL_INIT(b); + + memset(&b->b_sun, 0, sizeof(b->b_sun)); + b->b_sun.sun_family = AF_LOCAL; +#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN + b->b_sun.sun_len = sizeof(b->b_sun); +#endif + strlcpy(b->b_sun.sun_path, + path ? path : _PATH_BLSOCK, sizeof(b->b_sun.sun_path)); + + bl_init(b, srv); + return b; +} + +void +bl_destroy(bl_t b) +{ + bl_reset(b, false); + free(b); +} + +static int +bl_getsock(bl_t b, struct sockaddr_storage *ss, const struct sockaddr *sa, + socklen_t slen, const char *ctx) +{ + uint8_t family; + + memset(ss, 0, sizeof(*ss)); + + switch (slen) { + case 0: + return 0; + case sizeof(struct sockaddr_in): + family = AF_INET; + break; + case sizeof(struct sockaddr_in6): + family = AF_INET6; + break; + default: + bl_log(b, LOG_ERR, "%s: invalid socket len %u (%s)", + __func__, (unsigned)slen, ctx); + errno = EINVAL; + return -1; + } + + memcpy(ss, sa, slen); + + if (ss->ss_family != family) { + bl_log(b, LOG_INFO, + "%s: correcting socket family %d to %d (%s)", + __func__, ss->ss_family, family, ctx); + ss->ss_family = family; + } + +#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN + if (ss->ss_len != slen) { + 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; + } +#endif + return 0; +} + +int +bl_send(bl_t b, bl_type_t e, int pfd, const struct sockaddr *sa, + socklen_t slen, const char *ctx) +{ + struct msghdr msg; + struct iovec iov; + union { + char ctrl[CMSG_SPACE(sizeof(int))]; + uint32_t fd; + } ua; + struct cmsghdr *cmsg; + union { + bl_message_t bl; + char buf[512]; + } ub; + size_t ctxlen, tried; +#define NTRIES 5 + + ctxlen = strlen(ctx); + if (ctxlen > 128) + ctxlen = 128; + + iov.iov_base = ub.buf; + iov.iov_len = sizeof(bl_message_t) + ctxlen; + ub.bl.bl_len = (uint32_t)iov.iov_len; + ub.bl.bl_version = BL_VERSION; + ub.bl.bl_type = (uint32_t)e; + + if (bl_getsock(b, &ub.bl.bl_ss, sa, slen, ctx) == -1) + return -1; + + + ub.bl.bl_salen = slen; + memcpy(ub.bl.bl_data, ctx, ctxlen); + + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_flags = 0; + + msg.msg_control = ua.ctrl; + msg.msg_controllen = sizeof(ua.ctrl); + + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + + memcpy(CMSG_DATA(cmsg), &pfd, sizeof(pfd)); + + tried = 0; +again: + if (bl_init(b, false) == -1) + return -1; + + if ((sendmsg(b->b_fd, &msg, 0) == -1) && tried++ < NTRIES) { + bl_reset(b, false); + goto again; + } + return tried >= NTRIES ? -1 : 0; +} + +bl_info_t * +bl_recv(bl_t b) +{ + struct msghdr msg; + struct iovec iov; + union { + char ctrl[CMSG_SPACE(sizeof(int)) + CMSG_SPACE(CRED_SIZE)]; + uint32_t fd; + } ua; + struct cmsghdr *cmsg; +#if GOT_CRED != 0 + CRED_TYPE *sc; +#endif + union { + bl_message_t bl; + char buf[512]; + } ub; + int got; + ssize_t rlen; + size_t rem; + bl_info_t *bi = &b->b_info; + + got = 0; + memset(bi, 0, sizeof(*bi)); + + iov.iov_base = ub.buf; + iov.iov_len = sizeof(ub); + + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_flags = 0; + + msg.msg_control = ua.ctrl; + msg.msg_controllen = sizeof(ua.ctrl); + + rlen = recvmsg(b->b_fd, &msg, 0); + if (rlen == -1) { + 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, LOG_ERR, + "%s: unexpected cmsg_level %d", + __func__, cmsg->cmsg_level); + continue; + } + switch (cmsg->cmsg_type) { + case SCM_RIGHTS: + if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) { + 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(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)); + got |= GOT_FD; + break; +#ifdef CRED_MESSAGE + case CRED_MESSAGE: + sc = (void *)CMSG_DATA(cmsg); + bi->bi_uid = CRED_SC_UID(sc); + bi->bi_gid = CRED_SC_GID(sc); + got |= GOT_CRED; + break; +#endif + default: + bl_log(b, LOG_ERR, + "%s: unexpected cmsg_type %d", + __func__, cmsg->cmsg_type); + continue; + } + + } + + if (got != (GOT_CRED|GOT_FD)) { + bl_log(b, LOG_ERR, "message missing %s %s", +#if GOT_CRED != 0 + (got & GOT_CRED) == 0 ? "cred" : +#endif + "", (got & GOT_FD) == 0 ? "fd" : ""); + return NULL; + } + + rem = (size_t)rlen; + if (rem < sizeof(ub.bl)) { + 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, LOG_ERR, "bad version %d", ub.bl.bl_version); + return NULL; + } + + bi->bi_type = ub.bl.bl_type; + bi->bi_slen = ub.bl.bl_salen; + bi->bi_ss = ub.bl.bl_ss; +#ifndef CRED_MESSAGE + bi->bi_uid = -1; + bi->bi_gid = -1; +#endif + if (rem == 0) + bi->bi_msg[0] = '\0'; + 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/blacklist/lib/shlib_version b/contrib/blocklist/lib/shlib_version similarity index 50% rename from contrib/blacklist/lib/shlib_version rename to contrib/blocklist/lib/shlib_version index 97c9f92d6b8..3d7c908e43d 100644 --- a/contrib/blacklist/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 new file mode 100644 index 00000000000..619d962c23b --- /dev/null +++ b/contrib/blocklist/libexec/Makefile @@ -0,0 +1,6 @@ +# $NetBSD: Makefile,v 1.1.1.1 2020/06/15 01:52:53 christos Exp $ + +SCRIPTS= blocklistd-helper +SCRIPTSDIR= /libexec + +.include diff --git a/contrib/blocklist/libexec/blocklistd-helper b/contrib/blocklist/libexec/blocklistd-helper new file mode 100755 index 00000000000..f27cde4ed4e --- /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/midnightbsd-changes.sh b/contrib/blocklist/midnightbsd-changes.sh new file mode 100644 index 00000000000..3ac589cd4cb --- /dev/null +++ b/contrib/blocklist/midnightbsd-changes.sh @@ -0,0 +1,20 @@ +#!/bin/sh +# +# MidnightBSD-specific changes from upstream, applied after a vendor +# merge. Derived from FreeBSD's freebsd-changes.sh. +# + +# Remove Debian port +rm -fr port/debian + +# /libexec -> /usr/libexec +sed -i '' -e 's| /libexec| /usr/libexec|g' bin/blocklistd.8 +sed -i '' -e 's|"/libexec|"/usr/libexec|g' bin/internal.h + +# NetBSD: RT_ROUNDUP -> MidnightBSD: SA_SIZE (from net/route.h) +sed -i '' -e 's/RT_ROUNDUP/SA_SIZE/g' bin/conf.c + +# npfctl(8) -> ipf(8), ipfw(8), pfctl(8) +sed -i '' -e 's/npfctl 8 ,/ipf 8 ,\ +.Xr ipfw 8 ,\ +.Xr pfctl 8 ,/g' bin/blocklistd.8 diff --git a/contrib/blocklist/port/Makefile.am b/contrib/blocklist/port/Makefile.am new file mode 100644 index 00000000000..0e6085f9580 --- /dev/null +++ b/contrib/blocklist/port/Makefile.am @@ -0,0 +1,39 @@ +# +ACLOCAL_AMFLAGS = -I m4 +lib_LTLIBRARIES = libblocklist.la +include_HEADERS = $(srcdir)/../include/blocklist.h + +exampledir = $(datarootdir)/examples +example_DATA = $(srcdir)/../etc/blocklistd.conf $(srcdir)/../etc/npf.conf $(srcdir)/../etc/ipf.conf + +sbin_PROGRAMS = blocklistd blocklistctl +noinst_PROGRAMS = srvtest cltest +libexec_SCRIPTS = $(srcdir)/../libexec/blocklistd-helper + +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@ + +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 +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 = libblocklist.la +cltest_SOURCES = cltest.c ${SRCS} +cltest_LDADD = libblocklist.la diff --git a/contrib/blacklist/port/_strtoi.h b/contrib/blocklist/port/_strtoi.h similarity index 97% rename from contrib/blacklist/port/_strtoi.h rename to contrib/blocklist/port/_strtoi.h index 4b2b4e80f0d..f50eefd67ff 100644 --- a/contrib/blacklist/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/blacklist/port/clock_gettime.c b/contrib/blocklist/port/clock_gettime.c similarity index 100% rename from contrib/blacklist/port/clock_gettime.c rename to contrib/blocklist/port/clock_gettime.c diff --git a/contrib/blacklist/port/config.h b/contrib/blocklist/port/config.h similarity index 100% rename from contrib/blacklist/port/config.h rename to contrib/blocklist/port/config.h diff --git a/contrib/blacklist/port/configure.ac b/contrib/blocklist/port/configure.ac similarity index 90% rename from contrib/blacklist/port/configure.ac rename to contrib/blocklist/port/configure.ac index eef8065f060..99ecf8732c9 100644 --- a/contrib/blacklist/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_HEADERS([config.h]) 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 @@ AC_PROG_LN_S 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 @@ dnl Checks for functions 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/blacklist/port/fgetln.c b/contrib/blocklist/port/fgetln.c similarity index 97% rename from contrib/blacklist/port/fgetln.c rename to contrib/blocklist/port/fgetln.c index a41a383a665..006e19f5279 100644 --- a/contrib/blacklist/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/blacklist/port/fparseln.c b/contrib/blocklist/port/fparseln.c similarity index 97% rename from contrib/blacklist/port/fparseln.c rename to contrib/blocklist/port/fparseln.c index 5bfae54b9a9..22850ea9e30 100644 --- a/contrib/blacklist/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/blacklist/port/getprogname.c b/contrib/blocklist/port/getprogname.c similarity index 100% rename from contrib/blacklist/port/getprogname.c rename to contrib/blocklist/port/getprogname.c diff --git a/contrib/blacklist/port/m4/.cvsignore b/contrib/blocklist/port/m4/.cvsignore similarity index 100% rename from contrib/blacklist/port/m4/.cvsignore rename to contrib/blocklist/port/m4/.cvsignore diff --git a/contrib/blacklist/port/pidfile.c b/contrib/blocklist/port/pidfile.c similarity index 96% rename from contrib/blacklist/port/pidfile.c rename to contrib/blocklist/port/pidfile.c index 4deb2349d20..1dbbf510c4e 100644 --- a/contrib/blacklist/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/blacklist/port/popenve.c b/contrib/blocklist/port/popenve.c similarity index 97% rename from contrib/blacklist/port/popenve.c rename to contrib/blocklist/port/popenve.c index df57cde9d51..30aac98a7f6 100644 --- a/contrib/blacklist/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.3 2026/02/07 14:26:07 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.3 2026/02/07 14:26:07 christos Exp $"); #endif #endif /* LIBC_SCCS and not lint */ diff --git a/contrib/blacklist/port/port.h b/contrib/blocklist/port/port.h similarity index 77% rename from contrib/blacklist/port/port.h rename to contrib/blocklist/port/port.h index f82fb34b40f..d1a9ac6bd6e 100644 --- a/contrib/blacklist/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 @@ int clock_gettime(int, struct timespec *); #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/blacklist/port/sockaddr_snprintf.c b/contrib/blocklist/port/sockaddr_snprintf.c similarity index 98% rename from contrib/blacklist/port/sockaddr_snprintf.c rename to contrib/blocklist/port/sockaddr_snprintf.c index 558755b6294..a37eded14a8 100644 --- a/contrib/blacklist/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/blacklist/port/strlcat.c b/contrib/blocklist/port/strlcat.c similarity index 93% rename from contrib/blacklist/port/strlcat.c rename to contrib/blocklist/port/strlcat.c index d3c69b5fab7..8cabd654e6b 100644 --- a/contrib/blacklist/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/blacklist/port/strlcpy.c b/contrib/blocklist/port/strlcpy.c similarity index 92% rename from contrib/blacklist/port/strlcpy.c rename to contrib/blocklist/port/strlcpy.c index 6646e1ce969..3de72a640c5 100644 --- a/contrib/blacklist/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/blacklist/port/strtoi.c b/contrib/blocklist/port/strtoi.c similarity index 92% rename from contrib/blacklist/port/strtoi.c rename to contrib/blocklist/port/strtoi.c index 5514f1a00a3..b0bed7058cc 100644 --- a/contrib/blacklist/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 index 00000000000..848f31b0445 --- /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/blacklist/test/Makefile b/contrib/blocklist/test/Makefile similarity index 70% rename from contrib/blacklist/test/Makefile rename to contrib/blocklist/test/Makefile index a451274def0..d127955acdb 100644 --- a/contrib/blacklist/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/blacklist/test/cltest.c b/contrib/blocklist/test/cltest.c similarity index 95% rename from contrib/blacklist/test/cltest.c rename to contrib/blocklist/test/cltest.c index 6671429fc3c..dc77a522bad 100644 --- a/contrib/blacklist/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/blacklist/test/srvtest.c b/contrib/blocklist/test/srvtest.c similarity index 86% rename from contrib/blacklist/test/srvtest.c rename to contrib/blocklist/test/srvtest.c index 03a762ab81f..4eb9468ed5f 100644 --- a/contrib/blacklist/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 @@ __RCSID("$NetBSD: srvtest.c,v 1.10 2015/05/30 22:40:38 christos Exp $"); #include #include -#include "blacklist.h" +#include "blocklist.h" #ifdef BLDEBUG #include "bl.h" static void *b; @@ -71,9 +73,9 @@ process_tcp(int afd) 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 @@ process_udp(int afd) 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 @@ static __dead void 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 @@ main(int argc, char *argv[]) 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 @@ main(int argc, char *argv[]) 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 diff --git a/crypto/openssh/auth-pam.c b/crypto/openssh/auth-pam.c index 09efa0c6c6c..b7c7e940f2d 100644 --- a/crypto/openssh/auth-pam.c +++ b/crypto/openssh/auth-pam.c @@ -100,7 +100,7 @@ #endif #include "monitor_wrap.h" #include "srclimit.h" -#include "blacklist_client.h" +#include "blocklist_client.h" extern ServerOptions options; extern struct sshbuf *loginmsg; @@ -917,7 +917,7 @@ sshpam_query(void *ctx, char **name, char **info, sshbuf_free(buffer); return (0); } - BLACKLIST_NOTIFY(NULL, BLACKLIST_AUTH_FAIL, + BLOCKLIST_NOTIFY(NULL, BLOCKLIST_AUTH_FAIL, "PAM illegal user"); error("PAM: %s for %s%.100s from %.100s", msg, sshpam_authctxt->valid ? "" : "illegal user ", diff --git a/crypto/openssh/auth.c b/crypto/openssh/auth.c index 0f77a3a7288..da1a674126d 100644 --- a/crypto/openssh/auth.c +++ b/crypto/openssh/auth.c @@ -73,7 +73,7 @@ #include "monitor_wrap.h" #include "ssherr.h" #include "channels.h" -#include "blacklist_client.h" +#include "blocklist_client.h" /* import */ extern ServerOptions options; @@ -287,7 +287,7 @@ auth_log(struct ssh *ssh, int authenticated, int partial, else { authmsg = authenticated ? "Accepted" : "Failed"; if (authenticated) - BLACKLIST_NOTIFY(ssh, BLACKLIST_AUTH_OK, + BLOCKLIST_NOTIFY(ssh, BLOCKLIST_AUTH_OK, "Authenticated"); } @@ -337,7 +337,7 @@ auth_maxtries_exceeded(struct ssh *ssh) { Authctxt *authctxt = (Authctxt *)ssh->authctxt; - BLACKLIST_NOTIFY(ssh, BLACKLIST_AUTH_FAIL, "Maximum attempts exceeded"); + BLOCKLIST_NOTIFY(ssh, BLOCKLIST_AUTH_FAIL, "Maximum attempts exceeded"); error("maximum authentication attempts exceeded for " "%s%.100s from %.200s port %d ssh2", authctxt->valid ? "" : "invalid user ", @@ -498,7 +498,7 @@ getpwnamallow(struct ssh *ssh, const char *user) aix_restoreauthdb(); #endif if (pw == NULL) { - BLACKLIST_NOTIFY(ssh, BLACKLIST_AUTH_FAIL, "Invalid user"); + BLOCKLIST_NOTIFY(ssh, BLOCKLIST_AUTH_FAIL, "Invalid user"); logit("Invalid user %.100s from %.100s port %d", user, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); #ifdef CUSTOM_FAILED_LOGIN diff --git a/crypto/openssh/blacklist.c b/crypto/openssh/blocklist.c similarity index 89% rename from crypto/openssh/blacklist.c rename to crypto/openssh/blocklist.c index 33d02607dd9..f3c00016db6 100644 --- a/crypto/openssh/blacklist.c +++ b/crypto/openssh/blocklist.c @@ -46,16 +46,16 @@ #include "log.h" #include "misc.h" #include "servconf.h" -#include -#include "blacklist_client.h" +#include +#include "blocklist_client.h" -static struct blacklist *blstate = NULL; +static struct blocklist *blstate = NULL; /* import */ extern ServerOptions options; /* internal definition from bl.h */ -struct blacklist *bl_create(bool, char *, void (*)(int, const char *, va_list)); +struct blocklist *bl_create(bool, char *, void (*)(int, const char *, va_list)); /* impedence match vsyslog() to sshd's internal logging levels */ void @@ -80,18 +80,18 @@ im_log(int priority, const char *message, va_list args) } void -blacklist_init(void) +blocklist_init(void) { - if (options.use_blacklist) + if (options.use_blocklist) blstate = bl_create(false, NULL, im_log); } void -blacklist_notify(struct ssh *ssh, int action, const char *msg) +blocklist_notify(struct ssh *ssh, int action, const char *msg) { if (blstate != NULL && ssh_packet_connection_is_on_socket(ssh)) - (void)blacklist_r(blstate, action, + (void)blocklist_r(blstate, action, ssh_packet_get_connection_in(ssh), msg); } diff --git a/crypto/openssh/blacklist_client.h b/crypto/openssh/blocklist_client.h similarity index 77% rename from crypto/openssh/blacklist_client.h rename to crypto/openssh/blocklist_client.h index 601a44461e2..be92245e469 100644 --- a/crypto/openssh/blacklist_client.h +++ b/crypto/openssh/blocklist_client.h @@ -31,31 +31,31 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef BLACKLIST_CLIENT_H -#define BLACKLIST_CLIENT_H +#ifndef BLOCKLIST_CLIENT_H +#define BLOCKLIST_CLIENT_H -#ifndef BLACKLIST_API_ENUM +#ifndef BLOCKLIST_API_ENUM 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 -#ifdef USE_BLACKLIST -void blacklist_init(void); -void blacklist_notify(struct ssh *, int, const char *); +#ifdef USE_BLOCKLIST +void blocklist_init(void); +void blocklist_notify(struct ssh *, int, const char *); -#define BLACKLIST_INIT() blacklist_init() -#define BLACKLIST_NOTIFY(ssh,x,msg) blacklist_notify(ssh,x,msg) +#define BLOCKLIST_INIT() blocklist_init() +#define BLOCKLIST_NOTIFY(ssh,x,msg) blocklist_notify(ssh,x,msg) #else -#define BLACKLIST_INIT() -#define BLACKLIST_NOTIFY(ssh,x,msg) +#define BLOCKLIST_INIT() +#define BLOCKLIST_NOTIFY(ssh,x,msg) #endif -#endif /* BLACKLIST_CLIENT_H */ +#endif /* BLOCKLIST_CLIENT_H */ diff --git a/crypto/openssh/monitor.c b/crypto/openssh/monitor.c index 1feab4ec89e..5994a7fc76d 100644 --- a/crypto/openssh/monitor.c +++ b/crypto/openssh/monitor.c @@ -75,7 +75,7 @@ #include "misc.h" #include "servconf.h" #include "monitor.h" -#include "blacklist_client.h" +#include "blocklist_client.h" #ifdef GSSAPI #include "ssh-gss.h" @@ -350,7 +350,7 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) } } if (authctxt->failures > options.max_authtries) { - BLACKLIST_NOTIFY(ssh, BLACKLIST_AUTH_FAIL, + BLOCKLIST_NOTIFY(ssh, BLOCKLIST_AUTH_FAIL, "Too many authentication attempts"); /* Shouldn't happen */ fatal_f("privsep child made too many authentication " @@ -359,12 +359,12 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) } if (!authctxt->valid) { - BLACKLIST_NOTIFY(ssh, BLACKLIST_AUTH_FAIL, + BLOCKLIST_NOTIFY(ssh, BLOCKLIST_AUTH_FAIL, "Authenticated invalid user"); fatal_f("authenticated invalid user"); } if (strcmp(auth_method, "unknown") == 0) { - BLACKLIST_NOTIFY(ssh, BLACKLIST_AUTH_FAIL, + BLOCKLIST_NOTIFY(ssh, BLOCKLIST_AUTH_FAIL, "Authentication method name unknown"); fatal_f("authentication method name unknown"); } diff --git a/crypto/openssh/servconf.c b/crypto/openssh/servconf.c index 63b50ea3d9b..b3df3ffe634 100644 --- a/crypto/openssh/servconf.c +++ b/crypto/openssh/servconf.c @@ -215,7 +215,7 @@ initialize_server_options(ServerOptions *options) options->sshd_session_path = NULL; options->sshd_auth_path = NULL; options->refuse_connection = -1; - options->use_blacklist = -1; + options->use_blocklist = -1; } /* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */ @@ -504,8 +504,8 @@ fill_default_server_options(ServerOptions *options) options->sshd_auth_path = xstrdup(_PATH_SSHD_AUTH); if (options->refuse_connection == -1) options->refuse_connection = 0; - if (options->use_blacklist == -1) - options->use_blacklist = 0; + if (options->use_blocklist == -1) + options->use_blocklist = 0; assemble_algorithms(options); @@ -590,7 +590,7 @@ typedef enum { sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider, sRequiredRSASize, sChannelTimeout, sUnusedConnectionTimeout, sSshdSessionPath, sSshdAuthPath, sRefuseConnection, - sUseBlacklist, + sUseBlocklist, sDeprecated, sIgnore, sUnsupported } ServerOpCodes; @@ -762,8 +762,8 @@ static struct { { "sshdsessionpath", sSshdSessionPath, SSHCFG_GLOBAL }, { "sshdauthpath", sSshdAuthPath, SSHCFG_GLOBAL }, { "refuseconnection", sRefuseConnection, SSHCFG_ALL }, - { "useblacklist", sUseBlacklist, SSHCFG_GLOBAL }, - { "useblocklist", sUseBlacklist, SSHCFG_GLOBAL }, /* alias */ + { "useblocklist", sUseBlocklist, SSHCFG_GLOBAL }, + { "useblacklist", sUseBlocklist, SSHCFG_GLOBAL }, /* alias */ { NULL, sBadOption, 0 } }; @@ -2779,8 +2779,8 @@ process_server_config_line_depth(ServerOptions *options, char *line, multistate_ptr = multistate_flag; goto parse_multistate; - case sUseBlacklist: - intptr = &options->use_blacklist; + case sUseBlocklist: + intptr = &options->use_blocklist; goto parse_flag; case sDeprecated: @@ -3337,7 +3337,7 @@ dump_config(ServerOptions *o) dump_cfg_fmtint(sFingerprintHash, o->fingerprint_hash); dump_cfg_fmtint(sExposeAuthInfo, o->expose_userauth_info); dump_cfg_fmtint(sRefuseConnection, o->refuse_connection); - dump_cfg_fmtint(sUseBlacklist, o->use_blacklist); + dump_cfg_fmtint(sUseBlocklist, o->use_blocklist); /* string arguments */ dump_cfg_string(sPidFile, o->pid_file); diff --git a/crypto/openssh/servconf.h b/crypto/openssh/servconf.h index 6830c31bde9..9f3db6e3b0a 100644 --- a/crypto/openssh/servconf.h +++ b/crypto/openssh/servconf.h @@ -256,7 +256,7 @@ typedef struct { int refuse_connection; - int use_blacklist; + int use_blocklist; } ServerOptions; /* Information about the incoming connection as used by Match */ diff --git a/crypto/openssh/sshd-session.c b/crypto/openssh/sshd-session.c index 8366c5ba33d..a0dacc119c3 100644 --- a/crypto/openssh/sshd-session.c +++ b/crypto/openssh/sshd-session.c @@ -90,7 +90,7 @@ #include "ssh-gss.h" #endif #include "auth-options.h" -#include "blacklist_client.h" +#include "blocklist_client.h" #include "dh.h" #include "monitor_wrap.h" #include "sk-api.h" @@ -1155,7 +1155,7 @@ main(int ac, char **av) ssh_signal(SIGCHLD, SIG_DFL); ssh_signal(SIGINT, SIG_DFL); - BLACKLIST_INIT(); + BLOCKLIST_INIT(); /* * Register our connection. This turns encryption off because we do @@ -1374,7 +1374,7 @@ cleanup_exit(int i) #endif /* Override default fatal exit value when auth was attempted */ if (i == 255 && monitor_auth_attempted()) { - BLACKLIST_NOTIFY(the_active_state, BLACKLIST_AUTH_FAIL, + BLOCKLIST_NOTIFY(the_active_state, BLOCKLIST_AUTH_FAIL, "Fatal exit"); _exit(EXIT_AUTH_ATTEMPTED); } diff --git a/crypto/openssh/sshd_config b/crypto/openssh/sshd_config index 04f77c66151..12919f75fc3 100644 --- a/crypto/openssh/sshd_config +++ b/crypto/openssh/sshd_config @@ -105,7 +105,7 @@ AuthorizedKeysFile .ssh/authorized_keys #MaxStartups 10:30:100 #PermitTunnel no #ChrootDirectory none -#UseBlacklist no +#UseBlocklist no #VersionAddendum MidnightBSD-20250324 # no default banner path diff --git a/crypto/openssh/sshd_config.5 b/crypto/openssh/sshd_config.5 index ac225aa91fb..c0e63f7bc3f 100644 --- a/crypto/openssh/sshd_config.5 +++ b/crypto/openssh/sshd_config.5 @@ -2052,20 +2052,20 @@ The default is to never expire connections for having no open channels. This option may be useful in conjunction with .Cm ChannelTimeout . -.It Cm UseBlacklist +.It Cm UseBlocklist Specifies whether .Xr sshd 8 attempts to send authentication success and failure messages to the -.Xr blacklistd 8 +.Xr blocklistd 8 daemon. The default is .Cm no . -For forward compatibility with an upcoming -.Xr blacklistd -rename, the -.Cm UseBlocklist -alias can be used instead. +For backward compatibility with +.Xr blacklistd 8 , +the +.Cm UseBlacklist +alias can still be used. .It Cm UseDNS Specifies whether .Xr sshd 8 diff --git a/lib/Makefile b/lib/Makefile index 239d6231615..20d45bdb491 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -164,6 +164,7 @@ SUBDIR_DEPEND_flua= libjail SUBDIR.${MK_ATM}+= libngatm SUBDIR.${MK_BEARSSL}+= libbearssl libsecureboot SUBDIR.${MK_BLACKLIST}+=libblacklist +SUBDIR.${MK_BLOCKLIST}+=libblocklist SUBDIR.${MK_BLUETOOTH}+=libbluetooth libsdp SUBDIR.${MK_BSNMP}+= libbsnmp diff --git a/lib/libblacklist/Makefile b/lib/libblacklist/Makefile index e8d25ac7f1b..f031ed01a77 100644 --- a/lib/libblacklist/Makefile +++ b/lib/libblacklist/Makefile @@ -1,7 +1,6 @@ +BLOCKLIST_DIR=${SRCTOP}/contrib/blocklist -BLACKLIST_DIR=${SRCTOP}/contrib/blacklist - -.PATH: ${BLACKLIST_DIR}/lib ${BLACKLIST_DIR}/include +.PATH: ${BLOCKLIST_DIR}/lib ${BLOCKLIST_DIR}/include ${BLOCKLIST_DIR}/port LIB= blacklist SHLIB_MAJOR= 0 @@ -10,12 +9,13 @@ LIBADD+= pthread CFLAGS.clang+=-Wno-thread-safety-analysis -CFLAGS+=-I${BLACKLIST_DIR}/include -I${BLACKLIST_DIR}/port \ +CFLAGS+=-I${BLOCKLIST_DIR}/include -I${BLOCKLIST_DIR}/port \ -D_REENTRANT -DHAVE_CONFIG_H -DHAVE_DB_H -DHAVE_LIBUTIL_H \ -DHAVE_CLOCK_GETTIME -DHAVE_FGETLN -DHAVE_GETPROGNAME \ - -DHAVE_STRLCAT -DHAVE_STRLCPY -DHAVE_STRUCT_SOCKADDR_SA_LEN + -DHAVE_STRLCAT -DHAVE_STRLCPY -DHAVE_STRUCT_SOCKADDR_SA_LEN \ + -DHAVE_SYS_CDEFS_H -SRCS= bl.c blacklist.c +SRCS= old_bl.c blacklist.c vsyslog_r.c INCS= blacklist.h MAN= libblacklist.3 diff --git a/lib/libblocklist/Makefile b/lib/libblocklist/Makefile new file mode 100644 index 00000000000..783b620aecc --- /dev/null +++ b/lib/libblocklist/Makefile @@ -0,0 +1,29 @@ +BLOCKLIST_DIR=${SRCTOP}/contrib/blocklist + +.PATH: ${BLOCKLIST_DIR}/lib ${BLOCKLIST_DIR}/include ${BLOCKLIST_DIR}/port + +LIB= blocklist +SHLIB_MAJOR= 0 + +LIBADD+= pthread + +CFLAGS.clang+=-Wno-thread-safety-analysis + +CFLAGS+=-I${BLOCKLIST_DIR}/include -I${BLOCKLIST_DIR}/port \ + -D_REENTRANT -DHAVE_CONFIG_H -DHAVE_DB_H -DHAVE_LIBUTIL_H \ + -DHAVE_CLOCK_GETTIME -DHAVE_FGETLN -DHAVE_GETPROGNAME \ + -DHAVE_STRLCAT -DHAVE_STRLCPY -DHAVE_STRUCT_SOCKADDR_SA_LEN \ + -DHAVE_SYS_CDEFS_H + +SRCS= bl.c blocklist.c vsyslog_r.c +INCS= blocklist.h +MAN= libblocklist.3 + +MLINKS= libblocklist.3 blocklist_open.3 \ + libblocklist.3 blocklist_close.3 \ + libblocklist.3 blocklist.3 \ + libblocklist.3 blocklist_r.3 \ + libblocklist.3 blocklist_sa.3 \ + libblocklist.3 blocklist_sa_r.3 + +.include diff --git a/lib/libblocklist/Makefile.depend b/lib/libblocklist/Makefile.depend new file mode 100644 index 00000000000..577dc5747f1 --- /dev/null +++ b/lib/libblocklist/Makefile.depend @@ -0,0 +1,16 @@ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + include \ + include/xlocale \ + lib/${CSU_DIR} \ + lib/libc \ + lib/libcompiler_rt \ + lib/libthr \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/lib/libsysdecode/Makefile.depend b/lib/libsysdecode/Makefile.depend index 93728767d4f..71e0b9b7095 100644 --- a/lib/libsysdecode/Makefile.depend +++ b/lib/libsysdecode/Makefile.depend @@ -33,7 +33,7 @@ DIRDEPS = \ lib/libalias/libalias \ lib/libarchive \ lib/libbegemot \ - lib/libblacklist \ + lib/libblocklist \ lib/libblocksruntime \ lib/libbluetooth \ lib/libbsdstat \ diff --git a/libexec/Makefile b/libexec/Makefile index 20d4883ec50..a0838cda22a 100644 --- a/libexec/Makefile +++ b/libexec/Makefile @@ -4,7 +4,7 @@ SUBDIR= ${_atf} \ ${_atrun} \ - ${_blacklistd-helper} \ + ${_blocklistd-helper} \ ${_comsat} \ ${_dma} \ flua \ @@ -48,8 +48,8 @@ SUBDIR= ${_atf} \ _atrun= atrun .endif -.if ${MK_BLACKLIST} != "no" -_blacklistd-helper+= blacklistd-helper +.if ${MK_BLOCKLIST} != "no" +_blocklistd-helper+= blocklistd-helper .endif .if ${MK_BOOTPD} != "no" diff --git a/libexec/blacklistd-helper/Makefile b/libexec/blacklistd-helper/Makefile deleted file mode 100644 index a22ba37fc76..00000000000 --- a/libexec/blacklistd-helper/Makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BLACKLIST_DIR=${SRCTOP}/contrib/blacklist - -SCRIPTS= ${BLACKLIST_DIR}/libexec/blacklistd-helper - -.include diff --git a/libexec/blocklistd-helper/Makefile b/libexec/blocklistd-helper/Makefile new file mode 100644 index 00000000000..25630ac8484 --- /dev/null +++ b/libexec/blocklistd-helper/Makefile @@ -0,0 +1,8 @@ +BLOCKLIST_DIR=${SRCTOP}/contrib/blocklist + +SCRIPTS= ${BLOCKLIST_DIR}/libexec/blocklistd-helper + +# Compatibility with the old blacklist name +SCRIPTS+= blacklistd-helper + +.include diff --git a/libexec/blacklistd-helper/Makefile.depend b/libexec/blocklistd-helper/Makefile.depend similarity index 100% rename from libexec/blacklistd-helper/Makefile.depend rename to libexec/blocklistd-helper/Makefile.depend diff --git a/contrib/blacklist/libexec/blacklistd-helper b/libexec/blocklistd-helper/blacklistd-helper similarity index 88% rename from contrib/blacklist/libexec/blacklistd-helper rename to libexec/blocklistd-helper/blacklistd-helper index fa53c8c8493..4195f070e8e 100644 --- a/contrib/blacklist/libexec/blacklistd-helper +++ b/libexec/blocklistd-helper/blacklistd-helper @@ -11,6 +11,11 @@ pf= if [ -f "/etc/ipfw-blacklist.rc" ]; then + echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" >&2 + echo "@ WARNING: rename /etc/ipfw-blacklist.rc to @" >&2 + echo "@ /etc/ipfw-blocklist.rc @" >&2 + echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" >&2 + pf="ipfw" . /etc/ipfw-blacklist.rc ipfw_offset=${ipfw_offset:-2000} @@ -65,6 +70,22 @@ case "$4" in fi;; esac +if [ "$pf" = "pf" ]; then + for anchor in $(/sbin/pfctl -s Anchors 2> /dev/null); do + if [ "$anchor" = "blacklistd" ]; then + echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" >&2 + echo "@ WARNING: rename the blacklist anchor to blocklist @" >&2 + echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" >&2 + fi + done +fi + +if [ "$pf" = "ipfilter" ]; then + echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" >&2 + echo "@ WARNING: blacklist has been renamed to blocklist @" >&2 + echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" >&2 +fi + case "$1" in add) case "$pf" in diff --git a/libexec/fingerd/Makefile b/libexec/fingerd/Makefile index f0f797ad02d..a702706856c 100644 --- a/libexec/fingerd/Makefile +++ b/libexec/fingerd/Makefile @@ -9,10 +9,10 @@ MAN= fingerd.8 WARNS?= 2 WFORMAT=0 -.if ${MK_BLACKLIST_SUPPORT} != "no" -CFLAGS+= -DUSE_BLACKLIST -I${SRCTOP}/contrib/blacklist/include -LIBADD+= blacklist -LDFLAGS+=-L${LIBBLACKLISTDIR} +.if ${MK_BLOCKLIST_SUPPORT} != "no" +CFLAGS+= -DUSE_BLOCKLIST -I${SRCTOP}/contrib/blocklist/include +LIBADD+= blocklist +LDFLAGS+=-L${LIBBLOCKLISTDIR} .endif .include diff --git a/libexec/fingerd/Makefile.depend.options b/libexec/fingerd/Makefile.depend.options index 5a94eff626d..f68343adae8 100644 --- a/libexec/fingerd/Makefile.depend.options +++ b/libexec/fingerd/Makefile.depend.options @@ -1,5 +1,5 @@ # This file is not autogenerated - take care! -DIRDEPS_OPTIONS= BLACKLIST_SUPPORT +DIRDEPS_OPTIONS= BLOCKLIST_SUPPORT .include diff --git a/libexec/fingerd/fingerd.c b/libexec/fingerd/fingerd.c index dd51064a00a..e8376605e87 100644 --- a/libexec/fingerd/fingerd.c +++ b/libexec/fingerd/fingerd.c @@ -57,8 +57,8 @@ static char sccsid[] = "@(#)fingerd.c 8.1 (Berkeley) 6/4/93"; #include #include #include "pathnames.h" -#ifdef USE_BLACKLIST -#include +#ifdef USE_BLOCKLIST +#include #endif void logerr(const char *, ...) __printflike(1, 2) __dead2; @@ -156,8 +156,8 @@ main(int argc, char *argv[]) *ap = strtok(lp, " \t\r\n"); if (!*ap) { if (secure && ap == &av[4]) { -#ifdef USE_BLACKLIST - blacklist(1, STDIN_FILENO, "nousername"); +#ifdef USE_BLOCKLIST + blocklist(1, STDIN_FILENO, "nousername"); #endif puts("must provide username\r\n"); exit(1); @@ -165,8 +165,8 @@ main(int argc, char *argv[]) break; } if (secure && strchr(*ap, '@')) { -#ifdef USE_BLACKLIST - blacklist(1, STDIN_FILENO, "noforwarding"); +#ifdef USE_BLOCKLIST + blocklist(1, STDIN_FILENO, "noforwarding"); #endif puts("forwarding service denied\r\n"); exit(1); @@ -206,8 +206,8 @@ main(int argc, char *argv[]) } dup2(STDOUT_FILENO, STDERR_FILENO); -#ifdef USE_BLACKLIST - blacklist(0, STDIN_FILENO, "success"); +#ifdef USE_BLOCKLIST + blocklist(0, STDIN_FILENO, "success"); #endif execv(prog, comp); write(STDERR_FILENO, prog, strlen(prog)); diff --git a/libexec/ftpd/Makefile b/libexec/ftpd/Makefile index bc35f995acf..40aedb0d98c 100644 --- a/libexec/ftpd/Makefile +++ b/libexec/ftpd/Makefile @@ -25,11 +25,11 @@ SRCS+= ls.c cmp.c print.c util.c CFLAGS+=-Dmain=ls_main -I${SRCTOP}/bin/ls LIBADD+= m -.if ${MK_BLACKLIST_SUPPORT} != "no" -CFLAGS+= -DUSE_BLACKLIST -I${SRCTOP}/contrib/blacklist/include -SRCS+= blacklist.c -LIBADD+= blacklist -LDFLAGS+=-L${LIBBLACKLISTDIR} +.if ${MK_BLOCKLIST_SUPPORT} != "no" +CFLAGS+= -DUSE_BLOCKLIST -I${SRCTOP}/contrib/blocklist/include +SRCS+= blocklist.c +LIBADD+= blocklist +LDFLAGS+=-L${LIBBLOCKLISTDIR} .endif .if ${MK_INET6_SUPPORT} != "no" diff --git a/libexec/ftpd/Makefile.depend.options b/libexec/ftpd/Makefile.depend.options index 5f186bb031f..f5b76378ab2 100644 --- a/libexec/ftpd/Makefile.depend.options +++ b/libexec/ftpd/Makefile.depend.options @@ -1,5 +1,5 @@ # This file is not autogenerated - take care! -DIRDEPS_OPTIONS= BLACKLIST_SUPPORT PAM_SUPPORT +DIRDEPS_OPTIONS= BLOCKLIST_SUPPORT PAM_SUPPORT .include diff --git a/libexec/ftpd/blacklist.c b/libexec/ftpd/blocklist.c similarity index 84% rename from libexec/ftpd/blacklist.c rename to libexec/ftpd/blocklist.c index 0a45f936907..159e76f021a 100644 --- a/libexec/ftpd/blacklist.c +++ b/libexec/ftpd/blocklist.c @@ -31,25 +31,25 @@ #include #include -#include -#include "blacklist_client.h" +#include +#include "blocklist_client.h" -static struct blacklist *blstate; -extern int use_blacklist; +static struct blocklist *blstate; +extern int use_blocklist; void -blacklist_init(void) +blocklist_init(void) { - if (use_blacklist) - blstate = blacklist_open(); + if (use_blocklist) + blstate = blocklist_open(); } void -blacklist_notify(int action, int fd, const char *msg) +blocklist_notify(int action, int fd, const char *msg) { if (blstate == NULL) return; - (void)blacklist_r(blstate, action, fd, msg); + (void)blocklist_r(blstate, action, fd, msg); } diff --git a/libexec/ftpd/blacklist_client.h b/libexec/ftpd/blocklist_client.h similarity index 78% rename from libexec/ftpd/blacklist_client.h rename to libexec/ftpd/blocklist_client.h index 0b6805dc218..9cca5674a71 100644 --- a/libexec/ftpd/blacklist_client.h +++ b/libexec/ftpd/blocklist_client.h @@ -26,28 +26,28 @@ * SUCH DAMAGE. */ -#ifndef BLACKLIST_CLIENT_H -#define BLACKLIST_CLIENT_H +#ifndef BLOCKLIST_CLIENT_H +#define BLOCKLIST_CLIENT_H -#ifndef BLACKLIST_API_ENUM +#ifndef BLOCKLIST_API_ENUM enum { - BLACKLIST_AUTH_OK = 0, - BLACKLIST_AUTH_FAIL + BLOCKLIST_AUTH_OK = 0, + BLOCKLIST_AUTH_FAIL }; #endif -#ifdef USE_BLACKLIST -void blacklist_init(void); -void blacklist_notify(int, int, const char *); +#ifdef USE_BLOCKLIST +void blocklist_init(void); +void blocklist_notify(int, int, const char *); -#define BLACKLIST_INIT() blacklist_init() -#define BLACKLIST_NOTIFY(x, y, z) blacklist_notify(x, y, z) +#define BLOCKLIST_INIT() blocklist_init() +#define BLOCKLIST_NOTIFY(x, y, z) blocklist_notify(x, y, z) #else -#define BLACKLIST_INIT() -#define BLACKLIST_NOTIFY(x, y, z) +#define BLOCKLIST_INIT() +#define BLOCKLIST_NOTIFY(x, y, z) #endif -#endif /* BLACKLIST_CLIENT_H */ +#endif /* BLOCKLIST_CLIENT_H */ diff --git a/libexec/ftpd/ftpd.8 b/libexec/ftpd/ftpd.8 index a6bf60af460..ec8937f6027 100644 --- a/libexec/ftpd/ftpd.8 +++ b/libexec/ftpd/ftpd.8 @@ -108,9 +108,9 @@ is specified, accept connections only on the specified With this option set, .Nm sends authentication success and failure messages to the -.Xr blacklistd 8 +.Xr blocklistd 8 daemon. If this option is not specified, no communcation with the -.Xr blacklistd 8 +.Xr blocklistd 8 daemon is attempted. .It Fl D With this option set, diff --git a/libexec/ftpd/ftpd.c b/libexec/ftpd/ftpd.c index d031d8815fd..2191ba66629 100644 --- a/libexec/ftpd/ftpd.c +++ b/libexec/ftpd/ftpd.c @@ -93,7 +93,7 @@ static char sccsid[] = "@(#)ftpd.c 8.4 (Berkeley) 4/16/94"; #include #endif -#include "blacklist_client.h" +#include "blocklist_client.h" #include "pathnames.h" #include "extern.h" @@ -141,7 +141,7 @@ int noretr = 0; /* RETR command is disabled. */ int noguestretr = 0; /* RETR command is disabled for anon users. */ int noguestmkd = 0; /* MKD command is disabled for anon users. */ int noguestmod = 1; /* anon users may not modify existing files. */ -int use_blacklist = 0; +int use_blocklist = 0; off_t file_size; off_t byte_count; @@ -312,10 +312,10 @@ main(int argc, char *argv[], char **envp) break; case 'B': -#ifdef USE_BLACKLIST - use_blacklist = 1; +#ifdef USE_BLOCKLIST + use_blocklist = 1; #else - syslog(LOG_WARNING, "not compiled with USE_BLACKLIST support"); + syslog(LOG_WARNING, "not compiled with USE_BLOCKLIST support"); #endif break; @@ -640,7 +640,7 @@ main(int argc, char *argv[], char **envp) reply(220, "%s FTP server (%s) ready.", hostname, version); else reply(220, "FTP server ready."); - BLACKLIST_INIT(); + BLOCKLIST_INIT(); for (;;) (void) yyparse(); /* NOTREACHED */ @@ -1052,7 +1052,7 @@ user(char *name) (checkuser(_PATH_FTPUSERS, name, 1, NULL, &ecode) || (ecode != 0 && ecode != ENOENT))) { reply(530, "User %s access denied.", name); - BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL, STDIN_FILENO, "Access denied"); + BLOCKLIST_NOTIFY(BLOCKLIST_AUTH_FAIL, STDIN_FILENO, "Access denied"); if (logging) syslog(LOG_NOTICE, "FTP LOGIN REFUSED FROM %s, %s", @@ -1417,7 +1417,7 @@ pass(char *passwd) */ if (rval) { reply(530, "Login incorrect."); - BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL, STDIN_FILENO, "Login incorrect"); + BLOCKLIST_NOTIFY(BLOCKLIST_AUTH_FAIL, STDIN_FILENO, "Login incorrect"); if (logging) { syslog(LOG_NOTICE, "FTP LOGIN FAILED FROM %s", @@ -1435,7 +1435,7 @@ pass(char *passwd) } return; } else { - BLACKLIST_NOTIFY(BLACKLIST_AUTH_OK, STDIN_FILENO, "Login successful"); + BLOCKLIST_NOTIFY(BLOCKLIST_AUTH_OK, STDIN_FILENO, "Login successful"); } } login_attempts = 0; /* this time successful */ @@ -1455,7 +1455,7 @@ pass(char *passwd) *remote_ip = 0; remote_ip[sizeof(remote_ip) - 1] = 0; if (!auth_hostok(lc, remotehost, remote_ip)) { - BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL, STDIN_FILENO, "Permission denied"); + BLOCKLIST_NOTIFY(BLOCKLIST_AUTH_FAIL, STDIN_FILENO, "Permission denied"); syslog(LOG_INFO|LOG_AUTH, "FTP LOGIN FAILED (HOST) as %s: permission denied.", pw->pw_name); diff --git a/libexec/rc/rc.conf b/libexec/rc/rc.conf index 9c176e46180..d800f36c6ab 100644 --- a/libexec/rc/rc.conf +++ b/libexec/rc/rc.conf @@ -324,8 +324,10 @@ hastd_flags="" # Optional flags to hastd. ctld_enable="NO" # CAM Target Layer / iSCSI target daemon. local_unbound_enable="NO" # Local caching resolver local_unbound_tls="NO" # Use DNS over TLS -blacklistd_enable="NO" # Run blacklistd daemon (YES/NO). -blacklistd_flags="" # Optional flags for blacklistd(8). +blacklistd_enable="NO" # Renamed to blocklistd_enable. +blacklistd_flags="" # Renamed to blocklistd_flags. +blocklistd_enable="NO" # Run blocklistd daemon (YES/NO). +blocklistd_flags="" # Optional flags for blocklistd(8). mdnsd_enable="NO" # Run mdnsd, multicast DNS (or NO). mdnsresponder_enable="NO" # Run mdnsresponder (or NO). resolv_enable="YES" # Enable resolv / resolvconf diff --git a/libexec/rc/rc.d/Makefile b/libexec/rc/rc.d/Makefile index 695613a07f8..30abdde52b5 100644 --- a/libexec/rc/rc.d/Makefile +++ b/libexec/rc/rc.d/Makefile @@ -16,6 +16,7 @@ CONFS= DAEMON \ archdep \ bgfsck \ ${_blacklistd} \ + ${_blocklistd} \ bridge \ cfumass \ cleanvar \ @@ -183,6 +184,10 @@ CONFS+= autounmountd _blacklistd+= blacklistd .endif +.if ${MK_BLOCKLIST} != "no" +_blocklistd+= blocklistd +.endif + .if ${MK_BLUETOOTH} != "no" CONFGROUPS+= BLUETOOTH BLUETOOTH+= bluetooth \ diff --git a/libexec/rc/rc.d/blacklistd b/libexec/rc/rc.d/blacklistd index 44a97ad4b3b..e7c26716b20 100755 --- a/libexec/rc/rc.d/blacklistd +++ b/libexec/rc/rc.d/blacklistd @@ -29,15 +29,23 @@ # # PROVIDE: blacklistd -# REQUIRE: netif pf +# REQUIRE: netif ipfilter ipfw pf . /etc/rc.subr name="blacklistd" -desc="System blacklist daemon" +desc="The blacklist daemon has been renamed to blocklist" rcvar="blacklistd_enable" command="/usr/sbin/${name}" required_files="/etc/blacklistd.conf" +start_precmd="blacklistd_prestart" + +blacklistd_prestart() +{ + echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" + echo "@ WARNING: blacklistd has been renamed to blocklistd @" + echo "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" +} load_rc_config $name run_rc_command "$1" diff --git a/libexec/rc/rc.d/blocklistd b/libexec/rc/rc.d/blocklistd new file mode 100755 index 00000000000..19451e10ff5 --- /dev/null +++ b/libexec/rc/rc.d/blocklistd @@ -0,0 +1,43 @@ +#!/bin/sh +# +# Copyright (c) 2016 The FreeBSD Foundation +# +# This software was developed by Kurt Lidl under sponsorship from the +# FreeBSD Foundation. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# + +# PROVIDE: blocklistd +# REQUIRE: netif ipfilter ipfw pf + +. /etc/rc.subr + +name="blocklistd" +desc="System blocklist daemon" +rcvar="blocklistd_enable" +command="/usr/sbin/${name}" +required_files="/etc/blocklistd.conf" + +load_rc_config $name +run_rc_command "$1" diff --git a/secure/libexec/sshd-auth/Makefile b/secure/libexec/sshd-auth/Makefile index fbac25ac2a9..46667fac52e 100644 --- a/secure/libexec/sshd-auth/Makefile +++ b/secure/libexec/sshd-auth/Makefile @@ -31,11 +31,11 @@ CFLAGS+= -DUSE_BSM_AUDIT=1 -DHAVE_GETAUDIT_ADDR=1 LIBADD+= bsm .endif -.if ${MK_BLACKLIST_SUPPORT} != "no" -CFLAGS+= -DUSE_BLACKLIST=1 -I${SRCTOP}/contrib/blacklist/include -SRCS+= blacklist.c -LIBADD+= blacklist -LDFLAGS+=-L${LIBBLACKLISTDIR} +.if ${MK_BLOCKLIST_SUPPORT} != "no" +CFLAGS+= -DUSE_BLOCKLIST=1 -I${SRCTOP}/contrib/blocklist/include +SRCS+= blocklist.c +LIBADD+= blocklist +LDFLAGS+=-L${LIBBLOCKLISTDIR} .endif .if ${MK_GSSAPI} != "no" && ${MK_KERBEROS_SUPPORT} != "no" diff --git a/secure/libexec/sshd-session/Makefile b/secure/libexec/sshd-session/Makefile index 71594326a4b..4fc165be9f2 100644 --- a/secure/libexec/sshd-session/Makefile +++ b/secure/libexec/sshd-session/Makefile @@ -29,11 +29,11 @@ CFLAGS+= -DUSE_BSM_AUDIT=1 -DHAVE_GETAUDIT_ADDR=1 LIBADD+= bsm .endif -.if ${MK_BLACKLIST_SUPPORT} != "no" -CFLAGS+= -DUSE_BLACKLIST=1 -I${SRCTOP}/contrib/blacklist/include -SRCS+= blacklist.c -LIBADD+= blacklist -LDFLAGS+=-L${LIBBLACKLISTDIR} +.if ${MK_BLOCKLIST_SUPPORT} != "no" +CFLAGS+= -DUSE_BLOCKLIST=1 -I${SRCTOP}/contrib/blocklist/include +SRCS+= blocklist.c +LIBADD+= blocklist +LDFLAGS+=-L${LIBBLOCKLISTDIR} .endif .if ${MK_GSSAPI} != "no" && ${MK_KERBEROS_SUPPORT} != "no" diff --git a/secure/usr.sbin/sshd/Makefile.depend.options b/secure/usr.sbin/sshd/Makefile.depend.options index 69af5a2e8d7..c8816eb881f 100644 --- a/secure/usr.sbin/sshd/Makefile.depend.options +++ b/secure/usr.sbin/sshd/Makefile.depend.options @@ -1,5 +1,5 @@ # This file is not autogenerated - take care! -DIRDEPS_OPTIONS= AUDIT BLACKLIST_SUPPORT GSSAPI KERBEROS_SUPPORT TCP_WRAPPERS +DIRDEPS_OPTIONS= AUDIT BLOCKLIST_SUPPORT GSSAPI KERBEROS_SUPPORT TCP_WRAPPERS .include diff --git a/share/man/man5/src.conf.5 b/share/man/man5/src.conf.5 index f91344b57ce..36515401894 100644 --- a/share/man/man5/src.conf.5 +++ b/share/man/man5/src.conf.5 @@ -1,6 +1,6 @@ .\" DO NOT EDIT-- this file is @generated by tools/build/options/makeman. .\" $FreeBSD$ -.Dd September 4, 2026 +.Dd September 22, 2026 .Dt SRC.CONF 5 .Os .Sh NAME @@ -200,10 +200,15 @@ options provide "full" Relocation Read-Only (RELRO) support. With full RELRO the entire GOT is made read-only after performing relocation at startup, avoiding GOT overwrite attacks. .It Va WITHOUT_BLACKLIST -Set this if you do not want to build -.Xr blacklistd 8 -and -.Xr blacklistctl 8 . +This option has been renamed to +.Va WITHOUT_BLOCKLIST . +When set, it enforces these options: +.Pp +.Bl -item -compact +.It +.Va WITHOUT_BLOCKLIST +.El +.Pp When set, these options are also in effect: .Pp .Bl -inset -compact @@ -211,10 +216,36 @@ When set, these options are also in effect: (unless .Va WITH_BLACKLIST_SUPPORT is set explicitly) +.It Va WITHOUT_BLOCKLIST_SUPPORT +(unless +.Va WITH_BLOCKLIST_SUPPORT +is set explicitly) .El .It Va WITHOUT_BLACKLIST_SUPPORT +This option has been renamed to +.Va WITHOUT_BLOCKLIST_SUPPORT . +When set, it enforces these options: +.Pp +.Bl -item -compact +.It +.Va WITHOUT_BLOCKLIST_SUPPORT +.El +.It Va WITHOUT_BLOCKLIST +Set this if you do not want to build +.Xr blocklistd 8 +and +.Xr blocklistctl 8 . +When set, these options are also in effect: +.Pp +.Bl -inset -compact +.It Va WITHOUT_BLOCKLIST_SUPPORT +(unless +.Va WITH_BLOCKLIST_SUPPORT +is set explicitly) +.El +.It Va WITHOUT_BLOCKLIST_SUPPORT Build some programs without -.Xr libblacklist 3 +.Xr libblocklist 3 support, like .Xr fingerd 8 , .Xr ftpd 8 , diff --git a/share/mk/bsd.libnames.mk b/share/mk/bsd.libnames.mk index 88c766b8fdd..fdae820e419 100644 --- a/share/mk/bsd.libnames.mk +++ b/share/mk/bsd.libnames.mk @@ -26,6 +26,7 @@ LIBAVL?= ${LIBDESTDIR}${LIBDIR_BASE}/libavl.a LIBBE?= ${LIBDESTDIR}${LIBDIR_BASE}/libbe.a LIBBEGEMOT?= ${LIBDESTDIR}${LIBDIR_BASE}/libbegemot.a LIBBLACKLIST?= ${LIBDESTDIR}${LIBDIR_BASE}/libblacklist.a +LIBBLOCKLIST?= ${LIBDESTDIR}${LIBDIR_BASE}/libblocklist.a LIBBLOCKSRUNTIME?= ${LIBDESTDIR}${LIBDIR_BASE}/libBlocksRuntime.a LIBBLUETOOTH?= ${LIBDESTDIR}${LIBDIR_BASE}/libbluetooth.a LIBBSDXML?= ${LIBDESTDIR}${LIBDIR_BASE}/libbsdxml.a diff --git a/share/mk/local.dirdeps-options.mk b/share/mk/local.dirdeps-options.mk index 5f414adf36a..6e0fee74737 100644 --- a/share/mk/local.dirdeps-options.mk +++ b/share/mk/local.dirdeps-options.mk @@ -2,6 +2,7 @@ # avoid duplication DIRDEPS.AUDIT.yes= lib/libbsm DIRDEPS.BLACKLIST_SUPPORT.yes+= lib/libblacklist +DIRDEPS.BLOCKLIST_SUPPORT.yes+= lib/libblocklist DIRDEPS.CASPER.yes+= lib/libcasper/libcasper DIRDEPS.GSSAPI.yes+= lib/libgssapi DIRDEPS.JAIL.yes+= lib/libjail diff --git a/share/mk/src.libnames.mk b/share/mk/src.libnames.mk index 201146c106d..333738d9a2e 100644 --- a/share/mk/src.libnames.mk +++ b/share/mk/src.libnames.mk @@ -235,8 +235,11 @@ _LIBRARIES= \ .if ${MK_BLACKLIST} != "no" _LIBRARIES+= \ - blacklist \ - + blacklist +.endif +.if ${MK_BLOCKLIST} != "no" +_LIBRARIES+= \ + blocklist .endif .if ${MK_OFED} != "no" @@ -285,6 +288,9 @@ _DP_zstd= pthread .if ${MK_BLACKLIST} != "no" _DP_blacklist+= pthread .endif +.if ${MK_BLOCKLIST} != "no" +_DP_blocklist+= pthread +.endif _DP_crypto= pthread # See comment by _DP_archive above .if ${.MAKE.OS} == "MidnightBSD" || !defined(BOOTSTRAPPING) @@ -734,6 +740,7 @@ LIBGTESTDIR= ${OBJTOP}/lib/googletest/gtest LIBGTEST_MAINDIR= ${OBJTOP}/lib/googletest/gtest_main LIBALIASDIR= ${OBJTOP}/lib/libalias/libalias LIBBLACKLISTDIR= ${OBJTOP}/lib/libblacklist +LIBBLOCKLISTDIR= ${OBJTOP}/lib/libblocklist LIBBLOCKSRUNTIMEDIR= ${OBJTOP}/lib/libblocksruntime LIBMPORTDIR= ${OBJTOP}/lib/libmport LIBMSEARCHDIR= ${OBJTOP}/lib/libmsearch diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk index 8c6605043b3..1e762286cd3 100644 --- a/share/mk/src.opts.mk +++ b/share/mk/src.opts.mk @@ -61,6 +61,7 @@ __DEFAULT_YES_OPTIONS = \ AUTOFS \ BHYVE \ BLACKLIST \ + BLOCKLIST \ BLUETOOTH \ BOOT \ BOOTPARAMD \ @@ -231,6 +232,7 @@ __DEFAULT_DEPENDENT_OPTIONS= \ # .for var in \ BLACKLIST \ + BLOCKLIST \ BZIP2 \ INET \ INET6 \ @@ -487,6 +489,26 @@ MK_${vv:H}:= ${MK_${vv:T}} .endif .endfor +# +# The blacklist knobs are kept as aliases for the blocklist ones +# during the rename transition. +# +.if ${MK_BLACKLIST} == "no" +MK_BLOCKLIST:= no +.endif + +.if ${MK_BLACKLIST_SUPPORT} == "no" +MK_BLOCKLIST_SUPPORT:= no +.endif + +.if ${MK_BLOCKLIST} == "no" +MK_BLACKLIST:= no +.endif + +.if ${MK_BLOCKLIST_SUPPORT} == "no" +MK_BLACKLIST_SUPPORT:= no +.endif + # # Set defaults for the MK_*_SUPPORT variables. # diff --git a/targets/pseudo/userland/Makefile.depend b/targets/pseudo/userland/Makefile.depend index 7c50bec8267..9add8cd4aa9 100644 --- a/targets/pseudo/userland/Makefile.depend +++ b/targets/pseudo/userland/Makefile.depend @@ -831,6 +831,12 @@ DIRDEPS+= \ usr.sbin/blacklistd .endif +.if ${MK_BLOCKLIST_SUPPORT} != "no" +DIRDEPS+= \ + usr.sbin/blocklistctl \ + usr.sbin/blocklistd +.endif + .if ${MK_CXGBETOOL} != "no" DIRDEPS+= usr.sbin/cxgbetool .endif diff --git a/targets/pseudo/userland/lib/Makefile.depend b/targets/pseudo/userland/lib/Makefile.depend index dc1dd7ba1b2..b9e9e2ae41c 100644 --- a/targets/pseudo/userland/lib/Makefile.depend +++ b/targets/pseudo/userland/lib/Makefile.depend @@ -254,4 +254,8 @@ DIRDEPS+= \ DIRDEPS+= lib/libblacklist .endif +.if ${MK_BLOCKLIST_SUPPORT} != "no" +DIRDEPS+= lib/libblocklist +.endif + .include diff --git a/targets/pseudo/userland/libexec/Makefile.depend b/targets/pseudo/userland/libexec/Makefile.depend index af5e6f262aa..402d4307b5e 100644 --- a/targets/pseudo/userland/libexec/Makefile.depend +++ b/targets/pseudo/userland/libexec/Makefile.depend @@ -55,8 +55,8 @@ DIRDEPS = \ libexec/ypxfr \ -.if ${MK_BLACKLIST_SUPPORT} != "no" -DIRDEPS+= libexec/blacklistd-helper +.if ${MK_BLOCKLIST_SUPPORT} != "no" +DIRDEPS+= libexec/blocklistd-helper .endif .if ${MK_DMAGENT} != "no" diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc index c1aa20b19c6..4fcb5c4e714 100644 --- a/tools/build/mk/OptionalObsoleteFiles.inc +++ b/tools/build/mk/OptionalObsoleteFiles.inc @@ -196,7 +196,26 @@ OLD_FILES+=usr/share/man/man1/ld.1.gz .endif .endif -.if ${MK_BLACKLIST} == no +.if ${MK_BLOCKLIST} == no +OLD_FILES+=etc/blocklistd.conf +OLD_FILES+=etc/rc.d/blocklistd +OLD_FILES+=usr/include/blocklist.h +OLD_FILES+=usr/lib/libblocklist.a +OLD_FILES+=usr/lib/libblocklist_p.a +OLD_FILES+=usr/lib/libblocklist.so +OLD_LIBS+=usr/lib/libblocklist.so.0 +OLD_FILES+=usr/libexec/blocklistd-helper +OLD_FILES+=usr/sbin/blocklistctl +OLD_FILES+=usr/sbin/blocklistd +OLD_FILES+=usr/share/man/man3/blocklist.3.gz +OLD_FILES+=usr/share/man/man3/blocklist_close.3.gz +OLD_FILES+=usr/share/man/man3/blocklist_open.3.gz +OLD_FILES+=usr/share/man/man3/blocklist_r.3.gz +OLD_FILES+=usr/share/man/man3/blocklist_sa.3.gz +OLD_FILES+=usr/share/man/man3/blocklist_sa_r.3.gz +OLD_FILES+=usr/share/man/man5/blocklistd.conf.5.gz +OLD_FILES+=usr/share/man/man8/blocklistctl.8.gz +OLD_FILES+=usr/share/man/man8/blocklistd.8.gz OLD_FILES+=etc/blacklistd.conf OLD_FILES+=etc/rc.d/blacklistd OLD_FILES+=usr/include/blacklist.h diff --git a/tools/build/options/WITHOUT_BLACKLIST b/tools/build/options/WITHOUT_BLACKLIST index c54c83f2755..df9c9a41227 100644 --- a/tools/build/options/WITHOUT_BLACKLIST +++ b/tools/build/options/WITHOUT_BLACKLIST @@ -1,4 +1,2 @@ -Set this if you do not want to build -.Xr blacklistd 8 -and -.Xr blacklistctl 8 . +This option has been renamed to +.Va WITHOUT_BLOCKLIST . diff --git a/tools/build/options/WITHOUT_BLACKLIST_SUPPORT b/tools/build/options/WITHOUT_BLACKLIST_SUPPORT index 2bf22ea42ab..cd484727d63 100644 --- a/tools/build/options/WITHOUT_BLACKLIST_SUPPORT +++ b/tools/build/options/WITHOUT_BLACKLIST_SUPPORT @@ -1,7 +1,2 @@ -Build some programs without -.Xr libblacklist 3 -support, like -.Xr fingerd 8 , -.Xr ftpd 8 , -and -.Xr sshd 8 . +This option has been renamed to +.Va WITHOUT_BLOCKLIST_SUPPORT . diff --git a/tools/build/options/WITHOUT_BLOCKLIST b/tools/build/options/WITHOUT_BLOCKLIST new file mode 100644 index 00000000000..c456a98c672 --- /dev/null +++ b/tools/build/options/WITHOUT_BLOCKLIST @@ -0,0 +1,4 @@ +Set this if you do not want to build +.Xr blocklistd 8 +and +.Xr blocklistctl 8 . diff --git a/tools/build/options/WITHOUT_BLOCKLIST_SUPPORT b/tools/build/options/WITHOUT_BLOCKLIST_SUPPORT new file mode 100644 index 00000000000..e29d3454180 --- /dev/null +++ b/tools/build/options/WITHOUT_BLOCKLIST_SUPPORT @@ -0,0 +1,7 @@ +Build some programs without +.Xr libblocklist 3 +support, like +.Xr fingerd 8 , +.Xr ftpd 8 , +and +.Xr sshd 8 . diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile index 80c88e4576e..030d6f6dd1b 100644 --- a/usr.sbin/Makefile +++ b/usr.sbin/Makefile @@ -123,6 +123,8 @@ SUBDIR.${MK_AUTHPF}+= authpf SUBDIR.${MK_AUTOFS}+= autofs SUBDIR.${MK_BLACKLIST}+= blacklistctl SUBDIR.${MK_BLACKLIST}+= blacklistd +SUBDIR.${MK_BLOCKLIST}+= blocklistctl +SUBDIR.${MK_BLOCKLIST}+= blocklistd SUBDIR.${MK_BLUETOOTH}+= bluetooth SUBDIR.${MK_BOOTPARAMD}+= bootparamd SUBDIR.${MK_BSDINSTALL}+= bsdinstall diff --git a/usr.sbin/blacklistctl/Makefile b/usr.sbin/blacklistctl/Makefile index effba676115..0fa0f9990e1 100644 --- a/usr.sbin/blacklistctl/Makefile +++ b/usr.sbin/blacklistctl/Makefile @@ -1,21 +1,21 @@ - -BLACKLIST_DIR=${SRCTOP}/contrib/blacklist -.PATH: ${BLACKLIST_DIR}/bin ${BLACKLIST_DIR}/port +BLOCKLIST_DIR=${SRCTOP}/contrib/blocklist +.PATH: ${BLOCKLIST_DIR}/bin ${BLOCKLIST_DIR}/port PROG= blacklistctl -SRCS= blacklistctl.c conf.c state.c support.c internal.c \ +SRCS= blacklistctl.c conf.c state.c support.c old_internal.c \ sockaddr_snprintf.c pidfile.c strtoi.c popenve.c MAN= blacklistctl.8 LDFLAGS+=-L${LIBBLACKLISTDIR} -LIBADD+= blacklist util +LIBADD+= blocklist util -CFLAGS+=-I${BLACKLIST_DIR}/include -I${BLACKLIST_DIR}/port \ +CFLAGS+=-I${BLOCKLIST_DIR}/include -I${BLOCKLIST_DIR}/port \ + -D_PATH_BLCONF=\"/etc/blacklistd.conf\" \ -D_PATH_BLCONTROL=\"/usr/libexec/blacklistd-helper\" \ -DHAVE_CONFIG_H -DHAVE_DB_H -DHAVE_LIBUTIL_H \ -DHAVE_CLOCK_GETTIME -DHAVE_FGETLN -DHAVE_FPARSELN \ -DHAVE_GETPROGNAME -DHAVE_STRLCAT -DHAVE_STRLCPY \ - -DHAVE_STRUCT_SOCKADDR_SA_LEN + -DHAVE_STRUCT_SOCKADDR_SA_LEN -DHAVE_SYS_CDEFS_H # CFLAGS+= -D_REENTRANT .include diff --git a/usr.sbin/blacklistctl/Makefile.depend b/usr.sbin/blacklistctl/Makefile.depend index 022282c2ed3..88f44bab57d 100644 --- a/usr.sbin/blacklistctl/Makefile.depend +++ b/usr.sbin/blacklistctl/Makefile.depend @@ -6,7 +6,7 @@ DIRDEPS = \ include/arpa \ include/xlocale \ lib/${CSU_DIR} \ - lib/libblacklist \ + lib/libblocklist \ lib/libc \ lib/libcompiler_rt \ lib/libthr \ diff --git a/usr.sbin/blacklistd/Makefile b/usr.sbin/blacklistd/Makefile index a33ea1d285b..08105d99e5e 100644 --- a/usr.sbin/blacklistd/Makefile +++ b/usr.sbin/blacklistd/Makefile @@ -1,22 +1,22 @@ - -BLACKLIST_DIR=${SRCTOP}/contrib/blacklist -.PATH: ${BLACKLIST_DIR}/bin ${BLACKLIST_DIR}/port +BLOCKLIST_DIR=${SRCTOP}/contrib/blocklist +.PATH: ${BLOCKLIST_DIR}/bin ${BLOCKLIST_DIR}/port CONFS= blacklistd.conf PROG= blacklistd -SRCS= blacklistd.c conf.c run.c state.c support.c internal.c \ - sockaddr_snprintf.c pidfile.c strtoi.c popenve.c +SRCS= blacklistd.c conf.c run.c state.c support.c old_internal.c \ + sockaddr_snprintf.c pidfile.c strtoi.c popenve.c vsyslog_r.c MAN= blacklistd.8 blacklistd.conf.5 LDFLAGS+=-L${LIBBLACKLISTDIR} -LIBADD+= blacklist util +LIBADD+= blocklist util -CFLAGS+=-I${BLACKLIST_DIR}/include -I${BLACKLIST_DIR}/port \ +CFLAGS+=-I${BLOCKLIST_DIR}/include -I${BLOCKLIST_DIR}/port \ + -D_PATH_BLCONF=\"/etc/blacklistd.conf\" \ -D_PATH_BLCONTROL=\"/usr/libexec/blacklistd-helper\" \ -DHAVE_CONFIG_H -DHAVE_DB_H -DHAVE_LIBUTIL_H \ -DHAVE_CLOCK_GETTIME -DHAVE_FGETLN -DHAVE_FPARSELN \ -DHAVE_GETPROGNAME -DHAVE_STRLCAT -DHAVE_STRLCPY \ - -DHAVE_STRUCT_SOCKADDR_SA_LEN + -DHAVE_STRUCT_SOCKADDR_SA_LEN -DHAVE_SYS_CDEFS_H # CFLAGS+= -D_REENTRANT .include diff --git a/usr.sbin/blacklistd/Makefile.depend b/usr.sbin/blacklistd/Makefile.depend index 022282c2ed3..88f44bab57d 100644 --- a/usr.sbin/blacklistd/Makefile.depend +++ b/usr.sbin/blacklistd/Makefile.depend @@ -6,7 +6,7 @@ DIRDEPS = \ include/arpa \ include/xlocale \ lib/${CSU_DIR} \ - lib/libblacklist \ + lib/libblocklist \ lib/libc \ lib/libcompiler_rt \ lib/libthr \ diff --git a/usr.sbin/blocklistctl/Makefile b/usr.sbin/blocklistctl/Makefile new file mode 100644 index 00000000000..71e724faa5c --- /dev/null +++ b/usr.sbin/blocklistctl/Makefile @@ -0,0 +1,20 @@ +BLOCKLIST_DIR=${SRCTOP}/contrib/blocklist +.PATH: ${BLOCKLIST_DIR}/bin ${BLOCKLIST_DIR}/port + +PROG= blocklistctl +SRCS= blocklistctl.c conf.c state.c support.c internal.c \ + sockaddr_snprintf.c pidfile.c strtoi.c popenve.c +MAN= blocklistctl.8 + +LDFLAGS+=-L${LIBBLOCKLISTDIR} +LIBADD+= blocklist util + +CFLAGS+=-I${BLOCKLIST_DIR}/include -I${BLOCKLIST_DIR}/port \ + -D_PATH_BLCONTROL=\"/usr/libexec/blocklistd-helper\" \ + -DHAVE_CONFIG_H -DHAVE_DB_H -DHAVE_LIBUTIL_H \ + -DHAVE_CLOCK_GETTIME -DHAVE_FGETLN -DHAVE_FPARSELN \ + -DHAVE_GETPROGNAME -DHAVE_STRLCAT -DHAVE_STRLCPY \ + -DHAVE_STRUCT_SOCKADDR_SA_LEN -DHAVE_SYS_CDEFS_H +# CFLAGS+= -D_REENTRANT + +.include diff --git a/usr.sbin/blocklistctl/Makefile.depend b/usr.sbin/blocklistctl/Makefile.depend new file mode 100644 index 00000000000..88f44bab57d --- /dev/null +++ b/usr.sbin/blocklistctl/Makefile.depend @@ -0,0 +1,20 @@ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + gnu/lib/csu \ + include \ + include/arpa \ + include/xlocale \ + lib/${CSU_DIR} \ + lib/libblocklist \ + lib/libc \ + lib/libcompiler_rt \ + lib/libthr \ + lib/libutil \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/usr.sbin/blocklistd/Makefile b/usr.sbin/blocklistd/Makefile new file mode 100644 index 00000000000..118a2a1e5f0 --- /dev/null +++ b/usr.sbin/blocklistd/Makefile @@ -0,0 +1,21 @@ +BLOCKLIST_DIR=${SRCTOP}/contrib/blocklist +.PATH: ${BLOCKLIST_DIR}/bin ${BLOCKLIST_DIR}/port + +CONFS= blocklistd.conf +PROG= blocklistd +SRCS= blocklistd.c conf.c run.c state.c support.c internal.c \ + sockaddr_snprintf.c pidfile.c strtoi.c popenve.c vsyslog_r.c +MAN= blocklistd.8 blocklistd.conf.5 + +LDFLAGS+=-L${LIBBLOCKLISTDIR} +LIBADD+= blocklist util + +CFLAGS+=-I${BLOCKLIST_DIR}/include -I${BLOCKLIST_DIR}/port \ + -D_PATH_BLCONTROL=\"/usr/libexec/blocklistd-helper\" \ + -DHAVE_CONFIG_H -DHAVE_DB_H -DHAVE_LIBUTIL_H \ + -DHAVE_CLOCK_GETTIME -DHAVE_FGETLN -DHAVE_FPARSELN \ + -DHAVE_GETPROGNAME -DHAVE_STRLCAT -DHAVE_STRLCPY \ + -DHAVE_STRUCT_SOCKADDR_SA_LEN -DHAVE_SYS_CDEFS_H +# CFLAGS+= -D_REENTRANT + +.include diff --git a/usr.sbin/blocklistd/Makefile.depend b/usr.sbin/blocklistd/Makefile.depend new file mode 100644 index 00000000000..88f44bab57d --- /dev/null +++ b/usr.sbin/blocklistd/Makefile.depend @@ -0,0 +1,20 @@ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + gnu/lib/csu \ + include \ + include/arpa \ + include/xlocale \ + lib/${CSU_DIR} \ + lib/libblocklist \ + lib/libc \ + lib/libcompiler_rt \ + lib/libthr \ + lib/libutil \ + + +.include + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/usr.sbin/blocklistd/blocklistd.conf b/usr.sbin/blocklistd/blocklistd.conf new file mode 100644 index 00000000000..72f114290d9 --- /dev/null +++ b/usr.sbin/blocklistd/blocklistd.conf @@ -0,0 +1,16 @@ +# +# Blocklist rule +# adr/mask:port type proto owner name nfail duration +[local] +ssh stream * * * 3 24h +ftp stream * * * 3 24h +smtp stream * * * 3 24h +submission stream * * * 3 24h +#6161 stream tcp6 christos * 2 10m +* * * * * 3 60 + +# adr/mask:port type proto owner name nfail duration +[remote] +#129.168.0.0/16 * * * = * * +#6161 = = = =/24 = = +#* stream tcp * = = = diff --git a/usr.sbin/periodic/etc/security/520.pfdenied b/usr.sbin/periodic/etc/security/520.pfdenied index 13ed37b368d..1ee03eb4be3 100755 --- a/usr.sbin/periodic/etc/security/520.pfdenied +++ b/usr.sbin/periodic/etc/security/520.pfdenied @@ -41,7 +41,7 @@ rc=0 if check_yesno_period security_status_pfdenied_enable then TMP=`mktemp -t security` - for _a in "" $(pfctl -a "blacklistd" -sA 2>/dev/null) + for _a in "" $(pfctl -a "blacklistd" -sA 2>/dev/null) $(pfctl -a "blocklistd" -sA 2>/dev/null) do pfctl -a "${_a}" -sr -v -z 2>/dev/null | \ nawk '{if (/^block/) {buf=$0; getline; gsub(" +"," ",$0); if ($5 > 0) print buf$0;} }' >> ${TMP}