* @package simpleSAMLphp */ class sspmod_aggregator_Aggregator { // Configuration for the whole aggregator module private $gConfig; // Configuration for the specific aggregate private $aConfig; private $sets; private $excludeTags = array(); private $id; /** * Constructor for the Aggregator. * */ public function __construct($gConfig, $aConfig, $id) { $this->gConfig = $gConfig; $this->aConfig = $aConfig; $this->id = $id; $this->sets = array('saml20-idp-remote', 'saml20-sp-remote', 'shib13-idp-remote', 'shib13-sp-remote', 'attributeauthority-remote'); if ($this->aConfig->hasValue('set')) { $this->limitSets($this->aConfig->getString('set')); } } public function limitSets($set) { if (is_array($set)) { $this->sets = array_intersect($this->sets, $set); return; } switch($set) { case 'saml2' : $this->sets = array_intersect($this->sets, array('saml20-idp-remote', 'saml20-sp-remote')); break; case 'shib13' : $this->sets = array_intersect($this->sets, array('shib13-idp-remote', 'shib13-sp-remote')); break; case 'idp' : $this->sets = array_intersect($this->sets, array('saml20-idp-remote', 'shib13-idp-remote', 'attributeauthority-remote')); break; case 'sp' : $this->sets = array_intersect($this->sets, array('saml20-sp-remote', 'shib13-sp-remote')); break; default: $this->sets = array_intersect($this->sets, array($set)); } } /** * Add tag to excelude when collecting source metadata. * * $exclude May be string or array identifying a tag to exclude. */ public function exclude($exclude) { $this->excludeTags = array_merge($this->excludeTags, SimpleSAML_Utilities::arrayize($exclude)); } /** * Returns a list of entities with metadata */ public function getSources() { $sourcesDef = $this->aConfig->getArray('sources'); try { $sources = SimpleSAML_Metadata_MetaDataStorageSource::parseSources($sourcesDef); } catch (Exception $e) { throw new Exception('Invalid aggregator source configuration for aggregator ' . var_export($id, TRUE) . ': ' . $e->getMessage()); } /* Find list of all available entities. */ $entities = array(); foreach ($sources as $source) { foreach ($this->sets as $set) { foreach ($source->getMetadataSet($set) as $entityId => $metadata) { $metadata['entityid'] = $entityId; $metadata['metadata-set'] = $set; if (isset($metadata['tags']) && count(array_intersect($this->excludeTags, $metadata['tags'])) > 0) { SimpleSAML_Logger::debug('Excluding entity ID [' . $entityId . '] becuase it is tagged with one of [' . var_export($this->excludeTags, TRUE) . ']'); continue; } else { #echo('
'); print_r($metadata); exit;
}
if (!array_key_exists($entityId, $entities))
$entities[$entityId] = array();
if (array_key_exists($set, $entities[$entityId])) {
/* Entity already has metadata for the given set. */
continue;
}
$entities[$entityId][$set] = $metadata;
}
}
}
return $entities;
}
public function getMaxDuration() {
if ($this->aConfig->hasValue('maxDuration'))
return $this->aConfig->getInteger('maxDuration');
if ($this->gConfig->hasValue('maxDuration'))
return $this->gConfig->getInteger('maxDuration');
return NULL;
}
public function getReconstruct() {
if ($this->aConfig->hasValue('reconstruct'))
return $this->aConfig->getBoolean('reconstruct');
if ($this->gConfig->hasValue('reconstruct'))
return $this->gConfig->getBoolean('reconstruct');
return FALSE;
}
public function shouldSign() {
if ($this->aConfig->hasValue('sign.enable'))
return $this->aConfig->getBoolean('sign.enable');
if ($this->gConfig->hasValue('sign.enable'))
return $this->gConfig->getBoolean('sign.enable');
return FALSE;
}
public function getSigningInfo() {
if ($this->aConfig->hasValue('sign.privatekey')) {
return array(
'privatekey' => $this->aConfig->getString('sign.privatekey'),
'privatekey_pass' => $this->aConfig->getString('sign.privatekey_pass', NULL),
'certificate' => $this->aConfig->getString('sign.certificate'),
'id' => 'ID'
);
}
return array(
'privatekey' => $this->gConfig->getString('sign.privatekey'),
'privatekey_pass' => $this->gConfig->getString('sign.privatekey_pass', NULL),
'certificate' => $this->gConfig->getString('sign.certificate'),
'id' => 'ID'
);
}
public function getMetadataDocument() {
// Get metadata entries
$entities = $this->getSources();
$maxDuration = $this->getMaxDuration();
$reconstruct = $this->getReconstruct();
$entitiesDescriptor = new SAML2_XML_md_EntitiesDescriptor();
$entitiesDescriptor->Name = $this->id;
$entitiesDescriptor->validUntil = time() + $maxDuration;
// add RegistrationInfo extension if enabled
if ($this->gConfig->hasValue('RegistrationInfo')) {
$ri = new SAML2_XML_mdrpi_RegistrationInfo();
foreach ($this->gConfig->getArray('RegistrationInfo') as $riName => $riValues) {
switch ($riName) {
case 'authority':
$ri->registrationAuthority = $riValues;
break;
case 'instant':
$ri->registrationInstant = SAML2_Utils::xsDateTimeToTimestamp($riValues);
break;
case 'policies':
$ri->RegistrationPolicy = $riValues;
break;
}
}
$entitiesDescriptor->Extensions[] = $ri;
}
/* Build EntityDescriptor elements for them. */
foreach ($entities as $entity => $sets) {
$entityDescriptor = NULL;
foreach ($sets as $set => $metadata) {
if (!array_key_exists('entityDescriptor', $metadata)) {
/* One of the sets doesn't contain an EntityDescriptor element. */
$entityDescriptor = FALSE;
break;
}
if ($entityDescriptor == NULL) {
/* First EntityDescriptor elements. */
$entityDescriptor = $metadata['entityDescriptor'];
continue;
}
assert('is_string($entityDescriptor)');
if ($entityDescriptor !== $metadata['entityDescriptor']) {
/* Entity contains multiple different EntityDescriptor elements. */
$entityDescriptor = FALSE;
break;
}
}
if (is_string($entityDescriptor) && !$reconstruct) {
/* All metadata sets for the entity contain the same entity descriptor. Use that one. */
$tmp = new DOMDocument();
$tmp->loadXML(base64_decode($entityDescriptor));
$entitiesDescriptor->children[] = new SAML2_XML_md_EntityDescriptor($tmp->documentElement);
} else {
$tmp = new SimpleSAML_Metadata_SAMLBuilder($entity, $maxDuration, $maxDuration);
$orgmeta = NULL;
foreach ($sets as $set => $metadata) {
$tmp->addMetadata($set, $metadata);
$orgmeta = $metadata;
}
$tmp->addOrganizationInfo($orgmeta);
$entitiesDescriptor->children[] = new SAML2_XML_md_EntityDescriptor($tmp->getEntityDescriptor());
}
}
$document = $entitiesDescriptor->toXML();
// sign the metadata if enabled
if ($this->shouldSign()) {
$signer = new SimpleSAML_XML_Signer($this->getSigningInfo());
$signer->sign($document, $document, $document->firstChild);
}
return $document;
}
}