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 test_entity_attributes(self): fil = "sp_mdext_conf.py" cnf = Config().load_file(fil, metadata_construction=True) ed = entity_descriptor(cnf) entity_attributes = next( e for e in ed.extensions.extension_elements if e.tag == 'EntityAttributes' ) attributes = [ parse_str_as(Attribute, e.to_string()) for e in entity_attributes.children ] assert all( a.name in [ "urn:oasis:names:tc:SAML:profiles:subject-id:req", "somename", ] for a in attributes ) import saml2.attribute_converter attrc = saml2.attribute_converter.ac_factory() import saml2.mdstore mds = saml2.mdstore.MetadataStore(attrc, cnf) mds.load("inline", ed.to_string()) entityid = ed.entity_id entity_attributes = mds.entity_attributes(entityid) assert entity_attributes == { 'urn:oasis:names:tc:SAML:profiles:subject-id:req': ['any'], 'somename': ['x', 'y', 'z'], }
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, user, passwd, sp="", idp=None, metadata_file=None, xmlsec_binary=None, verbose=0, ca_certs="", disable_ssl_certificate_validation=True, key_file=None, cert_file=None, config=None): """ :param user: user name :param passwd: user password :param sp: The SP URL :param idp: The IdP PAOS endpoint :param metadata_file: Where the metadata file is if used :param xmlsec_binary: Where the xmlsec1 binary can be found (*) :param verbose: Chatty or not :param ca_certs: is the path of a file containing root CA certificates for SSL server certificate validation (*) :param disable_ssl_certificate_validation: If disable_ssl_certificate_validation is true, SSL cert validation will not be performed (*) :param key_file: Private key filename (*) :param cert_file: Certificate filename (*) :param config: Config() instance, overrides all the parameters marked with an asterisk (*) above """ if not config: config = Config() config.disable_ssl_certificate_validation = \ disable_ssl_certificate_validation config.key_file = key_file config.cert_file = cert_file config.ca_certs = ca_certs config.xmlsec_binary = xmlsec_binary Entity.__init__(self, "sp", config) self._idp = idp self._sp = sp self.user = user self.passwd = passwd self._verbose = verbose if metadata_file: self._metadata = MetadataStore([saml, samlp], None, config) self._metadata.load("local", metadata_file) logger.debug("Loaded metadata from '%s'" % metadata_file) else: self._metadata = None self.metadata = self._metadata self.cookie_handler = None self.done_ecp = False self.cookie_jar = cookielib.LWPCookieJar()
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 get_saml_client(domain): """Get SAML2 client.""" acs_url = domain + reverse('djangosaml2:acs') saml_settings = { 'metadata': { 'remote': [{ 'url': settings.SAML2_AUTH['METADATA_AUTO_CONF_URL'] }] }, 'service': { 'sp': { 'endpoints': { 'assertion_consumer_service': [ (acs_url, BINDING_HTTP_REDIRECT), (acs_url, BINDING_HTTP_POST) ], }, 'allow_unsolicited': True, 'authn_requests_signed': True, 'logout_requests_signed': True, 'want_assertions_signed': True, 'want_response_signed': True, }, }, } sp_config = Config() sp_config.load(saml_settings) sp_config.allow_unknown_attributes = True saml_client = Saml2Client(config=sp_config) return saml_client
def test_sp_type_false(self): fil = "sp_mdext_conf.py" cnf = Config().load_file(fil, metadata_construction=True) cnf.setattr('sp', 'sp_type_in_metadata', False) ed = entity_descriptor(cnf) assert all(e.tag is not SPType.c_tag for e in ed.extensions.extension_elements)
def test_dual(): cnf = Config().load_file(dotname("idp_sp_conf")) spe = cnf.getattr("endpoints", "sp") idpe = cnf.getattr("endpoints", "idp") assert spe assert idpe assert spe != idpe
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 _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 test_sp_type_true(self): fil = "sp_mdext_conf.py" cnf = Config().load_file(fil, metadata_construction=True) ed = entity_descriptor(cnf) assert ed.spsso_descriptor.extensions assert len(ed.spsso_descriptor.extensions.extension_elements) == 3 assert ed.extensions assert len(ed.extensions.extension_elements) > 1 assert any(e.tag is SPType.c_tag for e in ed.extensions.extension_elements)
def test_dual(): cnf = Config().load_file("idp_sp_conf") assert cnf.serves() == ["sp", "idp"] spcnf = cnf.copy_into("sp") assert isinstance(spcnf, SPConfig) assert spcnf.context == "sp" idpcnf = cnf.copy_into("idp") assert isinstance(idpcnf, IdPConfig) assert idpcnf.context == "idp"
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 dispatch(self, request, helper): if self.metadata_url is None: metadata_url = helper.fetch_state('metadata_url') else: metadata_url = self.metadata_url request_id = helper.fetch_state('request_id') settings = { 'entityid': request.build_absolute_uri('/organizations/%s/' % helper.organization.slug), 'metadata': { 'remote': [{ 'url': metadata_url, }], }, 'service': { 'sp': { 'endpoints': { 'assertion_consumer_service': [(request.build_absolute_uri( reverse('sentry-auth-sso')), BINDING_HTTP_POST)], }, 'allow_unsolicited': False, 'authn_requests_signed': False, 'logout_requests_signed': True, 'want_assertions_signed': False, 'want_response_signed': True, }, }, } config = Config() config.load(settings) client = Saml2Client(config) response = client.parse_authn_request_response( request.POST['SAMLResponse'], BINDING_HTTP_POST, outstanding={request_id: True}) extra = { key.lower(): value for key, value in response.get_identity().items() } user_info = response.get_subject() email = user_info.text username, domain = email.rsplit('@', 1) if not email: return helper.error('no email') helper.bind_state('email', email) helper.bind_state('name', extra.get('name', username)) return helper.next_step()
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 dispatch(self, request, helper): if self.metadata_url is None: metadata_url = helper.fetch_state('metadata_url') else: metadata_url = self.metadata_url org = self.get_active_organization(request) settings = { 'entityid': request.build_absolute_uri('/organizations/%s/' % org.slug), 'metadata': { 'remote': [{ 'url': metadata_url, }], }, 'service': { 'sp': { 'endpoints': { 'assertion_consumer_service': [(request.build_absolute_uri( reverse('sentry-auth-sso')), BINDING_HTTP_POST)], }, 'allow_unsolicited': False, 'authn_requests_signed': False, 'logout_requests_signed': True, 'want_assertions_signed': False, 'want_response_signed': True, }, }, } config = Config() config.load(settings) client = Saml2Client(config) request_id, headers = client.prepare_for_authenticate() helper.bind_state('request_id', request_id) for key, value in headers['headers']: if key is 'Location': # helper.incr_step() helper.request.session['auth']['idx'] += 1 helper.request.session.modified = True return self.redirect(value)
valid_for = 0 nspair = {"xs": "http://www.w3.org/2001/XMLSchema"} paths = [".", "/opt/local/bin"] if args.valid: # translate into hours valid_for = int(args.valid) * 24 eds = [] for filespec in args.config: 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)
def _get_security_context(key, cert): conf = Config() conf.key_file = key conf.cert_file = cert return security_context(conf)
def _create_entity_descriptor(entity_config): cnf = Config().load(copy.deepcopy(entity_config), metadata_construction=True) return entity_descriptor(cnf)
def create_metadata_from_config_dict(config): nspair = {"xs": "http://www.w3.org/2001/XMLSchema"} conf = Config().load(config, metadata_construction=True) return entity_descriptor(conf).to_string(nspair).decode("utf-8")
valid_for = 0 nspair = {"xs": "http://www.w3.org/2001/XMLSchema"} paths = [".", "/opt/local/bin"] if args.valid: # translate into hours valid_for = int(args.valid) * 24 eds = [] for filespec in args.config: 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) 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)
def verification_security_context(self, cert_and_key): conf = Config() conf.cert_file = cert_and_key[0] return security_context(conf)
def signature_security_context(self, cert_and_key): conf = Config() conf.cert_file = cert_and_key[0] conf.key_file = cert_and_key[1] return security_context(conf)
def _create_entity_descriptor(entity_config): cnf = Config().load(copy.deepcopy(entity_config)) return entity_descriptor(cnf)