diff --git a/lib/NGCP/Panel/Controller/Login.pm b/lib/NGCP/Panel/Controller/Login.pm index 6009659f1f..74aa7f6e89 100644 --- a/lib/NGCP/Panel/Controller/Login.pm +++ b/lib/NGCP/Panel/Controller/Login.pm @@ -7,7 +7,6 @@ use parent 'Catalyst::Controller'; use NGCP::Panel::Form::Login; use NGCP::Panel::Utils::Admin; -use Crypt::Eksblowfish::Bcrypt qw/bcrypt_hash en_base64 de_base64/; sub index :Path Form { my ( $self, $c, $realm ) = @_; @@ -30,64 +29,7 @@ sub index :Path Form { $c->log->debug("*** Login::index user=$user, pass=****, realm=$realm"); my $res; if($realm eq 'admin') { - my $dbadmin = $c->model('DB')->resultset('admins')->find({ - login => $user, - is_active => 1, - }); - if(defined $dbadmin && defined $dbadmin->saltedpass) { - $c->log->debug("login via bcrypt"); - my ($db_b64salt, $db_b64hash) = split /\$/, $dbadmin->saltedpass; - my $salt = de_base64($db_b64salt); - my $usr_b64hash = en_base64(bcrypt_hash({ - key_nul => 1, - cost => NGCP::Panel::Utils::Admin::get_bcrypt_cost(), - salt => $salt, - }, $pass)); - # fetch again to load user into session etc (otherwise we could - # simply compare the two hashes here :( - $res = $c->authenticate( - { - login => $user, - saltedpass => $db_b64salt . '$' . $usr_b64hash, - 'dbix_class' => { - searchargs => [{ - -and => [ - login => $user, - is_active => 1, - ], - }], - } - }, 'admin_bcrypt' - ); - } elsif(defined $dbadmin) { # we already know if the username is wrong, no need to check again - - # check md5 and migrate over to bcrypt on success - $c->log->debug("login via md5"); - $res = $c->authenticate( - { - login => $user, - md5pass => $pass, - 'dbix_class' => { - searchargs => [{ - -and => [ - login => $user, - is_active => 1, - ], - }], - } - }, 'admin'); - - if($res) { - # login ok, time to move user to bcrypt hashing - $c->log->debug("migrating to bcrypt"); - my $saltedpass = NGCP::Panel::Utils::Admin::generate_salted_hash($pass); - $dbadmin->update({ - md5pass => undef, - saltedpass => $saltedpass, - }); - } - - } + $res = NGCP::Panel::Utils::Admin::perform_auth($c, $user, $pass); } elsif($realm eq 'subscriber') { my ($u, $d, $t) = split /\@/, $user; if(defined $t) { diff --git a/lib/NGCP/Panel/Controller/Root.pm b/lib/NGCP/Panel/Controller/Root.pm index 923e4566ab..5ab78f20ea 100644 --- a/lib/NGCP/Panel/Controller/Root.pm +++ b/lib/NGCP/Panel/Controller/Root.pm @@ -7,6 +7,7 @@ BEGIN { extends 'Catalyst::Controller' } use Scalar::Util qw(blessed); use NGCP::Panel::Utils::DateTime qw(); use NGCP::Panel::Utils::Statistics qw(); +use NGCP::Panel::Utils::Admin; use DateTime qw(); use Time::HiRes qw(); use DateTime::Format::RFC3339 qw(); @@ -153,8 +154,8 @@ sub auto :Private { } else { $c->log->debug("++++++ Root::auto API admin request with http auth"); my $realm = "api_admin_http"; - my $res = $c->authenticate({}, $realm); - + my ($user, $pass) = $c->req->headers->authorization_basic; + my $res = NGCP::Panel::Utils::Admin::perform_auth($c, $user, $pass); unless($c->user_exists && $c->user->is_active) { $c->user->logout if($c->user); $c->log->debug("+++++ invalid api admin http login"); diff --git a/lib/NGCP/Panel/Controller/SOAP/Intercept.pm b/lib/NGCP/Panel/Controller/SOAP/Intercept.pm index f2505c5002..a221e5e6ce 100644 --- a/lib/NGCP/Panel/Controller/SOAP/Intercept.pm +++ b/lib/NGCP/Panel/Controller/SOAP/Intercept.pm @@ -92,6 +92,7 @@ sub _auth { }, $auth->{password})); die unless($usr_b64hash eq $db_b64hash); + die unless($admin->is_superuser || $admin->lawful_intercept); } else { my $md5admin = $c->model('DB')->resultset('admins')->search({ login => $auth->{username}, diff --git a/lib/NGCP/Panel/Utils/Admin.pm b/lib/NGCP/Panel/Utils/Admin.pm index fb647321ce..84a39ae66a 100644 --- a/lib/NGCP/Panel/Utils/Admin.pm +++ b/lib/NGCP/Panel/Utils/Admin.pm @@ -1,7 +1,7 @@ package NGCP::Panel::Utils::Admin; use Sipwise::Base; -use Crypt::Eksblowfish::Bcrypt qw/bcrypt_hash en_base64/; +use Crypt::Eksblowfish::Bcrypt qw/bcrypt_hash en_base64 de_base64/; use Data::Entropy::Algorithms qw/rand_bits/; sub get_bcrypt_cost { @@ -21,5 +21,68 @@ sub generate_salted_hash { return $b64salt . '$' . $b64hash; } +sub perform_auth { + my ($c, $user, $pass) = @_; + my $res; + + my $dbadmin = $c->model('DB')->resultset('admins')->find({ + login => $user, + is_active => 1, + }); + if(defined $dbadmin && defined $dbadmin->saltedpass) { + $c->log->debug("login via bcrypt"); + my ($db_b64salt, $db_b64hash) = split /\$/, $dbadmin->saltedpass; + my $salt = de_base64($db_b64salt); + my $usr_b64hash = en_base64(bcrypt_hash({ + key_nul => 1, + cost => get_bcrypt_cost(), + salt => $salt, + }, $pass)); + # fetch again to load user into session etc (otherwise we could + # simply compare the two hashes here :( + $res = $c->authenticate( + { + login => $user, + saltedpass => $db_b64salt . '$' . $usr_b64hash, + 'dbix_class' => { + searchargs => [{ + -and => [ + login => $user, + is_active => 1, + ], + }], + } + }, 'admin_bcrypt' + ); + } elsif(defined $dbadmin) { # we already know if the username is wrong, no need to check again + + # check md5 and migrate over to bcrypt on success + $c->log->debug("login via md5"); + $res = $c->authenticate( + { + login => $user, + md5pass => $pass, + 'dbix_class' => { + searchargs => [{ + -and => [ + login => $user, + is_active => 1, + ], + }], + } + }, 'admin'); + + if($res) { + # login ok, time to move user to bcrypt hashing + $c->log->debug("migrating to bcrypt"); + my $saltedpass = generate_salted_hash($pass); + $dbadmin->update({ + md5pass => undef, + saltedpass => $saltedpass, + }); + } + } + return $res; +} 1;