[LON-CAPA-cvs] cvs: loncom / lonlocal.pm

foxr lon-capa-cvs@mail.lon-capa.org
Fri, 28 May 2004 10:20:04 -0000


foxr		Fri May 28 06:20:04 2004 EDT

  Modified files:              
    /loncom	lonlocal.pm 
  Log:
  Good compile of the module
  
  
Index: loncom/lonlocal.pm
diff -u loncom/lonlocal.pm:1.2 loncom/lonlocal.pm:1.3
--- loncom/lonlocal.pm:1.2	Fri May 28 05:39:11 2004
+++ loncom/lonlocal.pm	Fri May 28 06:20:03 2004
@@ -1,5 +1,5 @@
 #
-# $Id: lonlocal.pm,v 1.2 2004/05/28 09:39:11 foxr Exp $
+# $Id: lonlocal.pm,v 1.3 2004/05/28 10:20:03 foxr Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -43,6 +43,7 @@
 
 use English;
 use Crypt::IDEA;
+use Fcntl;
 
 # LONCAPA modules
 
@@ -51,6 +52,10 @@
 # Global variables:
 
 my $perlvar;			# Refers to the apache perlsetvar hash.
+my $pathsep   = "/";		# Unix path seperator 
+my $fileindex = 0;		# Per process lonc uniquifier.
+my $lastError;			# Reason for last failure.
+
 
 # Initialization
 
@@ -98,15 +103,96 @@
 #     A two element list containing:
 #     - 	The private key that was  created
 #     - 	The full path to the file that contains it.
-#
+#     or undef on failure.
 sub CreateKeyFile {
 
     # To create the file we need some perlvars to tell us where the
     # certificate directory. We'll make a file named localkey.$pid
     # there, and set the mode before writing into it.
     #
-    
+    $fileindex++;
+    my $CertificateDir = $perlvar->{lonCertificateDirectory};
+    my $Filename       = $CertificateDir.$pathsep.".$fileindex.".$PID;
+
+    # If this file already exists, this is a recoverable error... we just
+    # delete the earlier incarnation of the file.
+
+    if (-w $Filename) {
+	unlink $Filename;
+    }
+
+    # If the file still exists this is really really bad:
+    # It most likely means someone has been devious enough to drop a key file
+    # in place to attemp to spoof the lond.  We'll fail in that case hoping
+    # that the user looks at the log to figure out that local connections
+    # are failing.
+    
+    if( -e $Filename) {
+	$lastError = "Key file already exists after deletion probably a spoof!";
+	return undef;
+    }
+    #  Now we can create the file  we use sysopen in order to ensure
+    # the file is created with the appropriate locked down permissions.
+
+    if(! sysopen(KEYFILE, $Filename, O_CREAT | O_EXCL | O_WRONLY, 0600)) {
+	$lastError = "Creation of key file failed ".$ERRNO;
+	return undef;
+    }
+    # Create the key, write it to the file and close the file:
+
+    my $key = CreateCipherKey();
+    print KEYFILE "$key\n";
+    close KEYFILE;
+
+    return \($key, $Filename);
+
     
 }
 
 
+# Name  	ReadKeyFile
+# Description	Opens the private local key file and reads the IDEA key from it.
+# Parameters
+#       	Name	          Type	       Description
+#               Filename	  string       path to key file
+#
+# NOTE:
+#   Reading the keyfile is a one-time thing.  This sub destroys the
+#   keyfile after reading it to ensure the one-timedness of the keys they
+#   contain!!
+# Returns	
+#    On success the IDEA key that was written into the key fileon failure undef.
+#
+#
+sub ReadKeyFile {
+    my $Filename = shift;
+
+    if(! open(KEYFILE, "<$Filename")) {
+	$lastError = "Key file open failed";
+	return undef
+    }
+    my $key = <KEYFILE>;
+    chomp;
+    close KEYFILE;
+    unlink $Filename;
+    #
+    #  If the filename still exists some spoofer wrote it with the wrong
+    #  permissions:
+    #
+    if(-e $Filename) {
+	$lastError = "Key file still exists after unlink";
+	return undef;
+    }
+    #
+    #  The IDEA key must be  IDEA::keysize*2 characters
+    #  long.   If it  isn't probably someone's trying to break us by
+    #  hitting the timing hole between the file write and read...
+    #  replacing our file... of course if they read this comment they'll
+    #  be too smart to put an incorrectly sized file
+    #
+    if(length($key) != IDEA::keysize*2) {
+	$lastError = "Key file has incorrect length";
+	return undef;
+    }
+    return $key;   
+}