2018-09-18 14:51:58 +02:00
|
|
|
#!/usr/bin/perl
|
|
|
|
|
|
|
|
use strict;
|
|
|
|
use Getopt::Long;
|
|
|
|
use Lemonldap::NG::Common::Conf;
|
|
|
|
use LWP::UserAgent;
|
|
|
|
use MIME::Base64;
|
|
|
|
use XML::LibXML;
|
2021-06-28 21:45:11 +02:00
|
|
|
|
|
|
|
sub toEntityIDkey {
|
2021-06-29 15:23:02 +02:00
|
|
|
my ( $prefix, $entityID ) = @_;
|
2021-06-28 21:45:11 +02:00
|
|
|
|
2021-06-29 15:23:02 +02:00
|
|
|
my $entityIDKey = $entityID;
|
|
|
|
$entityIDKey =~ s/^https?:\/\///;
|
|
|
|
$entityIDKey =~ s/[^a-zA-Z0-9]/-/g;
|
|
|
|
$entityIDKey =~ s/-+$//g;
|
|
|
|
return ( $prefix . $entityIDKey );
|
2021-06-28 21:45:11 +02:00
|
|
|
}
|
|
|
|
|
2018-09-18 14:51:58 +02:00
|
|
|
#==============================================================================
|
|
|
|
# Get command line options
|
|
|
|
#==============================================================================
|
|
|
|
my %opts;
|
2018-10-22 18:33:08 +02:00
|
|
|
my $result = GetOptions(
|
2021-06-29 15:18:01 +02:00
|
|
|
\%opts, 'metadata|m=s',
|
|
|
|
'verbose|v', 'help|h',
|
|
|
|
'spconfprefix|s=s', 'idpconfprefix|i=s',
|
|
|
|
'remove|r', 'nagios|a',
|
|
|
|
'ignore-sp=s@', 'ignore-idp=s@',
|
|
|
|
'dry-run|n'
|
2018-10-22 18:33:08 +02:00
|
|
|
);
|
2018-09-18 14:51:58 +02:00
|
|
|
|
|
|
|
#==============================================================================
|
|
|
|
# Help
|
|
|
|
#==============================================================================
|
|
|
|
if ( $opts{help} or !$opts{metadata} ) {
|
|
|
|
print STDERR
|
|
|
|
"\nScript to import SAML metadata bundle file into LL::NG configuration\n\n";
|
|
|
|
print STDERR "Usage: $0 -m <metadata file URL>\n\n";
|
|
|
|
print STDERR "Options:\n";
|
2021-06-29 15:18:01 +02:00
|
|
|
print STDERR
|
|
|
|
"\t-i (--idpconfprefix): Prefix used to set IDP configuration key\n";
|
2018-09-18 14:51:58 +02:00
|
|
|
print STDERR "\t-h (--help): print this message\n";
|
|
|
|
print STDERR "\t-m (--metadata): URL of metadata document\n";
|
2021-06-29 15:18:01 +02:00
|
|
|
print STDERR
|
|
|
|
"\t-s (--spconfprefix): Prefix used to set SP configuration key\n";
|
|
|
|
print STDERR
|
|
|
|
"\t--ignore-sp: ignore SP maching this entityID (can be specified multiple times)\n";
|
|
|
|
print STDERR
|
|
|
|
"\t--ignore-idp: ignore IdP matching this entityID (can be specified multiple times)\n";
|
|
|
|
print STDERR "\t-a (--nagios) : output statistics in Nagios format\n";
|
2021-06-29 15:34:48 +02:00
|
|
|
print STDERR "\t-n (--dry-run): print statistics but do not apply changes\n";
|
|
|
|
print STDERR "\t-v (--verbose): increase verbosity of output\n";
|
2021-06-29 15:23:02 +02:00
|
|
|
print STDERR
|
2021-06-29 15:34:48 +02:00
|
|
|
"\t-r (--remove): remove provider from LemonLDAP::NG if it does not appear in metadata\n";
|
2018-09-18 14:51:58 +02:00
|
|
|
exit 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
#==============================================================================
|
|
|
|
# Default values
|
|
|
|
#==============================================================================
|
|
|
|
|
2018-10-22 18:33:08 +02:00
|
|
|
my $spConfKeyPrefix = $opts{spconfprefix} || "sp-";
|
2018-10-22 18:17:20 +02:00
|
|
|
my $idpConfKeyPrefix = $opts{idpconfprefix} || "idp-";
|
2018-09-18 14:51:58 +02:00
|
|
|
|
2018-10-02 12:02:08 +02:00
|
|
|
# Set here attributes that are declared for your SP in the federation
|
2018-09-18 17:47:55 +02:00
|
|
|
# They will be set as exported attributes for all IDP
|
2021-06-29 15:23:02 +02:00
|
|
|
#
|
2018-09-18 17:47:55 +02:00
|
|
|
my $exportedAttributes = {
|
|
|
|
'cn' => '0;cn',
|
|
|
|
'eduPersonPrincipalName' => '0;eduPersonAffiliation',
|
|
|
|
'givenName' => '0;givenName',
|
|
|
|
'surname' => '0;surname',
|
|
|
|
'displayName' => '0;displayName',
|
|
|
|
'eduPersonAffiliation' => '0;eduPersonAffiliation',
|
|
|
|
'eduPersonPrimaryAffiliation' => '0;eduPersonPrimaryAffiliation',
|
|
|
|
'mail' => '0;mail',
|
|
|
|
'supannListeRouge' => '0;supannListeRouge',
|
|
|
|
'supannEtuCursusAnnee' => '0;supannEtuCursusAnnee',
|
|
|
|
};
|
2018-09-18 14:51:58 +02:00
|
|
|
|
2018-10-02 12:02:08 +02:00
|
|
|
# Set here options that are applied on all SP from the federation
|
|
|
|
my $spOptions = {
|
|
|
|
'samlSPMetaDataOptionsCheckSLOMessageSignature' => 1,
|
|
|
|
'samlSPMetaDataOptionsCheckSSOMessageSignature' => 1,
|
|
|
|
'samlSPMetaDataOptionsEnableIDPInitiatedURL' => 0,
|
|
|
|
'samlSPMetaDataOptionsEncryptionMode' => 'none',
|
|
|
|
'samlSPMetaDataOptionsForceUTF8' => 1,
|
|
|
|
'samlSPMetaDataOptionsNameIDFormat' => '',
|
|
|
|
'samlSPMetaDataOptionsNotOnOrAfterTimeout' => 72000,
|
|
|
|
'samlSPMetaDataOptionsOneTimeUse' => 0,
|
|
|
|
'samlSPMetaDataOptionsSessionNotOnOrAfterTimeout' => 72000,
|
|
|
|
'samlSPMetaDataOptionsSignSLOMessage' => 1,
|
|
|
|
'samlSPMetaDataOptionsSignSSOMessage' => 1
|
|
|
|
};
|
|
|
|
|
|
|
|
# Set here options that are applied on all IDP from the federation
|
|
|
|
my $idpOptions = {
|
|
|
|
'samlIDPMetaDataOptionsAdaptSessionUtime' => 0,
|
|
|
|
'samlIDPMetaDataOptionsAllowLoginFromIDP' => 0,
|
|
|
|
'samlIDPMetaDataOptionsAllowProxiedAuthn' => 0,
|
|
|
|
'samlIDPMetaDataOptionsCheckAudience' => 1,
|
|
|
|
'samlIDPMetaDataOptionsCheckSLOMessageSignature' => 1,
|
|
|
|
'samlIDPMetaDataOptionsCheckSSOMessageSignature' => 1,
|
|
|
|
'samlIDPMetaDataOptionsCheckTime' => 1,
|
|
|
|
'samlIDPMetaDataOptionsEncryptionMode' => 'none',
|
|
|
|
'samlIDPMetaDataOptionsForceAuthn' => 0,
|
|
|
|
'samlIDPMetaDataOptionsForceUTF8' => 0,
|
|
|
|
'samlIDPMetaDataOptionsIsPassive' => 0,
|
|
|
|
'samlIDPMetaDataOptionsNameIDFormat' => 'transient',
|
|
|
|
'samlIDPMetaDataOptionsRelayStateURL' => 0,
|
|
|
|
'samlIDPMetaDataOptionsSignSLOMessage' => -1,
|
|
|
|
'samlIDPMetaDataOptionsSignSSOMessage' => -1,
|
|
|
|
'samlIDPMetaDataOptionsStoreSAMLToken' => 0
|
|
|
|
};
|
|
|
|
|
2018-10-22 18:33:08 +02:00
|
|
|
my $idpCounter = {
|
|
|
|
'found' => 0,
|
|
|
|
'updated' => 0,
|
|
|
|
'created' => 0,
|
|
|
|
'rejected' => 0,
|
2021-06-28 21:45:11 +02:00
|
|
|
'removed' => 0,
|
|
|
|
'ignored' => 0
|
2018-10-22 18:33:08 +02:00
|
|
|
};
|
|
|
|
my $spCounter = {
|
|
|
|
'found' => 0,
|
|
|
|
'updated' => 0,
|
|
|
|
'created' => 0,
|
|
|
|
'rejected' => 0,
|
2021-06-28 21:45:11 +02:00
|
|
|
'removed' => 0,
|
|
|
|
'ignored' => 0,
|
2018-10-22 18:33:08 +02:00
|
|
|
};
|
2018-09-18 14:51:58 +02:00
|
|
|
|
2021-06-28 21:45:11 +02:00
|
|
|
# BlockList initialisation
|
2021-06-29 15:18:01 +02:00
|
|
|
my @spIgnorelist = @{ $opts{'ignore-sp'} || [] };
|
|
|
|
my @idpIgnorelist = @{ $opts{'ignore-idp'} || [] };
|
2021-06-28 21:45:11 +02:00
|
|
|
|
2018-09-18 14:51:58 +02:00
|
|
|
#==============================================================================
|
|
|
|
# Main
|
|
|
|
#==============================================================================
|
|
|
|
my $conf = Lemonldap::NG::Common::Conf->new();
|
|
|
|
my $lastConf = $conf->getConf();
|
|
|
|
|
|
|
|
if ( $opts{verbose} ) {
|
|
|
|
print "Read configuration " . $lastConf->{cfgNum} . "\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
# IDP and SP lists
|
2018-10-22 18:33:08 +02:00
|
|
|
my ( $idpList, $spList, $mdIdpList, $mdSpList );
|
2018-09-18 14:51:58 +02:00
|
|
|
|
|
|
|
# List current SAML partners
|
|
|
|
foreach my $spConfKey ( keys %{ $lastConf->{samlSPMetaDataXML} } ) {
|
|
|
|
my ( $tmp, $entityID ) =
|
|
|
|
( $lastConf->{samlSPMetaDataXML}->{$spConfKey}->{samlSPMetaDataXML} =~
|
|
|
|
/entityID=(['"])(.+?)\1/si );
|
2018-10-22 18:33:08 +02:00
|
|
|
if ( $spConfKey =~ /^$spConfKeyPrefix/ ) {
|
|
|
|
$spList->{$entityID} = $spConfKey;
|
|
|
|
if ( $opts{verbose} ) {
|
|
|
|
print "Existing SAML partner found: [SP] $entityID ($spConfKey)\n";
|
|
|
|
}
|
2018-09-18 14:51:58 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach my $idpConfKey ( keys %{ $lastConf->{samlIDPMetaDataXML} } ) {
|
|
|
|
my ( $tmp, $entityID ) =
|
|
|
|
( $lastConf->{samlIDPMetaDataXML}->{$idpConfKey}->{samlIDPMetaDataXML} =~
|
|
|
|
/entityID=(['"])(.+?)\1/si );
|
2018-10-22 18:33:08 +02:00
|
|
|
if ( $idpConfKey =~ /^$idpConfKeyPrefix/ ) {
|
|
|
|
$idpList->{$entityID} = $idpConfKey;
|
|
|
|
if ( $opts{verbose} ) {
|
|
|
|
print
|
|
|
|
"Existing SAML partner found: [IDP] $entityID ($idpConfKey)\n";
|
|
|
|
}
|
2018-09-18 14:51:58 +02:00
|
|
|
}
|
2018-11-08 12:32:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
# Download metadata file
|
|
|
|
my $ua = LWP::UserAgent->new;
|
|
|
|
$ua->timeout(10);
|
|
|
|
$ua->env_proxy;
|
|
|
|
|
|
|
|
my $metadata_file = $opts{metadata};
|
|
|
|
|
|
|
|
if ( $opts{verbose} ) {
|
|
|
|
print "Try to download metadata file at $metadata_file\n";
|
|
|
|
}
|
|
|
|
my $response = $ua->get($metadata_file);
|
2018-09-18 14:51:58 +02:00
|
|
|
|
2018-11-08 12:32:30 +01:00
|
|
|
if ( $response->is_success ) {
|
|
|
|
if ( $opts{verbose} ) {
|
|
|
|
print "Metadata file found\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
die $response->status_line;
|
|
|
|
}
|
2018-09-18 14:51:58 +02:00
|
|
|
|
2018-11-08 12:32:30 +01:00
|
|
|
my $dom = XML::LibXML->load_xml( string => $response->decoded_content );
|
2018-09-18 14:51:58 +02:00
|
|
|
|
2018-11-08 12:32:30 +01:00
|
|
|
# Remove extensions
|
|
|
|
foreach ( $dom->findnodes('//md:Extensions') ) { $_->unbindNode; }
|
|
|
|
|
|
|
|
# Browse all partners
|
|
|
|
foreach
|
|
|
|
my $partner ( $dom->findnodes('/md:EntitiesDescriptor/md:EntityDescriptor') )
|
|
|
|
{
|
|
|
|
my $entityID = $partner->getAttribute('entityID');
|
|
|
|
|
|
|
|
# Add required XML namespaces
|
|
|
|
$partner->setNamespace( "urn:oasis:names:tc:SAML:2.0:metadata", "md", 0 );
|
|
|
|
$partner->setNamespace( "urn:oasis:names:tc:SAML:2.0:assertion",
|
|
|
|
"saml", 0 );
|
|
|
|
$partner->setNamespace( "http://www.w3.org/2000/09/xmldsig#", "ds", 0 );
|
|
|
|
|
|
|
|
# Check IDP or SP
|
|
|
|
if ( my $idp = $partner->findnodes('./md:IDPSSODescriptor') ) {
|
|
|
|
$idpCounter->{found}++;
|
|
|
|
$mdIdpList->{$entityID} = 1;
|
|
|
|
|
|
|
|
# Check if SAML 2.0 is supported
|
|
|
|
if (
|
|
|
|
$partner->findnodes(
|
2018-09-18 14:51:58 +02:00
|
|
|
'./md:IDPSSODescriptor/md:SingleSignOnService[contains(@Binding,"urn:oasis:names:tc:SAML:2.0:")]'
|
2018-11-08 12:32:30 +01:00
|
|
|
)
|
|
|
|
)
|
|
|
|
{
|
2018-09-18 14:51:58 +02:00
|
|
|
|
2018-11-08 12:32:30 +01:00
|
|
|
# Read metadata
|
|
|
|
my $partner_metadata = $partner->toString;
|
|
|
|
$partner_metadata =~ s/\n//g;
|
2018-09-18 14:51:58 +02:00
|
|
|
|
2021-06-28 21:45:11 +02:00
|
|
|
# test if IDP entityID is inside the block list
|
|
|
|
|
2021-06-29 15:23:02 +02:00
|
|
|
if ( grep { $entityID eq $_ } @idpIgnorelist ) {
|
2021-06-29 15:18:01 +02:00
|
|
|
if ( $opts{verbose} ) {
|
|
|
|
print "IDP $entityID won't be update/added \n";
|
|
|
|
}
|
2021-06-28 21:45:11 +02:00
|
|
|
$idpCounter->{ignored}++;
|
2021-06-29 15:23:02 +02:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
# Check if entityID already in configuration
|
|
|
|
if ( defined $idpList->{$entityID} ) {
|
2021-06-28 21:45:11 +02:00
|
|
|
|
2021-06-29 15:23:02 +02:00
|
|
|
# Update metadata
|
|
|
|
$lastConf->{samlIDPMetaDataXML}->{ $idpList->{$entityID} }
|
|
|
|
->{samlIDPMetaDataXML} = $partner_metadata;
|
|
|
|
|
|
|
|
# Update attributes
|
|
|
|
$lastConf->{samlIDPMetaDataExportedAttributes}
|
|
|
|
->{ $idpList->{$entityID} } = $exportedAttributes;
|
|
|
|
|
|
|
|
# Update options
|
|
|
|
$lastConf->{samlIDPMetaDataOptions}
|
|
|
|
->{ $idpList->{$entityID} } = $idpOptions;
|
|
|
|
|
|
|
|
if ( $opts{verbose} ) {
|
|
|
|
print "Update IDP $entityID in configuration\n";
|
|
|
|
}
|
|
|
|
$idpCounter->{updated}++;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
# Create a new partner
|
|
|
|
my $confKey = toEntityIDkey( $idpConfKeyPrefix, $entityID );
|
|
|
|
|
|
|
|
# Metadata
|
|
|
|
$lastConf->{samlIDPMetaDataXML}->{$confKey}
|
|
|
|
->{samlIDPMetaDataXML} = $partner_metadata;
|
|
|
|
|
|
|
|
# Attributes
|
|
|
|
$lastConf->{samlIDPMetaDataExportedAttributes}->{$confKey}
|
|
|
|
= $exportedAttributes;
|
|
|
|
|
|
|
|
# Options
|
|
|
|
$lastConf->{samlIDPMetaDataOptions}->{$confKey} =
|
|
|
|
$idpOptions;
|
|
|
|
|
|
|
|
if ( $opts{verbose} ) {
|
|
|
|
print
|
|
|
|
"Declare new IDP $entityID (configuration key $confKey)\n";
|
|
|
|
}
|
|
|
|
$idpCounter->{created}++;
|
|
|
|
}
|
2018-11-08 12:32:30 +01:00
|
|
|
}
|
2021-06-29 15:23:02 +02:00
|
|
|
|
2018-11-08 12:32:30 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
print STDERR
|
2018-10-02 12:04:15 +02:00
|
|
|
"[WARN] IDP $entityID is not compatible with SAML 2.0, it will not be imported.\n"
|
2021-06-29 15:18:01 +02:00
|
|
|
if $opts{verbose};
|
2018-11-08 12:32:30 +01:00
|
|
|
$idpCounter->{rejected}++;
|
2018-09-18 14:51:58 +02:00
|
|
|
}
|
2018-11-08 12:32:30 +01:00
|
|
|
}
|
|
|
|
if ( my $sp = $partner->findnodes('./md:SPSSODescriptor') ) {
|
|
|
|
$spCounter->{found}++;
|
|
|
|
$mdSpList->{$entityID} = 1;
|
|
|
|
|
|
|
|
# Check if SAML 2.0 is supported
|
|
|
|
if (
|
|
|
|
$partner->findnodes(
|
|
|
|
'./md:SPSSODescriptor/md:AssertionConsumerService[contains(@Binding,"urn:oasis:names:tc:SAML:2.0:")]'
|
|
|
|
)
|
|
|
|
)
|
|
|
|
{
|
2018-09-18 14:51:58 +02:00
|
|
|
|
2018-11-08 12:32:30 +01:00
|
|
|
# Read requested attributes
|
|
|
|
my $requestedAttributes = {};
|
2018-09-18 17:47:55 +02:00
|
|
|
if (
|
|
|
|
$partner->findnodes(
|
2018-11-08 12:32:30 +01:00
|
|
|
'./md:SPSSODescriptor/md:AttributeConsumingService/md:RequestedAttribute'
|
2018-09-18 17:47:55 +02:00
|
|
|
)
|
|
|
|
)
|
|
|
|
{
|
2018-11-08 12:32:30 +01:00
|
|
|
foreach my $requestedAttribute (
|
2018-09-18 17:47:55 +02:00
|
|
|
$partner->findnodes(
|
|
|
|
'./md:SPSSODescriptor/md:AttributeConsumingService/md:RequestedAttribute'
|
|
|
|
)
|
|
|
|
)
|
|
|
|
{
|
2018-11-08 12:32:30 +01:00
|
|
|
my $name = $requestedAttribute->getAttribute("Name");
|
|
|
|
my $friendlyname =
|
|
|
|
$requestedAttribute->getAttribute("FriendlyName");
|
|
|
|
my $nameformat =
|
|
|
|
$requestedAttribute->getAttribute("NameFormat");
|
2020-03-17 16:45:59 +01:00
|
|
|
my $required =
|
|
|
|
( $requestedAttribute->getAttribute("isRequired") =~
|
|
|
|
/true/i ) ? 1 : 0;
|
2018-11-08 12:32:30 +01:00
|
|
|
$requestedAttributes->{$friendlyname} =
|
2020-03-17 16:45:59 +01:00
|
|
|
"$required;$name;$nameformat;$friendlyname";
|
2018-11-08 12:32:30 +01:00
|
|
|
if ( $opts{verbose} ) {
|
|
|
|
print
|
2018-09-18 17:47:55 +02:00
|
|
|
"Attribute $friendlyname ($name) requested by SP $entityID\n";
|
|
|
|
}
|
|
|
|
}
|
2018-11-08 12:32:30 +01:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
$requestedAttributes =
|
|
|
|
{ 'cn' => '1;cn', 'uid' => '1;uid', 'mail' => '1;mail' };
|
|
|
|
}
|
2018-09-18 17:47:55 +02:00
|
|
|
|
2018-11-08 12:32:30 +01:00
|
|
|
# Remove AttributeConsumingService node
|
|
|
|
foreach (
|
|
|
|
$partner->findnodes(
|
|
|
|
'./md:SPSSODescriptor/md:AttributeConsumingService')
|
|
|
|
)
|
|
|
|
{
|
|
|
|
$_->unbindNode;
|
|
|
|
}
|
2018-09-18 17:47:55 +02:00
|
|
|
|
2018-11-08 12:32:30 +01:00
|
|
|
# Read metadata
|
|
|
|
my $partner_metadata = $partner->toString;
|
|
|
|
$partner_metadata =~ s/\n//g;
|
2018-09-18 14:51:58 +02:00
|
|
|
|
2021-06-28 21:45:11 +02:00
|
|
|
# test if IDP entityID is inside the block list
|
2018-10-02 12:02:08 +02:00
|
|
|
|
2021-06-29 15:23:02 +02:00
|
|
|
if ( grep { $entityID eq $_ } @spIgnorelist ) {
|
2018-11-08 12:32:30 +01:00
|
|
|
if ( $opts{verbose} ) {
|
2021-06-29 15:23:02 +02:00
|
|
|
print "SP $entityID won't be update/added \n";
|
|
|
|
}
|
2021-06-28 21:45:11 +02:00
|
|
|
$spCounter->{ignored}++;
|
2021-06-29 15:23:02 +02:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
# Check if entityID already in configuration
|
|
|
|
if ( defined $spList->{$entityID} ) {
|
|
|
|
|
|
|
|
# Update metadata
|
|
|
|
$lastConf->{samlSPMetaDataXML}->{ $spList->{$entityID} }
|
|
|
|
->{samlSPMetaDataXML} = $partner_metadata;
|
|
|
|
|
|
|
|
# Update attributes
|
|
|
|
$lastConf->{samlSPMetaDataExportedAttributes}
|
|
|
|
->{ $spList->{$entityID} } = $requestedAttributes;
|
|
|
|
|
|
|
|
# Update options
|
2021-06-28 21:45:11 +02:00
|
|
|
# $lastConf->{samlSPMetaDataOptions}->{ $spList->{$entityID} } =
|
|
|
|
# $spOptions;
|
|
|
|
# FIX AGA
|
2021-06-29 15:23:02 +02:00
|
|
|
$lastConf->{samlSPMetaDataOptions}->{ $spList->{$entityID} }
|
|
|
|
= { %{$spOptions} };
|
|
|
|
|
|
|
|
if ( $opts{verbose} ) {
|
|
|
|
print "Update SP $entityID in configuration\n";
|
|
|
|
}
|
|
|
|
$spCounter->{updated}++;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
# Create a new partner
|
|
|
|
my $confKey = toEntityIDkey( $spConfKeyPrefix, $entityID );
|
|
|
|
|
|
|
|
# Metadata
|
|
|
|
$lastConf->{samlSPMetaDataXML}->{$confKey}
|
|
|
|
->{samlSPMetaDataXML} = $partner_metadata;
|
|
|
|
|
|
|
|
# Attributes
|
|
|
|
$lastConf->{samlSPMetaDataExportedAttributes}->{$confKey} =
|
|
|
|
$requestedAttributes;
|
2021-06-28 21:45:11 +02:00
|
|
|
|
|
|
|
# Options
|
|
|
|
# $lastConf->{samlSPMetaDataOptions}->{$confKey} = $spOptions;
|
|
|
|
|
2021-06-29 15:23:02 +02:00
|
|
|
# FIX AGA
|
|
|
|
$lastConf->{samlSPMetaDataOptions}->{$confKey} =
|
|
|
|
{ %{$spOptions} };
|
|
|
|
|
|
|
|
if ( $opts{verbose} ) {
|
|
|
|
print
|
|
|
|
"Declare new SP $entityID (configuration key $confKey)\n";
|
|
|
|
}
|
|
|
|
$spCounter->{created}++;
|
|
|
|
}
|
|
|
|
|
|
|
|
# handle eduPersonTargetedID
|
|
|
|
if ( $requestedAttributes->{eduPersonTargetedID} ) {
|
|
|
|
delete $requestedAttributes->{eduPersonTargetedID};
|
|
|
|
$lastConf->{samlSPMetaDataOptions}->{ $spList->{$entityID} }
|
|
|
|
->{samlSPMetaDataOptionsNameIDFormat} = 'persistent';
|
|
|
|
}
|
2018-09-18 14:51:58 +02:00
|
|
|
|
2018-10-22 18:33:08 +02:00
|
|
|
}
|
|
|
|
|
2018-09-18 14:51:58 +02:00
|
|
|
}
|
2018-11-08 12:32:30 +01:00
|
|
|
else {
|
|
|
|
print STDERR
|
|
|
|
"[WARN] SP $entityID is not compatible with SAML 2.0, it will not be imported.\n"
|
2021-06-29 15:18:01 +02:00
|
|
|
if $opts{verbose};
|
2018-11-08 12:32:30 +01:00
|
|
|
$spCounter->{rejected}++;
|
|
|
|
}
|
2018-09-18 14:51:58 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2018-11-08 12:32:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
# Remove partners
|
|
|
|
if ( $opts{remove} ) {
|
2021-06-29 15:23:02 +02:00
|
|
|
foreach my $entityID ( keys %$idpList ) {
|
|
|
|
my $idpConfKey = $idpList->{$entityID};
|
|
|
|
unless ( defined $mdIdpList->{$entityID} ) {
|
|
|
|
if ( grep { $entityID eq $_ } @idpIgnorelist ) {
|
2021-06-29 15:18:01 +02:00
|
|
|
$idpCounter->{ignored}++;
|
|
|
|
if ( $opts{verbose} ) {
|
|
|
|
print "IDP $idpConfKey won't be deleted \n";
|
|
|
|
}
|
2021-06-28 21:45:11 +02:00
|
|
|
}
|
2021-06-29 15:18:01 +02:00
|
|
|
else {
|
2021-06-28 21:45:11 +02:00
|
|
|
delete $lastConf->{samlIDPMetaDataXML}->{$idpConfKey};
|
|
|
|
delete $lastConf->{samlIDPMetaDataExportedAttributes}
|
|
|
|
->{$idpConfKey};
|
|
|
|
delete $lastConf->{samlIDPMetaDataOptions}->{$idpConfKey};
|
|
|
|
$idpCounter->{removed}++;
|
|
|
|
if ( $opts{verbose} ) {
|
|
|
|
print "Remove IDP $idpConfKey\n";
|
|
|
|
}
|
2018-10-22 18:33:08 +02:00
|
|
|
}
|
|
|
|
}
|
2018-11-08 12:32:30 +01:00
|
|
|
}
|
2018-10-22 18:33:08 +02:00
|
|
|
|
2021-06-29 15:23:02 +02:00
|
|
|
foreach my $entityID ( keys %$spList ) {
|
|
|
|
my $spConfKey = $spList->{$entityID};
|
|
|
|
unless ( defined $mdSpList->{$entityID} ) {
|
|
|
|
if ( grep { $entityID eq $_ } @spIgnorelist ) {
|
2021-06-29 15:18:01 +02:00
|
|
|
$spCounter->{ignored}++;
|
|
|
|
if ( $opts{verbose} ) {
|
|
|
|
print "SP $spConfKey won't be deleted \n";
|
|
|
|
}
|
2021-06-28 21:45:11 +02:00
|
|
|
}
|
2021-06-29 15:18:01 +02:00
|
|
|
else {
|
2021-06-28 21:45:11 +02:00
|
|
|
delete $lastConf->{samlSPMetaDataXML}->{$spConfKey};
|
2021-06-29 15:23:02 +02:00
|
|
|
delete $lastConf->{samlSPMetaDataExportedAttributes}
|
|
|
|
->{$spConfKey};
|
2021-06-28 21:45:11 +02:00
|
|
|
delete $lastConf->{samlSPMetaDataOptions}->{$spConfKey};
|
|
|
|
$spCounter->{removed}++;
|
|
|
|
if ( $opts{verbose} ) {
|
|
|
|
print "Remove SP $spConfKey\n";
|
|
|
|
}
|
2018-10-22 18:33:08 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-09-18 14:51:58 +02:00
|
|
|
}
|
|
|
|
|
2021-06-29 15:23:02 +02:00
|
|
|
my $numConf = "DRY-RUN";
|
2021-06-28 21:45:11 +02:00
|
|
|
my $exitCode = 0;
|
|
|
|
|
2021-06-29 15:18:01 +02:00
|
|
|
if ( !$opts{'dry-run'} ) {
|
|
|
|
|
|
|
|
# Register configuration
|
|
|
|
if ( $opts{verbose} ) {
|
|
|
|
print "[INFO] run mod EntityID will be inserted\n";
|
|
|
|
}
|
|
|
|
$numConf = $conf->saveConf( $lastConf, ( cfgNumFixed => 1 ) );
|
|
|
|
if ( $opts{verbose} ) {
|
|
|
|
print "[OK] Configuration $numConf saved\n";
|
|
|
|
$exitCode = 0;
|
|
|
|
}
|
|
|
|
unless ($numConf) {
|
|
|
|
print "[ERROR] Unable to save configuration\n";
|
|
|
|
$exitCode = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if ( $opts{verbose} ) {
|
|
|
|
print "[INFO] Dry-run mod no EntityID inserted\n";
|
|
|
|
}
|
2021-06-28 21:45:11 +02:00
|
|
|
}
|
2018-09-18 14:51:58 +02:00
|
|
|
|
2021-06-28 21:45:11 +02:00
|
|
|
if ( $opts{nagios} ) {
|
2021-06-29 15:23:02 +02:00
|
|
|
print "Metadata loaded inside Conf: ["
|
|
|
|
. $numConf
|
|
|
|
. "]|idp_found="
|
|
|
|
. $idpCounter->{found}
|
|
|
|
. ", idp_updated="
|
|
|
|
. $idpCounter->{updated}
|
|
|
|
. ", idp_created="
|
|
|
|
. $idpCounter->{created}
|
|
|
|
. ", idp_removed="
|
|
|
|
. $idpCounter->{removed}
|
|
|
|
. ", idp_rejected="
|
|
|
|
. $idpCounter->{rejected}
|
|
|
|
. ", idp_ignored="
|
|
|
|
. $idpCounter->{ignored}
|
|
|
|
. ", sp_found="
|
|
|
|
. $spCounter->{found}
|
|
|
|
. ", sp_updated="
|
|
|
|
. $spCounter->{updated}
|
|
|
|
. ", sp_created="
|
|
|
|
. $spCounter->{created}
|
|
|
|
. ", sp_removed="
|
|
|
|
. $spCounter->{removed}
|
|
|
|
. ", sp_rejected="
|
|
|
|
. $spCounter->{rejected}
|
|
|
|
. ", sp_ignored="
|
|
|
|
. $spCounter->{ignored} . "\n";
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
print "[IDP]\tFound: "
|
|
|
|
. $idpCounter->{found}
|
|
|
|
. "\tUpdated: "
|
|
|
|
. $idpCounter->{updated}
|
|
|
|
. "\tCreated: "
|
|
|
|
. $idpCounter->{created}
|
|
|
|
. "\tRemoved: "
|
|
|
|
. $idpCounter->{removed}
|
|
|
|
. "\tRejected: "
|
|
|
|
. $idpCounter->{rejected}
|
|
|
|
. "\tIgnored: "
|
|
|
|
. $idpCounter->{ignored} . "\n";
|
|
|
|
print "[SP]\tFound: "
|
|
|
|
. $spCounter->{found}
|
|
|
|
. "\tUpdated: "
|
|
|
|
. $spCounter->{updated}
|
|
|
|
. "\tCreated: "
|
|
|
|
. $spCounter->{created}
|
|
|
|
. "\tRemoved: "
|
|
|
|
. $spCounter->{removed}
|
|
|
|
. "\tRejected: "
|
|
|
|
. $spCounter->{rejected}
|
|
|
|
. "\tIgnored: "
|
|
|
|
. $spCounter->{ignored} . "\n";
|
2018-09-18 14:51:58 +02:00
|
|
|
}
|
2021-06-28 21:45:11 +02:00
|
|
|
|
|
|
|
exit $exitCode;
|
|
|
|
|