Newer
Older
package IdPAccountManager::Tools;
use Template;
renater.salaun
committed
use Encode;
my %log_levels = ('debug' => 0, 'info' => 1, 'trace' => 1, 'notice' => 2, 'error' => 3);
# get SHA256 hash for a string
sub sha256_hash {
my $s = shift;
return &Digest::SHA::sha256_base64($s);
}
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# This function generates a random password
sub generate_password{
my $length_of_randomstring=10;# the length of
# the random string to generate
# plusieurs tirages :
# 1-tirage des caractères obligatoires : les mettre dans un tableau
my @uppers=('A'..'N','P'..'Z');
my @lowers=('a'..'k','m'..'z');
my @punctuation=('%',';',':','!','?','&','$','*','(',')','{','}','[',']','<','>','.','=','-','#');
my @numerics=('0'..'9');
my @rndtab;
push(@rndtab,$uppers[rand @uppers]);
push(@rndtab,$lowers[rand @lowers]);
push(@rndtab,$punctuation[rand @punctuation]);
## Pas de caractères 8bit pour l'antispam
push(@rndtab,$numerics[rand @numerics]);
# 2-tirage des caractères optionnels : les ajouter au tableau
my @chars=('a'..'k','m'..'z','A'..'N','P'..'Z','0'..'9','_','%',';',':','!','?','&','$','*','(',')','{','}','[',']','<','>','.','=','-','#');
foreach (6..$length_of_randomstring) {
# rand @chars will generate a random
# number between 0 and scalar @chars
push(@rndtab,$chars[rand @chars]);
}
# 3-ordonnancement de ceux-ci : les retirer aléatoirement du tableau en les concaténant dans une chaîne
my $rndstring='';
my $cpt=1;
while($cpt<=$length_of_randomstring) {
my $indice = rand @rndtab;
$rndstring.=$rndtab[$indice];
splice (@rndtab, $indice, 1);
$cpt+=1;
}
return $rndstring;
}
## Updates simpleSamlPhp authsources.php configuration file
sub update_ssp_authsources {
my $tt2 = Template->new({'INCLUDE_PATH' => $Conf::global{'root_manager_dir'}.':'.$Conf::global{'root_manager_dir'}.'/templates/accountProfiles'});
my %args = ('accounts' => IdPAccountManager::TestAccount::list_test_accounts(),
#chdir $Conf::global{'root_manager_dir'};
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
my $template_file = 'templates/accountProfiles/valid-accounts.php.tt2';
my $output_file = 'conf/valid-accounts.php';
#printf "Trace : in=%s, out=%s\n", $template_file, $output_file;
unless ($tt2->process($template_file, \%args, $output_file)) {
IdPAccountManager::Tools::do_log('error', "Failed to update valid-accounts.php: %s", $tt2->error());
return undef;
}
}
## Dump a variable's content
sub dump_var {
my ($var, $level, $fd) = @_;
if (ref($var)) {
if (ref($var) eq 'ARRAY') {
foreach my $index (0..$#{$var}) {
print $fd "\t"x$level.$index."\n";
&dump_var($var->[$index], $level+1, $fd);
}
}elsif (ref($var) eq 'HASH') {
foreach my $key (sort keys %{$var}) {
print $fd "\t"x$level.'_'.$key.'_'."\n";
&dump_var($var->{$key}, $level+1, $fd);
}
}else {
if (defined $var) {
print $fd "\t"x$level."'$var'"."\n";
}else {
print $fd "\t"x$level."UNDEF\n";
}
}
}else {
if (defined $var) {
print $fd "\t"x$level."'$var'"."\n";
}else {
print $fd "\t"x$level."UNDEF\n";
}
}
}
sub do_log {
my $level = shift;
my $message = shift;
unless ($log_levels{$level} < $log_levels{$Conf::global{'log_level'}}) {
## Determine calling function and parameters
## If in 'err' level, build a stack trace
my $caller_string;
if ($level eq 'error'){
my $go_back = 1;
my @calls;
while (my @call = caller($go_back)) {
unshift @calls, $call[3].'#'.$call[2];
$go_back++;
}
$caller_string = join(' > ',@calls);
}else {
my @call = caller(1);
$caller_string = $call[3].'()';
}
$level = uc($level);
my $ip = $ENV{'REMOTE_HOST'}.'/'.$ENV{'REMOTE_ADDR'} || 'NOIP';
my $date = POSIX::strftime ("%Y:%m:%d %H:%M:%S", localtime(time));
my $user = lc($ENV{'mail'}) || 'NOEMAIL';
open LOG, ">>".$Conf::global{'log_file'}; printf LOG "$date - ($level) - $ip - $user - $caller_string $message\n", @_; close LOG;
}
return 1;
}
## Send a mail notice
## Default is to send email to the manager admins, unless other recipients are specified
## mail_notice(IN)
## IN is a HASH with expected entries :
## template : mail template file
## data : data used by the TT2 parser
sub mail_notice {
my %in = @_;
my $tt2_file = $in{'template'};
my $mail_data = $in{'data'};
$mail_data->{'conf'} ||= \%Conf::global;
my $notice_email = $in{'to'} || $Conf::global{'admin_email'};
$mail_data->{'to'} = $notice_email;
## Protection to prevent notifications during test dev phases
## Notify only admin_email
if ($Conf::global{'no_mail_outside'}) {
&do_log('info',"no_mail_outside option set; notification for %s rerouted to admins ; ", $notice_email);
$notice_email = $Conf::global{'admin_email'};
}
&do_log('trace', '(template=%s, to=%s)', $in{'template'}, $mail_data->{'to'});
open SENDMAIL, "|/usr/sbin/sendmail -f ".$Conf::global{'notice_from'}." $notice_email";
my $tt2 = Template->new(FILTERS => {qencode => [\&qencode, 0]});
unless ($tt2->process($tt2_file, $mail_data, \*SENDMAIL)) {
renater.salaun
committed
&do_log('error', "Error TT2 : %s", $tt2->error());
}
close SENDMAIL;
}
sub qencode {
my $string = shift;
# We are not able to determine the name of header field, so assume
# longest (maybe) one.
return MIME::EncWords::encode_mimewords(Encode::decode('utf8', $string),
Encoding=>'A',
Charset=> 'utf8',
Field=>"subject");
}
## usefull to pass parameters to TT2
sub encode_utf8 ($) {
my $string = shift||'';
return Encode::encode('utf8', $string);
}
renater.salaun
committed
## Escape characters that may interfer in an XML document
sub escape_xml {
my $s = shift;
$s =~ s/\&/&\;/gm;
$s =~ s/\"/"\;/gm;
$s =~ s/\</<\;/gm;
$s =~ s/\>/>\;/gm;
$s =~ s/\'/'/gm;
return $s;
}
## usefull to pass parameters to TT2
sub escape_quotes {
my $string = shift;
$string =~ s/\'/\\\'/g;
return $string;
}
renater.salaun
committed
## returns an integer (0 or 1), given an input string ('true' or 'false')
sub boolean2integer {
my $boolean = shift;
if ($boolean eq 'true') {
return 1;
}elsif ($boolean eq 'false') {
return 0;
}
return undef;
}
1; # Magic true value required at end of module
__END__
=head1 NAME
IdPAccountManager::Tools - Set of subroutines usefull for the Account manager
=head1 SYNOPSIS
=head1 DESCRIPTION
=head1 SUBROUTINES/METHODS
=head1 AUTHOR
Olivier Salaün (olivier.salaun@renater.fr)