예제 #1
0
    def _redirect(self, _response):
        rdseq = []
        url = None
        while _response.status_code in [302, 301, 303]:
            url = _response.headers["location"]
            if url in rdseq:
                raise FatalError("Loop detected in redirects")
            else:
                rdseq.append(url)
                if len(rdseq) > 8:
                    raise FatalError(
                        "Too long sequence of redirects: %s" % rdseq)

            logger.info("--> REDIRECT TO: %s" % url)
            # If back to me
            for_me = False
            try:
                self._endpoint, self._binding = self.which_endpoint(url)
                for_me = True
            except TypeError:
                pass

            if for_me:
                break
            else:
                try:
                    _response = self.instance.send(url, "GET")
                except Exception as err:
                    raise FatalError("%s" % err)

                self._log_response(_response)
                self.last_response = _response
                if _response.status_code >= 400:
                    break
        return url
예제 #2
0
파일: tool.py 프로젝트: dolph/pysaml2
 def err_check(self, test, err=None, bryt=True):
     if err:
         self.exception = err
     chk = self.check_factory(test)()
     chk(self, self.test_output)
     if bryt:
         e = FatalError("%s" % err)
         e.trace = "".join(traceback.format_exception(*sys.exc_info()))
         raise e
예제 #3
0
파일: tool.py 프로젝트: rohe/saml2test
 def err_check(self, test, err=None, bryt=True):
     if err:
         self.exception = err
     chk = self.check_factory(test)()
     chk(self, self.test_output)
     if bryt:
         e = FatalError("%s" % err)
         e.trace = "".join(traceback.format_exception(*sys.exc_info()))
         raise e
예제 #4
0
    def handle_result(self, response=None):
        #self.do_check(CheckHTTPResponse)
        if response:
            if isinstance(response(), Check):
                self.do_check(response)
            else:
                # A HTTP redirect or HTTP Post
                if 300 < self.last_response.status_code <= 303:
                    self._redirect(self.last_response)

                if self.last_response.status_code >= 400:
                    raise FatalError(self.last_response.reason)

                _txt = self.last_response.content
                assert _txt.startswith("<h2>")
        else:
            if 300 < self.last_response.status_code <= 303:
                self._redirect(self.last_response)

            _txt = self.last_response.content
            if self.last_response.status_code >= 400:
                raise FatalError("Did not expected error")
예제 #5
0
파일: tool.py 프로젝트: dolph/pysaml2
    def intermit(self):
        _response = self.last_response
        _last_action = None
        _same_actions = 0
        if _response.status_code >= 400:
            done = True
        else:
            done = False

        url = _response.url
        content = _response.text
        while not done:
            rdseq = []
            while _response.status_code in [302, 301, 303]:
                url = _response.headers["location"]
                if url in rdseq:
                    raise FatalError("Loop detected in redirects")
                else:
                    rdseq.append(url)
                    if len(rdseq) > 8:
                        raise FatalError("Too long sequence of redirects: %s" %
                                         rdseq)

                logger.info("HTTP %d Location: %s" %
                            (_response.status_code, url))
                # If back to me
                for_me = False
                for redirect_uri in self.my_endpoints():
                    if url.startswith(redirect_uri):
                        # Back at the RP
                        self.client.cookiejar = self.cjar["rp"]
                        for_me = True
                        try:
                            base, query = url.split("?")
                        except ValueError:
                            pass
                        else:
                            _response = parse_qs(query)
                            self.last_response = _response
                            self.last_content = _response
                            return _response

                if for_me:
                    done = True
                    break
                else:
                    try:
                        logger.info("GET %s" % url)
                        _response = self.client.send(url, "GET")
                    except Exception, err:
                        raise FatalError("%s" % err)

                    content = _response.text
                    logger.info("<-- CONTENT: %s" % content)
                    self.position = url
                    self.last_content = content
                    self.response = _response

                    if _response.status_code >= 400:
                        done = True
                        break

            if done or url is None:
                break

            _base = url.split("?")[0]

            try:
                _spec = self.interaction.pick_interaction(_base, content)
            except InteractionNeeded:
                self.position = url
                cnt = content.replace("\n", '').replace("\t",
                                                        '').replace("\r", '')
                logger.error("URL: %s" % url)
                logger.error("Page Content: %s" % cnt)
                raise
            except KeyError:
                self.position = url
                cnt = content.replace("\n", '').replace("\t",
                                                        '').replace("\r", '')
                logger.error("URL: %s" % url)
                logger.error("Page Content: %s" % cnt)
                self.err_check("interaction-needed")

            if _spec == _last_action:
                _same_actions += 1
                if _same_actions >= 3:
                    self.test_output.append({
                        "status": ERROR,
                        "message": "Interaction loop detection",
                        #"id": "exception",
                        #"name": "interaction needed",
                        "url": self.position
                    })
                    raise OperationError()
            else:
                _last_action = _spec

            if len(_spec) > 2:
                logger.info(">> %s <<" % _spec["page-type"])
                if _spec["page-type"] == "login":
                    self.login_page = content

            _op = Action(_spec["control"])

            try:
                _response = _op(self.client, self, url, _response, content,
                                self.features)
                if isinstance(_response, dict):
                    self.last_response = _response
                    self.last_content = _response
                    return _response
                content = _response.text
                self.position = url
                self.last_content = content
                self.response = _response

                if _response.status_code >= 400:
                    txt = "Got status code '%s', error: %s" % (
                        _response.status_code, content)
                    logger.error(txt)
                    self.test_output.append({
                        "status": ERROR,
                        "message": txt,
                        #"id": "exception",
                        #"name": "interaction needed",
                        "url": self.position
                    })
                    raise OperationError()
            except (FatalError, InteractionNeeded, OperationError):
                raise
            except Exception, err:
                self.err_check("exception", err, False)
예제 #6
0
    def intermit(self, page_types):
        """
        Currently handles only SP-issued redirects

        :param page_types: not used (could be used to implement wayf, disco)
        """
        _response = self.last_response
        _last_action = None
        _same_actions = 0
        if _response.status_code >= 400:
            try:
                self.last_content = _response.text
            except AttributeError:
                self.last_content = None
            raise FatalError(
                "HTTP response status code: %d" % _response.status_code)

        url = _response.url
        content = _response.text
        done = False
        while not done:
            rdseq = []
            while _response.status_code in [302, 301, 303]:
                url = _response.headers["location"]
                if url in rdseq:
                    raise FatalError("Loop detected in redirects")
                else:
                    rdseq.append(url)
                    if len(rdseq) > 8:
                        raise FatalError(
                            "Too long sequence of redirects: %s" % rdseq)

                # If back to me
                for_me = False
                try:
                    self._endpoint, self._binding = self.which_endpoint(url)
                    for_me = True
                except TypeError:
                    pass

                if for_me:
                    done = True
                    break
                else:
                    try:
                        _response = self.instance.send(url, "GET")
                    except Exception as err:
                        raise FatalError("%s" % err)

                    self._log_response(_response)
                    content = _response.text
                    self.position = url
                    self.last_content = content
                    self.response = _response

                    if _response.status_code >= 400:
                        done = True
                        break

            if done or url is None:
                break

            _base = url.split("?")[0]

            try:
                _spec = self.interaction.pick_interaction(_base, content)
            except InteractionNeeded:
                self.position = url
                logger.error("Page Content: %s" % content)
                raise
            except KeyError:
                self.position = url
                logger.error("Page Content: %s" % content)
                self.err_check("interaction-needed")

            if _spec == _last_action:
                _same_actions += 1
                if _same_actions >= 3:
                    raise InteractionNeeded("Interaction loop detection")
            else:
                _last_action = _spec

            if len(_spec) > 2:
                logger.info(">> %s <<" % _spec["page-type"])
                if _spec["page-type"] == "login":
                    self.login_page = content

            _op = Action(_spec["control"])

            try:
                _response = _op(self.instance, self, logger, url,
                                _response, content, self.features)
                if isinstance(_response, dict):
                    self.last_response = _response
                    self.last_content = _response
                    return _response
                content = _response.text
                self.position = url
                self.last_content = content
                self.response = _response

                if _response.status_code >= 400:
                    break
            except (FatalError, InteractionNeeded):
                raise
            except Exception as err:
                self.err_check("exception", err, False)

        self.last_response = _response
        try:
            self.last_content = _response.text
        except AttributeError:
            self.last_content = None