diff options
author | Roland Hedberg <roland@catalogix.se> | 2017-04-24 15:46:35 +0200 |
---|---|---|
committer | Roland Hedberg <roland@catalogix.se> | 2017-04-24 15:46:35 +0200 |
commit | 91bce29d7fd66537797cefa554f63edd0e404ce1 (patch) | |
tree | ddbfeeb2718d88fe5ac97b4be65855e402f8a182 /tests | |
parent | e2adbb523c37643453fbe62469ca7fb2bf1b43f0 (diff) | |
parent | 47e1b34f6c6fd9a48405f1560f24619d77526b3a (diff) | |
download | pysaml2-91bce29d7fd66537797cefa554f63edd0e404ce1.tar.gz |
Merge branch 'master' of github.com:rohe/pysaml2
Diffstat (limited to 'tests')
-rw-r--r-- | tests/sp_conf_nameidpolicy.py | 64 | ||||
-rw-r--r-- | tests/test_03_saml2.py | 27 | ||||
-rwxr-xr-x | tests/test_43_soap.py | 43 | ||||
-rw-r--r-- | tests/test_51_client.py | 35 | ||||
-rw-r--r-- | tests/test_requirements.txt | 4 |
5 files changed, 172 insertions, 1 deletions
diff --git a/tests/sp_conf_nameidpolicy.py b/tests/sp_conf_nameidpolicy.py new file mode 100644 index 00000000..d15989c2 --- /dev/null +++ b/tests/sp_conf_nameidpolicy.py @@ -0,0 +1,64 @@ +from pathutils import full_path +from pathutils import xmlsec_path + +CONFIG = { + "entityid": "urn:mace:example.com:saml:roland:sp", + "name": "urn:mace:example.com:saml:roland:sp", + "description": "My own SP", + "service": { + "sp": { + "endpoints": { + "assertion_consumer_service": [ + "http://lingon.catalogix.se:8087/"], + }, + "required_attributes": ["surName", "givenName", "mail"], + "optional_attributes": ["title"], + "idp": ["urn:mace:example.com:saml:roland:idp"], + "name_id_format": "urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", + "name_id_format_allow_create": "true" + } + }, + "debug": 1, + "key_file": full_path("test.key"), + "cert_file": full_path("test.pem"), + "encryption_keypairs": [{"key_file": full_path("test_1.key"), "cert_file": full_path("test_1.crt")}, + {"key_file": full_path("test_2.key"), "cert_file": full_path("test_2.crt")}], + "ca_certs": full_path("cacerts.txt"), + "xmlsec_binary": xmlsec_path, + "metadata": [{ + "class": "saml2.mdstore.MetaDataFile", + "metadata": [(full_path("idp.xml"), ), (full_path("vo_metadata.xml"), )], + }], + "virtual_organization": { + "urn:mace:example.com:it:tek": { + "nameid_format": "urn:oid:1.3.6.1.4.1.1466.115.121.1.15-NameID", + "common_identifier": "umuselin", + } + }, + "subject_data": "subject_data.db", + "accepted_time_diff": 60, + "attribute_map_dir": full_path("attributemaps"), + "valid_for": 6, + "organization": { + "name": ("AB Exempel", "se"), + "display_name": ("AB Exempel", "se"), + "url": "http://www.example.org", + }, + "contact_person": [{ + "given_name": "Roland", + "sur_name": "Hedberg", + "telephone_number": "+46 70 100 0000", + "email_address": ["tech@eample.com", + "tech@example.org"], + "contact_type": "technical" + }, + ], + "logger": { + "rotating": { + "filename": full_path("sp.log"), + "maxBytes": 100000, + "backupCount": 5, + }, + "loglevel": "info", + } +} diff --git a/tests/test_03_saml2.py b/tests/test_03_saml2.py index 136161ab..a71eb3cd 100644 --- a/tests/test_03_saml2.py +++ b/tests/test_03_saml2.py @@ -17,6 +17,7 @@ except ImportError: import cElementTree as ElementTree except ImportError: from elementtree import ElementTree +from defusedxml.common import EntitiesForbidden ITEMS = { NameID: ["""<?xml version="1.0" encoding="utf-8"?> @@ -166,6 +167,19 @@ def test_create_class_from_xml_string_wrong_class_spec(): assert kl == None +def test_create_class_from_xml_string_xxe(): + xml = """<?xml version="1.0"?> + <!DOCTYPE lolz [ + <!ENTITY lol "lol"> + <!ELEMENT lolz (#PCDATA)> + <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;"> + ]> + <lolz>&lol1;</lolz> + """ + with raises(EntitiesForbidden) as err: + create_class_from_xml_string(NameID, xml) + + def test_ee_1(): ee = saml2.extension_element_from_string( """<?xml version='1.0' encoding='UTF-8'?><foo>bar</foo>""") @@ -454,6 +468,19 @@ def test_ee_7(): assert nid.text.strip() == "http://federationX.org" +def test_ee_xxe(): + xml = """<?xml version="1.0"?> + <!DOCTYPE lolz [ + <!ENTITY lol "lol"> + <!ELEMENT lolz (#PCDATA)> + <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;"> + ]> + <lolz>&lol1;</lolz> + """ + with raises(EntitiesForbidden): + saml2.extension_element_from_string(xml) + + def test_extension_element_loadd(): ava = {'attributes': {}, 'tag': 'ExternalEntityAttributeAuthority', diff --git a/tests/test_43_soap.py b/tests/test_43_soap.py index 4cde3d6a..bf66a1d0 100755 --- a/tests/test_43_soap.py +++ b/tests/test_43_soap.py @@ -12,9 +12,13 @@ except ImportError: import cElementTree as ElementTree except ImportError: from elementtree import ElementTree +from defusedxml.common import EntitiesForbidden + +from pytest import raises import saml2.samlp as samlp from saml2.samlp import NAMESPACE as SAMLP_NAMESPACE +from saml2 import soap NAMESPACE = "http://schemas.xmlsoap.org/soap/envelope/" @@ -66,3 +70,42 @@ def test_make_soap_envelope(): assert len(body) == 1 saml_part = body[0] assert saml_part.tag == '{%s}AuthnRequest' % SAMLP_NAMESPACE + + +def test_parse_soap_enveloped_saml_thingy_xxe(): + xml = """<?xml version="1.0"?> + <!DOCTYPE lolz [ + <!ENTITY lol "lol"> + <!ELEMENT lolz (#PCDATA)> + <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;"> + ]> + <lolz>&lol1;</lolz> + """ + with raises(EntitiesForbidden): + soap.parse_soap_enveloped_saml_thingy(xml, None) + + +def test_class_instances_from_soap_enveloped_saml_thingies_xxe(): + xml = """<?xml version="1.0"?> + <!DOCTYPE lolz [ + <!ENTITY lol "lol"> + <!ELEMENT lolz (#PCDATA)> + <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;"> + ]> + <lolz>&lol1;</lolz> + """ + with raises(soap.XmlParseError): + soap.class_instances_from_soap_enveloped_saml_thingies(xml, None) + + +def test_open_soap_envelope_xxe(): + xml = """<?xml version="1.0"?> + <!DOCTYPE lolz [ + <!ENTITY lol "lol"> + <!ELEMENT lolz (#PCDATA)> + <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;"> + ]> + <lolz>&lol1;</lolz> + """ + with raises(soap.XmlParseError): + soap.open_soap_envelope(xml) diff --git a/tests/test_51_client.py b/tests/test_51_client.py index f6958162..7e42045b 100644 --- a/tests/test_51_client.py +++ b/tests/test_51_client.py @@ -7,6 +7,7 @@ import six from future.backports.urllib.parse import parse_qs from future.backports.urllib.parse import urlencode from future.backports.urllib.parse import urlparse +from pytest import raises from saml2.argtree import add_path from saml2.cert import OpenSSLWrapper @@ -25,6 +26,7 @@ from saml2.assertion import Assertion from saml2.authn_context import INTERNETPROTOCOLPASSWORD from saml2.client import Saml2Client from saml2.config import SPConfig +from saml2.pack import parse_soap_enveloped_saml from saml2.response import LogoutResponse from saml2.saml import NAMEID_FORMAT_PERSISTENT, EncryptedAssertion, Advice from saml2.saml import NAMEID_FORMAT_TRANSIENT @@ -38,6 +40,8 @@ from saml2.s_utils import do_attribute_statement from saml2.s_utils import factory from saml2.time_util import in_a_while, a_while_ago +from defusedxml.common import EntitiesForbidden + from fakeIDP import FakeIDP from fakeIDP import unpack_form from pathutils import full_path @@ -276,6 +280,26 @@ class TestClient: assert nid_policy.allow_create == "false" assert nid_policy.format == saml.NAMEID_FORMAT_TRANSIENT + def test_create_auth_request_nameid_policy_allow_create(self): + conf = config.SPConfig() + conf.load_file("sp_conf_nameidpolicy") + client = Saml2Client(conf) + ar_str = "%s" % client.create_authn_request( + "http://www.example.com/sso", message_id="id1")[1] + + ar = samlp.authn_request_from_string(ar_str) + print(ar) + assert ar.assertion_consumer_service_url == ("http://lingon.catalogix" + ".se:8087/") + assert ar.destination == "http://www.example.com/sso" + assert ar.protocol_binding == BINDING_HTTP_POST + assert ar.version == "2.0" + assert ar.provider_name == "urn:mace:example.com:saml:roland:sp" + assert ar.issuer.text == "urn:mace:example.com:saml:roland:sp" + nid_policy = ar.name_id_policy + assert nid_policy.allow_create == "true" + assert nid_policy.format == saml.NAMEID_FORMAT_PERSISTENT + def test_create_auth_request_vo(self): assert list(self.client.config.vorg.keys()) == [ "urn:mace:example.com:it:tek"] @@ -1552,6 +1576,17 @@ class TestClientWithDummy(): 'http://www.example.com/login' assert ac.authn_context_class_ref.text == INTERNETPROTOCOLPASSWORD +def test_parse_soap_enveloped_saml_xxe(): + xml = """<?xml version="1.0"?> + <!DOCTYPE lolz [ + <!ENTITY lol "lol"> + <!ELEMENT lolz (#PCDATA)> + <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;"> + ]> + <lolz>&lol1;</lolz> + """ + with raises(EntitiesForbidden): + parse_soap_enveloped_saml(xml, None) # if __name__ == "__main__": # tc = TestClient() diff --git a/tests/test_requirements.txt b/tests/test_requirements.txt index 537fccdf..33301079 100644 --- a/tests/test_requirements.txt +++ b/tests/test_requirements.txt @@ -1,3 +1,5 @@ +mock==2.0.0 pymongo==3.0.1 +pytest==3.0.3 responses==0.5.0 -mock
\ No newline at end of file +pyasn1==0.2.3 |