enable Bcrypt password storage
This commit is contained in:
@@ -34,6 +34,7 @@ requires:
|
||||
Dancer: 1.3112
|
||||
Dancer::Plugin::Auth::Extensible: 0.3
|
||||
Dancer::Plugin::DBIC: 0.1803
|
||||
Dancer::Plugin::Passphrase: 2
|
||||
File::ShareDir: 1.03
|
||||
Guard: 1.022
|
||||
HTML::Parser: 3.7
|
||||
|
||||
@@ -18,6 +18,7 @@ requires 'Daemon::Control' => 0.001000;
|
||||
requires 'Dancer' => 1.3112;
|
||||
requires 'Dancer::Plugin::DBIC' => 0.1803;
|
||||
requires 'Dancer::Plugin::Auth::Extensible' => 0.30;
|
||||
requires 'Dancer::Plugin::Passphrase' => 2.00;
|
||||
requires 'File::ShareDir' => 1.03;
|
||||
requires 'Guard' => 1.022;
|
||||
requires 'HTML::Parser' => 3.70;
|
||||
|
||||
@@ -99,9 +99,9 @@ $bool = $term->ask_yn(
|
||||
);
|
||||
deploy_db() if $bool;
|
||||
|
||||
say '';
|
||||
my $users = schema('netdisco')->resultset('User');
|
||||
if ($users->count == 0) {
|
||||
say '';
|
||||
$bool = $term->ask_yn(
|
||||
prompt => 'Would you like a default web user with Admin rights (discover, etc)?',
|
||||
default => 'n',
|
||||
@@ -136,6 +136,10 @@ if ($users->count == 0) {
|
||||
}
|
||||
}
|
||||
}
|
||||
elsif (!setting('safe_password_store')) {
|
||||
say '*** WARNING: Weak password hashes are being stored in the database! ***';
|
||||
say '*** WARNING: Please add "safe_password_store: true" to your ~/environments/deployment.yml file. ***';
|
||||
}
|
||||
|
||||
say '';
|
||||
$bool = $term->ask_yn(
|
||||
|
||||
@@ -210,7 +210,8 @@ C<name>, C<host>, C<user> and C<pass>).
|
||||
|
||||
In the same file uncomment and edit the C<domain_suffix> setting to be
|
||||
appropriate for your local site. If this is a fresh install, uncomment and set
|
||||
the C<no_auth> value to true (temporarily disables user authentication).
|
||||
the C<no_auth> value to true (temporarily disables user authentication). Have
|
||||
a quick read of the other settings to make sure you're happy, then move on.
|
||||
|
||||
=head1 Bootstrap
|
||||
|
||||
@@ -243,7 +244,7 @@ daemon at the same time. Similarly, if you use the device discovery with
|
||||
Netdisco 2, disable your system's cron jobs for the Netdisco 1.x poller.
|
||||
|
||||
At this point you can revisit the C<~/environments/deployment.yml> file to
|
||||
uncomment more configuration. Check out the community string settings, and
|
||||
uncomment more configuration. Enable the C<community> string settings, and
|
||||
C<housekeeping> which enables the automatic periodic device discovery. See
|
||||
L<Configuration|App::Netdisco::Manual::Configuration> for further details.
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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;
|
||||
|
||||
if ($user->$password_column !~ m/^{[A-Z]+}/) {
|
||||
debug 'authN: using legacy MD5';
|
||||
my $sum = Digest::MD5::md5_hex($password);
|
||||
return ($sum eq $user->$password_column ? 1 : 0);
|
||||
|
||||
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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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'),
|
||||
|
||||
@@ -72,6 +72,7 @@ web_plugins:
|
||||
- Device::Neighbors
|
||||
- Device::Addresses
|
||||
extra_web_plugins: []
|
||||
safe_password_store: true
|
||||
|
||||
# -------------
|
||||
# NETDISCO CORE
|
||||
|
||||
@@ -18,6 +18,11 @@ database:
|
||||
# RECOMMENDED SETTINGS
|
||||
# --------------------
|
||||
|
||||
# set to "false" if you MUST maintain backwards compatibility
|
||||
# with Netdisco 1.x web frontend.
|
||||
# ```````````````````````````````````````````````````````````
|
||||
safe_password_store: true
|
||||
|
||||
# will be stripped from fqdn when displayed in the web UI
|
||||
# also, do not forget the leading dot.
|
||||
# ```````````````````````````````````````````````````````
|
||||
@@ -48,8 +53,8 @@ database:
|
||||
# expiry:
|
||||
# when: '20 23 * * *'
|
||||
|
||||
# increase the performance of parallel DNS resolution for node names
|
||||
# (the default is max_outstanding: 10)
|
||||
# increase the performance of parallel DNS resolution for node
|
||||
# names (the default is max_outstanding: 10)
|
||||
# ````````````````````````````````````````````````````````````
|
||||
#dns:
|
||||
# max_outstanding: 100
|
||||
|
||||
|
||||
Reference in New Issue
Block a user