svn commit: r259432 - head/contrib/tcpdump

Pawel Jakub Dawidek pjd at FreeBSD.org
Sun Dec 15 23:02:37 UTC 2013


Author: pjd
Date: Sun Dec 15 23:02:36 2013
New Revision: 259432
URL: http://svnweb.freebsd.org/changeset/base/259432

Log:
  Make use of casperd's system.dns service when running without the -n option.
  Now tcpdump(8) is sandboxed even if DNS resolution is required.
  
  Sponsored by:	The FreeBSD Foundation

Modified:
  head/contrib/tcpdump/addrtoname.c
  head/contrib/tcpdump/tcpdump.c

Modified: head/contrib/tcpdump/addrtoname.c
==============================================================================
--- head/contrib/tcpdump/addrtoname.c	Sun Dec 15 22:59:34 2013	(r259431)
+++ head/contrib/tcpdump/addrtoname.c	Sun Dec 15 23:02:36 2013	(r259432)
@@ -32,6 +32,10 @@ static const char rcsid[] _U_ =
 #include "config.h"
 #endif
 
+#ifdef __FreeBSD__
+#include <libcapsicum.h>
+#include <libcapsicum_dns.h>
+#endif
 #include <tcpdump-stdinc.h>
 
 #ifdef USE_ETHER_NTOHOST
@@ -203,6 +207,9 @@ intoa(u_int32_t addr)
 
 static u_int32_t f_netmask;
 static u_int32_t f_localnet;
+#ifdef HAVE_LIBCAPSICUM
+extern cap_channel_t *capdns;
+#endif
 
 /*
  * Return a name for the IP address pointed to by ap.  This address
@@ -248,7 +255,13 @@ getname(const u_char *ap)
 	 */
 	if (!nflag &&
 	    (addr & f_netmask) == f_localnet) {
-		hp = gethostbyaddr((char *)&addr, 4, AF_INET);
+#ifdef HAVE_LIBCAPSICUM
+		if (capdns != NULL) {
+			hp = cap_gethostbyaddr(capdns, (char *)&addr, 4,
+			    AF_INET);
+		} else
+#endif
+			hp = gethostbyaddr((char *)&addr, 4, AF_INET);
 		if (hp) {
 			char *dotp;
 
@@ -293,7 +306,13 @@ getname6(const u_char *ap)
 	 * Do not print names if -n was given.
 	 */
 	if (!nflag) {
-		hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET6);
+#ifdef HAVE_LIBCAPSICUM
+		if (capdns != NULL) {
+			hp = cap_gethostbyaddr(capdns, (char *)&addr,
+			    sizeof(addr), AF_INET6);
+		} else
+#endif
+			hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET6);
 		if (hp) {
 			char *dotp;
 

Modified: head/contrib/tcpdump/tcpdump.c
==============================================================================
--- head/contrib/tcpdump/tcpdump.c	Sun Dec 15 22:59:34 2013	(r259431)
+++ head/contrib/tcpdump/tcpdump.c	Sun Dec 15 23:02:36 2013	(r259432)
@@ -76,6 +76,12 @@ extern int SIZE_BUF;
 #include <net/bpf.h>
 #include <fcntl.h>
 #include <libgen.h>
+#ifdef HAVE_LIBCAPSICUM
+#include <libcapsicum.h>
+#include <libcapsicum_dns.h>
+#include <libcapsicum_service.h>
+#include <nv.h>
+#endif	/* HAVE_LIBCAPSICUM */
 #endif	/* __FreeBSD__ */
 #ifndef WIN32
 #include <sys/wait.h>
@@ -123,6 +129,10 @@ static int infoprint;
 
 char *program_name;
 
+#ifdef HAVE_LIBCAPSICUM
+cap_channel_t *capdns;
+#endif
+
 int32_t thiszone;		/* seconds offset from gmt to local time */
 
 /* Forwards */
@@ -684,6 +694,45 @@ get_next_file(FILE *VFile, char *ptr)
 	return ret;
 }
 
+#ifdef HAVE_LIBCAPSICUM
+static cap_channel_t *
+capdns_setup(void)
+{
+	cap_channel_t *capcas, *capdnsloc;
+	const char *types[1];
+	int families[2];
+
+	capcas = cap_init();
+	if (capcas == NULL) {
+		warning("unable to contact casperd");
+		return (NULL);
+	}
+	capdnsloc = cap_service_open(capcas, "system.dns");
+	/* Casper capability no longer needed. */
+	cap_close(capcas);
+	if (capdnsloc == NULL) {
+		warning("unable to open system.dns service");
+		return (NULL);
+	}
+	/* Limit system.dns to reverse DNS lookups. */
+	types[0] = "ADDR";
+	if (cap_dns_type_limit(capdnsloc, types, 1) < 0) {
+		warning("unable to limit access to system.dns service");
+		cap_close(capdnsloc);
+		return (NULL);
+	}
+	families[0] = AF_INET;
+	families[1] = AF_INET6;
+	if (cap_dns_family_limit(capdnsloc, families, 2) < 0) {
+		warning("unable to limit access to system.dns service");
+		cap_close(capdnsloc);
+		return (NULL);
+	}
+
+	return (capdnsloc);
+}
+#endif	/* HAVE_LIBCAPSICUM */
+
 int
 main(int argc, char **argv)
 {
@@ -1417,6 +1466,12 @@ main(int argc, char **argv)
 		free(cmdbuf);
 		exit(0);
 	}
+
+#ifdef HAVE_LIBCAPSICUM
+	if (!nflag)
+		capdns = capdns_setup();
+#endif	/* HAVE_LIBCAPSICUM */
+
 	init_addrtoname(localnet, netmask);
         init_checksum();
 
@@ -1615,7 +1670,12 @@ main(int argc, char **argv)
 #endif /* WIN32 */
 
 #ifdef __FreeBSD__
-	cansandbox = (nflag && VFileName == NULL && zflag == NULL);
+	cansandbox = (VFileName == NULL && zflag == NULL);
+#ifdef HAVE_LIBCAPSICUM
+	cansandbox = (cansandbox && (nflag || capdns != NULL));
+#else
+	cansandbox = (cansandbox && nflag);
+#endif
 	if (cansandbox && cap_enter() < 0 && errno != ENOSYS)
 		error("unable to enter the capability mode");
 	if (cap_sandboxed())


More information about the svn-src-all mailing list