Example #1
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)
Example #2
0
def do_verify(environ, start_response, _):
    query_str = get_post(environ)
    if not isinstance(query_str, six.string_types):
        query_str = query_str.decode("ascii")
    query = parse_qs(query_str)

    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)
Example #3
0
 def set_cookie(self, user):
     uid = rndstr(32)
     self.uid2user[uid] = user
     cookie = SimpleCookie()
     cookie[self.cookie_name] = uid
     cookie[self.cookie_name]["path"] = "/"
     cookie[self.cookie_name]["expires"] = _expiration(480)
     logger.debug("Cookie expires: %s", cookie[self.cookie_name]["expires"])
     return cookie.output().split(": ", 1)
Example #4
0
 def set_cookie(self, user):
     uid = rndstr(32)
     self.uid2user[uid] = user
     cookie = SimpleCookie()
     cookie[self.cookie_name] = uid
     cookie[self.cookie_name]["path"] = "/"
     cookie[self.cookie_name]["expires"] = _expiration(480)
     logger.debug("Cookie expires: %s", cookie[self.cookie_name]["expires"])
     return cookie.output().split(": ", 1)
Example #5
0
    def redirect_to_auth(self, _cli, entity_id, came_from, sigalg=""):
        try:
            # Picks a binding to use for sending the Request to the IDP
            _binding, destination = _cli.pick_binding("single_sign_on_service",
                                                      self.bindings,
                                                      "idpsso",
                                                      entity_id=entity_id)
            logger.debug("binding: %s, destination: %s", _binding, destination)
            # Binding here is the response binding that is which binding the
            # IDP should use to return the response.
            acs = _cli.config.getattr("endpoints",
                                      "sp")["assertion_consumer_service"]
            # just pick one
            endp, return_binding = acs[0]

            extensions = None
            cert = None
            if _cli.config.generate_cert_func is not None:
                cert_str, req_key_str = _cli.config.generate_cert_func()
                cert = {"cert": cert_str, "key": req_key_str}
                spcertenc = SPCertEnc(x509_data=ds.X509Data(
                    x509_certificate=ds.X509Certificate(text=cert_str)))
                extensions = Extensions(extension_elements=[
                    element_to_extension_element(spcertenc)
                ])

            req_id, req = _cli.create_authn_request(
                destination,
                binding=return_binding,
                extensions=extensions,
                nameid_format=NAMEID_FORMAT_PERSISTENT,
            )
            _rstate = rndstr()
            self.cache.relay_state[_rstate] = came_from
            ht_args = _cli.apply_binding(_binding,
                                         "%s" % req,
                                         destination,
                                         relay_state=_rstate,
                                         sigalg=sigalg)
            _sid = req_id

            if cert is not None:
                self.cache.outstanding_certs[_sid] = cert

        except Exception as exc:
            logger.exception(exc)
            resp = ServiceError("Failed to construct the AuthnRequest: %s" %
                                exc)
            return resp

        # remember the request
        self.cache.outstanding_queries[_sid] = came_from
        return self.response(_binding, ht_args, do_not_start_response=True)
Example #6
0
    def redirect_to_auth(self, _cli, entity_id, came_from, sigalg=""):
        try:
            # Picks a binding to use for sending the Request to the IDP
            _binding, destination = _cli.pick_binding(
                "single_sign_on_service", self.bindings, "idpsso", entity_id=entity_id
            )
            logger.debug("binding: %s, destination: %s", _binding, destination)
            # Binding here is the response binding that is which binding the
            # IDP should use to return the response.
            acs = _cli.config.getattr("endpoints", "sp")["assertion_consumer_service"]
            # just pick one
            endp, return_binding = acs[0]

            extensions = None
            cert = None
            if _cli.config.generate_cert_func is not None:
                cert_str, req_key_str = _cli.config.generate_cert_func()
                cert = {"cert": cert_str, "key": req_key_str}
                spcertenc = SPCertEnc(
                    x509_data=ds.X509Data(
                        x509_certificate=ds.X509Certificate(text=cert_str)
                    )
                )
                extensions = Extensions(
                    extension_elements=[element_to_extension_element(spcertenc)]
                )

            req_id, req = _cli.create_authn_request(
                destination,
                binding=return_binding,
                extensions=extensions,
                nameid_format=NAMEID_FORMAT_PERSISTENT,
            )
            _rstate = rndstr()
            self.cache.relay_state[_rstate] = came_from
            ht_args = _cli.apply_binding(
                _binding, "%s" % req, destination, relay_state=_rstate, sigalg=sigalg
            )
            _sid = req_id

            if cert is not None:
                self.cache.outstanding_certs[_sid] = cert

        except Exception as exc:
            logger.exception(exc)
            resp = ServiceError("Failed to construct the AuthnRequest: %s" % exc)
            return resp

        # remember the request
        self.cache.outstanding_queries[_sid] = came_from
        return self.response(_binding, ht_args, do_not_start_response=True)
Example #7
0
 def __init__(self, config_file="", config=None, cache=None, stype="idp",
              symkey="", msg_cb=None):
     Entity.__init__(self, stype, config, config_file, msg_cb=msg_cb)
     self.eptid = None
     self.init_config(stype)
     self.cache = cache
     self.ticket = {}
     self.session_db = self.choose_session_storage()
     if symkey:
         self.symkey = symkey.encode()
     else:
         self.symkey = saml2_tophat.cryptography.symmetric.Default.generate_key()
     self.seed = rndstr()
     self.lock = threading.Lock()
Example #8
0
 def __init__(self,
              config_file="",
              config=None,
              cache=None,
              stype="idp",
              symkey="",
              msg_cb=None):
     Entity.__init__(self, stype, config, config_file, msg_cb=msg_cb)
     self.eptid = None
     self.init_config(stype)
     self.cache = cache
     self.ticket = {}
     self.session_db = self.choose_session_storage()
     if symkey:
         self.symkey = symkey.encode()
     else:
         self.symkey = saml2_tophat.cryptography.symmetric.Default.generate_key(
         )
     self.seed = rndstr()
     self.lock = threading.Lock()
Example #9
0
    def _pick_idp(self, came_from):
        """
        If more than one idp and if none is selected, I have to do wayf or
        disco
        """

        _cli = self.sp

        logger.debug("[_pick_idp] %s", self.environ)
        if "HTTP_PAOS" in self.environ:
            if self.environ["HTTP_PAOS"] == PAOS_HEADER_INFO:
                if MIME_PAOS in self.environ["HTTP_ACCEPT"]:
                    # Where should I redirect the user to
                    # entityid -> the IdP to use
                    # relay_state -> when back from authentication

                    logger.debug("- ECP client detected -")

                    _rstate = rndstr()
                    self.cache.relay_state[_rstate] = geturl(self.environ)
                    _entityid = _cli.config.ecp_endpoint(
                        self.environ["REMOTE_ADDR"])

                    if not _entityid:
                        return -1, ServiceError("No IdP to talk to")
                    logger.debug("IdP to talk to: %s", _entityid)
                    return ecp.ecp_auth_request(_cli, _entityid, _rstate)
                else:
                    return -1, ServiceError("Faulty Accept header")
            else:
                return -1, ServiceError("unknown ECP version")

        # Find all IdPs
        idps = self.sp.metadata.with_descriptor("idpsso")

        idp_entity_id = None

        kaka = self.environ.get("HTTP_COOKIE", "")
        if kaka:
            try:
                (idp_entity_id, _) = parse_cookie("ve_disco", "SEED_SAW", kaka)
            except ValueError:
                pass
            except TypeError:
                pass

        # Any specific IdP specified in a query part
        query = self.environ.get("QUERY_STRING")
        if not idp_entity_id and query:
            try:
                _idp_entity_id = dict(parse_qs(query))[self.idp_query_param][0]
                if _idp_entity_id in idps:
                    idp_entity_id = _idp_entity_id
            except KeyError:
                logger.debug("No IdP entity ID in query: %s", query)
                pass

        if not idp_entity_id:

            if self.wayf:
                if query:
                    try:
                        wayf_selected = dict(
                            parse_qs(query))["wayf_selected"][0]
                    except KeyError:
                        return self._wayf_redirect(came_from)
                    idp_entity_id = wayf_selected
                else:
                    return self._wayf_redirect(came_from)
            elif self.discosrv:
                if query:
                    idp_entity_id = _cli.parse_discovery_service_response(
                        query=self.environ.get("QUERY_STRING"))
                if not idp_entity_id:
                    sid_ = sid()
                    self.cache.outstanding_queries[sid_] = came_from
                    logger.debug("Redirect to Discovery Service function")
                    eid = _cli.config.entityid
                    ret = _cli.config.getattr("endpoints",
                                              "sp")["discovery_response"][0][0]
                    ret += "?sid=%s" % sid_
                    loc = _cli.create_discovery_service_request(
                        self.discosrv, eid, **{"return": ret})
                    return -1, SeeOther(loc)
            elif len(idps) == 1:
                # idps is a dictionary
                idp_entity_id = list(idps.keys())[0]
            elif not len(idps):
                return -1, ServiceError("Misconfiguration")
            else:
                return -1, NotImplemented("No WAYF or DS present!")

        logger.info("Chosen IdP: '%s'", idp_entity_id)
        return 0, idp_entity_id
Example #10
0
    def _pick_idp(self, came_from):
        """
        If more than one idp and if none is selected, I have to do wayf or
        disco
        """

        _cli = self.sp

        logger.debug("[_pick_idp] %s", self.environ)
        if "HTTP_PAOS" in self.environ:
            if self.environ["HTTP_PAOS"] == PAOS_HEADER_INFO:
                if MIME_PAOS in self.environ["HTTP_ACCEPT"]:
                    # Where should I redirect the user to
                    # entityid -> the IdP to use
                    # relay_state -> when back from authentication

                    logger.debug("- ECP client detected -")

                    _rstate = rndstr()
                    self.cache.relay_state[_rstate] = geturl(self.environ)
                    _entityid = _cli.config.ecp_endpoint(self.environ["REMOTE_ADDR"])

                    if not _entityid:
                        return -1, ServiceError("No IdP to talk to")
                    logger.debug("IdP to talk to: %s", _entityid)
                    return ecp.ecp_auth_request(_cli, _entityid, _rstate)
                else:
                    return -1, ServiceError("Faulty Accept header")
            else:
                return -1, ServiceError("unknown ECP version")

        # Find all IdPs
        idps = self.sp.metadata.with_descriptor("idpsso")

        idp_entity_id = None

        kaka = self.environ.get("HTTP_COOKIE", "")
        if kaka:
            try:
                (idp_entity_id, _) = parse_cookie("ve_disco", "SEED_SAW", kaka)
            except ValueError:
                pass
            except TypeError:
                pass

        # Any specific IdP specified in a query part
        query = self.environ.get("QUERY_STRING")
        if not idp_entity_id and query:
            try:
                _idp_entity_id = dict(parse_qs(query))[self.idp_query_param][0]
                if _idp_entity_id in idps:
                    idp_entity_id = _idp_entity_id
            except KeyError:
                logger.debug("No IdP entity ID in query: %s", query)
                pass

        if not idp_entity_id:

            if self.wayf:
                if query:
                    try:
                        wayf_selected = dict(parse_qs(query))["wayf_selected"][0]
                    except KeyError:
                        return self._wayf_redirect(came_from)
                    idp_entity_id = wayf_selected
                else:
                    return self._wayf_redirect(came_from)
            elif self.discosrv:
                if query:
                    idp_entity_id = _cli.parse_discovery_service_response(
                        query=self.environ.get("QUERY_STRING")
                    )
                if not idp_entity_id:
                    sid_ = sid()
                    self.cache.outstanding_queries[sid_] = came_from
                    logger.debug("Redirect to Discovery Service function")
                    eid = _cli.config.entityid
                    ret = _cli.config.getattr("endpoints", "sp")["discovery_response"][
                        0
                    ][0]
                    ret += "?sid=%s" % sid_
                    loc = _cli.create_discovery_service_request(
                        self.discosrv, eid, **{"return": ret}
                    )
                    return -1, SeeOther(loc)
            elif len(idps) == 1:
                # idps is a dictionary
                idp_entity_id = list(idps.keys())[0]
            elif not len(idps):
                return -1, ServiceError("Misconfiguration")
            else:
                return -1, NotImplemented("No WAYF or DS present!")

        logger.info("Chosen IdP: '%s'", idp_entity_id)
        return 0, idp_entity_id