19 'attributeauthority-remote' 33 $this->metadata = array();
36 $this->changed =
false;
43 $this->state = array();
81 if (preg_match(
'@^https?://@i',
$source[
'src'])) {
93 if (!isset($responseHeaders)) {
98 } elseif (preg_match(
'@^HTTP/1\.[01]\s304\s@', $responseHeaders[0])) {
103 } elseif (!preg_match(
'@^HTTP/1\.[01]\s200\s@', $responseHeaders[0])) {
112 $responseHeaders = null;
116 if (isset(
$source[
'conditionalGET']) &&
$source[
'conditionalGET']) {
130 foreach ($entities as $entity) {
132 if (isset(
$source[
'blacklist'])) {
133 if (!empty(
$source[
'blacklist']) && in_array($entity->getEntityID(),
$source[
'blacklist'],
true)) {
139 if (isset(
$source[
'whitelist'])) {
140 if (!empty(
$source[
'whitelist']) && !in_array($entity->getEntityID(),
$source[
'whitelist'],
true)) {
146 if (array_key_exists(
'certificates',
$source) &&
$source[
'certificates'] !== null) {
147 if (!$entity->validateSignature(
$source[
'certificates'])) {
148 SimpleSAML\Logger::info(
'Skipping "' . $entity->getEntityId() .
'" - could not verify signature using certificate.' .
"\n");
153 if (array_key_exists(
'validateFingerprint',
$source) &&
$source[
'validateFingerprint'] !== null) {
154 if (!array_key_exists(
'certificates',
$source) ||
$source[
'certificates'] == null) {
155 if (!$entity->validateFingerprint(
$source[
'validateFingerprint'])) {
156 SimpleSAML\Logger::info(
'Skipping "' . $entity->getEntityId() .
'" - could not verify signature using fingerprint.' .
"\n");
165 if (array_key_exists(
'template',
$source)) {
169 if (in_array(
'shib13-sp-remote', $this->types,
true)) {
172 if (in_array(
'shib13-idp-remote', $this->types,
true)) {
175 if (in_array(
'saml20-sp-remote', $this->types,
true)) {
178 if (in_array(
'saml20-idp-remote', $this->types,
true)) {
181 if (in_array(
'attributeauthority-remote', $this->types,
true)) {
182 $attributeAuthorities = $entity->getAttributeAuthorities();
183 if (!empty($attributeAuthorities)) {
198 $name =
$config->getString(
'technicalcontact_name', null);
199 $mail =
$config->getString(
'technicalcontact_email', null);
201 $rawheader =
"User-Agent: SimpleSAMLphp metarefresh, run by $name <$mail>\r\n";
203 if (isset(
$source[
'conditionalGET']) &&
$source[
'conditionalGET']) {
204 if (array_key_exists(
$source[
'src'], $this->state)) {
205 $sourceState = $this->state[
$source[
'src']];
207 if (isset($sourceState[
'last-modified'])) {
208 $rawheader .=
'If-Modified-Since: ' . $sourceState[
'last-modified'] .
"\r\n";
211 if (isset($sourceState[
'etag'])) {
212 $rawheader .=
'If-None-Match: ' . $sourceState[
'etag'] .
"\r\n";
217 return array(
'http' => array(
'header' => $rawheader));
223 if (isset($this->oldMetadataSrc)) {
224 foreach ($this->types as
$type) {
225 foreach ($this->oldMetadataSrc->getMetadataSet($type) as $entity) {
226 if (array_key_exists(
'metarefresh:src', $entity)) {
227 if ($entity[
'metarefresh:src'] ==
$source[
'src']) {
242 if (isset(
$source[
'conditionalGET']) &&
$source[
'conditionalGET']) {
244 if ($responseHeaders !== null) {
245 $candidates = array(
'last-modified',
'etag');
247 foreach ($candidates as $candidate) {
248 if (array_key_exists($candidate, $responseHeaders)) {
249 $this->state[
$source[
'src']][$candidate] = $responseHeaders[$candidate];
254 if (!empty($this->state[
$source[
'src']])) {
256 $this->state[$source[
'src']][
'requested_at'] = $this->
getTime();
257 $this->changed =
true;
272 if ($doc->documentElement === null) {
273 throw new Exception(
'Opened file is not an XML document: ' .
$source[
'src']);
284 if ($this->changed) {
288 "<?php\n/* This file was generated by the metarefresh module at ".$this->
getTime() .
".\n".
289 " Do not update it manually as it will get overwritten. */\n".
290 '$state = ' . var_export($this->state,
true) .
";\n?>\n",
302 foreach ($this->metadata as $category => $elements) {
304 echo '/* The following data should be added to metadata/' . $category .
'.php. */' .
"\n";
306 foreach ($elements as
$m) {
308 $entityID = $m[
'metadata'][
'entityid'];
311 echo '/* The following metadata was generated from ' .
$filename .
' on ' . $this->
getTime() .
'. */' .
"\n";
312 echo '$metadata[\'' . addslashes($entityID) .
'\'] =
' . var_export($m['metadata
'], true) . ';
' . "\n"; 330 private function addMetadata($filename, $metadata, $type, $template = null) 332 if ($metadata === null) { 336 if (isset($template)) { 337 $metadata = array_merge($metadata, $template); 340 $metadata['metarefresh:src
'] = $filename; 341 if (!array_key_exists($type, $this->metadata)) { 342 $this->metadata[$type] = array(); 345 // If expire is defined in constructor... 346 if (!empty($this->expire)) { 347 // If expire is already in metadata 348 if (array_key_exists('expire
', $metadata)) { 349 // Override metadata expire with more restrictive global config- 350 if ($this->expire < $metadata['expire
']) { 351 $metadata['expire
'] = $this->expire; 354 // If expire is not already in metadata use global config 356 $metadata['expire
'] = $this->expire; 359 $this->metadata[$type][] = array('filename
' => $filename, 'metadata
' => $metadata); 366 public function writeARPfile($config) 368 assert($config instanceof SimpleSAML_Configuration); 370 $arpfile = $config->getValue('arpfile
'); 371 $types = array('saml20-sp-remote
'); 374 foreach ($this->metadata as $category => $elements) { 375 if (!in_array($category, $types, true)) { 378 $md = array_merge($md, $elements); 381 // $metadata, $attributemap, $prefix, $suffix 382 $arp = new sspmod_metarefresh_ARP($md, 383 $config->getValue('attributemap
', ''), 384 $config->getValue('prefix
', ''), 385 $config->getValue('suffix
', '') 389 $arpxml = $arp->getXML(); 391 SimpleSAML\Logger::info('Writing ARP file:
' . $arpfile . "\n"); 392 file_put_contents($arpfile, $arpxml); 399 public function writeMetadataFiles($outputDir) 401 while (strlen($outputDir) > 0 && $outputDir[strlen($outputDir) - 1] === '/
') { 402 $outputDir = substr($outputDir, 0, strlen($outputDir) - 1); 405 if (!file_exists($outputDir)) { 406 SimpleSAML\Logger::info('Creating
directory:
' . $outputDir . "\n"); 407 $res = @mkdir($outputDir, 0777, true); 408 if ($res === false) { 409 throw new Exception('Error creating
directory:
' . $outputDir); 413 foreach ($this->types as $type) { 414 $filename = $outputDir . '/
' . $type . '.php
'; 416 if (array_key_exists($type, $this->metadata)) { 417 $elements = $this->metadata[$type]; 418 SimpleSAML\Logger::debug('Writing:
' . $filename); 420 $content = '<?
php' . "\n" . ' 423 foreach ($elements as $m) { 424 $entityID = $m['metadata
']['entityid
']; 426 $content .= '$metadata[\
'' . addslashes($entityID) .
'\'] =
' . var_export($m['metadata
'], true) . ';
' . "\n"; 429 $content .= "\n" . '?>
'; 431 SimpleSAML\Utils\System::writeFile($filename, $content, 0644); 432 } elseif (is_file($filename)) { 433 if (unlink($filename)) { 434 SimpleSAML\Logger::debug('Deleting stale metadata file:
' . $filename); 436 SimpleSAML\Logger::warning('Could not
delete stale metadata file:
' . $filename); 448 public function writeMetadataSerialize($outputDir) 450 assert(is_string($outputDir)); 452 $metaHandler = new SimpleSAML_Metadata_MetaDataStorageHandlerSerialize(array('directory' => $outputDir)); 454 /* First we add all the metadata entries to the metadata handler. */ 455 foreach ($this->metadata as $set => $elements) { 456 foreach ($elements as $m) { 457 $entityId = $m['metadata
']['entityid
']; 459 SimpleSAML\Logger::debug( 460 'metarefresh: Add metadata entry
' . 461 var_export($entityId, true) . ' in set ' . var_export($set, true) . '.
' 463 $metaHandler->saveMetadata($entityId, $set, $m['metadata
']); 467 /* Then we delete old entries which should no longer exist. */ 469 foreach ($metaHandler->getMetadataSets() as $set) { 470 foreach ($metaHandler->getMetadataSet($set) as $entityId => $metadata) { 471 if (!array_key_exists('expire
', $metadata)) { 472 SimpleSAML\Logger::warning( 473 'metarefresh: Metadata entry without expire timestamp:
' . var_export($entityId, true) . 474 ' in set ' . var_export($set, true) . '.
' 478 if ($metadata['expire
'] > $ct) { 481 SimpleSAML\Logger::debug('metarefresh:
' . $entityId . ' expired
' . date('l jS \of
F Y h:i:
s A
', $metadata['expire
'])); 482 SimpleSAML\Logger::debug( 483 'metarefresh: Delete expired metadata entry
' . 484 var_export($entityId, true) . ' in set ' . var_export($set, true) . '. (
' . ($ct - $metadata['expire
']) . ' sec)
' 486 $metaHandler->deleteMetadata($entityId, $set); 492 private function getTime() 494 /* The current date, as a string. */ 495 date_default_timezone_set('UTC
'); 496 return date('Y-m-d\\TH:i:
s\\Z
');
static writeFile($filename, $data, $mode=0600)
Atomically write a file.
static fetch($url, $context=array(), $getHeaders=false)
Helper function to retrieve a file or URL with proxy support, also supporting proxy basic authorizati...
static getInstance($instancename='simplesaml')
Get a configuration file by its instance name.