SUMMARY: remote login [2]

From: Wes Boudville (wes@cco.caltech.edu)
Date: Fri Apr 09 1993 - 21:40:10 CDT


This is an amendment to the summary I posted yesterday about
remote logins.

My original question was:

> Suppose I rlogin to a Sun4. I want to find either the hostname or
> the IP address of the computer that I'm logging in from. Any ideas?
> More specifically, how can I get the number of the socket that is
> assigned to my remote login by the server Sun? If I know this, then I
> can call getpeername to find the client address.
> Unfortunately, parsing the output of 'who', which looks at /etc/utmp,
> is not reliable. If I rlogin to the sun from a machine with a long name,
> then the name will be truncated in /etc/utmp.
> Please note that anything I try must be as a regular user. I do not
> have root privileges.
> This is frustrating. Clearly, if I successfully rlogin, then the
> system knows where I'm coming from. But how do I get at this information?
> [I suspect that to anyone who knows sockets well, this is trivial.]

The summary I posted yesterday described a shell script that turns out
to have limitations.

Also, several blokes had suggested that before I rlogin, I could
redefine my TERM to include the full hostname. This is passed by rlogind
into my remote environment. And there, I could parse TERM and unambiguously
extract where I'm coming from. This would certainly work.

The only problem with it is in the reason for my original posting,
which I didn't describe. I am writing an X program, "trade", which many
people will access. Currently, a user would rlogin from [say]
doofus.campus.edu and type

        $ trade -display doofus.campus.edu:0.0

It would be nice if they didn't have to type all that. The trouble with
amending their console environments is that they can login from
any computer & any account. And most aren't computer experienced.
Which is why I'm trying to simplify what they need to type.

Listed below is a subroutine that I wrote. This seems to be fairly
robust. It assumes that before you call it, you have already checked
that you are not logged in locally. It gets around the 16 character
hostname truncation in `who` output.

I have used this within "trade". I have been
able to rlogin to a computer where trade exists. Then typing

        $ trade

automatically displays X windows on my remote console. This has
been tested with the trade computer being a sun4/sunOS4.1.2,
hp9720/hpux8.05 and rs6000/aix3.2. And with me remotely logging in
from similar machines, and from Mac running MacX and PC clone
running DesqviewX.

Try the subroutine below, if you are interested.
Send me mail if you have any problems.

/****************************************************************/
/*
/
/ *******************
/ * *
/ * setdisplay.c *
/ * *
/ *******************
/
/
/ Author: Wes Boudville
/ wes@markets.caltech.edu
/
/ Copyright: Wes Boudville
/
/ Date: 1.4.93
/
/ */
#include <sys/types.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>

#define TRUE 1
#define FALSE 0
#define STRLEN 256

/**************************************************************/
/* this tries to find the IP address from which the user is
/ logged into the local computer.
/
/ output: FALSE if failed
/ TRUE if succeeded
/ display= [eg] '131.215.10.33'
/ or 'het.campus.edu'
/
/ Note: To use its output [if successful] to give an X address,
/ you must append [eg] ":0.0" to display.
/ */
        int setdisplay(display)

        char *display;
        {
        int ipfl,dot,i,fl,j,k,fndfl;
        FILE *fp;
        char s[STRLEN],name[STRLEN],remote[STRLEN];
        char remoteip[24];
        char tty[16];
        unsigned long t;
        struct hostent *h;

/*--------------------------------------------------*/
/* unused - see comment below about netstat */
/* get name of this machine
        if((i=gethostname(name,sizeof(name))==-1))
          return(FALSE);
/* get IP address of this machine
        if((h=gethostbyname(name))==0)
          return(FALSE);
*/
/*--------------------------------------------------*/

/* name is a scratch file */
        strcpy(name,"/tmp/nametmp");

/*--------------------------------------------------*/
/* get tty */
        sprintf(s,"echo `tty` > %s",name);
        system(s);
        fp=fopen(name,"r");
        fscanf(fp,"%s",tty);
        fclose(fp);

/* strip off any leading '/dev/' */
        if(strncmp(tty,"/dev/",5)==0)
          {
          i=strlen(tty);
          for(j=0;j<i-5;j++)
            tty[j]=tty[j+5];
          tty[j]='\0';
          }
/*--------------------------------------------------*/

/*--------------------------------------------------*/
/* get name of machine from which user is logged in
/ to this computer */

/* if this is an HP computer => 'who' needs '-R' to get
/ names of remote hosts */
/* look for /hp-ux */
        if((i=open("/hp-ux",O_RDONLY))==-1)
          fl=FALSE;
        else
          {
          fl=TRUE;
          close(i);
          }

        sprintf(s,"who");
        if(fl) strcat(s," -R ");
        strcat(s,"| grep ");
        strcat(s,tty);
        strcat(s," > ");
        strcat(s,name);
        system(s);
        fp=fopen(name,"r");
        fgets(s,STRLEN,fp);
        fclose(fp);

/* strip off any trailing '\n' */
        i=strlen(s);
        if(s[i-1]=='\n')
          {
          i--;
          s[i]='\0';
          }

/* search for '(' => start of hostname */
        j=0;
        fl=TRUE;
        while(fl)
          {
          if(s[j]=='(') fl=FALSE;
          else
            {
            j++;
            if(j>=i) fl=FALSE;
            }
          }

/* found '(' */
        if(s[j]=='(')
          {
          for(k=0;k<i-j-1;k++)
            remote[k]=s[k+j+1];
/* strip off any trailing ')' */
          if(remote[k-1]==')') k--;
          remote[k]='\0';

/* hostname in IP form? */
          ipfl=TRUE;
          for(i=0;i<k;i++)
            if(isalpha(remote[i]))
              ipfl=FALSE;
          }

/* didn't find '(' in 'who' output */
        else
          return(FALSE);
/*--------------------------------------------------*/

/*--------------------------------------------------*/
/* get netstat output for all remote connections
/ into a file */

/* It would be better to do 'netstat -n|grep localip'
/ where localip is IP address of local machine.
/ But if local machine has multiple IP addresses, then
/ the address found in h above may not match with the
/ local address from netstat. */

/* extract each component of local IP address */
/*
        bcopy(h->h_addr_list[0],(char *)&t,4);
        sprintf(localip,"%d.",(t>>24)&255);
        sprintf(s,"%d.",(t>>16)&255);
        strcat(localip,s);
        sprintf(s,"%d.",(t>>8)&255);
        strcat(localip,s);
        sprintf(s,"%d",t&255);
        strcat(localip,s);
        strcpy(s,"netstat -n | grep '");
        strcat(s,localip);
*/
        strcpy(s,"netstat -n | grep tcp");

/* put output in temp file */
        strcat(s," > ");
        strcat(s,name);

/* run netstat into file 'name' */
        system(s);
/*--------------------------------------------------*/

/*--------------------------------------------------*/
/*--------------------------------------------------*/
        fp=fopen(name,"r");
        fndfl=FALSE;
        fl=TRUE;
        while(fl)
          {
/* end of file? */
          if(fgets(s,STRLEN,fp)==NULL)
            {
            fl=FALSE;
            continue;
            }

/* extract remote IP & port number */
          sscanf(s,"%*s %*s %*s %*s %s",remoteip);

/* strip off port number */
          i=strlen(remoteip);
          k=0;
          dot=0;
          j=TRUE;
          while(j)
            {
            if(remoteip[k]=='.') dot++;
            if(dot>3) j=FALSE;
            else
              {
              k++;
              if(k>i) j=FALSE;
              }
            } /* j */
          remoteip[k]='\0'; /* put end of string */

/* compare the remote IP from netstat with 'who' output */
          if(ipfl) /* 'who' made IP output */
            {
            if(strcmp(remoteip,remote)==0)
              {
              strcpy(display,remote);
              fndfl=TRUE;
              fl=FALSE;
              }
            }

/* the 'who' output is a hostname or a partial hostname */
          else
            {
/* convert remoteip string to binary */
            t=inet_addr(remoteip);
/* convert it to a hostname */
            if((h=gethostbyaddr((char *)&t,4,AF_INET)))
              {
              k=strlen(h->h_name);
              i=strlen(remote);
              if(i>k) i=k;
              if(strncmp(remote,h->h_name,i)==0)
                {
                strcpy(display,h->h_name);
                fndfl=TRUE;
                fl=FALSE;
                }
              }
            } /* !ipfl */

          } /* fl */
/*--------------------------------------------------*/
/*--------------------------------------------------*/

/* delete temp file */
        fclose(fp);
        sprintf(s,"rm -fr %s\n",name);
        system(s);

/* no match? */
        if(!fndfl)
          return(FALSE);

        return(TRUE);
        }
/**************************************************************/



This archive was generated by hypermail 2.1.2 : Fri Sep 28 2001 - 23:07:42 CDT