summaryrefslogtreecommitdiffstats
path: root/src/ipv6nd.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2019-11-28 16:41:15 +0000
committerRoy Marples <roy@marples.name>2019-11-28 16:41:15 +0000
commitd5786118da1bad4c247631cae86344f1b249a8cb (patch)
treeb62b1e3a7ba544c9e842e6f595b25fdaab8059b4 /src/ipv6nd.c
parentf90486b1657f0331ae5e7d817b9ba3de90856d52 (diff)
downloaddhcpcd-d5786118da1bad4c247631cae86344f1b249a8cb.tar.xz
privsep: Add support for priviledge separation
Not enabled by default - enable with ./configure --enable-privsep Requires a user added to the system - default _dhcpcd Several processes will be spawned off the main state engine: a privileged actioneer and a generic network proxy. Only the privileged actioneer process will retain root permissions. When required, the privileged actioneer will also spawn BPF listeners for BOOTP (DHCP) and ARP. The BOOTP BPF listener should be a short lived process. On kernels with RFC 5227 support, the ARP BPF listener will only be used for ARPing and announcing a preferred address and will also be a short lived process. When not running in master mode, an address listener will be spawned for each address (with the exception of RA dervived addresses) dhcpcd cares about. TODO: * Solaris support. * ARP BPF address filtering.
Diffstat (limited to 'src/ipv6nd.c')
-rw-r--r--src/ipv6nd.c47
1 files changed, 36 insertions, 11 deletions
diff --git a/src/ipv6nd.c b/src/ipv6nd.c
index 06e158b9..ebd427d1 100644
--- a/src/ipv6nd.c
+++ b/src/ipv6nd.c
@@ -53,6 +53,7 @@
#include "ipv6.h"
#include "ipv6nd.h"
#include "logerr.h"
+#include "privsep.h"
#include "route.h"
#include "script.h"
@@ -272,7 +273,7 @@ ipv6nd_open(struct interface *ifp)
return fd;
}
#else
-static int
+int
ipv6nd_open(struct dhcpcd_ctx *ctx)
{
int fd;
@@ -285,7 +286,8 @@ ipv6nd_open(struct dhcpcd_ctx *ctx)
return -1;
ctx->nd_fd = fd;
- eloop_event_add(ctx->eloop, fd, ipv6nd_handledata, ctx);
+ if (!(ctx->options & DHCPCD_PRIVSEP))
+ eloop_event_add(ctx->eloop, fd, ipv6nd_handledata, ctx);
return fd;
}
#endif
@@ -363,6 +365,13 @@ ipv6nd_sendrsprobe(void *arg)
memcpy(CMSG_DATA(cm), &pi, sizeof(pi));
logdebugx("%s: sending Router Solicitation", ifp->name);
+#ifdef PRIVSEP
+ if (ifp->ctx->options & DHCPCD_PRIVSEP) {
+ if (ps_inet_sendmsg(ifp->ctx, PS_ND, &msg) == -1)
+ logerr(__func__);
+ goto sent;
+ }
+#endif
#ifdef __sun
s = state->nd_fd;
#else
@@ -376,6 +385,9 @@ ipv6nd_sendrsprobe(void *arg)
* associate with an access point. */
}
+#ifdef PRIVSEP
+sent:
+#endif
if (state->rsprobes++ < MAX_RTR_SOLICITATIONS)
eloop_timeout_add_sec(ifp->ctx->eloop,
RTR_SOLICITATION_INTERVAL, ipv6nd_sendrsprobe, ifp);
@@ -424,6 +436,14 @@ ipv6nd_sendadvertisement(void *arg)
cm->cmsg_len = CMSG_LEN(sizeof(pi));
memcpy(CMSG_DATA(cm), &pi, sizeof(pi));
logdebugx("%s: sending NA for %s", ifp->name, ia->saddr);
+
+#ifdef PRIVSEP
+ if (ifp->ctx->options & DHCPCD_PRIVSEP) {
+ if (ps_inet_sendmsg(ifp->ctx, PS_ND, &msg) == -1)
+ logerr(__func__);
+ goto sent;
+ }
+#endif
#ifdef __sun
s = state->nd_fd;
#else
@@ -432,6 +452,9 @@ ipv6nd_sendadvertisement(void *arg)
if (sendmsg(s, &msg, 0) == -1)
logerr(__func__);
+#ifdef PRIVSEP
+sent:
+#endif
if (++ia->na_count < MAX_NEIGHBOR_ADVERTISEMENT) {
eloop_timeout_add_sec(ctx->eloop,
state->retrans / 1000, ipv6nd_sendadvertisement, ia);
@@ -1763,7 +1786,7 @@ ipv6nd_drop(struct interface *ifp)
}
}
-static void
+void
ipv6nd_recvmsg(struct dhcpcd_ctx *ctx, struct msghdr *msg)
{
struct sockaddr_in6 *from = (struct sockaddr_in6 *)msg->msg_name;
@@ -1865,17 +1888,19 @@ ipv6nd_startrs1(void *arg)
#endif
}
+ if (!(ifp->ctx->options & DHCPCD_PRIVSEP)) {
#ifdef __sun
- if (ipv6nd_open(ifp) == -1) {
- logerr(__func__);
- return;
- }
+ if (ipv6nd_open(ifp) == -1) {
+ logerr(__func__);
+ return;
+ }
#else
- if (ipv6nd_open(ifp->ctx) == -1) {
- logerr(__func__);
- return;
- }
+ if (ipv6nd_open(ifp->ctx) == -1) {
+ logerr(__func__);
+ return;
+ }
#endif
+ }
/* Always make a new probe as the underlying hardware
* address could have changed. */