Пример #1
0
def main():
    sys.path.insert(0, os.getcwd())

    args = WsgiApplication.arg_parser()

    pefim_server_conf = __import__(args.server_config)
    try:
        global wsgi_app
        wsgi_app = WsgiApplication(args, base_dir=os.getcwd() + "/")

        global SRV
        SRV = wsgiserver.CherryPyWSGIServer(('0.0.0.0', pefim_server_conf.PORT), SessionMiddleware(
            application,
            pefim_server_conf.SESSION_OPTS))
        SRV.stats['Enabled'] = True

        if pefim_server_conf.HTTPS:
            SRV.ssl_adapter = ssl_pyopenssl.pyOpenSSLAdapter(pefim_server_conf.SERVER_CERT, pefim_server_conf.SERVER_KEY,
                                                             pefim_server_conf.CERT_CHAIN)
        wsgi_app.logger.info("Server starting")
        print "Server listening on port: %s" % pefim_server_conf.PORT
        try:
            SRV.start()
        except KeyboardInterrupt:
            SRV.stop()
    except Exception, excp:
        args = WsgiApplication.arg_parser(error="Invalid configuration in %s or %s, please consult the documentation."
                                                % (args.config, args.server_config),
                                          exception=" Exception:%s" % exception_trace(excp))
Пример #2
0
    def do(self, query, binding_in, relay_state="", encrypt_cert=None):
        try:
            resp_args, _resp = self.verify_request(query, binding_in)
        except UnknownPrincipal as excp:
            logger.error("UnknownPrincipal: %s" % (excp,))
            resp = ServiceError("UnknownPrincipal: %s" % (excp,))
            return resp(self.environ, self.start_response)
        except UnsupportedBinding as excp:
            logger.error("UnsupportedBinding: %s" % (excp,))
            resp = ServiceError("UnsupportedBinding: %s" % (excp,))
            return resp(self.environ, self.start_response)

        if not _resp:
            identity = USERS[self.user].copy()
            #identity["eduPersonTargetedID"] = get_eptid(IDP, query, session)
            logger.info("Identity: %s" % (identity,))

            if REPOZE_ID_EQUIVALENT:
                identity[REPOZE_ID_EQUIVALENT] = self.user
            try:
                _resp = IDP.create_authn_response(
                    identity, userid=self.user,
                    authn=AUTHN_BROKER[self.environ["idp.authn_ref"]],
                    **resp_args)
            except Exception as excp:
                logging.error(exception_trace(excp))
                resp = ServiceError("Exception: %s" % (excp,))
                return resp(self.environ, self.start_response)

        logger.info("AuthNResponse: %s" % _resp)
        http_args = IDP.apply_binding(self.binding_out,
                                      "%s" % _resp, self.destination,
                                      relay_state, response=True)
        logger.debug("HTTPargs: %s" % http_args)
        return self.response(self.binding_out, http_args)
Пример #3
0
    def do(self, query, binding_in, relay_state="", encrypt_cert=None,
           **kwargs):
        """

        :param query: The request
        :param binding_in: Which binding was used when receiving the query
        :param relay_state: The relay state provided by the SP
        :param encrypt_cert: Cert to use for encryption
        :return: A response
        """
        try:
            resp_args, _resp = self.verify_request(query, binding_in)
        except UnknownPrincipal as excp:
            logger.error("UnknownPrincipal: %s", excp)
            resp = ServiceError("UnknownPrincipal: %s" % (excp,))
            return resp(self.environ, self.start_response)
        except UnsupportedBinding as excp:
            logger.error("UnsupportedBinding: %s", excp)
            resp = ServiceError("UnsupportedBinding: %s" % (excp,))
            return resp(self.environ, self.start_response)

        if not _resp:
            identity = USERS[self.user].copy()
            # identity["eduPersonTargetedID"] = get_eptid(IDP, query, session)
            logger.info("Identity: %s", identity)

            if REPOZE_ID_EQUIVALENT:
                identity[REPOZE_ID_EQUIVALENT] = self.user
            try:
                try:
                    metod = self.environ["idp.authn"]
                except KeyError:
                    pass
                else:
                    resp_args["authn"] = metod

                _resp = IDP.create_authn_response(
                    identity, userid=self.user,
                    encrypt_cert_assertion=encrypt_cert,
                    **resp_args)
            except Exception as excp:
                logging.error(exception_trace(excp))
                resp = ServiceError("Exception: %s" % (excp,))
                return resp(self.environ, self.start_response)

        logger.info("AuthNResponse: %s", _resp)
        if self.op_type == "ecp":
            kwargs = {"soap_headers": [
                ecp.Response(
                    assertion_consumer_service_url=self.destination)]}
        else:
            kwargs = {}

        http_args = IDP.apply_binding(self.binding_out,
                                      "%s" % _resp, self.destination,
                                      relay_state, response=True, **kwargs)

        logger.debug("HTTPargs: %s", http_args)
        return self.response(self.binding_out, http_args)
Пример #4
0
    def do(self, query, binding_in, relay_state="", encrypt_cert=None,
           **kwargs):
        """

        :param query: The request
        :param binding_in: Which binding was used when receiving the query
        :param relay_state: The relay state provided by the SP
        :param encrypt_cert: Cert to use for encryption
        :return: A response
        """
        try:
            resp_args, _resp = self.verify_request(query, binding_in)
        except UnknownPrincipal as excp:
            logger.error("UnknownPrincipal: %s" % (excp,))
            resp = ServiceError("UnknownPrincipal: %s" % (excp,))
            return resp(self.environ, self.start_response)
        except UnsupportedBinding as excp:
            logger.error("UnsupportedBinding: %s" % (excp,))
            resp = ServiceError("UnsupportedBinding: %s" % (excp,))
            return resp(self.environ, self.start_response)

        if not _resp:
            identity = USERS[self.user].copy()
            # identity["eduPersonTargetedID"] = get_eptid(IDP, query, session)
            logger.info("Identity: %s" % (identity,))

            if REPOZE_ID_EQUIVALENT:
                identity[REPOZE_ID_EQUIVALENT] = self.user
            try:
                try:
                    metod = self.environ["idp.authn"]
                except KeyError:
                    pass
                else:
                    resp_args["authn"] = metod

                _resp = IDP.create_authn_response(
                    identity, userid=self.user,
                    encrypt_cert_assertion=encrypt_cert,
                    **resp_args)
            except Exception as excp:
                logging.error(exception_trace(excp))
                resp = ServiceError("Exception: %s" % (excp,))
                return resp(self.environ, self.start_response)

        logger.info("AuthNResponse: %s" % _resp)
        if self.op_type == "ecp":
            kwargs = {"soap_headers": [
                ecp.Response(
                    assertion_consumer_service_url=self.destination)]}
        else:
            kwargs = {}

        http_args = IDP.apply_binding(self.binding_out,
                                      "%s" % _resp, self.destination,
                                      relay_state, response=True, **kwargs)

        logger.debug("HTTPargs: %s" % http_args)
        return self.response(self.binding_out, http_args)
Пример #5
0
def application(environ, start_response):
    """
    WSGI application. Handles all requests.
    :param environ: WSGI enviroment.
    :param start_response: WSGI start response.
    :return: Depends on the request. Always a WSGI response where start_response first have to be initialized.
    """
    try:
        start_response = start_response_intercept(start_response)
        session = Session(environ)

        http_helper = HttpHandler(environ, start_response, session, logger)
        path = http_helper.path()

        environ = sphandler.verify_sp_user_validity(session, environ, path)
        http_helper.log_request()
        response = None
        if server_conf.OP_FRONTEND and ophandler.verify_provider_requests(
                path):
            response = ophandler.handle_provider_requests(
                environ, start_response, path, session)
        if server_conf.IDP_FRONTEND and idphandler.verify_provider_requests(
                path, environ):
            response = idphandler.handle_provider_requests(
                environ, start_response, path)
        elif sphandler.verify_sp_requests(path):
            response = sphandler.handle_sp_requests(environ, start_response,
                                                    path, session)
        elif http_helper.verify_static(path):
            return http_helper.handle_static(path)

        if response is None:
            response = http_helper.http404()

        http_helper.log_response(response)
        #Catch all unauthorized attempts and present a better web page.
        if start_response.status[0:3] == "401":
            mte = LOOKUP.get_template("unauthorized.mako")
            message = None
            if len(response) == 1:
                message = str(response[0])
            if message is None or len(message.strip()) == 0:
                message = "You are not authorized!"
            argv = {
                "message": message,
            }
            return [mte.render(**argv)]
        return response
    except Exception, excp:
        urn = uuid4().urn
        logger.error("uuid: " + str(urn) + str(exception_trace(excp)))
        argv = {
            "log_id": str(urn),
        }
        mte = LOOKUP.get_template("bad_request.mako")
        resp = BadRequest(mte.render(**argv))
        return resp(environ, start_response)
Пример #6
0
def application(environ, start_response):
    """
    WSGI application. Handles all requests.
    :param environ: WSGI enviroment.
    :param start_response: WSGI start response.
    :return: Depends on the request. Always a WSGI response where start_response first have to be initialized.
    """
    try:
        start_response = start_response_intercept(start_response)
        session = Session(environ)

        http_helper = HttpHandler(environ, start_response, session, logger)
        path = http_helper.path()

        environ = sphandler.verify_sp_user_validity(session, environ, path)
        http_helper.log_request()
        response = None
        if server_conf.OP_FRONTEND and ophandler.verify_provider_requests(path):
            response = ophandler.handle_provider_requests(environ, start_response, path, session)
        if server_conf.IDP_FRONTEND and idphandler.verify_provider_requests(path, environ):
            response = idphandler.handle_provider_requests(environ, start_response, path)
        elif sphandler.verify_sp_requests(path):
            response = sphandler.handle_sp_requests(environ, start_response, path, session)
        elif http_helper.verify_static(path):
            return http_helper.handle_static(path)

        if response is None:
            response = http_helper.http404()

        http_helper.log_response(response)
        #Catch all unauthorized attempts and present a better web page.
        if start_response.status[0:3] == "401":
            mte = LOOKUP.get_template("unauthorized.mako")
            message = None
            if len(response) == 1:
                message = str(response[0])
            if message is None or len(message.strip()) == 0:
                message = "You are not authorized!"
            argv = {
                "message": message,
            }
            return [mte.render(**argv)]
        return response
    except Exception, excp:
        urn = uuid4().urn
        logger.error("uuid: " + str(urn) + str(exception_trace(excp)))
        argv = {
            "log_id": str(urn),
        }
        mte = LOOKUP.get_template("bad_request.mako")
        resp = BadRequest(mte.render(**argv))
        return resp(environ, start_response)
Пример #7
0
    def do(self, query, binding_in, relay_state=""):
        try:
            resp_args, _resp = self.verify_request(query, binding_in)
        except UnknownPrincipal as excp:
            logger.error("UnknownPrincipal: %s", excp)
            resp = ServiceError("UnknownPrincipal: %s" % (excp, ))
            return resp(self.environ, self.start_response)
        except UnsupportedBinding as excp:
            logger.error("UnsupportedBinding: %s", excp)
            resp = ServiceError("UnsupportedBinding: %s" % (excp, ))
            return resp(self.environ, self.start_response)

        if not _resp:
            identity = USERS[self.user].copy()
            #identity["eduPersonTargetedID"] = get_eptid(IDP, query, session)
            logger.info("Identity: %s", identity)

            if REPOZE_ID_EQUIVALENT:
                identity[REPOZE_ID_EQUIVALENT] = self.user
            try:
                sign_assertion = IDP.config.getattr("sign_assertion", "idp")
                if sign_assertion is None:
                    sign_assertion = False
                _resp = IDP.create_authn_response(
                    identity,
                    userid=self.user,
                    authn=AUTHN_BROKER[self.environ["idp.authn_ref"]],
                    sign_assertion=sign_assertion,
                    sign_response=False,
                    **resp_args)
            except Exception as excp:
                logging.error(exception_trace(excp))
                resp = ServiceError("Exception: %s" % (excp, ))
                return resp(self.environ, self.start_response)

        logger.info("AuthNResponse: %s", _resp)
        http_args = IDP.apply_binding(self.binding_out,
                                      "%s" % _resp,
                                      self.destination,
                                      relay_state,
                                      response=True)
        logger.debug("HTTPargs: %s", http_args)
        return self.response(self.binding_out, http_args)
Пример #8
0
def application(environ, start_response):
    """
    WSGI application. Handles all requests.
    :param environ: WSGI enviroment.
    :param start_response: WSGI start response.
    :return: Depends on the request. Always a WSGI response where start_response first have to be initialized.
    """
    try:
        session = Session(environ)

        http_helper = HttpHandler(environ, start_response, session, logger)
        path = http_helper.path()

        environ = sphandler.verify_sp_user_validity(session, environ, path)
        http_helper.log_request()
        response = None
        if server_conf.OP_FRONTEND and ophandler.verify_provider_requests(path):
            response = ophandler.handle_provider_requests(environ, start_response, path, session)
        if server_conf.IDP_FRONTEND and idphandler.verify_provider_requests(path, environ):
            response = idphandler.handle_provider_requests(environ, start_response, path)
        elif sphandler.verify_sp_requests(path):
            response = sphandler.handle_sp_requests(environ, start_response, path, session)
        elif http_helper.verify_static(path):
            return http_helper.handle_static(path)

        if response is None:
            response = http_helper.http404()

        http_helper.log_response(response)
        return response
    except Exception, excp:
        urn = uuid4().urn
        logger.error("uuid: " + str(urn) + str(exception_trace(excp)))
        argv = {
            "log_id": str(urn),
        }
        mte = LOOKUP.get_template("bad_request.mako")
        resp = BadRequest(mte.render(**argv))
        return resp(environ, start_response)
Пример #9
0
    def _identity(self, user_resp, resp_args, relay_state, session):
        # Either a web response or user information
        if isinstance(user_resp, Response):
            return user_resp(self.environ, self.start_response)

        identity = user_resp
        #identity["eduPersonTargetedID"] = get_eptid(IDP, resp_args, session)
        logger.info("Identity: %s" % (identity,))

#        if REPOZE_ID_EQUIVALENT and self.user:
#            identity[REPOZE_ID_EQUIVALENT] = self.user

        try:
            authn=AUTHN_BROKER["1"]
            #self.binding_out = resp_args["binding"]
            _resp = IDP.create_authn_response(identity, userid=self.user,
                                              authn=authn,
                                              **resp_args)
            return self._authn_response(_resp, relay_state)
        except Exception, excp:
            logging.error(exception_trace(excp))
            resp = ServiceError("Exception: %s" % (excp,))
            return resp(self.environ, self.start_response)
Пример #10
0
                                break
                        for k, v in replace_dict.iteritems():
                            xml_str = xml_str.replace(k, v)

                        xml_str_list = xml_str.split("Assertion")

                        start_index = (xml_str_list[0][::-1].find("<")) * -1
                        _resp = xml_str_list[0][:(start_index - 1)] + assertion + xml_str_list[2][1:]
                        #name1 = assertion[assertion.find('<') + 1:assertion.find(':')]
                        #name2 = xml_str_list[0][len(xml_str_list[0]) + start_index:-1]
                        #_resp.replace(name2, name1)

                        if self.idphandler.idp_server.config.getattr("sign_response", "idp"):
                            _resp = self.idphandler.idp_server.sec.sign_statement(_resp, _class_sign, node_id=_node_id_sign)
            except Exception, excp:
                logging.error(exception_trace(excp))
                raise excp

        logger.info("AuthNResponse: %s" % _resp)
        http_args = self.idphandler.idp_server.apply_binding(self.binding_out,
                                                             "%s" % _resp, self.destination,
                                                             relay_state, response=True)
        logger.debug("HTTPargs: %s" % http_args)
        return self.response(self.binding_out, http_args)

    def _store_request(self, _dict):
        logger.debug("_store_request: %s" % _dict)
        key = sha1(_dict["SAMLRequest"]).hexdigest()
        # store the AuthnRequest
        self.idphandler.idp_server.ticket[key] = _dict
        return key
Пример #11
0
    def perform_logout(self, info, binding):
        """
        Perform logout. Means remove SSO session from IdP list, and a best
        effort to contact all SPs that have received assertions using this
        SSO session and letting them know the user has been logged out.

        :param info: Dict with SAMLRequest and possibly RelayState
        :param binding: SAML2 binding as string
        :return: SAML StatusCode

        :type info: dict
        :type binding: string
        :rtype: string
        """
        self.logger.debug("--- Single Log Out Service ---")
        if not info:
            raise eduid_idp.error.BadRequest('Error parsing request or no request', logger = self.logger)

        request = info["SAMLRequest"]
        req_key = _get_request_key(request)

        try:
            req_info = self.IDP.parse_logout_request(request, binding)
            assert isinstance(req_info, saml2.request.LogoutRequest)
            self.logger.debug("Parsed Logout request ({!s}):\n{!s}".format(binding, req_info.message))
        except Exception as exc:
            self.logger.debug("_perform_logout {!s}:\n{!s}".format(binding, pprint.pformat(info)))
            self.logger.error("Bad request parsing logout request : {!r}".format(exc))
            self.logger.debug("Exception parsing logout request :\n{!s}".format(exception_trace(exc)))
            raise eduid_idp.error.BadRequest("Failed parsing logout request", logger = self.logger)

        req_info.binding = binding
        if 'RelayState' in info:
            req_info.relay_state = info['RelayState']

        # look for the subject
        subject = req_info.subject_id()
        if subject is not None:
            self.logger.debug("Logout subject: {!s}".format(subject.text.strip()))
        # XXX should verify issuer (a.k.a. sender()) somehow perhaps
        self.logger.debug("Logout request sender : {!s}".format(req_info.sender()))

        _name_id = req_info.message.name_id
        _session_id = eduid_idp.mischttp.read_cookie(self.logger)
        _username = None
        if _session_id:
            # If the binding is REDIRECT, we can get the SSO session to log out from the
            # client idpauthn cookie
            session_ids = [_session_id]
        else:
            # For SOAP binding, no cookie is sent - only NameID. Have to figure out
            # the user based on NameID and then destroy *all* the users SSO sessions
            # unfortunately.
            _username = self.IDP.ident.find_local_id(_name_id)
            self.logger.debug("Logout message name_id: {!r} found username {!r}".format(
                _name_id, _username))
            session_ids = self.IDP.cache.get_sessions_for_user(_username)

        self.logger.debug("Logout resources: name_id {!r} username {!r}, session_ids {!r}".format(
            _name_id, _username, session_ids))

        if session_ids:
            status_code = self._logout_session_ids(session_ids, req_key)
        else:
            # No specific SSO session(s) were found, we have no choice but to logout ALL
            # the sessions for this NameID.
            status_code = self._logout_name_id(_name_id, req_key)

        self.logger.debug("Logout of sessions {!r} / NameID {!r} result : {!r}".format(
            session_ids, _name_id, status_code))
        return self._logout_response(req_info, status_code, req_key)
Пример #12
0
    def perform_logout(self, info, binding):
        """
        Perform logout. Means remove SSO session from IdP list, and a best
        effort to contact all SPs that have received assertions using this
        SSO session and letting them know the user has been logged out.

        :param info: Dict with SAMLRequest and possibly RelayState
        :param binding: SAML2 binding as string
        :return: SAML StatusCode

        :type info: dict
        :type binding: string
        :rtype: string
        """
        self.logger.debug("--- Single Log Out Service ---")
        if not info:
            raise eduid_idp.error.BadRequest('Error parsing request or no request', logger = self.logger)

        request = info["SAMLRequest"]
        req_key = ExpiringCache.key(request)

        try:
            req_info = self.context.idp.parse_logout_request(request, binding)
            assert isinstance(req_info, saml2.request.LogoutRequest)
            self.logger.debug("Parsed Logout request ({!s}):\n{!s}".format(binding, req_info.message))
        except Exception as exc:
            self.logger.debug("_perform_logout {!s}:\n{!s}".format(binding, pprint.pformat(info)))
            self.logger.error("Bad request parsing logout request : {!r}".format(exc))
            self.logger.debug("Exception parsing logout request :\n{!s}".format(exception_trace(exc)))
            raise eduid_idp.error.BadRequest("Failed parsing logout request", logger = self.logger)

        req_info.binding = binding
        if 'RelayState' in info:
            req_info.relay_state = info['RelayState']

        # look for the subject
        subject = req_info.subject_id()
        if subject is not None:
            self.logger.debug("Logout subject: {!s}".format(subject.text.strip()))
        # XXX should verify issuer (a.k.a. sender()) somehow perhaps
        self.logger.debug("Logout request sender : {!s}".format(req_info.sender()))

        _name_id = req_info.message.name_id
        _session_id = eduid_idp.mischttp.get_idpauthn_cookie(self.logger)
        _username = None
        if _session_id:
            # If the binding is REDIRECT, we can get the SSO session to log out from the
            # client idpauthn cookie
            session_ids = [eduid_idp.cache.SSOSessionId(_session_id)]
        else:
            # For SOAP binding, no cookie is sent - only NameID. Have to figure out
            # the user based on NameID and then destroy *all* the users SSO sessions
            # unfortunately.
            _username = self.context.idp.ident.find_local_id(_name_id)
            self.logger.debug("Logout message name_id: {!r} found username {!r}".format(
                _name_id, _username))
            session_ids = self.context.sso_sessions.get_sessions_for_user(_username)

        self.logger.debug("Logout resources: name_id {!r} username {!r}, session_ids {!r}".format(
            _name_id, _username, session_ids))

        if session_ids:
            status_code = self._logout_session_ids(session_ids, req_key)
        else:
            # No specific SSO session(s) were found, we have no choice but to logout ALL
            # the sessions for this NameID.
            status_code = self._logout_name_id(_name_id, req_key)

        self.logger.debug("Logout of sessions {!r} / NameID {!r} result : {!r}".format(
            session_ids, _name_id, status_code))
        return self._logout_response(req_info, status_code, req_key)
Пример #13
0
            return resp(self.environ, self.start_response)

        if not _resp:
            identity = USERS[self.user]
            logger.info("Identity: %s" % (identity, ))

            if REPOZE_ID_EQUIVALENT:
                identity[REPOZE_ID_EQUIVALENT] = self.user
            try:
                _resp = IDP.create_authn_response(
                    identity,
                    userid=self.user,
                    authn=AUTHN_BROKER[self.environ["idp.authn_ref"]],
                    **resp_args)
            except Exception, excp:
                logging.error(exception_trace(excp))
                resp = ServiceError("Exception: %s" % (excp, ))
                return resp(self.environ, self.start_response)

        logger.info("AuthNResponse: %s" % _resp)
        http_args = IDP.apply_binding(self.binding_out,
                                      "%s" % _resp,
                                      self.destination,
                                      relay_state,
                                      response=True)
        logger.debug("HTTPargs: %s" % http_args)
        return self.response(self.binding_out, http_args)

    def _store_request(self, _dict):
        logger.debug("_store_request: %s" % _dict)
        key = sha1(_dict["SAMLRequest"]).hexdigest()