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))
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)
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)
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)
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)
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)
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)
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)
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)
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
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)
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)
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()