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