From 9e607ccb2aa377f1bac790a9c7173ad4b5c77727 Mon Sep 17 00:00:00 2001 From: christos Date: Wed, 21 Jan 2015 16:16:00 +0000 Subject: [PATCH] Sync with current. --- external/bsd/blacklist/Makefile | 5 + external/bsd/blacklist/Makefile.inc | 6 + external/bsd/blacklist/README | 71 +++++++++ external/bsd/blacklist/bin/Makefile | 21 +-- external/bsd/blacklist/bin/blacklistctl.c | 52 +++++++ external/bsd/blacklist/bin/blacklistd.8 | 170 +++++++++++++++++++++ external/bsd/blacklist/bin/blacklistd.c | 86 +++++++---- external/bsd/blacklist/bin/conf.c | 66 +++++--- external/bsd/blacklist/bin/conf.h | 10 +- external/bsd/blacklist/bin/internal.h | 6 +- external/bsd/blacklist/bin/run.c | 22 +-- external/bsd/blacklist/bin/run.h | 8 +- external/bsd/blacklist/bin/state.c | 9 +- external/bsd/blacklist/bin/state.h | 6 +- external/bsd/blacklist/include/Makefile | 10 ++ external/bsd/blacklist/include/bl.h | 29 +++- external/bsd/blacklist/include/blacklist.h | 42 +++++ external/bsd/blacklist/lib/Makefile | 11 ++ external/bsd/blacklist/lib/bl.c | 66 +++----- external/bsd/blacklist/lib/blacklist.c | 101 ++++++++++++ external/bsd/blacklist/lib/libblacklist.3 | 110 +++++++++++++ external/bsd/blacklist/lib/shlib_version | 2 + external/bsd/blacklist/test/Makefile | 9 ++ external/bsd/blacklist/test/cltest.c | 30 ++-- external/bsd/blacklist/test/srvtest.c | 45 ++++-- 25 files changed, 823 insertions(+), 170 deletions(-) create mode 100644 external/bsd/blacklist/Makefile create mode 100644 external/bsd/blacklist/Makefile.inc create mode 100644 external/bsd/blacklist/README create mode 100644 external/bsd/blacklist/bin/blacklistctl.c create mode 100644 external/bsd/blacklist/bin/blacklistd.8 create mode 100644 external/bsd/blacklist/include/Makefile create mode 100644 external/bsd/blacklist/include/blacklist.h create mode 100644 external/bsd/blacklist/lib/Makefile create mode 100644 external/bsd/blacklist/lib/blacklist.c create mode 100644 external/bsd/blacklist/lib/libblacklist.3 create mode 100644 external/bsd/blacklist/lib/shlib_version create mode 100644 external/bsd/blacklist/test/Makefile diff --git a/external/bsd/blacklist/Makefile b/external/bsd/blacklist/Makefile new file mode 100644 index 000000000000..87281a53876d --- /dev/null +++ b/external/bsd/blacklist/Makefile @@ -0,0 +1,5 @@ +# $NetBSD: Makefile,v 1.1 2015/01/21 16:16:00 christos Exp $ + +SUBDIR = lib .WAIT include bin + +.include diff --git a/external/bsd/blacklist/Makefile.inc b/external/bsd/blacklist/Makefile.inc new file mode 100644 index 000000000000..8b742a97f72c --- /dev/null +++ b/external/bsd/blacklist/Makefile.inc @@ -0,0 +1,6 @@ +# $NetBSD: Makefile.inc,v 1.1 2015/01/21 16:16:00 christos Exp $ + +WARNS=6 +LDADD+= -lblacklist +DPADD+= ${LIBBLACKLIST} +CPPFLAGS+= -I${.CURDIR}/../include diff --git a/external/bsd/blacklist/README b/external/bsd/blacklist/README new file mode 100644 index 000000000000..cfd90799ac3e --- /dev/null +++ b/external/bsd/blacklist/README @@ -0,0 +1,71 @@ +# Tue Jan 20 21:18:54 EST 2015 + +This package contains library that can be used by network daemons to +communicate with a packet filter via a daemon to enforce opening and +closing ports dynamically based on policy. + +The interface to the packet filter is in etc/control (this is currently +designed for npf) and the configuration file (inspired from inetd.conf) +is in etc/conf. + +A patch to OpenSSH is in ssh.diff that adds blacklisting capabilities to +openssh. + +The network daemon (for example sshd) communicates to blacklistd, via +a unix socket like syslog. The library calls are simple and everything +is handled by the library. In the simplest form the only thing the +daemon needs to do is to call: + + blacklist(action, acceptedfd, message); + +Where: + action = 0 -> successful login clear blacklist state + 1 -> failed login, add to the failed count + acceptedfd -> the file descriptor where the server is + connected to the remote client. It is used + to determine the listening socket, and the + remote address. This allows any program to + contact the blacklist daemon, since the verification + if the program has access to the listening + socket is done by virtue that the port + number is retrieved from the kernel. + message -> an optional string that is used in debugging logs. + +The configuration file contains entries of the form: + +# Blacklist rule +# Port type protocol owner nfail disable +ssh stream tcp * 6 60m +ssh stream tcp6 * 6 60m + +Here note that owner is * because the connection is done from the +child ssh socket which runs with user privs. We also register for +both tcp and tcp6 since those are different listening sockets and +addresses. We use nfail = 6, because ssh allows 3 password attempts +per connection, and this will let us have 2 connections before +blocking. Finally we block for an hour; we could block forever +too by specifying * in the duration column. + +blacklistd and the library use syslog(3) to report errors. The +blacklist filter state is persisted automatically in /var/db/blacklistd.db +so that if the daemon is restarted, it remembers what connections +is currently handling. To start from a fresh state (if you restart +npf too for example), you can use -f. To watch the daemon at work, +you can use -d. + +The current control file is designed for npf, and it uses the +dynamic rule feature. You need to create a dynamic rule in your +/etc/npf.conf on the group referring to the interface you want to block +called blacklistd as follows: + +ext_if=bge0 + +group "external" on $ext_if { + ... + ruleset "blacklistd" + ... +} + +Enjoy, + +christos diff --git a/external/bsd/blacklist/bin/Makefile b/external/bsd/blacklist/bin/Makefile index 63152b06bf03..ca30fc5249b3 100644 --- a/external/bsd/blacklist/bin/Makefile +++ b/external/bsd/blacklist/bin/Makefile @@ -1,13 +1,14 @@ -.include +# $NetBSD: Makefile,v 1.5 2015/01/21 16:16:00 christos Exp $ -WARNS=6 -COPTS=-g -MKMAN=no -PROGS=srvtest cltest blacklistd -SRCS.srvtest = bl.c srvtest.c -SRCS.cltest = cltest.c -SRCS.blacklistd = bl.c blacklistd.c conf.c run.c state.c -LDADD.blacklistd += -lutil -LPADD.blacklistd += ${LIBUTIL} +BINDIR=/usr/sbin + +PROGS=blacklistd blacklistctl +MAN=blacklistd.8 +MLINKS=blacklistd.8 blacklistd.conf.5 +SRCS.blacklistd = blacklistd.c conf.c run.c state.c +SRCS.blacklistctl = blacklistctl.c conf.c state.c + +LDADD+=-lutil +DPADD+=${LIBUTIL} .include diff --git a/external/bsd/blacklist/bin/blacklistctl.c b/external/bsd/blacklist/bin/blacklistctl.c new file mode 100644 index 000000000000..f55a43d3ee62 --- /dev/null +++ b/external/bsd/blacklist/bin/blacklistctl.c @@ -0,0 +1,52 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "conf.h" +#include "state.h" +#include "internal.h" + +static const char * +fmttime(char *b, size_t l, time_t t) +{ + struct tm tm; + if (localtime_r(&t, &tm) == NULL) + snprintf(b, l, "*%jd*", (intmax_t)t); + else + strftime(b, l, "%Y/%m/%d %H:%M:%S", &tm); + return b; +} + +int +main(int argc, char *argv[]) +{ + const char *dbname = _PATH_BLSTATE; + DB *db; + struct conf c; + struct sockaddr_storage ss; + struct dbinfo dbi; + unsigned int i; + + db = state_open(dbname, O_RDONLY, 0); + if (db == NULL) + err(EXIT_FAILURE, "Can't open `%s'", dbname); + + for (i = 1; state_iterate(db, &ss, &c, &dbi, i) != 0; i = 0) { + char buf[BUFSIZ]; + printf("conf: %s\n", conf_print(buf, sizeof(buf), "", + ":", &c)); + sockaddr_snprintf(buf, sizeof(buf), "%a", (void *)&ss); + printf("addr: %s\n", buf); + printf("data: count=%d id=%s time=%s\n", dbi.count, + dbi.id, fmttime(buf, sizeof(buf), dbi.last)); + } + state_close(db); + return EXIT_SUCCESS; +} diff --git a/external/bsd/blacklist/bin/blacklistd.8 b/external/bsd/blacklist/bin/blacklistd.8 new file mode 100644 index 000000000000..7946a66336b8 --- /dev/null +++ b/external/bsd/blacklist/bin/blacklistd.8 @@ -0,0 +1,170 @@ +.\" $NetBSD: blacklistd.8,v 1.1 2015/01/21 16:16:00 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. +.\" +.Dd January 19, 2016 +.Dt BLACKLISTD 8 +.Os +.Sh NAME +.Nm blacklistd , +.Nm blacklistd.conf +.Nd block and release ports on demand to avoid DoS abuse +.Sh SYNOPSIS +.Nm +.Op Fl df +.Op Fl c Ar configfile +.Op Fl C Ar controlprog +.Op Fl D Ar dbfile +.Op Fl r Ar rulename +.Op Fl s Ar sockpath +.Op Fl t Ar timeout +.Sh DESCRIPTION +.Nm +is a daemon similar to +.Xr syslogd 8 +that listens to a socket at +.Ar sockpath +for notifications from other daemons about successful or failed connection +attempts. +Each notification contains a (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 . +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 +If the action is +.Dq add +and the number of tries limit is reached, then a +control script +.Ar controlprog +is invoked with arguments: +.Bd -literal -offset indent +control add
+.Ed +.Pp +and should invoke a packet filter command to block the connection +specified by the arguments. +The +.Ar rulename +argument can be set from the command line (default +.Dv blacklistd ). +The script should print a numerical id to stdout as a handle for +the rule that can be used later to remove that connection. +.Pp +If the action is +.Dq remove +Then the same control script is invoked as: +.Bd -literal -offset indent +control rem +.Ed +.Pp +where +.Ar id +is the number returned from the +.Dq add +action. +.Pp +.Nm +maintains a database of known connections in +.Ar dbfile . +On startup it reads entries from that file, and updates its internal state. +If the +.Fl f +flag is specified, then the database is truncated an all the rules named +.Ar rulename +are deleted by invoking the control script as: +.Bd -literal -offset indent +control flush +.Ed +.Pp +.Nm +checks the list of active entries every +.Ar timeout +seconds (default +.Dv 15 ) +and removes entries and block rules using the control program as necessary. +.Pp +The configuration file contains one tuple per line, and is similar to +.Xr inetd.conf . +There must be an entry for each field of the configuration file, with +entries for each field separated by a tab or a space. +Comments are denoted by a +.Dq # +at the beginning of a line. +There must be an entry for each field; entries can be numeric or symbolic, +where appropriate ( +.Dv service-name , +.Dv user ) +and can be +.Dq * +for all fields except +.Dv nfail and +.Dv duration : +The fields of the configuration file are as follows: +.Bd -literal -offset indent +service-name +socket-type +protocol +user +nfail +duration +.Ed +.Pp +Normally, +.Nm +disassociates itself from the terminal and writes messages to +.Xr syslogd 8 , +unless the +.Fl d +flag is specified, in which case it stays in the foreground and prints +diagnostic messages to +.Dv stdout . +.Sh FILES +.Bl -tag -width /etc/blacklistd/control -compact +.It Pa /etc/blacklistd/control +Shell script invoked to interface with the packet filter. +.It Pa /etc/blacklistd/conf +Configuration file. +.It Pa /var/db/blacklistd.db +Database of current connection entries. +.It Pa /var/run/blsock +Socket to receive connection notifications. +.El +.Sh SEE ALSO +.Xr blacklistd.conf 5 , +.Xr npfctl 8 , +.Xr syslogd 8 +.Sh HISTORY +.Nm +appeared in +.Nx 8 +.Sh AUTHORS +.An Christos Zoulas diff --git a/external/bsd/blacklist/bin/blacklistd.c b/external/bsd/blacklist/bin/blacklistd.c index 3bb90b0a5100..3b527da2ae44 100644 --- a/external/bsd/blacklist/bin/blacklistd.c +++ b/external/bsd/blacklist/bin/blacklistd.c @@ -1,4 +1,4 @@ -/* $NetBSD: blacklistd.c,v 1.5 2015/01/20 00:52:15 christos Exp $ */ +/* $NetBSD: blacklistd.c,v 1.6 2015/01/21 16:16:00 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -29,7 +29,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include -__RCSID("$NetBSD: blacklistd.c,v 1.5 2015/01/20 00:52:15 christos Exp $"); +__RCSID("$NetBSD: blacklistd.c,v 1.6 2015/01/21 16:16:00 christos Exp $"); #include #include @@ -87,11 +87,12 @@ sigdone(int n) { done++; } + static __dead void usage(void) { - fprintf(stderr, "Usage: %s -d [-c ] [-r ] " - "[-s ] [-C ] [-D ]\n", + fprintf(stderr, "Usage: %s [-df] [-c ] [-r ] " + "[-s ] [-C ] [-D ] [-t ]\n", getprogname()); exit(EXIT_FAILURE); } @@ -161,15 +162,15 @@ process(bl_t bl) return; if (debug) - printf("got type=%d fd=[%d %d] msg=%s cred=[u=%lu, g=%lu]\n", - bi->bi_type, bi->bi_fd[0], bi->bi_fd[1], bi->bi_msg, - (unsigned long)bi->bi_cred->sc_euid, - (unsigned long)bi->bi_cred->sc_egid); + printf("got type=%d fd=%d msg=%s cred=[u=%lu, g=%lu]\n", + bi->bi_type, bi->bi_fd, bi->bi_msg, + (unsigned long)bi->bi_cred.sc_euid, + (unsigned long)bi->bi_cred.sc_egid); - if (findconf(bi, &c) == NULL) + if (conf_find(bi->bi_fd, bi->bi_cred.sc_euid, &c) == NULL) goto out; - rfd = bi->bi_fd[1]; + rfd = bi->bi_fd; rsl = sizeof(rss); memset(&rss, 0, rsl); if (getpeername(rfd, (void *)&rss, &rsl) == -1) { @@ -192,15 +193,20 @@ process(bl_t bl) case BL_ADD: dbi.count++; dbi.last = ts.tv_sec; - if (dbi.id != -1) { - (*lfun)(LOG_ERR, "rule exists %d", dbi.id); + if (dbi.id[0]) { + (*lfun)(LOG_ERR, "rule exists %s", dbi.id); goto out; } if (dbi.count >= c.c_nfail) { - int res = run_add(c.c_proto, (in_port_t)c.c_port, &rss); + int res = run_add(c.c_proto, (in_port_t)c.c_port, &rss, + dbi.id, sizeof(dbi.id)); if (res == -1) goto out; - dbi.id = res; + sockaddr_snprintf(rbuf, sizeof(rbuf), "%a", + (void *)&rss); + syslog(LOG_INFO, "Blocked %s at port %d for %d seconds", + rbuf, c.c_port, c.c_duration); + } break; case BL_DELETE: @@ -214,8 +220,7 @@ process(bl_t bl) if (state_put(state, &rss, &c, &dbi) == -1) goto out; out: - close(bi->bi_fd[0]); - close(bi->bi_fd[1]); + close(bi->bi_fd); } static void @@ -226,6 +231,7 @@ update(void) struct conf c; struct dbinfo dbi; unsigned int f, n; + char buf[128]; if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { (*lfun)(LOG_ERR, "clock_gettime failed (%m)"); @@ -237,18 +243,23 @@ update(void) { time_t when = c.c_duration + dbi.last; if (debug) { - char buf[128], b1[64], b2[64]; + char b1[64], b2[64]; sockaddr_snprintf(buf, sizeof(buf), "%a:%p", (void *)&ss); - printf("%s:[%u] %s count=%d duration=%d exp=%s " + printf("%s:[%u] %s count=%d duration=%d last=%s " "now=%s\n", __func__, n, buf, dbi.count, - c.c_duration, fmttime(b1, sizeof(b1), when), + c.c_duration, fmttime(b1, sizeof(b1), dbi.last), fmttime(b2, sizeof(b2), ts.tv_sec)); } - if (when >= ts.tv_sec) + if (c.c_duration == -1 || when >= ts.tv_sec) continue; - if (dbi.id != -1) + if (dbi.id[0]) { run_rem(dbi.id); + sockaddr_snprintf(buf, sizeof(buf), "%a", (void *)&ss); + syslog(LOG_INFO, + "Released %s at port %d after %d seconds", + buf, c.c_port, c.c_duration); + } state_del(state, &ss, &c); } } @@ -256,15 +267,17 @@ update(void) int main(int argc, char *argv[]) { - int c; bl_t bl; - int tout; - int flags = O_RDWR|O_EXCL|O_CLOEXEC; - const char *spath = _PATH_BLSOCK; + int c, tout, flags, reset; + const char *spath; setprogname(argv[0]); - while ((c = getopt(argc, argv, "C:c:D:ds:r:")) != -1) { + spath = _PATH_BLSOCK; + reset = 0; + tout = 0; + flags = O_RDWR|O_EXCL|O_CLOEXEC; + while ((c = getopt(argc, argv, "C:c:D:dfr:s:t:")) != -1) { switch (c) { case 'C': controlprog = optarg; @@ -278,12 +291,18 @@ main(int argc, char *argv[]) case 'd': debug++; break; + case 'f': + reset++; + break; case 'r': rulename = optarg; break; case 's': spath = optarg; break; + case 't': + tout = atoi(optarg) * 1000; + break; default: usage(); } @@ -296,15 +315,20 @@ main(int argc, char *argv[]) if (debug) { lfun = dlog; - tout = 5000; + if (tout == 0) + tout = 5000; } else { daemon(0, 0); - tout = 15000; + if (tout == 0) + tout = 15000; } - run_flush(); + if (reset) { + flags |= O_TRUNC; + run_flush(); + } - bl = bl_create2(true, spath, lfun); + bl = bl_create(true, spath, lfun); if (bl == NULL || !bl_isconnected(bl)) return EXIT_FAILURE; state = state_open(dbfile, flags, 0600); @@ -319,7 +343,7 @@ main(int argc, char *argv[]) while (!done) { if (rconf) { rconf = 0; - parseconf(configfile); + conf_parse(configfile); } switch (poll(&pfd, 1, tout)) { case -1: diff --git a/external/bsd/blacklist/bin/conf.c b/external/bsd/blacklist/bin/conf.c index 7b572ae7e8f8..0855f2e89441 100644 --- a/external/bsd/blacklist/bin/conf.c +++ b/external/bsd/blacklist/bin/conf.c @@ -1,4 +1,4 @@ -/* $NetBSD: conf.c,v 1.2 2015/01/20 00:19:21 christos Exp $ */ +/* $NetBSD: conf.c,v 1.3 2015/01/21 16:16:00 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -29,7 +29,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include -__RCSID("$NetBSD: conf.c,v 1.2 2015/01/20 00:19:21 christos Exp $"); +__RCSID("$NetBSD: conf.c,v 1.3 2015/01/21 16:16:00 christos Exp $"); #include #include @@ -213,7 +213,7 @@ getvalue(const char *f, size_t l, int *r, char **p, static int -parseconfline(const char *f, size_t l, char *p, struct conf *c) +conf_parseline(const char *f, size_t l, char *p, struct conf *c) { int e; @@ -237,7 +237,7 @@ parseconfline(const char *f, size_t l, char *p, struct conf *c) } static int -sortconf(const void *v1, const void *v2) +conf_sort(const void *v1, const void *v2) { const struct conf *c1 = v1; const struct conf *c2 = v2; @@ -249,36 +249,51 @@ sortconf(const void *v1, const void *v2) CMP(c1, c2, c_proto); CMP(c1, c2, c_family); CMP(c1, c2, c_uid); +#undef CMP return 0; } -static void -printconf(const char *pref, const struct conf *c) +static int +conf_eq(const struct conf *c1, const struct conf *c2) { - printf("%s%d\t%d\t%d\t%d\t%d\t%d\n", pref, - c->c_port, c->c_proto, c->c_family, - c->c_uid, c->c_nfail, c->c_duration); +#define CMP(a, b, f) \ + if ((a)->f != (b)->f && (b)->f != -1) return 0; + CMP(c1, c2, c_port); + CMP(c1, c2, c_proto); + CMP(c1, c2, c_family); + CMP(c1, c2, c_uid); +#undef CMP + return 1; +} + +const char * +conf_print(char *buf, size_t len, const char *pref, const char *delim, + const struct conf *c) +{ + snprintf(buf, len, "%s%d%s%d%s%d%s%d%s%d%s%d", pref, + c->c_port, delim, c->c_proto, delim, c->c_family, delim, + c->c_uid, delim, c->c_nfail, delim, c->c_duration); + return buf; } const struct conf * -findconf(bl_info_t *bi, struct conf *cr) +conf_find(int fd, uid_t uid, struct conf *cr) { - int lfd; int proto; socklen_t slen; struct sockaddr_storage ss; size_t i; + char buf[BUFSIZ]; - lfd = bi->bi_fd[0]; slen = sizeof(ss); memset(&ss, 0, slen); - if (getsockname(lfd, (void *)&ss, &slen) == -1) { + if (getsockname(fd, (void *)&ss, &slen) == -1) { (*lfun)(LOG_ERR, "getsockname failed (%m)"); return NULL; } slen = sizeof(proto); - if (getsockopt(lfd, SOL_SOCKET, SO_TYPE, &proto, &slen) == -1) { + if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &proto, &slen) == -1) { (*lfun)(LOG_ERR, "getsockopt failed (%m)"); return NULL; } @@ -307,20 +322,23 @@ findconf(bl_info_t *bi, struct conf *cr) return NULL; } - cr->c_uid = (int)bi->bi_cred->sc_euid; + cr->c_uid = (int)uid; cr->c_family = ss.ss_family; cr->c_nfail = -1; cr->c_duration = -1; if (debug) - printconf("look:\t", cr); + printf("%s\n", conf_print(buf, sizeof(buf), + "look:\t", "\t", cr)); for (i = 0; i < nconf; i++) { if (debug) - printconf("check:\t", &conf[i]); - if (sortconf(cr, &conf[i]) == 0) { + printf("%s\n", conf_print(buf, sizeof(buf), "check:\t", + "\t", &conf[i])); + if (conf_eq(cr, &conf[i])) { if (debug) - printconf("found: ", &conf[i]); + printf("%s\n", conf_print(buf, sizeof(buf), + "found:\t", "\t", &conf[i])); cr->c_nfail = conf[i].c_nfail; cr->c_duration = conf[i].c_duration; return cr; @@ -333,7 +351,7 @@ findconf(bl_info_t *bi, struct conf *cr) void -parseconf(const char *f) +conf_parse(const char *f) { FILE *fp; char *line; @@ -361,12 +379,12 @@ parseconf(const char *f) } c = tc; } - if (parseconfline(f, lineno, line, &c[nc]) == -1) + if (conf_parseline(f, lineno, line, &c[nc]) == -1) continue; nc++; } fclose(fp); - qsort(c, nc, sizeof(*c), sortconf); + qsort(c, nc, sizeof(*c), conf_sort); tc = conf; nconf = nc; @@ -374,8 +392,10 @@ parseconf(const char *f) free(tc); if (debug) { + char buf[BUFSIZ]; printf("port\ttype\tproto\towner\tnfail\tduration\n"); for (nc = 0; nc < nconf; nc++) - printconf("", &c[nc]); + printf("%s\n", + conf_print(buf, sizeof(buf), "", "\t", &c[nc])); } } diff --git a/external/bsd/blacklist/bin/conf.h b/external/bsd/blacklist/bin/conf.h index 2488b4aacf36..93f598f22ef6 100644 --- a/external/bsd/blacklist/bin/conf.h +++ b/external/bsd/blacklist/bin/conf.h @@ -1,7 +1,7 @@ -/* $NetBSD: conf.h,v 1.3 2015/01/20 00:19:21 christos Exp $ */ +/* $NetBSD: conf.h,v 1.4 2015/01/21 16:16:00 christos Exp $ */ /*- - * Copyright (c) 2014 The NetBSD Foundation, Inc. + * Copyright (c) 2015 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -41,8 +41,10 @@ struct conf { }; __BEGIN_DECLS -void parseconf(const char *); -const struct conf *findconf(bl_info_t *, struct conf *); +const char *conf_print(char *, size_t, const char *, const char *, + const struct conf *); +void conf_parse(const char *); +const struct conf *conf_find(int, uid_t, struct conf *); __END_DECLS #endif /* _CONF_H */ diff --git a/external/bsd/blacklist/bin/internal.h b/external/bsd/blacklist/bin/internal.h index 8f11ea39da35..f35f8d0dbe1d 100644 --- a/external/bsd/blacklist/bin/internal.h +++ b/external/bsd/blacklist/bin/internal.h @@ -1,7 +1,7 @@ -/* $NetBSD: internal.h,v 1.4 2015/01/20 00:19:21 christos Exp $ */ +/* $NetBSD: internal.h,v 1.5 2015/01/21 16:16:00 christos Exp $ */ /*- - * Copyright (c) 2014 The NetBSD Foundation, Inc. + * Copyright (c) 2015 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -33,7 +33,7 @@ #define _PATH_BLCONF "/etc/blacklistd/conf" #define _PATH_BLCONTROL "/etc/blacklistd/control" -#define _PATH_BLSTATE "/var/run/blacklistd.db" +#define _PATH_BLSTATE "/var/db/blacklistd.db" struct conf *conf; size_t nconf; diff --git a/external/bsd/blacklist/bin/run.c b/external/bsd/blacklist/bin/run.c index 0d6fa14b6e23..48581b5dde59 100644 --- a/external/bsd/blacklist/bin/run.c +++ b/external/bsd/blacklist/bin/run.c @@ -1,4 +1,4 @@ -/* $NetBSD: run.c,v 1.2 2015/01/20 00:52:15 christos Exp $ */ +/* $NetBSD: run.c,v 1.3 2015/01/21 16:16:00 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -29,7 +29,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include -__RCSID("$NetBSD: run.c,v 1.2 2015/01/20 00:52:15 christos Exp $"); +__RCSID("$NetBSD: run.c,v 1.3 2015/01/21 16:16:00 christos Exp $"); #include #include @@ -93,11 +93,11 @@ run_flush(void) } int -run_add(int proto, in_port_t port, const struct sockaddr_storage *ss) +run_add(int proto, in_port_t port, const struct sockaddr_storage *ss, + char *id, size_t len) { const char *prname; char poname[64], adname[128], *rv; - int id, e; size_t off; switch (proto) { @@ -120,19 +120,13 @@ run_add(int proto, in_port_t port, const struct sockaddr_storage *ss) return -1; rv[strcspn(rv, "\n")] = '\0'; off = strncmp(rv, "OK ", 3) == 0 ? 3 : 0; - id = (int)strtoi(rv + off, NULL, 0, 0, INT_MAX, &e); - if (e) { - (*lfun)(LOG_ERR, "%s: bad number %s (%m)", __func__, rv); - id = -1; - } + strlcpy(id, rv + off, len); free(rv); - return id; + return 0; } void -run_rem(int id) +run_rem(const char *id) { - char buf[64]; - snprintf(buf, sizeof(buf), "%d", id); - free(run("rem", buf, NULL)); + free(run("rem", id, NULL)); } diff --git a/external/bsd/blacklist/bin/run.h b/external/bsd/blacklist/bin/run.h index 3844c5c289bd..f13f4a0ce16c 100644 --- a/external/bsd/blacklist/bin/run.h +++ b/external/bsd/blacklist/bin/run.h @@ -1,7 +1,7 @@ -/* $NetBSD: run.h,v 1.1 2015/01/20 00:19:21 christos Exp $ */ +/* $NetBSD: run.h,v 1.2 2015/01/21 16:16:00 christos Exp $ */ /*- - * Copyright (c) 2014 The NetBSD Foundation, Inc. + * Copyright (c) 2015 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -34,8 +34,8 @@ __BEGIN_DECLS void run_flush(void); struct sockaddr_storage; -int run_add(int, in_port_t, const struct sockaddr_storage *); -void run_rem(int id); +int run_add(int, in_port_t, const struct sockaddr_storage *, char *, size_t); +void run_rem(const char *); __END_DECLS #endif /* _RUN_H */ diff --git a/external/bsd/blacklist/bin/state.c b/external/bsd/blacklist/bin/state.c index 741a25089eba..7bfb2d02206e 100644 --- a/external/bsd/blacklist/bin/state.c +++ b/external/bsd/blacklist/bin/state.c @@ -1,4 +1,4 @@ -/* $NetBSD: state.c,v 1.2 2015/01/20 00:52:15 christos Exp $ */ +/* $NetBSD: state.c,v 1.3 2015/01/21 16:16:00 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__RCSID("$NetBSD: state.c,v 1.2 2015/01/20 00:52:15 christos Exp $"); +__RCSID("$NetBSD: state.c,v 1.3 2015/01/21 16:16:00 christos Exp $"); #include #include @@ -161,10 +161,9 @@ state_get(DB *db, const struct sockaddr_storage *ss, const struct conf *c, switch (rv = (*db->get)(db, &k, &v, 0)) { case 0: case 1: - if (rv) { + if (rv) memset(dbi, 0, sizeof(*dbi)); - dbi->id = -1; - } else + else memcpy(dbi, v.data, sizeof(*dbi)); if (debug) printf("%s: returns %d\n", __func__, rv); diff --git a/external/bsd/blacklist/bin/state.h b/external/bsd/blacklist/bin/state.h index 2fb900702cce..18160f3546e6 100644 --- a/external/bsd/blacklist/bin/state.h +++ b/external/bsd/blacklist/bin/state.h @@ -1,7 +1,7 @@ -/* $NetBSD: state.h,v 1.1 2015/01/20 00:19:21 christos Exp $ */ +/* $NetBSD: state.h,v 1.2 2015/01/21 16:16:00 christos Exp $ */ /*- - * Copyright (c) 2014 The NetBSD Foundation, Inc. + * Copyright (c) 2015 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -37,7 +37,7 @@ struct dbinfo { int count; time_t last; - int id; + char id[64]; }; __BEGIN_DECLS diff --git a/external/bsd/blacklist/include/Makefile b/external/bsd/blacklist/include/Makefile new file mode 100644 index 000000000000..6854907be25e --- /dev/null +++ b/external/bsd/blacklist/include/Makefile @@ -0,0 +1,10 @@ +# $NetBSD: Makefile,v 1.1 2015/01/21 16:16:00 christos Exp $ + +# Doing a make includes builds /usr/include + +NOOBJ= # defined + +INCS= blacklist.h +INCSDIR= /usr/include + +.include diff --git a/external/bsd/blacklist/include/bl.h b/external/bsd/blacklist/include/bl.h index 0981d1b4e661..778913510d63 100644 --- a/external/bsd/blacklist/include/bl.h +++ b/external/bsd/blacklist/include/bl.h @@ -1,4 +1,4 @@ -/* $NetBSD: bl.h,v 1.6 2015/01/20 00:52:15 christos Exp $ */ +/* $NetBSD: bl.h,v 1.7 2015/01/21 16:16:00 christos Exp $ */ /*- * Copyright (c) 2014 The NetBSD Foundation, Inc. @@ -31,23 +31,44 @@ #ifndef _BL_H #define _BL_H +#include +#include +#include #include "blacklist.h" struct sockcred; +typedef enum { + BL_INVALID, + BL_ADD, + BL_DELETE +} bl_type_t; + typedef struct { bl_type_t bi_type; - int *bi_fd; - struct sockcred *bi_cred; + int bi_fd; + union { + char bi_space[SOCKCREDSIZE(NGROUPS_MAX)]; + struct sockcred _bi_cred; + } bi_u; char bi_msg[1024]; } bl_info_t; +#define bi_cred bi_u._bi_cred + #define _PATH_BLSOCK "/var/run/blsock" __BEGIN_DECLS -bl_t bl_create2(bool, const char *, void (*)(int, const char *, ...)); + +typedef struct blacklist *bl_t; + +bl_t bl_create(bool, const char *, void (*)(int, const char *, ...)); +void bl_destroy(bl_t); +int bl_send(bl_t, bl_type_t, int, const char *); +int bl_getfd(bl_t); bl_info_t *bl_recv(bl_t); bool bl_isconnected(bl_t); + __END_DECLS #endif /* _BL_H */ diff --git a/external/bsd/blacklist/include/blacklist.h b/external/bsd/blacklist/include/blacklist.h new file mode 100644 index 000000000000..ecdd2c0514fa --- /dev/null +++ b/external/bsd/blacklist/include/blacklist.h @@ -0,0 +1,42 @@ +/* $NetBSD: blacklist.h,v 1.1 2015/01/21 16:16:00 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 + +__BEGIN_DECLS +struct blacklist; +int blacklist(int, int, const char *); +int blacklist_r(struct blacklist *, int, int, const char *); +struct blacklist *blacklist_open(void); +void blacklist_close(struct blacklist *); +__END_DECLS + +#endif /* _BLACKLIST_H */ diff --git a/external/bsd/blacklist/lib/Makefile b/external/bsd/blacklist/lib/Makefile new file mode 100644 index 000000000000..fac79d064fbc --- /dev/null +++ b/external/bsd/blacklist/lib/Makefile @@ -0,0 +1,11 @@ +# $NetBSD: Makefile,v 1.1 2015/01/21 16:16:00 christos Exp $ + +LIB=blacklist +SRCS=bl.c blacklist.c +MAN=libblacklist.3 +MLINKS+=libblacklist.3 blacklist_open.3 +MLINKS+=libblacklist.3 blacklist_close.3 +MLINKS+=libblacklist.3 blacklist.3 +MLINKS+=libblacklist.3 blacklist_r.3 + +.include diff --git a/external/bsd/blacklist/lib/bl.c b/external/bsd/blacklist/lib/bl.c index 29e4c51ed4f6..a85a263a9ed0 100644 --- a/external/bsd/blacklist/lib/bl.c +++ b/external/bsd/blacklist/lib/bl.c @@ -1,4 +1,4 @@ -/* $NetBSD: bl.c,v 1.7 2015/01/20 00:52:15 christos Exp $ */ +/* $NetBSD: bl.c,v 1.8 2015/01/21 16:16:00 christos Exp $ */ /*- * Copyright (c) 2014 The NetBSD Foundation, Inc. @@ -29,7 +29,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include -__RCSID("$NetBSD: bl.c,v 1.7 2015/01/20 00:52:15 christos Exp $"); +__RCSID("$NetBSD: bl.c,v 1.8 2015/01/21 16:16:00 christos Exp $"); #include #include @@ -56,7 +56,7 @@ typedef struct { struct blacklist { int b_fd; int b_connected; - const char *b_path; + char b_path[MAXPATHLEN]; void (*b_fun)(int, const char *, ...); bl_info_t b_info; }; @@ -125,7 +125,7 @@ bl_init(bl_t b, bool srv) b->b_connected = true; if (setsockopt(b->b_fd, 0, LOCAL_CREDS, - &one, sizeof(one)) == -1) { + &one, (socklen_t)sizeof(one)) == -1) { (*b->b_fun)(LOG_ERR, "%s: setsockopt LOCAL_CREDS " "failed (%m)", __func__); goto out; @@ -144,63 +144,38 @@ out: } bl_t -bl_create2(bool srv, const char *path, void (*fun)(int, const char *, ...)) +bl_create(bool srv, const char *path, void (*fun)(int, const char *, ...)) { - bl_t b = malloc(sizeof(*b)); - bl_info_t *bi; + bl_t b = calloc(1, sizeof(*b)); if (b == NULL) goto out; - bi = &b->b_info; - bi->bi_fd = malloc(2 * sizeof(int)); - if (bi->bi_fd == NULL) - goto out1; - bi->bi_cred = malloc(SOCKCREDSIZE(NGROUPS_MAX)); - if (bi->bi_cred == NULL) - goto out2; - b->b_fun = fun == NULL ? syslog : fun; b->b_fd = -1; - b->b_path = strdup(path ? path : _PATH_BLSOCK); - if (b->b_path == NULL) - goto out3; + strlcpy(b->b_path, path ? path : _PATH_BLSOCK, MAXPATHLEN); b->b_connected = false; bl_init(b, srv); return b; -out3: - free(bi->bi_cred); -out2: - free(bi->bi_fd); -out1: - free(b); out: + free(b); (*fun)(LOG_ERR, "%s: malloc failed (%m)", __func__); return NULL; } -bl_t -bl_create(void) -{ - return bl_create2(false, NULL, NULL); -} - void bl_destroy(bl_t b) { bl_reset(b); - free(__UNCONST(b->b_path)); - free(b->b_info.bi_cred); - free(b->b_info.bi_fd); free(b); } int -bl_send(bl_t b, bl_type_t e, int lfd, int pfd, const char *ctx) +bl_send(bl_t b, bl_type_t e, int pfd, const char *ctx) { struct msghdr msg; struct iovec iov; union { - char ctrl[CMSG_SPACE(2 * sizeof(int))]; - uint32_t fd[2]; + char ctrl[CMSG_SPACE(sizeof(int))]; + uint32_t fd; } ua; struct cmsghdr *cmsg; union { @@ -231,13 +206,12 @@ bl_send(bl_t b, bl_type_t e, int lfd, int pfd, const char *ctx) msg.msg_controllen = sizeof(ua.ctrl); cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_len = CMSG_LEN(2 * sizeof(int)); + cmsg->cmsg_len = CMSG_LEN(sizeof(int)); cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_RIGHTS; - fd = (void *)CMSG_DATA(cmsg); - fd[0] = lfd; - fd[1] = pfd; + fd = CMSG_DATA(cmsg); + *fd = pfd; tried = 0; again: @@ -257,9 +231,9 @@ bl_recv(bl_t b) struct msghdr msg; struct iovec iov; union { - char ctrl[CMSG_SPACE(2 * sizeof(int)) + + char ctrl[CMSG_SPACE(sizeof(int)) + CMSG_SPACE(SOCKCREDSIZE(NGROUPS_MAX))]; - uint32_t fd[2]; + uint32_t fd; struct sockcred sc; } ua; struct cmsghdr *cmsg; @@ -297,21 +271,21 @@ bl_recv(bl_t b) } switch (cmsg->cmsg_type) { case SCM_RIGHTS: - if (cmsg->cmsg_len != CMSG_LEN(2 * sizeof(int))) { + if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) { (*b->b_fun)(LOG_ERR, "%s: unexpected cmsg_len %d != %zu", __func__, cmsg->cmsg_len, CMSG_LEN(2 * sizeof(int))); continue; } - fd = (void *)CMSG_DATA(cmsg); - memcpy(bi->bi_fd, fd, sizeof(*bi->bi_fd) * 2); + fd = CMSG_DATA(cmsg); + bi->bi_fd = *fd; break; case SCM_CREDS: sc = (void *)CMSG_DATA(cmsg); if (sc->sc_ngroups > NGROUPS_MAX) sc->sc_ngroups = NGROUPS_MAX; - memcpy(bi->bi_cred, sc, SOCKCREDSIZE(sc->sc_ngroups)); + memcpy(&bi->bi_cred, sc, SOCKCREDSIZE(sc->sc_ngroups)); break; default: (*b->b_fun)(LOG_ERR, "%s: unexpected cmsg_type %d", diff --git a/external/bsd/blacklist/lib/blacklist.c b/external/bsd/blacklist/lib/blacklist.c new file mode 100644 index 000000000000..3d4b5d150570 --- /dev/null +++ b/external/bsd/blacklist/lib/blacklist.c @@ -0,0 +1,101 @@ +/* $NetBSD: blacklist.c,v 1.1 2015/01/21 16:16:00 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. + */ +#include +__RCSID("$NetBSD: blacklist.c,v 1.1 2015/01/21 16:16:00 christos Exp $"); + +#include +#include + +#include +#include +#include +#include +static const char * +expandm(char *buf, size_t len, const char *fmt) +{ + char *p; + size_t r; + + if ((p = strstr(fmt, "%m")) == NULL) + return fmt; + + r = (size_t)(p - fmt); + if (r >= len) + return fmt; + + strlcpy(buf, fmt, r + 1); + strlcat(buf, strerror(errno), len); + strlcat(buf, fmt + r + 2, len); + + return buf; +} + +static void +dlog(int level, const char *fmt, ...) +{ + char buf[BUFSIZ]; + va_list ap; + + fprintf(stderr, "%s: ", getprogname()); + va_start(ap, fmt); + vfprintf(stderr, expandm(buf, sizeof(buf), fmt), ap); + va_end(ap); + fprintf(stderr, "\n"); +} + +int +blacklist(int action, int rfd, const char *msg) +{ + struct blacklist *bl; + int rv; + if ((bl = blacklist_open()) == NULL) + return -1; + rv = blacklist_r(bl, action, rfd, msg); + blacklist_close(bl); + return rv; +} + +int +blacklist_r(struct blacklist *bl, int action, int rfd, const char *msg) +{ + return bl_send(bl, action ? BL_ADD : BL_DELETE, rfd, msg); +} + +struct blacklist * +blacklist_open(void) { + return bl_create(false, NULL, dlog); +} + +void +blacklist_close(struct blacklist *bl) +{ + bl_destroy(bl); +} diff --git a/external/bsd/blacklist/lib/libblacklist.3 b/external/bsd/blacklist/lib/libblacklist.3 new file mode 100644 index 000000000000..f19178e11ebb --- /dev/null +++ b/external/bsd/blacklist/lib/libblacklist.3 @@ -0,0 +1,110 @@ +.\" $NetBSD: libblacklist.3,v 1.1 2015/01/21 16:16:00 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. +.\" +.Dd January 19, 2016 +.Dt LIBBLACKLIST 3 +.Os +.Sh NAME +.Nm blacklist_open , +.Nm blacklist_close , +.Nm blacklist_r , +.Nm blacklist +.Nd Blacklistd notification library +.Sh LIBRARY +.Lb libblacklist +.Sh SYNOPSIS +.In blacklist.h +.Ft struct blacklist * +.Fn blacklist_open "void" +.Ft void +.Fn blacklist_close "struct blacklist *cookie" +.Ft int +.Fn blacklist "int action" "int fd" "const char *msg" +.Fn blacklist_r "struct blacklist cookie" "int action" "int fd" "const char *msg" +.Sh DESCRIPTION +These functions can be used by daemons to notify +.Xr blacklistd 8 +about successful and failed remote connections so that blacklistd can +block or release port access to prevent Denial of Service attacks. +.Pp +The function +.Fn blacklist_open +creates a the necessary state to communicate with +.Xr blacklistd 8 +and returns a pointer to it, or +.Dv NULL +on failure. +.Pp +The +.Fn blacklist_close +function frees all memory and resources used. +.Pp +The +.Fn blacklist +function sends a message to +.Xr blacklistd 8 , +with an +.Ar action +argument specifying +.Dv 1 +for a failed connection or +.Dv 0 +for a successful connection, +a file descriptor +.Ar fd +specifying the accepted file descriptor connected to the client, +and an optional message in the +.Ar msg +argument. +.Pp +The +.Fn blacklist_r +function is more efficient because it keeps the blacklist state around. +.Pp +All functions log errors to +.Xr syslogd 8 . +.Sh RETURN VALUES +The function +.Fn bl_open +returns a cookie on success and +.Dv NULL +on failure setting errno to an appropriate value. +.Pp +The +.Fn bl_send , +function returns +.Dv 0 +on success and +.Dv -1 +on failure setting errno to an appropriate value. +.Sh SEE ALSO +.Xr blacklistd 8 , +.Xr blacklistd.conf 5 +.Sh AUTHORS +.An Christos Zoulas diff --git a/external/bsd/blacklist/lib/shlib_version b/external/bsd/blacklist/lib/shlib_version new file mode 100644 index 000000000000..97c9f92d6b8f --- /dev/null +++ b/external/bsd/blacklist/lib/shlib_version @@ -0,0 +1,2 @@ +major=0 +minor=0 diff --git a/external/bsd/blacklist/test/Makefile b/external/bsd/blacklist/test/Makefile new file mode 100644 index 000000000000..3043c7ce1354 --- /dev/null +++ b/external/bsd/blacklist/test/Makefile @@ -0,0 +1,9 @@ +# $NetBSD: Makefile,v 1.1 2015/01/21 16:16:00 christos Exp $ + +MKMAN=no + +PROGS=srvtest cltest +SRCS.srvtest = srvtest.c +SRCS.cltest = cltest.c + +.include diff --git a/external/bsd/blacklist/test/cltest.c b/external/bsd/blacklist/test/cltest.c index 4de22a83bb6e..3182e9b08e29 100644 --- a/external/bsd/blacklist/test/cltest.c +++ b/external/bsd/blacklist/test/cltest.c @@ -10,10 +10,12 @@ #include static __dead void -usage(void) +usage(int c) { - fprintf(stderr, "Usage: %s [-a ] [-m ]\n", getprogname()); - exit(1); + warnx("Unknown option `%c'", (char)c); + fprintf(stderr, "Usage: %s [-u] [-a ] [-m ] [-p ]\n", + getprogname()); + exit(EXIT_FAILURE); } static void @@ -49,8 +51,10 @@ main(int argc, char *argv[]) struct sockaddr_storage ss; const char *msg = "hello"; const char *addr = "127.0.0.1"; + int type = SOCK_STREAM; + in_port_t port = 6161; - while ((c = getopt(argc, argv, "a:m:")) == -1) { + while ((c = getopt(argc, argv, "a:m:p:u")) == -1) { switch (c) { case 'a': addr = optarg; @@ -58,21 +62,27 @@ main(int argc, char *argv[]) case 'm': msg = optarg; break; + case 'p': + port = (in_port_t)atoi(optarg); + break; + case 'u': + type = SOCK_DGRAM; + break; default: - usage(); + usage(c); } } - getaddr(addr, 6161, &ss); + getaddr(addr, port, &ss); - if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) - err(1, "socket"); + if ((sfd = socket(AF_INET, type, 0)) == -1) + err(EXIT_FAILURE, "socket"); if (connect(sfd, (const void *)&ss, ss.ss_len) == -1) - err(1, "connect"); + err(EXIT_FAILURE, "connect"); size_t len = strlen(msg) + 1; if (write(sfd, msg, len) != (ssize_t)len) - err(1, "write"); + err(EXIT_FAILURE, "write"); return 0; } diff --git a/external/bsd/blacklist/test/srvtest.c b/external/bsd/blacklist/test/srvtest.c index 89e58b1f1c8d..0d9a9b18679d 100644 --- a/external/bsd/blacklist/test/srvtest.c +++ b/external/bsd/blacklist/test/srvtest.c @@ -14,7 +14,7 @@ #include "blacklist.h" static void -process(bl_t bl, int sfd, int afd) +process(int afd) { ssize_t n; char buffer[256]; @@ -24,17 +24,17 @@ process(bl_t bl, int sfd, int afd) if ((n = read(afd, buffer, sizeof(buffer))) == -1) err(1, "read"); buffer[sizeof(buffer) - 1] = '\0'; - printf("%s: sending %d %d %s\n", getprogname(), sfd, afd, buffer); - bl_send(bl, BL_ADD, sfd, afd, buffer); + printf("%s: sending %d %s\n", getprogname(), afd, buffer); + blacklist(1, afd, buffer); exit(0); } static int -cr(int af, in_port_t p) +cr(int af, int type, in_port_t p) { int sfd; struct sockaddr_storage ss; - sfd = socket(af == AF_INET ? PF_INET : PF_INET6, SOCK_STREAM, 0); + sfd = socket(af == AF_INET ? PF_INET : PF_INET6, type, 0); if (sfd == -1) err(1, "socket"); @@ -61,7 +61,7 @@ cr(int af, in_port_t p) } static void -handle(bl_t bl, int sfd) +handle(int sfd) { struct sockaddr_storage ss; socklen_t alen = sizeof(ss); @@ -74,7 +74,7 @@ handle(bl_t bl, int sfd) case -1: err(1, "fork"); case 0: - process(bl, sfd, afd); + process(afd); break; default: close(afd); @@ -82,19 +82,38 @@ handle(bl_t bl, int sfd) } } +static __dead void +usage(int c) +{ + warnx("Unknown option `%c'", (char)c); + fprintf(stderr, "Usage: %s [-u] [-p ]\n", getprogname()); + exit(EXIT_FAILURE); +} + int main(int argc, char *argv[]) { - bl_t bl; struct pollfd pfd[2]; + int type = SOCK_STREAM, c; + in_port_t port = 6161; signal(SIGCHLD, SIG_IGN); - pfd[0].fd = cr(AF_INET, 6161); - pfd[1].fd = cr(AF_INET6, 6161); - pfd[0].events = pfd[1].events = POLLIN; + while ((c = getopt(argc, argv, "up:")) != -1) + switch (c) { + case 'u': + type = SOCK_DGRAM; + break; + case 'p': + port = (in_port_t)atoi(optarg); + break; + default: + usage(c); + } - bl = bl_create(); + pfd[0].fd = cr(AF_INET, type, port); + pfd[1].fd = cr(AF_INET6, type, port); + pfd[0].events = pfd[1].events = POLLIN; for (;;) { if (poll(pfd, __arraycount(pfd), INFTIM) == -1) @@ -102,7 +121,7 @@ main(int argc, char *argv[]) for (size_t i = 0; i < __arraycount(pfd); i++) { if ((pfd[i].revents & POLLIN) == 0) continue; - handle(bl, pfd[i].fd); + handle(pfd[i].fd); } } }