summaryrefslogtreecommitdiff
path: root/usr.sbin/tcpdump/tcpdump.c
diff options
context:
space:
mode:
authorCan Erkin Acar <canacar@cvs.openbsd.org>2004-01-28 19:44:56 +0000
committerCan Erkin Acar <canacar@cvs.openbsd.org>2004-01-28 19:44:56 +0000
commit87d1aa5c72a876badad301facf67f7ee8ec5880b (patch)
treeca8152a20e4c4e01f6872b9741bc361313522cad /usr.sbin/tcpdump/tcpdump.c
parenta9765aa5e532b4e14ae9e6a3d66d5c3a514d6de2 (diff)
privilege separated tcpdump, joint work with otto@
tested by avsm@ vincent@ dhartmei@ markus@ hshoexer@ and others go for it deraadt@
Diffstat (limited to 'usr.sbin/tcpdump/tcpdump.c')
-rw-r--r--usr.sbin/tcpdump/tcpdump.c86
1 files changed, 46 insertions, 40 deletions
diff --git a/usr.sbin/tcpdump/tcpdump.c b/usr.sbin/tcpdump/tcpdump.c
index 16df5b6c8d6..ac3fb064849 100644
--- a/usr.sbin/tcpdump/tcpdump.c
+++ b/usr.sbin/tcpdump/tcpdump.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcpdump.c,v 1.34 2003/09/25 13:32:58 jmc Exp $ */
+/* $OpenBSD: tcpdump.c,v 1.35 2004/01/28 19:44:55 canacar Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
@@ -26,7 +26,7 @@ static const char copyright[] =
"@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997\n\
The Regents of the University of California. All rights reserved.\n";
static const char rcsid[] =
- "@(#) $Header: /cvs/OpenBSD/src/usr.sbin/tcpdump/tcpdump.c,v 1.34 2003/09/25 13:32:58 jmc Exp $ (LBL)";
+ "@(#) $Header: /cvs/OpenBSD/src/usr.sbin/tcpdump/tcpdump.c,v 1.35 2004/01/28 19:44:55 canacar Exp $ (LBL)";
#endif
/*
@@ -62,6 +62,7 @@ static const char rcsid[] =
#include <net/pfvar.h>
#include "pfctl.h"
#include "pfctl_parser.h"
+#include "privsep.h"
int aflag; /* translate network and broadcast addresses */
int dflag; /* print filter code */
@@ -81,7 +82,6 @@ int Xflag; /* print packet in emacs-hexl style */
int packettype;
-
char *program_name;
int32_t thiszone; /* seconds offset from gmt to local time */
@@ -138,6 +138,16 @@ lookup_printer(int type)
/* NOTREACHED */
}
+static int
+init_pfosfp(void)
+{
+ pf_osfp_initialize();
+ if (pfctl_file_fingerprints(-1,
+ PF_OPT_QUIET|PF_OPT_NOACTION, PF_OSFP_FILE) == 0)
+ return 1;
+ return 0;
+}
+
static pcap_t *pd;
extern int optind;
@@ -149,9 +159,9 @@ main(int argc, char **argv)
{
register int cnt, op, i;
bpf_u_int32 localnet, netmask;
- register char *cp, *infile, *cmdbuf, *device, *RFileName, *WFileName;
+ register char *cp, *infile, *device, *RFileName, *WFileName;
pcap_handler printer;
- struct bpf_program fcode;
+ struct bpf_program *fcode;
RETSIGTYPE (*oldhandler)(int);
u_char *pcap_userdata;
char ebuf[PCAP_ERRBUF_SIZE];
@@ -161,6 +171,11 @@ main(int argc, char **argv)
infile = NULL;
RFileName = NULL;
WFileName = NULL;
+
+ if (priv_init(argc, argv))
+ error("Failed to setup privsep");
+
+ /* state: STATE_INIT */
if ((cp = strrchr(argv[0], '/')) != NULL)
program_name = cp + 1;
else
@@ -224,9 +239,6 @@ main(int argc, char **argv)
break;
case 'o':
- pf_osfp_initialize();
- if (pfctl_file_fingerprints(-1,
- PF_OPT_QUIET|PF_OPT_NOACTION, PF_OSFP_FILE) == 0)
oflag = 1;
break;
@@ -313,21 +325,12 @@ main(int argc, char **argv)
if (aflag && nflag)
error("-a and -n options are incompatible");
- if (tflag > 0)
- thiszone = gmt2local(0);
-
if (RFileName != NULL) {
- /*
- * We don't need network access, so set it back to the user id.
- * Also, this prevents the user from reading anyone's
- * trace file.
- */
- seteuid(getuid());
- setuid(getuid());
-
- pd = pcap_open_offline(RFileName, ebuf);
+ pd = priv_pcap_offline(RFileName, ebuf);
if (pd == NULL)
error("%s", ebuf);
+
+ /* state: STATE_BPF */
localnet = 0;
netmask = 0;
if (fflag != 0)
@@ -338,51 +341,45 @@ main(int argc, char **argv)
if (device == NULL)
error("%s", ebuf);
}
- pd = pcap_open_live(device, snaplen, !pflag, 1000, ebuf);
+ pd = priv_pcap_live(device, snaplen, !pflag, 1000, ebuf);
if (pd == NULL)
error("%s", ebuf);
+
+ /* state: STATE_BPF */
i = pcap_snapshot(pd);
if (snaplen < i) {
warning("snaplen raised from %d to %d", snaplen, i);
snaplen = i;
}
- if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) {
+
+ if (pcap_lookupnet(device, &localnet, &netmask, ebuf)) {
warning("%s", ebuf);
localnet = 0;
netmask = 0;
}
-
- /*
- * Let user own process after socket has been opened.
- */
- seteuid(getuid());
- setuid(getuid());
}
- if (infile)
- cmdbuf = read_infile(infile);
- else
- cmdbuf = copy_argv(&argv[optind]);
- if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0)
+ fcode = priv_pcap_setfilter(pd, Oflag, netmask);
+ /* state: STATE_FILTER */
+ if (fcode == NULL)
error("%s", pcap_geterr(pd));
if (dflag) {
- bpf_dump(&fcode, dflag);
+ bpf_dump(fcode, dflag);
exit(0);
}
init_addrtoname(localnet, netmask);
- (void)setsignal(SIGTERM, cleanup);
- (void)setsignal(SIGINT, cleanup);
- /* Cooperate with nohup(1) */
+ setsignal(SIGTERM, cleanup);
+ setsignal(SIGINT, cleanup);
+ /* Cooperate with nohup(1) XXX is this still necessary/working? */
if ((oldhandler = setsignal(SIGHUP, cleanup)) != SIG_DFL)
(void)setsignal(SIGHUP, oldhandler);
- if (pcap_setfilter(pd, &fcode) < 0)
- error("%s", pcap_geterr(pd));
if (WFileName) {
pcap_dumper_t *p;
- p = pcap_dump_open(pd, WFileName);
+ p = priv_pcap_dump_open(pd, WFileName);
+ /* state: STATE_RUN */
if (p == NULL)
error("%s", pcap_geterr(pd));
{
@@ -395,12 +392,21 @@ main(int argc, char **argv)
} else {
printer = lookup_printer(pcap_datalink(pd));
pcap_userdata = 0;
+ priv_init_done();
+ /* state: STATE_RUN */
}
if (RFileName == NULL) {
(void)fprintf(stderr, "%s: listening on %s\n",
program_name, device);
(void)fflush(stderr);
}
+
+ if (oflag)
+ oflag = init_pfosfp();
+ if (tflag > 0)
+ thiszone = gmt2local(0);
+
+
if (pcap_loop(pd, cnt, printer, pcap_userdata) < 0) {
(void)fprintf(stderr, "%s: pcap_loop: %s\n",
program_name, pcap_geterr(pd));