Exemplo n.º 1
0
    def response(self, binding, http_args):
        resp = None
        if binding == BINDING_HTTP_ARTIFACT:
            resp = Redirect()
        elif http_args["data"]:
            resp = Response(http_args["data"], headers=http_args["headers"])
        else:
            for header in http_args["headers"]:
                if header[0] == "Location":
                    resp = Redirect(header[1])

        if not resp:
            resp = ServiceError("Don't know how to return response")

        return resp(self.environ, self.start_response)
Exemplo n.º 2
0
def slo(environ, start_response, user):
    # so here I might get either a LogoutResponse or a LogoutRequest
    client = environ['repoze.who.plugins']["saml2auth"]
    sc = client.saml_client

    if "QUERY_STRING" in environ:
        query = parse_qs(environ["QUERY_STRING"])
        logger.info("query: %s" % query)
        try:
            response = sc.parse_logout_request_response(
                query["SAMLResponse"][0], binding=BINDING_HTTP_REDIRECT)
            if response:
                logger.info("LOGOUT response parsed OK")
        except KeyError:
            # return error reply
            response = None

        if response is None:
            request = sc.lo

    headers = []
    delco = delete_cookie(environ, "pysaml2")
    if delco:
        headers.append(delco)
    resp = Redirect("/done", headers=headers)
    return resp(environ, start_response)
Exemplo n.º 3
0
    def verify(self, request, **kwargs):
        """
        Verifies that the given username and password was correct
        :param request: Either the query part of a URL a urlencoded
            body of a HTTP message or a parse such.
        :param kwargs: Catch whatever else is sent.
        :return: redirect back to where ever the base applications
            wants the user after authentication.
        """

        #logger.debug("verify(%s)" % request)
        if isinstance(request, six.string_types):
            _dict = parse_qs(request)
        elif isinstance(request, dict):
            _dict = request
        else:
            raise ValueError("Wrong type of input")

        # verify username and password
        try:
            self._verify(_dict["password"][0], _dict["login"][0])
            timestamp = str(int(time.mktime(time.gmtime())))
            msg = "::".join([_dict["login"][0], timestamp])
            info = self.symmetric.encrypt(msg.encode())
            self.active[info] = timestamp
            cookie = make_cookie(self.cookie_name, info, self.srv.seed)
            return_to = create_return_url(self.return_to, _dict["query"][0],
                                          **{self.query_param: "true"})
            resp = Redirect(return_to, headers=[cookie])
        except (ValueError, KeyError):
            resp = Unauthorized("Unknown user or wrong password")

        return resp
Exemplo n.º 4
0
def do_verify(environ, start_response, _):
    query = parse_qs(get_post(environ))

    logger.debug("do_verify: %s", query)

    try:
        _ok, user = verify_username_and_password(query)
    except KeyError:
        _ok = False
        user = None

    if not _ok:
        resp = Unauthorized("Unknown user or wrong password")
    else:
        uid = rndstr(24)
        IDP.cache.uid2user[uid] = user
        IDP.cache.user2uid[user] = uid
        logger.debug("Register %s under '%s'", user, uid)

        kaka = set_cookie("idpauthn", "/", uid, query["authn_reference"][0])

        lox = "%s?id=%s&key=%s" % (query["redirect_uri"][0], uid,
                                   query["key"][0])
        logger.debug("Redirect => %s", lox)
        resp = Redirect(lox, headers=[kaka], content="text/html")

    return resp(environ, start_response)
Exemplo n.º 5
0
 def setup_idp(self, user, reference, redirect_uri, key):
     uid = rndstr(24)
     self.idphandler.idp_server.cache.uid2user[uid] = user
     self.idphandler.idp_server.cache.user2uid[user] = uid
     logger.debug("Register %s under '%s'" % (user, uid))
     cookie = self.idphandler.set_authorization_cookie(uid, reference)
     lox = "%s?id=%s&key=%s" % (redirect_uri, uid, key)
     logger.debug("Redirect => %s" % lox)
     resp = Redirect(lox, headers=[cookie], content="text/html")
     return resp
Exemplo n.º 6
0
    def do(self, response, binding, relay_state="", mtype="response"):
        """
        :param response: The SAML response, transport encoded
        :param binding: Which binding the query came in over
        """
        # tmp_outstanding_queries = dict(self.outstanding_queries)
        if not response:
            logger.info("Missing Response")
            resp = Unauthorized('Unknown user')
            return resp(self.environ, self.start_response)

        try:
            conv_info = {
                'remote_addr': self.environ['REMOTE_ADDR'],
                'request_uri': self.environ['REQUEST_URI'],
                'entity_id': self.sp.config.entityid,
                'endpoints': self.sp.config.getattr('endpoints', 'sp')
            }

            self.response = self.sp.parse_authn_request_response(
                response,
                binding,
                self.outstanding_queries,
                self.cache.outstanding_certs,
                conv_info=conv_info)
        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)
        except VerificationError as err:
            resp = ServiceError("Verification error: %s" % (err, ))
            return resp(self.environ, self.start_response)
        except SignatureError as err:
            resp = ServiceError("Signature error: %s" % (err, ))
            return resp(self.environ, self.start_response)
        except Exception as err:
            resp = ServiceError("Other error: %s" % (err, ))
            return resp(self.environ, self.start_response)

        logger.info("AVA: %s", self.response.ava)

        user = User(self.response.name_id, self.response.ava, self.response)
        cookie = self.cache.set_cookie(user)

        resp = Redirect("/", headers=[
            cookie,
        ])
        return resp(self.environ, self.start_response)
Exemplo n.º 7
0
    def construct_authn_response(self, idp, state, identity, name_id, authn, resp_args, relay_state,
                                 sign_response=True):
        """
        Constructs an auth response

        :type idp: saml.server.Server
        :type state: satosa.state.State
        :type identity: dict[str, str]
        :type name_id: saml2.saml.NameID
        :type authn: dict[str, str]
        :type resp_args: dict[str, str]
        :type relay_state: str
        :type sign_response: bool

        :param idp: The saml frontend idp server
        :param state: The current state
        :param identity: Information about an user (The ava attributes)
        :param name_id: The name id
        :param authn: auth info
        :param resp_args: response arguments
        :param relay_state: the relay state
        :param sign_response: Flag for signing the response or not
        :return: The constructed response
        """

        _resp = idp.create_authn_response(identity,
                                          name_id=name_id,
                                          authn=authn,
                                          sign_response=sign_response,
                                          **resp_args)

        http_args = idp.apply_binding(
            resp_args["binding"], "%s" % _resp, resp_args["destination"],
            relay_state, response=True)

        satosa_logging(LOGGER, logging.DEBUG, "HTTPargs: %s" % http_args, state)

        resp = None
        if http_args["data"]:
            resp = Response(http_args["data"], headers=http_args["headers"])
        else:
            for header in http_args["headers"]:
                if header[0] == "Location":
                    resp = Redirect(header[1])

        if not resp:
            msg = "Don't know how to return response"
            satosa_logging(LOGGER, logging.ERROR, msg, state)
            resp = ServiceError(msg)

        return resp
Exemplo n.º 8
0
    def slo_redirect_or_post(self, query, binding):
        log.debug("Query: " + query)
        log.debug("Binding: " + binding)

        try:
            req_info = self.parse_logout_request(query, binding)
        except Exception as exc:
            log.exception("Message parsing failed.")
            return BadRequest("Message parsing failed")

        msg = req_info.message
        if msg.name_id:
            lid = self.ident.find_local_id(msg.name_id)
            if lid in self.cache.user2uid:
                uid = self.cache.user2uid[lid]
                if uid in self.cache.uid2user:
                    del self.cache.uid2user[uid]
                del self.cache.user2uid[lid]
            try:
                self.session_db.remove_authn_statements(msg.name_id)
            except KeyError as exc:
                log.exception("Session removal failed")

        resp = self.create_logout_response(msg, [binding])

        binding, destination = self.pick_binding("single_logout_service",
                                                 [binding], "spsso", req_info)
        response = True

        try:
            hinfo = self.apply_binding(binding,
                                       "%s" % resp,
                                       destination,
                                       query['relay_state'],
                                       response=response)
        except Exception as exc:
            log.exception("ServiceError: %s", exc)
            return ServiceError("%s" % exc)

        if binding == BINDING_HTTP_REDIRECT:
            for key, value in hinfo["headers"]:
                if key.lower() == "location":
                    return Redirect(value, headers=hinfo["headers"])

            return ServiceError("missing Location header")
        else:
            return Response(hinfo["data"], headers=hinfo["headers"])
Exemplo n.º 9
0
    def response(self, binding, http_args, do_not_start_response=False):
        if binding == BINDING_HTTP_ARTIFACT:
            resp = Redirect()
        elif binding == BINDING_HTTP_REDIRECT:
            for param, value in http_args["headers"]:
                if param == "Location":
                    resp = SeeOther(str(value))
                    break
            else:
                resp = ServiceError("Parameter error")
        else:
            resp = Response(http_args["data"], headers=http_args["headers"])

        if do_not_start_response:
            return resp
        else:
            return resp(self.environ, self.start_response)
Exemplo n.º 10
0
 def verify(self, environ, start_response):
     session = Session(environ)
     if self.MUTLIPLEAUTHENTICATIONCOUNTER in session:
         authn_method = session[self.MUTLIPLEAUTHENTICATIONCOUNTER]
         if authn_method > (self.auth_list_lengt - 1) or self.auth_list_lengt == 0:
             resp = Unauthorized("No authentication method")
         elif authn_method == (self.auth_list_lengt - 1):
             return self.auth_list[authn_method].verify(environ, start_response)
         else:
             _ok = self.auth_list[authn_method].verify_bool(environ, start_response)
             if _ok:
                 session[self.MUTLIPLEAUTHENTICATIONCOUNTER] = authn_method + 1
                 resp = Redirect(session[self.MULTIPLEAUTHENTICATIONREDIRECT])
             else:
                 return self.auth_list[authn_method].verify(environ, start_response)
     else:
         resp = Unauthorized("No authentication method")
     return resp(environ, start_response)
Exemplo n.º 11
0
    def construct_authn_response(self,
                                 identity,
                                 name_id,
                                 authn,
                                 resp_args,
                                 relay_state,
                                 sign_response=True):
        """

        :param identity:
        :param name_id:
        :param authn:
        :param resp_args:
        :param relay_state:
        :param sign_response:
        :return:
        """

        _resp = self.idp.create_authn_response(identity,
                                               name_id=name_id,
                                               authn=authn,
                                               sign_response=sign_response,
                                               **resp_args)

        http_args = self.idp.apply_binding(resp_args["binding"],
                                           "%s" % _resp,
                                           resp_args["destination"],
                                           relay_state,
                                           response=True)

        logger.debug("HTTPargs: %s" % http_args)

        resp = None
        if http_args["data"]:
            resp = Response(http_args["data"], headers=http_args["headers"])
        else:
            for header in http_args["headers"]:
                if header[0] == "Location":
                    resp = Redirect(header[1])

        if not resp:
            resp = ServiceError("Don't know how to return response")

        return resp(self.environ, self.start_response)
Exemplo n.º 12
0
def authn_response(server_env, req_info, userid, identity,
                   authn=None, authn_decl=None, service=""):
    # base 64 encoded request

    logger.debug("User info: %s" % identity)

    if service:
        issuer = "%s%s" % (server_env["base_url"], service)
    else:
        issuer = None

    logger.info("ISSUER: %s" % issuer)
    _idp = server_env["idp"]

    binding, destination = _idp.pick_binding("assertion_consumer_service",
                                             entity_id=req_info.sender())

    logger.debug("binding: %s, destination: %s" % (binding, destination))

    authn_resp = _idp.create_authn_response(identity, req_info.message.id,
                                            destination,
                                            req_info.sender(),
                                            req_info.message.name_id_policy,
                                            str(userid), authn=authn, 
                                            sign_assertion=server_env["SIGN"],
                                            authn_decl=authn_decl,
                                            issuer=issuer)

    logger.info("LOGIN success: sp_entity_id=%s#authn=%s" % (req_info.sender(),
                                                             authn))
    logger.debug("AuthNResponse: %s" % authn_resp)

    ht_args = _idp.apply_binding(binding, "%s" % authn_resp, destination,
                                 req_info.relay_state, response=True)

    logger.debug("ht_args: %s" % ht_args)

    if "status" in ht_args and ht_args["status"] == 302:
        return Redirect(ht_args["data"], headers=ht_args["headers"])
    else:
        return Response(ht_args["data"], headers=ht_args["headers"])
Exemplo n.º 13
0
def logout(environ, start_response, user):
    # This is where it starts when a user wants to log out
    client = environ['repoze.who.plugins']["saml2auth"]
    subject_id = environ["repoze.who.identity"]['repoze.who.userid']
    logger.info("[logout] subject_id: '%s'" % (subject_id, ))
    target = "/done"

    # What if more than one
    _dict = client.saml_client.global_logout(subject_id)
    logger.info("[logout] global_logout > %s" % (_dict, ))
    rem = environ['repoze.who.plugins'][client.rememberer_name]
    rem.forget(environ, subject_id)

    for key, item in _dict.items():
        if isinstance(item, tuple):
            binding, htargs = item
        else:  # result from logout, should be OK
            pass

    resp = Redirect("Successful Logout", headers=[("Location", target)])
    return resp(environ, start_response)
Exemplo n.º 14
0
    def do(self, response, binding, relay_state="", mtype="response"):
        """
        :param response: The SAML response, transport encoded
        :param binding: Which binding the query came in over
        """
        #tmp_outstanding_queries = dict(self.outstanding_queries)
        if not response:
            logger.info("Missing Response")
            resp = Unauthorized('Unknown user')
            return resp(self.environ, self.start_response)

        try:
            self.response = self.sp.parse_authn_request_response(
                response, binding, self.outstanding_queries,
                self.cache.outstanding_certs)
        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)
        except VerificationError as err:
            resp = ServiceError("Verification error: %s" % (err, ))
            return resp(self.environ, self.start_response)
        except Exception as err:
            resp = ServiceError("Other error: %s" % (err, ))
            return resp(self.environ, self.start_response)

        logger.info("AVA: %s" % self.response.ava)

        user = User(self.response.name_id, self.response.ava)
        cookie = self.cache.set_cookie(user)

        resp = Redirect("/", headers=[
            ("Location", "/"),
            cookie,
        ])
        return resp(self.environ, self.start_response)
Exemplo n.º 15
0
    def authenticate(self, environ, start_response, reference, key,
                     redirect_uri, **kwargs):
        _sid = ""
        _encrypt_sid = ""
        if "certificate_str" in kwargs and kwargs[
                "certificate_str"] is not None:
            _sid = self.sphandler.add_certificate_to_cache(
                kwargs["certificate_str"])
        if "certificate_key_str" in kwargs and kwargs[
                "certificate_key_str"] is not None:
            _encrypt_sid = self.sphandler.add_certificate_to_cache(
                kwargs["certificate_key_str"])

        query_dict = {
            "key": key,
            "authn_reference": reference,
            "redirect_uri": redirect_uri
        }
        f = {'query': self.encrypt_dict(query_dict)}
        urllib.urlencode(f)

        query = "/" + self.idphandler.IDP_VERIFY_URL + "?" + urllib.urlencode(
            f)

        cookie_load = {
            "query": query,
            "sid": _sid,
            "encrypt_sid": _encrypt_sid
        }

        cookie_load = self.encrypt_dict(cookie_load)

        cookie = self.idphandler.set_cookie(self.SPAUTHENTICATIONCOOKIE, "/",
                                            cookie_load)
        resp = Redirect("/" + self.sphandler.sp_conf.SPVERIFYBASEIDP,
                        headers=[cookie])

        return resp(environ, start_response)
Exemplo n.º 16
0
def logout(environ, start_response, sp):
    user = CACHE.get_user(environ)

    if user is None:
        sso = SSO(sp, environ, start_response, cache=CACHE, **ARGS)
        return sso.do()

    logger.info("[logout] subject_id: '%s'", user.name_id)

    # What if more than one
    data = sp.global_logout(user.name_id)
    logger.info("[logout] global_logout > %s", data)

    for entity_id, logout_info in data.items():
        if isinstance(logout_info, tuple):
            binding, http_info = logout_info

            if binding == BINDING_HTTP_POST:
                body = "".join(http_info["data"])
                resp = Response(body)
                return resp(environ, start_response)
            elif binding == BINDING_HTTP_REDIRECT:
                for key, value in http_info["headers"]:
                    if key.lower() == "location":
                        resp = Redirect(value)
                        return resp(environ, start_response)

                resp = ServiceError("missing Location header")
                return resp(environ, start_response)
            else:
                resp = ServiceError("unknown logout binding: %s", binding)
                return resp(environ, start_response)
        else:  # result from logout, should be OK
            pass

    return finish_logout(environ, start_response)
Exemplo n.º 17
0
 def authn_redirect(self, environ):
     cookie_dict = self.sp_auth_cookie(environ)
     return Redirect(cookie_dict["query"])
Exemplo n.º 18
0
    def do(self,
           request,
           binding,
           relay_state="",
           encrypt_cert=None,
           **kwargs):

        logger.info("--- Single Log Out Service ---")
        try:
            logger.debug("req: '%s'", request)
            req_info = IDP.parse_logout_request(request, binding)
        except Exception as exc:
            logger.error("Bad request: %s", exc)
            resp = BadRequest("%s" % exc)
            return resp(self.environ, self.start_response)

        msg = req_info.message
        if msg.name_id:
            lid = IDP.ident.find_local_id(msg.name_id)
            logger.info("local identifier: %s", lid)
            if lid in IDP.cache.user2uid:
                uid = IDP.cache.user2uid[lid]
                if uid in IDP.cache.uid2user:
                    del IDP.cache.uid2user[uid]
                del IDP.cache.user2uid[lid]
            # remove the authentication
            try:
                IDP.session_db.remove_authn_statements(msg.name_id)
            except KeyError as exc:
                logger.error("Unknown session: %s", exc)
                resp = ServiceError("Unknown session: %s", exc)
                return resp(self.environ, self.start_response)

        resp = IDP.create_logout_response(msg, [binding])

        if binding == BINDING_SOAP:
            destination = ""
            response = False
        else:
            binding, destination = IDP.pick_binding("single_logout_service",
                                                    [binding], "spsso",
                                                    req_info)
            response = True

        try:
            hinfo = IDP.apply_binding(binding,
                                      "%s" % resp,
                                      destination,
                                      relay_state,
                                      response=response)
        except Exception as exc:
            logger.error("ServiceError: %s", exc)
            resp = ServiceError("%s" % exc)
            return resp(self.environ, self.start_response)

        #_tlh = dict2list_of_tuples(hinfo["headers"])
        delco = delete_cookie(self.environ, "idpauthn")
        if delco:
            hinfo["headers"].append(delco)
        logger.info("Header: %s", (hinfo["headers"], ))

        if binding == BINDING_HTTP_REDIRECT:
            for key, value in hinfo['headers']:
                if key.lower() == 'location':
                    resp = Redirect(value, headers=hinfo["headers"])
                    return resp(self.environ, self.start_response)

            resp = ServiceError('missing Location header')
            return resp(self.environ, self.start_response)
        else:
            resp = Response(hinfo["data"], headers=hinfo["headers"])
            return resp(self.environ, self.start_response)
Exemplo n.º 19
0
Arquivo: sp.py Projeto: dolph/pysaml2
            resp = ServiceError("UnsupportedBinding: %s" % (excp,))
            return resp(self.environ, self.start_response)
        except VerificationError, err:
            resp = ServiceError("Verification error: %s" % (err,))
            return resp(self.environ, self.start_response)
        except Exception, err:
            resp = ServiceError("Other error: %s" % (err,))
            return resp(self.environ, self.start_response)

        logger.info("AVA: %s" % self.response.ava)

        user = User(self.response.name_id, self.response.ava)
        cookie = self.cache.set_cookie(user)

        resp = Redirect("/", headers=[
            ("Location", "/"),
            cookie,
        ])
        return resp(self.environ, self.start_response)

    def verify_attributes(self, ava):
        logger.info("SP: %s" % self.sp.config.entityid)
        rest = POLICY.get_entity_categories(
            self.sp.config.entityid, self.sp.metadata)

        akeys = [k.lower() for k in ava.keys()]

        res = {"less": [], "more": []}
        for key, attr in rest.items():
            if key not in ava:
                if key not in akeys:
                    res["less"].append(key)
Exemplo n.º 20
0
 def response(self, binding, http_args):
     if binding == BINDING_HTTP_ARTIFACT:
         resp = Redirect()
     else:
         resp = Response(http_args["data"], headers=http_args["headers"])
     return resp(self.environ, self.start_response)