Sync with current.

This commit is contained in:
christos 2015-01-21 16:16:00 +00:00
parent fff8d9a1f5
commit 9e607ccb2a
25 changed files with 823 additions and 170 deletions

5
external/bsd/blacklist/Makefile vendored Normal file
View File

@ -0,0 +1,5 @@
# $NetBSD: Makefile,v 1.1 2015/01/21 16:16:00 christos Exp $
SUBDIR = lib .WAIT include bin
.include <bsd.subdir.mk>

6
external/bsd/blacklist/Makefile.inc vendored Normal file
View File

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

71
external/bsd/blacklist/README vendored Normal file
View File

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

View File

@ -1,13 +1,14 @@
.include <bsd.own.mk>
# $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 <bsd.prog.mk>

View File

@ -0,0 +1,52 @@
#include <stdio.h>
#include <time.h>
#include <util.h>
#include <fcntl.h>
#include <db.h>
#include <err.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#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;
}

170
external/bsd/blacklist/bin/blacklistd.8 vendored Normal file
View File

@ -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 <rulename> <proto> <port> <address>
.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 <rulename> <id>
.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 <rulename>
.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

View File

@ -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 <sys/cdefs.h>
__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 <sys/types.h>
#include <sys/socket.h>
@ -87,11 +87,12 @@ sigdone(int n)
{
done++;
}
static __dead void
usage(void)
{
fprintf(stderr, "Usage: %s -d [-c <config>] [-r <rulename>] "
"[-s <sockpath>] [-C <controlprog>] [-D <dbfile>]\n",
fprintf(stderr, "Usage: %s [-df] [-c <config>] [-r <rulename>] "
"[-s <sockpath>] [-C <controlprog>] [-D <dbfile>] [-t <timeout>]\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:

View File

@ -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 <sys/cdefs.h>
__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 <stdio.h>
#include <string.h>
@ -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]));
}
}

View File

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

View File

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

View File

@ -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 <sys/cdefs.h>
__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 <stdio.h>
#include <util.h>
@ -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));
}

View File

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

View File

@ -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 <sys/cdefs.h>
__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 <sys/types.h>
#include <sys/socket.h>
@ -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);

View File

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

10
external/bsd/blacklist/include/Makefile vendored Normal file
View File

@ -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 <bsd.prog.mk>

View File

@ -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 <stdbool.h>
#include <sys/param.h>
#include <sys/socket.h>
#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 */

View File

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

11
external/bsd/blacklist/lib/Makefile vendored Normal file
View File

@ -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 <bsd.lib.mk>

View File

@ -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 <sys/cdefs.h>
__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 <sys/param.h>
#include <sys/types.h>
@ -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",

101
external/bsd/blacklist/lib/blacklist.c vendored Normal file
View File

@ -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 <sys/cdefs.h>
__RCSID("$NetBSD: blacklist.c,v 1.1 2015/01/21 16:16:00 christos Exp $");
#include <stdio.h>
#include <bl.h>
#include <stdarg.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
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);
}

View File

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

View File

@ -0,0 +1,2 @@
major=0
minor=0

9
external/bsd/blacklist/test/Makefile vendored Normal file
View File

@ -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 <bsd.prog.mk>

View File

@ -10,10 +10,12 @@
#include <err.h>
static __dead void
usage(void)
usage(int c)
{
fprintf(stderr, "Usage: %s [-a <addr>] [-m <msg>]\n", getprogname());
exit(1);
warnx("Unknown option `%c'", (char)c);
fprintf(stderr, "Usage: %s [-u] [-a <addr>] [-m <msg>] [-p <port>]\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;
}

View File

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