Tweaked class comments in containerPanel
[ganymede.git] / webforms / ganypass.pl
blob30541228a2fd10898d28ede2ffe2db3e78e5f535
1 #!<##PERLEXE##>
2 #####################################################################
4 # Ganymede Password Changer
6 # This script is used to process the form in
9 # This script accepts a username, old password, new
10 # password and verified new password, then passes them
11 # to xmlclient, which attempts to change the Ganymede
12 # password for user from the old_pass to new_pass
14 #####################################################################
15 use CGI;
17 # add this for errors!!!
18 use CGI::Carp qw/fatalsToBrowser/;
20 #####################################################################
22 $minlength = 8;
24 $tmpdir = "/tmp";
25 $pass_advice = "<table><td>
26 <p>Characteristics of good passwords:</p>
28 <ul>
29 <li>easy to remember</li>
30 <li>$minlength characters long</li>
31 <li>not easily generated from a dictionary</li>
32 <li>contain at least one numeric, whitespace, or punctuation character</li>
33 <li>contain both uppercase and lowercase letters</li>
34 </ul>
35 </td></table>";
37 # create the query with whatever CGI info we get from our environment
39 $query = new CGI;
40 $my_url = $query->url();
41 $xml_path = "<#XMLPATH#>";
42 $xmlclient = $xml_path . "/xmlclient";
44 # Yes, the software is smarter than you, if you didn't include bin
45 # when installWeb asked you for the location of the client utils.
47 if (!-f $xmlclient) {
48 $xmlclient = $xml_path . "/bin/xmlclient";
51 # If this script is run from a different location from where the
52 # image files for the HTML result pages are located, the variable
53 # $web_loc must be changed to an HTTP path to the image files
55 $web_loc = ".";
57 # write out the CGI header
59 print $query->header;
61 print <<ENDSTARTHEAD;
62 <html>
63 <head>
64 <title>Ganymede Password Changer</title>
65 ENDSTARTHEAD
67 # Print Javascript basic form checker
68 JSVerifyForm();
70 print <<ENDHEAD;
72 </head>
73 <body bgcolor="#FFFFFF">
74 ENDHEAD
76 if (!-f $xmlclient) {
77 print "<center><p>Error, can't find xmlclient</p></center>\n";
78 print_tail();
79 print $query->end_html;
80 exit 0;
83 if ($query->param) {
84 $user = $query->param('user');
85 $old_pass = $query->param('old_pass');
86 $new_pass = $query->param('new_pass');
87 $verify = $query->param('verify');
89 if ($new_pass eq $verify) {
90 make_xml();
91 $xml_output = `$xmlclient $filename 2>&1`;
92 $xml_status = $? >> 8;
93 if (($xml_status == 0)) {
94 $time = `/bin/date`;
95 print_success();
96 } else {
97 # we need to make an error message more clear
98 if ($xml_output =~ /It is based on the dictionary word ([^.]*)/) {
99 $word = $1;
101 if ($word eq $user) {
102 $xml_output = "The new password you proposed was based on your username. You must choose a password that can not be easily guessed from your account's name.";
103 } else {
104 $xml_output = "The new password you proposed can be derived from the word '$1', so is too easily guessable by password cracking programs.\n\nPlease choose again.";
107 $loggedin_ok = 1;
108 } elsif ($xml_output =~ /is too short/) {
109 $xml_output = "The new password you proposed is too short.\nPick a password that is at least 6 characters long.";
111 $loggedin_ok = 1;
112 } elsif ($xml_output =~ /simplistic/) {
113 $xml_output = "The new password you proposed follows too predictable a pattern.\n\nPlease try to pick a more random password.";
115 $loggedin_ok = 1;
116 } elsif ($xml_output =~ /DIFFERENT/) {
117 $xml_output = "The new password you proposed does not contain enough different characters.\n\nPlease try to pick a more complex password.";
119 $loggedin_ok = 1;
120 } elsif ($xml_output =~ /used too recently/ && $xml_output =~ /last used with this account at ([^.]*)/) {
121 $xml_output = "The new password you proposed was used for this account at $1.\n\nYou must choose a password that has not been used in conjunction with this account recently.";
123 $loggedin_ok = 1;
124 } elsif ($xml_output =~ /It is based on your username/) {
125 $xml_output = "The new password you proposed was based on your username.\n\nYou must choose a password that can not be easily guessed from your account's name.";
127 $loggedin_ok = 1;
128 } elsif ($xml_output =~ /punctuation/) {
129 $xml_output = "Passwords must have at least one numeric, whitespace, or punctuation character.";
131 $loggedin_ok = 1;
132 } elsif ($xml_output =~ /It needs to be mixed case/) {
133 $xml_output = "Passwords must have at least one upper case and at least one lower case letter.";
135 $loggedin_ok = 1;
136 } elsif ($xml_output =~ /contains an unacceptable character \('([^'])'\)/) {
137 $xml_output = "The new password you proposed contains an unacceptable character: $1\n\nPlease try again.";
139 $loggedin_ok = 1;
140 } elsif ($xml_output =~ /semaphore disabled/) {
141 # Couldn't login to server... the server is going down for some reason?
142 # Can't login to the Ganymede server.. semaphore disabled: schema edit
143 # Error, couldn't log in to server.. bad username or password?
145 # XML submission failed.
147 $xml_output = "The Ganymede server is not currently accepting logins.\nPlease try again later.";
148 } elsif ($xml_output =~ /bad username/) {
149 # Couldn't login to server... bad username/password?
150 # Error, couldn't log in to server.. bad username or password?
151 # XML submission failed.
153 $xml_output = "You did not enter your current username and/or password correctly.\n\nPlease try again.";
156 print_failure($xml_output);
158 } else {
159 print_nomatch();
162 unlink $filename; #remove temp xml file
163 print_tail();
164 } else {
165 print_default();
168 print $query->end_html;
171 ######################################################################
173 # make_xml
175 ######################################################################
177 sub make_xml {
178 # we want a really random filename
180 $randnum = int(rand 4096);
182 $filename = "$tmpdir/ganypass.$randnum.$$.xml"; #give temp xml file random name
184 $old_pass =~ s/&/&amp;/g; #parse passwords for " and &, replace with xml equivalents
185 $new_pass =~ s/&/&amp;/g;
186 $old_pass =~ s/\"/&quot;/g;
187 $new_pass =~ s/\"/&quot;/g;
188 $old_pass =~ s/</&lt;/g;
189 $new_pass =~ s/</&lt;/g;
190 $old_pass =~ s/>/&gt;/g;
191 $new_pass =~ s/>/&gt;/g;
193 if (-f $filename) {
194 die "Error, $filename already exists!";
197 open(XMLF, ">$filename") || die "Couldn't write to $filename";
198 chmod 0600, $filename;
200 select XMLF;
201 print <<WRITEXML;
202 <ganymede major="1" minor="0" persona="$user" password="$old_pass">
203 <ganydata>
204 <object type="User" id="$user">
205 <Password><password plaintext="$new_pass"/></Password>
206 </object>
207 </ganydata>
208 </ganymede>
209 WRITEXML
211 close(XMLF);
212 chmod 0600, $filename;
213 select STDOUT;
216 ######################################################################
218 # print_default
220 ######################################################################
222 sub print_default {
224 print <<ENDDEFAULT;
225 <table border="0">
226 <tr>
227 <td align="left">
228 <a href="http://www.arlut.utexas.edu/gash2/"><img src="$web_loc/ganymede_title2_sm.gif" border="0"></a>
229 </td>
230 <td width="100%" align="center">
231 <h1>Ganymede Password Changing Utility</h1>
232 </td>
233 <!--
235 If you want a link to your home page, uncomment this and tweak
236 accordingly.
238 <td align="right">
239 <a href="/"><img src="$web_loc/arlbw.jpg" border="0"></a>
240 </td>
243 </tr>
245 <tr>
246 <td align="center">
247 <a href="http://www.arlut.utexas.edu/gash2/"><small>[Ganymede Home]</small></a>
248 </td>
249 <td width="100%" align="center">
250 <small>[Click <a href="$web_loc/index.html" target="_top">here</a>
251 to go directly to the Ganymede login page]</small>
252 </td>
254 <!--
256 If you want a link to your home page, uncomment this and tweak
257 accordingly.
259 <td align="center">
260 <a href="http://www.arlut.utexas.edu/"><small>[ARL:UT Home]</small></a>
261 </td>
264 </tr>
265 </table>
267 <hr noshade />
268 <center>
269 <table border="0" width="60%">
270 <tr>
272 <td align="center">
274 <!--
276 You need to change this as well, of course
280 <p>This form changes your user password for Ganymede and all network
281 services managed by Ganymede at ARL:UT.</p>
283 $pass_advice
285 <p>All use of this form is logged, and you will receive email from Ganymede
286 notifying you of the success of your password change request.</p>
287 </td>
288 </tr>
289 </table>
290 </center>
292 ENDDEFAULT
294 print_form();
296 print_tail();
299 ######################################################################
301 # print_form
303 ######################################################################
305 sub print_form
307 $minstrlen = length("$minlength");
308 $semispaces = "&nbsp;&nbsp;&nbsp;" . ("&nbsp;" x $minstrlen);
309 $spaces = ("&nbsp;" x $minstrlen) . $semispaces;
311 print <<ENDHTML
312 <script type="text/javascript">
313 var minlen = $minlength;
315 function create_limiteron(formName, elementName) {
316 return function()
318 var len1 = document.getElementById(formName).value.length;
320 if (len1 > minlen) {
321 document.getElementById(elementName).innerHTML = len1 + "$semispaces";
323 else {
324 if (len1 < 10 && minlen >= 10) {
325 document.getElementById(elementName).innerHTML = "&nbsp;" + len1 + " / " + minlen;
326 } else {
327 document.getElementById(elementName).innerHTML = len1 + " / " + minlen;
333 function create_limiteroff(elementName) {
334 return function()
336 document.getElementById(elementName).innerHTML = "$spaces";
340 var limiter = create_limiteron("new_pass", "counter");
341 var limiterOff = create_limiteroff("counter");
342 var limiter2 = create_limiteron("verify", "counter2");
343 var limiterOff2 = create_limiteroff("counter2");
345 </script>
347 <center>
348 <form method="post" action="$my_url" name="former">
349 <table width="60%" bgcolor="#ccffcc" border="1" cellpadding="2">
350 <tr bgcolor="#663366">
351 <td colspan="2" align="center">
352 <big><font color="ffffcc">Ganymede Password Changer</font></big>
353 </td>
354 </tr>
356 <tr>
357 <td align="right"><b>Username?</b></td>
358 <td><input type="text" name="user"></td>
359 </tr>
361 <tr>
362 <td align=right><b>Old Password?</b></td>
363 <td><input type="password" name="old_pass"></td>
364 </tr>
366 <tr>
367 <td align=right><b>New Password?</b> </td>
368 <td><input type="password" id="new_pass" name="new_pass" onKeyDown=limiter() onKeyUp=limiter() onFocus=limiter() onBlur=limiterOff()>
369 <pre style="display:inline"><div id="counter" style=display:inline>$spaces</div></pre> </td>
370 </tr>
372 <tr>
373 <td align=right><b>Verify New Password</b></td>
374 <td><input type="password" id="verify" name="verify" onKeyDown=limiter2() onKeyUp=limiter2() onFocus=limiter2() onBlur=limiterOff2()>
375 <pre style="display:inline"><div id="counter2" style=display:inline>$spaces</div></pre> </td>
376 </tr>
378 <tr>
379 <td colspan="2" align="center"><input type="button" value="submit" onClick="VerifyForm(document.former)"></td>
380 </tr>
382 <tr bgcolor="#663366">
383 <td colspan="2">&nbsp;</td>
384 </tr>
386 </table>
387 </form>
388 </center>
389 ENDHTML
393 ######################################################################
395 # print_success
397 ######################################################################
399 sub print_success {
400 print <<ENDSUCCESS;
401 <table border="0">
402 <tr>
403 <td align="left">
404 <a href="http://www.arlut.utexas.edu/gash2/"><img src="$web_loc/ganymede_title2_sm.gif" border="0"></a>
405 </td>
406 <td width="100%" align="center">
407 <h1>Password Changed Successfully</h1>
408 </td>
409 <td align="right">
410 <a href="/"><img src="/graphics/arlbw.jpg" border="0"></a>
411 </td>
412 </tr>
414 <tr>
415 <td align="center">
416 <a href="http://www.arlut.utexas.edu/gash2/"><small>[Ganymede Home]</small></a>
417 </td>
418 <td width="100%" align="center">
419 <small>[Click <a href="$web_loc/index.html" target="_top">here</a> to go directly to the Ganymede login page]</small>
420 </td>
421 <td align="center">
422 <a href="/"><small>[ARL:UT Home]</small></a>
423 </td>
424 </tr>
425 </table>
427 <hr noshade="noshade"/>
429 <center>
430 <table border="0" width="60%">
431 <tr>
432 <td align="center">
433 <p>Ganymede has accepted your password change
434 request, and is currently working to propagate your changed password
435 information into the network. It may take a few minutes for your new
436 password to take effect everywhere.</p>
438 <p>As additional confirmation, in a few moments you will receive a
439 mail message from Ganymede describing the change to your
440 account.</p>
441 </td>
442 </tr>
443 </table>
444 </center>
446 <br/>
448 <center>
449 <table width="60%" bgcolor="#ccffcc" border="1" cellpadding="2">
450 <tr bgcolor="#663366">
451 <td colspan="2" align="center">
452 <big><font color="ffffcc">Ganymede Password Changer</font></big>
453 </td>
454 </tr>
456 <tr><td colspan="2"><br/></td></tr>
458 <tr><td colspan="2" align="center">Time: $time</td></tr>
460 <tr><td colspan="2"><br/></td></tr>
462 <tr><td colspan="2" align="center">Password change request processed for user $user</td></tr>
464 <tr><td colspan="2"><br/></td></tr>
466 <tr bgcolor="663366">
467 <td colspan="2">&nbsp;</td>
468 </tr>
469 </table>
470 </center>
472 ENDSUCCESS
475 ######################################################################
477 # print_failure
479 ######################################################################
481 sub print_failure {
482 my ($failure) = @_;
484 $failure =~ s/</&lt;/g;
485 $failure =~ s/>/&gt;/g;
487 if (!$loggedin_ok) {
488 $about_mess = "<p>If your current password was not entered properly, you may receive
489 mail from Ganymede reporting a failure to login. This is normal, and
490 is simply letting you know that someone unsuccessfully attempted to
491 make a change in Ganymede on your behalf.</p>";
492 } else {
493 $about_mess = $pass_advice;
496 print <<ENDFAILURE;
497 <table border="0">
498 <tr>
499 <td align="left">
500 <a href="http://www.arlut.utexas.edu/gash2/"><img src="$web_loc/ganymede_title2_sm.gif" border="0"/></a>
501 </td>
502 <td width="100%" align="center">
503 <h1>Password not changed<br/>Check username and password</h1>
504 </td>
505 <td align="right">
506 <a href="/"><img src="$web_loc/graphics/arlbw.jpg" border="0"></a>
507 </td>
508 </tr>
510 <tr>
511 <td align="center">
512 <a href="http://www.arlut.utexas.edu/gash2/"><small>[Ganymede Home]</small></a>
513 </td>
514 <td width="100%" align="center">
515 <small>[Click <a href="$web_loc/index.html" target="_top">here</a> to go directly to the Ganymede login page]</small>
516 </td>
517 <td align="center">
518 <a href="/"><small>[ARL:UT Home]</small></a>
519 </td>
520 </tr>
521 </table>
523 <hr noshade="noshade"/>
525 <center>
527 <table border="0" width="60%">
528 <tr>
529 <td align="center">
530 <p>Ganymede was not able to accept your
531 password change request. The following error message was
532 reported:</p>
534 <font color="red"><pre>$failure</pre></font>
535 $about_mess
536 </td>
537 </tr>
538 </table>
540 <form method="POST" action="$my_url">
541 <table width="60%" bgcolor="#ccffcc" border="1" cellpadding="2">
542 <tr bgcolor="#663366">
543 <td colspan="2" align="center">
544 <big><font color="ffffcc">Ganymede Password Changer</font></big>
545 </td>
546 </tr>
548 <tr>
549 <td align="right"><b>Username?</b></td>
550 <td><input type="text" name="user" value="$user"></td>
551 </tr>
553 <tr>
554 <td align="right"><b>Old Password?</b></td>
555 <td><input type="password" name="old_pass"></td>
556 </tr>
558 <tr>
559 <td align="right"><b>New Password?</b></td>
560 <td><input type="password" name="new_pass"></td>
561 </tr>
563 <tr>
564 <td align="right"><b>Verify New Password</b></td>
565 <td><input type="password" name="verify"></td>
566 </tr>
568 <tr>
569 <td colspan="2" align="center"><input type="submit" value="SUBMIT"></td>
570 </tr>
572 <tr bgcolor="663366">
573 <td colspan="2">&nbsp;</td>
574 </tr>
575 </table>
576 </form>
577 </center>
579 ENDFAILURE
582 ######################################################################
584 # print_nomatch
586 ######################################################################
588 sub print_nomatch {
589 print <<ENDNOMATCH;
590 <table border="0">
591 <tr>
592 <td align="left">
593 <a href="http://www.arlut.utexas.edu/gash2/"><img src="$web_loc/ganymede_title2_sm.gif" border="0"/></a>
594 </td>
595 <td width="100%" align="center">
596 <h1>Password not changed<br/>password verification failed</h1>
597 </td>
598 <td align="right">
599 <a href="/"><img src="$web_loc/arlbw.jpg" border="0"></a>
600 </td>
601 </tr>
603 <tr>
604 <td align="center">
605 <a href="http://www.arlut.utexas.edu/gash2/"><small>[Ganymede Home]</small></A>
606 </td>
607 <td width="100%" align="center">
608 <small>[Click <a href="$web_loc/index.html" target="_top">here</a> to go directly to the Ganymede login page]</small>
609 </td>
610 <td align="center">
611 <a href="/"><small>[ARL:UT Home]</small></a>
612 </td>
613 </tr>
614 </table>
616 <hr noshade="noshade"/>
618 <center>
619 <table border="0" width="60%">
620 <tr>
621 <td align="center">
622 <p>Ganymede was not able to accept your
623 password change request. You did not enter your new password
624 consistently. Please try again.</p>
625 </td>
626 </tr>
627 </table>
629 <form method="POST" action="$my_url">
630 <table width="60%" bgcolor="#ccffcc" border="1" cellpadding="2">
631 <tr bgcolor="#663366">
632 <td colspan="2" align="center">
633 <big><font color="ffffcc">Ganymede Password Changer</font></big>
634 </td>
635 </tr>
637 <tr>
638 <td align="right"><b>Username?</b></td>
639 <td><input type="text" name="user" value="$user"></td>
640 </tr>
642 <tr>
643 <td align="right"><b>Old Password?</b></td>
644 <td><input type="password" name="old_pass"></td>
645 </tr>
647 <tr>
648 <td align="right"><b>New Password?</b></td>
649 <td><input type="password" name="new_pass"></td>
650 </tr>
652 <tr>
653 <td align="right"><b>Verify New Password</b></td>
654 <td><input type="password" name="verify"></td>
655 </tr>
657 <tr>
658 <td colspan="2" align="center"><input type="submit" value="SUBMIT"></td>
659 </tr>
661 <tr bgcolor="663366">
662 <td colspan="2">&nbsp;</td>
663 </tr>
665 </table>
666 </form>
667 </center>
668 ENDNOMATCH
671 ######################################################################
673 # print_tail
675 ######################################################################
677 sub print_tail {
678 print <<END;
679 <hr noshade>
680 <a href="mailto:webmaster\@arlut.utexas.edu">webmaster\@arlut.utexas.edu</a><P>
684 ######################################################################
686 # JSVerifyForm
688 # Javascript basic form checker
689 ######################################################################
690 sub JSVerifyForm()
692 print <<ENDVERIFY;
693 <script>
694 // Verify All Users in the form
695 function VerifyForm(former)
697 if (former.user.value == '') { alert('Please fill in the Username item before submitting'); former.user.focus(); return 0; }
698 if (former.old_pass.value == '') { alert('Please fill in the Old Password item before submitting'); former.old_pass.focus(); return 0; }
699 if (former.new_pass.value == '') { alert('Please fill in the New Password item before submitting'); former.new_pass.focus(); return 0; }
700 if (former.new_pass.value != former.verify.value) { alert('The new and verify passwords do not match, please update before submitting'); former.new_pass.focus(); return 0; }
702 // submit form now
703 former.submit();
704 } // VerifyForm
705 </script>
706 ENDVERIFY