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
This commit is contained in:
Jose Luis Duran 2025-10-12 17:14:27 +00:00
parent 4d56eb007b
commit 7238317403
No known key found for this signature in database
GPG key ID: 5415E244477475CC
63 changed files with 2425 additions and 143 deletions

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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 ",

View file

@ -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

View file

@ -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);
}

View file

@ -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 */

View file

@ -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");
}

View file

@ -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);

View file

@ -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 */

View file

@ -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);
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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
MAN= libblocklist.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
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>

30
lib/libblocklist/Makefile Normal file
View file

@ -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>

View file

@ -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

View file

@ -38,7 +38,7 @@ DIRDEPS = \
lib/libarchive \
lib/libbe \
lib/libbegemot \
lib/libblacklist \
lib/libblocklist \
lib/libblocksruntime \
lib/libbluetooth \
lib/libbsddialog \

View file

@ -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"

View file

@ -1,7 +0,0 @@
BLOCKLIST_DIR=${SRCTOP}/contrib/blocklist
PACKAGE= blocklist
SCRIPTS= ${BLOCKLIST_DIR}/libexec/blacklistd-helper
.include <bsd.prog.mk>

View file

@ -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>

View file

@ -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

View file

@ -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>

View file

@ -1,5 +1,5 @@
# This file is not autogenerated - take care!
DIRDEPS_OPTIONS= BLACKLIST_SUPPORT
DIRDEPS_OPTIONS= BLOCKLIST_SUPPORT
.include <dirdeps-options.mk>

View file

@ -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));

View file

@ -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
#

View file

@ -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

View file

@ -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"

View file

@ -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"

View file

@ -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 {

View file

@ -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"

View file

@ -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"

View file

@ -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>

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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"

View file

@ -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

View file

@ -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 .

View file

@ -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 .

View file

@ -0,0 +1,4 @@
Set this if you do not want to build
.Xr blocklistd 8
and
.Xr blocklistctl 8 .

View file

@ -0,0 +1,6 @@
Build some programs without
.Xr libblocklist 3
support, like
.Xr fingerd 8
and
.Xr sshd 8 .

View file

@ -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

View file

@ -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>

View file

@ -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>

View file

@ -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 * = = =

View file

@ -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>

View file

@ -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

View file

@ -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>

View file

@ -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

View file

@ -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 * = = =

View file

@ -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}