DaemonForums  

Go Back   DaemonForums > Miscellaneous > Programming

Programming C, bash, Python, Perl, PHP, Java, you name it.

 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
  #1   (View Single Post)  
Old 7th June 2013
unixjingleman unixjingleman is offline
Fdisk Soldier
 
Join Date: Jan 2011
Posts: 70
Thanked 0 Times in 0 Posts
Default need help with my own rlogind.c

Hi
I have a few quesitons regarding a version of rlogind.c that i'm hacking on. I'm not crazy enough to think that anyone will use it or distribute it, i'm just doing it as a programming exercise. I use a variation of rlogin.c, for the client, from the one in the original w.rich stevens network prog book.
The server program has a function to multiplex between the network and master-side of the pseudo terminal.This is after a function has been called which opens the master and slave of the pseudo terminal and exec()s /bin/login like so:
Code:
if(excel("/bin/login", "login", "-p", "-h", hp->h_name, "-f", user_name, (char *)0)== -1)
   perror("/bin/login error");
Before the exec() of /bin/login the slave side is opened after a fork() and a setsid() to put what ever is exec()'d after this fork() in it's own session. Then the slave-side becomes the CTTY of anything executed in this child. Also dup2 is then called to set the stdin, stout, stderr to the slave's file descriptor(returned from open()ing the slave-side, as explained above). Thus, i thought, /bin/login would have it's stdin, stout and std err connected to the slave-side of the pseudo term(?). Is this wrong? What would stop this being the case? What would stop the output from /bin/login from ending up at the master-side of the tty and thus be output on the socket(to be sent to the client)? Or is it most likely to be the multiplexing of socket/master-side I/O that is wrong? Here is the code that does this multiplexing(of socket and master-side I/O....a tiny bit of it is from the BSD version of rlogind.c):
Code:
  
    rcvstate = READING;

    if(child_pid == 0){
      for(;;){
        if(rcvstate == READING)
       	       if((pcc = read(fdm, pibuf, sizeof(pibuf))) < 0)
                   continue;
               
          if(pcc > 1){
               rcvstate = WRITING;
	       pbp = pibuf;
          }
        
        if(pcc == 0)
              break;
       	else if (pcc == 1 && pkcontrol(pibuf[0])) {
		pibuf[0] |= oobdata[0];
		(void)send(connfd, &pibuf[0], 1, MSG_OOB);
		if (pibuf[0] & TIOCPKT_FLUSHWRITE)
			pcc = 0;
		}
        else if (pcc > 1 && pibuf[0] == 0 
                 && rcvstate == WRITING){
               pbp++;

                while((rem = pcc - (pbp - pibuf)) > 0){
                if((n = write(connfd, pbp, rem)) < 0){
                    sleep(1);
	            continue;
                }
                if(n == 0)
                    break;
		pbp += n;
        }
        if(rem == 0)
           rcvstate = READING;
        if(n ==0)
           break; 
       
                   
       } else {
               if (pkcontrol(pibuf[0])) {
		pibuf[0] |= oobdata[0];
		(void)send(connfd, &pibuf[0], 1 , MSG_OOB);
         }
         pcc = 0;
     }
     
  } /* End of for.... */
 if(ignoreeof == 0)
    kill(getppid(), SIGTERM);
 exit(0);
}/* End of child */

/* Parent........*/
   
   if(signal(SIGTERM, sig_term) == SIG_ERR)
	perror("signal handler for protocol parent!");
   rcvstate = READING;
        for(;;){

          if(rcvstate == READING){
             if((fcc = read(connfd, fibuf, sizeof(fibuf))) < 0)
                  continue;
          if(fcc == 0)
             break;
          if(fcc > 0){
            cc = fcc;
            rcvstate = WRITING;
          }
       }
          if(fcc > 0 && rcvstate == WRITING){
            fbp = fibuf;
          if(fibuf[0] == magic[0] &&
                  fibuf[1] == magic[1]) {
        top:
            for(cp = fibuf; cp < fibuf+fcc-1; cp++)
               if(cp[0] == magic[0] &&
                  cp[1] == magic[1]) {
                    remaining = fcc - (cp-fibuf);
                    n = control(fdm, cp, remaining);
                    if(n){
                         remaining -= n;
			 if(remaining > 0)
				bcopy(cp+n, cp, remaining);
                         fcc -= n;
                         goto top; /* Ugly eh? ;process another `in-band' magic cookie!...*/
		    }
              }
             rcvstate = READING;
           }
           else{
             while(( rem = cc - (fbp - fibuf)) > 0){
		if((n = write(fdm, fbp, rem)) < 0)
                   continue;
	        if(n == 0)
		   break;
                fbp += n;
       
           }
         if(n == 0)
		break;
         if(rem == 0)
                rcvstate = READING;
         }
        }
    }
    if(sigcaught == 0)
      kill(child_pid, SIGTERM);

    /* Return to caller....*/         
  
}

}
I've looked at /etc/login.access i even removed the user i was trying to log in as from wheel! I was hoping that with the pseudo term and network set up(the network functions are executing without (p)errors) that /bin/login would just execute the login shell in the same environment( as you can see i used the "-p" flag to /bin/login! Then when /bin/login exec()'d /usr/local/bin/bash that the code above would pass the output from bash to the slave-side, which would appear at the master-side(since the slave is in raw-mode). As the slave was put in raw-mode anything output to it would appear as output for the socket and visa-versa(Although the master-side in the server isn't set to raw). Is that the right way to do it? When i run the server on FreeBSD no errors are output. When the client is run on os x there is a read error on the client function called reader()(from the rlogin client in rich stevens' net prog book).
So do i have to edit /etc/ttys and put "secure" for evert ttyXY? I ran tcpdump and the only packets exchanged were the client sending the user name and the server successfully reading this and sending back an "o.k". What are the "gotchas" for /bin/login and pseudo terms talking to the network? Why might the login fail? I've tried exec()ing /bin/login with and without the "-f" flag. When i did use the "-f" flag i tried logging in as the user who was already logged in and with a user who was not already logged in! I don't know why i can't get this to work(?)
I can post the whole code of the server and/or the client if necessary. But that is kinda crazy(as is wanting to code such an application as rlogind!)
Any help/suggestions would be gratefully received
Thank you very much in advance.

Last edited by unixjingleman; 29th December 2013 at 05:24 PM. Reason: Have changed the code
Reply With Quote
 

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT. The time now is 12:04 PM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content copyright © 2007-2010, the authors
Daemon image copyright ©1988, Marshall Kirk McKusick