示例#1
0
    def _func(self, conv=None):
        ava = conv.events.get_message(EV_PROTOCOL_RESPONSE, AuthnResponse).ava

        conf = conv.entity.config
        entcat = conv.extra_args["entcat"]

        req_attr = conf.getattr('required_attributes', 'sp')

        ec_attr = []
        for ec in conf.entity_category:
            ec_attr.extend(entcat[ec])

        # I would expect IdPs to release attributes that I'm allowed
        # to receive according to the ent cat classification and
        # I require them
        missing = []
        if req_attr:
            for attr in req_attr:
                if attr in ec_attr and attr not in ava:
                    missing.append(attr)

        res = TestResult(self.cid)
        if missing:
            res.message = "Attributes I expected but not received: {}".format(
                missing)
            res.status = CRITICAL

        return res
示例#2
0
    def _func(self, conv=None, output=None):
        response = conv.events.get_message(EV_PROTOCOL_RESPONSE,
                                           AuthnResponse).response
        # Assumes only one assertion
        # TODO deal with more then one assertion if necessary
        subj = response.assertion[0].subject
        request = conv.events.get_message(EV_PROTOCOL_REQUEST, AuthnRequest)

        # Nameid format
        nformat = sp_name_qualifier = ''
        if "name_id.format" in self._kwargs:
            nformat = self._kwargs["name_id.format"]
        else:
            if request.name_id_policy:
                nformat = request.name_id_policy.format
                sp_name_qualifier = request.name_id_policy.sp_name_qualifier

        if request.name_id_policy:
            sp_name_qualifier = request.name_id_policy.sp_name_qualifier

        res = TestResult(self.cid)
        if nformat:
            if subj.name_id.format == nformat:
                if sp_name_qualifier:
                    if subj.name_id.sp_name_qualifier != sp_name_qualifier:
                        res.message = "The IdP returns wrong NameID format"
                        res.status = CRITICAL
            else:
                res.message = "The IdP returns wrong NameID format"
                res.status = CRITICAL

        return res
示例#3
0
    def _func(self, conv):
        html = conv.events.last_item(EV_HTML_SRC)
        pattern = conv.extra_args['target_info']['echopageContentPattern']

        res = TestResult(self.cid)
        for pat in pattern:
            if not re.search(pat, html):
                res.message = "Could not find '{}' on page".format(pat)
                res.status = CRITICAL

        return res
示例#4
0
    def _func(self, conv):
        signing_algorithms = conv.crypto_algorithms['signing_algorithms']
        req = conv.events.get_message(EV_PROTOCOL_REQUEST, request.AuthnRequest)
        res = TestResult(self.cid)
        if req.message.signature is None:
            res.message = 'Missing response signature'
            res.status = CRITICAL

        sig_alg = req.message.signature.signed_info.signature_method.algorithm
        if sig_alg not in signing_algorithms:
            res.message = "Not allowed digest algorithm: {}".format(sig_alg)
            res.status = CRITICAL

        return res
示例#5
0
    def _func(self, conv):
        digest_algorithms = conv.crypto_algorithms['digest_algorithms']
        req = conv.events.get_message(EV_PROTOCOL_REQUEST, request.AuthnRequest)
        res = TestResult(self.cid)
        if req.message.signature is None:
            res.message = 'Missing response signature'
            res.status = CRITICAL

        for ref in req.message.signature.signed_info.reference:
            if ref.digest_method.algorithm not in digest_algorithms:
                res.message = "Not allowed digest algorithm: {}".format(
                    ref.digest_method.algorithm)
                res.status = CRITICAL
                break

        return res
示例#6
0
    def _binding_support(self, conv, request, binding, typ):
        service = REQ2SRV[request]
        md = conv.entity.metadata
        entity_id = conv.entity_id
        func = getattr(md, service, None)
        res = TestResult(self.cid)
        try:
            func(entity_id, binding, typ)
        except UnknownPrincipal:
            res.message = "Unknown principal: %s" % entity_id
            res.status = CRITICAL
        except UnsupportedBinding:
            res.message = "Unsupported binding at the IdP: %s" % binding
            res.status = CRITICAL

        return res
示例#7
0
    def _func(self, conv):
        entity_id = conv.events.last_item('issuer')
        md = conv.entity.metadata
        res = TestResult(self.cid)
        try:
            srv = md.service(entity_id, self._kwargs['typ'],
                             self._kwargs['service'],
                             binding=self._kwargs['binding'])
        except KeyError:
            res.message = "Can't find service"
            res.status = CRITICAL
        else:
            if not srv:
                res.message = "Can't find service"
                res.status = CRITICAL

        return res
示例#8
0
    def _func(self, conv):
        # Check that the logout response says it was a success
        resp = conv.events.last_item(EV_PROTOCOL_RESPONSE)
        status = resp.response.status
        res = TestResult(self.cid)
        if status.status_code.value != STATUS_SUCCESS:
            res.message = self.msg
            res.status = CRITICAL
        else:
            # Check that there are no valid cookies
            # should only result in a warning

            if conv.entity.cookies(conv.destination):
                res.message = "Remaining cookie ?"
                res.status = WARNING

        return res
示例#9
0
    def _func(self, conv):
        req = conv.events.last_item(EV_RESPONSE)
        res = TestResult(self.cid)
        # First, was the whole message signed
        if 'SigAlg' in req:
            if not verify_redirect_signature(
                    req['SAMLRequest'], conv.entity.sec):
                res.message = "Was not able to verify Redirect message " \
                                "signature"
                res.status = CRITICAL

        # Secondly, was the XML doc signed
        req = conv.events.get_message(EV_PROTOCOL_REQUEST, request.AuthnRequest)
        if req.message.signature is None:
            res.message = 'Missing response signature'
            res.status = CRITICAL

        return res
示例#10
0
    def _func(self, conv):
        redirect = conv.events.last_item(EV_REDIRECT_URL)
        res = TestResult(self.cid)
        if '?' not in redirect:
            res.message = "Incorrect redirect url"
            res.status = CRITICAL
            return res

        req = dict(
            [(k, v[0]) for k, v in parse_qs(redirect.split('?')[1]).items()])

        try:
            saml_req = req["SAMLRequest"]
        except KeyError:
            res.message = "No SAMLRequest query parameter"
            res.status = CRITICAL
            return res

        _srv = conv.entity
        if not _srv.parse_authn_request(saml_req):
            res.message = "No or incorrect AuthnRequest"
            res.status = CRITICAL

        return res
示例#11
0
    def __call__(self):
        mdict = self.conv.entity.metadata.metadata
        # Should only be one of each
        md = list(mdict.values())[0]
        ed = list(md.entity.values())[0]
        res = TestResult('CheckSaml2IntMetaData')

        assert len(ed["idpsso_descriptor"])
        idpsso = ed["idpsso_descriptor"][0]

        # contact person
        if "contact_person" not in idpsso and "contact_person" not in ed:
            res.message = "Metadata should contain contact person information"
            res.status = WARNING
            return res
        else:
            item = []
            if "contact_person" in idpsso:
                for contact in idpsso["contact_person"]:
                    item.append(contact["contact_type"])
            if "contact_person" in ed:
                for contact in ed["contact_person"]:
                    item.append(contact["contact_type"])

            if "support" in item and "technical" in item:
                pass
            elif "support" not in item and "technical" not in item:
                res.message = "Missing technical and support contact information"
                res.status = WARNING
            elif "technical" not in item:
                res.message = "Missing technical contact information"
                res.status = WARNING
            elif "support" not in item:
                res.message = "Missing support contact information"
                res.status = WARNING

            if res:
                return res

        # NameID format
        if "name_id_format" not in idpsso:
            res.message = "Metadata should specify NameID format support"
            res.status = WARNING
            return res
        else:
            # should support Transient
            id_formats = []
            for nformat in idpsso["name_id_format"]:
                id_formats.append(nformat["text"])

            if NAMEID_FORMAT_TRANSIENT not in id_formats:
                res.message = "IdP should support Transient NameID Format"
                res.status = WARNING
                return res
示例#12
0
    def _func(self, conv=None, output=None):

        res = TestResult(self.cid)

        if "saml_status" in self._kwargs:
            status_value = self._kwargs["saml_status"]
        else:
            res.message = "Configuration Error: Missing saml_status in assert verify_saml_status"
            res.status = CRITICAL
            return res

        if status_value == 'urn:oasis:names:tc:SAML:2.0:status:Success':
            """
            We can't check for success because saml2 testing doesn't tell. So we assume, that if we don't see any
            status errors it should have been a success.
            """
            we_had_errors = False
            for test_exception in STATUSCODE2EXCEPTION:
                try:
                    exception = conv.events.get_message(EV_PROTOCOL_RESPONSE, test_exception)
                except Exception as e:
                    pass
                else:
                    we_had_errors = True

            if we_had_errors:
                res.message = "ERROR: {}: {}".format(exception.__class__.__name__, str(exception))
                res.status = CRITICAL
            else:
                res.message = "No errors reported, assuming {}".format(status_value)
            return res

        else:


            try:
                status_error_exception = STATUSCODE2EXCEPTION[status_value]
            except Exception as e:
                res.message = "Configuration Error: Can not find a definition for {} ".format(status_value)
                res.status = CRITICAL
                return res

            try:
                exception = conv.events.get_message(EV_PROTOCOL_RESPONSE, status_error_exception)
            except Exception as e:
                res.message = "Status error {} was not found ".format(status_value)
                res.status = CRITICAL
                return res

            res.message = "{}: {}".format(exception.__class__.__name__, str(exception))


        return res

        if "saml_status" in self._kwargs:
            status_value = self._kwargs["saml_status"]
            if response.status.status_code.value == status_value:
                res = TestResult(self.cid)
            else:
                res.message = "The test target returned status = %s, but the "
                "test configuration expected %s." % \
                (response.status.status_code.value.status_value)
                res.status = CRITICAL
        else:
                res.message = "Missing  saml_status in assert verify_saml_status"
                res.status = CRITICAL

        return res