def response_factory(xmlstr, conf, return_addr=None, outstanding_queries=None, timeslack=0, decode=True, request_id=0, origxml=None, asynchop=True, allow_unsolicited=False): sec_context = security_context(conf) if not timeslack: try: timeslack = int(conf.accepted_time_diff) except TypeError: timeslack = 0 attribute_converters = conf.attribute_converters entity_id = conf.entityid response = StatusResponse(sec_context, return_addr, timeslack, request_id) try: response.loads(xmlstr, decode, origxml) if response.response.assertion or response.response.encrypted_assertion: authnresp = AuthnResponse(sec_context, attribute_converters, entity_id, return_addr, outstanding_queries, timeslack, asynchop, allow_unsolicited) authnresp.update(response) return authnresp except TypeError: response.signature_check = sec_context.correctly_signed_logout_response response.loads(xmlstr, decode, origxml) logoutresp = LogoutResponse(sec_context, return_addr, timeslack) logoutresp.update(response) return logoutresp return response
def test_only_use_keys_in_metadata(self): conf = config.SPConfig() conf.load_file("sp_2_conf") sc = security_context(conf) # should fail raises(MissingKey, 'sc.correctly_signed_response(self._sign_resp_)')
def authn_response(conf, return_addrs, outstanding_queries=None, timeslack=0, asynchop=True, allow_unsolicited=False, want_assertions_signed=False, conv_info=None): sec = security_context(conf) if not timeslack: try: timeslack = int(conf.accepted_time_diff) except TypeError: timeslack = 0 return AuthnResponse(sec, conf.attribute_converters, conf.entityid, return_addrs, outstanding_queries, timeslack, asynchop=asynchop, allow_unsolicited=allow_unsolicited, want_assertions_signed=want_assertions_signed, conv_info=conv_info)
def test_xmlsec_err_non_ascii_ava(): conf = config.SPConfig() conf.load_file("server_conf") md = MetadataStore([saml, samlp], None, conf) md.load("local", IDP_EXAMPLE) 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"): ("Föö", ""), ("", "", "givenName"): ("Bär", ""), }) ) with raises(XmlsecError): sec.sign_statement( assertion, class_name(assertion), key_file=INVALID_KEY, node_id=assertion.id, )
def response_factory(xmlstr, conf, return_addr=None, outstanding_queries=None, timeslack=0, decode=True, request_id=0, origxml=None, asynchop=True, allow_unsolicited=False): sec_context = security_context(conf) if not timeslack: try: timeslack = int(conf.accepted_time_diff) except TypeError: timeslack = 0 attribute_converters = conf.attribute_converters entity_id = conf.entityid response = StatusResponse(sec_context, return_addr, timeslack, request_id, asynchop) try: response.loads(xmlstr, decode, origxml) if response.response.assertion or response.response.encrypted_assertion: authnresp = AuthnResponse(sec_context, attribute_converters, entity_id, return_addr, outstanding_queries, timeslack, asynchop, allow_unsolicited) authnresp.update(response) return authnresp except TypeError: response.signature_check = sec_context.correctly_signed_logout_response response.loads(xmlstr, decode, origxml) logoutresp = LogoutResponse(sec_context, return_addr, timeslack, asynchop=asynchop) logoutresp.update(response) return logoutresp return response
def test_xbox_non_ascii_ava(): conf = config.SPConfig() conf.load_file("server_conf") md = MetadataStore([saml, samlp], None, conf) md.load("local", IDP_EXAMPLE) 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"): ("Föö", ""), ("", "", "givenName"): ("Bär", ""), } ) ) sigass = sec.sign_statement( assertion, class_name(assertion), key_file=PRIV_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, key_file=PRIV_KEY) _seass = saml.encrypted_assertion_from_string(decr_text) assertions = [] assers = extension_elements_to_elements( _seass.extension_elements, [saml, samlp] ) for ass in assers: _txt = sec.verify_signature( str(ass), PUB_KEY, node_name=class_name(assertion) ) if _txt: assertions.append(ass) assert assertions print(assertions)
def __init__(self, cargs, kwargs): self.nspair = {"xs": "http://www.w3.org/2001/XMLSchema"} _cnf = kwargs['conf'] res = read_multi_conf(_cnf, True) eds = [] for key, cnf in res.items(): eds.append(entity_descriptor(cnf)) valid_for = 0 """ Setting things to None here that are now unused, but might be useful someday """ conf = Config() conf.key_file = None conf.cert_file = None conf.debug = 1 conf.xmlsec_binary = None args_name = None args_id = None args_sign = None secc = security_context(conf) desc, xmldoc = entities_descriptor(eds, valid_for, args_name, args_id, args_sign, secc) valid_instance(desc) self.desc = desc self.xmldoc = xmldoc
def authn_response( conf, return_addrs, outstanding_queries=None, timeslack=0, asynchop=True, allow_unsolicited=False, want_assertions_signed=False, ): sec = security_context(conf) if not timeslack: try: timeslack = int(conf.accepted_time_diff) except TypeError: timeslack = 0 return AuthnResponse( sec, conf.attribute_converters, conf.entityid, return_addrs, outstanding_queries, timeslack, asynchop=asynchop, allow_unsolicited=allow_unsolicited, want_assertions_signed=want_assertions_signed, )
def __init__(self, attrc, config, ca_certs=None, check_validity=True, disable_ssl_certificate_validation=False, filter=None): """ :params attrc: :params config: Config() :params ca_certs: :params disable_ssl_certificate_validation: """ MetaData.__init__(self, attrc, check_validity=check_validity) if disable_ssl_certificate_validation: self.http = HTTPBase(verify=False, ca_bundle=ca_certs) else: self.http = HTTPBase(verify=True, ca_bundle=ca_certs) self.security = security_context(config) self.ii = 0 self.metadata = {} self.check_validity = check_validity self.filter = filter self.to_old = {}
def setup_class(self): # This would be one way to initialize the security context : # # conf = config.SPConfig() # conf.load_file("server_conf") # conf.only_use_keys_in_metadata = False # # but instead, FakeConfig() is used to really only use the minimal # set of parameters needed for these test cases. Other test cases # (TestSecurityMetadata below) excersise the SPConfig() mechanism. # conf = FakeConfig() self.sec = sigver.security_context(FakeConfig()) 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_crypto_backend(): idpc = IdPConfig() idpc.load(IDP_XMLSECURITY) assert idpc.crypto_backend == 'XMLSecurity' sec = security_context(idpc) assert isinstance(sec.crypto, CryptoBackendXMLSecurity)
def __init__(self, onts, attrc, config, ca_certs=None, check_validity=True, disable_ssl_certificate_validation=False): """ :params onts: :params attrc: :params config: Config() :params ca_certs: :params disable_ssl_certificate_validation: """ self.onts = onts self.attrc = attrc if disable_ssl_certificate_validation: self.http = HTTPBase(verify=False, ca_bundle=ca_certs) else: self.http = HTTPBase(verify=True, ca_bundle=ca_certs) self.security = security_context(config) self.ii = 0 self.metadata = {} self.check_validity = check_validity
def create_metadata_string(configfile, config=None, valid=None, cert=None, keyfile=None, mid=None, name=None, sign=None): valid_for = 0 nspair = {"xs": "http://www.w3.org/2001/XMLSchema"} # paths = [".", "/opt/local/bin"] if valid: valid_for = int(valid) # Hours eds = [] if config is None: if configfile.endswith(".py"): configfile = configfile[:-3] config = Config().load_file(configfile, metadata_construction=True) eds.append(entity_descriptor(config)) conf = Config() conf.key_file = config.key_file or keyfile conf.cert_file = config.cert_file or cert conf.debug = 1 conf.xmlsec_binary = config.xmlsec_binary secc = security_context(conf) if mid: eid, xmldoc = entities_descriptor(eds, valid_for, name, mid, sign, secc) else: eid = eds[0] if sign: eid, xmldoc = sign_entity_descriptor(eid, mid, secc) else: xmldoc = None valid_instance(eid) return metadata_tostring_fix(eid, nspair, xmldoc)
def __init__(self, entity_type, config=None, config_file="", virtual_organization=""): self.entity_type = entity_type self.users = None if config: self.config = config elif config_file: self.config = config_factory(entity_type, config_file) else: raise SAMLError("Missing configuration") for item in ["cert_file", "key_file", "ca_certs"]: _val = getattr(self.config, item, None) if not _val: continue if _val.startswith("http"): r = requests.request("GET", _val) if r.status_code == 200: _, filename = make_temp(r.text, ".pem", False) setattr(self.config, item, filename) else: raise Exception( "Could not fetch certificate from %s" % _val) try: self.signkey = RSA.importKey( open(self.config.getattr("key_file", ""), 'r').read(), passphrase=self.config.key_file_passphrase) except (KeyError, TypeError): self.signkey = None HTTPBase.__init__(self, self.config.verify_ssl_cert, self.config.ca_certs, self.config.key_file, self.config.cert_file) if self.config.vorg: for vo in self.config.vorg.values(): vo.sp = self self.metadata = self.config.metadata self.config.setup_logger() self.debug = self.config.debug self.sec = security_context(self.config) if virtual_organization: if isinstance(virtual_organization, basestring): self.vorg = self.config.vorg[virtual_organization] elif isinstance(virtual_organization, VirtualOrg): self.vorg = virtual_organization else: self.vorg = None self.artifact = {} if self.metadata: self.sourceid = self.metadata.construct_source_id() else: self.sourceid = {}
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 __init__( self, onts, attrc, config, ca_certs=None, check_validity=True, disable_ssl_certificate_validation=False, filter=None, ): """ :params onts: :params attrc: :params config: Config() :params ca_certs: :params disable_ssl_certificate_validation: """ self.onts = onts self.attrc = attrc if disable_ssl_certificate_validation: self.http = HTTPBase(verify=False, ca_bundle=ca_certs) else: self.http = HTTPBase(verify=True, ca_bundle=ca_certs) self.security = security_context(config) self.ii = 0 self.metadata = {} self.check_validity = check_validity self.filter = filter
def setup_class(self): conf = config.SPConfig() conf.load_file("server_conf") md = MetadataStore([saml, samlp], None, conf) md.load("local", METADATA_CERT) conf.metadata = md conf.only_use_keys_in_metadata = False self.sec = sigver.security_context(conf) assertion = factory( saml.Assertion, version="2.0", id="id-11111", issuer=saml.Issuer(text="the-issuer"), issue_instant="2009-10-30T13:20:28Z", signature=sigver.pre_signature_part("id-11111", self.sec.my_cert, 1), attribute_statement=do_attribute_statement({ ("name:surName", "nameformat", "surName"): ("Foo", ""), ("name:givenName", "nameformat", "givenName"): ("Bar", ""), }) ) assertion = factory( saml.Assertion, version="2.0", id="id-11111", issue_instant="2009-10-30T13:20:28Z", signature=sigver.pre_signature_part("id-11111", self.sec.my_cert, 1), attribute_statement=do_attribute_statement( {("", "", "surName"): ("Foo", ""), ("", "", "givenName"): ("Bar", ""), }) )
def test_xmlsec_err(): conf = config.SPConfig() conf.load_file("server_conf") md = MetadataStore([saml, samlp], None, conf) md.load("local", IDP_EXAMPLE) conf.metadata = md conf.only_use_keys_in_metadata = False sec = sigver.security_context(conf) assertion = factory( saml.Assertion, version="2.0", id="id-11111", issue_instant="2009-10-30T13:20:28Z", signature=sigver.pre_signature_part("id-11111", sec.my_cert, 1), attribute_statement=do_attribute_statement( {("", "", "surName"): ("Foo", ""), ("", "", "givenName"): ("Bar", ""), }) ) with raises(XmlsecError): sec.sign_statement( assertion, class_name(assertion), key_file=INVALID_KEY, node_id=assertion.id, )
def test_xbox_non_ascii_ava(): conf = config.SPConfig() conf.load_file("server_conf") md = MetadataStore([saml, samlp], None, conf) md.load("local", IDP_EXAMPLE) conf.metadata = md conf.only_use_keys_in_metadata = False sec = sigver.security_context(conf) assertion = factory( saml.Assertion, version="2.0", id="id-11111", issue_instant="2009-10-30T13:20:28Z", signature=sigver.pre_signature_part("id-11111", sec.my_cert, 1), attribute_statement=do_attribute_statement( { ("", "", "surName"): ("Föö", ""), ("", "", "givenName"): ("Bär", ""), } ) ) sigass = sec.sign_statement( assertion, class_name(assertion), key_file=PRIV_KEY, node_id=assertion.id, ) _ass0 = saml.assertion_from_string(sigass) encrypted_assertion = EncryptedAssertion() encrypted_assertion.add_extension_element(_ass0) tmp = make_temp( str(pre_encryption_part()).encode('utf-8'), decode=False ) enctext = sec.crypto.encrypt( str(encrypted_assertion), conf.cert_file, tmp.name, "des-192", '/*[local-name()="EncryptedAssertion"]/*[local-name()="Assertion"]', ) decr_text = sec.decrypt(enctext, key_file=PRIV_KEY) _seass = saml.encrypted_assertion_from_string(decr_text) assertions = [] assers = extension_elements_to_elements( _seass.extension_elements, [saml, samlp] ) for ass in assers: _txt = sec.verify_signature( str(ass), PUB_KEY, node_name=class_name(assertion) ) if _txt: assertions.append(ass) assert assertions print(assertions)
def test_split_backend_metadata_to_separate_files(self, tmpdir, cert_and_key, satosa_config_dict, saml_frontend_config, saml_backend_config): satosa_config_dict["FRONTEND_MODULES"] = [saml_frontend_config] satosa_config_dict["BACKEND_MODULES"] = [ saml_backend_config, saml_backend_config ] create_and_write_saml_metadata(satosa_config_dict, cert_and_key[1], cert_and_key[0], str(tmpdir), None, split_backend_metadata=True) conf = Config() conf.cert_file = cert_and_key[0] security_ctx = security_context(conf) written_metadata_files = [ saml_backend_config["name"], saml_backend_config["name"] ] for file in written_metadata_files: md = MetaDataFile(None, os.path.join(str(tmpdir), "{}_0.xml".format(file)), security=security_ctx) assert md.load()
def __init__(self, config=None, identity_cache=None, state_cache=None, virtual_organization=None, config_file="", logger=None): """ :param config: A saml2.config.Config instance :param identity_cache: Where the class should store identity information :param state_cache: Where the class should keep state information :param virtual_organization: Which if any virtual organization this SP belongs to """ self.users = Population(identity_cache) # for server state storage if state_cache is None: self.state = {} # in memory storage else: self.state = state_cache if config: self.config = config elif config_file: self.config = config_factory("sp", config_file) else: raise Exception("Missing configuration") self.metadata = self.config.metadata if logger is None: self.logger = self.config.setup_logger() else: self.logger = logger # we copy the config.debug variable in an internal # field for convenience and because we may need to # change it during the tests self.debug = self.config.debug self.sec = security_context(self.config, log=self.logger, debug=self.debug) if virtual_organization: self.vorg = VirtualOrg(self, virtual_organization) else: self.vorg = None if "allow_unsolicited" in self.config: self.allow_unsolicited = self.config.allow_unsolicited else: self.allow_unsolicited = False if getattr(self.config, 'authn_requests_signed', 'false') == 'true': self.authn_requests_signed_default = True else: self.authn_requests_signed_default = False if getattr(self.config, 'logout_requests_signed', 'false') == 'true': self.logout_requests_signed_default = True else: self.logout_requests_signed_default = False
def test_split_frontend_metadata_to_separate_files( self, tmpdir, cert_and_key, satosa_config_dict, saml_mirror_frontend_config, saml_backend_config, oidc_backend_config): satosa_config_dict["FRONTEND_MODULES"] = [saml_mirror_frontend_config] satosa_config_dict["BACKEND_MODULES"] = [ oidc_backend_config, saml_backend_config ] create_and_write_saml_metadata(satosa_config_dict, cert_and_key[1], cert_and_key[0], str(tmpdir), None, split_frontend_metadata=True) conf = Config() conf.cert_file = cert_and_key[0] security_ctx = security_context(conf) file_pattern = "{}*.xml".format(saml_mirror_frontend_config["name"]) written_metadata_files = glob.glob( os.path.join(str(tmpdir), file_pattern)) assert len(written_metadata_files) == 2 for file in written_metadata_files: md = MetaDataFile(None, file, security=security_ctx) assert md.load()
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 __init__(self, entity_type, config=None, config_file="", virtual_organization=""): self.entity_type = entity_type self.users = None if config: self.config = config elif config_file: self.config = config_factory(entity_type, config_file) else: raise SAMLError("Missing configuration") for item in ["cert_file", "key_file", "ca_certs"]: _val = getattr(self.config, item, None) if not _val: continue if _val.startswith("http"): r = requests.request("GET", _val) if r.status_code == 200: _, filename = make_temp(r.text, ".pem", False) setattr(self.config, item, filename) else: raise Exception( "Could not fetch certificate from %s" % _val) try: self.signkey = RSA.importKey( open(self.config.getattr("key_file", ""), 'r').read()) except (KeyError, TypeError): self.signkey = None HTTPBase.__init__(self, self.config.verify_ssl_cert, self.config.ca_certs, self.config.key_file, self.config.cert_file) if self.config.vorg: for vo in self.config.vorg.values(): vo.sp = self self.metadata = self.config.metadata self.config.setup_logger() self.debug = self.config.debug self.sec = security_context(self.config) if virtual_organization: if isinstance(virtual_organization, six.string_types): self.vorg = self.config.vorg[virtual_organization] elif isinstance(virtual_organization, VirtualOrg): self.vorg = virtual_organization else: self.vorg = None self.artifact = {} if self.metadata: self.sourceid = self.metadata.construct_source_id() else: self.sourceid = {}
def get_metadata(self): """Returns SAML Identity Provider Metadata""" edesc = entity_descriptor(self._config, 24) if self._config.key_file: edesc = sign_entity_descriptor(edesc, 24, None, security_context(self._config)) response = make_response(str(edesc)) response.headers['Content-type'] = 'text/xml; charset=utf-8' return response
def test_only_use_keys_in_metadata(self): conf = config.SPConfig() conf.load_file("sp_2_conf") sc = security_context(conf) # should fail raises(MissingKey, 'sc.correctly_signed_response("%s" % self._sign_resp_)')
def __init__(self, config=None, identity_cache=None, state_cache=None, virtual_organization=None, config_file=""): """ :param config: A saml2.config.Config instance :param identity_cache: Where the class should store identity information :param state_cache: Where the class should keep state information :param virtual_organization: Which if any virtual organization this SP belongs to """ self.users = Population(identity_cache) # for server state storage if state_cache is None: self.state = {} # in memory storage else: self.state = state_cache if config: self.config = config elif config_file: self.config = config_factory("sp", config_file) else: raise Exception("Missing configuration") self.metadata = self.config.metadata self.config.setup_logger() # we copy the config.debug variable in an internal # field for convenience and because we may need to # change it during the tests self.debug = self.config.debug self.sec = security_context(self.config) if virtual_organization: self.vorg = VirtualOrg(self, virtual_organization) else: self.vorg = None if "allow_unsolicited" in self.config: self.allow_unsolicited = self.config.allow_unsolicited else: self.allow_unsolicited = False if getattr(self.config, 'authn_requests_signed', 'false') == 'true': self.authn_requests_signed_default = True else: self.authn_requests_signed_default = False if getattr(self.config, 'logout_requests_signed', 'false') == 'true': self.logout_requests_signed_default = True else: self.logout_requests_signed_default = False
def __init__(self, config=None, identity_cache=None, state_cache=None, virtual_organization="",config_file=""): """ :param config: A saml2.config.Config instance :param identity_cache: Where the class should store identity information :param state_cache: Where the class should keep state information :param virtual_organization: A specific virtual organization """ self.users = Population(identity_cache) # for server state storage if state_cache is None: self.state = {} # in memory storage else: self.state = state_cache if config: self.config = config elif config_file: self.config = config_factory("sp", config_file) else: raise Exception("Missing configuration") if self.config.vorg: for vo in self.config.vorg.values(): vo.sp = self self.metadata = self.config.metadata self.config.setup_logger() # we copy the config.debug variable in an internal # field for convenience and because we may need to # change it during the tests self.debug = self.config.debug self.sec = security_context(self.config) if virtual_organization: if isinstance(virtual_organization, basestring): self.vorg = self.config.vorg[virtual_organization] elif isinstance(virtual_organization, VirtualOrg): self.vorg = virtual_organization else: self.vorg = {} for foo in ["allow_unsolicited", "authn_requests_signed", "logout_requests_signed"]: if self.config.getattr("sp", foo) == 'true': setattr(self, foo, True) else: setattr(self, foo, False) # extra randomness self.seed = rndstr(32) self.logout_requests_signed_default = True self.allow_unsolicited = self.config.getattr("allow_unsolicited", "sp")
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 _metadata_endpoint(self, context): """ Endpoint for retrieving the backend metadata :type context: satosa.context.Context :rtype: satosa.response.Response :param context: The current context :return: response with metadata """ logger.debug("Sending metadata response") conf = self.sp.config metadata = entity_descriptor(conf) # creare gli attribute_consuming_service cnt = 0 for (attribute_consuming_service ) in metadata.spsso_descriptor.attribute_consuming_service: attribute_consuming_service.index = str(cnt) cnt += 1 cnt = 0 for (assertion_consumer_service ) in metadata.spsso_descriptor.assertion_consumer_service: assertion_consumer_service.is_default = "true" if not cnt else "" assertion_consumer_service.index = str(cnt) cnt += 1 # nameformat patch... tutto questo non rispecchia gli standard OASIS for reqattr in metadata.spsso_descriptor.attribute_consuming_service[ 0].requested_attribute: reqattr.name_format = None reqattr.friendly_name = None # attribute consuming service service name patch service_name = metadata.spsso_descriptor.attribute_consuming_service[ 0].service_name[0] service_name.lang = "it" service_name.text = metadata.entity_id # remove extension disco and uuinfo (spid-testenv2) # metadata.spsso_descriptor.extensions = [] # load ContactPerson Extensions self._metadata_contact_person(metadata, conf) # metadata signature secc = security_context(conf) # sign_dig_algs = self.get_kwargs_sign_dig_algs() eid, xmldoc = sign_entity_descriptor(metadata, None, secc, **sign_dig_algs) valid_instance(eid) return Response(text_type(xmldoc).encode("utf-8"), content="text/xml; charset=utf8")
def attribute_response(conf, return_addrs, timeslack=0, asynchop=False, test=False): sec = security_context(conf) if not timeslack: try: timeslack = int(conf.accepted_time_diff) except TypeError: timeslack = 0 return AttributeResponse( sec, conf.attribute_converters, conf.entityid, return_addrs, timeslack, asynchop=asynchop, test=test )
def attribute_response(conf, return_addrs, timeslack=0, asynchop=False, test=False, conv_info=None): sec = security_context(conf) if not timeslack: try: timeslack = int(conf.accepted_time_diff) except TypeError: timeslack = 0 return AttributeResponse(sec, conf.attribute_converters, conf.entityid, return_addrs, timeslack, asynchop=asynchop, test=test, conv_info=conv_info)
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 __init__(self, config_file="", config=None, _cache="", stype="idp"): self.ident = None if config_file: self.load_config(config_file, stype) elif config: self.conf = config else: raise Exception("Missing configuration") self.conf.setup_logger() self.metadata = self.conf.metadata self.sec = security_context(self.conf) self._cache = _cache
def authn_response(conf, return_addr, outstanding_queries=None, timeslack=0, asynchop=True, allow_unsolicited=False): # Horrible hack allow_unsolicited = True sec = security_context(conf) if not timeslack: try: timeslack = int(conf.accepted_time_diff) except TypeError: timeslack = 0 return AuthnResponse(sec, conf.attribute_converters, conf.entityid, return_addr, outstanding_queries, timeslack, asynchop=asynchop, allow_unsolicited=allow_unsolicited)
def test_oidc_saml(self, tmpdir, cert_and_key, satosa_config_dict, oidc_frontend_config, saml_backend_config): satosa_config_dict["FRONTEND_MODULES"] = [oidc_frontend_config] satosa_config_dict["BACKEND_MODULES"] = [saml_backend_config] create_and_write_saml_metadata(satosa_config_dict, cert_and_key[1], cert_and_key[0], str(tmpdir), None) conf = Config() conf.cert_file = cert_and_key[0] security_ctx = security_context(conf) md = MetaDataFile(None, os.path.join(str(tmpdir), "backend.xml"), security=security_ctx) assert md.load() assert not os.path.isfile(os.path.join(str(tmpdir), "frontend.xml"))
def authn_resp(self): authn_resp = AuthnResponse( security_context(SPConfig()), None, 'https://sp.example.com', allow_unsolicited=True, return_addrs=['http://sp.example.com/demo1/index.php?acs']) xmlstr = """<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_8e8dc5f69a98cc4c1ff3427e5ce34606fd672f91e6" Version="2.0" IssueInstant="2014-07-17T01:01:48Z" Destination="http://sp.example.com/acs" InResponseTo="abc123"> <saml:Issuer>https://idp.example.com</saml:Issuer> <samlp:Status> <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/> </samlp:Status> <saml:Assertion xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" ID="_d71a3a8e9fcc45c9e9d248ef7049393fc8f04e5f75" Version="2.0" IssueInstant="2014-07-17T01:01:48Z"> <saml:Issuer>https://idp.example.com</saml:Issuer> <saml:Subject> <saml:NameID SPNameQualifier="https://sp.example.com" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">_ce3d2948b4cf20146dee0a0b3dd6f69b6cf86f62d7</saml:NameID> <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"> <saml:SubjectConfirmationData NotOnOrAfter="2024-01-18T06:21:48Z" Recipient="https://sp.example.com/acs" InResponseTo="abc123"/> </saml:SubjectConfirmation> </saml:Subject> <saml:Conditions NotBefore="2014-07-17T01:01:18Z" NotOnOrAfter="2024-01-18T06:21:48Z"> <saml:AudienceRestriction> <saml:Audience>https://sp.example.com</saml:Audience> </saml:AudienceRestriction> </saml:Conditions> <saml:AuthnStatement AuthnInstant="2014-07-17T01:01:48Z" SessionNotOnOrAfter="2024-07-17T09:01:48Z" SessionIndex="_be9967abd904ddcae3c0eb4189adbe3f71e327cf93"> <saml:AuthnContext> <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef> </saml:AuthnContext> </saml:AuthnStatement> <saml:AttributeStatement> <saml:Attribute Name="uid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"> <saml:AttributeValue xsi:type="xs:string">test</saml:AttributeValue> </saml:Attribute> <saml:Attribute Name="mail" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"> <saml:AttributeValue xsi:type="xs:string">[email protected]</saml:AttributeValue> </saml:Attribute> <saml:Attribute Name="eduPersonAffiliation" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"> <saml:AttributeValue xsi:type="xs:string">users</saml:AttributeValue> <saml:AttributeValue xsi:type="xs:string">examplerole1</saml:AttributeValue> </saml:Attribute> </saml:AttributeStatement> </saml:Assertion> </samlp:Response>""" authn_resp.loads(xmlstr) authn_resp.parse_assertion() return authn_resp
def __init__(self, onts, attrc, config, ca_certs=None, disable_ssl_certificate_validation=False): """ :params onts: :params attrc: :params config: Config() :params ca_certs: :params disable_ssl_certificate_validation: """ self.onts = onts self.attrc = attrc self.http = HTTPBase(verify=disable_ssl_certificate_validation, ca_bundle=ca_certs) self.security = security_context(config) self.ii = 0 self.metadata = {}
def test_split_backend_metadata_to_separate_files(self, tmpdir, cert_and_key, satosa_config_dict, saml_frontend_config, saml_backend_config): satosa_config_dict["FRONTEND_MODULES"] = [saml_frontend_config] satosa_config_dict["BACKEND_MODULES"] = [saml_backend_config, saml_backend_config] create_and_write_saml_metadata(satosa_config_dict, cert_and_key[1], cert_and_key[0], str(tmpdir), None, split_backend_metadata=True) conf = Config() conf.cert_file = cert_and_key[0] security_ctx = security_context(conf) written_metadata_files = [saml_backend_config["name"], saml_backend_config["name"]] for file in written_metadata_files: md = MetaDataFile(None, os.path.join(str(tmpdir), "{}_0.xml".format(file)), security=security_ctx) assert md.load()
def authn_resp(self): authn_resp = AuthnResponse(security_context(SPConfig()), None, 'https://sp.example.com', allow_unsolicited=True, return_addrs=['http://sp.example.com/demo1/index.php?acs']) xmlstr = """<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_8e8dc5f69a98cc4c1ff3427e5ce34606fd672f91e6" Version="2.0" IssueInstant="2014-07-17T01:01:48Z" Destination="http://sp.example.com/acs" InResponseTo="abc123"> <saml:Issuer>https://idp.example.com</saml:Issuer> <samlp:Status> <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/> </samlp:Status> <saml:Assertion xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" ID="_d71a3a8e9fcc45c9e9d248ef7049393fc8f04e5f75" Version="2.0" IssueInstant="2014-07-17T01:01:48Z"> <saml:Issuer>https://idp.example.com</saml:Issuer> <saml:Subject> <saml:NameID SPNameQualifier="https://sp.example.com" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient">_ce3d2948b4cf20146dee0a0b3dd6f69b6cf86f62d7</saml:NameID> <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"> <saml:SubjectConfirmationData NotOnOrAfter="2024-01-18T06:21:48Z" Recipient="https://sp.example.com/acs" InResponseTo="abc123"/> </saml:SubjectConfirmation> </saml:Subject> <saml:Conditions NotBefore="2014-07-17T01:01:18Z" NotOnOrAfter="2024-01-18T06:21:48Z"> <saml:AudienceRestriction> <saml:Audience>https://sp.example.com</saml:Audience> </saml:AudienceRestriction> </saml:Conditions> <saml:AuthnStatement AuthnInstant="2014-07-17T01:01:48Z" SessionNotOnOrAfter="2024-07-17T09:01:48Z" SessionIndex="_be9967abd904ddcae3c0eb4189adbe3f71e327cf93"> <saml:AuthnContext> <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef> </saml:AuthnContext> </saml:AuthnStatement> <saml:AttributeStatement> <saml:Attribute Name="uid" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"> <saml:AttributeValue xsi:type="xs:string">test</saml:AttributeValue> </saml:Attribute> <saml:Attribute Name="mail" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"> <saml:AttributeValue xsi:type="xs:string">[email protected]</saml:AttributeValue> </saml:Attribute> <saml:Attribute Name="eduPersonAffiliation" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"> <saml:AttributeValue xsi:type="xs:string">users</saml:AttributeValue> <saml:AttributeValue xsi:type="xs:string">examplerole1</saml:AttributeValue> </saml:Attribute> </saml:AttributeStatement> </saml:Assertion> </samlp:Response>""" authn_resp.loads(xmlstr) authn_resp.parse_assertion() return authn_resp
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"): ("Föö", ""), ("", "", "givenName"): ("Bär", ""), }) )
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 _make_metadata(config_dict, option): """ Creates metadata from the given idp config :type config_dict: dict[str, Any] :type option: vopaas.metadata_creation.make_vopaas_metadata.MetadataOption :rtype: str :param config_dict: config :param option: metadata creation settings :return: A xml string """ eds = [] cnf = Config() cnf.load(copy.deepcopy(config_dict), metadata_construction=True) if option.valid: cnf.valid_for = option.valid eds.append(entity_descriptor(cnf)) conf = Config() conf.key_file = option.keyfile conf.cert_file = option.cert conf.debug = 1 conf.xmlsec_binary = option.xmlsec secc = security_context(conf) if option.id: desc, xmldoc = entities_descriptor(eds, option.valid, option.name, option.id, option.sign, secc) valid_instance(desc) print(desc.to_string(NSPAIR)) else: for eid in eds: if option.sign: assert conf.key_file assert conf.cert_file eid, xmldoc = sign_entity_descriptor(eid, option.id, secc) else: xmldoc = None valid_instance(eid) xmldoc = metadata_tostring_fix(eid, NSPAIR, xmldoc).decode() return xmldoc
def italian_sp_metadata(conf, md_type: str = "spid"): metadata = entity_descriptor(conf) # this will renumber acs starting from 0 and set index=0 as is_default cnt = 0 for (attribute_consuming_service ) in metadata.spsso_descriptor.attribute_consuming_service: attribute_consuming_service.index = str(cnt) cnt += 1 cnt = 0 for (assertion_consumer_service ) in metadata.spsso_descriptor.assertion_consumer_service: assertion_consumer_service.is_default = "true" if not cnt else "" assertion_consumer_service.index = str(cnt) cnt += 1 # nameformat patch for reqattr in metadata.spsso_descriptor.attribute_consuming_service[ 0].requested_attribute: reqattr.name_format = ( None # "urn:oasis:names:tc:SAML:2.0:attrname-format:basic" ) reqattr.friendly_name = None metadata.extensions = None # attribute consuming service service name patch service_name = metadata.spsso_descriptor.attribute_consuming_service[ 0].service_name[0] service_name.lang = "it" service_name.text = conf._sp_name if md_type == 'spid': spid_contacts_29_v3(metadata) elif md_type == 'cie': cie_contacts(metadata) # metadata signature secc = security_context(conf) sign_dig_algs = dict(sign_alg=conf._sp_signing_algorithm, digest_alg=conf._sp_digest_algorithm) eid, xmldoc = sign_entity_descriptor(metadata, None, secc, **sign_dig_algs) return xmldoc
def __init__(self, entity_type, config=None, config_file="", virtual_organization=""): self.entity_type = entity_type self.users = None if config: self.config = config elif config_file: self.config = config_factory(entity_type, config_file) else: raise SAMLError("Missing configuration") HTTPBase.__init__(self, self.config.verify_ssl_cert, self.config.ca_certs, self.config.key_file, self.config.cert_file) if self.config.vorg: for vo in list(self.config.vorg.values()): vo.sp = self self.metadata = self.config.metadata self.config.setup_logger() self.debug = self.config.debug self.seed = rndbytes(32) self.sec = security_context(self.config) if virtual_organization: if isinstance(virtual_organization, str): self.vorg = self.config.vorg[virtual_organization] elif isinstance(virtual_organization, VirtualOrg): self.vorg = virtual_organization else: self.vorg = None self.artifact = {} if self.metadata: self.sourceid = self.metadata.construct_source_id() else: self.sourceid = {}
def test_split_frontend_metadata_to_separate_files(self, tmpdir, cert_and_key, satosa_config_dict, saml_mirror_frontend_config, saml_backend_config, oidc_backend_config): satosa_config_dict["FRONTEND_MODULES"] = [saml_mirror_frontend_config] satosa_config_dict["BACKEND_MODULES"] = [oidc_backend_config, saml_backend_config] create_and_write_saml_metadata(satosa_config_dict, cert_and_key[1], cert_and_key[0], str(tmpdir), None, split_frontend_metadata=True) conf = Config() conf.cert_file = cert_and_key[0] security_ctx = security_context(conf) file_pattern = "{}*.xml".format(saml_mirror_frontend_config["name"]) written_metadata_files = glob.glob(os.path.join(str(tmpdir), file_pattern)) assert len(written_metadata_files) == 2 for file in written_metadata_files: md = MetaDataFile(None, file, security=security_ctx) assert md.load()
def __init__(self, entity_type, config=None, config_file="", virtual_organization=""): self.entity_type = entity_type self.users = None if config: self.config = config elif config_file: self.config = config_factory(entity_type, config_file) else: raise SAMLError("Missing configuration") HTTPBase.__init__(self, self.config.verify_ssl_cert, self.config.ca_certs, self.config.key_file, self.config.cert_file) if self.config.vorg: for vo in self.config.vorg.values(): vo.sp = self self.metadata = self.config.metadata self.config.setup_logger() self.debug = self.config.debug self.seed = rndstr(32) self.sec = security_context(self.config) if virtual_organization: if isinstance(virtual_organization, basestring): self.vorg = self.config.vorg[virtual_organization] elif isinstance(virtual_organization, VirtualOrg): self.vorg = virtual_organization else: self.vorg = None self.artifact = {} if self.metadata: self.sourceid = self.metadata.construct_source_id() else: self.sourceid = {}
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", IDP_EXAMPLE) 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 create_metadata_string(configfile, config, valid, cert, keyfile, id, name, sign): valid_for = 0 nspair = {"xs": "http://www.w3.org/2001/XMLSchema"} #paths = [".", "/opt/local/bin"] if valid: valid_for = int(valid) # Hours eds = [] if config is not None: eds.append(entity_descriptor(config)) else: if configfile.endswith(".py"): configfile = configfile[:-3] config = Config().load_file(configfile, metadata_construction=True) eds.append(entity_descriptor(config)) conf = Config() conf.key_file = keyfile conf.cert_file = cert conf.debug = 1 conf.xmlsec_binary = config.xmlsec_binary secc = security_context(conf) if id: desc = entities_descriptor(eds, valid_for, name, id, sign, secc) valid_instance(desc) return metadata_tostring_fix(desc, nspair) else: for eid in eds: if sign: desc = sign_entity_descriptor(eid, id, secc) else: desc = eid valid_instance(desc) return metadata_tostring_fix(desc, nspair)
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
bas, fil = os.path.split(filespec) if bas != "": sys.path.insert(0, bas) if fil.endswith(".py"): fil = fil[:-3] cnf = Config().load_file(fil, metadata_construction=True) if valid_for: cnf.valid_for = valid_for eds.append(entity_descriptor(cnf)) conf = Config() conf.key_file = args.keyfile conf.cert_file = args.cert conf.debug = 1 conf.xmlsec_binary = args.xmlsec secc = security_context(conf) if args.id: desc, xmldoc = entities_descriptor(eds, valid_for, args.name, args.id, args.sign, secc) valid_instance(desc) xmldoc = metadata_tostring_fix(desc, nspair, xmldoc) print(xmldoc.decode("utf-8")) else: for eid in eds: if args.sign: assert conf.key_file assert conf.cert_file eid, xmldoc = sign_entity_descriptor(eid, args.id, secc) else: xmldoc = None