diff options
Diffstat (limited to 'contrib/pf/pflogd')
-rw-r--r-- | contrib/pf/pflogd/pflogd.8 | 58 | ||||
-rw-r--r-- | contrib/pf/pflogd/pflogd.c | 138 | ||||
-rw-r--r-- | contrib/pf/pflogd/pidfile.c | 3 | ||||
-rw-r--r-- | contrib/pf/pflogd/privsep.c | 98 |
4 files changed, 127 insertions, 170 deletions
diff --git a/contrib/pf/pflogd/pflogd.8 b/contrib/pf/pflogd/pflogd.8 index cbb7802..0eef77b 100644 --- a/contrib/pf/pflogd/pflogd.8 +++ b/contrib/pf/pflogd/pflogd.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: pflogd.8,v 1.32 2006/12/08 10:26:38 joel Exp $ +.\" $OpenBSD: pflogd.8,v 1.25 2005/01/02 18:15:02 jmc Exp $ .\" .\" Copyright (c) 2001 Can Erkin Acar. All rights reserved. .\" @@ -24,6 +24,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" +.\" $FreeBSD$ +.\" .Dd July 9, 2001 .Dt PFLOGD 8 .Os @@ -35,28 +37,25 @@ .Op Fl Dx .Op Fl d Ar delay .Op Fl f Ar filename -.Op Fl i Ar interface .Op Fl s Ar snaplen .Op Ar expression .Sh DESCRIPTION .Nm is a background daemon which reads packets logged by .Xr pf 4 -to a -.Xr pflog 4 -interface, normally -.Pa pflog0 , +to the packet logging interface +.Pa pflog0 and writes the packets to a logfile (normally .Pa /var/log/pflog ) in -.Xr tcpdump 8 +.Xr tcpdump 1 binary format. These logs can be reviewed later using the .Fl r option of -.Xr tcpdump 8 , +.Xr tcpdump 1 , hopefully offline in case there are bugs in the packet parsing code of -.Xr tcpdump 8 . +.Xr tcpdump 1 . .Pp .Nm closes and then re-opens the log file when it receives @@ -84,9 +83,7 @@ temporarily uses the old snaplen to keep the log file consistent. tries to preserve the integrity of the log file against I/O errors. Furthermore, integrity of an existing log file is verified before appending. -If there is an invalid log file or an I/O error, the log file is moved -out of the way and a new one is created. -If a new file cannot be created, logging is suspended until a +If there is an invalid log file or an I/O error, logging is suspended until a .Dv SIGHUP or a .Dv SIGALRM @@ -106,26 +103,18 @@ If not specified, the default is 60 seconds. Log output filename. Default is .Pa /var/log/pflog . -.It Fl i Ar interface -Specifies the -.Xr pflog 4 -interface to use. -By default, -.Nm -will use -.Ar pflog0 . .It Fl s Ar snaplen Analyze at most the first .Ar snaplen -bytes of data from each packet rather than the default of 116. -The default of 116 is adequate for IP, ICMP, TCP, and UDP headers but may +bytes of data from each packet rather than the default of 96. +The default of 96 is adequate for IP, ICMP, TCP, and UDP headers but may truncate protocol information for other protocols. Other file parsers may desire a higher snaplen. .It Fl x Check the integrity of an existing log file, and return. .It Ar expression Selects which packets will be dumped, using the regular language of -.Xr tcpdump 8 . +.Xr tcpdump 1 . .El .Sh FILES .Bl -tag -width /var/run/pflogd.pid -compact @@ -142,13 +131,6 @@ Log specific tcp packets to a different log file with a large snaplen # pflogd -s 1600 -f suspicious.log port 80 and host evilhost .Ed .Pp -Log from another -.Xr pflog 4 -interface, excluding specific packets: -.Bd -literal -offset indent -# pflogd -i pflog3 -f network3.log "not (tcp and port 23)" -.Ed -.Pp Display binary logs: .Bd -literal -offset indent # tcpdump -n -e -ttt -r /var/log/pflog @@ -168,7 +150,7 @@ Tcpdump can restrict the output to packets logged on a specified interface, a rule number, a reason, a direction, an IP family or an action. .Pp -.Bl -tag -width "ruleset authpf " -compact +.Bl -tag -width "reason match " -compact .It ip Address family equals IPv4. .It ip6 @@ -177,16 +159,12 @@ Address family equals IPv6. Interface name equals "kue0". .It on kue0 Interface name equals "kue0". -.It ruleset authpf -Ruleset name equals "authpf". .It rulenum 10 Rule number equals 10. .It reason match Reason equals match. Also accepts "bad-offset", "fragment", "bad-timestamp", "short", -"normalize", "memory", "congestion", "ip-option", "proto-cksum", -"state-mismatch", "state-insert", "state-limit", "src-limit", -and "synproxy". +"normalize" and "memory". .It action pass Action equals pass. Also accepts "block". @@ -202,18 +180,16 @@ the wi0 interface: # tcpdump -n -e -ttt -i pflog0 inbound and action block and on wi0 .Ed .Sh SEE ALSO +.Xr tcpdump 1 , .Xr pcap 3 , .Xr pf 4 , .Xr pflog 4 , .Xr pf.conf 5 , -.Xr newsyslog 8 , -.Xr tcpdump 8 +.Xr newsyslog 8 .Sh HISTORY The .Nm command appeared in .Ox 3.0 . .Sh AUTHORS -.Nm -was written by -.An Can Erkin Acar Aq canacar@openbsd.org . +Can Erkin Acar diff --git a/contrib/pf/pflogd/pflogd.c b/contrib/pf/pflogd/pflogd.c index 168deb1..5f7ebdd 100644 --- a/contrib/pf/pflogd/pflogd.c +++ b/contrib/pf/pflogd/pflogd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pflogd.c,v 1.37 2006/10/26 13:34:47 jmc Exp $ */ +/* $OpenBSD: pflogd.c,v 1.33 2005/02/09 12:09:30 henning Exp $ */ /* * Copyright (c) 2001 Theo de Raadt @@ -30,6 +30,9 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + #include <sys/types.h> #include <sys/ioctl.h> #include <sys/file.h> @@ -45,7 +48,12 @@ #include <errno.h> #include <stdarg.h> #include <fcntl.h> +#ifdef __FreeBSD__ +#include "pidfile.h" +#else #include <util.h> +#endif + #include "pflogd.h" pcap_t *hpcap; @@ -73,7 +81,7 @@ int flush_buffer(FILE *); int init_pcap(void); void logmsg(int, const char *, ...); void purge_buffer(void); -int reset_dump(int); +int reset_dump(void); int scan_dump(FILE *, off_t); int set_snaplen(int); void set_suspended(int); @@ -82,8 +90,6 @@ void sig_close(int); void sig_hup(int); void usage(void); -static int try_reset_dump(int); - /* buffer must always be greater than snaplen */ static int bufpkt = 0; /* number of packets in buffer */ static int buflen = 0; /* allocated size of buffer */ @@ -102,9 +108,8 @@ set_suspended(int s) return; suspended = s; - setproctitle("[%s] -s %d -i %s -f %s", - suspended ? "suspended" : "running", - cur_snaplen, interface, filename); + setproctitle("[%s] -s %d -f %s", + suspended ? "suspended" : "running", cur_snaplen, filename); } char * @@ -147,12 +152,15 @@ logmsg(int pri, const char *message, ...) va_end(ap); } +#ifdef __FreeBSD__ +__dead2 void +#else __dead void +#endif usage(void) { - fprintf(stderr, "usage: pflogd [-Dx] [-d delay] [-f filename]"); - fprintf(stderr, " [-i interface] [-s snaplen]\n"); - fprintf(stderr, " [expression]\n"); + fprintf(stderr, "usage: pflogd [-Dx] [-d delay] [-f filename] "); + fprintf(stderr, "[-s snaplen] [expression]\n"); exit(1); } @@ -232,25 +240,7 @@ set_snaplen(int snap) } int -reset_dump(int nomove) -{ - int ret; - - for (;;) { - ret = try_reset_dump(nomove); - if (ret <= 0) - break; - } - - return (ret); -} - -/* - * tries to (re)open log file, nomove flag is used with -x switch - * returns 0: success, 1: retry (log moved), -1: error - */ -int -try_reset_dump(int nomove) +reset_dump(void) { struct pcap_file_header hdr; struct stat st; @@ -272,26 +262,26 @@ try_reset_dump(int nomove) */ fd = priv_open_log(); if (fd < 0) - return (-1); + return (1); fp = fdopen(fd, "a+"); if (fp == NULL) { - logmsg(LOG_ERR, "Error: %s: %s", filename, strerror(errno)); close(fd); - return (-1); + logmsg(LOG_ERR, "Error: %s: %s", filename, strerror(errno)); + return (1); } if (fstat(fileno(fp), &st) == -1) { - logmsg(LOG_ERR, "Error: %s: %s", filename, strerror(errno)); fclose(fp); - return (-1); + logmsg(LOG_ERR, "Error: %s: %s", filename, strerror(errno)); + return (1); } /* set FILE unbuffered, we do our own buffering */ if (setvbuf(fp, NULL, _IONBF, 0)) { - logmsg(LOG_ERR, "Failed to set output buffers"); fclose(fp); - return (-1); + logmsg(LOG_ERR, "Failed to set output buffers"); + return (1); } #define TCPDUMP_MAGIC 0xa1b2c3d4 @@ -299,9 +289,11 @@ try_reset_dump(int nomove) if (st.st_size == 0) { if (snaplen != cur_snaplen) { logmsg(LOG_NOTICE, "Using snaplen %d", snaplen); - if (set_snaplen(snaplen)) + if (set_snaplen(snaplen)) { + fclose(fp); logmsg(LOG_WARNING, "Failed, using old settings"); + } } hdr.magic = TCPDUMP_MAGIC; hdr.version_major = PCAP_VERSION_MAJOR; @@ -313,15 +305,11 @@ try_reset_dump(int nomove) if (fwrite((char *)&hdr, sizeof(hdr), 1, fp) != 1) { fclose(fp); - return (-1); + return (1); } } else if (scan_dump(fp, st.st_size)) { + /* XXX move file and continue? */ fclose(fp); - if (nomove || priv_move_log()) { - logmsg(LOG_ERR, - "Invalid/incompatible log file, move it away"); - return (-1); - } return (1); } @@ -337,7 +325,11 @@ int scan_dump(FILE *fp, off_t size) { struct pcap_file_header hdr; +#ifdef __FreeBSD__ + struct pcap_sf_pkthdr ph; +#else struct pcap_pkthdr ph; +#endif off_t pos; /* @@ -360,6 +352,7 @@ scan_dump(FILE *fp, off_t size) hdr.version_minor != PCAP_VERSION_MINOR || hdr.linktype != hpcap->linktype || hdr.snaplen > PFLOGD_MAXSNAPLEN) { + logmsg(LOG_ERR, "Invalid/incompatible log file, move it away"); return (1); } @@ -406,18 +399,35 @@ void dump_packet_nobuf(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) { FILE *f = (FILE *)user; +#ifdef __FreeBSD__ + struct pcap_sf_pkthdr sh; +#endif if (suspended) { packets_dropped++; return; } +#ifdef __FreeBSD__ + sh.ts.tv_sec = (bpf_int32)h->ts.tv_sec; + sh.ts.tv_usec = (bpf_int32)h->ts.tv_usec; + sh.caplen = h->caplen; + sh.len = h->len; + + if (fwrite((char *)&sh, sizeof(sh), 1, f) != 1) { +#else if (fwrite((char *)h, sizeof(*h), 1, f) != 1) { +#endif off_t pos = ftello(f); /* try to undo header to prevent corruption */ +#ifdef __FreeBSD__ + if (pos < sizeof(sh) || + ftruncate(fileno(f), pos - sizeof(sh))) { +#else if (pos < sizeof(*h) || ftruncate(fileno(f), pos - sizeof(*h))) { +#endif logmsg(LOG_ERR, "Write failed, corrupted logfile!"); set_suspended(1); gotsig_close = 1; @@ -486,7 +496,12 @@ void dump_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) { FILE *f = (FILE *)user; +#ifdef __FreeBSD__ + struct pcap_sf_pkthdr sh; + size_t len = sizeof(sh) + h->caplen; +#else size_t len = sizeof(*h) + h->caplen; +#endif if (len < sizeof(*h) || h->caplen > (size_t)cur_snaplen) { logmsg(LOG_NOTICE, "invalid size %u (%u/%u), packet dropped", @@ -513,9 +528,19 @@ dump_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) return; } - append: + append: +#ifdef __FreeBSD__ + sh.ts.tv_sec = (bpf_int32)h->ts.tv_sec; + sh.ts.tv_usec = (bpf_int32)h->ts.tv_usec; + sh.caplen = h->caplen; + sh.len = h->len; + + memcpy(bufpos, &sh, sizeof(sh)); + memcpy(bufpos + sizeof(sh), sp, h->caplen); +#else memcpy(bufpos, h, sizeof(*h)); memcpy(bufpos + sizeof(*h), sp, h->caplen); +#endif bufpos += len; bufleft -= len; @@ -532,9 +557,13 @@ main(int argc, char **argv) pcap_handler phandler = dump_packet; const char *errstr = NULL; +#ifdef __FreeBSD__ + /* another ?paranoid? safety measure we do not have */ +#else closefrom(STDERR_FILENO + 1); +#endif - while ((ch = getopt(argc, argv, "Dxd:f:i:s:")) != -1) { + while ((ch = getopt(argc, argv, "Dxd:s:f:")) != -1) { switch (ch) { case 'D': Debug = 1; @@ -547,9 +576,6 @@ main(int argc, char **argv) case 'f': filename = optarg; break; - case 'i': - interface = optarg; - break; case 's': snaplen = strtonum(optarg, 0, PFLOGD_MAXSNAPLEN, &errstr); @@ -622,7 +648,7 @@ main(int argc, char **argv) bufpkt = 0; } - if (reset_dump(Xflag) < 0) { + if (reset_dump()) { if (Xflag) return (1); @@ -634,13 +660,21 @@ main(int argc, char **argv) while (1) { np = pcap_dispatch(hpcap, PCAP_NUM_PKTS, phandler, (u_char *)dpcap); - if (np < 0) + if (np < 0) { +#ifdef __FreeBSD__ + if (errno == ENXIO) { + logmsg(LOG_ERR, + "Device not/no longer configured"); + break; + } +#endif logmsg(LOG_NOTICE, "%s", pcap_geterr(hpcap)); + } if (gotsig_close) break; if (gotsig_hup) { - if (reset_dump(0)) { + if (reset_dump()) { logmsg(LOG_ERR, "Logging suspended: open error"); set_suspended(1); @@ -651,8 +685,6 @@ main(int argc, char **argv) if (gotsig_alrm) { if (dpcap) flush_buffer(dpcap); - else - gotsig_hup = 1; gotsig_alrm = 0; alarm(delay); } diff --git a/contrib/pf/pflogd/pidfile.c b/contrib/pf/pflogd/pidfile.c index 61eca26..db6007f 100644 --- a/contrib/pf/pflogd/pidfile.c +++ b/contrib/pf/pflogd/pidfile.c @@ -1,3 +1,4 @@ +/* $FreeBSD$ */ /* $OpenBSD: pidfile.c,v 1.5 2002/05/26 09:29:02 deraadt Exp $ */ /* $NetBSD: pidfile.c,v 1.4 2001/02/19 22:43:42 cgd Exp $ */ @@ -47,7 +48,7 @@ static const char rcsid[] = "$OpenBSD: pidfile.c,v 1.5 2002/05/26 09:29:02 deraa #include <stdio.h> #include <stdlib.h> #include <unistd.h> -#if defined(__FreeBSD__) +#ifdef __FreeBSD__ #include "pidfile.h" #else #include <util.h> diff --git a/contrib/pf/pflogd/privsep.c b/contrib/pf/pflogd/privsep.c index 1139cb4..ac64ebe 100644 --- a/contrib/pf/pflogd/privsep.c +++ b/contrib/pf/pflogd/privsep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: privsep.c,v 1.16 2006/10/25 20:55:04 moritz Exp $ */ +/* $OpenBSD: privsep.c,v 1.13 2004/12/22 09:21:02 otto Exp $ */ /* * Copyright (c) 2003 Can Erkin Acar @@ -16,10 +16,13 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <sys/types.h> + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> #include <sys/time.h> #include <sys/socket.h> -#include <sys/ioctl.h> #include <net/if.h> #include <net/bpf.h> @@ -27,21 +30,19 @@ #include <err.h> #include <errno.h> #include <fcntl.h> -#include <limits.h> -#include <pcap.h> -#include <pcap-int.h> #include <pwd.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <pcap.h> +#include <pcap-int.h> #include <syslog.h> #include <unistd.h> #include "pflogd.h" enum cmd_types { PRIV_SET_SNAPLEN, /* set the snaplength */ - PRIV_MOVE_LOG, /* move logfile away */ PRIV_OPEN_LOG /* open logfile for appending */ }; @@ -56,8 +57,10 @@ static int may_read(int, void *, size_t); static void must_read(int, void *, size_t); static void must_write(int, void *, size_t); static int set_snaplen(int snap); -static int move_log(const char *name); +/* bpf filter expression common to parent and child */ +extern char *filter; +extern char *errbuf; extern char *filename; extern pcap_t *hpcap; @@ -69,7 +72,11 @@ priv_init(void) int snaplen, ret, olderrno; struct passwd *pw; +#ifdef __FreeBSD__ + for (i = 1; i < NSIG; i++) +#else for (i = 1; i < _NSIG; i++) +#endif signal(i, SIG_DFL); /* Create sockets */ @@ -95,12 +102,16 @@ priv_init(void) err(1, "unable to chdir"); gidset[0] = pw->pw_gid; - if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1) - err(1, "setresgid() failed"); if (setgroups(1, gidset) == -1) err(1, "setgroups() failed"); - if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1) - err(1, "setresuid() failed"); + if (setegid(pw->pw_gid) == -1) + err(1, "setegid() failed"); + if (setgid(pw->pw_gid) == -1) + err(1, "setgid() failed"); + if (seteuid(pw->pw_uid) == -1) + err(1, "seteuid() failed"); + if (setuid(pw->pw_uid) == -1) + err(1, "setuid() failed"); close(socks[0]); priv_fd = socks[1]; return 0; @@ -154,13 +165,6 @@ priv_init(void) close(fd); break; - case PRIV_MOVE_LOG: - logmsg(LOG_DEBUG, - "[priv]: msg PRIV_MOVE_LOG received"); - ret = move_log(filename); - must_write(socks[0], &ret, sizeof(int)); - break; - default: logmsg(LOG_ERR, "[priv]: unknown command %d", cmd); _exit(1); @@ -184,47 +188,6 @@ set_snaplen(int snap) return 0; } -static int -move_log(const char *name) -{ - char ren[PATH_MAX]; - int len; - - for (;;) { - int fd; - - len = snprintf(ren, sizeof(ren), "%s.bad.%08x", - name, arc4random()); - if (len >= sizeof(ren)) { - logmsg(LOG_ERR, "[priv] new name too long"); - return (1); - } - - /* lock destinanion */ - fd = open(ren, O_CREAT|O_EXCL, 0); - if (fd >= 0) { - close(fd); - break; - } - /* if file exists, try another name */ - if (errno != EEXIST && errno != EINTR) { - logmsg(LOG_ERR, "[priv] failed to create new name: %s", - strerror(errno)); - return (1); - } - } - - if (rename(name, ren)) { - logmsg(LOG_ERR, "[priv] failed to rename %s to %s: %s", - name, ren, strerror(errno)); - return (1); - } - - logmsg(LOG_NOTICE, - "[priv]: log file %s moved to %s", name, ren); - - return (0); -} /* * send the snaplength to privileged process @@ -266,21 +229,6 @@ priv_open_log(void) return (fd); } -/* Move-away and reopen log-file */ -int -priv_move_log(void) -{ - int cmd, ret; - - if (priv_fd < 0) - errx(1, "%s: called from privileged portion\n", __func__); - - cmd = PRIV_MOVE_LOG; - must_write(priv_fd, &cmd, sizeof(int)); - must_read(priv_fd, &ret, sizeof(int)); - - return (ret); -} /* If priv parent gets a TERM or HUP, pass it through to child instead */ static void |