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