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

(-)a/C4/Auth.pm (-1 / +87 lines)
Lines 23-28 use Digest::MD5 qw(md5_base64); Link Here
23
use JSON qw/encode_json decode_json/;
23
use JSON qw/encode_json decode_json/;
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 Fcntl qw/O_RDONLY/; # O_RDONLY is used in generate_salt
26
28
27
require Exporter;
29
require Exporter;
28
use C4::Context;
30
use C4::Context;
Lines 1464-1469 sub get_session { Link Here
1464
    return $session;
1466
    return $session;
1465
}
1467
}
1466
1468
1469
# Using Bcrypt method for hashing. This can be changed to something else in future, if needed.
1470
sub hash_password {
1471
    my $password = shift;
1472
1473
    # Generate a salt if one is not passed
1474
    my $settings = shift;
1475
    unless( defined $settings ){ # if there are no settings, we need to create a salt and append settings
1476
    # Set the cost to 8 and append a NULL
1477
      $settings = '$2a$08$'.en_base64(generate_salt('weak', 16));
1478
    }
1479
    # Encrypt it
1480
    return bcrypt($password, $settings);
1481
}
1482
1483
=head2 generate_salt
1484
1485
    use C4::Auth;
1486
    my $salt = C4::Auth::generate_salt($strength, $length);
1487
1488
=item strength
1489
1490
For general password salting a C<$strength> of C<weak> is recommend,
1491
For generating a server-salt a C<$strength> of C<strong> is recommended
1492
1493
'strong' uses /dev/random which may block until sufficient entropy is acheived.
1494
'weak' uses /dev/urandom and is non-blocking.
1495
1496
=back
1497
1498
=item length
1499
1500
C<$length> is a positive integer which specifies the desired length of the returned string
1501
1502
=back
1503
1504
=cut
1505
1506
1507
# the implementation of generate_salt is loosely based on Crypt::Random::Provider::File
1508
sub generate_salt {
1509
    # strength is 'strong' or 'weak'
1510
    # length is number of bytes to read, positive integer
1511
    my ($strength, $length) = @_;
1512
1513
    my $source;
1514
1515
    if( $length < 1 ){
1516
        die "non-positive strength of '$strength' passed to C4::Auth::generate_salt\n";
1517
    }
1518
1519
    if( $strength eq "strong" ){
1520
        $source = '/dev/random'; # blocking
1521
    } else {
1522
        unless( $strength eq 'weak' ){
1523
            warn "unsuppored strength of '$strength' passed to C4::Auth::generate_salt, defaulting to 'weak'\n";
1524
        }
1525
        $source = '/dev/urandom'; # non-blocking
1526
    }
1527
1528
    sysopen SOURCE, $source, O_RDONLY
1529
        or die "failed to open source '$source' in C4::Auth::generate_salt\n";
1530
1531
    # $bytes is the bytes just read
1532
    # $string is the concatenation of all the bytes read so far
1533
    my( $bytes, $string ) = ("", "");
1534
1535
    # keep reading until we have $length bytes in $strength
1536
    while( length($string) < $length ){
1537
        # return the number of bytes read, 0 (EOF), or -1 (ERROR)
1538
        my $return = sysread SOURCE, $bytes, $length - length($string);
1539
1540
        # if no bytes were read, keep reading (if using /dev/random it is possible there was insufficient entropy so this may block)
1541
        next unless $return;
1542
        if( $return == -1 ){
1543
            die "error while reading from $source in C4::Auth::generate_salt\n";
1544
        }
1545
1546
        $string .= $bytes;
1547
    }
1548
1549
    close SOURCE;
1550
    return $string;
1551
}
1552
1553
1467
sub checkpw {
1554
sub checkpw {
1468
1555
1469
    my ( $dbh, $userid, $password, $query ) = @_;
1556
    my ( $dbh, $userid, $password, $query ) = @_;
1470
- 

Return to bug 9611