Example #1
0
 def _authn_statement(self,
                      authn_class=None,
                      authn_auth=None,
                      authn_decl=None,
                      authn_decl_ref=None):
     """
     Construct the AuthnStatement
     :param authn_class: Authentication Context Class reference
     :param authn_auth: Authenticating Authority
     :param authn_decl: Authentication Context Declaration
     :param authn_decl_ref: Authentication Context Declaration reference
     :return: An AuthnContext instance
     """
     if authn_class:
         return factory(saml.AuthnStatement,
                        authn_instant=instant(),
                        session_index=sid(),
                        authn_context=self._authn_context_class_ref(
                            authn_class, authn_auth))
     elif authn_decl:
         return factory(saml.AuthnStatement,
                        authn_instant=instant(),
                        session_index=sid(),
                        authn_context=self._authn_context_decl(
                            authn_decl, authn_auth))
     elif authn_decl_ref:
         return factory(saml.AuthnStatement,
                        authn_instant=instant(),
                        session_index=sid(),
                        authn_context=self._authn_context_decl_ref(
                            authn_decl_ref, authn_auth))
     else:
         return factory(saml.AuthnStatement,
                        authn_instant=instant(),
                        session_index=sid())
Example #2
0
 def _authn_statement(self, authn_class=None, authn_auth=None,
                      authn_decl=None, authn_decl_ref=None):
     """
     Construct the AuthnStatement
     :param authn_class: Authentication Context Class reference
     :param authn_auth: Authenticating Authority
     :param authn_decl: Authentication Context Declaration
     :param authn_decl_ref: Authentication Context Declaration reference
     :return: An AuthnContext instance
     """
     if authn_class:
         return factory(
             saml.AuthnStatement,
             authn_instant=instant(),
             session_index=sid(),
             authn_context=self._authn_context_class_ref(
                 authn_class, authn_auth))
     elif authn_decl:
         return factory(
             saml.AuthnStatement,
             authn_instant=instant(),
             session_index=sid(),
             authn_context=self._authn_context_decl(authn_decl, authn_auth))
     elif authn_decl_ref:
         return factory(
             saml.AuthnStatement,
             authn_instant=instant(),
             session_index=sid(),
             authn_context=self._authn_context_decl_ref(authn_decl_ref,
                                                        authn_auth))
     else:
         return factory(
             saml.AuthnStatement,
             authn_instant=instant(),
             session_index=sid())
Example #3
0
def authn_statement(authn_class=None,
                    authn_auth=None,
                    authn_decl=None,
                    authn_decl_ref=None,
                    authn_instant="",
                    subject_locality="",
                    session_not_on_or_after=None):
    """
    Construct the AuthnStatement
    :param authn_class: Authentication Context Class reference
    :param authn_auth: Authenticating Authority
    :param authn_decl: Authentication Context Declaration
    :param authn_decl_ref: Authentication Context Declaration reference
    :param authn_instant: When the Authentication was performed.
        Assumed to be seconds since the Epoch.
    :param subject_locality: Specifies the DNS domain name and IP address
        for the system from which the assertion subject was apparently
        authenticated.
    :return: An AuthnContext instance
    """
    if authn_instant:
        _instant = instant(time_stamp=authn_instant)
    else:
        _instant = instant()

    if authn_class:
        res = factory(saml.AuthnStatement,
                      authn_instant=_instant,
                      session_index=sid(),
                      session_not_on_or_after=session_not_on_or_after,
                      authn_context=_authn_context_class_ref(
                          authn_class, authn_auth))
    elif authn_decl:
        res = factory(saml.AuthnStatement,
                      authn_instant=_instant,
                      session_index=sid(),
                      session_not_on_or_after=session_not_on_or_after,
                      authn_context=_authn_context_decl(
                          authn_decl, authn_auth))
    elif authn_decl_ref:
        res = factory(saml.AuthnStatement,
                      authn_instant=_instant,
                      session_index=sid(),
                      session_not_on_or_after=session_not_on_or_after,
                      authn_context=_authn_context_decl_ref(
                          authn_decl_ref, authn_auth))
    else:
        res = factory(saml.AuthnStatement,
                      authn_instant=_instant,
                      session_index=sid(),
                      session_not_on_or_after=session_not_on_or_after)

    if subject_locality:
        res.subject_locality = saml.SubjectLocality(text=subject_locality)

    return res
Example #4
0
def authn_statement(authn_class=None, authn_auth=None,
                    authn_decl=None, authn_decl_ref=None, authn_instant="",
                    subject_locality="", session_not_on_or_after=None):
    """
    Construct the AuthnStatement
    :param authn_class: Authentication Context Class reference
    :param authn_auth: Authenticating Authority
    :param authn_decl: Authentication Context Declaration
    :param authn_decl_ref: Authentication Context Declaration reference
    :param authn_instant: When the Authentication was performed.
        Assumed to be seconds since the Epoch.
    :param subject_locality: Specifies the DNS domain name and IP address
        for the system from which the assertion subject was apparently
        authenticated.
    :return: An AuthnContext instance
    """
    if authn_instant:
        _instant = instant(time_stamp=authn_instant)
    else:
        _instant = instant()

    if authn_class:
        res = factory(
            saml.AuthnStatement,
            authn_instant=_instant,
            session_index=sid(),
            session_not_on_or_after=session_not_on_or_after,
            authn_context=_authn_context_class_ref(
                authn_class, authn_auth))
    elif authn_decl:
        res = factory(
            saml.AuthnStatement,
            authn_instant=_instant,
            session_index=sid(),
            session_not_on_or_after=session_not_on_or_after,
            authn_context=_authn_context_decl(authn_decl, authn_auth))
    elif authn_decl_ref:
        res = factory(
            saml.AuthnStatement,
            authn_instant=_instant,
            session_index=sid(),
            session_not_on_or_after=session_not_on_or_after,
            authn_context=_authn_context_decl_ref(authn_decl_ref,
                                                  authn_auth))
    else:
        res = factory(
            saml.AuthnStatement,
            authn_instant=_instant,
            session_index=sid(),
            session_not_on_or_after=session_not_on_or_after)

    if subject_locality:
        res.subject_locality = saml.SubjectLocality(text=subject_locality)

    return res
Example #5
0
 def add_certificate_to_cache(self, certificate_str):
     _sid = sid()
     while _sid in self.certificate_cache():
         _sid = sid()
     cache = self.certificate_cache()
     cache[_sid] = {
         "timeout": datetime.datetime.now() + datetime.timedelta(minutes=self.sp_conf.CERT_TIMEOUT),
         "cert": base64.b64encode(certificate_str)
     }
     self.sphandlercache[self.certificate_cache_name] = cache
     return _sid
Example #6
0
 def add_certificate_to_cache(self, certificate_str):
     _sid = sid()
     while _sid in self.certificate_cache():
         _sid = sid()
     cache = self.certificate_cache()
     cache[_sid] = {
         "timeout":
         datetime.datetime.now() +
         datetime.timedelta(minutes=self.sp_conf.CERT_TIMEOUT),
         "cert":
         base64.b64encode(certificate_str)
     }
     self.sphandlercache[self.certificate_cache_name] = cache
     return _sid
Example #7
0
def entities_descriptor(eds, valid_for, name, ident, sign, secc):
    entities = md.EntitiesDescriptor(entity_descriptor=eds)
    if valid_for:
        entities.valid_until = in_a_while(hours=valid_for)
    if name:
        entities.name = name
    if ident:
        entities.id = ident

    if sign:
        if not ident:
            ident = sid()

        if not secc.key_file:
            raise Exception("If you want to do signing you should define " +
                            "a key to sign with")

        if not secc.my_cert:
            raise Exception("If you want to do signing you should define " +
                            "where your public key are")

        entities.signature = pre_signature_part(ident, secc.my_cert, 1)
        entities.id = ident
        xmldoc = secc.sign_statement("%s" % entities, class_name(entities))
        entities = md.entities_descriptor_from_string(xmldoc)
    return entities
Example #8
0
 def persistent(self, entity_id, subject_id):
     """ Keeps the link between a permanent identifier and a 
     temporary/pseudo-temporary identifier for a subject
     
     The store supports look-up both ways: from a permanent local
     identifier to a identifier used talking to a SP and from an
     identifier given back by an SP to the local permanent.
     
     :param entity_id: SP entity ID or VO entity ID
     :param subject_id: The local permanent identifier of the subject
     :return: An arbitrary identifier for the subject unique to the
         service/group of services/VO with a given entity_id
     """
     try:
         return self._get_remote("persistent", entity_id, subject_id)
     except KeyError:
         temp_id = "xyz"
         while True:
             temp_id = sid()
             try:
                 self._get_local("persistent", entity_id, temp_id)
             except KeyError:
                 break
         self._store("persistent", entity_id, subject_id, temp_id)
         self.map.sync()
         
         return temp_id
Example #9
0
    def authz_decision_query(self, entityid, action,
                                evidence=None, resource=None, subject=None,
                                binding=saml2.BINDING_HTTP_REDIRECT, sign=None):
        """ Creates an authz decision query.

        :param entityid: The entity ID of the IdP to send the request to
        :param action: The action you want to perform (has to be at least one)
        :param evidence: Why you should be able to perform the action
        :param resource: The resource you want to perform the action on
        :param subject: Who wants to do the thing
        :param binding: Which binding to use for sending the request
        :param sign: Whether the request should be signed or not.
        :return: AuthzDecisionQuery instance
        """

        spentityid = self._issuer()
        service_url = self.service_url()
        my_name = self._my_name()

        logger.info("spentityid: %s\nservice_url: %s\nmy_name: %s" % (
                            spentityid, service_url, my_name))

#        authen_req = self.authn_request(session_id, location,
#                                service_url, spentityid, my_name, vorg,
#                                scoping, sign)
        
        request = samlp.AuthzDecisionQuery(action, evidence, resource,
                                           subject=subject,
                                           issuer=spentityid,
                                           id=sid(),
                                           issue_instant=instant(),
                                           version=VERSION,
                                           destination=entityid)

        return request
Example #10
0
def test_create_artifact_resolve():
    b64art = create_artifact(SP, "aabbccddeeffgghhiijj", 1)
    artifact = base64.b64decode(b64art)

    #assert artifact[:2] == '\x00\x04'
    #assert int(artifact[2:4]) == 0
    #
    s = sha1(SP)
    assert artifact[4:24] == s.digest()

    idp = Server(config_file="idp_all_conf")

    typecode = artifact[:2]
    assert typecode == ARTIFACT_TYPECODE

    destination = idp.artifact2destination(b64art, "spsso")

    msg = idp.create_artifact_resolve(b64art, destination, sid())

    print msg

    args = idp.use_soap(msg, destination, None, False)

    sp = Saml2Client(config_file="servera_conf")

    ar = sp.parse_artifact_resolve(args["data"])

    print ar

    assert ar.artifact.text == b64art
Example #11
0
    def _handle_discovery_request(self):
        """Handle SAML Discovery Service request. This method is called
        internally by the `authenticate` method when multiple acceptable IdPs
        are detected.

        Returns:
            Tuple containing session Id and Flask Response object to return to
                user containing either HTTP_REDIRECT to configured Discovery
                Service end point.

        Raises:
            AuthException: when unable to find discovery response end point.
        """
        session_id = sid()
        try:
            return_url = self._config.getattr('endpoints',
                                              'sp')['discovery_response'][0][0]
        except KeyError:
            raise AuthException(
                "Multiple IdPs configured with no configured Discovery" + \
                " response end point.")
        return_url += "?session_id=%s" % session_id
        disco_url = Saml2Client.create_discovery_service_request(
            self.discovery_service_end_point, self._config.entityid,
            **{'return': return_url})
        LOGGER.debug("Redirect to Discovery Service %s", disco_url)
        return (session_id, make_response('', 302, {'Location': disco_url}))
Example #12
0
    def _status_response(self, response_class, issuer, status, sign=False,
                         **kwargs):
        """ Create a StatusResponse.

        :param response_class: Which subclass of StatusResponse that should be
            used
        :param issuer: The issuer of the response message
        :param status: The return status of the response operation
        :param sign: Whether the response should be signed or not
        :param kwargs: Extra arguments to the response class
        :return: Class instance or string representation of the instance
        """

        mid = sid()

        for key in ["destination", "binding"]:
            try:
                del kwargs[key]
            except KeyError:
                pass

        if not status:
            status = success_status_factory()

        response = response_class(issuer=issuer, id=mid, version=VERSION,
                                  issue_instant=instant(),
                                  status=status, **kwargs)

        if sign:
            return self.sign(response, mid)
        else:
            return response
Example #13
0
    def make_logout_response(self,
                             idp_entity_id,
                             request_id,
                             status_code,
                             binding=BINDING_HTTP_REDIRECT):
        """ Constructs a LogoutResponse

        :param idp_entity_id: The entityid of the IdP that want to do the
            logout
        :param request_id: The Id of the request we are replying to
        :param status_code: The status code of the response
        :param binding: The type of binding that will be used for the response
        :return: A LogoutResponse instance
        """

        destination = self.config.single_logout_services(
            idp_entity_id, binding)[0]

        status = samlp.Status(status_code=samlp.StatusCode(value=status_code))

        response = samlp.LogoutResponse(
            id=sid(),
            version=VERSION,
            issue_instant=instant(),
            destination=destination,
            issuer=self._issuer(),
            in_response_to=request_id,
            status=status,
        )

        return response, destination
Example #14
0
def entities_descriptor(eds, valid_for, name, ident, sign, secc):
    entities = md.EntitiesDescriptor(entity_descriptor=eds)
    if valid_for:
        entities.valid_until = in_a_while(hours=valid_for)
    if name:
        entities.name = name
    if ident:
        entities.id = ident

    if sign:
        if not ident:
            ident = sid()

        if not secc.key_file:
            raise SAMLError("If you want to do signing you should define " +
                            "a key to sign with")

        if not secc.my_cert:
            raise SAMLError("If you want to do signing you should define " +
                            "where your public key are")

        entities.signature = pre_signature_part(ident, secc.my_cert, 1)
        entities.id = ident
        xmldoc = secc.sign_statement("%s" % entities, class_name(entities))
        entities = md.entities_descriptor_from_string(xmldoc)
    else:
        xmldoc = None

    return entities, xmldoc
Example #15
0
def test_create_artifact_resolve():
    b64art = create_artifact(SP, "aabbccddeeffgghhiijj", 1)
    artifact = base64.b64decode(b64art)

    #assert artifact[:2] == '\x00\x04'
    #assert int(artifact[2:4]) == 0
    #
    s = sha1(SP.encode('ascii'))
    assert artifact[4:24] == s.digest()

    with closing(Server(config_file="idp_all_conf")) as idp:
        typecode = artifact[:2]
        assert typecode == ARTIFACT_TYPECODE

        destination = idp.artifact2destination(b64art, "spsso")

        msg_id, msg = idp.create_artifact_resolve(b64art, destination, sid())

        print(msg)

        args = idp.use_soap(msg, destination, None, False)

        sp = Saml2Client(config_file="servera_conf")

        ar = sp.parse_artifact_resolve(args["data"])

        print(ar)

        assert ar.artifact.text == b64art
Example #16
0
    def multiple_signatures(self, statement, to_sign, key=None, key_file=None):
        """
        Sign multiple parts of a statement

        :param statement: The statement that should be sign, this is XML text
        :param to_sign: A list of (items, id, id attribute name) tuples that
            specifies what to sign
        :param key: A key that should be used for doing the signing
        :param key_file: A file that contains the key to be used
        :return: A possibly multiple signed statement
        """
        for (item, id, id_attr) in to_sign:
            if not id:
                if not item.id:
                    id = item.id = sid()
                else:
                    id = item.id

            if not item.signature:
                item.signature = pre_signature_part(id, self.cert_file)

            statement = self.sign_statement_using_xmlsec(statement,
                                                         class_name(item),
                                                         key=key,
                                                         key_file=key_file,
                                                         nodeid=id,
                                                         id_attr=id_attr)
        return statement
Example #17
0
    def multiple_signatures(self, statement, to_sign, key=None, key_file=None):
        """
        Sign multiple parts of a statement

        :param statement: The statement that should be sign, this is XML text
        :param to_sign: A list of (items, id, id attribute name) tuples that
            specifies what to sign
        :param key: A key that should be used for doing the signing
        :param key_file: A file that contains the key to be used
        :return: A possibly multiple signed statement
        """
        for (item, sid, id_attr) in to_sign:
            if not sid:
                if not item.id:
                    sid = item.id = sid()
                else:
                    sid = item.id

            if not item.signature:
                item.signature = pre_signature_part(sid, self.cert_file)

            statement = self.sign_statement(statement, class_name(item),
                                            key=key, key_file=key_file,
                                            node_id=sid, id_attr=id_attr)
        return statement
Example #18
0
    def authenticate(self,
                     entityid=None,
                     relay_state="",
                     binding=BINDING_HTTP_REDIRECT,
                     log=None,
                     vorg="",
                     scoping=None,
                     sign=None,
                     **kwargs):
        """ Makes an authentication request.

        :param entityid: The entity ID of the IdP to send the request to
        :param relay_state: To where the user should be returned after
            successfull log in.
        :param binding: Which binding to use for sending the request
        :param log: Where to write log messages
        :param vorg: The entity_id of the virtual organization I'm a member of
        :param scoping: For which IdPs this query are aimed.
        :param sign: Whether the request should be signed or not.
        :return: AuthnRequest response
        """
        destination = self._sso_location(entityid, binding=binding)
        session_id = sid()

        _req_str = "%s" % self.authn(destination, session_id, vorg, scoping,
                                     log, sign, **kwargs)

        logger.info("AuthNReq: %s" % _req_str)

        info = self.apply_binding(binding, _req_str, destination, relay_state)
        return session_id, info
Example #19
0
    def authenticate(self, entityid=None, relay_state="",
                     binding=BINDING_HTTP_REDIRECT,
                     log=None, vorg="", scoping=None, sign=None, **kwargs):
        """ Makes an authentication request.

        :param entityid: The entity ID of the IdP to send the request to
        :param relay_state: To where the user should be returned after
            successfull log in.
        :param binding: Which binding to use for sending the request
        :param log: Where to write log messages
        :param vorg: The entity_id of the virtual organization I'm a member of
        :param scoping: For which IdPs this query are aimed.
        :param sign: Whether the request should be signed or not.
        :return: AuthnRequest response
        """
        destination = self._sso_location(entityid, binding=binding)
        session_id = sid()

        _req_str = "%s" % self.authn(destination, session_id, vorg, scoping, log,
                                       sign, **kwargs)

        logger.info("AuthNReq: %s" % _req_str)

        info = self.apply_binding(binding, _req_str, destination, relay_state)
        return session_id, info
Example #20
0
    def construct_logout_request(self, subject_id, destination, issuer_entity_id, reason=None, expire=None):
        """ Constructs a LogoutRequest
        
        :param subject_id: The identifier of the subject
        :param destination:
        :param issuer_entity_id: The entity ID of the IdP the request is
            target at.
        :param reason: An indication of the reason for the logout, in the
            form of a URI reference.
        :param expire: The time at which the request expires,
            after which the recipient may discard the message.
        :return: A LogoutRequest instance
        """

        session_id = sid()
        # create NameID from subject_id
        name_id = saml.NameID(text=self.users.get_entityid(subject_id, issuer_entity_id, False))

        request = samlp.LogoutRequest(
            id=session_id,
            version=VERSION,
            issue_instant=instant(),
            destination=destination,
            issuer=self.issuer(),
            name_id=name_id,
        )

        if reason:
            request.reason = reason

        if expire:
            request.not_on_or_after = expire

        return request
Example #21
0
    def make_logout_response(self, idp_entity_id, request_id, status_code, binding=BINDING_HTTP_REDIRECT):
        """ Constructs a LogoutResponse

        :param idp_entity_id: The entityid of the IdP that want to do the
            logout
        :param request_id: The Id of the request we are replying to
        :param status_code: The status code of the response
        :param binding: The type of binding that will be used for the response
        :return: A LogoutResponse instance
        """

        destination = self.config.single_logout_services(idp_entity_id, binding)[0]

        status = samlp.Status(status_code=samlp.StatusCode(value=status_code))

        response = samlp.LogoutResponse(
            id=sid(),
            version=VERSION,
            issue_instant=instant(),
            destination=destination,
            issuer=self.issuer(),
            in_response_to=request_id,
            status=status,
        )

        return response, destination
Example #22
0
    def _status_response(self, response_class, issuer, status, sign=False,
                         **kwargs):
        """ Create a StatusResponse.

        :param response_class: Which subclass of StatusResponse that should be
            used
        :param issuer: The issuer of the response message
        :param status: The return status of the response operation
        :param sign: Whether the response should be signed or not
        :param kwargs: Extra arguments to the response class
        :return: Class instance or string representation of the instance
        """

        mid = sid()

        for key in ["destination", "binding"]:
            try:
                del kwargs[key]
            except KeyError:
                pass

        if not status:
            status = success_status_factory()

        response = response_class(issuer=issuer, id=mid, version=VERSION,
                                  issue_instant=instant(),
                                  status=status, **kwargs)

        if sign:
            return self.sign(response, mid)
        else:
            return response
Example #23
0
    def _handle_discovery_request(self):
        """Handle SAML Discovery Service request. This method is called
        internally by the `authenticate` method when multiple acceptable IdPs
        are detected.

        Returns:
            Tuple containing session Id and Flask Response object to return to
                user containing either HTTP_REDIRECT to configured Discovery
                Service end point.

        Raises:
            AuthException: when unable to find discovery response end point.
        """
        session_id = sid()
        try:
            return_url = self._config.getattr(
                'endpoints', 'sp')['discovery_response'][0][0]
        except KeyError:
            raise AuthException(
                "Multiple IdPs configured with no configured Discovery" + \
                " response end point.")
        return_url += "?session_id=%s" % session_id
        disco_url = Saml2Client.create_discovery_service_request(
            self.discovery_service_end_point,
            self._config.entityid, **{'return': return_url})
        LOGGER.debug("Redirect to Discovery Service %s", disco_url)
        return (session_id, make_response('', 302, {'Location': disco_url}))
Example #24
0
 def __init__(self, sp_logger, args):
     """
     Constructor for the SpHandler.
     :param sp_logger: A logger.
     """
     #Metadata for the SP
     self.sp_metadata = create_metadata_string(args.spconf + ".py", None,
                                               args.valid, args.cert,
                                               args.keyfile, args.id_sp,
                                               args.name_sp, args.sign)
     #Log class. (see import logging)
     self.logger = sp_logger
     #Configurations for the SP handler. (pyOpSamlProxy.client.sp.conf)
     self.sp_conf = importlib.import_module(
         args.spconf)  #pyOpSamlProxy.client.sp.conf
     #Name of the configuration file. See above.
     self.sp_conf_name = self.sp_conf.WORKING_DIR + args.spconf
     #SP configuration object. (See project pysaml2; saml2.client.Saml2Client)
     self.sp = Saml2Client(config_file="%s" % self.sp_conf_name)
     #Extra arguments for the pyOpSamlProxy.client.sp.util.SSO object.
     self.args = {}
     #URL to SAML discovery server.
     self.args["discosrv"] = self.sp_conf.DISCOSRV
     #URL to SAML WAYF server.
     self.args["wayf"] = self.sp_conf.WAYF
     #URL to op server authorization when the SP have been authenticated.
     #TODO have to be changed when Saml to Saml is implemented.
     self.authorization_url = "%s/authorization" % self.sp_conf.ISSUER
     #Handles the SAML authentication for an op server.
     self.authnmethod = SPAuthnMethodHandler(None,
                                             self.sp_conf.SPVERIFYBASE,
                                             self.authorization_url)
     #Handles SAML authentication for an IdP server.
     # Setup performed by pyOpSamlProxy.provider.idp.handler.handler.
     self.sp_authentication = None
     #Handles the user info response with Saml attributes.
     self.userinfo = UserInfoSpHandler(self.sp_conf.OPENID2SAMLMAP, self)
     #The handler for the op server. Must be set after creation
     #This must be the instance of the class pyOpSamlProxy.provider.op.handler.OpHandler.
     self.ophandler = None
     #Contains the user cache for the SpHandler, like collected IdP attributes.
     #Dictionary where userid is key and value is an instance of the class
     #pyOpSamlProxy.client.sp.handler.SpHandlerCache
     self.sphandlercache = self.sp_conf.CACHE
     self.certificate_cache_name = "CERTIFICATE_CACHE"
     self.certificate_cookie_name = sid()
     self.certificate_cookie_seed = sid()
Example #25
0
 def _authn_statement(self, authn_class=None, authn_auth=None, 
                         authn_decl=None):
     if authn_class:
         return factory(saml.AuthnStatement, 
                     authn_instant=instant(), 
                     session_index=sid(),
                     authn_context=self._authn_context_class_ref(
                                                 authn_class, authn_auth))
     elif authn_decl:
         return factory(saml.AuthnStatement, 
                     authn_instant=instant(), 
                     session_index=sid(),
                     authn_context=self._authn_context_decl_ref(authn_decl))
     else:
         return factory(saml.AuthnStatement,
                     authn_instant=instant(), 
                     session_index=sid())
Example #26
0
 def _authn_statement(self, authn_class=None, authn_auth=None, authn_decl=None):
     if authn_class:
         return factory(
             saml.AuthnStatement,
             authn_instant=instant(),
             session_index=sid(),
             authn_context=self._authn_context_class_ref(authn_class, authn_auth),
         )
     elif authn_decl:
         return factory(
             saml.AuthnStatement,
             authn_instant=instant(),
             session_index=sid(),
             authn_context=self._authn_context_decl_ref(authn_decl),
         )
     else:
         return factory(saml.AuthnStatement, authn_instant=instant(), session_index=sid())
Example #27
0
def sign_entity_descriptor(edesc, ident, secc):
    if not ident:
        ident = sid()

    edesc.signature = pre_signature_part(ident, secc.my_cert, 1)
    edesc.id = ident
    xmldoc = secc.sign_statement_using_xmlsec("%s" % edesc, class_name(edesc))
    return md.entity_descriptor_from_string(xmldoc)
Example #28
0
def sign_entity_descriptor(edesc, ident, secc):
    if not ident:
        ident = sid()

    edesc.signature = pre_signature_part(ident, secc.my_cert, 1)
    edesc.id = ident
    xmldoc = secc.sign_statement("%s" % edesc, class_name(edesc))
    return md.entity_descriptor_from_string(xmldoc)
Example #29
0
 def _wayf_redirect(self, cookie):
     sid_ = sid()
     self.cache_outstanding_queries[sid_] = self.verification_endpoint
     return (
         -1,
         SeeOther(
             headers=[("Location", "%s?%s" % (self.sp_conf.WAYF, sid_)), cookie]
         ),
     )
def authentication_request(cls, ecp, idp_entity_id, destination,
                           log=None, sign=False):
    """ Does a authentication request to an Identity provider.
    This function uses the SOAP binding other bindings could be used but are
    not
    supported right now.

    :param cls: The SAML2 client instance
    :param ecp: The ECP client instance
    :param idp_entity_id: The identifier of the subject
    :param destination: To whom the query should be sent
    :param log: Function to use for logging
    :param sign: Whether the request should be signed or not
    :return: A Authentication Response
    """

    if log is None:
        log = cls.logger

    session_id = sid()
    acsus = cls.config.endpoint('assertion_consumer_service',
                                saml2.BINDING_PAOS)
    if not acsus and log:
        log.error("Couldn't find own PAOS endpoint")
        
    acsu = acsus[0]

    spentityid = cls.config.entityid

    # create the request
    request = cls.authn_request(session_id,
                                destination,
                                acsu,
                                spentityid,
                                "",
                                log=LOG(),
                                sign=sign,
                                binding=saml2.BINDING_PAOS,
                                nameid_format=saml.NAMEID_FORMAT_PERSISTENT)

    try:
        try:
            headers = {config.USERNAME_HEADER: ecp.user}
        except AttributeError:
            headers = None

        print >> sys.stderr, "Headers: {0:>s}".format(headers)
            
        # send the request and receive the response
        response = ecp.phase2(request, acsu, idp_entity_id, headers,
                              destination)
    except Exception, exc:
        exception_trace("soap", exc, log)
        if log:
            log.info("SoapClient exception: %s" % (exc,))
        return None
Example #31
0
    def transient_nameid(self, sp_entity_id, userid):
        """ Returns a random one-time identifier. One-time means it is
        kept around as long as the session is active.
        
        :param sp_entity_id: A qualifier to bind the created identifier to
        :param userid: The local persistent identifier for the subject.
        :return: The created identifier,
        """
        temp_id = sid()
        while True:
            try:
                _ = self._get_local("transient", sp_entity_id, temp_id)
                temp_id = sid()
            except KeyError:
                break
        self._store("transient", sp_entity_id, userid, temp_id)
        self.map.sync()

        return saml.NameID(format=saml.NAMEID_FORMAT_TRANSIENT, sp_name_qualifier=sp_entity_id, text=temp_id)
Example #32
0
    def message_args(self, message_id=0):
        if not message_id:
            message_id = sid(self.seed)

        return {
            "id": message_id,
            "version": VERSION,
            "issue_instant": instant(),
            "issuer": self._issuer()
        }
Example #33
0
 def __init__(self, sp_logger, args):
     """
     Constructor for the SpHandler.
     :param sp_logger: A logger.
     """
     #Metadata for the SP
     self.sp_metadata = create_metadata_string(args.spconf + ".py", None, args.valid, args.cert, args.keyfile,
                                               args.id_sp, args.name_sp, args.sign)
     #Log class. (see import logging)
     self.logger = sp_logger
     #Configurations for the SP handler. (pyOpSamlProxy.client.sp.conf)
     self.sp_conf = importlib.import_module(args.spconf)  #pyOpSamlProxy.client.sp.conf
     #Name of the configuration file. See above.
     self.sp_conf_name = self.sp_conf.WORKING_DIR + args.spconf
     #SP configuration object. (See project pysaml2; saml2.client.Saml2Client)
     self.sp = Saml2Client(config_file="%s" % self.sp_conf_name)
     #Extra arguments for the pyOpSamlProxy.client.sp.util.SSO object.
     self.args = {}
     #URL to SAML discovery server.
     self.args["discosrv"] = self.sp_conf.DISCOSRV
     #URL to SAML WAYF server.
     self.args["wayf"] = self.sp_conf.WAYF
     #URL to op server authorization when the SP have been authenticated.
     #TODO have to be changed when Saml to Saml is implemented.
     self.authorization_url = "%s/authorization" % self.sp_conf.ISSUER
     #Handles the SAML authentication for an op server.
     self.authnmethod = SPAuthnMethodHandler(None, self.sp_conf.SPVERIFYBASE, self.authorization_url)
     #Handles SAML authentication for an IdP server.
     # Setup performed by pyOpSamlProxy.provider.idp.handler.handler.
     self.sp_authentication = None
     #Handles the user info response with Saml attributes.
     self.userinfo = UserInfoSpHandler(self.sp_conf.OPENID2SAMLMAP, self)
     #The handler for the op server. Must be set after creation
     #This must be the instance of the class pyOpSamlProxy.provider.op.handler.OpHandler.
     self.ophandler = None
     #Contains the user cache for the SpHandler, like collected IdP attributes.
     #Dictionary where userid is key and value is an instance of the class
     #pyOpSamlProxy.client.sp.handler.SpHandlerCache
     self.sphandlercache = self.sp_conf.CACHE
     self.certificate_cache_name = "CERTIFICATE_CACHE"
     self.certificate_cookie_name = sid()
     self.certificate_cookie_seed = sid()
Example #34
0
def sign_entity_descriptor(edesc, valid_for, ident, secc):
    if valid_for:
        edesc.valid_until = in_a_while(hours=valid_for)

    if not ident:
        ident = sid()

    edesc.signature = pre_signature_part(ident, secc.my_cert, 1)
    edesc.id = ident
    xmldoc = secc.sign_statement_using_xmlsec("%s" % edesc, class_name(edesc))
    return md.entity_descriptor_from_string(xmldoc)
Example #35
0
 def construct_message(self):
     session_id = sid()  # Should be bound to session
     sp = self.entity
     url = sp.config.getattr("endpoints", "sp")["discovery_response"][0][0]
     return_to = "{url}?{query}".format(url=url, query=urlencode(({"sid": session_id})))
     redirect_url = sp.create_discovery_service_request(
         self.req_args["discovery_service_url"], sp.config.entityid, **{"return": return_to}
     )
     logger.debug("Redirect to Discovery Service: %s", redirect_url)
     self.conv.events.store(EV_REDIRECT_URL, redirect_url, sub="construct_message", sender=self.__class__)
     return SeeOther(redirect_url)
Example #36
0
def sign_entity_descriptor(edesc, valid_for, ident, secc):
    if valid_for:
        edesc.valid_until = in_a_while(hours=valid_for)

    if not ident:
        ident = sid()

    edesc.signature = pre_signature_part(ident, secc.my_cert, 1)
    edesc.id = ident
    xmldoc = secc.sign_statement_using_xmlsec("%s" % edesc, class_name(edesc))
    return md.entity_descriptor_from_string(xmldoc)
Example #37
0
def disco_srv(environ, start_response):
    disco_url = environ["PATH_INFO"][4:]
    sid_ = sid()
    #SP.cache.outstanding_queries[sid_] = "/userinfo"
    logger.info("Redirect to Discovery Service function")
    eid = SP.config.entityid
    ret = SP.config.getattr("endpoints", "sp")["discovery_response"][0][0]
    ret += "?sid=%s" % sid_
    loc = SP.create_discovery_service_request(disco_url, eid,
                                              **{"return": ret})
    resp = SeeOther(loc)
    return resp(environ, start_response)
Example #38
0
def disco_srv(environ, start_response):
    disco_url = environ["PATH_INFO"][4:]
    sid_ = sid()
    #SP.cache.outstanding_queries[sid_] = "/userinfo"
    logger.info("Redirect to Discovery Service function")
    eid = SP.config.entityid
    ret = SP.config.getattr("endpoints", "sp")["discovery_response"][0][0]
    ret += "?sid=%s" % sid_
    loc = SP.create_discovery_service_request(disco_url, eid,
                                              **{"return": ret})
    resp = SeeOther(loc)
    return resp(environ, start_response)
Example #39
0
def attribute_query(cls, subject_id, destination, attribute=None, name_id=None,
                    sp_name_qualifier=None, name_qualifier=None,
                    nameid_format=None, sign=False):
    """ Does a attribute request to an attribute authority, this is
    by default done over SOAP. Other bindings could be used but are not
    supported right now.

    :param subject_id: The identifier of the subject
    :param destination: To whom the query should be sent
    :param attribute: A dictionary of attributes and values that is asked for
    :param name_id: A NameID instance that describes the entity the information
        is asked for.
    :param sp_name_qualifier: The unique identifier of the
        service provider or affiliation of providers for whom the
        identifier was generated.
    :param name_qualifier: The unique identifier of the identity
        provider that generated the identifier.
    :param nameid_format: The format of the name ID
    :param sign: Whether the request should be signed or not
    :return: The Assertion
    """

    global CLIENT

    logger = LOG()
    session_id = sid()

    if not name_id:
        args = {
            "subject_id": subject_id,
            "sp_name_qualifier": sp_name_qualifier,
            "format": nameid_format,
            "name_qualifier": name_qualifier
        }
        if not name_qualifier and not sp_name_qualifier:
            args["sp_name_qualifier"] = cls.config.entityid
    else:
        args = {"name_id": name_id}

    if sign:
        args["sign_prepare"] = True

    request = cls.create_attribute_query(destination,
                                         attribute=attribute,
                                         message_id=session_id,
                                         **args)

    try:
        args = CLIENT.use_soap(request, destination, sign=sign)
        response = CLIENT.send(**args)
    except Exception, exc:
        exception_trace("SoapClient exception", exc, logger)
        return None
Example #40
0
    def attribute_query(self,
                        subject_id,
                        destination,
                        issuer_id=None,
                        attribute=None,
                        sp_name_qualifier=None,
                        name_qualifier=None,
                        nameid_format=None,
                        real_id=None):
        """ Does a attribute request to an attribute authority, this is
        by default done over SOAP. Other bindings could be used but not
        supported right now.
        
        :param subject_id: The identifier of the subject
        :param destination: To whom the query should be sent
        :param issuer_id: Who is sending this query
        :param attribute: A dictionary of attributes and values that is asked for
        :param sp_name_qualifier: The unique identifier of the
            service provider or affiliation of providers for whom the
            identifier was generated.
        :param name_qualifier: The unique identifier of the identity
            provider that generated the identifier.
        :param nameid_format: The format of the name ID
        :param real_id: The identifier which is the key to this entity in the
            identity database
        :return: The attributes returned
        """

        session_id = sid()
        issuer = self._issuer(issuer_id)

        request = self.create_attribute_query(session_id,
                                              subject_id,
                                              destination,
                                              issuer,
                                              attribute,
                                              sp_name_qualifier,
                                              name_qualifier,
                                              nameid_format=nameid_format)

        logger.info("Request, created: %s" % request)

        soapclient = SOAPClient(destination,
                                self.config.key_file,
                                self.config.cert_file,
                                ca_certs=self.config.ca_certs)
        logger.info("SOAP client initiated")

        try:
            response = soapclient.send(request)
        except Exception, exc:
            logger.info("SoapClient exception: %s" % (exc, ))
            return None
Example #41
0
    def transient_nameid(self, sp_entity_id, userid):
        """ Returns a random one-time identifier. One-time means it is
        kept around as long as the session is active.
        
        :param sp_entity_id: A qualifier to bind the created identifier to
        :param userid: The local persistent identifier for the subject.
        :return: The created identifier,
        """
        temp_id = sid()
        while True:
            try:
                _ = self._get_local("transient", sp_entity_id, temp_id)
                temp_id = sid()
            except KeyError:
                break
        self._store("transient", sp_entity_id, userid, temp_id)
        self.map.sync()

        return saml.NameID(format=saml.NAMEID_FORMAT_TRANSIENT,
                            sp_name_qualifier=sp_entity_id,
                            text=temp_id)
Example #42
0
    def _message(self,
                 request_cls,
                 destination=None,
                 message_id=0,
                 consent=None,
                 extensions=None,
                 sign=False,
                 sign_prepare=False,
                 nsprefix=None,
                 **kwargs):
        """
        Some parameters appear in all requests so simplify by doing
        it in one place

        :param request_cls: The specific request type
        :param destination: The recipient
        :param message_id: A message identifier
        :param consent: Whether the principal have given her consent
        :param extensions: Possible extensions
        :param sign: Whether the request should be signed or not.
        :param sign_prepare: Whether the signature should be prepared or not.
        :param kwargs: Key word arguments specific to one request type
        :return: A tuple containing the request ID and an instance of the
            request_cls
        """
        if not message_id:
            message_id = sid()

        for key, val in self.message_args(message_id).items():
            if key not in kwargs:
                kwargs[key] = val

        req = request_cls(**kwargs)
        reqid = req.id

        if destination:
            req.destination = destination

        if consent:
            req.consent = "true"

        if extensions:
            req.extensions = extensions

        if nsprefix:
            req.register_prefix(nsprefix)

        if sign:
            return reqid, self.sign(req, sign_prepare=sign_prepare)
        else:
            logger.info("REQUEST: %s" % req)
            return reqid, req
def attribute_query(cls, subject_id, destination, issuer_id=None,
                    attribute=None, sp_name_qualifier=None, name_qualifier=None,
                    nameid_format=None, log=None, sign=False):
    """ Does a attribute request to an attribute authority, this is
    by default done over SOAP. Other bindings could be used but are not
    supported right now.

    :param subject_id: The identifier of the subject
    :param destination: To whom the query should be sent
    :param issuer_id: Who is sending this query
    :param attribute: A dictionary of attributes and values that is asked for
    :param sp_name_qualifier: The unique identifier of the
        service provider or affiliation of providers for whom the
        identifier was generated.
    :param name_qualifier: The unique identifier of the identity
        provider that generated the identifier.
    :param nameid_format: The format of the name ID
    :param log: Function to use for logging
    :param sign: Whether the request should be signed or not
    :return: The Assertion
    """

    if log is None:
        log = cls.logger

    session_id = sid()
    issuer = cls.issuer(issuer_id)

    if not name_qualifier and not sp_name_qualifier:
        sp_name_qualifier = cls.config.entityid

    request = cls.create_attribute_query(session_id, subject_id,
                                         destination, issuer, attribute,
                                         sp_name_qualifier,
                                         name_qualifier,
                                         nameid_format=nameid_format)

    #    soapclient = HTTP.send(destination, cls.config.key_file,
    #                           cls.config.cert_file)

    if sign:
        request.signature= pre_signature_part(request.id, cls.sec.my_cert, 1)

    try:
        if sign:
            response = HTTP.send(request, path=destination, sign=True,
                                 sec=cls.sec)
        else:
            response = HTTP.send(request, path=destination)
    except Exception, exc:
        exception_trace("SoapClient exception", exc, log)
        return None
Example #44
0
def response_factory(sign=False, encrypt=False, **kwargs):
    response = samlp.Response(id=sid(), version=VERSION,
                              issue_instant=instant())

    if sign:
        response.signature = pre_signature_part(kwargs["id"])
    if encrypt:
        pass

    for key, val in kwargs.items():
        setattr(response, key, val)

    return response
Example #45
0
    def create_authn_request(self):
        try:
            #sid_ = sid()
            #self.outstanding_queries[sid_] = came_from
            idps = self.sp.metadata.with_descriptor("idpsso")
            if len(idps) == 1:
                self.entity_id = idps.keys()[0]
            elif len(idps) > 1:
                raise Exception("TestSp only supports 1 idp in the metadata!")
            else:
                Exception("No IdP metadata found!")

            _binding, destination = self.sp.pick_binding("single_sign_on_service", self.bindings, "idpsso",
                                                         entity_id=self.entity_id)

            self.cert_str, self.cert_key_str = self.generate_cert()
            cert = {
                        "cert": self.cert_str,
                        "key": self.cert_key_str
                    }
            spcertenc = SPCertEnc(
                x509_data=xmldsig.X509Data(x509_certificate=xmldsig.X509Certificate(text=self.cert_str)))
            extensions = Extensions(extension_elements=[element_to_extension_element(spcertenc)])

            try:
                vorg_name = self.sp.vorg._name
            except AttributeError:
                vorg_name = ""

            if self.sp.authn_requests_signed:
                self.sid = s_utils.sid()
                req_id, self.msg_str = self.sp.create_authn_request(destination, vorg=vorg_name,
                                                                    sign=self.sp.authn_requests_signed,
                                                                    message_id=self.sid,
                                                                    extensions=extensions)
                self.sid = req_id
            else:
                req_id, req = self.sp.create_authn_request(destination, vorg=vorg_name, sign=False)
                self.msg_str = "%s" % req
                self.sid = req_id

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

            self.rstate = rndstr()
            self.ht_args = self.sp.apply_binding(_binding, self.msg_str, destination, relay_state=self.rstate)
            url = self.ht_args["headers"][0][1]

        except Exception, exc:
            raise Exception("Failed to construct the AuthnRequest: %s" % exc)
Example #46
0
def response_factory(sign=False, encrypt=False, **kwargs):
    response = samlp.Response(id=sid(),
                              version=VERSION,
                              issue_instant=instant())

    if sign:
        response.signature = pre_signature_part(kwargs["id"])
    if encrypt:
        pass

    for key, val in kwargs.items():
        setattr(response, key, val)

    return response
Example #47
0
    def _message(self, request_cls, destination=None, message_id=0,
                 consent=None, extensions=None, sign=False, sign_prepare=False,
                 nsprefix=None, sign_alg=None, digest_alg=None, **kwargs):
        """
        Some parameters appear in all requests so simplify by doing
        it in one place

        :param request_cls: The specific request type
        :param destination: The recipient
        :param message_id: A message identifier
        :param consent: Whether the principal have given her consent
        :param extensions: Possible extensions
        :param sign: Whether the request should be signed or not.
        :param sign_prepare: Whether the signature should be prepared or not.
        :param kwargs: Key word arguments specific to one request type
        :return: A tuple containing the request ID and an instance of the
            request_cls
        """
        if not message_id:
            message_id = sid()

        for key, val in self.message_args(message_id).items():
            if key not in kwargs:
                kwargs[key] = val

        req = request_cls(**kwargs)

        if destination:
            req.destination = destination

        if consent:
            req.consent = "true"

        if extensions:
            req.extensions = extensions

        if nsprefix:
            req.register_prefix(nsprefix)

        if self.msg_cb:
            req = self.msg_cb(req)

        reqid = req.id

        if sign:
            return reqid, self.sign(req, sign_prepare=sign_prepare,
                                    sign_alg=sign_alg, digest_alg=digest_alg)
        else:
            logger.info("REQUEST: %s", req)
            return reqid, req
Example #48
0
    def attribute_query(self, subject_id, destination, issuer_id=None,
                attribute=None, sp_name_qualifier=None, name_qualifier=None,
                nameid_format=None, log=None, real_id=None):
        """ Does a attribute request to an attribute authority, this is
        by default done over SOAP. Other bindings could be used but not
        supported right now.
        
        :param subject_id: The identifier of the subject
        :param destination: To whom the query should be sent
        :param issuer_id: Who is sending this query
        :param attribute: A dictionary of attributes and values that is asked for
        :param sp_name_qualifier: The unique identifier of the
            service provider or affiliation of providers for whom the
            identifier was generated.
        :param name_qualifier: The unique identifier of the identity
            provider that generated the identifier.
        :param nameid_format: The format of the name ID
        :param log: Function to use for logging
        :param real_id: The identifier which is the key to this entity in the
            identity database
        :return: The attributes returned
        """

        if log is None:
            log = self.logger

        session_id = sid()
        issuer = self._issuer(issuer_id)
        
        request = self.create_attribute_query(session_id, subject_id,
                    destination, issuer, attribute, sp_name_qualifier,
                    name_qualifier, nameid_format=nameid_format)
        
        if log:
            log.info("Request, created: %s" % request)
        
        soapclient = SOAPClient(destination, self.config.key_file,
                                self.config.cert_file,
                                ca_certs=self.config.ca_certs)
        if log:
            log.info("SOAP client initiated")

        try:
            response = soapclient.send(request)
        except Exception, exc:
            if log:
                log.info("SoapClient exception: %s" % (exc,))
            return None
Example #49
0
    def artifact2message(self, artifact, descriptor):
        """

        :param artifact: The Base64 encoded SAML artifact as sent over the net
        :param descriptor: The type of entity on the other side
        :return: A SAML message (request/response)
        """

        destination = self.artifact2destination(artifact, descriptor)

        if not destination:
            raise SAMLError("Missing endpoint location")

        _sid = sid()
        msg = self.create_artifact_resolve(artifact, destination, _sid)
        return self.send_using_soap(msg, destination)
Example #50
0
    def artifact2message(self, artifact, descriptor):
        """

        :param artifact: The Base64 encoded SAML artifact as sent over the net
        :param descriptor: The type of entity on the other side
        :return: A SAML message (request/response)
        """

        destination = self.artifact2destination(artifact, descriptor)

        if not destination:
            raise SAMLError("Missing endpoint location")

        _sid = sid()
        msg = self.create_artifact_resolve(artifact, destination, _sid)
        return self.send_using_soap(msg, destination)
Example #51
0
    def _message(self,
                 request_cls,
                 destination=None,
                 id=0,
                 consent=None,
                 extensions=None,
                 sign=False,
                 **kwargs):
        """
        Some parameters appear in all requests so simplify by doing
        it in one place

        :param request_cls: The specific request type
        :param destination: The recipient
        :param id: A message identifier
        :param consent: Whether the principal have given her consent
        :param extensions: Possible extensions
        :param kwargs: Key word arguments specific to one request type
        :return: An instance of the request_cls
        """
        if not id:
            id = sid(self.seed)

        req = request_cls(id=id,
                          version=VERSION,
                          issue_instant=instant(),
                          issuer=self._issuer(),
                          **kwargs)

        if destination:
            req.destination = destination

        if consent:
            req.consent = consent

        if extensions:
            req.extensions = extensions

        if sign:
            req.signature = pre_signature_part(req.id, self.sec.my_cert, 1)
            to_sign = [(class_name(req), req.id)]
        else:
            to_sign = []

        logger.info("REQUEST: %s" % req)

        return signed_instance_factory(req, self.sec, to_sign)
Example #52
0
def sign_entity_descriptor(edesc, ident, secc):
    """

    :param edesc: EntityDescriptor instance
    :param ident: EntityDescriptor identifier
    :param secc: Security context
    :return: Tuple with EntityDescriptor instance and Signed XML document
    """

    if not ident:
        ident = sid()

    edesc.signature = pre_signature_part(ident, secc.my_cert, 1)
    edesc.id = ident
    xmldoc = secc.sign_statement("%s" % edesc, class_name(edesc))
    edesc = md.entity_descriptor_from_string(xmldoc)
    return edesc, xmldoc
Example #53
0
def sign_entity_descriptor(edesc, ident, secc):
    """

    :param edesc: EntityDescriptor instance
    :param ident: EntityDescriptor identifier
    :param secc: Security context
    :return: Tuple with EntityDescriptor instance and Signed XML document
    """

    if not ident:
        ident = sid()

    edesc.signature = pre_signature_part(ident, secc.my_cert, 1)
    edesc.id = ident
    xmldoc = secc.sign_statement("%s" % edesc, class_name(edesc))
    edesc = md.entity_descriptor_from_string(xmldoc)
    return edesc, xmldoc
Example #54
0
    def authenticate(
        self,
        entityid=None,
        relay_state="",
        binding=saml2.BINDING_HTTP_REDIRECT,
        log=None,
        vorg="",
        scoping=None,
        sign=None,
    ):
        """ Makes an authentication request.

        :param entityid: The entity ID of the IdP to send the request to
        :param relay_state: To where the user should be returned after
            successfull log in.
        :param binding: Which binding to use for sending the request
        :param log: Where to write log messages
        :param vorg: The entity_id of the virtual organization I'm a member of
        :param scoping: For which IdPs this query are aimed.
        :param sign: Whether the request should be signed or not.
        :return: AuthnRequest response
        """

        location = self._sso_location(entityid)
        session_id = sid()

        _req_str = "%s" % self.authn(location, session_id, vorg, scoping, log, sign)

        if log:
            log.info("AuthNReq: %s" % _req_str)

        if binding == saml2.BINDING_HTTP_POST:
            # No valid ticket; Send a form to the client
            # THIS IS NOT TO BE USED RIGHT NOW
            if log:
                log.info("HTTP POST")
            (head, response) = http_post_message(_req_str, location, relay_state)
        elif binding == saml2.BINDING_HTTP_REDIRECT:
            if log:
                log.info("HTTP REDIRECT")
            (head, _body) = http_redirect_message(_req_str, location, relay_state)
            response = head[0]
        else:
            raise Exception("Unkown binding type: %s" % binding)
        return session_id, response
Example #55
0
    def create_logout_response(self, request, binding, status=None,
                               sign=False, issuer=None):
        """ Create a LogoutResponse. What is returned depends on which binding
        is used.
        
        :param request: The request this is a response to
        :param binding: Which binding the request came in over
        :param status: The return status of the response operation
        :param issuer: The issuer of the message
        :return: A logout message.
        """
        mid = sid()

        if not status:
            status = success_status_factory()

        # response and packaging differs depending on binding
        response = ""
        if binding in [BINDING_SOAP, BINDING_HTTP_POST]:
            response = logoutresponse_factory(sign=sign, id = mid,
                                              in_response_to = request.id,
                                              status = status)
        elif binding == BINDING_HTTP_REDIRECT:
            sp_entity_id = request.issuer.text.strip()
            srvs = self.metadata.single_logout_service(sp_entity_id, "spsso")
            if not srvs:
                raise Exception("Nowhere to send the response")

            destination = destinations(srvs)[0]

            _issuer = self.issuer(issuer)
            response = logoutresponse_factory(sign=sign, id = mid,
                                              in_response_to = request.id,
                                              status = status,
                                              issuer = _issuer,
                                              destination = destination,
                                              sp_entity_id = sp_entity_id,
                                              instant=instant())
        if sign:
            to_sign = [(class_name(response), mid)]
            response = signed_instance_factory(response, self.sec, to_sign)

        logger.info("Response: %s" % (response,))

        return response
Example #56
0
    def authz_decision_query(self,
                             entityid,
                             action,
                             evidence=None,
                             resource=None,
                             subject=None,
                             binding=saml2.BINDING_HTTP_REDIRECT,
                             sign=None):
        """ Creates an authz decision query.

        :param entityid: The entity ID of the IdP to send the request to
        :param action: The action you want to perform (has to be at least one)
        :param evidence: Why you should be able to perform the action
        :param resource: The resource you want to perform the action on
        :param subject: Who wants to do the thing
        :param binding: Which binding to use for sending the request
        :param sign: Whether the request should be signed or not.
        :return: AuthzDecisionQuery instance
        """

        spentityid = self._issuer()
        service_url = self.service_url()
        my_name = self._my_name()

        logger.info("spentityid: %s\nservice_url: %s\nmy_name: %s" %
                    (spentityid, service_url, my_name))

        #        authen_req = self.authn_request(session_id, location,
        #                                service_url, spentityid, my_name, vorg,
        #                                scoping, sign)

        request = samlp.AuthzDecisionQuery(action,
                                           evidence,
                                           resource,
                                           subject=subject,
                                           issuer=spentityid,
                                           id=sid(),
                                           issue_instant=instant(),
                                           version=VERSION,
                                           destination=entityid)

        return request
Example #57
0
    def authenticate(self,
                     entityid=None,
                     relay_state="",
                     binding=saml2.BINDING_HTTP_REDIRECT,
                     vorg="",
                     scoping=None,
                     sign=None):
        """ Makes an authentication request.

        :param entityid: The entity ID of the IdP to send the request to
        :param relay_state: To where the user should be returned after
            successfull log in.
        :param binding: Which binding to use for sending the request
        :param vorg: The entity_id of the virtual organization I'm a member of
        :param scoping: For which IdPs this query are aimed.
        :param sign: Whether the request should be signed or not.
        :return: AuthnRequest response
        """

        location = self._sso_location(entityid, binding)
        session_id = sid()

        _req_str = "%s" % self.authn(location, session_id, vorg, scoping, sign)

        logger.info("AuthNReq: %s" % _req_str)

        if binding == saml2.BINDING_HTTP_POST:
            # No valid ticket; Send a form to the client
            # THIS IS NOT TO BE USED RIGHT NOW
            logger.info("HTTP POST")
            (head, response) = http_post_message(_req_str, location,
                                                 relay_state)
        elif binding == saml2.BINDING_HTTP_REDIRECT:
            logger.info("HTTP REDIRECT")
            (head, _body) = http_redirect_message(_req_str, location,
                                                  relay_state)
            response = head[0]
        else:
            raise Exception("Unkown binding type: %s" % binding)
        return session_id, response
Example #58
0
    def make_logout_response(self,
                             idp_entity_id,
                             request_id,
                             status_code,
                             binding=BINDING_HTTP_REDIRECT):
        """ 
        XXX There were issues with an explicit closing tag on 
        StatusCode. Check wether we still need this. XXX
        Constructs a LogoutResponse

        :param idp_entity_id: The entityid of the IdP that want to do the
            logout
        :param request_id: The Id of the request we are replying to
        :param status_code: The status code of the response
        :param binding: The type of binding that will be used for the response
        :return: A LogoutResponse instance
        """
        srvs = self.metadata.single_logout_service(idp_entity_id, binding,
                                                   "idpsso")

        destination = destinations(srvs)[0]
        logger.info("destination to provider: %s" % destination)

        status = samlp.Status(
            status_code=samlp.StatusCode(value=status_code, text='\n'),
            status_message=samlp.StatusMessage(text='logout success'))

        response = samlp.LogoutResponse(
            id=sid(),
            version=VERSION,
            issue_instant=instant(),
            destination=destination,
            issuer=saml.Issuer(text=self.config.entityid,
                               format=saml.NAMEID_FORMAT_ENTITY),
            in_response_to=request_id,
            status=status,
        )

        return response, destination
Example #59
0
    def construct_logout_request(self,
                                 subject_id,
                                 destination,
                                 issuer_entity_id,
                                 reason=None,
                                 expire=None):
        """ Constructs a LogoutRequest
        
        :param subject_id: The identifier of the subject
        :param destination:
        :param issuer_entity_id: The entity ID of the IdP the request is
            target at.
        :param reason: An indication of the reason for the logout, in the
            form of a URI reference.
        :param expire: The time at which the request expires,
            after which the recipient may discard the message.
        :return: A LogoutRequest instance
        """

        session_id = sid()
        # create NameID from subject_id
        name_id = saml.NameID(
            text=self.users.get_entityid(subject_id, issuer_entity_id, False))

        request = samlp.LogoutRequest(id=session_id,
                                      version=VERSION,
                                      issue_instant=instant(),
                                      destination=destination,
                                      issuer=self._issuer(),
                                      name_id=name_id)

        if reason:
            request.reason = reason

        if expire:
            request.not_on_or_after = expire

        return request