File Coverage

blib/lib/Lemonldap/NG/Handler/Main/Jail.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package Lemonldap::NG::Handler::Main::Jail;
2              
3 2     2   29261 use strict;
  2         4  
  2         83  
4              
5 2     2   2233 use Safe;
  2         57737  
  2         104  
6 2     2   491 use Lemonldap::NG::Common::Safelib; #link protected safe Safe object
  0            
  0            
7             use constant SAFEWRAP => ( Safe->can("wrap_code_ref") ? 1 : 0 );
8             use Mouse;
9             use Lemonldap::NG::Handler::Main::Logger;
10              
11             has customFunctions => ( is => 'rw', isa => 'Maybe[Str]' );
12              
13             has useSafeJail => ( is => 'rw', isa => 'Maybe[Int]' );
14              
15             has safe => ( is => 'rw' );
16              
17             our $VERSION = '1.3.1';
18              
19             # for accessing $datas and $apacheRequest
20             use Lemonldap::NG::Handler::Main ':jailSharedVars';
21              
22             ## @imethod protected build_safe()
23             # Build and return the security jail used to compile rules and headers.
24             # @return Safe object
25             sub build_safe {
26             my $self = shift;
27              
28             return $self->safe if ( $self->safe );
29              
30             $self->useSafeJail(1) unless defined $self->useSafeJail;
31              
32             my @t =
33             $self->customFunctions ? split( /\s+/, $self->customFunctions ) : ();
34             foreach (@t) {
35             Lemonldap::NG::Handler::Main::Logger->lmLog( "Custom function : $_",
36             'debug' );
37             my $sub = $_;
38             unless (/::/) {
39             $sub = "$self\::$_";
40             }
41             else {
42             s/^.*:://;
43             }
44             next if ( $self->can($_) );
45             eval "sub $_ {
46             my \$uri = \$Lemonldap::NG::Handler::Main::apacheRequest->unparsed_uri();
47             Apache2::URI::unescape_url(\$uri);
48             return $sub(\$uri, \@_)
49             }";
50             Lemonldap::NG::Handler::Main::Logger->lmLog( $@, 'error' ) if ($@);
51             }
52              
53             if ( $self->useSafeJail ) {
54             $self->safe( Safe->new );
55             $self->safe->share_from( 'main', ['%ENV'] );
56             }
57             else {
58             $self->safe($self);
59             }
60              
61             # Share objects with Safe jail
62             $self->safe->share_from( 'Lemonldap::NG::Common::Safelib',
63             $Lemonldap::NG::Common::Safelib::functions );
64              
65             $self->safe->share_from( 'Lemonldap::NG::Handler::Main',
66             [ '$datas', '$apacheRequest', '&ip', '&portal' ] );
67             $self->safe->share(@t);
68             $self->safe->share_from( 'MIME::Base64', ['&encode_base64'] );
69              
70             return $self->safe;
71             }
72              
73             ## @method reval
74             # Fake reval method if useSafeJail is off
75             sub reval {
76             my ( $self, $e ) = splice @_;
77             return eval $e;
78             }
79              
80             ## @method wrap_code_ref
81             # Fake wrap_code_ref method if useSafeJail is off
82             sub wrap_code_ref {
83             my ( $self, $e ) = splice @_;
84             return $e;
85             }
86              
87             ## @method share
88             # Fake share method if useSafeJail is off
89             sub share {
90             my ( $self, @vars ) = splice @_;
91             $self->share_from( scalar(caller), \@vars );
92             }
93              
94             ## @method share_from
95             # Fake share_from method if useSafeJail is off
96             sub share_from {
97             my ( $self, $pkg, $vars ) = splice @_;
98              
99             no strict 'refs';
100             foreach my $arg (@$vars) {
101             my ( $var, $type );
102             $type = $1 if ( $var = $arg ) =~ s/^(\W)//;
103             for ( 1 .. 2 ) { # assign twice to avoid any 'used once' warnings
104             *{$var} =
105             ( !$type ) ? \&{ $pkg . "::$var" }
106             : ( $type eq '&' ) ? \&{ $pkg . "::$var" }
107             : ( $type eq '$' ) ? \${ $pkg . "::$var" }
108             : ( $type eq '@' ) ? \@{ $pkg . "::$var" }
109             : ( $type eq '%' ) ? \%{ $pkg . "::$var" }
110             : ( $type eq '*' ) ? *{ $pkg . "::$var" }
111             : undef;
112             }
113             }
114             }
115              
116             ## @imethod protected jail_reval()
117             # Build and return restricted eval command with SAFEWRAP, if activated
118             # @return evaluation of $reval or $reval2
119             sub jail_reval {
120             my ( $self, $reval ) = splice @_;
121              
122             # if nothing is returned by reval, add the return statement to
123             # the "no safe wrap" reval
124             my $nosw_reval = $reval;
125             if ( $reval !~ /^sub\{return\(.*\}$/ ) {
126             $nosw_reval =~ s/^sub{(.*)}$/sub{return($1)}/;
127             }
128              
129             return (
130             SAFEWRAP
131             ? $self->safe->wrap_code_ref( $self->safe->reval($reval) )
132             : $self->safe->reval($nosw_reval)
133             );
134              
135             }
136              
137             1;