package IdPAccountManager::Tools; use Digest::SHA; use Encode; use Template; use Template::Stash; INIT { ## a TT2 virtual method to get a variable type $Template::Stash::LIST_OPS->{isa} = sub { my ($list, $type) = @_; return 1 if ($type eq 'ARRAY'); return 0; }; $Template::Stash::SCALAR_OPS->{isa} = sub { my ($list, $type) = @_; return 1 if ($type eq 'SCALAR'); return 0; }; } # get SHA256 hash for a string sub sha256_hash { my ($s) = @_; return Digest::SHA::sha256_base64($s); } # 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 ($templates_dir, $conf) = @_; my $tt2 = Template->new({ INCLUDE_PATH => $templates_dir }); my %args = ( accounts => IdPAccountManager::TestAccount::Data::Manager->get_testaccounts(), conf => $conf, ); #chdir $Conf::global{root_manager_dir}; my $template_file = '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)) { return undef; } } ## 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 (%args) = @_; my $tt2_file = $args{template}; my $mail_data = $args{data}; my $logger = $args{logger}; $mail_data->{conf} ||= $args{conf}; my $notice_email = $args{to} || $args{admin_email}; $mail_data->{to} = $notice_email; ## Protection to prevent notifications during test dev phases ## Notify only admin_email or dev_sp_contact addresses if ($args{dev_no_mail_outside}) { my %rcpt = map { $_ => 1 } split(/,/, $notice_email); my %authorized_rcpt = map { $_ => 1 } split( /,/, join(',', $args{admin_email}, $args{dev_sp_contact}) ); my $change_rcpt = 0; foreach my $email (keys %rcpt) { unless ($authorized_rcpt{$email}) { $change_rcpt = 1; last; } } if ($change_rcpt) { $logger->infof( "no_mail_outside option set; notification for %s rerouted to admins ; ", $notice_email ); $notice_email = $args{admin_email}; } } $logger->tracef( sprintf('(template=%s, to=%s)', $in{template}, $mail_data->{to}) ); open SENDMAIL, "|/usr/sbin/sendmail -f " . $args{notice_from} . " $notice_email"; my $tt2 = Template->new(FILTERS => { qencode => [ \qencode, 0 ] }); unless ($tt2->process($tt2_file, $mail_data, \*SENDMAIL)) { $logger->errorf("Error TT2 : %s", $tt2->error()); } close SENDMAIL; } sub qencode { my ($string) = @_; # 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" ); } 1; __END__ =head1 NAME IdPAccountManager::Tools - Set of subroutines usefull for the Test Account manager =head1 DESCRIPTION The Test Account manager instanciates test accounts associated to a SAML Identity Provider. This module gathers a set of usefull subroutines. =head1 SUBROUTINES/METHODS =over 8 =item C<dump_var ($var, $level, $fd)> Dumps a complex perl data structure. $var is a reference to the variable to dump. $level should be set to 0 (subroutine called recursively). $fd is the file descriptor for the output (default is STDOUT). =item C<encode_utf8 ($string)> Return a UTF8 encoded version of $string. =item C<escape_xml ($string)> Escape XML chars in $string. =item C<generate_password> Returns a random password following some security guidelines. =item C<mail_notice (ARGS)> Send a mail notice. Supported arguments include: =over 12 =item C<template> TT2 mail template to parse. =item C<to> Destination email address. =item C<data> A hashref with parameters used to parse the mail template. =back =item C<qencode ($string)> Retunrs a Q-encoded version of $string. =item C<sha256_hash ($string)> Returns a SHA256 hash for $string. =item C<update_ssp_authsources> Update simpleSAMLphp authsources.php configuration file with the currently valid test accounts. =back