70        if (!array_key_exists(
'server', 
$config)) {
 
   71            throw new \Exception(__CLASS__.
": the 'server' configuration option is not set.");
 
   73            $this->server = 
$config[
'server'];
 
   76        if (array_key_exists(
'validateFingerprint', 
$config)) {
 
   77            $this->validateFingerprint = 
$config[
'validateFingerprint'];
 
   79            $this->validateFingerprint = 
null;
 
   82        if (array_key_exists(
'cachedir', 
$config)) {
 
   86            $this->cacheDir = 
null;
 
   89        if (array_key_exists(
'cachelength', 
$config)) {
 
   90            $this->cacheLength = 
$config[
'cachelength'];
 
   92            $this->cacheLength = 86400;
 
  121        assert(is_string($set));
 
  125        return $this->cacheDir.
'/'.$set.
'-'.$cachekey.
'.cached.xml';
 
  141        assert(is_string($set));
 
  144        if (empty($this->cacheDir)) {
 
  149        if (!file_exists($cachefilename)) {
 
  152        if (!is_readable($cachefilename)) {
 
  153            throw new \Exception(__CLASS__.
': could not read cache file for entity ['.$cachefilename.
']');
 
  161        $stat = stat($cachefilename);
 
  162        if ($stat[
'mtime'] + $this->cacheLength <= time()) {
 
  163            Logger::debug(__CLASS__.
': cache file older that the cachelength option allows.');
 
  167        $rawData = file_get_contents($cachefilename);
 
  168        if (empty($rawData)) {
 
  169            $error = error_get_last();
 
  170            throw new \Exception(
 
  171                __CLASS__.
': error reading metadata from cache file "'.$cachefilename.
'": '.$error[
'message']
 
  175        $data = unserialize($rawData);
 
  176        if (
$data === 
false) {
 
  177            throw new \Exception(__CLASS__.
': error unserializing cached data from file "'.$cachefilename.
'".');
 
  180        if (!is_array(
$data)) {
 
  181            throw new \Exception(__CLASS__.
': Cached metadata from "'.$cachefilename.
'" wasn\'t an array.');
 
  199        assert(is_string($set));
 
  201        assert(is_array(
$data));
 
  203        if (empty($this->cacheDir)) {
 
  208        if (!is_writable(dirname($cachefilename))) {
 
  209            throw new \Exception(__CLASS__.
': could not write cache file for entity ['.$cachefilename.
']');
 
  212        file_put_contents($cachefilename, serialize(
$data));
 
  227        assert(is_string($set));
 
  230            case 'saml20-idp-remote':
 
  232            case 'saml20-sp-remote':
 
  234            case 'shib13-idp-remote':
 
  236            case 'shib13-sp-remote':
 
  238            case 'attributeauthority-remote':
 
  268    public function getMetaData($index, $set) 
  270        assert(is_string($index)); 
  271        assert(is_string($set)); 
  273        Logger::info(__CLASS__.': loading metadata entity [
'.$index.'] from [
'.$set.']
'); 
  275        // read from cache if possible 
  277            $data = $this->getFromCache($set, $index); 
  278        } catch (\Exception $e) { 
  279            Logger::error($e->getMessage()); 
  280            // proceed with fetching metadata even if the cache is broken 
  284        if ($data !== null && array_key_exists('expires
', $data) && $data['expires
'] < time()) { 
  285            // metadata has expired 
  290            // metadata found in cache and not expired 
  291            Logger::debug(__CLASS__.': 
using cached metadata 
for: 
'.$index.'.
'); 
  295        // look at Metadata Query Protocol: https://github.com/iay/md-query/blob/master/draft-young-md-query.txt 
  296        $mdq_url = $this->server.'/entities/
'.urlencode($index); 
  298        Logger::debug(__CLASS__.': downloading metadata 
for "'.$index.'" from [
'.$mdq_url.']
'); 
  300            $xmldata = HTTP::fetch($mdq_url); 
  301        } catch (\Exception $e) { 
  302            // Avoid propagating the exception, make sure we can handle the error later 
  306        if (empty($xmldata)) { 
  307            $error = error_get_last(); 
  308            Logger::info('Unable to fetch metadata 
for "'.$index.'" from 
'.$mdq_url.': 
'. 
  309                (is_array($error) ? $error['message
'] : 'no 
error available
')); 
  314        $entity = \SimpleSAML_Metadata_SAMLParser::parseString($xmldata); 
  315        Logger::debug(__CLASS__.': completed parsing of [
'.$mdq_url.']
'); 
  317        if ($this->validateFingerprint !== null) { 
  318            if (!$entity->validateFingerprint($this->validateFingerprint)) { 
  319                throw new \Exception(__CLASS__.': 
error, could not verify signature 
for entity: 
'.$index.'".'); 
  323        $data = self::getParsedSet($entity, $set); 
  324        if ($data === null) { 
  325            throw new \Exception(__CLASS__.': no metadata for set "'.$set.'" available from "'.$index.'".'); 
  329            $this->writeToCache($set, $index, $data); 
  330        } catch (\Exception $e) { 
  331            // Proceed without writing to cache 
  332            Logger::error('Error writing MDQ result to cache: '.$e->getMessage()); 
An exception for terminatinating execution or to throw for unit testing.
static getInstance($instancename='simplesaml')
Get a configuration file by its instance name.
error($a_errmsg)
set error message @access public