--- loncom/lonssl.pm 2015/11/08 03:15:13 1.14 +++ loncom/lonssl.pm 2018/07/29 03:03:36 1.16 @@ -1,5 +1,5 @@ # -# $Id: lonssl.pm,v 1.14 2015/11/08 03:15:13 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 @@ sub SetFdBlocking { # 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 @@ sub PromoteClientSocket { 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 @@ sub PromoteClientSocket { # 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 @@ sub PromoteClientSocket { 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 @@ sub PromoteClientSocket { #---------------------------------------------------------------------- # 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 @@ sub PromoteClientSocket { # 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 @@ sub PromoteServerSocket { my ($PlaintextSocket, $CACert, $MyCert, - $KeyFile) = @_; + $KeyFile, + $peer) = @_; @@ -209,7 +216,9 @@ sub PromoteServerSocket { 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; @@ -333,4 +342,64 @@ sub KeyFile { return $KeyFilename; } +sub Read_Connect_Config { + my ($secureconf,$perlvarref) = @_; + return unless (ref($secureconf) eq 'HASH'); + + unless (ref($perlvarref) eq 'HASH') { + $perlvarref = $perlvar; + } + + # Clean out the old table first. + foreach my $key (keys(%{$secureconf})) { + delete($secureconf->{$key}); + } + + my $result; + my $tablename = $perlvarref->{'lonTabDir'}."/connectionrules.tab"; + if (open(my $fh,"<$tablename")) { + while (my $line = <$fh>) { + chomp($line); + my ($name,$value) = split(/=/,$line); + if ($value =~ /^(?:no|yes|req)$/) { + if ($name =~ /^conn(to|from)_(dom|intdom|other)$/) { + $secureconf->{'conn'.$1}{$2} = $value; + } + } + } + close($fh); + return 'ok'; + } + return; +} + +sub Read_Host_Types { + my ($hosttypes,$perlvarref) = @_; + return unless (ref($hosttypes) eq 'HASH'); + + unless (ref($perlvarref) eq 'HASH') { + $perlvarref = $perlvar; + } + + # Clean out the old table first. + foreach my $key (keys(%{$hosttypes})) { + delete($hosttypes->{$key}); + } + + my $result; + my $tablename = $perlvarref->{'lonTabDir'}."/hosttypes.tab"; + if (open(my $fh,"<$tablename")) { + while (my $line = <$fh>) { + chomp($line); + my ($name,$value) = split(/:/,$line); + if (($name ne '') && ($value =~ /^(dom|intdom|other)$/)) { + $hosttypes->{$name} = $value; + } + } + close($fh); + return 'ok'; + } + return; +} + 1;