diff options
Diffstat (limited to 'dev-python/pysaml2')
-rw-r--r-- | dev-python/pysaml2/Manifest | 6 | ||||
-rw-r--r-- | dev-python/pysaml2/files/xxe-4.0.2.patch | 305 | ||||
-rw-r--r-- | dev-python/pysaml2/metadata.xml | 19 | ||||
-rw-r--r-- | dev-python/pysaml2/pysaml2-4.0.2-r1.ebuild | 36 |
4 files changed, 366 insertions, 0 deletions
diff --git a/dev-python/pysaml2/Manifest b/dev-python/pysaml2/Manifest new file mode 100644 index 000000000000..c8e8bc40886f --- /dev/null +++ b/dev-python/pysaml2/Manifest @@ -0,0 +1,6 @@ +AUX xxe-4.0.2.patch 10657 SHA256 23542dc862b0cfd2739635609280f504bae3c674309efe7ef1547fdb025b3704 SHA512 5c18a3c850526e6fd0410d0526bbf385d3383978b944de80da781301114f6a9081d2a3c662f45990fbd7ed88f971382b1ce30d974e4e76e19c11d6aa74d010d1 WHIRLPOOL cde2e3e392c4de9c8f0e5195ef36c5bbf1c2203476b2c8537ab244d29df08db07214105789d4a220709e2d74b833500187bffe7f9e71cbde3e491b31ca4d6594 +DIST pysaml2-4.0.2.tar.gz 13657558 SHA256 24cec8dbc20a7772854563ffc9a19297afcc38c4c7558c063b4c8c302f8a958b SHA512 debe23c2b193ca9f937bdb4fc9e8f308fa012c18e50e40183f7e531434af52b6e4d36608be3e9b0321190930cdfd9eb24555ed1805083e32db8de0f57e5afb14 WHIRLPOOL 303217ea7408986435a31ac97deae3d2b14393674d360d30cbdacf1c673d265b21505af1dea8c536c4698dc6861058f6e57421aaa5bb411daa68d5d02c1ba2c2 +EBUILD pysaml2-4.0.2-r1.ebuild 1030 SHA256 39b82bc7da8483f369bb452529956d2fbbf2ba0cd535fe1bb3da831f74e7507a SHA512 7f0405c7dcad153ad041e1ced22c8d490e566fd090fd6baf61e9de3977de6d2d90c7b3e34899ce072b4bc0be58055e656546f62eef6ed57561a6ad85b2be3a4a WHIRLPOOL fce89a096c8f0020479cc660396a99a88682b81101d306d0b9f2fe3dade81a00e0115089e34fe3bb92206b0d762f9afbb47aa844cd5aea1752d63f12446735ab +MISC ChangeLog 3831 SHA256 4edc981b493403b3953512d95c2f9a7108ea1b705f2af15fbccdb2bf8d34e66c SHA512 c7fa4cb396e8cc690d6135ed06f2ce1276638b9706a68d09e8c81950f345af72f0feaa8b9fcb29758859c5c6cd56710ad19ef1bf6287cdc7d54a0cd0359b2289 WHIRLPOOL 7853873c0cb3a02996797832748f442a684afedfaca5ce76a61478dbe5aff0cfeab83f36cd8868a94b87d70cd1f3d156c01ba451b51acdce59484e129944572a +MISC ChangeLog-2015 917 SHA256 1c446d216c83f23ca8eef8fe654c6deedd5cb609d419df5285a11454ee769690 SHA512 cb37fd45d00f34eb4c2468dd897a64cf5bd336be49c0b4d552d609b324429f464ec8554791676da5e79fe920bd24afb96661ae44eff994444f3a8269a35281aa WHIRLPOOL 841aaff196ce76a308d206e3e91995da2e8cc5b58d9c7bd072f082ac305eefd0d53428c5015fede3c84bdeee13e71fda2b86ece48850c569b49d74cc8ce5b62e +MISC metadata.xml 606 SHA256 95c5ac166fff49bcde7bf9c03cf8a63365af2ca7c8c6ce97fa193c6c666de450 SHA512 7b4facbe3e25898488fffb7b39f9ff7eedd12492f668fa294952711efb3ca9549f2653ab6bc2a948286deff5f45116b0b8bd9a5fc796e99413acc9334eade348 WHIRLPOOL d745827861c1426adad6872a3dd154b7c8ca675691967ffec0df539068055d74a550424714fd22af9e28945768b2c12ba473fc194b450a1a8e95dab865760c91 diff --git a/dev-python/pysaml2/files/xxe-4.0.2.patch b/dev-python/pysaml2/files/xxe-4.0.2.patch new file mode 100644 index 000000000000..8e1a2ef53cc0 --- /dev/null +++ b/dev-python/pysaml2/files/xxe-4.0.2.patch @@ -0,0 +1,305 @@ +diff -Naur pysaml2/setup.py pysaml2.new/setup.py +--- pysaml2/setup.py 2015-12-06 00:46:33.000000000 -0600 ++++ pysaml2.new/setup.py 2017-01-10 20:31:43.387413477 -0600 +@@ -17,6 +17,7 @@ + 'pytz', + 'pyOpenSSL', + 'python-dateutil', ++ 'defusedxml', + 'six' + ] + +diff -Naur pysaml2/src/saml2/__init__.py pysaml2.new/src/saml2/__init__.py +--- pysaml2/src/saml2/__init__.py 2016-01-07 05:53:57.000000000 -0600 ++++ pysaml2.new/src/saml2/__init__.py 2017-01-10 20:34:04.171641116 -0600 +@@ -35,6 +35,7 @@ + import cElementTree as ElementTree + except ImportError: + from elementtree import ElementTree ++import defusedxml.ElementTree + + root_logger = logging.getLogger(__name__) + root_logger.level = logging.NOTSET +@@ -86,7 +87,7 @@ + """ + if not isinstance(xml_string, six.binary_type): + xml_string = xml_string.encode('utf-8') +- tree = ElementTree.fromstring(xml_string) ++ tree = defusedxml.ElementTree.fromstring(xml_string) + return create_class_from_element_tree(target_class, tree) + + +@@ -268,7 +269,7 @@ + + + def extension_element_from_string(xml_string): +- element_tree = ElementTree.fromstring(xml_string) ++ element_tree = defusedxml.ElementTree.fromstring(xml_string) + return _extension_element_from_element_tree(element_tree) + + +diff -Naur pysaml2/src/saml2/pack.py pysaml2.new/src/saml2/pack.py +--- pysaml2/src/saml2/pack.py 2015-12-11 07:31:39.000000000 -0600 ++++ pysaml2.new/src/saml2/pack.py 2017-01-10 20:35:35.382435020 -0600 +@@ -37,6 +37,7 @@ + import cElementTree as ElementTree + except ImportError: + from elementtree import ElementTree ++import defusedxml.ElementTree + + NAMESPACE = "http://schemas.xmlsoap.org/soap/envelope/" + FORM_SPEC = """<form method="post" action="%s"> +@@ -235,7 +236,7 @@ + :param text: The SOAP object as XML + :return: header parts and body as saml.samlbase instances + """ +- envelope = ElementTree.fromstring(text) ++ envelope = defusedxml.ElementTree.fromstring(text) + assert envelope.tag == '{%s}Envelope' % NAMESPACE + + # print(len(envelope)) +diff -Naur pysaml2/src/saml2/soap.py pysaml2.new/src/saml2/soap.py +--- pysaml2/src/saml2/soap.py 2015-05-18 02:54:05.000000000 -0500 ++++ pysaml2.new/src/saml2/soap.py 2017-01-10 20:36:16.163808770 -0600 +@@ -19,6 +19,7 @@ + except ImportError: + #noinspection PyUnresolvedReferences + from elementtree import ElementTree ++import defusedxml.ElementTree + + + logger = logging.getLogger(__name__) +@@ -133,7 +134,7 @@ + :param expected_tags: What the tag of the SAML thingy is expected to be. + :return: SAML thingy as a string + """ +- envelope = ElementTree.fromstring(text) ++ envelope = defusedxml.ElementTree.fromstring(text) + + # Make sure it's a SOAP message + assert envelope.tag == '{%s}Envelope' % soapenv.NAMESPACE +@@ -183,7 +184,7 @@ + :return: The body and headers as class instances + """ + try: +- envelope = ElementTree.fromstring(text) ++ envelope = defusedxml.ElementTree.fromstring(text) + except Exception as exc: + raise XmlParseError("%s" % exc) + +@@ -209,7 +210,7 @@ + :return: dictionary with two keys "body"/"header" + """ + try: +- envelope = ElementTree.fromstring(text) ++ envelope = defusedxml.ElementTree.fromstring(text) + except Exception as exc: + raise XmlParseError("%s" % exc) + +diff -Naur pysaml2/tests/test_03_saml2.py pysaml2.new/tests/test_03_saml2.py +--- pysaml2/tests/test_03_saml2.py 2015-06-06 02:15:20.000000000 -0500 ++++ pysaml2.new/tests/test_03_saml2.py 2017-01-10 20:38:32.541728380 -0600 +@@ -17,6 +17,7 @@ + import cElementTree as ElementTree + except ImportError: + from elementtree import ElementTree ++from defusedxml.common import EntitiesForbidden + + ITEMS = { + NameID: ["""<?xml version="1.0" encoding="utf-8"?> +@@ -27,7 +28,7 @@ + </NameID> + """, """<?xml version="1.0" encoding="utf-8"?> + <NameID xmlns="urn:oasis:names:tc:SAML:2.0:assertion" +- SPNameQualifier="https://foo.example.com/sp" ++ SPNameQualifier="https://foo.example.com/sp" + Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">_1632879f09d08ea5ede2dc667cbed7e429ebc4335c</NameID> + """, """<?xml version="1.0" encoding="utf-8"?> + <NameID xmlns="urn:oasis:names:tc:SAML:2.0:assertion" +@@ -47,9 +48,9 @@ + SubjectConfirmationData: + """<?xml version="1.0" encoding="utf-8"?> + <SubjectConfirmationData xmlns="urn:oasis:names:tc:SAML:2.0:assertion" +-InResponseTo="_1683146e27983964fbe7bf8f08961108d166a652e5" +-NotOnOrAfter="2010-02-18T13:52:13.959Z" +-NotBefore="2010-01-16T12:00:00Z" ++InResponseTo="_1683146e27983964fbe7bf8f08961108d166a652e5" ++NotOnOrAfter="2010-02-18T13:52:13.959Z" ++NotBefore="2010-01-16T12:00:00Z" + Recipient="http://192.168.0.10/saml/sp" />""", + SubjectConfirmation: + """<?xml version="1.0" encoding="utf-8"?> +@@ -166,6 +167,19 @@ + 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>""") +@@ -193,7 +207,7 @@ + def test_ee_3(): + ee = saml2.extension_element_from_string( + """<?xml version='1.0' encoding='UTF-8'?> +- <foo xmlns="urn:mace:example.com:saml:ns" ++ <foo xmlns="urn:mace:example.com:saml:ns" + id="xyz">bar</foo>""") + assert ee != None + print(ee.__dict__) +@@ -454,6 +468,19 @@ + 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 -Naur pysaml2/tests/test_43_soap.py pysaml2.new/tests/test_43_soap.py +--- pysaml2/tests/test_43_soap.py 2013-04-28 09:38:07.000000000 -0500 ++++ pysaml2.new/tests/test_43_soap.py 2017-01-10 20:39:53.730364008 -0600 +@@ -12,16 +12,20 @@ + 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/" + + example = """<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/"> + <Body> +- <samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" +- xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ++ <samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ++ xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" + ID="_6c3a4f8b9c2d" Version="2.0" IssueInstant="2004-03-27T08:42:00Z"> + <saml:Issuer>https://www.example.com/SAML</saml:Issuer> + <Status> +@@ -55,7 +59,7 @@ + envelope.tag = '{%s}Envelope' % NAMESPACE + body = ElementTree.Element('') + body.tag = '{%s}Body' % NAMESPACE +- envelope.append(body) ++ envelope.append(body) + request = samlp.AuthnRequest() + request.become_child_element_of(body) + +@@ -66,3 +70,42 @@ + 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 -Naur pysaml2/tests/test_51_client.py pysaml2.new/tests/test_51_client.py +--- pysaml2/tests/test_51_client.py 2015-12-11 05:10:01.000000000 -0600 ++++ pysaml2.new/tests/test_51_client.py 2017-01-10 20:42:12.819280442 -0600 +@@ -5,6 +5,7 @@ + import uuid + import six + from six.moves.urllib.parse import parse_qs, urlencode, urlparse ++from pytest import raises + from saml2.cert import OpenSSLWrapper + from saml2.xmldsig import SIG_RSA_SHA256 + from saml2 import BINDING_HTTP_POST +@@ -21,6 +22,7 @@ + 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 +@@ -34,6 +36,8 @@ + 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 +@@ -1445,6 +1449,18 @@ + '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/dev-python/pysaml2/metadata.xml b/dev-python/pysaml2/metadata.xml new file mode 100644 index 000000000000..e06acc272e6a --- /dev/null +++ b/dev-python/pysaml2/metadata.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd"> +<pkgmetadata> + <maintainer type="person"> + <email>prometheanfire@gentoo.org</email> + <name>Matthew Thode</name> + </maintainer> + <maintainer type="project"> + <email>openstack@gentoo.org</email> + <name>Openstack</name> + </maintainer> + <longdescription lang="en"> + Python implementation of SAML Version 2 to be used in a WSGI environment + </longdescription> + <upstream> + <remote-id type="pypi">pysaml2</remote-id> + <remote-id type="github">rohe/pysaml2</remote-id> + </upstream> +</pkgmetadata> diff --git a/dev-python/pysaml2/pysaml2-4.0.2-r1.ebuild b/dev-python/pysaml2/pysaml2-4.0.2-r1.ebuild new file mode 100644 index 000000000000..f6c60886769a --- /dev/null +++ b/dev-python/pysaml2/pysaml2-4.0.2-r1.ebuild @@ -0,0 +1,36 @@ +# Copyright 1999-2017 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +EAPI=6 +PYTHON_COMPAT=( python2_7 python3_4 python3_5 ) + +inherit distutils-r1 + +DESCRIPTION="Python implementation of SAML Version 2 to be used in a WSGI environment" +HOMEPAGE="https://github.com/rohe/pysaml2" +SRC_URI="mirror://pypi/${PN:0:1}/${PN}/${P}.tar.gz" + +LICENSE="Apache-2.0" +SLOT="0" +KEYWORDS="amd64 ~arm64 x86" +IUSE="" + +PATCHES=( "${FILESDIR}/xxe-4.0.2.patch" ) + +DEPEND=" + dev-python/setuptools[${PYTHON_USEDEP}] +" +RDEPEND=" + dev-python/decorator[${PYTHON_USEDEP}] + >=dev-python/requests-1.0.0[${PYTHON_USEDEP}] + dev-python/future[${PYTHON_USEDEP}] + dev-python/paste[${PYTHON_USEDEP}] + dev-python/zope-interface[${PYTHON_USEDEP}] + dev-python/repoze-who[${PYTHON_USEDEP}] + >=dev-python/pycrypto-2.5[${PYTHON_USEDEP}] + dev-python/pytz[${PYTHON_USEDEP}] + dev-python/pyopenssl[${PYTHON_USEDEP}] + dev-python/python-dateutil[${PYTHON_USEDEP}] + dev-python/six[${PYTHON_USEDEP}] + dev-python/defusedxml[${PYTHON_USEDEP}] +" |