NetBSD Problem Report #17142

Received: (qmail 1671 invoked by uid 605); 2 Jun 2002 13:38:29 -0000
Message-Id: <200206021338.g52DcGK25276@hrududu.wongs.net>
Date: Sun, 2 Jun 2002 09:38:16 -0400 (EDT)
From: ben@wongs.net
Sender: gnats-bugs-owner@netbsd.org
Reply-To: Benjamin.Wong@cc.gatech.edu
To: gnats-bugs@gnats.netbsd.org
Subject: Fingerd filters out international characters
X-Send-Pr-Version: 3.95

>Number:         17142
>Category:       bin
>Synopsis:       Fingerd filters out international characters
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Jun 02 13:39:00 +0000 2002
>Closed-Date:    Sat May 22 02:51:32 +0000 2021
>Last-Modified:  Sat May 22 02:51:32 +0000 2021
>Originator:     Ben Wong
>Release:        NetBSD-1.5.2
>Organization:
Georgia Institute of Technology
>Environment:

System: NetBSD hrududu.wongs.net 1.5 NetBSD 1.5 (HRUDUDU) #8: Tue May 15 04:47:24 EDT 2001 hackerb9@hrududu.wongs.net:/usr/src/sys/arch/i386/compile/HRUDUDU i386


>Description:

If a .plan file has international characters (e.g., latin1 or
unicode), the NetBSD finger daemon will clear the high-bit to make it
7-bit ASCII. RFC 1196 is quite clear on this point: characters between
128 and 255 are allowed for international data. It is up to the client
(finger) to filter out characters the terminal cannot (or should not)
reproduce.

>How-To-Repeat:

* Create an 8-bit .plan file. Latin-1 is sufficient, but here's unicode:

  echo "NetBSD \M-c\M^A\M-/\M-e\M^[\M-=\M-i\M^Z\M^[\M-g\M^Z\M^D\M-e\M^A\M-=\M-c\M^B\M^J\M-c\M^A\M-*\M-c\M^A\M^O\M-c\M^A\M-'\M-c\M^A\M^B\M-c\M^B\M^K" | unvis > ~/.plan

* Start up an xterm that can display unicode characters:

  xterm -u8 -fn '-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso10646-1'

* Turn on the fingerd in /etc/inetd.conf

* Try using finger to see the plan. It is mangled.

* Try using cat to see the plan. It works.


>Fix:

RFC 1196 recommends putting the filtering into the client instead of
the server. That way a user (or a sysadmin at an international site)
can choose to not filter the data.

RFC 1196: 3.3.  Client security

   It is expected that there will normally be some client program that
   the user runs to query the initial RUIP.  By default, this program
   SHOULD filter any unprintable data, leaving only printable 7-bit
   characters (ASCII 32 through ASCII 126), tabs (ASCII 9), and CRLFs.
   This is to protect against people playing with terminal escape codes,
   changing other peoples' X window names, or committing other dastardly
   or confusing deeds.  Two separate user options SHOULD be considered
   to modify this behavior, so that users may choose to view
   international or control characters:

      -    one to allow all characters less than ASCII 32

      -    another to allow all characters greater than ASCII 126

   For environments that live and breathe international data, the system
   administrator SHOULD be given a mechanism to enable the latter option
   by default for all users on a particular system.  This can be done
   via a global environment variable or similar mechanism.
>Release-Note:
>Audit-Trail:

From: itojun@iijlab.net
To: Benjamin.Wong@cc.gatech.edu
Cc: gnats-bugs@gnats.netbsd.org
Subject: Re: bin/17142: Fingerd filters out international characters 
Date: Sun, 02 Jun 2002 23:17:57 +0900

 >>Synopsis:       Fingerd filters out international characters

 	actually, the observation is not correct - libexec/fingerd just
 	invokes usr.bin/finger.  usr.bin/finger filters out 8th bit of
 	characters.  usr.bin/finger/lprint.c:show_text is the culprit.

 itojun

From: itojun@iijlab.net
To: Benjamin.Wong@cc.gatech.edu, gnats-bugs@gnats.netbsd.org
Cc:  
Subject: Re: bin/17142: Fingerd filters out international characters 
Date: Sun, 02 Jun 2002 23:33:54 +0900

 >>>Synopsis:       Fingerd filters out international characters
 >	actually, the observation is not correct - libexec/fingerd just
 >	invokes usr.bin/finger.  usr.bin/finger filters out 8th bit of
 >	characters.  usr.bin/finger/lprint.c:show_text is the culprit.

 	proposed fix follows.  you need to specify -n to both client and server:
 	- specify -n to fingerd to avoid vis(3) translation on sender side
 	- specify -n to finger to avoid stripping off 8th bit

 	alternatively, we may move vis(3) translation to the client side,
 	and make server side send anything in .plan.  however, i'm afraid
 	we will cause trouble to old-fashioned clients by doing so.

 	if there's any prior art for option character/behavior, we should
 	follow them.

 itojun


 Index: etc/inetd.conf
 ===================================================================
 RCS file: /cvsroot/basesrc/etc/inetd.conf,v
 retrieving revision 1.46
 diff -u -r1.46 inetd.conf
 --- etc/inetd.conf	2001/11/21 10:27:53	1.46
 +++ etc/inetd.conf	2002/06/02 14:30:59
 @@ -16,8 +16,8 @@
  #uucpd		stream	tcp	nowait	root	/usr/libexec/uucpd	uucpd -l
  #uucpd		stream	tcp6	nowait	root	/usr/libexec/uucpd	uucpd -l
  #nntp		stream	tcp	nowait	usenet	/usr/libexec/nntpd	nntpd
 -#finger		stream	tcp	nowait	nobody	/usr/libexec/fingerd	fingerd -l
 -#finger		stream	tcp6	nowait	nobody	/usr/libexec/fingerd	fingerd -l
 +#finger		stream	tcp	nowait	nobody	/usr/libexec/fingerd	fingerd -l -n
 +#finger		stream	tcp6	nowait	nobody	/usr/libexec/fingerd	fingerd -l -n
  #ident		stream	tcp	nowait	nobody:kmem /usr/libexec/identd	identd -l -o -e -N
  #tftp		dgram	udp	wait	root	/usr/libexec/tftpd	tftpd -l -s /tftpboot
  #tftp		dgram	udp6	wait	root	/usr/libexec/tftpd	tftpd -l -s /tftpboot
 Index: libexec/fingerd/fingerd.8
 ===================================================================
 RCS file: /cvsroot/basesrc/libexec/fingerd/fingerd.8,v
 retrieving revision 1.12
 diff -u -r1.12 fingerd.8
 --- libexec/fingerd/fingerd.8	2002/01/15 02:19:50	1.12
 +++ libexec/fingerd/fingerd.8	2002/06/02 14:30:59
 @@ -49,6 +49,7 @@
  .Op Fl p
  .Op Fl S
  .Op Fl g
 +.Op Fl n
  .Op Fl P Ar filename
  .Sh DESCRIPTION
  .Nm
 @@ -146,6 +147,9 @@
  that may be passed in from the remote client.
  .It Fl g
  Do not show any gecos information besides the users' real names.
 +.It Fl n
 +Do not strip off 8th bit of the character stream, nor translate them with
 +.Xr vis 3 .
  .It Fl P
  Use an alternate program as the local information provider.
  The default local program
 Index: libexec/fingerd/fingerd.c
 ===================================================================
 RCS file: /cvsroot/basesrc/libexec/fingerd/fingerd.c,v
 retrieving revision 1.14
 diff -u -r1.14 fingerd.c
 --- libexec/fingerd/fingerd.c	2002/04/09 00:55:15	1.14
 +++ libexec/fingerd/fingerd.c	2002/06/02 14:31:00
 @@ -83,7 +83,7 @@
  	logging = no_forward = user_required = short_list = 0;
  	openlog("fingerd", LOG_PID, LOG_DAEMON);
  	opterr = 0;
 -	while ((ch = getopt(argc, argv, "gsluShmpP:")) != -1)
 +	while ((ch = getopt(argc, argv, "gsluShmpP:n")) != -1)
  		switch (ch) {
  		case 'l':
  			logging = 1;
 @@ -112,6 +112,9 @@
  			break;
  		case 'g':
  			av[ac++] = "-g";
 +			break;
 +		case 'n':
 +			av[ac++] = "-n";
  			break;
  		case '?':
  		default:
 Index: usr.bin/finger/extern.h
 ===================================================================
 RCS file: /cvsroot/basesrc/usr.bin/finger/extern.h,v
 retrieving revision 1.6
 diff -u -r1.6 extern.h
 --- usr.bin/finger/extern.h	1998/07/26 21:35:28	1.6
 +++ usr.bin/finger/extern.h	2002/06/02 14:31:00
 @@ -43,6 +43,7 @@
  extern int oflag;
  extern int gflag;
  extern int pplan;
 +extern int nflag;

  void	 enter_lastlog __P((PERSON *));
  PERSON	*enter_person __P((struct passwd *));
 Index: usr.bin/finger/finger.1
 ===================================================================
 RCS file: /cvsroot/basesrc/usr.bin/finger/finger.1,v
 retrieving revision 1.11
 diff -u -r1.11 finger.1
 --- usr.bin/finger/finger.1	1999/03/22 18:16:37	1.11
 +++ usr.bin/finger/finger.1	2002/06/02 14:31:00
 @@ -41,7 +41,7 @@
  .Nd user information lookup program
  .Sh SYNOPSIS
  .Nm
 -.Op Fl lmpshog
 +.Op Fl lmpshogn
  .Op Ar user ...
  .Op Ar user@host ...
  .Sh DESCRIPTION
 @@ -148,6 +148,9 @@
  All name matching performed by
  .Nm
  is case insensitive.
 +.It Fl n
 +Do not strip off 8th bit of the character stream, nor translate them with
 +.Xr vis 3 .
  .El
  .Pp
  If no options are specified,
 Index: usr.bin/finger/finger.c
 ===================================================================
 RCS file: /cvsroot/basesrc/usr.bin/finger/finger.c,v
 retrieving revision 1.15
 diff -u -r1.15 finger.c
 --- usr.bin/finger/finger.c	2002/05/02 13:04:10	1.15
 +++ usr.bin/finger/finger.c	2002/06/02 14:31:01
 @@ -93,7 +93,7 @@

  DB *db;
  time_t now;
 -int entries, gflag, lflag, mflag, oflag, sflag, pplan;
 +int entries, gflag, lflag, mflag, oflag, sflag, pplan, nflag;
  char tbuf[1024];

  static void loginlist __P((void));
 @@ -109,7 +109,7 @@

  	oflag = 1;		/* default to old "office" behavior */

 -	while ((ch = getopt(argc, argv, "lmpshog")) != -1)
 +	while ((ch = getopt(argc, argv, "lmpshogn")) != -1)
  		switch(ch) {
  		case 'l':
  			lflag = 1;		/* long format */
 @@ -131,6 +131,9 @@
  			break;
  		case 'g':
  			gflag = 1;		/* no gecos info, besides name */
 +			break;
 +		case 'n':
 +			nflag = 1;		/* no vis() translation */
  			break;
  		case '?':
  		default:
 Index: usr.bin/finger/lprint.c
 ===================================================================
 RCS file: /cvsroot/basesrc/usr.bin/finger/lprint.c,v
 retrieving revision 1.12
 diff -u -r1.12 lprint.c
 --- usr.bin/finger/lprint.c	1998/12/19 16:00:33	1.12
 +++ usr.bin/finger/lprint.c	2002/06/02 14:31:02
 @@ -361,8 +361,12 @@
  {
  	char visout[5], *s2;

 -	ch = toascii(ch);
 -	vis(visout, ch, VIS_SAFE|VIS_NOSLASH, 0);
 -	for (s2 = visout; *s2; s2++)
 -		(void)putchar(*s2);
 +	if (nflag)
 +		putchar(ch);
 +	else {
 +		ch = toascii(ch);
 +		vis(visout, ch, VIS_SAFE|VIS_NOSLASH, 0);
 +		for (s2 = visout; *s2; s2++)
 +			(void)putchar(*s2);
 +	}
  }
 Index: usr.bin/finger/net.c
 ===================================================================
 RCS file: /cvsroot/basesrc/usr.bin/finger/net.c,v
 retrieving revision 1.14
 diff -u -r1.14 net.c
 --- usr.bin/finger/net.c	2000/07/07 15:13:22	1.14
 +++ usr.bin/finger/net.c	2002/06/02 14:31:02
 @@ -139,15 +139,17 @@
  	 */
  	if ((fp = fdopen(s, "r")) != NULL)
  		while ((c = getc(fp)) != EOF) {
 -			c &= 0x7f;
 +			if (!nflag)
 +				c &= 0x7f;
  			if (c == '\r') {
  				if (lastc == '\r')	/* ^M^M - skip dupes */
  					continue;
  				c = '\n';
  				lastc = '\r';
  			} else {
 -				if (!isprint(c) && !isspace(c))
 -					c |= 0x40;
 +				if (!nflag)
 +					if (!isprint(c) && !isspace(c))
 +						c |= 0x40;
  				if (lastc != '\r' || c != '\n')
  					lastc = c;
  				else {

From: itojun@iijlab.net
To: Benjamin.Wong@cc.gatech.edu, gnats-bugs@gnats.netbsd.org
Cc:  
Subject: Re: bin/17142: Fingerd filters out international characters 
Date: Mon, 03 Jun 2002 00:10:34 +0900

 >>>>Synopsis:       Fingerd filters out international characters
 >>	actually, the observation is not correct - libexec/fingerd just
 >>	invokes usr.bin/finger.  usr.bin/finger filters out 8th bit of
 >>	characters.  usr.bin/finger/lprint.c:show_text is the culprit.
 >	proposed fix follows.  you need to specify -n to both client and server:
 >	- specify -n to fingerd to avoid vis(3) translation on sender side
 >	- specify -n to finger to avoid stripping off 8th bit

 	more proper fix would be to extend finger protocol to pass charset
 	information...

 itojun

From: David Laight <david@l8s.co.uk>
To: Benjamin.Wong@cc.gatech.edu
Cc: gnats-bugs@gnats.netbsd.org
Subject: Re: bin/17142: Fingerd filters out international characters
Date: Wed, 5 Jun 2002 21:36:52 +0100

 > 
 > * Turn on the fingerd in /etc/inetd.conf
 > 
 > * Try using finger to see the plan. It is mangled.

 Do you know which of the above is stripping the top bits?

 Changing 'finger' is dangerous - you really need to strip
 the escape characters - even if you don't strip to 7-bit chars.



 >    For environments that live and breathe international data, the system
 >    administrator SHOULD be given a mechanism to enable the latter option
 >    by default for all users on a particular system.  This can be done
 >    via a global environment variable or similar mechanism.

 But the entire internet is one 'environment'......

 By far the worst thing to get set is the 'answerback' message
 of a terminal, followed by a request to send it to the host.

 (I recall some people getting VERY confused by a directory
 with a filename that caused a terminal to send its identification
 sequence... and that had been accidental!)

 	David

 -- 
 David Laight: david@l8s.co.uk
State-Changed-From-To: open->closed
State-Changed-By: dholland@NetBSD.org
State-Changed-When: Sat, 22 May 2021 02:51:32 +0000
State-Changed-Why:
It was the way it was for reasons, and nowadays fingerd is a dead article
anyway, so there's no point keeping this open or thinking about it further :-|


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.46 2020/01/03 16:35:01 leot Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2020 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.