Annotation of loncom/lonlocal.pm, revision 1.7

1.2       foxr        1: #
1.7     ! albertel    2: # $Id: lonlocal.pm,v 1.6 2004/06/17 10:15:46 foxr Exp $
1.2       foxr        3: #
                      4: # Copyright Michigan State University Board of Trustees
                      5: #
                      6: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                      7: #
                      8: # LON-CAPA is free software; you can redistribute it and/or modify
                      9: # it under the terms of the GNU General Public License as published by
                     10: # the Free Software Foundation; either version 2 of the License, or
                     11: # (at your option) any later version.
                     12: #
                     13: # LON-CAPA is distributed in the hope that it will be useful,
                     14: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     15: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     16: # GNU General Public License for more details.
                     17: #
                     18: # You should have received a copy of the GNU General Public License
                     19: # along with LON-CAPA; if not, write to the Free Software
                     20: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     21: #
                     22: # /home/httpd/html/adm/gpl.txt
                     23: #
                     24: # http://www.lon-capa.org/
                     25: #
                     26: package lonlocal;
                     27: 
                     28: #
                     29: #   Module that provides support for local connections between secure
                     30: #   lonc and secure lond.
                     31: #
                     32: #   A local connection exchanges one-time session keys through a 
                     33: #   file that is written in the certificate directory by lonc and
                     34: #   read/deleted by lond.  The file is created with permissions
                     35: #   rw------- (0600) to prevent it from being snooped unless the system
                     36: #   itself has been broken.  In addition the file will not be around
                     37: #   for very long so it will be hard to find.
                     38: #
                     39: 
                     40: use strict;
                     41: 
                     42: # CPAN/standard modules
                     43: 
                     44: use Crypt::IDEA;
1.3       foxr       45: use Fcntl;
1.2       foxr       46: 
                     47: # LONCAPA modules
                     48: 
                     49: use LONCAPA::Configuration;
                     50: 
                     51: # Global variables:
                     52: 
                     53: my $perlvar;			# Refers to the apache perlsetvar hash.
1.3       foxr       54: my $pathsep   = "/";		# Unix path seperator 
                     55: my $fileindex = 0;		# Per process lonc uniquifier.
                     56: my $lastError;			# Reason for last failure.
                     57: 
1.2       foxr       58: 
1.5       foxr       59: #  Debugging:
                     60: 
1.6       foxr       61: my $DEBUG = 0;
1.5       foxr       62: 
                     63: sub Debug {
                     64:     my $msg = shift;
1.7     ! albertel   65:     if ($DEBUG) { print STDERR "$msg\n"; }
1.5       foxr       66: }
                     67: 
1.2       foxr       68: # Initialization
                     69: 
                     70: $perlvar = LONCAPA::Configuration::read_conf('loncapa.conf');
                     71: 
                     72: 
                     73: #------------------------------------------------------------------------
                     74: #
1.5       foxr       75: # Name          CreateCipherKey
1.2       foxr       76: # Description:  Create an encryption key.
                     77: # Returns:      The key.
                     78: #
                     79: sub CreateCipherKey {
                     80: 
                     81:     my $keylength;
                     82:     my $binaryKey;
                     83:     my $cipherkey;
                     84:     
1.5       foxr       85:     # we'll use the output of /dev/urandom to produce our key.
1.2       foxr       86:     # On a system with decent entropy, this ought to be much more
                     87:     # random than all the playing that used to be done to get a key.
1.5       foxr       88:     # On a system with not so decent entropy we'll still get an ok key.
                     89:     # My concern with /dev/random is that we may block for an indefinite
                     90:     # time period...where for us decent keys are probably good enough.
1.2       foxr       91:     
                     92:     $keylength   =  IDEA::keysize();
1.5       foxr       93:     open(RANDOM, "</dev/urandom");
1.2       foxr       94:     sysread(RANDOM, $binaryKey, $keylength);
                     95:     close RANDOM;
                     96:     
                     97:     #  The key must be returned in a stringified form in order to be
                     98:     #  transmitted to the peer:
                     99:     
                    100:     my $hexdigits = $keylength*2;	# Assume 8 bits/byte.
                    101:     my $template  = "H".$hexdigits;
                    102:     $cipherkey = unpack($template, $binaryKey);
                    103:     
                    104:     return $cipherkey;
                    105: }
                    106: 
                    107: #------------------------------------------------------------------------
                    108: #
                    109: # Name  	CreateKeyFile
                    110: # Description	Creates a private key file and writes an IDEA key into it.  
                    111: #
                    112: # Returns	
                    113: #     A two element list containing:
                    114: #     - 	The private key that was  created
                    115: #     - 	The full path to the file that contains it.
1.3       foxr      116: #     or undef on failure.
1.2       foxr      117: sub CreateKeyFile {
                    118: 
                    119:     # To create the file we need some perlvars to tell us where the
                    120:     # certificate directory. We'll make a file named localkey.$pid
                    121:     # there, and set the mode before writing into it.
                    122:     #
1.3       foxr      123:     $fileindex++;
                    124:     my $CertificateDir = $perlvar->{lonCertificateDirectory};
1.5       foxr      125:     my $Filename       = $CertificateDir.$pathsep.".$fileindex.".$$;
1.3       foxr      126: 
                    127:     # If this file already exists, this is a recoverable error... we just
                    128:     # delete the earlier incarnation of the file.
                    129: 
                    130:     if (-w $Filename) {
                    131: 	unlink $Filename;
                    132:     }
                    133: 
                    134:     # If the file still exists this is really really bad:
                    135:     # It most likely means someone has been devious enough to drop a key file
                    136:     # in place to attemp to spoof the lond.  We'll fail in that case hoping
                    137:     # that the user looks at the log to figure out that local connections
                    138:     # are failing.
                    139:     
                    140:     if( -e $Filename) {
                    141: 	$lastError = "Key file already exists after deletion probably a spoof!";
                    142: 	return undef;
                    143:     }
                    144:     #  Now we can create the file  we use sysopen in order to ensure
                    145:     # the file is created with the appropriate locked down permissions.
                    146: 
                    147:     if(! sysopen(KEYFILE, $Filename, O_CREAT | O_EXCL | O_WRONLY, 0600)) {
1.5       foxr      148: 	$lastError = "Creation of key file failed ".$!;
1.3       foxr      149: 	return undef;
                    150:     }
                    151:     # Create the key, write it to the file and close the file:
                    152: 
                    153:     my $key = CreateCipherKey();
                    154:     print KEYFILE "$key\n";
                    155:     close KEYFILE;
                    156: 
1.5       foxr      157:     return ($key, $Filename);
1.3       foxr      158: 
1.2       foxr      159:     
                    160: }
                    161: 
                    162: 
1.3       foxr      163: # Name  	ReadKeyFile
                    164: # Description	Opens the private local key file and reads the IDEA key from it.
                    165: # Parameters
                    166: #       	Name	          Type	       Description
                    167: #               Filename	  string       path to key file
                    168: #
                    169: # NOTE:
                    170: #   Reading the keyfile is a one-time thing.  This sub destroys the
                    171: #   keyfile after reading it to ensure the one-timedness of the keys they
                    172: #   contain!!
                    173: # Returns	
                    174: #    On success the IDEA key that was written into the key fileon failure undef.
                    175: #
                    176: #
                    177: sub ReadKeyFile {
                    178:     my $Filename = shift;
1.5       foxr      179:     Debug("ReadKeyFile: $Filename");
                    180: 
1.3       foxr      181: 
                    182:     if(! open(KEYFILE, "<$Filename")) {
1.5       foxr      183: 	Debug(" Open of $Filename failed\n");
1.3       foxr      184: 	$lastError = "Key file open failed";
                    185: 	return undef
                    186:     }
                    187:     my $key = <KEYFILE>;
1.5       foxr      188:     chomp($key);
                    189:     Debug(" Read key: $key");
1.3       foxr      190:     close KEYFILE;
                    191:     unlink $Filename;
                    192:     #
                    193:     #  If the filename still exists some spoofer wrote it with the wrong
                    194:     #  permissions:
                    195:     #
                    196:     if(-e $Filename) {
1.5       foxr      197: 	Debug("File did not get deleted");
1.3       foxr      198: 	$lastError = "Key file still exists after unlink";
                    199: 	return undef;
                    200:     }
                    201:     #
                    202:     #  The IDEA key must be  IDEA::keysize*2 characters
                    203:     #  long.   If it  isn't probably someone's trying to break us by
                    204:     #  hitting the timing hole between the file write and read...
                    205:     #  replacing our file... of course if they read this comment they'll
                    206:     #  be too smart to put an incorrectly sized file
                    207:     #
1.5       foxr      208:     my $keylen = length($key);
                    209:     my $rightlen= IDEA::keysize()*2;
                    210:     if($keylen != $rightlen) {
                    211: 	Debug("Key is incorrect length is $keylen sb $rightlen");
1.3       foxr      212: 	$lastError = "Key file has incorrect length";
                    213: 	return undef;
                    214:     }
1.5       foxr      215:     Debug("Returning key: $key to caller");
1.3       foxr      216:     return $key;   
                    217: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.