Beispiel #1
0
def op_info(environ, start_response, session_info, events, jlog, **kwargs):
    _ev = Operation("ProviderConfiguration", path=environ["PATH_INFO"])
    try:
        _ev.query = environ["QUERY_STRING"]
    except KeyError:
        pass
    events.store(EV_REQUEST, _ev)
    _op = session_info["op"]
    logger.info('OP keys:{}'.format(key_summary(_op.keyjar, '')))
    return wsgi_wrapper(environ, start_response, _op.providerinfo_endpoint,
                        session_info, events, jlog)
Beispiel #2
0
def op_info(environ, start_response, session_info, events, jlog, **kwargs):
    _ev = Operation("ProviderConfiguration", path=environ["PATH_INFO"])
    try:
        _ev.query = environ["QUERY_STRING"]
    except KeyError:
        pass
    events.store(EV_REQUEST, _ev)
    _op = session_info["op"]
    logger.info('OP keys:{}'.format(key_summary(_op.keyjar, '')))
    return wsgi_wrapper(environ, start_response, _op.providerinfo_endpoint,
                        session_info, events, jlog)
Beispiel #3
0
    def index(self, resource, rel):
        ev = init_events('/.well-known/webfinger',
                         'Test tool version:{}'.format(self.version))
        ev.store(EV_REQUEST, Operation('WebFinger', resource=resource,
                                       rel=rel))

        if rel != 'http://openid.net/specs/connect/1.0/issuer':
            ev.store(
                EV_FAULT,
                FailedOperation('Webfinger', error='unknown rel', rel=rel))
            try:
                op_id, test_id = parse_resource(resource)
            except (ValueError, TypeError):
                logger.error('webfinger resource specification faulty')
                raise cherrypy.HTTPError(
                    400, 'webfinger resource specification faulty')
            else:
                write_events(ev, op_id, test_id)
            raise cherrypy.NotFound()

        try:
            op_id, test_id = parse_resource(resource)
        except (ValueError, TypeError):
            logger.error('webfinger resource specification faulty')
            raise cherrypy.HTTPError(
                400, 'webfinger resource specification faulty')
        else:
            _path = '/'.join([op_id, test_id])

        cnf = cherrypy.request.config
        subj = resource
        _base = cnf['base_url']
        dummy = None

        # introducing an error
        if 'rp-discovery-webfinger-http-href' in resource:
            _base = _base.replace('https', 'http')
        if 'rp-discovery-webfinger-unknown-member' in resource:
            dummy = "foobar"

        if _base.endswith('/'):
            href = '{}{}'.format(_base, _path)
        else:
            href = '{}/{}'.format(_base, _path)

        ev.store(EV_RESPONSE,
                 Operation('Webfinger', href=href, subj=resource, dummy=dummy))
        write_events(ev, op_id, test_id)
        resp = self.srv.response(subj, href, dummy=dummy)
        cherrypy.response.headers['Content-Type'] = 'application/jrd+json'
        return as_bytes(resp)
Beispiel #4
0
def store_request(op, where):
    _ev = Operation(where, path=url())

    try:
        op.events.store(EV_REQUEST, _ev)
    except Exception as err:
        raise
Beispiel #5
0
def authorization(environ, start_response, session_info, events, jlog,
                  **kwargs):
    events.store(EV_REQUEST, Operation("Authorization"))
    _op = session_info["op"]
    logger.info('OP keys:{}'.format(key_summary(_op.keyjar, '')))
    return wsgi_wrapper(environ, start_response, _op.authorization_endpoint,
                        session_info, events, jlog)
Beispiel #6
0
def registration(environ, start_response, session_info, events, jlog,
                 **kwargs):
    events.store(EV_REQUEST, Operation("ClientRegistration"))
    _op = session_info["op"]

    if environ["REQUEST_METHOD"] == "POST":
        return wsgi_wrapper(environ, start_response, _op.registration_endpoint,
                            session_info, events, jlog)
    elif environ["REQUEST_METHOD"] == "GET":
        return wsgi_wrapper(environ, start_response, _op.read_registration,
                            session_info, events, jlog)
    else:
        resp = ServiceError("Method not supported")
        return resp(environ, start_response)
Beispiel #7
0
def webfinger(environ, start_response, session_info, events, jlog, **kwargs):
    _query = session_info['parameters']
    events.store(EV_REQUEST, Operation("WebFinger", _query))

    try:
        assert _query["rel"] == [OIC_ISSUER]
        resource = _query["resource"][0]
    except AssertionError:
        errmsg = "Wrong 'rel' value: %s" % _query["rel"][0]
        events.store(EV_FAULT, errmsg)
        resp = BadRequest(errmsg)
    except KeyError:
        errmsg = "Missing 'rel' parameter in request"
        events.store(EV_FAULT, errmsg)
        resp = BadRequest(errmsg)
    else:
        wf = WebFinger()

        _url = os.path.join(kwargs["op_arg"]["baseurl"],
                            session_info['oper_id'], session_info["test_id"])

        _mesg = wf.response(subject=resource, base=_url)
        if session_info['test_id'] == 'rp-discovery-webfinger-http-href':
            _msg = json.loads(_mesg)
            _msg['links'][0]['href'] = _msg['links'][0]['href'].replace(
                'https', 'http')
            _mesg = json.dumps(_msg)
        elif session_info[
                'test_id'] == 'rp-discovery-webfinger-unknown-member':
            _msg = json.loads(_mesg)
            _msg['dummy'] = 'foobar'
            _mesg = json.dumps(_msg)

        resp = Response(_mesg, content="application/jrd+json")

        events.store(EV_RESPONSE, resp.message)

    jlog.info(resp2json(resp))

    dump_log(session_info, events)
    return resp(environ, start_response)
Beispiel #8
0
    def application(self, environ, start_response):
        """
        :param environ: The HTTP application environment
        :param start_response: The application to run when the handling of the
            request is done
        :return: The response as a list of lines
        """

        path = environ.get('PATH_INFO', '').lstrip('/')
        response_encoder = ResponseEncoder(environ=environ,
                                           start_response=start_response)
        parameters = parse_qs(environ["QUERY_STRING"])

        session_info = {
            "addr": get_client_address(environ),
            'cookie': environ.get("HTTP_COOKIE", ''),
            'path': path,
            'parameters': parameters
        }

        jlog = JLog(LOGGER, session_info['addr'])
        jlog.info(session_info)

        if path == "robots.txt":
            return static(environ, start_response, "static/robots.txt")

        if path.startswith("static/"):
            return static(environ, start_response, path)
        elif path.startswith("tar/"):
            return static(environ, start_response, path)
        elif path.startswith("log"):
            return display_log(path, environ, start_response, lookup=LOOKUP)
        elif path.startswith('clear/'):
            return clear_log(path, environ, start_response, lookup=LOOKUP)
        elif path.startswith('mktar/'):
            return make_tar(path, environ, start_response, lookup=LOOKUP)
        elif path.startswith("_static/"):
            return static(environ, start_response, path)
        elif path.startswith("jwks.json"):
            try:
                mode, endpoint = extract_mode(self.op_args["baseurl"])
                events = Events()
                events.store('Init',
                             '===========================================')
                op, path, jlog.id = self.op_setup(environ, mode, events,
                                                  self.test_conf, endpoint)
                jwks = op.generate_jwks(mode)
                resp = Response(jwks,
                                headers=[('Content-Type', 'application/json')])
                return resp(environ, start_response)
            except KeyError:
                # Try to load from static file
                return static(environ, start_response, "static/jwks.json")

        events = Events()
        events.store('Init', '===========================================')

        if path == "test_list":
            return rp_test_list(environ, start_response)
        elif path == "":
            return registration(environ, start_response)
        elif path == "generate_client_credentials":
            client_id, client_secret = generate_static_client_credentials(
                parameters)
            return response_encoder.return_json(
                json.dumps({"client_id": client_id,
                            "client_secret": client_secret}))
        elif path == "3rd_party_init_login":
            return rp_support_3rd_party_init_login(environ, start_response)

        # path should be <oper_id>/<test_id>/<endpoint>
        try:
            mode = parse_path(path)
        except ValueError:
            resp = BadRequest('Illegal path')
            return resp(environ, start_response)

        try:
            endpoint = mode['endpoint']
        except KeyError:
            _info = {'error': 'No endpoint', 'mode': mode}
            events.store(EV_FAULT, _info)
            jlog.error(_info)
            resp = BadRequest('Illegal path')
            return resp(environ, start_response)

        if endpoint == ".well-known/webfinger":
            session_info['endpoint'] = endpoint
            try:
                _p = urlparse(parameters["resource"][0])
            except KeyError:
                events.store(EV_FAULT,
                             FailedOperation('webfinger',
                                             'No resource defined'))
                jlog.error({'reason': 'No resource defined'})
                resp = ServiceError("No resource defined")
                return resp(environ, start_response)

            if _p.scheme in ["http", "https"]:
                events.store(EV_REQUEST,
                             Operation(name='webfinger', type='url',
                                       path=_p.path))
                mode = parse_path(_p.path)
            elif _p.scheme == "acct":
                _l, _ = _p.path.split('@')

                _a = _l.split('.')
                if len(_a) == 2:
                    _oper_id = _a[0]
                    _test_id = _a[1]
                elif len(_a) > 2:
                    _oper_id = ".".join(_a[:-1])
                    _test_id = _a[-1]
                else:
                    _oper_id = _a[0]
                    _test_id = 'default'

                mode.update({'oper_id': _oper_id, 'test_id': _test_id})
                events.store(EV_REQUEST,
                             Operation(name='webfinger', type='acct',
                                       oper_id=_oper_id, test_id=_test_id))
            else:
                _msg = "Unknown scheme: {}".format(_p.scheme)
                events.events(EV_FAULT, FailedOperation('webfinger', _msg))
                jlog.error({'reason': _msg})
                resp = ServiceError(_msg)
                return resp(environ, start_response)
        elif endpoint == "claim":
            authz = environ["HTTP_AUTHORIZATION"]
            _ev = Operation('claim')
            try:
                assert authz.startswith("Bearer")
            except AssertionError:
                resp = BadRequest()
            else:
                _ev.authz = authz
                events.store(EV_REQUEST, _ev)
                tok = authz[7:]
                # mode, endpoint = extract_mode(self.op_args["baseurl"])
                _op, _, sid = self.op_setup(environ, mode, events,
                                            self.test_conf, endpoint)
                try:
                    _claims = _op.claim_access_token[tok]
                except KeyError:
                    resp = BadRequest()
                else:
                    del _op.claim_access_token[tok]
                    _info = Message(**_claims)
                    jwt_key = _op.keyjar.get_signing_key()
                    resp = Response(_info.to_jwt(key=jwt_key,
                                                 algorithm="RS256"),
                                    content='application/jwt')
            return resp(environ, start_response)

        if mode:
            session_info.update(mode)
            jlog.id = mode['oper_id']

        try:
            _op, path, jlog.id = self.op_setup(environ, mode, events,
                                               self.test_conf,
                                               endpoint)
        except UnknownTestID as err:
            resp = BadRequest('Unknown test ID: {}'.format(err.args[0]))
            return resp(environ, start_response)

        session_info["op"] = _op
        session_info["path"] = path
        session_info['test_conf'] = self.test_conf[session_info['test_id']]

        for regex, callback in URLS:
            match = re.search(regex, endpoint)
            if match is not None:
                _op = HTTPRequest(endpoint=endpoint,
                                  method=environ["REQUEST_METHOD"])
                try:
                    _op.authz = environ["HTTP_AUTHORIZATION"]
                except KeyError:
                    pass
                events.store(EV_HTTP_REQUEST, _op)
                try:
                    environ['oic.url_args'] = match.groups()[0]
                except IndexError:
                    environ['oic.url_args'] = endpoint

                jlog.info({'callback': callback.__name__})
                try:
                    return callback(environ, start_response, session_info,
                                    events, op_arg=self.op_args, jlog=jlog)
                except Exception as err:
                    print("%s" % err)
                    message = traceback.format_exception(*sys.exc_info())
                    print(message)
                    events.store(EV_EXCEPTION, err)
                    LOGGER.exception("%s" % err)
                    resp = ServiceError("%s" % err)
                    return resp(environ, start_response)

        LOGGER.debug("unknown page: '{}'".format(endpoint))
        events.store(EV_FAULT, 'No such page: {}'.format(endpoint))
        resp = NotFound("Couldn't find the side you asked for!")
        return resp(environ, start_response)