aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile2
-rw-r--r--lib/bl.c116
-rw-r--r--lib/blocklist.c15
-rw-r--r--lib/libblocklist.352
-rw-r--r--lib/shlib_version2
5 files changed, 117 insertions, 70 deletions
diff --git a/lib/Makefile b/lib/Makefile
index 43da41f83b90..147f311c4782 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.6 2016/01/05 13:07:46 christos Exp $
+# $NetBSD: Makefile,v 1.1.1.1 2020/06/15 01:52:53 christos Exp $
.include <bsd.own.mk>
diff --git a/lib/bl.c b/lib/bl.c
index 2be77a422483..80396ed12b28 100644
--- a/lib/bl.c
+++ b/lib/bl.c
@@ -1,4 +1,4 @@
-/* $NetBSD: bl.c,v 1.29 2020/03/10 13:36:08 roy Exp $ */
+/* $NetBSD: bl.c,v 1.9 2025/03/30 01:53:59 christos Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -32,8 +32,10 @@
#include "config.h"
#endif
+#ifdef HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
-__RCSID("$NetBSD: bl.c,v 1.29 2020/03/10 13:36:08 roy Exp $");
+#endif
+__RCSID("$NetBSD: bl.c,v 1.9 2025/03/30 01:53:59 christos Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -57,6 +59,10 @@ __RCSID("$NetBSD: bl.c,v 1.29 2020/03/10 13:36:08 roy Exp $");
#include <pthread.h>
#endif
+#if defined(SO_RECVUCRED)
+#include <ucred.h>
+#endif
+
#include "bl.h"
typedef struct {
@@ -82,7 +88,8 @@ struct blocklist {
int b_fd;
int b_connected;
struct sockaddr_un b_sun;
- void (*b_fun)(int, const char *, va_list);
+ struct syslog_data b_syslog_data;
+ void (*b_fun)(int, struct syslog_data *, const char *, va_list);
bl_info_t b_info;
};
@@ -115,14 +122,16 @@ bl_reset(bl_t b, bool locked)
}
static void
-bl_log(void (*fun)(int, const char *, va_list), int level,
- const char *fmt, ...)
+bl_log(bl_t b, int level, const char *fmt, ...)
{
va_list ap;
int serrno = errno;
+ if (b->b_fun == NULL)
+ return;
+
va_start(ap, fmt);
- (*fun)(level, fmt, ap);
+ (*b->b_fun)(level, &b->b_syslog_data, fmt, ap);
va_end(ap);
errno = serrno;
}
@@ -152,7 +161,7 @@ bl_init(bl_t b, bool srv)
b->b_fd = socket(PF_LOCAL,
SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK|SOCK_NOSIGPIPE, 0);
if (b->b_fd == -1) {
- bl_log(b->b_fun, LOG_ERR, "%s: socket failed (%s)",
+ bl_log(b, LOG_ERR, "%s: socket failed (%s)",
__func__, strerror(errno));
BL_UNLOCK(b);
return -1;
@@ -186,7 +195,7 @@ bl_init(bl_t b, bool srv)
rv = connect(b->b_fd, (const void *)sun, (socklen_t)sizeof(*sun));
if (rv == 0) {
if (srv) {
- bl_log(b->b_fun, LOG_ERR,
+ bl_log(b, LOG_ERR,
"%s: another daemon is handling `%s'",
__func__, sun->sun_path);
goto out;
@@ -199,7 +208,7 @@ bl_init(bl_t b, bool srv)
* and only log once.
*/
if (b->b_connected != 1) {
- bl_log(b->b_fun, LOG_DEBUG,
+ bl_log(b, LOG_DEBUG,
"%s: connect failed for `%s' (%s)",
__func__, sun->sun_path, strerror(errno));
b->b_connected = 1;
@@ -207,8 +216,7 @@ bl_init(bl_t b, bool srv)
BL_UNLOCK(b);
return -1;
}
- bl_log(b->b_fun, LOG_DEBUG, "Connected to blocklist server",
- __func__);
+ bl_log(b, LOG_DEBUG, "Connected to blocklist server", __func__);
}
if (srv) {
@@ -219,8 +227,7 @@ bl_init(bl_t b, bool srv)
(void)umask(om);
errno = serrno;
if (rv == -1) {
- bl_log(b->b_fun, LOG_ERR,
- "%s: bind failed for `%s' (%s)",
+ bl_log(b, LOG_ERR, "%s: bind failed for `%s' (%s)",
__func__, sun->sun_path, strerror(errno));
goto out;
}
@@ -231,8 +238,8 @@ bl_init(bl_t b, bool srv)
#if defined(LOCAL_CREDS)
#define CRED_LEVEL 0
#define CRED_NAME LOCAL_CREDS
-#define CRED_SC_UID sc_euid
-#define CRED_SC_GID sc_egid
+#define CRED_SC_UID(x) (x)->sc_euid
+#define CRED_SC_GID(x) (x)->sc_egid
#define CRED_MESSAGE SCM_CREDS
#define CRED_SIZE SOCKCREDSIZE(NGROUPS_MAX)
#define CRED_TYPE struct sockcred
@@ -240,12 +247,21 @@ bl_init(bl_t b, bool srv)
#elif defined(SO_PASSCRED)
#define CRED_LEVEL SOL_SOCKET
#define CRED_NAME SO_PASSCRED
-#define CRED_SC_UID uid
-#define CRED_SC_GID gid
+#define CRED_SC_UID(x) (x)->uid
+#define CRED_SC_GID(x) (x)->gid
#define CRED_MESSAGE SCM_CREDENTIALS
#define CRED_SIZE sizeof(struct ucred)
#define CRED_TYPE struct ucred
#define GOT_CRED 2
+#elif defined(SO_RECVUCRED)
+#define CRED_LEVEL SOL_SOCKET
+#define CRED_NAME SO_RECVUCRED
+#define CRED_SC_UID(x) ucred_geteuid(x)
+#define CRED_SC_GID(x) ucred_getegid(x)
+#define CRED_MESSAGE SCM_UCRED
+#define CRED_SIZE ucred_size()
+#define CRED_TYPE ucred_t
+#define GOT_CRED 2
#else
#define GOT_CRED 0
/*
@@ -259,7 +275,7 @@ bl_init(bl_t b, bool srv)
#ifdef CRED_LEVEL
if (setsockopt(b->b_fd, CRED_LEVEL, CRED_NAME,
&one, (socklen_t)sizeof(one)) == -1) {
- bl_log(b->b_fun, LOG_ERR, "%s: setsockopt %s "
+ bl_log(b, LOG_ERR, "%s: setsockopt %s "
"failed (%s)", __func__, __STRING(CRED_NAME),
strerror(errno));
goto out;
@@ -275,12 +291,15 @@ out:
}
bl_t
-bl_create(bool srv, const char *path, void (*fun)(int, const char *, va_list))
+bl_create(bool srv, const char *path,
+ void (*fun)(int, struct syslog_data *, const char *, va_list))
{
+ static struct syslog_data sd = SYSLOG_DATA_INIT;
bl_t b = calloc(1, sizeof(*b));
if (b == NULL)
- goto out;
- b->b_fun = fun == NULL ? vsyslog : fun;
+ return NULL;
+ b->b_fun = fun;
+ b->b_syslog_data = sd;
b->b_fd = -1;
b->b_connected = -1;
BL_INIT(b);
@@ -295,11 +314,6 @@ bl_create(bool srv, const char *path, void (*fun)(int, const char *, va_list))
bl_init(b, srv);
return b;
-out:
- free(b);
- bl_log(fun, LOG_ERR, "%s: malloc failed (%s)", __func__,
- strerror(errno));
- return NULL;
}
void
@@ -327,7 +341,7 @@ bl_getsock(bl_t b, struct sockaddr_storage *ss, const struct sockaddr *sa,
family = AF_INET6;
break;
default:
- bl_log(b->b_fun, LOG_ERR, "%s: invalid socket len %u (%s)",
+ bl_log(b, LOG_ERR, "%s: invalid socket len %u (%s)",
__func__, (unsigned)slen, ctx);
errno = EINVAL;
return -1;
@@ -336,7 +350,7 @@ bl_getsock(bl_t b, struct sockaddr_storage *ss, const struct sockaddr *sa,
memcpy(ss, sa, slen);
if (ss->ss_family != family) {
- bl_log(b->b_fun, LOG_INFO,
+ bl_log(b, LOG_INFO,
"%s: correcting socket family %d to %d (%s)",
__func__, ss->ss_family, family, ctx);
ss->ss_family = family;
@@ -344,7 +358,7 @@ bl_getsock(bl_t b, struct sockaddr_storage *ss, const struct sockaddr *sa,
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
if (ss->ss_len != slen) {
- bl_log(b->b_fun, LOG_INFO,
+ bl_log(b, LOG_INFO,
"%s: correcting socket len %u to %u (%s)",
__func__, ss->ss_len, (unsigned)slen, ctx);
ss->ss_len = (uint8_t)slen;
@@ -424,16 +438,18 @@ bl_recv(bl_t b)
union {
char ctrl[CMSG_SPACE(sizeof(int)) + CMSG_SPACE(CRED_SIZE)];
uint32_t fd;
- CRED_TYPE sc;
} ua;
struct cmsghdr *cmsg;
+#if GOT_CRED != 0
CRED_TYPE *sc;
+#endif
union {
bl_message_t bl;
char buf[512];
} ub;
int got;
ssize_t rlen;
+ size_t rem;
bl_info_t *bi = &b->b_info;
got = 0;
@@ -449,18 +465,18 @@ bl_recv(bl_t b)
msg.msg_flags = 0;
msg.msg_control = ua.ctrl;
- msg.msg_controllen = sizeof(ua.ctrl) + 100;
+ msg.msg_controllen = sizeof(ua.ctrl);
rlen = recvmsg(b->b_fd, &msg, 0);
if (rlen == -1) {
- bl_log(b->b_fun, LOG_ERR, "%s: recvmsg failed (%s)", __func__,
+ bl_log(b, LOG_ERR, "%s: recvmsg failed (%s)", __func__,
strerror(errno));
return NULL;
}
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
if (cmsg->cmsg_level != SOL_SOCKET) {
- bl_log(b->b_fun, LOG_ERR,
+ bl_log(b, LOG_ERR,
"%s: unexpected cmsg_level %d",
__func__, cmsg->cmsg_level);
continue;
@@ -468,10 +484,15 @@ bl_recv(bl_t b)
switch (cmsg->cmsg_type) {
case SCM_RIGHTS:
if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) {
- bl_log(b->b_fun, LOG_ERR,
+ int *fd = (void *)CMSG_DATA(cmsg);
+ size_t len = cmsg->cmsg_len / sizeof(int);
+ bl_log(b, LOG_ERR,
"%s: unexpected cmsg_len %d != %zu",
__func__, cmsg->cmsg_len,
- CMSG_LEN(2 * sizeof(int)));
+ CMSG_LEN(sizeof(int)));
+
+ for (size_t i = 0; i < len; i++)
+ (void)close(fd[i]);
continue;
}
memcpy(&bi->bi_fd, CMSG_DATA(cmsg), sizeof(bi->bi_fd));
@@ -480,13 +501,13 @@ bl_recv(bl_t b)
#ifdef CRED_MESSAGE
case CRED_MESSAGE:
sc = (void *)CMSG_DATA(cmsg);
- bi->bi_uid = sc->CRED_SC_UID;
- bi->bi_gid = sc->CRED_SC_GID;
+ bi->bi_uid = CRED_SC_UID(sc);
+ bi->bi_gid = CRED_SC_GID(sc);
got |= GOT_CRED;
break;
#endif
default:
- bl_log(b->b_fun, LOG_ERR,
+ bl_log(b, LOG_ERR,
"%s: unexpected cmsg_type %d",
__func__, cmsg->cmsg_type);
continue;
@@ -495,7 +516,7 @@ bl_recv(bl_t b)
}
if (got != (GOT_CRED|GOT_FD)) {
- bl_log(b->b_fun, LOG_ERR, "message missing %s %s",
+ bl_log(b, LOG_ERR, "message missing %s %s",
#if GOT_CRED != 0
(got & GOT_CRED) == 0 ? "cred" :
#endif
@@ -503,13 +524,15 @@ bl_recv(bl_t b)
return NULL;
}
- if ((size_t)rlen <= sizeof(ub.bl)) {
- bl_log(b->b_fun, LOG_ERR, "message too short %zd", rlen);
+ 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->b_fun, LOG_ERR, "bad version %d", ub.bl.bl_version);
+ bl_log(b, LOG_ERR, "bad version %d", ub.bl.bl_version);
return NULL;
}
@@ -520,7 +543,12 @@ bl_recv(bl_t b)
bi->bi_uid = -1;
bi->bi_gid = -1;
#endif
- strlcpy(bi->bi_msg, ub.bl.bl_data, MIN(sizeof(bi->bi_msg),
- ((size_t)rlen - sizeof(ub.bl) + 1)));
+ 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/lib/blocklist.c b/lib/blocklist.c
index 9c09f4186ba6..139fc4342626 100644
--- a/lib/blocklist.c
+++ b/lib/blocklist.c
@@ -1,4 +1,4 @@
-/* $NetBSD: blocklist.c,v 1.6 2019/11/06 20:50:01 christos Exp $ */
+/* $NetBSD: blocklist.c,v 1.4 2025/02/11 17:48:30 christos Exp $ */
/*-
* Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -32,8 +32,10 @@
#include "config.h"
#endif
+#ifdef HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
-__RCSID("$NetBSD: blocklist.c,v 1.6 2019/11/06 20:50:01 christos Exp $");
+#endif
+__RCSID("$NetBSD: blocklist.c,v 1.4 2025/02/11 17:48:30 christos Exp $");
#include <stdio.h>
#include <bl.h>
@@ -98,7 +100,14 @@ blocklist_r(struct blocklist *bl, int action, int rfd, const char *msg)
struct blocklist *
blocklist_open(void) {
- return bl_create(false, NULL, vsyslog);
+ return bl_create(false, NULL, vsyslog_r);
+}
+
+struct blocklist *
+blocklist_open2(
+ void (*logger)(int, struct syslog_data *, const char *, va_list))
+{
+ return bl_create(false, NULL, logger);
}
void
diff --git a/lib/libblocklist.3 b/lib/libblocklist.3
index 8368624dbc6a..7a016625a047 100644
--- a/lib/libblocklist.3
+++ b/lib/libblocklist.3
@@ -1,4 +1,4 @@
-.\" $NetBSD: libblocklist.3,v 1.10 2020/03/30 15:47:15 christos Exp $
+.\" $NetBSD: libblocklist.3,v 1.7 2025/02/05 20:14:30 christos Exp $
.\"
.\" Copyright (c) 2015 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -27,23 +27,26 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd March 30, 2020
+.Dd February 5, 2025
.Dt LIBBLOCKLIST 3
.Os
.Sh NAME
.Nm blocklist_open ,
+.Nm blocklist_open2 ,
.Nm blocklist_close ,
.Nm blocklist_r ,
.Nm blocklist ,
.Nm blocklist_sa ,
.Nm blocklist_sa_r
-.Nd Blacklistd notification library
+.Nd Blocklistd notification library
.Sh LIBRARY
.Lb libblocklist
.Sh SYNOPSIS
.In blocklist.h
.Ft struct blocklist *
.Fn blocklist_open "void"
+.Ft struct blocklist *
+.Fn blocklist_open2 "void (*logger)(int, struct syslog_data *, va_list)"
.Ft void
.Fn blocklist_close "struct blocklist *cookie"
.Ft int
@@ -68,6 +71,19 @@ and returns a pointer to it, or
.Dv NULL
on failure.
.Pp
+The function
+.Fn blocklist_open2
+is similar to
+.Fn blocklist_open
+but allows a
+.Fa logger
+to be specified.
+If the
+.Fa logger
+is
+.Dv NULL ,
+then no logging is performed.
+.Pp
The
.Fn blocklist_close
function frees all memory and resources used.
@@ -89,27 +105,21 @@ argument.
The
.Ar action
parameter can take these values:
-.Bl -tag -width ".Va BLOCKLIST_ABUSIVE_BEHAVIOR"
+.Bl -tag -width ".Dv BLOCKLIST_ABUSIVE_BEHAVIOR"
+.It Va BLOCKLIST_BAD_USER
+The sending daemon has determined the username presented for
+authentication is invalid.
+This is considered as one failure count.
.It Va BLOCKLIST_AUTH_FAIL
There was an unsuccessful authentication attempt.
-.It Va BLOCKLIST_AUTH_OK
-A user successfully authenticated.
+This is considered as two failure counts together.
.It Va BLOCKLIST_ABUSIVE_BEHAVIOR
-The sending daemon has detected abusive behavior
-from the remote system.
-The remote address should
-be blocked as soon as possible.
-.It Va BLOCKLIST_BAD_USER
-The sending daemon has determined the username
-presented for authentication is invalid.
-The
-.Xr blocklistd 8
-daemon compares the username to a configured list of forbidden
-usernames and
-blocks the address immediately if a forbidden username matches.
-(The
-.Ar BLOCKLIST_BAD_USER
-support is not currently available.)
+The sending daemon has detected abusive behavior from the remote system.
+This is considered as a total immediate failure.
+The remote address will be blocked as soon as possible.
+.It Va BLOCKLIST_AUTH_OK
+A valid user successfully authenticated.
+Any entry for the remote address will be removed as soon as possible.
.El
.Pp
The
diff --git a/lib/shlib_version b/lib/shlib_version
index 97c9f92d6b8f..3d7c908e43d6 100644
--- a/lib/shlib_version
+++ b/lib/shlib_version
@@ -1,2 +1,2 @@
major=0
-minor=0
+minor=1