lemonldap-ng/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/2F/Mail2F.pm

151 lines
3.8 KiB
Perl
Raw Normal View History

2019-02-03 14:43:44 +01:00
package Lemonldap::NG::Portal::2F::Mail2F;
use strict;
use Mouse;
use Lemonldap::NG::Portal::Main::Constants qw(
2019-03-07 18:22:16 +01:00
PE_BADCREDENTIALS
PE_ERROR
PE_FORMEMPTY
PE_OK
PE_SENDRESPONSE
PE_MUSTHAVEMAIL
2019-02-03 14:43:44 +01:00
);
2019-02-12 18:21:38 +01:00
our $VERSION = '2.1.0';
2019-02-03 14:43:44 +01:00
extends 'Lemonldap::NG::Portal::Main::SecondFactor',
2019-03-07 18:22:16 +01:00
'Lemonldap::NG::Portal::Lib::SMTP';
2019-02-03 14:43:44 +01:00
# INITIALIZATION
has prefix => ( is => 'rw', default => 'mail' );
2019-02-03 14:43:44 +01:00
has random => (
is => 'rw',
default => sub {
return Lemonldap::NG::Common::Crypto::srandom();
2019-02-03 14:43:44 +01:00
}
);
has ott => (
is => 'rw',
lazy => 1,
default => sub {
2019-03-07 18:22:16 +01:00
my $ott =
$_[0]->{p}->loadModule('Lemonldap::NG::Portal::Lib::OneTimeToken');
2019-02-03 14:43:44 +01:00
$ott->timeout( $_[0]->{conf}->{mail2fTimeout}
2019-03-07 18:22:16 +01:00
|| $_[0]->{conf}->{formTimeout} );
2019-02-03 14:43:44 +01:00
return $ott;
}
);
sub init {
my ($self) = @_;
2019-02-14 22:41:58 +01:00
$self->{conf}->{mail2fCodeRegex} ||= '\d{6}';
unless ( $self->conf->{mailSessionKey} ) {
$self->error("Missing 'mailSessionKey' parameter, aborting");
return 0;
2019-02-03 14:43:44 +01:00
}
$self->prefix( $self->conf->{sfPrefix} )
if ( $self->conf->{sfPrefix} );
2019-02-03 14:43:44 +01:00
return $self->SUPER::init();
}
sub run {
my ( $self, $req, $token ) = @_;
my $checkLogins = $req->param('checkLogins');
my $code = $self->random->randregex( $self->conf->{mail2fCodeRegex} );
$self->logger->debug("Generated two-factor code: $code");
$self->ott->updateToken( $token, __mail2fcode => $code );
my $dest = $req->{sessionInfo}->{ $self->conf->{mailSessionKey} };
unless ($dest) {
$self->logger->error( "Could not find mail attribute for login "
2019-03-07 18:22:16 +01:00
. $req->{sessionInfo}->{_user} );
2019-02-03 14:43:44 +01:00
return PE_MUSTHAVEMAIL;
}
# Build mail content
my %tplPrms;
$tplPrms{MAIN_LOGO} = $self->conf->{portalMainLogo};
my $tr = $self->translate($req);
my $subject = $self->conf->{mail2fSubject};
unless ($subject) {
$subject = 'mail2fSubject';
$tr->( \$subject );
}
2019-02-14 22:41:58 +01:00
my ( $body, $html );
2019-02-03 14:43:44 +01:00
if ( $self->conf->{mail2fBody} ) {
# We use a specific text message, no html
$body = $self->conf->{mail2fBody};
}
else {
# Use HTML template
$body = $self->loadTemplate(
$req,
2019-02-03 14:43:44 +01:00
'mail_2fcode',
filter => $tr,
params => \%tplPrms
);
$html = 1;
}
# Replace variables in body
$body =~ s/\$code/$code/g;
$body =~ s/\$(\w+)/$req->{sessionInfo}->{$1} || ''/ge;
# Send mail
unless ( $self->send_mail( $dest, $subject, $body, $html ) ) {
$self->logger->error( 'Unable to send 2F code mail to ' . $dest );
return PE_ERROR;
}
# Prepare form
my $tmp = $self->p->sendHtml(
$req,
'ext2fcheck',
params => {
MAIN_LOGO => $self->conf->{portalMainLogo},
2019-06-28 15:56:57 +02:00
SKIN => $self->p->getSkin($req),
2019-02-03 14:43:44 +01:00
TOKEN => $token,
PREFIX => $self->prefix,
2019-02-03 14:43:44 +01:00
TARGET => '/' . $self->prefix . '2fcheck',
LEGEND => 'enterMail2fCode',
2019-02-03 14:43:44 +01:00
CHECKLOGINS => $checkLogins
}
);
$req->response($tmp);
return PE_SENDRESPONSE;
}
sub verify {
my ( $self, $req, $session ) = @_;
my $usercode;
unless ( $usercode = $req->param('code') ) {
$self->logger->error('Mail2F: no code');
return PE_FORMEMPTY;
}
my $savedcode = $session->{__mail2fcode};
unless ($savedcode) {
$self->logger->error(
'Unable to find generated 2F code in token session');
return PE_ERROR;
}
2019-02-10 22:47:56 +01:00
$self->logger->debug(
"Verifying Mail 2F code: $usercode against $savedcode");
2019-02-03 14:43:44 +01:00
2019-02-10 22:47:56 +01:00
return PE_OK if ( $usercode eq $savedcode );
$self->userLogger->warn( 'Second factor failed for '
2019-03-07 18:22:16 +01:00
. $session->{ $self->conf->{whatToTrace} } );
2019-02-10 22:47:56 +01:00
return PE_BADCREDENTIALS;
2019-02-03 14:43:44 +01:00
}
1;