From jooji@neptune.oceancomputer.com  Mon Dec 28 15:02:38 1998
Received: from neptune.oceancomputer.com (ns1.oceancomputer.com [209.36.77.133])
          by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id PAA07787
          for <FreeBSD-gnats-submit@freebsd.org>; Mon, 28 Dec 1998 15:02:37 -0800 (PST)
          (envelope-from jooji@neptune.oceancomputer.com)
Received: (from jooji@localhost)
	by neptune.oceancomputer.com (8.9.1/8.8.8) id SAA00571;
	Mon, 28 Dec 1998 18:02:15 -0500 (EST)
	(envelope-from jooji)
Message-Id: <199812282302.SAA00571@neptune.oceancomputer.com>
Date: Mon, 28 Dec 1998 18:02:15 -0500 (EST)
From: jooji@neptune.oceancomputer.com
Reply-To: jooji@neptune.oceancomputer.com
To: FreeBSD-gnats-submit@freebsd.org
Subject: telnetd can log wrong IP address to utmp
X-Send-Pr-Version: 3.2

>Number:         9226
>Category:       bin
>Synopsis:       telnetd can log wrong IP address to utmp
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    brian
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Dec 28 15:10:00 PST 1998
>Closed-Date:    Wed May 24 15:32:21 PDT 2000
>Last-Modified:  Wed May 24 15:32:46 PDT 2000
>Originator:     Jasper O'Malley
>Release:        FreeBSD 2.2.8-STABLE i386
>Organization:
Ocean Computer Group, Inc.
>Environment:

Made the world and a new kernel with sources cvsupped on Dec 21:

FreeBSD neptune.oceancomputer.com 2.2.8-STABLE FreeBSD 2.2.8-STABLE #0: Tue Dec
22 10:21:07 EST 1998

>Description:

After renumbering a customer's network with new IP addresses, I telneted into
my server (neptune.oceancomputer.com), where I noticed that "who", "w -n", and
"last" were displaying the old IP address of the machine I was telneting from
as the source address. "netstat -n" correctly displayed the new IP address.

It's the result of a reverse DNS that doesn't agree with forward DNS (because
the cache on the server's nameserver hadn't expired the old forward DNS for
the customer site yet). My guess is that telnetd (or login?) apparently does a
reverse lookup on the source IP address from the socket object, and if the
hostname length exceeds UT_HOSTSIZE, it does a forward lookup on the hostname
it just got, and sticks that in ut_host[]. If the hostname generated by the
reverse lookup resolves to a different IP, and it's larger than UT_HOSTSIZE,
the wrong IP address gets stuck in utmp.

Here's the output from "who", "w", "w -n", and "last":

jooji@neptune:~ {7} who
jooji    ttyp0   Dec 28 12:35   (206.34.173.214)

jooji@neptune:~ {8} w
12:41PM  up 6 days,  1:27, 1 user, load averages: 0.06, 0.01, 0.00
USER     TTY      FROM              LOGIN@  IDLE WHAT
jooji    p0       rb01pxy.vnacj.or 12:35PM     - w

jooji@neptune:~ {9} w -n
12:41PM  up 6 days,  1:28, 1 user, load averages: 0.06, 0.01, 0.00
USER     TTY      FROM              LOGIN@  IDLE WHAT
jooji    p0       206.34.173.214   12:35PM     - w -n

jooji@neptune:~ {10} last jooji | head -1
jooji    ttyp0    206.34.173.214   Mon Dec 28 12:35   still logged in

[end output]

And here's the output from netstat -finet showing the correct source IP
(216.116.129.214):

jooji@neptune:~ {11} netstat -nfinet
Active Internet connections
Proto Recv-Q Send-Q  Local Address          Foreign Address        (state)
tcp        0      4  209.36.77.133.23       216.116.129.214.1661   ESTABLISHED

[end output]

And the output of nslookup, showing the disparate forward and reverse
DNS as neptune sees it:

jooji@neptune:~ {12} nslookup rb01pxy.vnacj.org
Server:  ns1.oceancomputer.com
Address:  209.36.77.133

Non-authoritative answer:
Name:    rb01pxy.vnacj.org
Address:  206.34.173.214

jooji@neptune:~ {13} nslookup 216.116.129.214
Server:  ns1.oceancomputer.com
Address:  209.36.77.133

Name:    rb01pxy.vnacj.org
Address:  216.116.129.214

[end output]

At first glance, it appears to be little more than a nuisance, but it could
allow some malicious bastard to jump into your machine with a bogus entry
in your lastlog.

>How-To-Repeat:

Change the IP address on a machine, update the reverse DNS, and leave forward
DNS where it is. Then telnet into a FreeBSD box.

>Fix:
	
Change the source for whatever actually fills the ut_host[] array in the
utmp structure for the connection so that if the hostname exceeds UT_HOSTSIZE,
it enters the IP address from the socket object (socket->sin_addr), rather
than doing a forward lookup on the hostname. I don't have a patch to offer
just now, but I'll see to it tonight.

>Release-Note:
>Audit-Trail:

From: "Jasper O'Malley" <jooji@neptune.oceancomputer.com>
To: FreeBSD-gnats-submit@FreeBSD.ORG, freebsd-bugs@FreeBSD.ORG
Cc:  Subject: Re: bin/9226: telnetd can log wrong IP address to utmp
Date: Tue, 29 Dec 1998 00:46:13 -0500 (EST)

 I've found the easiest bit to fix to clear up the instant problem. In
 src/libexec/telnetd/sys_term.c, a line reads:
 
 int     utmp_len = MAXHOSTNAMELEN;
 
 It should probably read:
 
 int     utmp_len = UT_HOSTSIZE;
 
 and should be moved after the #ifdef NEWINIT/#endif block (in which
 utmp.h is included). The diff provided should work okay.
 
 This will prevent telnetd from passing hostnames longer than UT_HOSTSIZE
 on as arguments to "login -h", which is what gets the hostname relooked
 up by login(1) in the first place. It doesn't appear this change will
 break anything else, but I can't swear to it.
 
 Better solutions would be to:
 
  a) Make UT_HOSTSIZE bigger, which would break 4.4BSD utmp compatibility,
     which isn't why it hasn't been done yet.
 
  b) Rewrite/patch login(1), xterm(1), sshd(8) et al. to stop logging
     hostnames in utmp altogether (how many people have hostnames less than 
     16 characters long these days?). Make other applications do the
     reverse lookups later, a la w(1) and netstat(1).
 
 Here's the patch:
 
 *** /usr/src/libexec/telnetd/sys_term.c	Wed Dec 24 14:23:18 1997
 --- sys_term.c	Mon Dec 28 23:05:37 1998
 ***************
 *** 52,58 ****
   # define PARENT_DOES_UTMP
   #endif
   
 - int     utmp_len = MAXHOSTNAMELEN;
   #ifdef	NEWINIT
   #include <initreq.h>
   #else	/* NEWINIT*/
 --- 52,57 ----
 ***************
 *** 99,104 ****
 --- 98,109 ----
   #  endif /* _SC_CRAY_SECURE_SYS */
   # endif	/* CRAY */
   #endif	/* NEWINIT */
 + 
 + #ifdef UT_HOSTSIZE
 + int     utmp_len = UT_HOSTSIZE; 
 + #else
 + int     utmp_len = MAXHOSTNAMELEN;
 + #endif /* UT_HOSTSIZE */
   
   #ifdef	STREAMSPTY
   #include <sac.h>
 
 

From: Peter Wemm <peter@netplex.com.au>
To: "Jasper O'Malley" <jooji@neptune.oceancomputer.com>
Cc: FreeBSD-gnats-submit@FreeBSD.ORG, freebsd-bugs@FreeBSD.ORG
Subject: Re: bin/9226: telnetd can log wrong IP address to utmp 
Date: Tue, 29 Dec 1998 14:02:05 +0800

 "Jasper O'Malley" wrote:
 [..]
 > This will prevent telnetd from passing hostnames longer than UT_HOSTSIZE
 > on as arguments to "login -h", which is what gets the hostname relooked
 > up by login(1) in the first place. It doesn't appear this change will
 > break anything else, but I can't swear to it.
 > 
 > Better solutions would be to:
 > 
 >  a) Make UT_HOSTSIZE bigger, which would break 4.4BSD utmp compatibility,
 >     which isn't why it hasn't been done yet.
 > 
 >  b) Rewrite/patch login(1), xterm(1), sshd(8) et al. to stop logging
 >     hostnames in utmp altogether (how many people have hostnames less than 
 >     16 characters long these days?). Make other applications do the
 >     reverse lookups later, a la w(1) and netstat(1).
 
 Without having looked at the code, I suspect telnetd suffers the same
 problem as rlogind/rshd used to (until I fixed them a week or so ago).
 Even with your patch, telnetd will log a forged hostname if it's shorter
 than 16 chars.
 
 What would be better would be to reverse lookup the name and check for 
 validity before passing it on or using it in any logs anywhere.  Yes, this 
 is a pest if a machine has just exploded it's named, but I'd rather have 
 hostnames/ip addresses in the logs that I can trust.
 
 Re: utmp/wtmp format..  We've already changed the username length from 8 
 to 16 chars, which is different to 2.x.  We could change the hostname to 
 32 and would then be compatable with BSD/OS's utmp format.
 
 However, while there, we should do a couple of other things... in
 particular, add a ut_pid field (which is damn useful!!) and possibly a
 couple of other things to ease porting problems (perhaps even a getutent()
 -like emulation).
 
 Cheers,
 -Peter
 
 
 

From: David Greenman <dg@root.com>
To: Peter Wemm <peter@netplex.com.au>
Cc: "Jasper O'Malley" <jooji@neptune.oceancomputer.com>,
        FreeBSD-gnats-submit@FreeBSD.ORG, freebsd-bugs@FreeBSD.ORG
Subject: Re: bin/9226: telnetd can log wrong IP address to utmp 
Date: Mon, 28 Dec 1998 22:46:58 -0800

 >"Jasper O'Malley" wrote:
 >[..]
 >> This will prevent telnetd from passing hostnames longer than UT_HOSTSIZE
 >> on as arguments to "login -h", which is what gets the hostname relooked
 >> up by login(1) in the first place. It doesn't appear this change will
 >> break anything else, but I can't swear to it.
 >> 
 >> Better solutions would be to:
 >> 
 >>  a) Make UT_HOSTSIZE bigger, which would break 4.4BSD utmp compatibility,
 >>     which isn't why it hasn't been done yet.
 >> 
 >>  b) Rewrite/patch login(1), xterm(1), sshd(8) et al. to stop logging
 >>     hostnames in utmp altogether (how many people have hostnames less than 
 >>     16 characters long these days?). Make other applications do the
 >>     reverse lookups later, a la w(1) and netstat(1).
 >
 >Without having looked at the code, I suspect telnetd suffers the same
 >problem as rlogind/rshd used to (until I fixed them a week or so ago).
 >Even with your patch, telnetd will log a forged hostname if it's shorter
 >than 16 chars.
 >
 >What would be better would be to reverse lookup the name and check for 
 >validity before passing it on or using it in any logs anywhere.  Yes, this 
 >is a pest if a machine has just exploded it's named, but I'd rather have 
 >hostnames/ip addresses in the logs that I can trust.
 >
 >Re: utmp/wtmp format..  We've already changed the username length from 8 
 >to 16 chars, which is different to 2.x.  We could change the hostname to 
 >32 and would then be compatable with BSD/OS's utmp format.
 >
 >However, while there, we should do a couple of other things... in
 >particular, add a ut_pid field (which is damn useful!!) and possibly a
 >couple of other things to ease porting problems (perhaps even a getutent()
 >-like emulation).
 
    I feel pretty strongly that both the IP address and hostname should be
 logged. It's easy for the bad guy to do some temporary munging of DNS, do
 the nasty stuff, and then undue the DNS stuff to make it difficult to
 impossible to know where the attacker came from. IP addresses nail this
 down much better.
 
 -DG
 
 David Greenman
 Co-founder/Principal Architect, The FreeBSD Project

From: Peter Wemm <peter@netplex.com.au>
To: "Jasper O'Malley" <jooji@webnology.com>
Cc: freebsd-gnats-submit@freebsd.org
Subject: Re: bin/9226: telnetd can log wrong IP address to utmp 
Date: Tue, 29 Dec 1998 14:58:54 +0800

 "Jasper O'Malley" wrote:
 > On Tue, 29 Dec 1998, Peter Wemm wrote:
 > 
 > > Without having looked at the code, I suspect telnetd suffers the same
 > > problem as rlogind/rshd used to (until I fixed them a week or so ago).
 > > Even with your patch, telnetd will log a forged hostname if it's shorter
 > > than 16 chars.
 > 
 > Absolutely true. I've got a patch to make telnetd feed IP addresses
 > exclusively to "login -h", but I imagine I'd have a harder time getting
 > that one committed.
 
 Yeah.. :-)
 
 > > Yes, this is a pest if a machine has just exploded it's named, but I'd
 > > rather have hostnames/ip addresses in the logs that I can trust.
 > 
 > I'm not a big fan of denying access for what might be transient DNS
 > failures...as long as the "validation" involved falling back to logging 
 > the IP address from the socket object, with the *option* of booting people
 > with mismatched hostname/address pairs, I'm game.
 
 Yes.  The "right" thing to do is check if the DNS names are consistant.  
 If so, then use them.  If not, then use the IP addresses.  That's what 
 rshd and rlogind now do.  Telnetd has got a 'bugger off' option if there 
 is no DNS name, but that's an option. :-)
 
 > > Re: utmp/wtmp format..  We've already changed the username length from 8 
 > > to 16 chars, which is different to 2.x.  We could change the hostname to 
 > > 32 and would then be compatable with BSD/OS's utmp format.
 > 
 > I once saw a suggestion on a NetBSD mailing list to make ut_host
 > variable-length (up to MAXHOSTNAMELEN) that I thought was pretty neat. And
 > the old Linux utaddr field isn't a bad idea, either.
 
 I like the ut_addr field, but how big do you make it?  4 bytes?  What
 about a 16 byte IPv6 address?  What I'm partial to is a description record 
 at the beginning of a utmp/wtmp file that specifies the field sizes.  As 
 long as it's padded to a record length it could probably be done without 
 too much impact.  The other option is a utmp.conf file or something.  Or 
 even utmp.db if we want to get really twisted. :-)
 
 > Cheers,
 > Mick
 > 
 > The Reverend Jasper P. O'Malley          dotdot:jooji@webnology.com
 >     Systems Administrator                  ringring:asktheadmiral
 > 	Webnology, LLC               woowoo:http://www.webnology.com/~jooji
 > 
 
 Cheers,
 -Peter
 --
 Peter Wemm <peter@netplex.com.au>   Netplex Consulting
 "No coffee, No workee!" :-)
 
 

From: "Jasper O'Malley" <jooji@neptune.oceancomputer.com>
To: FreeBSD-gnats-submit@FreeBSD.ORG
Cc:  Subject: Re: bin/9226: telnetd can log wrong IP address to utmp
Date: Thu, 31 Dec 1998 13:54:50 -0500 (EST)

 I've got a patch for src/libexec/telnetd/telnetd.c (in addition to my
 other patch already submitted for src/libexec/telnetd/sys_term.c) that
 does reverse-forward double-checking of source IP addresses before it
 passes the hostname argument to "login -h". If a forward lookup of the
 hostname generated by a reverse lookup of the IP address from the socket
 object doesn't result in that same IP address, the original IP address is
 what gets logged to utmp, not the bogus hostname, and not a bogus IP
 address. As usual, any connection from a host with an IP address that
 reverse resolves to a hostname longer than 16 characters is logged to utmp
 with the IP address.
 
 The first patch (necessary to completely close the hole) should be
 earlier in the audit trail for this PR.
 
 Here's the second:
 
 *** /usr/src/libexec/telnetd/telnetd.c	Sun May  3 12:33:32 1998
 --- telnetd.c	Thu Dec 31 13:45:26 1998
 ***************
 *** 771,776 ****
 --- 771,778 ----
   {
   	char *host = NULL;
   	struct hostent *hp;
 + 	char **p = NULL;
 + 	char temp_host_name[MAXHOSTNAMELEN];
   	int ptynum;
   
   	/*
 ***************
 *** 821,827 ****
            Please contact your net administrator");
   	} else if (hp &&
   	    (strlen(hp->h_name) <= ((utmp_len < 0) ? -utmp_len : utmp_len))) {
 ! 		host = hp->h_name;
   	} else {
   		host = inet_ntoa(who->sin_addr);
   	}
 --- 823,852 ----
            Please contact your net administrator");
   	} else if (hp &&
   	    (strlen(hp->h_name) <= ((utmp_len < 0) ? -utmp_len : utmp_len))) {
 ! 
 ! 		/* Here we check the validity of the hostname resolved with *
 ! 		 * the gethostbyaddr() above. If a gethostbyname() resolves *
 ! 		 * to the same IP address we used to do the gethostbyaddr() *
 ! 		 * the hostname is valid. If not, pass the original address *
 ! 		 * on to be logged into utmp */
 ! 
 ! 		strncpy(temp_host_name, hp->h_name, sizeof(temp_host_name)-1);
 ! 		temp_host_name[sizeof(temp_host_name)-1] = 0;
 ! 		hp = gethostbyname(temp_host_name);
 ! 		host = inet_ntoa(who->sin_addr); /* default to log IP */
 ! 		if (hp != NULL) {
 ! 			p = hp->h_addr_list;
 ! 			while(1) {
 ! 				if (*p == 0)  /* no addresses match */
 ! 					break;
 ! 				if (!bcmp(*p, &who->sin_addr, 
 ! 					(size_t)hp->h_length)) { /* match */ 
 ! 					host = temp_host_name;
 ! 					break;
 ! 				}
 ! 				++p;
 ! 			}
 ! 		}
   	} else {
   		host = inet_ntoa(who->sin_addr);
   	}
 
 [end patch]
 
 Cheers,
 Mick
 
 

From: "Jasper O'Malley" <jooji@webnology.com>
To: "Matus \"fantomas\" Uhlar" <uhlar@fantomas.sk>
Cc: freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: bin/9226: telnetd can log wrong IP address to utmp
Date: Mon, 4 Jan 1999 08:24:07 -0600 (CST)

 On Mon, 4 Jan 1999, Matus "fantomas" Uhlar wrote:
 
 > tcp_wrappers  do this and I think it's enough;
 
 So logging a bad hostname--or worse, a bad IP address--is acceptable if
 you don't use TCP Wrappers? The real solution is, as David suggested, to
 log both IP addresses and hostnames to utmp. Barring that, I'd like to
 patch login to add the -a switch, where IP addresses are passed to login
 rather than hostnames, and any lookups are done with login itself
 (deprecating the -h switch). There needs to be a standard way to pass
 stuff to utmp, and only certain applications should have to bother with
 address lookups.
 
 Cheers,
 Mick
 
 
 

From: "Jasper O'Malley" <jooji@neptune.oceancomputer.com>
To: FreeBSD-gnats-submit@FreeBSD.ORG
Cc:  
Subject: Re: bin/9226: telnetd can log wrong IP address to utmp 
Date: Wed, 13 Jan 1999 19:50:35 -0500 (EST)

 I've tested and submitted patches to resolve this PR. Any chance of
 getting it closed?
 
 Cheers,
 Mick
 
 

From: Michael Grant <mgrant@grant.org>
To: freebsd-gnats-submit@FreeBSD.org, jooji@neptune.oceancomputer.com
Cc:  
Subject: Re: bin/9226: telnetd can log wrong IP address to utmp
Date: Wed, 24 May 2000 19:07:45 +0200

 I'm running 3.4-stable.
 
 the -u option to telnetd doesn't seem to work, I still get hostnames in
 utmp even when -u0 is used.
 
 I noticed that it passes the whole hostname to login with the -h
 option.  Why not add an option to login.conf to convert or leave the
 hostname as an IP address, this way, it works for all things in general
 rather than having to change rsh, telnet, and ssh?
 
 Perhaps a reason not to do this is that some dns trickery with the
 reverse dns could spoof the user's real ip address.
 
 -Mike
 
 
State-Changed-From-To: open->feedback 
State-Changed-By: brian 
State-Changed-When: Wed May 24 15:21:08 PDT 2000 
State-Changed-Why:  
I believe this can be closed after the stuff I did last year (or before?) 
with realhostname() and trimdomain().  If there are any known problems 
in 3-stable, 4-stable or 5, please let me know asap. 


Responsible-Changed-From-To: freebsd-bugs->brian 
Responsible-Changed-By: brian 
Responsible-Changed-When: Wed May 24 15:21:08 PDT 2000 
Responsible-Changed-Why:  
I fixed this stuff in April last year 
State-Changed-From-To: feedback->closed 
State-Changed-By: brian 
State-Changed-When: Wed May 24 15:32:21 PDT 2000 
State-Changed-Why:  
Mail to the originator bounces 
>Unformatted:
