[LON-CAPA-cvs] cvs: loncom / lond /auth lonauth.pm londes.js lonlogin.pm /interface createaccount.pm loncommon.pm loncreateuser.pm lonpreferences.pm
raeburn
raeburn at source.lon-capa.org
Wed Feb 17 14:15:49 EST 2016
raeburn Wed Feb 17 19:15:49 2016 EDT
Modified files:
/loncom/auth lonlogin.pm lonauth.pm londes.js
/loncom lond
/loncom/interface lonpreferences.pm createaccount.pm
loncreateuser.pm loncommon.pm
Log:
- Bug 5679
-------------- next part --------------
Index: loncom/auth/lonlogin.pm
diff -u loncom/auth/lonlogin.pm:1.164 loncom/auth/lonlogin.pm:1.165
--- loncom/auth/lonlogin.pm:1.164 Sat Jun 6 14:39:42 2015
+++ loncom/auth/lonlogin.pm Wed Feb 17 19:15:39 2016
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Login Screen
#
-# $Id: lonlogin.pm,v 1.164 2015/06/06 14:39:42 raeburn Exp $
+# $Id: lonlogin.pm,v 1.165 2016/02/17 19:15:39 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -352,18 +352,9 @@
lextkey=this.document.client.elements.lextkey.value;
initkeys();
-this.document.server.elements.upass0.value
- =this.document.client.elements.upass$now.value.substr(0,15);
-this.document.server.elements.upass1.value
- =this.document.client.elements.upass$now.value.substr(15,15);
-this.document.server.elements.upass2.value
- =this.document.client.elements.upass$now.value.substr(30,15);
-
if(this.document.server.action.substr(0,5) === 'http:'){
- for (var idx in [1,2,3]){
- this.document.server.elements['upass' + idx].value =
- crypted(this.document.server.elements['upass' + idx].value);
- }
+ this.document.server.elements.upass0.value
+ =getCrypted(this.document.client.elements.upass$now.value);
}
this.document.client.elements.uname.value='';
@@ -479,8 +470,6 @@
<input type="hidden" name="serverid" value="$lonhost" />
<input type="hidden" name="uname" value="" />
<input type="hidden" name="upass0" value="" />
- <input type="hidden" name="upass1" value="" />
- <input type="hidden" name="upass2" value="" />
<input type="hidden" name="udom" value="" />
<input type="hidden" name="localpath" value="$env{'form.localpath'}" />
<input type="hidden" name="localres" value="$env{'form.localres'}" />
Index: loncom/auth/lonauth.pm
diff -u loncom/auth/lonauth.pm:1.138 loncom/auth/lonauth.pm:1.139
--- loncom/auth/lonauth.pm:1.138 Fri Mar 6 21:56:41 2015
+++ loncom/auth/lonauth.pm Wed Feb 17 19:15:40 2016
@@ -1,7 +1,7 @@
# The LearningOnline Network
# User Authentication Module
#
-# $Id: lonauth.pm,v 1.138 2015/03/06 21:56:41 raeburn Exp $
+# $Id: lonauth.pm,v 1.139 2016/02/17 19:15:40 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -346,8 +346,8 @@
(undef,$form{'iptoken'}) = split('=',$iptokenstr);
}
- my $upass = $ENV{HTTPS} ? join("", @form{qw(upass0 upass1 upass2)})
- : decrypt($key, @form{qw(upass0 upass1 upass2)});
+ my $upass = $ENV{HTTPS} ? $form{'upass0'}
+ : &Apache::loncommon::des_decrypt($key,$form{'upass0'});
# ---------------------------------------------------------------- Authenticate
@@ -525,34 +525,6 @@
}
}
-sub decrypt {
- my ($key, @chunks) = @_;
-
- my $keybin = pack("H16",$key);
-
- my $cipher;
- if ($Crypt::DES::VERSION >= 2.03) {
- $cipher = new Crypt::DES $keybin;
- } else {
- $cipher = new DES $keybin;
- }
-
- my $upass='';
- for (my $i=0;$i<=2;$i++) {
- my $chunk =
- $cipher->decrypt(
- unpack("a8",pack("H16",substr($chunks[$i],0,16))));
-
- $chunk .=
- $cipher->decrypt(
- unpack("a8",pack("H16",substr($chunks[$i],16,16))));
-
- $chunk = substr($chunk,1,ord(substr($chunk,0,1)));
- $upass .= $chunk;
- }
- return $upass;
-}
-
sub check_can_host {
my ($r,$form,$authhost,$domdesc) = @_;
return unless (ref($form) eq 'HASH');
Index: loncom/auth/londes.js
diff -u loncom/auth/londes.js:1.9 loncom/auth/londes.js:1.10
--- loncom/auth/londes.js:1.9 Fri May 22 17:01:28 2009
+++ loncom/auth/londes.js Wed Feb 17 19:15:40 2016
@@ -4,7 +4,7 @@
// Encryption Routines according to Data Encryption Standard DES
// Federal Information Processing Standards Publication 46-2 (1993 Dec 30)
//
-// $Id: londes.js,v 1.9 2009/05/22 17:01:28 bisitz Exp $
+// $Id: londes.js,v 1.10 2016/02/17 19:15:40 raeburn Exp $
//
// Copyright Michigan State University Board of Trustees
//
@@ -376,5 +376,22 @@
return(hexstring(b3)+hexstring(b2)+hexstring(b1)+hexstring(b0));
}
+function getCrypted(text) {
+ var cryptedtext = '';
+ if (text.length > 0) {
+ var rem = text.length % 15;
+ var count = Math.floor(text.length/15);
+ if (rem > 0) {
+ count ++;
+ }
+ for (var i=0; i<count; i++) {
+ var start = i*15;
+ cryptedtext += crypted(text.substr(start,15));
+ }
+ }
+ return cryptedtext;
+}
+
+
// ]]>
</script>
Index: loncom/lond
diff -u loncom/lond:1.517 loncom/lond:1.518
--- loncom/lond:1.517 Sun Jan 31 21:25:53 2016
+++ loncom/lond Wed Feb 17 19:15:44 2016
@@ -2,7 +2,7 @@
# The LearningOnline Network
# lond "LON Daemon" Server (port "LOND" 5663)
#
-# $Id: lond,v 1.517 2016/01/31 21:25:53 raeburn Exp $
+# $Id: lond,v 1.518 2016/02/17 19:15:44 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -55,13 +55,16 @@
use Fcntl qw(:flock);
use Apache::lonnet;
use Mail::Send;
+use Crypt::Eksblowfish::Bcrypt;
+use Digest::SHA;
+use Encode;
my $DEBUG = 0; # Non zero to enable debug log entries.
my $status='';
my $lastlog='';
-my $VERSION='$Revision: 1.517 $'; #' stupid emacs
+my $VERSION='$Revision: 1.518 $'; #' stupid emacs
my $remoteVERSION;
my $currenthostid="default";
my $currentdomainid;
@@ -2013,15 +2016,14 @@
my ($howpwd,$contentpwd)=split(/:/,$realpasswd);
if ($howpwd eq 'internal') {
&Debug("internal auth");
- my $salt=time;
- $salt=substr($salt,6,2);
- my $ncpass=crypt($npass,$salt);
+ my $ncpass = &hash_passwd($udom,$npass);
if(&rewrite_password_file($udom, $uname, "internal:$ncpass")) {
my $msg="Result of password change for $uname: pwchange_success";
if ($lonhost) {
$msg .= " - request originated from: $lonhost";
}
&logthis($msg);
+ &update_passwd_history($uname,$udom,$howpwd,$context);
&Reply($client, "ok\n", $userinput);
} else {
&logthis("Unable to open $uname passwd "
@@ -2030,6 +2032,9 @@
}
} elsif ($howpwd eq 'unix' && $context ne 'reset_by_email') {
my $result = &change_unix_password($uname, $npass);
+ if ($result eq 'ok') {
+ &update_passwd_history($uname,$udom,$howpwd,$context);
+ }
&logthis("Result of password change for $uname: ".
$result);
&Reply($client, \$result, $userinput);
@@ -2052,6 +2057,42 @@
}
®ister_handler("passwd", \&change_password_handler, 1, 1, 0);
+sub hash_passwd {
+ my ($domain,$plainpass, at rest) = @_;
+ my ($salt,$cost);
+ if (@rest) {
+ $cost = $rest[0];
+ # salt is first 22 characters, base-64 encoded by bcrypt
+ my $plainsalt = substr($rest[1],0,22);
+ $salt = Crypt::Eksblowfish::Bcrypt::de_base64($plainsalt);
+ } else {
+ my $defaultcost;
+ my %domconfig =
+ &Apache::lonnet::get_dom('configuration',['password'],$domain);
+ if (ref($domconfig{'password'}) eq 'HASH') {
+ $defaultcost = $domconfig{'password'}{'cost'};
+ }
+ if (($defaultcost eq '') || ($defaultcost =~ /D/)) {
+ $cost = 10;
+ } else {
+ $cost = $defaultcost;
+ }
+ # Generate random 16-octet base64 salt
+ $salt = "";
+ $salt .= pack("C", int rand(256)) for 1..16;
+ }
+ my $hash = &Crypt::Eksblowfish::Bcrypt::bcrypt_hash({
+ key_nul => 1,
+ cost => $cost,
+ salt => $salt,
+ }, Digest::SHA::sha512(Encode::encode('UTF-8',$plainpass)));
+
+ my $result = join("!", "", "bcrypt", sprintf("%02d",$cost),
+ &Crypt::Eksblowfish::Bcrypt::en_base64($salt).
+ &Crypt::Eksblowfish::Bcrypt::en_base64($hash));
+ return $result;
+}
+
#
# Create a new user. User in this case means a lon-capa user.
# The user must either already exist in some authentication realm
@@ -2095,7 +2136,8 @@
."makeuser";
}
unless ($fperror) {
- my $result=&make_passwd_file($uname,$udom,$umode,$npass, $passfilename);
+ my $result=&make_passwd_file($uname,$udom,$umode,$npass,
+ $passfilename,'makeuser');
&Reply($client,\$result, $userinput); #BUGBUG - could be fail
} else {
&Failure($client, \$fperror, $userinput);
@@ -2164,12 +2206,14 @@
my $result = &change_unix_password($uname, $npass);
&logthis("Result of password change for $uname: ".$result);
if ($result eq "ok") {
+ &update_passwd_history($uname,$udom,$umode,'changeuserauth');
&Reply($client, \$result);
} else {
&Failure($client, \$result);
}
} else {
- my $result=&make_passwd_file($uname,$udom,$umode,$npass,$passfilename);
+ my $result=&make_passwd_file($uname,$udom,$umode,$npass,
+ $passfilename,'changeuserauth');
#
# If the current auth mode is internal, and the old auth mode was
# unix, or krb*, and the user is an author for this domain,
@@ -2190,6 +2234,17 @@
}
®ister_handler("changeuserauth", \&change_authentication_handler, 1,1, 0);
+sub update_passwd_history {
+ my ($uname,$udom,$umode,$context) = @_;
+ my $proname=&propath($udom,$uname);
+ my $now = time;
+ if (open(my $fh,">>$proname/passwd.log")) {
+ print $fh "$now:$umode:$context\n";
+ close($fh);
+ }
+ return;
+}
+
#
# Determines if this is the home server for a user. The home server
# for a user will have his/her lon-capa passwd file. Therefore all we need
@@ -7147,7 +7202,18 @@
}
if ($howpwd ne 'nouser') {
if($howpwd eq "internal") { # Encrypted is in local password file.
- $validated = (crypt($password, $contentpwd) eq $contentpwd);
+ if (length($contentpwd) == 13) {
+ $validated = (crypt($password,$contentpwd) eq $contentpwd);
+ if ($validated) {
+ my $ncpass = &hash_passwd($domain,$password);
+ if (&rewrite_password_file($domain,$user,"$howpwd:$ncpass")) {
+ &update_passwd_history($user,$domain,$howpwd,'conversion');
+ &logthis("Validated password hashed with bcrypt for $user:$domain");
+ }
+ }
+ } else {
+ $validated = &check_internal_passwd($password,$contentpwd,$domain);
+ }
}
elsif ($howpwd eq "unix") { # User is a normal unix user.
$contentpwd = (getpwnam($user))[1];
@@ -7215,6 +7281,39 @@
return $validated;
}
+sub check_internal_passwd {
+ my ($plainpass,$stored,$domain) = @_;
+ my (undef,$method, at rest) = split(/!/,$stored);
+ if ($method eq "bcrypt") {
+ my $result = &hash_passwd($domain,$plainpass, at rest);
+ if ($result ne $stored) {
+ return 0;
+ }
+ # Upgrade to a larger number of rounds if necessary
+ my $defaultcost;
+ my %domconfig =
+ &Apache::lonnet::get_dom('configuration',['password'],$domain);
+ if (ref($domconfig{'password'}) eq 'HASH') {
+ $defaultcost = $domconfig{'password'}{'cost'};
+ }
+ if (($defaultcost eq '') || ($defaultcost =~ /D/)) {
+ $defaultcost = 10;
+ }
+ return 1 unless($rest[0]<$defaultcost);
+ }
+ return 0;
+}
+
+sub get_last_authchg {
+ my ($domain,$user) = @_;
+ my $lastmod;
+ my $logname = &propath($domain,$user).'/passwd.log';
+ if (-e "$logname") {
+ $lastmod = (stat("$logname"))[9];
+ }
+ return $lastmod;
+}
+
sub krb4_authen {
my ($password,$null,$user,$contentpwd) = @_;
my $validated = 0;
@@ -7530,26 +7629,26 @@
sub make_passwd_file {
- my ($uname,$udom,$umode,$npass,$passfilename)=@_;
+ my ($uname,$udom,$umode,$npass,$passfilename,$action)=@_;
my $result="ok";
if ($umode eq 'krb4' or $umode eq 'krb5') {
{
my $pf = IO::File->new(">$passfilename");
if ($pf) {
print $pf "$umode:$npass\n";
+ &update_passwd_history($uname,$udom,$umode,$action);
} else {
$result = "pass_file_failed_error";
}
}
} elsif ($umode eq 'internal') {
- my $salt=time;
- $salt=substr($salt,6,2);
- my $ncpass=crypt($npass,$salt);
+ my $ncpass = &hash_passwd($udom,$npass);
{
&Debug("Creating internal auth");
my $pf = IO::File->new(">$passfilename");
if($pf) {
- print $pf "internal:$ncpass\n";
+ print $pf "internal:$ncpass\n";
+ &update_passwd_history($uname,$udom,$umode,$action);
} else {
$result = "pass_file_failed_error";
}
Index: loncom/interface/lonpreferences.pm
diff -u loncom/interface/lonpreferences.pm:1.218 loncom/interface/lonpreferences.pm:1.219
--- loncom/interface/lonpreferences.pm:1.218 Sun Jan 31 21:25:37 2016
+++ loncom/interface/lonpreferences.pm Wed Feb 17 19:15:48 2016
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Preferences
#
-# $Id: lonpreferences.pm,v 1.218 2016/01/31 21:25:37 raeburn Exp $
+# $Id: lonpreferences.pm,v 1.219 2016/02/17 19:15:48 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -1409,21 +1409,18 @@
uextkey=this.document.client.elements.ukey_cpass.value;
lextkey=this.document.client.elements.lkey_cpass.value;
initkeys();
-
- this.document.pserver.elements.currentpass.value
- =crypted(this.document.client.elements.currentpass.value);
-
+ this.document.pserver.elements.currentpass.value =
+ getCrypted(this.document.client.elements.currentpass.value);
uextkey=this.document.client.elements.ukey_npass1.value;
lextkey=this.document.client.elements.lkey_npass1.value;
initkeys();
this.document.pserver.elements.newpass_1.value
- =crypted(this.document.client.elements.newpass_1.value);
-
+ =getCrypted(this.document.client.elements.newpass_1.value);
uextkey=this.document.client.elements.ukey_npass2.value;
lextkey=this.document.client.elements.lkey_npass2.value;
initkeys();
this.document.pserver.elements.newpass_2.value
- =crypted(this.document.client.elements.newpass_2.value);
+ =getCrypted(this.document.client.elements.newpass_2.value);
|;
if ($caller eq 'reset_by_email') {
$output .= qq|
@@ -1438,6 +1435,7 @@
$ output .= qq|
this.document.pserver.submit();
}
+
</script>
|;
}
@@ -1463,7 +1461,7 @@
.&Apache::lonhtmlcommon::row_closure()
.&Apache::lonhtmlcommon::row_title(
'<label for="uname">'.$lt{'username'}.'</label>')
- .'<input type="text" name="uname" size="15" />'
+ .'<input type="text" name="uname" size="20" />'
.'<input type="hidden" name="currentpass" value="'.$currentpass.'" />'
.&Apache::lonhtmlcommon::row_closure()
.&Apache::lonhtmlcommon::row_title(
@@ -1473,16 +1471,16 @@
} else {
$output .= &Apache::lonhtmlcommon::row_title(
'<label for="currentpass">'.$lt{'currentpass'}.'</label>')
- .'<input type="password" name="currentpass" size="10"/>'
+ .'<input type="password" name="currentpass" size="20"/>'
.&Apache::lonhtmlcommon::row_closure();
}
$output .= &Apache::lonhtmlcommon::row_title(
'<label for="newpass_1">'.$lt{'newpass'}.'</label>')
- .'<input type="password" name="newpass_1" size="10" />'
+ .'<input type="password" name="newpass_1" size="20" />'
.&Apache::lonhtmlcommon::row_closure()
.&Apache::lonhtmlcommon::row_title(
'<label for="newpass_2">'.$lt{'confirmpass'}.'</label>')
- .'<input type="password" name="newpass_2" size="10" />'
+ .'<input type="password" name="newpass_2" size="20" />'
.&Apache::lonhtmlcommon::row_closure(1)
.&Apache::lonhtmlcommon::end_pick_box();
$output .= '<p><input type="button" value="'.$lt{'changepass'}.'" onclick="send();" /></p>'
@@ -1605,7 +1603,7 @@
return 1;
}
my ($ckey,$n1key,$n2key)=split(/&/,$tmpinfo);
- #
+ #
$currentpass = &Apache::loncommon::des_decrypt($ckey ,$currentpass);
$newpass1 = &Apache::loncommon::des_decrypt($n1key,$newpass1);
$newpass2 = &Apache::loncommon::des_decrypt($n2key,$newpass2);
@@ -2283,7 +2281,7 @@
}elsif($env{'form.action'} eq 'changepass'){
&passwordchanger($r);
}elsif($env{'form.action'} eq 'verify_and_change_pass'){
- &verify_and_change_password($r);
+ &verify_and_change_password($r,'preferences');
}elsif($env{'form.action'} eq 'changescreenname'){
&screennamechanger($r);
}elsif($env{'form.action'} eq 'verify_and_change_screenname'){
Index: loncom/interface/createaccount.pm
diff -u loncom/interface/createaccount.pm:1.70 loncom/interface/createaccount.pm:1.71
--- loncom/interface/createaccount.pm:1.70 Tue Jun 9 21:22:55 2015
+++ loncom/interface/createaccount.pm Wed Feb 17 19:15:48 2016
@@ -4,7 +4,7 @@
# kerberos, or SSO) or an e-mail address. Requests to use an e-mail address as
# username may be processed automatically, or may be queued for approval.
#
-# $Id: createaccount.pm,v 1.70 2015/06/09 21:22:55 damieng Exp $
+# $Id: createaccount.pm,v 1.71 2016/02/17 19:15:48 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -431,7 +431,7 @@
initkeys();
server.elements.upass.value
- = crypted(client.elements.upass$now.value);
+ = getCrypted(client.elements.upass$now.value);
client.elements.uname.value='';
client.elements.upass$now.value='';
@@ -444,6 +444,7 @@
}
return false;
}
+
// ]]>
</script>
ENDSCRIPT
Index: loncom/interface/loncreateuser.pm
diff -u loncom/interface/loncreateuser.pm:1.407 loncom/interface/loncreateuser.pm:1.408
--- loncom/interface/loncreateuser.pm:1.407 Sun Jan 31 21:25:38 2016
+++ loncom/interface/loncreateuser.pm Wed Feb 17 19:15:48 2016
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Create a user
#
-# $Id: loncreateuser.pm,v 1.407 2016/01/31 21:25:38 raeburn Exp $
+# $Id: loncreateuser.pm,v 1.408 2016/02/17 19:15:48 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -2244,8 +2244,8 @@
'<input type="text" name="uname" size="25" value="" autocomplete="off" />';
$rowcount ++;
$output .= &Apache::lonhtmlcommon::row_closure(1);
- my $upassone = '<input type="password" name="upass'.$now.'" size="10" autocomplete="off" />';
- my $upasstwo = '<input type="password" name="upasscheck'.$now.'" size="10" autocomplete="off" />';
+ my $upassone = '<input type="password" name="upass'.$now.'" size="20" autocomplete="off" />';
+ my $upasstwo = '<input type="password" name="upasscheck'.$now.'" size="20" autocomplete="off" />';
$output .= &Apache::lonhtmlcommon::row_title(&mt('Password').'<b>*</b>',
'LC_pick_box_title',
'LC_oddrow_value')."\n".
Index: loncom/interface/loncommon.pm
diff -u loncom/interface/loncommon.pm:1.1232 loncom/interface/loncommon.pm:1.1233
--- loncom/interface/loncommon.pm:1.1232 Wed Jan 27 00:24:09 2016
+++ loncom/interface/loncommon.pm Wed Feb 17 19:15:48 2016
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# a pile of common routines
#
-# $Id: loncommon.pm,v 1.1232 2016/01/27 00:24:09 raeburn Exp $
+# $Id: loncommon.pm,v 1.1233 2016/02/17 19:15:48 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -16766,11 +16766,19 @@
} else {
$cypher=new DES $keybin;
}
- my $plaintext=
- $cypher->decrypt(unpack("a8",pack("H16",substr($cyphertext,0,16))));
- $plaintext.=
- $cypher->decrypt(unpack("a8",pack("H16",substr($cyphertext,16,16))));
- $plaintext=substr($plaintext,1,ord(substr($plaintext,0,1)) );
+ my $plaintext='';
+ my $cypherlength = length($cyphertext);
+ my $numchunks = int($cypherlength/32);
+ for (my $j=0; $j<$numchunks; $j++) {
+ my $start = $j*32;
+ my $cypherblock = substr($cyphertext,$start,32);
+ my $chunk =
+ $cypher->decrypt(unpack("a8",pack("H16",substr($cypherblock,0,16))));
+ $chunk .=
+ $cypher->decrypt(unpack("a8",pack("H16",substr($cypherblock,16,16))));
+ $chunk=substr($chunk,1,ord(substr($chunk,0,1)) );
+ $plaintext .= $chunk;
+ }
return $plaintext;
}
More information about the LON-CAPA-cvs
mailing list