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
This commit is contained in:
Pawel Jakub Dawidek 2013-12-15 23:02:36 +00:00
parent 36492dd3f5
commit 197731f68f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=259432
2 changed files with 82 additions and 3 deletions

View File

@ -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;

View File

@ -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())