diff options
| author | Jose Luis Duran <jlduran@FreeBSD.org> | 2025-10-12 17:14:27 +0000 |
|---|---|---|
| committer | Jose Luis Duran <jlduran@FreeBSD.org> | 2025-10-12 17:14:27 +0000 |
| commit | 7238317403b95a8e35cf0bc7cd66fbd78ecbe521 (patch) | |
| tree | b480b030557dcd146b771d786e0492809e86bbc0 | |
| parent | 4d56eb007b18881becb2107f87bd2a7edca3e6bf (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
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} |
