From e8520be90c3d8ff000e5bcd2c4eb7ab83cf28441 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=85kre=20Solberg?= <andreas.solberg@uninett.no> Date: Thu, 17 Jan 2008 11:06:59 +0000 Subject: [PATCH] Added the possibility for the logger to get the trackID it self... Temporary thing, we shuold rewrite and improve the logging class a bit. git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@165 44740490-163a-0410-bde0-09ae8108e29a --- lib/SimpleSAML/Logger.php | 9 +- .../MetaDataStorageHandlerSAML2Meta.php | 205 +++++++++++++++--- lib/SimpleSAML/XML/Parser.php | 9 + templates/default/en/admin-metadatalist.php | 9 + www/admin/metadata.php | 53 +++++ 5 files changed, 256 insertions(+), 29 deletions(-) diff --git a/lib/SimpleSAML/Logger.php b/lib/SimpleSAML/Logger.php index 7b2daad00..d6392d798 100644 --- a/lib/SimpleSAML/Logger.php +++ b/lib/SimpleSAML/Logger.php @@ -9,7 +9,7 @@ */ require_once('SimpleSAML/Configuration.php'); - +require_once('SimpleSAML/Session.php'); /** * A logger class. @@ -33,9 +33,14 @@ class SimpleSAML_Logger { /* * Log a message to syslog. */ - public function log($priority, $trackid, $module, $submodule, $eventtype, $content, $message) { + public function log($priority, $trackid = null, $module, $submodule, $eventtype, $content, $message) { if ($priority < $this->loglevel) return; + if ($trackid == null) { + $session = SimpleSAML_Session::getInstance(true); + $trackid = $session->getTrackID(); + } + $contentstring = ''; if (is_array($content)) { $contentstring = implode('|', $content); diff --git a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerSAML2Meta.php b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerSAML2Meta.php index 018a368f6..f5376c440 100644 --- a/lib/SimpleSAML/Metadata/MetaDataStorageHandlerSAML2Meta.php +++ b/lib/SimpleSAML/Metadata/MetaDataStorageHandlerSAML2Meta.php @@ -13,6 +13,7 @@ require_once('SimpleSAML/Configuration.php'); require_once('SimpleSAML/Utilities.php'); require_once('SimpleSAML/XML/Parser.php'); require_once('SimpleSAML/Metadata/MetaDataStorageHandler.php'); +require_once('SimpleSAML/Logger.php'); /** * Configuration of SimpleSAMLphp @@ -21,6 +22,7 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerSAML2Meta extends SimpleSAML_Met private static $cachedfiles; + private $logger; /* This constructor is included in case it is needed in the the * future. Including it now allows us to write parent::__construct() in @@ -28,6 +30,8 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerSAML2Meta extends SimpleSAML_Met */ protected function __construct() { if (!isset($this->cachedfiles)) $this->cachedfiles = array(); + $this->logger = new SimpleSAML_Logger(); + } @@ -54,36 +58,61 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerSAML2Meta extends SimpleSAML_Met $config = SimpleSAML_Configuration::getInstance(); assert($config instanceof SimpleSAML_Configuration); + + $metadatalocations = $config->getValue('metadata.locations'); - $metadatasetfile = $config->getBaseDir() . '' . - $config->getValue('metadatadir') . 'xml/' . $settofile[$set] . '.xml'; + if (!is_array($metadatalocations)) throw new Exception('Could not find config parameter: metadata.locations in config.php'); + if (!array_key_exists($set, $metadatalocations)) throw new Exception('Could not find metadata location for this set: ' . $set); + $metadatalocation = $metadatalocations[$set]; - if (array_key_exists($metadatasetfile, $this->cachedfiles)) { - $metadataxml = self::$cachedfiles[$metadatasetfile]; + $xml = true; + if (preg_match('@^http(s)?://@i', $metadatalocation)) { + // The metadata location is an URL + $metadatasetfile = $metadatalocation; } else { + $metadatasetfile = $config->getBaseDir() . '' . + $config->getValue('metadatadir') . $metadatalocation; if (!file_exists($metadatasetfile)) throw new Exception('Could not find SAML 2.0 Metadata file :'. $metadatasetfile); - - // for now testing with the shib aai metadata... - //$metadataxml = file_get_contents("http://www.switch.ch/aai/federation/SWITCHaai/metadata.switchaai_signed.xml"); - $metadataxml = file_get_contents($metadatasetfile); - self::$cachedfiles[$metadatasetfile] = $metadataxml; + if (preg_match('@\.php$@', $metadatalocation)) { + $xml = false; + } } - $metadata = null; - switch ($set) { - case 'saml20-idp-remote' : $metadata = $this->getmetadata_saml20idpremote($metadataxml); break; - case 'saml20-idp-hosted' : $metadata = $this->getmetadata_saml20idphosted($metadataxml); break; - case 'saml20-sp-remote' : $metadata = $this->getmetadata_saml20spremote($metadataxml); break; - case 'saml20-sp-hosted' : $metadata = $this->getmetadata_saml20sphosted($metadataxml); break; - case 'shib13-idp-remote' : $metadata = $this->getmetadata_shib13idpremote($metadataxml); break; - case 'shib13-idp-hosted' : throw new Exception('Meta data parsing for Shib 1.3 IdP Hosted not yet implemented.'); - case 'shib13-sp-remote' : throw new Exception('Meta data parsing for Shib 1.3 SP Remote not yet implemented.'); - case 'shib13-sp-hosted' : throw new Exception('Meta data parsing for Shib 1.3 SP Hosted not yet implemented.'); + + if ($xml) { + + if (array_key_exists($metadatasetfile, $this->cachedfiles)) { + $metadataxml = self::$cachedfiles[$metadatasetfile]; + } else { + $metadataxml = file_get_contents($metadatasetfile); + self::$cachedfiles[$metadatasetfile] = $metadataxml; + } + /* + echo '<pre>content:'; print_r($metadataxml); echo '</pre>'; + echo '<p>file[' . $metadatasetfile. ']'; + */ + $metadata = null; + switch ($set) { + case 'saml20-idp-remote' : $metadata = $this->getmetadata_saml20idpremote($metadataxml); break; + case 'saml20-idp-hosted' : $metadata = $this->getmetadata_saml20idphosted($metadataxml); break; + case 'saml20-sp-remote' : $metadata = $this->getmetadata_saml20spremote($metadataxml); break; + case 'saml20-sp-hosted' : $metadata = $this->getmetadata_saml20sphosted($metadataxml); break; + case 'shib13-idp-remote' : $metadata = $this->getmetadata_shib13idpremote($metadataxml); break; + case 'shib13-idp-hosted' : throw new Exception('Not implemented SAML 2.0 XML metadata for Shib 1.3 IdP Hosted, use files instead.'); break; + case 'shib13-sp-remote' : $metadata = $this->getmetadata_shib13spremote($metadataxml); break; + case 'shib13-sp-hosted' : throw new Exception('Not implemented SAML 2.0 XML metadata for Shib 1.3 SP Hosted, use files instead.'); break; + } + + } else { + + $metadata = $this->loadFile($metadatasetfile); } - if (!is_array($metadata)) { + $this->logger->log(LOG_INFO, null, 'MetaData', 'Handler.SAML2Meta', 'INFO', 'Loading', + 'Loading metadata set [' . $set . '] from [' . $metadatasetfile . ']' ); + + if (!is_array($metadata)) throw new Exception('Could not load metadata set [' . $set . '] from file: ' . $metadatasetfile); - } /* echo '<pre>'; print_r($metadata); @@ -98,6 +127,21 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerSAML2Meta extends SimpleSAML_Met $this->hostmap[$set][$entry['host']] = $key; } } + + + } + + private function loadFile($metadatasetfile) { + $metadata = null; + if (!file_exists($metadatasetfile)) { + throw new Exception('Could not open file: ' . $metadatasetfile); + } + include($metadatasetfile); + + if (!is_array($metadata)) { + throw new Exception('(SAML2Metastoragehandler:loadFile)Could not load metadata set [' . $set . '] from file: ' . $metadatasetfile); + } + return $metadata; } @@ -141,7 +185,8 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerSAML2Meta extends SimpleSAML_Met } catch (Exception $e) { - echo 'Error reading one metadata entry: ' . $e; + $this->logger->log(LOG_INFO, null, 'MetaData', 'Handler.SAML2Meta', 'WARNING', 'Parsing', + 'Error parsing [' . __FUNCTION__ . '] ' . $e->getMessage() ); } } @@ -178,7 +223,8 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerSAML2Meta extends SimpleSAML_Met $metadata[$entityid]['ForceAuthn'] = (isset($seek_forceauth) ? ($seek_forceauth === 'true') : false); } catch (Exception $e) { - echo 'Error reading one metadata entry: ' . $e; + $this->logger->log(LOG_INFO, null, 'MetaData', 'Handler.SAML2Meta', 'WARNING', 'Parsing', + 'Error parsing [' . __FUNCTION__ . '] ' . $e->getMessage() ); } } @@ -223,8 +269,8 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerSAML2Meta extends SimpleSAML_Met $metadata[$entityid]['requireconsent'] = (isset($seek_requireconsent) ? ($seek_requireconsent === 'true') : false); } catch (Exception $e) { - // TODO: do syslog, not echo. - echo 'Error reading one metadata entry: ' . $e; + $this->logger->log(LOG_INFO, null, 'MetaData', 'Handler.SAML2Meta', 'WARNING', 'Parsing', + 'Error parsing [' . __FUNCTION__ . '] ' . $e->getMessage() ); } } @@ -289,7 +335,8 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerSAML2Meta extends SimpleSAML_Met } catch (Exception $e) { - echo 'Error reading one metadata entry: ' . $e; + $this->logger->log(LOG_INFO, null, 'MetaData', 'Handler.SAML2Meta', 'WARNING', 'Parsing', + 'Error parsing [' . __FUNCTION__ . '] ' . $e->getMessage() ); } } @@ -319,15 +366,119 @@ class SimpleSAML_Metadata_MetaDataStorageHandlerSAML2Meta extends SimpleSAML_Met $metadata_entry = SimpleSAML_XML_Parser::fromSimpleXMLElement($idpentity); $metadata[$entityid]['SingleSignOnService'] = $metadata_entry->getValue("/saml2meta:EntityDescriptor/saml2meta:IDPSSODescriptor/saml2meta:SingleSignOnService[@Binding='urn:mace:shibboleth:1.0:profiles:AuthnRequest']/@Location", true); + + $metadata[$entityid]['certFingerprint'] = SimpleSAML_Utilities::cert_fingerprint($metadata_entry->getValue("/saml2meta:EntityDescriptor/saml2meta:IDPSSODescriptor/saml2meta:KeyDescriptor[@use='signing']/ds:KeyInfo/ds:X509Data/ds:X509Certificate", true)); + + $seek_base64 = $metadata_entry->getValue("/saml2meta:EntityDescriptor/saml2meta:IDPSSODescriptor/saml2meta:Extensions/saml2:Attribute[@Name='urn:mace:feide.no:simplesamlphp:base64attributes']/saml2:AttributeValue"); + $metadata[$entityid]['base64attributes'] = (isset($seek_base64) ? ($seek_base64 === 'true') : false); + + + $metadata[$entityid]['name'] = $metadata_entry->getValueAlternatives( + array("/saml2meta:EntityDescriptor/saml2meta:IDPSSODescriptor/saml2meta:Extensions/saml2:Attribute[@Name='urn:mace:feide.no:simplesamlphp:name']/saml2:AttributeValue", + "/saml2meta:EntityDescriptor/saml2meta:IDPSSODescriptor/saml2meta:Organization/saml2meta:OrganizationDisplayName" + )); + + $metadata[$entityid]['description'] = $metadata_entry->getValue("/saml2meta:EntityDescriptor/saml2meta:IDPSSODescriptor/saml2meta:Extensions/saml2:Attribute[@Name='urn:mace:feide.no:simplesamlphp:description']/saml2:AttributeValue"); + } catch (Exception $e) { - echo 'Error reading one metadata entry: ' . $e; + $this->logger->log(LOG_INFO, null, 'MetaData', 'Handler.SAML2Meta', 'WARNING', 'Parsing', + 'Error parsing [' . __FUNCTION__ . '] ' . $e->getMessage() ); } } return $metadata; } + + /* + <EntityDescriptor entityID="https://tim-test.ethz.ch/shibboleth"> + <SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:1.1:protocol"> + <KeyDescriptor use="signing"> + <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> + <ds:KeyName>tim-test.ethz.ch</ds:KeyName> + </ds:KeyInfo> + </KeyDescriptor> + <NameIDFormat>urn:mace:shibboleth:1.0:nameIdentifier</NameIDFormat> + + <AssertionConsumerService Binding="urn:oasis:names:tc:SAML:1.0:profiles:browser-post" + Location="https://tim-test.ethz.ch/Shibboleth.shire" index="1" isDefault="true"/> + + </SPSSODescriptor> + + + </EntityDescriptor> + */ + private function getmetadata_shib13spremote($metadataxml) { + // Create a parser for the metadata document. + $metadata_parser = new SimpleSAML_XML_Parser($metadataxml); + + // Get all entries in the metadata. + $idpentities = $metadata_parser->simplexml->xpath('/saml2meta:EntitiesDescriptor/saml2meta:EntityDescriptor[./saml2meta:SPSSODescriptor]'); + if (!$idpentities) throw new Exception('Could not find any entity descriptors in the meta data file: ' . $metadatasetfile); + + // Array to hold the resulting metadata, to return at the end of this function. + $metadata = array(); + + // Traverse all entries. + foreach ($idpentities as $idpentity) { + try { + $entityid = (string) $idpentity['entityID']; + if (!$entityid) throw new Exception('Could not find entityID in element'); + + + /* + array('entityid', 'spNameQualifier', 'AssertionConsumerService', 'SingleLogoutService', 'NameIDFormat'), + array('base64attributes', 'attributemap', 'simplesaml.attributes', 'attributes') + */ + + $metadata[$entityid] = array('entityid' => $entityid); + $metadata_entry = SimpleSAML_XML_Parser::fromSimpleXMLElement($idpentity); + + $metadata[$entityid]['spNameQualifier'] = $metadata_entry->getValueDefault("/saml2meta:EntityDescriptor/saml2meta:SPSSODescriptor/saml2meta:Extensions/saml2:Attribute[@Name='urn:mace:feide.no:simplesamlphp:spnamequalifier']/saml2:AttributeValue", $metadata[$entityid]['entityid']); + + $metadata[$entityid]['audience'] = $metadata_entry->getValueDefault("/saml2meta:EntityDescriptor/saml2meta:SPSSODescriptor/saml2meta:Extensions/saml2:Attribute[@Name='urn:mace:feide.no:simplesamlphp:audience']/saml2:AttributeValue", $metadata[$entityid]['entityid']); + + + $metadata[$entityid]['NameIDFormat'] = $metadata_entry->getValueDefault("/saml2meta:EntityDescriptor/saml2meta:SPSSODescriptor/saml2meta:NameIDFormat", + 'urn:mace:shibboleth:1.0:nameIdentifier'); + + $seek_base64 = $metadata_entry->getValue("/saml2meta:EntityDescriptor/saml2meta:SPSSODescriptor/saml2meta:Extensions/saml2:Attribute[@Name='urn:mace:feide.no:simplesamlphp:base64attributes']/saml2:AttributeValue"); + $metadata[$entityid]['base64attributes'] = (isset($seek_base64) ? ($seek_base64 === 'true') : false); + + + $metadata[$entityid]['name'] = $metadata_entry->getValueAlternatives( + array("/saml2meta:EntityDescriptor/saml2meta:SPSSODescriptor/saml2meta:Extensions/saml2:Attribute[@Name='urn:mace:feide.no:simplesamlphp:name']/saml2:AttributeValue", + "/saml2meta:EntityDescriptor/saml2meta:SPSSODescriptor/saml2meta:Organization/saml2meta:OrganizationDisplayName" + )); + + $metadata[$entityid]['description'] = $metadata_entry->getValue("/saml2meta:EntityDescriptor/saml2meta:SPSSODescriptor/saml2meta:Extensions/saml2:Attribute[@Name='urn:mace:feide.no:simplesamlphp:description']/saml2:AttributeValue"); + + $metadata[$entityid]['simplesaml.attributes'] = $metadata_entry->getValue("/saml2meta:EntityDescriptor/saml2meta:SPSSODescriptor/saml2meta:Extensions/saml2:Attribute[@Name='urn:mace:feide.no:simplesamlphp:simplesaml.attributes']/saml2:AttributeValue"); + + + $seek_attributes = $metadata_entry->getValue("/saml2meta:EntityDescriptor/saml2meta:SPSSODescriptor/saml2meta:Extensions/saml2:Attribute[@Name='urn:mace:feide.no:simplesamlphp:attributes']/saml2:AttributeValue"); + if (isset($seek_attributes)) $metadata[$entityid]['attributes'] = explode(',', $seek_attributes); + + $metadata[$entityid]['attributemap'] = $metadata_entry->getValue("/saml2meta:EntityDescriptor/saml2meta:SPSSODescriptor/saml2meta:Extensions/saml2:Attribute[@Name='urn:mace:feide.no:simplesamlphp:attributemap']/saml2:AttributeValue"); + + $metadata[$entityid]['AssertionConsumerService'] = $metadata_entry->getValue("/saml2meta:EntityDescriptor/saml2meta:SPSSODescriptor/saml2meta:AssertionConsumerService/@Location", true); + + + + } catch (Exception $e) { + $this->logger->log(LOG_INFO, null, 'MetaData', 'Handler.SAML2Meta', 'WARNING', 'Parsing', + 'Error parsing [' . __FUNCTION__ . '] ' . $e->getMessage() ); + } + + } + return $metadata; + } + + + + + public function getMetaData($entityid = null, $set = 'saml20-sp-hosted') { if (!isset($entityid)) { return $this->getMetaDataCurrent($set); diff --git a/lib/SimpleSAML/XML/Parser.php b/lib/SimpleSAML/XML/Parser.php index f5e88866f..82ce7ada1 100644 --- a/lib/SimpleSAML/XML/Parser.php +++ b/lib/SimpleSAML/XML/Parser.php @@ -17,6 +17,7 @@ class SimpleSAML_XML_Parser { var $simplexml = null; + function __construct($xml) { #parent::construct($xml); @@ -44,6 +45,14 @@ class SimpleSAML_XML_Parser { } + public function getValueDefault($xpath, $defvalue) { + try { + return $this->getValue($xpath, true); + } catch (Exception $e) { + return $defvalue; + } + } + public function getValue($xpath, $required = false) { $result = $this->simplexml->xpath($xpath); diff --git a/templates/default/en/admin-metadatalist.php b/templates/default/en/admin-metadatalist.php index 22fd84de3..9dec31ca1 100644 --- a/templates/default/en/admin-metadatalist.php +++ b/templates/default/en/admin-metadatalist.php @@ -84,6 +84,15 @@ if (array_key_exists('metadata.saml20-idp-remote', $data)) showEntry('SAML 2.0 Identity Provider (Remote)', $data['metadata.saml20-idp-remote']); + if (array_key_exists('metadata.shib13-sp-hosted', $data)) + showEntry('Shib 1.3 Service Provider (Hosted)', $data['metadata.shib13-sp-hosted']); + if (array_key_exists('metadata.shib13-sp-remote', $data)) + showEntry('Shib 1.3 Service Provider (Remote)', $data['metadata.shib13-sp-remote']); + if (array_key_exists('metadata.shib13-idp-hosted', $data)) + showEntry('Shib 1.3 Identity Provider (Hosted)', $data['metadata.shib13-idp-hosted']); + if (array_key_exists('metadata.shib13-idp-remote', $data)) + showEntry('Shib 1.3 Identity Provider (Remote)', $data['metadata.shib13-idp-remote']); + ?> diff --git a/www/admin/metadata.php b/www/admin/metadata.php index 56491ee8c..301aacb28 100644 --- a/www/admin/metadata.php +++ b/www/admin/metadata.php @@ -65,6 +65,59 @@ try { } + + + + if ($config->getValue('enable.shib13-sp') === true) { + $results = array(); + + $metalist = $metadata->getList('shib13-sp-hosted'); + foreach ($metalist AS $entityid => $mentry) { + $results[$entityid] = SimpleSAML_Utilities::checkAssocArrayRules($mentry, + array('entityid', 'host', 'NameIDFormat', 'ForceAuthn'), + array() + ); + } + $et->data['metadata.shib13-sp-hosted'] = $results; + + $results = array(); + $metalist = $metadata->getList('shib13-idp-remote'); + foreach ($metalist AS $entityid => $mentry) { + $results[$entityid] = SimpleSAML_Utilities::checkAssocArrayRules($mentry, + array('entityid', 'SingleSignOnService', 'SingleLogoutService', 'certFingerprint'), + array('name', 'description', 'base64attributes') + ); + } + $et->data['metadata.shib13-idp-remote'] = $results; + + } + + if ($config->getValue('enable.shib13-idp') === true) { + $results = array(); + $metalist = $metadata->getList('shib13-idp-hosted'); + foreach ($metalist AS $entityid => $mentry) { + $results[$entityid] = SimpleSAML_Utilities::checkAssocArrayRules($mentry, + array('entityid', 'host', 'privatekey', 'certificate', 'auth'), + array('requireconsent') + ); + } + $et->data['metadata.shib13-idp-hosted'] = $results; + + $results = array(); + $metalist = $metadata->getList('shib13-sp-remote'); + foreach ($metalist AS $entityid => $mentry) { + $results[$entityid] = SimpleSAML_Utilities::checkAssocArrayRules($mentry, + array('entityid', 'spNameQualifier', 'AssertionConsumerService', 'audience', 'NameIDFormat'), + array('base64attributes', 'attributemap', 'simplesaml.attributes', 'attributes', 'name', 'description') + ); + } + $et->data['metadata.shib13-sp-remote'] = $results; + + } + + + + $et->data['header'] = 'Metadata overview'; -- GitLab