summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorRoland Hedberg <roland@catalogix.se>2017-04-24 15:46:35 +0200
committerRoland Hedberg <roland@catalogix.se>2017-04-24 15:46:35 +0200
commit91bce29d7fd66537797cefa554f63edd0e404ce1 (patch)
treeddbfeeb2718d88fe5ac97b4be65855e402f8a182 /tests
parente2adbb523c37643453fbe62469ca7fb2bf1b43f0 (diff)
parent47e1b34f6c6fd9a48405f1560f24619d77526b3a (diff)
downloadpysaml2-91bce29d7fd66537797cefa554f63edd0e404ce1.tar.gz
Merge branch 'master' of github.com:rohe/pysaml2
Diffstat (limited to 'tests')
-rw-r--r--tests/sp_conf_nameidpolicy.py64
-rw-r--r--tests/test_03_saml2.py27
-rwxr-xr-xtests/test_43_soap.py43
-rw-r--r--tests/test_51_client.py35
-rw-r--r--tests/test_requirements.txt4
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