Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 23 Jul 2001 22:39:04 -0700
From:      Kris Kennaway <kris@obsecurity.org>
To:        audit@FreeBSD.org
Subject:   rwhod signal fixes
Message-ID:  <20010723223904.A1381@xor.obsecurity.org>

next in thread | raw e-mail | index | archive | help

--J2SCkAp4GZ/dPZZf
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Another one from OpenBSD (modulo a few local changes).  I can't test
this; is anyone able to do so?

Kris

Index: rwhod.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /mnt/ncvs/src/usr.sbin/rwhod/rwhod.c,v
retrieving revision 1.15
diff -u -r1.15 rwhod.c
--- rwhod.c	2000/12/22 21:30:15	1.15
+++ rwhod.c	2001/07/24 05:35:56
@@ -63,6 +63,7 @@
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <poll.h>
 #include <netdb.h>
 #include <paths.h>
 #include <stdio.h>
@@ -149,16 +150,20 @@
 struct	servent *sp;
 int	s, utmpf;
=20
+int	gothup;
+
 #define	WHDRSIZE	(sizeof(mywd) - sizeof(mywd.wd_we))
=20
-void	 run_as __P((uid_t *, gid_t *));
 int	 configure __P((int));
-void	 getboottime __P((int));
-void	 onalrm __P((int));
+void	 getboottime __P((void));
+void	 handleread __P((int s));
+void	 hup __P((int));
 void	 quit __P((char *));
 void	 rt_xaddrs __P((caddr_t, caddr_t, struct rt_addrinfo *));
-int	 verify __P((char *, int));
+void	 run_as __P((uid_t *, gid_t *));
+void	 timer __P((void));
 static void usage __P((void));
+int	 verify __P((char *, int));
 #ifdef DEBUG
 char	*interval __P((int, char *));
 void	 Sendto __P((int, const void *, size_t, int,
@@ -166,17 +171,23 @@
 #define	 sendto Sendto
 #endif
=20
+void
+hup(signo)
+	int signo;
+{
+	gothup =3D 1;
+}
+
 int
 main(argc, argv)
 	int argc;
 	char *argv[];
 {
-	struct sockaddr_in from;
-	struct stat st;
-	char path[64];
+	struct pollfd pfd[1];
 	int on =3D 1;
 	char *cp;
 	struct sockaddr_in sin;
+	struct timeval start, next, delta, now;
 	uid_t unpriv_uid;
 	gid_t unpriv_gid;
=20
@@ -213,7 +224,7 @@
 #ifndef DEBUG
 	daemon(1, 0);
 #endif
-	(void) signal(SIGHUP, getboottime);
+	(void) signal(SIGHUP, hup);
 	openlog("rwhod", LOG_PID, LOG_DAEMON);
 	sp =3D getservbyname("who", "udp");
 	if (sp =3D=3D NULL) {
@@ -240,7 +251,7 @@
 		syslog(LOG_ERR, "%s: %m", _PATH_UTMP);
 		exit(1);
 	}
-	getboottime(0);
+	getboottime();
 	if ((s =3D socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
 		syslog(LOG_ERR, "socket: %m");
 		exit(1);
@@ -263,74 +274,109 @@
 	if (!configure(s))
 		exit(1);
 	if (!quiet_mode) {
-		signal(SIGALRM, onalrm);
-		onalrm(0);
+		timer();
+		gettimeofday(&start, NULL);
+		delta.tv_sec =3D AL_INTERVAL;
+		delta.tv_usec =3D 0;
+		timeradd(&start, &delta, &next);
 	}
+
+	pfd[0].fd =3D s;
+	pfd[0].revents =3D POLLIN;
 	for (;;) {
-		struct whod wd;
-		int cc, whod, len =3D sizeof(from);
+		int n;
=20
-		cc =3D recvfrom(s, (char *)&wd, sizeof(struct whod), 0,
-			(struct sockaddr *)&from, &len);
-		if (cc <=3D 0) {
-			if (cc < 0 && errno !=3D EINTR)
-				syslog(LOG_WARNING, "recv: %m");
-			continue;
-		}
-		if (from.sin_port !=3D sp->s_port && !insecure_mode) {
-			syslog(LOG_WARNING, "%d: bad source port from %s",
-			    ntohs(from.sin_port), inet_ntoa(from.sin_addr));
-			continue;
-		}
-		if (cc < WHDRSIZE) {
-			syslog(LOG_WARNING, "short packet from %s",
-			    inet_ntoa(from.sin_addr));
-			continue;
-		}
-		if (wd.wd_vers !=3D WHODVERSION)
-			continue;
-		if (wd.wd_type !=3D WHODTYPE_STATUS)
-			continue;
-		if (!verify(wd.wd_hostname, sizeof wd.wd_hostname)) {
-			syslog(LOG_WARNING, "malformed host name from %s",
-			    inet_ntoa(from.sin_addr));
-			continue;
-		}
-		(void) snprintf(path, sizeof path, "whod.%s", wd.wd_hostname);
-		/*
-		 * Rather than truncating and growing the file each time,
-		 * use ftruncate if size is less than previous size.
-		 */
-		whod =3D open(path, O_WRONLY | O_CREAT, 0644);
-		if (whod < 0) {
-			syslog(LOG_WARNING, "%s: %m", path);
-			continue;
+		n =3D poll(pfd, 1, 1000);
+
+		if (gothup) {
+			gothup =3D 0;
+			getboottime();
+		}
+
+		if (n =3D=3D 1)
+			handleread(s);
+		if (!quiet_mode) {
+			gettimeofday(&now, NULL);
+			if (timercmp(&now, &next, >)) {
+			    timer();
+			    timeradd(&now, &delta, &next);
+			}
 		}
+	=09
+	}
+}
+
+void
+handleread(s)
+	int s;
+{
+	struct sockaddr_in from;
+	struct stat st;
+	char path[64];
+	struct whod wd;
+	int cc, whod, len =3D sizeof(from);
+
+	cc =3D recvfrom(s, (char *)&wd, sizeof(struct whod), 0,
+	    (struct sockaddr *)&from, &len);
+	if (cc <=3D 0) {
+		if (cc < 0 && errno !=3D EINTR)
+			syslog(LOG_WARNING, "recv: %m");
+		return;
+	}
+	if (from.sin_port !=3D sp->s_port && !insecure_mode) {
+		syslog(LOG_WARNING, "%d: bad source port from %s",
+		    ntohs(from.sin_port), inet_ntoa(from.sin_addr));
+		return;
+	}
+	if (cc < WHDRSIZE) {
+		syslog(LOG_WARNING, "short packet from %s",
+		    inet_ntoa(from.sin_addr));
+		return;
+	}
+	if (wd.wd_vers !=3D WHODVERSION)
+		return;
+	if (wd.wd_type !=3D WHODTYPE_STATUS)
+		return;
+	wd.wd_hostname[sizeof(wd.wd_hostname)-1] =3D '\0';
+	if (!verify(wd.wd_hostname, sizeof wd.wd_hostname)) {
+		syslog(LOG_WARNING, "malformed host name from %s",
+		    inet_ntoa(from.sin_addr));
+		return;
+	}
+	(void) snprintf(path, sizeof path, "whod.%s", wd.wd_hostname);
+	/*
+	 * Rather than truncating and growing the file each time,
+	 * use ftruncate if size is less than previous size.
+	 */
+	whod =3D open(path, O_WRONLY | O_CREAT, 0644);
+	if (whod < 0) {
+		syslog(LOG_WARNING, "%s: %m", path);
+		return;
+	}
 #if ENDIAN !=3D BIG_ENDIAN
-		{
-			int i, n =3D (cc - WHDRSIZE)/sizeof(struct whoent);
-			struct whoent *we;
-
-			/* undo header byte swapping before writing to file */
-			wd.wd_sendtime =3D ntohl(wd.wd_sendtime);
-			for (i =3D 0; i < 3; i++)
-				wd.wd_loadav[i] =3D ntohl(wd.wd_loadav[i]);
-			wd.wd_boottime =3D ntohl(wd.wd_boottime);
-			we =3D wd.wd_we;
-			for (i =3D 0; i < n; i++) {
-				we->we_idle =3D ntohl(we->we_idle);
-				we->we_utmp.out_time =3D
-				    ntohl(we->we_utmp.out_time);
-				we++;
-			}
+	{
+		int i, n =3D (cc - WHDRSIZE)/sizeof(struct whoent);
+		struct whoent *we;
+
+		/* undo header byte swapping before writing to file */
+		wd.wd_sendtime =3D ntohl(wd.wd_sendtime);
+		for (i =3D 0; i < 3; i++)
+			wd.wd_loadav[i] =3D ntohl(wd.wd_loadav[i]);
+		wd.wd_boottime =3D ntohl(wd.wd_boottime);
+		we =3D wd.wd_we;
+		for (i =3D 0; i < n; i++) {
+			we->we_idle =3D ntohl(we->we_idle);
+			we->we_utmp.out_time =3D
+			    ntohl(we->we_utmp.out_time);
+			we++;
 		}
-#endif
-		(void) time((time_t *)&wd.wd_recvtime);
-		(void) write(whod, (char *)&wd, cc);
-		if (fstat(whod, &st) < 0 || st.st_size > cc)
-			ftruncate(whod, cc);
-		(void) close(whod);
 	}
+#endif
+	(void) time((time_t *)&wd.wd_recvtime);
+	(void) write(whod, (char *)&wd, cc);
+	if (fstat(whod, &st) < 0 || st.st_size > cc)
+		ftruncate(whod, cc);
+	(void) close(whod);
 }
=20
 static void
@@ -391,8 +437,7 @@
 int	alarmcount;
=20
 void
-onalrm(signo)
-	int signo;
+timer()
 {
 	register struct neighbor *np;
 	register struct whoent *we =3D mywd.wd_we, *wlast;
@@ -404,7 +449,7 @@
=20
 	now =3D time(NULL);
 	if (alarmcount % 10 =3D=3D 0)
-		getboottime(0);
+		getboottime();
 	alarmcount++;
 	(void) fstat(utmpf, &stb);
 	if ((stb.st_mtime !=3D utmptime) || (stb.st_size > utmpsize)) {
@@ -418,14 +463,14 @@
 			if (! utmp) {
 				syslog(LOG_WARNING, "malloc failed");
 				utmpsize =3D 0;
-				goto done;
+				return;
 			}
 		}
 		(void) lseek(utmpf, (off_t)0, L_SET);
 		cc =3D read(utmpf, (char *)utmp, stb.st_size);
 		if (cc < 0) {
 			syslog(LOG_ERR, "read(%s): %m", _PATH_UTMP);
-			goto done;
+			return;
 		}
 		wlast =3D &mywd.wd_we[1024 / sizeof(struct whoent) - 1];
 		utmpent =3D cc / sizeof(struct utmp);
@@ -493,13 +538,10 @@
 		syslog(LOG_ERR, "chdir(%s): %m", _PATH_RWHODIR);
 		exit(1);
 	}
-done:
-	(void) alarm(AL_INTERVAL);
 }
=20
 void
-getboottime(signo)
-	int signo;
+getboottime()
 {
 	int mib[2];
 	size_t size;
@@ -691,10 +733,10 @@
 	register struct whoent *we;
 	struct sockaddr_in *sin =3D (struct sockaddr_in *)to;
=20
-	printf("sendto %x.%d\n", ntohl(sin->sin_addr.s_addr),
-				 ntohs(sin->sin_port));
+	printf("sendto %s.%d\n", inet_ntoa(sin->sin_addr),
+	    ntohs(sin->sin_port));
 	printf("hostname %s %s\n", w->wd_hostname,
-	   interval(ntohl(w->wd_sendtime) - ntohl(w->wd_boottime), "  up"));
+	    interval(ntohl(w->wd_sendtime) - ntohl(w->wd_boottime), "  up"));
 	printf("load %4.2f, %4.2f, %4.2f\n",
 	    ntohl(w->wd_loadav[0]) / 100.0, ntohl(w->wd_loadav[1]) / 100.0,
 	    ntohl(w->wd_loadav[2]) / 100.0);
@@ -702,9 +744,9 @@
 	for (we =3D w->wd_we, cc /=3D sizeof(struct whoent); cc > 0; cc--, we++) {
 		time_t t =3D ntohl(we->we_utmp.out_time);
 		printf("%-8.8s %s:%s %.12s",
-			we->we_utmp.out_name,
-			w->wd_hostname, we->we_utmp.out_line,
-			ctime(&t)+4);
+		    we->we_utmp.out_name,
+		    w->wd_hostname, we->we_utmp.out_line,
+		    ctime(&t)+4);
 		we->we_idle =3D ntohl(we->we_idle) / 60;
 		if (we->we_idle) {
 			if (we->we_idle >=3D 100*60)
@@ -728,18 +770,19 @@
 	int days, hours, minutes;
=20
 	if (time < 0 || time > 3*30*24*60*60) {
-		(void) sprintf(resbuf, "   %s ??:??", updown);
+		(void) snprintf(resbuf, sizeof(resbuf),
+		    "   %s ??:??", updown);
 		return (resbuf);
 	}
 	minutes =3D (time + 59) / 60;		/* round to minutes */
 	hours =3D minutes / 60; minutes %=3D 60;
 	days =3D hours / 24; hours %=3D 24;
 	if (days)
-		(void) sprintf(resbuf, "%s %2d+%02d:%02d",
-		    updown, days, hours, minutes);
+		(void) snprintf(resbuf, sizeof(resbuf),
+		    "%s %2d+%02d:%02d", updown, days, hours, minutes);
 	else
-		(void) sprintf(resbuf, "%s    %2d:%02d",
-		    updown, hours, minutes);
+		(void) snprintf(resbuf, sizeof(resbuf),
+		    "%s    %2d:%02d", updown, hours, minutes);
 	return (resbuf);
 }
 #endif

--J2SCkAp4GZ/dPZZf
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (FreeBSD)
Comment: For info see http://www.gnupg.org

iD8DBQE7XQn3Wry0BWjoQKURArY3AJsGycSh05K0Q3szHse/o8eRkOccIQCg4eoO
5O8+xbwyYyjp+nQfX4pFwYg=
=H8VJ
-----END PGP SIGNATURE-----

--J2SCkAp4GZ/dPZZf--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-audit" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010723223904.A1381>