svn commit: r350556 - head/sbin/ping6

Alan Somers asomers at FreeBSD.org
Sat Aug 3 13:53:15 UTC 2019


Author: asomers
Date: Sat Aug  3 13:53:14 2019
New Revision: 350556
URL: https://svnweb.freebsd.org/changeset/base/350556

Log:
  Capsicumize ping6
  
  Add capsicum support to ping6, mostly copying the strategy used for ping.
  
  Submitted by:	Ján Sučan <jansucan at gmail.com>
  Reviewed by:	markj
  MFC after:	2 weeks
  Sponsored by:	Google, inc. (Google Summer of Code 2019)
  Differential Revision:	https://reviews.freebsd.org/D21050

Modified:
  head/sbin/ping6/Makefile
  head/sbin/ping6/ping6.c

Modified: head/sbin/ping6/Makefile
==============================================================================
--- head/sbin/ping6/Makefile	Sat Aug  3 04:30:22 2019	(r350555)
+++ head/sbin/ping6/Makefile	Sat Aug  3 13:53:14 2019	(r350556)
@@ -1,5 +1,7 @@
 # $FreeBSD$
 
+.include <src.opts.mk>
+
 PACKAGE=runtime
 PROG=	ping6
 MAN=	ping6.8
@@ -11,5 +13,13 @@ BINOWN=	root
 BINMODE=4555
 
 LIBADD=	ipsec m md
+
+.if ${MK_DYNAMICROOT} == "no"
+.warning ${PROG} built without libcasper support
+.elif ${MK_CASPER} != "no" && !defined(RESCUE)
+LIBADD+=	casper
+LIBADD+=	cap_dns
+CFLAGS+=-DWITH_CASPER
+.endif
 
 .include <bsd.prog.mk>

Modified: head/sbin/ping6/ping6.c
==============================================================================
--- head/sbin/ping6/ping6.c	Sat Aug  3 04:30:22 2019	(r350555)
+++ head/sbin/ping6/ping6.c	Sat Aug  3 13:53:14 2019	(r350556)
@@ -104,6 +104,7 @@ __FBSDID("$FreeBSD$");
  */
 
 #include <sys/param.h>
+#include <sys/capsicum.h>
 #include <sys/uio.h>
 #include <sys/socket.h>
 #include <sys/time.h>
@@ -118,6 +119,10 @@ __FBSDID("$FreeBSD$");
 #include <arpa/nameser.h>
 #include <netdb.h>
 
+#include <capsicum_helpers.h>
+#include <casper/cap_dns.h>
+#include <libcasper.h>
+
 #include <ctype.h>
 #include <err.h>
 #include <errno.h>
@@ -214,7 +219,8 @@ static struct sockaddr_in6 dst;	/* who to ping6 */
 static struct sockaddr_in6 src;	/* src addr of this packet */
 static socklen_t srclen;
 static size_t datalen = DEFDATALEN;
-static int s;			/* socket file descriptor */
+static int ssend;		/* send socket file descriptor */
+static int srecv;		/* receive socket file descriptor */
 static u_char outpack[MAXPACKETLEN];
 static char BSPACE = '\b';	/* characters written for flood */
 static char BBELL = '\a';	/* characters written for AUDIBLE */
@@ -224,6 +230,7 @@ static int ident;		/* process id to identify our packe
 static u_int8_t nonce[8];	/* nonce field for node information */
 static int hoplimit = -1;	/* hoplimit */
 static u_char *packet = NULL;
+static cap_channel_t *capdns;
 
 /* counters */
 static long nmissedmax;		/* max value of ntransmitted - nreceived - 1 */
@@ -256,6 +263,7 @@ static volatile sig_atomic_t seeninfo;
 #endif
 
 int	 main(int, char *[]);
+static cap_channel_t *capdns_setup(void);
 static void	 fill(char *, char *);
 static int	 get_hoplim(struct msghdr *);
 static int	 get_pathmtu(struct msghdr *);
@@ -318,6 +326,9 @@ main(int argc, char *argv[])
 #ifdef IPV6_USE_MIN_MTU
 	int mflag = 0;
 #endif
+	cap_rights_t rights_srecv;
+	cap_rights_t rights_ssend;
+	cap_rights_t rights_stdin;
 
 	/* just to be sure */
 	memset(&smsghdr, 0, sizeof(smsghdr));
@@ -325,6 +336,7 @@ main(int argc, char *argv[])
 
 	alarmtimeout = preload = 0;
 	datap = &outpack[ICMP6ECHOLEN + ICMP6ECHOTMLEN];
+	capdns = capdns_setup();
 #ifndef IPSEC
 #define ADDOPTS
 #else
@@ -503,7 +515,7 @@ main(int argc, char *argv[])
 			hints.ai_socktype = SOCK_RAW;
 			hints.ai_protocol = IPPROTO_ICMPV6;
 
-			error = getaddrinfo(optarg, NULL, &hints, &res);
+			error = cap_getaddrinfo(capdns, optarg, NULL, &hints, &res);
 			if (error) {
 				errx(1, "invalid source address: %s",
 				     gai_strerror(error));
@@ -619,14 +631,14 @@ main(int argc, char *argv[])
 	} else
 		target = argv[argc - 1];
 
-	/* getaddrinfo */
+	/* cap_getaddrinfo */
 	memset(&hints, 0, sizeof(struct addrinfo));
 	hints.ai_flags = AI_CANONNAME;
 	hints.ai_family = AF_INET6;
 	hints.ai_socktype = SOCK_RAW;
 	hints.ai_protocol = IPPROTO_ICMPV6;
 
-	error = getaddrinfo(target, NULL, &hints, &res);
+	error = cap_getaddrinfo(capdns, target, NULL, &hints, &res);
 	if (error)
 		errx(1, "%s", gai_strerror(error));
 	if (res->ai_canonname)
@@ -635,13 +647,16 @@ main(int argc, char *argv[])
 		hostname = target;
 
 	if (!res->ai_addr)
-		errx(1, "getaddrinfo failed");
+		errx(1, "cap_getaddrinfo failed");
 
 	(void)memcpy(&dst, res->ai_addr, res->ai_addrlen);
 
-	if ((s = socket(res->ai_family, res->ai_socktype,
+	if ((ssend = socket(res->ai_family, res->ai_socktype,
 	    res->ai_protocol)) < 0)
-		err(1, "socket");
+		err(1, "socket ssend");
+	if ((srecv = socket(res->ai_family, res->ai_socktype,
+	    res->ai_protocol)) < 0)
+		err(1, "socket srecv");
 	freeaddrinfo(res);
 
 	/* set the source address if specified. */
@@ -656,7 +671,7 @@ main(int argc, char *argv[])
 			if (dst.sin6_scope_id == 0)
 				dst.sin6_scope_id = src.sin6_scope_id;
 		}
-		if (bind(s, (struct sockaddr *)&src, srclen) != 0)
+		if (bind(ssend, (struct sockaddr *)&src, srclen) != 0)
 			err(1, "bind");
 	}
 	/* set the gateway (next hop) if specified */
@@ -666,15 +681,15 @@ main(int argc, char *argv[])
 		hints.ai_socktype = SOCK_RAW;
 		hints.ai_protocol = IPPROTO_ICMPV6;
 
-		error = getaddrinfo(gateway, NULL, &hints, &res);
+		error = cap_getaddrinfo(capdns, gateway, NULL, &hints, &res);
 		if (error) {
-			errx(1, "getaddrinfo for the gateway %s: %s",
+			errx(1, "cap_getaddrinfo for the gateway %s: %s",
 			     gateway, gai_strerror(error));
 		}
 		if (res->ai_next && (options & F_VERBOSE))
 			warnx("gateway resolves to multiple addresses");
 
-		if (setsockopt(s, IPPROTO_IPV6, IPV6_NEXTHOP,
+		if (setsockopt(ssend, IPPROTO_IPV6, IPV6_NEXTHOP,
 		    res->ai_addr, res->ai_addrlen)) {
 			err(1, "setsockopt(IPV6_NEXTHOP)");
 		}
@@ -690,25 +705,25 @@ main(int argc, char *argv[])
 		int opton = 1;
 
 #ifdef IPV6_RECVHOPOPTS
-		if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVHOPOPTS, &opton,
+		if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVHOPOPTS, &opton,
 		    sizeof(opton)))
 			err(1, "setsockopt(IPV6_RECVHOPOPTS)");
 #else  /* old adv. API */
-		if (setsockopt(s, IPPROTO_IPV6, IPV6_HOPOPTS, &opton,
+		if (setsockopt(srecv, IPPROTO_IPV6, IPV6_HOPOPTS, &opton,
 		    sizeof(opton)))
 			err(1, "setsockopt(IPV6_HOPOPTS)");
 #endif
 #ifdef IPV6_RECVDSTOPTS
-		if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVDSTOPTS, &opton,
+		if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVDSTOPTS, &opton,
 		    sizeof(opton)))
 			err(1, "setsockopt(IPV6_RECVDSTOPTS)");
 #else  /* old adv. API */
-		if (setsockopt(s, IPPROTO_IPV6, IPV6_DSTOPTS, &opton,
+		if (setsockopt(srecv, IPPROTO_IPV6, IPV6_DSTOPTS, &opton,
 		    sizeof(opton)))
 			err(1, "setsockopt(IPV6_DSTOPTS)");
 #endif
 #ifdef IPV6_RECVRTHDRDSTOPTS
-		if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVRTHDRDSTOPTS, &opton,
+		if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVRTHDRDSTOPTS, &opton,
 		    sizeof(opton)))
 			err(1, "setsockopt(IPV6_RECVRTHDRDSTOPTS)");
 #endif
@@ -751,31 +766,34 @@ main(int argc, char *argv[])
 	arc4random_buf(nonce, sizeof(nonce));
 	optval = 1;
 	if (options & F_DONTFRAG)
-		if (setsockopt(s, IPPROTO_IPV6, IPV6_DONTFRAG,
+		if (setsockopt(ssend, IPPROTO_IPV6, IPV6_DONTFRAG,
 		    &optval, sizeof(optval)) == -1)
 			err(1, "IPV6_DONTFRAG");
 	hold = 1;
 
-	if (options & F_SO_DEBUG)
-		(void)setsockopt(s, SOL_SOCKET, SO_DEBUG, (char *)&hold,
+	if (options & F_SO_DEBUG) {
+		(void)setsockopt(ssend, SOL_SOCKET, SO_DEBUG, (char *)&hold,
 		    sizeof(hold));
+		(void)setsockopt(srecv, SOL_SOCKET, SO_DEBUG, (char *)&hold,
+		    sizeof(hold));
+	}
 	optval = IPV6_DEFHLIM;
 	if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr))
-		if (setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
+		if (setsockopt(ssend, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
 		    &optval, sizeof(optval)) == -1)
 			err(1, "IPV6_MULTICAST_HOPS");
 #ifdef IPV6_USE_MIN_MTU
 	if (mflag != 1) {
 		optval = mflag > 1 ? 0 : 1;
 
-		if (setsockopt(s, IPPROTO_IPV6, IPV6_USE_MIN_MTU,
+		if (setsockopt(ssend, IPPROTO_IPV6, IPV6_USE_MIN_MTU,
 		    &optval, sizeof(optval)) == -1)
 			err(1, "setsockopt(IPV6_USE_MIN_MTU)");
 	}
 #ifdef IPV6_RECVPATHMTU
 	else {
 		optval = 1;
-		if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVPATHMTU,
+		if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVPATHMTU,
 		    &optval, sizeof(optval)) == -1)
 			err(1, "setsockopt(IPV6_RECVPATHMTU)");
 	}
@@ -785,29 +803,38 @@ main(int argc, char *argv[])
 #ifdef IPSEC
 #ifdef IPSEC_POLICY_IPSEC
 	if (options & F_POLICY) {
-		if (setpolicy(s, policy_in) < 0)
+		if (setpolicy(srecv, policy_in) < 0)
 			errx(1, "%s", ipsec_strerror());
-		if (setpolicy(s, policy_out) < 0)
+		if (setpolicy(ssend, policy_out) < 0)
 			errx(1, "%s", ipsec_strerror());
 	}
 #else
 	if (options & F_AUTHHDR) {
 		optval = IPSEC_LEVEL_REQUIRE;
 #ifdef IPV6_AUTH_TRANS_LEVEL
-		if (setsockopt(s, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL,
+		if (setsockopt(ssend, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL,
 		    &optval, sizeof(optval)) == -1)
 			err(1, "setsockopt(IPV6_AUTH_TRANS_LEVEL)");
+		if (setsockopt(srecv, IPPROTO_IPV6, IPV6_AUTH_TRANS_LEVEL,
+		     &optval, sizeof(optval)) == -1)
+			err(1, "setsockopt(IPV6_AUTH_TRANS_LEVEL)");
 #else /* old def */
-		if (setsockopt(s, IPPROTO_IPV6, IPV6_AUTH_LEVEL,
+		if (setsockopt(ssend, IPPROTO_IPV6, IPV6_AUTH_LEVEL,
 		    &optval, sizeof(optval)) == -1)
 			err(1, "setsockopt(IPV6_AUTH_LEVEL)");
+		if (setsockopt(srecv, IPPROTO_IPV6, IPV6_AUTH_LEVEL,
+		    &optval, sizeof(optval)) == -1)
+			err(1, "setsockopt(IPV6_AUTH_LEVEL)");
 #endif
 	}
 	if (options & F_ENCRYPT) {
 		optval = IPSEC_LEVEL_REQUIRE;
-		if (setsockopt(s, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL,
+		if (setsockopt(ssend, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL,
 		    &optval, sizeof(optval)) == -1)
 			err(1, "setsockopt(IPV6_ESP_TRANS_LEVEL)");
+		if (setsockopt(srecv, IPPROTO_IPV6, IPV6_ESP_TRANS_LEVEL,
+		    &optval, sizeof(optval)) == -1)
+			err(1, "setsockopt(IPV6_ESP_TRANS_LEVEL)");
 	}
 #endif /*IPSEC_POLICY_IPSEC*/
 #endif
@@ -825,7 +852,7 @@ main(int argc, char *argv[])
 	} else {
 		ICMP6_FILTER_SETPASSALL(&filt);
 	}
-	if (setsockopt(s, IPPROTO_ICMPV6, ICMP6_FILTER, &filt,
+	if (setsockopt(srecv, IPPROTO_ICMPV6, ICMP6_FILTER, &filt,
 	    sizeof(filt)) < 0)
 		err(1, "setsockopt(ICMP6_FILTER)");
     }
@@ -836,11 +863,11 @@ main(int argc, char *argv[])
 		int opton = 1;
 
 #ifdef IPV6_RECVRTHDR
-		if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVRTHDR, &opton,
+		if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVRTHDR, &opton,
 		    sizeof(opton)))
 			err(1, "setsockopt(IPV6_RECVRTHDR)");
 #else  /* old adv. API */
-		if (setsockopt(s, IPPROTO_IPV6, IPV6_RTHDR, &opton,
+		if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RTHDR, &opton,
 		    sizeof(opton)))
 			err(1, "setsockopt(IPV6_RTHDR)");
 #endif
@@ -849,7 +876,7 @@ main(int argc, char *argv[])
 /*
 	optval = 1;
 	if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr))
-		if (setsockopt(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
+		if (setsockopt(ssend, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
 		    &optval, sizeof(optval)) == -1)
 			err(1, "IPV6_MULTICAST_LOOP");
 */
@@ -916,7 +943,7 @@ main(int argc, char *argv[])
 			memset(&hints, 0, sizeof(hints));
 			hints.ai_family = AF_INET6;
 
-			if ((error = getaddrinfo(argv[hops], NULL, &hints,
+			if ((error = cap_getaddrinfo(capdns, argv[hops], NULL, &hints,
 			    &res)))
 				errx(1, "%s", gai_strerror(error));
 			if (res->ai_addr->sa_family != AF_INET6)
@@ -931,6 +958,15 @@ main(int argc, char *argv[])
 		scmsgp = CMSG_NXTHDR(&smsghdr, scmsgp);
 	}
 
+	/* From now on we will use only reverse DNS lookups. */
+	if (capdns != NULL) {
+		const char *types[1];
+
+		types[0] = "ADDR2NAME";
+		if (cap_dns_type_limit(capdns, types, nitems(types)) < 0)
+			err(1, "unable to limit access to system.dns service");
+	}
+
 	if (!(options & F_SRCADDR)) {
 		/*
 		 * get the source address. XXX since we revoked the root
@@ -976,14 +1012,36 @@ main(int argc, char *argv[])
 		close(dummy);
 	}
 
+	if (connect(ssend, (struct sockaddr *)&dst, sizeof(dst)) != 0)
+		err(1, "connect() ssend");
+
+	caph_cache_catpages();
+	if (caph_enter_casper() < 0)
+		err(1, "caph_enter_casper");
+
+	cap_rights_init(&rights_stdin);
+	if (cap_rights_limit(STDIN_FILENO, &rights_stdin) < 0)
+		err(1, "cap_rights_limit stdin");
+	if (caph_limit_stdout() < 0)
+		err(1, "caph_limit_stdout");
+	if (caph_limit_stderr() < 0)
+		err(1, "caph_limit_stderr");
+
+	cap_rights_init(&rights_srecv, CAP_RECV, CAP_EVENT, CAP_SETSOCKOPT);
+	if (caph_rights_limit(srecv, &rights_srecv) < 0)
+		err(1, "cap_rights_limit srecv");
+	cap_rights_init(&rights_ssend, CAP_SEND, CAP_SETSOCKOPT);
+	if (caph_rights_limit(ssend, &rights_ssend) < 0)
+		err(1, "cap_rights_limit ssend");
+
 #if defined(SO_SNDBUF) && defined(SO_RCVBUF)
 	if (sockbufsize) {
 		if (datalen > (size_t)sockbufsize)
 			warnx("you need -b to increase socket buffer size");
-		if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sockbufsize,
+		if (setsockopt(ssend, SOL_SOCKET, SO_SNDBUF, &sockbufsize,
 		    sizeof(sockbufsize)) < 0)
 			err(1, "setsockopt(SO_SNDBUF)");
-		if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &sockbufsize,
+		if (setsockopt(srecv, SOL_SOCKET, SO_RCVBUF, &sockbufsize,
 		    sizeof(sockbufsize)) < 0)
 			err(1, "setsockopt(SO_RCVBUF)");
 	}
@@ -997,7 +1055,7 @@ main(int argc, char *argv[])
 		 * to get some stuff for /etc/ethers.
 		 */
 		hold = 48 * 1024;
-		setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&hold,
+		setsockopt(srecv, SOL_SOCKET, SO_RCVBUF, (char *)&hold,
 		    sizeof(hold));
 	}
 #endif
@@ -1005,25 +1063,32 @@ main(int argc, char *argv[])
 	optval = 1;
 #ifndef USE_SIN6_SCOPE_ID
 #ifdef IPV6_RECVPKTINFO
-	if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVPKTINFO, &optval,
+	if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVPKTINFO, &optval,
 	    sizeof(optval)) < 0)
 		warn("setsockopt(IPV6_RECVPKTINFO)"); /* XXX err? */
 #else  /* old adv. API */
-	if (setsockopt(s, IPPROTO_IPV6, IPV6_PKTINFO, &optval,
+	if (setsockopt(srecv, IPPROTO_IPV6, IPV6_PKTINFO, &optval,
 	    sizeof(optval)) < 0)
 		warn("setsockopt(IPV6_PKTINFO)"); /* XXX err? */
 #endif
 #endif /* USE_SIN6_SCOPE_ID */
 #ifdef IPV6_RECVHOPLIMIT
-	if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &optval,
+	if (setsockopt(srecv, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &optval,
 	    sizeof(optval)) < 0)
 		warn("setsockopt(IPV6_RECVHOPLIMIT)"); /* XXX err? */
 #else  /* old adv. API */
-	if (setsockopt(s, IPPROTO_IPV6, IPV6_HOPLIMIT, &optval,
+	if (setsockopt(srecv, IPPROTO_IPV6, IPV6_HOPLIMIT, &optval,
 	    sizeof(optval)) < 0)
 		warn("setsockopt(IPV6_HOPLIMIT)"); /* XXX err? */
 #endif
 
+	cap_rights_clear(&rights_srecv, CAP_SETSOCKOPT);
+	if (caph_rights_limit(srecv, &rights_srecv) < 0)
+		err(1, "cap_rights_limit srecv setsockopt");
+	cap_rights_clear(&rights_ssend, CAP_SETSOCKOPT);
+	if (caph_rights_limit(ssend, &rights_ssend) < 0)
+		err(1, "cap_rights_limit ssend setsockopt");
+
 	printf("PING6(%lu=40+8+%lu bytes) ", (unsigned long)(40 + pingerlen()),
 	    (unsigned long)(pingerlen() - 8));
 	printf("%s --> ", pr_addr((struct sockaddr *)&src, sizeof(src)));
@@ -1081,7 +1146,7 @@ main(int argc, char *argv[])
 		}
 #endif
 		FD_ZERO(&rfds);
-		FD_SET(s, &rfds);
+		FD_SET(srecv, &rfds);
 		gettimeofday(&now, NULL);
 		timeout.tv_sec = last.tv_sec + intvl.tv_sec - now.tv_sec;
 		timeout.tv_usec = last.tv_usec + intvl.tv_usec - now.tv_usec;
@@ -1096,7 +1161,7 @@ main(int argc, char *argv[])
 		if (timeout.tv_sec < 0)
 			timeout.tv_sec = timeout.tv_usec = 0;
 
-		n = select(s + 1, &rfds, NULL, NULL, &timeout);
+		n = select(srecv + 1, &rfds, NULL, NULL, &timeout);
 		if (n < 0)
 			continue;	/* EINTR */
 		if (n == 1) {
@@ -1111,7 +1176,7 @@ main(int argc, char *argv[])
 			m.msg_control = (void *)cm;
 			m.msg_controllen = CONTROLLEN;
 
-			cc = recvmsg(s, &m, 0);
+			cc = recvmsg(srecv, &m, 0);
 			if (cc < 0) {
 				if (errno != EINTR) {
 					warn("recvmsg");
@@ -1325,15 +1390,13 @@ pinger(void)
 		errx(1, "internal error; length mismatch");
 #endif
 
-	smsghdr.msg_name = (caddr_t)&dst;
-	smsghdr.msg_namelen = sizeof(dst);
 	memset(&iov, 0, sizeof(iov));
 	iov[0].iov_base = (caddr_t)outpack;
 	iov[0].iov_len = cc;
 	smsghdr.msg_iov = iov;
 	smsghdr.msg_iovlen = 1;
 
-	i = sendmsg(s, &smsghdr, 0);
+	i = sendmsg(ssend, &smsghdr, 0);
 
 	if (i < 0 || i != cc)  {
 		if (i < 0)
@@ -2497,7 +2560,8 @@ pr_addr(struct sockaddr *addr, int addrlen)
 	if ((options & F_HOSTNAME) == 0)
 		flag |= NI_NUMERICHOST;
 
-	if (getnameinfo(addr, addrlen, buf, sizeof(buf), NULL, 0, flag) == 0)
+	if (cap_getnameinfo(capdns, addr, addrlen, buf, sizeof(buf), NULL, 0,
+		flag) == 0)
 		return (buf);
 	else
 		return "?";
@@ -2631,7 +2695,7 @@ setpolicy(int so __unused, char *policy)
 	buf = ipsec_set_policy(policy, strlen(policy));
 	if (buf == NULL)
 		errx(1, "%s", ipsec_strerror());
-	if (setsockopt(s, IPPROTO_IPV6, IPV6_IPSEC_POLICY, buf,
+	if (setsockopt(ssend, IPPROTO_IPV6, IPV6_IPSEC_POLICY, buf,
 	    ipsec_get_policylen(buf)) < 0)
 		warnx("Unable to set IPsec policy");
 	free(buf);
@@ -2727,4 +2791,30 @@ usage(void)
 	    "[-x waittime]\n"
 	    "             [-X timeout] [hops ...] host\n");
 	exit(1);
+}
+
+static cap_channel_t *
+capdns_setup(void)
+{
+	cap_channel_t *capcas, *capdnsloc;
+	const char *types[2];
+	int families[1];
+
+	capcas = cap_init();
+	if (capcas == NULL)
+		err(1, "unable to create casper process");
+	capdnsloc = cap_service_open(capcas, "system.dns");
+	/* Casper capability no longer needed. */
+	cap_close(capcas);
+	if (capdnsloc == NULL)
+		err(1, "unable to open system.dns service");
+	types[0] = "NAME2ADDR";
+	types[1] = "ADDR2NAME";
+	if (cap_dns_type_limit(capdnsloc, types, nitems(types)) < 0)
+		err(1, "unable to limit access to system.dns service");
+	families[0] = AF_INET6;
+	if (cap_dns_family_limit(capdnsloc, families, nitems(families)) < 0)
+		err(1, "unable to limit access to system.dns service");
+
+	return (capdnsloc);
 }


More information about the svn-src-all mailing list