diff options
-rw-r--r-- | setup.cfg | 2 | ||||
-rw-r--r-- | src/saml2/config.py | 7 | ||||
-rw-r--r-- | src/saml2/mdstore.py | 8 | ||||
-rw-r--r-- | tests/invalid_metadata_file.xml | 1 | ||||
-rw-r--r-- | tests/test_30_mdstore.py | 13 | ||||
-rw-r--r-- | tests/test_50_server.py | 14 |
6 files changed, 35 insertions, 10 deletions
@@ -54,7 +54,7 @@ install_requires = requests >= 1.0.0 six importlib_resources - xmlschema + xmlschema >= 1.2.1 [options.packages.find] diff --git a/src/saml2/config.py b/src/saml2/config.py index 8b865dcb..6687a60f 100644 --- a/src/saml2/config.py +++ b/src/saml2/config.py @@ -404,7 +404,12 @@ class Config(object): if endps and service in endps: for endpspec in endps[service]: try: - endp, bind = endpspec + # endspec sometime is str, sometime is a tuple + if type(endpspec) in (tuple, list): + # slice prevents 3-tuple, eg: sp's assertion_consumer_service + endp, bind = endpspec[0:2] + else: + endp, bind = endpspec if binding is None or bind == binding: spec.append(endp) except ValueError: diff --git a/src/saml2/mdstore.py b/src/saml2/mdstore.py index 96acfa1e..44930773 100644 --- a/src/saml2/mdstore.py +++ b/src/saml2/mdstore.py @@ -7,12 +7,12 @@ import os import sys from itertools import chain from warnings import warn as _warn - from hashlib import sha1 from os.path import isfile from os.path import join import requests + import six from saml2 import md @@ -24,7 +24,6 @@ from saml2 import SAMLError from saml2 import BINDING_HTTP_REDIRECT from saml2 import BINDING_HTTP_POST from saml2 import BINDING_SOAP - from saml2.httpbase import HTTPBase from saml2.extension.idpdisc import BINDING_DISCO from saml2.extension.idpdisc import DiscoveryResponse @@ -612,7 +611,10 @@ class InMemoryMetaData(MetaData): self.entity[entity_descr.entity_id] = _ent def parse(self, xmlstr): - self.entities_descr = md.entities_descriptor_from_string(xmlstr) + try: + self.entities_descr = md.entities_descriptor_from_string(xmlstr) + except Exception as e: + raise SAMLError(f'Failed to parse metadata file: {self.filename}') from e if not self.entities_descr: self.entity_descr = md.entity_descriptor_from_string(xmlstr) diff --git a/tests/invalid_metadata_file.xml b/tests/invalid_metadata_file.xml new file mode 100644 index 00000000..249c87ce --- /dev/null +++ b/tests/invalid_metadata_file.xml @@ -0,0 +1 @@ +this content is invalid diff --git a/tests/test_30_mdstore.py b/tests/test_30_mdstore.py index 4dfa80f3..bfe261dd 100644 --- a/tests/test_30_mdstore.py +++ b/tests/test_30_mdstore.py @@ -7,6 +7,8 @@ from collections import OrderedDict from unittest.mock import Mock from unittest.mock import patch +from pytest import raises + import responses from six.moves.urllib import parse @@ -19,6 +21,7 @@ from saml2.mdstore import locations from saml2.mdstore import name from saml2 import sigver from saml2.httpbase import HTTPBase +from saml2 import SAMLError from saml2 import BINDING_SOAP from saml2 import BINDING_HTTP_REDIRECT from saml2 import BINDING_HTTP_POST @@ -156,6 +159,10 @@ METADATACONF = { "class": "saml2.mdstore.MetaDataFile", "metadata": [(full_path("swamid-2.0.xml"),)], }], + "14": [{ + "class": "saml2.mdstore.MetaDataFile", + "metadata": [(full_path("invalid_metadata_file.xml"),)], + }], } @@ -170,6 +177,12 @@ def _fix_valid_until(xmlstring): xmlstring) +def test_invalid_metadata(): + mds = MetadataStore(ATTRCONV, sec_config, disable_ssl_certificate_validation=True) + with raises(SAMLError): + mds.imp(METADATACONF["14"]) + + def test_swami_1(): UMU_IDP = 'https://idp.umu.se/saml2/idp/metadata.php' mds = MetadataStore(ATTRCONV, sec_config, diff --git a/tests/test_50_server.py b/tests/test_50_server.py index dfc24eee..07ef4b91 100644 --- a/tests/test_50_server.py +++ b/tests/test_50_server.py @@ -6,6 +6,7 @@ import os from contextlib import closing from six.moves.urllib.parse import parse_qs import uuid +import re from saml2.cert import OpenSSLWrapper from saml2.sigver import make_temp, DecryptError, EncryptError, CertificateError @@ -129,8 +130,10 @@ class TestServer1(): self.verify_assertion(assertion) assert assertion[0].signature is None - assert 'EncryptedAssertion><encas1:Assertion xmlns:encas0="http://www.w3.org/2001/XMLSchema-instance" ' \ - 'xmlns:encas1="urn:oasis:names:tc:SAML:2.0:assertion"' in decr_text + assert re.search( + r':EncryptedAssertion><encas[0-9]:Assertion ([^ >]* )*xmlns:encas[0-9]="urn:oasis:names:tc:SAML:2.0:assertion"', + decr_text, + ) def verify_advice_assertion(self, resp, decr_text): assert resp.assertion[0].signature is None @@ -1188,9 +1191,10 @@ class TestServer1NonAsciiAva(): def verify_encrypted_assertion(self, assertion, decr_text): self.verify_assertion(assertion) assert assertion[0].signature is None - - assert 'EncryptedAssertion><encas1:Assertion xmlns:encas0="http://www.w3.org/2001/XMLSchema-instance" ' \ - 'xmlns:encas1="urn:oasis:names:tc:SAML:2.0:assertion"' in decr_text + assert re.search( + r':EncryptedAssertion><encas[0-9]:Assertion ([^ >]* )*xmlns:encas[0-9]="urn:oasis:names:tc:SAML:2.0:assertion"', + decr_text, + ) def verify_advice_assertion(self, resp, decr_text): assert resp.assertion[0].signature is None |