public function loadSource($source)
{
if (preg_match('@^https?://@i', $source['src'])) {
// Build new HTTP context
$context = $this->createContext($source);
// GET!
try {
list($data, $responseHeaders) = \SimpleSAML\Utils\HTTP::fetch($source['src'], $context, TRUE);
} catch (Exception $e) {
SimpleSAML\Logger::warning('metarefresh: ' . $e->getMessage());
}
// We have response headers, so the request succeeded
if (!isset($responseHeaders)) {
// No response headers, this means the request failed in some way, so re-use old data
SimpleSAML\Logger::debug('No response from ' . $source['src'] . ' - attempting to re-use cached metadata');
$this->addCachedMetadata($source);
return;
} elseif (preg_match('@^HTTP/1\\.[01]\\s304\\s@', $responseHeaders[0])) {
// 304 response
SimpleSAML\Logger::debug('Received HTTP 304 (Not Modified) - attempting to re-use cached metadata');
$this->addCachedMetadata($source);
return;
} elseif (!preg_match('@^HTTP/1\\.[01]\\s200\\s@', $responseHeaders[0])) {
// Other error
SimpleSAML\Logger::debug('Error from ' . $source['src'] . ' - attempting to re-use cached metadata');
$this->addCachedMetadata($source);
return;
}
} else {
// Local file.
$data = file_get_contents($source['src']);
$responseHeaders = NULL;
}
// Everything OK. Proceed.
if (isset($source['conditionalGET']) && $source['conditionalGET']) {
// Stale or no metadata, so a fresh copy
SimpleSAML\Logger::debug('Downloaded fresh copy');
}
try {
$entities = $this->loadXML($data, $source);
} catch (Exception $e) {
SimpleSAML\Logger::debug('XML parser error when parsing ' . $source['src'] . ' - attempting to re-use cached metadata');
$this->addCachedMetadata($source);
return;
}
foreach ($entities as $entity) {
if (isset($source['blacklist'])) {
if (!empty($source['blacklist']) && in_array($entity->getEntityID(), $source['blacklist'])) {
SimpleSAML\Logger::info('Skipping "' . $entity->getEntityID() . '" - blacklisted.' . "\n");
continue;
}
}
if (isset($source['whitelist'])) {
if (!empty($source['whitelist']) && !in_array($entity->getEntityID(), $source['whitelist'])) {
SimpleSAML\Logger::info('Skipping "' . $entity->getEntityID() . '" - not in the whitelist.' . "\n");
continue;
}
}
if (array_key_exists('certificates', $source) && $source['certificates'] !== NULL) {
if (!$entity->validateSignature($source['certificates'])) {
SimpleSAML\Logger::info('Skipping "' . $entity->getEntityId() . '" - could not verify signature using certificate.' . "\n");
continue;
}
}
if (array_key_exists('validateFingerprint', $source) && $source['validateFingerprint'] !== NULL) {
if (!array_key_exists('certificates', $source) || $source['certificates'] == NULL) {
if (!$entity->validateFingerprint($source['validateFingerprint'])) {
SimpleSAML\Logger::info('Skipping "' . $entity->getEntityId() . '" - could not verify signature using fingerprint.' . "\n");
continue;
}
} else {
SimpleSAML\Logger::info('Skipping validation with fingerprint since option certificate is set.' . "\n");
}
}
$template = NULL;
if (array_key_exists('template', $source)) {
$template = $source['template'];
}
$this->addMetadata($source['src'], $entity->getMetadata1xSP(), 'shib13-sp-remote', $template);
$this->addMetadata($source['src'], $entity->getMetadata1xIdP(), 'shib13-idp-remote', $template);
$this->addMetadata($source['src'], $entity->getMetadata20SP(), 'saml20-sp-remote', $template);
$this->addMetadata($source['src'], $entity->getMetadata20IdP(), 'saml20-idp-remote', $template);
$attributeAuthorities = $entity->getAttributeAuthorities();
if (!empty($attributeAuthorities)) {
$this->addMetadata($source['src'], $attributeAuthorities[0], 'attributeauthority-remote', $template);
}
}
$this->saveState($source, $responseHeaders);
}