diff options
Diffstat (limited to 'bin')
| -rw-r--r-- | bin/Makefile | 12 | ||||
| -rw-r--r-- | bin/blocklistctl.8 | 16 | ||||
| -rw-r--r-- | bin/blocklistctl.c | 4 | ||||
| -rw-r--r-- | bin/blocklistd.8 | 99 | ||||
| -rw-r--r-- | bin/blocklistd.c | 62 | ||||
| -rw-r--r-- | bin/blocklistd.conf.5 | 30 | ||||
| -rw-r--r-- | bin/conf.c | 201 | ||||
| -rw-r--r-- | bin/conf.h | 2 | ||||
| -rw-r--r-- | bin/internal.c | 6 | ||||
| -rw-r--r-- | bin/internal.h | 8 | ||||
| -rw-r--r-- | bin/run.c | 2 | ||||
| -rw-r--r-- | bin/run.h | 2 | ||||
| -rw-r--r-- | bin/state.c | 4 | ||||
| -rw-r--r-- | bin/state.h | 2 | ||||
| -rw-r--r-- | bin/support.c | 2 | ||||
| -rw-r--r-- | bin/support.h | 2 |
16 files changed, 300 insertions, 154 deletions
diff --git a/bin/Makefile b/bin/Makefile index 280c72fd3af1..d935e10e7ea9 100644 --- a/bin/Makefile +++ b/bin/Makefile @@ -1,12 +1,12 @@ -# $NetBSD: Makefile,v 1.11 2015/01/27 19:40:36 christos Exp $ +# $NetBSD: Makefile,v 1.10 2015/01/22 17:49:41 christos Exp $ BINDIR=/sbin -PROGS=blacklistd blacklistctl -MAN.blacklistd=blacklistd.8 blacklistd.conf.5 -MAN.blacklistctl=blacklistctl.8 -SRCS.blacklistd = blacklistd.c conf.c run.c state.c support.c internal.c -SRCS.blacklistctl = blacklistctl.c conf.c state.c support.c internal.c +PROGS=blocklistd blocklistctl +MAN.blocklistd=blocklistd.8 blocklistd.conf.5 +MAN.blocklistctl=blocklistctl.8 +SRCS.blocklistd = blocklistd.c conf.c run.c state.c support.c internal.c +SRCS.blocklistctl = blocklistctl.c conf.c state.c support.c internal.c DBG=-g LDADD+=-lutil diff --git a/bin/blocklistctl.8 b/bin/blocklistctl.8 index 7c6521117745..f3de48a6a9bd 100644 --- a/bin/blocklistctl.8 +++ b/bin/blocklistctl.8 @@ -1,4 +1,4 @@ -.\" $NetBSD: blacklistctl.8,v 1.9 2016/06/08 12:48:37 wiz Exp $ +.\" $NetBSD: blocklistctl.8,v 1.8 2016/06/07 17:31:02 christos Exp $ .\" .\" Copyright (c) 2015 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -28,11 +28,11 @@ .\" POSSIBILITY OF SUCH DAMAGE. .\" .Dd June 7, 2016 -.Dt BLACKLISTCTL 8 +.Dt BLOCKLISTCTL 8 .Os .Sh NAME -.Nm blacklistctl -.Nd display and change the state of blacklistd +.Nm blocklistctl +.Nd display and change the state of blocklistd .Sh SYNOPSIS .Nm .Cm dump @@ -40,7 +40,7 @@ .Sh DESCRIPTION .Nm is a program used to display the state of -.Xr blacklistd 8 +.Xr blocklistd 8 .Pp The following options are available: .Bl -tag -width indent @@ -60,17 +60,17 @@ Normally the width of addresses is good for IPv4, the flag, makes the display wide enough for IPv6 addresses. .El .Sh SEE ALSO -.Xr blacklistd 8 +.Xr blocklistd 8 .Sh NOTES Sometimes the reported number of failed attempts can exceed the number of attempts that -.Xr blacklistd 8 +.Xr blocklistd 8 is configured to block. This can happen either because the rule has been removed manually, or because there were more attempts in flight while the rule block was being added. This condition is normal; in that case -.Xr blacklistd 8 +.Xr blocklistd 8 will first attempt to remove the existing rule, and then it will re-add it to make sure that there is only one rule active. .Sh HISTORY diff --git a/bin/blocklistctl.c b/bin/blocklistctl.c index aebbf72acc5e..a11ae8739cca 100644 --- a/bin/blocklistctl.c +++ b/bin/blocklistctl.c @@ -1,4 +1,4 @@ -/* $NetBSD: blacklistctl.c,v 1.23 2018/05/24 19:21:01 christos Exp $ */ +/* $NetBSD: blocklistctl.c,v 1.22 2018/05/24 19:19:37 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -33,7 +33,7 @@ #endif #include <sys/cdefs.h> -__RCSID("$NetBSD: blacklistctl.c,v 1.23 2018/05/24 19:21:01 christos Exp $"); +__RCSID("$NetBSD: blocklistctl.c,v 1.22 2018/05/24 19:19:37 christos Exp $"); #include <stdio.h> #include <time.h> diff --git a/bin/blocklistd.8 b/bin/blocklistd.8 index 5846047304dc..c28e8ac08e90 100644 --- a/bin/blocklistd.8 +++ b/bin/blocklistd.8 @@ -1,4 +1,4 @@ -.\" $NetBSD: blacklistd.8,v 1.18 2016/07/30 06:09:29 dholland Exp $ +.\" $NetBSD: blocklistd.8,v 1.23 2020/04/21 13:57:12 christos Exp $ .\" .\" Copyright (c) 2015 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -27,11 +27,11 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd June 7, 2016 -.Dt BLACKLISTD 8 +.Dd April 21, 2020 +.Dt BLOCKLISTD 8 .Os .Sh NAME -.Nm blacklistd +.Nm blocklistd .Nd block and release ports on demand to avoid DoS abuse .Sh SYNOPSIS .Nm @@ -55,16 +55,52 @@ If no such file is specified, then it only listens to the socket path specified by .Ar sockspath or if that is not specified to -.Pa /var/run/blacklistd.sock . +.Pa /var/run/blocklistd.sock . Each notification contains an (action, port, protocol, address, owner) tuple that identifies the remote connection and the action. This tuple is consulted against entries in .Ar configfile with syntax specified in -.Xr blacklistd.conf 5 . +.Xr blocklistd.conf 5 . If an entry is matched, a state entry is created for that tuple. Each entry contains a number of tries limit and a duration. .Pp +The way +.Nm +does configuration entry matching is by having the client side pass the +file descriptor associated with the connection the client wants to blocklist +as well as passing socket credentials. +.Pp +The file descriptor is used to retrieve information (address and port) +about the remote side with +.Xr getpeername 2 +and the local side with +.Xr getsockname 2 . +.Pp +By examining the port of the local side, +.Nm +can determine if the client program +.Dq owns +the port. +By examining the optional address portion on the local side, it can match +interfaces. +By examining the remote address, it can match specific allow or deny rules. +.Pp +Finally +.Nm +can examine the socket credentials to match the user in the configuration file. +.Pp +While this works well for TCP sockets, it cannot be relied on for unbound +UDP sockets. +It is also less meaningful when it comes to connections using non-privileged +ports. +On the other hand, if we receive a request that has a local endpoint indicating +a UDP privileged port, we can presume that the client was privileged to be +able to acquire that port. +.Pp +Once an entry is matched +.Nm +can perform various actions. If the action is .Dq add and the number of tries limit is reached, then a @@ -80,17 +116,17 @@ specified by the arguments. The .Ar rulename argument can be set from the command line (default -.Dv blacklistd ) . +.Dv blocklistd ) . The script could print a numerical id to stdout as a handle for the rule that can be used later to remove that connection, but that is not required as all information to remove the rule is kept. .Pp If the action is -.Dq remove +.Dq rem Then the same control script is invoked as: .Bd -literal -offset indent -control remove <rulename> <proto> <address> <mask> <port> <id> +control rem <rulename> <proto> <address> <mask> <port> <id> .Ed .Pp where @@ -117,7 +153,7 @@ The following options are available: Use .Ar controlprog to communicate with the packet filter, usually -.Pa /libexec/blacklistd-helper . +.Pa /libexec/blocklistd-helper . The following arguments are passed to the control program: .Bl -tag -width protocol .It action @@ -148,12 +184,12 @@ The add command is expected to return the rule identifier string to stdout. .El .It Fl c Ar configuration The name of the configuration file to read, usually -.Pa /etc/blacklistd.conf . +.Pa /etc/blocklistd.conf . .It Fl D Ar dbfile The Berkeley DB file where .Nm stores its state, usually -.Pa /var/run/blacklistd.db . +.Pa /var/db/blocklistd.db . .It Fl d Normally, .Nm @@ -174,11 +210,11 @@ will create sockets to listen to. This is useful for chrooted environments. .It Fl R Ar rulename Specify the default rule name for the packet filter rules, usually -.Dv blacklistd . +.Dv blocklistd . .It Fl r Re-read the firewall rules from the internal database, then remove and re-add them. -This helps for packet filters that don't retain state across reboots. +This helps for packet filters that do not retain state across reboots. .It Fl s Ar sockpath Add .Ar sockpath @@ -198,20 +234,41 @@ diagnostic messages to instead of .Xr syslogd 8 . .El +.Sh SIGNAL HANDLING +.Nm +deals with the following signals: +.Bl -tag -width "USR2" +.It Dv HUP +Receipt of this signal causes +.Nm +to re-read the configuration file. +.It Dv INT , Dv TERM & Dv QUIT +These signals tell +.Nm +to exit in an orderly fashion. +.It Dv USR1 +This signal tells +.Nm +to increase the internal debugging level by 1. +.It Dv USR2 +This signal tells +.Nm +to decrease the internal debugging level by 1. +.El .Sh FILES -.Bl -tag -width /libexec/blacklistd-helper -compact -.It Pa /libexec/blacklistd-helper +.Bl -tag -width /libexec/blocklistd-helper -compact +.It Pa /libexec/blocklistd-helper Shell script invoked to interface with the packet filter. -.It Pa /etc/blacklistd.conf +.It Pa /etc/blocklistd.conf Configuration file. -.It Pa /var/db/blacklistd.db +.It Pa /var/db/blocklistd.db Database of current connection entries. -.It Pa /var/run/blacklistd.sock +.It Pa /var/run/blocklistd.sock Socket to receive connection notifications. .El .Sh SEE ALSO -.Xr blacklistd.conf 5 , -.Xr blacklistctl 8 , +.Xr blocklistd.conf 5 , +.Xr blocklistctl 8 , .Xr npfctl 8 , .Xr syslogd 8 .Sh HISTORY diff --git a/bin/blocklistd.c b/bin/blocklistd.c index ac92bbf2ffbf..01dd629aecd0 100644 --- a/bin/blocklistd.c +++ b/bin/blocklistd.c @@ -1,4 +1,4 @@ -/* $NetBSD: blacklistd.c,v 1.38 2019/02/27 02:20:18 christos Exp $ */ +/* $NetBSD: blocklistd.c,v 1.42 2020/03/11 02:33:18 roy Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -32,7 +32,7 @@ #include "config.h" #endif #include <sys/cdefs.h> -__RCSID("$NetBSD: blacklistd.c,v 1.38 2019/02/27 02:20:18 christos Exp $"); +__RCSID("$NetBSD: blocklistd.c,v 1.42 2020/03/11 02:33:18 roy Exp $"); #include <sys/types.h> #include <sys/socket.h> @@ -123,7 +123,7 @@ getremoteaddress(bl_info_t *bi, struct sockaddr_storage *rss, socklen_t *rsl) return 0; if (errno != ENOTCONN) { - (*lfun)(LOG_ERR, "getpeername failed (%m)"); + (*lfun)(LOG_ERR, "getpeername failed (%m)"); return -1; } @@ -141,13 +141,13 @@ getremoteaddress(bl_info_t *bi, struct sockaddr_storage *rss, socklen_t *rsl) break; default: (*lfun)(LOG_ERR, "bad client passed socket family %u", - (unsigned)bi->bi_ss.ss_family); + (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); + (unsigned)*rsl, (unsigned)bi->bi_slen); return -1; } @@ -157,7 +157,7 @@ getremoteaddress(bl_info_t *bi, struct sockaddr_storage *rss, socklen_t *rsl) if (*rsl != rss->ss_len) { (*lfun)(LOG_ERR, "bad client passed socket internal length %u != %u", - (unsigned)*rsl, (unsigned)rss->ss_len); + (unsigned)*rsl, (unsigned)rss->ss_len); return -1; } #endif @@ -176,12 +176,12 @@ process(bl_t bl) struct timespec ts; if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { - (*lfun)(LOG_ERR, "clock_gettime failed (%m)"); + (*lfun)(LOG_ERR, "clock_gettime failed (%m)"); return; } if ((bi = bl_recv(bl)) == NULL) { - (*lfun)(LOG_ERR, "no message (%m)"); + (*lfun)(LOG_ERR, "no message (%m)"); return; } @@ -214,33 +214,38 @@ process(bl_t bl) } 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 (dbi.id[0]) { + if (c.c_nfail != -1 && dbi.count >= c.c_nfail) { /* - * We should not be getting this since the rule - * should have blocked the address. A possible - * explanation is that someone removed that rule, - * and another would be that we got another attempt - * before we added the rule. In anycase, we remove - * and re-add the rule because we don't want to add - * it twice, because then we'd lose track of it. + * No point in re-adding the rule. + * It might exist already due to latency in processing + * and removing the rule is the wrong thing to do as + * it allows a window to attack again. */ - (*lfun)(LOG_DEBUG, "rule exists %s", dbi.id); - (void)run_change("rem", &c, dbi.id, 0); - dbi.id[0] = '\0'; - } - if (c.c_nfail != -1 && dbi.count >= c.c_nfail) { - int res = run_change("add", &c, dbi.id, sizeof(dbi.id)); - if (res == -1) - goto out; + if (dbi.id[0] == '\0') { + int res = run_change("add", &c, + dbi.id, sizeof(dbi.id)); + if (res == -1) + goto out; + } sockaddr_snprintf(rbuf, sizeof(rbuf), "%a", (void *)&rss); (*lfun)(LOG_INFO, "blocked %s/%d:%d for %d seconds", rbuf, c.c_lmask, c.c_port, c.c_duration); - } break; case BL_DELETE: @@ -249,8 +254,11 @@ process(bl_t bl) dbi.count = 0; dbi.last = 0; break; + case BL_BADUSER: + /* ignore for now */ + break; default: - (*lfun)(LOG_ERR, "unknown message %d", bi->bi_type); + (*lfun)(LOG_ERR, "unknown message %d", bi->bi_type); } state_put(state, &c, &dbi); @@ -292,7 +300,7 @@ update(void) void *ss = &c.c_ss; if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { - (*lfun)(LOG_ERR, "clock_gettime failed (%m)"); + (*lfun)(LOG_ERR, "clock_gettime failed (%m)"); return; } diff --git a/bin/blocklistd.conf.5 b/bin/blocklistd.conf.5 index 3b85fb889e32..6d1eb36e098e 100644 --- a/bin/blocklistd.conf.5 +++ b/bin/blocklistd.conf.5 @@ -1,4 +1,4 @@ -.\" $NetBSD: blacklistd.conf.5,v 1.7 2017/06/07 13:50:57 wiz Exp $ +.\" $NetBSD: blocklistd.conf.5,v 1.9 2019/11/06 20:33:30 para Exp $ .\" .\" Copyright (c) 2015 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -27,17 +27,17 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd June 5, 2017 -.Dt BLACKLISTD.CONF 5 +.Dd May 18, 2020 +.Dt BLOCKLISTD.CONF 5 .Os .Sh NAME -.Nm blacklistd.conf -.Nd configuration file format for blacklistd +.Nm blocklistd.conf +.Nd configuration file format for blocklistd .Sh DESCRIPTION The .Nm -files contains configuration entries for -.Xr blacklistd 8 +file contains configuration entries for +.Xr blocklistd 8 in a fashion similar to .Xr inetd.conf 5 . Only one entry per line is permitted. @@ -125,18 +125,18 @@ The second field is the socket .Dv dgram , or numeric. The third field is the -.Va prococol : +.Va protocol : .Dv tcp , .Dv udp , .Dv tcp6 , .Dv udp6 , or numeric. -The fourth file is the effective user +The fourth field is the effective user .Va ( owner ) of the daemon process reporting the event, either as a username or a userid. .Pp -The rest of the fields are controlling the behavior of the filter. +The rest of the fields control the behavior of the filter. .Pp The .Va name @@ -192,12 +192,12 @@ rule that matched. .Pp The .Va remote -rules can be used for whitelisting specific addresses, changing the mask +rules can be used for allowing specific addresses, changing the mask size, the rule that the packet filter uses, the number of failed attempts, or the block duration. .Sh FILES -.Bl -tag -width /etc/blacklistd.conf -compact -.It Pa /etc/blacklistd.conf +.Bl -tag -width /etc/blocklistd.conf -compact +.It Pa /etc/blocklistd.conf Configuration file. .El .Sh EXAMPLES @@ -214,8 +214,8 @@ bnx0:ssh * * * * 3 6h 8.8.0.0/16:ssh * * * /24 = = .Ed .Sh SEE ALSO -.Xr blacklistctl 8 , -.Xr blacklistd 8 +.Xr blocklistctl 8 , +.Xr blocklistd 8 .Sh HISTORY .Nm first appeared in diff --git a/bin/conf.c b/bin/conf.c index 3ec1e085c276..6beb1051459b 100644 --- a/bin/conf.c +++ b/bin/conf.c @@ -1,4 +1,4 @@ -/* $NetBSD: conf.c,v 1.24 2016/04/04 15:52:56 christos Exp $ */ +/* $NetBSD: conf.c,v 1.30 2020/03/12 19:47:32 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -33,7 +33,7 @@ #endif #include <sys/cdefs.h> -__RCSID("$NetBSD: conf.c,v 1.24 2016/04/04 15:52:56 christos Exp $"); +__RCSID("$NetBSD: conf.c,v 1.30 2020/03/12 19:47:32 christos Exp $"); #include <stdio.h> #ifdef HAVE_LIBUTIL_H @@ -46,6 +46,7 @@ __RCSID("$NetBSD: conf.c,v 1.24 2016/04/04 15:52:56 christos Exp $"); #include <ctype.h> #include <inttypes.h> #include <netdb.h> +#include <unistd.h> #include <pwd.h> #include <syslog.h> #include <errno.h> @@ -55,6 +56,7 @@ __RCSID("$NetBSD: conf.c,v 1.24 2016/04/04 15:52:56 christos Exp $"); #include <arpa/inet.h> #include <netinet/in.h> #include <net/if.h> +#include <net/route.h> #include <sys/socket.h> #include "bl.h" @@ -90,7 +92,7 @@ advance(char **p) } static int -getnum(const char *f, size_t l, bool local, void *rp, const char *name, +conf_getnum(const char *f, size_t l, bool local, void *rp, const char *name, const char *p) { int e; @@ -127,13 +129,14 @@ out: } static int -getnfail(const char *f, size_t l, bool local, struct conf *c, const char *p) +conf_getnfail(const char *f, size_t l, bool local, struct conf *c, + const char *p) { - return getnum(f, l, local, &c->c_nfail, "nfail", p); + return conf_getnum(f, l, local, &c->c_nfail, "nfail", p); } static int -getsecs(const char *f, size_t l, bool local, struct conf *c, const char *p) +conf_getsecs(const char *f, size_t l, bool local, struct conf *c, const char *p) { int e; char *ep; @@ -173,9 +176,9 @@ again: } break; } - } else + } else tot = im; - + if (e == 0) { c->c_duration = (int)tot; return 0; @@ -193,7 +196,7 @@ out: } static int -getport(const char *f, size_t l, bool local, void *r, const char *p) +conf_getport(const char *f, size_t l, bool local, void *r, const char *p) { struct servent *sv; @@ -207,14 +210,14 @@ getport(const char *f, size_t l, bool local, void *r, const char *p) return 0; } - return getnum(f, l, local, r, "service", p); + return conf_getnum(f, l, local, r, "service", p); } static int -getmask(const char *f, size_t l, bool local, const char **p, int *mask) +conf_getmask(const char *f, size_t l, bool local, const char **p, int *mask) { char *d; - const char *s = *p; + const char *s = *p; if ((d = strchr(s, ':')) != NULL) { *d++ = '\0'; @@ -226,11 +229,12 @@ getmask(const char *f, size_t l, bool local, const char **p, int *mask) } *d++ = '\0'; - return getnum(f, l, local, mask, "mask", d); + return conf_getnum(f, l, local, mask, "mask", d); } static int -gethostport(const char *f, size_t l, bool local, struct conf *c, const char *p) +conf_gethostport(const char *f, size_t l, bool local, struct conf *c, + const char *p) { char *d; // XXX: Ok to write to string. in_port_t *port = NULL; @@ -249,7 +253,7 @@ gethostport(const char *f, size_t l, bool local, struct conf *c, const char *p) } else pstr = p; - if (getmask(f, l, local, &pstr, &c->c_lmask) == -1) + if (conf_getmask(f, l, local, &pstr, &c->c_lmask) == -1) goto out; if (d) { @@ -264,7 +268,7 @@ gethostport(const char *f, size_t l, bool local, struct conf *c, const char *p) sin6->sin6_len = sizeof(*sin6); #endif port = &sin6->sin6_port; - } + } } else if (pstr != p || strchr(p, '.') || conf_is_interface(p)) { if (pstr == p) pstr = "*"; @@ -300,7 +304,7 @@ gethostport(const char *f, size_t l, bool local, struct conf *c, const char *p) } } - if (getport(f, l, local, &c->c_port, pstr) == -1) + if (conf_getport(f, l, local, &c->c_port, pstr) == -1) return -1; if (port && c->c_port != FSTAR && c->c_port != FEQUAL) @@ -320,7 +324,7 @@ out2: } static int -getproto(const char *f, size_t l, bool local __unused, struct conf *c, +conf_getproto(const char *f, size_t l, bool local __unused, struct conf *c, const char *p) { if (strcmp(p, "stream") == 0) { @@ -331,22 +335,22 @@ getproto(const char *f, size_t l, bool local __unused, struct conf *c, c->c_proto = IPPROTO_UDP; return 0; } - return getnum(f, l, local, &c->c_proto, "protocol", p); + return conf_getnum(f, l, local, &c->c_proto, "protocol", p); } static int -getfamily(const char *f, size_t l, bool local __unused, struct conf *c, +conf_getfamily(const char *f, size_t l, bool local __unused, struct conf *c, const char *p) { if (strncmp(p, "tcp", 3) == 0 || strncmp(p, "udp", 3) == 0) { c->c_family = p[3] == '6' ? AF_INET6 : AF_INET; return 0; } - return getnum(f, l, local, &c->c_family, "family", p); + return conf_getnum(f, l, local, &c->c_family, "family", p); } static int -getuid(const char *f, size_t l, bool local __unused, struct conf *c, +conf_getuid(const char *f, size_t l, bool local __unused, struct conf *c, const char *p) { struct passwd *pw; @@ -356,21 +360,22 @@ getuid(const char *f, size_t l, bool local __unused, struct conf *c, return 0; } - return getnum(f, l, local, &c->c_uid, "user", p); + return conf_getnum(f, l, local, &c->c_uid, "user", p); } static int -getname(const char *f, size_t l, bool local, struct conf *c, +conf_getname(const char *f, size_t l, bool local, struct conf *c, const char *p) { - if (getmask(f, l, local, &p, &c->c_rmask) == -1) + if (conf_getmask(f, l, local, &p, &c->c_rmask) == -1) return -1; - + if (strcmp(p, "*") == 0) { strlcpy(c->c_name, rulename, CONFNAMESZ); return 0; } + if (strcmp(p, "=") == 0) { if (local) goto out; @@ -406,19 +411,19 @@ conf_parseline(const char *f, size_t l, char *p, struct conf *c, bool local) p++; memset(c, 0, sizeof(*c)); - e = getvalue(f, l, local, c, &p, gethostport); + e = getvalue(f, l, local, c, &p, conf_gethostport); if (e) return -1; - e = getvalue(f, l, local, c, &p, getproto); + e = getvalue(f, l, local, c, &p, conf_getproto); if (e) return -1; - e = getvalue(f, l, local, c, &p, getfamily); + e = getvalue(f, l, local, c, &p, conf_getfamily); if (e) return -1; - e = getvalue(f, l, local, c, &p, getuid); + e = getvalue(f, l, local, c, &p, conf_getuid); if (e) return -1; - e = getvalue(f, l, local, c, &p, getname); + e = getvalue(f, l, local, c, &p, conf_getname); if (e) return -1; - e = getvalue(f, l, local, c, &p, getnfail); + e = getvalue(f, l, local, c, &p, conf_getnfail); if (e) return -1; - e = getvalue(f, l, local, c, &p, getsecs); + e = getvalue(f, l, local, c, &p, conf_getsecs); if (e) return -1; return 0; @@ -473,7 +478,6 @@ conf_amask_eq(const void *v1, const void *v2, size_t len, int mask) return 1; goto out; case FEQUAL: - (*lfun)(LOG_CRIT, "%s: Internal error: bad mask %d", __func__, mask); abort(); @@ -687,7 +691,7 @@ conf_addr_eq(const struct sockaddr_storage *s1, static int conf_eq(const struct conf *c1, const struct conf *c2) { - + if (!conf_addr_eq(&c1->c_ss, &c2->c_ss, c2->c_lmask)) return 0; @@ -744,7 +748,7 @@ fmtport(char *b, size_t l, int port) if (port == FSTAR) return; - if (b[0] == '\0' || strcmp(b, "*") == 0) + if (b[0] == '\0' || strcmp(b, "*") == 0) snprintf(b, l, "%d", port); else { snprintf(buf, sizeof(buf), ":%d", port); @@ -820,7 +824,7 @@ conf_print(char *buf, size_t len, const char *pref, const char *delim, fmtmask(ha, sizeof(ha), c->c_family, c->c_lmask); fmtport(ha, sizeof(ha), c->c_port); - + sp = *delim == '\t' ? 20 : -1; hb[0] = '\0'; if (*delim) @@ -878,7 +882,7 @@ conf_merge(struct conf *c, const struct conf *sc) (*lfun)(LOG_DEBUG, "%s: %s", __func__, conf_print(buf, sizeof(buf), "to:\t", "", c)); } - + if (sc->c_name[0]) memcpy(c->c_name, sc->c_name, CONFNAMESZ); if (sc->c_uid != FEQUAL) @@ -998,32 +1002,73 @@ confset_match(const struct confset *cs, struct conf *c, return i; } -const struct conf * -conf_find(int fd, uid_t uid, const struct sockaddr_storage *rss, - struct conf *cr) -{ - int proto; - socklen_t slen; - struct sockaddr_storage lss; - size_t i; - char buf[BUFSIZ]; +#ifdef AF_ROUTE +static int +conf_route_perm(int fd) { +/* Disable for now, the access check in the routing socket uses curlwp */ +#if defined(RTM_IFANNOUNCE) && defined(RT_ROUNDUP) + /* + * Send a routing message that is not supported to check for access + * We expect EOPNOTSUPP for having access, since we are sending a + * request the system does not understand and EACCES if we don't have + * access. + */ + static struct sockaddr_in sin = { +#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN + .sin_len = sizeof(sin), +#endif + .sin_family = AF_INET, + }; + char buf[4096]; + struct rt_msghdr *rtm = (void *)buf; + char *cp = (char *)(rtm + 1); + size_t l; - memset(cr, 0, sizeof(*cr)); - slen = sizeof(lss); - memset(&lss, 0, slen); - if (getsockname(fd, (void *)&lss, &slen) == -1) { - (*lfun)(LOG_ERR, "getsockname failed (%m)"); - return NULL; +#define NEXTADDR(s) \ + l = RT_ROUNDUP(sizeof(*s)); memmove(cp, s, l); cp += l; + memset(buf, 0, sizeof(buf)); + rtm->rtm_type = RTM_IFANNOUNCE; + rtm->rtm_flags = 0; + rtm->rtm_addrs = RTA_DST|RTA_GATEWAY; + rtm->rtm_version = RTM_VERSION; + rtm->rtm_seq = 666; + NEXTADDR(&sin); + NEXTADDR(&sin); + rtm->rtm_msglen = (u_short)((char *)cp - (char *)rtm); + if (write(fd, rtm, rtm->rtm_msglen) != -1) { + (*lfun)(LOG_ERR, "Writing to routing socket succeeded!"); + return 0; + } + switch (errno) { + case EACCES: + return 0; + case EOPNOTSUPP: + return 1; + default: + (*lfun)(LOG_ERR, + "Unexpected error writing to routing socket (%m)"); + return 0; } +#else + return 0; +#endif +} +#endif + +static int +conf_handle_inet(int fd, const void *lss, struct conf *cr) +{ + char buf[BUFSIZ]; + int proto; + socklen_t slen = sizeof(proto); - slen = sizeof(proto); if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &proto, &slen) == -1) { - (*lfun)(LOG_ERR, "getsockopt failed (%m)"); - return NULL; + (*lfun)(LOG_ERR, "getsockopt failed (%m)"); + return -1; } if (debug) { - sockaddr_snprintf(buf, sizeof(buf), "%a:%p", (void *)&lss); + sockaddr_snprintf(buf, sizeof(buf), "%a:%p", lss); (*lfun)(LOG_DEBUG, "listening socket: %s", buf); } @@ -1035,19 +1080,54 @@ conf_find(int fd, uid_t uid, const struct sockaddr_storage *rss, cr->c_proto = IPPROTO_UDP; break; default: - (*lfun)(LOG_ERR, "unsupported protocol %d", proto); + (*lfun)(LOG_ERR, "unsupported protocol %d", proto); + return -1; + } + return 0; +} + +const struct conf * +conf_find(int fd, uid_t uid, const struct sockaddr_storage *rss, + struct conf *cr) +{ + socklen_t slen; + struct sockaddr_storage lss; + size_t i; + char buf[BUFSIZ]; + + memset(cr, 0, sizeof(*cr)); + slen = sizeof(lss); + memset(&lss, 0, slen); + if (getsockname(fd, (void *)&lss, &slen) == -1) { + (*lfun)(LOG_ERR, "getsockname failed (%m)"); return NULL; } switch (lss.ss_family) { case AF_INET: cr->c_port = ntohs(((struct sockaddr_in *)&lss)->sin_port); + if (conf_handle_inet(fd, &lss, cr) == -1) + return NULL; break; case AF_INET6: cr->c_port = ntohs(((struct sockaddr_in6 *)&lss)->sin6_port); + if (conf_handle_inet(fd, &lss, cr) == -1) + return NULL; break; +#ifdef AF_ROUTE + case AF_ROUTE: + if (!conf_route_perm(fd)) { + (*lfun)(LOG_ERR, + "permission denied to routing socket (%m)"); + return NULL; + } + cr->c_proto = FSTAR; + cr->c_port = FSTAR; + memcpy(&lss, rss, sizeof(lss)); + break; +#endif default: - (*lfun)(LOG_ERR, "unsupported family %d", lss.ss_family); + (*lfun)(LOG_ERR, "unsupported family %d", lss.ss_family); return NULL; } @@ -1119,6 +1199,7 @@ conf_parse(const char *f) confset_free(&lc); confset_free(&rc); fclose(fp); + free(line); return; } } @@ -1131,7 +1212,7 @@ conf_parse(const char *f) fclose(fp); confset_sort(&lc); confset_sort(&rc); - + confset_replace(&rconf, &rc); confset_replace(&lconf, &lc); diff --git a/bin/conf.h b/bin/conf.h index 03f1942e3e32..3062c1d35c1a 100644 --- a/bin/conf.h +++ b/bin/conf.h @@ -1,4 +1,4 @@ -/* $NetBSD: conf.h,v 1.6 2015/01/27 19:40:36 christos Exp $ */ +/* $NetBSD: conf.h,v 1.5 2015/01/21 19:24:03 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. diff --git a/bin/internal.c b/bin/internal.c index 5c039e4dc5d2..c3099d82a141 100644 --- a/bin/internal.c +++ b/bin/internal.c @@ -1,4 +1,4 @@ -/* $NetBSD: internal.c,v 1.5 2015/01/27 19:40:37 christos Exp $ */ +/* $NetBSD: internal.c,v 1.4 2015/01/25 20:59:39 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -33,7 +33,7 @@ #endif #include <sys/cdefs.h> -__RCSID("$NetBSD: internal.c,v 1.5 2015/01/27 19:40:37 christos Exp $"); +__RCSID("$NetBSD: internal.c,v 1.4 2015/01/25 20:59:39 christos Exp $"); #include <stdio.h> #include <syslog.h> @@ -41,7 +41,7 @@ __RCSID("$NetBSD: internal.c,v 1.5 2015/01/27 19:40:37 christos Exp $"); #include "internal.h" int debug; -const char *rulename = "blacklistd"; +const char *rulename = "blocklistd"; const char *controlprog = _PATH_BLCONTROL; struct confset lconf, rconf; struct ifaddrs *ifas; diff --git a/bin/internal.h b/bin/internal.h index 5a40e49fbbd5..e2319775e5e3 100644 --- a/bin/internal.h +++ b/bin/internal.h @@ -1,4 +1,4 @@ -/* $NetBSD: internal.h,v 1.14 2016/04/04 15:52:56 christos Exp $ */ +/* $NetBSD: internal.h,v 1.13 2015/10/14 16:01:29 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -32,13 +32,13 @@ #define _INTERNAL_H #ifndef _PATH_BLCONF -#define _PATH_BLCONF "/etc/blacklistd.conf" +#define _PATH_BLCONF "/etc/blocklistd.conf" #endif #ifndef _PATH_BLCONTROL -#define _PATH_BLCONTROL "/libexec/blacklistd-helper" +#define _PATH_BLCONTROL "/libexec/blocklistd-helper" #endif #ifndef _PATH_BLSTATE -#define _PATH_BLSTATE "/var/db/blacklistd.db" +#define _PATH_BLSTATE "/var/db/blocklistd.db" #endif extern struct confset rconf, lconf; diff --git a/bin/run.c b/bin/run.c index 8499edd3d9c2..5588f0198c04 100644 --- a/bin/run.c +++ b/bin/run.c @@ -75,7 +75,7 @@ run(const char *cmd, const char *name, ...) (argv[i] = va_arg(ap, char *)) != NULL; i++) continue; va_end(ap); - + if (debug) { size_t z; int r; diff --git a/bin/run.h b/bin/run.h index bafc3e554690..ec310191b3c2 100644 --- a/bin/run.h +++ b/bin/run.h @@ -1,4 +1,4 @@ -/* $NetBSD: run.h,v 1.5 2015/01/27 19:40:37 christos Exp $ */ +/* $NetBSD: run.h,v 1.4 2015/01/22 04:13:04 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. diff --git a/bin/state.c b/bin/state.c index f2622c82c251..27d3eeceaff2 100644 --- a/bin/state.c +++ b/bin/state.c @@ -1,4 +1,4 @@ -/* $NetBSD: state.c,v 1.19 2016/09/26 19:43:43 christos Exp $ */ +/* $NetBSD: state.c,v 1.18 2016/04/04 15:52:56 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -33,7 +33,7 @@ #endif #include <sys/cdefs.h> -__RCSID("$NetBSD: state.c,v 1.19 2016/09/26 19:43:43 christos Exp $"); +__RCSID("$NetBSD: state.c,v 1.18 2016/04/04 15:52:56 christos Exp $"); #include <sys/types.h> #include <sys/socket.h> diff --git a/bin/state.h b/bin/state.h index 2e9257006e80..823f97e8451f 100644 --- a/bin/state.h +++ b/bin/state.h @@ -1,4 +1,4 @@ -/* $NetBSD: state.h,v 1.5 2015/01/27 19:40:37 christos Exp $ */ +/* $NetBSD: state.h,v 1.4 2015/01/24 07:46:20 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. diff --git a/bin/support.c b/bin/support.c index 79a1c6ee93ac..d560d2303223 100644 --- a/bin/support.c +++ b/bin/support.c @@ -46,7 +46,7 @@ __RCSID("$NetBSD: support.c,v 1.9 2018/09/18 22:12:19 christos Exp $"); #include "support.h" static __attribute__((__format_arg__(3))) const char * -expandm(char *buf, size_t len, const char *fmt) +expandm(char *buf, size_t len, const char *fmt) { char *p; size_t r; diff --git a/bin/support.h b/bin/support.h index 899649ce8319..b27016f5a7ec 100644 --- a/bin/support.h +++ b/bin/support.h @@ -1,4 +1,4 @@ -/* $NetBSD: support.h,v 1.7 2016/04/04 15:52:56 christos Exp $ */ +/* $NetBSD: support.h,v 1.6 2015/06/02 14:02:10 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. |
