[LON-CAPA-cvs] cvs: newloncapa /types LondConnection.pm

foxr lon-capa-cvs@mail.lon-capa.org
Sun, 23 Mar 2003 00:05:27 -0000


foxr		Sat Mar 22 19:05:27 2003 EDT

  Modified files:              
    /newloncapa/types	LondConnection.pm 
  Log:
  Add key negotation and debug that part of the connection process.
  
  
Index: newloncapa/types/LondConnection.pm
diff -u newloncapa/types/LondConnection.pm:1.2 newloncapa/types/LondConnection.pm:1.3
--- newloncapa/types/LondConnection.pm:1.2	Wed Feb 26 22:02:27 2003
+++ newloncapa/types/LondConnection.pm	Sat Mar 22 19:05:27 2003
@@ -9,6 +9,16 @@
 use Fcntl;
 use POSIX;
 use Crypt::IDEA;
+
+$DebugLevel=10;
+
+sub Debug {
+    my $level   = shift;
+    my $message = shift;
+    if ($level < $DebugLevel) {
+	print($message."\n");
+    }
+}
 =pod 
    Dump the internal state of the object: For debugging purposes.
 =cut
@@ -31,6 +41,7 @@
     my $newstate = shift;
     my $oldstate = $self->{State};
     $self->{State} = $newstate;
+    $self->{TimeoutRemaining} = $self->{TimeoutValue};
     if($self->{TransitionCallback}) {
 	($self->{TransitionCallback})->($self, $oldstate); 
     }
@@ -46,6 +57,7 @@
     my $class    = shift;	# class name.
     my $Hostname = shift;	# Name of host to connect to.
     my $Port     = shift;	# Port to connect 
+    &Debug(4,$class."::new( ".$Hostname.",".$Port.")\n");
     my $self     = { Host               => $Hostname,
 	             Port               => $Port,
 	             State              => "Initialized",
@@ -57,7 +69,9 @@
 		     TransitionCallback => undef,
 	             Timeoutable        => 0,
 	             TimeoutValue       => 60,
-	             TimeoutRemaining   => 0};
+	             TimeoutRemaining   => 0,
+		     CipherKey          => "",
+		     Cipher             => undef};
     bless($self, $class);
     unless ($self->{Socket} = IO::Socket::INET->new(PeerHost => $self->{Host},
 					       PeerPort => $self->{Port},
@@ -109,6 +123,7 @@
     my $data    = '';
     my $rv      = $socket->recv($data, POSIX::BUFSIZ,  0);
     my $errno   = $! + 0;	             # Force numeric context.
+
     unless (defined($rv) && length($data)) { # Read failed,
 	if(($errno == POSIX::EWOULDBLOCK)   ||
 	   ($errno == POSIX::EAGAIN)        ||
@@ -118,7 +133,7 @@
 	}
 
 	# Connection likely lost.
-
+	&Debug(4, "Connection lost");
 	$self->{TransactionRequest} = '';
 	$socket->close();
 	$self->Transition("Disconnected");
@@ -126,10 +141,13 @@
     }
     #  Append the data to the buffer.  And figure out if the read is done:
 
-
+    &Debug(9,"Received from host: ".$data);
     $self->{TransactionReply} .= $data;
     if($self->{TransactionReply} =~ /(.*\n)/) {
-	if ($self->{State}  eq "Connected") { # We received the challenge:
+	&Debug(8,"Readable End of line detected");
+	if ($self->{State}  eq "Initialized") { # We received the challenge:
+
+	    &Debug(8," Transition out of Initialized");
 	    $self->{TransactionRequest} = $self->{TransactionReply};
 	    $self->{InformWritable}     = 1;
 	    $self->{InformReadable}     = 0;
@@ -140,11 +158,30 @@
 	    if($self->{TransactionReply} != "ok\n") {
 		return -1;
 	    }
-	    $self->Transition("Idle");
+	    $self->Transition("RequestingKey");
 	    $self->{InformReadable}  = 0;
-	    $self->{InformWritable}  = 0;
-	    $self->{Timeoutable}     = 0;
+	    $self->{InformWritable}  = 1;
+	    $self->{TransactionRequest} = "ekey\n";
 	    return 0;
+	} elsif ($self->{State}  eq "ReceivingKey") {
+	    my $buildkey = $self->{TransactionReply};
+	    my $key = $self->{Host}.$perlvar{'lonHostID'};
+	    $key=~tr/a-z/A-Z/;
+	    $key=~tr/G-P/0-9/;
+	    $key=~tr/Q-Z/0-9/;
+	    $key=$key.$buildkey.$key.$buildkey.$key.$buildkey;
+	    $key=substr($key,0,32);
+	    my $cipherkey=pack("H32",$key);
+	    $self->{Cipher} = new IDEA $cipherkey;
+	    if($self->{Cipher} == undef) {
+		return -1;
+	    } else {
+		$self->Transition("Idle");
+		$self->{InformWritable}  =  0;
+		$self->{InformReadable}  =  0;
+		$self->{Timeoutable}     = 0;
+		return 0;
+	    }
 	} elsif ($self->{State}  eq "ReceivingReply") {
 	    $self->{InformWritable}     = 0;
 	    $self->{InformReadable}     = 0;
@@ -176,7 +213,6 @@
     my $socket   = $self->{Socket};
     my $nwritten = $socket->send($self->{TransactionRequest}, 0);
     my $errno    = $! + 0;
-
     unless (defined $nwritten) {
 	if($errno != POSIX::EINTR) {
 	    return -1;
@@ -200,13 +236,18 @@
 		$self->Transition("Initialized");
 	    } elsif($self->{State} eq "ChallengeReceived") {
 		$self->Transition("ChallengeReplied");
+	    } elsif($self->{State} eq "RequestingKey") {
+		$self->Transition("ReceivingKey");
+		$self->{InformWritable} = 0;
+		$self->{InformReadable} = 1;
+		$self->{TransactionReply} = '';
 	    } elsif ($self->{State} eq "SendingRequest") {
 		$self->Transition("ReceivingReply");
 		$self->{TimeoutRemaining} = $self->{TimeoutValue};
 	    }
+	    return 0;
 	}
-	return 0;
-    } else {
+    } else {			# The write failed (e.g. partner disconnected).
 	return -1;
     }
 	
@@ -321,7 +362,7 @@
   return the state of the flag that indicates the object wants to be informed
    of timeouts.
 =cut
-sub WandTimeout {
+sub WantTimeout {
     my $self = shift;
     return $self->{Timeoutable};
 }
@@ -337,6 +378,8 @@
 =item Initialized: "init" sent.
 =item ChallengeReceived: lond sent its challenge to us.
 =item ChallengeReplied:  We replied to lond's challenge waiting for lond's ok.
+=item RequestingKey:    We are requesting an encryption key.
+=item ReceivingKey:     We are receiving an encryption key.
 =item Idle:  Connection was negotiated but no requests are active.
 =item SendingRequest: A request is being sent to the peer.
 =item ReceivingReply: Waiting for an entire reply from the peer.
@@ -359,6 +402,8 @@
 Timeoutable        - True if the current operation is allowed to timeout.
 TimeoutValue       - Number of seconds in the timeout.
 TimeoutRemaining   - Number of seconds left in the timeout.
+CipherKey          - The key that was negotiated with the peer.
+Cipher             - The cipher obtained via the key.