120 lines
3.1 KiB
Perl
120 lines
3.1 KiB
Perl
package Lemonldap::NG::Portal::2F::Radius;
|
|
|
|
use strict;
|
|
use Mouse;
|
|
use Lemonldap::NG::Portal::Main::Constants qw(
|
|
PE_BADOTP
|
|
PE_ERROR
|
|
PE_MALFORMEDUSER
|
|
PE_OK
|
|
PE_SENDRESPONSE
|
|
);
|
|
|
|
our $VERSION = '2.0.10';
|
|
|
|
extends 'Lemonldap::NG::Portal::Main::SecondFactor';
|
|
|
|
# INITIALIZATION
|
|
|
|
has prefix => ( is => 'rw', default => 'radius' );
|
|
has radius => ( is => 'rw' );
|
|
|
|
sub init {
|
|
my ($self) = @_;
|
|
|
|
foreach (qw(radius2fSecret radius2fServer)) {
|
|
unless ( $self->conf->{$_} ) {
|
|
$self->error("Missing $_ parameter, aborting");
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
eval { require Authen::Radius };
|
|
if ($@) {
|
|
$self->error("Unable to load Authen::Radius: $@");
|
|
return 0;
|
|
}
|
|
|
|
$self->error('Radius connect failed')
|
|
unless (
|
|
$self->radius(
|
|
Authen::Radius->new(
|
|
Host => $self->conf->{radius2fServer},
|
|
Secret => $self->conf->{radius2fSecret},
|
|
TimeOut => $self->conf->{radius2fTimeout},
|
|
)
|
|
)
|
|
);
|
|
|
|
$self->prefix( $self->conf->{sfPrefix} )
|
|
if ( $self->conf->{sfPrefix} );
|
|
return $self->SUPER::init();
|
|
}
|
|
|
|
sub run {
|
|
my ( $self, $req, $token ) = @_;
|
|
|
|
my $checkLogins = $req->param('checkLogins');
|
|
$self->logger->debug("Radius2F: checkLogins set") if $checkLogins;
|
|
|
|
my $stayconnected = $req->param('stayconnected');
|
|
$self->logger->debug("Radius2F: stayconnected set") if $stayconnected;
|
|
|
|
# Prepare form
|
|
my $tmp = $self->p->sendHtml(
|
|
$req,
|
|
'ext2fcheck',
|
|
params => {
|
|
MAIN_LOGO => $self->conf->{portalMainLogo},
|
|
SKIN => $self->p->getSkin($req),
|
|
TOKEN => $token,
|
|
PREFIX => $self->prefix,
|
|
TARGET => '/'
|
|
. $self->prefix
|
|
. '2fcheck?skin='
|
|
. $self->p->getSkin($req),
|
|
LEGEND => 'enterRadius2fCode',
|
|
CHECKLOGINS => $checkLogins,
|
|
STAYCONNECTED => $stayconnected
|
|
}
|
|
);
|
|
$self->logger->debug("Prepare Radius 2F verification");
|
|
|
|
$req->response($tmp);
|
|
return PE_SENDRESPONSE;
|
|
}
|
|
|
|
sub verify {
|
|
my ( $self, $req, $session ) = @_;
|
|
|
|
# Some Radius Servers allow empty codes and perform
|
|
# out of band, interactive verification (InWebo...)
|
|
my $code = $req->param('code');
|
|
|
|
# Launch Radius request
|
|
my $userAttr =
|
|
$self->conf->{radius2fUsernameSessionKey} || $self->conf->{whatToTrace};
|
|
my $username = $session->{$userAttr};
|
|
unless ($username) {
|
|
$self->logger->error(
|
|
"Could not find Radius username from session attribute $userAttr");
|
|
return PE_MALFORMEDUSER;
|
|
}
|
|
|
|
$self->logger->debug("Checking Radius credentials $username:$code");
|
|
|
|
my $res = $self->radius->check_pwd( $username, $code );
|
|
unless ( $res == 1 ) {
|
|
$self->userLogger->warn( "Radius second factor failed for "
|
|
. $session->{ $self->conf->{whatToTrace} } );
|
|
$self->logger->warn(
|
|
"Radius server replied: " . $self->radius->get_error );
|
|
return PE_BADOTP;
|
|
}
|
|
|
|
$self->logger->debug("Radius server accepted 2F credentials");
|
|
return PE_OK;
|
|
}
|
|
|
|
1;
|