[LON-CAPA-cvs] cvs: newloncapa /types LondConnection.pm
foxr
lon-capa-cvs@mail.lon-capa.org
Wed, 09 Apr 2003 01:08:14 -0000
foxr Tue Apr 8 21:08:14 2003 EDT
Modified files:
/newloncapa/types LondConnection.pm
Log:
1. Read in hosts.tab file so that:
2. Opens are now done with a parameter that is the loncapa hostname
rather than the IP hostname.
Index: newloncapa/types/LondConnection.pm
diff -u newloncapa/types/LondConnection.pm:1.4 newloncapa/types/LondConnection.pm:1.5
--- newloncapa/types/LondConnection.pm:1.4 Tue Apr 1 18:22:35 2003
+++ newloncapa/types/LondConnection.pm Tue Apr 8 21:08:14 2003
@@ -9,8 +9,22 @@
use Fcntl;
use POSIX;
use Crypt::IDEA;
+use LONCAPA::Configuration;
-$DebugLevel=10;
+my $DebugLevel=10;
+
+# Read the configuration file for apache to get the perl
+# variable set.
+
+my $perlvarref = LONCAPA::Configuration::read_conf('loncapa.conf');
+my %perlvar = %{$perlvarref};
+my $hoststab =
+ LONCAPA::Configuration::read_hosts(
+ "$perlvar{'lonTabDir'}/hosts.tab") ||
+ die "Can't read host table!!";
+my %hostshash = %{$hoststab};
+
+close(CONFIG);
sub Debug {
my $level = shift;
@@ -50,7 +64,8 @@
=pod
Construct a new lond connection.
Parameters (besides the class name) include:
-=item hostname - host the remote lond is on.
+=item hostname - host the remote lond is on.
+ This host is a host in the hosts.tab file
=item port - port number the remote lond is listening on.
=cut
sub new {
@@ -58,7 +73,22 @@
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,
+
+ # The host must map to an entry in the hosts table:
+ # We connect to the dns host that corresponds to that
+ # system and use the hostname for the encryption key
+ # negotion. In the objec these become the Host and
+ # LoncapaHim fields of the object respectively.
+ #
+ if (!exists $hostshash{$Hostname}) {
+ return undef; # No such host!!!
+ }
+ my @ConfigLine = @{$hostshash{$Hostname}};
+ my $DnsName = $ConfigLine[3]; # 4'th item is dns of host.
+ Debug(5, "Connecting to ".$DnsName);
+ # Now create the object...
+ my $self = { Host => $DnsName,
+ LoncapaHim => $Hostname,
Port => $Port,
State => "Initialized",
TransactionRequest => "",
@@ -165,7 +195,7 @@
return 0;
} elsif ($self->{State} eq "ReceivingKey") {
my $buildkey = $self->{TransactionReply};
- my $key = $self->{Host}.$perlvar{'lonHostID'};
+ my $key = $self->{LoncapaHim}.$perlvar{'lonHostID'};
$key=~tr/a-z/A-Z/;
$key=~tr/G-P/0-9/;
$key=~tr/Q-Z/0-9/;
@@ -183,6 +213,17 @@
return 0;
}
} elsif ($self->{State} eq "ReceivingReply") {
+
+ # If the data are encrypted, decrypt first.
+
+ my $answer = $self->{TransactionReply};
+ if($answer =~ /^enc\:/) {
+ $answer = $self->Decrypt($answer);
+ $self->{TransactionReply} = $answer;
+ }
+
+ # finish the transaction
+
$self->{InformWritable} = 0;
$self->{InformReadable} = 0;
$self->{Timeoutable} = 0;
@@ -296,6 +337,13 @@
if($self->{State} ne "Idle") {
return -1; # Error indicator.
}
+ # if the transaction is to be encrypted encrypt the data:
+
+ if($data =~ /^encrypt\:/) {
+ $data = $self->Encrypt($data);
+ }
+
+ # Setup the trasaction
$self->{TransactionRequest} = $data;
$self->{TransactionReply} = "";
@@ -369,12 +417,88 @@
return $self->{Timeoutable};
}
-
+=pod
+ Returns the reply from the last transaction.
+=cut
sub GetReply {
my $self = shift;
return $self->{TransactionReply};
}
+
+=pod
+ Returns the encrypted version of the command string.
+ The command input string is of the form:
+ encrypt:command
+ The output string can be directly sent to lond as it's of the form:
+ enc:length:<encodedrequest>
+'
+=cut
+sub Encrypt {
+ my $self = shift; # Reference to the object.
+ my $request = shift; # Text to send.
+
+
+ # Split the encrypt: off the request and figure out it's length.
+ # the cipher works in blocks of 8 bytes.
+
+ my $cmd = $request;
+ $cmd =~ s/^encrypt\://; # strip off encrypt:
+ chomp($cmd); # strip off trailing \n
+ my $length=length($cmd); # Get the string length.
+ $cmd .= " "; # Pad with blanks so we can fill out a block.
+
+ # encrypt the request in 8 byte chunks to create the encrypted
+ # output request.
+
+ my $Encoded = '';
+ for(my $index = 0; $index <= $length; $index += 8) {
+ $Encoded .=
+ unpack("H16",
+ $self->{Cipher}->encrypt(substr($cmd,
+ $index, 8)));
+ }
+
+ # Build up the answer as enc:length:$encrequest.
+
+ $request = "enc:$length:$Encoded\n";
+ return $request;
+
+}
+=pod
+ Decrypt
+ Decrypt a response from the server. The response is in the form:
+ enc:<length>:<encrypted data>
+=cut
+sub Decrypt {
+ my $self = shift; # Recover reference to object
+ my $encrypted = shift; # This is the encrypted data.
+
+ # Bust up the response into length, and encryptedstring:
+
+ my ($enc, $length, $EncryptedString) = split(/:/,$encrypted);
+ chomp($EncryptedString);
+
+ # Decode the data in 8 byte blocks. The string is encoded
+ # as hex digits so there are two characters per byte:
+
+ $decrpyted = "";
+ for(my $index = 0; $index < length($EncryptedString);
+ $index += 16) {
+ $decrypted .= $self->{Cipher}->decrypt(
+ pack("H16",
+ substr($EncryptedString,
+ $index,
+ 16)));
+ }
+ # the answer may have trailing pads to fill out a block.
+ # $length tells us the actual length of the decrypted string:
+
+ $decrypted = substr($decrypted, 0, $length);
+
+ return $decrypted;
+
+}
1;
=pod
@@ -428,7 +552,10 @@
The client to manage the work flow for the object.
=item SetTimeoutCallback -Set a function to be called when a transaction times
out. The function will be called with the object as its sole parameter.
-
+=item Encrypt - Encrypts a block of text according to the cipher negotiated
+ with the peer (assumes the text is a command).
+=item Decrypt - Decrypts a block of text according to the cipher negotiated
+ with the peer (assumes the block was a reply.
=head2 The following are selector member functions: