enable Bcrypt password storage

This commit is contained in:
Oliver Gorwits
2014-02-08 19:10:03 +00:00
parent f8cf6aad73
commit 545f878cb7
11 changed files with 114 additions and 66 deletions

View File

@@ -223,6 +223,13 @@ Value: List of Modules. Default: Empty List.
List of additional L<App::Netdisco::Web::Plugin> names to load. See also the
C<web_plugins> setting.
=head3 C<safe_password_store>
Value: Boolean. Default: true.
Set to "C<false>" if you MUST maintain backwards compatibility with the Netdisco
1.x web interface. Strongly recommended that you leave this set to "C<true>".
=head2 Netdisco Core
=head3 C<mibhome>

View File

@@ -90,61 +90,6 @@ hook 'after' => sub {
}
};
get qr{^/(?:login(?:/denied)?)?} => sub {
template 'index';
};
# Override default login_handler so that we can log access in the
# database
post '/login' => sub {
my ($success, $realm) = authenticate_user(
params->{username}, params->{password}
);
if ($success) {
session logged_in_user => params->{username};
session logged_in_user_realm => $realm;
schema('netdisco')->resultset('UserLog')->create({
username => session('logged_in_user'),
userip => request->remote_address,
event => "Login",
details => params->{return_url},
});
redirect params->{return_url} || uri_for('/');
} else {
schema('netdisco')->resultset('UserLog')->create({
username => params->{username},
userip => request->remote_address,
event => "Login Failure",
details => params->{return_url},
});
vars->{login_failed}++;
forward uri_for('/login'), { login_failed => 1 }, { method => 'GET' };
}
};
# Since we override the default login_handler, logout has to be handled as
# well
any ['get','post'] => '/logout' => sub {
schema('netdisco')->resultset('UserLog')->create({
username => session('logged_in_user'),
userip => request->remote_address,
event => "Logout",
details => '',
});
session->destroy;
if (params->{return_url}) {
redirect params->{return_url};
} else {
return "OK, logged out successfully.";
}
};
any qr{.*} => sub {
var('notfound' => true);
status 'not_found';

View File

@@ -10,7 +10,7 @@ use base 'Dancer::Plugin::Auth::Extensible::Provider::Base';
use Dancer ':syntax';
use Dancer::Plugin::DBIC;
use Dancer::Plugin::Passphrase;
use Digest::MD5;
sub authenticate_user {
@@ -77,8 +77,25 @@ sub match_with_local_pass {
return unless $password and $user->$password_column;
my $sum = Digest::MD5::md5_hex($password);
return ($sum eq $user->$password_column ? 1 : 0);
if ($user->$password_column !~ m/^{[A-Z]+}/) {
debug 'authN: using legacy MD5';
my $sum = Digest::MD5::md5_hex($password);
if ($sum eq $user->$password_column) {
if (setting('safe_password_store')) {
# upgrade password if successful, and permitted
$user->update({password => passphrase($password)->generate});
}
return 1;
}
else {
return 0;
}
}
else {
debug 'authN: using Passphrase';
return passphrase($password)->matches($user->$password_column);
}
}
sub match_with_ldap {

View File

@@ -27,4 +27,59 @@ hook 'before' => sub {
}
};
get qr{^/(?:login(?:/denied)?)?} => sub {
template 'index';
};
# override default login_handler so we can log access in the database
post '/login' => sub {
my ($success, $realm) = authenticate_user(
params->{username}, params->{password}
);
if ($success) {
session logged_in_user => params->{username};
session logged_in_user_realm => $realm;
schema('netdisco')->resultset('UserLog')->create({
username => session('logged_in_user'),
userip => request->remote_address,
event => "Login",
details => params->{return_url},
});
redirect params->{return_url} || uri_for('/');
}
else {
schema('netdisco')->resultset('UserLog')->create({
username => params->{username},
userip => request->remote_address,
event => "Login Failure",
details => params->{return_url},
});
vars->{login_failed}++;
forward uri_for('/login'), { login_failed => 1 }, { method => 'GET' };
}
};
# we override the default login_handler, so logout has to be handled as well
any ['get','post'] => '/logout' => sub {
schema('netdisco')->resultset('UserLog')->create({
username => session('logged_in_user'),
userip => request->remote_address,
event => "Logout",
details => '',
});
session->destroy;
if (params->{return_url}) {
redirect params->{return_url};
}
else {
return "OK, logged out successfully.";
}
};
true;

View File

@@ -4,6 +4,7 @@ use Dancer ':syntax';
use Dancer::Plugin::Ajax;
use Dancer::Plugin::DBIC;
use Dancer::Plugin::Auth::Extensible;
use Dancer::Plugin::Passphrase;
use App::Netdisco::Web::Plugin;
use Digest::MD5 ();
@@ -21,6 +22,16 @@ sub _sanity_ok {
return 1;
}
sub _make_password {
my $pass = (shift || passphrase->generate_random);
if (setting('safe_password_store')) {
return passphrase($pass)->generate;
}
else {
return Digest::MD5::md5_hex($pass),
}
}
ajax '/ajax/control/admin/users/add' => require_role admin => sub {
send_error('Bad Request', 400) unless _sanity_ok();
@@ -28,7 +39,7 @@ ajax '/ajax/control/admin/users/add' => require_role admin => sub {
my $user = schema('netdisco')->resultset('User')
->create({
username => param('username'),
password => Digest::MD5::md5_hex(param('password')),
password => _make_password(param('password')),
fullname => param('fullname'),
ldap => (param('ldap') ? \'true' : \'false'),
port_control => (param('port_control') ? \'true' : \'false'),
@@ -56,7 +67,7 @@ ajax '/ajax/control/admin/users/update' => require_role admin => sub {
$user->update({
((param('password') ne '********')
? (password => Digest::MD5::md5_hex(param('password')))
? (password => _make_password(param('password')))
: ()),
fullname => param('fullname'),
ldap => (param('ldap') ? \'true' : \'false'),