示例#1
0
文件: validate.py 项目: hopil/LinOTP
    def check_yubikey(self):
        '''
        This function is used to validate the output of a yubikey

        method:
            validate/check_yubikey

        :param pass: The password that consist of the static yubikey prefix and the otp
        :type pass: string

        :return: JSON Object

        returns:
            JSON response::

                {
                    "version": "LinOTP 2.4",
                    "jsonrpc": "2.0",
                    "result": {
                        "status": true,
                        "value": false
                    },
                    "detail" : {
                        "username": username,
                        "realm": realm
                    },
                    "id": 0
                }
        '''

        param = request.params
        passw = getParam(param, "pass", required)
        try:

            ok = False
            try:
                th = TokenHandler()
                ok, opt = th.checkYubikeyPass(passw)
                c.audit['success'] = ok

            except AuthorizeException as exx:
                log.warning("[check_yubikey] authorization failed for validate/check_yubikey: %r"
                            % exx)
                c.audit['success'] = False
                c.audit['info'] = unicode(exx)
                ok = False

            Session.commit()
            return sendResult(response, ok, 0, opt=opt)

        except Exception as exx:
            log.exception("[check_yubikey] validate/check_yubikey failed: %r" % exx)
            c.audit['info'] = unicode(exx)
            Session.rollback()
            return sendError(response, u"validate/check_yubikey failed: %s"
                             % unicode(exx), 0)

        finally:
            Session.close()
            log.debug('[check_yubikey] done')
示例#2
0
    def webkdc_validate(self):
        # Called by WebAuth via the Elm remctld scripts.
        # Verifies a one-time passcode and indicates how long
        # the token should be considered valid.

        param = {}

        try:
            param.update(request.params)
            username = param["user"]
            code = param["code"]

            user = User(username, "", "")
            th = TokenHandler()

            if ('token' in param):
                serial = param["token"]
                (ok, opt) = th.checkSerialPass(serial,
                                               code,
                                               options=None,
                                               user=user)
            else:
                (ok, opt) = th.checkUserPass(user, code)

            ret = {
                "success": ok,
            }

            if (ok):
                ret['expiration'] = round(
                    time.time()) + 60 * 60,  # one hour from now
            else:
                if opt == None:
                    opt = {}
                ret['error'] = c.audit.get('info')
                log.error("[webkdc_validate] authorization failed: %s" %
                          ret['error'])
                ret['code'] = -310

            Session.commit()

            return sendResult(response, ret, 0, opt=opt)

        except Exception as exx:
            log.error("[webkdc_validate] validate/webkdc_validate failed: %r" %
                      exx)
            log.error("[webkdc_validate] %s" % traceback.format_exc())

            Session.rollback()
            return sendError(
                response,
                u"validate/webkdc_validate failed: %s" % unicode(exx), 0)

        finally:
            Session.close()
示例#3
0
    def test_autenroll_wo_pass(self,
                               mocked_policy_src_realm,
                               mocked_policy_autosignment_wo,
                               mockedgetTokens4UserOrSerial,
                               mocked_getTokensOfType,
                               mocked_assignToken,
                               mocked_context
                               ):

        thdle = TokenHandler()

        options = {}
        user = User("Hugo", realm="def_realm")
        otp = '123467'

        class Token(object):

            LinOtpCountWindow = 10
            typ = ""

            def setType(self, type_name):
                self.typ = type_name

            def getType(self):
                return self.typ

            def getSerial(self):
                return 'ABCDEFG'

        aToken = Token()

        class MockPasswordTokenClass(PasswordTokenClass):

            def check_otp_exist(self, *args, **kwargs):
                return 1

        pwtoken = MockPasswordTokenClass(aToken)

        mocked_policy_src_realm.return_value = None
        mocked_policy_autosignment_wo.return_value = True
        mockedgetTokens4UserOrSerial.return_value = []
        mocked_getTokensOfType.return_value = [pwtoken]
        mocked_assignToken.return_value = True

        mocked_context = {'audit': {}}

        res = thdle.auto_assign_otp_only(otp, user, options)

        self.assertTrue(res)
        self.assertTrue(mocked_assignToken.called)

        return
示例#4
0
    def test_autenroll_wo_pass(
        self,
        mocked_policy_src_realm,
        mocked_policy_autosignment_wo,
        mockedgetTokens4UserOrSerial,
        mocked_getTokensOfType,
        mocked_assignToken,
        mocked_context,
    ):

        thdle = TokenHandler()

        options = {}
        user = User("Hugo", realm="def_realm")
        otp = "123467"

        class Token(object):

            LinOtpCountWindow = 10
            typ = ""

            def setType(self, type_name):
                self.typ = type_name

            def getType(self):
                return self.typ

            def getSerial(self):
                return "ABCDEFG"

        aToken = Token()

        class MockPasswordTokenClass(PasswordTokenClass):
            def check_otp_exist(self, *args, **kwargs):
                return 1

        pwtoken = MockPasswordTokenClass(aToken)

        mocked_policy_src_realm.return_value = None
        mocked_policy_autosignment_wo.return_value = True
        mockedgetTokens4UserOrSerial.return_value = []
        mocked_getTokensOfType.return_value = [pwtoken]
        mocked_assignToken.return_value = True

        g.audit = {}

        res = thdle.auto_assign_otp_only(otp, user, options)

        assert res
        assert mocked_assignToken.called

        return
示例#5
0
    def test_isTokenOwner_no_user(self):
        """
        test if no user is given
        """

        serial = "fake_123_token"
        user = User()

        th = TokenHandler()

        with pytest.raises(TokenAdminError) as exx:
            th.isTokenOwner(serial, user)

        exx.match('no user found')

        return
示例#6
0
    def test_isTokenOwner_no_user(self):
        """
        test if no user is given
        """

        serial = "fake_123_token"
        user = User()

        th = TokenHandler()

        with self.assertRaises(TokenAdminError) as exx:
            th.isTokenOwner(serial, user)

        assert 'no user found' in exx.exception.message

        return
示例#7
0
文件: validate.py 项目: eespinosa/Elm
    def webkdc_validate(self):
        # Called by WebAuth via the Elm remctld scripts.
        # Verifies a one-time passcode and indicates how long
        # the token should be considered valid.

        param = {}

        try:
            param.update(request.params)
            username = param["user"]
            code = param["code"]

            user = User(username, "", "")
            th = TokenHandler()
           
            if ('token' in param):
                serial = param["token"]
                (ok, opt) = th.checkSerialPass(serial, code, options = None, user=user)
            else:
                (ok, opt) = th.checkUserPass(user, code)

            ret = {
                "success" : ok,
            }

            if (ok):
                ret['expiration']  = round(time.time()) + 60 * 60, # one hour from now
            else:
                if opt == None:
                    opt = {}
                ret['error'] = c.audit.get('info')
                log.error("[webkdc_validate] authorization failed: %s" % ret['error'])
                ret['code'] = -310

            Session.commit()

            return sendResult(response, ret, 0, opt=opt)

        except Exception as exx:
            log.error("[webkdc_validate] validate/webkdc_validate failed: %r" % exx)
            log.error("[webkdc_validate] %s" % traceback.format_exc())

            Session.rollback()
            return sendError(response, u"validate/webkdc_validate failed: %s" % unicode(exx), 0)

        finally:
            Session.close()
示例#8
0
    def test_compare_user(self, mocked_getUserId,
                          mocked_getTokens4UserOrSerial):
        """
        test for isTokenOwner

        the isTokenOwner should only compare the resolver conf and user id
        """

        th = TokenHandler()

        user = User(login="******",
                    realm="realm",
                    resolver_config_identifier="blah")

        # ----------------------------------------------------------------- --

        # test for same user as uid is the same and the resolver class with
        # conf is the same, only the resolver description is different

        mocked_getUserId.return_value = (
            "1234",
            "migrated resolver info",
            "passwdResolver.conf1",
        )
        mocked_getTokens4UserOrSerial.return_value = [MockedToken()]

        result = th.isTokenOwner("TokenSerial", user)

        assert result

        # ----------------------------------------------------------------- --

        # test for different user as uid is the same and the resolver class
        # with different conf, but same resolver description

        mocked_getUserId.return_value = (
            "1234",
            "resolver info",
            "passwdResolver.conf2",
        )
        mocked_getTokens4UserOrSerial.return_value = [MockedToken()]

        result = th.isTokenOwner("TokenSerial", user)

        assert not result

        return
示例#9
0
    def test_hasOwner_token_and_root_user(self, mocked_getTokens4UserOrSerial):
        """
        test if token hasOwner
        """

        serial = "fake_123_token"

        mocked_getTokens4UserOrSerial.return_value = [
            FakeToken('0', 'res', "resC")
        ]

        th = TokenHandler()

        res = th.hasOwner(serial)

        assert res == True

        return
示例#10
0
    def test_hasOwner_token_and_no_user(self, mocked_getTokens4UserOrSerial):
        """
        test if token hasOwner with user is 0,0,0
        """

        serial = "fake_123_token"

        mocked_getTokens4UserOrSerial.return_value = [
            FakeToken(None, 'res', 'resC')
        ]

        th = TokenHandler()

        res = th.hasOwner(serial)

        assert res == False

        return
示例#11
0
    def test_isTokenOwner_no_token(self, mocked_getUserId,
                                   mocked_getTokens4UserOrSerial):
        """
        test if no token is found
        """

        mocked_getUserId.return_value = ('123', 'res', 'resC')
        mocked_getTokens4UserOrSerial.return_value = []

        serial = "fake_123_token"
        user = User(login="******")

        th = TokenHandler()

        with self.assertRaises(TokenAdminError) as exx:
            th.isTokenOwner(serial, user)

        assert 'no token found' in exx.exception.message

        return
示例#12
0
    def test_isTokenOwner_no_token(self, mocked_getUserId,
                                   mocked_getTokens4UserOrSerial):
        """
        test if no token is found
        """

        mocked_getUserId.return_value = ('123', 'res', 'resC')
        mocked_getTokens4UserOrSerial.return_value = []

        serial = "fake_123_token"
        user = User(login="******")

        th = TokenHandler()

        with pytest.raises(TokenAdminError) as exx:
            th.isTokenOwner(serial, user)

        exx.match('no token found')

        return
示例#13
0
    def test_compare_user(self, mocked_getUserId,
                          mocked_getTokens4UserOrSerial):
        """
        test for isTokenOwner
        
        the isTokenOwner should only compare the resolver conf and user id
        """

        th = TokenHandler()

        user = User(login='******',
                    realm='realm',
                    resolver_config_identifier='blah')

        # ----------------------------------------------------------------- --

        # test for same user as uid is the same and the resolver class with
        # conf is the same, only the resolver description is different

        mocked_getUserId.return_value = ('1234', 'migrated resolver info',
                                         'passwdResolver.conf1')
        mocked_getTokens4UserOrSerial.return_value = [MockedToken()]

        result = th.isTokenOwner('TokenSerial', user)

        self.assertTrue(result)

        # ----------------------------------------------------------------- --

        # test for different user as uid is the same and the resolver class
        # with different conf, but same resolver description

        mocked_getUserId.return_value = ('1234', 'resolver info',
                                         'passwdResolver.conf2')
        mocked_getTokens4UserOrSerial.return_value = [MockedToken()]

        result = th.isTokenOwner('TokenSerial', user)

        self.assertFalse(result)

        return
示例#14
0
    def test_compare_user(self,
                          mocked_getUserId,
                          mocked_getTokens4UserOrSerial):
        """
        test for isTokenOwner
        
        the isTokenOwner should only compare the resolver conf and user id
        """

        th = TokenHandler()

        user = User(login='******', realm='realm',
                    resolver_config_identifier='blah')

        # ----------------------------------------------------------------- --

        # test for same user as uid is the same and the resolver class with
        # conf is the same, only the resolver description is different

        mocked_getUserId.return_value = ('1234', 'migrated resolver info',
                                         'passwdResolver.conf1')
        mocked_getTokens4UserOrSerial.return_value = [MockedToken()]

        result = th.isTokenOwner('TokenSerial', user)

        self.assertTrue(result)

        # ----------------------------------------------------------------- --

        # test for different user as uid is the same and the resolver class
        # with different conf, but same resolver description

        mocked_getUserId.return_value = ('1234', 'resolver info',
                                         'passwdResolver.conf2')
        mocked_getTokens4UserOrSerial.return_value = [MockedToken()]

        result = th.isTokenOwner('TokenSerial', user)

        self.assertFalse(result)

        return
示例#15
0
    def test_isTokenOwner_token_and_user(self, mocked_getUserId,
                                         mocked_getTokens4UserOrSerial):
        """
        test if token owner is found
        """

        serial = "fake_123_token"
        user = User(login="******")

        mocked_getUserId.return_value = ('123', 'res', 'resC')
        mocked_getTokens4UserOrSerial.return_value = [
            FakeToken("123", 'res', "resC")
        ]

        th = TokenHandler()

        res = th.isTokenOwner(serial, user)

        assert res == True

        return
示例#16
0
    def test_hasOwner_token_and_user(self, mocked_getUserId,
                                     mocked_getTokens4UserOrSerial):
        """
        test if token hasOwner
        """

        serial = "fake_123_token"
        user = User(login="******")

        mocked_getUserId.return_value = ("123", "res", "resC")
        mocked_getTokens4UserOrSerial.return_value = [
            FakeToken("123", "res", "resC")
        ]

        th = TokenHandler()

        res = th.hasOwner(serial)

        assert res

        return
示例#17
0
    def test_losttoken(self, mocked_getTokenOwner, mocked__get_policies,
                       mocked_get_policy_definitions):
        """Verify the policy evaluation in losttoken honores general actions."""

        fake_user = LinotpUser(login='******', realm='defaultrealm')
        mocked_getTokenOwner.return_value = fake_user

        policy_set = copy.deepcopy(PolicySet)

        mocked_get_policy_definitions.return_value = {
            'enrollment': {
                'lostTokenPWLen': {
                    'type':
                    'int',
                    'desc':
                    'The length of the password in case of '
                    'temporary token.'
                },
                'lostTokenPWContents': {
                    'type':
                    'str',
                    'desc':
                    'The contents of the temporary password, '
                    'described by the characters C, c, n, s.'
                },
                'lostTokenValid': {
                    'type':
                    'set',
                    'value': ['int', 'duration'],
                    'desc':
                    'The length of the validity for the temporary '
                    'token as days or duration with "d"-days, "h"-hours,'
                    ' "m"-minutes, "s"-seconds.'
                },
            }
        }
        # ----------------------------------------------------------------- --

        # verify that general policy is honored

        policy_set['general']['action'] = (
            'lostTokenPWLen=5, lostTokenPWContents=n, lostTokenValid=2')

        mocked__get_policies.return_value = policy_set

        end_date = (datetime.date.today() +
                    datetime.timedelta(days=2)).strftime("%d/%m/%y")
        end_date = "%s 23:59" % end_date

        th = TokenHandler()
        res = th.losttoken('mySerial', 'mySerial_new')

        assert res['password'].isdigit()
        assert len(res['password']) == 5
        assert res['end_date'] == end_date

        # ----------------------------------------------------------------- --

        # verify that user specific policy is honored

        policy_set['fake_user']['action'] = (
            'lostTokenPWLen=3, lostTokenPWContents=c, lostTokenValid=1')

        mocked__get_policies.return_value = policy_set

        end_date = (datetime.date.today() +
                    datetime.timedelta(days=1)).strftime("%d/%m/%y")
        end_date = "%s 23:59" % end_date

        th = TokenHandler()
        res = th.losttoken(serial='mySerial', new_serial='mySerial_new')

        assert not res['password'].isdigit()
        assert len(res['password']) == 3
        assert res['end_date'] == end_date
示例#18
0
    def test_losttoken(
        self,
        mocked_getTokenOwner,
        mocked__get_policies,
        mocked_get_policy_definitions,
    ):
        """Verify the policy evaluation in losttoken honores general actions."""

        fake_user = LinotpUser(login="******", realm="defaultrealm")
        mocked_getTokenOwner.return_value = fake_user

        policy_set = copy.deepcopy(PolicySet)

        mocked_get_policy_definitions.return_value = {
            "enrollment": {
                "lostTokenPWLen": {
                    "type":
                    "int",
                    "desc":
                    "The length of the password in case of "
                    "temporary token.",
                },
                "lostTokenPWContents": {
                    "type":
                    "str",
                    "desc":
                    "The contents of the temporary password, "
                    "described by the characters C, c, n, s.",
                },
                "lostTokenValid": {
                    "type":
                    "set",
                    "value": ["int", "duration"],
                    "desc":
                    "The length of the validity for the temporary "
                    'token as days or duration with "d"-days, "h"-hours,'
                    ' "m"-minutes, "s"-seconds.',
                },
            }
        }
        # ----------------------------------------------------------------- --

        # verify that general policy is honored

        policy_set["general"][
            "action"] = "lostTokenPWLen=5, lostTokenPWContents=n, lostTokenValid=2"

        mocked__get_policies.return_value = policy_set

        end_date = (datetime.date.today() +
                    datetime.timedelta(days=2)).strftime("%d/%m/%y")
        end_date = "%s 23:59" % end_date

        th = TokenHandler()
        res = th.losttoken("mySerial", "mySerial_new")

        assert res["password"].isdigit()
        assert len(res["password"]) == 5
        assert res["end_date"] == end_date

        # ----------------------------------------------------------------- --

        # verify that user specific policy is honored

        policy_set["fake_user"][
            "action"] = "lostTokenPWLen=3, lostTokenPWContents=c, lostTokenValid=1"

        mocked__get_policies.return_value = policy_set

        end_date = (datetime.date.today() +
                    datetime.timedelta(days=1)).strftime("%d/%m/%y")
        end_date = "%s 23:59" % end_date

        th = TokenHandler()
        res = th.losttoken(serial="mySerial", new_serial="mySerial_new")

        assert not res["password"].isdigit()
        assert len(res["password"]) == 3
        assert res["end_date"] == end_date
示例#19
0
    def checkUserPass(self, user, passw, options=None):
        """
        :param user: the to be identified user
        :param passw: the identifiaction pass
        :param options: optional parameters, which are provided
                    to the token checkOTP / checkPass

        :return: tuple of True/False and optional information
        """

        log.debug('entering function checkUserPass(%r)' % user.login)
        # the upper layer will catch / at least should ;-)

        opt = None
        serial = None
        resolverClass = None
        uid = None
        audit = context['audit']
        user_exists = False

        if user is not None and (user.isEmpty() is False):
            # the upper layer will catch / at least should
            try:
                (uid, _resolver, resolverClass) = getUserId(user)
                user_exists = True
            except:
                pass_on = context.get('Config').get(
                    'linotp.PassOnUserNotFound', False)
                if pass_on and 'true' == pass_on.lower():
                    audit['action_detail'] = (
                        'authenticated by PassOnUserNotFound')
                    return (True, opt)
                else:
                    audit['action_detail'] = 'User not found'
                    return (False, opt)

        # if we have an user, check if we forward the request to another server
        if user_exists:
            servers = get_auth_forward(user)
            if servers:
                res, opt = ForwardServerPolicy.do_request(
                    servers, env, user, passw, options)
                return res, opt

        tokenList = linotp.lib.token.getTokens4UserOrSerial(user, serial)

        if len(tokenList) == 0:
            audit['action_detail'] = 'User has no tokens assigned'

            # here we check if we should to autoassign and try to do it
            log.debug('about to check auto_assigning')

            th = TokenHandler()
            auto_assign_return = th.auto_assignToken(passw, user)
            if auto_assign_return is True:
                # We can not check the token, as the OTP value is already used!
                # but we will auth the user....
                return (True, opt)

            auto_enroll_return, opt = th.auto_enrollToken(passw,
                                                          user,
                                                          options=options)
            if auto_enroll_return is True:
                # we always have to return a false, as
                # we have a challenge tiggered
                return (False, opt)

            pass_on = context.get('Config').get('linotp.PassOnUserNoToken',
                                                False)
            if pass_on and 'true' == pass_on.lower():
                audit['action_detail'] = 'authenticated by PassOnUserNoToken'
                return (True, opt)

            #  Check if there is an authentication policy passthru
            from linotp.lib.policy import get_auth_passthru
            if get_auth_passthru(user):
                log.debug('user %r has no token. Checking for '
                          'passthru in realm %r' % (user.login, user.realm))
                y = getResolverObject(resolverClass)
                audit['action_detail'] = 'Authenticated against Resolver'
                if y.checkPass(uid, passw):
                    return (True, opt)

            #  Check if there is an authentication policy passOnNoToken
            from linotp.lib.policy import get_auth_passOnNoToken
            if get_auth_passOnNoToken(user):
                log.info('user %r has not token. PassOnNoToken'
                         ' set - authenticated!')
                audit['action_detail'] = (
                    'Authenticated by passOnNoToken policy')
                return (True, opt)

            return (False, opt)

        if passw is None:
            raise ParameterError(u"Missing parameter:pass", id=905)

        (res, opt) = self.checkTokenList(tokenList,
                                         passw,
                                         user,
                                         options=options)
        log.debug('return of __checkTokenList: %r ' % (res, ))

        return (res, opt)
示例#20
0
文件: validate.py 项目: soitun/LinOTP
    def checkUserPass(self, user, passw, options=None):
        """
        :param user: the to be identified user
        :param passw: the identification pass
        :param options: optional parameters, which are provided
                    to the token checkOTP / checkPass

        :return: tuple of True/False and optional information
        """

        # the upper layer will catch / at least should ;-)

        opt = None
        serial = None
        resolverClass = None
        uid = None
        user_exists = False

        if user:
            # the upper layer will catch / at least should
            try:
                (uid, _resolver,
                 resolverClass) = getUserId(user, check_existance=True)
                user_exists = True
            except Exception as _exx:
                pass_on = context.get("Config").get(
                    "linotp.PassOnUserNotFound", False)
                if pass_on and pass_on.lower() == "true":
                    g.audit[
                        "action_detail"] = "authenticated by PassOnUserNotFound"
                    return (True, opt)
                else:
                    g.audit["action_detail"] = "User not found"
                    return (False, opt)

        # if we have an user, check if we forward the request to another server
        if user_exists and not get_auth_forward_on_no_token(user):
            servers = get_auth_forward(user)
            if servers:
                log.info("forwarding auth request for user {} to {}".format(
                    user, servers))
                res, opt = ForwardServerPolicy.do_request(
                    servers, env, user, passw, options)
                log.info("result of auth request for user {}: ({}, {})".format(
                    user, res, opt))
                g.audit["action_detail"] = "Forwarded, result {}".format(res)
                return res, opt
            else:
                log.info(
                    "NOT forwarding auth request for user {} (no servers)".
                    format(user))
                g.audit["action_detail"] = "Not forwarded (no servers)"
        else:
            log.info(
                "NOT forwarding auth request for user {} "
                "(get_auth_forward_on_no_token returned False)".format(user))

        # ------------------------------------------------------------------ --

        th = TokenHandler()

        # ------------------------------------------------------------------ --

        # auto asignement with otp only if user has no active token

        auto_assign_otp_return = th.auto_assign_otp_only(otp=passw,
                                                         user=user,
                                                         options=options)

        if auto_assign_otp_return:
            return (True, None)

        # ------------------------------------------------------------------ --

        token_type = None
        if options:
            token_type = options.get("token_type", None)

        # ------------------------------------------------------------------ --

        # if there is a serial provided in the parameters, it overwrites the
        # token selection by user

        query_user = user
        if options and "serial" in options and options["serial"]:
            serial = options["serial"]
            query_user = None

        # ------------------------------------------------------------------ --

        tokenList = getTokens4UserOrSerial(query_user,
                                           serial,
                                           token_type=token_type,
                                           read_for_update=True)

        if len(tokenList) == 0:
            g.audit["action_detail"] = "User has no tokens assigned"

            # here we check if we should to autoassign and try to do it
            auto_assign_return = th.auto_assignToken(passw, user)
            if auto_assign_return:
                # We can not check the token, as the OTP value is already used!
                # but we will auth the user....
                return (True, opt)

            auto_enroll_return, opt = th.auto_enrollToken(passw,
                                                          user,
                                                          options=options)
            if auto_enroll_return:
                # we always have to return a false, as
                # we have a challenge tiggered
                return (False, opt)

            pass_on = context.get("Config").get("linotp.PassOnUserNoToken",
                                                False)
            if pass_on and pass_on.lower() == "true":
                g.audit["action_detail"] = "authenticated by PassOnUserNoToken"
                return (True, opt)

            # Check if there is an authentication policy passthru

            if get_auth_passthru(user):
                log.debug(
                    "user %r has no token. Checking for passthru in realm %r",
                    user.login,
                    user.realm,
                )
                y = getResolverObject(resolverClass)
                g.audit["action_detail"] = "Authenticated against Resolver"
                if y.checkPass(uid, passw):
                    return (True, opt)

            # Check alternatively if there is an authentication
            # policy passOnNoToken
            elif get_auth_passOnNoToken(user):
                log.info("user %r has not token. PassOnNoToken"
                         " set - authenticated!")
                g.audit[
                    "action_detail"] = "Authenticated by passOnNoToken policy"
                return (True, opt)

            # if we have an user, check if we forward the request to another
            # server
            elif get_auth_forward_on_no_token(user):
                servers = get_auth_forward(user)
                if servers:
                    log.info(
                        "forwarding auth request for user {} to {}".format(
                            user, servers))
                    res, opt = ForwardServerPolicy.do_request(
                        servers, env, user, passw, options)
                    log.info(
                        "result of auth request for user {}: ({}, {})".format(
                            user, res, opt))
                    g.audit["action_detail"] = "Forwarded, result {}".format(
                        res)
                    return res, opt
                else:
                    log.info(
                        "NOT forwarding auth request for user {} (no servers)".
                        format(user))
                    g.audit["action_detail"] = "Not forwarded (no servers)"

            return False, opt

        if passw is None:
            raise ParameterError("Missing parameter:pass", id=905)

        (res, opt) = self.checkTokenList(tokenList,
                                         passw,
                                         user,
                                         options=options)

        return (res, opt)
示例#21
0
    def check(self):
        '''
        This function is used to login

        method:
            openid/check

        arguments:
            user     - user to login
            realm    - in which realm the user should login
            pass     - password

        returns:
            JSON response
        '''
        ok = False
        param = {}
        do_redirect = None
        message = None

        try:
            param.update(request.params)

            same_user = True
            passw = getParam(param, "pass", optional)

            ## getUserFromParam will return default realm if no realm is
            ## provided via @ append or extra parameter realm
            ## if the provided realm does not exist, the realm is left empty
            user = getUserFromParam(param, optional)

            ## if the requested user has a realm specified (via @realm append)
            ## and this is not the same as the user from getUserFromParam
            ## the requested user is not a valid one!
            p_user = param.get('user', '')
            if "@" in p_user:
                if p_user != "%s@%s" % (user.login, user.realm):
                    same_user = False

            c.audit['user'] = user.login
            c.audit['realm'] = user.realm or getDefaultRealm()
            th = TokenHandler()
            if same_user is True:
                (ok, opt) = th.checkUserPass(user, passw)

            c.audit['success'] = ok

            if ok:
                ## if the user authenticated successfully we need to set the cookie aka
                ## the ticket and we need to remember this ticket.
                user = "******" % (user.login, c.audit['realm'])
                log.debug("[check] user=%s" % user)
                token = self.storage.set_user_token(user, expire=self.COOKIE_EXPIRE)
                log.debug("[check] token=%s" % token)
                cookie = "%s:%s" % (user, token)
                log.debug("[check] cookie=%s" % cookie)
                response.set_cookie(COOKIE_NAME, cookie, max_age=self.COOKIE_EXPIRE)
            else:
                message = "Your login attempt was not successful!"

            Session.commit()
            # Only if we logged in successfully we redirect to the original
            # page (Servive Provider). Otherwise we will redirect to the
            # status page

            p = {}
            redirect_to = getParam(param, "redirect_to", optional)
            if redirect_to and ok:
                p = {}
                for k in  [ 'openid.return_to', "openid.realm", "openid.ns", "openid.claimed_id", "openid.mode",
                            "openid.identity" ]:
                    p[k] = param[k]
            else:
                if message is not None:
                    p["message"] = message
                redirect_to = "/openid/status"

            do_redirect = url(str("%s?%s" % (redirect_to, urlencode(p))))

        except Exception as exx:
            log.exception("[check] openid/check failed: %r" % exx)
            Session.rollback()
            return sendError(response, "openid/check failed: %r" % exx, 0)

        finally:
            Session.close()
            log.debug('[check] done')

        if do_redirect:
            log.debug("[check] now redirecting to %s" % do_redirect)
            redirect(do_redirect)
示例#22
0
    def _check(self, param):
        '''
        basic check function, that can be used by different controllers

        :param param: dict of all caller parameters
        :type param: dict

        :return: Tuple of True or False and opt
        :rtype: Tuple(boolean, opt)

        '''
        opt = None

        options = {}

        ## put everythin in the options but the user, pass, init
        options.update(param)
        for para in ["pass", "user", "init"]:
            if options.has_key(para):
                del options[para]

        passw = getParam(param, "pass", optional)
        user = getUserFromParam(param, optional)

        # support for ocra application challenge verification
        challenge = getParam(param, "challenge", optional)
        if challenge is not None:
            options = {}
            options['challenge'] = challenge

        c.audit['user'] = user.login
        realm = user.realm or getDefaultRealm()
        c.audit['realm'] = realm

        # AUTHORIZATION Pre Check
        # we need to overwrite the user.realm in case the user does not exist in the original realm (setrealm-policy)
        user.realm = set_realm(user.login, realm, exception=True)
        check_user_authorization(user.login, user.realm, exception=True)

        if isSelfTest() == True:
            initTime = getParam(param, "init", optional)
            if initTime is not None:
                if options is None:
                    options = {}
                options['initTime'] = initTime
        th = TokenHandler()
        (ok, opt) = th.checkUserPass(user, passw, options=options)

        c.audit['success'] = ok

        if ok:
            # AUTHORIZATION post check
            check_auth_tokentype(c.audit['serial'], exception=True, user=user)
            check_auth_serial(c.audit['serial'], exception=True, user=user)

        # add additional details
        if is_auth_return(ok, user=user):
            if opt == None:
                opt = {}
            if ok:
                opt['realm'] = c.audit.get('realm')
                opt['user'] = c.audit.get('user')
                opt['tokentype'] = c.audit.get('token_type')
                opt['serial'] = c.audit.get('serial')
            else:
                opt['error'] = c.audit.get('action_detail')

        return (ok, opt)
示例#23
0
    def _check(self, param):
        '''
        basic check function, that can be used by different controllers

        :param param: dict of all caller parameters
        :type param: dict

        :return: Tuple of True or False and opt
        :rtype: Tuple(boolean, opt)

        '''
        log.debug("[_check] entering function")
        opt = None

        options = {}

        ## put everything in the options but the user, pass, init
        options.update(param)
        for para in ["pass", "user", "init"]:
            if options.has_key(para):
                del options[para]

        passw = getParam(param, "pass", optional)
        user = getUserFromParam(param, optional)

        # support for ocra application challenge verification
        challenge = getParam(param, "challenge", optional)
        if challenge is not None:
            options = {}
            options['challenge'] = challenge

        c.audit['user'] = user.login
        realm = user.realm or getDefaultRealm()
        c.audit['realm'] = realm

        # AUTHORIZATION Pre Check
        # we need to overwrite the user.realm in case the user does not exist in the original realm (setrealm-policy)
        user.realm = set_realm(user.login, realm, exception=True)
        check_user_authorization(user.login, user.realm, exception=True)

        if isSelfTest() == True:
            initTime = getParam(param, "init", optional)
            if initTime is not None:
                if options is None:
                    options = {}
                options['initTime'] = initTime
        th = TokenHandler()
        log.debug("[_check] calling th.checkUserPass")
        (ok, opt) = th.checkUserPass(user, passw, options=options)

        c.audit['success'] = ok

        if ok:
            # AUTHORIZATION post check
            check_auth_tokentype(c.audit['serial'], exception=True, user=user)
            check_auth_serial(c.audit['serial'], exception=True, user=user)

        # add additional details
        if is_auth_return(ok, user=user):
            if opt == None:
                opt = {}
            if ok:
                opt['realm'] = c.audit.get('realm')
                opt['user'] = c.audit.get('user')
                opt['tokentype'] = c.audit.get('token_type')
                opt['serial'] = c.audit.get('serial')
            else:
                opt['error'] = c.audit.get('action_detail')

        log.debug("[_check] exiting function")
        return (ok, opt)
示例#24
0
文件: validate.py 项目: kuffz/LinOTP
    def checkUserPass(self, user, passw, options=None):
        """
        :param user: the to be identified user
        :param passw: the identifiaction pass
        :param options: optional parameters, which are provided
                    to the token checkOTP / checkPass

        :return: tuple of True/False and optional information
        """

        log.debug('entering function checkUserPass(%r)'
                  % user.login)
        # the upper layer will catch / at least should ;-)

        opt = None
        serial = None
        resolverClass = None
        uid = None
        audit = context['audit']
        user_exists = False

        if user is not None and (user.isEmpty() == False):
            # the upper layer will catch / at least should
            try:
                (uid, _resolver, resolverClass) = getUserId(user)
                user_exists = True
            except:
                pass_on = context.get('Config').get(
                                            'linotp.PassOnUserNotFound', False)
                if pass_on and 'true' == pass_on.lower():
                    audit['action_detail'] = (
                                        'authenticated by PassOnUserNotFound')
                    return (True, opt)
                else:
                    audit['action_detail'] = 'User not found'
                    return (False, opt)

        # if we have an user, check if we forward the request to another server
        if user_exists:
            from linotp.lib.policy import get_auth_forward
            servers = get_auth_forward(user)
            if servers:
                if 'radius://' in servers:
                    rad = RadiusRequest(servers=servers)
                    res, opt = rad.do_request(servers, user, passw, options)
                    return res, opt
                elif 'http://' in servers or 'https://' in servers:
                    http = HttpRequest(servers=servers)
                    res, opt = http.do_request(user, passw, options)
                    return res, opt

        tokenList = linotp.lib.token.getTokens4UserOrSerial(user, serial)

        if len(tokenList) == 0:
            audit['action_detail'] = 'User has no tokens assigned'

            # here we check if we should to autoassign and try to do it
            log.debug('about to check auto_assigning')

            th = TokenHandler()
            auto_assign_return = th.auto_assignToken(passw, user)
            if auto_assign_return is True:
                # We can not check the token, as the OTP value is already used!
                # but we will auth the user....
                return (True, opt)

            auto_enroll_return, opt = th.auto_enrollToken(passw, user,
                                                            options=options)
            if auto_enroll_return is True:
                # we always have to return a false, as
                # we have a challenge tiggered
                return (False, opt)

            pass_on = context.get('Config').get('linotp.PassOnUserNoToken',
                                                         False)
            if pass_on and 'true' == pass_on.lower():
                audit['action_detail'] = 'authenticated by PassOnUserNoToken'
                return (True, opt)

            #  Check if there is an authentication policy passthru
            from linotp.lib.policy import get_auth_passthru
            if get_auth_passthru(user):
                log.debug('user %r has no token. Checking for '
                          'passthru in realm %r' % (user.login, user.realm))
                y = getResolverObject(resolverClass)
                audit['action_detail'] = 'Authenticated against Resolver'
                if y.checkPass(uid, passw):
                    return (True, opt)

            #  Check if there is an authentication policy passOnNoToken
            from linotp.lib.policy import get_auth_passOnNoToken
            if get_auth_passOnNoToken(user):
                log.info('user %r has not token. PassOnNoToken'
                         ' set - authenticated!')
                audit['action_detail'] = (
                    'Authenticated by passOnNoToken policy')
                return (True, opt)

            return (False, opt)

        if passw is None:
            raise ParameterError(u"Missing parameter:pass", id=905)

        (res, opt) = self.checkTokenList(
            tokenList, passw, user, options=options)
        log.debug('return of __checkTokenList: %r ' % (res,))

        return (res, opt)
示例#25
0
    def check_yubikey(self):
        '''
        This function is used to validate the output of a yubikey

        method:
            validate/check_yubikey

        :param pass: The password that consist of the static yubikey prefix and the otp
        :type pass: string

        :return: JSON Object

        returns:
            JSON response::

                {
                    "version": "LinOTP 2.4",
                    "jsonrpc": "2.0",
                    "result": {
                        "status": true,
                        "value": false
                    },
                    "detail" : {
                        "username": username,
                        "realm": realm
                    },
                    "id": 0
                }
        '''

        param = request.params
        passw = getParam(param, "pass", required)
        try:

            ok = False
            try:
                th = TokenHandler()
                ok, opt = th.checkYubikeyPass(passw)
                c.audit['success'] = ok

            except AuthorizeException as exx:
                log.warning(
                    "[check_yubikey] authorization failed for validate/check_yubikey: %r"
                    % exx)
                c.audit['success'] = False
                c.audit['info'] = unicode(exx)
                ok = False

            Session.commit()
            return sendResult(response, ok, 0, opt=opt)

        except Exception as exx:
            log.error("[check_yubikey] validate/check_yubikey failed: %r" %
                      exx)
            log.error("[check_yubikey] %s" % traceback.format_exc())
            c.audit['info'] = unicode(exx)
            Session.rollback()
            return sendError(
                response, u"validate/check_yubikey failed: %s" % unicode(exx),
                0)

        finally:
            Session.close()
            log.debug('[check_yubikey] done')
示例#26
0
    def enroll(self):
        """
        method:
            api/helpdesk/enroll

        description:
            method to enroll a token as helpdesk

        arguments:
            * type: the token type, currently only 'email'
            * user: the new token owner
            * realm: (optional) the realm the user belongs to - used to identify the user

        returns:
            success as boolean

        """

        ret = False
        response_detail = {}

        params = self.request_params

        try:

            if 'user' not in params:
                raise ParameterError('missing parameter: user!')

            if 'type' not in params:
                raise ParameterError('missing parameter: type!')

            # --------------------------------------------------------------- --

            # determine token class

            token_cls_alias = params.get("type")
            lower_alias = token_cls_alias.lower()

            if lower_alias not in tokenclass_registry:
                raise TokenAdminError('admin/init failed: unknown token '
                                      'type %r' % token_cls_alias, id=1610)

            token_cls = tokenclass_registry.get(lower_alias)

            # --------------------------------------------------------------- --

            # call the token class hook in order to enrich/overwrite the
            # parameters

            helper_params = token_cls.get_helper_params_pre(params)
            params.update(helper_params)

            # --------------------------------------------------------------- --

            # fetch user from parameters.

            user = getUserFromParam(params)

            # --------------------------------------------------------------- --

            # create a new pin according to the policies

            if 'pin' not in params:
                params['pin'] = createRandomPin(user, min_pin_length=6)

            # --------------------------------------------------------------- --

            if 'otpkey' not in params:
                params['genkey'] = '1'

            # --------------------------------------------------------------- --

            # check admin authorization

            res = checkPolicyPre('admin', 'init', params, user=user)

            # --------------------------------------------------------------- --

            helper_params = token_cls.get_helper_params_post(params, user=user)
            params.update(helper_params)

            # --------------------------------------------------------------- --

            # create new serial

            th = TokenHandler()

            serial = th.genSerial(token_cls_alias)
            params['serial'] = serial

            log.info("[init] initialize token. user: %s, serial: %s"
                     % (user.login, serial))

            # --------------------------------------------------------------- --

            # scope_extension: we are in scope helpdesk
            # this is eg required to notify the emailtoken to use the
            # email from user if none is given as param

            params['::scope::'] = {
                'helpdesk': True,
                'user': user
            }

            (ret, token) = th.initToken(params, user)

            # --------------------------------------------------------------- --

            # different token types return different information on
            # initialization (e.g. otpkey, pairing_url, etc)

            initDetail = token.getInitDetail(params, user)
            response_detail.update(initDetail)

            # --------------------------------------------------------------- --

            # prepare data for audit

            if token is not None and ret is True:
                c.audit['serial'] = token.getSerial()
                c.audit['token_type'] = token.type

            c.audit['success'] = ret
            c.audit['user'] = user.login
            c.audit['realm'] = user.realm

            c.audit['action_detail'] += get_token_num_info()

            res = checkPolicyPost('admin', 'init', params, user=user)
            pin = res.get('new_pin', params['pin'])

            message = ("A new ${tokentype} token (${serial}) "
                       "with pin '${Pin}' "
                       "for ${givenname} ${surname} has been enrolled.")
            info = {
                'message': message,
                'Subject': 'New %s token enrolled' % token.type,
                'Pin': pin,
                'tokentype': token.type
            }
            info.update(response_detail)

            notify_user(user, 'enrollment', info, required=True)

            c.audit['action_detail'] += get_token_num_info()

            c.audit['success'] = ret

            return sendResult(response, ret)

        except PolicyException as pex:
            log.exception("Policy Exception while enrolling token")
            Session.rollback()
            return sendError(response, pex, 1)

        except Exception as exx:
            log.exception("Exception while enrolling token")
            Session.rollback()
            return sendError(response, exx, 1)
示例#27
0
文件: validate.py 项目: ppires/LinOTP
    def checkUserPass(self, user, passw, options=None):
        """
        :param user: the to be identified user
        :param passw: the identification pass
        :param options: optional parameters, which are provided
                    to the token checkOTP / checkPass

        :return: tuple of True/False and optional information
        """

        # the upper layer will catch / at least should ;-)

        opt = None
        serial = None
        resolverClass = None
        uid = None
        user_exists = False

        if user is not None and not user.is_empty:
            # the upper layer will catch / at least should
            try:
                (uid, _resolver, resolverClass) = getUserId(
                                                    user, check_existance=True)
                user_exists = True
            except Exception as _exx:
                pass_on = context.get('Config').get(
                    'linotp.PassOnUserNotFound', False)
                if pass_on and 'true' == pass_on.lower():
                    g.audit['action_detail'] = (
                        'authenticated by PassOnUserNotFound')
                    return (True, opt)
                else:
                    g.audit['action_detail'] = 'User not found'
                    return (False, opt)

        # if we have an user, check if we forward the request to another server
        if user_exists and get_auth_forward_on_no_token(user) is False:
            servers = get_auth_forward(user)
            if servers:
                res, opt = ForwardServerPolicy.do_request(servers, env,
                                                          user, passw, options)
                return res, opt

        # ------------------------------------------------------------------ --

        th = TokenHandler()

        # ------------------------------------------------------------------ --

        # auto asignement with otp only if user has no active token

        auto_assign_otp_return = th.auto_assign_otp_only(
                                                    otp=passw,
                                                    user=user,
                                                    options=options)

        if auto_assign_otp_return is True:
            return (True, None)

        # ------------------------------------------------------------------ --

        token_type = None
        if options:
            token_type = options.get('token_type', None)

        # ------------------------------------------------------------------ --

        # if there is a serial provided in the parameters, it overwrites the
        # token selection by user

        query_user = user
        if options and 'serial' in  options and options['serial']:
            serial = options['serial']
            query_user = None

        # ------------------------------------------------------------------ --

        tokenList = getTokens4UserOrSerial(
                               query_user,
                               serial,
                               token_type=token_type,
                               read_for_update=True
                               )

        if len(tokenList) == 0:
            g.audit['action_detail'] = 'User has no tokens assigned'

            # here we check if we should to autoassign and try to do it
            auto_assign_return = th.auto_assignToken(passw, user)
            if auto_assign_return is True:
                # We can not check the token, as the OTP value is already used!
                # but we will auth the user....
                return (True, opt)

            auto_enroll_return, opt = th.auto_enrollToken(passw, user,
                                                          options=options)
            if auto_enroll_return is True:
                # we always have to return a false, as
                # we have a challenge tiggered
                return (False, opt)

            pass_on = context.get('Config').get('linotp.PassOnUserNoToken',
                                                False)
            if pass_on and 'true' == pass_on.lower():
                g.audit['action_detail'] = 'authenticated by PassOnUserNoToken'
                return (True, opt)

            # Check if there is an authentication policy passthru

            if get_auth_passthru(user):
                log.debug('user %r has no token. Checking for '
                          'passthru in realm %r' % (user.login, user.realm))
                y = getResolverObject(resolverClass)
                g.audit['action_detail'] = 'Authenticated against Resolver'
                if y.checkPass(uid, passw):
                    return (True, opt)

            # Check alternatively if there is an authentication
            # policy passOnNoToken
            elif get_auth_passOnNoToken(user):
                log.info('user %r has not token. PassOnNoToken'
                         ' set - authenticated!')
                g.audit['action_detail'] = (
                    'Authenticated by passOnNoToken policy')
                return (True, opt)

            # if we have an user, check if we forward the request to another server
            elif get_auth_forward_on_no_token(user) is True:
                servers = get_auth_forward(user)
                if servers:
                    res, opt = ForwardServerPolicy.do_request(
                                            servers, env, user, passw, options)
                    return res, opt

            return False, opt

        if passw is None:
            raise ParameterError("Missing parameter:pass", id=905)

        (res, opt) = self.checkTokenList(
            tokenList, passw, user, options=options)

        return (res, opt)
示例#28
0
    def checkUserPass(self, user, passw, options=None):
        """
        :param user: the to be identified user
        :param passw: the identification pass
        :param options: optional parameters, which are provided
                    to the token checkOTP / checkPass

        :return: tuple of True/False and optional information
        """

        # the upper layer will catch / at least should ;-)

        opt = None
        serial = None
        resolverClass = None
        uid = None
        audit = context['audit']
        user_exists = False

        if user is not None and not user.is_empty:
            # the upper layer will catch / at least should
            try:
                (uid, _resolver, resolverClass) = getUserId(
                                                    user, check_existance=True)
                user_exists = True
            except Exception as _exx:
                pass_on = context.get('Config').get(
                    'linotp.PassOnUserNotFound', False)
                if pass_on and 'true' == pass_on.lower():
                    audit['action_detail'] = (
                        'authenticated by PassOnUserNotFound')
                    return (True, opt)
                else:
                    audit['action_detail'] = 'User not found'
                    return (False, opt)

        # if we have an user, check if we forward the request to another server
        if user_exists and get_auth_forward_on_no_token(user) is False:
            servers = get_auth_forward(user)
            if servers:
                res, opt = ForwardServerPolicy.do_request(servers, env,
                                                          user, passw, options)
                return res, opt

        # ------------------------------------------------------------------ --

        th = TokenHandler()

        # ------------------------------------------------------------------ --

        # auto asignement with otp only if user has no active token

        auto_assign_otp_return = th.auto_assign_otp_only(
                                                    otp=passw,
                                                    user=user,
                                                    options=options)

        if auto_assign_otp_return is True:
            return (True, None)

        # ------------------------------------------------------------------ --

        token_type = None
        if options:
            token_type = options.get('token_type', None)

        # ------------------------------------------------------------------ --

        # if there is a serial provided in the parameters, it overwrites the
        # token selection by user

        query_user = user
        if options and 'serial' in  options and options['serial']:
            serial = options['serial']
            query_user = None

        # ------------------------------------------------------------------ --

        tokenList = getTokens4UserOrSerial(
                               query_user,
                               serial,
                               token_type=token_type,
                               read_for_update=True
                               )

        if len(tokenList) == 0:
            audit['action_detail'] = 'User has no tokens assigned'

            # here we check if we should to autoassign and try to do it
            auto_assign_return = th.auto_assignToken(passw, user)
            if auto_assign_return is True:
                # We can not check the token, as the OTP value is already used!
                # but we will auth the user....
                return (True, opt)

            auto_enroll_return, opt = th.auto_enrollToken(passw, user,
                                                          options=options)
            if auto_enroll_return is True:
                # we always have to return a false, as
                # we have a challenge tiggered
                return (False, opt)

            pass_on = context.get('Config').get('linotp.PassOnUserNoToken',
                                                False)
            if pass_on and 'true' == pass_on.lower():
                audit['action_detail'] = 'authenticated by PassOnUserNoToken'
                return (True, opt)

            # Check if there is an authentication policy passthru

            if get_auth_passthru(user):
                log.debug('user %r has no token. Checking for '
                          'passthru in realm %r' % (user.login, user.realm))
                y = getResolverObject(resolverClass)
                audit['action_detail'] = 'Authenticated against Resolver'
                if y.checkPass(uid, passw):
                    return (True, opt)

            # Check alternatively if there is an authentication
            # policy passOnNoToken
            elif get_auth_passOnNoToken(user):
                log.info('user %r has not token. PassOnNoToken'
                         ' set - authenticated!')
                audit['action_detail'] = (
                    'Authenticated by passOnNoToken policy')
                return (True, opt)

            # if we have an user, check if we forward the request to another server
            elif get_auth_forward_on_no_token(user) is True:
                servers = get_auth_forward(user)
                if servers:
                    res, opt = ForwardServerPolicy.do_request(
                                            servers, env, user, passw, options)
                    return res, opt

            return False, opt

        if passw is None:
            raise ParameterError(u"Missing parameter:pass", id=905)

        (res, opt) = self.checkTokenList(
            tokenList, passw, user, options=options)

        return (res, opt)