#!/usr/bin/perl
#####################################################
#  gdipc.pl         Part of GnuDIP 2.1.1            #
#                                                   #
#    The GnuDIP command line client                 #
#                                                   #
#    See COPYING for licensing information          #
#                                                   #
#       Mike Machado <mike@innercite.com>           #
#                                                   #
#    Small modifications by:                        #
#       Jason Spangler <jasons@usemail.com>         #
#                                                   #
#####################################################

  use Socket;
  use strict;
  use MD5;

  #### Set up varialbes
  my $VER = "2.1.1";
  my $CONFIGFILE = "$ENV{'HOME'}/.GnuDIP2";
  my $server_port = "3495";

	# JMS Hack: if first argument is -f, use second argument as config file name
  if ( ($ARGV[0] eq '-f') && ($#ARGV >= 1) ) {
		$CONFIGFILE = "$ARGV[1]";
		shift;
		shift;
  }

  #### Open users config file
  my $haveconfig = open(CONFIG,"$CONFIGFILE") || "NO";
  if ($ARGV[0] eq '-h') {
     print " gdipc.pl [-f configfile] [-c, -i, -r, -v]\n";
     print "   gdipc.pl: Send your information to the server once your prefs have been set\n";
     print "   gdipc.pl -c: Change or create your preferences\n";
     print "   gdipc.pl -i: Interactive mode (reads from stdin rather than \$HOME/.GnuDIP2)\n";
     print "   gdipc.pl -r: Send a offline request to the server to not have your hostname point to anything until next login\n";
     print "   gdipc.pl -v: Show version information\n";
   } elsif ($ARGV[0] eq '-c') {
     print "   Changing preferences:\n";

     print "     New Username: ";
     my $newusername = <STDIN>;
     chop($newusername);
    
     my $salt = substr($newusername, 0, 2);
     system("stty -echo");

     my $notsamepass = 1;

     my $newpass;
     while($notsamepass) {
       print "     New Password: ";
       $newpass = <STDIN>;
       chop($newpass);

       print "\n     New Password Again: ";
       my $newpass1 = <STDIN>;
       chop($newpass1);

       if(!checksame($newpass, $newpass1)) {
          print "\n\n  Please enter the same password twice!\n";
       } else {
          $notsamepass = 0;
       }

     }

     
     system("stty echo");

     print "\n     Domain: ";
     my $newdomain = <STDIN>;
     chop($newdomain);

     print "     New GnuDIP Server: ";
     my $newserverip = <STDIN>;
     chop($newserverip);

     my $md5 = new MD5;
     $md5->add($newpass);
     my $digest = $md5->digest();
     my $digestpass = unpack("H*", $digest);
     $md5->reset();

     open(CONFIG, ">$CONFIGFILE") || die "Cound not create prefs file $!\n";
     print CONFIG "$newusername:$digestpass:$newdomain:$newserverip";
     close(CONFIG);
     chmod 0600, $CONFIGFILE;

   } elsif ($ARGV[0] eq '-v') {
     print "   gdipc.pl: Version $VER\n";
     print "   See http://gnudip.cheapnet.net for more information\n";
     print "   or email me:\n";
     print "   Mike Machado <mike\@innercite.com>\n";
   } elsif ($ARGV[0] eq '-i') {
     print "   Interactive Mode:\n";

     print "     Username: ";
     my $username = <STDIN>;
     chop($username);
    
     system("stty -echo");
     print "     Password: ";
     my $pass = <STDIN>;
     chop($pass);

     system("stty echo");
     print "\n     Domain: ";
     my $domain = <STDIN>;
     chop($domain);

     print "     GnuDIP Server: ";
     my $serverip = <STDIN>;
     chop($serverip);

     my $md5 = new MD5;
     $md5->add($pass);
     my $digest = $md5->digest();
     my $digestpass = unpack("H*", $digest);
     $md5->reset();

     sendlogin($username, $digestpass, $domain, $serverip, "0");


   } elsif ($ARGV[0] eq '-r') {
     if ($haveconfig eq 'NO') {
        print "   gdipc.pl: You must first set up your prefenrences with gdipc.pl -c\n";
        exit;
      } else {
				# JMS Hack: read all lines from config file in case of multiple hosts
				while (<CONFIG>)
					{
					chomp;
	        my ($username, $pass, $domain, $serverip) = split(/:/);
        	sendlogin($username, $pass, $domain, $serverip, "1");
					}
        close(CONFIG);
      }

   } else {
     if ($haveconfig eq 'NO') {
        print "   gdipc.pl: You must first set up your prefenrences with gdipc.pl -c\n";
        exit;
      } else {
	# JMS Hack: read all lines from config file in case of multiple hosts
	while (<CONFIG>) {
		chomp;
	        my ($username, $pass, $domain, $serverip) = split(/:/);
        	sendlogin($username, $pass, $domain, $serverip, "0");
       		close(CONFIG);
	}
     }
   }


#### Sub to connect to server and send the data
sub sendlogin {
 my $username = shift;
 my $pass = shift;
 my $domain = shift;
 my $serverip = shift;
 my $serveraction = shift;
 my $response;

 # JMS Hack: message for debugging
 #print "Trying $username $pass $domain $serverip $serveraction\n";

 socket(SERVER, PF_INET, SOCK_STREAM, getprotobyname('tcp'));
 my $inet_addr = gethostbyname($serverip);
 my $paddr = sockaddr_in($server_port, $inet_addr);
 connect(SERVER, $paddr) || die "Could not connect to $serverip:$server_port\n";

 #### Change to non-buffer writes for our socket
 select(SERVER);
 $| = 1;
 select(STDOUT);

 chomp(my $sharedsecret = <SERVER>);

 my $md5 = new MD5;
 $md5->add($pass.'.'.$sharedsecret);
 my $digest = $md5->digest();
 my $digeststr = unpack("H*", $digest);

 print SERVER "$username:$digeststr:$domain:$serveraction\n";

 chomp($response = <SERVER>);
 if ($response eq "0") {
    print " Successfully updated to new IP address for ${username}\n";
 } elsif ($response eq "1") {
    print " Invalid login attempt for ${username}\n";
 } elsif ($response eq "2") {
    print " Offline request successful for ${username}\(login again to repoint your hostname\)\n";
 } else {
    print " Server did not respond to login attempt for ${username}\n";
 }

 close(SERVER);

}


#### Check to see if the two passed in args are the same
sub checksame {
  my $arg1 = shift;
  my $arg2 = shift;

  return 1 if $arg1 eq $arg2;
  return 0;
}
