aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJose Luis Duran <jlduran@FreeBSD.org>2025-10-12 17:14:27 +0000
committerJose Luis Duran <jlduran@FreeBSD.org>2025-10-12 17:14:27 +0000
commit7238317403b95a8e35cf0bc7cd66fbd78ecbe521 (patch)
treeb480b030557dcd146b771d786e0492809e86bbc0
parent4d56eb007b18881becb2107f87bd2a7edca3e6bf (diff)
blocklist: Rename blacklist to blocklist
Follow up upstream rename from blacklist to blocklist. - Old names and rc scripts are still valid, but emitting an ugly warning - Old firewall rules and anchor names should work, but emitting an ugly warning - Old MK_BLACKLIST* knobs are wired to the new ones Although care has been taken not to break current configurations, this is a large patch containing mostly duplicated code. If issues arise, it will be swiftly reverted. Reviewed by: ivy (pkgbase) Approved by: emaste (mentor) MFC after: 2 days Relnotes: yes
-rw-r--r--contrib/blocklist/bin/blacklistctl.c170
-rw-r--r--contrib/blocklist/bin/blacklistd.c592
-rw-r--r--contrib/blocklist/bin/old_internal.c50
-rw-r--r--contrib/blocklist/bin/old_internal.h58
-rw-r--r--contrib/blocklist/include/blacklist.h65
-rw-r--r--contrib/blocklist/include/old_bl.h80
-rw-r--r--contrib/blocklist/lib/blacklist.c117
-rw-r--r--contrib/blocklist/lib/old_bl.c554
-rw-r--r--crypto/openssh/auth-pam.c4
-rw-r--r--crypto/openssh/auth.c8
-rw-r--r--crypto/openssh/blocklist.c (renamed from crypto/openssh/blacklist.c)16
-rw-r--r--crypto/openssh/blocklist_client.h (renamed from crypto/openssh/blacklist_client.h)30
-rw-r--r--crypto/openssh/monitor.c8
-rw-r--r--crypto/openssh/servconf.c18
-rw-r--r--crypto/openssh/servconf.h2
-rw-r--r--crypto/openssh/sshd-session.c10
-rw-r--r--crypto/openssh/sshd_config2
-rw-r--r--crypto/openssh/sshd_config.514
-rw-r--r--lib/Makefile1
-rw-r--r--lib/libblacklist/Makefile24
-rw-r--r--lib/libblocklist/Makefile30
-rw-r--r--lib/libblocklist/Makefile.depend16
-rw-r--r--lib/libsysdecode/Makefile.depend2
-rw-r--r--libexec/Makefile6
-rw-r--r--libexec/blacklistd-helper/Makefile7
-rw-r--r--libexec/blocklistd-helper/Makefile10
-rw-r--r--libexec/blocklistd-helper/Makefile.depend (renamed from libexec/blacklistd-helper/Makefile.depend)0
-rw-r--r--libexec/blocklistd-helper/blacklistd-helper293
-rw-r--r--libexec/fingerd/Makefile8
-rw-r--r--libexec/fingerd/Makefile.depend.options2
-rw-r--r--libexec/fingerd/fingerd.c16
-rw-r--r--libexec/rc/rc.conf6
-rw-r--r--libexec/rc/rc.d/Makefile5
-rwxr-xr-xlibexec/rc/rc.d/blacklistd10
-rw-r--r--libexec/rc/rc.d/blocklistd46
-rw-r--r--release/packages/ucl/blocklist-all.ucl8
-rw-r--r--secure/libexec/sshd-auth/Makefile10
-rw-r--r--secure/libexec/sshd-session/Makefile10
-rw-r--r--secure/usr.sbin/sshd/Makefile.depend.options2
-rw-r--r--share/man/man5/periodic.conf.52
-rw-r--r--share/man/man5/src.conf.543
-rw-r--r--share/mk/bsd.libnames.mk1
-rw-r--r--share/mk/local.dirdeps-options.mk1
-rw-r--r--share/mk/src.libnames.mk10
-rw-r--r--share/mk/src.opts.mk10
-rw-r--r--targets/pseudo/userland/Makefile.depend6
-rw-r--r--targets/pseudo/userland/lib/Makefile.depend4
-rw-r--r--targets/pseudo/userland/libexec/Makefile.depend4
-rw-r--r--tools/build/mk/OptionalObsoleteFiles.inc21
-rw-r--r--tools/build/options/WITHOUT_BLACKLIST6
-rw-r--r--tools/build/options/WITHOUT_BLACKLIST_SUPPORT8
-rw-r--r--tools/build/options/WITHOUT_BLOCKLIST4
-rw-r--r--tools/build/options/WITHOUT_BLOCKLIST_SUPPORT6
-rw-r--r--usr.sbin/Makefile2
-rw-r--r--usr.sbin/blacklistctl/Makefile10
-rw-r--r--usr.sbin/blacklistd/Makefile13
-rw-r--r--usr.sbin/blacklistd/blacklistd.conf10
-rw-r--r--usr.sbin/blocklistctl/Makefile22
-rw-r--r--usr.sbin/blocklistctl/Makefile.depend18
-rw-r--r--usr.sbin/blocklistd/Makefile23
-rw-r--r--usr.sbin/blocklistd/Makefile.depend18
-rw-r--r--usr.sbin/blocklistd/blocklistd.conf16
-rwxr-xr-xusr.sbin/periodic/etc/security/520.pfdenied2
63 files changed, 2426 insertions, 144 deletions
diff --git a/contrib/blocklist/bin/blacklistctl.c b/contrib/blocklist/bin/blacklistctl.c
new file mode 100644
index 000000000000..6298a08b10b4
--- /dev/null
+++ b/contrib/blocklist/bin/blacklistctl.c
@@ -0,0 +1,170 @@
+/* $NetBSD: blocklistctl.c,v 1.4 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 <sys/cdefs.h>
+#endif
+__RCSID("$NetBSD: blocklistctl.c,v 1.4 2025/02/11 17:48:30 christos Exp $");
+
+#include <stdio.h>
+#include <time.h>
+#ifdef HAVE_LIBUTIL_H
+#include <libutil.h>
+#endif
+#ifdef HAVE_UTIL_H
+#include <util.h>
+#endif
+#include <fcntl.h>
+#include <string.h>
+#include <syslog.h>
+#include <err.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/socket.h>
+
+#include "conf.h"
+#include "state.h"
+#include "old_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("%*.*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/%s:%s\t", 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/blacklistd.c b/contrib/blocklist/bin/blacklistd.c
new file mode 100644
index 000000000000..ded3075ed707
--- /dev/null
+++ b/contrib/blocklist/bin/blacklistd.c
@@ -0,0 +1,592 @@
+/* $NetBSD: blocklistd.c,v 1.10 2025/03/26 17:09:35 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 <sys/cdefs.h>
+#endif
+__RCSID("$NetBSD: blocklistd.c,v 1.10 2025/03/26 17:09:35 christos Exp $");
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/queue.h>
+
+#ifdef HAVE_LIBUTIL_H
+#include <libutil.h>
+#endif
+#ifdef HAVE_UTIL_H
+#include <util.h>
+#endif
+#include <string.h>
+#include <signal.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <inttypes.h>
+#include <syslog.h>
+#include <ctype.h>
+#include <limits.h>
+#include <errno.h>
+#include <poll.h>
+#include <fcntl.h>
+#include <err.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <ifaddrs.h>
+#include <netinet/in.h>
+
+#include "old_bl.h"
+#include "old_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 <config>] [-R <rulename>] "
+ "[-P <sockpathsfile>] [-C <controlprog>] [-D <dbfile>] "
+ "[-s <sockpath>] [-t <timeout>]\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 one less than the
+ * configured limit. Fallthrough to the normal BL_ADD
+ * processing, which will increment the failure count
+ * to the threshhold, and block the abusive address.
+ */
+ if (c.c_nfail != -1)
+ dbi.count = c.c_nfail - 1;
+ /*FALLTHROUGH*/
+ case BL_ADD:
+ 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;
+ case BL_BADUSER:
+ /* ignore for now */
+ 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);
+ }
+ state_del(state, &c);
+ 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 = realloc(*blp, sizeof(**blp) * *maxfd);
+ if (*blp == NULL)
+ err(EXIT_FAILURE, "malloc");
+ *pfdp = realloc(*pfdp, sizeof(**pfdp) * *maxfd);
+ 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 = realloc(*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 = realloc(blsock,
+ sizeof(*blsock) * maxblsock);
+ 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);
+ if (state == NULL)
+ return EXIT_FAILURE;
+
+ if (restore) {
+ if (!flush)
+ rules_flush();
+ rules_restore();
+ }
+
+ 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)");
+ return 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);
+ return 0;
+}
diff --git a/contrib/blocklist/bin/old_internal.c b/contrib/blocklist/bin/old_internal.c
new file mode 100644
index 000000000000..79093cc8b8ab
--- /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 <sys/cdefs.h>
+#endif
+__RCSID("$NetBSD: internal.c,v 1.2 2025/02/11 17:48:30 christos Exp $");
+
+#include <stdio.h>
+#include <syslog.h>
+#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 000000000000..becee563e81d
--- /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/blocklist/include/blacklist.h b/contrib/blocklist/include/blacklist.h
new file mode 100644
index 000000000000..f97cf34c4bcb
--- /dev/null
+++ b/contrib/blocklist/include/blacklist.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 _BLACKLIST_H
+#define _BLACKLIST_H
+
+#include <sys/socket.h>
+#include <syslog.h>
+
+#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 *);
+
+#if defined(__cplusplus)
+}
+#endif
+
+/* action values for user applications */
+#define BLACKLIST_API_ENUM 1
+enum {
+ BLACKLIST_AUTH_OK = 0,
+ BLACKLIST_AUTH_FAIL,
+ BLACKLIST_ABUSIVE_BEHAVIOR,
+ BLACKLIST_BAD_USER
+};
+
+#endif /* _BLACKLIST_H */
diff --git a/contrib/blocklist/include/old_bl.h b/contrib/blocklist/include/old_bl.h
new file mode 100644
index 000000000000..1ab64a4d9b69
--- /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 <stdbool.h>
+#include <stdarg.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#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/blacklist.c b/contrib/blocklist/lib/blacklist.c
new file mode 100644
index 000000000000..12e5f83e09af
--- /dev/null
+++ b/contrib/blocklist/lib/blacklist.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 <sys/cdefs.h>
+#endif
+__RCSID("$NetBSD: blocklist.c,v 1.4 2025/02/11 17:48:30 christos Exp $");
+
+#include <stdio.h>
+#include <old_bl.h>
+
+#include <stdarg.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <syslog.h>
+
+int
+blacklist_sa(int action, int rfd, const struct sockaddr *sa, socklen_t salen,
+ const char *msg)
+{
+ struct blacklist *bl;
+ int rv;
+ if ((bl = blacklist_open()) == NULL)
+ return -1;
+ rv = blacklist_sa_r(bl, action, rfd, sa, salen, msg);
+ blacklist_close(bl);
+ return rv;
+}
+
+int
+blacklist_sa_r(struct blacklist *bl, int action, int rfd,
+ const struct sockaddr *sa, socklen_t slen, const char *msg)
+{
+ bl_type_t internal_action;
+
+ /* internal values are not the same as user application values */
+ switch (action) {
+ case BLACKLIST_AUTH_FAIL:
+ internal_action = BL_ADD;
+ break;
+ case BLACKLIST_AUTH_OK:
+ internal_action = BL_DELETE;
+ break;
+ case BLACKLIST_ABUSIVE_BEHAVIOR:
+ internal_action = BL_ABUSE;
+ break;
+ case BLACKLIST_BAD_USER:
+ internal_action = BL_BADUSER;
+ break;
+ default:
+ internal_action = BL_INVALID;
+ break;
+ }
+ return bl_send(bl, internal_action, rfd, sa, slen, msg);
+}
+
+int
+blacklist(int action, int rfd, const char *msg)
+{
+ return blacklist_sa(action, rfd, NULL, 0, msg);
+}
+
+int
+blacklist_r(struct blacklist *bl, int action, int rfd, const char *msg)
+{
+ return blacklist_sa_r(bl, action, rfd, NULL, 0, msg);
+}
+
+struct blacklist *
+blacklist_open(void) {
+ 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
+blacklist_close(struct blacklist *bl)
+{
+ bl_destroy(bl);
+}
diff --git a/contrib/blocklist/lib/old_bl.c b/contrib/blocklist/lib/old_bl.c
new file mode 100644
index 000000000000..ffbbd3f620ac
--- /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 <sys/cdefs.h>
+#endif
+__RCSID("$NetBSD: bl.c,v 1.9 2025/03/30 01:53:59 christos Exp $");
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/un.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <syslog.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <netinet/in.h>
+#ifdef _REENTRANT
+#include <pthread.h>
+#endif
+
+#if defined(SO_RECVUCRED)
+#include <ucred.h>
+#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/crypto/openssh/auth-pam.c b/crypto/openssh/auth-pam.c
index df08dbd99a9d..217fae531afa 100644
--- a/crypto/openssh/auth-pam.c
+++ b/crypto/openssh/auth-pam.c
@@ -101,7 +101,7 @@
#endif
#include "monitor_wrap.h"
#include "srclimit.h"
-#include "blacklist_client.h"
+#include "blocklist_client.h"
extern ServerOptions options;
extern struct sshbuf *loginmsg;
@@ -937,7 +937,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 0a1c8f71b390..28ee390f4a15 100644
--- a/crypto/openssh/auth.c
+++ b/crypto/openssh/auth.c
@@ -75,7 +75,7 @@
#include "monitor_wrap.h"
#include "ssherr.h"
#include "channels.h"
-#include "blacklist_client.h"
+#include "blocklist_client.h"
/* import */
extern ServerOptions options;
@@ -289,7 +289,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");
}
@@ -339,7 +339,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 ",
@@ -500,7 +500,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
index 33d02607dd98..f3c00016db66 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 <blacklist.h>
-#include "blacklist_client.h"
+#include <blocklist.h>
+#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
index 601a44461e20..be92245e4690 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 b826ecdb9065..77dccf0d84f1 100644
--- a/crypto/openssh/monitor.c
+++ b/crypto/openssh/monitor.c
@@ -85,7 +85,7 @@
#include "misc.h"
#include "servconf.h"
#include "monitor.h"
-#include "blacklist_client.h"
+#include "blocklist_client.h"
#ifdef GSSAPI
#include "ssh-gss.h"
@@ -355,7 +355,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 "
@@ -364,12 +364,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 5ab34973bbcb..07d3bee2fcb9 100644
--- a/crypto/openssh/servconf.c
+++ b/crypto/openssh/servconf.c
@@ -217,7 +217,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. */
@@ -506,8 +506,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);
@@ -591,7 +591,7 @@ typedef enum {
sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider,
sRequiredRSASize, sChannelTimeout, sUnusedConnectionTimeout,
sSshdSessionPath, sSshdAuthPath, sRefuseConnection,
- sUseBlacklist,
+ sUseBlocklist,
sDeprecated, sIgnore, sUnsupported
} ServerOpCodes;
@@ -761,8 +761,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 }
};
@@ -2742,8 +2742,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:
@@ -3297,7 +3297,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 ad3974322e83..38b2afeb15bd 100644
--- a/crypto/openssh/servconf.h
+++ b/crypto/openssh/servconf.h
@@ -253,7 +253,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 62c76cc1c8aa..e8299c254567 100644
--- a/crypto/openssh/sshd-session.c
+++ b/crypto/openssh/sshd-session.c
@@ -108,7 +108,7 @@
#include "sk-api.h"
#include "srclimit.h"
#include "dh.h"
-#include "blacklist_client.h"
+#include "blocklist_client.h"
/* Re-exec fds */
#define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1)
@@ -217,7 +217,7 @@ mm_is_monitor(void)
static void
grace_alarm_handler(int sig)
{
- BLACKLIST_NOTIFY(the_active_state, BLACKLIST_AUTH_FAIL,
+ BLOCKLIST_NOTIFY(the_active_state, BLOCKLIST_AUTH_FAIL,
"Grace period expired");
/*
* Try to kill any processes that we have spawned, E.g. authorized
@@ -1203,7 +1203,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
@@ -1282,7 +1282,7 @@ main(int ac, char **av)
if ((r = kex_exchange_identification(ssh, -1,
options.version_addendum)) != 0) {
- BLACKLIST_NOTIFY(ssh, BLACKLIST_AUTH_FAIL, "Banner exchange");
+ BLOCKLIST_NOTIFY(ssh, BLOCKLIST_AUTH_FAIL, "Banner exchange");
sshpkt_fatal(ssh, r, "banner exchange");
}
@@ -1430,7 +1430,7 @@ cleanup_exit(int i)
#endif
/* Override default fatal exit value when auth was attempted */
if (i == 255 && 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 50a3d228fa58..708be7fe2870 100644
--- a/crypto/openssh/sshd_config
+++ b/crypto/openssh/sshd_config
@@ -107,7 +107,7 @@ AuthorizedKeysFile .ssh/authorized_keys
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
-#UseBlacklist no
+#UseBlocklist no
#VersionAddendum FreeBSD-20250801
# no default banner path
diff --git a/crypto/openssh/sshd_config.5 b/crypto/openssh/sshd_config.5
index ff1be7ba6ccf..c637d68f90c6 100644
--- a/crypto/openssh/sshd_config.5
+++ b/crypto/openssh/sshd_config.5
@@ -2020,20 +2020,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 d43e4d395f56..75a2355aa452 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -163,6 +163,7 @@ SUBDIR_DEPEND_virtual_oss= libsamplerate
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 bfd9edb9614c..07c770883eab 100644
--- a/lib/libblacklist/Makefile
+++ b/lib/libblacklist/Makefile
@@ -1,6 +1,6 @@
BLOCKLIST_DIR=${SRCTOP}/contrib/blocklist
-.PATH: ${BLOCKLIST_DIR}/lib ${BLOCKLIST_DIR}/include
+.PATH: ${BLOCKLIST_DIR}/lib ${BLOCKLIST_DIR}/include ${BLOCKLIST_DIR}/port
PACKAGE= blocklist
LIB= blacklist
@@ -13,17 +13,19 @@ 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_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
-
-MLINKS= libblacklist.3 blacklist_open.3 \
- libblacklist.3 blacklist_close.3 \
- libblacklist.3 blacklist.3 \
- libblacklist.3 blacklist_r.3 \
- libblacklist.3 blacklist_sa.3 \
- libblacklist.3 blacklist_sa_r.3
+MAN= libblocklist.3
+
+MLINKS+=libblocklist.3 libblacklist.3 \
+ libblocklist.3 blacklist_open.3 \
+ libblocklist.3 blacklist_close.3 \
+ libblocklist.3 blacklist.3 \
+ libblocklist.3 blacklist_r.3 \
+ libblocklist.3 blacklist_sa.3 \
+ libblocklist.3 blacklist_sa_r.3
.include <bsd.lib.mk>
diff --git a/lib/libblocklist/Makefile b/lib/libblocklist/Makefile
new file mode 100644
index 000000000000..127abb23f43e
--- /dev/null
+++ b/lib/libblocklist/Makefile
@@ -0,0 +1,30 @@
+BLOCKLIST_DIR=${SRCTOP}/contrib/blocklist
+
+.PATH: ${BLOCKLIST_DIR}/lib ${BLOCKLIST_DIR}/include ${BLOCKLIST_DIR}/port
+
+PACKAGE= blocklist
+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 <bsd.lib.mk>
diff --git a/lib/libblocklist/Makefile.depend b/lib/libblocklist/Makefile.depend
new file mode 100644
index 000000000000..577dc5747f1e
--- /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 <dirdeps.mk>
+
+.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 1c40e21d361d..a9ccf3aa0870 100644
--- a/lib/libsysdecode/Makefile.depend
+++ b/lib/libsysdecode/Makefile.depend
@@ -38,7 +38,7 @@ DIRDEPS = \
lib/libarchive \
lib/libbe \
lib/libbegemot \
- lib/libblacklist \
+ lib/libblocklist \
lib/libblocksruntime \
lib/libbluetooth \
lib/libbsddialog \
diff --git a/libexec/Makefile b/libexec/Makefile
index e87b48b153a8..180dd10b5d29 100644
--- a/libexec/Makefile
+++ b/libexec/Makefile
@@ -4,7 +4,7 @@
SUBDIR= ${_atf} \
${_atrun} \
- ${_blacklistd-helper} \
+ ${_blocklistd-helper} \
${_comsat} \
${_dma} \
flua \
@@ -37,8 +37,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 d32b69c278a8..000000000000
--- a/libexec/blacklistd-helper/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-BLOCKLIST_DIR=${SRCTOP}/contrib/blocklist
-
-PACKAGE= blocklist
-
-SCRIPTS= ${BLOCKLIST_DIR}/libexec/blacklistd-helper
-
-.include <bsd.prog.mk>
diff --git a/libexec/blocklistd-helper/Makefile b/libexec/blocklistd-helper/Makefile
new file mode 100644
index 000000000000..5c72b5155662
--- /dev/null
+++ b/libexec/blocklistd-helper/Makefile
@@ -0,0 +1,10 @@
+BLOCKLIST_DIR=${SRCTOP}/contrib/blocklist
+
+PACKAGE= blocklist
+
+SCRIPTS= ${BLOCKLIST_DIR}/libexec/blocklistd-helper
+
+# blacklist
+SCRIPTS+= blacklistd-helper
+
+.include <bsd.prog.mk>
diff --git a/libexec/blacklistd-helper/Makefile.depend b/libexec/blocklistd-helper/Makefile.depend
index 11aba52f82cf..11aba52f82cf 100644
--- a/libexec/blacklistd-helper/Makefile.depend
+++ b/libexec/blocklistd-helper/Makefile.depend
diff --git a/libexec/blocklistd-helper/blacklistd-helper b/libexec/blocklistd-helper/blacklistd-helper
new file mode 100644
index 000000000000..4195f070e8ee
--- /dev/null
+++ b/libexec/blocklistd-helper/blacklistd-helper
@@ -0,0 +1,293 @@
+#!/bin/sh
+#echo "run $@" 1>&2
+#set -x
+# $1 command
+# $2 rulename
+# $3 protocol
+# $4 address
+# $5 mask
+# $6 port
+# $7 id
+
+pf=
+if [ -f "/etc/ipfw-blacklist.rc" ]; then
+ 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}
+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
+
+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
+ ipfilter)
+ # N.B.: If you reload /etc/ipf.conf then you need to stop and
+ # restart blacklistd (and make sure blacklistd_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 blacklistd; then
+ # /etc/rc.d/blacklistd 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 blacklistd
+ #
+ # where "blacklistd" 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 blacklistd 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 "<port$6>" || \
+ echo "block in quick $proto from <port$6> 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/blacklistd 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/libexec/fingerd/Makefile b/libexec/fingerd/Makefile
index 296cb504bab1..e2fe412df8bc 100644
--- a/libexec/fingerd/Makefile
+++ b/libexec/fingerd/Makefile
@@ -7,10 +7,10 @@ MAN= fingerd.8
WARNS?= 2
WFORMAT=0
-.if ${MK_BLACKLIST_SUPPORT} != "no"
-CFLAGS+= -DUSE_BLACKLIST -I${SRCTOP}/contrib/blocklist/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 <bsd.prog.mk>
diff --git a/libexec/fingerd/Makefile.depend.options b/libexec/fingerd/Makefile.depend.options
index 5a94eff626dc..f68343adae89 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 <dirdeps-options.mk>
diff --git a/libexec/fingerd/fingerd.c b/libexec/fingerd/fingerd.c
index c30d5e5e0ef5..8b63aa338b0c 100644
--- a/libexec/fingerd/fingerd.c
+++ b/libexec/fingerd/fingerd.c
@@ -45,8 +45,8 @@
#include <stdlib.h>
#include <string.h>
#include "pathnames.h"
-#ifdef USE_BLACKLIST
-#include <blacklist.h>
+#ifdef USE_BLOCKLIST
+#include <blocklist.h>
#endif
void logerr(const char *, ...) __printflike(1, 2) __dead2;
@@ -144,8 +144,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);
@@ -153,8 +153,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);
@@ -194,8 +194,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/rc/rc.conf b/libexec/rc/rc.conf
index c776a815003c..b7cce777c4f6 100644
--- a/libexec/rc/rc.conf
+++ b/libexec/rc/rc.conf
@@ -319,8 +319,10 @@ ctld_enable="NO" # CAM Target Layer / iSCSI target daemon.
local_unbound_enable="NO" # Local caching DNS resolver
local_unbound_oomprotect="YES" # Don't kill local_unbound when swap space is exhausted.
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).
resolv_enable="YES" # Enable resolv / resolvconf
#
diff --git a/libexec/rc/rc.d/Makefile b/libexec/rc/rc.d/Makefile
index f6d1a34ceb9e..093da31ed787 100644
--- a/libexec/rc/rc.d/Makefile
+++ b/libexec/rc/rc.d/Makefile
@@ -111,9 +111,10 @@ AUTOFS= automount \
automountd \
autounmountd
-CONFGROUPS.${MK_BLACKLIST}+= BLOCKLIST
+CONFGROUPS.${MK_BLOCKLIST}+= BLOCKLIST
BLOCKLISTPACKAGE= blocklist
-BLOCKLIST= blacklistd
+BLOCKLIST= blacklistd \
+ blocklistd
CONFGROUPS.${MK_BLUETOOTH}+= BLUETOOTH
BLUETOOTHPACKAGE= bluetooth
diff --git a/libexec/rc/rc.d/blacklistd b/libexec/rc/rc.d/blacklistd
index 5248b0ea3580..9157e258f43f 100755
--- a/libexec/rc/rc.d/blacklistd
+++ b/libexec/rc/rc.d/blacklistd
@@ -34,13 +34,21 @@
. /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"
# no svcj options needed
: ${blacklistd_svcj_options:=""}
+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 100644
index 000000000000..24cbae77fd40
--- /dev/null
+++ b/libexec/rc/rc.d/blocklistd
@@ -0,0 +1,46 @@
+#!/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 pf
+
+. /etc/rc.subr
+
+name="blocklistd"
+desc="System blocklist daemon"
+rcvar="blocklistd_enable"
+command="/usr/sbin/${name}"
+required_files="/etc/blocklistd.conf"
+
+# no svcj options needed
+: ${blocklistd_svcj_options:=""}
+
+load_rc_config $name
+run_rc_command "$1"
diff --git a/release/packages/ucl/blocklist-all.ucl b/release/packages/ucl/blocklist-all.ucl
index 92f304ac9151..273df85fc22b 100644
--- a/release/packages/ucl/blocklist-all.ucl
+++ b/release/packages/ucl/blocklist-all.ucl
@@ -19,12 +19,14 @@
comment = "Network blocklist daemon"
desc = <<EOD
-The blacklistd(8) daemon monitors failed access attempts from remote network
+The blocklistd(8) daemon monitors failed access attempts from remote network
locations and automatically blocks the originating network address using the
system packet filter.
-blacklistd(8) relies on each network daemon to report access attempts, so
-only daemons which have had blacklist support added will work.
+blocklistd(8) relies on each network daemon to report access attempts, so
+only daemons which have had blocklist support added will work.
+
+The blocklistd(8) daemon was previously named blacklistd(8).
EOD
annotations {
diff --git a/secure/libexec/sshd-auth/Makefile b/secure/libexec/sshd-auth/Makefile
index a127b50b407a..0ee49585a023 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/blocklist/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_KERBEROS_SUPPORT} != "no"
diff --git a/secure/libexec/sshd-session/Makefile b/secure/libexec/sshd-session/Makefile
index 9e95c94000ff..a7849f2a35f8 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/blocklist/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_KERBEROS_SUPPORT} != "no"
diff --git a/secure/usr.sbin/sshd/Makefile.depend.options b/secure/usr.sbin/sshd/Makefile.depend.options
index 69af5a2e8d79..c8816eb881fb 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 <dirdeps-options.mk>
diff --git a/share/man/man5/periodic.conf.5 b/share/man/man5/periodic.conf.5
index a2ed2b09d772..8910895d9b89 100644
--- a/share/man/man5/periodic.conf.5
+++ b/share/man/man5/periodic.conf.5
@@ -981,7 +981,7 @@ since yesterday's check.
Space-separated list of additional anchors whose denied packets log entries to
show.
The main ruleset (i.e., the empty-string anchor) and any
-.Xr blacklistd 8
+.Xr blocklistd 8
anchors, if present, are always shown.
.It Va security_status_pfdenied_period
.Pq Vt str
diff --git a/share/man/man5/src.conf.5 b/share/man/man5/src.conf.5
index 5c8ae5b83e5f..1bb609336532 100644
--- a/share/man/man5/src.conf.5
+++ b/share/man/man5/src.conf.5
@@ -1,5 +1,5 @@
.\" DO NOT EDIT-- this file is @generated by tools/build/options/makeman.
-.Dd September 25, 2025
+.Dd October 1, 2025
.Dt SRC.CONF 5
.Os
.Sh NAME
@@ -226,10 +226,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
@@ -237,10 +242,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
and
diff --git a/share/mk/bsd.libnames.mk b/share/mk/bsd.libnames.mk
index 3ff4c4e90a1b..2f099e0579b2 100644
--- a/share/mk/bsd.libnames.mk
+++ b/share/mk/bsd.libnames.mk
@@ -27,6 +27,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 4eef5311375e..5773c4979e56 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 3e108591251a..b2ed63759c19 100644
--- a/share/mk/src.libnames.mk
+++ b/share/mk/src.libnames.mk
@@ -264,8 +264,12 @@ _LIBRARIES+= \
.if ${MK_BLACKLIST} != "no"
_LIBRARIES+= \
- blacklist \
+ blacklist
+.endif
+.if ${MK_BLOCKLIST} != "no"
+_LIBRARIES+= \
+ blocklist
.endif
.if ${MK_OFED} != "no"
@@ -319,6 +323,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} == "FreeBSD" || !defined(BOOTSTRAPPING)
@@ -865,6 +872,7 @@ LIBGTESTDIR= ${_LIB_OBJTOP}/lib/googletest/gtest
LIBGTEST_MAINDIR= ${_LIB_OBJTOP}/lib/googletest/gtest_main
LIBALIASDIR= ${_LIB_OBJTOP}/lib/libalias/libalias
LIBBLACKLISTDIR= ${_LIB_OBJTOP}/lib/libblacklist
+LIBBLOCKLISTDIR= ${_LIB_OBJTOP}/lib/libblocklist
LIBBLOCKSRUNTIMEDIR= ${_LIB_OBJTOP}/lib/libblocksruntime
LIBBSNMPDIR= ${_LIB_OBJTOP}/lib/libbsnmp/libbsnmp
LIBCASPERDIR= ${_LIB_OBJTOP}/lib/libcasper/libcasper
diff --git a/share/mk/src.opts.mk b/share/mk/src.opts.mk
index 9bd4e6a1842f..446f78a2acf3 100644
--- a/share/mk/src.opts.mk
+++ b/share/mk/src.opts.mk
@@ -66,6 +66,7 @@ __DEFAULT_YES_OPTIONS = \
AUTOFS \
BHYVE \
BLACKLIST \
+ BLOCKLIST \
BLUETOOTH \
BOOT \
BOOTPARAMD \
@@ -242,6 +243,7 @@ __LIBC_MALLOC_DEFAULT= jemalloc
#
.for var in \
BLACKLIST \
+ BLOCKLIST \
BZIP2 \
INET \
INET6 \
@@ -391,6 +393,14 @@ MK_SOURCELESS_HOST:= no
MK_SOURCELESS_UCODE:= no
.endif
+.if ${MK_BLACKLIST} == "no"
+MK_BLOCKLIST:= no
+.endif
+
+.if ${MK_BLACKLIST_SUPPORT} == "no"
+MK_BLOCKLIST_SUPPORT:= no
+.endif
+
.if ${MK_CDDL} == "no"
MK_CTF:= no
MK_DTRACE:= no
diff --git a/targets/pseudo/userland/Makefile.depend b/targets/pseudo/userland/Makefile.depend
index 5f72461ab12e..e21d7dd70eb7 100644
--- a/targets/pseudo/userland/Makefile.depend
+++ b/targets/pseudo/userland/Makefile.depend
@@ -806,6 +806,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 8e1b0282be48..63c7e69719c2 100644
--- a/targets/pseudo/userland/lib/Makefile.depend
+++ b/targets/pseudo/userland/lib/Makefile.depend
@@ -255,6 +255,10 @@ DIRDEPS+= \
DIRDEPS+= lib/libblacklist
.endif
+.if ${MK_BLOCKLIST_SUPPORT} != "no"
+DIRDEPS+= lib/libblocklist
+.endif
+
.if ${MK_ZFS} != "no"
DIRDEPS+= cddl/lib/libzutil
.endif
diff --git a/targets/pseudo/userland/libexec/Makefile.depend b/targets/pseudo/userland/libexec/Makefile.depend
index 4a6d72f914e3..9e5eec3f0c81 100644
--- a/targets/pseudo/userland/libexec/Makefile.depend
+++ b/targets/pseudo/userland/libexec/Makefile.depend
@@ -38,8 +38,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 13d7703148d2..7cf742616e63 100644
--- a/tools/build/mk/OptionalObsoleteFiles.inc
+++ b/tools/build/mk/OptionalObsoleteFiles.inc
@@ -161,7 +161,26 @@ OLD_FILES+=usr/share/man/man8/bhyveload.8.gz
OLD_DIRS+=usr/share/examples/bhyve
.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 c54c83f27553..df9c9a41227f 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 ff1c2c43d595..cd484727d636 100644
--- a/tools/build/options/WITHOUT_BLACKLIST_SUPPORT
+++ b/tools/build/options/WITHOUT_BLACKLIST_SUPPORT
@@ -1,6 +1,2 @@
-Build some programs without
-.Xr libblacklist 3
-support, like
-.Xr fingerd 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 000000000000..c456a98c672f
--- /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 000000000000..f06ebc6e4263
--- /dev/null
+++ b/tools/build/options/WITHOUT_BLOCKLIST_SUPPORT
@@ -0,0 +1,6 @@
+Build some programs without
+.Xr libblocklist 3
+support, like
+.Xr fingerd 8
+and
+.Xr sshd 8 .
diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile
index 3c5fd0973a43..44679ca290a5 100644
--- a/usr.sbin/Makefile
+++ b/usr.sbin/Makefile
@@ -121,6 +121,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 7bdff4158bb4..8a01f52926a7 100644
--- a/usr.sbin/blacklistctl/Makefile
+++ b/usr.sbin/blacklistctl/Makefile
@@ -4,19 +4,21 @@ BLOCKLIST_DIR=${SRCTOP}/contrib/blocklist
PACKAGE= blocklist
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
+MAN= blocklistctl.8
+MLINKS= blocklistctl.8 blacklistctl.8
LDFLAGS+=-L${LIBBLACKLISTDIR}
-LIBADD+= blacklist util
+LIBADD+= blocklist util
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 <bsd.prog.mk>
diff --git a/usr.sbin/blacklistd/Makefile b/usr.sbin/blacklistd/Makefile
index e0a3ddd80881..b4ba4ca2f9ad 100644
--- a/usr.sbin/blacklistd/Makefile
+++ b/usr.sbin/blacklistd/Makefile
@@ -5,19 +5,22 @@ PACKAGE= blocklist
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
-MAN= blacklistd.8 blacklistd.conf.5
+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= blocklistd.8 blocklistd.conf.5
+MLINKS= blocklistd.8 blacklistd.8 \
+ blocklistd.conf.5 blacklistd.conf.5
LDFLAGS+=-L${LIBBLACKLISTDIR}
-LIBADD+= blacklist util
+LIBADD+= blocklist util
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 <bsd.prog.mk>
diff --git a/usr.sbin/blacklistd/blacklistd.conf b/usr.sbin/blacklistd/blacklistd.conf
index b8dee6768cc7..ec995e038574 100644
--- a/usr.sbin/blacklistd/blacklistd.conf
+++ b/usr.sbin/blacklistd/blacklistd.conf
@@ -1,6 +1,9 @@
-#
+# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+# @ The file blacklistd.conf has been renamed to blocklistd.conf @
+# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+
# Blacklist rule
-# adr/mask:port type proto owner name nfail disable
+# adr/mask:port type proto owner name nfail duration
[local]
ssh stream * * * 3 24h
ftp stream * * * 3 24h
@@ -9,8 +12,9 @@ submission stream * * * 3 24h
#6161 stream tcp6 christos * 2 10m
* * * * * 3 60
-# adr/mask:port type proto owner name nfail disable
+# adr/mask:port type proto owner name nfail duration
[remote]
#129.168.0.0/16 * * * = * *
+#[2001:db8::]/32:ssh * * * = * *
#6161 = = = =/24 = =
#* stream tcp * = = =
diff --git a/usr.sbin/blocklistctl/Makefile b/usr.sbin/blocklistctl/Makefile
new file mode 100644
index 000000000000..55891bfb2670
--- /dev/null
+++ b/usr.sbin/blocklistctl/Makefile
@@ -0,0 +1,22 @@
+BLOCKLIST_DIR=${SRCTOP}/contrib/blocklist
+.PATH: ${BLOCKLIST_DIR}/bin ${BLOCKLIST_DIR}/port
+
+PACKAGE= blocklist
+
+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 <bsd.prog.mk>
diff --git a/usr.sbin/blocklistctl/Makefile.depend b/usr.sbin/blocklistctl/Makefile.depend
new file mode 100644
index 000000000000..6b74110bfe08
--- /dev/null
+++ b/usr.sbin/blocklistctl/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libblocklist \
+ lib/libc \
+ lib/libcompiler_rt \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.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 000000000000..ccee9637e208
--- /dev/null
+++ b/usr.sbin/blocklistd/Makefile
@@ -0,0 +1,23 @@
+BLOCKLIST_DIR=${SRCTOP}/contrib/blocklist
+.PATH: ${BLOCKLIST_DIR}/bin ${BLOCKLIST_DIR}/port
+
+PACKAGE= blocklist
+
+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 <bsd.prog.mk>
diff --git a/usr.sbin/blocklistd/Makefile.depend b/usr.sbin/blocklistd/Makefile.depend
new file mode 100644
index 000000000000..6b74110bfe08
--- /dev/null
+++ b/usr.sbin/blocklistd/Makefile.depend
@@ -0,0 +1,18 @@
+# Autogenerated - do NOT edit!
+
+DIRDEPS = \
+ include \
+ include/arpa \
+ include/xlocale \
+ lib/${CSU_DIR} \
+ lib/libblocklist \
+ lib/libc \
+ lib/libcompiler_rt \
+ lib/libutil \
+
+
+.include <dirdeps.mk>
+
+.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 000000000000..c6c7f7c2fafc
--- /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 * * * = * *
+#[2001:db8::]/32:ssh * * * = * *
+#6161 = = = =/24 = =
+#* stream tcp * = = =
diff --git a/usr.sbin/periodic/etc/security/520.pfdenied b/usr.sbin/periodic/etc/security/520.pfdenied
index 9852936257bc..d87dfa0ae64c 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) ${security_status_pfdenied_additionalanchors}
+ for _a in "" $(pfctl -a "blacklistd" -sA 2>/dev/null) $(pfctl -a "blocklistd" -sA 2>/dev/null) ${security_status_pfdenied_additionalanchors}
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}