def test_xmlsec_err(): conf = config.SPConfig() conf.load_file("server_conf") md = MetadataStore([saml, samlp], None, conf) md.load("local", full_path("idp_example.xml")) conf.metadata = md conf.only_use_keys_in_metadata = False sec = sigver.security_context(conf) assertion = factory( saml.Assertion, version="2.0", id="11111", issue_instant="2009-10-30T13:20:28Z", signature=sigver.pre_signature_part("11111", sec.my_cert, 1), attribute_statement=do_attribute_statement( {("", "", "surName"): ("Foo", ""), ("", "", "givenName"): ("Bar", ""), }) ) try: sec.sign_statement(assertion, class_name(assertion), key_file=full_path("tes.key"), node_id=assertion.id) except (XmlsecError, SigverError) as err: # should throw an exception pass else: assert False
def test_enc1(): with closing(Server("idp_conf")) as server: name_id = server.ident.transient_nameid( "urn:mace:example.com:saml:roland:sp", "id12") resp_ = server.create_authn_response( IDENTITY, "id12", "http://lingon.catalogix.se:8087/", "urn:mace:example.com:saml:roland:sp", name_id=name_id) statement = pre_encrypt_assertion(resp_) tmpl = full_path("enc_tmpl.xml") # tmpl_file = open(tmpl, "w") # tmpl_file.write("%s" % pre_encryption_part()) # tmpl_file.close() data = full_path("pre_enc.xml") # data_file = open(data, "w") # data_file.write("%s" % statement) # data_file.close() key_type = "des-192" com_list = [xmlsec_path, "encrypt", "--pubkey-cert-pem", full_path("pubkey.pem"), "--session-key", key_type, "--xml-data", data, "--node-xpath", ASSERT_XPATH] crypto = CryptoBackendXmlSec1(xmlsec_path) (_stdout, _stderr, output) = crypto._run_xmlsec( com_list, [tmpl], exception=EncryptError, validate_output=False) print(output) assert _stderr == "" assert _stdout == ""
def test_3(): cnf = Config() cnf.load_file(dotname("sp_1_conf")) assert cnf.entityid == "urn:mace:example.com:saml:roland:sp" assert cnf.debug == 1 assert cnf.key_file == full_path("test.key") assert cnf.cert_file == full_path("test.pem") #assert cnf.xmlsec_binary == "/usr/local/bin/xmlsec1" assert cnf.accepted_time_diff == 60 assert cnf.secret == "0123456789" assert cnf.metadata is not None assert cnf.attribute_converters is not None
def test_xbox(): conf = config.SPConfig() conf.load_file("server_conf") md = MetadataStore([saml, samlp], None, conf) md.load("local", full_path("idp_example.xml")) conf.metadata = md conf.only_use_keys_in_metadata = False sec = sigver.security_context(conf) assertion = factory( saml.Assertion, version="2.0", id="11111", issue_instant="2009-10-30T13:20:28Z", signature=sigver.pre_signature_part("11111", sec.my_cert, 1), attribute_statement=do_attribute_statement( {("", "", "surName"): ("Foo", ""), ("", "", "givenName"): ("Bar", "")} ), ) sigass = sec.sign_statement(assertion, class_name(assertion), key_file=full_path("test.key"), node_id=assertion.id) _ass0 = saml.assertion_from_string(sigass) encrypted_assertion = EncryptedAssertion() encrypted_assertion.add_extension_element(_ass0) _, pre = make_temp(str(pre_encryption_part()).encode("utf-8"), decode=False) enctext = sec.crypto.encrypt( str(encrypted_assertion), conf.cert_file, pre, "des-192", '/*[local-name()="EncryptedAssertion"]/*[local-name()="Assertion"]', ) decr_text = sec.decrypt(enctext) _seass = saml.encrypted_assertion_from_string(decr_text) assertions = [] assers = extension_elements_to_elements(_seass.extension_elements, [saml, samlp]) sign_cert_file = full_path("test.pem") for ass in assers: _ass = "%s" % ass # _ass = _ass.replace('xsi:nil="true" ', '') # assert sigass == _ass _txt = sec.verify_signature(_ass, sign_cert_file, node_name=class_name(assertion)) if _txt: assertions.append(ass) print(assertions)
def test_identity_attribute_2(): (forward, backward) = utils.parse_attribute_map([full_path("attribute.map")]) a = Attribute(name="urn:oid:2.5.4.5", name_format=NAME_FORMAT_URI) assert utils.identity_attribute("name",a,forward) == "urn:oid:2.5.4.5" # if there would be a map it would be serialNumber assert utils.identity_attribute("friendly",a,forward) == "urn:oid:2.5.4.5"
def test_filter_on_wire_representation_2(): r = [ Attribute( friendly_name="surName", name="urn:oid:2.5.4.4", name_format="urn:oasis:names:tc:SAML:2.0:attrname-format:uri", ), Attribute( friendly_name="givenName", name="urn:oid:2.5.4.42", name_format="urn:oasis:names:tc:SAML:2.0:attrname-format:uri", ), ] o = [ Attribute( friendly_name="title", name="urn:oid:2.5.4.12", name_format="urn:oasis:names:tc:SAML:2.0:attrname-format:uri", ) ] acs = attribute_converter.ac_factory(full_path("attributemaps")) ava = {"sn": ["Hedberg"], "givenname": ["Roland"], "title": ["Master"], "uid": ["rohe0002"]} ava = assertion.filter_on_wire_representation(ava, acs, r, o) assert _eq(ava.keys(), ["sn", "givenname", "title"])
def test_parse_attribute_map(): (forward, backward) = utils.parse_attribute_map( [full_path("attribute.map")]) assert _eq(forward.keys(), backward.values()) assert _eq(forward.values(), backward.keys()) print forward.keys() assert _oeq(forward.keys(), [ ('urn:oid:1.3.6.1.4.1.5923.1.1.1.7', NAME_FORMAT_URI), ('urn:oid:0.9.2342.19200300.100.1.1', NAME_FORMAT_URI), ('urn:oid:1.3.6.1.4.1.5923.1.1.1.1', NAME_FORMAT_URI), ('urn:oid:2.5.4.42', NAME_FORMAT_URI), ('urn:oid:2.5.4.4', NAME_FORMAT_URI), ('urn:oid:0.9.2342.19200300.100.1.3', NAME_FORMAT_URI), ('urn:oid:2.5.4.12', NAME_FORMAT_URI)]) assert _eq(forward.keys(), [ ('urn:oid:1.3.6.1.4.1.5923.1.1.1.7', NAME_FORMAT_URI), ('urn:oid:0.9.2342.19200300.100.1.1', NAME_FORMAT_URI), ('urn:oid:1.3.6.1.4.1.5923.1.1.1.1', NAME_FORMAT_URI), ('urn:oid:2.5.4.42', NAME_FORMAT_URI), ('urn:oid:2.5.4.4', NAME_FORMAT_URI), ('urn:oid:0.9.2342.19200300.100.1.3', NAME_FORMAT_URI), ('urn:oid:2.5.4.12', NAME_FORMAT_URI)]) assert _eq(backward.keys(), ["surName", "givenName", "title", "uid", "mail", "eduPersonAffiliation", "eduPersonEntitlement"])
def test_identity_attribute_1(): (forward, backward) = utils.parse_attribute_map( [full_path("attribute.map")]) a = Attribute(name="urn:oid:2.5.4.4", name_format=NAME_FORMAT_URI) assert utils.identity_attribute("name", a, forward) == "urn:oid:2.5.4.4" assert utils.identity_attribute("friendly", a, forward) == "surName"
def test_assertion_2(): AVA = {'mail': u'*****@*****.**', 'eduPersonTargetedID': 'http://lingon.ladok.umu.se:8090/idp!http://lingon.ladok.umu.se:8088/sp!95e9ae91dbe62d35198fbbd5e1fb0976', 'displayName': u'Roland Hedberg', 'uid': 'http://roland.hedberg.myopenid.com/'} ava = Assertion(AVA) policy = Policy({ "default": { "lifetime": {"minutes": 240}, "attribute_restrictions": None, # means all I have "name_form": NAME_FORMAT_URI }, }) ava = ava.apply_policy("", policy) acs = ac_factory(full_path("attributemaps")) attribute = from_local(acs, ava, policy.get_name_form("")) assert len(attribute) == 4 names = [attr.name for attr in attribute] assert _eq(names, ['urn:oid:0.9.2342.19200300.100.1.3', 'urn:oid:1.3.6.1.4.1.5923.1.1.1.10', 'urn:oid:2.16.840.1.113730.3.1.241', 'urn:oid:0.9.2342.19200300.100.1.1'])
def test_filter_values_req_opt_4(): r = [ Attribute( friendly_name="surName", name="urn:oid:2.5.4.4", name_format="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"), Attribute( friendly_name="givenName", name="urn:oid:2.5.4.42", name_format="urn:oasis:names:tc:SAML:2.0:attrname-format:uri")] o = [ Attribute( friendly_name="title", name="urn:oid:2.5.4.12", name_format="urn:oasis:names:tc:SAML:2.0:attrname-format:uri")] acs = attribute_converter.ac_factory(full_path("attributemaps")) rava = attribute_converter.list_to_local(acs, r) oava = attribute_converter.list_to_local(acs, o) ava = {"sn": ["Hedberg"], "givenName": ["Roland"], "eduPersonAffiliation": ["staff"], "uid": ["rohe0002"]} ava = assertion.filter_on_demands(ava, rava, oava) print ava assert _eq(ava.keys(), ['givenName', 'sn']) assert ava == {'givenName': ['Roland'], 'sn': ['Hedberg']}
def test_assertion_consumer_service(): c = IdPConfig() c.load_file(dotname("idp_conf")) c.context = "idp" c.metadata.load("local", full_path("InCommon-metadata.xml")) entity_id = "https://www.zimride.com/shibboleth" acs = c.metadata.assertion_consumer_service(entity_id) assert len(acs) == 1 assert acs[0]["location"] == 'https://www.zimride.com/Shibboleth.sso/SAML2/POST'
def test_metadata(): conf = config.Config() conf.load_file("idp_conf_mdb") umu_idp = 'https://idp.umu.se/saml2/idp/metadata.php' # Set up a Metadata store mds = MetadataStore(ATTRCONV, conf, disable_ssl_certificate_validation=True) # Import metadata from local file. mds.imp([{"class": "saml2_tophat.mdstore.MetaDataFile", "metadata": [(full_path("swamid-2.0.xml"), )]}]) assert len(mds) == 1 # One source try: export_mdstore_to_mongo_db(mds, "metadata", "test") except ConnectionFailure: pass else: mdmdb = MetadataMDB(ATTRCONV, "metadata", "test") # replace all metadata instances with this one mds.metadata = {"mongo_db": mdmdb} idps = mds.with_descriptor("idpsso") assert idps.keys() idpsso = mds.single_sign_on_service(umu_idp) assert len(idpsso) == 1 assert destinations(idpsso) == [ 'https://idp.umu.se/saml2/idp/SSOService.php'] _name = name(mds[umu_idp]) assert _name == u'Ume\xe5 University' certs = mds.certs(umu_idp, "idpsso", "signing") assert len(certs) == 1 sps = mds.with_descriptor("spsso") assert len(sps) == 417 wants = mds.attribute_requirement('https://connect.sunet.se/shibboleth') assert wants["optional"] == [] lnamn = [d_to_local_name(mds.attrc, attr) for attr in wants["required"]] assert _eq(lnamn, ['eduPersonPrincipalName', 'mail', 'givenName', 'sn', 'eduPersonScopedAffiliation', 'eduPersonAffiliation']) wants = mds.attribute_requirement( "https://gidp.geant.net/sp/module.php/saml/sp/metadata.php/default-sp") # Optional lnamn = [d_to_local_name(mds.attrc, attr) for attr in wants["optional"]] assert _eq(lnamn, ['displayName', 'commonName', 'schacHomeOrganization', 'eduPersonAffiliation', 'schacHomeOrganizationType']) # Required lnamn = [d_to_local_name(mds.attrc, attr) for attr in wants["required"]] assert _eq(lnamn, ['eduPersonTargetedID', 'mail', 'eduPersonScopedAffiliation'])
def generate_cert(): sn = uuid.uuid4().urn cert_info = { "cn": "localhost", "country_code": "se", "state": "ac", "city": "Umea", "organization": "ITS", "organization_unit": "DIRG" } osw = OpenSSLWrapper() ca_cert_str = osw.read_str_from_file( full_path("root_cert/localhost.ca.crt")) ca_key_str = osw.read_str_from_file( full_path("root_cert/localhost.ca.key")) req_cert_str, req_key_str = osw.create_certificate(cert_info, request=True, sn=sn, key_length=2048) cert_str = osw.create_cert_signed_certificate(ca_cert_str, ca_key_str, req_cert_str) return cert_str, req_key_str
def test_load_local(): # string representation of XML idp definition idp_metadata = open(full_path("metadata.xml")).read() saml_config = Config() config_dict = { "metadata": {"inline": [idp_metadata]} } cfg = saml_config.load(config_dict) assert cfg
def test_enc2(): crypto = CryptoBackendXmlSec1(xmlsec_path) server = Server("idp_conf") name_id = server.ident.transient_nameid("urn:mace:example.com:saml:roland:sp", "id12") resp_ = server.create_authn_response( IDENTITY, "id12", "http://lingon.catalogix.se:8087/", "urn:mace:example.com:saml:roland:sp", name_id=name_id ) enc_resp = crypto.encrypt_assertion(resp_, full_path("pubkey.pem"), pre_encryption_part()) print enc_resp assert enc_resp
def test_sha256_signing(): conf = config.SPConfig() conf.load_file("server_conf") md = MetadataStore([saml, samlp], None, conf) md.load("local", full_path("idp_example.xml")) conf.metadata = md conf.only_use_keys_in_metadata = False sec = sigver.security_context(conf) assertion = factory( saml.Assertion, version="2.0", id="11111", issue_instant="2009-10-30T13:20:28Z", signature=sigver.pre_signature_part("11111", sec.my_cert, 1, sign_alg=SIG_RSA_SHA256), attribute_statement=do_attribute_statement( {("", "", "surName"): ("Foo", ""), ("", "", "givenName"): ("Bar", "")} ), ) s = sec.sign_statement(assertion, class_name(assertion), key_file=full_path("test.key"), node_id=assertion.id) assert s
def test_metadata(): conf = config.Config() conf.load_file("idp_conf_mdb") UMU_IDP = "https://idp.umu.se/saml2/idp/metadata.php" # Set up a Metadata store mds = MetadataStore(list(ONTS.values()), ATTRCONV, conf, disable_ssl_certificate_validation=True) # Import metadata from local file. mds.imp({"local": [full_path("swamid-2.0.xml")]}) assert len(mds) == 1 # One source export_mdstore_to_mongo_db(mds, "metadata", "test") mdmdb = MetadataMDB(ONTS, ATTRCONV, "metadata", "test") # replace all metadata instances with this one mds.metadata = {"mongo_db": mdmdb} idps = mds.with_descriptor("idpsso") assert list(idps.keys()) idpsso = mds.single_sign_on_service(UMU_IDP) assert len(idpsso) == 1 assert destinations(idpsso) == ["https://idp.umu.se/saml2/idp/SSOService.php"] _name = name(mds[UMU_IDP]) assert _name == "Ume\xe5 University" certs = mds.certs(UMU_IDP, "idpsso", "signing") assert len(certs) == 1 sps = mds.with_descriptor("spsso") assert len(sps) == 431 wants = mds.attribute_requirement("https://connect.sunet.se/shibboleth") assert wants["optional"] == [] lnamn = [d_to_local_name(mds.attrc, attr) for attr in wants["required"]] assert _eq( lnamn, ["eduPersonPrincipalName", "mail", "givenName", "sn", "eduPersonScopedAffiliation", "eduPersonAffiliation"], ) wants = mds.attribute_requirement("https://gidp.geant.net/sp/module.php/saml/sp/metadata.php/default-sp") # Optional lnamn = [d_to_local_name(mds.attrc, attr) for attr in wants["optional"]] assert _eq( lnamn, ["displayName", "commonName", "schacHomeOrganization", "eduPersonAffiliation", "schacHomeOrganizationType"], ) # Required lnamn = [d_to_local_name(mds.attrc, attr) for attr in wants["required"]] assert _eq(lnamn, ["eduPersonTargetedID", "mail", "eduPersonScopedAffiliation"])
def test_other_response(self): xml_response = open(full_path("attribute_response.xml")).read() resp = response_factory( xml_response, self.conf, return_addrs=['https://myreviewroom.com/saml2/acs/'], outstanding_queries={'id-f4d370f3d03650f3ec0da694e2348bfe': "http://localhost:8088/sso"}, timeslack=TIMESLACK, decode=False) assert isinstance(resp, StatusResponse) assert isinstance(resp, AuthnResponse) resp.sec.only_use_keys_in_metadata=False resp.parse_assertion() si = resp.session_info() assert si print(si["ava"])
def setup_class(self): conf = config.SPConfig() conf.load_file("server_conf") md = MetadataStore([saml, samlp], None, conf) md.load("local", full_path("metadata_cert.xml")) conf.metadata = md conf.only_use_keys_in_metadata = False self.sec = sigver.security_context(conf) assertion = factory( saml.Assertion, version="2.0", id="11111", issue_instant="2009-10-30T13:20:28Z", signature=sigver.pre_signature_part("11111", self.sec.my_cert, 1), attribute_statement=do_attribute_statement( {("", "", "surName"): ("Foo", ""), ("", "", "givenName"): ("Bar", ""), }) )
def setup_class(self): xmlexec = get_xmlsec_binary() md = MetadataStore([saml, samlp], None, xmlexec) md.load("local", full_path("metadata_cert.xml")) crypto = get_xmlsec_cryptobackend() self.sec = sigver.SecurityContext(crypto, key_file=PRIV_KEY, cert_file=PUB_KEY, debug=1, metadata=md) self._assertion = factory( saml.Assertion, version="2.0", id="11111", issue_instant="2009-10-30T13:20:28Z", signature=sigver.pre_signature_part("11111", self.sec.my_cert, 1), attribute_statement=do_attribute_statement({ ("","","surName"): ("Foo",""), ("","","givenName") :("Bar",""), }) )
def test_metadata(): conf = config.Config() conf.load_file("idp_conf_mdb") UMU_IDP = 'https://idp.umu.se/saml2/idp/metadata.php' mds = MetadataStore(ONTS.values(), ATTRCONV, conf, disable_ssl_certificate_validation=True) mds.imp({"local": [full_path("swamid-1.0.xml")]}) assert len(mds) == 1 # One source export_mdstore_to_mongo_db(mds, "metadata", "test") mdmdb = MetadataMDB(ONTS, ATTRCONV, "metadata", "test") # replace all metadata instances with this one mds.metadata = {"mongo_db": mdmdb} idps = mds.with_descriptor("idpsso") assert idps.keys() idpsso = mds.single_sign_on_service(UMU_IDP) assert len(idpsso) == 1 assert destinations(idpsso) == [ 'https://idp.umu.se/saml2/idp/SSOService.php'] _name = name(mds[UMU_IDP]) assert _name == u'Umeå University (SAML2)' certs = mds.certs(UMU_IDP, "idpsso", "signing") assert len(certs) == 1 sps = mds.with_descriptor("spsso") assert len(sps) == 108 wants = mds.attribute_requirement('https://connect8.sunet.se/shibboleth') lnamn = [d_to_local_name(mds.attrc, attr) for attr in wants["optional"]] assert _eq(lnamn, ['eduPersonPrincipalName', 'mail', 'givenName', 'sn', 'eduPersonScopedAffiliation']) wants = mds.attribute_requirement('https://beta.lobber.se/shibboleth') assert wants["required"] == [] lnamn = [d_to_local_name(mds.attrc, attr) for attr in wants["optional"]] assert _eq(lnamn, ['eduPersonPrincipalName', 'mail', 'givenName', 'sn', 'eduPersonScopedAffiliation', 'eduPersonEntitlement'])
def test_filter_ava3(): policy = Policy({ "default": { "lifetime": {"minutes": 15}, #"attribute_restrictions": None # means all I have "entity_categories": ["swamid"] } }) mds = MetadataStore(ONTS.values(), ATTRCONV, sec_config, disable_ssl_certificate_validation=True) mds.imp([{"class": "saml2.mdstore.MetaDataFile", "metadata": [(full_path("entity_cat_sfs_hei.xml"), )]}]) ava = {"givenName": ["Derek"], "sn": ["Jeter"], "mail": ["*****@*****.**"], "c": ["USA"], "eduPersonTargetedID": "foo!bar!xyz", "norEduPersonNIN": "19800101134"} ava = policy.filter(ava, "urn:mace:example.com:saml:roland:sp", mds) assert _eq(list(ava.keys()), ['eduPersonTargetedID', "norEduPersonNIN"])
def test_okta(): conf = config.Config() conf.load_file("server_conf") conf.id_attr_name = 'Id' md = MetadataStore([saml, samlp], None, conf) md.load("local", full_path("idp_example.xml")) conf.metadata = md conf.only_use_keys_in_metadata = False sec = sigver.security_context(conf) with open(OKTA_RESPONSE) as f: enctext = f.read() decr_text = sec.decrypt(enctext) _seass = saml.encrypted_assertion_from_string(decr_text) assers = extension_elements_to_elements(_seass.extension_elements, [saml, samlp]) with open(OKTA_ASSERTION) as f: okta_assertion = f.read() expected_assert = assertion_from_string(okta_assertion) assert len(assers) == 1 assert assers[0] == expected_assert
def test_entity_category_import_from_path(): # The entity category module myentitycategory.py is in the tests # directory which is on the standard module search path. # The module uses a custom interpretation of the REFEDs R&S entity category # by adding eduPersonUniqueId. policy = Policy({ "default": { "lifetime": {"minutes": 15}, "entity_categories": ["myentitycategory"] } }) mds = MetadataStore(ATTRCONV, sec_config, disable_ssl_certificate_validation=True) # The file entity_cat_rs.xml contains the SAML metadata for an SP # tagged with the REFEDs R&S entity category. mds.imp([{"class": "saml2.mdstore.MetaDataFile", "metadata": [(full_path("entity_cat_rs.xml"),)]}]) ava = {"givenName": ["Derek"], "sn": ["Jeter"], "displayName": "Derek Jeter", "mail": ["*****@*****.**"], "c": ["USA"], "eduPersonTargetedID": "foo!bar!xyz", "eduPersonUniqueId": "*****@*****.**", "eduPersonScopedAffiliation": "*****@*****.**", "eduPersonPrincipalName": "*****@*****.**", "norEduPersonNIN": "19800101134"} ava = policy.filter(ava, "urn:mace:example.com:saml:roland:sp", mds) # We expect c and norEduPersonNIN to be filtered out since they are not # part of the custom entity category. assert _eq(list(ava.keys()), ["eduPersonTargetedID", "eduPersonPrincipalName", "eduPersonUniqueId", "displayName", "givenName", "eduPersonScopedAffiliation", "mail", "sn"])
def test_complete_flow(): client = ecp_client.Client("user", "password", metadata_file=full_path("idp_all.xml")) sp = Saml2Client(config_file=dotname("servera_conf")) with closing(Server(config_file=dotname("idp_all_conf"))) as idp: IDP_ENTITY_ID = idp.config.entityid #SP_ENTITY_ID = sp.config.entityid # ------------ @Client ----------------------------- headers = client.add_paos_headers([]) assert len(headers) == 2 # ------------ @SP ----------------------------- response = DummyResponse(set_list2dict(headers)) assert sp.can_handle_ecp_response(response) sid, message = sp.create_ecp_authn_request(IDP_ENTITY_ID, relay_state="XYZ") # ------------ @Client ----------------------------- respdict = client.parse_soap_message(message) cargs = client.parse_sp_ecp_response(respdict) assert isinstance(respdict["body"], AuthnRequest) assert len(respdict["header"]) == 2 item0 = respdict["header"][0] assert isinstance(item0, Request) or isinstance(item0, RelayState) destination = respdict["body"].destination ht_args = client.apply_binding(BINDING_SOAP, respdict["body"], destination) # Time to send to the IDP # ----------- @IDP ------------------------------- req = idp.parse_authn_request(ht_args["data"], BINDING_SOAP) assert isinstance(req.message, AuthnRequest) # create Response and return in the SOAP response sp_entity_id = req.sender() name_id = idp.ident.transient_nameid("id12", sp.config.entityid) binding, destination = idp.pick_binding("assertion_consumer_service", [BINDING_PAOS], entity_id=sp_entity_id) resp = idp.create_ecp_authn_request_response(destination, { "eduPersonEntitlement": "Short stop", "surName": "Jeter", "givenName": "Derek", "mail": "*****@*****.**", "title": "The man" }, req.message.id, destination, sp_entity_id, name_id=name_id, authn=AUTHN) # ------------ @Client ----------------------------- # The client got the response from the IDP repackage and send it to the SP respdict = client.parse_soap_message(resp) idp_response = respdict["body"] assert isinstance(idp_response, Response) assert len(respdict["header"]) == 1 _ecp_response = None for item in respdict["header"]: if item.c_tag == "Response" and item.c_namespace == ecp_prof.NAMESPACE: _ecp_response = item #_acs_url = _ecp_response.assertion_consumer_service_url # done phase2 at the client ht_args = client.use_soap(idp_response, cargs["rc_url"], [cargs["relay_state"]]) print(ht_args) # ------------ @SP ----------------------------- respdict = sp.unpack_soap_message(ht_args["data"]) # verify the relay_state for header in respdict["header"]: inst = create_class_from_xml_string(RelayState, header) if isinstance(inst, RelayState): assert inst.text == "XYZ" # parse the response # Explicitly allow unsigned responses for this test sp.want_response_signed = False resp = sp.parse_authn_request_response(respdict["body"], None, {sid: "/"}) print(resp.response) assert resp.response.destination == "http://lingon.catalogix.se:8087/paos" assert resp.response.status.status_code.value == STATUS_SUCCESS
sec_config = config.Config() #sec_config.xmlsec_binary = sigver.get_xmlsec_binary(["/opt/local/bin"]) ONTS = { saml.NAMESPACE: saml, mdui.NAMESPACE: mdui, mdattr.NAMESPACE: mdattr, dri.NAMESPACE: dri, ui.NAMESPACE: ui, idpdisc.NAMESPACE: idpdisc, md.NAMESPACE: md, xmldsig.NAMESPACE: xmldsig, xmlenc.NAMESPACE: xmlenc } ATTRCONV = ac_factory(full_path("attributemaps")) METADATACONF = { "1": { "local": [full_path("swamid-1.0.xml")] }, "2": { "local": [full_path("InCommon-metadata.xml")] }, "3": { "local": [full_path("extended.xml")] }, "7": { "local": [full_path("metadata_sp_1.xml"), full_path("InCommon-metadata.xml")], "remote": [
Location="http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/metadata.php"/> </IDPSSODescriptor> <Organization> <OrganizationName xml:lang="en">Catalogix</OrganizationName> <OrganizationDisplayName xml:lang="en">Catalogix</OrganizationDisplayName> <OrganizationURL xml:lang="en">http://www.catalogix.se</OrganizationURL> </Organization> <ContactPerson contactType="technical"> <SurName>Hedberg</SurName> <EmailAddress>[email protected]</EmailAddress> </ContactPerson> </EntityDescriptor> </EntitiesDescriptor> """.format(cert_data=TEST_CERT) ATTRCONV = ac_factory(full_path("attributemaps")) METADATACONF = { "1": [{ "class": "saml2.mdstore.MetaDataFile", "metadata": [(full_path("swamid-1.0.xml"), )], }], "2": [{ "class": "saml2.mdstore.MetaDataFile", "metadata": [(full_path("InCommon-metadata.xml"), )], }], "3": [{ "class": "saml2.mdstore.MetaDataFile", "metadata": [(full_path("extended.xml"), )], }], # "7": [{
}, "nameid_format": NAMEID_FORMAT_PERSISTENT, # "attribute_restrictions":{ # "givenName": None, # "surName": None, # } } }, "subject_data": ("mongodb", "subject"), "session_storage": ("mongodb", "session") }, }, "debug": 1, "key_file": full_path("test.key"), "cert_file": full_path("test.pem"), #"xmlsec_binary": None, "xmlsec_path": ["/opt/local/bin", "usr/local/bin"], "metadata": { "local": [full_path("servera.xml"), full_path("vo_metadata.xml")], }, "attribute_map_dir": full_path("attributemaps"), "organization": { "name": "Exempel AB", "display_name": [("Exempel ÄB", "se"), ("Example Co.", "en")], "url": "http://www.example.com/roland", },
import mock from contextlib import closing from saml2 import config from saml2.authn_context import INTERNETPROTOCOLPASSWORD from saml2.server import Server from saml2.response import response_factory from saml2.response import StatusResponse from saml2.response import AuthnResponse from saml2.sigver import SignatureError from pathutils import full_path FALSE_ASSERT_SIGNED = full_path("saml_false_signed.xml") TIMESLACK = 60*5 def _eq(l1, l2): return set(l1) == set(l2) IDENTITY = {"eduPersonAffiliation": ["staff", "member"], "surName": ["Jeter"], "givenName": ["Derek"], "mail": ["*****@*****.**"], "title": ["shortstop"]} AUTHN = { "class_ref": INTERNETPROTOCOLPASSWORD,
sec_config = config.Config() ONTS = { saml.NAMESPACE: saml, mdui.NAMESPACE: mdui, mdattr.NAMESPACE: mdattr, dri.NAMESPACE: dri, ui.NAMESPACE: ui, idpdisc.NAMESPACE: idpdisc, md.NAMESPACE: md, xmldsig.NAMESPACE: xmldsig, xmlenc.NAMESPACE: xmlenc } ATTRCONV = ac_factory(full_path("attributemaps")) METADATACONF = { "1": [{ "class": "saml2.mdstore.MetaDataFile", "metadata": [(full_path("swamid-2.0.xml"), )], }], } def test_swamid_sp(): mds = MetadataStore(ONTS.values(), ATTRCONV, sec_config, disable_ssl_certificate_validation=True, filter=AllowDescriptor(["spsso"])) mds.imp(METADATACONF["1"]) sps = mds.with_descriptor("spsso")
# -*- coding: utf-8 -*- from pymongo.errors import ConnectionFailure from saml2.attribute_converter import d_to_local_name from saml2.attribute_converter import ac_factory from saml2.mongo_store import export_mdstore_to_mongo_db from saml2.mongo_store import MetadataMDB from saml2.mdstore import MetadataStore from saml2.mdstore import locations from saml2.mdstore import name from saml2 import config from pathutils import full_path __author__ = 'rolandh' ATTRCONV = ac_factory(full_path("attributemaps")) def _eq(l1, l2): return set(l1) == set(l2) def test_metadata(): conf = config.Config() conf.load_file("idp_conf_mdb") umu_idp = 'https://idp.umu.se/saml2/idp/metadata.php' # Set up a Metadata store mds = MetadataStore(ATTRCONV, conf, disable_ssl_certificate_validation=True) # Import metadata from local file.
def test_metadata(): conf = config.Config() conf.load_file("idp_conf_mdb") umu_idp = 'https://idp.umu.se/saml2/idp/metadata.php' # Set up a Metadata store mds = MetadataStore(ATTRCONV, conf, disable_ssl_certificate_validation=True) # Import metadata from local file. mds.imp([{ "class": "saml2.mdstore.MetaDataFile", "metadata": [(full_path("swamid-2.0.xml"), )] }]) assert len(mds) == 1 # One source try: export_mdstore_to_mongo_db(mds, "metadata", "test") except ConnectionFailure: pass else: mdmdb = MetadataMDB(ATTRCONV, "metadata", "test") # replace all metadata instances with this one mds.metadata = {"mongo_db": mdmdb} idps = mds.with_descriptor("idpsso") assert idps.keys() idpsso = mds.single_sign_on_service(umu_idp) assert len(idpsso) == 1 assert list(locations(idpsso)) == [ 'https://idp.umu.se/saml2/idp/SSOService.php' ] _name = name(mds[umu_idp]) assert _name == u'Ume\xe5 University' certs = mds.certs(umu_idp, "idpsso", "signing") assert len(certs) == 1 sps = mds.with_descriptor("spsso") assert len(sps) == 417 wants = mds.attribute_requirement( 'https://connect.sunet.se/shibboleth') assert wants["optional"] == [] lnamn = [ d_to_local_name(mds.attrc, attr) for attr in wants["required"] ] assert _eq(lnamn, [ 'eduPersonPrincipalName', 'mail', 'givenName', 'sn', 'eduPersonScopedAffiliation', 'eduPersonAffiliation' ]) wants = mds.attribute_requirement( "https://gidp.geant.net/sp/module.php/saml/sp/metadata.php/default-sp" ) # Optional lnamn = [ d_to_local_name(mds.attrc, attr) for attr in wants["optional"] ] assert _eq(lnamn, [ 'displayName', 'commonName', 'schacHomeOrganization', 'eduPersonAffiliation', 'schacHomeOrganizationType' ]) # Required lnamn = [ d_to_local_name(mds.attrc, attr) for attr in wants["required"] ] assert _eq( lnamn, ['eduPersonTargetedID', 'mail', 'eduPersonScopedAffiliation'])
sec_config = config.Config() #sec_config.xmlsec_binary = sigver.get_xmlsec_binary(["/opt/local/bin"]) ONTS = { saml.NAMESPACE: saml, mdui.NAMESPACE: mdui, mdattr.NAMESPACE: mdattr, dri.NAMESPACE: dri, ui.NAMESPACE: ui, idpdisc.NAMESPACE: idpdisc, md.NAMESPACE: md, xmldsig.NAMESPACE: xmldsig, xmlenc.NAMESPACE: xmlenc } ATTRCONV = ac_factory(full_path("attributemaps")) METADATACONF = { "1": [{ "class": "saml2.mdstore.MetaDataFile", "metadata": [(full_path("swamid-1.0.xml"), )], }], "2": [{ "class": "saml2.mdstore.MetaDataFile", "metadata": [(full_path("InCommon-metadata.xml"), )], }], "3": [{ "class": "saml2.mdstore.MetaDataFile", "metadata": [(full_path("extended.xml"), )], }], "7": [{
import xmldsig import xmlenc ONTS = { saml.NAMESPACE: saml, mdui.NAMESPACE: mdui, mdattr.NAMESPACE: mdattr, dri.NAMESPACE: dri, ui.NAMESPACE: ui, idpdisc.NAMESPACE: idpdisc, md.NAMESPACE: md, xmldsig.NAMESPACE: xmldsig, xmlenc.NAMESPACE: xmlenc } ATTRCONV = ac_factory(full_path("attributemaps")) sec_config = config.Config() sec_config.xmlsec_binary = sigver.get_xmlsec_binary(["/opt/local/bin"]) __author__ = 'rolandh' MDS = MetadataStore(ONTS.values(), ATTRCONV, sec_config, disable_ssl_certificate_validation=True) MDS.imp({"mdfile": [full_path("swamid.md")]}) def _eq(l1, l2): return set(l1) == set(l2)
{ "name": "urn:oid:1.3.6.1.4.1.5923.1.1.1.2", "required": False, }, { "friendly_name": "eduPersonNickname", "required": True, }, { "friendly_name": "eduPersonScopedAffiliation", }, ], } }, "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", } },
from saml2.sigver import pre_encryption_part from saml2.sigver import make_temp from saml2.sigver import XmlsecError from saml2.sigver import SigverError from saml2.mdstore import MetadataStore from saml2.saml import assertion_from_string from saml2.saml import EncryptedAssertion from saml2.samlp import response_from_string from saml2.s_utils import factory, do_attribute_statement import pytest from py.test import raises from pathutils import full_path SIGNED = full_path("saml_signed.xml") UNSIGNED = full_path("saml_unsigned.xml") SIMPLE_SAML_PHP_RESPONSE = full_path("simplesamlphp_authnresponse.xml") OKTA_RESPONSE = full_path("okta_response.xml") OKTA_ASSERTION = full_path("okta_assertion") PUB_KEY = full_path("test.pem") PRIV_KEY = full_path("test.key") ENC_PUB_KEY = full_path("pki/test_1.crt") ENC_PRIV_KEY = full_path("pki/test.key") INVALID_KEY = full_path("non-existent.key") IDP_EXAMPLE = full_path("idp_example.xml") METADATA_CERT = full_path("metadata_cert.xml")
Location="http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/metadata.php"/> </IDPSSODescriptor> <Organization> <OrganizationName xml:lang="en">Catalogix</OrganizationName> <OrganizationDisplayName xml:lang="en">Catalogix</OrganizationDisplayName> <OrganizationURL xml:lang="en">http://www.catalogix.se</OrganizationURL> </Organization> <ContactPerson contactType="technical"> <SurName>Hedberg</SurName> <EmailAddress>[email protected]</EmailAddress> </ContactPerson> </EntityDescriptor> </EntitiesDescriptor> """ ATTRCONV = ac_factory(full_path("attributemaps")) METADATACONF = { "1": { "local": [full_path("swamid-1.0.xml")] }, "2": { "local": [full_path("InCommon-metadata.xml")] }, "3": { "local": [full_path("extended.xml")] }, # "7": { # "local": [full_path("metadata_sp_1.xml"), # full_path("InCommon-metadata.xml")], # "remote": [
from saml2.sigver import pre_encryption_part from saml2.sigver import make_temp from saml2.sigver import XmlsecError from saml2.sigver import SigverError from saml2.mdstore import MetadataStore from saml2.saml import assertion_from_string from saml2.saml import EncryptedAssertion from saml2.samlp import response_from_string from saml2.s_utils import factory, do_attribute_statement import pytest from py.test import raises from pathutils import full_path SIGNED = full_path("saml_signed.xml") UNSIGNED = full_path("saml_unsigned.xml") SIMPLE_SAML_PHP_RESPONSE = full_path("simplesamlphp_authnresponse.xml") OKTA_RESPONSE = full_path("okta_response.xml") OKTA_ASSERTION = full_path("okta_assertion") PUB_KEY = full_path("test.pem") PRIV_KEY = full_path("test.key") ENC_PUB_KEY = full_path("pki/test_1.crt") ENC_PRIV_KEY = full_path("pki/test.key") def _eq(l1, l2): return set(l1) == set(l2)
def setup_class(self): self.acs = attribute_converter.ac_factory(full_path("attributemaps"))
"service": { "sp": { "endpoints": { "assertion_consumer_service": [ "http://lingon.catalogix.se:8087/"], }, "name": "test", "idp": { "urn:mace:example.com:saml:roland:idp": { 'single_sign_on_service': {'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect': 'http://localhost:8088/sso/'}}, } } }, "key_file": full_path("test.key"), "cert_file": full_path("test.pem"), "metadata": [{ "class": "saml2.mdstore.MetaDataFile", "metadata": [(full_path("metadata.xml"), ), (full_path("urn-mace-swami.se-swamid-test-1.0-metadata.xml"), )], }], "virtual_organization": { "coip": { "nameid_format": "urn:oasis:names:tc:SAML:2.0:nameid-format:transient", "common_identifier": "eduPersonPrincipalName", "attribute_auth": [ "https://coip-test.sunet.se/idp/shibboleth", ] } },
<EmailAddress>[email protected]</EmailAddress> </ContactPerson> </EntityDescriptor> </EntitiesDescriptor> """.format(cert_data=TEST_CERT) ONTS = { saml.NAMESPACE: saml, md.NAMESPACE: md, xmldsig.NAMESPACE: xmldsig, xmlenc.NAMESPACE: xmlenc } ONTS.update(load_extensions()) ATTRCONV = ac_factory(full_path("attributemaps")) METADATACONF = { "1": [{ "class": "saml2.mdstore.MetaDataFile", "metadata": [(full_path("swamid-1.0.xml"),)], }], "2": [{ "class": "saml2.mdstore.MetaDataFile", "metadata": [(full_path("InCommon-metadata.xml"),)], }], "3": [{ "class": "saml2.mdstore.MetaDataFile", "metadata": [(full_path("extended.xml"),)], }], # "7": [{
from saml2.sigver import make_temp from saml2.sigver import XmlsecError from saml2.sigver import SigverError from saml2.mdstore import MetadataStore from saml2.saml import assertion_from_string from saml2.saml import EncryptedAssertion from saml2.samlp import response_from_string from saml2.s_utils import factory, do_attribute_statement #from pyasn1.codec.der import decoder from py.test import raises from pathutils import full_path SIGNED = full_path("saml_signed.xml") UNSIGNED = full_path("saml_unsigned.xml") SIMPLE_SAML_PHP_RESPONSE = full_path("simplesamlphp_authnresponse.xml") PUB_KEY = full_path("test.pem") PRIV_KEY = full_path("test.key") ENC_PUB_KEY = full_path("pki/test_1.crt") ENC_PRIV_KEY = full_path("pki/test.key") def _eq(l1, l2): return set(l1) == set(l2) CERT1 = """MIICsDCCAhmgAwIBAgIJAJrzqSSwmDY9MA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
def test_metadata_extension_algsupport(): mds = MetadataStore(list(ONTS.values()), ATTRCONV, None) mds.imp(METADATACONF["12"]) mdf = mds.metadata[full_path("uu.xml")] assert mds
"single_sign_on_service": [("%s/sso" % BASE, BINDING_HTTP_REDIRECT)], "single_logout_service": [("%s/slo" % BASE, BINDING_SOAP), ("%s/slop" % BASE, BINDING_HTTP_POST)] }, "policy": { "default": { "lifetime": { "minutes": 15 }, "entity_categories": ["swamid", "edugain"], "name_form": NAME_FORMAT_URI, } }, "subject_data": full_path("subject_data.db"), #"domain": "umu.se", #"name_qualifier": "" }, }, "debug": 1, "key_file": full_path("test.key"), "cert_file": full_path("test.pem"), "xmlsec_binary": xmlsec_path, "metadata": [{ "class": "saml2_tophat.mdstore.MetaDataFile",
#!/usr/bin/env python # -*- coding: utf-8 -*- from pathutils import dotname, full_path from pytest import raises from saml2 import xmldsig as ds from saml2.config import config_factory from saml2.response import VerificationError from saml2.response import authn_response HOLDER_OF_KEY_RESPONSE_FILE = full_path("saml_hok.xml") INVALID_HOLDER_OF_KEY_RESPONSE_FILE = full_path("saml_hok_invalid.xml") class TestHolderOfKeyResponse: def test_valid_hok_response_is_parsed(self): """Verifies that response with 'holder-of-key' subject confirmations is parsed successfully.""" resp = self._get_test_response(HOLDER_OF_KEY_RESPONSE_FILE) resp.do_not_verify = True resp.parse_assertion() assert resp.get_subject() is not None assert len(resp.assertion.subject.subject_confirmation) == 2 actual_hok_certs = [ ki.x509_data[0].x509_certificate.text.strip() for sc in resp.assertion.subject.subject_confirmation for ki in sc.subject_confirmation_data.extensions_as_elements( ds.KeyInfo.c_tag, ds) ] assert actual_hok_certs == self._expected_hok_certs()
def test_metadata_extension_algsupport(): mds = MetadataStore(ATTRCONV, None) mds.imp(METADATACONF["12"]) mdf = mds.metadata[full_path("uu.xml")] assert mds
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": [ (HOME, BINDING_HTTP_POST)], "single_logout_service": [ (HOME + "slo", BINDING_HTTP_REDIRECT)], }, "required_attributes": ["surName", "givenName", "mail"], "optional_attributes": ["title"], "idp": ["urn:mace:example.com:saml:roland:idp"], "subject_data": full_path("subject_data.db"), } }, "debug": 1, "key_file": full_path("test.key"), "cert_file": full_path("test.pem"), "xmlsec_binary": None, "metadata": { "local": [full_path("idp_slo_redirect.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", } },
#!/usr/bin/env python # -*- coding: utf-8 -*- from contextlib import closing from datetime import datetime from dateutil import parser from saml2.authn_context import INTERNETPROTOCOLPASSWORD from saml2.server import Server from saml2.response import authn_response from saml2.config import config_factory from pathutils import dotname, full_path XML_RESPONSE_FILE = full_path("saml_signed.xml") XML_RESPONSE_FILE2 = full_path("saml2_response.xml") def _eq(l1, l2): return set(l1) == set(l2) IDENTITY = { "eduPersonAffiliation": ["staff", "member"], "surName": ["Jeter"], "givenName": ["Derek"], "mail": ["*****@*****.**"], "title": ["shortstop"] } AUTHN = { "class_ref": INTERNETPROTOCOLPASSWORD,