def testValidateXML(self): """ Tests the validate_xml method of the OneLogin_Saml2_XML """ metadata_unloaded = '<xml><EntityDescriptor>' res = OneLogin_Saml2_XML.validate_xml(metadata_unloaded, 'saml-schema-metadata-2.0.xsd') self.assertIsInstance(res, str) self.assertIn('unloaded_xml', res) metadata_invalid = self.file_contents( join(self.data_path, 'metadata', 'noentity_metadata_settings1.xml')) res = OneLogin_Saml2_XML.validate_xml(metadata_invalid, 'saml-schema-metadata-2.0.xsd') self.assertIsInstance(res, str) self.assertIn('invalid_xml', res) metadata_expired = self.file_contents( join(self.data_path, 'metadata', 'expired_metadata_settings1.xml')) res = OneLogin_Saml2_XML.validate_xml(metadata_expired, 'saml-schema-metadata-2.0.xsd') self.assertIsInstance(res, OneLogin_Saml2_XML._element_class) metadata_ok = self.file_contents( join(self.data_path, 'metadata', 'metadata_settings1.xml')) res = OneLogin_Saml2_XML.validate_xml(metadata_ok, 'saml-schema-metadata-2.0.xsd') self.assertIsInstance(res, OneLogin_Saml2_XML._element_class)
def test_start_authentication(self, _, service_provider, identity_providers): configuration = create_autospec(spec=SAMLConfiguration) configuration.service_provider_debug_mode = MagicMock( return_value=False) configuration.service_provider_strict_mode = MagicMock( return_value=False) configuration.get_service_provider = MagicMock( return_value=service_provider) configuration.get_identity_providers = MagicMock( return_value=identity_providers) onelogin_configuration = SAMLOneLoginConfiguration(configuration) subject_parser = SAMLSubjectParser() parser = DSLParser() visitor = DSLEvaluationVisitor() evaluator = DSLEvaluator(parser, visitor) subject_filter = SAMLSubjectFilter(evaluator) authentication_manager = SAMLAuthenticationManager( onelogin_configuration, subject_parser, subject_filter) with self.app.test_request_context("/"): result = authentication_manager.start_authentication( self._db, fixtures.IDP_1_ENTITY_ID, "") query_items = parse_qs(urlsplit(result).query) saml_request = query_items["SAMLRequest"][0] decoded_saml_request = OneLogin_Saml2_Utils.decode_base64_and_inflate( saml_request) validation_result = OneLogin_Saml2_XML.validate_xml( decoded_saml_request, "saml-schema-protocol-2.0.xsd", False) assert isinstance(validation_result, OneLogin_Saml2_XML._element_class) saml_request_dom = fromstring(decoded_saml_request) acs_url = saml_request_dom.get("AssertionConsumerServiceURL") assert acs_url == SERVICE_PROVIDER_WITH_UNSIGNED_REQUESTS.acs_service.url acs_binding = saml_request_dom.get("ProtocolBinding") assert (acs_binding == SERVICE_PROVIDER_WITH_UNSIGNED_REQUESTS. acs_service.binding.value) sso_url = saml_request_dom.get("Destination") assert sso_url == IDENTITY_PROVIDERS[0].sso_service.url name_id_policy_nodes = OneLogin_Saml2_XML.query( saml_request_dom, "./samlp:NameIDPolicy") assert name_id_policy_nodes is not None assert len(name_id_policy_nodes) == 1 name_id_policy_node = name_id_policy_nodes[0] name_id_format = name_id_policy_node.get("Format") assert (name_id_format == SERVICE_PROVIDER_WITH_UNSIGNED_REQUESTS.name_id_format)
def testValidateXML(self): """ Tests the validate_xml method of the OneLogin_Saml2_XML """ metadata_unloaded = '<xml><EntityDescriptor>' res = OneLogin_Saml2_XML.validate_xml(metadata_unloaded, 'saml-schema-metadata-2.0.xsd') self.assertIsInstance(res, str) self.assertIn('unloaded_xml', res) metadata_invalid = self.file_contents(join(self.data_path, 'metadata', 'noentity_metadata_settings1.xml')) res = OneLogin_Saml2_XML.validate_xml(metadata_invalid, 'saml-schema-metadata-2.0.xsd') self.assertIsInstance(res, str) self.assertIn('invalid_xml', res) metadata_expired = self.file_contents(join(self.data_path, 'metadata', 'expired_metadata_settings1.xml')) res = OneLogin_Saml2_XML.validate_xml(metadata_expired, 'saml-schema-metadata-2.0.xsd') self.assertIsInstance(res, OneLogin_Saml2_XML._element_class) metadata_ok = self.file_contents(join(self.data_path, 'metadata', 'metadata_settings1.xml')) res = OneLogin_Saml2_XML.validate_xml(metadata_ok, 'saml-schema-metadata-2.0.xsd') self.assertIsInstance(res, OneLogin_Saml2_XML._element_class)
def validateAssertion(xml, fingerprint=None, fingerprintalg=None): result = { 'schemaValidate': False, 'signCheck': False, 'certValidity': False, 'certAllowed': True, 'error': 0, 'msg': '', 'assertionName': None, 'chkTime': None, 'chkStatus': None, 'serviceAttributes': None } assert isinstance(xml, compat.text_types) if len(xml) == 0: result['error'] = 1 result['msg'] = 'Empty string supplied as input' return result OneLoginResponse = OneLogin_Saml2_Response({}, Saml2_Utils.b64encode(xml)) xml = xmlRemoveDeclaration(xml) parsedassertion = etree.fromstring(xml) # assertion name path assertionNameXpath = "local-name(/*)" assertionName = parsedassertion.xpath(assertionNameXpath) assertionName = str(assertionName) # find assertion schema if assertionName == 'EntityDescriptor': asscertionShema = 'saml-schema-metadata-2.0.xsd' elif assertionName == 'Response': asscertionShema = 'saml-schema-protocol-2.0.xsd' elif assertionName == 'AuthnRequest': asscertionShema = 'saml-schema-protocol-2.0.xsd' else: result['error'] = 2 result['msg'] = 'Assertion unknown' return result # siganture node path signatureNodeXpath = ".//*[local-name()='Signature']" if assertionName == 'Response': signatureNodeXpath = "*[local-name(/*)='Response']//*[local-name()='Signature']" result['assertionName'] = assertionName # get certificate signing try: signingcert = easyspid.lib.easyspid.get_signature_cert(xml) except Exception as error: signingcert = False # validate xml against its schema schemaCheck = OneLogin_Saml2_XML.validate_xml(xml, asscertionShema, False) if isinstance(schemaCheck, str): result['msg'] = schemaCheck result['schemaValidate'] = False result['error'] = 3 else: result['schemaValidate'] = True # check signature if signingcert: signingfingerprintalg = 'sha1' if fingerprintalg is not None: signingfingerprintalg = fingerprintalg signingfingerprint = (easyspid.lib.easyspid.calcCertFingerprint( signingcert, signingfingerprintalg))['result'] if assertionName == 'EntityDescriptor' and fingerprint is None: allowedCert = easyspid.lib.easyspid.get_metadata_allowed_cert(xml) allowedfingerprint = (easyspid.lib.easyspid.calcCertFingerprint( allowedCert, signingfingerprintalg))['result'] elif assertionName != 'EntityDescriptor' and fingerprint is None: allowedfingerprint = signingfingerprint if fingerprint is not None: allowedfingerprint = fingerprint signCheck = Saml2_Utils.validate_sign( xml, cert=signingcert, fingerprint=signingfingerprint, fingerprintalg=signingfingerprintalg, validatecert=False, debug=False, xpath=signatureNodeXpath, multicerts=None) if signCheck: result['signCheck'] = True else: result['error'] = 3 # check expired certificate certTimeValdity = easyspid.lib.easyspid.timeValidateCert(signingcert) if certTimeValdity: result['certValidity'] = True # checktime certificate allow if allowedfingerprint != signingfingerprint: result['certAllowed'] = False result['error'] = 3 elif not signingcert and assertionName == 'AuthnRequest': result['signCheck'] = None result['certValidity'] = None result['certAllowed'] = None if assertionName == 'Response': try: OneLoginResponse.validate_timestamps(raise_exceptions=True) result['chkTime'] = True except OneLogin_Saml2_ValidationError as error: result['chkTime'] = False result['error'] = 3 try: OneLoginResponse.check_status() result['chkStatus'] = True except OneLogin_Saml2_ValidationError as error: result['chkStatus'] = False result['error'] = 3 try: result['serviceAttributes'] = OneLoginResponse.get_attributes() except: pass return result
def validate_metadata(self, xml, fingerprint=None, fingerprintalg='sha1', validatecert=False): """ Validates an XML SP Metadata. :param xml: Metadata's XML that will be validate :type xml: string :param fingerprint: The fingerprint of the public cert :type: string :param fingerprintalg: The algorithm used to build the fingerprint :type: string :param validatecert: If true, will verify the signature and if the cert is valid. :type: bool :returns: a dictionary with the list of found validation errors and signature check :rtype: dict """ result = { 'schemaValidate': True, 'signCheck': False, 'error': 0, 'msg': '' } assert isinstance(xml, compat.text_types) if len(xml) == 0: raise Exception('Empty string supplied as input') #errors = {'validate':[], 'signCheck':0} root = OneLogin_Saml2_XML.validate_xml( xml, 'saml-schema-metadata-2.0.xsd', self._OneLogin_Saml2_Settings__debug) if isinstance(root, str): result['msg'] = root result['schemaValidate'] = False else: if root.tag != '{%s}EntityDescriptor' % OneLogin_Saml2_Constants.NS_MD: result['msg'] = 'noEntityDescriptor_xml' result['error'] = 1 result['schemaValidate'] = False #errors.append('noEntityDescriptor_xml') else: if (len( root.findall( './/md:SPSSODescriptor', namespaces=OneLogin_Saml2_Constants.NSMAP))) != 1: #errors.append('onlySPSSODescriptor_allowed_xml') result['msg'] = 'onlySPSSODescriptor_allowed_xml' result['error'] = 2 result['schemaValidate'] = False else: valid_until, cache_duration = root.get( 'validUntil'), root.get('cacheDuration') if valid_until: valid_until = Saml2_Utils.parse_SAML_to_time( valid_until) expire_time = Saml2_Utils.get_expire_time( cache_duration, valid_until) if expire_time is not None and int( time()) > int(expire_time): #errors.append('expired_xml') result['msg'] = 'expired_xml' result['error'] = 3 result['schemaValidate'] = False # Validate Sign signCheck = Saml2_Utils.validate_metadata_sign( xml, fingerprint=fingerprint, fingerprintalg=fingerprintalg, validatecert=validatecert) if signCheck: result['signCheck'] = True return result