diff --git a/setup.py b/setup.py index 22cbeaf..bc67932 100755 --- a/setup.py +++ b/setup.py @@ -51,7 +51,7 @@ if sys.version_info < (2, 7): setup( name='pysaml2', - version='2.4.0', + version='2.5.0', description='Python implementation of SAML Version 2', # long_description = read("README"), author='Roland Hedberg', @@ -59,14 +59,15 @@ setup( license='Apache 2.0', url='https://github.com/rohe/pysaml2', - packages=['saml2', 'xmldsig', 'xmlenc', 's2repoze', 's2repoze.plugins', - "saml2/profile", "saml2/schema", "saml2/extension", - "saml2/attributemaps", "saml2/authn_context", + packages=['saml2', 'saml2/xmldsig', 'saml2/xmlenc', 'saml2/s2repoze', + 'saml2/s2repoze.plugins', "saml2/profile", "saml2/schema", + "saml2/extension", "saml2/attributemaps", "saml2/authn_context", "saml2/entity_category", "saml2/userinfo"], package_dir={'': 'src'}, package_data={'': ['xml/*.xml']}, - classifiers=["Development Status :: 4 - Beta", + classifiers=[ + "Development Status :: 4 - Beta", "License :: OSI Approved :: Apache Software License", "Topic :: Software Development :: Libraries :: Python Modules", "Programming Language :: Python :: 2.6", diff --git a/src/idp_test/__init__.py b/src/idp_test/__init__.py index 6e01710..ad84846 100644 --- a/src/idp_test/__init__.py +++ b/src/idp_test/__init__.py @@ -8,15 +8,17 @@ import sys import logging import imp -import xmldsig -import xmlenc +from saml2 import xmldsig +from saml2 import xmlenc from saml2.client import Saml2Client from saml2.config import SPConfig -from saml2.mdstore import MetadataStore, ToOld +from saml2.mdstore import MetadataStore from saml2.mdstore import MetaData +from saml2.mdstore import ToOld -from saml2test import CheckError, FatalError +from saml2test import CheckError +from saml2test import FatalError from saml2test import exception_trace from saml2test import ContextFilter diff --git a/src/saml2/config.py b/src/saml2/config.py index cbc2b8b..d7953a0 100644 --- a/src/saml2/config.py +++ b/src/saml2/config.py @@ -31,8 +31,8 @@ from saml2.extension import idpdisc from saml2.extension import dri from saml2.extension import mdattr from saml2.extension import ui -import xmldsig -import xmlenc +from saml2 import xmldsig +from saml2 import xmlenc ONTS = { diff --git a/src/saml2/extension/pefim.py b/src/saml2/extension/pefim.py index 2e05668..8ddceaf 100644 --- a/src/saml2/extension/pefim.py +++ b/src/saml2/extension/pefim.py @@ -2,7 +2,7 @@ import saml2 from saml2 import SamlBase -from xmldsig import X509Data +from saml2.xmldsig import X509Data NAMESPACE = 'urn:net:eustix:names:tc:PEFIM:0.0:assertion' diff --git a/src/saml2/extension/shibmd.py b/src/saml2/extension/shibmd.py index 0613f56..de6e3fb 100644 --- a/src/saml2/extension/shibmd.py +++ b/src/saml2/extension/shibmd.py @@ -6,8 +6,7 @@ import saml2 from saml2 import SamlBase - -import xmldsig as ds +from saml2 import xmldsig as ds NAMESPACE = 'urn:mace:shibboleth:metadata:1.0' diff --git a/src/saml2/md.py b/src/saml2/md.py index 60b60ad..f5c779f 100644 --- a/src/saml2/md.py +++ b/src/saml2/md.py @@ -5,11 +5,10 @@ # import saml2 -from saml2 import SamlBase - -import xmldsig as ds -import xmlenc as xenc from saml2 import saml +from saml2 import SamlBase +from saml2 import xmldsig as ds +from saml2 import xmlenc as xenc NAMESPACE = 'urn:oasis:names:tc:SAML:2.0:metadata' diff --git a/src/saml2/mdstore.py b/src/saml2/mdstore.py index 36344cf..aeb4feb 100644 --- a/src/saml2/mdstore.py +++ b/src/saml2/mdstore.py @@ -113,8 +113,8 @@ def repack_cert(cert): class MetaData(object): - def __init__(self, onts, attrc, metadata='', node_name=None, check_validity=True, - security=None, **kwargs): + def __init__(self, onts, attrc, metadata='', node_name=None, + check_validity=True, security=None, **kwargs): self.onts = onts self.attrc = attrc self.metadata = metadata @@ -616,7 +616,8 @@ class MetaDataExtern(InMemoryMetaData): Accessible but HTTP GET. """ - def __init__(self, onts, attrc, url=None, security=None, cert=None, http=None, **kwargs): + def __init__(self, onts, attrc, url=None, security=None, cert=None, + http=None, **kwargs): """ :params onts: :params attrc: @@ -827,8 +828,12 @@ class MetadataStore(object): # Separately handle MDExtern if MDloader == MetaDataExtern: - item['http'] = self.http - item['security'] = self.security + kwargs = { + 'http': self.http, + 'security': self.security + } + else: + kwargs = {} for key in item['metadata']: # Separately handle MetaDataFile and directory @@ -840,7 +845,11 @@ class MetadataStore(object): _md.load() self.metadata[_fil] = _md return - _md = MDloader(self.onts, self.attrc, *key) + + if len(key) == 2: + kwargs["cert"] = key[1] + + _md = MDloader(self.onts, self.attrc, key[0], **kwargs) _md.load() self.metadata[key[0]] = _md diff --git a/src/saml2/metadata.py b/src/saml2/metadata.py index 3941847..4ea556f 100644 --- a/src/saml2/metadata.py +++ b/src/saml2/metadata.py @@ -19,7 +19,7 @@ from saml2 import BINDING_SOAP from saml2 import samlp from saml2 import class_name -import xmldsig as ds +from saml2 import xmldsig as ds from saml2.sigver import pre_signature_part diff --git a/src/saml2/mongo_store.py b/src/saml2/mongo_store.py index 2dccdfb..86c5607 100644 --- a/src/saml2/mongo_store.py +++ b/src/saml2/mongo_store.py @@ -19,8 +19,8 @@ from saml2.extension import idpdisc from saml2.extension import dri from saml2.extension import mdattr from saml2.extension import ui -import xmldsig -import xmlenc +from saml2 import xmldsig +from saml2 import xmlenc ONTS = { diff --git a/src/saml2/response.py b/src/saml2/response.py index bddc032..b18c765 100644 --- a/src/saml2/response.py +++ b/src/saml2/response.py @@ -26,8 +26,8 @@ from saml2.samlp import STATUS_UNKNOWN_PRINCIPAL from saml2.samlp import STATUS_UNSUPPORTED_BINDING from saml2.samlp import STATUS_RESPONDER -import xmldsig as ds -import xmlenc as xenc +from saml2 import xmldsig as ds +from saml2 import xmlenc as xenc from saml2 import samlp from saml2 import class_name diff --git a/src/s2repoze/__init__.py b/src/saml2/s2repoze/__init__.py similarity index 100% rename from src/s2repoze/__init__.py rename to src/saml2/s2repoze/__init__.py diff --git a/src/s2repoze/plugins/__init__.py b/src/saml2/s2repoze/plugins/__init__.py similarity index 100% rename from src/s2repoze/plugins/__init__.py rename to src/saml2/s2repoze/plugins/__init__.py diff --git a/src/s2repoze/plugins/challenge_decider.py b/src/saml2/s2repoze/plugins/challenge_decider.py similarity index 100% rename from src/s2repoze/plugins/challenge_decider.py rename to src/saml2/s2repoze/plugins/challenge_decider.py diff --git a/src/s2repoze/plugins/entitlement.py b/src/saml2/s2repoze/plugins/entitlement.py similarity index 100% rename from src/s2repoze/plugins/entitlement.py rename to src/saml2/s2repoze/plugins/entitlement.py diff --git a/src/s2repoze/plugins/formswithhidden.py b/src/saml2/s2repoze/plugins/formswithhidden.py similarity index 100% rename from src/s2repoze/plugins/formswithhidden.py rename to src/saml2/s2repoze/plugins/formswithhidden.py diff --git a/src/s2repoze/plugins/ini.py b/src/saml2/s2repoze/plugins/ini.py similarity index 100% rename from src/s2repoze/plugins/ini.py rename to src/saml2/s2repoze/plugins/ini.py diff --git a/src/s2repoze/plugins/sp.py b/src/saml2/s2repoze/plugins/sp.py similarity index 99% rename from src/s2repoze/plugins/sp.py rename to src/saml2/s2repoze/plugins/sp.py index 8c93b2a..41c7c3d 100644 --- a/src/s2repoze/plugins/sp.py +++ b/src/saml2/s2repoze/plugins/sp.py @@ -14,7 +14,7 @@ import traceback import saml2 from urlparse import parse_qs, urlparse from saml2.md import Extensions -import xmldsig as ds +from saml2 import xmldsig as ds from StringIO import StringIO diff --git a/src/saml2/saml.py b/src/saml2/saml.py index 3ee8b5c..339bdbb 100644 --- a/src/saml2/saml.py +++ b/src/saml2/saml.py @@ -11,8 +11,8 @@ from saml2.validate import valid_domain_name import saml2 from saml2 import SamlBase -import xmldsig as ds -import xmlenc as xenc +from saml2 import xmldsig as ds +from saml2 import xmlenc as xenc NAMESPACE = 'urn:oasis:names:tc:SAML:2.0:assertion' diff --git a/src/saml2/samlp.py b/src/saml2/samlp.py index 06b4e4c..6928d79 100644 --- a/src/saml2/samlp.py +++ b/src/saml2/samlp.py @@ -5,10 +5,9 @@ # import saml2 -from saml2 import SamlBase - -import xmldsig as ds from saml2 import saml +from saml2 import SamlBase +from saml2 import xmldsig as ds NAMESPACE = 'urn:oasis:names:tc:SAML:2.0:protocol' diff --git a/src/saml2/sdb.py b/src/saml2/sdb.py index d22ede3..f70226c 100644 --- a/src/saml2/sdb.py +++ b/src/saml2/sdb.py @@ -11,8 +11,8 @@ from saml2.extension import idpdisc from saml2.extension import dri from saml2.extension import mdattr from saml2.extension import ui -import xmldsig -import xmlenc +from saml2 import xmldsig +from saml2 import xmlenc ONTS = { diff --git a/src/saml2/sigver.py b/src/saml2/sigver.py index efe96fe..d905756 100644 --- a/src/saml2/sigver.py +++ b/src/saml2/sigver.py @@ -7,25 +7,31 @@ Based on the use of xmlsec1 binaries and not the python xmlsec module. """ import base64 -from binascii import hexlify import hashlib import logging -import random import os import ssl -from time import mktime import urllib + +from time import mktime +from binascii import hexlify + from Crypto.PublicKey.RSA import importKey from Crypto.Signature import PKCS1_v1_5 from Crypto.Util.asn1 import DerSequence from Crypto.PublicKey import RSA -from saml2.cert import OpenSSLWrapper -from saml2.extension import pefim -from saml2.saml import EncryptedAssertion +from Crypto.Hash import SHA +from Crypto.Hash import SHA224 +from Crypto.Hash import SHA256 +from Crypto.Hash import SHA384 +from Crypto.Hash import SHA512 -import xmldsig as ds +from tempfile import NamedTemporaryFile +from subprocess import Popen +from subprocess import PIPE -from saml2 import samlp, SamlBase +from saml2 import samlp +from saml2 import SamlBase from saml2 import SAMLError from saml2 import extension_elements_to_elements from saml2 import class_name @@ -33,32 +39,29 @@ from saml2 import saml from saml2 import ExtensionElement from saml2 import VERSION -from saml2.s_utils import sid, rndstr +from saml2.cert import OpenSSLWrapper +from saml2.extension import pefim +from saml2.saml import EncryptedAssertion + +import saml2.xmldsig as ds + +from saml2.s_utils import sid from saml2.s_utils import Unsupported from saml2.time_util import instant from saml2.time_util import utc_now from saml2.time_util import str_to_time -from tempfile import NamedTemporaryFile -from subprocess import Popen, PIPE - -from xmldsig import SIG_RSA_SHA1 -from xmldsig import SIG_RSA_SHA224 -from xmldsig import SIG_RSA_SHA256 -from xmldsig import SIG_RSA_SHA384 -from xmldsig import SIG_RSA_SHA512 -from xmlenc import EncryptionMethod -from xmlenc import EncryptedKey -from xmlenc import CipherData -from xmlenc import CipherValue -from xmlenc import EncryptedData - -from Crypto.Hash import SHA -from Crypto.Hash import SHA224 -from Crypto.Hash import SHA256 -from Crypto.Hash import SHA384 -from Crypto.Hash import SHA512 +from saml2.xmldsig import SIG_RSA_SHA1 +from saml2.xmldsig import SIG_RSA_SHA224 +from saml2.xmldsig import SIG_RSA_SHA256 +from saml2.xmldsig import SIG_RSA_SHA384 +from saml2.xmldsig import SIG_RSA_SHA512 +from saml2.xmlenc import EncryptionMethod +from saml2.xmlenc import EncryptedKey +from saml2.xmlenc import CipherData +from saml2.xmlenc import CipherValue +from saml2.xmlenc import EncryptedData logger = logging.getLogger(__name__) diff --git a/src/xmldsig/__init__.py b/src/saml2/xmldsig/__init__.py similarity index 100% rename from src/xmldsig/__init__.py rename to src/saml2/xmldsig/__init__.py diff --git a/src/xmlenc/__init__.py b/src/saml2/xmlenc/__init__.py similarity index 99% rename from src/xmlenc/__init__.py rename to src/saml2/xmlenc/__init__.py index dd9fac4..2fd0756 100644 --- a/src/xmlenc/__init__.py +++ b/src/saml2/xmlenc/__init__.py @@ -6,8 +6,7 @@ import saml2 from saml2 import SamlBase - -import xmldsig as ds +from saml2 import xmldsig as ds NAMESPACE = 'http://www.w3.org/2001/04/xmlenc#' diff --git a/src/sp_test/base.py b/src/sp_test/base.py index babed88..c4e26c7 100644 --- a/src/sp_test/base.py +++ b/src/sp_test/base.py @@ -22,10 +22,7 @@ from saml2test.interaction import Action from saml2test.interaction import Interaction from saml2test.interaction import InteractionNeeded -import xmldsig as ds - from sp_test.tests import ErrorResponse -from sp_test.check import VerifyEchopageContents __author__ = 'rolandh' diff --git a/tests/test_00_xmldsig.py b/tests/test_00_xmldsig.py index 8b40e9d..09d189a 100644 --- a/tests/test_00_xmldsig.py +++ b/tests/test_00_xmldsig.py @@ -11,7 +11,7 @@ try: except ImportError: from elementtree import ElementTree import ds_data -import xmldsig as ds +import saml2.xmldsig as ds class TestObject: diff --git a/tests/test_01_xmlenc.py b/tests/test_01_xmlenc.py index 6bb20f5..05532f4 100644 --- a/tests/test_01_xmlenc.py +++ b/tests/test_01_xmlenc.py @@ -1,6 +1,6 @@ import saml2 -import xmlenc as xenc -import xmldsig +import saml2.xmlenc as xenc +from saml2 import xmldsig data1 = """ diff --git a/tests/test_02_saml.py b/tests/test_02_saml.py index dc3018c..a1f03d3 100644 --- a/tests/test_02_saml.py +++ b/tests/test_02_saml.py @@ -12,9 +12,10 @@ except ImportError: from elementtree import ElementTree import saml2 -import saml2_data, ds_data +import saml2_data +import ds_data -import xmldsig as ds +from saml2 import xmldsig as ds from saml2 import saml diff --git a/tests/test_04_samlp.py b/tests/test_04_samlp.py index dae7653..73a9fd1 100644 --- a/tests/test_04_samlp.py +++ b/tests/test_04_samlp.py @@ -6,18 +6,17 @@ __author__ = 'roland.hedberg@adm.umu.se (Roland Hedberg)' -import unittest try: from xml.etree import ElementTree except ImportError: from elementtree import ElementTree import saml2 -import saml2_data, ds_data, samlp_data +import samlp_data from saml2 import saml from saml2 import samlp -import xmldsig as ds +from saml2 import xmldsig as ds # class TestRequestAbstractType: diff --git a/tests/test_05_md.py b/tests/test_05_md.py index c02d668..4975a74 100644 --- a/tests/test_05_md.py +++ b/tests/test_05_md.py @@ -13,8 +13,7 @@ except ImportError: from elementtree import ElementTree import saml2 -import xmldsig as ds - +from saml2 import xmldsig as ds from saml2 import saml from saml2 import samlp from saml2 import md diff --git a/tests/test_30_mdstore.py b/tests/test_30_mdstore.py index 21819a5..1e4ed8e 100644 --- a/tests/test_30_mdstore.py +++ b/tests/test_30_mdstore.py @@ -61,16 +61,16 @@ METADATACONF = { "class": "saml2.mdstore.MetaDataFile", "metadata": [(full_path("extended.xml"), )], }], - "7": [{ - "class": "saml2.mdstore.MetaDataFile", - "metadata": [(full_path("metadata_sp_1.xml"), ), - (full_path("InCommon-metadata.xml"), )], }, - { - "class": "saml2.mdstore.MetaDataExtern", - "metadata": [ - ("https://kalmar2.org/simplesaml/module.php/aggregator/?id=kalmarcentral2&set=saml2", - full_path("kalmar2.pem")), ], - }], + # "7": [{ + # "class": "saml2.mdstore.MetaDataFile", + # "metadata": [(full_path("metadata_sp_1.xml"), ), + # (full_path("InCommon-metadata.xml"), )], }, + # { + # "class": "saml2.mdstore.MetaDataExtern", + # "metadata": [ + # ("https://kalmar2.org/simplesaml/module.php/aggregator/?id=kalmarcentral2&set=saml2", + # full_path("kalmar2.pem")), ], + # }], "4": [{ "class": "saml2.mdstore.MetaDataFile", "metadata": [(full_path("metadata_example.xml"), )], @@ -86,7 +86,14 @@ METADATACONF = { "9": [{ "class": "saml2.mdstore.MetaDataFile", "metadata": [(full_path("metadata"), )] - }] + }], + "10": [{ + "class": "saml2.mdstore.MetaDataExtern", + "metadata": [ + ("http://md.incommon.org/InCommon/InCommon-metadata-export.xml", + full_path("inc-md-cert.pem"))] + } + ] } @@ -277,5 +284,16 @@ def test_load_local_dir(): assert len(mds) == 3 # Three sources assert len(mds.keys()) == 4 # number of idps + +def test_load_extern_incommon(): + sec_config.xmlsec_binary = sigver.get_xmlsec_binary(["/opt/local/bin"]) + mds = MetadataStore(ONTS.values(), ATTRCONV, sec_config, + disable_ssl_certificate_validation=True) + + mds.imp(METADATACONF["10"]) + print mds + assert mds + assert len(mds.keys()) + if __name__ == "__main__": - test_load_local_dir() + test_load_extern_incommon() diff --git a/tests/test_30_mdstore_old.py b/tests/test_30_mdstore_old.py index b847e11..7ef04de 100644 --- a/tests/test_30_mdstore_old.py +++ b/tests/test_30_mdstore_old.py @@ -58,13 +58,13 @@ METADATACONF = { "3": { "local": [full_path("extended.xml")] }, - "7": { - "local": [full_path("metadata_sp_1.xml"), - full_path("InCommon-metadata.xml")], - "remote": [ - {"url": "https://kalmar2.org/simplesaml/module.php/aggregator/?id=kalmarcentral2&set=saml2", - "cert": full_path("kalmar2.pem")}] - }, + # "7": { + # "local": [full_path("metadata_sp_1.xml"), + # full_path("InCommon-metadata.xml")], + # "remote": [ + # {"url": "https://kalmar2.org/simplesaml/module.php/aggregator/?id=kalmarcentral2&set=saml2", + # "cert": full_path("kalmar2.pem")}] + # }, "4": { "local": [full_path("metadata_example.xml")] }, @@ -76,6 +76,11 @@ METADATACONF = { }, "9": { "local": [full_path("metadata")] + }, + "10": { + "remote": [ + {"url": "http://md.incommon.org/InCommon/InCommon-metadata-export.xml", + "cert": full_path("inc-md-cert.pem")}] } } @@ -266,5 +271,16 @@ def test_load_local_dir(): assert len(mds) == 3 # Three sources assert len(mds.keys()) == 4 # number of idps + +def test_load_external(): + sec_config.xmlsec_binary = sigver.get_xmlsec_binary(["/opt/local/bin"]) + mds = MetadataStore(ONTS.values(), ATTRCONV, sec_config, + disable_ssl_certificate_validation=True) + + mds.imp(METADATACONF["10"]) + print mds + assert len(mds) == 1 # One source + assert len(mds.keys()) > 1 # number of idps + if __name__ == "__main__": - test_mdx_certs() + test_load_external() diff --git a/tests/test_41_response.py b/tests/test_41_response.py index 65d01b2..0a0c005 100644 --- a/tests/test_41_response.py +++ b/tests/test_41_response.py @@ -16,7 +16,7 @@ from pathutils import full_path FALSE_ASSERT_SIGNED = full_path("saml_false_signed.xml") -TIMESLACK = 20000000 # Roughly +- 12 month +TIMESLACK = 40000000 # Roughly +- 24 month def _eq(l1, l2): diff --git a/tools/mdexport.py b/tools/mdexport.py index c37f69e..92b76d0 100755 --- a/tools/mdexport.py +++ b/tools/mdexport.py @@ -12,8 +12,8 @@ from saml2.extension import mdrpi from saml2.extension import mdui from saml2.extension import shibmd from saml2.extension import ui -import xmldsig -import xmlenc +from saml2 import xmldsig +from saml2 import xmlenc import argparse diff --git a/tools/mdexport_test.py b/tools/mdexport_test.py index b7faca3..bace10d 100755 --- a/tools/mdexport_test.py +++ b/tools/mdexport_test.py @@ -9,8 +9,8 @@ from saml2.extension import dri from saml2.extension import mdattr from saml2.extension import ui from saml2.extension import shibmd -import xmldsig -import xmlenc +from saml2 import xmldsig +from saml2 import xmlenc from saml2.mdstore import MetaDataFile, MetaDataExtern diff --git a/tools/mdimport.py b/tools/mdimport.py index 6f83d95..4c238ed 100755 --- a/tools/mdimport.py +++ b/tools/mdimport.py @@ -6,8 +6,8 @@ from saml2.mdstore import MetaDataMD, MetaDataFile __author__ = 'rolandh' -import xmldsig -import xmlenc +from saml2 import xmldsig +from saml2 import xmlenc from saml2 import md from saml2 import saml from saml2.extension import dri @@ -40,7 +40,7 @@ print time.time() - start start = time.time() for i in range(1, 10): mdf = MetaDataFile(ONTS.values(), ac_factory("../tests/attributemaps"), - "../tests/swamid-2.0.xml") + "../tests/swamid-2.0.xml") mdf.load() _ = mdf.keys() diff --git a/tools/merge_metadata.py b/tools/merge_metadata.py index c4ad3b3..401dcff 100755 --- a/tools/merge_metadata.py +++ b/tools/merge_metadata.py @@ -12,8 +12,8 @@ from saml2.extension import mdrpi from saml2.extension import mdui from saml2.extension import shibmd from saml2.extension import ui -import xmldsig -import xmlenc +from saml2 import xmldsig +from saml2 import xmlenc import argparse diff --git a/tools/verify_metadata.py b/tools/verify_metadata.py index 0b6f4d0..d62a110 100755 --- a/tools/verify_metadata.py +++ b/tools/verify_metadata.py @@ -1,10 +1,14 @@ #!/usr/bin/env python -from saml2.sigver import _get_xmlsec_cryptobackend, SecurityContext -from saml2.httpbase import HTTPBase + +import argparse from saml2 import saml from saml2 import md +from saml2 import xmldsig +from saml2 import xmlenc + from saml2.attribute_converter import ac_factory +from saml2.httpbase import HTTPBase from saml2.extension import dri from saml2.extension import idpdisc from saml2.extension import mdattr @@ -12,12 +16,12 @@ from saml2.extension import mdrpi from saml2.extension import mdui from saml2.extension import shibmd from saml2.extension import ui -import xmldsig -import xmlenc -import argparse +from saml2.sigver import _get_xmlsec_cryptobackend +from saml2.sigver import SecurityContext -from saml2.mdstore import MetaDataFile, MetaDataExtern +from saml2.mdstore import MetaDataFile +from saml2.mdstore import MetaDataExtern __author__ = 'rolandh'