Subject: bin/7995: comsat doesn't play too well with procmail and has a bug
To: None <gnats-bugs@gnats.netbsd.org>
From: TheMan <andrew@untraceable.net>
List: netbsd-bugs
Date: 07/14/1999 15:06:28
>Number:         7995
>Category:       bin
>Synopsis:       procmail's biff messages are not entirely understood by comsat *and* comsat has a bug from when it was vis-ified
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Jul 14 14:50:05 1999
>Last-Modified:
>Originator:     TheMan
>Organization:
me
>Release:        -current
>Environment:
	
System: NetBSD noc 1.3.3 NetBSD 1.3.3 (LINGAM) #11: Wed Jun 30 23:59:08 EDT 1999 root@:/usr/src/sys/arch/i386/compile/LINGAM i386


>Description:

comsat doesn't completely understand the messages that procmail sends
it after delivering mail, and can generate garbage or portions of old
messages as the notification by mistake.  more details on this in my
pr bin/7980.  but then i found a bug in the way comsat uses strvis(3).
this bug was introduced in 1.12 when comsat was taught to use vis
instead of some old stuff.

basically, comsat used to strip off the nl from the line it's about to
output (put out?), scan it for "dangerous" characters, print it, and
then fputs the correct "\n" or "n\r" sequence depending on the
terminal's settings.  now, it simply passes it all to strvis(3) and
prints it.  completely independently of the terminal settings.  bleah!

>How-To-Repeat:

turn on biff.  turn on comsat.  set up procmail and your .forward
file.  start reading your email using, for example, mutt (or,
basically, anything that will frob the onlcr tty flag off).  receive
mail in a folder other than your system inbox.  notice the following:

 (1) you seen garbage on your screen from a message other than the one
you received.  become confused.  (patch included below)
 (2) the garbage seems to step down your screen in the manner of
something ignorant of the absence of the onlcr flag.  wonder why,
since comsat seems to try to behave correctly.  realize that strvis(3)
is now being used, and "\n\r" is not.

>Fix:

--- comsat.c-orig	Mon Jul  6 07:09:06 1998
+++ comsat.c	Wed Jul 14 17:29:04 1999
@@ -79,9 +79,9 @@
 time_t	lastmsgtime;
 int	nutmp, uf;
 
-void jkfprintf __P((FILE *, char[], off_t));
+void jkfprintf __P((FILE *, char[], off_t, char *));
 void mailfor __P((char *));
-void notify __P((struct utmp *, off_t));
+void notify __P((struct utmp *, off_t, char *));
 void onalrm __P((int));
 void reapchildren __P((int));
 int main __P((int, char *[]));
@@ -193,24 +193,27 @@
 	char *name;
 {
 	struct utmp *utp = &utmp[nutmp];
-	char *cp;
+	char *cp, *folder;
 	off_t offset;
 
 	if (!(cp = strchr(name, '@')))
 		return;
 	*cp = '\0';
 	offset = atoi(cp + 1);
+	if ((folder = strchr(cp + 1, ':')))
+		folder += 1;
 	while (--utp >= utmp)
 		if (!strncmp(utp->ut_name, name, sizeof(utmp[0].ut_name)))
-			notify(utp, offset);
+			notify(utp, offset, folder);
 }
 
 static char *cr;
 
 void
-notify(utp, offset)
+notify(utp, offset, folder)
 	struct utmp *utp;
 	off_t offset;
+	char *folder;
 {
 	FILE *tp;
 	struct passwd *p;
@@ -258,24 +261,38 @@
 	if (logging)
 		syslog(LOG_INFO, "biff message for %s", name);
 
-	(void)fprintf(tp, "%s\007New mail for %s@%.*s\007 has arrived:%s----%s",
-	    cr, name, (int)sizeof(hostname), hostname, cr, cr);
-	jkfprintf(tp, name, offset);
+	if (!folder)
+		(void)fprintf(tp,
+		    "%s\007New mail for %s@%.*s\007 has arrived:%s----%s",
+		    cr, name, (int)sizeof(hostname), hostname, cr, cr);
+	else
+		(void)fprintf(tp,
+	"%s\007New mail for %s@%.*s\007 has arrived:%sFolder: %s%s----%s",
+		    cr, name, (int)sizeof(hostname), hostname, cr, folder,
+		    cr, cr);
+	jkfprintf(tp, name, offset, folder);
 	(void)fclose(tp);
 	_exit(0);
 }
 
 void
-jkfprintf(tp, name, offset)
+jkfprintf(tp, name, offset, folder)
 	FILE *tp;
 	char name[];
 	off_t offset;
+	char *folder;
 {
 	FILE *fi;
 	int linecnt, charcnt, inheader;
-	char line[BUFSIZ], visline[BUFSIZ*4];
+	char line[BUFSIZ], visline[BUFSIZ*4], *nl;
+	struct stat st;
 
-	if ((fi = fopen(name, "r")) == NULL)
+	fi = NULL;
+	if (folder != NULL && (fi = fopen(folder, "r")) == NULL)
+		return;
+	if (fi == NULL && (fi = fopen(name, "r")) == NULL)
+		return;
+	if (fstat(fileno(fi), &st) == -1 || getuid() != st.st_uid)
 		return;
 
 	(void)fseek(fi, offset, SEEK_SET);
@@ -288,6 +305,7 @@
 	charcnt = 560;
 	inheader = 1;
 	while (fgets(line, sizeof(line), fi) != NULL) {
+		line[sizeof(line - 1)] = 0;
 		if (inheader) {
 			if (line[0] == '\n') {
 				inheader = 0;
@@ -303,9 +321,12 @@
 			(void)fclose(fi);
 			return;
 		}
+		if ((nl = strchr(line, '\n')))
+			*nl = 0;
 		/* strip weird stuff so can't trojan horse stupid terminals */
 		(void)strvis(visline, line, VIS_CSTYLE);
-		fputs(visline, tp);
+		(void)fputs(visline, tp);
+	        (void)fputs(cr, tp);
 		--linecnt;
 	}
 	(void)fprintf(tp, "----%s\n", cr);
59c59
< .Dl user@mailbox-offset
---
> .Dl user@mailbox-offset[:/path/to/folder]
77a78,84
> .Pp
> The default
> file that
> .Nm
> searches is the user's system mailbox.  This
> can be overridden by specifying the folder to which new mail
> has been added in the udp message as indicated above.
110c117,118
< runs as root so that it can open the users maildrop.
---
> runs as root so that it can setuid to the user in order to open the user's
> maildrop.
>Audit-Trail:
>Unformatted: