File:
[LON-CAPA] /
loncom /
interface /
lonpreferences.pm
Revision
1.3:
download - view:
text,
annotated -
select for diffs
Fri Feb 15 22:04:39 2002 UTC (22 years, 4 months ago) by
matthew
Branches:
MAIN
CVS tags:
HEAD
Commit of working but not complete code, in case my machine crashes over the
weekend. I've put too much effort into this javascript that I don't want to
take any chances. Can now attempt to change password. More changes will be
forthcoming.
1: # The LearningOnline Network
2: # Preferences
3: #
4: # $Id: lonpreferences.pm,v 1.3 2002/02/15 22:04:39 matthew Exp $
5: #
6: # Copyright Michigan State University Board of Trustees
7: #
8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
9: #
10: # LON-CAPA is free software; you can redistribute it and/or modify
11: # it under the terms of the GNU General Public License as published by
12: # the Free Software Foundation; either version 2 of the License, or
13: # (at your option) any later version.
14: #
15: # LON-CAPA is distributed in the hope that it will be useful,
16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18: # GNU General Public License for more details.
19: #
20: # You should have received a copy of the GNU General Public License
21: # along with LON-CAPA; if not, write to the Free Software
22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23: #
24: # /home/httpd/html/adm/gpl.txt
25: #
26: # http://www.lon-capa.org/
27: #
28: # (Internal Server Error Handler
29: #
30: # (Login Screen
31: # 5/21/99,5/22,5/25,5/26,5/31,6/2,6/10,7/12,7/14,
32: # 1/14/00,5/29,5/30,6/1,6/29,7/1,11/9 Gerd Kortemeyer)
33: #
34: # 3/1/1 Gerd Kortemeyer)
35: #
36: # 3/1 Gerd Kortemeyer
37: #
38: # 2/13/02 2/14 2/15 Matthew Hall
39: #
40: # This package uses the "londes.js" javascript code.
41: #
42: # TODOs that have to be completed:
43: # interface with lonnet to change the password
44:
45: package Apache::lonpreferences;
46:
47: use strict;
48: use Apache::Constants qw(:common);
49: use Apache::File;
50: use Crypt::DES;
51: use DynaLoader; # for Crypt::DES version
52:
53: #------------------- forms to be output
54: my $passwordform =<<ENDPASSWORDFORM;
55: <form name="client" action="/adm/preferences" method="post">
56: <input type="hidden" name="action" value="changepass">
57: <input type="submit" value="Change password">
58: </form>
59: ENDPASSWORDFORM
60:
61: my $environmentform = <<ENDENVIRONMENTFORM;
62: <p>
63: There are currently no environment variables you can change.
64: </p>
65: <!----
66: You may set the following environment variables:
67: <table>
68: <tr><th>Environment Setting</th><th>Current Value</th></tr>
69: <tr>
70: <td colspan="2">
71: <font color="#ff0000">No variables currently set up</font>
72: </td>
73: </tr>
74: </table>
75: -->
76: ENDENVIRONMENTFORM
77: #------------------ end of forms to be output
78:
79: ################################################################
80: # Handler subroutines #
81: ################################################################
82: #
83: # Write lonnet::passwd to do the call below.
84: # Use:
85: # my $answer=reply("encrypt:passwd:$udom:$uname:$upass",$tryserver);
86: #
87: # I really should write some javascript to check on the client side for
88: # mismatched passwords, but other problems are more pressing
89: #
90: ##################################################
91: # password associated functions #
92: ##################################################
93: sub des_keys {
94: # Make a new key for DES encryption
95: # Each key has two parts which are returned seperately
96: my @hexstr=('0','1','2','3','4','5','6','7',
97: '8','9','a','b','c','d','e','f');
98: my $lkey='';
99: for (0..7) {
100: $lkey.=$hexstr[rand(15)];
101: }
102: my $ukey='';
103: for (0..7) {
104: $ukey.=$hexstr[rand(15)];
105: }
106: return ($lkey,$ukey);
107: }
108:
109: sub des_decrypt {
110: my ($key,$cyphertext) = @_;
111: my $keybin=pack("H16",$key);
112: my $cypher;
113: if ($Crypt::DES::VERSION>=2.03) {
114: $cypher=new Crypt::DES $keybin;
115: } else {
116: $cypher=new DES $keybin;
117: }
118: my $plaintext=
119: $cypher->decrypt(unpack("a8",pack("H16",substr($cyphertext,0,16))));
120: $plaintext.=
121: $cypher->decrypt(unpack("a8",pack("H16",substr($cyphertext,16,16))));
122: $plaintext=unpack("a8",$plaintext);
123: $plaintext=substr($plaintext,1,ord(substr($plaintext,0,1)));
124: unpack("a8",$plaintext);
125: return $plaintext;
126: }
127:
128: sub passwordchanger {
129: # Passwords are encrypted using londes.js (DES encryption)
130: #
131: my $r = shift;
132: my $user = $ENV{'user.name'};
133: my $domain = $ENV{'user.domain'};
134: my $homeserver = $ENV{'user.home'};
135: my $currentauth=&Apache::lonnet::queryauthenticate($user,$domain);
136: # Check for authentication types that allow changing of the password.
137: return if ($currentauth !~ /^(unix|internal):/);
138: #
139: # Generate keys
140: my ($lkey_cpass ,$ukey_cpass ) = &des_keys();
141: my ($lkey_npass1,$ukey_npass1) = &des_keys();
142: my ($lkey_npass2,$ukey_npass2) = &des_keys();
143: # Store the keys
144: my $lonhost = $r->dir_config('lonHostID');
145: my $logtoken=Apache::lonnet::reply('tmpput:'
146: .$ukey_cpass . $lkey_cpass .'&'
147: .$ukey_npass1 . $lkey_npass1.'&'
148: .$ukey_npass2 . $lkey_npass2,
149: $lonhost);
150: # Hexify these keys
151: $ukey_cpass = hex($ukey_cpass);
152: $lkey_cpass = hex($lkey_cpass);
153: $ukey_npass1= hex($ukey_npass1);
154: $lkey_npass1= hex($lkey_npass1);
155: $ukey_npass2= hex($ukey_npass2);
156: $lkey_npass2= hex($lkey_npass2);
157: # Output javascript to deal with passwords
158: $r->print(<<ENDHEADER);
159: <html>
160: <head>
161: <title>The LearningOnline Network with CAPA</title>
162: </head>
163: ENDHEADER
164: # Output DES javascript
165: {
166: my $include = $r->dir_config('lonIncludes');
167: my $jsh=Apache::File->new($include."/londes.js");
168: $r->print(<$jsh>);
169: }
170: $r->print(<<ENDFORM);
171:
172: <body bgcolor="#FFFFFF" onLoad="init();">
173:
174: <script language="JavaScript">
175:
176: function send() {
177: uextkey=this.document.client.elements.ukey_cpass.value;
178: lextkey=this.document.client.elements.lkey_cpass.value;
179: initkeys();
180:
181: this.document.server.elements.currentpass.value
182: =crypted(this.document.client.elements.currentpass.value);
183:
184: uextkey=this.document.client.elements.ukey_npass1.value;
185: lextkey=this.document.client.elements.lkey_npass1.value;
186: initkeys();
187: this.document.server.elements.newpass_1.value
188: =crypted(this.document.client.elements.newpass_1.value);
189:
190: uextkey=this.document.client.elements.ukey_npass2.value;
191: lextkey=this.document.client.elements.lkey_npass2.value;
192: initkeys();
193: this.document.server.elements.newpass_2.value
194: =crypted(this.document.client.elements.newpass_2.value);
195:
196: this.document.server.submit();
197: }
198:
199: </script>
200: <h1>Preferences for $user</h1>
201: <h3>$user is a member of domain $domain</h3>
202: <p>
203: Change password for $user
204: </p>
205: <p>
206: <!-- We seperate the forms into 'server' and 'client' in order to
207: ensure that unencrypted passwords will not be sent out by a
208: crappy browser -->
209:
210: <form name="server" action="/adm/preferences" method="post">
211: <input type="hidden" name="logtoken" value="$logtoken" />
212: <input type="hidden" name="action" value="verify_and_change_pass" />
213: <input type="hidden" name="currentpass" value="" />
214: <input type="hidden" name="newpass_1" value="" />
215: <input type="hidden" name="newpass_2" value="" />
216: </form>
217:
218: <form name="client" >
219: <table>
220: <tr><td align="right"> Current password: </td>
221: <td><input type="password" name="currentpass" /> </td></tr>
222: <tr><td align="right"> New password: </td>
223: <td><input type="password" name="newpass_1" /> </td></tr>
224: <tr><td align="right"> Confirm password: </td>
225: <td><input type="password" name="newpass_2" /> </td></tr>
226: <tr><td colspan="2" align="center">
227: <input type="button" value="Change Password" onClick="send();">
228: </table>
229: <input type="hidden" name="ukey_cpass" value="$ukey_cpass" />
230: <input type="hidden" name="lkey_cpass" value="$lkey_cpass" />
231: <input type="hidden" name="ukey_npass1" value="$ukey_npass1" />
232: <input type="hidden" name="lkey_npass1" value="$lkey_npass1" />
233: <input type="hidden" name="ukey_npass2" value="$ukey_npass2" />
234: <input type="hidden" name="lkey_npass2" value="$lkey_npass2" />
235: </form>
236: </p>
237: ENDFORM
238: #
239: return;
240: }
241:
242: sub verify_and_change_password {
243: my $r = shift;
244: my $user = $ENV{'user.name'};
245: my $domain = $ENV{'user.domain'};
246: my $homeserver = $ENV{'user.home'};
247: my $currentauth=&Apache::lonnet::queryauthenticate($user,$domain);
248: #
249: $r->print("<h1>verify and change password</h1>\n");
250: #
251: my $currentpass = $ENV{'form.currentpass'};
252: my $newpass1 = $ENV{'form.newpass_1'};
253: my $newpass2 = $ENV{'form.newpass_2'};
254: my $logtoken = $ENV{'form.logtoken'};
255: # Check for empty data
256: if (!(defined($currentpass) &&
257: defined($newpass1) &&
258: defined($newpass2))){
259: $r->print("<font color='#ff0000'>ERROR</font> Password data was ".
260: "blank.\n");
261: return;
262: }
263: # Get the keys
264: my $lonhost = $r->dir_config('lonHostID');
265: my $tmpinfo = Apache::lonnet::reply('tmpget:'.$logtoken,$lonhost);
266: if (($tmpinfo=~/^error/) || ($tmpinfo eq 'con_lost')) {
267: $r->print(<<ENDERROR);
268: <p>
269: <font color="#ff0000">ERROR:</font> Unable to retrieve stored token for
270: password decryption.
271: </p>
272: ENDERROR
273: return;
274: }
275: my ($ckey,$n1key,$n2key)=split(/&/,$tmpinfo);
276: # decrypt
277: my $currentpass = &des_decrypt($ckey ,$currentpass);
278: my $newpass1 = &des_decrypt($n1key,$newpass1);
279: my $newpass2 = &des_decrypt($n2key,$newpass2);
280: # Sanity check
281: if ($newpass1 ne $newpass2) {
282: $r->print('<font color="#ff0000">ERROR:</font>The new passwords you '.
283: 'entered do not match. Please try again.');
284: &passwordchanger($r);
285: return;
286: }
287: }
288:
289: ################################################################
290: # Main handler #
291: ################################################################
292: sub handler {
293: my $r = shift;
294: my $user = $ENV{'user.name'};
295: my $domain = $ENV{'user.domain'};
296: $r->content_type('text/html');
297: $r->send_http_header;
298: return OK if $r->header_only;
299: # Spit out the header
300: if ($ENV{'form.action'} eq 'changepass') {
301: &passwordchanger($r);
302: } elsif ($ENV{'form.action'} eq 'verify_and_change_pass') {
303: &verify_and_change_password($r);
304: } else {
305: $r->print(<<ENDHEADER);
306: <html>
307: <head>
308: <title>The LearningOnline Network with CAPA</title>
309: </head>
310: <body bgcolor="#FFFFFF" >
311: <h1>Preferences for $user</h1>
312: <h3>$user is a member of domain $domain</h3>
313: ENDHEADER
314: # Determine current authentication method
315: my $currentauth=&Apache::lonnet::queryauthenticate($user,$domain);
316: if ($currentauth =~ /^(unix|internal):/) {
317: $r->print($passwordform);
318: }
319: $r->print($environmentform);
320: }
321: # Spit out the footer
322: $r->print(<<ENDFOOTER);
323: </body>
324: </html>
325: ENDFOOTER
326: return OK;
327: }
328:
329: 1;
330: __END__
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>