[LON-CAPA-cvs] cvs: loncom / LondConnection.pm lond lonssl.pm

raeburn raeburn at source.lon-capa.org
Sat Jul 28 23:03:36 EDT 2018


raeburn		Sun Jul 29 03:03:36 2018 EDT

  Modified files:              
    /loncom	lond lonssl.pm LondConnection.pm 
  Log:
  - Include verification of common name when creating SSL tunnel. Fall back
    to insecure connection (if allowed) if verification fails. 
  
  
-------------- next part --------------
Index: loncom/lond
diff -u loncom/lond:1.543 loncom/lond:1.544
--- loncom/lond:1.543	Fri Mar 23 01:02:22 2018
+++ loncom/lond	Sun Jul 29 03:03:36 2018
@@ -2,7 +2,7 @@
 # The LearningOnline Network
 # lond "LON Daemon" Server (port "LOND" 5663)
 #
-# $Id: lond,v 1.543 2018/03/23 01:02:22 raeburn Exp $
+# $Id: lond,v 1.544 2018/07/29 03:03:36 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -65,7 +65,7 @@
 my $status='';
 my $lastlog='';
 
-my $VERSION='$Revision: 1.543 $'; #' stupid emacs
+my $VERSION='$Revision: 1.544 $'; #' stupid emacs
 my $remoteVERSION;
 my $currenthostid="default";
 my $currentdomainid;
@@ -423,7 +423,8 @@
     my $SSLSocket = lonssl::PromoteServerSocket($Socket,
 						$CACertificate,
 						$Certificate,
-						$KeyFile);
+						$KeyFile,
+						$clientname);
     if(! ($SSLSocket) ) {	# SSL socket promotion failed.
 	my $err = lonssl::LastError();
 	&logthis("<font color=\"red\"> CRITICAL "
Index: loncom/lonssl.pm
diff -u loncom/lonssl.pm:1.15 loncom/lonssl.pm:1.16
--- loncom/lonssl.pm:1.15	Tue Feb 28 05:42:06 2017
+++ loncom/lonssl.pm	Sun Jul 29 03:03:36 2018
@@ -1,5 +1,5 @@
 #
-# $Id: lonssl.pm,v 1.15 2017/02/28 05:42:06 raeburn Exp $
+# $Id: lonssl.pm,v 1.16 2018/07/29 03:03:36 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -116,6 +116,7 @@
 #                                          issued to this host.
 #                KeyFile string    	   Full pathname to the host's private 
 #                                          key file for the certificate.
+#               peer    string             lonHostID of remote LON-CAPA server 
 # Returns
 #	-	Reference to an SSL socket on success
 #       -	undef on failure.  Reason for failure can be interrogated from 
@@ -127,10 +128,11 @@
     my ($PlaintextSocket,
 	$CACert,
 	$MyCert,
-	$KeyFile)          = @_;
+	$KeyFile,
+        $peer)          = @_;
     
     
-    Debug("Client promotion using key: $KeyFile, Cert: $MyCert, CA: $CACert\n");
+    Debug("Client promotion using key: $KeyFile, Cert: $MyCert, CA: $CACert, Remote Host: $peer\n");
 
     # To create the ssl socket we need to duplicate the existing
     # socket.  Otherwise closing the ssl socket will close the plaintext socket
@@ -146,9 +148,11 @@
     # mode of SSL_VERIFY_NONE should be explicitly set for client, if 
     # verification is not to be used, and SSL_verify_mode is not set.
     # Starting with rev. 1.95, the default became SSL_VERIFY_PEER which
-    # prevents connections to lond.
-    # Set SSL_verify_mode to Net::SSLeay::VERIFY_NONE() instead of to
-    # SSL_VERIFY_NONE for compatibility with IO::Socket::SSL rev. 1.01
+    # prevents an SSL connection to lond unless SSL_verifycn_name is set
+    # to the lonHostID of the remote host, (and the remote certificate has
+    # the remote lonHostID as CN, and has been signed by the LON-CAPA CA. 
+    # Set SSL_verify_mode to Net::SSLeay::VERIFY_PEER() instead of to
+    # SSL_VERIFY_PEER for compatibility with IO::Socket::SSL rev. 1.01
     # used by CentOS/RHEL/Scientific Linux 5).
     
     my $client = IO::Socket::SSL->new_from_fd($dupfno,
@@ -156,7 +160,8 @@
 					      SSL_key_file  => $KeyFile,
 					      SSL_cert_file => $MyCert,
 					      SSL_ca_file   => $CACert,
-					      SSL_verify_mode => Net::SSLeay::VERIFY_NONE());
+					      SSL_verifycn_name => $peer,
+					      SSL_verify_mode => Net::SSLeay::VERIFY_PEER());
     
     if(!$client) {
 	$lasterror = IO::Socket::SSL::errstr();
@@ -168,7 +173,7 @@
 #----------------------------------------------------------------------
 # Name	PromoteServerSocket
 # Description	Given an ordinary IO::Socket::INET Creates an SSL socket 
-#               for a server that is connected to the same client.l
+#               for a server that is connected to the same client.
 # Parameters	Name	Type	           Description
 #               Socket	IO::Socket::INET   Original ordinary socket.
 #               CACert	string	           Full path name to the certificate 
@@ -177,6 +182,7 @@
 #                                          issued to this host.
 #                KeyFile string    	   Full pathname to the host's private 
 #                                          key file for the certificate.
+#                peer   string             lonHostID of remote LON-CAPA client
 # Returns
 #	-	Reference to an SSL socket on success
 #       -	undef on failure.  Reason for failure can be interrogated from 
@@ -188,7 +194,8 @@
     my ($PlaintextSocket,
 	$CACert,
 	$MyCert,
-	$KeyFile)          = @_;
+	$KeyFile,
+        $peer)          = @_;
 
 
 
@@ -209,7 +216,9 @@
 					      SSL_use_cert  => 1,
 					      SSL_key_file  => $KeyFile,
 					      SSL_cert_file => $MyCert,
-					      SSL_ca_file   => $CACert);
+					      SSL_ca_file   => $CACert,
+					      SSL_verifycn_name => $peer,
+					      SSL_verify_mode => Net::SSLeay::VERIFY_PEER());
     if(!$client) {
 	$lasterror = IO::Socket::SSL::errstr();
 	return undef;
Index: loncom/LondConnection.pm
diff -u loncom/LondConnection.pm:1.55 loncom/LondConnection.pm:1.56
--- loncom/LondConnection.pm:1.55	Fri Oct 20 20:20:21 2017
+++ loncom/LondConnection.pm	Sun Jul 29 03:03:36 2018
@@ -1,7 +1,7 @@
 #   This module defines and implements a class that represents
 #   a connection to a lond daemon.
 #
-# $Id: LondConnection.pm,v 1.55 2017/10/20 20:20:21 raeburn Exp $
+# $Id: LondConnection.pm,v 1.56 2018/07/29 03:03:36 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -43,6 +43,7 @@
 my $DebugLevel=0;
 my %perlvar;
 my %secureconf;
+my %badcerts;
 my %hosttypes; 
 my $InsecureOk;
 
@@ -79,6 +80,7 @@
     unless (lonssl::Read_Host_Types(\%hosttypes,\%perlvar) eq 'ok') {
         Debug(1,"Failed to retrieve hosttypes hash.\n");
     }
+    undef(%badcerts);
 }
 
 sub ResetReadConfig {
@@ -172,6 +174,21 @@
     }
     &Debug(4,$class."::new( ".$DnsName.",".$Port.",".$lonid.")\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:
     #  We connect to the dns host that corresponds to that
     #  system and use the hostname for the encryption key 
@@ -187,6 +204,7 @@
                      Port               => $Port,
                      State              => "Initialized",
 		     AuthenticationMode => "",
+		     InsecureOK         => $allowinsecure,                     
                      TransactionRequest => "",
                      TransactionReply   => "",
                      NextRequest        => "",
@@ -259,18 +277,11 @@
 	my ($ca, $cert) = lonssl::CertificateFile;
 	my $sslkeyfile  = lonssl::KeyFile;
 
-        my ($conntype,$gotconninfo);
-        if ((ref($secureconf{'connto'}) eq 'HASH') &&
-            (exists($hosttypes{$lonid}))) {
-            $conntype = $secureconf{'connto'}{$hosttypes{$lonid}};
-            if ($conntype ne '') {
-                $gotconninfo = 1;
-            }
-        }
-	if (($conntype ne 'no') && (defined($ca)) && (defined($cert)) && (defined($sslkeyfile))) {
+	if (($conntype ne 'no') && (defined($ca)) && (defined($cert)) && (defined($sslkeyfile)) &&
+            (!exists($badcerts{$self->{LoncapaHim}}))) {
 	    $self->{AuthenticationMode} = "ssl";
 	    $self->{TransactionRequest} = "init:ssl:$perlvar{'lonVersion'}\n";
-	} elsif (($gotconninfo && $conntype ne 'req') || (!$gotconninfo && $InsecureOk)) { 
+	} elsif ($self->{InsecureOK}) {
 	    # Allowed to do insecure:
 	    $self->{AuthenticationMode} = "insecure";
 	    $self->{TransactionRequest} = "init::$perlvar{'lonVersion'}\n";
@@ -424,7 +435,8 @@
 	    }
 	    elsif ($ConnectionMode eq "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:
 
 			my $flags = fcntl($socket, F_GETFL, 0);
@@ -433,6 +445,9 @@
 			return 0;
 		    }
 		    else {	         # Failed in ssl exchange.
+		        if (($sslresult == -1) && ($self->{InsecureOK})) {
+			    $badcerts{$self->{LoncapaHim}} = 1;
+			}
 			&Debug(3,"init:ssl failed key negotiation!");
 			$self->Transition("Disconnected");
 			$socket->close;
@@ -1027,6 +1042,7 @@
 sub ExchangeKeysViaSSL {
     my $self   = shift;
     my $socket = $self->{Socket};
+    my $peer = $self->{LoncapaHim};
 
     #  Get our signed certificate, the certificate authority's 
     #  certificate and our private key file.  All of these
@@ -1041,7 +1057,8 @@
     my $SSLSocket = lonssl::PromoteClientSocket($socket,
 						$SSLCACertificate,
 						$SSLCertificate,
-						$SSLKey);
+						$SSLKey,
+                                                $peer);
     if(defined $SSLSocket) {
 	my $key  = <$SSLSocket>;
 	lonssl::Close($SSLSocket);
@@ -1057,7 +1074,7 @@
     else {
 	# Failed!!
 	Debug(3, "Failed to negotiate SSL connection!");
-	return 0;
+	return -1;
     }
     # should not get here
     return 0;
@@ -1082,16 +1099,7 @@
 #
 sub CompleteInsecure {
     my $self = shift;
-    $self->{LoncapaHim};
-    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)) {
+    if ($self->{InsecureOK}) {
 	$self->{AuthenticationMode} = "insecure";
 	&Debug(8," Transition out of Initialized:insecure");
 	$self->{TransactionRequest} = $self->{TransactionReply};


More information about the LON-CAPA-cvs mailing list