lemonldap-ng/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Plugins/BruteForceProtection.pm
Xavier Guimard 5886cbe2a0 Tidy
2019-02-05 23:12:17 +01:00

75 lines
2.2 KiB
Perl

package Lemonldap::NG::Portal::Plugins::BruteForceProtection;
use strict;
use Mouse;
use Lemonldap::NG::Portal::Main::Constants qw(PE_OK PE_WAIT);
our $VERSION = '2.0.1';
extends 'Lemonldap::NG::Portal::Main::Plugin';
# INITIALIZATION
use constant afterData => 'run';
sub init {
my ($self) = @_;
unless ( $self->conf->{loginHistoryEnabled} ) {
$self->logger->error(
'"History" plugin is required for "BruteForceProtection" plugin');
return 0;
}
return 1;
}
# RUNNING METHOD
sub run {
my ( $self, $req ) = @_;
my $MaxAge = $self->conf->{bruteForceProtectionMaxAge} + 1;
my $countFailed = 0;
my @lastFailedLoginEpoch = ();
# Auth_N-2 failed login epoch
if ( defined $req->sessionInfo->{_loginHistory}->{failedLogin} ) {
$countFailed = @{ $req->sessionInfo->{_loginHistory}->{failedLogin} };
}
$self->logger->debug(" Number of failedLogin = $countFailed");
return PE_OK
if ( $countFailed <= $self->conf->{bruteForceProtectionMaxFailed} );
foreach ( 0 .. $self->conf->{bruteForceProtectionMaxFailed} - 1 ) {
if ( defined $req->sessionInfo->{_loginHistory}->{failedLogin}->[$_] ) {
push @lastFailedLoginEpoch,
$req->sessionInfo->{_loginHistory}->{failedLogin}->[$_]->{_utime};
}
}
$self->logger->debug("BruteForceProtection enabled");
# If Auth_N-MaxFailed older than MaxAge -> another try allowed
$MaxAge =
$lastFailedLoginEpoch[0] -
$lastFailedLoginEpoch[ $self->conf->{bruteForceProtectionMaxFailed} - 1 ]
if $self->conf->{bruteForceProtectionMaxFailed};
$self->logger->debug(" -> MaxAge = $MaxAge");
return PE_OK
if ( $MaxAge > $self->conf->{bruteForceProtectionMaxAge} );
# Delta between the two last failed logins -> Auth_N - Auth_N-1
my $delta = 0;
$delta = time - $lastFailedLoginEpoch[1]
if defined $lastFailedLoginEpoch[1];
$self->logger->debug(" -> Delta = $delta");
# Delta between the two last failed logins < Tempo => wait
return PE_OK
unless ( $delta <= $self->conf->{bruteForceProtectionTempo} );
# Account locked
return PE_WAIT;
}
1;