Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F102134267
D25604.id74999.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D25604.id74999.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D25604: Capsicumize traceroute6
Attached
Detach File
Event Timeline
Log In to Comment