Diff for /loncom/LondConnection.pm between versions 1.55 and 1.62

version 1.55, 2017/10/20 20:20:21 version 1.62, 2018/12/14 02:05:38
Line 43  use LONCAPA::lonssl; Line 43  use LONCAPA::lonssl;
 my $DebugLevel=0;  my $DebugLevel=0;
 my %perlvar;  my %perlvar;
 my %secureconf;  my %secureconf;
 my %hosttypes;   my %badcerts;
   my %hosttypes;
   my %crlchecked;
 my $InsecureOk;  my $InsecureOk;
   
 #  #
Line 79  sub ReadConfig { Line 81  sub ReadConfig {
     unless (lonssl::Read_Host_Types(\%hosttypes,\%perlvar) eq 'ok') {      unless (lonssl::Read_Host_Types(\%hosttypes,\%perlvar) eq 'ok') {
         Debug(1,"Failed to retrieve hosttypes hash.\n");          Debug(1,"Failed to retrieve hosttypes hash.\n");
     }      }
       %badcerts = ();
       %crlchecked = ();
 }  }
   
 sub ResetReadConfig {  sub ResetReadConfig {
Line 161  host the remote lond is on. This host is Line 165  host the remote lond is on. This host is
   
  port number the remote lond is listening on.   port number the remote lond is listening on.
   
   =item lonid
   
    lonid of the remote lond is listening on.
   
   =item deflonid
   
    default lonhostID of the remote lond is listening on.
   
 =cut  =cut
   
 sub new {  sub new {
     my ($class, $DnsName, $Port, $lonid) = @_;      my ($class, $DnsName, $Port, $lonid, $deflonid, $loncaparev) = @_;
   
     if (!$ConfigRead) {      if (!$ConfigRead) {
  ReadConfig();   ReadConfig();
  $ConfigRead = 1;   $ConfigRead = 1;
     }      }
     &Debug(4,$class."::new( ".$DnsName.",".$Port.",".$lonid.")\n");      &Debug(4,$class."::new( ".$DnsName.",".$Port.",".$lonid.",".$deflonid.",".$loncaparev.")\n");
   
       my ($conntype,$gotconninfo,$allowinsecure);
       if ((ref($secureconf{'connto'}) eq 'HASH') &&
           (exists($hosttypes{$lonid}))) {
           $conntype = $secureconf{'connto'}{$hosttypes{$lonid}};
           if ($conntype ne '') {
               if ($conntype ne 'req') {
                   $allowinsecure = 1;
               }
               $gotconninfo = 1;
           }
       }
       unless ($gotconninfo) {
           $allowinsecure = $InsecureOk;
       }
   
     # The host must map to an entry in the hosts table:      # The host must map to an entry in the hosts table:
     #  We connect to the dns host that corresponds to that      #  We connect to the dns host that corresponds to that
Line 184  sub new { Line 211  sub new {
     # Now create the object...      # Now create the object...
     my $self     = { Host               => $DnsName,      my $self     = { Host               => $DnsName,
                      LoncapaHim         => $lonid,                       LoncapaHim         => $lonid,
                        LoncapaDefid       => $deflonid,
                        LoncapaRev         => $loncaparev, 
                      Port               => $Port,                       Port               => $Port,
                      State              => "Initialized",                       State              => "Initialized",
      AuthenticationMode => "",       AuthenticationMode => "",
        InsecureOK         => $allowinsecure,
                      TransactionRequest => "",                       TransactionRequest => "",
                      TransactionReply   => "",                       TransactionReply   => "",
                      NextRequest        => "",                       NextRequest        => "",
Line 258  sub new { Line 288  sub new {
   
  my ($ca, $cert) = lonssl::CertificateFile;   my ($ca, $cert) = lonssl::CertificateFile;
  my $sslkeyfile  = lonssl::KeyFile;   my $sslkeyfile  = lonssl::KeyFile;
           my $badcertfile = lonssl::has_badcert_file($self->{LoncapaHim});
           my ($loncaparev) = ($perlvar{'lonVersion'} =~ /^[\'\"]?([\w.\-]+)[\'\"]?$/);
   
         my ($conntype,$gotconninfo);   if (($conntype ne 'no') && (defined($ca)) && (defined($cert)) && (defined($sslkeyfile)) &&
         if ((ref($secureconf{'connto'}) eq 'HASH') &&              (!exists($badcerts{$self->{LoncapaHim}})) && !$badcertfile) {
             (exists($hosttypes{$lonid}))) {  
             $conntype = $secureconf{'connto'}{$hosttypes{$lonid}};  
             if ($conntype ne '') {  
                 $gotconninfo = 1;  
             }  
         }  
  if (($conntype ne 'no') && (defined($ca)) && (defined($cert)) && (defined($sslkeyfile))) {  
     $self->{AuthenticationMode} = "ssl";      $self->{AuthenticationMode} = "ssl";
     $self->{TransactionRequest} = "init:ssl:$perlvar{'lonVersion'}\n";      $self->{TransactionRequest} = "init:ssl:$loncaparev\n";
  } elsif (($gotconninfo && $conntype ne 'req') || (!$gotconninfo && $InsecureOk)) {    } elsif ($self->{InsecureOK}) {
     # Allowed to do insecure:      # Allowed to do insecure:
     $self->{AuthenticationMode} = "insecure";      $self->{AuthenticationMode} = "insecure";
     $self->{TransactionRequest} = "init::$perlvar{'lonVersion'}\n";      $self->{TransactionRequest} = "init::$loncaparev\n";
  } else {   } else {
     # Not allowed to do insecure...      # Not allowed to do insecure...
     $socket->close;      $socket->close;
Line 424  sub Readable { Line 449  sub Readable {
     }      }
     elsif ($ConnectionMode eq "ssl") {      elsif ($ConnectionMode eq "ssl") {
  if($Response =~ /^ok:ssl/) {     # Good ssl...   if($Response =~ /^ok:ssl/) {     # Good ssl...
     if($self->ExchangeKeysViaSSL()) { # Success skip to vsn stuff      my $sslresult = $self->ExchangeKeysViaSSL();
                       if ($sslresult == 1) { # Success skip to vsn stuff
  # Need to reset to non blocking:   # Need to reset to non blocking:
   
  my $flags = fcntl($socket, F_GETFL, 0);   my $flags = fcntl($socket, F_GETFL, 0);
  fcntl($socket, F_SETFL, $flags | O_NONBLOCK);   fcntl($socket, F_SETFL, $flags | O_NONBLOCK);
  $self->ToVersionRequest();   $self->ToVersionRequest();
  return 0;   return 0;
     }      } 
     else {         # Failed in ssl exchange.      else { # Failed in ssl exchange.
           if (($sslresult == -1) && (lonssl::LastError == -1) && ($self->{InsecureOK})) {
                               my $badcertdir = &lonssl::BadCertDir();
                               if (($badcertdir) && $self->{LoncapaHim}) {
                                   if (open(my $fh,'>',"$badcertdir/".$self->{LoncapaHim})) {
                                       close($fh);
                                   }
                               }
       $badcerts{$self->{LoncapaHim}} = 1;
                               &Debug(3,"SSL verification failed: close socket and initiate insecure connection");
                               $self->Transition("ReInitNoSSL");
                               $socket->close;
                               return -1;
    }
  &Debug(3,"init:ssl failed key negotiation!");   &Debug(3,"init:ssl failed key negotiation!");
  $self->Transition("Disconnected");   $self->Transition("Disconnected");
  $socket->close;   $socket->close;
  return -1;   return -1;
     }                      }
  }    } 
  elsif ($Response =~ /^[0-9]+/) { # Old style lond.   elsif ($Response =~ /^[0-9]+/) { # Old style lond.
     return $self->CompleteInsecure();      return $self->CompleteInsecure();
Line 502  sub Readable { Line 541  sub Readable {
     }      }
  } elsif ($self->{State}  eq "ReceivingKey") {   } elsif ($self->{State}  eq "ReceivingKey") {
     my $buildkey = $self->{TransactionReply};      my $buildkey = $self->{TransactionReply};
               chomp($buildkey);
     my $key = $self->{LoncapaHim}.$perlvar{'lonHostID'};      my $key = $self->{LoncapaHim}.$perlvar{'lonHostID'};
     $key=~tr/a-z/A-Z/;      $key=~tr/a-z/A-Z/;
     $key=~tr/G-P/0-9/;      $key=~tr/G-P/0-9/;
Line 1027  sub CreateCipher { Line 1067  sub CreateCipher {
 sub ExchangeKeysViaSSL {  sub ExchangeKeysViaSSL {
     my $self   = shift;      my $self   = shift;
     my $socket = $self->{Socket};      my $socket = $self->{Socket};
       my $peer = $self->{LoncapaHim};
       my $peerdef = $self->{LoncapaDefid};
       my $loncaparev = $self->{LoncapaRev};
   
     #  Get our signed certificate, the certificate authority's       #  Get our signed certificate, the certificate authority's 
     #  certificate and our private key file.  All of these      #  certificate and our private key file.  All of these
Line 1035  sub ExchangeKeysViaSSL { Line 1078  sub ExchangeKeysViaSSL {
     my ($SSLCACertificate,      my ($SSLCACertificate,
  $SSLCertificate) = lonssl::CertificateFile();   $SSLCertificate) = lonssl::CertificateFile();
     my $SSLKey             = lonssl::KeyFile();      my $SSLKey             = lonssl::KeyFile();
       my $CRLFile;
       unless ($crlchecked{$peerdef}) {
           $CRLFile = lonssl::CRLFile();
           $crlchecked{$peerdef} = 1;
       }
     #  Promote our connection to ssl and read the key from lond.      #  Promote our connection to ssl and read the key from lond.
   
     my $SSLSocket = lonssl::PromoteClientSocket($socket,      my $SSLSocket = lonssl::PromoteClientSocket($socket,
  $SSLCACertificate,   $SSLCACertificate,
  $SSLCertificate,   $SSLCertificate,
  $SSLKey);   $SSLKey,
                                                   $peer,
                                                   $peerdef,
                                                   $CRLFile,
                                                   $loncaparev);
     if(defined $SSLSocket) {      if(defined $SSLSocket) {
  my $key  = <$SSLSocket>;   my $key  = <$SSLSocket>;
  lonssl::Close($SSLSocket);   lonssl::Close($SSLSocket);
Line 1057  sub ExchangeKeysViaSSL { Line 1108  sub ExchangeKeysViaSSL {
     else {      else {
  # Failed!!   # Failed!!
  Debug(3, "Failed to negotiate SSL connection!");   Debug(3, "Failed to negotiate SSL connection!");
  return 0;   return -1;
     }      }
     # should not get here      # should not get here
     return 0;      return 0;
Line 1082  sub ExchangeKeysViaSSL { Line 1133  sub ExchangeKeysViaSSL {
 #  #
 sub CompleteInsecure {  sub CompleteInsecure {
     my $self = shift;      my $self = shift;
     $self->{LoncapaHim};      if ($self->{InsecureOK}) {
     my ($conntype,$gotconninfo);  
     if ((ref($secureconf{'connto'}) eq 'HASH') &&  
         (exists($hosttypes{$self->{LoncapaHim}}))) {  
         $conntype = $secureconf{'connto'}{$hosttypes{$self->{LoncapaHim}}};  
         if ($conntype ne '') {  
             $gotconninfo = 1;  
         }  
     }   
     if ((($gotconninfo) && ($conntype ne 'req')) || (!$gotconninfo && $InsecureOk)) {  
  $self->{AuthenticationMode} = "insecure";   $self->{AuthenticationMode} = "insecure";
  &Debug(8," Transition out of Initialized:insecure");   &Debug(8," Transition out of Initialized:insecure");
  $self->{TransactionRequest} = $self->{TransactionReply};   $self->{TransactionRequest} = $self->{TransactionReply};
Line 1203  sub PeerLoncapaHim { Line 1245  sub PeerLoncapaHim {
     return $self->{LoncapaHim};      return $self->{LoncapaHim};
 }  }
   
   #
   # Get the Authentication mode
   #
   
   sub GetKeyMode {
       my $self = shift;
       return $self->{AuthenticationMode};
   }
   
 1;  1;
   
 =pod  =pod

Removed from v.1.55  
changed lines
  Added in v.1.62


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>