From 124f93d208b1d12a1a35157554b9748b57f32b5a Mon Sep 17 00:00:00 2001
From: Kristof Bajnok <bajnokk@niif.hu>
Date: Tue, 14 Nov 2017 14:27:22 +0100
Subject: [PATCH] Make MDQ more robust on errors (fixes #723)

Don't bail out if the MDQ cache is broken or the query fails, because
later other metadata sources might provide the metadata for the entity.
---
 lib/SimpleSAML/Metadata/Sources/MDQ.php | 27 ++++++++++++++++++-------
 lib/SimpleSAML/Utils/HTTP.php           |  2 +-
 2 files changed, 21 insertions(+), 8 deletions(-)

diff --git a/lib/SimpleSAML/Metadata/Sources/MDQ.php b/lib/SimpleSAML/Metadata/Sources/MDQ.php
index d85a09ba1..975f79246 100644
--- a/lib/SimpleSAML/Metadata/Sources/MDQ.php
+++ b/lib/SimpleSAML/Metadata/Sources/MDQ.php
@@ -262,7 +262,8 @@ class MDQ extends \SimpleSAML_Metadata_MetaDataStorageSource
      *
      * @return array An associative array with metadata for the given entity, or NULL if we are unable to
      *         locate the entity.
-     * @throws \Exception If an error occurs while downloading metadata, validating the signature or writing to cache.
+     * @throws \Exception If an error occurs while validating the signature or the metadata is in an
+     *         incorrect set.
      */
     public function getMetaData($index, $set)
     {
@@ -272,7 +273,13 @@ class MDQ extends \SimpleSAML_Metadata_MetaDataStorageSource
         Logger::info(__CLASS__.': loading metadata entity ['.$index.'] from ['.$set.']');
 
         // read from cache if possible
-        $data = $this->getFromCache($set, $index);
+        try {
+            $data = $this->getFromCache($set, $index);
+        } catch (\Exception $e) {
+            Logger::error($e->getMessage());
+            // proceed with fetching metadata even if the cache is broken
+            $data = null;
+        }
 
         if ($data !== null && array_key_exists('expires', $data) && $data['expires'] < time()) {
             // metadata has expired
@@ -292,14 +299,15 @@ class MDQ extends \SimpleSAML_Metadata_MetaDataStorageSource
         try {
             $xmldata = HTTP::fetch($mdq_url);
         } catch (\Exception $e) {
-            Logger::warning('Fetching metadata for '.$index.': '.$e->getMessage());
+            // Avoid propagating the exception, make sure we can handle the error later
+            $xmldata = false;
         }
 
         if (empty($xmldata)) {
             $error = error_get_last();
-            throw new \Exception(
-                'Error downloading metadata for "'.$index.'" from "'.$mdq_url.'": '.$error['message']
-            );
+            Logger::info('Unable to fetch metadata for "'.$index.'" from '.$mdq_url.': '.
+                (is_array($error) ? $error['message'] : 'no error available'));
+            return null;
         }
 
         /** @var string $xmldata */
@@ -317,7 +325,12 @@ class MDQ extends \SimpleSAML_Metadata_MetaDataStorageSource
             throw new \Exception(__CLASS__.': no metadata for set "'.$set.'" available from "'.$index.'".');
         }
 
-        $this->writeToCache($set, $index, $data);
+        try {
+            $this->writeToCache($set, $index, $data);
+        } catch (\Exception $e) {
+            // Proceed without writing to cache
+            Logger::error('Error writing MDQ result to cache: '.$e->getMessage());
+        }
 
         return $data;
     }
diff --git a/lib/SimpleSAML/Utils/HTTP.php b/lib/SimpleSAML/Utils/HTTP.php
index abeca2e28..03b4d1bab 100644
--- a/lib/SimpleSAML/Utils/HTTP.php
+++ b/lib/SimpleSAML/Utils/HTTP.php
@@ -444,7 +444,7 @@ class HTTP
         }
 
         $context = stream_context_create($context);
-        $data = file_get_contents($url, false, $context);
+        $data = @file_get_contents($url, false, $context);
         if ($data === false) {
             $error = error_get_last();
             throw new \SimpleSAML_Error_Exception('Error fetching '.var_export($url, true).':'.
-- 
GitLab