Commit Graph

704 Commits

Author SHA1 Message Date
Nicholas J. Kain
aa684baad7
Don't use ctype.h functions. 2023-02-11 20:45:30 -05:00
Nicholas J. Kain
841c8663e9
Make example s6 script handle empty leasefile properly.
Prior to this change, ndhc would fail to run with a malformed
command error if the leasefile was empty since the -r parameter
requires an argument.

Note that this script requires execline 2.9.1.0 for the
eltest program.  For earlier versions of s6, it should be
fine to use the POSIX test program instead.
2023-01-18 12:54:55 -05:00
Nicholas J. Kain
44511e6789
Don't overwrite a possibly valid leasefile if we have no valid lease. 2023-01-18 08:08:33 -05:00
Nicholas J. Kain
1b8dc7f05e
random: Use sfc64 instead of gjrand. 2022-10-13 08:43:11 -04:00
Nicholas J. Kain
1c1ea86604
ifset: Use a slightly better portable ctz().
The behavior is identical but the codegen is improved.
2022-09-24 14:12:02 -04:00
Nicholas J. Kain
95c70ba2a7
Properly force a restart if scriptd exists and dies.
Also use designated initializers for the poll structure.
2022-09-08 07:21:57 -04:00
Nicholas J. Kain
26f81272ee
scriptd: Signal handlers don't need SA_NOCLDWAIT set. 2022-09-08 07:17:11 -04:00
Nicholas J. Kain
5eccd4893a
Set FD_CLOEXEC on scriptd(Sock|Stream).
These have no reason to be inherited by the script when it is
run by posix_spawn().
2022-09-07 17:25:22 -04:00
Nicholas J. Kain
f7db9fd5e7
Correct regression introduced by previous commit.
safe_recv(..., len), when used on a blocking fd, will attempt
to call recv and collect data until either EOF, a hard error,
or len bytes are collected.

The previous commit used safe_recv() in a blocking mode to read
a single byte into a buffer that was larger than a byte.  This
would cause ndhc to stall as safe_recv() would try to fill that
buffer when no more data would ever be sent.

This issue would only happen if ndhc is supposed to run a script.

Introduce and use safe_recv_once() that will correct this problem and
fill the semantic gap for blocking fds.  I add a new call because in
some cases the above behavior might be required for a blocking fd, too.

Note that the above issue is not a problem for nonblocking fds; the
EAGAIN or EWOULDBLOCK path will return a short read.
2022-09-07 17:08:43 -04:00
Nicholas J. Kain
ebd2c4c01a
scriptd: Wait to notify s6 until script completes.
The motivation here is to be safe in cases where the script
is setting up firewall rules or tunnels and where subsequent
tasks require these to be complete before starting.

I expect that this is a common case where a script is used.

The implementation behaves almost identically to how ifchd works.
2022-09-07 04:45:30 -04:00
Nicholas J. Kain
4d739acbdd
Use a helper to ensure xid always changes when we advance it.
The purpose of the changing xid is to prevent misinterpreting
delayed messages, and the rare chance where it's randomly the
same breaks this sequence-id property.
2022-08-28 04:41:11 -04:00
Nicholas J. Kain
9b8e2facbf
Advance the xid before we send each DHCPDISCOVER. 2022-08-28 04:06:15 -04:00
Nicholas J. Kain
c755902fbc
Reseed the PRNG whenever we reset the DHCP state. 2022-08-28 04:00:06 -04:00
Nicholas J. Kain
1f0a8f29de
Use the HWRNG for generating DUIDs and IAIDs.
Before these were generated from a freshly seeded PRNG which reduces the
state space of possible DUIDs and skews the distribution of both DUIDs
and IAIDs as a function of the PRNG choice.

None of this really matters much in practice, but do things right.
2022-08-28 04:00:06 -04:00
Nicholas J. Kain
d43fc12306
Advance the xid after we consume a DHCPACK or DHCPNAK.
This isn't strictly required by the RFC but it is good practice.
2022-08-28 04:00:02 -04:00
Nicholas J. Kain
6446f80a02
privs: Don't use libc isdigit()
Avoid locale dependence and UB risk from integer promotion
2022-08-27 10:29:11 -04:00
Nicholas J. Kain
7fb968e861
Use memccpy() and memcpy() instead of nstr{cpy,lcpy,cat}.
These are standard, either in POSIX or C23.

The semantics are slightly different as the error path does not
enforce null-termination in the function itself, so enforce that
by hand.  As a nice side effect, this makes those error paths
easier to audit.
2022-08-27 04:11:12 -04:00
Nicholas J. Kain
e223b4c5a8 Use {O,SOCK}_CLOEXEC more consistently. 2022-08-13 00:42:27 -04:00
Nicholas J. Kain
867b70e83e nk/privs.c: Fix a trivial warning. 2022-08-10 12:10:55 -04:00
Nicholas J. Kain
6c44f536ad Build with -Wstrict-overflow=5 and fix revealed warnings.
Some of these are actual bugs, but none are security-sensitive.
2022-08-10 11:32:30 -04:00
Nicholas J. Kain
9338aa37c2 Use libc snprintf and nstr{cpy,cat}.
We don't need async-safe snprintf anymore, and nstr{cpy,cat} are
more ergonomic and efficient where they can used.
2022-08-09 14:17:31 -04:00
Nicholas J. Kain
898765e0a8 scriptd: Use posix_spawn rather than fork/exec.
Also don't bother providing an artificial environment.
2022-08-09 13:40:10 -04:00
Nicholas J. Kain
45e8e0bad2 Remove an obsolete comment. 2022-08-06 12:41:35 -04:00
Nicholas J. Kain
cee287a522 Add Codeberg as a git source. 2022-08-03 20:58:19 -04:00
Nicholas J. Kain
cd859ce8c3 nk/privs: Make capabilities conditional on __linux__ define. 2022-03-08 23:35:12 -05:00
Nicholas J. Kain
9998790488 nk/privs: Use NO_NEW_PRIVS by default when setting non-empty capset.
There's no need to gate it behind a #define anymore given that
Linux 3.5 was released in 2012.
2022-03-08 14:54:57 -05:00
Nicholas J. Kain
b21edf205a nk/hwrng: Use libc wrapper for getrandom by default. 2022-03-08 13:46:23 -05:00
Nicholas J. Kain
0b53d93648 Update documentation and add more configuration examples. 2022-03-08 12:38:27 -05:00
Nicholas J. Kain
5bca0a3d48 Add example config file and s6 run file. 2022-03-08 12:23:05 -05:00
Nicholas J. Kain
484a9c516b Use stb_snprintf instead of libc snprintf.
This gives us consistent behavior and stb_snprintf is async signal
safe.
2022-03-07 20:42:00 -05:00
Nicholas J. Kain
3773acf64d When rfkill is disabled, resync the carrier state to be safe.
This change guards against possible regressions introduced by
f3766990f9 if rfkill were to
prevent netlink carrier up events from being delivered while
rfkill is in effect for the interface.
2022-03-07 14:00:59 -05:00
Nicholas J. Kain
f6dfd9a58a nk/exec.c: Update documentation comment 2022-02-25 07:10:07 -05:00
Nicholas J. Kain
9cd65f35d9 Get rid of nk/copy_cmdarg.h 2022-02-25 07:01:55 -05:00
Nicholas J. Kain
12631c59bb Update to latest nk/exec.c; see ncron repo for changes.
Notably, nk_generate_env() no longer calls malloc().
2022-02-25 06:43:42 -05:00
Nicholas J. Kain
7572e2eb8b snprintf() truncation checks were one byte too conservative. 2022-02-25 06:18:08 -05:00
Nicholas J. Kain
ba8f674e15 nk/exec: Simplify and remove double null termination.
The current code pads with an extra character that is then rewritten
into a null character.  This isn't necessary with post-C99
implementations of standardized snprintf, so get rid of it.

Also add a note warning that nk_generate_env() and nk_execute()
are not async signal safe and are thus unsuitable for use in
multithreaded processes.

nk_execute() could be rewritten to be async signal safe without much
trouble, as the only problem point is snprintf() which is not guaranteed
to be async signal safe by POSIX.

However, nk_generate_env() performs chroot() if a chroot_path is
specified, and chroot() is not async signal safe in POSIX.
Additionally, malloc() can be called in rare cases where user
information fields are very long, and malloc() is obviously not async
signal safe.  Finally, snprintf() is used here, too, but it could be
replaced.

Converting to posix_spawn() is a no-go because posix_spawn() has no
facility for changing rlimits or chroot on the spawned process.

In summary, I don't think the gains are worth it.  Multithreaded
processes should just not fork().
2022-02-25 04:53:02 -05:00
Nicholas J. Kain
62aef529f4 Use safe_write() in nk/exec.c 2022-02-25 00:05:57 -05:00
Nicholas J. Kain
286b86d62c Preserve errno across signals. 2022-02-24 06:57:49 -05:00
Nicholas J. Kain
a9874d4959 Support running an executable file when a new lease is acquired.
If no 'script-file = SCRIPTFILE' is specified in the configuration
file and if no '-X SCRIPTFILE' or '--script-file SCRIPTFILE'
command argument is provided, then this functionality is entirely
inactive and no associated subprocess is spawned.

Otherwise, ndhc will spawn a subprocess that runs as root that has the
sole job of forking off a subprocess that exec's the specified script in
a sanitized and fixed-state environment whenever a new DHCPv4 lease is
acquired.

Note that this script is provided no information about ndhc or the
DHCP state in the environment or in any argument fields; it is the
responsibility of this script to gather whatever information it needs
from either the filesystem or syscalls.  This design is intended to
avoid the historical problems that are associated with dhcp clients
invoking scripts.

The path of the scriptfile cannot be changed after ndhc is initially
run; ndhc forks off the privsep script subprocess that executes scripts
after it has read the configuration file and command arguments, but
before it begins processing network data; thus, it is impossible for the
network-handling process to modify or influence the script assuming
proper OS memory protection.

The privsep channel communicates that the script should be run by simply
writing a newline; anything else will result in ndhc terminating itself.

Before the recommended way to update system state after a change in
lease information was to run the fcactus program and watch the
associated leasefile for the interface for modification; now no external
program is needed for this job.
2022-02-24 03:58:37 -05:00
Nicholas J. Kain
2fb16567f1 Support s6 service startup notification
This can be enabled via the s6-notify configure option; see
http://www.skarnet.org/software/s6/notifywhenup.html for details.

ndhc will signal that it is ready when the first valid lease is
obtained.  Programs dependent on a working network interface
can then simply use s6-wait on the associated ndhc service dir.

A typical command line option assuming the s6 service directory
notification-fd contains '3' would be '--s6-notify 3', and
a typical configure file option would be 's6-notify 3'.
2022-02-13 05:25:17 -05:00
Nicholas J. Kain
d67e1599df Update the manpage a bit. 2022-02-12 12:57:10 -05:00
Nicholas J. Kain
416bed7eec Minor README update 2022-02-06 21:02:14 -05:00
Nicholas J. Kain
1732bccccc Relicense as MIT.
It's a lot more common than BSD 2-clause it is both compatible
and nearly identical in effect.
2022-02-06 20:05:29 -05:00
Nicholas J. Kain
9fddfbda61 Simplify Makefile 2022-01-23 19:37:40 -05:00
Nicholas J. Kain
6f85b2aaf2 Update Makefile to generate dependency info 2022-01-23 18:42:40 -05:00
Nicholas J. Kain
8db8c5589d Replace CMake with GNU Make.
There was previously support for both build systems, but ndhc is
undemanding and there is no point in maintaining a complex
CMake build.
2022-01-22 18:39:41 -05:00
Nicholas J. Kain
1055c27bcf Update Makefile build flags 2022-01-22 15:49:16 -05:00
Nicholas J. Kain
a71b95ad34 CMake: Update to latest policies 2022-01-21 19:01:37 -05:00
Nicholas J. Kain
6ec0a5c731 Replace mostly obsolete -[static 1] with reliable old *-.
This notation originally had the sole advantage of implying
that the pointer was non-NULL, but it has seen little use and
now clang presents warnings about it in certain contexts.
2022-01-11 22:35:19 -05:00
Nicholas J. Kain
6047f04a12 Guard against carrier being spuriously set down.
Corrects a possible regression introduced by the previous patch.
2022-01-11 22:16:44 -05:00