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())
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to