[Koha-patches] [PATCH] bug 9611: removing external dependency for password salt generator

Srdjan srdjan at catalyst.net.nz
Fri Aug 23 06:41:56 CEST 2013


From: Chris Hall <chrish at catalyst.net.nz>

To address packaging issues with Crypt::Random::Source, this patch
replaces the salt generation with a wrapper for /dev/urandom and
/dev/random.

The test plan for this patch is the same as that for the base patch
for bug 9611.

Signed-off-by: Galen Charlton <gmc at esilibrary.com>
---
 C4/Auth.pm | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 87 insertions(+)

diff --git a/C4/Auth.pm b/C4/Auth.pm
index 1e17e59..429181d 100644
--- a/C4/Auth.pm
+++ b/C4/Auth.pm
@@ -23,6 +23,8 @@ use Digest::MD5 qw(md5_base64);
 use JSON qw/encode_json decode_json/;
 use URI::Escape;
 use CGI::Session;
+use Crypt::Eksblowfish::Bcrypt qw(bcrypt en_base64);
+use Fcntl qw/O_RDONLY/; # O_RDONLY is used in generate_salt
 
 require Exporter;
 use C4::Context;
@@ -1464,6 +1466,91 @@ sub get_session {
     return $session;
 }
 
+# Using Bcrypt method for hashing. This can be changed to something else in future, if needed.
+sub hash_password {
+    my $password = shift;
+
+    # Generate a salt if one is not passed
+    my $settings = shift;
+    unless( defined $settings ){ # if there are no settings, we need to create a salt and append settings
+    # Set the cost to 8 and append a NULL
+      $settings = '$2a$08$'.en_base64(generate_salt('weak', 16));
+    }
+    # Encrypt it
+    return bcrypt($password, $settings);
+}
+
+=head2 generate_salt
+
+    use C4::Auth;
+    my $salt = C4::Auth::generate_salt($strength, $length);
+
+=item strength
+
+For general password salting a C<$strength> of C<weak> is recommend,
+For generating a server-salt a C<$strength> of C<strong> is recommended
+
+'strong' uses /dev/random which may block until sufficient entropy is acheived.
+'weak' uses /dev/urandom and is non-blocking.
+
+=back
+
+=item length
+
+C<$length> is a positive integer which specifies the desired length of the returned string
+
+=back
+
+=cut
+
+
+# the implementation of generate_salt is loosely based on Crypt::Random::Provider::File
+sub generate_salt {
+    # strength is 'strong' or 'weak'
+    # length is number of bytes to read, positive integer
+    my ($strength, $length) = @_;
+
+    my $source;
+
+    if( $length < 1 ){
+        die "non-positive strength of '$strength' passed to C4::Auth::generate_salt\n";
+    }
+
+    if( $strength eq "strong" ){
+        $source = '/dev/random'; # blocking
+    } else {
+        unless( $strength eq 'weak' ){
+            warn "unsuppored strength of '$strength' passed to C4::Auth::generate_salt, defaulting to 'weak'\n";
+        }
+        $source = '/dev/urandom'; # non-blocking
+    }
+
+    sysopen SOURCE, $source, O_RDONLY
+        or die "failed to open source '$source' in C4::Auth::generate_salt\n";
+
+    # $bytes is the bytes just read
+    # $string is the concatenation of all the bytes read so far
+    my( $bytes, $string ) = ("", "");
+
+    # keep reading until we have $length bytes in $strength
+    while( length($string) < $length ){
+        # return the number of bytes read, 0 (EOF), or -1 (ERROR)
+        my $return = sysread SOURCE, $bytes, $length - length($string);
+
+        # if no bytes were read, keep reading (if using /dev/random it is possible there was insufficient entropy so this may block)
+        next unless $return;
+        if( $return == -1 ){
+            die "error while reading from $source in C4::Auth::generate_salt\n";
+        }
+
+        $string .= $bytes;
+    }
+
+    close SOURCE;
+    return $string;
+}
+
+
 sub checkpw {
 
     my ( $dbh, $userid, $password, $query ) = @_;
-- 
1.8.1.2


More information about the Koha-patches mailing list