From 4cd2bbd00075027161911e77acb0eceeed63fa34 Mon Sep 17 00:00:00 2001 From: Tim van Dijen <tvdijen@gmail.com> Date: Tue, 1 Mar 2022 23:37:46 +0100 Subject: [PATCH] Rewrite SAMLParser using symfony/filesystem --- lib/SimpleSAML/Metadata/SAMLParser.php | 49 +++++++++++++++++--------- 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/lib/SimpleSAML/Metadata/SAMLParser.php b/lib/SimpleSAML/Metadata/SAMLParser.php index 3b79cd0e6..46fa2b25d 100644 --- a/lib/SimpleSAML/Metadata/SAMLParser.php +++ b/lib/SimpleSAML/Metadata/SAMLParser.php @@ -6,6 +6,7 @@ namespace SimpleSAML\Metadata; use DOMDocument; use DOMElement; +use Exception; use RobRichards\XMLSecLibs\XMLSecurityDSig; use RobRichards\XMLSecLibs\XMLSecurityKey; use SAML2\Constants; @@ -38,6 +39,15 @@ use SAML2\XML\shibmd\Scope; use SimpleSAML\Assert\Assert; use SimpleSAML\Logger; use SimpleSAML\Utils; +use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\HttpFoundation\File\File; + +use function array_diff; +use function array_intersect; +use function array_key_exists; +use function array_map; +use function array_merge; +use function count; /** * This is class for parsing of SAML 2.0 metadata. @@ -161,6 +171,11 @@ class SAMLParser */ private string $entityDescriptor; + /** + * @var \Symfony\Component\Filesystem\Filesystem; + */ + protected Filesystem $fileSystem; + /** * This is the constructor for the SAMLParser class. @@ -177,6 +192,7 @@ class SAMLParser array $validators = [], array $parentExtensions = [] ) { + $this->fileSystem = new Filesystem(); $this->spDescriptors = []; $this->idpDescriptors = []; @@ -236,8 +252,8 @@ class SAMLParser try { $doc = DOMDocumentFactory::fromString($data); - } catch (\Exception $e) { - throw new \Exception('Failed to read XML from file: ' . $file); + } catch (Exception $e) { + throw new Exception('Failed to read XML from file: ' . $file); } return self::parseDocument($doc); @@ -256,8 +272,8 @@ class SAMLParser { try { $doc = DOMDocumentFactory::fromString($metadata); - } catch (\Exception $e) { - throw new \Exception('Failed to parse XML string.'); + } catch (Exception $e) { + throw new Exception('Failed to parse XML string.'); } return self::parseDocument($doc); @@ -307,7 +323,7 @@ class SAMLParser public static function parseDescriptorsFile(string $file): array { if (empty($file)) { - throw new \Exception('Cannot open file; file name not specified.'); + throw new Exception('Cannot open file; file name not specified.'); } /** @var string $data */ @@ -316,8 +332,8 @@ class SAMLParser try { $doc = DOMDocumentFactory::fromString($data); - } catch (\Exception $e) { - throw new \Exception('Failed to read XML from file: ' . $file); + } catch (Exception $e) { + throw new Exception('Failed to read XML from file: ' . $file); } return self::parseDescriptorsElement($doc->documentElement); @@ -339,8 +355,8 @@ class SAMLParser { try { $doc = DOMDocumentFactory::fromString($string); - } catch (\Exception $e) { - throw new \Exception('Failed to parse XML string.'); + } catch (Exception $e) { + throw new Exception('Failed to parse XML string.'); } return self::parseDescriptorsElement($doc->documentElement); @@ -361,7 +377,7 @@ class SAMLParser public static function parseDescriptorsElement(DOMElement $element = null): array { if ($element === null) { - throw new \Exception('Document was empty.'); + throw new Exception('Document was empty.'); } $xmlUtils = new Utils\XML(); @@ -370,7 +386,7 @@ class SAMLParser } elseif ($xmlUtils->isDOMNodeOfType($element, 'EntitiesDescriptor', '@md') === true) { return self::processDescriptorsElement(new EntitiesDescriptor($element)); } else { - throw new \Exception('Unexpected root node: [' . $element->namespaceURI . ']:' . $element->localName); + throw new Exception('Unexpected root node: [' . $element->namespaceURI . ']:' . $element->localName); } } @@ -1247,7 +1263,7 @@ class SAMLParser $xmlUtils = new Utils\XML(); if ($xmlUtils->isDOMNodeOfType($ed, 'EntityDescriptor', '@md') === false) { - throw new \Exception('Expected first element in the metadata document to be an EntityDescriptor element.'); + throw new Exception('Expected first element in the metadata document to be an EntityDescriptor element.'); } return new EntityDescriptor($ed); @@ -1270,12 +1286,13 @@ class SAMLParser foreach ($certificates as $cert) { Assert::string($cert); $certFile = $configUtils->getCertPath($cert); - if (!file_exists($certFile)) { - throw new \Exception( + if (!$this->fileSystem->exists($certFile)) { + throw new Exception( 'Could not find certificate file [' . $certFile . '], which is needed to validate signature' ); } - $certData = file_get_contents($certFile); + $file = new File($certFile); + $certData = $file->getContent(); foreach ($this->validators as $validator) { $key = new XMLSecurityKey(XMLSecurityKey::RSA_SHA256, ['type' => 'public']); @@ -1284,7 +1301,7 @@ class SAMLParser if ($validator->validate($key)) { return true; } - } catch (\Exception $e) { + } catch (Exception $e) { // this certificate did not sign this element, skip } } -- GitLab