X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2FAuth%2Finternal.pm;h=92dff03189e1b87ff70ef6fc7bff159bbe69ea60;hb=HEAD;hp=86fddd237993a7f04ee2e379437d6507b20a7562;hpb=3ff1fb4e10fdaef86527c10bd416e988d2a62a49;p=freeside.git diff --git a/FS/FS/Auth/internal.pm b/FS/FS/Auth/internal.pm index 86fddd237..92dff0318 100644 --- a/FS/FS/Auth/internal.pm +++ b/FS/FS/Auth/internal.pm @@ -2,14 +2,87 @@ package FS::Auth::internal; #use base qw( FS::Auth ); use strict; +use Crypt::Eksblowfish::Bcrypt qw(bcrypt_hash en_base64 de_base64); +use FS::Record qw( qsearchs ); +use FS::access_user; sub authenticate { - my( $username, $check_password ) = @_; + my($self, $username, $check_password, $totp_code ) = @_; + my $access_user = + ref($username) ? $username + : qsearchs('access_user', { 'username' => $username, + 'disabled' => '', + } + ) + or return 0; + my $pw_check; + if ( $access_user->_password_encoding eq 'bcrypt' ) { + + my( $cost, $salt, $hash ) = split(',', $access_user->_password); + + my $check_hash = en_base64( bcrypt_hash( { key_nul => 1, + cost => $cost, + salt => de_base64($salt), + }, + $check_password + ) + ); + + $pw_check = $hash eq $check_hash; + + } else { + + return 0 if $access_user->_password eq 'notyet' + || $access_user->_password eq ''; + + $pw_check = $access_user->_password eq $check_password; + + } + + return $pw_check if ! $pw_check || ! length($access_user->totp_secret32); + + #2fa + $access_user->google_auth->verify( $totp_code, 1 ); } +sub autocreate { 0; } + sub change_password { + my($self, $access_user, $new_password) = @_; + + # do nothing if the password is unchanged + #XXX breaks password changes in employee edit ($access_user object already + # has new [plaintext] password) + #return if $self->authenticate( $access_user, $new_password ); + + $self->change_password_fields( $access_user, $new_password ); + + $access_user->replace; + +} + +sub change_password_fields { + my($self, $access_user, $new_password) = @_; + + $access_user->_password_encoding('bcrypt'); + + my $cost = 8; + + my $salt = pack( 'C*', map int(rand(256)), 1..16 ); + + my $hash = bcrypt_hash( { key_nul => 1, + cost => $cost, + salt => $salt, + }, + $new_password, + ); + + $access_user->_password( + join(',', $cost, en_base64($salt), en_base64($hash) ) + ); + } 1;