Annotation of loncom/auth/lonauth.pm, revision 1.60

1.1       albertel    1: # The LearningOnline Network
                      2: # User Authentication Module
1.27      www         3: #
1.60    ! www         4: # $Id: lonauth.pm,v 1.59 2003/11/12 16:55:40 www Exp $
1.27      www         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: #
1.2       www        28: # 5/21/99,5/22,5/25,5/26,5/27,5/29,6/2,6/11,6/14,6/15
1.4       www        29: # 16/11,12/16,
1.9       www        30: # 1/14,2/24,2/28,2/29,3/7,5/29,5/30,5/31,6/1,6/5,6/29,
1.19      www        31: # 7/1,7/10,10/2,10/5,10/9,10/26,10/30,11/10,
                     32: # 05/28,05/29 Gerd Kortemeyer
1.22      www        33: # 07/28,08/03 Gerd Kortemeyer
1.24      www        34: # 8/20 Gerd Kortemeyer
1.1       albertel   35: 
                     36: package Apache::lonauth;
                     37: 
1.18      albertel   38: use strict;
1.1       albertel   39: use Apache::Constants qw(:common);
                     40: use Apache::File;
                     41: use CGI qw(:standard);
                     42: use CGI::Cookie();
1.26      harris41   43: use DynaLoader; # for Crypt::DES version
1.8       www        44: use Crypt::DES;
1.45      matthew    45: use Apache::loncommon();
1.1       albertel   46: use Apache::lonnet();
1.12      www        47: use Apache::lonmenu();
1.18      albertel   48: use Fcntl qw(:flock);
1.56      www        49: use Apache::lonlocal;
1.37      www        50: 
                     51: my %FORM;
                     52: 
1.1       albertel   53: # ------------------------------------------------------------ Successful login
                     54: 
                     55: sub success {
1.6       www        56:     my ($r, $username, $domain, $authhost,$lowerurl) = @_;
1.1       albertel   57:     my $lonids=$r->dir_config('lonIDsDir');
1.4       www        58: 
                     59: # See if old ID present, if so, remove
1.17      www        60: 
                     61:     my $filename;
                     62:     opendir(DIR,$lonids);
                     63:     while ($filename=readdir(DIR)) {
                     64:        if ($filename=~/^$username\_\d+\_$domain\_$authhost\.id$/) {
                     65: 	  unlink($lonids.'/'.$filename);
                     66:        }
1.4       www        67:     }
1.17      www        68:     closedir(DIR);
1.4       www        69: 
                     70: # Give them a new cookie
                     71: 
1.17      www        72:     my $cookie;
1.5       www        73:     my $now=time;
                     74:     $cookie="$username\_$now\_$domain\_$authhost";
                     75: 
                     76: # Initialize roles
                     77: 
                     78:     my $userroles=Apache::lonnet::rolesinit($domain,$username,$authhost);
                     79: 
1.7       www        80: # ------------------------------------ Check browser type and MathML capability
1.6       www        81: 
1.45      matthew    82:     my ($httpbrowser,$clientbrowser,$clientversion,$clientmathml,
                     83:         $clientunicode,$clientos) = &Apache::loncommon::decode_user_agent($r);
1.6       www        84: 
1.40      www        85: # -------------------------------------- Any accessibility options to remember?
                     86:     if (($FORM{'interface'}) && ($FORM{'remember'} eq 'true')) {
1.41      albertel   87: 	foreach ('imagesuppress','appletsuppress',
                     88: 		 'embedsuppress','fontenhance','blackwhite') {
                     89: 	    if ($FORM{$_} eq 'true') {
                     90: 		&Apache::lonnet::put('environment',{$_ => 'on'},
                     91: 				     $domain,$username);
                     92: 	    } else {
                     93: 		&Apache::lonnet::del('environment',[$_],$domain,$username);
                     94: 	    }
                     95: 	}
                     96:     }
1.11      www        97: # ------------------------------------------------------------- Get environment
                     98: 
1.32      albertel   99:     my $userenv;
                    100:     my %userenv=Apache::lonnet::dump('environment',$domain,$username);
                    101:     my ($tmp) = keys(%userenv);
                    102:     if ($tmp !~ /^(con_lost|error|no_such_host)/i) {
                    103: 	foreach my $key (keys(%userenv)) {
                    104: 	    $userenv.="environment.$key=$userenv{$key}\n";
                    105: 	}
1.11      www       106:     }
1.38      www       107:     if (($userenv{'interface'}) && (!$FORM{'interface'})) {
                    108: 	$FORM{'interface'}=$userenv{'interface'};
                    109:     }
1.47      www       110:     $ENV{'environment.remote'}=$userenv{'remote'};
1.54      www       111: # --------------- Do not trust query string to be put directly into environment
                    112:     foreach ('imagesuppress','appletsuppress',
                    113: 	     'embedsuppress','fontenhance','blackwhite',
                    114: 	     'interface','localpath','localres') {
                    115: 	$FORM{$_}=~s/[\n\r\=]//gs;
                    116:     }
1.7       www       117: # --------------------------------------------------------- Write first profile
1.5       www       118: 
1.41      albertel  119:     {
                    120: 	my $idf=Apache::File->new(">$lonids/$cookie.id");
                    121: 	unless (flock($idf,LOCK_EX)) {
                    122: 	    &Apache::lonnet::logthis("<font color=blue>WARNING: ".
                    123: 			   'Could not obtain exclusive lock in lonauth: '.$!);
                    124: 	    $idf->close();
                    125: 	    return 'error: '.$!;
                    126: 	}
                    127: 	if ($userenv ne '') { print $idf "$userenv\n"; }
                    128: 	print $idf "user.name=$username\n";
                    129: 	print $idf "user.domain=$domain\n";
                    130: 	print $idf "user.home=$authhost\n";
                    131: 	print $idf "browser.type=$clientbrowser\n";
                    132: 	print $idf "browser.version=$clientversion\n";
                    133: 	print $idf "browser.mathml=$clientmathml\n";
                    134: 	print $idf "browser.unicode=$clientunicode\n";
                    135: 	print $idf "browser.os=$clientos\n";
1.53      www       136:         if ($FORM{'localpath'}) {
                    137:            print $idf "browser.localpath=$FORM{'localpath'}\n";
                    138:            print $idf "browser.localres=$FORM{'localres'}\n";
                    139:         }
1.41      albertel  140: 	print $idf "request.course.fn=\n";
                    141: 	print $idf "request.course.uri=\n";
                    142: 	print $idf "request.course.sec=\n";
                    143: 	print $idf "request.role=cm\n";
1.48      www       144:         print $idf "request.role.adv=$ENV{'user.adv'}\n";
1.42      www       145: 	print $idf "request.host=$ENV{'REMOTE_ADDR'}\n";
1.41      albertel  146: 	if ($FORM{'interface'}) {
                    147: 	    $FORM{'interface'}=~s/\W//gs;
                    148: 	    print $idf "browser.interface=$FORM{'interface'}\n";
                    149: 	    $ENV{'browser.interface'}=$FORM{'interface'};
                    150: 	    foreach ('imagesuppress','appletsuppress',
                    151: 		     'embedsuppress','fontenhance','blackwhite') {
                    152: 		if (($FORM{$_} eq 'true') ||
                    153: 		    ($userenv{$_} eq 'on')) {
                    154: 		    print $idf "browser.$_=on\n";
                    155: 		}
1.18      albertel  156: 	    }
1.41      albertel  157: 	}
                    158: 	if ($userroles ne '') { print $idf "$userroles"; }
                    159: 	$idf->close();
                    160:     }
                    161:     $ENV{'request.role'}='cm';
1.48      www       162:     $ENV{'request.role.adv'}=$ENV{'user.adv'};
1.41      albertel  163:     $ENV{'browser.type'}=$clientbrowser;
1.7       www       164: # -------------------------------------------------------------------- Log this
                    165: 
                    166:     &Apache::lonnet::log($domain,$username,$authhost,
                    167:                          "Login $ENV{'REMOTE_ADDR'}");
1.4       www       168: 
1.14      www       169: # ------------------------------------------------- Check for critical messages
                    170: 
1.21      www       171:     my @what=&Apache::lonnet::dump('critical',$domain,$username);
1.14      www       172:     if ($what[0]) {
1.22      www       173: 	if (($what[0] ne 'con_lost') && ($what[0]!~/^error\:/)) {
1.21      www       174: 	    $lowerurl='/adm/email?critical=display';
1.14      www       175:         }
                    176:     }
                    177: 
1.5       www       178: # ------------------------------------------------------------ Get cookie ready
                    179: 
1.1       albertel  180:     $cookie="lonID=$cookie; path=/";
1.12      www       181: # -------------------------------------------------------- Menu script and info
1.31      www       182:     my $windowinfo=&Apache::lonmenu::open($clientos);
1.35      www       183:     my $startupremote=&Apache::lonmenu::startupremote($lowerurl);
                    184:     my $setflags=&Apache::lonmenu::setflags();
                    185:     my $maincall=&Apache::lonmenu::maincall();
1.52      www       186:     my $bodytag=&Apache::loncommon::bodytag('Successful Login');
1.60    ! www       187:     my $add=&addcontent();
1.5       www       188: # ------------------------------------------------- Output for successful login
                    189: 
1.1       albertel  190:     $r->send_cgi_header(<<ENDHEADER);
1.60    ! www       191: Content-type: text/html$add
1.1       albertel  192: Set-cookie: $cookie
                    193: 
                    194: ENDHEADER
1.58      www       195:     my %lt=&Apache::lonlocal::texthash(
                    196: 				       'wel' => 'Welcome',
                    197: 				       'mes' => 'Welcome to the Learning<i>Online</i> Network with CAPA. Please wait while your session is being set up',
                    198: 				       'pro' => 'Problems',
                    199: 				       'log' => 'loginproblems.html',
                    200: 				       );
1.1       albertel  201:     $r->print(<<ENDSUCCESS);
                    202: <html>
                    203: <head>
1.4       www       204: <title>Successful Login to the LearningOnline Network with CAPA</title>
1.35      www       205: $startupremote
1.1       albertel  206: </head>
1.43      www       207: $bodytag
1.35      www       208: $setflags
1.19      www       209: $windowinfo
1.58      www       210: <h1>$lt{'wel'}</h1>
                    211: $lt{'mes'}.<p>
                    212: <a href="/adm/$lt{'log'}">$lt{'pro'}?</a></p>
1.35      www       213: $maincall
1.6       www       214: </body>
1.1       albertel  215: </html>
                    216: ENDSUCCESS
                    217: }
                    218: 
                    219: # --------------------------------------------------------------- Failed login!
                    220: 
                    221: sub failed {
                    222:     my ($r,$message) = @_;
1.52      www       223:     my $bodytag=&Apache::loncommon::bodytag('Unsuccessful Login');
1.60    ! www       224:     my $add=&addcontent();
1.1       albertel  225:     $r->send_cgi_header(<<ENDFHEADER);
1.60    ! www       226: Content-type: text/html$add
1.1       albertel  227: 
                    228: ENDFHEADER
                    229:     $r->print(<<ENDFAILED);
                    230: <html>
                    231: <head>
1.4       www       232: <title>Unsuccessful Login to the LearningOnline Network with CAPA</title>
1.1       albertel  233: </head>
                    234: <html>
1.43      www       235: $bodytag
1.1       albertel  236: <h1>Sorry ...</h1>
1.43      www       237: <p><b>$message</b></p>
1.46      matthew   238: <p>Please <a href="/adm/login?username=$FORM{'uname'}&domain=$FORM{'udom'}">log in again</a>.</p>
1.43      www       239: <p>
                    240: <a href="/adm/loginproblems.html">Problems?</a></p>
1.1       albertel  241: </body>
                    242: </html>
                    243: ENDFAILED
1.60    ! www       244: }
        !           245: 
        !           246: # --------------------------------------------------------------------- Charset
        !           247: 
        !           248: sub addcontent {
        !           249:     my $encoding=&Apache::lonlocal::current_encoding;
        !           250:     if ($encoding) {
        !           251: 	return '; charset='.$encoding;
        !           252:     } else {
        !           253: 	return '';
        !           254:     }
1.1       albertel  255: }
                    256: 
1.55      www       257: # ------------------------------------------------------------------ Rerouting!
                    258: 
                    259: sub reroute {
                    260:     my $r=shift;
                    261:     my $bodytag=&Apache::loncommon::bodytag('Rerouting');
                    262:     $r->send_cgi_header(<<ENDRFHEADER);
                    263: Content-type: text/html
                    264: 
                    265: ENDRFHEADER
                    266:     $r->print(<<ENDRFAILED);
                    267: <html>
                    268: <head>
                    269: <title>Rerouting Login to the LearningOnline Network with CAPA</title>
                    270: </head>
                    271: <html>
                    272: $bodytag
                    273: <h1>Sorry ...</h1>
                    274: Please <a href="/">log in again</a>.
                    275: </body>
                    276: </html>
                    277: ENDRFAILED
                    278: }
                    279: 
1.1       albertel  280: # ---------------------------------------------------------------- Main handler
                    281: 
                    282: sub handler {
                    283:     my $r = shift;
1.55      www       284: 
                    285: # Are we re-routing?
                    286:     if (-e '/home/httpd/html/lon-status/reroute.txt') {
                    287: 	&reroute($r);
                    288: 	return OK;
                    289:     }
1.56      www       290: 
1.57      www       291:     &Apache::lonlocal::get_language_handle($r);
1.1       albertel  292: 
1.59      www       293: # -------------------------------- Prevent users from attempting to login twice
                    294:     my %cookies=CGI::Cookie->parse($r->header_in('Cookie'));
                    295:     my $lonid=$cookies{'lonID'};
                    296:     my $cookie;
                    297:     if ($lonid) {
                    298: 	my $handle=$lonid->value;
                    299:         $handle=~s/\W//g;
                    300:         my $lonidsdir=$r->dir_config('lonIDsDir');
                    301:         if ((-e "$lonidsdir/$handle.id") && ($handle ne '')) {
                    302: # Indeed, a valid token is found
                    303: 	    $r->send_cgi_header(<<ENDFHEADER);
                    304: Content-type: text/html
                    305: 
                    306: ENDFHEADER
                    307: 	    my $bodytag=&Apache::loncommon::bodytag('Already logged in');
                    308: 	    $r->print(<<ENDFAILED);
                    309: <html>
                    310: <head>
                    311: <title>Already logged in</title>
                    312: </head>
                    313: <html>
                    314: $bodytag
                    315: <h1>You are already logged in</h1>
                    316: <p>Please either <a href="/adm/roles">continue the current session</a> or
                    317: <a href="/adm/logout">logout</a>.</p>
                    318: <p>
                    319: <a href="/adm/loginproblems.html">Problems?</a></p>
                    320: </body>
                    321: </html>
                    322: ENDFAILED
                    323:            return OK;
                    324: 	}
                    325:     }
                    326: 
                    327: # ---------------------------------------------------- No valid token, continue
                    328: 
                    329: 
1.1       albertel  330:     my $buffer;
1.49      albertel  331:     $r->read($buffer,$r->header_in('Content-length'),0);
1.1       albertel  332:     my @pairs=split(/&/,$buffer);
1.37      www       333:     my $pair; my $name; my $value;
                    334:     undef %FORM;
                    335:     %FORM=();
1.1       albertel  336:     foreach $pair (@pairs) {
                    337:        ($name,$value) = split(/=/,$pair);
1.7       www       338:        $value =~ tr/+/ /;
                    339:        $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
1.1       albertel  340:        $FORM{$name}=$value;
                    341:     } 
                    342: 
                    343:     if ((!$FORM{'uname'}) || (!$FORM{'upass'}) || (!$FORM{'udom'})) {
1.43      www       344: 	failed($r,'Username, password and domain need to be specified.');
1.1       albertel  345:         return OK;
                    346:     }
                    347:     $FORM{'uname'} =~ s/\W//g;
                    348:     $FORM{'udom'}  =~ s/\W//g;
                    349: 
                    350:     my $role   = $r->dir_config('lonRole');
                    351:     my $domain = $r->dir_config('lonDefDomain');
                    352:     my $prodir = $r->dir_config('lonUsersDir');
                    353: 
1.8       www       354: # ---------------------------------------- Get the information from login token
                    355: 
                    356:     my $tmpinfo=Apache::lonnet::reply('tmpget:'.$FORM{'logtoken'},
                    357:                                       $FORM{'serverid'});
                    358: 
                    359:     if (($tmpinfo=~/^error/) || ($tmpinfo eq 'con_lost')) {
1.43      www       360: 	failed($r,'Information needed to verify your login information is missing, inaccessible or expired.');
1.8       www       361:         return OK;
1.44      www       362:     } else {
                    363:         unless (&Apache::lonnet::reply('tmpdel:'.$FORM{'logtoken'},
                    364:                                          $FORM{'serverid'}) eq 'ok') {
                    365:             &failed($r,'Session could not be opened.');
                    366: 	}
1.8       www       367:     }
1.9       www       368:     my ($key,$firsturl)=split(/&/,$tmpinfo);
1.8       www       369: 
                    370:     my $keybin=pack("H16",$key);
                    371: 
1.26      harris41  372:     my $cipher;
                    373:     if ($Crypt::DES::VERSION>=2.03) {
                    374: 	$cipher=new Crypt::DES $keybin;
                    375:     }
                    376:     else {
                    377: 	$cipher=new DES $keybin;
                    378:     }
1.8       www       379: 
                    380:     my $upass=$cipher->decrypt(
                    381:        unpack("a8",pack("H16",substr($FORM{'upass'},0,16))));
                    382: 
                    383:     $upass.=$cipher->decrypt(
                    384:        unpack("a8",pack("H16",substr($FORM{'upass'},16,16))));
                    385: 
                    386:     $upass=substr($upass,1,ord(substr($upass,0,1)));
                    387: 
1.1       albertel  388: # ---------------------------------------------------------------- Authenticate
                    389:     my $authhost=Apache::lonnet::authenticate($FORM{'uname'},
1.8       www       390:                                               $upass,
1.1       albertel  391:                                               $FORM{'udom'});
                    392:     
                    393: # --------------------------------------------------------------------- Failed?
                    394: 
                    395:     if ($authhost eq 'no_host') {
1.43      www       396: 	failed($r,'Username and/or password could not be authenticated.');
1.1       albertel  397:         return OK;
                    398:     }
                    399: 
1.59      www       400:     if (($firsturl eq '') || 
                    401: 	($firsturl=~/^\/adm\/(logout|remote)/)) {
1.24      www       402: 	$firsturl='/adm/roles';
1.7       www       403:     }
1.1       albertel  404: 
1.8       www       405:     success($r,$FORM{'uname'},$FORM{'udom'},$authhost,$firsturl);
1.1       albertel  406:     return OK;
                    407: }
                    408: 
                    409: 1;
                    410: __END__
1.7       www       411: 
                    412: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.