#!/usr/bin/perl -w
#############################
#Written 1st of Jan'2004
#The nfrm server
#############################

use IO::Socket;
use Net::Ident;
use Net::hostent;

#trap all the signals -use to close log file
$SIG{'INT'} = 'CLEANUP';
$SIG{'HUP'} = 'CLEANUP';
$SIG{'QUIT'} = 'CLEANUP';
$SIG{'PIPE'} = 'CLEANUP';
$SIG{'ALRM'} = 'CLEANUP';

sub getid()
{
	my ($sock)=@_;
	my $name=$sock->Net::Ident::ident_lookup(10);
	return $name;
}

sub CLEANUP {
    print "\n\nAborted\n";
    my $date=`date`;
    print LOG "\n\nAborted at $date \n ";
    close LOG;
    exit 1;
}



#body of the server code starts here
#open the log file
open (LOG,">>/var/log/nfrm");

#this socket uses fork to get a child process for doing the job while
#it waits to accept the jobs
$parent_sock = new IO::Socket::INET(LocalHost =>'#INTERFACE_ADDRESS_TO_WHICH_CLIENTS_BIND#',
			     LocalPort => 5677, #SOME_PORT_TO_WHICH_THE_CLIENTS_BIND
			     Proto     =>'tcp',
			     Listen    => 15,
			     Reuse     => 1,
			     );

#report failure...
die "Couldn't setup server :$!" unless $parent_sock;

#Log messages
print LOG "[Server $0 accepting clients]\n";

#Handle incoming requests
#Should we switch to the fork version??

while(defined($new_sock=$parent_sock->accept()))
{$new_sock->autoflush(1);
 $hostinfo = gethostbyaddr($new_sock->peeraddr);
 printf LOG "[Connected from %s]\n",$hostinfo->name|| $new_sock->peerhost;
 print $new_sock "Command?\n";
OUTER: while (<$new_sock>)
   { 
     if (/^nfrm/i) {@list= split(/ +/);
	            print LOG "nfrm $list[1]";
		    chomp $list[1];
		    #authenticate the user on the other end
		    #of connection
		    $ruser=&getid( $new_sock);
		    #check if this is crypted or not
		    #crypted begins with a '['
		    if($ruser=~ /^\[/)
			{
			  $decrypt=`echo "$ruser" | /usr/sbin/idecrypt`;
			  @the_fields=split(/ +/,$decrypt);
			  @ypcat_lines=`ypcat passwd|grep $the_fields[5]`;
			  print @ypcat_lines;
			  $count=0;
			  do
			  {
				 @frags=split(/:/,$ypcat_lines[$count]);
				 print $frags[2],"\n";
				 chomp $frags[2];
				 chomp $the_fields[5];
				 if($frags[2] == $the_fields[5])
					{
						$ruser=$frags[0];
						$count=$#ypcat_lines;
					}
				 $count++;
			  }while ($count <$#ypcat_lines);
			  if($ruser=~ /^\[/)
				{ print LOG "Is this attack $ruser\n";
				  last;
				}
			}
			
		    print "remote user:",$ruser,"\n";
		    if("$ruser" ne "$list[1]")
			{
				print $new_sock "Permission denied\n";
				print LOG "$ruser attempted to nfrm on $list[1] 's account\n";
				#exit the loop and cleanup
				last;
			}
		    chomp(@list);
                    open (TMP,">/tmp/$list[1]");
                    print TMP `nfrm $list[1]`;
 		    close ( TMP );
		    open (TMP,"/tmp/$list[1]");
                    my $i =0;
         INNER:     while($line=<TMP>)
                    { 
			print $new_sock $line."\n";
 		    }
			last;
		    }
    else { last;}
   }
 printf LOG "[Closing connection from %s]\n",$hostinfo->name||$new_sock->peerhost;
 close ($new_sock);
}
