Hi, attached patch updates arpwatch to add -u <username> flag, to drop privileges to non-privileged user after startup. Patch taken from Debian/Ubuntu, which originates from RedHat. user/group _arpwatch added to PLIST, and a user to be added to users.list
rc script is updated to add -u _arpwatch user to to the daemon. manpage. any comments, objections, or even OK? cheers, Sebastian Index: Makefile =================================================================== RCS file: /cvs/ports/net/arpwatch/Makefile,v retrieving revision 1.49 diff -u -r1.49 Makefile --- Makefile 24 Jul 2018 18:59:20 -0000 1.49 +++ Makefile 29 Oct 2018 13:51:33 -0000 @@ -3,7 +3,7 @@ COMMENT= monitor arp & rarp requests DISTNAME= arpwatch-2.1a15 -REVISION= 18 +REVISION= 19 CATEGORIES= net MASTER_SITES= ftp://ftp.ee.lbl.gov/ Index: patches/patch-arpwatch.8 =================================================================== RCS file: /cvs/ports/net/arpwatch/patches/patch-arpwatch.8,v retrieving revision 1.1 diff -u -r1.1 patch-arpwatch.8 --- patches/patch-arpwatch.8 1 Jun 2001 23:36:32 -0000 1.1 +++ patches/patch-arpwatch.8 29 Oct 2018 13:51:33 -0000 @@ -1,8 +1,40 @@ $OpenBSD: patch-arpwatch.8,v 1.1 2001/06/01 23:36:32 jakob Exp $ ---- arpwatch.8.orig Sat Jun 2 01:22:23 2001 -+++ arpwatch.8 Sat Jun 2 01:22:47 2001 -@@ -152,7 +152,7 @@ addresses was a DECnet address. +Add -u flag, to drop privileges to that user given + +Index: arpwatch.8 +--- arpwatch.8.orig ++++ arpwatch.8 +@@ -43,6 +43,9 @@ arpwatch - keep track of ethernet/ip address pairings + ]] [ + .B -r + .I file ++] [ ++.B -u ++.I username + ] + .ad + .SH DESCRIPTION +@@ -94,6 +97,18 @@ of reading from the network. In this case, + .B arpwatch + does not fork. + .LP ++The ++.B -u ++flag instructs ++.B arpwatch ++to drop root privileges and change the UID to ++.I username ++and GID to the primary group of ++.I username . ++This is recommended for security reasons, but ++.I username ++has to have write access to the default directory. ++.LP + Note that an empty + .I arp.dat + file must be created before the first time you run +@@ -152,7 +167,7 @@ addresses was a DECnet address. .na .nh .nf Index: patches/patch-arpwatch_c =================================================================== RCS file: /cvs/ports/net/arpwatch/patches/patch-arpwatch_c,v retrieving revision 1.1 diff -u -r1.1 patch-arpwatch_c --- patches/patch-arpwatch_c 15 May 2018 19:10:24 -0000 1.1 +++ patches/patch-arpwatch_c 29 Oct 2018 13:51:33 -0000 @@ -2,11 +2,80 @@ - Do not bail if the interface does not have an IP assigned. - time_t format string fixes +- add -u flag, to drop privileges to that user Index: arpwatch.c --- arpwatch.c.orig +++ arpwatch.c -@@ -223,9 +223,11 @@ main(int argc, char **argv) +@@ -63,6 +63,9 @@ struct rtentry; + #include <syslog.h> + #include <unistd.h> + ++#include <pwd.h> ++#include <grp.h> ++ + #include <pcap.h> + + #include "gnuc.h" +@@ -141,6 +144,24 @@ int sanity_ether(struct ether_header *, struct ether_a + int sanity_fddi(struct fddi_header *, struct ether_arp *, int); + __dead void usage(void) __attribute__((volatile)); + ++void dropprivileges(const char* user) ++{ ++ struct passwd* pw; ++ pw = getpwnam( user ); ++ if ( pw ) { ++ if ( initgroups(pw->pw_name, pw->pw_gid) != 0 || setgid(pw->pw_gid) != 0 || ++ setuid(pw->pw_uid) != 0 ) { ++ syslog(LOG_ERR, "Couldn't change to '%.32s' uid=%d gid=%d", user,pw->pw_uid, pw->pw_gid); ++ exit(1); ++ } ++ } ++ else { ++ syslog(LOG_ERR, "Couldn't find user '%.32s' in /etc/passwd", user); ++ exit(1); ++ } ++ syslog(LOG_INFO, "Running as uid=%d gid=%d", getuid(), getgid()); ++} ++ + int + main(int argc, char **argv) + { +@@ -153,6 +174,7 @@ main(int argc, char **argv) + register char *interface, *rfilename; + struct bpf_program code; + char errbuf[PCAP_ERRBUF_SIZE]; ++ char* username = NULL; + + if (argv[0] == NULL) + prog = "arpwatch"; +@@ -170,7 +192,7 @@ main(int argc, char **argv) + interface = NULL; + rfilename = NULL; + pd = NULL; +- while ((op = getopt(argc, argv, "df:i:n:Nr:")) != EOF) ++ while ((op = getopt(argc, argv, "df:i:n:Nr:u:")) != EOF) + switch (op) { + + case 'd': +@@ -202,6 +224,15 @@ main(int argc, char **argv) + rfilename = optarg; + break; + ++ case 'u': ++ if ( optarg ) { ++ username = strdup(optarg); ++ } else { ++ fprintf(stderr, "%s: Need username after -u\n", prog); ++ usage(); ++ } ++ break; ++ + default: + usage(); + } +@@ -223,9 +254,11 @@ main(int argc, char **argv) /* Determine network and netmask */ if (pcap_lookupnet(interface, &net, &netmask, errbuf) < 0) { @@ -21,7 +90,26 @@ } /* Drop into the background if not debugging */ -@@ -401,7 +403,7 @@ process_ether(register u_char *u, register const struc +@@ -279,12 +312,16 @@ main(int argc, char **argv) + #endif + } + ++ if ( username ) { ++ dropprivileges( username ); ++ } else { + /* + * Revert to non-privileged user after opening sockets + * (not needed on most systems). + */ +- setgid(getgid()); +- setuid(getuid()); ++ setgid(getgid()); ++ setuid(getuid()); ++ } + + /* Must be ethernet or fddi */ + linktype = pcap_datalink(pd); +@@ -401,7 +438,7 @@ process_ether(register u_char *u, register const struc t = h->ts.tv_sec; can_checkpoint = 0; if (!ent_add(sia, sea, t, NULL)) @@ -30,7 +118,7 @@ intoa(sia), e2str(sea), t); can_checkpoint = 1; } -@@ -550,7 +552,7 @@ process_fddi(register u_char *u, register const struct +@@ -550,7 +587,7 @@ process_fddi(register u_char *u, register const struct t = h->ts.tv_sec; can_checkpoint = 0; if (!ent_add(sia, sea, t, NULL)) @@ -38,4 +126,13 @@ + syslog(LOG_ERR, "ent_add(%s, %s, %lld) failed", intoa(sia), e2str(sea), t); can_checkpoint = 1; + } +@@ -750,7 +787,7 @@ usage(void) + extern char version[]; + + (void)fprintf(stderr, "Version %s\n", version); +- (void)fprintf(stderr, "usage: %s [-dN] [-f datafile] [-i interface]" ++ (void)fprintf(stderr, "usage: %s [-dN] [-f datafile] [-i interface] [-u username]" + " [-n net[/width]] [-r file]\n", prog); + exit(1); } Index: pkg/PLIST =================================================================== RCS file: /cvs/ports/net/arpwatch/pkg/PLIST,v retrieving revision 1.11 diff -u -r1.11 PLIST --- pkg/PLIST 16 May 2018 12:37:32 -0000 1.11 +++ pkg/PLIST 29 Oct 2018 13:51:33 -0000 @@ -1,4 +1,6 @@ @comment $OpenBSD: PLIST,v 1.11 2018/05/16 12:37:32 jasper Exp $ +@newgroup _arpwatch:820 +@newuser _arpwatch:820:_arpwatch:daemon:arpwatch user:/nonexistent:/sbin/nologin @man man/man8/arpsnmp.8 @man man/man8/arpwatch.8 @bin sbin/arpsnmp @@ -7,6 +9,7 @@ share/examples/arpwatch/ share/examples/arpwatch/arp.dat @mode 644 +@owner _arpwatch @sample /var/arpwatch/arp.dat @mode share/examples/arpwatch/arp2ethers Index: pkg/arpwatch.rc =================================================================== RCS file: /cvs/ports/net/arpwatch/pkg/arpwatch.rc,v retrieving revision 1.2 diff -u -r1.2 arpwatch.rc --- pkg/arpwatch.rc 11 Jan 2018 19:27:04 -0000 1.2 +++ pkg/arpwatch.rc 29 Oct 2018 13:51:33 -0000 @@ -2,7 +2,7 @@ # # $OpenBSD: arpwatch.rc,v 1.2 2018/01/11 19:27:04 rpe Exp $ -daemon="${TRUEPREFIX}/sbin/arpwatch" +daemon="${TRUEPREFIX}/sbin/arpwatch -u _arpwatch" . /etc/rc.d/rc.subr