From 59d86ee7071cab8b2a76defd4d92785f2c634b2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=85kre=20Solberg?= <andreas.solberg@uninett.no> Date: Mon, 28 Apr 2008 09:37:11 +0000 Subject: [PATCH] Added support for __default__ host configuration and __dynamic__ entity pointing to generated metadata git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@522 44740490-163a-0410-bde0-09ae8108e29a --- lib/SimpleSAML/Bindings/SAML20/HTTPPost.php | 4 +- lib/SimpleSAML/Bindings/Shib13/HTTPPost.php | 11 +++- .../Metadata/MetaDataStorageHandler.php | 37 ++++++++---- .../MetaDataStorageHandlerFlatfile.php | 26 +++++++- .../Metadata/MetaDataStorageSource.php | 60 ++++++++++++++----- lib/SimpleSAML/XML/SAML20/AuthnResponse.php | 13 +++- metadata-templates/saml20-idp-hosted.php | 4 +- metadata-templates/saml20-sp-hosted.php | 4 +- metadata-templates/shib13-idp-hosted.php | 6 +- metadata-templates/shib13-sp-hosted.php | 4 +- www/shib13/idp/SSOService.php | 5 +- 11 files changed, 129 insertions(+), 45 deletions(-) diff --git a/lib/SimpleSAML/Bindings/SAML20/HTTPPost.php b/lib/SimpleSAML/Bindings/SAML20/HTTPPost.php index 21db2627c..8c64cde2a 100644 --- a/lib/SimpleSAML/Bindings/SAML20/HTTPPost.php +++ b/lib/SimpleSAML/Bindings/SAML20/HTTPPost.php @@ -62,9 +62,9 @@ class SimpleSAML_Bindings_SAML20_HTTPPost { </html>'; } - public function sendResponse($response, $idpentityid, $spentityid, $relayState = null) { + public function sendResponse($response, $idmetaindex, $spentityid, $relayState = null) { - $idpmd = $this->metadata->getMetaData($idpentityid, 'saml20-idp-hosted'); + $idpmd = $this->metadata->getMetaData($idmetaindex, 'saml20-idp-hosted'); $spmd = $this->metadata->getMetaData($spentityid, 'saml20-sp-remote'); $destination = $spmd['AssertionConsumerService']; diff --git a/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php b/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php index d9faa9085..d917508b4 100644 --- a/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php +++ b/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php @@ -59,9 +59,14 @@ class SimpleSAML_Bindings_Shib13_HTTPPost { </html>'; } - public function sendResponse($response, $idpentityid, $spentityid, $relayState = null, $claimedacs = null) { + /** + * Send an authenticationResponse using HTTP-POST. + * + * @param $idpmetaindex The metaindex of the IdP to send from. + */ + public function sendResponse($response, $idpmetaindex, $spentityid, $relayState = null, $claimedacs = null) { - $idpmd = $this->metadata->getMetaData($idpentityid, 'shib13-idp-hosted'); + $idpmd = $this->metadata->getMetaData($idpmetaindex, 'shib13-idp-hosted'); $spmd = $this->metadata->getMetaData($spentityid, 'shib13-sp-remote'); $destination = $spmd['AssertionConsumerService']; @@ -74,6 +79,8 @@ class SimpleSAML_Bindings_Shib13_HTTPPost { $publiccert = $this->configuration->getPathValue('certdir') . $idpmd['certificate']; $certchain_pem_file = isset($idpmd['certificatechain']) ? $this->configuration->getPathValue('certdir') . $idpmd['certificatechain'] : null; + +# throw new Exception('lookup: ' . $idpentityid); if (!file_exists($privatekey)) throw new Exception('Could not find private key file [' . $privatekey . ']'); diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageHandler.php b/lib/SimpleSAML/Metadata/MetaDataStorageHandler.php index 9eab4050c..9398679a8 100644 --- a/lib/SimpleSAML/Metadata/MetaDataStorageHandler.php +++ b/lib/SimpleSAML/Metadata/MetaDataStorageHandler.php @@ -6,7 +6,7 @@ require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSA /** * This file defines a class for metadata handling. * - * @author Andreas Ĺkre Solberg, UNINETT AS. <andreas.solberg@uninett.no> + * @author Andreas Ă…kre Solberg, UNINETT AS. <andreas.solberg@uninett.no> * @package simpleSAMLphp * @version $Id$ */ @@ -179,9 +179,10 @@ class SimpleSAML_Metadata_MetaDataStorageHandler { * It will throw an exception if it is unable to locate the entity id. * * @param $set The set we look for the entity id in. + * @param $type Do you want to return the metaindex or the entityID. [entityid|metaindex] * @return The entity id which is associated with the current hostname/path combination. */ - public function getMetaDataCurrentEntityID($set = 'saml20-sp-hosted') { + public function getMetaDataCurrentEntityID($set = 'saml20-sp-hosted', $type = 'entityid') { assert('is_string($set)'); @@ -189,9 +190,9 @@ class SimpleSAML_Metadata_MetaDataStorageHandler { $currenthostwithpath = SimpleSAML_Utilities::getSelfHostWithPath(); // sp.example.org/university foreach($this->sources as $source) { - $entityId = $source->getEntityIdFromHostPath($currenthostwithpath, $set); - if($entityId !== NULL) { - return $entityId; + $index = $source->getEntityIdFromHostPath($currenthostwithpath, $set, $type); + if($index !== NULL) { + return $index; } } @@ -204,13 +205,23 @@ class SimpleSAML_Metadata_MetaDataStorageHandler { } foreach($this->sources as $source) { - $entityId = $source->getEntityIdFromHostPath($currenthost, $set); + $index = $source->getEntityIdFromHostPath($currenthost, $set, $type); + if($index !== NULL) { + return $index; + } + } + + + /* Then we look for the DEFAULT entry. */ + foreach($this->sources as $source) { + $entityId = $source->getEntityIdFromHostPath('__DEFAULT__', $set, $type); if($entityId !== NULL) { return $entityId; } } + /* We were unable to find the hostname/path in any metadata source. */ throw new Exception('Could not find any default metadata entities in set [' . $set . '] for host [' . $currenthost . ' : ' . $currenthostwithpath . ']'); } @@ -241,28 +252,28 @@ class SimpleSAML_Metadata_MetaDataStorageHandler { * This function looks up the metadata for the given entity id in the given set. It will throw an * exception if it is unable to locate the metadata. * - * @param $entityId The entity id we are looking up. This parameter may be NULL, in which case we look up + * @param $index The entity id we are looking up. This parameter may be NULL, in which case we look up * the current entity id based on the current hostname/path. * @param $set The set of metadata we are looking up the entity id in. */ - public function getMetaData($entityId, $set = 'saml20-sp-hosted') { + public function getMetaData($index, $set = 'saml20-sp-hosted') { assert('is_string($set)'); - if($entityId === NULL) { - $entityId = $this->getMetaDataCurrentEntityID($set); + if($index === NULL) { + $index = $this->getMetaDataCurrentEntityID($set, 'metaindex'); } - assert('is_string($entityId)'); + assert('is_string($index)'); foreach($this->sources as $source) { - $metadata = $source->getMetaData($entityId, $set); + $metadata = $source->getMetaData($index, $set); if($metadata !== NULL) { return $metadata; } } - throw new Exception('Unable to locate metadata for \'' . $entityId . '\' in set \'' . $set . '\'.'); + throw new Exception('Unable to locate metadata for \'' . $index . '\' in set \'' . $set . '\'.'); } } diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerFlatfile.php b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerFlatfile.php index 52c8eef49..e4a0fbcd6 100644 --- a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerFlatfile.php +++ b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerFlatfile.php @@ -1,6 +1,7 @@ <?php require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSAML/Configuration.php'); +require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSAML/Utilities.php'); require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSAML/Metadata/MetaDataStorageSource.php'); /** @@ -116,13 +117,36 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerFlatFile extends SimpleSAML_Meta /* Add the entity id of an entry to each entry in the metadata. */ foreach ($metadataSet AS $entityId => &$entry) { - $entry['entityid'] = $entityId; + if (preg_match('/__DYNAMIC(:[0-9]+)?__/', $entityId)) { + $entry['entityid'] = $this->generateDynamicHostedEntityID($set); + } else { + $entry['entityid'] = $entityId; + } } $this->cachedMetadata[$set] = $metadataSet; return $metadataSet; } + + private function generateDynamicHostedEntityID($set) { + + /* Get the configuration. */ + $config = SimpleSAML_Configuration::getInstance(); + $baseurl = SimpleSAML_Utilities::selfURLhost() . '/' . $config->getBaseURL(); + + if ($set === 'saml20-idp-hosted') { + return $baseurl . 'saml2/idp/metadata.php'; + } elseif($set === 'saml20-sp-hosted') { + return $baseurl . 'saml2/sp/metadata.php'; + } elseif($set === 'shib13-idp-hosted') { + return $baseurl . 'shib13/idp/metadata.php'; + } elseif($set === 'shib13-sp-hosted') { + return $baseurl . 'shib13/sp/metadata.php'; + } else { + throw new Exception('Can not generate dynamic EntityID for metadata of this type: [' . $set . ']'); + } + } } diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageSource.php b/lib/SimpleSAML/Metadata/MetaDataStorageSource.php index 29268bcb7..ce9622415 100644 --- a/lib/SimpleSAML/Metadata/MetaDataStorageSource.php +++ b/lib/SimpleSAML/Metadata/MetaDataStorageSource.php @@ -11,6 +11,7 @@ require_once((isset($SIMPLESAML_INCPREFIX)?$SIMPLESAML_INCPREFIX:'') . 'SimpleSA * to the getSource static function. * * @author Olav Morken, UNINETT AS. + * @author Andreas Aakre Solberg, UNINETT AS. * @package simpleSAMLphp * @version $Id$ */ @@ -70,21 +71,27 @@ abstract class SimpleSAML_Metadata_MetaDataStorageSource { * * @param $hostPath The host/path combination we are looking up. * @param $set Which set of metadata we are looking it up in. + * @param $type Do you want to return the metaindex or the entityID. [entityid|metaindex] + * @return An entity id which matches the given host/path combination, or NULL if * we are unable to locate one which matches. */ - public function getEntityIdFromHostPath($hostPath, $set) { + public function getEntityIdFromHostPath($hostPath, $set, $type = 'entityid') { $metadataSet = $this->getMetadataSet($set); - foreach($metadataSet AS $entityId => $entry) { + foreach($metadataSet AS $index => $entry) { if(!array_key_exists('host', $entry)) { continue; } if($hostPath === $entry['host']) { - return $entityId; + if ($type === 'entityid') { + return $entry['entityid']; + } else { + return $index; + } } } @@ -100,21 +107,27 @@ abstract class SimpleSAML_Metadata_MetaDataStorageSource { * * @param $set Which set of metadata we are looking it up in. * @param $ip IP address + * @param $type Do you want to return the metaindex or the entityID. [entityid|metaindex] * @return The entity id of a entity which have a CIDR hint where the provided * IP address match. */ - public function getPreferredEntityIdFromCIDRhint($set, $ip) { + public function getPreferredEntityIdFromCIDRhint($set, $ip, $type = 'entityid') { $metadataSet = $this->getMetadataSet($set); - foreach($metadataSet AS $entityId => $entry) { + foreach($metadataSet AS $index => $entry) { if(!array_key_exists('hint.cidr', $entry)) continue; if(!is_array($entry['hint.cidr'])) continue; foreach ($entry['hint.cidr'] AS $hint_entry) { - if (SimpleSAML_Utilities::ipCIDRcheck($hint_entry, $ip)) - return $entityId; + if (SimpleSAML_Utilities::ipCIDRcheck($hint_entry, $ip)) { + if ($type === 'entityid') { + return $entry['entityid']; + } else { + return $index; + } + } } } @@ -123,6 +136,21 @@ abstract class SimpleSAML_Metadata_MetaDataStorageSource { return NULL; } + /* + * + */ + private function lookupIndexFromEntityId($entityId, $set) { + + assert('is_string($entityId)'); + assert('isset($set)'); + + $metadataSet = $this->getMetadataSet($set); + + foreach($metadataSet AS $index => $entry) + if ($entry['entityid'] === $entityId) return $index; + + return NULL; + } /** * This function retrieves metadata for the given entity id in the given set of metadata. @@ -132,22 +160,26 @@ abstract class SimpleSAML_Metadata_MetaDataStorageSource { * override this function if it doesn't implement the getMetadataSet function, or if the * implementation of getMetadataSet is slow. * - * @param $entityId The entity id we are looking up. + * @param $index The entityId or metaindex we are looking up. * @param $set The set we are looking for metadata in. * @return An associative array with metadata for the given entity, or NULL if we are unable to * locate the entity. */ - public function getMetaData($entityId, $set) { + public function getMetaData($index, $set) { - assert('is_string($entityId)'); + assert('is_string($index)'); + assert('isset($set)'); $metadataSet = $this->getMetadataSet($set); - if(!array_key_exists($entityId, $metadataSet)) { - return NULL; - } + if(array_key_exists($index, $metadataSet)) + return $metadataSet[$index]; + + $indexlookup = $this->lookupIndexFromEntityId($index, $set); + if (isset($indexlookup) && array_key_exists($indexlookup, $metadataSet)) + return $metadataSet[$indexlookup]; - return $metadataSet[$entityId]; + return NULL; } } diff --git a/lib/SimpleSAML/XML/SAML20/AuthnResponse.php b/lib/SimpleSAML/XML/SAML20/AuthnResponse.php index 76b4669fa..c17ded36f 100644 --- a/lib/SimpleSAML/XML/SAML20/AuthnResponse.php +++ b/lib/SimpleSAML/XML/SAML20/AuthnResponse.php @@ -395,9 +395,18 @@ class SimpleSAML_XML_SAML20_AuthnResponse extends SimpleSAML_XML_AuthnResponse { } if ($base64) { - foreach(explode('_', $value) AS $v) { - $this->attributes[$name][] = base64_decode($v); + + if ($name != 'jpegPhoto') { + foreach(explode('_', $value) AS $v) { + + $this->attributes[$name][] = base64_decode($v); + } + + } else { + $this->attributes[$name][] = $value; + file_put_contents('/tmp/image2.jpg', $value); } + } else { $this->attributes[$name][] = $value; } diff --git a/metadata-templates/saml20-idp-hosted.php b/metadata-templates/saml20-idp-hosted.php index 1dada8ea5..d87cef831 100644 --- a/metadata-templates/saml20-idp-hosted.php +++ b/metadata-templates/saml20-idp-hosted.php @@ -28,10 +28,10 @@ $metadata = array( // The SAML entity ID is the index of this config. - 'idp.example.org' => array( + '__DYNAMIC:1__' => array( // The hostname of the server (VHOST) that this SAML entity will use. - 'host' => 'sp.example.org', + 'host' => '__DEFAULT__', // X.509 key and certificate. Relative to the cert directory. 'privatekey' => 'server.pem', diff --git a/metadata-templates/saml20-sp-hosted.php b/metadata-templates/saml20-sp-hosted.php index b540d2676..17ac7a7a2 100644 --- a/metadata-templates/saml20-sp-hosted.php +++ b/metadata-templates/saml20-sp-hosted.php @@ -27,8 +27,8 @@ $metadata = array( /* * Example of a hosted SP */ - 'sp-entityid' => array( - 'host' => 'sp.example.org' + '__DYNAMIC:1__' => array( + 'host' => '__DEFAULT__' ) ); diff --git a/metadata-templates/shib13-idp-hosted.php b/metadata-templates/shib13-idp-hosted.php index 10a5f190b..5a3313320 100644 --- a/metadata-templates/shib13-idp-hosted.php +++ b/metadata-templates/shib13-idp-hosted.php @@ -8,9 +8,9 @@ $metadata = array( - 'dev3.andreas.feide.no' => array( - 'issuer' => 'dev3.andreas.feide.no', - 'host' => 'dev3.andreas.feide.no', + '__DYNAMIC:1__' => array( + + 'host' => '__DEFAULT__', 'audience' => 'urn:mace:feide:shiblab', // X.509 key and certificate. Relative to the cert directory. diff --git a/metadata-templates/shib13-sp-hosted.php b/metadata-templates/shib13-sp-hosted.php index b61f4c867..cddb485e8 100644 --- a/metadata-templates/shib13-sp-hosted.php +++ b/metadata-templates/shib13-sp-hosted.php @@ -9,8 +9,8 @@ $metadata = array( /* * Example of hosted Shibboleth 1.3 SP. */ - 'sp-provider-id' => array( - 'host' => 'sp.example.org' + '__DYNAMIC:1__' => array( + 'host' => '__DEFAULT__' ) ); diff --git a/www/shib13/idp/SSOService.php b/www/shib13/idp/SSOService.php index 2eb81ecee..a99f48ff7 100644 --- a/www/shib13/idp/SSOService.php +++ b/www/shib13/idp/SSOService.php @@ -36,7 +36,8 @@ if (!$config->getValue('enable.shib13-idp', false)) SimpleSAML_Utilities::fatalError($session->getTrackID(), 'NOACCESS'); try { - $idpentityid = $metadata->getMetaDataCurrentEntityID('shib13-idp-hosted'); + $idpentityid = $metadata->getMetaDataCurrentEntityID('shib13-idp-hosted', 'entityid'); + $idmetaindex = $metadata->getMetaDataCurrentEntityID('shib13-idp-hosted', 'metaindex'); $idpmetadata = $metadata->getMetaDataCurrent('shib13-idp-hosted'); } catch (Exception $exception) { SimpleSAML_Utilities::fatalError($session->getTrackID(), 'METADATA', $exception); @@ -188,7 +189,7 @@ if (!$session->isAuthenticated($authority) ) { throw new Exception('Could not retrieve issuer of the AuthNRequest (ProviderID)'); $httppost->sendResponse($authnResponseXML, - $idpentityid, $issuer, isset($requestcache['RelayState']) ? $requestcache['RelayState'] : null, $shire); + $idpmetaindex, $issuer, isset($requestcache['RelayState']) ? $requestcache['RelayState'] : null, $shire); } catch(Exception $exception) { SimpleSAML_Utilities::fatalError($session->getTrackID(), 'GENERATEAUTHNRESPONSE', $exception); -- GitLab