2009-04-21 15:24:38 +02:00
|
|
|
##@file
|
|
|
|
# Functions shared in Safe jail
|
|
|
|
|
|
|
|
##@class
|
|
|
|
# Functions shared in Safe jail
|
2009-04-05 10:12:16 +02:00
|
|
|
package Lemonldap::NG::Common::Safelib;
|
|
|
|
|
|
|
|
use strict;
|
2010-06-11 15:00:05 +02:00
|
|
|
use Encode;
|
|
|
|
use MIME::Base64;
|
2017-03-17 17:31:17 +01:00
|
|
|
use Lemonldap::NG::Common::IPv6;
|
2009-04-05 10:12:16 +02:00
|
|
|
|
|
|
|
#use AutoLoader qw(AUTOLOAD);
|
|
|
|
|
2019-11-05 19:15:35 +01:00
|
|
|
our $VERSION = '2.0.7';
|
2009-04-05 10:12:16 +02:00
|
|
|
|
|
|
|
# Set here all the names of functions that must be available in Safe objects.
|
|
|
|
# Not that only functions, not methods, can be written here
|
2010-06-11 15:00:05 +02:00
|
|
|
our $functions =
|
2015-09-28 13:12:53 +02:00
|
|
|
[
|
2019-11-05 17:16:07 +01:00
|
|
|
qw(&checkLogonHours &date &checkDate &basic &unicode2iso &iso2unicode &groupMatch &isInNet6 &varIsInUri)
|
2015-09-28 13:12:53 +02:00
|
|
|
];
|
2009-04-21 15:24:38 +02:00
|
|
|
|
|
|
|
## @function boolean checkLogonHours(string logon_hours, string syntax, string time_correction, boolean default_access)
|
|
|
|
# Function to check logon hours
|
|
|
|
# @param $logon_hours string representing allowed logon hours (GMT)
|
|
|
|
# @param $syntax optional hexadecimal (default) or octetstring
|
|
|
|
# @param $time_correction optional hours to add or to subtract
|
|
|
|
# @param $default_access optional what result to return for users without logons hours
|
|
|
|
# @return 1 if access allowed, 0 else
|
|
|
|
sub checkLogonHours {
|
2016-01-02 10:29:05 +01:00
|
|
|
my ( $logon_hours, $syntax, $time_correction, $default_access ) = @_;
|
2009-04-21 15:24:38 +02:00
|
|
|
|
|
|
|
# Active Directory - logonHours: $attr_src_syntax = octetstring
|
|
|
|
# Samba - sambaLogonHours: ???
|
|
|
|
# LL::NG - ssoLogonHours: $attr_src_syntax = hexadecimal
|
|
|
|
$syntax ||= "hexadecimal";
|
|
|
|
|
|
|
|
# Default access if no value
|
|
|
|
$default_access ||= "0";
|
|
|
|
return $default_access unless $logon_hours;
|
|
|
|
|
|
|
|
# Get the base2 value of logon_hours
|
|
|
|
# Each byte represent an hour of the week
|
|
|
|
# Begin with sunday at 0h00
|
|
|
|
my $base2_logon_hours;
|
|
|
|
if ( $syntax eq "octetstring" ) {
|
2010-03-01 21:32:28 +01:00
|
|
|
$base2_logon_hours = unpack( "B*", $logon_hours );
|
2009-04-21 15:24:38 +02:00
|
|
|
}
|
|
|
|
if ( $syntax eq "hexadecimal" ) {
|
2010-03-01 21:32:28 +01:00
|
|
|
|
2009-04-21 15:24:38 +02:00
|
|
|
# Remove white spaces
|
|
|
|
$logon_hours =~ s/ //g;
|
2010-03-01 21:32:28 +01:00
|
|
|
$base2_logon_hours = unpack( "B*", pack( "H*", $logon_hours ) );
|
2009-04-21 15:24:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
# Get the present day and hour
|
2010-03-01 21:32:28 +01:00
|
|
|
my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) =
|
|
|
|
gmtime(time);
|
2009-04-21 15:24:38 +02:00
|
|
|
|
|
|
|
# Get the hour position
|
2010-03-01 21:32:28 +01:00
|
|
|
my $hourpos = $wday * 24 + $hour;
|
|
|
|
|
2009-04-21 15:24:38 +02:00
|
|
|
# Use time_correction
|
|
|
|
if ($time_correction) {
|
2010-03-01 21:32:28 +01:00
|
|
|
my ( $sign, $time ) = ( $time_correction =~ /([+|-]?)(\d+)/ );
|
2020-02-20 23:34:02 +01:00
|
|
|
if ( $sign =~ /-/ ) { $hourpos -= $time; }
|
|
|
|
else { $hourpos += $time; }
|
2009-04-21 15:24:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
# Get the corresponding byte
|
2010-03-01 21:32:28 +01:00
|
|
|
return substr( $base2_logon_hours, $hourpos, 1 );
|
2009-04-21 15:24:38 +02:00
|
|
|
}
|
|
|
|
|
2019-11-15 19:42:15 +01:00
|
|
|
## @function integer listMatch
|
|
|
|
# Test if a value is found in a collection
|
|
|
|
# @param $list Can be a hash, array or string including the separator
|
|
|
|
# @param $value string The value to search for
|
|
|
|
# @param $ignorecase boolean Be case insensitive
|
|
|
|
# @return 1 if the value was found, 0 else
|
|
|
|
# NOTE: this function is not exported directly in this module because we don't
|
|
|
|
# want the usr to have to worry about separator. Is is wrapped in a closure in
|
|
|
|
# Jail.pm
|
|
|
|
sub listMatch {
|
|
|
|
my ( $sep, $list, $value, $ignorecase ) = @_;
|
|
|
|
my $flags = $ignorecase ? 'i' : '';
|
|
|
|
my @a;
|
|
|
|
if ( ref($list) eq "ARRAY" ) {
|
|
|
|
@a = @{$list};
|
|
|
|
}
|
|
|
|
elsif ( ref($list) eq "HASH" ) {
|
|
|
|
@a = keys %{$list};
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
@a = split $sep, $list;
|
|
|
|
}
|
|
|
|
if ( grep /(?$flags)^\Q$value\E$/, @a ) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-04 10:36:38 +02:00
|
|
|
## @function integer date
|
|
|
|
# Get current local date
|
|
|
|
# @param $gmt optional boolean To return GMT date (default is local date)
|
|
|
|
# @return current date on format YYYYMMDDHHMMSS
|
|
|
|
sub date {
|
|
|
|
my $gmt = shift;
|
2014-07-24 17:48:32 +02:00
|
|
|
my ( $sec, $min, $hour, $mday, $mon, $year ) = $gmt ? gmtime : localtime;
|
2014-07-04 10:36:38 +02:00
|
|
|
|
|
|
|
$year += 1900;
|
|
|
|
$mon += 1;
|
|
|
|
$mon = "0" . $mon if ( $mon < 10 );
|
|
|
|
$mday = "0" . $mday if ( $mday < 10 );
|
|
|
|
$hour = "0" . $hour if ( $hour < 10 );
|
|
|
|
$min = "0" . $min if ( $min < 10 );
|
|
|
|
$sec = "0" . $sec if ( $sec < 10 );
|
|
|
|
|
|
|
|
return $year . $mon . $mday . $hour . $min . $sec;
|
|
|
|
}
|
|
|
|
|
2009-04-21 15:25:54 +02:00
|
|
|
## @function boolean checkDate(string start, string end, boolean default_access)
|
2009-04-21 15:24:38 +02:00
|
|
|
# Function to check a date
|
|
|
|
# @param $start string Start date (GMT)
|
|
|
|
# @param $end string End date (GMT)
|
|
|
|
# @param $default_access optional what result to return for users without start or end start
|
|
|
|
# @return 1 if access allowed, 0 else
|
|
|
|
sub checkDate {
|
2016-01-02 10:29:05 +01:00
|
|
|
my ( $start, $end, $default_access ) = @_;
|
2009-04-21 15:24:38 +02:00
|
|
|
|
|
|
|
# Get date in string
|
2010-03-01 21:32:28 +01:00
|
|
|
$start = substr( $start, 0, 14 );
|
|
|
|
$end = substr( $end, 0, 14 );
|
2009-04-21 15:24:38 +02:00
|
|
|
|
|
|
|
# Default access if no value
|
|
|
|
$default_access ||= "0";
|
2010-03-01 21:32:28 +01:00
|
|
|
return $default_access unless ( $start or $end );
|
2009-04-21 15:24:38 +02:00
|
|
|
|
|
|
|
# If no start, set start to 0
|
|
|
|
$start ||= 0;
|
|
|
|
|
|
|
|
# If no end, set end to the end of the world
|
|
|
|
$end ||= 999999999999999;
|
|
|
|
|
|
|
|
# Get the present day and hour
|
2014-07-04 10:36:38 +02:00
|
|
|
my $date = &date;
|
2009-04-21 15:24:38 +02:00
|
|
|
|
2010-03-01 21:32:28 +01:00
|
|
|
return 1 if ( ( $date >= $start ) and ( $date <= $end ) );
|
2009-04-21 15:24:38 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-06-11 15:00:05 +02:00
|
|
|
## @function string basic(string login, string password)
|
|
|
|
# Return string that can be used for HTTP-BASIC authentication
|
|
|
|
# @param login User login
|
|
|
|
# @param password User password
|
|
|
|
# @return Authorization header content
|
|
|
|
sub basic {
|
2016-01-02 10:29:05 +01:00
|
|
|
my ( $login, $password ) = @_;
|
2010-06-11 15:00:05 +02:00
|
|
|
|
|
|
|
# UTF-8 strings should be ISO encoded
|
|
|
|
$login = &unicode2iso($login);
|
|
|
|
$password = &unicode2iso($password);
|
|
|
|
|
2016-03-09 20:46:33 +01:00
|
|
|
return "Basic " . encode_base64( $login . ":" . $password, '' );
|
2010-06-11 15:00:05 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
## @function string unicode2iso(string string)
|
|
|
|
# Convert UTF-8 in ISO-8859-1
|
|
|
|
# @param string UTF-8 string
|
|
|
|
# @return ISO string
|
|
|
|
sub unicode2iso {
|
2016-01-02 10:29:05 +01:00
|
|
|
my ($string) = @_;
|
2010-06-11 15:00:05 +02:00
|
|
|
|
|
|
|
return encode( "iso-8859-1", decode( "utf-8", $string ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
## @function string iso2unicode(string string)
|
|
|
|
# Convert ISO-8859-1 in UTF-8
|
|
|
|
# @param string ISO string
|
|
|
|
# @return UTF-8 string
|
|
|
|
sub iso2unicode {
|
2016-01-02 10:29:05 +01:00
|
|
|
my ($string) = @_;
|
2010-06-11 15:00:05 +02:00
|
|
|
|
|
|
|
return encode( "utf-8", decode( "iso-8859-1", $string ) );
|
|
|
|
}
|
|
|
|
|
2015-09-28 13:12:53 +02:00
|
|
|
## @function int groupMatch(hashref groups, string attribute, string value)
|
|
|
|
# Check in hGroups structure if a group attribute contains a value
|
|
|
|
# @param groups The $hGroups variable
|
|
|
|
# @param attribute Name of the attribute
|
|
|
|
# @param value Value to check
|
|
|
|
# @return int Number of values that match
|
|
|
|
sub groupMatch {
|
2016-03-23 13:55:09 +01:00
|
|
|
my ( $groups, $attribute, $value ) = @_;
|
2015-09-28 13:12:53 +02:00
|
|
|
|
|
|
|
my $match = 0;
|
|
|
|
|
|
|
|
foreach my $group ( keys %$groups ) {
|
|
|
|
if ( ref( $groups->{$group}->{$attribute} ) eq "ARRAY" ) {
|
|
|
|
foreach ( @{ $groups->{$group}->{$attribute} } ) {
|
|
|
|
$match++ if ( $_ =~ /$value/ );
|
|
|
|
}
|
|
|
|
}
|
2015-09-28 16:12:08 +02:00
|
|
|
else {
|
|
|
|
$match++ if ( $groups->{$group}->{$attribute} =~ /$value/ );
|
|
|
|
}
|
2015-09-28 13:12:53 +02:00
|
|
|
}
|
|
|
|
return $match;
|
|
|
|
}
|
|
|
|
|
2017-03-17 17:31:17 +01:00
|
|
|
sub isInNet6 {
|
|
|
|
my ( $ip, $net ) = @_;
|
|
|
|
$net =~ s#/(\d+)##;
|
|
|
|
my $bits = $1;
|
|
|
|
return net6( $ip, $bits ) eq net6( $net, $bits ) ? 1 : 0;
|
|
|
|
}
|
|
|
|
|
2019-11-05 17:16:07 +01:00
|
|
|
sub varIsInUri {
|
|
|
|
my ( $uri, $wanteduri, $attribute, $restricted ) = @_;
|
|
|
|
return $restricted
|
|
|
|
? $uri =~ /$wanteduri$attribute$/o
|
|
|
|
: $uri =~ /$wanteduri$attribute/o;
|
|
|
|
}
|
|
|
|
|
2009-04-05 10:12:16 +02:00
|
|
|
1;
|