View | Details | Raw Unified | Return to bug 9611
Collapse All | Expand All

(-)a/C4/Auth.pm (-5 / +49 lines)
Lines 23-28 use Digest::MD5 qw(md5_base64); Link Here
23
use Storable qw(thaw freeze);
23
use Storable qw(thaw freeze);
24
use URI::Escape;
24
use URI::Escape;
25
use CGI::Session;
25
use CGI::Session;
26
use Crypt::Eksblowfish::Bcrypt qw(bcrypt en_base64);
27
use Crypt::Random::Source;
26
28
27
require Exporter;
29
require Exporter;
28
use C4::Context;
30
use C4::Context;
Lines 46-52 BEGIN { Link Here
46
    $debug       = $ENV{DEBUG};
48
    $debug       = $ENV{DEBUG};
47
    @ISA         = qw(Exporter);
49
    @ISA         = qw(Exporter);
48
    @EXPORT      = qw(&checkauth &get_template_and_user &haspermission &get_user_subpermissions);
50
    @EXPORT      = qw(&checkauth &get_template_and_user &haspermission &get_user_subpermissions);
49
    @EXPORT_OK   = qw(&check_api_auth &get_session &check_cookie_auth &checkpw &get_all_subpermissions &get_user_subpermissions);
51
    @EXPORT_OK   = qw(&check_api_auth hash_password &get_session &check_cookie_auth &checkpw &get_all_subpermissions &get_user_subpermissions);
50
    %EXPORT_TAGS = ( EditPermissions => [qw(get_all_subpermissions get_user_subpermissions)] );
52
    %EXPORT_TAGS = ( EditPermissions => [qw(get_all_subpermissions get_user_subpermissions)] );
51
    $ldap        = C4::Context->config('useldapserver') || 0;
53
    $ldap        = C4::Context->config('useldapserver') || 0;
52
    $cas         = C4::Context->preference('casAuthentication');
54
    $cas         = C4::Context->preference('casAuthentication');
Lines 1429-1434 sub get_session { Link Here
1429
    return $session;
1431
    return $session;
1430
}
1432
}
1431
1433
1434
# Using Bcrypt method for hashing. This can be changed to something else in future, if needed.
1435
sub hash_password {
1436
    my $password = shift;
1437
1438
    # Generate a salt if one is not passed
1439
    my $settings = shift;
1440
    unless( defined $settings ){ # if there are no settings, we need to create a salt and append settings
1441
    # Set the cost to 8 and append a NULL
1442
      $settings = '$2a$08$'.en_base64(generate_salt('strong'));
1443
    }
1444
    # Encrypt it
1445
    return bcrypt($password, $settings);
1446
}
1447
1448
# Return a random salt
1449
sub generate_salt {
1450
    my ($type) = @_;
1451
1452
        if ($type eq 'strong') {
1453
                return Crypt::Random::Source::get_strong(16);
1454
        } else {
1455
                return Crypt::Random::Source::get_weak(16);
1456
        }
1457
}
1458
1432
sub checkpw {
1459
sub checkpw {
1433
1460
1434
    my ( $dbh, $userid, $password, $query ) = @_;
1461
    my ( $dbh, $userid, $password, $query ) = @_;
Lines 1454-1463 sub checkpw { Link Here
1454
      );
1481
      );
1455
    $sth->execute($userid);
1482
    $sth->execute($userid);
1456
    if ( $sth->rows ) {
1483
    if ( $sth->rows ) {
1457
        my ( $md5password, $cardnumber, $borrowernumber, $userid, $firstname,
1484
        my ( $stored_hash, $cardnumber, $borrowernumber, $userid, $firstname,
1458
            $surname, $branchcode, $flags )
1485
            $surname, $branchcode, $flags )
1459
          = $sth->fetchrow;
1486
          = $sth->fetchrow;
1460
        if ( md5_base64($password) eq $md5password and $md5password ne "!") {
1487
1488
        # check what encryption algorithm was implemented: Bcrypt - if the hash starts with '$2' it is Bcrypt else md5
1489
        my $hash;
1490
        if ( substr($stored_hash,0,2) eq '$2') {
1491
            $hash = hash_password($password, $stored_hash);
1492
        } else {
1493
            $hash = md5_base64($password);
1494
        }
1495
        if ( $hash eq $stored_hash and $stored_hash ne "!") {
1461
1496
1462
            C4::Context->set_userenv( "$borrowernumber", $userid, $cardnumber,
1497
            C4::Context->set_userenv( "$borrowernumber", $userid, $cardnumber,
1463
                $firstname, $surname, $branchcode, $flags );
1498
                $firstname, $surname, $branchcode, $flags );
Lines 1470-1479 sub checkpw { Link Here
1470
      );
1505
      );
1471
    $sth->execute($userid);
1506
    $sth->execute($userid);
1472
    if ( $sth->rows ) {
1507
    if ( $sth->rows ) {
1473
        my ( $md5password, $cardnumber, $borrowernumber, $userid, $firstname,
1508
        my ( $stored_hash, $cardnumber, $borrowernumber, $userid, $firstname,
1474
            $surname, $branchcode, $flags )
1509
            $surname, $branchcode, $flags )
1475
          = $sth->fetchrow;
1510
          = $sth->fetchrow;
1476
        if ( md5_base64($password) eq $md5password ) {
1511
1512
        # check what encryption algorithm was implemented: Bcrypt - if the hash starts with '$2' it is Bcrypt else md5
1513
        my $hash;
1514
        if ( substr($stored_hash,0,2) eq '$2') {
1515
            $hash = hash_password($password, $stored_hash);
1516
        } else {
1517
            $hash = md5_base64($password);
1518
        }
1519
1520
        if ( $hash eq $stored_hash ) {
1477
1521
1478
            C4::Context->set_userenv( $borrowernumber, $userid, $cardnumber,
1522
            C4::Context->set_userenv( $borrowernumber, $userid, $cardnumber,
1479
                $firstname, $surname, $branchcode, $flags );
1523
                $firstname, $surname, $branchcode, $flags );
(-)a/C4/Members.pm (-25 / +8 lines)
Lines 24-30 use strict; Link Here
24
#use warnings; FIXME - Bug 2505
24
#use warnings; FIXME - Bug 2505
25
use C4::Context;
25
use C4::Context;
26
use C4::Dates qw(format_date_in_iso format_date);
26
use C4::Dates qw(format_date_in_iso format_date);
27
use Digest::MD5 qw(md5_base64);
28
use String::Random qw( random_string );
27
use String::Random qw( random_string );
29
use Date::Calc qw/Today Add_Delta_YM check_date Date_to_Days/;
28
use Date::Calc qw/Today Add_Delta_YM check_date Date_to_Days/;
30
use C4::Log; # logaction
29
use C4::Log; # logaction
Lines 40-45 use DateTime; Link Here
40
use DateTime::Format::DateParse;
39
use DateTime::Format::DateParse;
41
use Koha::DateUtils;
40
use Koha::DateUtils;
42
use Text::Unaccent qw( unac_string );
41
use Text::Unaccent qw( unac_string );
42
use C4::Auth qw(hash_password);
43
43
44
our ($VERSION,@ISA,@EXPORT,@EXPORT_OK,$debug);
44
our ($VERSION,@ISA,@EXPORT,@EXPORT_OK,$debug);
45
45
Lines 719-725 sub ModMember { Link Here
719
        if ($data{password} eq '****' or $data{password} eq '') {
719
        if ($data{password} eq '****' or $data{password} eq '') {
720
            delete $data{password};
720
            delete $data{password};
721
        } else {
721
        } else {
722
            $data{password} = md5_base64($data{password});
722
            $data{password} = hash_password($data{password});
723
        }
723
        }
724
    }
724
    }
725
	my $execute_success=UpdateInTable("borrowers",\%data);
725
	my $execute_success=UpdateInTable("borrowers",\%data);
Lines 768-777 sub AddMember { Link Here
768
    }
768
    }
769
769
770
    # create a disabled account if no password provided
770
    # create a disabled account if no password provided
771
    $data{'password'} = ($data{'password'})? md5_base64($data{'password'}) : '!';
771
    $data{'password'} = ($data{'password'})? hash_password($data{'password'}) : '!';
772
    $data{'borrowernumber'}=InsertInTable("borrowers",\%data);
772
    $data{'borrowernumber'}=InsertInTable("borrowers",\%data);
773
773
774
774
775
	# generate a proper login if none provided
776
	$data{'userid'} = Generate_Userid($data{'borrowernumber'}, $data{'firstname'}, $data{'surname'}) if $data{'userid'} eq '';
777
	# create a disabled account if no password provided
778
	$data{'password'} = ($data{'password'})? hash_password($data{'password'}) : '!';
779
	$data{'borrowernumber'}=InsertInTable("borrowers",\%data);	
775
    # mysql_insertid is probably bad.  not necessarily accurate and mysql-specific at best.
780
    # mysql_insertid is probably bad.  not necessarily accurate and mysql-specific at best.
776
    logaction("MEMBERS", "CREATE", $data{'borrowernumber'}, "") if C4::Context->preference("BorrowersLog");
781
    logaction("MEMBERS", "CREATE", $data{'borrowernumber'}, "") if C4::Context->preference("BorrowersLog");
777
    
782
    
Lines 1386-1413 sub GetExpiryDate { Link Here
1386
    }
1391
    }
1387
}
1392
}
1388
1393
1389
=head2 checkuserpassword (OUEST-PROVENCE)
1390
1391
check for the password and login are not used
1392
return the number of record 
1393
0=> NOT USED 1=> USED
1394
1395
=cut
1396
1397
sub checkuserpassword {
1398
    my ( $borrowernumber, $userid, $password ) = @_;
1399
    $password = md5_base64($password);
1400
    my $dbh = C4::Context->dbh;
1401
    my $sth =
1402
      $dbh->prepare(
1403
"Select count(*) from borrowers where borrowernumber !=? and userid =? and password=? "
1404
      );
1405
    $sth->execute( $borrowernumber, $userid, $password );
1406
    my $number_rows = $sth->fetchrow;
1407
    return $number_rows;
1408
1409
}
1410
1411
=head2 GetborCatFromCatType
1394
=head2 GetborCatFromCatType
1412
1395
1413
  ($codes_arrayref, $labels_hashref) = &GetborCatFromCatType();
1396
  ($codes_arrayref, $labels_hashref) = &GetborCatFromCatType();
(-)a/members/member-password.pl (-2 / +1 lines)
Lines 55-61 my $minpw = C4::Context->preference('minPasswordLength'); Link Here
55
push(@errors,'SHORTPASSWORD') if( $newpassword && $minpw && (length($newpassword) < $minpw ) );
55
push(@errors,'SHORTPASSWORD') if( $newpassword && $minpw && (length($newpassword) < $minpw ) );
56
56
57
if ( $newpassword  && !scalar(@errors) ) {
57
if ( $newpassword  && !scalar(@errors) ) {
58
    my $digest=md5_base64($input->param('newpassword'));
58
    my $digest=C4::Auth::hash_password($input->param('newpassword'));
59
    my $uid = $input->param('newuserid');
59
    my $uid = $input->param('newuserid');
60
    my $dbh=C4::Context->dbh;
60
    my $dbh=C4::Context->dbh;
61
    if (changepassword($uid,$member,$digest)) {
61
    if (changepassword($uid,$member,$digest)) {
62
- 

Return to bug 9611