Create a Common::Safe module, to be able to disable Safe jail with useSafeJail in Portal (#270)
This commit is contained in:
parent
b7b2681967
commit
0865635a7b
|
@ -20,6 +20,7 @@ lib/Lemonldap/NG/Common/Conf/Serializer.pm
|
|||
lib/Lemonldap/NG/Common/Conf/SOAP.pm
|
||||
lib/Lemonldap/NG/Common/Crypto.pm
|
||||
lib/Lemonldap/NG/Common/Regexp.pm
|
||||
lib/Lemonldap/NG/Common/Safe.pm
|
||||
lib/Lemonldap/NG/Common/Safelib.pm
|
||||
Makefile.PL
|
||||
MANIFEST This list of files
|
||||
|
|
82
modules/lemonldap-ng-common/lib/Lemonldap/NG/Common/Safe.pm
Normal file
82
modules/lemonldap-ng-common/lib/Lemonldap/NG/Common/Safe.pm
Normal file
|
@ -0,0 +1,82 @@
|
|||
## @file
|
||||
# LL::NG module for Safe jail
|
||||
|
||||
## @package
|
||||
# LL::NG module for Safe jail
|
||||
package Lemonldap::NG::Common::Safe;
|
||||
|
||||
use strict;
|
||||
use base qw(Safe);
|
||||
use constant SAFEWRAP => ( Safe->can("wrap_code_ref") ? 1 : 0 );
|
||||
|
||||
our $VERSION = 1.0.2;
|
||||
|
||||
our $self; # Safe cannot share a variable declared with my
|
||||
|
||||
## @constructor Lemonldap::NG::Common::Safe new(Lemonldap::NG::Portal::Simple portal)
|
||||
# Build a new Safe object
|
||||
# @param portal Lemonldap::NG::Portal::Simple object
|
||||
# @return Lemonldap::NG::Common::Safe object
|
||||
sub new {
|
||||
my ( $class, $portal ) = splice @_;
|
||||
my $self = {};
|
||||
|
||||
unless ( $portal->{useSafeJail} ) {
|
||||
|
||||
# Fake jail
|
||||
$portal->lmLog( "Creating a fake Safe jail", 'debug' );
|
||||
bless $self, $class;
|
||||
}
|
||||
else {
|
||||
|
||||
# Safe jail
|
||||
$self = $class->SUPER::new();
|
||||
$portal->lmLog( "Creating a real Safe jail", 'debug' );
|
||||
}
|
||||
|
||||
# Store portal object
|
||||
$self->{p} = $portal;
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
## @method reval(string $e)
|
||||
# Evaluate an expression, inside or outside jail
|
||||
# @param e Expression to evaluate
|
||||
sub reval {
|
||||
local $self = shift;
|
||||
my ($e) = splice @_;
|
||||
my $result;
|
||||
|
||||
# Replace $date
|
||||
$e =~ s/\$date/&POSIX::strftime("%Y%m%d%H%M%S",localtime())/e;
|
||||
|
||||
# Replace variables by session content
|
||||
$e =~ s/\$(?!ENV)(\w+)/\$self->{p}->{sessionInfo}->{$1}/g;
|
||||
|
||||
$self->{p}->lmLog( "Evaluate expression: $e", 'debug' );
|
||||
|
||||
if ( $self->{p}->{useSafeJail} ) {
|
||||
|
||||
# Share $self to access sessionInfo HASH
|
||||
$self->SUPER::share('$self');
|
||||
|
||||
# Test SAFEWRAP and run reval
|
||||
$result = (
|
||||
SAFEWRAP
|
||||
? $self->SUPER::wrap_code_ref( $self->SUPER::reval($e) )
|
||||
: $self->SUPER::reval($e)
|
||||
);
|
||||
}
|
||||
else {
|
||||
|
||||
# Use a standard eval
|
||||
$result = eval $e;
|
||||
}
|
||||
|
||||
$self->{p}->lmLog( "Evaluation result: $result", 'debug' );
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
1;
|
|
@ -187,6 +187,7 @@ t/01-Lemonldap-NG-Portal-Simple.t
|
|||
t/02-Lemonldap-NG-Portal-SharedConf.t
|
||||
t/03-XSS-protection.t
|
||||
t/04-Lemonldap-NG-Portal-SOAP.t
|
||||
t/05-Lemonldap-NG-Portal-Safe.t
|
||||
t/10-Lemonldap-NG-Portal-i18n.t
|
||||
t/20-Lemonldap-NG-Portal-AuthApache.t
|
||||
t/21-Lemonldap-NG-Portal-AuthSSL.t
|
||||
|
|
|
@ -11,7 +11,7 @@ use Lemonldap::NG::Portal::Simple;
|
|||
use Lemonldap::NG::Portal::_LibAccess;
|
||||
use base qw(Lemonldap::NG::Portal::_LibAccess);
|
||||
|
||||
our $VERSION = '1.0.0';
|
||||
our $VERSION = '1.0.2';
|
||||
our $catlevel = 0;
|
||||
|
||||
## @method void menuInit()
|
||||
|
@ -84,7 +84,6 @@ sub displayModules {
|
|||
foreach my $module (@modules) {
|
||||
my $cond = $self->{ 'portalDisplay' . $module };
|
||||
$cond = 1 unless defined $cond;
|
||||
$cond =~ s/\$(\w+)/$self->{sessionInfo}->{$1}/g;
|
||||
|
||||
$self->lmLog( "Evaluate condition $cond for module $module", 'debug' );
|
||||
|
||||
|
|
|
@ -17,10 +17,10 @@ use Lemonldap::NG::Common::CGI;
|
|||
use CGI::Cookie;
|
||||
require POSIX;
|
||||
use Lemonldap::NG::Portal::_i18n; #inherits
|
||||
use Lemonldap::NG::Common::Safelib; #link protected safe Safe object
|
||||
use Lemonldap::NG::Common::Apache::Session
|
||||
; #link protected session Apache::Session object
|
||||
use Safe;
|
||||
use Lemonldap::NG::Common::Safe; #link protected safe Safe object
|
||||
use Lemonldap::NG::Common::Safelib;
|
||||
use Digest::MD5;
|
||||
|
||||
# Special comments for doxygen
|
||||
|
@ -188,9 +188,8 @@ our %EXPORT_TAGS = ( 'all' => [ @EXPORT, 'import' ], );
|
|||
|
||||
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
|
||||
|
||||
# Secure jail
|
||||
# Share secure jail between threads
|
||||
our $safe;
|
||||
our $self; # Safe cannot share a variable declared with my
|
||||
|
||||
BEGIN {
|
||||
eval {
|
||||
|
@ -581,6 +580,7 @@ sub setDefaultValues {
|
|||
|
||||
# Other
|
||||
$self->{logoutServices} ||= {};
|
||||
$self->{useSafeJail} = 1 unless defined $self->{useSafeJail};
|
||||
|
||||
}
|
||||
|
||||
|
@ -1091,7 +1091,10 @@ sub get_module {
|
|||
sub safe {
|
||||
my $self = shift;
|
||||
return $safe if ($safe);
|
||||
$safe = new Safe;
|
||||
|
||||
$safe = Lemonldap::NG::Common::Safe->new($self);
|
||||
|
||||
# Get custom functions
|
||||
my @t =
|
||||
$self->{customFunctions}
|
||||
? split( /\s+/, $self->{customFunctions} )
|
||||
|
@ -1110,10 +1113,17 @@ sub safe {
|
|||
}";
|
||||
$self->lmLog( $@, 'error' ) if ($@);
|
||||
}
|
||||
|
||||
# Share %ENV
|
||||
$safe->share_from( 'main', ['%ENV'] );
|
||||
|
||||
# Share Safelib
|
||||
$safe->share_from( 'Lemonldap::NG::Common::Safelib',
|
||||
$Lemonldap::NG::Common::Safelib::functions );
|
||||
|
||||
# Share custom functions and &encode_base64
|
||||
$safe->share( '&encode_base64', @t );
|
||||
|
||||
return $safe;
|
||||
}
|
||||
|
||||
|
@ -1736,15 +1746,13 @@ sub setSessionInfo {
|
|||
PE_OK;
|
||||
}
|
||||
|
||||
##@apmethod int setMacro()
|
||||
##@apmethod int setMacros()
|
||||
# Macro mechanism.
|
||||
# * store macro results in $self->{sessionInfo}
|
||||
#@return Lemonldap::NG::Portal constant
|
||||
sub setMacros {
|
||||
local $self = shift;
|
||||
$self->safe->share('$self');
|
||||
my $self = shift;
|
||||
while ( my ( $n, $e ) = each( %{ $self->{macros} } ) ) {
|
||||
$e =~ s/\$(?!ENV)(\w+)/\$self->{sessionInfo}->{$1}/g;
|
||||
$self->{sessionInfo}->{$n} = $self->safe->reval($e);
|
||||
}
|
||||
PE_OK;
|
||||
|
@ -1755,11 +1763,9 @@ sub setMacros {
|
|||
# * store all groups name that the user match in $self->{sessionInfo}->{groups}
|
||||
#@return Lemonldap::NG::Portal constant
|
||||
sub setLocalGroups {
|
||||
local $self = shift;
|
||||
my $self = shift;
|
||||
my $groups;
|
||||
$self->safe->share('$self');
|
||||
while ( my ( $group, $expr ) = each %{ $self->{groups} } ) {
|
||||
$expr =~ s/\$(\w+)/\$self->{sessionInfo}->{$1}/g;
|
||||
$groups .= $group . $self->{multiValuesSeparator}
|
||||
if ( $self->safe->reval($expr) );
|
||||
}
|
||||
|
@ -1937,7 +1943,6 @@ sub grantSession {
|
|||
|
||||
# Eval grantSessionRule
|
||||
my $grantSessionRule = $self->{grantSessionRule};
|
||||
$grantSessionRule =~ s/\$(\w+)/\$self->{sessionInfo}->{$1}/g;
|
||||
|
||||
unless ( $self->safe->reval($grantSessionRule) ) {
|
||||
$self->lmLog(
|
||||
|
@ -2070,7 +2075,6 @@ sub issuerForAuthUser {
|
|||
my $rule = $self->{ 'issuerDB' . $issuerDBtype . 'Rule' };
|
||||
|
||||
if ( defined $rule ) {
|
||||
$rule =~ s/\$(\w+)/\$self->{sessionInfo}->{$1}/g;
|
||||
|
||||
$self->lmLog( "Applying rule: $rule", 'debug' );
|
||||
|
||||
|
|
|
@ -6,9 +6,8 @@
|
|||
package Lemonldap::NG::Portal::_LibAccess;
|
||||
|
||||
use strict;
|
||||
use Lemonldap::NG::Common::Safelib; #link protected safe Safe object
|
||||
use Safe;
|
||||
use constant SAFEWRAP => ( Safe->can("wrap_code_ref") ? 1 : 0 );
|
||||
|
||||
our $VERSION = '1.0.2';
|
||||
|
||||
# Global variables
|
||||
our ( $defaultCondition, $locationCondition, $locationRegexp, $cfgNum ) =
|
||||
|
@ -94,15 +93,8 @@ sub _conditionSub {
|
|||
if ( $cond =~ /^(?:accept|unprotect)$/i );
|
||||
return sub { 0 }
|
||||
if ( $cond =~ /^(?:deny$|logout)/i );
|
||||
$cond =~ s/\$date/&POSIX::strftime("%Y%m%d%H%M%S",localtime())/e;
|
||||
$cond =~ s/\$(\w+)/\$self->{sessionInfo}->{$1}/g;
|
||||
my $sub = "sub {my \$self = shift; return ( $cond )}";
|
||||
$sub = (
|
||||
SAFEWRAP
|
||||
? $self->safe->wrap_code_ref( $self->safe->reval($sub) )
|
||||
: $self->safe->reval($sub)
|
||||
);
|
||||
return $sub;
|
||||
return $self->safe->reval($sub);
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -9,11 +9,9 @@ use strict;
|
|||
use Lemonldap::NG::Portal::Simple;
|
||||
use Lemonldap::NG::Portal::_LibAccess;
|
||||
require SOAP::Lite;
|
||||
use Safe;
|
||||
use constant SAFEWRAP => ( Safe->can("wrap_code_ref") ? 1 : 0 );
|
||||
use base qw(Lemonldap::NG::Portal::_LibAccess);
|
||||
|
||||
our $VERSION = '1.0.0';
|
||||
our $VERSION = '1.0.2';
|
||||
|
||||
## @method void startSoapServices()
|
||||
# Check the URI requested (PATH_INFO environment variable) and launch the
|
||||
|
|
49
modules/lemonldap-ng-portal/t/05-Lemonldap-NG-Portal-Safe.t
Normal file
49
modules/lemonldap-ng-portal/t/05-Lemonldap-NG-Portal-Safe.t
Normal file
|
@ -0,0 +1,49 @@
|
|||
# Before `make install' is performed this script should be runnable with
|
||||
# `make test'. After `make install' it should work as `perl Lemonldap-NG-Portal.t'
|
||||
|
||||
#########################
|
||||
|
||||
# change 'tests => 1' to 'tests => last_test_to_print';
|
||||
|
||||
use Test::More tests => 8;
|
||||
|
||||
BEGIN { use_ok( 'Lemonldap::NG::Portal::Simple', ':all' ) }
|
||||
|
||||
#########################
|
||||
|
||||
# Insert your test code below, the Test::More module is use()ed here so read
|
||||
# its man page ( perldoc Test::More ) for help writing this test script.
|
||||
|
||||
|
||||
|
||||
# Create portal object with Safe jail (the default)
|
||||
my $p;
|
||||
$ENV{REQUEST_METHOD} = "GET";
|
||||
ok(
|
||||
$p = Lemonldap::NG::Portal::Simple->new(
|
||||
{
|
||||
globalStorage => 'Apache::Session::File',
|
||||
domain => 'example.com',
|
||||
}
|
||||
),
|
||||
'Portal object'
|
||||
);
|
||||
|
||||
# Fake data
|
||||
my $sessionData = "coudot";
|
||||
$p->{sessionInfo}->{uid} = $sessionData;
|
||||
my $envData = "127.0.0.1";
|
||||
$ENV{REMOTE_ADDR} = $envData;
|
||||
|
||||
# Real Safe jail
|
||||
ok( $p->{useSafeJail} == 1, 'Safe jail on' );
|
||||
ok( $p->safe->reval('$uid') eq $sessionData, 'Safe jail on - session data' );
|
||||
ok( $p->safe->reval('$ENV{REMOTE_ADDR}') eq $envData, 'Safe jail on - env data' );
|
||||
|
||||
# Fake Safe jail
|
||||
$p->{useSafeJail} = 0;
|
||||
ok( $p->{useSafeJail} == 0, 'Safe jail off' );
|
||||
ok( $p->safe->reval('$uid') eq $sessionData, 'Safe jail off - session data' );
|
||||
ok( $p->safe->reval('$ENV{REMOTE_ADDR}') eq $envData, 'Safe jail off - env data' );
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user