Merge branch 'v2.0'

This commit is contained in:
Xavier 2019-06-23 07:21:55 +02:00
commit 9e16e2b75c
11 changed files with 111 additions and 97 deletions

View File

@ -1,2 +1 @@
/usr/sbin/llng-fastcgi-server
/etc/lemonldap-ng/nginx*

View File

@ -1,3 +1,4 @@
/etc/lemonldap-ng/nginx*
/etc/lemonldap-ng/handler-apache2.conf
/etc/lemonldap-ng/handler-nginx.conf
/etc/lemonldap-ng/test-apache2.conf

View File

@ -44,13 +44,13 @@ GetOptions(
);
if ($group) {
my $grp = getgrnam($group) or warn "Can't change uid to $group";
POSIX::setgid($grp);
my $grp = getgrnam($group) or die "Can't change gid to $group";
POSIX::setgid($grp) or die "setgid: $!";
}
if ($user) {
my $uid = getpwnam($user) or warn "Can't change uid to $user";
POSIX::setuid($uid);
my $uid = getpwnam($user) or die "Can't change uid to $user";
POSIX::setuid($uid) or die "setuid: $!";
}
unless ($>) {

View File

@ -10,7 +10,6 @@ package Lemonldap::NG::Common::Apache::Session::Generate::SHA256;
use strict;
use Crypt::URandom;
use Digest::SHA qw(sha256 sha256_hex sha256_base64);
our $VERSION = '2.1.0';
@ -22,15 +21,17 @@ sub generate {
$length = $session->{args}->{IDLength};
}
$session->{data}->{_session_id} = substr(
Digest::SHA::sha256_hex(
Digest::SHA::sha256_hex(
time() . {} . Crypt::URandom::urandom($length) . $$
)
),
0, $length
);
eval {
$session->{data}->{_session_id} =
unpack( 'H*', Crypt::URandom::urandom( int( $length / 2 ) ) );
};
if ($@) {
print STDERR "Crypt::URandom::urandom failed: $@\n";
require Digest::SHA;
$session->{data}->{_session_id} =
substr( Digest::SHA::sha256_hex( time() . {} . rand() . $$ ),
0, $length );
}
}
sub validate {

View File

@ -19,7 +19,6 @@ use Lemonldap::NG::Portal::Main::Constants qw(
PE_OK
PE_SENDRESPONSE
PE_TOKENEXPIRED
PE_INFO
);
our $VERSION = '2.1.0';
@ -31,7 +30,7 @@ extends 'Lemonldap::NG::Portal::Main::Plugin';
has sfModules => ( is => 'rw', default => sub { [] } );
has sfRModules => ( is => 'rw', default => sub { [] } );
has sfReq => ( is => 'rw' );
has sfRule => ( is => 'rw' );
has sfMsgRule => ( is => 'rw' );
has ott => (
is => 'rw',
@ -108,7 +107,7 @@ sub init {
}
unless (
$self->sfRule(
$self->sfMsgRule(
$self->p->HANDLER->buildSub(
$self->p->HANDLER->substitute(
$self->conf->{sfRemovedMsgRule}
@ -202,19 +201,27 @@ sub run {
$self->p->updatePersistentSession( $req,
{ _2fDevices => to_json($_2fDevices) } );
# Display notification or message if required
my $res = 0;
if ( $self->sfRule->( $req, $req->sessionInfo ) ) {
my $notifEngine = $self->p->loadedModules->{
'Lemonldap::NG::Portal::Plugins::Notifications'};
if ( $notifEngine && $self->conf->{sfRemovedUseNotif} ) {
$self->logger->debug("Notifications plugin enabled");
$res =
$self->_sendNotification( $req, $notifEngine, $removed );
}
else {
$res = $self->_sendInfo( $req, $removed );
}
# Display message if required
if ( $self->sfMsgRule->( $req, $req->sessionInfo ) ) {
my $uid = $req->user;
my $date = strftime "%Y-%m-%d", localtime;
my $ref = $self->conf->{sfRemovedNotifRef} || 'RemoveSF';
my $title = $self->conf->{sfRemovedNotifTitle}
|| 'Second factor notification';
my $msg = $self->conf->{sfRemovedNotifMsg}
|| "$removed expired second factor(s) has/have been removed!";
$msg =~ s/_removedSF_/$removed/;
my $params =
$removed > 1
? { trspan => "expired2Fremoved, $removed" }
: { trspan => "oneExpired2Fremoved" };
my $res =
$self->conf->{sfRemovedUseNotif}
? $self->createNotification( $req, $uid, $date, $ref, $title,
$msg )
: $self->displayTemplate( $req, 'simpleInfo', $params );
return $res if $res;
}
}
@ -494,57 +501,4 @@ sub restoreSession {
: $self->_displayRegister( $req, @path );
}
sub _sendInfo {
my ( $self, $req, $removed ) = @_;
$self->logger->debug("Return simpleInfo template");
$req->info(
$self->loadTemplate(
'simpleInfo',
(
$removed > 1
? (
params => {
trspan => "expired2Fremoved, $removed"
}
)
: ( params => { trspan => "oneExpired2Fremoved" } )
)
)
);
return PE_INFO;
}
sub _sendNotification {
my ( $self, $req, $notifEngine, $removed ) = @_;
my $uid = $req->user;
my $date = strftime "%Y-%m-%d", localtime;
my $ref = $self->conf->{sfRemovedNotifRef} || 'RemoveSF';
my $title =
$self->conf->{sfRemovedNotifTitle} || 'Second factor notification';
my $msg = $self->conf->{sfRemovedNotifMsg}
|| "$removed expired second factor(s) has/have been removed!";
$msg =~ s/_removedSF_/$removed/;
# Prepare notification
my $content =
$self->conf->{oldNotifFormat}
? '<?xml version="1.0" encoding="UTF-8"?><root><notification uid="_uid_" date="_date_" reference="_ref_"><title>_title_</title><text>_msg_</text></notification></root>'
: '[{"uid":"_uid_","date":"_date_","title":"_title_","reference":"_ref_","text":"_msg_"}]';
$content =~ s/_uid_/$uid/;
$content =~ s/_ref_/$ref/;
$content =~ s/_date_/$date/;
$content =~ s/_title_/$title/;
$content =~ s/_msg_/$msg/;
if ( $notifEngine->module->notifObject->newNotification($content) ) {
$self->logger->debug("Notification SF successfully appended");
$self->userLogger->notice("Notification SF successfully appended");
return PE_OK;
}
else {
$self->logger->debug("Notification NOT created!");
return $self->_sendInfo( $req, $removed );
}
}
1;

View File

@ -5,6 +5,11 @@ package Lemonldap::NG::Portal::Main::Plugin;
use strict;
use Mouse;
use HTML::Template;
use Lemonldap::NG::Portal::Main::Constants qw(
PE_OK
PE_INFO
PE_ERROR
);
our $VERSION = '2.1.0';
@ -61,6 +66,48 @@ sub loadTemplate {
return $self->p->loadTemplate(@_);
}
sub displayTemplate {
my ( $self, $req, $template, $params ) = @_;
$self->logger->debug("Return $template template");
$req->info(
$self->loadTemplate(
$template, params => $params
)
);
return PE_INFO;
}
sub createNotification {
my ( $self, $req, $uid, $date, $ref, $title, $msg ) = @_;
my $notifEngine = $self->p->loadedModules->{
'Lemonldap::NG::Portal::Plugins::Notifications'};
return PE_ERROR unless $notifEngine;
# Prepare notification
my $content =
$self->conf->{oldNotifFormat}
? '<?xml version="1.0" encoding="UTF-8"?><root><notification uid="_uid_" date="_date_" reference="_ref_"><title>_title_</title><text>_msg_</text></notification></root>'
: '[{"uid":"_uid_","date":"_date_","title":"_title_","reference":"_ref_","text":"_msg_"}]';
$content =~ s/_uid_/$uid/;
$content =~ s/_date_/$date/;
$content =~ s/_ref_/$ref/;
$content =~ s/_title_/$title/;
$content =~ s/_msg_/$msg/;
if ( $notifEngine->module->notifObject->newNotification($content) )
{
$self->logger->debug("Notification $ref successfully created");
$self->userLogger->notice(
"Notification $ref / $date successfully created for $uid");
return PE_OK;
}
else {
$self->logger->debug("Notification $ref NOT created!");
return PE_ERROR;
}
}
1;
__END__

View File

@ -70,7 +70,7 @@ sub run {
$self->logger->debug("No impersonation required")
if ( $spoofId eq $req->{user} );
if ( $spoofId !~ /$self->{conf}->{userControl}/o ) {
unless ( $spoofId =~ /$self->{conf}->{userControl}/o ) {
$self->userLogger->error('Malformed spoofed Id');
$self->logger->debug("Impersonation tried with spoofed Id: $spoofId");
$spoofId = $req->{user};

View File

@ -70,8 +70,7 @@ SKIP: {
my @form = ( $res->[2]->[0] =~ m#<form.*?</form>#sg );
pop @form;
shift @form;
ok( @form == 2, 'Display 2 choices' )
or explain( $res->[2]->[0], '2 forms' );
ok( @form == 3, 'Display 3 choices' ) or explain(scalar(@form),3);
foreach (@form) {
expectForm( [ $res->[0], $res->[1], [$_] ], undef, undef, 'test' );
}

View File

@ -5,7 +5,7 @@ use IO::String;
require 't/test-lib.pm';
my $res;
my $maintests = 0;
my $maintests = 3;
my $client;
eval { unlink 't/userdb.db' };
@ -35,7 +35,15 @@ SKIP: {
$client = iniCmb(
'if($env->{HTTP_X} eq "rtyler") then [Dm] and [DB] else if($env->{HTTP_X} eq "dvador") then [DB] else [DB]'
);
expectCookie( try('rtyler') );
my $id = expectCookie( try('rtyler') );
my $res;
ok( $res = $client->_get("/sessions/global/$id"), 'Get session content' );
ok( $res = eval { JSON::from_json( $res->[2]->[0] ) }, ' GET JSON' )
or print STDERR $@;
ok(
( $res->{demo} eq 'rtyler' and $res->{dbi} eq 'rtyler' ),
' Demo and DBI exported variables exist in session'
);
expectCookie( try('dvador') );
expectReject( try('dwho') );
}
@ -66,10 +74,11 @@ sub iniCmb {
if (
my $res = LLNG::Manager::Test->new( {
ini => {
logLevel => 'error',
useSafeJail => 1,
authentication => 'Combination',
userDB => 'Same',
logLevel => 'error',
useSafeJail => 1,
authentication => 'Combination',
userDB => 'Same',
restSessionServer => 1,
combination => $expr,
combModules => {
@ -90,8 +99,8 @@ sub iniCmb {
dbiAuthLoginCol => 'user',
dbiAuthPasswordCol => 'password',
dbiAuthPasswordHash => '',
dbiExportedVars => {},
demoExportedVars => {},
dbiExportedVars => { dbi => 'user' },
demoExportedVars => { demo => 'uid' },
}
}
)

View File

@ -71,7 +71,7 @@
"LockDirectory": "t/sessions/lock",
"generateModule": "Lemonldap::NG::Common::Apache::Session::Generate::SHA256"
},
"groups": { "su":"$uid eq \"rtyler\"", "test_su": "$uid eq \"rtyler\"", "su_test": "$uid eq \"rtyler\"" },
"groups": { "su":"$uid and $uid eq \"rtyler\"", "test_su": "$uid and $uid eq \"rtyler\"", "su_test": "$uid and $uid eq \"rtyler\"" },
"key": "qwertyui",
"locationRules": {
"auth.example.com" : {

View File

@ -3,7 +3,11 @@
if ( $ENV{LLNGTESTLDAP} ) {
my $slapd_bin = $ENV{LLNGTESTLDAP_SLAPD_BIN} || '/usr/sbin/slapd';
my $slapadd_bin = $ENV{LLNGTESTLDAP_SLAPADD_BIN} || '/usr/sbin/slapadd';
my $slapd_schema_dir = $ENV{LLNGTESTLDAP_SCHEMA_DIR} || '/etc/slapd/schema';
my $slapd_schema_dir =
( $ENV{LLNGTESTLDAP_SCHEMA_DIR}
and -d $ENV{LLNGTESTLDAP_SCHEMA_DIR} ? $ENV{LLNGTESTLDAP_SCHEMA_DIR}
: -d '/etc/slapd/schema' ? '/etc/slapd/schema'
: '/etc/ldap/schema' );
eval { mkdir 't/testslapd/slapd.d' };
eval { mkdir 't/testslapd/data' };
system('cp t/testslapd/slapd.ldif t/testslapd/slapd-test.ldif');