diff --git a/lib/SimpleSAML/Bindings/SAML20/HTTPPost.php b/lib/SimpleSAML/Bindings/SAML20/HTTPPost.php index 21db2627c45fb0aa9efc12556b831bb26cceacf9..8c64cde2adea86843d02358fb5af3af5dbb04d77 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 d9faa9085be2242738fde790c14dbdaff5a9bc2a..d917508b44511bb192ea65016a35c59eaaa19e49 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 9eab4050c5db616bfe4e7dbb36bfc594e35cecfa..9398679a8fb36a7144857d1aa788187cea772db6 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 52c8eef490dc7b0682374f70a61e86e69b3201ae..e4a0fbcd6aa8c2e1b6361a022276e5a794d807e3 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 29268bcb7906ec71590ab374c2e0434fb633e1f2..ce96224158b058bc5292ffb18eb04a4208d8d7a0 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 76b4669fa505af3be43ab3c7a15a77926070f88e..c17ded36f41e90af500ce62464b7b5dfcd5acbf8 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 1dada8ea5bf4c6e6e189daa5d6c899e26ea2552d..d87cef831aa9b9c5cd4065a0bec06d6b41a67ad7 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 b540d2676854ffb89819981ba114d744ad184889..17ac7a7a243e2e62af4d0bc9a1a14a4f91fbbc51 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 10a5f190b3dc4f3aa0e895a30caf8060bc80e777..5a33133209a0c5654ea02684f54da030263d842d 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 b61f4c867e77a9732547764afa88de098444b138..cddb485e832b5bf4bb8fee08ab5f939726cf00ac 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 2eb81ecee3eb42f3108ce62003028af4f25b9cda..a99f48ff74126e0f9753f12de710a100a9674546 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);