Annotation of loncom/lonlocal.pm, revision 1.3
1.2 foxr 1: #
1.3 ! foxr 2: # $Id: lonlocal.pm,v 1.2 2004/05/28 09:39:11 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 English;
45: use Crypt::IDEA;
1.3 ! foxr 46: use Fcntl;
1.2 foxr 47:
48: # LONCAPA modules
49:
50: use LONCAPA::Configuration;
51:
52: # Global variables:
53:
54: my $perlvar; # Refers to the apache perlsetvar hash.
1.3 ! foxr 55: my $pathsep = "/"; # Unix path seperator
! 56: my $fileindex = 0; # Per process lonc uniquifier.
! 57: my $lastError; # Reason for last failure.
! 58:
1.2 foxr 59:
60: # Initialization
61:
62: $perlvar = LONCAPA::Configuration::read_conf('loncapa.conf');
63:
64:
65: #------------------------------------------------------------------------
66: #
67: # Name BuildKey
68: # Description: Create an encryption key.
69: # Returns: The key.
70: #
71: sub CreateCipherKey {
72:
73: my $keylength;
74: my $binaryKey;
75: my $cipherkey;
76:
77: # we'll use the output of /dev/random to produce our key.
78: # On a system with decent entropy, this ought to be much more
79: # random than all the playing that used to be done to get a key.
80: #
81:
82: $keylength = IDEA::keysize();
83: open(RANDOM, "</dev/random");
84: sysread(RANDOM, $binaryKey, $keylength);
85: close RANDOM;
86:
87: # The key must be returned in a stringified form in order to be
88: # transmitted to the peer:
89:
90: my $hexdigits = $keylength*2; # Assume 8 bits/byte.
91: my $template = "H".$hexdigits;
92: $cipherkey = unpack($template, $binaryKey);
93:
94: return $cipherkey;
95: }
96:
97: #------------------------------------------------------------------------
98: #
99: # Name CreateKeyFile
100: # Description Creates a private key file and writes an IDEA key into it.
101: #
102: # Returns
103: # A two element list containing:
104: # - The private key that was created
105: # - The full path to the file that contains it.
1.3 ! foxr 106: # or undef on failure.
1.2 foxr 107: sub CreateKeyFile {
108:
109: # To create the file we need some perlvars to tell us where the
110: # certificate directory. We'll make a file named localkey.$pid
111: # there, and set the mode before writing into it.
112: #
1.3 ! foxr 113: $fileindex++;
! 114: my $CertificateDir = $perlvar->{lonCertificateDirectory};
! 115: my $Filename = $CertificateDir.$pathsep.".$fileindex.".$PID;
! 116:
! 117: # If this file already exists, this is a recoverable error... we just
! 118: # delete the earlier incarnation of the file.
! 119:
! 120: if (-w $Filename) {
! 121: unlink $Filename;
! 122: }
! 123:
! 124: # If the file still exists this is really really bad:
! 125: # It most likely means someone has been devious enough to drop a key file
! 126: # in place to attemp to spoof the lond. We'll fail in that case hoping
! 127: # that the user looks at the log to figure out that local connections
! 128: # are failing.
! 129:
! 130: if( -e $Filename) {
! 131: $lastError = "Key file already exists after deletion probably a spoof!";
! 132: return undef;
! 133: }
! 134: # Now we can create the file we use sysopen in order to ensure
! 135: # the file is created with the appropriate locked down permissions.
! 136:
! 137: if(! sysopen(KEYFILE, $Filename, O_CREAT | O_EXCL | O_WRONLY, 0600)) {
! 138: $lastError = "Creation of key file failed ".$ERRNO;
! 139: return undef;
! 140: }
! 141: # Create the key, write it to the file and close the file:
! 142:
! 143: my $key = CreateCipherKey();
! 144: print KEYFILE "$key\n";
! 145: close KEYFILE;
! 146:
! 147: return \($key, $Filename);
! 148:
1.2 foxr 149:
150: }
151:
152:
1.3 ! foxr 153: # Name ReadKeyFile
! 154: # Description Opens the private local key file and reads the IDEA key from it.
! 155: # Parameters
! 156: # Name Type Description
! 157: # Filename string path to key file
! 158: #
! 159: # NOTE:
! 160: # Reading the keyfile is a one-time thing. This sub destroys the
! 161: # keyfile after reading it to ensure the one-timedness of the keys they
! 162: # contain!!
! 163: # Returns
! 164: # On success the IDEA key that was written into the key fileon failure undef.
! 165: #
! 166: #
! 167: sub ReadKeyFile {
! 168: my $Filename = shift;
! 169:
! 170: if(! open(KEYFILE, "<$Filename")) {
! 171: $lastError = "Key file open failed";
! 172: return undef
! 173: }
! 174: my $key = <KEYFILE>;
! 175: chomp;
! 176: close KEYFILE;
! 177: unlink $Filename;
! 178: #
! 179: # If the filename still exists some spoofer wrote it with the wrong
! 180: # permissions:
! 181: #
! 182: if(-e $Filename) {
! 183: $lastError = "Key file still exists after unlink";
! 184: return undef;
! 185: }
! 186: #
! 187: # The IDEA key must be IDEA::keysize*2 characters
! 188: # long. If it isn't probably someone's trying to break us by
! 189: # hitting the timing hole between the file write and read...
! 190: # replacing our file... of course if they read this comment they'll
! 191: # be too smart to put an incorrectly sized file
! 192: #
! 193: if(length($key) != IDEA::keysize*2) {
! 194: $lastError = "Key file has incorrect length";
! 195: return undef;
! 196: }
! 197: return $key;
! 198: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>