Page MenuHomeFreeBSD

D25604.id74999.diff
No OneTemporary

D25604.id74999.diff

Index: usr.sbin/traceroute6/Makefile
===================================================================
--- usr.sbin/traceroute6/Makefile
+++ usr.sbin/traceroute6/Makefile
@@ -13,6 +13,8 @@
# A PARTICULAR PURPOSE.
# $FreeBSD$
+.include <src.opts.mk>
+
TRACEROUTE_DISTDIR?= ${SRCTOP}/contrib/traceroute
.PATH: ${TRACEROUTE_DISTDIR}
@@ -26,8 +28,14 @@
CFLAGS+= -DIPSEC -DHAVE_POLL
CFLAGS+= -I${.CURDIR} -I${TRACEROUTE_DISTDIR} -I.
+.if ${MK_CASPER} != "no"
+LIBADD+= casper
+LIBADD+= cap_dns
+CFLAGS+=-DWITH_CASPER
+.endif
+
WARNS?= 3
-LIBADD= ipsec
+LIBADD+= ipsec
.include <bsd.prog.mk>
Index: usr.sbin/traceroute6/traceroute6.c
===================================================================
--- usr.sbin/traceroute6/traceroute6.c
+++ usr.sbin/traceroute6/traceroute6.c
@@ -249,6 +249,7 @@
*/
#include <sys/param.h>
+#include <sys/capsicum.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/uio.h>
@@ -260,6 +261,10 @@
#include <arpa/inet.h>
+#include <libcasper.h>
+#include <casper/cap_dns.h>
+#include <capsicum_helpers.h>
+
#include <netdb.h>
#include <stdio.h>
#include <err.h>
@@ -290,7 +295,7 @@
#define MAXPACKET 65535 /* max ip packet size */
#ifndef HAVE_GETIPNODEBYNAME
-#define getipnodebyname(x, y, z, u) gethostbyname2((x), (y))
+#define getipnodebyname(x, y, z, u) cap_gethostbyname2(capdns, (x), (y))
#define freehostent(x)
#endif
@@ -314,6 +319,8 @@
const char *inetname(struct sockaddr *);
u_int32_t sctp_crc32c(void *, u_int32_t);
u_int16_t in_cksum(u_int16_t *addr, int);
+u_int16_t udp_cksum(struct sockaddr_in6 *, struct sockaddr_in6 *,
+ void *, u_int32_t);
u_int16_t tcp_chksum(struct sockaddr_in6 *, struct sockaddr_in6 *,
void *, u_int32_t);
void usage(void);
@@ -337,6 +344,8 @@
char *source = NULL;
char *hostname;
+static cap_channel_t *capdns;
+
u_long nprobes = 3;
u_long first_hop = 1;
u_long max_hops = 30;
@@ -366,6 +375,23 @@
size_t size, minlen;
uid_t uid;
u_char type, code;
+ cap_rights_t rights;
+ const char *types[] = { "NAME", "ADDR" };
+ int families[1];
+ cap_channel_t *casper;
+
+ casper = cap_init();
+ if (casper == NULL)
+ errx(1, "unable to create casper process");
+ capdns = cap_service_open(casper, "system.dns");
+ if (capdns == NULL)
+ errx(1, "unable to open system.dns service");
+ if (cap_dns_type_limit(capdns, types, 2) < 0)
+ errx(1, "unable to limit access to system.dns service");
+ families[0] = AF_INET6;
+ if (cap_dns_family_limit(capdns, families, 1) < 0)
+ errx(1, "unable to limit access to system.dns service");
+ cap_close(casper);
/*
* Receive ICMP
@@ -558,8 +584,8 @@
sndsock = rcvsock;
break;
case IPPROTO_UDP:
- if ((sndsock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
- perror("socket(SOCK_DGRAM)");
+ if ((sndsock = socket(AF_INET6, SOCK_RAW, IPPROTO_UDP)) < 0) {
+ perror("socket(SOCK_RAW)");
exit(5);
}
break;
@@ -604,7 +630,9 @@
hints.ai_socktype = SOCK_RAW;
hints.ai_protocol = IPPROTO_ICMPV6;
hints.ai_flags = AI_CANONNAME;
- error = getaddrinfo(*argv, NULL, &hints, &res);
+
+ error = cap_getaddrinfo(capdns, *argv, NULL, &hints, &res);
+
if (error) {
fprintf(stderr,
"traceroute6: %s\n", gai_strerror(error));
@@ -622,7 +650,7 @@
exit(1);
}
if (res->ai_next) {
- if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf,
+ if (cap_getnameinfo(capdns, res->ai_addr, res->ai_addrlen, hbuf,
sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
strlcpy(hbuf, "?", sizeof(hbuf));
fprintf(stderr, "traceroute6: Warning: %s has multiple "
@@ -808,7 +836,7 @@
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_DGRAM; /*dummy*/
hints.ai_flags = AI_NUMERICHOST;
- error = getaddrinfo(source, "0", &hints, &res);
+ error = cap_getaddrinfo(capdns, source, "0", &hints, &res);
if (error) {
printf("traceroute6: %s: %s\n", source,
gai_strerror(error));
@@ -844,7 +872,7 @@
perror("getsockname");
exit(1);
}
- if (getnameinfo((struct sockaddr *)&Src, Src.sin6_len,
+ if (cap_getnameinfo(capdns, (struct sockaddr *)&Src, Src.sin6_len,
src0, sizeof(src0), NULL, 0, NI_NUMERICHOST)) {
fprintf(stderr, "getnameinfo failed for source\n");
exit(1);
@@ -884,7 +912,7 @@
/*
* Message to users
*/
- if (getnameinfo((struct sockaddr *)&Dst, Dst.sin6_len, hbuf,
+ if (cap_getnameinfo(capdns, (struct sockaddr *)&Dst, Dst.sin6_len, hbuf,
sizeof(hbuf), NULL, 0, NI_NUMERICHOST))
strlcpy(hbuf, "(invalid)", sizeof(hbuf));
fprintf(stderr, "traceroute6");
@@ -899,6 +927,30 @@
if (first_hop > 1)
printf("Skipping %lu intermediate hops\n", first_hop - 1);
+ if (connect(sndsock, (struct sockaddr *)&Dst,
+ sizeof(Dst)) != 0) {
+ fprintf(stderr, "connect: %s\n", strerror(errno));
+ exit(1);
+ }
+
+ /*
+ * Here we enter capability mode. Further down access to global
+ * namespaces (e.g filesystem) is restricted (see capsicum(4)).
+ * We must connect(2) our socket before this point.
+ */
+
+ if (caph_enter_casper() < 0) {
+ fprintf(stderr, "caph_enter_casper: %s\n", strerror(errno));
+ exit(1);
+ }
+
+ cap_rights_init(&rights, CAP_SEND, CAP_SETSOCKOPT);
+ if (caph_rights_limit(sndsock, &rights) < 0) {
+ fprintf(stderr, "caph_rights_limit sndsock: %s\n",
+ strerror(errno));
+ exit(1);
+ }
+
/*
* Main loop
*/
@@ -1047,6 +1099,7 @@
{
struct icmp6_hdr *icp;
struct sctphdr *sctp;
+ struct udphdr *outudp;
struct sctp_chunkhdr *chk;
struct sctp_init_chunk *init;
struct sctp_paramhdr *param;
@@ -1072,6 +1125,11 @@
icp->icmp6_seq = htons(seq);
break;
case IPPROTO_UDP:
+ outudp = (struct udphdr *) outpacket;
+ outudp->uh_sport = htons(ident);
+ outudp->uh_dport = htons(port+seq);
+ outudp->uh_ulen = htons(datalen);
+ outudp->uh_sum = udp_cksum(&Src, &Dst, outpacket, datalen);
break;
case IPPROTO_NONE:
/* No space for anything. No harm as seq/tv32 are decorative. */
@@ -1158,12 +1216,11 @@
fprintf(stderr, "Unknown probe protocol %d.\n", useproto);
exit(1);
}
-
- i = sendto(sndsock, (char *)outpacket, datalen, 0,
- (struct sockaddr *)&Dst, Dst.sin6_len);
+
+ i = send(sndsock, (char *)outpacket, datalen, 0);
if (i < 0 || (u_long)i != datalen) {
if (i < 0)
- perror("sendto");
+ perror("send");
printf("traceroute6: wrote %s %lu chars, ret=%d\n",
hostname, datalen, i);
(void) fflush(stdout);
@@ -1275,7 +1332,7 @@
hlen = sizeof(struct ip6_hdr);
if (cc < hlen + sizeof(struct icmp6_hdr)) {
if (verbose) {
- if (getnameinfo((struct sockaddr *)from, from->sin6_len,
+ if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len,
hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
strlcpy(hbuf, "invalid", sizeof(hbuf));
printf("packet too short (%d bytes) from %s\n", cc,
@@ -1288,7 +1345,7 @@
#else
if (cc < (int)sizeof(struct icmp6_hdr)) {
if (verbose) {
- if (getnameinfo((struct sockaddr *)from, from->sin6_len,
+ if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len,
hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
strlcpy(hbuf, "invalid", sizeof(hbuf));
printf("data too short (%d bytes) from %s\n", cc, hbuf);
@@ -1354,7 +1411,7 @@
break;
case IPPROTO_UDP:
udp = (struct udphdr *)up;
- if (udp->uh_sport == htons(srcport) &&
+ if (udp->uh_sport == htons(ident) &&
udp->uh_dport == htons(port + seq))
return (1);
break;
@@ -1410,7 +1467,7 @@
u_int8_t *p;
int i;
- if (getnameinfo((struct sockaddr *)from, from->sin6_len,
+ if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len,
sbuf, sizeof(sbuf), NULL, 0, NI_NUMERICHOST) != 0)
strlcpy(sbuf, "invalid", sizeof(sbuf));
printf("\n%d bytes from %s to %s", cc, sbuf,
@@ -1489,7 +1546,7 @@
struct sockaddr_in6 *from = (struct sockaddr_in6 *)mhdr->msg_name;
char hbuf[NI_MAXHOST];
- if (getnameinfo((struct sockaddr *)from, from->sin6_len,
+ if (cap_getnameinfo(capdns, (struct sockaddr *)from, from->sin6_len,
hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
strlcpy(hbuf, "invalid", sizeof(hbuf));
if (as_path)
@@ -1536,7 +1593,7 @@
}
cp = NULL;
if (!nflag) {
- if (getnameinfo(sa, sa->sa_len, line, sizeof(line), NULL, 0,
+ if (cap_getnameinfo(capdns, sa, sa->sa_len, line, sizeof(line), NULL, 0,
NI_NAMEREQD) == 0) {
if ((cp = strchr(line, '.')) &&
!strcmp(cp + 1, domain))
@@ -1547,7 +1604,7 @@
if (cp)
return cp;
- if (getnameinfo(sa, sa->sa_len, line, sizeof(line), NULL, 0,
+ if (cap_getnameinfo(capdns, sa, sa->sa_len, line, sizeof(line), NULL, 0,
NI_NUMERICHOST) != 0)
strlcpy(line, "invalid", sizeof(line));
return line;
@@ -1677,6 +1734,33 @@
return (answer);
}
+u_int16_t
+udp_cksum(struct sockaddr_in6 *src, struct sockaddr_in6 *dst,
+ void *payload, u_int32_t len)
+{
+ struct {
+ struct in6_addr src;
+ struct in6_addr dst;
+ u_int32_t len;
+ u_int8_t zero[3];
+ u_int8_t next;
+ } pseudo_hdr;
+ u_int16_t sum[2];
+
+ pseudo_hdr.src = src->sin6_addr;
+ pseudo_hdr.dst = dst->sin6_addr;
+ pseudo_hdr.len = htonl(len);
+ pseudo_hdr.zero[0] = 0;
+ pseudo_hdr.zero[1] = 0;
+ pseudo_hdr.zero[2] = 0;
+ pseudo_hdr.next = IPPROTO_UDP;
+
+ sum[1] = in_cksum((u_int16_t *)&pseudo_hdr, sizeof(pseudo_hdr));
+ sum[0] = in_cksum(payload, len);
+
+ return (~in_cksum(sum, sizeof(sum)));
+}
+
u_int16_t
tcp_chksum(struct sockaddr_in6 *src, struct sockaddr_in6 *dst,
void *payload, u_int32_t len)

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 9, 1:12 AM (2 h, 45 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14546128
Default Alt Text
D25604.id74999.diff (9 KB)

Event Timeline