Commit 312e152b authored by Christophe Maudoux's avatar Christophe Maudoux

Append brutForceProtection plugin (#1506)

parent 5494fd07
......@@ -19,6 +19,7 @@ sub defaultValues {
'authentication' => 'Demo',
'available2F' => 'UTOTP,TOTP,U2F,REST,Ext2F,Yubikey',
'available2FSelfRegistration' => 'TOTP,U2F,Yubikey',
'brutForceProtection' => 1,
'captcha_mail_enabled' => 1,
'captcha_register_enabled' => 1,
'captcha_size' => 6,
......
......@@ -607,6 +607,10 @@ sub attributes {
'default' => 'TOTP,U2F,Yubikey',
'type' => 'text'
},
'brutForceProtection' => {
'default' => 1,
'type' => 'bool'
},
'captcha_login_enabled' => {
'default' => 0,
'type' => 'bool'
......
......@@ -604,12 +604,16 @@ sub attributes {
type => 'bool',
documentation => 'Avoid portal to be displayed inside frames',
},
portalCheckLogins => {
default => 1,
type => 'bool',
documentation => 'Display login history checkbox in portal',
},
brutForceProtection => {
default => 1,
type => 'bool',
documentation => 'Prevent brut force attack after two failed logins',
},
portalForceAuthnInterval => {
type => 'int',
default => 5,
......
......@@ -727,6 +727,7 @@ sub tree {
'trustedDomains',
'useSafeJail',
'checkXSS',
'brutForceProtection',
'lwpOpts',
'lwpSslOpts',
{
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
......@@ -19,6 +19,7 @@ our @pList = (
notification => '::Plugins::Notifications',
portalCheckLogins => '::Plugins::History',
stayConnected => '::Plugins::StayConnected',
brutForceProtection => '::Plugins::BrutForceProtection',
grantSessionRule => '::Plugins::GrantSession',
upgradeSession => '::Plugins::Upgrade',
autoSigninRules => '::Plugins::AutoSignin',
......
......@@ -294,6 +294,7 @@ sub authenticate {
$req->steps(
[ 'setSessionInfo', 'setMacros',
'setPersistentSessionInfo', 'storeHistory',
@{ $self->afterData },
sub {PE_BADCREDENTIALS}
]
);
......
package Lemonldap::NG::Portal::Plugins::BrutForceProtection;
use Data::Dumper;
use strict;
use Mouse;
use Lemonldap::NG::Portal::Main::Constants qw(PE_INFO PE_OK);
our $VERSION = '2.0.0';
extends 'Lemonldap::NG::Portal::Main::Plugin',
'Lemonldap::NG::Portal::Lib::OtherSessions';
# INITIALIZATION
use constant afterData => 'run';
sub init {1}
# RUNNING METHOD
sub run {
my ( $self, $req ) = @_;
my $countFailed
= @{ $req->sessionInfo->{_loginHistory}->{failedLogin} } || 0;
# Last failed login epoch before this authentication -> Auth_N-1
my $lastFailedLoginEpoch
= $req->sessionInfo->{_loginHistory}->{failedLogin}->[1]->{_utime}
|| 0;
# If Auth. N-1 older than 10 minutes -> another try allowed
if ( ( time - $lastFailedLoginEpoch ) > 600 ) {
$lastFailedLoginEpoch = 0;
}
# Delta between the two last failed logins -> Auth_N - Auth_N-1
my $delta = time - $lastFailedLoginEpoch;
$self->logger->debug( " successLogin -> "
. Dumper( $req->sessionInfo->{_loginHistory}->{successLogin} ) );
$self->logger->debug( " failedLogin -> "
. Dumper( $req->sessionInfo->{_loginHistory}->{failedLogin} ) );
$self->logger->debug(" Number of failedLogin -> $countFailed");
$self->logger->debug(" Last failedLogin epoch -> $lastFailedLoginEpoch");
$self->logger->debug( " Local time = " . localtime );
$self->logger->debug(" Delta Auth_N - Auth_N-1 = $delta");
# If Delta between the two last failed logins < 10s and more than 2 failedLogins => waiting = failedLogins * 10s
if ( $countFailed > 2 and ( $delta < 10 ) ) {
sleep $countFailed * 10;
}
return PE_OK;
}
1;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment