diff options
author | Pawel Jakub Dawidek <pjd@FreeBSD.org> | 2013-12-15 23:02:36 +0000 |
---|---|---|
committer | Pawel Jakub Dawidek <pjd@FreeBSD.org> | 2013-12-15 23:02:36 +0000 |
commit | 197731f68f5f6a240eb15db44670a811fd8828df (patch) | |
tree | a0452c0927a90f3988e817a5f9f94965efa2f17c /contrib/tcpdump/tcpdump.c | |
parent | 36492dd3f5bb6532aa8f81c939fb551d39b4aed2 (diff) |
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
Notes
Notes:
svn path=/head/; revision=259432
Diffstat (limited to 'contrib/tcpdump/tcpdump.c')
-rw-r--r-- | contrib/tcpdump/tcpdump.c | 62 |
1 files changed, 61 insertions, 1 deletions
diff --git a/contrib/tcpdump/tcpdump.c b/contrib/tcpdump/tcpdump.c index afcc152142dd..e1a34f4ea934 100644 --- a/contrib/tcpdump/tcpdump.c +++ b/contrib/tcpdump/tcpdump.c @@ -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()) |