[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