Subject: misc/543: -a option of rlogind is bogus
To: None <gnats-admin@sun-lamp.cs.berkeley.edu>
From: None <ziff@eecs.umich.edu>
List: netbsd-bugs
Date: 10/31/1994 16:05:08
>Number:         543
>Category:       misc
>Synopsis:       The domain name spoofing option of rlogind is missing
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    gnats-admin (Misc Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Oct 31 16:05:05 1994
>Originator:     Brian Moore
>Organization:
"University of Michigan - DCO"
>Release:        1.0
>Environment:
	Gateway 2000 4DX/66V, NetBSD 1.0, i386
System: NetBSD houdini.eecs.umich.edu 1.0 NetBSD 1.0 (HOUDINI) #0: Wed Oct 26 17:43:44 EDT 1994 root@houdini.eecs.umich.edu:/usr/src/sys/arch/i386/compile/HOUDINI i386


>Description:
	While looking into the rlogin for root problem, I noticed that the
	code for the option for domain name spoofing, -a, is only half there.
	The code for setting up the flag, check_all, for the option is there, 
	and the support functions local_domain and top_domain are there, but
	there isn't any code to do the actual spoof check.
>How-To-Repeat:
	Set up a machine with a IP address and domain name so that 
	gethostbyaddr() != gethostbyaddr().  If the domain name is in
	your local domain, then try to rlogin.  You won't see any kind of
	error message.  If the domain name is outside of your local domain
	then edit /etc/inetd.conf to add a -a to the rlogind command.
>Fix:
	I whipped up this fix from looking at rshd.c, and stealing code
	from it, since it does the same exact routine.  This fix is most
	likely bogus, but I did test it and it did complain and bump me out.
	This patch really needs to be cleaned up, so that it does the nice
	and clean logging that rshd does, but for right now it should
	work.

diff -c rlogind.c.orig rlogind.c
*** rlogind.c.orig      Mon Oct 31 15:51:24 1994
--- rlogind.c   Mon Oct 31 18:12:01 1994
***************
*** 165,172 ****
        int master, pid, on = 1;
        int authenticated = 0;
        register struct hostent *hp;
!       char hostname[2 * MAXHOSTNAMELEN + 1];
!       char c;
  
        alarm(60);
        read(f, &c, 1);
--- 165,172 ----
        int master, pid, on = 1;
        int authenticated = 0;
        register struct hostent *hp;
!       char remotehost[2 * MAXHOSTNAMELEN + 1];
!       char c, *hostname;
  
        alarm(60);
        read(f, &c, 1);
***************
*** 178,187 ****
        fromp->sin_port = ntohs((u_short)fromp->sin_port);
        hp = gethostbyaddr((char *)&fromp->sin_addr, sizeof(struct in_addr),
            fromp->sin_family);
!       if (hp)
!               (void)strcpy(hostname, hp->h_name);
!       else
!               (void)strcpy(hostname, inet_ntoa(fromp->sin_addr));
  
        {
                if (fromp->sin_family != AF_INET ||
--- 178,219 ----
        fromp->sin_port = ntohs((u_short)fromp->sin_port);
        hp = gethostbyaddr((char *)&fromp->sin_addr, sizeof(struct in_addr),
            fromp->sin_family);
!       if (hp) {
!                 /*
!                  * If name returned by gethostbyaddr is in our domain,
!                  * attempt to verify that we haven't been fooled by someone
!                  * in a remote net; look up the name and check that this
!                  * address corresponds to the name.
!                  */
!                 hostname = hp->h_name;
!                 if (check_all || local_domain(hp->h_name)) {
!                         strncpy(remotehost, hp->h_name, sizeof(remotehost) - 1
);
!                         remotehost[sizeof(remotehost) - 1] = 0;
!                         hp = gethostbyname(remotehost);
!                         if (hp == NULL) {
!                                 syslog(LOG_INFO,
!                                     "Couldn't look up address for %s",
!                                     remotehost);
!                               exit(1);
!                       } else for (; ; hp->h_addr_list++) {
!                                 if (hp->h_addr_list[0] == NULL) {
!                                         syslog(LOG_NOTICE,
!                                           "Host addr %s not listed for host %s
",
!                                             inet_ntoa(fromp->sin_addr),
!                                             hp->h_name);
!                                       exit(1);
!                               }
!                                 if (!bcmp(hp->h_addr_list[0],
!                                     (caddr_t)&fromp->sin_addr,
!                                     sizeof(fromp->sin_addr))) {
!                                         hostname = hp->h_name;
!                                         break;
!                               }
!                      }
!               }
!               (void)strcpy( remotehost, hostname);
!       } else
!                 (void)strcpy(remotehost, inet_ntoa(fromp->sin_addr));
  
        {
                if (fromp->sin_family != AF_INET ||
***************
*** 242,251 ****
                if (authenticated) {
  
                        execl(_PATH_LOGIN, "login", "-p",
!                           "-h", hostname, "-f", lusername, (char *)NULL);
                } else
                        execl(_PATH_LOGIN, "login", "-p",
!                           "-h", hostname, lusername, (char *)NULL);
                fatal(STDERR_FILENO, _PATH_LOGIN, 1);
                /*NOTREACHED*/
        }
--- 274,283 ----
                if (authenticated) {
  
                        execl(_PATH_LOGIN, "login", "-p",
!                           "-h", remotehost, "-f", lusername, (char *)NULL);
                } else
                        execl(_PATH_LOGIN, "login", "-p",
!                           "-h", remotehost, lusername, (char *)NULL);
                fatal(STDERR_FILENO, _PATH_LOGIN, 1);
                /*NOTREACHED*/
        }

>Audit-Trail:
>Unformatted: