From d5372cfe07670a6ee842af9eb199cdf06fc86390 Mon Sep 17 00:00:00 2001 From: Cody Finegan <44886+codyfinegan@users.noreply.github.com> Date: Thu, 19 Jan 2023 15:29:08 +1300 Subject: [PATCH] SP metadata will be loaded from the SP when the image boots. (#3) Co-authored-by: Cody Finegan --- .gitignore | 2 + metadata/saml20-sp-remote.php | 91 +++++++++++++++++++++++++---------- 2 files changed, 67 insertions(+), 26 deletions(-) diff --git a/.gitignore b/.gitignore index 461131d..e8abb80 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ .idea server.pem server.crt +simplesamlphp-*/ +simplesamlphp-*.tar.gz diff --git a/metadata/saml20-sp-remote.php b/metadata/saml20-sp-remote.php index a122e8e..be50ee5 100644 --- a/metadata/saml20-sp-remote.php +++ b/metadata/saml20-sp-remote.php @@ -23,30 +23,69 @@ $instances[] = $totara_instance; } +$config = \SimpleSAML\Configuration::getInstance(); +$temp_dir = $config->getPathValue('tempdir'); + +// Load each metadata file +$load_metadata = function (string $domain, bool $reset = false) use ($temp_dir) { + // Key it + $filename = $temp_dir . sha1($domain) . '.xml'; + if (file_exists($filename) && !$reset) { + return file_get_contents($filename); + } + + $ch = curl_init($domain); + $fp = fopen($filename, 'w'); + + curl_setopt($ch, CURLOPT_FILE, $fp); + curl_setopt($ch, CURLOPT_HEADER, 0); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); + + curl_exec($ch); + + if (curl_error($ch)) { + // Silently continue + curl_close($ch); + fclose($fp); + return false; + } + + curl_close($ch); + fclose($fp); + + return file_get_contents($filename); +}; + +$reset = isset($_GET['refresh_metadata']) && $_GET['refresh_metadata'] === 'y'; + +$metadata = []; foreach ($instances as $totara_instance) { - $metadata[$totara_instance . '/auth/saml2/sp/metadata.php'] = [ - 'metadata-set' => 'saml20-idp-remote', - 'entityid' => $totara_instance . '/auth/saml2/sp/metadata.php', - 'SingleSignOnService' => [ - [ - 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect', - 'Location' => $totara_instance . '/auth/saml2/www/saml2/idp/SSOService.php', - ], - ], - 'SingleLogoutService' => [ - [ - 'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect', - 'Location' => $totara_instance . '/auth/saml2/sp/saml2-logout.php', - ], - ], - 'AssertionConsumerService' => $totara_instance . '/auth/saml2/sp/saml2-acs.php', - 'NameIDFormat' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient', - 'contacts' => [ - [ - 'emailAddress' => 'team.platform@totara.com', - 'contactType' => 'technical', - 'givenName' => 'Administrator', - ], - ], - ]; -} \ No newline at end of file + $xml = $load_metadata($totara_instance . '/auth/saml2/sp/metadata.php', $reset); + + // No data, silently ignore it. + if (!$xml) { + continue; + } + + \SimpleSAML\Utils\XML::checkSAMLMessage($xml, 'saml-meta'); + $entities = \SimpleSAML\Metadata\SAMLParser::parseDescriptorsString($xml); + + // get all metadata for the entities + foreach ($entities as &$entity) { + $data = $entity->getMetadata20SP(); + + if (isset($data['entityDescriptor'])) { + unset($data['entityDescriptor']); + } + + $entity = [ + 'saml20-sp-remote' => $data, + ]; + } + + // transpose from $entities[entityid][type] to $output[type][entityid] + $output = \SimpleSAML\Utils\Arrays::transpose($entities); + + $metadata = array_merge($metadata, $output['saml20-sp-remote']); +}