Tag import of NetBSD's external/bsd/blacklist
Reviewed by: rpaulo Approved by: rpaulo Sponsored by: The FreeBSD Foundation
This commit is contained in:
parent
3c597435d8
commit
7828fb4d26
5
20160409/Makefile
Normal file
5
20160409/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
# $NetBSD: Makefile,v 1.2 2015/01/22 17:49:41 christos Exp $
|
||||
|
||||
SUBDIR = lib .WAIT include bin etc libexec
|
||||
|
||||
.include <bsd.subdir.mk>
|
10
20160409/Makefile.inc
Normal file
10
20160409/Makefile.inc
Normal file
@ -0,0 +1,10 @@
|
||||
# $NetBSD: Makefile.inc,v 1.3 2015/01/23 03:57:22 christos Exp $
|
||||
|
||||
WARNS=6
|
||||
.if !defined(LIB)
|
||||
LDADD+= -lblacklist
|
||||
DPADD+= ${LIBBLACKLIST}
|
||||
.endif
|
||||
CPPFLAGS+= -I${.CURDIR}/../include
|
||||
CPPFLAGS+=-DHAVE_STRUCT_SOCKADDR_SA_LEN -DHAVE_UTIL_H -DHAVE_DB_H
|
||||
|
103
20160409/README
Normal file
103
20160409/README
Normal file
@ -0,0 +1,103 @@
|
||||
# $NetBSD: README,v 1.7 2015/01/26 00:34:50 christos Exp $
|
||||
|
||||
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 libexec/blacklistd-helper
|
||||
(this is currently designed for npf) and the configuration file
|
||||
(inspired from inetd.conf) is in etc/blacklistd.conf.
|
||||
|
||||
On NetBSD you can find an example npf.conf and blacklistd.conf in
|
||||
/usr/share/examples/blacklistd; you need to adjust the interface
|
||||
in npf.conf and copy both files to /etc; then you just enable
|
||||
blacklistd=YES in /etc/rc.conf, start it up, and you are all set.
|
||||
|
||||
There is also a startup file in etc/rc.d/blacklistd
|
||||
|
||||
Patches to various daemons to add blacklisting capabilitiers are in the
|
||||
"diff" directory:
|
||||
- OpenSSH: diff/ssh.diff [tcp socket example]
|
||||
- Bind: diff/named.diff [both tcp and udp]
|
||||
- ftpd: diff/ftpd.diff [tcp]
|
||||
|
||||
These patches have been applied to NetBSD-current.
|
||||
|
||||
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.
|
||||
|
||||
Unfortunately there is no way to get information about the "peer"
|
||||
from a udp socket, because there is no connection and that information
|
||||
is kept with the server. In that case the daemon can provide the
|
||||
peer information to blacklistd via:
|
||||
|
||||
blacklist_sa(action, acceptedfd, sockaddr, sockaddr_len, message);
|
||||
|
||||
The configuration file contains entries of the form:
|
||||
|
||||
# Blacklist rule
|
||||
# host/Port type protocol owner name nfail disable
|
||||
192.168.1.1:ssh stream tcp * -int 10 1m
|
||||
8.8.8.8:ssh stream tcp * -ext 6 60m
|
||||
ssh stream tcp6 * * 6 60m
|
||||
http stream tcp * * 6 60m
|
||||
|
||||
Here note that owner is * because the connection is done from the
|
||||
child ssh socket which runs with user privs. We treat ipv4 connections
|
||||
differently by maintaining two different rules one for the external
|
||||
interface and one from the internal We also register for both tcp
|
||||
and tcp6 since those are different listening sockets and addresses;
|
||||
we don't bother with ipv6 and separate rules. 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
|
||||
int_if=sk0
|
||||
|
||||
group "external" on $ext_if {
|
||||
...
|
||||
ruleset "blacklistd-ext"
|
||||
ruleset "blacklistd"
|
||||
...
|
||||
}
|
||||
|
||||
group "internal" on $int_if {
|
||||
...
|
||||
ruleset "blacklistd-int"
|
||||
...
|
||||
}
|
||||
|
||||
Enjoy,
|
||||
|
||||
christos
|
21
20160409/TODO
Normal file
21
20160409/TODO
Normal file
@ -0,0 +1,21 @@
|
||||
# $NetBSD: TODO,v 1.7 2015/01/23 21:34:01 christos Exp $
|
||||
|
||||
- don't poll periodically, find the next timeout
|
||||
- use the socket also for commands? Or separate socket?
|
||||
- add functionality to the control program. Should it change the database
|
||||
directly, or talk to the daemon to have it do it?
|
||||
- perhaps handle interfaces too instead of addresses for dynamic ip?
|
||||
<bge0/4>? What to do with multiple addresses?
|
||||
- perhaps rate limit against DoS
|
||||
- perhaps instead of scanning the list have a sparse map by port?
|
||||
- do we want to use libnpf directly for efficiency?
|
||||
- add more daemons ftpd?
|
||||
- do we care about the db state becoming too large?
|
||||
- instead of a yes = bump one, no = return to 0 interface, do we want
|
||||
to have something more flexible like?
|
||||
+n
|
||||
-n
|
||||
block
|
||||
unblock
|
||||
- do we need an api in blacklistctl to perform maintenance
|
||||
- fix the blacklistctl output to be more user friendly
|
15
20160409/bin/Makefile
Normal file
15
20160409/bin/Makefile
Normal file
@ -0,0 +1,15 @@
|
||||
# $NetBSD: Makefile,v 1.11 2015/01/27 19:40:36 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
|
||||
DBG=-g
|
||||
|
||||
LDADD+=-lutil
|
||||
DPADD+=${LIBUTIL}
|
||||
|
||||
.include <bsd.prog.mk>
|
81
20160409/bin/blacklistctl.8
Normal file
81
20160409/bin/blacklistctl.8
Normal file
@ -0,0 +1,81 @@
|
||||
.\" $NetBSD: blacklistctl.8,v 1.7 2015/04/30 06:20:43 riz 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 April 29, 2015
|
||||
.Dt BLACKLISTCTL 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm blacklistctl
|
||||
.Nd display and change the state of blacklistd
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Cm dump
|
||||
.Op Fl abdnrw
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
is a program used to display the state of
|
||||
.Xr blacklistd 8
|
||||
.Pp
|
||||
The following options are available:
|
||||
.Bl -tag -width indent
|
||||
.It Fl a
|
||||
Show all database entries, by default it shows only the embryonic ones.
|
||||
.It Fl b
|
||||
Show only the blocked entries.
|
||||
.It Fl d
|
||||
Increase debugging level.
|
||||
.It Fl n
|
||||
Don't display a header.
|
||||
.It Fl r
|
||||
Show the remaining blocked time instead of the last activity time.
|
||||
.It Fl w
|
||||
Normally the width of addresses is good for IPv4, the
|
||||
.Fl w
|
||||
flag, makes the display wide enough for IPv6 addresses.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr blacklistd 8
|
||||
.Sh NOTES
|
||||
Sometimes the reported number of failed attempts can exceed the number
|
||||
of attempts that
|
||||
.Xr blacklistd 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
|
||||
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
|
||||
.Nm
|
||||
appeared in
|
||||
.Nx 7 .
|
||||
.Sh AUTHORS
|
||||
.An Christos Zoulas
|
151
20160409/bin/blacklistctl.c
Normal file
151
20160409/bin/blacklistctl.c
Normal file
@ -0,0 +1,151 @@
|
||||
/* $NetBSD: blacklistctl.c,v 1.20 2016/04/04 15:52:56 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: blacklistctl.c,v 1.20 2016/04/04 15:52:56 christos Exp $");
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#ifdef HAVE_LIBUTIL_H
|
||||
#include <libutil.h>
|
||||
#endif
|
||||
#ifdef HAVE_UTIL_H
|
||||
#include <util.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <err.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "conf.h"
|
||||
#include "state.h"
|
||||
#include "internal.h"
|
||||
#include "support.h"
|
||||
|
||||
static __dead void
|
||||
usage(int c)
|
||||
{
|
||||
if (c == 0)
|
||||
warnx("Missing/unknown command");
|
||||
else
|
||||
warnx("Unknown option `%c'", (char)c);
|
||||
fprintf(stderr, "Usage: %s dump [-abdnrw]\n", getprogname());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
const char *dbname = _PATH_BLSTATE;
|
||||
DB *db;
|
||||
struct conf c;
|
||||
struct dbinfo dbi;
|
||||
unsigned int i;
|
||||
struct timespec ts;
|
||||
int all, blocked, remain, wide, noheader;
|
||||
int o;
|
||||
|
||||
noheader = wide = blocked = all = remain = 0;
|
||||
lfun = dlog;
|
||||
|
||||
if (argc == 1 || strcmp(argv[1], "dump") != 0)
|
||||
usage(0);
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
while ((o = getopt(argc, argv, "abD:dnrw")) != -1)
|
||||
switch (o) {
|
||||
case 'a':
|
||||
all = 1;
|
||||
blocked = 0;
|
||||
break;
|
||||
case 'b':
|
||||
blocked = 1;
|
||||
case 'D':
|
||||
dbname = optarg;
|
||||
break;
|
||||
break;
|
||||
case 'd':
|
||||
debug++;
|
||||
break;
|
||||
case 'n':
|
||||
noheader = 1;
|
||||
break;
|
||||
case 'r':
|
||||
remain = 1;
|
||||
break;
|
||||
case 'w':
|
||||
wide = 1;
|
||||
break;
|
||||
default:
|
||||
usage(o);
|
||||
break;
|
||||
}
|
||||
|
||||
db = state_open(dbname, O_RDONLY, 0);
|
||||
if (db == NULL)
|
||||
err(EXIT_FAILURE, "Can't open `%s'", dbname);
|
||||
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
wide = wide ? 8 * 4 + 7 : 4 * 3 + 3;
|
||||
if (!noheader)
|
||||
printf("%*.*s/ma:port\tid\tnfail\t%s\n", wide, wide,
|
||||
"address", remain ? "remaining time" : "last access");
|
||||
for (i = 1; state_iterate(db, &c, &dbi, i) != 0; i = 0) {
|
||||
char buf[BUFSIZ];
|
||||
if (!all) {
|
||||
if (blocked) {
|
||||
if (dbi.count < c.c_nfail)
|
||||
continue;
|
||||
} else {
|
||||
if (dbi.count >= c.c_nfail)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
sockaddr_snprintf(buf, sizeof(buf), "%a", (void *)&c.c_ss);
|
||||
printf("%*.*s/%d:%d\t", wide, wide, buf, c.c_lmask, c.c_port);
|
||||
if (remain)
|
||||
fmtydhms(buf, sizeof(buf),
|
||||
c.c_duration - (ts.tv_sec - dbi.last));
|
||||
else
|
||||
fmttime(buf, sizeof(buf), dbi.last);
|
||||
printf("%s\t%d/%d\t%-s\n", dbi.id, dbi.count, c.c_nfail, buf);
|
||||
}
|
||||
state_close(db);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
222
20160409/bin/blacklistd.8
Normal file
222
20160409/bin/blacklistd.8
Normal file
@ -0,0 +1,222 @@
|
||||
.\" $NetBSD: blacklistd.8,v 1.15 2016/03/11 17:16:40 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 June 4, 2015
|
||||
.Dt BLACKLISTD 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm blacklistd
|
||||
.Nd block and release ports on demand to avoid DoS abuse
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl dfrv
|
||||
.Op Fl C Ar controlprog
|
||||
.Op Fl c Ar configfile
|
||||
.Op Fl D Ar dbfile
|
||||
.Op Fl P Ar sockpathsfile
|
||||
.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 sockets at paths specified in the
|
||||
.Ar sockpathsfile
|
||||
for notifications from other daemons about successful or failed connection
|
||||
attempts.
|
||||
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 .
|
||||
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 .
|
||||
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> <address> <mask> <port>
|
||||
.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 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
|
||||
Then the same control script is invoked as:
|
||||
.Bd -literal -offset indent
|
||||
control remove <rulename> <proto> <address> <mask> <port> <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.
|
||||
.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 following options are available:
|
||||
.Bl -tag -width indent
|
||||
.It Fl C Ar controlprog
|
||||
Use
|
||||
.Ar controlprog
|
||||
to communicate with the packet filter, usually
|
||||
.Pa /libexec/blacklistd-helper .
|
||||
The following arguments are passed to the control program:
|
||||
.Bl -tag -width protocol
|
||||
.It action
|
||||
The action to perform:
|
||||
.Dv add ,
|
||||
.Dv rem ,
|
||||
or
|
||||
.Dv flush
|
||||
to add, remove or flush a firewall rule.
|
||||
.It name
|
||||
The rule name.
|
||||
.It protocol
|
||||
The optional protocol name (can be empty):
|
||||
.Dv tcp ,
|
||||
.Dv tcp6 ,
|
||||
.Dv udp ,
|
||||
.Dv udp6 .
|
||||
.It address
|
||||
The IPv4 or IPv6 numeric address to be blocked or released.
|
||||
.It mask
|
||||
The numeric mask to be applied to the blocked or released address
|
||||
.It port
|
||||
The optional numeric port to be blocked (can be empty).
|
||||
.It id
|
||||
For packet filters that support removal of rules by rule identifier, the
|
||||
identifier of the rule to be removed.
|
||||
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 .
|
||||
.It Fl D Ar dbfile
|
||||
The Berkeley DB file where
|
||||
.Nm
|
||||
stores its state, usually
|
||||
.Pa /var/run/blacklistd.db .
|
||||
.It Fl d
|
||||
Normally,
|
||||
.Nm
|
||||
disassociates itself from the terminal unless the
|
||||
.Fl d
|
||||
flag is specified, in which case it stays in the foreground.
|
||||
.It Fl f
|
||||
Truncate the state database and flush all the rules named
|
||||
.Ar rulename
|
||||
are deleted by invoking the control script as:
|
||||
.Bd -literal -offset indent
|
||||
control flush <rulename>
|
||||
.Ed
|
||||
.It Fl P Ar sockspathsfile
|
||||
A file containing a list of pathnames, one per line that
|
||||
.Nm
|
||||
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 .
|
||||
.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.
|
||||
.It Fl s Ar sockpath
|
||||
Add
|
||||
.Ar sockpath
|
||||
to the list of Unix sockets
|
||||
.Nm
|
||||
listens to.
|
||||
.It Fl t Ar timeout
|
||||
The interval in seconds
|
||||
.Nm
|
||||
polls the state file to update the rules.
|
||||
.It Fl v
|
||||
Cause
|
||||
.Nm
|
||||
to print
|
||||
diagnostic messages to
|
||||
.Dv stdout
|
||||
instead of
|
||||
.Xr syslogd 8 .
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width /libexec/blacklistd-helper -compact
|
||||
.It Pa /libexec/blacklistd-helper
|
||||
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/blacklistd.sock
|
||||
Socket to receive connection notifications.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr blacklistd.conf 5 ,
|
||||
.Xr blacklistctl 8 ,
|
||||
.Xr npfctl 8 ,
|
||||
.Xr syslogd 8
|
||||
.Sh HISTORY
|
||||
.Nm
|
||||
appeared in
|
||||
.Nx 7 .
|
||||
.Sh AUTHORS
|
||||
.An Christos Zoulas
|
537
20160409/bin/blacklistd.c
Normal file
537
20160409/bin/blacklistd.c
Normal file
@ -0,0 +1,537 @@
|
||||
/* $NetBSD: blacklistd.c,v 1.34 2016/04/04 15:52:56 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: blacklistd.c,v 1.34 2016/04/04 15:52:56 christos Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
#ifdef HAVE_LIBUTIL_H
|
||||
#include <libutil.h>
|
||||
#endif
|
||||
#ifdef HAVE_UTIL_H
|
||||
#include <util.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <syslog.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
#include <poll.h>
|
||||
#include <fcntl.h>
|
||||
#include <err.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "bl.h"
|
||||
#include "internal.h"
|
||||
#include "conf.h"
|
||||
#include "run.h"
|
||||
#include "state.h"
|
||||
#include "support.h"
|
||||
|
||||
static const char *configfile = _PATH_BLCONF;
|
||||
static DB *state;
|
||||
static const char *dbfile = _PATH_BLSTATE;
|
||||
static sig_atomic_t readconf;
|
||||
static sig_atomic_t done;
|
||||
static int vflag;
|
||||
|
||||
static void
|
||||
sigusr1(int n __unused)
|
||||
{
|
||||
debug++;
|
||||
}
|
||||
|
||||
static void
|
||||
sigusr2(int n __unused)
|
||||
{
|
||||
debug--;
|
||||
}
|
||||
|
||||
static void
|
||||
sighup(int n __unused)
|
||||
{
|
||||
readconf++;
|
||||
}
|
||||
|
||||
static void
|
||||
sigdone(int n __unused)
|
||||
{
|
||||
done++;
|
||||
}
|
||||
|
||||
static __dead void
|
||||
usage(int c)
|
||||
{
|
||||
if (c)
|
||||
warnx("Unknown option `%c'", (char)c);
|
||||
fprintf(stderr, "Usage: %s [-vdfr] [-c <config>] [-R <rulename>] "
|
||||
"[-P <sockpathsfile>] [-C <controlprog>] [-D <dbfile>] "
|
||||
"[-s <sockpath>] [-t <timeout>]\n", getprogname());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static int
|
||||
getremoteaddress(bl_info_t *bi, struct sockaddr_storage *rss, socklen_t *rsl)
|
||||
{
|
||||
*rsl = sizeof(*rss);
|
||||
memset(rss, 0, *rsl);
|
||||
|
||||
if (getpeername(bi->bi_fd, (void *)rss, rsl) != -1)
|
||||
return 0;
|
||||
|
||||
if (errno != ENOTCONN) {
|
||||
(*lfun)(LOG_ERR, "getpeername failed (%m)");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bi->bi_slen == 0) {
|
||||
(*lfun)(LOG_ERR, "unconnected socket with no peer in message");
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (bi->bi_ss.ss_family) {
|
||||
case AF_INET:
|
||||
*rsl = sizeof(struct sockaddr_in);
|
||||
break;
|
||||
case AF_INET6:
|
||||
*rsl = sizeof(struct sockaddr_in6);
|
||||
break;
|
||||
default:
|
||||
(*lfun)(LOG_ERR, "bad client passed socket family %u",
|
||||
(unsigned)bi->bi_ss.ss_family);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (*rsl != bi->bi_slen) {
|
||||
(*lfun)(LOG_ERR, "bad client passed socket length %u != %u",
|
||||
(unsigned)*rsl, (unsigned)bi->bi_slen);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(rss, &bi->bi_ss, *rsl);
|
||||
|
||||
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
|
||||
if (*rsl != rss->ss_len) {
|
||||
(*lfun)(LOG_ERR,
|
||||
"bad client passed socket internal length %u != %u",
|
||||
(unsigned)*rsl, (unsigned)rss->ss_len);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
process(bl_t bl)
|
||||
{
|
||||
struct sockaddr_storage rss;
|
||||
socklen_t rsl;
|
||||
char rbuf[BUFSIZ];
|
||||
bl_info_t *bi;
|
||||
struct conf c;
|
||||
struct dbinfo dbi;
|
||||
struct timespec ts;
|
||||
|
||||
if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {
|
||||
(*lfun)(LOG_ERR, "clock_gettime failed (%m)");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((bi = bl_recv(bl)) == NULL) {
|
||||
(*lfun)(LOG_ERR, "no message (%m)");
|
||||
return;
|
||||
}
|
||||
|
||||
if (getremoteaddress(bi, &rss, &rsl) == -1)
|
||||
goto out;
|
||||
|
||||
if (debug) {
|
||||
sockaddr_snprintf(rbuf, sizeof(rbuf), "%a:%p", (void *)&rss);
|
||||
(*lfun)(LOG_DEBUG, "processing type=%d fd=%d remote=%s msg=%s"
|
||||
" uid=%lu gid=%lu", bi->bi_type, bi->bi_fd, rbuf,
|
||||
bi->bi_msg, (unsigned long)bi->bi_uid,
|
||||
(unsigned long)bi->bi_gid);
|
||||
}
|
||||
|
||||
if (conf_find(bi->bi_fd, bi->bi_uid, &rss, &c) == NULL) {
|
||||
(*lfun)(LOG_DEBUG, "no rule matched");
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
if (state_get(state, &c, &dbi) == -1)
|
||||
goto out;
|
||||
|
||||
if (debug) {
|
||||
char b1[128], b2[128];
|
||||
(*lfun)(LOG_DEBUG, "%s: db state info for %s: count=%d/%d "
|
||||
"last=%s now=%s", __func__, rbuf, dbi.count, c.c_nfail,
|
||||
fmttime(b1, sizeof(b1), dbi.last),
|
||||
fmttime(b2, sizeof(b2), ts.tv_sec));
|
||||
}
|
||||
|
||||
switch (bi->bi_type) {
|
||||
case BL_ADD:
|
||||
dbi.count++;
|
||||
dbi.last = ts.tv_sec;
|
||||
if (dbi.id[0]) {
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
(*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;
|
||||
sockaddr_snprintf(rbuf, sizeof(rbuf), "%a",
|
||||
(void *)&rss);
|
||||
(*lfun)(LOG_INFO,
|
||||
"blocked %s/%d:%d for %d seconds",
|
||||
rbuf, c.c_lmask, c.c_port, c.c_duration);
|
||||
|
||||
}
|
||||
break;
|
||||
case BL_DELETE:
|
||||
if (dbi.last == 0)
|
||||
goto out;
|
||||
dbi.last = 0;
|
||||
break;
|
||||
default:
|
||||
(*lfun)(LOG_ERR, "unknown message %d", bi->bi_type);
|
||||
}
|
||||
if (state_put(state, &c, &dbi) == -1)
|
||||
goto out;
|
||||
out:
|
||||
close(bi->bi_fd);
|
||||
}
|
||||
|
||||
static void
|
||||
update_interfaces(void)
|
||||
{
|
||||
struct ifaddrs *oifas, *nifas;
|
||||
|
||||
if (getifaddrs(&nifas) == -1)
|
||||
return;
|
||||
|
||||
oifas = ifas;
|
||||
ifas = nifas;
|
||||
|
||||
if (oifas)
|
||||
freeifaddrs(oifas);
|
||||
}
|
||||
|
||||
static void
|
||||
update(void)
|
||||
{
|
||||
struct timespec ts;
|
||||
struct conf c;
|
||||
struct dbinfo dbi;
|
||||
unsigned int f, n;
|
||||
char buf[128];
|
||||
void *ss = &c.c_ss;
|
||||
|
||||
if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {
|
||||
(*lfun)(LOG_ERR, "clock_gettime failed (%m)");
|
||||
return;
|
||||
}
|
||||
|
||||
again:
|
||||
for (n = 0, f = 1; state_iterate(state, &c, &dbi, f) == 1;
|
||||
f = 0, n++)
|
||||
{
|
||||
time_t when = c.c_duration + dbi.last;
|
||||
if (debug > 1) {
|
||||
char b1[64], b2[64];
|
||||
sockaddr_snprintf(buf, sizeof(buf), "%a:%p", ss);
|
||||
(*lfun)(LOG_DEBUG, "%s:[%u] %s count=%d duration=%d "
|
||||
"last=%s " "now=%s", __func__, n, buf, dbi.count,
|
||||
c.c_duration, fmttime(b1, sizeof(b1), dbi.last),
|
||||
fmttime(b2, sizeof(b2), ts.tv_sec));
|
||||
}
|
||||
if (c.c_duration == -1 || when >= ts.tv_sec)
|
||||
continue;
|
||||
if (dbi.id[0]) {
|
||||
run_change("rem", &c, dbi.id, 0);
|
||||
sockaddr_snprintf(buf, sizeof(buf), "%a", ss);
|
||||
syslog(LOG_INFO, "released %s/%d:%d after %d seconds",
|
||||
buf, c.c_lmask, c.c_port, c.c_duration);
|
||||
}
|
||||
state_del(state, &c);
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
addfd(struct pollfd **pfdp, bl_t **blp, size_t *nfd, size_t *maxfd,
|
||||
const char *path)
|
||||
{
|
||||
bl_t bl = bl_create(true, path, vflag ? vdlog : vsyslog);
|
||||
if (bl == NULL || !bl_isconnected(bl))
|
||||
exit(EXIT_FAILURE);
|
||||
if (*nfd >= *maxfd) {
|
||||
*maxfd += 10;
|
||||
*blp = realloc(*blp, sizeof(**blp) * *maxfd);
|
||||
if (*blp == NULL)
|
||||
err(EXIT_FAILURE, "malloc");
|
||||
*pfdp = realloc(*pfdp, sizeof(**pfdp) * *maxfd);
|
||||
if (*pfdp == NULL)
|
||||
err(EXIT_FAILURE, "malloc");
|
||||
}
|
||||
|
||||
(*pfdp)[*nfd].fd = bl_getfd(bl);
|
||||
(*pfdp)[*nfd].events = POLLIN;
|
||||
(*blp)[*nfd] = bl;
|
||||
*nfd += 1;
|
||||
}
|
||||
|
||||
static void
|
||||
uniqueadd(struct conf ***listp, size_t *nlist, size_t *mlist, struct conf *c)
|
||||
{
|
||||
struct conf **list = *listp;
|
||||
|
||||
if (c->c_name[0] == '\0')
|
||||
return;
|
||||
for (size_t i = 0; i < *nlist; i++) {
|
||||
if (strcmp(list[i]->c_name, c->c_name) == 0)
|
||||
return;
|
||||
}
|
||||
if (*nlist == *mlist) {
|
||||
*mlist += 10;
|
||||
void *p = realloc(*listp, *mlist * sizeof(*list));
|
||||
if (p == NULL)
|
||||
err(EXIT_FAILURE, "Can't allocate for rule list");
|
||||
list = *listp = p;
|
||||
}
|
||||
list[(*nlist)++] = c;
|
||||
}
|
||||
|
||||
static void
|
||||
rules_flush(void)
|
||||
{
|
||||
struct conf **list;
|
||||
size_t nlist, mlist;
|
||||
|
||||
list = NULL;
|
||||
mlist = nlist = 0;
|
||||
for (size_t i = 0; i < rconf.cs_n; i++)
|
||||
uniqueadd(&list, &nlist, &mlist, &rconf.cs_c[i]);
|
||||
for (size_t i = 0; i < lconf.cs_n; i++)
|
||||
uniqueadd(&list, &nlist, &mlist, &lconf.cs_c[i]);
|
||||
|
||||
for (size_t i = 0; i < nlist; i++)
|
||||
run_flush(list[i]);
|
||||
free(list);
|
||||
}
|
||||
|
||||
static void
|
||||
rules_restore(void)
|
||||
{
|
||||
struct conf c;
|
||||
struct dbinfo dbi;
|
||||
unsigned int f;
|
||||
|
||||
for (f = 1; state_iterate(state, &c, &dbi, f) == 1; f = 0) {
|
||||
if (dbi.id[0] == '\0')
|
||||
continue;
|
||||
(void)run_change("rem", &c, dbi.id, 0);
|
||||
(void)run_change("add", &c, dbi.id, sizeof(dbi.id));
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int c, tout, flags, flush, restore;
|
||||
const char *spath, *blsock;
|
||||
|
||||
setprogname(argv[0]);
|
||||
|
||||
spath = NULL;
|
||||
blsock = _PATH_BLSOCK;
|
||||
flush = 0;
|
||||
restore = 0;
|
||||
tout = 0;
|
||||
flags = O_RDWR|O_EXCL|O_CLOEXEC;
|
||||
while ((c = getopt(argc, argv, "C:c:D:dfP:rR:s:t:v")) != -1) {
|
||||
switch (c) {
|
||||
case 'C':
|
||||
controlprog = optarg;
|
||||
break;
|
||||
case 'c':
|
||||
configfile = optarg;
|
||||
break;
|
||||
case 'D':
|
||||
dbfile = optarg;
|
||||
break;
|
||||
case 'd':
|
||||
debug++;
|
||||
break;
|
||||
case 'f':
|
||||
flush++;
|
||||
break;
|
||||
case 'P':
|
||||
spath = optarg;
|
||||
break;
|
||||
case 'R':
|
||||
rulename = optarg;
|
||||
break;
|
||||
case 'r':
|
||||
restore++;
|
||||
break;
|
||||
case 's':
|
||||
blsock = optarg;
|
||||
break;
|
||||
case 't':
|
||||
tout = atoi(optarg) * 1000;
|
||||
break;
|
||||
case 'v':
|
||||
vflag++;
|
||||
break;
|
||||
default:
|
||||
usage(c);
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
if (argc)
|
||||
usage(0);
|
||||
|
||||
signal(SIGHUP, sighup);
|
||||
signal(SIGINT, sigdone);
|
||||
signal(SIGQUIT, sigdone);
|
||||
signal(SIGTERM, sigdone);
|
||||
signal(SIGUSR1, sigusr1);
|
||||
signal(SIGUSR2, sigusr2);
|
||||
|
||||
openlog(getprogname(), LOG_PID, LOG_DAEMON);
|
||||
|
||||
if (debug) {
|
||||
lfun = dlog;
|
||||
if (tout == 0)
|
||||
tout = 5000;
|
||||
} else {
|
||||
if (tout == 0)
|
||||
tout = 15000;
|
||||
}
|
||||
|
||||
update_interfaces();
|
||||
conf_parse(configfile);
|
||||
if (flush) {
|
||||
rules_flush();
|
||||
flags |= O_TRUNC;
|
||||
}
|
||||
|
||||
if (restore)
|
||||
rules_restore();
|
||||
|
||||
struct pollfd *pfd = NULL;
|
||||
bl_t *bl = NULL;
|
||||
size_t nfd = 0;
|
||||
size_t maxfd = 0;
|
||||
|
||||
if (spath == NULL)
|
||||
addfd(&pfd, &bl, &nfd, &maxfd, blsock);
|
||||
else {
|
||||
FILE *fp = fopen(spath, "r");
|
||||
char *line;
|
||||
if (fp == NULL)
|
||||
err(EXIT_FAILURE, "Can't open `%s'", spath);
|
||||
for (; (line = fparseln(fp, NULL, NULL, NULL, 0)) != NULL;
|
||||
free(line))
|
||||
addfd(&pfd, &bl, &nfd, &maxfd, line);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
state = state_open(dbfile, flags, 0600);
|
||||
if (state == NULL)
|
||||
state = state_open(dbfile, flags | O_CREAT, 0600);
|
||||
if (state == NULL)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
if (!debug) {
|
||||
if (daemon(0, 0) == -1)
|
||||
err(EXIT_FAILURE, "daemon failed");
|
||||
if (pidfile(NULL) == -1)
|
||||
err(EXIT_FAILURE, "Can't create pidfile");
|
||||
}
|
||||
|
||||
for (size_t t = 0; !done; t++) {
|
||||
if (readconf) {
|
||||
readconf = 0;
|
||||
conf_parse(configfile);
|
||||
}
|
||||
switch (poll(pfd, (nfds_t)nfd, tout)) {
|
||||
case -1:
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
(*lfun)(LOG_ERR, "poll (%m)");
|
||||
return EXIT_FAILURE;
|
||||
case 0:
|
||||
state_sync(state);
|
||||
break;
|
||||
default:
|
||||
for (size_t i = 0; i < nfd; i++)
|
||||
if (pfd[i].revents & POLLIN)
|
||||
process(bl[i]);
|
||||
}
|
||||
if (t % 100 == 0)
|
||||
state_sync(state);
|
||||
if (t % 10000 == 0)
|
||||
update_interfaces();
|
||||
update();
|
||||
}
|
||||
state_close(state);
|
||||
return 0;
|
||||
}
|
222
20160409/bin/blacklistd.conf.5
Normal file
222
20160409/bin/blacklistd.conf.5
Normal file
@ -0,0 +1,222 @@
|
||||
.\" $NetBSD: blacklistd.conf.5,v 1.3 2015/04/30 06:20:43 riz 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 April 29, 2015
|
||||
.Dt BLACKLISTD.CONF 5
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm blacklistd.conf
|
||||
.Nd configuration file format for blacklistd
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
files contains configuration lines for
|
||||
.Xr blacklistd 8 .
|
||||
It contains one entry per line, and is similar to
|
||||
.Xr inetd.conf 5 .
|
||||
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.
|
||||
.Pp
|
||||
There are two kinds of configuration lines,
|
||||
.Va local
|
||||
and
|
||||
.Va remote .
|
||||
By default, configuration lines are
|
||||
.Va local ,
|
||||
i.e. the address specified refers to the addresses on the local machine.
|
||||
To switch to between
|
||||
.Va local
|
||||
and
|
||||
.Va remote
|
||||
configuration lines you can specify the stanzas:
|
||||
.Dq [local]
|
||||
and
|
||||
.Dq [remote] .
|
||||
.Pp
|
||||
On
|
||||
.Va local
|
||||
and
|
||||
.Va remote
|
||||
lines
|
||||
.Dq *
|
||||
means use the default, or wildcard match.
|
||||
In addition, for
|
||||
.Va remote
|
||||
lines
|
||||
.Dq =
|
||||
means use the values from the matched
|
||||
.Va local
|
||||
configuration line.
|
||||
.Pp
|
||||
The first four fields,
|
||||
.Va location ,
|
||||
.Va type ,
|
||||
.Va proto ,
|
||||
and
|
||||
.Va owner
|
||||
are used to match the
|
||||
.Va local
|
||||
or
|
||||
.Va remote
|
||||
addresses, whereas the last 3 fields
|
||||
.Va name ,
|
||||
.Va nfail ,
|
||||
and
|
||||
.Va disable
|
||||
are used to modify the filtering action.
|
||||
.Pp
|
||||
The first field denotes the
|
||||
.Va location
|
||||
as an address, mask, and port.
|
||||
The syntax for the
|
||||
.Va location
|
||||
is:
|
||||
.Bd -literal -offset indent
|
||||
[<address>|<interface>][/<mask>][:<port>]
|
||||
.Ed
|
||||
.Pp
|
||||
The
|
||||
.Dv address
|
||||
can be an IPv4 address in numeric format, an IPv6 address
|
||||
in numeric format and enclosed by square brackets, or an interface name.
|
||||
Mask modifiers are not allowed on interfaces because interfaces
|
||||
have multiple address in different protocols where the mask has a different
|
||||
size.
|
||||
.Pp
|
||||
The
|
||||
.Dv mask
|
||||
is always numeric, but the
|
||||
.Dv port
|
||||
can be either numeric or symbolic.
|
||||
.Pp
|
||||
The second field is the socket
|
||||
.Va type :
|
||||
.Dv stream ,
|
||||
.Dv dgram ,
|
||||
or numeric.
|
||||
The third field is the
|
||||
.Va prococol :
|
||||
.Dv tcp ,
|
||||
.Dv udp ,
|
||||
.Dv tcp6 ,
|
||||
.Dv udp6 ,
|
||||
or numeric.
|
||||
The fourth file 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.
|
||||
.Pp
|
||||
The
|
||||
.Va name
|
||||
field, is the name of the packet filter rule to be used.
|
||||
If the
|
||||
.Va name
|
||||
starts with a
|
||||
.Dq - ,
|
||||
then the default rulename is prepended to the given name.
|
||||
If the
|
||||
.Dv name
|
||||
contains a
|
||||
.Dq / ,
|
||||
the remaining portion of the name is interpreted as the mask to be
|
||||
applied to the address specified in the rule, so one can block whole
|
||||
subnets for a single rule violation.
|
||||
.Pp
|
||||
The
|
||||
.Va nfail
|
||||
field contains the number of failed attempts before access is blocked,
|
||||
defaulting to
|
||||
.Dq *
|
||||
meaning never, and the last field
|
||||
.Va disable
|
||||
specifies the amount of time since the last access that the blocking
|
||||
rule should be active, defaulting to
|
||||
.Dq *
|
||||
meaning forever.
|
||||
The default unit for
|
||||
.Va disable
|
||||
is seconds, but one can specify suffixes for different units, such as
|
||||
.Dq m
|
||||
for minutes
|
||||
.Dq h
|
||||
for hours and
|
||||
.Dq d
|
||||
for days.
|
||||
.Pp
|
||||
Matching is done first by checking the
|
||||
.Va local
|
||||
rules one by one, from the most specific to the least specific.
|
||||
If a match is found, then the
|
||||
.Va remote
|
||||
rules are applied, and if a match is found the
|
||||
.Va name ,
|
||||
.Va nfail ,
|
||||
and
|
||||
.Va disable
|
||||
fields can be altered by the
|
||||
.Va remote
|
||||
rule that matched.
|
||||
.Pp
|
||||
The
|
||||
.Va remote
|
||||
rules can be used for whitelisting specific addresses, changing the mask
|
||||
size, or the rule that the packet filter uses, the number of failed attempts,
|
||||
or the blocked duration.
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/blacklistd.conf -compact
|
||||
.It Pa /etc/blacklistd.conf
|
||||
Configuration file.
|
||||
.El
|
||||
.Sh EXAMPLES
|
||||
.Bd -literal -offset
|
||||
# Block ssh, after 3 attempts for 6 hours on the bnx0 interface
|
||||
[local]
|
||||
# location type proto owner name nfail duration
|
||||
bnx0:ssh * * * * 3 6h
|
||||
[remote]
|
||||
# Never block 1.2.3.4
|
||||
1.2.3.4:ssh * * * * * *
|
||||
# For addresses coming from 8.8.0.0/16 block class C networks instead
|
||||
# individual hosts, but keep the rest of the blocking parameters the same.
|
||||
8.8.0.0/16:ssh * * * /24 = =
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr blacklistctl 8 ,
|
||||
.Xr blacklistd 8
|
||||
.Sh HISTORY
|
||||
.Nm
|
||||
appeared in
|
||||
.Nx 7 .
|
||||
.Sh AUTHORS
|
||||
.An Christos Zoulas
|
1142
20160409/bin/conf.c
Normal file
1142
20160409/bin/conf.c
Normal file
File diff suppressed because it is too large
Load Diff
65
20160409/bin/conf.h
Normal file
65
20160409/bin/conf.h
Normal file
@ -0,0 +1,65 @@
|
||||
/* $NetBSD: conf.h,v 1.6 2015/01/27 19:40:36 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _CONF_H
|
||||
#define _CONF_H
|
||||
|
||||
#include <sys/socket.h>
|
||||
|
||||
struct conf {
|
||||
struct sockaddr_storage c_ss;
|
||||
int c_lmask;
|
||||
int c_port;
|
||||
int c_proto;
|
||||
int c_family;
|
||||
int c_uid;
|
||||
int c_nfail;
|
||||
char c_name[128];
|
||||
int c_rmask;
|
||||
int c_duration;
|
||||
};
|
||||
|
||||
struct confset {
|
||||
struct conf *cs_c;
|
||||
size_t cs_n;
|
||||
size_t cs_m;
|
||||
};
|
||||
|
||||
#define CONFNAMESZ sizeof(((struct conf *)0)->c_name)
|
||||
|
||||
__BEGIN_DECLS
|
||||
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, const struct sockaddr_storage *,
|
||||
struct conf *);
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _CONF_H */
|
48
20160409/bin/internal.c
Normal file
48
20160409/bin/internal.c
Normal file
@ -0,0 +1,48 @@
|
||||
/* $NetBSD: internal.c,v 1.5 2015/01/27 19:40:37 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: internal.c,v 1.5 2015/01/27 19:40:37 christos Exp $");
|
||||
|
||||
#include <stdio.h>
|
||||
#include <syslog.h>
|
||||
#include "conf.h"
|
||||
#include "internal.h"
|
||||
|
||||
int debug;
|
||||
const char *rulename = "blacklistd";
|
||||
const char *controlprog = _PATH_BLCONTROL;
|
||||
struct confset lconf, rconf;
|
||||
struct ifaddrs *ifas;
|
||||
void (*lfun)(int, const char *, ...) = syslog;
|
57
20160409/bin/internal.h
Normal file
57
20160409/bin/internal.h
Normal file
@ -0,0 +1,57 @@
|
||||
/* $NetBSD: internal.h,v 1.14 2016/04/04 15:52:56 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _INTERNAL_H
|
||||
#define _INTERNAL_H
|
||||
|
||||
#ifndef _PATH_BLCONF
|
||||
#define _PATH_BLCONF "/etc/blacklistd.conf"
|
||||
#endif
|
||||
#ifndef _PATH_BLCONTROL
|
||||
#define _PATH_BLCONTROL "/libexec/blacklistd-helper"
|
||||
#endif
|
||||
#ifndef _PATH_BLSTATE
|
||||
#define _PATH_BLSTATE "/var/db/blacklistd.db"
|
||||
#endif
|
||||
|
||||
extern struct confset rconf, lconf;
|
||||
extern int debug;
|
||||
extern const char *rulename;
|
||||
extern const char *controlprog;
|
||||
extern struct ifaddrs *ifas;
|
||||
|
||||
#if !defined(__syslog_attribute__) && !defined(__syslog__)
|
||||
#define __syslog__ __printf__
|
||||
#endif
|
||||
|
||||
extern void (*lfun)(int, const char *, ...)
|
||||
__attribute__((__format__(__syslog__, 2, 3)));
|
||||
|
||||
#endif /* _INTERNAL_H */
|
156
20160409/bin/run.c
Normal file
156
20160409/bin/run.c
Normal file
@ -0,0 +1,156 @@
|
||||
/* $NetBSD: run.c,v 1.14 2016/04/04 15:52:56 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: run.c,v 1.14 2016/04/04 15:52:56 christos Exp $");
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_LIBUTIL_H
|
||||
#include <libutil.h>
|
||||
#endif
|
||||
#ifdef HAVE_UTIL_H
|
||||
#include <util.h>
|
||||
#endif
|
||||
#include <stdarg.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <syslog.h>
|
||||
#include <string.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
|
||||
#include "run.h"
|
||||
#include "conf.h"
|
||||
#include "internal.h"
|
||||
#include "support.h"
|
||||
|
||||
extern char **environ;
|
||||
|
||||
static char *
|
||||
run(const char *cmd, const char *name, ...)
|
||||
{
|
||||
const char *argv[20];
|
||||
size_t i;
|
||||
va_list ap;
|
||||
FILE *fp;
|
||||
char buf[10240], *res;
|
||||
|
||||
argv[0] = "control";
|
||||
argv[1] = cmd;
|
||||
argv[2] = name;
|
||||
va_start(ap, name);
|
||||
for (i = 3; i < __arraycount(argv) &&
|
||||
(argv[i] = va_arg(ap, char *)) != NULL; i++)
|
||||
continue;
|
||||
va_end(ap);
|
||||
|
||||
if (debug) {
|
||||
size_t z;
|
||||
int r;
|
||||
|
||||
r = snprintf(buf, sizeof(buf), "run %s [", controlprog);
|
||||
if (r == -1 || (z = (size_t)r) >= sizeof(buf))
|
||||
z = sizeof(buf);
|
||||
for (i = 0; argv[i]; i++) {
|
||||
r = snprintf(buf + z, sizeof(buf) - z, "%s%s",
|
||||
argv[i], argv[i + 1] ? " " : "");
|
||||
if (r == -1 || (z += (size_t)r) >= sizeof(buf))
|
||||
z = sizeof(buf);
|
||||
}
|
||||
(*lfun)(LOG_DEBUG, "%s]", buf);
|
||||
}
|
||||
|
||||
fp = popenve(controlprog, __UNCONST(argv), environ, "r");
|
||||
if (fp == NULL) {
|
||||
(*lfun)(LOG_ERR, "popen %s failed (%m)", controlprog);
|
||||
return NULL;
|
||||
}
|
||||
if (fgets(buf, sizeof(buf), fp) != NULL)
|
||||
res = strdup(buf);
|
||||
else
|
||||
res = NULL;
|
||||
pclose(fp);
|
||||
if (debug)
|
||||
(*lfun)(LOG_DEBUG, "%s returns %s", cmd, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
void
|
||||
run_flush(const struct conf *c)
|
||||
{
|
||||
free(run("flush", c->c_name, NULL));
|
||||
}
|
||||
|
||||
int
|
||||
run_change(const char *how, const struct conf *c, char *id, size_t len)
|
||||
{
|
||||
const char *prname;
|
||||
char poname[64], adname[128], maskname[32], *rv;
|
||||
size_t off;
|
||||
|
||||
switch (c->c_proto) {
|
||||
case -1:
|
||||
prname = "";
|
||||
break;
|
||||
case IPPROTO_TCP:
|
||||
prname = "tcp";
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
prname = "udp";
|
||||
break;
|
||||
default:
|
||||
(*lfun)(LOG_ERR, "%s: bad protocol %d", __func__, c->c_proto);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (c->c_port != -1)
|
||||
snprintf(poname, sizeof(poname), "%d", c->c_port);
|
||||
else
|
||||
poname[0] = '\0';
|
||||
|
||||
snprintf(maskname, sizeof(maskname), "%d", c->c_lmask);
|
||||
sockaddr_snprintf(adname, sizeof(adname), "%a", (const void *)&c->c_ss);
|
||||
|
||||
rv = run(how, c->c_name, prname, adname, maskname, poname, id, NULL);
|
||||
if (rv == NULL)
|
||||
return -1;
|
||||
if (len != 0) {
|
||||
rv[strcspn(rv, "\n")] = '\0';
|
||||
off = strncmp(rv, "OK ", 3) == 0 ? 3 : 0;
|
||||
strlcpy(id, rv + off, len);
|
||||
}
|
||||
free(rv);
|
||||
return 0;
|
||||
}
|
41
20160409/bin/run.h
Normal file
41
20160409/bin/run.h
Normal file
@ -0,0 +1,41 @@
|
||||
/* $NetBSD: run.h,v 1.5 2015/01/27 19:40:37 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _RUN_H
|
||||
#define _RUN_H
|
||||
|
||||
__BEGIN_DECLS
|
||||
struct conf;
|
||||
void run_flush(const struct conf *);
|
||||
struct sockaddr_storage;
|
||||
int run_change(const char *, const struct conf *, char *, size_t);
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _RUN_H */
|
233
20160409/bin/state.c
Normal file
233
20160409/bin/state.c
Normal file
@ -0,0 +1,233 @@
|
||||
/* $NetBSD: state.c,v 1.18 2016/04/04 15:52:56 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: state.c,v 1.18 2016/04/04 15:52:56 christos Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <syslog.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "bl.h"
|
||||
#include "internal.h"
|
||||
#include "conf.h"
|
||||
#include "support.h"
|
||||
#include "state.h"
|
||||
|
||||
static HASHINFO openinfo = {
|
||||
4096, /* bsize */
|
||||
32, /* ffactor */
|
||||
256, /* nelem */
|
||||
8 * 1024 * 1024,/* cachesize */
|
||||
NULL, /* hash() */
|
||||
0 /* lorder */
|
||||
};
|
||||
|
||||
int
|
||||
state_close(DB *db)
|
||||
{
|
||||
if (db == NULL)
|
||||
return -1;
|
||||
if ((*db->close)(db) == -1) {
|
||||
(*lfun)(LOG_ERR, "%s: can't close db (%m)", __func__);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
DB *
|
||||
state_open(const char *dbname, int flags, mode_t perm)
|
||||
{
|
||||
DB *db;
|
||||
|
||||
#ifdef __APPLE__
|
||||
flags &= O_CREAT|O_EXCL|O_EXLOCK|O_NONBLOCK|O_RDONLY|
|
||||
O_RDWR|O_SHLOCK|O_TRUNC;
|
||||
#endif
|
||||
db = dbopen(dbname, flags, perm, DB_HASH, &openinfo);
|
||||
if (db == NULL) {
|
||||
if (errno == ENOENT && (flags & O_CREAT) == 0)
|
||||
return NULL;
|
||||
(*lfun)(LOG_ERR, "%s: can't open `%s' (%m)", __func__, dbname);
|
||||
}
|
||||
return db;
|
||||
}
|
||||
|
||||
static int
|
||||
state_sizecheck(const DBT *t)
|
||||
{
|
||||
if (sizeof(struct conf) == t->size)
|
||||
return 0;
|
||||
(*lfun)(LOG_ERR, "Key size mismatch %zu != %zu", sizeof(struct conf),
|
||||
t->size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
dumpkey(const struct conf *k)
|
||||
{
|
||||
char buf[10240];
|
||||
blhexdump(buf, sizeof(buf), __func__, k, sizeof(*k));
|
||||
(*lfun)(LOG_DEBUG, "%s", buf);
|
||||
(*lfun)(LOG_DEBUG, "%s: %s", __func__,
|
||||
conf_print(buf, sizeof(buf), "", "", k));
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
state_del(DB *db, const struct conf *c)
|
||||
{
|
||||
int rv;
|
||||
DBT k;
|
||||
|
||||
if (db == NULL)
|
||||
return -1;
|
||||
|
||||
k.data = __UNCONST(c);
|
||||
k.size = sizeof(*c);
|
||||
|
||||
switch (rv = (*db->del)(db, &k, 0)) {
|
||||
case 0:
|
||||
case 1:
|
||||
if (debug > 1) {
|
||||
(*lfun)(LOG_DEBUG, "%s: returns %d", __func__, rv);
|
||||
(*db->sync)(db, 0);
|
||||
}
|
||||
return 0;
|
||||
default:
|
||||
(*lfun)(LOG_ERR, "%s: failed (%m)", __func__);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
state_get(DB *db, const struct conf *c, struct dbinfo *dbi)
|
||||
{
|
||||
int rv;
|
||||
DBT k, v;
|
||||
|
||||
if (db == NULL)
|
||||
return -1;
|
||||
|
||||
k.data = __UNCONST(c);
|
||||
k.size = sizeof(*c);
|
||||
|
||||
switch (rv = (*db->get)(db, &k, &v, 0)) {
|
||||
case 0:
|
||||
case 1:
|
||||
if (rv)
|
||||
memset(dbi, 0, sizeof(*dbi));
|
||||
else
|
||||
memcpy(dbi, v.data, sizeof(*dbi));
|
||||
if (debug > 1)
|
||||
(*lfun)(LOG_DEBUG, "%s: returns %d", __func__, rv);
|
||||
return 0;
|
||||
default:
|
||||
(*lfun)(LOG_ERR, "%s: failed (%m)", __func__);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
state_put(DB *db, const struct conf *c, const struct dbinfo *dbi)
|
||||
{
|
||||
int rv;
|
||||
DBT k, v;
|
||||
|
||||
if (db == NULL)
|
||||
return -1;
|
||||
|
||||
k.data = __UNCONST(c);
|
||||
k.size = sizeof(*c);
|
||||
v.data = __UNCONST(dbi);
|
||||
v.size = sizeof(*dbi);
|
||||
|
||||
switch (rv = (*db->put)(db, &k, &v, 0)) {
|
||||
case 0:
|
||||
if (debug > 1) {
|
||||
(*lfun)(LOG_DEBUG, "%s: returns %d", __func__, rv);
|
||||
(*db->sync)(db, 0);
|
||||
}
|
||||
return 0;
|
||||
case 1:
|
||||
errno = EEXIST;
|
||||
/*FALLTHROUGH*/
|
||||
default:
|
||||
(*lfun)(LOG_ERR, "%s: failed (%m)", __func__);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
state_iterate(DB *db, struct conf *c, struct dbinfo *dbi, unsigned int first)
|
||||
{
|
||||
int rv;
|
||||
DBT k, v;
|
||||
|
||||
if (db == NULL)
|
||||
return -1;
|
||||
|
||||
first = first ? R_FIRST : R_NEXT;
|
||||
|
||||
switch (rv = (*db->seq)(db, &k, &v, first)) {
|
||||
case 0:
|
||||
if (state_sizecheck(&k) == -1)
|
||||
return -1;
|
||||
memcpy(c, k.data, sizeof(*c));
|
||||
if (debug > 2)
|
||||
dumpkey(c);
|
||||
memcpy(dbi, v.data, sizeof(*dbi));
|
||||
if (debug > 1)
|
||||
(*lfun)(LOG_DEBUG, "%s: returns %d", __func__, rv);
|
||||
return 1;
|
||||
case 1:
|
||||
if (debug > 1)
|
||||
(*lfun)(LOG_DEBUG, "%s: returns %d", __func__, rv);
|
||||
return 0;
|
||||
default:
|
||||
(*lfun)(LOG_ERR, "%s: failed (%m)", __func__);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
state_sync(DB *db)
|
||||
{
|
||||
return (*db->sync)(db, 0);
|
||||
}
|
62
20160409/bin/state.h
Normal file
62
20160409/bin/state.h
Normal file
@ -0,0 +1,62 @@
|
||||
/* $NetBSD: state.h,v 1.5 2015/01/27 19:40:37 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _STATE_H
|
||||
#define _STATE_H
|
||||
|
||||
#ifdef HAVE_DB_185_H
|
||||
#include <db_185.h>
|
||||
#elif HAVE_DB_H
|
||||
#include <db.h>
|
||||
#else
|
||||
#error "no db.h"
|
||||
#endif
|
||||
#include <time.h>
|
||||
|
||||
struct dbinfo {
|
||||
int count;
|
||||
time_t last;
|
||||
char id[64];
|
||||
};
|
||||
|
||||
__BEGIN_DECLS
|
||||
struct sockaddr_storage;
|
||||
struct conf;
|
||||
|
||||
DB *state_open(const char *, int, mode_t);
|
||||
int state_close(DB *);
|
||||
int state_get(DB *, const struct conf *, struct dbinfo *);
|
||||
int state_put(DB *, const struct conf *, const struct dbinfo *);
|
||||
int state_del(DB *, const struct conf *);
|
||||
int state_iterate(DB *, struct conf *, struct dbinfo *, unsigned int);
|
||||
int state_sync(DB *);
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _STATE_H */
|
157
20160409/bin/support.c
Normal file
157
20160409/bin/support.c
Normal file
@ -0,0 +1,157 @@
|
||||
/* $NetBSD: support.c,v 1.8 2016/04/04 15:52:56 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: support.c,v 1.8 2016/04/04 15:52:56 christos Exp $");
|
||||
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "support.h"
|
||||
|
||||
static __attribute__((__format_arg__(3))) 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;
|
||||
}
|
||||
|
||||
void
|
||||
vdlog(int level __unused, const char *fmt, va_list ap)
|
||||
{
|
||||
char buf[BUFSIZ];
|
||||
|
||||
// fprintf(stderr, "%s: ", getprogname());
|
||||
vfprintf(stderr, expandm(buf, sizeof(buf), fmt), ap);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
void
|
||||
dlog(int level, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vdlog(level, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
const char *
|
||||
fmtydhms(char *b, size_t l, time_t t)
|
||||
{
|
||||
time_t s, m, h, d, y;
|
||||
int z;
|
||||
size_t o;
|
||||
|
||||
s = t % 60;
|
||||
t /= 60;
|
||||
m = t % 60;
|
||||
t /= 60;
|
||||
h = t % 60;
|
||||
t /= 24;
|
||||
d = t % 24;
|
||||
t /= 356;
|
||||
y = t;
|
||||
|
||||
z = 0;
|
||||
o = 0;
|
||||
#define APPEND(a) \
|
||||
if (a) { \
|
||||
z = snprintf(b + o, l - o, "%jd%s", (intmax_t)a, __STRING(a)); \
|
||||
if (z == -1) \
|
||||
return b; \
|
||||
o += (size_t)z; \
|
||||
if (o >= l) \
|
||||
return b; \
|
||||
}
|
||||
APPEND(y)
|
||||
APPEND(d)
|
||||
APPEND(h)
|
||||
APPEND(m)
|
||||
APPEND(s)
|
||||
return b;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
blhexdump(char *buf, size_t len, const char *str, const void *b, size_t l)
|
||||
{
|
||||
size_t z, cz;
|
||||
int r;
|
||||
const unsigned char *p = b;
|
||||
const unsigned char *e = p + l;
|
||||
|
||||
r = snprintf(buf, len, "%s: ", str);
|
||||
if (r == -1)
|
||||
return -1;
|
||||
if ((cz = z = (size_t)r) >= len)
|
||||
cz = len;
|
||||
|
||||
while (p < e) {
|
||||
r = snprintf(buf + cz, len - cz, "%.2x", *p++);
|
||||
if (r == -1)
|
||||
return -1;
|
||||
if ((cz = (z += (size_t)r)) >= len)
|
||||
cz = len;
|
||||
}
|
||||
return (ssize_t)z;
|
||||
}
|
44
20160409/bin/support.h
Normal file
44
20160409/bin/support.h
Normal file
@ -0,0 +1,44 @@
|
||||
/* $NetBSD: support.h,v 1.7 2016/04/04 15:52:56 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _SUPPORT_H
|
||||
#define _SUPPORT_H
|
||||
|
||||
__BEGIN_DECLS
|
||||
const char *fmttime(char *, size_t, time_t);
|
||||
const char *fmtydhms(char *, size_t, time_t);
|
||||
void vdlog(int, const char *, va_list)
|
||||
__attribute__((__format__(__printf__, 2, 0)));
|
||||
void dlog(int, const char *, ...)
|
||||
__attribute__((__format__(__printf__, 2, 3)));
|
||||
ssize_t blhexdump(char *, size_t, const char *, const void *, size_t);
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _SUPPORT_H */
|
91
20160409/diff/ftpd.diff
Normal file
91
20160409/diff/ftpd.diff
Normal file
@ -0,0 +1,91 @@
|
||||
--- /dev/null 2015-01-23 17:30:40.000000000 -0500
|
||||
+++ pfilter.c 2015-01-23 17:12:02.000000000 -0500
|
||||
@@ -0,0 +1,24 @@
|
||||
+#include <stdio.h>
|
||||
+#include <blacklist.h>
|
||||
+
|
||||
+#include "pfilter.h"
|
||||
+
|
||||
+static struct blacklist *blstate;
|
||||
+
|
||||
+void
|
||||
+pfilter_open(void)
|
||||
+{
|
||||
+ if (blstate == NULL)
|
||||
+ blstate = blacklist_open();
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+pfilter_notify(int what, const char *msg)
|
||||
+{
|
||||
+ pfilter_open();
|
||||
+
|
||||
+ if (blstate == NULL)
|
||||
+ return;
|
||||
+
|
||||
+ blacklist_r(blstate, what, 0, msg);
|
||||
+}
|
||||
--- /dev/null 2015-01-23 17:30:40.000000000 -0500
|
||||
+++ pfilter.h 2015-01-23 17:07:25.000000000 -0500
|
||||
@@ -0,0 +1,2 @@
|
||||
+void pfilter_open(void);
|
||||
+void pfilter_notify(int, const char *);
|
||||
Index: Makefile
|
||||
===================================================================
|
||||
RCS file: /cvsroot/src/libexec/ftpd/Makefile,v
|
||||
retrieving revision 1.63
|
||||
diff -u -p -u -r1.63 Makefile
|
||||
--- Makefile 14 Aug 2011 11:46:28 -0000 1.63
|
||||
+++ Makefile 23 Jan 2015 22:32:20 -0000
|
||||
@@ -11,6 +11,10 @@ LDADD+= -lcrypt -lutil
|
||||
MAN= ftpd.conf.5 ftpusers.5 ftpd.8
|
||||
MLINKS= ftpusers.5 ftpchroot.5
|
||||
|
||||
+SRCS+= pfilter.c
|
||||
+LDADD+= -lblacklist
|
||||
+DPADD+= ${LIBBLACKLIST}
|
||||
+
|
||||
.if defined(NO_INTERNAL_LS)
|
||||
CPPFLAGS+=-DNO_INTERNAL_LS
|
||||
.else
|
||||
Index: ftpd.c
|
||||
===================================================================
|
||||
RCS file: /cvsroot/src/libexec/ftpd/ftpd.c,v
|
||||
retrieving revision 1.200
|
||||
diff -u -p -u -r1.200 ftpd.c
|
||||
--- ftpd.c 31 Jul 2013 19:50:47 -0000 1.200
|
||||
+++ ftpd.c 23 Jan 2015 22:32:20 -0000
|
||||
@@ -165,6 +165,8 @@ __RCSID("$NetBSD: ftpd.c,v 1.200 2013/07
|
||||
#include <security/pam_appl.h>
|
||||
#endif
|
||||
|
||||
+#include "pfilter.h"
|
||||
+
|
||||
#define GLOBAL
|
||||
#include "extern.h"
|
||||
#include "pathnames.h"
|
||||
@@ -471,6 +473,8 @@ main(int argc, char *argv[])
|
||||
if (EMPTYSTR(confdir))
|
||||
confdir = _DEFAULT_CONFDIR;
|
||||
|
||||
+ pfilter_open();
|
||||
+
|
||||
if (dowtmp) {
|
||||
#ifdef SUPPORT_UTMPX
|
||||
ftpd_initwtmpx();
|
||||
@@ -1401,6 +1405,7 @@ do_pass(int pass_checked, int pass_rval,
|
||||
if (rval) {
|
||||
reply(530, "%s", rval == 2 ? "Password expired." :
|
||||
"Login incorrect.");
|
||||
+ pfilter_notify(1, rval == 2 ? "exppass" : "badpass");
|
||||
if (logging) {
|
||||
syslog(LOG_NOTICE,
|
||||
"FTP LOGIN FAILED FROM %s", remoteloghost);
|
||||
@@ -1444,6 +1449,7 @@ do_pass(int pass_checked, int pass_rval,
|
||||
*remote_ip = 0;
|
||||
remote_ip[sizeof(remote_ip) - 1] = 0;
|
||||
if (!auth_hostok(lc, remotehost, remote_ip)) {
|
||||
+ pfilter_notify(1, "bannedhost");
|
||||
syslog(LOG_INFO|LOG_AUTH,
|
||||
"FTP LOGIN FAILED (HOST) as %s: permission denied.",
|
||||
pw->pw_name);
|
216
20160409/diff/named.diff
Normal file
216
20160409/diff/named.diff
Normal file
@ -0,0 +1,216 @@
|
||||
--- /dev/null 2015-01-22 01:48:00.000000000 -0500
|
||||
+++ dist/bin/named/pfilter.c 2015-01-22 01:35:16.000000000 -0500
|
||||
@@ -0,0 +1,42 @@
|
||||
+#include <config.h>
|
||||
+
|
||||
+#include <isc/platform.h>
|
||||
+#include <isc/util.h>
|
||||
+#include <named/types.h>
|
||||
+#include <named/client.h>
|
||||
+
|
||||
+#include <blacklist.h>
|
||||
+
|
||||
+#include "pfilter.h"
|
||||
+
|
||||
+static struct blacklist *blstate;
|
||||
+
|
||||
+void
|
||||
+pfilter_open(void)
|
||||
+{
|
||||
+ if (blstate == NULL)
|
||||
+ blstate = blacklist_open();
|
||||
+}
|
||||
+
|
||||
+#define TCP_CLIENT(c) (((c)->attributes & NS_CLIENTATTR_TCP) != 0)
|
||||
+
|
||||
+void
|
||||
+pfilter_notify(isc_result_t res, ns_client_t *client, const char *msg)
|
||||
+{
|
||||
+ isc_socket_t *socket;
|
||||
+
|
||||
+ pfilter_open();
|
||||
+
|
||||
+ if (TCP_CLIENT(client))
|
||||
+ socket = client->tcpsocket;
|
||||
+ else {
|
||||
+ socket = client->udpsocket;
|
||||
+ if (!client->peeraddr_valid)
|
||||
+ return;
|
||||
+ }
|
||||
+ if (socket == NULL)
|
||||
+ return;
|
||||
+ blacklist_sa_r(blstate,
|
||||
+ res != ISC_R_SUCCESS, isc_socket_getfd(socket),
|
||||
+ &client->peeraddr.type.sa, client->peeraddr.length, msg);
|
||||
+}
|
||||
--- /dev/null 2015-01-22 01:48:00.000000000 -0500
|
||||
+++ dist/bin/named/pfilter.h 2015-01-22 01:16:56.000000000 -0500
|
||||
@@ -0,0 +1,2 @@
|
||||
+void pfilter_open(void);
|
||||
+void pfilter_notify(isc_result_t, ns_client_t *, const char *);
|
||||
Index: bin/named/Makefile
|
||||
===================================================================
|
||||
RCS file: /cvsroot/src/external/bsd/bind/bin/named/Makefile,v
|
||||
retrieving revision 1.8
|
||||
diff -u -u -r1.8 Makefile
|
||||
--- bin/named/Makefile 31 Dec 2013 20:23:12 -0000 1.8
|
||||
+++ bin/named/Makefile 23 Jan 2015 21:37:09 -0000
|
||||
@@ -33,7 +33,9 @@
|
||||
lwaddr.c lwdclient.c lwderror.c \
|
||||
lwdgabn.c lwdgnba.c lwdgrbn.c lwdnoop.c lwresd.c lwsearch.c \
|
||||
main.c notify.c query.c server.c sortlist.c statschannel.c \
|
||||
- tkeyconf.c tsigconf.c \
|
||||
+ pfilter.c tkeyconf.c tsigconf.c \
|
||||
update.c xfrout.c zoneconf.c ${SRCS_UNIX}
|
||||
|
||||
+LDADD+=-lblacklist
|
||||
+DPADD+=${LIBBLACKLIST}
|
||||
.include <bsd.prog.mk>
|
||||
Index: dist/bin/named/client.c
|
||||
===================================================================
|
||||
RCS file: /cvsroot/src/external/bsd/bind/dist/bin/named/client.c,v
|
||||
retrieving revision 1.11
|
||||
diff -u -u -r1.11 client.c
|
||||
--- dist/bin/named/client.c 10 Dec 2014 04:37:51 -0000 1.11
|
||||
+++ dist/bin/named/client.c 23 Jan 2015 21:37:09 -0000
|
||||
@@ -65,6 +65,8 @@
|
||||
#include <named/server.h>
|
||||
#include <named/update.h>
|
||||
|
||||
+#include "pfilter.h"
|
||||
+
|
||||
/***
|
||||
*** Client
|
||||
***/
|
||||
@@ -3101,6 +3103,7 @@
|
||||
result = ns_client_checkaclsilent(client, sockaddr ? &netaddr : NULL,
|
||||
acl, default_allow);
|
||||
|
||||
+ pfilter_notify(result, client, opname);
|
||||
if (result == ISC_R_SUCCESS)
|
||||
ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
|
||||
NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3),
|
||||
Index: dist/bin/named/main.c
|
||||
===================================================================
|
||||
RCS file: /cvsroot/src/external/bsd/bind/dist/bin/named/main.c,v
|
||||
retrieving revision 1.15
|
||||
diff -u -u -r1.15 main.c
|
||||
--- dist/bin/named/main.c 10 Dec 2014 04:37:51 -0000 1.15
|
||||
+++ dist/bin/named/main.c 23 Jan 2015 21:37:09 -0000
|
||||
@@ -83,6 +83,9 @@
|
||||
#ifdef HAVE_LIBXML2
|
||||
#include <libxml/xmlversion.h>
|
||||
#endif
|
||||
+
|
||||
+#include "pfilter.h"
|
||||
+
|
||||
/*
|
||||
* Include header files for database drivers here.
|
||||
*/
|
||||
@@ -1206,6 +1209,8 @@
|
||||
|
||||
parse_command_line(argc, argv);
|
||||
|
||||
+ pfilter_open();
|
||||
+
|
||||
/*
|
||||
* Warn about common configuration error.
|
||||
*/
|
||||
Index: dist/bin/named/query.c
|
||||
===================================================================
|
||||
RCS file: /cvsroot/src/external/bsd/bind/dist/bin/named/query.c,v
|
||||
retrieving revision 1.17
|
||||
diff -u -u -r1.17 query.c
|
||||
--- dist/bin/named/query.c 10 Dec 2014 04:37:52 -0000 1.17
|
||||
+++ dist/bin/named/query.c 23 Jan 2015 21:37:09 -0000
|
||||
@@ -65,6 +65,8 @@
|
||||
#include <named/sortlist.h>
|
||||
#include <named/xfrout.h>
|
||||
|
||||
+#include "pfilter.h"
|
||||
+
|
||||
#if 0
|
||||
/*
|
||||
* It has been recommended that DNS64 be changed to return excluded
|
||||
@@ -762,6 +764,8 @@
|
||||
}
|
||||
|
||||
result = ns_client_checkaclsilent(client, NULL, queryacl, ISC_TRUE);
|
||||
+ if (result != ISC_R_SUCCESS)
|
||||
+ pfilter_notify(result, client, "validatezonedb");
|
||||
if ((options & DNS_GETDB_NOLOG) == 0) {
|
||||
char msg[NS_CLIENT_ACLMSGSIZE("query")];
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
@@ -1026,6 +1030,8 @@
|
||||
result = ns_client_checkaclsilent(client, NULL,
|
||||
client->view->cacheacl,
|
||||
ISC_TRUE);
|
||||
+ if (result == ISC_R_SUCCESS)
|
||||
+ pfilter_notify(result, client, "cachedb");
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
/*
|
||||
* We were allowed by the "allow-query-cache" ACL.
|
||||
Index: dist/bin/named/update.c
|
||||
===================================================================
|
||||
RCS file: /cvsroot/src/external/bsd/bind/dist/bin/named/update.c,v
|
||||
retrieving revision 1.9
|
||||
diff -u -u -r1.9 update.c
|
||||
--- dist/bin/named/update.c 10 Dec 2014 04:37:52 -0000 1.9
|
||||
+++ dist/bin/named/update.c 23 Jan 2015 21:37:09 -0000
|
||||
@@ -59,6 +59,8 @@
|
||||
#include <named/server.h>
|
||||
#include <named/update.h>
|
||||
|
||||
+#include "pfilter.h"
|
||||
+
|
||||
/*! \file
|
||||
* \brief
|
||||
* This module implements dynamic update as in RFC2136.
|
||||
@@ -307,6 +309,7 @@
|
||||
|
||||
result = ns_client_checkaclsilent(client, NULL, queryacl, ISC_TRUE);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
+ pfilter_notify(result, client, "queryacl");
|
||||
dns_name_format(zonename, namebuf, sizeof(namebuf));
|
||||
dns_rdataclass_format(client->view->rdclass, classbuf,
|
||||
sizeof(classbuf));
|
||||
@@ -324,6 +327,7 @@
|
||||
sizeof(classbuf));
|
||||
|
||||
result = DNS_R_REFUSED;
|
||||
+ pfilter_notify(result, client, "updateacl");
|
||||
ns_client_log(client, NS_LOGCATEGORY_UPDATE_SECURITY,
|
||||
NS_LOGMODULE_UPDATE, ISC_LOG_INFO,
|
||||
"update '%s/%s' denied", namebuf, classbuf);
|
||||
@@ -362,6 +366,7 @@
|
||||
msg = "disabled";
|
||||
} else {
|
||||
result = ns_client_checkaclsilent(client, NULL, acl, ISC_FALSE);
|
||||
+ pfilter_notify(result, client, "updateacl");
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
level = ISC_LOG_DEBUG(3);
|
||||
msg = "approved";
|
||||
Index: dist/bin/named/xfrout.c
|
||||
===================================================================
|
||||
RCS file: /cvsroot/src/external/bsd/bind/dist/bin/named/xfrout.c,v
|
||||
retrieving revision 1.7
|
||||
diff -u -u -r1.7 xfrout.c
|
||||
--- dist/bin/named/xfrout.c 10 Dec 2014 04:37:52 -0000 1.7
|
||||
+++ dist/bin/named/xfrout.c 23 Jan 2015 21:37:09 -0000
|
||||
@@ -54,6 +54,8 @@
|
||||
#include <named/server.h>
|
||||
#include <named/xfrout.h>
|
||||
|
||||
+#include "pfilter.h"
|
||||
+
|
||||
/*! \file
|
||||
* \brief
|
||||
* Outgoing AXFR and IXFR.
|
||||
@@ -822,6 +824,7 @@
|
||||
&client->peeraddr,
|
||||
&db);
|
||||
|
||||
+ pfilter_notify(result, client, "zonexfr");
|
||||
if (result == ISC_R_NOPERM) {
|
||||
char _buf1[DNS_NAME_FORMATSIZE];
|
||||
char _buf2[DNS_RDATACLASS_FORMATSIZE];
|
124
20160409/diff/proftpd.diff
Normal file
124
20160409/diff/proftpd.diff
Normal file
@ -0,0 +1,124 @@
|
||||
--- Make.rules.in.orig 2015-05-27 20:25:54.000000000 -0400
|
||||
+++ Make.rules.in 2016-01-25 21:48:47.000000000 -0500
|
||||
@@ -110,3 +110,8 @@
|
||||
|
||||
FTPWHO_OBJS=ftpwho.o scoreboard.o misc.o
|
||||
BUILD_FTPWHO_OBJS=utils/ftpwho.o utils/scoreboard.o utils/misc.o
|
||||
+
|
||||
+CPPFLAGS+=-DHAVE_BLACKLIST
|
||||
+LIBS+=-lblacklist
|
||||
+OBJS+= pfilter.o
|
||||
+BUILD_OBJS+= src/pfilter.o
|
||||
--- /dev/null 2016-01-22 17:30:55.000000000 -0500
|
||||
+++ include/pfilter.h 2016-01-22 16:18:33.000000000 -0500
|
||||
@@ -0,0 +1,3 @@
|
||||
+
|
||||
+void pfilter_notify(int);
|
||||
+void pfilter_init(void);
|
||||
--- modules/mod_auth.c.orig 2015-05-27 20:25:54.000000000 -0400
|
||||
+++ modules/mod_auth.c 2016-01-22 16:21:06.000000000 -0500
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
#include "conf.h"
|
||||
#include "privs.h"
|
||||
+#include "pfilter.h"
|
||||
|
||||
extern pid_t mpid;
|
||||
|
||||
@@ -84,6 +85,8 @@
|
||||
_("Login timeout (%d %s): closing control connection"), TimeoutLogin,
|
||||
TimeoutLogin != 1 ? "seconds" : "second");
|
||||
|
||||
+ pfilter_notify(1);
|
||||
+
|
||||
/* It's possible that any listeners of this event might terminate the
|
||||
* session process themselves (e.g. mod_ban). So write out that the
|
||||
* TimeoutLogin has been exceeded to the log here, in addition to the
|
||||
@@ -913,6 +916,7 @@
|
||||
pr_memscrub(pass, strlen(pass));
|
||||
}
|
||||
|
||||
+ pfilter_notify(1);
|
||||
pr_log_auth(PR_LOG_NOTICE, "SECURITY VIOLATION: Root login attempted");
|
||||
return 0;
|
||||
}
|
||||
@@ -1726,6 +1730,7 @@
|
||||
return 1;
|
||||
|
||||
auth_failure:
|
||||
+ pfilter_notify(1);
|
||||
if (pass)
|
||||
pr_memscrub(pass, strlen(pass));
|
||||
session.user = session.group = NULL;
|
||||
--- src/main.c.orig 2016-01-22 17:36:43.000000000 -0500
|
||||
+++ src/main.c 2016-01-22 17:37:58.000000000 -0500
|
||||
@@ -49,6 +49,7 @@
|
||||
#endif
|
||||
|
||||
#include "privs.h"
|
||||
+#include "pfilter.h"
|
||||
|
||||
int (*cmd_auth_chk)(cmd_rec *);
|
||||
void (*cmd_handler)(server_rec *, conn_t *);
|
||||
@@ -1050,6 +1051,7 @@
|
||||
pid_t pid;
|
||||
sigset_t sig_set;
|
||||
|
||||
+ pfilter_init();
|
||||
if (!nofork) {
|
||||
|
||||
/* A race condition exists on heavily loaded servers where the parent
|
||||
@@ -1169,7 +1171,8 @@
|
||||
|
||||
/* Reseed pseudo-randoms */
|
||||
srand((unsigned int) (time(NULL) * getpid()));
|
||||
-
|
||||
+#else
|
||||
+ pfilter_init();
|
||||
#endif /* PR_DEVEL_NO_FORK */
|
||||
|
||||
/* Child is running here */
|
||||
--- /dev/null 2016-01-22 17:30:55.000000000 -0500
|
||||
+++ src/pfilter.c 2016-01-22 16:37:55.000000000 -0500
|
||||
@@ -0,0 +1,41 @@
|
||||
+#include "pfilter.h"
|
||||
+#include "conf.h"
|
||||
+#include "privs.h"
|
||||
+#ifdef HAVE_BLACKLIST
|
||||
+#include <blacklist.h>
|
||||
+#endif
|
||||
+
|
||||
+static struct blacklist *blstate;
|
||||
+
|
||||
+void
|
||||
+pfilter_init(void)
|
||||
+{
|
||||
+#ifdef HAVE_BLACKLIST
|
||||
+ if (blstate == NULL)
|
||||
+ blstate = blacklist_open();
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+pfilter_notify(int a)
|
||||
+{
|
||||
+#ifdef HAVE_BLACKLIST
|
||||
+ conn_t *c = session.c;
|
||||
+ int fd;
|
||||
+
|
||||
+ if (c == NULL)
|
||||
+ return;
|
||||
+ if (c->rfd != -1)
|
||||
+ fd = c->rfd;
|
||||
+ else if (c->wfd != -1)
|
||||
+ fd = c->wfd;
|
||||
+ else
|
||||
+ return;
|
||||
+
|
||||
+ if (blstate == NULL)
|
||||
+ pfilter_init();
|
||||
+ if (blstate == NULL)
|
||||
+ return;
|
||||
+ (void)blacklist_r(blstate, a, fd, "proftpd");
|
||||
+#endif
|
||||
+}
|
231
20160409/diff/ssh.diff
Normal file
231
20160409/diff/ssh.diff
Normal file
@ -0,0 +1,231 @@
|
||||
--- /dev/null 2015-01-22 23:10:33.000000000 -0500
|
||||
+++ dist/pfilter.c 2015-01-22 23:46:03.000000000 -0500
|
||||
@@ -0,0 +1,28 @@
|
||||
+#include "namespace.h"
|
||||
+#include "includes.h"
|
||||
+#include "ssh.h"
|
||||
+#include "packet.h"
|
||||
+#include "log.h"
|
||||
+#include "pfilter.h"
|
||||
+#include <blacklist.h>
|
||||
+
|
||||
+static struct blacklist *blstate;
|
||||
+
|
||||
+void
|
||||
+pfilter_init(void)
|
||||
+{
|
||||
+ blstate = blacklist_open();
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+pfilter_notify(int a)
|
||||
+{
|
||||
+ int fd;
|
||||
+ if (blstate == NULL)
|
||||
+ pfilter_init();
|
||||
+ if (blstate == NULL)
|
||||
+ return;
|
||||
+ // XXX: 3?
|
||||
+ fd = packet_connection_is_on_socket() ? packet_get_connection_in() : 3;
|
||||
+ (void)blacklist_r(blstate, a, fd, "ssh");
|
||||
+}
|
||||
--- /dev/null 2015-01-20 21:14:44.000000000 -0500
|
||||
+++ dist/pfilter.h 2015-01-20 20:16:20.000000000 -0500
|
||||
@@ -0,0 +1,3 @@
|
||||
+
|
||||
+void pfilter_notify(int);
|
||||
+void pfilter_init(void);
|
||||
Index: bin/sshd/Makefile
|
||||
===================================================================
|
||||
RCS file: /cvsroot/src/crypto/external/bsd/openssh/bin/sshd/Makefile,v
|
||||
retrieving revision 1.10
|
||||
diff -u -u -r1.10 Makefile
|
||||
--- bin/sshd/Makefile 19 Oct 2014 16:30:58 -0000 1.10
|
||||
+++ bin/sshd/Makefile 22 Jan 2015 21:39:21 -0000
|
||||
@@ -15,7 +15,7 @@
|
||||
auth2-none.c auth2-passwd.c auth2-pubkey.c \
|
||||
monitor_mm.c monitor.c monitor_wrap.c \
|
||||
kexdhs.c kexgexs.c kexecdhs.c sftp-server.c sftp-common.c \
|
||||
- roaming_common.c roaming_serv.c sandbox-rlimit.c
|
||||
+ roaming_common.c roaming_serv.c sandbox-rlimit.c pfilter.c
|
||||
|
||||
COPTS.auth-options.c= -Wno-pointer-sign
|
||||
COPTS.ldapauth.c= -Wno-format-nonliteral # XXX: should fix
|
||||
@@ -68,3 +68,6 @@
|
||||
|
||||
LDADD+= -lwrap
|
||||
DPADD+= ${LIBWRAP}
|
||||
+
|
||||
+LDADD+= -lblacklist
|
||||
+DPADD+= ${LIBBLACKLIST}
|
||||
Index: dist/auth.c
|
||||
===================================================================
|
||||
RCS file: /cvsroot/src/crypto/external/bsd/openssh/dist/auth.c,v
|
||||
retrieving revision 1.10
|
||||
diff -u -u -r1.10 auth.c
|
||||
--- dist/auth.c 19 Oct 2014 16:30:58 -0000 1.10
|
||||
+++ dist/auth.c 22 Jan 2015 21:39:22 -0000
|
||||
@@ -62,6 +62,7 @@
|
||||
#include "monitor_wrap.h"
|
||||
#include "krl.h"
|
||||
#include "compat.h"
|
||||
+#include "pfilter.h"
|
||||
|
||||
#ifdef HAVE_LOGIN_CAP
|
||||
#include <login_cap.h>
|
||||
@@ -362,6 +363,8 @@
|
||||
compat20 ? "ssh2" : "ssh1",
|
||||
authctxt->info != NULL ? ": " : "",
|
||||
authctxt->info != NULL ? authctxt->info : "");
|
||||
+ if (!authctxt->postponed)
|
||||
+ pfilter_notify(!authenticated);
|
||||
free(authctxt->info);
|
||||
authctxt->info = NULL;
|
||||
}
|
||||
Index: dist/sshd.c
|
||||
===================================================================
|
||||
RCS file: /cvsroot/src/crypto/external/bsd/openssh/dist/sshd.c,v
|
||||
retrieving revision 1.15
|
||||
diff -u -u -r1.15 sshd.c
|
||||
--- dist/sshd.c 28 Oct 2014 21:36:16 -0000 1.15
|
||||
+++ dist/sshd.c 22 Jan 2015 21:39:22 -0000
|
||||
@@ -109,6 +109,7 @@
|
||||
#include "roaming.h"
|
||||
#include "ssh-sandbox.h"
|
||||
#include "version.h"
|
||||
+#include "pfilter.h"
|
||||
|
||||
#ifdef LIBWRAP
|
||||
#include <tcpd.h>
|
||||
@@ -364,6 +365,7 @@
|
||||
killpg(0, SIGTERM);
|
||||
}
|
||||
|
||||
+ pfilter_notify(1);
|
||||
/* Log error and exit. */
|
||||
sigdie("Timeout before authentication for %s", get_remote_ipaddr());
|
||||
}
|
||||
@@ -1160,6 +1162,7 @@
|
||||
for (i = 0; i < options.max_startups; i++)
|
||||
startup_pipes[i] = -1;
|
||||
|
||||
+ pfilter_init();
|
||||
/*
|
||||
* Stay listening for connections until the system crashes or
|
||||
* the daemon is killed with a signal.
|
||||
Index: auth1.c
|
||||
===================================================================
|
||||
RCS file: /cvsroot/src/crypto/external/bsd/openssh/dist/auth1.c,v
|
||||
retrieving revision 1.9
|
||||
diff -u -u -r1.9 auth1.c
|
||||
--- auth1.c 19 Oct 2014 16:30:58 -0000 1.9
|
||||
+++ auth1.c 14 Feb 2015 15:40:51 -0000
|
||||
@@ -41,6 +41,7 @@
|
||||
#endif
|
||||
#include "monitor_wrap.h"
|
||||
#include "buffer.h"
|
||||
+#include "pfilter.h"
|
||||
|
||||
/* import */
|
||||
extern ServerOptions options;
|
||||
@@ -445,6 +446,7 @@
|
||||
else {
|
||||
debug("do_authentication: invalid user %s", user);
|
||||
authctxt->pw = fakepw();
|
||||
+ pfilter_notify(1);
|
||||
}
|
||||
|
||||
/* Configuration may have changed as a result of Match */
|
||||
Index: auth2.c
|
||||
===================================================================
|
||||
RCS file: /cvsroot/src/crypto/external/bsd/openssh/dist/auth2.c,v
|
||||
retrieving revision 1.9
|
||||
diff -u -u -r1.9 auth2.c
|
||||
--- auth2.c 19 Oct 2014 16:30:58 -0000 1.9
|
||||
+++ auth2.c 14 Feb 2015 15:40:51 -0000
|
||||
@@ -52,6 +52,7 @@
|
||||
#include "pathnames.h"
|
||||
#include "buffer.h"
|
||||
#include "canohost.h"
|
||||
+#include "pfilter.h"
|
||||
|
||||
#ifdef GSSAPI
|
||||
#include "ssh-gss.h"
|
||||
@@ -256,6 +257,7 @@
|
||||
} else {
|
||||
logit("input_userauth_request: invalid user %s", user);
|
||||
authctxt->pw = fakepw();
|
||||
+ pfilter_notify(1);
|
||||
}
|
||||
#ifdef USE_PAM
|
||||
if (options.use_pam)
|
||||
Index: sshd.c
|
||||
===================================================================
|
||||
RCS file: /cvsroot/src/crypto/external/bsd/openssh/dist/sshd.c,v
|
||||
retrieving revision 1.16
|
||||
diff -u -r1.16 sshd.c
|
||||
--- sshd.c 25 Jan 2015 15:52:44 -0000 1.16
|
||||
+++ sshd.c 14 Feb 2015 09:55:06 -0000
|
||||
@@ -628,6 +628,8 @@
|
||||
explicit_bzero(pw->pw_passwd, strlen(pw->pw_passwd));
|
||||
endpwent();
|
||||
|
||||
+ pfilter_init();
|
||||
+
|
||||
/* Change our root directory */
|
||||
if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1)
|
||||
fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR,
|
||||
|
||||
Index: auth-pam.c
|
||||
===================================================================
|
||||
RCS file: /cvsroot/src/crypto/external/bsd/openssh/dist/auth-pam.c,v
|
||||
retrieving revision 1.7
|
||||
diff -u -u -r1.7 auth-pam.c
|
||||
--- auth-pam.c 3 Jul 2015 00:59:59 -0000 1.7
|
||||
+++ auth-pam.c 23 Jan 2016 00:01:16 -0000
|
||||
@@ -114,6 +114,7 @@
|
||||
#include "ssh-gss.h"
|
||||
#endif
|
||||
#include "monitor_wrap.h"
|
||||
+#include "pfilter.h"
|
||||
|
||||
extern ServerOptions options;
|
||||
extern Buffer loginmsg;
|
||||
@@ -809,6 +810,7 @@
|
||||
free(msg);
|
||||
return (0);
|
||||
}
|
||||
+ pfilter_notify(1);
|
||||
error("PAM: %s for %s%.100s from %.100s", msg,
|
||||
sshpam_authctxt->valid ? "" : "illegal user ",
|
||||
sshpam_authctxt->user,
|
||||
Index: auth.c
|
||||
===================================================================
|
||||
RCS file: /cvsroot/src/crypto/external/bsd/openssh/dist/auth.c,v
|
||||
retrieving revision 1.15
|
||||
diff -u -u -r1.15 auth.c
|
||||
--- auth.c 21 Aug 2015 08:20:59 -0000 1.15
|
||||
+++ auth.c 23 Jan 2016 00:01:16 -0000
|
||||
@@ -656,6 +656,7 @@
|
||||
|
||||
pw = getpwnam(user);
|
||||
if (pw == NULL) {
|
||||
+ pfilter_notify(1);
|
||||
logit("Invalid user %.100s from %.100s",
|
||||
user, get_remote_ipaddr());
|
||||
return (NULL);
|
||||
Index: auth1.c
|
||||
===================================================================
|
||||
RCS file: /cvsroot/src/crypto/external/bsd/openssh/dist/auth1.c,v
|
||||
retrieving revision 1.12
|
||||
diff -u -u -r1.12 auth1.c
|
||||
--- auth1.c 3 Jul 2015 00:59:59 -0000 1.12
|
||||
+++ auth1.c 23 Jan 2016 00:01:16 -0000
|
||||
@@ -376,6 +376,7 @@
|
||||
char *msg;
|
||||
size_t len;
|
||||
|
||||
+ pfilter_notify(1);
|
||||
error("Access denied for user %s by PAM account "
|
||||
"configuration", authctxt->user);
|
||||
len = buffer_len(&loginmsg);
|
10
20160409/etc/Makefile
Normal file
10
20160409/etc/Makefile
Normal file
@ -0,0 +1,10 @@
|
||||
# $NetBSD: Makefile,v 1.3 2015/01/26 00:18:40 christos Exp $
|
||||
|
||||
SUBDIR=rc.d
|
||||
|
||||
FILESDIR= /usr/share/examples/blacklist
|
||||
FILESMODE= 644
|
||||
FILES= blacklistd.conf npf.conf
|
||||
|
||||
.include <bsd.files.mk>
|
||||
.include <bsd.subdir.mk>
|
14
20160409/etc/blacklistd.conf
Normal file
14
20160409/etc/blacklistd.conf
Normal file
@ -0,0 +1,14 @@
|
||||
# Blacklist rule
|
||||
# adr/mask:port type proto owner name nfail disable
|
||||
[local]
|
||||
ssh stream * * * 3 6h
|
||||
ftp stream * * * 3 6h
|
||||
domain * * named * 3 12h
|
||||
#6161 stream tcp6 christos * 2 10m
|
||||
* * * * * 3 60
|
||||
|
||||
# adr/mask:port type proto owner name nfail disable
|
||||
[remote]
|
||||
#129.168.0.0/16 * * * = * *
|
||||
#6161 = = = =/24 = =
|
||||
#* stream tcp * = = =
|
15
20160409/etc/npf.conf
Normal file
15
20160409/etc/npf.conf
Normal file
@ -0,0 +1,15 @@
|
||||
# Transparent firewall example for blacklistd
|
||||
|
||||
$ext_if = "bnx0"
|
||||
|
||||
set bpf.jit on;
|
||||
alg "icmp"
|
||||
|
||||
group "external" on $ext_if {
|
||||
ruleset "blacklistd"
|
||||
pass final all
|
||||
}
|
||||
|
||||
group default {
|
||||
pass final all
|
||||
}
|
6
20160409/etc/rc.d/Makefile
Normal file
6
20160409/etc/rc.d/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
# $NetBSD: Makefile,v 1.1 2015/01/22 17:49:41 christos Exp $
|
||||
|
||||
SCRIPTS=blacklistd
|
||||
SCRIPTSDIR=/etc/rc.d
|
||||
|
||||
.include <bsd.prog.mk>
|
57
20160409/etc/rc.d/blacklistd
Normal file
57
20160409/etc/rc.d/blacklistd
Normal file
@ -0,0 +1,57 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# $NetBSD: blacklistd,v 1.1 2015/01/22 17:49:41 christos Exp $
|
||||
#
|
||||
|
||||
# PROVIDE: blacklistd
|
||||
# REQUIRE: npf
|
||||
# BEFORE: SERVERS
|
||||
|
||||
$_rc_subr_loaded . /etc/rc.subr
|
||||
|
||||
name="blacklistd"
|
||||
rcvar=$name
|
||||
command="/sbin/${name}"
|
||||
pidfile="/var/run/${name}.pid"
|
||||
required_files="/etc/${name}.conf"
|
||||
start_precmd="${name}_precmd"
|
||||
extra_commands="reload"
|
||||
|
||||
_sockfile="/var/run/${name}.sockets"
|
||||
_sockname="blsock"
|
||||
|
||||
blacklistd_precmd()
|
||||
{
|
||||
# Create default list of blacklistd sockets to watch
|
||||
#
|
||||
( umask 022 ; > $_sockfile )
|
||||
|
||||
# Find /etc/rc.d scripts with "chrootdir" rcorder(8) keyword,
|
||||
# and if $${app}_chrootdir is a directory, add appropriate
|
||||
# blacklistd socket to list of sockets to watch.
|
||||
#
|
||||
for _lr in $(rcorder -k chrootdir /etc/rc.d/*); do
|
||||
(
|
||||
_l=${_lr##*/}
|
||||
load_rc_config ${_l}
|
||||
eval _ldir=\$${_l}_chrootdir
|
||||
if checkyesno $_l && [ -n "$_ldir" ]; then
|
||||
echo "${_ldir}/var/run/${_sockname}" >> $_sockfile
|
||||
fi
|
||||
)
|
||||
done
|
||||
|
||||
# If other sockets have been provided, change run_rc_command()'s
|
||||
# internal copy of $blacklistd_flags to force use of specific
|
||||
# blacklistd sockets.
|
||||
#
|
||||
if [ -s $_sockfile ]; then
|
||||
echo "/var/run/${_sockname}" >> $_sockfile
|
||||
rc_flags="-P $_sockfile $rc_flags"
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
load_rc_config $name
|
||||
run_rc_command "$1"
|
10
20160409/include/Makefile
Normal file
10
20160409/include/Makefile
Normal 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>
|
76
20160409/include/bl.h
Normal file
76
20160409/include/bl.h
Normal file
@ -0,0 +1,76 @@
|
||||
/* $NetBSD: bl.h,v 1.13 2016/03/11 17:16:40 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 _BL_H
|
||||
#define _BL_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include "blacklist.h"
|
||||
|
||||
typedef enum {
|
||||
BL_INVALID,
|
||||
BL_ADD,
|
||||
BL_DELETE
|
||||
} bl_type_t;
|
||||
|
||||
typedef struct {
|
||||
bl_type_t bi_type;
|
||||
int bi_fd;
|
||||
uid_t bi_uid;
|
||||
gid_t bi_gid;
|
||||
socklen_t bi_slen;
|
||||
struct sockaddr_storage bi_ss;
|
||||
char bi_msg[1024];
|
||||
} bl_info_t;
|
||||
|
||||
#define bi_cred bi_u._bi_cred
|
||||
|
||||
#ifndef _PATH_BLSOCK
|
||||
#define _PATH_BLSOCK "/var/run/blacklistd.sock"
|
||||
#endif
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
typedef struct blacklist *bl_t;
|
||||
|
||||
bl_t bl_create(bool, const char *, void (*)(int, const char *, va_list));
|
||||
void bl_destroy(bl_t);
|
||||
int bl_send(bl_t, bl_type_t, int, const struct sockaddr *, socklen_t,
|
||||
const char *);
|
||||
int bl_getfd(bl_t);
|
||||
bl_info_t *bl_recv(bl_t);
|
||||
bool bl_isconnected(bl_t);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _BL_H */
|
46
20160409/include/blacklist.h
Normal file
46
20160409/include/blacklist.h
Normal file
@ -0,0 +1,46 @@
|
||||
/* $NetBSD: blacklist.h,v 1.3 2015/01/23 18:48:56 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2014 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _BLACKLIST_H
|
||||
#define _BLACKLIST_H
|
||||
|
||||
#include <sys/socket.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
struct blacklist *blacklist_open(void);
|
||||
void blacklist_close(struct blacklist *);
|
||||
int blacklist(int, int, const char *);
|
||||
int blacklist_r(struct blacklist *, int, int, const char *);
|
||||
int blacklist_sa(int, int, const struct sockaddr *, socklen_t, const char *);
|
||||
int blacklist_sa_r(struct blacklist *, int, int,
|
||||
const struct sockaddr *, socklen_t, const char *);
|
||||
__END_DECLS
|
||||
|
||||
#endif /* _BLACKLIST_H */
|
19
20160409/lib/Makefile
Normal file
19
20160409/lib/Makefile
Normal file
@ -0,0 +1,19 @@
|
||||
# $NetBSD: Makefile,v 1.6 2016/01/05 13:07:46 christos Exp $
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
USE_SHLIBDIR= yes
|
||||
|
||||
CPPFLAGS+=-D_REENTRANT
|
||||
LIBDPLIBS+=pthread ${NETBSDSRCDIR}/lib/libpthread
|
||||
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
|
||||
MLINKS+=libblacklist.3 blacklist_sa.3
|
||||
MLINKS+=libblacklist.3 blacklist_sa_r.3
|
||||
|
||||
.include <bsd.lib.mk>
|
524
20160409/lib/bl.c
Normal file
524
20160409/lib/bl.c
Normal file
@ -0,0 +1,524 @@
|
||||
/* $NetBSD: bl.c,v 1.27 2015/12/30 16:42:48 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2014 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: bl.c,v 1.27 2015/12/30 16:42:48 christos Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <netinet/in.h>
|
||||
#ifdef _REENTRANT
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include "bl.h"
|
||||
|
||||
typedef struct {
|
||||
uint32_t bl_len;
|
||||
uint32_t bl_version;
|
||||
uint32_t bl_type;
|
||||
uint32_t bl_salen;
|
||||
struct sockaddr_storage bl_ss;
|
||||
char bl_data[];
|
||||
} bl_message_t;
|
||||
|
||||
struct blacklist {
|
||||
#ifdef _REENTRANT
|
||||
pthread_mutex_t b_mutex;
|
||||
# define BL_INIT(b) pthread_mutex_init(&b->b_mutex, NULL)
|
||||
# define BL_LOCK(b) pthread_mutex_lock(&b->b_mutex)
|
||||
# define BL_UNLOCK(b) pthread_mutex_unlock(&b->b_mutex)
|
||||
#else
|
||||
# define BL_INIT(b) do {} while(/*CONSTCOND*/0)
|
||||
# define BL_LOCK(b) BL_INIT(b)
|
||||
# define BL_UNLOCK(b) BL_INIT(b)
|
||||
#endif
|
||||
int b_fd;
|
||||
int b_connected;
|
||||
struct sockaddr_un b_sun;
|
||||
void (*b_fun)(int, const char *, va_list);
|
||||
bl_info_t b_info;
|
||||
};
|
||||
|
||||
#define BL_VERSION 1
|
||||
|
||||
bool
|
||||
bl_isconnected(bl_t b)
|
||||
{
|
||||
return b->b_connected == 0;
|
||||
}
|
||||
|
||||
int
|
||||
bl_getfd(bl_t b)
|
||||
{
|
||||
return b->b_fd;
|
||||
}
|
||||
|
||||
static void
|
||||
bl_reset(bl_t b, bool locked)
|
||||
{
|
||||
int serrno = errno;
|
||||
if (!locked)
|
||||
BL_LOCK(b);
|
||||
close(b->b_fd);
|
||||
errno = serrno;
|
||||
b->b_fd = -1;
|
||||
b->b_connected = -1;
|
||||
if (!locked)
|
||||
BL_UNLOCK(b);
|
||||
}
|
||||
|
||||
static void
|
||||
bl_log(void (*fun)(int, const char *, va_list), int level,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int serrno = errno;
|
||||
|
||||
va_start(ap, fmt);
|
||||
(*fun)(level, fmt, ap);
|
||||
va_end(ap);
|
||||
errno = serrno;
|
||||
}
|
||||
|
||||
static int
|
||||
bl_init(bl_t b, bool srv)
|
||||
{
|
||||
static int one = 1;
|
||||
/* AF_UNIX address of local logger */
|
||||
mode_t om;
|
||||
int rv, serrno;
|
||||
struct sockaddr_un *sun = &b->b_sun;
|
||||
|
||||
#ifndef SOCK_NONBLOCK
|
||||
#define SOCK_NONBLOCK 0
|
||||
#endif
|
||||
#ifndef SOCK_CLOEXEC
|
||||
#define SOCK_CLOEXEC 0
|
||||
#endif
|
||||
#ifndef SOCK_NOSIGPIPE
|
||||
#define SOCK_NOSIGPIPE 0
|
||||
#endif
|
||||
|
||||
BL_LOCK(b);
|
||||
|
||||
if (b->b_fd == -1) {
|
||||
b->b_fd = socket(PF_LOCAL,
|
||||
SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK|SOCK_NOSIGPIPE, 0);
|
||||
if (b->b_fd == -1) {
|
||||
bl_log(b->b_fun, LOG_ERR, "%s: socket failed (%m)",
|
||||
__func__);
|
||||
BL_UNLOCK(b);
|
||||
return -1;
|
||||
}
|
||||
#if SOCK_CLOEXEC == 0
|
||||
fcntl(b->b_fd, F_SETFD, FD_CLOEXEC);
|
||||
#endif
|
||||
#if SOCK_NONBLOCK == 0
|
||||
fcntl(b->b_fd, F_SETFL, fcntl(b->b_fd, F_GETFL) | O_NONBLOCK);
|
||||
#endif
|
||||
#if SOCK_NOSIGPIPE == 0
|
||||
#ifdef SO_NOSIGPIPE
|
||||
int o = 1;
|
||||
setsockopt(b->b_fd, SOL_SOCKET, SO_NOSIGPIPE, &o, sizeof(o));
|
||||
#else
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
if (bl_isconnected(b)) {
|
||||
BL_UNLOCK(b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* We try to connect anyway even when we are a server to verify
|
||||
* that no other server is listening to the socket. If we succeed
|
||||
* to connect and we are a server, someone else owns it.
|
||||
*/
|
||||
rv = connect(b->b_fd, (const void *)sun, (socklen_t)sizeof(*sun));
|
||||
if (rv == 0) {
|
||||
if (srv) {
|
||||
bl_log(b->b_fun, LOG_ERR,
|
||||
"%s: another daemon is handling `%s'",
|
||||
__func__, sun->sun_path);
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
if (!srv) {
|
||||
/*
|
||||
* If the daemon is not running, we just try a
|
||||
* connect, so leave the socket alone until it does
|
||||
* and only log once.
|
||||
*/
|
||||
if (b->b_connected != 1) {
|
||||
bl_log(b->b_fun, LOG_DEBUG,
|
||||
"%s: connect failed for `%s' (%m)",
|
||||
__func__, sun->sun_path);
|
||||
b->b_connected = 1;
|
||||
}
|
||||
BL_UNLOCK(b);
|
||||
return -1;
|
||||
}
|
||||
bl_log(b->b_fun, LOG_DEBUG, "Connected to blacklist server",
|
||||
__func__);
|
||||
}
|
||||
|
||||
if (srv) {
|
||||
(void)unlink(sun->sun_path);
|
||||
om = umask(0);
|
||||
rv = bind(b->b_fd, (const void *)sun, (socklen_t)sizeof(*sun));
|
||||
serrno = errno;
|
||||
(void)umask(om);
|
||||
errno = serrno;
|
||||
if (rv == -1) {
|
||||
bl_log(b->b_fun, LOG_ERR,
|
||||
"%s: bind failed for `%s' (%m)",
|
||||
__func__, sun->sun_path);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
b->b_connected = 0;
|
||||
#define GOT_FD 1
|
||||
#if defined(LOCAL_CREDS)
|
||||
#define CRED_LEVEL 0
|
||||
#define CRED_NAME LOCAL_CREDS
|
||||
#define CRED_SC_UID sc_euid
|
||||
#define CRED_SC_GID sc_egid
|
||||
#define CRED_MESSAGE SCM_CREDS
|
||||
#define CRED_SIZE SOCKCREDSIZE(NGROUPS_MAX)
|
||||
#define CRED_TYPE struct sockcred
|
||||
#define GOT_CRED 2
|
||||
#elif defined(SO_PASSCRED)
|
||||
#define CRED_LEVEL SOL_SOCKET
|
||||
#define CRED_NAME SO_PASSCRED
|
||||
#define CRED_SC_UID uid
|
||||
#define CRED_SC_GID gid
|
||||
#define CRED_MESSAGE SCM_CREDENTIALS
|
||||
#define CRED_SIZE sizeof(struct ucred)
|
||||
#define CRED_TYPE struct ucred
|
||||
#define GOT_CRED 2
|
||||
#else
|
||||
#define GOT_CRED 0
|
||||
/*
|
||||
* getpeereid() and LOCAL_PEERCRED don't help here
|
||||
* because we are not a stream socket!
|
||||
*/
|
||||
#define CRED_SIZE 0
|
||||
#define CRED_TYPE void * __unused
|
||||
#endif
|
||||
|
||||
#ifdef CRED_LEVEL
|
||||
if (setsockopt(b->b_fd, CRED_LEVEL, CRED_NAME,
|
||||
&one, (socklen_t)sizeof(one)) == -1) {
|
||||
bl_log(b->b_fun, LOG_ERR, "%s: setsockopt %s "
|
||||
"failed (%m)", __func__, __STRING(CRED_NAME));
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
BL_UNLOCK(b);
|
||||
return 0;
|
||||
out:
|
||||
bl_reset(b, true);
|
||||
BL_UNLOCK(b);
|
||||
return -1;
|
||||
}
|
||||
|
||||
bl_t
|
||||
bl_create(bool srv, const char *path, void (*fun)(int, const char *, va_list))
|
||||
{
|
||||
bl_t b = calloc(1, sizeof(*b));
|
||||
if (b == NULL)
|
||||
goto out;
|
||||
b->b_fun = fun == NULL ? vsyslog : fun;
|
||||
b->b_fd = -1;
|
||||
b->b_connected = -1;
|
||||
BL_INIT(b);
|
||||
|
||||
memset(&b->b_sun, 0, sizeof(b->b_sun));
|
||||
b->b_sun.sun_family = AF_LOCAL;
|
||||
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
|
||||
b->b_sun.sun_len = sizeof(b->b_sun);
|
||||
#endif
|
||||
strlcpy(b->b_sun.sun_path,
|
||||
path ? path : _PATH_BLSOCK, sizeof(b->b_sun.sun_path));
|
||||
|
||||
bl_init(b, srv);
|
||||
return b;
|
||||
out:
|
||||
free(b);
|
||||
bl_log(fun, LOG_ERR, "%s: malloc failed (%m)", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
bl_destroy(bl_t b)
|
||||
{
|
||||
bl_reset(b, false);
|
||||
free(b);
|
||||
}
|
||||
|
||||
static int
|
||||
bl_getsock(bl_t b, struct sockaddr_storage *ss, const struct sockaddr *sa,
|
||||
socklen_t slen, const char *ctx)
|
||||
{
|
||||
uint8_t family;
|
||||
|
||||
memset(ss, 0, sizeof(*ss));
|
||||
|
||||
switch (slen) {
|
||||
case 0:
|
||||
return 0;
|
||||
case sizeof(struct sockaddr_in):
|
||||
family = AF_INET;
|
||||
break;
|
||||
case sizeof(struct sockaddr_in6):
|
||||
family = AF_INET6;
|
||||
break;
|
||||
default:
|
||||
bl_log(b->b_fun, LOG_ERR, "%s: invalid socket len %u (%s)",
|
||||
__func__, (unsigned)slen, ctx);
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(ss, sa, slen);
|
||||
|
||||
if (ss->ss_family != family) {
|
||||
bl_log(b->b_fun, LOG_INFO,
|
||||
"%s: correcting socket family %d to %d (%s)",
|
||||
__func__, ss->ss_family, family, ctx);
|
||||
ss->ss_family = family;
|
||||
}
|
||||
|
||||
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
|
||||
if (ss->ss_len != slen) {
|
||||
bl_log(b->b_fun, LOG_INFO,
|
||||
"%s: correcting socket len %u to %u (%s)",
|
||||
__func__, ss->ss_len, (unsigned)slen, ctx);
|
||||
ss->ss_len = (uint8_t)slen;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
bl_send(bl_t b, bl_type_t e, int pfd, const struct sockaddr *sa,
|
||||
socklen_t slen, const char *ctx)
|
||||
{
|
||||
struct msghdr msg;
|
||||
struct iovec iov;
|
||||
union {
|
||||
char ctrl[CMSG_SPACE(sizeof(int))];
|
||||
uint32_t fd;
|
||||
} ua;
|
||||
struct cmsghdr *cmsg;
|
||||
union {
|
||||
bl_message_t bl;
|
||||
char buf[512];
|
||||
} ub;
|
||||
size_t ctxlen, tried;
|
||||
#define NTRIES 5
|
||||
|
||||
ctxlen = strlen(ctx);
|
||||
if (ctxlen > 128)
|
||||
ctxlen = 128;
|
||||
|
||||
iov.iov_base = ub.buf;
|
||||
iov.iov_len = sizeof(bl_message_t) + ctxlen;
|
||||
ub.bl.bl_len = (uint32_t)iov.iov_len;
|
||||
ub.bl.bl_version = BL_VERSION;
|
||||
ub.bl.bl_type = (uint32_t)e;
|
||||
|
||||
if (bl_getsock(b, &ub.bl.bl_ss, sa, slen, ctx) == -1)
|
||||
return -1;
|
||||
|
||||
|
||||
ub.bl.bl_salen = slen;
|
||||
memcpy(ub.bl.bl_data, ctx, ctxlen);
|
||||
|
||||
msg.msg_name = NULL;
|
||||
msg.msg_namelen = 0;
|
||||
msg.msg_iov = &iov;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_flags = 0;
|
||||
|
||||
msg.msg_control = ua.ctrl;
|
||||
msg.msg_controllen = sizeof(ua.ctrl);
|
||||
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(int));
|
||||
cmsg->cmsg_level = SOL_SOCKET;
|
||||
cmsg->cmsg_type = SCM_RIGHTS;
|
||||
|
||||
memcpy(CMSG_DATA(cmsg), &pfd, sizeof(pfd));
|
||||
|
||||
tried = 0;
|
||||
again:
|
||||
if (bl_init(b, false) == -1)
|
||||
return -1;
|
||||
|
||||
if ((sendmsg(b->b_fd, &msg, 0) == -1) && tried++ < NTRIES) {
|
||||
bl_reset(b, false);
|
||||
goto again;
|
||||
}
|
||||
return tried >= NTRIES ? -1 : 0;
|
||||
}
|
||||
|
||||
bl_info_t *
|
||||
bl_recv(bl_t b)
|
||||
{
|
||||
struct msghdr msg;
|
||||
struct iovec iov;
|
||||
union {
|
||||
char ctrl[CMSG_SPACE(sizeof(int)) + CMSG_SPACE(CRED_SIZE)];
|
||||
uint32_t fd;
|
||||
CRED_TYPE sc;
|
||||
} ua;
|
||||
struct cmsghdr *cmsg;
|
||||
CRED_TYPE *sc;
|
||||
union {
|
||||
bl_message_t bl;
|
||||
char buf[512];
|
||||
} ub;
|
||||
int got;
|
||||
ssize_t rlen;
|
||||
bl_info_t *bi = &b->b_info;
|
||||
|
||||
got = 0;
|
||||
memset(bi, 0, sizeof(*bi));
|
||||
|
||||
iov.iov_base = ub.buf;
|
||||
iov.iov_len = sizeof(ub);
|
||||
|
||||
msg.msg_name = NULL;
|
||||
msg.msg_namelen = 0;
|
||||
msg.msg_iov = &iov;
|
||||
msg.msg_iovlen = 1;
|
||||
msg.msg_flags = 0;
|
||||
|
||||
msg.msg_control = ua.ctrl;
|
||||
msg.msg_controllen = sizeof(ua.ctrl) + 100;
|
||||
|
||||
rlen = recvmsg(b->b_fd, &msg, 0);
|
||||
if (rlen == -1) {
|
||||
bl_log(b->b_fun, LOG_ERR, "%s: recvmsg failed (%m)", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
|
||||
if (cmsg->cmsg_level != SOL_SOCKET) {
|
||||
bl_log(b->b_fun, LOG_ERR,
|
||||
"%s: unexpected cmsg_level %d",
|
||||
__func__, cmsg->cmsg_level);
|
||||
continue;
|
||||
}
|
||||
switch (cmsg->cmsg_type) {
|
||||
case SCM_RIGHTS:
|
||||
if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) {
|
||||
bl_log(b->b_fun, LOG_ERR,
|
||||
"%s: unexpected cmsg_len %d != %zu",
|
||||
__func__, cmsg->cmsg_len,
|
||||
CMSG_LEN(2 * sizeof(int)));
|
||||
continue;
|
||||
}
|
||||
memcpy(&bi->bi_fd, CMSG_DATA(cmsg), sizeof(bi->bi_fd));
|
||||
got |= GOT_FD;
|
||||
break;
|
||||
#ifdef CRED_MESSAGE
|
||||
case CRED_MESSAGE:
|
||||
sc = (void *)CMSG_DATA(cmsg);
|
||||
bi->bi_uid = sc->CRED_SC_UID;
|
||||
bi->bi_gid = sc->CRED_SC_GID;
|
||||
got |= GOT_CRED;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
bl_log(b->b_fun, LOG_ERR,
|
||||
"%s: unexpected cmsg_type %d",
|
||||
__func__, cmsg->cmsg_type);
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (got != (GOT_CRED|GOT_FD)) {
|
||||
bl_log(b->b_fun, LOG_ERR, "message missing %s %s",
|
||||
#if GOT_CRED != 0
|
||||
(got & GOT_CRED) == 0 ? "cred" :
|
||||
#endif
|
||||
"", (got & GOT_FD) == 0 ? "fd" : "");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((size_t)rlen <= sizeof(ub.bl)) {
|
||||
bl_log(b->b_fun, LOG_ERR, "message too short %zd", rlen);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ub.bl.bl_version != BL_VERSION) {
|
||||
bl_log(b->b_fun, LOG_ERR, "bad version %d", ub.bl.bl_version);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bi->bi_type = ub.bl.bl_type;
|
||||
bi->bi_slen = ub.bl.bl_salen;
|
||||
bi->bi_ss = ub.bl.bl_ss;
|
||||
#ifndef CRED_MESSAGE
|
||||
bi->bi_uid = -1;
|
||||
bi->bi_gid = -1;
|
||||
#endif
|
||||
strlcpy(bi->bi_msg, ub.bl.bl_data, MIN(sizeof(bi->bi_msg),
|
||||
((size_t)rlen - sizeof(ub.bl) + 1)));
|
||||
return bi;
|
||||
}
|
88
20160409/lib/blacklist.c
Normal file
88
20160409/lib/blacklist.c
Normal file
@ -0,0 +1,88 @@
|
||||
/* $NetBSD: blacklist.c,v 1.5 2015/01/22 16:19:53 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2014 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: blacklist.c,v 1.5 2015/01/22 16:19:53 christos Exp $");
|
||||
|
||||
#include <stdio.h>
|
||||
#include <bl.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <syslog.h>
|
||||
|
||||
int
|
||||
blacklist_sa(int action, int rfd, const struct sockaddr *sa, socklen_t salen,
|
||||
const char *msg)
|
||||
{
|
||||
struct blacklist *bl;
|
||||
int rv;
|
||||
if ((bl = blacklist_open()) == NULL)
|
||||
return -1;
|
||||
rv = blacklist_sa_r(bl, action, rfd, sa, salen, msg);
|
||||
blacklist_close(bl);
|
||||
return rv;
|
||||
}
|
||||
|
||||
int
|
||||
blacklist_sa_r(struct blacklist *bl, int action, int rfd,
|
||||
const struct sockaddr *sa, socklen_t slen, const char *msg)
|
||||
{
|
||||
return bl_send(bl, action ? BL_ADD : BL_DELETE, rfd, sa, slen, msg);
|
||||
}
|
||||
|
||||
int
|
||||
blacklist(int action, int rfd, const char *msg)
|
||||
{
|
||||
return blacklist_sa(action, rfd, NULL, 0, msg);
|
||||
}
|
||||
|
||||
int
|
||||
blacklist_r(struct blacklist *bl, int action, int rfd, const char *msg)
|
||||
{
|
||||
return blacklist_sa_r(bl, action, rfd, NULL, 0, msg);
|
||||
}
|
||||
|
||||
struct blacklist *
|
||||
blacklist_open(void) {
|
||||
return bl_create(false, NULL, vsyslog);
|
||||
}
|
||||
|
||||
void
|
||||
blacklist_close(struct blacklist *bl)
|
||||
{
|
||||
bl_destroy(bl);
|
||||
}
|
125
20160409/lib/libblacklist.3
Normal file
125
20160409/lib/libblacklist.3
Normal file
@ -0,0 +1,125 @@
|
||||
.\" $NetBSD: libblacklist.3,v 1.3 2015/01/25 23:09:28 wiz 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 22, 2015
|
||||
.Dt LIBBLACKLIST 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm blacklist_open ,
|
||||
.Nm blacklist_close ,
|
||||
.Nm blacklist_r ,
|
||||
.Nm blacklist ,
|
||||
.Nm blacklist_sa
|
||||
.Nm blacklist_sa_r ,
|
||||
.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"
|
||||
.Ft int
|
||||
.Fn blacklist_r "struct blacklist *cookie" "int action" "int fd" "const char *msg"
|
||||
.Ft int
|
||||
.Fn blacklist_sa "int action" "int fd" "const struct sockaddr *sa" "socklen_t salen" "const char *msg"
|
||||
.Ft int
|
||||
.Fn blacklist_sa_r "struct blacklist *cookie" "int action" "int fd" "const struct sockaddr *sa" "socklen_t salen" "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
|
||||
The
|
||||
.Fn blacklist_sa
|
||||
and
|
||||
.Fn blacklist_sa_r
|
||||
functions can be used with unconnected sockets, where
|
||||
.Xr getpeername 2
|
||||
will not work, the server will pass the peer name in the message.
|
||||
.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.conf 5 ,
|
||||
.Xr blacklistd 8
|
||||
.Sh AUTHORS
|
||||
.An Christos Zoulas
|
2
20160409/lib/shlib_version
Normal file
2
20160409/lib/shlib_version
Normal file
@ -0,0 +1,2 @@
|
||||
major=0
|
||||
minor=0
|
6
20160409/libexec/Makefile
Normal file
6
20160409/libexec/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
# $NetBSD: Makefile,v 1.1 2015/01/22 17:49:41 christos Exp $
|
||||
|
||||
SCRIPTS= blacklistd-helper
|
||||
SCRIPTSDIR= /libexec
|
||||
|
||||
.include <bsd.prog.mk>
|
82
20160409/libexec/blacklistd-helper
Normal file
82
20160409/libexec/blacklistd-helper
Normal file
@ -0,0 +1,82 @@
|
||||
#!/bin/sh
|
||||
#echo "run $@" 1>&2
|
||||
#set -x
|
||||
# $1 command
|
||||
# $2 rulename
|
||||
# $3 protocol
|
||||
# $4 address
|
||||
# $5 mask
|
||||
# $6 port
|
||||
# $7 id
|
||||
|
||||
pf=
|
||||
for f in npf pf; do
|
||||
if [ -f "/etc/$f.conf" ]; then
|
||||
pf="$f"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -z "$pf" ]; then
|
||||
echo "$0: Unsupported packet filter" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -n "$3" ]; then
|
||||
proto="proto $3"
|
||||
fi
|
||||
|
||||
if [ -n "$6" ]; then
|
||||
port="port $6"
|
||||
fi
|
||||
|
||||
addr="$4"
|
||||
mask="$5"
|
||||
case "$4" in
|
||||
::ffff:*.*.*.*)
|
||||
if [ "$5" = 128 ]; then
|
||||
mask=32
|
||||
addr=${4#::ffff:}
|
||||
fi;;
|
||||
esac
|
||||
|
||||
case "$1" in
|
||||
add)
|
||||
case "$pf" in
|
||||
npf)
|
||||
/sbin/npfctl rule "$2" add block in final $proto from \
|
||||
"$addr/$mask" to any $port
|
||||
;;
|
||||
pf)
|
||||
# insert $ip/$mask into per-protocol anchored table
|
||||
/sbin/pfctl -a "$2" -t "port$6" -T add "$addr/$mask"
|
||||
echo "block in quick $proto from <port$6> to any $port" | \
|
||||
/sbin/pfctl -a "$2" -f -
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
rem)
|
||||
case "$pf" in
|
||||
npf)
|
||||
/sbin/npfctl rule "$2" rem-id "$7"
|
||||
;;
|
||||
pf)
|
||||
/sbin/pfctl -a "$2" -t "port$6" -T delete "$addr/$mask"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
flush)
|
||||
case "$pf" in
|
||||
npf)
|
||||
/sbin/npfctl rule "$2" flush
|
||||
;;
|
||||
pf)
|
||||
/sbin/pfctl -a "$2" -t "port$6" -T flush
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
echo "$0: Unknown command '$1'" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
25
20160409/port/Makefile.am
Normal file
25
20160409/port/Makefile.am
Normal file
@ -0,0 +1,25 @@
|
||||
#
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
lib_LTLIBRARIES = libblacklist.la
|
||||
include_HEADERS = blacklist.h
|
||||
|
||||
bin_PROGRAMS = blacklistd blacklistctl srvtest cltest
|
||||
|
||||
VPATH = ../bin:../lib:../test
|
||||
|
||||
AM_CPPFLAGS = -I../include -DDOT="."
|
||||
AM_CFLAGS = @WARNINGS@
|
||||
|
||||
libblacklist_la_SOURCES = bl.c blacklist.c
|
||||
libblacklist_la_LDFLAGS = -no-undefined -version-info 0:0:0
|
||||
libblacklist_la_LIBADD = $(LTLIBOBJS)
|
||||
|
||||
SRCS = internal.c support.c run.c conf.c state.c
|
||||
blacklistd_SOURCES = blacklistd.c ${SRCS}
|
||||
blacklistd_LDADD = libblacklist.la
|
||||
blacklistctl_SOURCES = blacklistctl.c ${SRCS}
|
||||
blacklistctl_LDADD = libblacklist.la
|
||||
srvtest_SOURCES = srvtest.c ${SRCS}
|
||||
srvtest_LDADD = libblacklist.la
|
||||
cltest_SOURCES = cltest.c ${SRCS}
|
||||
cltest_LDADD = libblacklist.la
|
93
20160409/port/_strtoi.h
Normal file
93
20160409/port/_strtoi.h
Normal file
@ -0,0 +1,93 @@
|
||||
/* $NetBSD: _strtoi.h,v 1.1 2015/01/22 02:15:59 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||
*
|
||||
* Original version ID:
|
||||
* NetBSD: src/lib/libc/locale/_wcstoul.h,v 1.2 2003/08/07 16:43:03 agc Exp
|
||||
*
|
||||
* Created by Kamil Rytarowski, based on ID:
|
||||
* NetBSD: src/common/lib/libc/stdlib/_strtoul.h,v 1.7 2013/05/17 12:55:56 joerg Exp
|
||||
*/
|
||||
|
||||
/*
|
||||
* function template for strtoi and strtou
|
||||
*
|
||||
* parameters:
|
||||
* _FUNCNAME : function name
|
||||
* __TYPE : return and range limits type
|
||||
* __WRAPPED : wrapped function, strtoimax or strtoumax
|
||||
*/
|
||||
|
||||
__TYPE
|
||||
_FUNCNAME(const char * __restrict nptr, char ** __restrict endptr, int base,
|
||||
__TYPE lo, __TYPE hi, int * rstatus)
|
||||
{
|
||||
int serrno;
|
||||
__TYPE im;
|
||||
char *ep;
|
||||
int rep;
|
||||
|
||||
/* endptr may be NULL */
|
||||
|
||||
if (endptr == NULL)
|
||||
endptr = &ep;
|
||||
|
||||
if (rstatus == NULL)
|
||||
rstatus = &rep;
|
||||
|
||||
serrno = errno;
|
||||
errno = 0;
|
||||
|
||||
im = __WRAPPED(nptr, endptr, base);
|
||||
|
||||
*rstatus = errno;
|
||||
errno = serrno;
|
||||
|
||||
if (*rstatus == 0) {
|
||||
/* No digits were found */
|
||||
if (nptr == *endptr)
|
||||
*rstatus = ECANCELED;
|
||||
/* There are further characters after number */
|
||||
else if (**endptr != '\0')
|
||||
*rstatus = ENOTSUP;
|
||||
}
|
||||
|
||||
if (im < lo) {
|
||||
if (*rstatus == 0)
|
||||
*rstatus = ERANGE;
|
||||
return lo;
|
||||
}
|
||||
if (im > hi) {
|
||||
if (*rstatus == 0)
|
||||
*rstatus = ERANGE;
|
||||
return hi;
|
||||
}
|
||||
|
||||
return im;
|
||||
}
|
17
20160409/port/clock_gettime.c
Normal file
17
20160409/port/clock_gettime.c
Normal file
@ -0,0 +1,17 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
int
|
||||
clock_gettime(int clock __unused, struct timespec *ts)
|
||||
{
|
||||
struct timeval tv;
|
||||
if (gettimeofday(&tv, NULL) == -1)
|
||||
return -1;
|
||||
ts->tv_sec = tv.tv_sec;
|
||||
ts->tv_nsec = tv.tv_usec * 1000;
|
||||
return 0;
|
||||
}
|
3
20160409/port/config.h
Normal file
3
20160409/port/config.h
Normal file
@ -0,0 +1,3 @@
|
||||
#if defined(__FreeBSD__)
|
||||
#include "port.h"
|
||||
#endif
|
91
20160409/port/configure.ac
Normal file
91
20160409/port/configure.ac
Normal file
@ -0,0 +1,91 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT([blacklistd],[0.1],[christos@netbsd.com])
|
||||
AM_INIT_AUTOMAKE([subdir-objects foreign])
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
AC_SUBST(WARNINGS)
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC_STDC
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
AM_PROG_CC_C_O
|
||||
AC_C_BIGENDIAN
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LN_S
|
||||
LT_INIT([disable-static pic-only])
|
||||
gl_VISIBILITY
|
||||
dnl Checks for headers
|
||||
AC_HEADER_STDC
|
||||
AC_HEADER_MAJOR
|
||||
AC_HEADER_SYS_WAIT
|
||||
AC_CHECK_HEADERS(stdint.h fcntl.h stdint.h inttypes.h unistd.h)
|
||||
AC_CHECK_HEADERS(sys/un.h sys/socket.h limits.h)
|
||||
AC_CHECK_HEADERS(arpa/inet.h getopt.h err.h)
|
||||
AC_CHECK_HEADERS(sys/types.h util.h sys/time.h time.h)
|
||||
AC_CHECK_HEADERS(netatalk/at.h net/if_dl.h db.h db_185.h)
|
||||
AC_CHECK_LIB(rt, clock_gettime)
|
||||
AC_CHECK_LIB(db, __db185_open)
|
||||
AC_CHECK_LIB(util, pidfile)
|
||||
AC_CHECK_LIB(util, sockaddr_snprintf)
|
||||
|
||||
AH_BOTTOM([
|
||||
#ifndef __NetBSD__
|
||||
#include "port.h"
|
||||
#endif
|
||||
])
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
AC_TYPE_OFF_T
|
||||
AC_TYPE_SIZE_T
|
||||
AC_SYS_LARGEFILE
|
||||
AC_CHECK_MEMBERS([struct sockaddr.sa_len], [], [], [#include <sys/socket.h>])
|
||||
|
||||
AC_TYPE_PID_T
|
||||
AC_TYPE_UINT8_T
|
||||
AC_TYPE_UINT16_T
|
||||
AC_TYPE_UINT32_T
|
||||
AC_TYPE_INT32_T
|
||||
AC_TYPE_UINT64_T
|
||||
AC_TYPE_INT64_T
|
||||
AC_TYPE_INTPTR_T
|
||||
AC_TYPE_UINTPTR_T
|
||||
|
||||
AC_MSG_CHECKING(for gcc compiler warnings)
|
||||
AC_ARG_ENABLE(warnings,
|
||||
[ --disable-warnings disable compiler warnings],
|
||||
[if test "${enableval}" = no -o "$GCC" = no; then
|
||||
AC_MSG_RESULT(no)
|
||||
WARNINGS=
|
||||
else
|
||||
AC_MSG_RESULT(yes)
|
||||
WARNINGS="-Wall -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith \
|
||||
-Wmissing-declarations -Wredundant-decls -Wnested-externs \
|
||||
-Wsign-compare -Wreturn-type -Wswitch -Wshadow \
|
||||
-Wcast-qual -Wwrite-strings -Wextra -Wunused-parameter -Wformat=2"
|
||||
fi], [
|
||||
if test "$GCC" = yes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
WARNINGS="-Wall -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith \
|
||||
-Wmissing-declarations -Wredundant-decls -Wnested-externs \
|
||||
-Wsign-compare -Wreturn-type -Wswitch -Wshadow \
|
||||
-Wcast-qual -Wwrite-strings -Wextra -Wunused-parameter -Wformat=2"
|
||||
else
|
||||
WARNINGS=
|
||||
AC_MSG_RESULT(no)
|
||||
fi])
|
||||
|
||||
dnl Checks for functions
|
||||
AC_CHECK_FUNCS(strerror)
|
||||
|
||||
dnl Provide implementation of some required functions if necessary
|
||||
AC_REPLACE_FUNCS(strtoi sockaddr_snprintf popenve clock_gettime strlcpy strlcat getprogname fparseln fgetln pidfile)
|
||||
|
||||
dnl See if we are cross-compiling
|
||||
AM_CONDITIONAL(IS_CROSS_COMPILE, test "$cross_compiling" = yes)
|
||||
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_OUTPUT
|
106
20160409/port/fgetln.c
Normal file
106
20160409/port/fgetln.c
Normal file
@ -0,0 +1,106 @@
|
||||
/* $NetBSD: fgetln.c,v 1.1 2015/01/22 03:48:07 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#if !HAVE_FGETLN
|
||||
#include <stdlib.h>
|
||||
#ifndef HAVE_NBTOOL_CONFIG_H
|
||||
/* These headers are required, but included from nbtool_config.h */
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
char *
|
||||
fgetln(FILE *fp, size_t *len)
|
||||
{
|
||||
static char *buf = NULL;
|
||||
static size_t bufsiz = 0;
|
||||
char *ptr;
|
||||
|
||||
|
||||
if (buf == NULL) {
|
||||
bufsiz = BUFSIZ;
|
||||
if ((buf = malloc(bufsiz)) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fgets(buf, bufsiz, fp) == NULL)
|
||||
return NULL;
|
||||
|
||||
*len = 0;
|
||||
while ((ptr = strchr(&buf[*len], '\n')) == NULL) {
|
||||
size_t nbufsiz = bufsiz + BUFSIZ;
|
||||
char *nbuf = realloc(buf, nbufsiz);
|
||||
|
||||
if (nbuf == NULL) {
|
||||
int oerrno = errno;
|
||||
free(buf);
|
||||
errno = oerrno;
|
||||
buf = NULL;
|
||||
return NULL;
|
||||
} else
|
||||
buf = nbuf;
|
||||
|
||||
if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL) {
|
||||
buf[bufsiz] = '\0';
|
||||
*len = strlen(buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
*len = bufsiz;
|
||||
bufsiz = nbufsiz;
|
||||
}
|
||||
|
||||
*len = (ptr - buf) + 1;
|
||||
return buf;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char *p;
|
||||
size_t len;
|
||||
|
||||
while ((p = fgetln(stdin, &len)) != NULL) {
|
||||
(void)printf("%zu %s", len, p);
|
||||
free(p);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
236
20160409/port/fparseln.c
Normal file
236
20160409/port/fparseln.c
Normal file
@ -0,0 +1,236 @@
|
||||
/* $NetBSD: fparseln.c,v 1.1 2015/01/22 03:48:07 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997 Christos Zoulas. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
__RCSID("$NetBSD: fparseln.c,v 1.1 2015/01/22 03:48:07 christos Exp $");
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if ! HAVE_FPARSELN || BROKEN_FPARSELN
|
||||
|
||||
#define FLOCKFILE(fp)
|
||||
#define FUNLOCKFILE(fp)
|
||||
|
||||
#if defined(_REENTRANT) && !HAVE_NBTOOL_CONFIG_H
|
||||
#define __fgetln(f, l) __fgetstr(f, l, '\n')
|
||||
#else
|
||||
#define __fgetln(f, l) fgetln(f, l)
|
||||
#endif
|
||||
|
||||
static int isescaped(const char *, const char *, int);
|
||||
|
||||
/* isescaped():
|
||||
* Return true if the character in *p that belongs to a string
|
||||
* that starts in *sp, is escaped by the escape character esc.
|
||||
*/
|
||||
static int
|
||||
isescaped(const char *sp, const char *p, int esc)
|
||||
{
|
||||
const char *cp;
|
||||
size_t ne;
|
||||
|
||||
/* No escape character */
|
||||
if (esc == '\0')
|
||||
return 0;
|
||||
|
||||
/* Count the number of escape characters that precede ours */
|
||||
for (ne = 0, cp = p; --cp >= sp && *cp == esc; ne++)
|
||||
continue;
|
||||
|
||||
/* Return true if odd number of escape characters */
|
||||
return (ne & 1) != 0;
|
||||
}
|
||||
|
||||
|
||||
/* fparseln():
|
||||
* Read a line from a file parsing continuations ending in \
|
||||
* and eliminating trailing newlines, or comments starting with
|
||||
* the comment char.
|
||||
*/
|
||||
char *
|
||||
fparseln(FILE *fp, size_t *size, size_t *lineno, const char str[3], int flags)
|
||||
{
|
||||
static const char dstr[3] = { '\\', '\\', '#' };
|
||||
|
||||
size_t s, len;
|
||||
char *buf;
|
||||
char *ptr, *cp;
|
||||
int cnt;
|
||||
char esc, con, nl, com;
|
||||
|
||||
len = 0;
|
||||
buf = NULL;
|
||||
cnt = 1;
|
||||
|
||||
if (str == NULL)
|
||||
str = dstr;
|
||||
|
||||
esc = str[0];
|
||||
con = str[1];
|
||||
com = str[2];
|
||||
/*
|
||||
* XXX: it would be cool to be able to specify the newline character,
|
||||
* but unfortunately, fgetln does not let us
|
||||
*/
|
||||
nl = '\n';
|
||||
|
||||
FLOCKFILE(fp);
|
||||
|
||||
while (cnt) {
|
||||
cnt = 0;
|
||||
|
||||
if (lineno)
|
||||
(*lineno)++;
|
||||
|
||||
if ((ptr = __fgetln(fp, &s)) == NULL)
|
||||
break;
|
||||
|
||||
if (s && com) { /* Check and eliminate comments */
|
||||
for (cp = ptr; cp < ptr + s; cp++)
|
||||
if (*cp == com && !isescaped(ptr, cp, esc)) {
|
||||
s = cp - ptr;
|
||||
cnt = s == 0 && buf == NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (s && nl) { /* Check and eliminate newlines */
|
||||
cp = &ptr[s - 1];
|
||||
|
||||
if (*cp == nl)
|
||||
s--; /* forget newline */
|
||||
}
|
||||
|
||||
if (s && con) { /* Check and eliminate continuations */
|
||||
cp = &ptr[s - 1];
|
||||
|
||||
if (*cp == con && !isescaped(ptr, cp, esc)) {
|
||||
s--; /* forget continuation char */
|
||||
cnt = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (s == 0) {
|
||||
/*
|
||||
* nothing to add, skip realloc except in case
|
||||
* we need a minimal buf to return an empty line
|
||||
*/
|
||||
if (cnt || buf != NULL)
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((cp = realloc(buf, len + s + 1)) == NULL) {
|
||||
FUNLOCKFILE(fp);
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
buf = cp;
|
||||
|
||||
(void) memcpy(buf + len, ptr, s);
|
||||
len += s;
|
||||
buf[len] = '\0';
|
||||
}
|
||||
|
||||
FUNLOCKFILE(fp);
|
||||
|
||||
if ((flags & FPARSELN_UNESCALL) != 0 && esc && buf != NULL &&
|
||||
strchr(buf, esc) != NULL) {
|
||||
ptr = cp = buf;
|
||||
while (cp[0] != '\0') {
|
||||
int skipesc;
|
||||
|
||||
while (cp[0] != '\0' && cp[0] != esc)
|
||||
*ptr++ = *cp++;
|
||||
if (cp[0] == '\0' || cp[1] == '\0')
|
||||
break;
|
||||
|
||||
skipesc = 0;
|
||||
if (cp[1] == com)
|
||||
skipesc += (flags & FPARSELN_UNESCCOMM);
|
||||
if (cp[1] == con)
|
||||
skipesc += (flags & FPARSELN_UNESCCONT);
|
||||
if (cp[1] == esc)
|
||||
skipesc += (flags & FPARSELN_UNESCESC);
|
||||
if (cp[1] != com && cp[1] != con && cp[1] != esc)
|
||||
skipesc = (flags & FPARSELN_UNESCREST);
|
||||
|
||||
if (skipesc)
|
||||
cp++;
|
||||
else
|
||||
*ptr++ = *cp++;
|
||||
*ptr++ = *cp++;
|
||||
}
|
||||
*ptr = '\0';
|
||||
len = strlen(buf);
|
||||
}
|
||||
|
||||
if (size)
|
||||
*size = len;
|
||||
return buf;
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
int main(int, char **);
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
char *ptr;
|
||||
size_t size, line;
|
||||
|
||||
line = 0;
|
||||
while ((ptr = fparseln(stdin, &size, &line, NULL,
|
||||
FPARSELN_UNESCALL)) != NULL)
|
||||
printf("line %d (%d) |%s|\n", line, size, ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
# This is a test
|
||||
line 1
|
||||
line 2 \
|
||||
line 3 # Comment
|
||||
line 4 \# Not comment \\\\
|
||||
|
||||
# And a comment \
|
||||
line 5 \\\
|
||||
line 6
|
||||
|
||||
*/
|
||||
|
||||
#endif /* TEST */
|
||||
#endif /* ! HAVE_FPARSELN || BROKEN_FPARSELN */
|
24
20160409/port/getprogname.c
Normal file
24
20160409/port/getprogname.c
Normal file
@ -0,0 +1,24 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
extern char *__progname;
|
||||
|
||||
const char *
|
||||
getprogname(void)
|
||||
{
|
||||
return __progname;
|
||||
}
|
||||
|
||||
void
|
||||
setprogname(char *p)
|
||||
{
|
||||
char *q;
|
||||
if (p == NULL)
|
||||
return;
|
||||
if ((q = strrchr(p, '/')) != NULL)
|
||||
__progname = ++q;
|
||||
else
|
||||
__progname = p;
|
||||
}
|
1
20160409/port/m4/.cvsignore
Normal file
1
20160409/port/m4/.cvsignore
Normal file
@ -0,0 +1 @@
|
||||
*.m4
|
183
20160409/port/pidfile.c
Normal file
183
20160409/port/pidfile.c
Normal file
@ -0,0 +1,183 @@
|
||||
/* $NetBSD: pidfile.c,v 1.2 2016/04/05 12:28:57 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Jason R. Thorpe, Matthias Scheler and Julio Merino.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
__RCSID("$NetBSD: pidfile.c,v 1.2 2016/04/05 12:28:57 christos Exp $");
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <paths.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#ifdef HAVE_LIBUTIL_H
|
||||
#include <libutil.h>
|
||||
#endif
|
||||
#ifdef HAVE_UTIL_H
|
||||
#include <util.h>
|
||||
#endif
|
||||
|
||||
static pid_t pidfile_pid;
|
||||
static char *pidfile_path;
|
||||
|
||||
/* Deletes an existent pidfile iff it was created by this process. */
|
||||
static void
|
||||
pidfile_cleanup(void)
|
||||
{
|
||||
|
||||
if ((pidfile_path != NULL) && (pidfile_pid == getpid()))
|
||||
(void) unlink(pidfile_path);
|
||||
}
|
||||
|
||||
/* Registers an atexit(3) handler to delete the pidfile we have generated.
|
||||
* We only register the handler when we create a pidfile, so we can assume
|
||||
* that the pidfile exists.
|
||||
*
|
||||
* Returns 0 on success or -1 if the handler could not be registered. */
|
||||
static int
|
||||
register_atexit_handler(void)
|
||||
{
|
||||
static bool done = false;
|
||||
|
||||
if (!done) {
|
||||
if (atexit(pidfile_cleanup) < 0)
|
||||
return -1;
|
||||
done = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Given a new pidfile name in 'path', deletes any previously-created pidfile
|
||||
* if the previous file differs to the new one.
|
||||
*
|
||||
* If a previous file is deleted, returns 1, which means that a new pidfile
|
||||
* must be created. Otherwise, this returns 0, which means that the existing
|
||||
* file does not need to be touched. */
|
||||
static int
|
||||
cleanup_old_pidfile(const char* path)
|
||||
{
|
||||
if (pidfile_path != NULL) {
|
||||
if (strcmp(pidfile_path, path) != 0) {
|
||||
pidfile_cleanup();
|
||||
|
||||
free(pidfile_path);
|
||||
pidfile_path = NULL;
|
||||
|
||||
return 1;
|
||||
} else
|
||||
return 0;
|
||||
} else
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Constructs a name for a pidfile in the default location (/var/run). If
|
||||
* 'basename' is NULL, uses the name of the current program for the name of
|
||||
* the pidfile.
|
||||
*
|
||||
* Returns a pointer to a dynamically-allocatd string containing the absolute
|
||||
* path to the pidfile; NULL on failure. */
|
||||
static char *
|
||||
generate_varrun_path(const char *bname)
|
||||
{
|
||||
char *path;
|
||||
|
||||
if (bname == NULL)
|
||||
bname = getprogname();
|
||||
|
||||
/* _PATH_VARRUN includes trailing / */
|
||||
if (asprintf(&path, "%s%s.pid", _PATH_VARRUN, bname) == -1)
|
||||
return NULL;
|
||||
return path;
|
||||
}
|
||||
|
||||
/* Creates a pidfile with the provided name. The new pidfile is "registered"
|
||||
* in the global variables pidfile_path and pidfile_pid so that any further
|
||||
* call to pidfile(3) can check if we are recreating the same file or a new
|
||||
* one.
|
||||
*
|
||||
* Returns 0 on success or -1 if there is any error. */
|
||||
static int
|
||||
create_pidfile(const char* path)
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
if (register_atexit_handler() == -1)
|
||||
return -1;
|
||||
|
||||
if (cleanup_old_pidfile(path) == 0)
|
||||
return 0;
|
||||
|
||||
pidfile_path = strdup(path);
|
||||
if (pidfile_path == NULL)
|
||||
return -1;
|
||||
|
||||
if ((f = fopen(path, "w")) == NULL) {
|
||||
free(pidfile_path);
|
||||
pidfile_path = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
pidfile_pid = getpid();
|
||||
|
||||
(void) fprintf(f, "%d\n", pidfile_pid);
|
||||
(void) fclose(f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pidfile(const char *path)
|
||||
{
|
||||
|
||||
if (path == NULL || strchr(path, '/') == NULL) {
|
||||
char *default_path;
|
||||
|
||||
if ((default_path = generate_varrun_path(path)) == NULL)
|
||||
return -1;
|
||||
|
||||
if (create_pidfile(default_path) == -1) {
|
||||
free(default_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(default_path);
|
||||
return 0;
|
||||
} else
|
||||
return create_pidfile(path);
|
||||
}
|
274
20160409/port/popenve.c
Normal file
274
20160409/port/popenve.c
Normal file
@ -0,0 +1,274 @@
|
||||
/* $NetBSD: popenve.c,v 1.2 2015/01/22 03:10:50 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software written by Ken Arnold and
|
||||
* published in UNIX Review, Vol. 6, No. 8.
|
||||
*
|
||||
* 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.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)popen.c 8.3 (Berkeley) 5/3/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: popenve.c,v 1.2 2015/01/22 03:10:50 christos Exp $");
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <paths.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef __weak_alias
|
||||
__weak_alias(popen,_popen)
|
||||
__weak_alias(pclose,_pclose)
|
||||
#endif
|
||||
|
||||
static struct pid {
|
||||
struct pid *next;
|
||||
FILE *fp;
|
||||
#ifdef _REENTRANT
|
||||
int fd;
|
||||
#endif
|
||||
pid_t pid;
|
||||
} *pidlist;
|
||||
|
||||
#ifdef _REENTRANT
|
||||
static rwlock_t pidlist_lock = RWLOCK_INITIALIZER;
|
||||
#endif
|
||||
|
||||
static struct pid *
|
||||
pdes_get(int *pdes, const char **type)
|
||||
{
|
||||
struct pid *cur;
|
||||
int flags = strchr(*type, 'e') ? O_CLOEXEC : 0;
|
||||
int serrno;
|
||||
|
||||
if (strchr(*type, '+')) {
|
||||
#ifndef SOCK_CLOEXEC
|
||||
#define SOCK_CLOEXEC 0
|
||||
#endif
|
||||
int stype = flags ? (SOCK_STREAM | SOCK_CLOEXEC) : SOCK_STREAM;
|
||||
*type = "r+";
|
||||
if (socketpair(AF_LOCAL, stype, 0, pdes) < 0)
|
||||
return NULL;
|
||||
#if SOCK_CLOEXEC == 0
|
||||
fcntl(pdes[0], F_SETFD, FD_CLOEXEC);
|
||||
fcntl(pdes[1], F_SETFD, FD_CLOEXEC);
|
||||
#endif
|
||||
} else {
|
||||
*type = strrchr(*type, 'r') ? "r" : "w";
|
||||
#if SOCK_CLOEXEC != 0
|
||||
if (pipe2(pdes, flags) == -1)
|
||||
return NULL;
|
||||
#else
|
||||
if (pipe(pdes) == -1)
|
||||
return NULL;
|
||||
fcntl(pdes[0], F_SETFL, fcntl(pdes[0], F_GETFL) | flags);
|
||||
fcntl(pdes[1], F_SETFL, fcntl(pdes[1], F_GETFL) | flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
if ((cur = malloc(sizeof(*cur))) != NULL)
|
||||
return cur;
|
||||
serrno = errno;
|
||||
(void)close(pdes[0]);
|
||||
(void)close(pdes[1]);
|
||||
errno = serrno;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
pdes_child(int *pdes, const char *type)
|
||||
{
|
||||
struct pid *old;
|
||||
|
||||
/* POSIX.2 B.3.2.2 "popen() shall ensure that any streams
|
||||
from previous popen() calls that remain open in the
|
||||
parent process are closed in the new child process. */
|
||||
for (old = pidlist; old; old = old->next)
|
||||
#ifdef _REENTRANT
|
||||
(void)close(old->fd); /* don't allow a flush */
|
||||
#else
|
||||
(void)close(fileno(old->fp)); /* don't allow a flush */
|
||||
#endif
|
||||
|
||||
if (type[0] == 'r') {
|
||||
(void)close(pdes[0]);
|
||||
if (pdes[1] != STDOUT_FILENO) {
|
||||
(void)dup2(pdes[1], STDOUT_FILENO);
|
||||
(void)close(pdes[1]);
|
||||
}
|
||||
if (type[1] == '+')
|
||||
(void)dup2(STDOUT_FILENO, STDIN_FILENO);
|
||||
} else {
|
||||
(void)close(pdes[1]);
|
||||
if (pdes[0] != STDIN_FILENO) {
|
||||
(void)dup2(pdes[0], STDIN_FILENO);
|
||||
(void)close(pdes[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pdes_parent(int *pdes, struct pid *cur, pid_t pid, const char *type)
|
||||
{
|
||||
FILE *iop;
|
||||
|
||||
/* Parent; assume fdopen can't fail. */
|
||||
if (*type == 'r') {
|
||||
iop = fdopen(pdes[0], type);
|
||||
#ifdef _REENTRANT
|
||||
cur->fd = pdes[0];
|
||||
#endif
|
||||
(void)close(pdes[1]);
|
||||
} else {
|
||||
iop = fdopen(pdes[1], type);
|
||||
#ifdef _REENTRANT
|
||||
cur->fd = pdes[1];
|
||||
#endif
|
||||
(void)close(pdes[0]);
|
||||
}
|
||||
|
||||
/* Link into list of file descriptors. */
|
||||
cur->fp = iop;
|
||||
cur->pid = pid;
|
||||
cur->next = pidlist;
|
||||
pidlist = cur;
|
||||
}
|
||||
|
||||
static void
|
||||
pdes_error(int *pdes, struct pid *cur)
|
||||
{
|
||||
free(cur);
|
||||
(void)close(pdes[0]);
|
||||
(void)close(pdes[1]);
|
||||
}
|
||||
|
||||
FILE *
|
||||
popenve(const char *cmd, char *const *argv, char *const *envp, const char *type)
|
||||
{
|
||||
struct pid *cur;
|
||||
int pdes[2], serrno;
|
||||
pid_t pid;
|
||||
|
||||
if ((cur = pdes_get(pdes, &type)) == NULL)
|
||||
return NULL;
|
||||
|
||||
#ifdef _REENTRANT
|
||||
(void)rwlock_rdlock(&pidlist_lock);
|
||||
#endif
|
||||
switch (pid = vfork()) {
|
||||
case -1: /* Error. */
|
||||
serrno = errno;
|
||||
#ifdef _REENTRANT
|
||||
(void)rwlock_unlock(&pidlist_lock);
|
||||
#endif
|
||||
pdes_error(pdes, cur);
|
||||
errno = serrno;
|
||||
return NULL;
|
||||
/* NOTREACHED */
|
||||
case 0: /* Child. */
|
||||
pdes_child(pdes, type);
|
||||
execve(cmd, argv, envp);
|
||||
_exit(127);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
pdes_parent(pdes, cur, pid, type);
|
||||
|
||||
#ifdef _REENTRANT
|
||||
(void)rwlock_unlock(&pidlist_lock);
|
||||
#endif
|
||||
|
||||
return cur->fp;
|
||||
}
|
||||
|
||||
/*
|
||||
* pclose --
|
||||
* Pclose returns -1 if stream is not associated with a `popened' command,
|
||||
* if already `pclosed', or waitpid returns an error.
|
||||
*/
|
||||
int
|
||||
pcloseve(FILE *iop)
|
||||
{
|
||||
struct pid *cur, *last;
|
||||
int pstat;
|
||||
pid_t pid;
|
||||
|
||||
#ifdef _REENTRANT
|
||||
rwlock_wrlock(&pidlist_lock);
|
||||
#endif
|
||||
|
||||
/* Find the appropriate file pointer. */
|
||||
for (last = NULL, cur = pidlist; cur; last = cur, cur = cur->next)
|
||||
if (cur->fp == iop)
|
||||
break;
|
||||
if (cur == NULL) {
|
||||
#ifdef _REENTRANT
|
||||
(void)rwlock_unlock(&pidlist_lock);
|
||||
#endif
|
||||
errno = ESRCH;
|
||||
return -1;
|
||||
}
|
||||
|
||||
(void)fclose(iop);
|
||||
|
||||
/* Remove the entry from the linked list. */
|
||||
if (last == NULL)
|
||||
pidlist = cur->next;
|
||||
else
|
||||
last->next = cur->next;
|
||||
|
||||
#ifdef _REENTRANT
|
||||
(void)rwlock_unlock(&pidlist_lock);
|
||||
#endif
|
||||
|
||||
do {
|
||||
pid = waitpid(cur->pid, &pstat, 0);
|
||||
} while (pid == -1 && errno == EINTR);
|
||||
|
||||
free(cur);
|
||||
|
||||
return pid == -1 ? -1 : pstat;
|
||||
}
|
86
20160409/port/port.h
Normal file
86
20160409/port/port.h
Normal file
@ -0,0 +1,86 @@
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#ifndef __unused
|
||||
#define __unused __attribute__((__unused__))
|
||||
#endif
|
||||
|
||||
#ifndef __dead
|
||||
#define __dead __attribute__((__noreturn__))
|
||||
#endif
|
||||
|
||||
#ifndef __RCSID
|
||||
#define __RCSID(a)
|
||||
#endif
|
||||
|
||||
#ifndef __UNCONST
|
||||
#define __UNCONST(a) ((void *)(intptr_t)(a))
|
||||
#endif
|
||||
|
||||
#ifndef __arraycount
|
||||
#define __arraycount(a) (sizeof(a) / sizeof(a[0]))
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
size_t strlcpy(char *, const char *, size_t);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRLCAT
|
||||
size_t strlcat(char *, const char *, size_t);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_POPENVE
|
||||
FILE *popenve(const char *, char *const *, char *const *, const char *);
|
||||
int pcloseve(FILE *);
|
||||
#define pclose(a) pcloseve(a);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SOCKADDR_SNPRINTF
|
||||
struct sockaddr;
|
||||
int sockaddr_snprintf(char *, size_t, const char *, const struct sockaddr *);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRTOI
|
||||
intmax_t strtoi(const char *, char **, int, intmax_t, intmax_t, int *);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_GETPROGNAME
|
||||
const char *getprogname(void);
|
||||
void setprogname(char *);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_PIDFILE
|
||||
int pidfile(const char *);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FPARSELN
|
||||
#define FPARSELN_UNESCALL 0xf
|
||||
#define FPARSELN_UNESCCOMM 0x1
|
||||
#define FPARSELN_UNESCCONT 0x2
|
||||
#define FPARSELN_UNESCESC 0x4
|
||||
#define FPARSELN_UNESCREST 0x8
|
||||
char *fparseln(FILE *, size_t *, size_t *, const char delim[3], int);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FGETLN
|
||||
char *fgetln(FILE *, size_t *);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_CLOCK_GETTIME
|
||||
struct timespec;
|
||||
int clock_gettime(int, struct timespec *);
|
||||
#define CLOCK_REALTIME 0
|
||||
#endif
|
||||
|
||||
#if !defined(__FreeBSD__)
|
||||
#define _PATH_BLCONF "conf"
|
||||
#define _PATH_BLCONTROL "control"
|
||||
#define _PATH_BLSOCK "blacklistd.sock"
|
||||
#define _PATH_BLSTATE "blacklistd.db"
|
||||
#endif
|
383
20160409/port/sockaddr_snprintf.c
Normal file
383
20160409/port/sockaddr_snprintf.c
Normal file
@ -0,0 +1,383 @@
|
||||
/* $NetBSD: sockaddr_snprintf.c,v 1.10 2016/04/05 12:28:57 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2004 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
__RCSID("$NetBSD: sockaddr_snprintf.c,v 1.10 2016/04/05 12:28:57 christos Exp $");
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#ifdef __linux__
|
||||
#undef HAVE_NETATALK_AT_H
|
||||
#endif
|
||||
#ifdef HAVE_NETATALK_AT_H
|
||||
#include <netatalk/at.h>
|
||||
#endif
|
||||
#ifdef HAVE_NET_IF_DL_H
|
||||
#include <net/if_dl.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_LIBUTIL_H
|
||||
#include <libutil.h>
|
||||
#endif
|
||||
#ifdef HAVE_UTIL_H
|
||||
#include <util.h>
|
||||
#endif
|
||||
#include <netdb.h>
|
||||
|
||||
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
|
||||
#define SLEN(a) (a)->a ## _len
|
||||
#else
|
||||
static socklen_t
|
||||
socklen(u_int af)
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return sizeof(struct sockaddr_in);
|
||||
case AF_INET6:
|
||||
return sizeof(struct sockaddr_in6);
|
||||
case AF_LOCAL:
|
||||
return sizeof(struct sockaddr_un);
|
||||
#ifdef HAVE_NET_IF_DL_H
|
||||
case AF_LINK:
|
||||
return sizeof(struct sockaddr_dl);
|
||||
#endif
|
||||
#ifdef HAVE_NETATALK_AT_H
|
||||
case AF_APPLETALK:
|
||||
return sizeof(struct sockaddr_at);
|
||||
#endif
|
||||
default:
|
||||
return sizeof(struct sockaddr_storage);
|
||||
}
|
||||
}
|
||||
|
||||
#define SLEN(a) socklen((a)->a ## _family)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETATALK_AT_H
|
||||
static int
|
||||
debug_at(char *str, size_t len, const struct sockaddr_at *sat)
|
||||
{
|
||||
return snprintf(str, len, "sat_len=%u, sat_family=%u, sat_port=%u, "
|
||||
"sat_addr.s_net=%u, sat_addr.s_node=%u, "
|
||||
"sat_range.r_netrange.nr_phase=%u, "
|
||||
"sat_range.r_netrange.nr_firstnet=%u, "
|
||||
"sat_range.r_netrange.nr_lastnet=%u",
|
||||
SLEN(sat), sat->sat_family, sat->sat_port,
|
||||
sat->sat_addr.s_net, sat->sat_addr.s_node,
|
||||
sat->sat_range.r_netrange.nr_phase,
|
||||
sat->sat_range.r_netrange.nr_firstnet,
|
||||
sat->sat_range.r_netrange.nr_lastnet);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
debug_in(char *str, size_t len, const struct sockaddr_in *sin)
|
||||
{
|
||||
return snprintf(str, len, "sin_len=%u, sin_family=%u, sin_port=%u, "
|
||||
"sin_addr.s_addr=%08x",
|
||||
SLEN(sin), sin->sin_family, sin->sin_port,
|
||||
sin->sin_addr.s_addr);
|
||||
}
|
||||
|
||||
static int
|
||||
debug_in6(char *str, size_t len, const struct sockaddr_in6 *sin6)
|
||||
{
|
||||
const uint8_t *s = sin6->sin6_addr.s6_addr;
|
||||
|
||||
return snprintf(str, len, "sin6_len=%u, sin6_family=%u, sin6_port=%u, "
|
||||
"sin6_flowinfo=%u, "
|
||||
"sin6_addr=%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:"
|
||||
"%02x:%02x:%02x:%02x:%02x:%02x, sin6_scope_id=%u",
|
||||
SLEN(sin6), sin6->sin6_family, sin6->sin6_port,
|
||||
sin6->sin6_flowinfo, s[0x0], s[0x1], s[0x2], s[0x3], s[0x4], s[0x5],
|
||||
s[0x6], s[0x7], s[0x8], s[0x9], s[0xa], s[0xb], s[0xc], s[0xd],
|
||||
s[0xe], s[0xf], sin6->sin6_scope_id);
|
||||
}
|
||||
|
||||
static int
|
||||
debug_un(char *str, size_t len, const struct sockaddr_un *sun)
|
||||
{
|
||||
return snprintf(str, len, "sun_len=%u, sun_family=%u, sun_path=%*s",
|
||||
SLEN(sun), sun->sun_family, (int)sizeof(sun->sun_path),
|
||||
sun->sun_path);
|
||||
}
|
||||
|
||||
#ifdef HAVE_NET_IF_DL_H
|
||||
static int
|
||||
debug_dl(char *str, size_t len, const struct sockaddr_dl *sdl)
|
||||
{
|
||||
const uint8_t *s = (const void *)sdl->sdl_data;
|
||||
|
||||
return snprintf(str, len, "sdl_len=%u, sdl_family=%u, sdl_index=%u, "
|
||||
"sdl_type=%u, sdl_nlen=%u, sdl_alen=%u, sdl_slen=%u, sdl_data="
|
||||
"%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
SLEN(sdl), sdl->sdl_family, sdl->sdl_index,
|
||||
sdl->sdl_type, sdl->sdl_nlen, sdl->sdl_alen, sdl->sdl_slen,
|
||||
s[0x0], s[0x1], s[0x2], s[0x3], s[0x4], s[0x5],
|
||||
s[0x6], s[0x7], s[0x8], s[0x9], s[0xa], s[0xb]);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
sockaddr_snprintf(char * const sbuf, const size_t len, const char * const fmt,
|
||||
const struct sockaddr * const sa)
|
||||
{
|
||||
const void *a = NULL;
|
||||
char abuf[1024], nbuf[1024], *addr = NULL;
|
||||
|
||||
char Abuf[1024], pbuf[32], *name = NULL, *port = NULL;
|
||||
char *ebuf = &sbuf[len - 1], *buf = sbuf;
|
||||
const char *ptr, *s;
|
||||
int p = -1;
|
||||
#ifdef HAVE_NETATALK_AT_H
|
||||
const struct sockaddr_at *sat = NULL;
|
||||
#endif
|
||||
const struct sockaddr_in *sin4 = NULL;
|
||||
const struct sockaddr_in6 *sin6 = NULL;
|
||||
const struct sockaddr_un *sun = NULL;
|
||||
#ifdef HAVE_NET_IF_DL_H
|
||||
const struct sockaddr_dl *sdl = NULL;
|
||||
char *w = NULL;
|
||||
#endif
|
||||
int na = 1;
|
||||
|
||||
#define ADDC(c) do { if (buf < ebuf) *buf++ = c; else buf++; } \
|
||||
while (/*CONSTCOND*/0)
|
||||
#define ADDS(p) do { for (s = p; *s; s++) ADDC(*s); } \
|
||||
while (/*CONSTCOND*/0)
|
||||
#define ADDNA() do { if (na) ADDS("N/A"); } \
|
||||
while (/*CONSTCOND*/0)
|
||||
|
||||
switch (sa->sa_family) {
|
||||
case AF_UNSPEC:
|
||||
goto done;
|
||||
#ifdef HAVE_NETATALK_AT_H
|
||||
case AF_APPLETALK:
|
||||
sat = ((const struct sockaddr_at *)(const void *)sa);
|
||||
p = ntohs(sat->sat_port);
|
||||
(void)snprintf(addr = abuf, sizeof(abuf), "%u.%u",
|
||||
ntohs(sat->sat_addr.s_net), sat->sat_addr.s_node);
|
||||
(void)snprintf(port = pbuf, sizeof(pbuf), "%d", p);
|
||||
break;
|
||||
#endif
|
||||
case AF_LOCAL:
|
||||
sun = ((const struct sockaddr_un *)(const void *)sa);
|
||||
(void)strlcpy(addr = abuf, sun->sun_path, sizeof(abuf));
|
||||
break;
|
||||
case AF_INET:
|
||||
sin4 = ((const struct sockaddr_in *)(const void *)sa);
|
||||
p = ntohs(sin4->sin_port);
|
||||
a = &sin4->sin_addr;
|
||||
break;
|
||||
case AF_INET6:
|
||||
sin6 = ((const struct sockaddr_in6 *)(const void *)sa);
|
||||
p = ntohs(sin6->sin6_port);
|
||||
a = &sin6->sin6_addr;
|
||||
break;
|
||||
#ifdef HAVE_NET_IF_DL_H
|
||||
case AF_LINK:
|
||||
sdl = ((const struct sockaddr_dl *)(const void *)sa);
|
||||
(void)strlcpy(addr = abuf, link_ntoa(sdl), sizeof(abuf));
|
||||
if ((w = strchr(addr, ':')) != 0) {
|
||||
*w++ = '\0';
|
||||
addr = w;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (addr == abuf)
|
||||
name = addr;
|
||||
|
||||
if (a && getnameinfo(sa, (socklen_t)SLEN(sa), addr = abuf,
|
||||
(unsigned int)sizeof(abuf), NULL, 0,
|
||||
NI_NUMERICHOST|NI_NUMERICSERV) != 0)
|
||||
return -1;
|
||||
|
||||
for (ptr = fmt; *ptr; ptr++) {
|
||||
if (*ptr != '%') {
|
||||
ADDC(*ptr);
|
||||
continue;
|
||||
}
|
||||
next_char:
|
||||
switch (*++ptr) {
|
||||
case '?':
|
||||
na = 0;
|
||||
goto next_char;
|
||||
case 'a':
|
||||
ADDS(addr);
|
||||
break;
|
||||
case 'p':
|
||||
if (p != -1) {
|
||||
(void)snprintf(nbuf, sizeof(nbuf), "%d", p);
|
||||
ADDS(nbuf);
|
||||
} else
|
||||
ADDNA();
|
||||
break;
|
||||
case 'f':
|
||||
(void)snprintf(nbuf, sizeof(nbuf), "%d", sa->sa_family);
|
||||
ADDS(nbuf);
|
||||
break;
|
||||
case 'l':
|
||||
(void)snprintf(nbuf, sizeof(nbuf), "%d", SLEN(sa));
|
||||
ADDS(nbuf);
|
||||
break;
|
||||
case 'A':
|
||||
if (name)
|
||||
ADDS(name);
|
||||
else if (!a)
|
||||
ADDNA();
|
||||
else {
|
||||
getnameinfo(sa, (socklen_t)SLEN(sa),
|
||||
name = Abuf,
|
||||
(unsigned int)sizeof(nbuf), NULL, 0, 0);
|
||||
ADDS(name);
|
||||
}
|
||||
break;
|
||||
case 'P':
|
||||
if (port)
|
||||
ADDS(port);
|
||||
else if (p == -1)
|
||||
ADDNA();
|
||||
else {
|
||||
getnameinfo(sa, (socklen_t)SLEN(sa), NULL, 0,
|
||||
port = pbuf,
|
||||
(unsigned int)sizeof(pbuf), 0);
|
||||
ADDS(port);
|
||||
}
|
||||
break;
|
||||
case 'I':
|
||||
#ifdef HAVE_NET_IF_DL_H
|
||||
if (sdl && addr != abuf) {
|
||||
ADDS(abuf);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
ADDNA();
|
||||
}
|
||||
break;
|
||||
case 'F':
|
||||
if (sin6) {
|
||||
(void)snprintf(nbuf, sizeof(nbuf), "%d",
|
||||
sin6->sin6_flowinfo);
|
||||
ADDS(nbuf);
|
||||
break;
|
||||
} else {
|
||||
ADDNA();
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
if (sin6) {
|
||||
(void)snprintf(nbuf, sizeof(nbuf), "%d",
|
||||
sin6->sin6_scope_id);
|
||||
ADDS(nbuf);
|
||||
break;
|
||||
} else {
|
||||
ADDNA();
|
||||
}
|
||||
break;
|
||||
case 'R':
|
||||
#ifdef HAVE_NETATALK_AT_H
|
||||
if (sat) {
|
||||
const struct netrange *n =
|
||||
&sat->sat_range.r_netrange;
|
||||
(void)snprintf(nbuf, sizeof(nbuf),
|
||||
"%d:[%d,%d]", n->nr_phase , n->nr_firstnet,
|
||||
n->nr_lastnet);
|
||||
ADDS(nbuf);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
ADDNA();
|
||||
}
|
||||
break;
|
||||
case 'D':
|
||||
switch (sa->sa_family) {
|
||||
#ifdef HAVE_NETATALK_AT_H
|
||||
case AF_APPLETALK:
|
||||
debug_at(nbuf, sizeof(nbuf), sat);
|
||||
break;
|
||||
#endif
|
||||
case AF_LOCAL:
|
||||
debug_un(nbuf, sizeof(nbuf), sun);
|
||||
break;
|
||||
case AF_INET:
|
||||
debug_in(nbuf, sizeof(nbuf), sin4);
|
||||
break;
|
||||
case AF_INET6:
|
||||
debug_in6(nbuf, sizeof(nbuf), sin6);
|
||||
break;
|
||||
#ifdef HAVE_NET_IF_DL_H
|
||||
case AF_LINK:
|
||||
debug_dl(nbuf, sizeof(nbuf), sdl);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
ADDS(nbuf);
|
||||
break;
|
||||
default:
|
||||
ADDC('%');
|
||||
if (na == 0)
|
||||
ADDC('?');
|
||||
if (*ptr == '\0')
|
||||
goto done;
|
||||
/*FALLTHROUGH*/
|
||||
case '%':
|
||||
ADDC(*ptr);
|
||||
break;
|
||||
}
|
||||
na = 1;
|
||||
}
|
||||
done:
|
||||
if (buf < ebuf)
|
||||
*buf = '\0';
|
||||
else if (len != 0)
|
||||
sbuf[len - 1] = '\0';
|
||||
return (int)(buf - sbuf);
|
||||
}
|
96
20160409/port/strlcat.c
Normal file
96
20160409/port/strlcat.c
Normal file
@ -0,0 +1,96 @@
|
||||
/* $NetBSD: strlcat.c,v 1.2 2015/01/22 03:48:07 christos Exp $ */
|
||||
/* $OpenBSD: strlcat.c,v 1.10 2003/04/12 21:56:39 millert Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
|
||||
* FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined(_KERNEL) && !defined(_STANDALONE)
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
__RCSID("$NetBSD: strlcat.c,v 1.2 2015/01/22 03:48:07 christos Exp $");
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#ifdef _LIBC
|
||||
#include "namespace.h"
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _LIBC
|
||||
# ifdef __weak_alias
|
||||
__weak_alias(strlcat, _strlcat)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#else
|
||||
#include <lib/libkern/libkern.h>
|
||||
#endif /* !_KERNEL && !_STANDALONE */
|
||||
|
||||
#if !HAVE_STRLCAT
|
||||
/*
|
||||
* Appends src to string dst of size siz (unlike strncat, siz is the
|
||||
* full size of dst, not space left). At most siz-1 characters
|
||||
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
|
||||
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
|
||||
* If retval >= siz, truncation occurred.
|
||||
*/
|
||||
size_t
|
||||
strlcat(char *dst, const char *src, size_t siz)
|
||||
{
|
||||
#if 1
|
||||
char *d = dst;
|
||||
const char *s = src;
|
||||
size_t n = siz;
|
||||
size_t dlen;
|
||||
|
||||
/* Find the end of dst and adjust bytes left but don't go past end */
|
||||
while (n-- != 0 && *d != '\0')
|
||||
d++;
|
||||
dlen = d - dst;
|
||||
n = siz - dlen;
|
||||
|
||||
if (n == 0)
|
||||
return(dlen + strlen(s));
|
||||
while (*s != '\0') {
|
||||
if (n != 1) {
|
||||
*d++ = *s;
|
||||
n--;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
*d = '\0';
|
||||
|
||||
return(dlen + (s - src)); /* count does not include NUL */
|
||||
#else
|
||||
|
||||
/*
|
||||
* Find length of string in dst (maxing out at siz).
|
||||
*/
|
||||
size_t dlen = strnlen(dst, siz);
|
||||
|
||||
/*
|
||||
* Copy src into any remaining space in dst (truncating if needed).
|
||||
* Note strlcpy(dst, src, 0) returns strlen(src).
|
||||
*/
|
||||
return dlen + strlcpy(dst + dlen, src, siz - dlen);
|
||||
#endif
|
||||
}
|
||||
#endif
|
78
20160409/port/strlcpy.c
Normal file
78
20160409/port/strlcpy.c
Normal file
@ -0,0 +1,78 @@
|
||||
/* $NetBSD: strlcpy.c,v 1.2 2015/01/22 03:48:07 christos Exp $ */
|
||||
/* $OpenBSD: strlcpy.c,v 1.7 2003/04/12 21:56:39 millert Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
|
||||
* FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined(_KERNEL) && !defined(_STANDALONE)
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
__RCSID("$NetBSD: strlcpy.c,v 1.2 2015/01/22 03:48:07 christos Exp $");
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#ifdef _LIBC
|
||||
#include "namespace.h"
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _LIBC
|
||||
# ifdef __weak_alias
|
||||
__weak_alias(strlcpy, _strlcpy)
|
||||
# endif
|
||||
#endif
|
||||
#else
|
||||
#include <lib/libkern/libkern.h>
|
||||
#endif /* !_KERNEL && !_STANDALONE */
|
||||
|
||||
|
||||
#if !HAVE_STRLCPY
|
||||
/*
|
||||
* Copy src to string dst of size siz. At most siz-1 characters
|
||||
* will be copied. Always NUL terminates (unless siz == 0).
|
||||
* Returns strlen(src); if retval >= siz, truncation occurred.
|
||||
*/
|
||||
size_t
|
||||
strlcpy(char *dst, const char *src, size_t siz)
|
||||
{
|
||||
char *d = dst;
|
||||
const char *s = src;
|
||||
size_t n = siz;
|
||||
|
||||
/* Copy as many bytes as will fit */
|
||||
if (n != 0 && --n != 0) {
|
||||
do {
|
||||
if ((*d++ = *s++) == 0)
|
||||
break;
|
||||
} while (--n != 0);
|
||||
}
|
||||
|
||||
/* Not enough room in dst, add NUL and traverse rest of src */
|
||||
if (n == 0) {
|
||||
if (siz != 0)
|
||||
*d = '\0'; /* NUL-terminate dst */
|
||||
while (*s++)
|
||||
;
|
||||
}
|
||||
|
||||
return(s - src - 1); /* count does not include NUL */
|
||||
}
|
||||
#endif
|
61
20160409/port/strtoi.c
Normal file
61
20160409/port/strtoi.c
Normal file
@ -0,0 +1,61 @@
|
||||
/* $NetBSD: strtoi.c,v 1.3 2015/01/22 03:10:50 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2005 The DragonFly Project. All rights reserved.
|
||||
* Copyright (c) 2003 Citrus Project,
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Created by Kamil Rytarowski, based on ID:
|
||||
* NetBSD: src/common/lib/libc/stdlib/strtoul.c,v 1.3 2008/08/20 19:58:34 oster Exp
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: strtoi.c,v 1.3 2015/01/22 03:10:50 christos Exp $");
|
||||
|
||||
#if defined(_KERNEL)
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <lib/libkern/libkern.h>
|
||||
#elif defined(_STANDALONE)
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <lib/libkern/libkern.h>
|
||||
#include <lib/libsa/stand.h>
|
||||
#else
|
||||
#include <stddef.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#define _FUNCNAME strtoi
|
||||
#define __TYPE intmax_t
|
||||
#define __WRAPPED strtoimax
|
||||
|
||||
#if !HAVE_STRTOI
|
||||
#include "_strtoi.h"
|
||||
#endif
|
12
20160409/test/Makefile
Normal file
12
20160409/test/Makefile
Normal file
@ -0,0 +1,12 @@
|
||||
# $NetBSD: Makefile,v 1.3 2015/05/30 22:40:38 christos Exp $
|
||||
|
||||
MKMAN=no
|
||||
|
||||
PROGS=srvtest cltest
|
||||
SRCS.srvtest = srvtest.c
|
||||
SRCS.cltest = cltest.c
|
||||
CPPFLAGS+=-DBLDEBUG
|
||||
LDADD+=-lutil
|
||||
DPADD+=${LIBUTIL}
|
||||
|
||||
.include <bsd.prog.mk>
|
136
20160409/test/cltest.c
Normal file
136
20160409/test/cltest.c
Normal file
@ -0,0 +1,136 @@
|
||||
/* $NetBSD: cltest.c,v 1.6 2015/01/22 05:44:28 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: cltest.c,v 1.6 2015/01/22 05:44:28 christos Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <err.h>
|
||||
#ifdef HAVE_UTIL_H
|
||||
#include <util.h>
|
||||
#endif
|
||||
|
||||
static __dead void
|
||||
usage(int c)
|
||||
{
|
||||
warnx("Unknown option `%c'", (char)c);
|
||||
fprintf(stderr, "Usage: %s [-u] [-a <addr>] [-m <msg>] [-p <port>]\n",
|
||||
getprogname());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static void
|
||||
getaddr(const char *a, in_port_t p, struct sockaddr_storage *ss,
|
||||
socklen_t *slen)
|
||||
{
|
||||
int c;
|
||||
|
||||
memset(ss, 0, sizeof(*ss));
|
||||
p = htons(p);
|
||||
|
||||
if (strchr(a, ':')) {
|
||||
struct sockaddr_in6 *s6 = (void *)ss;
|
||||
c = inet_pton(AF_INET6, a, &s6->sin6_addr);
|
||||
s6->sin6_family = AF_INET6;
|
||||
*slen = sizeof(*s6);
|
||||
s6->sin6_port = p;
|
||||
} else {
|
||||
struct sockaddr_in *s = (void *)ss;
|
||||
c = inet_pton(AF_INET, a, &s->sin_addr);
|
||||
s->sin_family = AF_INET;
|
||||
*slen = sizeof(*s);
|
||||
s->sin_port = p;
|
||||
}
|
||||
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
|
||||
ss->ss_len = (uint8_t)*slen;
|
||||
#endif
|
||||
if (c == -1)
|
||||
err(EXIT_FAILURE, "Invalid address `%s'", a);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int sfd;
|
||||
int c;
|
||||
struct sockaddr_storage ss;
|
||||
const char *msg = "hello";
|
||||
const char *addr = "127.0.0.1";
|
||||
int type = SOCK_STREAM;
|
||||
in_port_t port = 6161;
|
||||
socklen_t slen;
|
||||
char buf[128];
|
||||
|
||||
while ((c = getopt(argc, argv, "a:m:p:u")) != -1) {
|
||||
switch (c) {
|
||||
case 'a':
|
||||
addr = optarg;
|
||||
break;
|
||||
case 'm':
|
||||
msg = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
port = (in_port_t)atoi(optarg);
|
||||
break;
|
||||
case 'u':
|
||||
type = SOCK_DGRAM;
|
||||
break;
|
||||
default:
|
||||
usage(c);
|
||||
}
|
||||
}
|
||||
|
||||
getaddr(addr, port, &ss, &slen);
|
||||
|
||||
if ((sfd = socket(AF_INET, type, 0)) == -1)
|
||||
err(EXIT_FAILURE, "socket");
|
||||
|
||||
sockaddr_snprintf(buf, sizeof(buf), "%a:%p", (const void *)&ss);
|
||||
printf("connecting to: %s\n", buf);
|
||||
if (connect(sfd, (const void *)&ss, slen) == -1)
|
||||
err(EXIT_FAILURE, "connect");
|
||||
|
||||
size_t len = strlen(msg) + 1;
|
||||
if (write(sfd, msg, len) != (ssize_t)len)
|
||||
err(EXIT_FAILURE, "write");
|
||||
return 0;
|
||||
}
|
220
20160409/test/srvtest.c
Normal file
220
20160409/test/srvtest.c
Normal file
@ -0,0 +1,220 @@
|
||||
/* $NetBSD: srvtest.c,v 1.10 2015/05/30 22:40:38 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: srvtest.c,v 1.10 2015/05/30 22:40:38 christos Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <poll.h>
|
||||
#include <err.h>
|
||||
|
||||
#include "blacklist.h"
|
||||
#ifdef BLDEBUG
|
||||
#include "bl.h"
|
||||
static void *b;
|
||||
#endif
|
||||
|
||||
#ifndef INFTIM
|
||||
#define INFTIM -1
|
||||
#endif
|
||||
|
||||
static void
|
||||
process_tcp(int afd)
|
||||
{
|
||||
ssize_t n;
|
||||
char buffer[256];
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
|
||||
if ((n = read(afd, buffer, sizeof(buffer))) == -1)
|
||||
err(1, "read");
|
||||
buffer[sizeof(buffer) - 1] = '\0';
|
||||
printf("%s: sending %d %s\n", getprogname(), afd, buffer);
|
||||
#ifdef BLDEBUG
|
||||
blacklist_r(b, 1, afd, buffer);
|
||||
#else
|
||||
blacklist(1, afd, buffer);
|
||||
#endif
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void
|
||||
process_udp(int afd)
|
||||
{
|
||||
ssize_t n;
|
||||
char buffer[256];
|
||||
struct sockaddr_storage ss;
|
||||
socklen_t slen;
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
|
||||
slen = (socklen_t)sizeof(ss);
|
||||
memset(&ss, 0, sizeof(ss));
|
||||
if ((n = recvfrom(afd, buffer, sizeof(buffer), 0, (void *)&ss,
|
||||
&slen)) == -1)
|
||||
err(1, "recvfrom");
|
||||
buffer[sizeof(buffer) - 1] = '\0';
|
||||
printf("%s: sending %d %s\n", getprogname(), afd, buffer);
|
||||
blacklist_sa(1, afd, (void *)&ss, slen, buffer);
|
||||
exit(0);
|
||||
}
|
||||
static int
|
||||
cr(int af, int type, in_port_t p)
|
||||
{
|
||||
int sfd;
|
||||
struct sockaddr_storage ss;
|
||||
socklen_t slen;
|
||||
sfd = socket(af == AF_INET ? PF_INET : PF_INET6, type, 0);
|
||||
if (sfd == -1)
|
||||
err(1, "socket");
|
||||
|
||||
p = htons(p);
|
||||
memset(&ss, 0, sizeof(ss));
|
||||
if (af == AF_INET) {
|
||||
struct sockaddr_in *s = (void *)&ss;
|
||||
s->sin_family = AF_INET;
|
||||
slen = sizeof(*s);
|
||||
s->sin_port = p;
|
||||
} else {
|
||||
struct sockaddr_in6 *s6 = (void *)&ss;
|
||||
s6->sin6_family = AF_INET6;
|
||||
slen = sizeof(*s6);
|
||||
s6->sin6_port = p;
|
||||
}
|
||||
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
|
||||
ss.ss_len = (uint8_t)slen;
|
||||
#endif
|
||||
|
||||
if (bind(sfd, (const void *)&ss, slen) == -1)
|
||||
err(1, "bind");
|
||||
|
||||
if (type != SOCK_DGRAM)
|
||||
if (listen(sfd, 5) == -1)
|
||||
err(1, "listen");
|
||||
return sfd;
|
||||
}
|
||||
|
||||
static void
|
||||
handle(int type, int sfd)
|
||||
{
|
||||
struct sockaddr_storage ss;
|
||||
socklen_t alen = sizeof(ss);
|
||||
int afd;
|
||||
|
||||
if (type != SOCK_DGRAM) {
|
||||
if ((afd = accept(sfd, (void *)&ss, &alen)) == -1)
|
||||
err(1, "accept");
|
||||
} else
|
||||
afd = sfd;
|
||||
|
||||
/* Create child process */
|
||||
switch (fork()) {
|
||||
case -1:
|
||||
err(1, "fork");
|
||||
case 0:
|
||||
if (type == SOCK_DGRAM)
|
||||
process_udp(afd);
|
||||
else
|
||||
process_tcp(afd);
|
||||
break;
|
||||
default:
|
||||
close(afd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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[])
|
||||
{
|
||||
#ifdef __linux__
|
||||
#define NUMFD 1
|
||||
#else
|
||||
#define NUMFD 2
|
||||
#endif
|
||||
struct pollfd pfd[NUMFD];
|
||||
int type = SOCK_STREAM, c;
|
||||
in_port_t port = 6161;
|
||||
|
||||
signal(SIGCHLD, SIG_IGN);
|
||||
|
||||
#ifdef BLDEBUG
|
||||
b = bl_create(false, "blsock", vsyslog);
|
||||
#endif
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
pfd[0].fd = cr(AF_INET, type, port);
|
||||
pfd[0].events = POLLIN;
|
||||
#if NUMFD > 1
|
||||
pfd[1].fd = cr(AF_INET6, type, port);
|
||||
pfd[1].events = POLLIN;
|
||||
#endif
|
||||
|
||||
for (;;) {
|
||||
if (poll(pfd, __arraycount(pfd), INFTIM) == -1)
|
||||
err(1, "poll");
|
||||
for (size_t i = 0; i < __arraycount(pfd); i++) {
|
||||
if ((pfd[i].revents & POLLIN) == 0)
|
||||
continue;
|
||||
handle(type, pfd[i].fd);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user