Exemplo n.º 1
0
    def smspin(self):
        '''
        This function is used in conjunction with an SMS token:
        the user authenticates with user and pin (pass) and
        will receive on his mobile an OTP as message

        method:
            validate/smspin

        arguments:
            * user:    username / loginname
            * pass:    the password that consists of a possible fixed password
            * realm:   additional realm to match the user to a useridresolver

        returns:
            JSON response
        '''
        ret = False
        param = self.request_params
        state = ''
        message = 'No sms message defined!'

        try:
            user = getUserFromParam(param)
            g.audit['user'] = user.login
            g.audit['realm'] = user.realm or getDefaultRealm()
            g.audit['success'] = 0

            (ret, opt) = self._check(param)

            ## here we build some backward compatibility
            if type(opt) is dict:
                state = opt.get('state', '') or ''
                message = opt.get('message', '') or 'No sms message defined!'

            # sucessfull submit
            if (message in ['sms with otp already submitted', 'sms submitted']
                    and len(state) > 0):
                ret = True
                g.audit['success'] = 1

            # sending sms failed should be an error
            elif message in ['sending sms failed']:
                ret = True
                g.audit['success'] = 0

            # anything else is an exception
            else:
                raise Exception(message)

            db.session.commit()
            return sendResult(response, ret, opt)

        except Exception as exx:
            log.exception("[smspin] validate/smspin failed: %r" % exx)
            # If an internal error occurs or the SMS gateway did not send
            # the SMS, we write this to the detail info.
            g.audit['info'] = str(exx)
            db.session.rollback()
            return sendResult(response, False, 0)
Exemplo n.º 2
0
    def webkdc_userinfo(self):
        # Called by WebAuth via the Elm remctld scripts.
        # Returns information about whether the user owns any tokens.

        # TODO: Require some sort of session token.
        param = {}

        try:
            param.update(request.params)
            user = getUserFromParam(param, optionalOrRequired = True)
            if (user is not None and user.isEmpty() == False):
                (userid, idResolver, idResolverClass) = getUserId(user)

                sqlQuery = Session.query(model.Token).with_lockmode("update").filter(
                   model.Token.LinOtpUserid == userid).filter(
                    model.Token.LinOtpIdResClass == idResolverClass).filter(
                     model.Token.LinOtpIsactive == 1)

                tokenList = []
                for token in sqlQuery:
                    tokenList.append(token.LinOtpTokenSerialnumber)

            Session.commit()

            return sendResult(response, tokenList, 0)

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

            Session.rollback()
            return sendError(response, u"validate/webkdc_userinfo failed: %s" % unicode(exx), 0)
        finally:
            Session.close()
Exemplo n.º 3
0
    def samlcheck(self):
        '''
        This function is used to validate the username and the otp value/password
        in a SAML environment. If ``linotp.allowSamlAttributes = True``
        then the attributes of the authenticated users are also contained
        in the response.

        method:
            validate/samlcheck

        arguments:
            * user:    username / loginname
            * pass:    the password that consists of a possible fixes password component and the OTP value
            * realm:   optional realm to match the user to a useridresolver

        returns:
            JSON response
        '''

        try:
            opt = None
            param = self.request_params
            (ok, opt) = self._check(param)
            attributes = {}

            if True == ok:
                allowSAML = False
                try:
                    allowSAML = getFromConfig("allowSamlAttributes")
                except:
                    log.warning("[samlcheck] Calling controller samlcheck. But allowSamlAttributes is False.")
                if "True" == allowSAML:
                    ## Now we get the attributes of the user
                    user = getUserFromParam(param)
                    (uid, resId, resIdC) = getUserId(user)
                    userInfo = getUserInfo(uid, resId, resIdC)
                    log.debug("[samlcheck] getting attributes for: %s@%s"
                              % (user.login, user.realm))

                    res = userInfo
                    for key in ['username',
                                'surname',
                                'mobile',
                                'phone',
                                'givenname',
                                'email']:
                        if key in res:
                            attributes[key] = res[key]

            Session.commit()
            return sendResult(response, { 'auth': ok, 'attributes' : attributes } , 0, opt)

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

        finally:
            Session.close()
Exemplo n.º 4
0
    def samlcheck(self):
        '''
        This function is used to validate the username and the otp value/password
        in a SAML environment. If ``linotp.allowSamlAttributes = True``
        then the attributes of the authenticated users are also contained
        in the response.

        method:
            validate/samlcheck

        arguments:
            * user:    username / loginname
            * pass:    the password that consists of a possible fixes password component and the OTP value
            * realm:   optional realm to match the user to a useridresolver

        returns:
            JSON response
        '''

        try:
            opt = None
            param = request.params
            (ok, opt) = self._check(param)
            attributes = {}

            if True == ok:
                allowSAML = False
                try:
                    allowSAML = getFromConfig("allowSamlAttributes")
                except:
                    log.warning("[samlcheck] Calling controller samlcheck. But allowSamlAttributes is False.")
                if "True" == allowSAML:
                    ## Now we get the attributes of the user
                    user = getUserFromParam(param)
                    (uid, resId, resIdC) = getUserId(user)
                    userInfo = getUserInfo(uid, resId, resIdC)
                    log.debug("[samlcheck] getting attributes for: %s@%s"
                              % (user.login, user.realm))

                    res = userInfo
                    for key in ['username',
                                'surname',
                                'mobile',
                                'phone',
                                'givenname',
                                'email']:
                        if key in res:
                            attributes[key] = res[key]

            Session.commit()
            return sendResult(response, { 'auth': ok, 'attributes' : attributes } , 0, opt)

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

        finally:
            Session.close()
Exemplo n.º 5
0
    def pair(self):

        try:

            params = dict(**request.params)
            enc_response = params.get('pairing_response')
            if enc_response is None:
                raise Exception('Parameter missing')

            dec_response = decrypt_pairing_response(enc_response)

            if not dec_response.serial:
                raise ValidateError(
                    'Pairing responses with no serial attached '
                    'are currently not implemented.')

            serial = dec_response.serial
            user_public_key = dec_response.user_public_key
            user_token_id = dec_response.user_token_id
            user = dec_response.user_login

            user = getUserFromParam(params, optional)

            # TODO: pairing policy
            tokens = getTokens4UserOrSerial(None, serial)

            if not tokens:
                raise Exception('Invalid serial in pairing response')

            if len(tokens) > 1:
                raise Exception('Multiple tokens found. Pairing not possible')

            token = tokens[0]

            if token.type != 'qr':
                raise Exception('Pairing is only implemented for the qrtoken')

            token.ensure_state('pairing_url_sent')
            token.addToTokenInfo('user_token_id', user_token_id)
            b64_user_public_key = b64encode(user_public_key)
            token.addToTokenInfo('user_public_key', b64_user_public_key)

            params['serial'] = serial
            params['user_public_key'] = user_public_key
            params['user_token_id'] = user_token_id
            params['user'] = user
            params['content_type'] = CONTENT_TYPE_PAIRING
            params['data'] = serial

            token.change_state('pairing_response_received')
            Session.commit()
            return sendResult(response, False)

        except Exception:
            Session.rollback()
            return sendResult(response, False, 0, status=False)

        finally:
            Session.close()
Exemplo n.º 6
0
    def pair(self):

        try:

            params = dict(**request.params)
            enc_response = params.get('pairing_response')
            if enc_response is None:
                raise Exception('Parameter missing')

            dec_response = decrypt_pairing_response(enc_response)

            if not dec_response.serial:
                raise ValidateError('Pairing responses with no serial attached '
                                    'are currently not implemented.')

            serial = dec_response.serial
            user_public_key = dec_response.user_public_key
            user_token_id = dec_response.user_token_id
            user = dec_response.user_login

            user = getUserFromParam(params, optional)

            # TODO: pairing policy
            tokens = getTokens4UserOrSerial(None, serial)

            if not tokens:
                raise Exception('Invalid serial in pairing response')

            if len(tokens) > 1:
                raise Exception('Multiple tokens found. Pairing not possible')

            token = tokens[0]

            if token.type != 'qr':
                raise Exception('Pairing is only implemented for the qrtoken')

            token.ensure_state('pairing_url_sent')
            token.addToTokenInfo('user_token_id', user_token_id)
            b64_user_public_key = b64encode(user_public_key)
            token.addToTokenInfo('user_public_key', b64_user_public_key)

            params['serial'] = serial
            params['user_public_key'] = user_public_key
            params['user_token_id'] = user_token_id
            params['user'] = user
            params['content_type'] = CONTENT_TYPE_PAIRING
            params['data'] = serial

            token.change_state('pairing_response_received')
            Session.commit()
            return sendResult(response, False)

        except Exception:
            Session.rollback()
            return sendResult(response, False, 0, status=False)

        finally:
            Session.close()
Exemplo n.º 7
0
    def check_status(self):
        """
        check the status of a transaction - for polling support
        """

        try:

            param = {}
            param.update(request.params)

            #
            # we require either state or transactionid as parameter

            transid = param.get('state', param.get('transactionid', None))
            if not transid:
                raise ParameterError(_('Missing required parameter "state" or '
                                     '"transactionid"!'))

            #
            # serial is an optional parameter

            serial = param.get('serial', None)

            #
            # but user is an required parameter

            if "user" not in param:
                raise ParameterError(_('Missing required parameter "serial"'
                                     ' or "user"!'))

            user = getUserFromParam(param)

            passw = param.get('pass', None)
            if passw is None:
                raise ParameterError(_('Missing required parameter "pass"!'))

            use_offline = param.get('use_offline', False)

            va = ValidationHandler()
            ok, opt = va.check_status(transid=transid, user=user,
                                      serial=serial, password=passw,
                                      use_offline=use_offline)

            c.audit['success'] = ok
            c.audit['info'] = unicode(opt)

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

        except Exception as exx:
            log.exception("check_status failed: %r" % exx)
            c.audit['info'] = unicode(exx)
            Session.rollback()
            return sendResult(response, False, 0)

        finally:
            Session.close()
Exemplo n.º 8
0
    def samlcheck(self):
        """
        This function is used to validate the username and the otp value/password
        in a SAML environment. If ``linotp.allowSamlAttributes = True``
        then the attributes of the authenticated users are also contained
        in the response.

        method:
            validate/samlcheck

        arguments:
            * user:    username / loginname
            * pass:    the password that consists of a possible fixes password component and the OTP value
            * realm:   optional realm to match the user to a useridresolver

        returns:
            JSON response
        """

        try:
            opt = None
            param = request.params
            (ok, opt) = self._check(param)
            attributes = {}

            if True == ok:
                allowSAML = False
                try:
                    allowSAML = getFromConfig("allowSamlAttributes")
                except:
                    log.warning("[samlcheck] Calling controller samlcheck. But allowSamlAttributes == False.")
                if "True" == allowSAML:
                    ## Now we get the attributes of the user
                    user = getUserFromParam(param, optional)
                    (uid, resId, resIdC) = getUserId(user)
                    userInfo = getUserInfo(uid, resId, resIdC)
                    # users   = getUserList({ 'username':user.getUser()} , user)
                    log.debug("[samlcheck] getting attributes for: %s@%s" % (user.getUser(), user.getRealm()))

                    res = userInfo
                    for key in ["username", "surname", "mobile", "phone", "givenname", "email"]:
                        if key in res:
                            attributes[key] = res[key]

            Session.commit()
            return sendResult(response, {"auth": ok, "attributes": attributes}, 0, opt)

        except Exception as exx:
            log.error("[samlcheck] validate/check failed: %r" % exx)
            log.error("[samlcheck] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response, "validate/samlcheck failed: %s" % unicode(exx), 0)

        finally:
            Session.close()
            log.debug("[samlcheck] done")
Exemplo n.º 9
0
    def check_status(self):
        """
        check the status of a transaction - for polling support
        """

        try:

            param = self.request_params

            #
            # we require either state or transactionid as parameter

            transid = param.get('state', param.get('transactionid', None))
            if not transid:
                raise ParameterError(_('Missing required parameter "state" or '
                                     '"transactionid"!'))

            #
            # serial is an optional parameter

            serial = param.get('serial', None)

            # user is an optional parameter:
            # if no 'user' in the parameters, the User object will be empty
            user = getUserFromParam(param)

            passw = param.get('pass')
            if passw is None:
                raise ParameterError(_('Missing required parameter "pass"!'))

            use_offline = param.get('use_offline', False)

            va = ValidationHandler()
            ok, opt = va.check_status(transid=transid, user=user,
                                      serial=serial, password=passw,
                                      use_offline=use_offline)

            c.audit['success'] = ok
            c.audit['info'] = unicode(opt)

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

        except Exception as exx:
            log.exception("check_status failed: %r" % exx)
            c.audit['info'] = unicode(exx)
            Session.rollback()
            return sendResult(response, False, 0)

        finally:
            Session.close()
Exemplo n.º 10
0
    def check_status(self):
        """
        check the status of a transaction - for polling support
        """

        try:

            param = self.request_params

            #
            # we require either state or transactionid as parameter

            transid = param.get('state', param.get('transactionid', None))
            if not transid:
                raise ParameterError(
                    _('Missing required parameter "state" or '
                      '"transactionid"!'))

            #
            # serial is an optional parameter

            serial = param.get('serial', None)

            # user is an optional parameter:
            # if no 'user' in the parameters, the User object will be empty
            user = getUserFromParam(param)

            passw = param.get('pass')
            if passw is None:
                raise ParameterError(_('Missing required parameter "pass"!'))

            use_offline = param.get('use_offline', False)

            va = ValidationHandler()
            ok, opt = va.check_status(transid=transid,
                                      user=user,
                                      serial=serial,
                                      password=passw,
                                      use_offline=use_offline)

            g.audit['success'] = ok
            g.audit['info'] = str(opt)

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

        except Exception as exx:
            log.exception("check_status failed: %r" % exx)
            g.audit['info'] = str(exx)
            db.session.rollback()
            return sendResult(response, False, 0)
Exemplo n.º 11
0
    def test_split_at_atsign(
        self,
        mock_getFromConfig,
        mock_getDefaultRealm,
        mock_getResolversOfUser,
        mock_getRealms,
    ):
        """
        test the test sets for split at @ sign
        """

        errors = []
        config_id = 0

        for test_set in self.test_sets:
            config_id += 1
            config = test_set["config"]

            mock_getFromConfig.return_value = config["split@sign"]
            mock_getDefaultRealm.return_value = config["defaultRealm"]
            mock_getResolversOfUser.return_value = config["resolversOfUser"]
            mock_getRealms.return_value = config["realms"]

            # ------------------------------------------------------------- --
            run_id = 0
            for run in test_set["runs"]:

                run_id += 1
                param = run["params"]
                result = run["result"]

                user = getUserFromParam(param)

                msg = ("Failed for config: %r\n at run[%r] %r\n"
                       "result was %r" % (config, run_id, run, user))

                try:

                    assert user.login == result["login"], msg
                    assert user.realm == result["realm"], msg

                except Exception as _exx:
                    errors.append(msg)

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

        if errors:
            raise Exception(errors)

        return
Exemplo n.º 12
0
    def check_status(self):
        """
        check the status of a transaction - for polling support
        """
        param = {}
        ok = False
        opt = None

        try:
            param.update(request.params)

            transid = param.get('state', param.get('transactionid', None))
            if not transid:
                raise ParameterError(_('Missing required parameter "state" or '
                                     '"transactionid"!'))

            serial = param.get('serial', None)
            user = getUserFromParam(param, False)

            if not user and not serial:
                raise ParameterError(_('Missing required parameter "serial"'
                                     ' or "user"!'))

            passw = param.get('pass', None)
            if not passw:
                raise ParameterError(_('Missing required parameter "pass"!'))

            use_offline = param.get('use_offline', False)

            va = ValidationHandler()
            ok, opt = va.check_status(transid=transid, user=user,
                                      serial=serial, password=passw,
                                      use_offline=use_offline)

            c.audit['success'] = ok
            c.audit['info'] = unicode(opt)

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

        except Exception as exx:
            log.exception("check_status failed: %r" % exx)
            c.audit['info'] = unicode(exx)
            Session.rollback()
            return sendResult(response, False, 0)

        finally:
            Session.close()
            log.debug('[check] done')
Exemplo n.º 13
0
    def test_split_at_atsign(self,
                             mock_getFromConfig,
                             mock_getDefaultRealm,
                             mock_getResolversOfUser,
                             mock_getRealms):
        """
        test the test sets for split at @ sign
        """

        errors = []
        config_id = 0

        for test_set in self.test_sets:
            config_id += 1
            config = test_set['config']

            mock_getFromConfig.return_value = config['split@sign']
            mock_getDefaultRealm.return_value = config['defaultRealm']
            mock_getResolversOfUser.return_value = config['resolversOfUser']
            mock_getRealms.return_value = config['realms']

            # ------------------------------------------------------------- --
            run_id = 0
            for run in test_set['runs']:

                run_id += 1
                param = run['params']
                result = run['result']

                user = getUserFromParam(param)

                msg = ("Failed for config: %r\n at run[%r] %r\n"
                       "result was %r" % (config, run_id, run, user))

                try:

                    self.assertTrue(user.login == result['login'], msg)
                    self.assertTrue(user.realm == result['realm'], msg)

                except Exception as _exx:
                    errors.append(msg)

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

        if errors:
            raise Exception(errors)

        return
Exemplo n.º 14
0
    def test_split_at_atsign(self,
                             mock_getFromConfig,
                             mock_getDefaultRealm,
                             mock_getResolversOfUser,
                             mock_getRealms):
        """
        test the test sets for split at @ sign
        """

        errors = []
        config_id = 0

        for test_set in self.test_sets:
            config_id += 1
            config = test_set['config']

            mock_getFromConfig.return_value = config['split@sign']
            mock_getDefaultRealm.return_value = config['defaultRealm']
            mock_getResolversOfUser.return_value = config['resolversOfUser']
            mock_getRealms.return_value = config['realms']

            # ------------------------------------------------------------- --
            run_id = 0
            for run in test_set['runs']:

                run_id += 1
                param = run['params']
                result = run['result']

                user = getUserFromParam(param)

                msg = ("Failed for config: %r\n at run[%r] %r\n"
                       "result was %r" % (config, run_id, run, user))

                try:

                    self.assertTrue(user.login == result['login'], msg)
                    self.assertTrue(user.realm == result['realm'], msg)

                except Exception as _exx:
                    errors.append(msg)

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

        if errors:
            raise Exception(errors)

        return
Exemplo n.º 15
0
    def do_autosms_test(self, policy, user, client_ip, expected_result):
        new_policy = {
            "name": "autosms",
            "scope": "authentication",
            "realm": "*",
            "action": "autosms",
        }
        if policy:
            new_policy.update(policy)
        self.set_policy(new_policy)

        context["Client"] = client_ip
        context["RequestUser"] = getUserFromParam({"user": user})

        result = get_auth_AutoSMSPolicy()
        assert result == expected_result
Exemplo n.º 16
0
    def parse_requesting_user(self):
        """
        load the requesting user

        The result is placed into request_context['RequestUser']
        """
        from linotp.useridresolver.UserIdResolver import (ResolverNotAvailable)

        requestUser = None
        try:
            requestUser = getUserFromParam(self.request_params)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r", exx)
        except (ResolverNotAvailable, NoResolverFound) as exx:
            log.error("Failed to connect to server %r", exx)

        request_context['RequestUser'] = requestUser
Exemplo n.º 17
0
    def autosms(self):
        '''
        This function is used to test the autosms policy

        method:
            testing/autosms

        arguments:
            user    - username / loginname
            realm   - additional realm to match the user to a useridresolver


        returns:
            JSON response
        '''
        log.debug('[autosms]')

        param = request.params
        try:

            if isSelfTest() == False:
                Session.rollback()
                return sendError(
                    response,
                    "The testing controller can only be used in SelfTest mode!",
                    0)

            user = getUserFromParam(param, required)
            ok = get_auth_AutoSMSPolicy()

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

        except Exception as e:
            log.error("[autosms] validate/check failed: %r", e)
            log.error("[autosms] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response, "validate/check failed:" + unicode(e),
                             0)

        finally:
            Session.close()
            log.debug('[autosms] done')
Exemplo n.º 18
0
    def webkdc_userinfo(self):
        # Called by WebAuth via the Elm remctld scripts.
        # Returns information about whether the user owns any tokens.

        # TODO: Require some sort of session token.
        param = {}

        try:
            param.update(request.params)
            user = getUserFromParam(param, optionalOrRequired=True)
            if (user is not None and user.isEmpty() == False):
                (userid, idResolver, idResolverClass) = getUserId(user)

                sqlQuery = Session.query(
                    model.Token).with_lockmode("update").filter(
                        model.Token.LinOtpUserid == userid).filter(
                            model.Token.LinOtpIdResClass == idResolverClass
                        ).filter(model.Token.LinOtpIsactive == True)

                tokenList = {}
                for token in sqlQuery:
                    tokenList[token.LinOtpTokenSerialnumber] = json.loads(
                        token.LinOtpTokenInfo)

            Session.commit()

            return sendResult(response, tokenList, 0)

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

            Session.rollback()
            return sendError(
                response,
                u"validate/webkdc_userinfo failed: %s" % unicode(exx), 0)
        finally:
            Session.close()
Exemplo n.º 19
0
    def autosms(self):
        '''
        This function is used to test the autosms policy

        method:
            testing/autosms

        arguments:
            user    - username / loginname
            realm   - additional realm to match the user to a useridresolver


        returns:
            JSON response
        '''
        log.debug('[autosms]')

        param = request.params
        try:

            if isSelfTest() == False:
                Session.rollback()
                return sendError(response, "The testing controller can only be used in SelfTest mode!", 0)

            user = getUserFromParam(param, required)
            ok = get_auth_AutoSMSPolicy()

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

        except Exception as e:
            log.error("[autosms] validate/check failed: %r", e)
            log.error("[autosms] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response, "validate/check failed:" + unicode(e), 0)

        finally:
            Session.close()
            log.debug('[autosms] done')
Exemplo n.º 20
0
    def resolverinfo(self, realm):
        """
        get the resolvers for one realm and the number of users per resolver
        :param realm: the realm to query
        :return: dict with resolvernames as keys and number of users as value
        """
        realminfo = self.context.get('Config').getRealms().get(realm)
        resolvers = realminfo.get('useridresolver', '')
        realmdict = {}

        for resolver in resolvers:
            package, module, classs, conf = splitResolver(resolver)
            realmdict[conf] = 0

        user = getUserFromParam({'realm': realm}, optionalOrRequired=True)
        users_iters = iterate_users(getUserListIterators({'realm': realm}, user))

        for next_one in users_iters:
            for key in realmdict:
                if key in next_one:
                    realmdict[key] += 1

        return realmdict
Exemplo n.º 21
0
    def resolverinfo(self, realm):
        """
        get the resolvers for one realm and the number of users per resolver
        :param realm: the realm to query
        :return: dict with resolvernames as keys and number of users as value
        """
        realminfo = context.get('Config').getRealms().get(realm)
        resolver_specs = realminfo.get('useridresolver', '')
        realmdict = {}

        for resolver_spec in resolver_specs:
            __, config_identifier = parse_resolver_spec(resolver_spec)
            realmdict[config_identifier] = 0

        user = getUserFromParam({'realm': realm}, optionalOrRequired=True)
        users_iters = iterate_users(getUserListIterators({'realm': realm}, user))

        for next_one in users_iters:
            for key in realmdict:
                if key in next_one:
                    realmdict[key] += 1

        return realmdict
Exemplo n.º 22
0
    def resolverinfo(self, realm):
        """
        get the resolvers for one realm and the number of users per resolver
        :param realm: the realm to query
        :return: dict with resolvernames as keys and number of users as value
        """

        realminfo = context.get('Config').getRealms().get(realm)
        resolver_specs = realminfo.get('useridresolver', '')
        realmdict = {}

        for resolver_spec in resolver_specs:
            __, config_identifier = parse_resolver_spec(resolver_spec)
            realmdict[config_identifier] = 0

        user = getUserFromParam({'realm': realm})
        users = getUserList({'realm': realm, 'username': '******'}, user)

        for next_one in users:
            resolver = next_one['useridresolver'].split('.')[-1]
            if resolver in realmdict:
                realmdict[resolver] += 1

        return realmdict
Exemplo n.º 23
0
    def resolverinfo(self, realm):
        """
        get the resolvers for one realm and the number of users per resolver
        :param realm: the realm to query
        :return: dict with resolvernames as keys and number of users as value
        """

        realminfo = context.get("Config").getRealms().get(realm)
        resolver_specs = realminfo.get("useridresolver", "")
        realmdict = {}

        for resolver_spec in resolver_specs:
            __, config_identifier = parse_resolver_spec(resolver_spec)
            realmdict[config_identifier] = 0

        user = getUserFromParam({"realm": realm})
        users = getUserList({"realm": realm, "username": "******"}, user)

        for next_one in users:
            resolver = next_one["useridresolver"].split(".")[-1]
            if resolver in realmdict:
                realmdict[resolver] += 1

        return realmdict
Exemplo n.º 24
0
    def resolverinfo(self, realm):
        """
        get the resolvers for one realm and the number of users per resolver
        :param realm: the realm to query
        :return: dict with resolvernames as keys and number of users as value
        """

        realminfo = context.get('Config').getRealms().get(realm)
        resolver_specs = realminfo.get('useridresolver', '')
        realmdict = {}

        for resolver_spec in resolver_specs:
            __, config_identifier = parse_resolver_spec(resolver_spec)
            realmdict[config_identifier] = 0

        user = getUserFromParam({'realm': realm})
        users = getUserList({'realm': realm, 'username': '******'}, user)

        for next_one in users:
            resolver = next_one['useridresolver'].split('.')[-1]
            if resolver in realmdict:
                realmdict[resolver] += 1

        return realmdict
Exemplo n.º 25
0
    def create_context(self, request):
        """
        create the request context for all controllers
        """

        linotp_config = getLinotpConfig()

        request_context['Config'] = linotp_config
        request_context['Policies'] = getPolicies()
        request_context['translate'] = translate

        initResolvers()

        request_params = {}

        try:
            request_params.update(request.params)
        except UnicodeDecodeError as exx:
            log.error("Faild to decode request parameters %r" % exx)

        request_context['Params'] = request_params

        authUser = None
        try:
            authUser = getUserFromRequest(request)
        except UnicodeDecodeError as exx:
            log.error("Faild to decode request parameters %r" % exx)

        request_context['AuthUser'] = authUser

        requestUser = None
        try:
            requestUser = getUserFromParam(request_params, True)
        except UnicodeDecodeError as exx:
            log.error("Faild to decode request parameters %r" % exx)
        request_context['RequestUser'] = requestUser

        client = None
        try:
            client = get_client(request=request)
        except UnicodeDecodeError as exx:
            log.error("Faild to decode request parameters %r" % exx)

        request_context['Client'] = client

        request_context['Audit'] = Audit
        request_context['audit'] = Audit.initialize(request,
                                                         client=client)

        defaultRealm = ""
        try:
            defaultRealm = getDefaultRealm(linotp_config)
        except UnicodeDecodeError as exx:
            log.error("Faild to decode request parameters %r" % exx)

        request_context['defaultRealm'] = defaultRealm

        realms = None
        try:
            realms = getRealms()
        except UnicodeDecodeError as exx:
            log.error("Faild to decode request parameters %r" % exx)

        request_context['Realms'] = realms

        request_context['hsm'] = None
        if hasattr(self, "hsm"):
            request_context['hsm'] = self.hsm

        # copy some system entries from pylons
        syskeys = {
                   "radius.nas_identifier": "LinOTP",
                   "radius.dictfile": "/etc/linotp2/dictionary"
        }

        sysconfig = {}
        for key, default in syskeys.items():
            try:
                sysconfig[key] = config.get(key, default)
            except:
                log.info('no sytem config entry %s' % key)

        request_context['SystemConfig'] = sysconfig
Exemplo n.º 26
0
    def getotp(self):
        '''
        This function is used to retrieve the current otp value for a given user or a given serial
        If the user has more than one token, the list of the tokens is returend.

        method:
            gettoken/getotp

        arguments:
            user    - username / loginname
            realm   - additional realm to match the user to a useridresolver
            serial  - the serial number of the token
            curTime - used ONLY for internal testing: datetime.datetime object

        returns:
            JSON response
        '''

        getotp_active = config.get("linotpGetotp.active")
        if "True" != getotp_active:
            return sendError(response, "getotp is not activated.", 0)

        param = request.params
        ret = {}
        res = -1
        otpval = ""
        passw = ""
        serials = []

        try:

            serial = getParam(param, "serial", optional)
            user = getUserFromParam(param, optional)
            curTime = getParam(param, "curTime", optional)

            c.audit['user'] = user.login
            if "" != user.login:
                c.audit['realm'] = user.realm or getDefaultRealm()

            if serial:
                log.debug("[getotp] retrieving OTP value for token %s" % serial)
            elif user.login:
                log.debug("[getotp] retrieving OTP value for token for user %s@%s" % (user.login, user.realm))
                toks = getTokens4UserOrSerial(user, serial)
                tokennum = len(toks)
                if tokennum > 1:
                    log.debug("[getotp] The user has more than one token. Returning the list of serials")
                    res = -3
                    for token in toks:
                        serials.append(token.getSerial())
                elif 1 == tokennum:
                    serial = toks[0].getSerial()
                    log.debug("[getotp] retrieving OTP for token %s for user %s@%s" %
                                (serial, user.login, user.realm))
                else:
                    log.debug("[getotp] no token found for user %s@%s" % (user.login, user.realm))
                    res = -4
            else:
                res = -5

            # if a serial was given or a unique serial could be received from the given user.
            if serial:
                max_count = checkPolicyPre('gettoken', 'max_count', param)
                log.debug("[getmultiotp] checkpolicypre returned %s" % max_count)
                if max_count <= 0:
                    return sendError(response, "The policy forbids receiving OTP values for the token %s in this realm" % serial , 1)

                (res, pin, otpval, passw) = getOtp(serial, curTime=curTime)

            c.audit['success'] = True

            if int(res) < 0:
                ret['result'] = False
                if -1 == otpval:
                    ret['description'] = "No Token with this serial number"
                if -2 == otpval:
                    ret['description'] = "This Token does not support the getOtp function"
                if -3 == otpval:
                    ret['description'] = "The user has more than one token"
                    ret['serials'] = serials
                if -4 == otpval:
                    ret['description'] = "No Token found for this user"
                if -5 == otpval:
                    ret['description'] = "you need to provide a user or a serial"
            else:
                ret['result'] = True
                ret['otpval'] = otpval
                ret['pin'] = pin
                ret['pass'] = passw

            Session.commit()
            return sendResult(response, ret , 0)

        except PolicyException as pe:
            log.exception("[getotp] gettoken/getotp policy failed: %r" % pe)
            Session.rollback()
            return sendError(response, unicode(pe), 1)

        except Exception as e:
            log.exception("[getotp] gettoken/getotp failed: %r" % e)
            Session.rollback()
            return sendError(response, "gettoken/getotp failed: %s" % unicode(e), 0)

        finally:
            Session.close()
            log.debug('[getotp] done')
Exemplo n.º 27
0
    def request(self):
        """
        method:
            ocra/request

        description:
            request a challenge for a user or for a serial number (token).

        arguments:
            * serial: (required - string)
              Serial number of the token, for which a challenge should
              be generated (either serial or user is required)

            * user: (required  - string)
              The user for whose token a challenge should be generated
              If the user has more than one token, an error is returend.
              (either serial or user is required)

            * data: (required - String: URLendoced)
              These are the display data, that can be used to generate the
              challenge

        remark:
            the app will report a wrong qrcode, if the policy::

                {'authentication' : qrtanurl=https://localhost }

            is not defined !!

        returns:

            A JSON respone::

                        {
                            "version": "LinOTP 2.4",
                            "jsonrpc": "2.0",
                            "result": {
                                "status": true,
                                "value": false,
                            },
                            "detail": {
                                    "transactionid" : TRANSAKTIONSID,
                                    "data" : DATAOBJECT,
                            }
                        }

            * transactionid:
              This is the transaction ID, that is used later for
              verifying the Return code /TAN.

            * data:
              This is an object (URL) which can be used to generate a
              QR-Code to be displayed to the QRTAN App
        """
        res = {}
        description = ('ocra/request: request a challenge for a given user or'
                       ' token (serial). You must either provide a parameter '
                       '"user" or a parameter "serial".')
        dataobj = ""

        try:
            param = getLowerParams(request.params)
            log.info("[request] saving default configuration: %r" % param)

            checkPolicyPre('ocra', "request")

            serial = param.get('serial')
            user = getUserFromParam(param)

            if user.is_empty and serial is None:

                log.exception("[request] user or serial is required")
                raise ParameterError("Usage: %s" % description, id=77)

            if not serial:
                if not user.exists():
                    raise UserError("getUserId failed: no user >%s< found!"
                                    % user.login, id=1205)

            message = param.get('data')
            if message is None:
                message = ''

            # ocra token

            tokens = getTokens4UserOrSerial(user, serial)

            if len(tokens) > 1:
                error = ('More than one token found: unable to create '
                         'challenge for (u:%r,s:%r)!' % (user, serial))
                raise Exception(error)

            if len(tokens) == 0:
                error = ('No token found: unable to create challenge for'
                         ' (u:%r,s:%r)!' % (user, serial))
                raise Exception(error)

            ocra = tokens[0]
            (transId, challenge, res, url) = ocra.challenge(message)

            u = urlencode({'u': str(url.encode("utf-8"))})

            uInfo = {'tr': transId,
                     'ch': challenge,
                     'me': str(message.encode("utf-8")),
                     'u': u[2:]}

            detail = {"transactionid": transId,
                      'challenge': challenge,
                      'message': str(message.encode("utf-8")),
                      'url': str(url.encode("utf-8")), }

            # create the app_url from the data

            dataobj = 'lseqr://req?%s' % (str(urlencode(uInfo)))

            # append the signature to the url

            signature = {'si': ocra.signData(dataobj)}
            uInfo['si'] = signature
            dataobj = '%s&%s' % (dataobj, str(urlencode(signature)))

            detail["data"] = dataobj

            c.audit['success'] = res

            Session.commit()
            qr = param.get('qr')
            if qr is not None:
                param['alt'] = detail
                return sendQRImageResult(response, dataobj, param)
            else:
                return sendResult(response, res, 1, opt=detail)

        except PolicyException as pe:
            log.exception("[request] policy failed: %r" % pe)
            Session.rollback()
            return sendError(response, unicode(pe))

        except Exception as exx:
            log.exception("[request] failed: %r" % exx)
            Session.rollback()
            return sendError(response, unicode(exx))

        finally:
            Session.close()
Exemplo n.º 28
0
    def document_split_at_atsign(self,
                                 mock_getFromConfig,
                                 mock_getDefaultRealm,
                                 mock_getResolversOfUser,
                                 mock_getRealms):
        """
        create documentation for the split at @sign behaviour
        """

        table = []

        raisedException = None

        config_id = 0

        for test_set in self.test_sets:
            config_id += 1
            config = test_set['config']

            mock_getFromConfig.return_value = config['split@sign']
            mock_getDefaultRealm.return_value = config['defaultRealm']
            mock_getResolversOfUser.return_value = config['resolversOfUser']
            mock_getRealms.return_value = config['realms']

            table.append('')
            cparams = json.dumps(config)
            cc = cparams.replace(
                '{', ' * ').replace(
                    ',', ' * ').replace(
                        '}', '')

            panel = ("{panel:title=Configuration|borderColor=blue|"
                     "titleBGColor=#708090|titleColor=white|bgColor=#dcdcdc}")
            cc = cc.replace(
                "true", 'Ja').replace(
                    "resolversOfUser", "User wird Resolver gefunden").replace(
                        "realms", "Benutzer ist in folgenden Realms")

            table.append('%s %s' % (panel, cc))
            table.append('')

            # ------------------------------------------------------------- --
            run_id = 0
            for run in test_set['runs']:

                run_id += 1
                param = run['params']

                user = getUserFromParam(param)

                jparams = json.dumps(param)
                pp = jparams.replace(
                    '{', '|* ').replace(
                        ',', ' * ').replace(
                            '}', '')

                result = {'login': user.login, 'realm': user.realm}
                rparams = json.dumps(result)
                rr = rparams.replace(
                    '{', '|* ').replace(
                        ',', ' * ').replace(
                            '}', '')

                table.append('||Parameters: %s||Result: %s|' % (pp, rr))

            table.append('{panel}')
            table.append('')

        with open('/tmp/split_at_atsign.txt', 'w') as ff:
            ff.write("\n".join(table).replace(
                ' * ', '\n* ').replace(
                    '[', '- ').replace(
                        ']', ''))

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

        if raisedException:
            raise raisedException


# eof #
Exemplo n.º 29
0
    def getotp(self):
        '''
        This function is used to retrieve the current otp value for a given user or a given serial
        If the user has more than one token, the list of the tokens is returend.

        method:
            gettoken/getotp

        arguments:
            user    - username / loginname
            realm   - additional realm to match the user to a useridresolver
            serial  - the serial number of the token
            curTime - used ONY for internal testing: datetime.datetime object

        returns:
            JSON response
        '''

        getotp_active = config.get("linotpGetotp.active")
        if "True" != getotp_active:
            return sendError(response, "getotp is not activated.", 0)

        param = request.params
        ret = {}
        res = -1
        otpval = ""
        passw = ""
        serials = []

        try:

            serial = getParam(param, "serial", optional)
            user = getUserFromParam(param, optional)
            curTime = getParam(param, "curTime", optional)

            c.audit['user'] = user.login
            if "" != user.login:
                c.audit['realm'] = user.realm or getDefaultRealm()

            if serial:
                log.debug("[getotp] retrieving OTP value for token %s" %
                          serial)
            elif user.login:
                log.debug(
                    "[getotp] retrieving OTP value for token for user %s@%s" %
                    (user.login, user.realm))
                toks = getTokens4UserOrSerial(user, serial)
                tokennum = len(toks)
                if tokennum > 1:
                    log.debug(
                        "[getotp] The user has more than one token. Returning the list of serials"
                    )
                    res = -3
                    for token in toks:
                        serials.append(token.getSerial())
                elif 1 == tokennum:
                    serial = toks[0].getSerial()
                    log.debug(
                        "[getotp] retrieving OTP for token %s for user %s@%s" %
                        (serial, user.login, user.realm))
                else:
                    log.debug("[getotp] no token found for user %s@%s" %
                              (user.login, user.realm))
                    res = -4
            else:
                res = -5

            # if a serial was given or a unique serial could be received from the given user.
            if serial:
                max_count = checkPolicyPre('gettoken', 'max_count', param)
                log.debug("[getmultiotp] checkpolicypre returned %s" %
                          max_count)
                if max_count <= 0:
                    return sendError(
                        response,
                        "The policy forbids receiving OTP values for the token %s in this realm"
                        % serial, 1)

                (res, pin, otpval, passw) = getOtp(serial, curTime=curTime)

            c.audit['success'] = True

            if int(res) < 0:
                ret['result'] = False
                if -1 == otpval:
                    ret['description'] = "No Token with this serial number"
                if -2 == otpval:
                    ret['description'] = "This Token does not support the getOtp function"
                if -3 == otpval:
                    ret['description'] = "The user has more than one token"
                    ret['serials'] = serials
                if -4 == otpval:
                    ret['description'] = "No Token found for this user"
                if -5 == otpval:
                    ret['description'] = "you need to provide a user or a serial"
            else:
                ret['result'] = True
                ret['otpval'] = otpval
                ret['pin'] = pin
                ret['pass'] = passw

            Session.commit()
            return sendResult(response, ret, 0)

        except PolicyException as pe:
            log.error("[getotp] gettoken/getotp policy failed: %r" % pe)
            log.error("[getotp] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response, unicode(pe), 1)

        except Exception as e:
            log.error("[getotp] gettoken/getotp failed: %r" % e)
            log.error("[getotp] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response,
                             "gettoken/getotp failed: %s" % unicode(e), 0)

        finally:
            Session.close()
            log.debug('[getotp] done')
Exemplo n.º 30
0
    def userview_flexi(self):
        '''
        This function is used to fill the flexigrid.
        Unlike the complex /admin/userlist function, it only returns a
        simple array of the tokens.
        '''
        param = request.params

        try:
            #serial  = getParam(param,"serial",optional)
            c.page = getParam(param, "page", optional)
            c.filter = getParam(param, "query", optional)
            qtype = getParam(param, "qtype", optional)
            c.sort = getParam(param, "sortname", optional)
            c.dir = getParam(param, "sortorder", optional)
            c.psize = getParam(param, "rp", optional)
            c.realm = getParam(param, "realm", optional)

            user = getUserFromParam(param, optional)
            # check admin authorization
            # check if we got a realm or resolver, that is ok!
            checkPolicyPre('admin', 'userlist', {
                'user': user.login,
                'realm': c.realm
            })

            if c.filter == "":
                c.filter = "*"

            log.debug(
                "[userview_flexi] page: %s, filter: %s, sort: %s, dir: %s" %
                (c.page, c.filter, c.sort, c.dir))

            if c.page is None:
                c.page = 1
            if c.psize is None:
                c.psize = 20

            c.userArray = getUserList({
                qtype: c.filter,
                'realm': c.realm
            }, user)
            c.userNum = len(c.userArray)

            lines = []
            for u in c.userArray:
                # shorten the useridresolver, to get a better display value
                resolver_display = ""
                if "useridresolver" in u:
                    if len(u['useridresolver'].split(".")) > 3:
                        resolver_display = u['useridresolver'].split(".")[
                            3] + " (" + u['useridresolver'].split(".")[1] + ")"
                    else:
                        resolver_display = u['useridresolver']
                # Arrange the table more helpfully.
                lines.append({
                    'id':
                    u['username'],
                    'cell': [
                        (u['username']) if u.has_key('username') else (""),
                        (u['givenname']) if u.has_key('givenname') else (""),
                        (u['surname']) if u.has_key('surname') else (""),
                        (u['email']) if u.has_key('email') else (""),
                        (u['userid']) if u.has_key('userid') else (""),
                    ]
                })

            log.debug("[userview_flexi] Elements in c.userArray: %s" %
                      len(c.userArray))
            # sorting
            reverse = False
            sortnames = {
                'username': 0,
                'givenname': 1,
                'surname': 2,
                'email': 3,
                'userid': 4
            }
            if c.dir == "desc":
                reverse = True

            lines = sorted(lines,
                           key=lambda user: user['cell'][sortnames[c.sort]],
                           reverse=reverse,
                           cmp=unicode_compare)
            # end: sorting

            # reducing the page
            if c.page and c.psize:
                page = int(c.page)
                psize = int(c.psize)
                start = psize * (page - 1)
                end = start + psize
                lines = lines[start:end]

            # We need to return 'page', 'total', 'rows'
            response.content_type = 'application/json'
            res = {"page": int(c.page), "total": c.userNum, "rows": lines}

            c.audit['success'] = True

            Session.commit()
            return json.dumps(res, indent=3)

        except PolicyException as pe:
            log.error("[userview_flexi] Error during checking policies: %r" %
                      pe)
            log.error("[userview_flexi] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response, unicode(pe), 1)

        except Exception as e:
            log.error("[userview_flexi] failed: %r" % e)
            log.error("[userview_flexi] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response, e)

        finally:
            Session.close()
            log.debug('[userview_flexi] done')
Exemplo n.º 31
0
    def smspin(self):
        '''
        This function is used in conjunction with an SMS token:
        the user authenticates with user and pin (pass) and
        will receive on his mobile an OTP as message

        method:
            validate/smspin

        arguments:
            * user:    username / loginname
            * pass:    the password that consists of a possible fixed password
            * realm:   additional realm to match the user to a useridresolver

        returns:
            JSON response
        '''
        ret = False
        param = request.params
        state = ''
        message = 'No sms message defined!'

        try:
            user = getUserFromParam(param, optional)
            c.audit['user'] = user.login
            c.audit['realm'] = user.realm or getDefaultRealm()
            c.audit['success'] = 0

            (ret, opt) = self._check(param)

            ## here we build some backward compatibility
            if type(opt) is dict:
                state = opt.get('state', '') or ''
                message = opt.get('message', '') or 'No sms message defined!'

            # sucessfull submit
            if (message in ['sms with otp already submitted',
                            'sms submitted']
                and len(state) > 0):
                ret = True
                c.audit['success'] = 1

            # sending sms failed should be an error
            elif message in ['sending sms failed']:
                ret = True
                c.audit['success'] = 0

            # anything else is an exception
            else:
                raise Exception(message)

            Session.commit()
            return sendResult(response, ret, opt)

        except Exception as exx:
            log.exception("[smspin] validate/smspin failed: %r" % exx)
            # If an internal error occurs or the SMS gateway did not send
            # the SMS, we write this to the detail info.
            c.audit['info'] = unicode(exx)
            Session.rollback()
            return sendResult(response, False, 0)

        finally:
            Session.close()
            log.debug("[smspin] done")
Exemplo n.º 32
0
    def check_s(self):
        '''
        This function is used to validate the serial and the otp value/password.

        method:
            validate/check_s

        arguments:
            * serial:  the serial number of the token
            * pass:    the password that consists of a possible fixes password component
                        and the OTP value

        returns:
            JSON response
        '''
        param = {}
        param.update(request.params)

        options = {}
        options.update(param)
        for k in ['user', 'serial', "pass", "init"]:
            if k in options:
                del options[k]

        if 'init' in param:
            if isSelfTest() is True:
                options['initTime'] = param.get('init')

        try:
            passw = getParam(param, "pass", optional)
            serial = getParam(param, 'serial', optional)
            if serial is None:
                user = getParam(param, 'user', optional)
                if user is not None:
                    user = getUserFromParam(param, optional)
                    toks = getTokens4UserOrSerial(user=user)
                    if len(toks) == 0:
                        raise Exception("No token found!")
                    elif len(toks) > 1:
                        raise Exception("More than one token found!")
                    else:
                        tok = toks[0].token
                        desc = tok.get()
                        realms = desc.get('LinOtp.RealmNames')
                        if realms is None or len(realms) == 0:
                            realm = getDefaultRealm()
                        elif len(realms) > 0:
                            realm = realms[0]

                        userInfo = getUserInfo(tok.LinOtpUserid, tok.LinOtpIdResolver, tok.LinOtpIdResClass)
                        user = User(login=userInfo.get('username'), realm=realm)

                        serial = tok.getSerial()

            c.audit['serial'] = serial

            if isSelfTest() is True:
                initTime = getParam(param, "init", optional)
                if initTime is not None:
                    if options is None:
                        options = {}
                    options['initTime'] = initTime

            options['scope'] = {"check_s": True}
            vh = ValidationHandler()
            (ok, opt) = vh.checkSerialPass(serial, passw, options=options)
            c.audit['success'] = ok
            Session.commit()

            qr = param.get('qr', None)
            if qr and opt and 'message' in opt:
                try:
                    dataobj = opt.get('message')
                    param['alt'] = "%s" % opt
                    if 'transactionid' in opt:
                        param['transactionid'] = opt['transactionid']
                    return sendQRImageResult(response, dataobj, param)
                except Exception as exc:
                    log.warning("failed to send QRImage: %r " % exc)
                    return sendQRImageResult(response, opt, param)
            else:
                return sendResult(response, ok, 0, opt=opt)

        except Exception as exx:
            log.exception("[check_s] validate/check_s failed: %r" % exx)
            c.audit['info'] = unicode(exx)
            Session.rollback()
            return sendResult(response, False, id=0, status=False)

        finally:
            Session.close()
            log.debug('[check_s] done')
Exemplo n.º 33
0
    def userview_flexi(self):
        """
        This function is used to fill the flexigrid.
        Unlike the complex /admin/userlist function, it only returns a
        simple array of the tokens.
        """
        param = request.params

        try:
            # serial  = getParam(param,"serial",optional)
            c.page = getParam(param, "page", optional)
            c.filter = getParam(param, "query", optional)
            qtype = getParam(param, "qtype", optional)
            c.sort = getParam(param, "sortname", optional)
            c.dir = getParam(param, "sortorder", optional)
            c.psize = getParam(param, "rp", optional)
            c.realm = getParam(param, "realm", optional)

            user = getUserFromParam(param, optional)
            # check admin authorization
            # check if we got a realm or resolver, that is ok!
            checkPolicyPre("admin", "userlist", {"user": user.login, "realm": c.realm})

            if c.filter == "":
                c.filter = "*"

            log.debug("[userview_flexi] page: %s, filter: %s, sort: %s, dir: %s" % (c.page, c.filter, c.sort, c.dir))

            if c.page is None:
                c.page = 1
            if c.psize is None:
                c.psize = 20

            c.userArray = getUserList({qtype: c.filter, "realm": c.realm}, user)
            c.userNum = len(c.userArray)

            lines = []
            for u in c.userArray:
                # shorten the useridresolver, to get a better display value
                resolver_display = ""
                if "useridresolver" in u:
                    if len(u["useridresolver"].split(".")) > 3:
                        resolver_display = (
                            u["useridresolver"].split(".")[3] + " (" + u["useridresolver"].split(".")[1] + ")"
                        )
                    else:
                        resolver_display = u["useridresolver"]
                lines.append(
                    {
                        "id": u["username"],
                        "cell": [
                            (u["username"]) if u.has_key("username") else (""),
                            (resolver_display),
                            (u["surname"]) if u.has_key("surname") else (""),
                            (u["givenname"]) if u.has_key("givenname") else (""),
                            (u["email"]) if u.has_key("email") else (""),
                            (u["mobile"]) if u.has_key("mobile") else (""),
                            (u["phone"]) if u.has_key("phone") else (""),
                            (u["userid"]) if u.has_key("userid") else (""),
                        ],
                    }
                )

            # sorting
            reverse = False
            sortnames = {
                "username": 0,
                "useridresolver": 1,
                "surname": 2,
                "givenname": 3,
                "email": 4,
                "mobile": 5,
                "phone": 6,
                "userid": 7,
            }
            if c.dir == "desc":
                reverse = True

            lines = sorted(
                lines, key=lambda user: user["cell"][sortnames[c.sort]], reverse=reverse, cmp=unicode_compare
            )
            # end: sorting

            # reducing the page
            if c.page and c.psize:
                page = int(c.page)
                psize = int(c.psize)
                start = psize * (page - 1)
                end = start + psize
                lines = lines[start:end]

            # We need to return 'page', 'total', 'rows'
            response.content_type = "application/json"
            res = {"page": int(c.page), "total": c.userNum, "rows": lines}

            c.audit["success"] = True

            Session.commit()
            return json.dumps(res, indent=3)

        except PolicyException as pe:
            log.error("[userview_flexi] Error during checking policies: %r" % pe)
            log.error("[userview_flexi] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response, unicode(pe), 1)

        except Exception as e:
            log.error("[userview_flexi] failed: %r" % e)
            log.error("[userview_flexi] %s" % traceback.format_exc())
            Session.rollback()
            return sendError(response, e)

        finally:
            Session.close()
            log.debug("[userview_flexi] done")
Exemplo n.º 34
0
    def create_context(self, request):
        """
        create the request context for all controllers
        """

        linotp_config = getLinotpConfig()

        self.request_context = {}
        self.request_context['Config'] = linotp_config
        self.request_context['Policies'] = getPolicies(config=linotp_config)
        self.request_context['translate'] = translate

        request_params = {}

        try:
            request_params.update(request.params)
        except UnicodeDecodeError as exx:
            log.error("Faild to decode request parameters %r" % exx)

        self.request_context['Params'] = request_params

        authUser = None
        try:
            authUser = getUserFromRequest(request)
        except UnicodeDecodeError as exx:
            log.error("Faild to decode request parameters %r" % exx)

        self.request_context['AuthUser'] = authUser

        requestUser = None
        try:
            requestUser = getUserFromParam(request_params, True)
        except UnicodeDecodeError as exx:
            log.error("Faild to decode request parameters %r" % exx)
        self.request_context['RequestUser'] = requestUser

        client = None
        try:
            client = get_client(request=request)
        except UnicodeDecodeError as exx:
            log.error("Faild to decode request parameters %r" % exx)

        self.request_context['Client'] = client

        self.request_context['audit'] = {}

        defaultRealm = ""
        try:
            defaultRealm = getDefaultRealm(linotp_config)
        except UnicodeDecodeError as exx:
            log.error("Faild to decode request parameters %r" % exx)

        self.request_context['defaultRealm'] = defaultRealm

        realms = None
        try:
            realms = getRealms(context=self.request_context)
        except UnicodeDecodeError as exx:
            log.error("Faild to decode request parameters %r" % exx)

        self.request_context['Realms'] = realms

        return
Exemplo n.º 35
0
    def check_s(self):
        '''
        This function is used to validate the serial and the otp value/password.

        method:
            validate/check_s

        arguments:
            * serial:  the serial number of the token
            * pass:    the password that consists of a possible fixes password component
                        and the OTP value

        returns:
            JSON response
        '''
        param = self.request_params

        options = {}
        options.update(param)
        for k in ['user', 'serial', "pass", "init"]:
            if k in options:
                del options[k]

        if 'init' in param:
            if isSelfTest() is True:
                options['initTime'] = param.get('init')

        try:
            passw = param.get("pass")
            serial = param.get('serial')
            if serial is None:
                user = param.get('user')
                if user is not None:
                    user = getUserFromParam(param)
                    toks = getTokens4UserOrSerial(user=user)
                    if len(toks) == 0:
                        raise Exception("No token found!")
                    elif len(toks) > 1:
                        raise Exception("More than one token found!")
                    else:
                        tok = toks[0].token
                        desc = tok.get()
                        realms = desc.get('LinOtp.RealmNames')
                        if realms is None or len(realms) == 0:
                            realm = getDefaultRealm()
                        elif len(realms) > 0:
                            realm = realms[0]

                        userInfo = getUserInfo(tok.LinOtpUserid,
                                               tok.LinOtpIdResolver,
                                               tok.LinOtpIdResClass)
                        user = User(login=userInfo.get('username'),
                                    realm=realm)

                        serial = tok.getSerial()

            c.audit['serial'] = serial

            if isSelfTest() is True:
                initTime = param.get("init")
                if initTime is not None:
                    if options is None:
                        options = {}
                    options['initTime'] = initTime

            options['scope'] = {"check_s": True}
            vh = ValidationHandler()
            (ok, opt) = vh.checkSerialPass(serial, passw, options=options)
            c.audit['success'] = ok
            Session.commit()

            qr = param.get('qr', None)
            if qr and opt and 'message' in opt:
                try:
                    dataobj = opt.get('message')
                    param['alt'] = "%s" % opt
                    if 'transactionid' in opt:
                        param['transactionid'] = opt['transactionid']
                    return sendQRImageResult(response, dataobj, param)
                except Exception as exc:
                    log.warning("failed to send QRImage: %r " % exc)
                    return sendQRImageResult(response, opt, param)
            else:
                return sendResult(response, ok, 0, opt=opt)

        except Exception as exx:
            log.exception("[check_s] validate/check_s failed: %r" % exx)
            c.audit['info'] = unicode(exx)
            Session.rollback()
            return sendResult(response, False, id=0, status=False)

        finally:
            Session.close()
Exemplo n.º 36
0
    def userview_flexi(self):
        '''
        This function is used to fill the flexigrid.
        Unlike the complex /admin/userlist function, it only returns a
        simple array of the tokens.
        '''
        param = self.request_params

        try:

            c.page = param.get("page")
            c.filter = param.get("query")
            qtype = param.get("qtype")
            c.sort = param.get("sortname")
            c.dir = param.get("sortorder")
            c.psize = param.get("rp")
            c.realm = param.get("realm")

            user = getUserFromParam(param)
            # check admin authorization
            # check if we got a realm or resolver, that is ok!
            checkPolicyPre('admin', 'userlist', {
                'user': user.login,
                'realm': c.realm
            })

            if c.filter == "":
                c.filter = "*"

            log.debug(
                "[userview_flexi] page: %s, filter: %s, sort: %s, dir: %s" %
                (c.page, c.filter, c.sort, c.dir))

            if c.page is None:
                c.page = 1
            if c.psize is None:
                c.psize = 20

            c.userArray = getUserList({
                qtype: c.filter,
                'realm': c.realm
            }, user)
            c.userNum = len(c.userArray)

            lines = []
            for u in c.userArray:
                # shorten the useridresolver, to get a better display value
                resolver_display = ""
                if "useridresolver" in u:
                    if len(u['useridresolver'].split(".")) > 3:
                        resolver_display = u['useridresolver'].split(".")[
                            3] + " (" + u['useridresolver'].split(".")[1] + ")"
                    else:
                        resolver_display = u['useridresolver']
                lines.append({
                    'id':
                    u['username'],
                    'cell': [
                        (u['username']) if 'username' in u else (""),
                        (resolver_display),
                        (u['surname']) if 'surname' in u else (""),
                        (u['givenname']) if 'givenname' in u else (""),
                        (u['email']) if 'email' in u else (""),
                        (u['mobile']) if 'mobile' in u else (""),
                        (u['phone']) if 'phone' in u else (""),
                        (u['userid']) if 'userid' in u else (""),
                    ]
                })

            # sorting
            reverse = False
            sortnames = {
                'username': 0,
                'useridresolver': 1,
                'surname': 2,
                'givenname': 3,
                'email': 4,
                'mobile': 5,
                'phone': 6,
                'userid': 7
            }
            if c.dir == "desc":
                reverse = True

            lines = sorted(lines,
                           key=lambda user: user['cell'][sortnames[c.sort]],
                           reverse=reverse)
            # end: sorting

            # reducing the page
            if c.page and c.psize:
                page = int(c.page)
                psize = int(c.psize)
                start = psize * (page - 1)
                end = start + psize
                lines = lines[start:end]

            # We need to return 'page', 'total', 'rows'
            res = {"page": int(c.page), "total": c.userNum, "rows": lines}

            c.audit['success'] = True

            Session.commit()
            return sendResult(response, res)

        except PolicyException as pe:
            log.exception(
                "[userview_flexi] Error during checking policies: %r" % pe)
            Session.rollback()
            return sendError(response, str(pe), 1)

        except Exception as e:
            log.exception("[userview_flexi] failed: %r" % e)
            Session.rollback()
            return sendError(response, e)

        finally:
            Session.close()
Exemplo n.º 37
0
    def document_split_at_atsign(self, mock_getFromConfig,
                                 mock_getDefaultRealm, mock_getResolversOfUser,
                                 mock_getRealms):
        """
        create documentation for the split at @sign behaviour
        """

        table = []

        raisedException = None

        config_id = 0

        for test_set in self.test_sets:
            config_id += 1
            config = test_set['config']

            mock_getFromConfig.return_value = config['split@sign']
            mock_getDefaultRealm.return_value = config['defaultRealm']
            mock_getResolversOfUser.return_value = config['resolversOfUser']
            mock_getRealms.return_value = config['realms']

            table.append('')
            cparams = json.dumps(config)
            cc = cparams.replace('{', ' * ').replace(',',
                                                     ' * ').replace('}', '')

            panel = ("{panel:title=Configuration|borderColor=blue|"
                     "titleBGColor=#708090|titleColor=white|bgColor=#dcdcdc}")
            cc = cc.replace("true", 'Ja').replace(
                "resolversOfUser", "User wird Resolver gefunden").replace(
                    "realms", "Benutzer ist in folgenden Realms")

            table.append('%s %s' % (panel, cc))
            table.append('')

            # ------------------------------------------------------------- --
            run_id = 0
            for run in test_set['runs']:

                run_id += 1
                param = run['params']

                user = getUserFromParam(param)

                jparams = json.dumps(param)
                pp = jparams.replace('{',
                                     '|* ').replace(',',
                                                    ' * ').replace('}', '')

                result = {'login': user.login, 'realm': user.realm}
                rparams = json.dumps(result)
                rr = rparams.replace('{',
                                     '|* ').replace(',',
                                                    ' * ').replace('}', '')

                table.append('||Parameters: %s||Result: %s|' % (pp, rr))

            table.append('{panel}')
            table.append('')

        with open('/tmp/split_at_atsign.txt', 'w') as ff:
            ff.write("\n".join(table).replace(' * ', '\n* ').replace(
                '[', '- ').replace(']', ''))

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

        if raisedException:
            raise raisedException


# eof #
Exemplo n.º 38
0
    def userview_flexi(self):
        '''
        This function is used to fill the flexigrid.
        Unlike the complex /admin/userlist function, it only returns a
        simple array of the tokens.
        '''
        param = request.params

        try:
            #serial  = getParam(param,"serial",optional)
            c.page = getParam(param, "page", optional)
            c.filter = getParam(param, "query", optional)
            qtype = getParam(param, "qtype", optional)
            c.sort = getParam(param, "sortname", optional)
            c.dir = getParam(param, "sortorder", optional)
            c.psize = getParam(param, "rp", optional)
            c.realm = getParam(param, "realm", optional)

            user = getUserFromParam(param, optional)
            # check admin authorization
            # check if we got a realm or resolver, that is ok!
            checkPolicyPre('admin', 'userlist', { 'user': user.login,
                                                 'realm' : c.realm },
                           context=self.request_context)

            if c.filter == "":
                c.filter = "*"

            log.debug("[userview_flexi] page: %s, filter: %s, sort: %s, dir: %s"
                      % (c.page, c.filter, c.sort, c.dir))

            if c.page is None:
                c.page = 1
            if c.psize is None:
                c.psize = 20

            c.userArray = getUserList({ qtype:c.filter,
                                       'realm':c.realm }, user)
            c.userNum = len(c.userArray)

            lines = []
            for u in c.userArray:
                # shorten the useridresolver, to get a better display value
                resolver_display = ""
                if "useridresolver" in u:
                    if len(u['useridresolver'].split(".")) > 3:
                        resolver_display = u['useridresolver'].split(".")[3] + " (" + u['useridresolver'].split(".")[1] + ")"
                    else:
                        resolver_display = u['useridresolver']
                lines.append(
                    { 'id' : u['username'],
                        'cell': [
                            (u['username']) if u.has_key('username') else (""),
                            (resolver_display),
                            (u['surname']) if u.has_key('surname') else (""),
                            (u['givenname']) if u.has_key('givenname') else (""),
                            (u['email']) if u.has_key('email') else (""),
                            (u['mobile']) if u.has_key('mobile') else (""),
                            (u['phone']) if u.has_key('phone') else (""),
                            (u['userid']) if u.has_key('userid') else (""),
                             ]
                    }
                    )

            # sorting
            reverse = False
            sortnames = { 'username' : 0, 'useridresolver' : 1,
                    'surname' : 2, 'givenname' : 3, 'email' : 4,
                    'mobile' :5, 'phone' : 6, 'userid' : 7 }
            if c.dir == "desc":
                reverse = True

            lines = sorted(lines,
                           key=lambda user: user['cell'][sortnames[c.sort]],
                           reverse=reverse,
                           cmp=unicode_compare)
            # end: sorting

            # reducing the page
            if c.page and c.psize:
                page = int(c.page)
                psize = int(c.psize)
                start = psize * (page - 1)
                end = start + psize
                lines = lines[start:end]

            # We need to return 'page', 'total', 'rows'
            response.content_type = 'application/json'
            res = { "page": int(c.page),
                "total": c.userNum,
                "rows": lines }

            c.audit['success'] = True

            Session.commit()
            return sendResult(response, res)

        except PolicyException as pe:
            log.exception("[userview_flexi] Error during checking policies: %r" % pe)
            Session.rollback()
            return sendError(response, unicode(pe), 1)

        except Exception as e:
            log.exception("[userview_flexi] failed: %r" % e)
            Session.rollback()
            return sendError(response, e)

        finally:
            Session.close()
            log.debug('[userview_flexi] done')
Exemplo n.º 39
0
    def check_s(self):
        """
        This function is used to validate the serial and the otp value/password.

        method:
            validate/check_s

        arguments:
            * serial:  the serial number of the token
            * pass:    the password that consists of a possible fixes password component
                        and the OTP value

        returns:
            JSON response
        """
        param = {}
        param.update(request.params)

        options = {}
        options.update(param)
        for k in ["user", "serial", "pass", "init"]:
            if k in options:
                del options[k]

        if "init" in param:
            if isSelfTest() == True:
                options["initTime"] = param.get("init")

        try:
            passw = getParam(param, "pass", optional)
            serial = getParam(param, "serial", optional)
            if serial is None:
                user = getParam(param, "user", optional)
                if user is not None:
                    user = getUserFromParam(param, optional)
                    toks = getTokens4UserOrSerial(user=user)
                    if len(toks) == 0:
                        raise Exception("No token found!")
                    elif len(toks) > 1:
                        raise Exception("More than one token found!")
                    else:
                        tok = toks[0].token
                        desc = tok.get()
                        realms = desc.get("LinOtp.RealmNames")
                        if realms is None or len(realms) == 0:
                            realm = getDefaultRealm()
                        elif len(realms) > 0:
                            realm = realms[0]

                        userInfo = getUserInfo(tok.LinOtpUserid, tok.LinOtpIdResolver, tok.LinOtpIdResClass)
                        user = User(login=userInfo.get("username"), realm=realm)

                        serial = tok.getSerial()

            c.audit["serial"] = serial

            if isSelfTest() == True:
                initTime = getParam(param, "init", optional)
                if initTime is not None:
                    if options is None:
                        options = {}
                    options["initTime"] = initTime

            (ok, opt) = checkSerialPass(serial, passw, options=options)

            c.audit["success"] = ok
            Session.commit()

            qr = getParam(param, "qr", optional)
            if qr is not None and opt is not None and opt.has_key("message"):
                try:
                    dataobj = opt.get("message")
                    param["alt"] = "%s" % opt
                    return sendQRImageResult(response, dataobj, param)
                except Exception as exc:
                    log.warning("failed to send QRImage: %r " % exc)
                    return sendQRImageResult(response, opt, param)
            else:
                return sendResult(response, ok, 0, opt=opt)

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

        finally:
            Session.close()
            log.debug("[check_s] done")
Exemplo n.º 40
0
    def checkstatus(self):
        """
        method:
            ocra/checkstatus

        description:
            Methode zur assynchronen Ueberpruefungen eines Challenge
            Response Valiadation requests

        arguments:

            * transactionid:  (required one of  - string - (hex))
                    Dies ist eine Transaktions-ID, die bei der Challenge
                    ausgegeben wurde.

            * serial: (required one of  - string)
                    die Serien Nummer des OCRA Token

            * user: (required one of  - string)
                    die Benutzer eines Tokens

            required is one of (user,serial,transactionid)

        returns:

            A JSON response::

                {
                 "version": "LinOTP 2.4",
                 "jsonrpc": "2.0",
                 "result": {
                     "status": true,
                     "value": [
                             {
                             "serial": SERIENNUMMER1,
                             "transactionid": TRANSACTIONID1,
                             "received_tan": true,
                             "valid_tan": true,
                             "failcount": 0
                             },
                             {
                             "serial": SERIENNUMMER1,
                             "transactionid": TRANSACTIONID2,
                             "received_tan": false,
                             "valid_tan": false,
                             "failcount": 0
                             },
                             {
                             "serial": SERIENNUMMER2,
                             "transactionid": TRANSACTIONID3,
                             "received_tan": true,
                             "valid_tan": false,
                             "failcount": 2
                             },
                         ]
                     },
                 "id": 0
                 }

        exception:

        """
        res = {}
        description = ('ocra/checkstatus: check the token status - '
                       'for assynchronous verification. Missing parameter: '
                       'You need to provide one of the parameters '
                       '"transactionid", "user" or "serial"')

        try:
            param = getLowerParams(request.params)
            log.debug("[checkstatus] check OCRA token status: %r" % param)

            checkPolicyPre('ocra', "status")

            transid = param.get('transactionid')
            user = getUserFromParam(param)
            serial = param.get('serial')

            if transid is None and user.is_empty and serial is None:
                # raise exception
                log.exception("[ocra/checkstatus] : missing transactionid, user or serial number for token")
                raise ParameterError("Usage: %s" % description, id=77)

            tokens = []
            serials = set()
            status = []

            if serial is not None:
                serials.add(serial)

            # if we have a transaction, get serial from this challenge

            if transid is not None:
                ocraChallenge = None
                try:
                    ocraChallenge = OcraTokenClass.getTransaction(transid)
                except:
                    pass
                if ocraChallenge is not None:
                    serials.add(ocraChallenge.tokenserial)

            # if we have a serial number of  token

            if len(serials) > 0:
                for serial in serials:
                    tokens.extend(getTokens4UserOrSerial(serial=serial))

            # if we have a user

            if not user.is_empty:
                try:
                    tokens.extend(getTokens4UserOrSerial(user=user))
                except:
                    log.warning("no token or user %r found!" % user)

            for token in tokens:
                if token.getType() == 'ocra':
                    challenges = []
                    if transid is None:
                        serial = token.getSerial()
                        challenges = OcraTokenClass.getTransactions4serial(
                                                                        serial)
                    else:
                        challenges.append(OcraTokenClass.getTransaction(
                                                                    transid))

                    for challenge in challenges:
                        stat = token.getStatus(challenge.transid)
                        if stat is not None and len(stat) > 0:
                            status.append(stat)

            res['values'] = status
            c.audit['success'] = res

            Session.commit()
            return sendResult(response, res, 1)

        except PolicyException as pe:
            log.exception("[checkstatus] policy failed: %r" % pe)
            Session.rollback()
            return sendError(response, unicode(pe))

        except Exception as exx:
            log.exception("[checkstatus] failed: %r" % exx)
            Session.rollback()
            return sendResult(response, unicode(exx), 0)

        finally:
            Session.close()
Exemplo n.º 41
0
    def userview_flexi(self):
        """
        This function is used to fill the flexigrid.
        Unlike the complex /admin/userlist function, it only returns a
        simple array of the tokens.
        """
        param = self.request_params

        try:

            c.page = param.get("page")
            c.filter = param.get("query")
            qtype = param.get("qtype")
            c.sort = param.get("sortname")
            c.dir = param.get("sortorder")
            c.psize = param.get("rp")
            c.realm = param.get("realm")

            user = getUserFromParam(param)
            # check admin authorization
            # check if we got a realm or resolver, that is ok!
            checkPolicyPre(
                "admin", "userlist", {"user": user.login, "realm": c.realm}
            )

            if c.filter == "":
                c.filter = "*"

            log.debug(
                "[userview_flexi] page: %s, filter: %s, sort: %s, dir: %s",
                c.page,
                c.filter,
                c.sort,
                c.dir,
            )

            if c.page is None:
                c.page = 1
            if c.psize is None:
                c.psize = 20

            c.userArray = getUserList(
                {qtype: c.filter, "realm": c.realm}, user
            )
            c.userNum = len(c.userArray)

            lines = []
            for u in c.userArray:
                # shorten the useridresolver, to get a better display value
                resolver_display = ""
                if "useridresolver" in u:
                    if len(u["useridresolver"].split(".")) > 3:
                        resolver_display = (
                            u["useridresolver"].split(".")[3]
                            + " ("
                            + u["useridresolver"].split(".")[1]
                            + ")"
                        )
                    else:
                        resolver_display = u["useridresolver"]
                lines.append(
                    {
                        "id": u["username"],
                        "cell": [
                            (u["username"]) if "username" in u else (""),
                            (resolver_display),
                            (u["surname"]) if "surname" in u else (""),
                            (u["givenname"]) if "givenname" in u else (""),
                            (u["email"]) if "email" in u else (""),
                            (u["mobile"]) if "mobile" in u else (""),
                            (u["phone"]) if "phone" in u else (""),
                            (u["userid"]) if "userid" in u else (""),
                        ],
                    }
                )

            # sorting
            reverse = False
            sortnames = {
                "username": 0,
                "useridresolver": 1,
                "surname": 2,
                "givenname": 3,
                "email": 4,
                "mobile": 5,
                "phone": 6,
                "userid": 7,
            }
            if c.dir == "desc":
                reverse = True

            lines = sorted(
                lines,
                key=lambda user: user["cell"][sortnames[c.sort]],
                reverse=reverse,
            )
            # end: sorting

            # reducing the page
            if c.page and c.psize:
                page = int(c.page)
                psize = int(c.psize)
                start = psize * (page - 1)
                end = start + psize
                lines = lines[start:end]

            # We need to return 'page', 'total', 'rows'
            res = {"page": int(c.page), "total": c.userNum, "rows": lines}

            g.audit["success"] = True

            db.session.commit()
            return sendResult(response, res)

        except PolicyException as pe:
            log.error(
                "[userview_flexi] Error during checking policies: %r", pe
            )
            db.session.rollback()
            return sendError(response, pe, 1)

        except Exception as exx:
            log.error("[userview_flexi] failed: %r", exx)
            db.session.rollback()
            return sendError(response, exx)
Exemplo n.º 42
0
    def request(self):
        """
        method:
            ocra/request

        description:
            request a challenge for a user or for a serial number (token).

        arguments:
            * serial: (required - string)
              Serial number of the token, for which a challenge should
              be generated (either serial or user is required)

            * user: (required  - string)
              The user for whose token a challenge should be generated
              If the user has more than one token, an error is returend.
              (either serial or user is required)

            * data: (required - String: URLendoced)
              These are the display data, that can be used to generate the challenge

        remark:
            the app will report a wrong qrcode, if the policy::

                {'authentication' : qrtanurl=https://localhost }

            is not defined !!

        returns:

            A JSON respone::

                        {
                            "version": "LinOTP 2.4",
                            "jsonrpc": "2.0",
                            "result": {
                                "status": true,
                                "value": false,
                            },
                            "detail": {
                                    "transactionid" : TRANSAKTIONSID,
                                    "data" : DATAOBJECT,
                            }
                        }

            * transactionid:
              This is the transaction ID, that is used later for
              verifying the Return code /TAN.

            * data:
              This is an object (URL) which can be used to generate a
              QR-Code to be displayed to the QRTAN App
        """
        res = {}
        description = 'ocra/request: request a challenge for a given user or token (serial). You must either provide a parameter "user" or a parameter "serial".'
        dataobj = ""

        try:
            param = getLowerParams(request.params)
            log.info("[request] saving default configuration: %r" % param)

            checkPolicyPre('ocra', "request")

            serial = getParam(param, 'serial', optional)
            user = getUserFromParam(param, optional)

            if user.isEmpty() and serial is None:
                ## raise exception
                log.exception("[request] user or serial is required")
                raise ParameterError("Usage: %s" % description, id=77)

            message = getParam(param, 'data'  , optional)
            if message is None:
                message = ''

            ## ocra token
            tokens = getTokens4UserOrSerial(user, serial)

            if len(tokens) > 1 :
                error = ('More than one token found: unable to create challenge '
                        'for (u:%r,s:%r)!' % (user, serial))
                log.error(error)
                raise Exception(error)

            if len(tokens) == 0:
                error = ('No token found: unable to create challenge for'
                          ' (u:%r,s:%r)!' % (user, serial))
                log.error(error)
                raise Exception(error)

            ocra = tokens[0]
            (transId, challenge, res, url) = ocra.challenge(message)

            u = urlencode({'u':str(url.encode("utf-8"))})

            uInfo = {'tr': transId, 'ch' : challenge,
                      'me': str(message.encode("utf-8")), 'u': u[2:]}
            detail = {"transactionid"   : transId,
                      'challenge'       : challenge,
                      'message'         : str(message.encode("utf-8")),
                      'url'             : str(url.encode("utf-8")),
                     }

            ## create the app_url from the data'''
            dataobj = 'lseqr://req?%s' % (str(urlencode(uInfo)))

            ## append the signature to the url '''
            signature = {'si' : ocra.signData(dataobj)}
            uInfo['si'] = signature
            dataobj = '%s&%s' % (dataobj, str(urlencode(signature)))

            detail["data"] = dataobj

            c.audit['success'] = res
            #c.audit['info'] += "%s=%s, " % (k, value)

            Session.commit()
            qr = getParam(param, 'qr', optional)
            if qr is not None:
                param['alt'] = detail
                return sendQRImageResult(response, dataobj, param)
            else:
                return sendResult(response, res, 1, opt=detail)

        except PolicyException as pe:
            log.exception("[request] policy failed: %r" % pe)
            Session.rollback()
            return sendError(response, unicode(pe))

        except Exception as exx:
            log.exception("[request] failed: %r" % exx)
            Session.rollback()
            return sendError(response, unicode(exx))

        finally:
            Session.close()
            log.debug("[request] done")
Exemplo n.º 43
0
    def create_context(self, request, environment):
        """
        create the request context for all controllers
        """

        linotp_config = getLinotpConfig()

        request_context['Config'] = linotp_config
        request_context['Policies'] = parse_policies(linotp_config)
        request_context['translate'] = translate
        request_context['CacheManager'] = environment['beaker.cache']

        initResolvers()

        request_params = {}

        try:
            request_params.update(request.params)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)

        request_context['Params'] = request_params

        authUser = None
        try:
            authUser = getUserFromRequest(request)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)

        request_context['AuthUser'] = authUser
        request_context['UserLookup'] = {}

        requestUser = None
        try:
            requestUser = getUserFromParam(request_params)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)
        request_context['RequestUser'] = requestUser

        client = None
        try:
            client = get_client(request=request)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)

        request_context['Client'] = client

        request_context['Audit'] = Audit
        request_context['audit'] = Audit.initialize(request, client=client)

        defaultRealm = ""
        try:
            defaultRealm = getDefaultRealm(linotp_config)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)

        request_context['defaultRealm'] = defaultRealm

        realms = None
        try:
            realms = getRealms()
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)

        request_context['Realms'] = realms

        request_context['hsm'] = None
        if hasattr(self, "hsm"):
            request_context['hsm'] = self.hsm

        # copy some system entries from pylons
        syskeys = {
            "radius.nas_identifier": "LinOTP",
            "radius.dictfile": "/etc/linotp2/dictionary"
        }

        sysconfig = {}
        for key, default in syskeys.items():
            sysconfig[key] = config.get(key, default)

        request_context['SystemConfig'] = sysconfig
Exemplo n.º 44
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 everything in the options but the user, pass, init
        options.update(param)
        for para in ["pass", "user", "init"]:
            if para in options:
                del options[para]

        passw = param.get("pass")
        user = getUserFromParam(param)

        # support for challenge verification
        challenge = param.get("challenge")
        if challenge is not None:
            options = {}
            options["challenge"] = challenge

        g.audit["user"] = user.login
        realm = user.realm or getDefaultRealm()
        g.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)

        vh = ValidationHandler()
        (ok, opt) = vh.checkUserPass(user, passw, options=options)

        g.audit.update(request_context.get("audit", {}))
        g.audit["success"] = ok

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

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

        return (ok, opt)
Exemplo n.º 45
0
    def checkstatus(self):
        """
        method:
            ocra/checkstatus

        description:
            Methode zur assynchronen Ueberpruefungen eines Challenge Response Valiadation requests

        arguments:

            * transactionid:  (required one of  - string - (hex))
                    Dies ist eine Transaktions-ID, die bei der Challenge ausgegeben wurde.

            * serial: (required one of  - string)
                    die Serien Nummer des OCRA Token

            * user: (required one of  - string)
                    die Benutzer eines Tokens

            required is one of (user,serial,transactionid)

        returns:

            A JSON response::

                {
                 "version": "LinOTP 2.4",
                 "jsonrpc": "2.0",
                 "result": {
                     "status": true,
                     "value": [
                             {
                             "serial": SERIENNUMMER1,
                             "transactionid": TRANSACTIONID1,
                             "received_tan": true,
                             "valid_tan": true,
                             "failcount": 0
                             },
                             {
                             "serial": SERIENNUMMER1,
                             "transactionid": TRANSACTIONID2,
                             "received_tan": false,
                             "valid_tan": false,
                             "failcount": 0
                             },
                             {
                             "serial": SERIENNUMMER2,
                             "transactionid": TRANSACTIONID3,
                             "received_tan": true,
                             "valid_tan": false,
                             "failcount": 2
                             },
                         ]
                     },
                 "id": 0
                 }

        exception:

        """
        res = {}
        description = 'ocra/checkstatus: check the token status - for assynchronous verification. Missing parameter: You need to provide one of the parameters "transactionid", "user" or "serial"'

        try:
            param = getLowerParams(request.params)
            log.debug("[checkstatus] check OCRA token status: %r" % param)

            checkPolicyPre('ocra', "status")

            transid = getParam(param, 'transactionid'   , optional)
            user = getUserFromParam(param, optional)
            #user   = getParam(param, 'user'          ,optional)
            serial = getParam(param, 'serial'          , optional)

            if transid is None and user.isEmpty() and serial is None:
                ## raise exception
                log.exception("[ocra/checkstatus] : missing transactionid, user or serial number for token")
                raise ParameterError("Usage: %s" % description, id=77)

            tokens = []
            serials = set()
            status = []

            if serial is not None:
                serials.add(serial)

            ## if we have a transaction, get serial from this challenge
            if transid is not None :
                ocraChallenge = None
                try:
                    ocraChallenge = OcraTokenClass.getTransaction(transid)
                except:
                    pass
                if ocraChallenge is not None:
                    serials.add(ocraChallenge.tokenserial)

            ## if we have a serial number of  token
            if len(serials) > 0:
                for serial in serials:
                    tokens.extend(getTokens4UserOrSerial(serial=serial))

            ## if we have a user
            if user.isEmpty() == False:
                try:
                    tokens.extend(getTokens4UserOrSerial(user=user))
                except:
                    log.warning("no token or user %r found!" % user)

            for token in tokens:
                if token.getType() == 'ocra':
                    challenges = []
                    if transid is None:
                        serial = token.getSerial()
                        challenges = OcraTokenClass.getTransactions4serial(serial)
                    else:
                        challenges.append(OcraTokenClass.getTransaction(transid))

                    for challenge in challenges:
                        stat = token.getStatus(challenge.transid)
                        if stat is not None and len(stat) > 0:
                            status.append(stat)

            res['values'] = status
            c.audit['success'] = res

            Session.commit()
            return sendResult(response, res, 1)

        except PolicyException as pe:
            log.exception("[checkstatus] policy failed: %r" % pe)
            Session.rollback()
            return sendError(response, unicode(pe))

        except Exception as exx:
            log.exception("[checkstatus] failed: %r" % exx)
            Session.rollback()
            return sendResult(response, unicode(exx), 0)

        finally:
            Session.close()
            log.debug('[ocra/checkstatus] done')
Exemplo n.º 46
0
    def check_status(self):
        """
        check the status of a transaction - for polling support
        """

        try:

            param = self.request_params

            #
            # we require either state or transactionid as parameter

            transid = param.get("state", param.get("transactionid", None))
            if not transid:
                raise ParameterError(
                    _(
                        'Missing required parameter "state" or '
                        '"transactionid"!'
                    )
                )

            #
            # serial is an optional parameter

            serial = param.get("serial", None)

            # user is an optional parameter:
            # if no 'user' in the parameters, the User object will be empty
            user = getUserFromParam(param)

            passw = param.get("pass")
            if passw is None:
                raise ParameterError(_('Missing required parameter "pass"!'))

            use_offline = param.get("use_offline", False)

            va = ValidationHandler()
            ok, opt = va.check_status(
                transid=transid,
                user=user,
                serial=serial,
                password=passw,
                use_offline=use_offline,
            )

            serials = []
            types = []
            owner = None
            challenges = Challenges.lookup_challenges(transid=transid)

            for ch in challenges:
                tokens = getTokens4UserOrSerial(serial=ch.getTokenSerial())
                if not tokens:
                    continue

                for token in tokens:
                    serials.append(token.getSerial())
                    types.append(token.getType())

                    if not owner:
                        owner = get_token_owner(token)

            if owner:
                g.audit["user"] = g.audit["user"] or owner.login
                g.audit["realm"] = g.audit["realm"] or owner.realm

            g.audit["serial"] = " ".join(serials)
            g.audit["token_type"] = " ".join(types)

            g.audit["success"] = ok
            g.audit["info"] = str(opt)

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

        except Exception as exx:
            log.error("check_status failed: %r", exx)
            g.audit["info"] = str(exx)
            db.session.rollback()
            return sendResult(response, False, 0)
Exemplo n.º 47
0
    def getotp(self):
        '''
        This function is used to retrieve the current otp value for a given
        user or a given serial. If the user has more than one token, the list
        of the tokens is returend.

        method:
            gettoken/getotp

        arguments:
            user    - username / loginname
            realm   - additional realm to match the user to a useridresolver
            serial  - the serial number of the token
            curTime - used ONLY for internal testing: datetime.datetime object

        returns:
            JSON response
        '''

        getotp_active = config.get("GETOTP_ENABLED")
        if not getotp_active:
            return sendError(response, "getotp is not activated.", 0)

        param = self.request_params
        ret = {}
        res = -1
        otpval = ""
        passw = ""
        serials = []

        try:

            serial = getParam(param, "serial", optional)
            user = getUserFromParam(param)
            curTime = getParam(param, "curTime", optional)

            g.audit['user'] = user.login
            if "" != user.login:
                g.audit['realm'] = user.realm or getDefaultRealm()

            if serial:
                log.debug("[getotp] retrieving OTP value for token %s", serial)

            elif user.login:
                log.debug(
                    "[getotp] retrieving OTP value for token for user "
                    "%s@%s", user.login, user.realm)

                toks = getTokens4UserOrSerial(user, serial)
                tokennum = len(toks)

                if tokennum > 1:
                    log.debug("[getotp] The user has more than one token."
                              "Returning the list of serials")
                    res = -3
                    for token in toks:
                        serials.append(token.getSerial())
                elif 1 == tokennum:
                    serial = toks[0].getSerial()
                    log.debug(
                        "[getotp] retrieving OTP for token %s for user"
                        " %s@%s", serial, user.login, user.realm)
                else:
                    log.debug("[getotp] no token found for user %s@%s",
                              user.login, user.realm)
                    res = -4
            else:
                res = -5

            # if a serial was given or a unique serial could be
            # received from the given user.

            if serial:
                max_count = checkPolicyPre('gettoken', 'max_count', param)
                log.debug("[getmultiotp] max_count policy: %s", max_count)
                if max_count <= 0:
                    return sendError(
                        response, "The policy forbids receiving"
                        " OTP values for the token %s in "
                        "this realm" % serial, 1)

                (res, pin, otpval, passw) = getOtp(serial, curTime=curTime)

            g.audit['success'] = True

            if int(res) < 0:
                ret['result'] = False
                if -1 == otpval:
                    ret['description'] = "No Token with this serial number"
                if -2 == otpval:
                    ret['description'] = ("This Token does not support the"
                                          " getOtp function")
                if -3 == otpval:
                    ret['description'] = "The user has more than one token"
                    ret['serials'] = serials
                if -4 == otpval:
                    ret['description'] = "No Token found for this user"
                if -5 == otpval:
                    ret['description'] = ("you need to provide a user or "
                                          "a serial")
            else:
                ret['result'] = True
                ret['otpval'] = otpval
                ret['pin'] = pin
                ret['pass'] = passw

            db.session.commit()
            return sendResult(response, ret, 0)

        except PolicyException as pe:
            log.exception("[getotp] gettoken/getotp policy failed: %r", pe)
            db.session.rollback()
            return sendError(response, str(pe), 1)

        except Exception as exx:
            log.exception("[getotp] gettoken/getotp failed: %r", exx)
            db.session.rollback()
            return sendError(response, "gettoken/getotp failed: %s" % exx, 0)
Exemplo n.º 48
0
    def check_s(self):
        """
        This function is used to validate the serial and the otp value/password.
        If the otppin policy is set, the endpoint /validate/check_s does not work.

        method:
            validate/check_s

        arguments:
            * serial:  the serial number of the token
            * pass:    the password that consists of a possible fixes password component
                        and the OTP value

        returns:
            JSON response
        """
        param = self.request_params

        options = {}
        options.update(param)
        for k in ["user", "serial", "pass", "init"]:
            if k in options:
                del options[k]

        try:
            passw = param.get("pass")
            serial = param.get("serial")
            if serial is None:
                user = param.get("user")
                if user is not None:
                    user = getUserFromParam(param)
                    toks = getTokens4UserOrSerial(user=user)
                    if len(toks) == 0:
                        raise Exception("No token found!")
                    elif len(toks) > 1:
                        raise Exception("More than one token found!")
                    else:
                        tok = toks[0].token
                        desc = tok.get()
                        realms = desc.get("LinOtp.RealmNames")
                        if realms is None or len(realms) == 0:
                            realm = getDefaultRealm()
                        elif len(realms) > 0:
                            realm = realms[0]

                        userInfo = getUserInfo(
                            tok.LinOtpUserid,
                            tok.LinOtpIdResolver,
                            tok.LinOtpIdResClass,
                        )
                        user = User(
                            login=userInfo.get("username"), realm=realm
                        )

                        serial = tok.getSerial()

            g.audit["serial"] = serial

            options["scope"] = {"check_s": True}
            vh = ValidationHandler()
            (ok, opt) = vh.checkSerialPass(serial, passw, options=options)
            g.audit["success"] = ok
            db.session.commit()

            qr = param.get("qr", None)
            if qr and opt and "message" in opt:
                try:
                    dataobj = opt.get("message")
                    param["alt"] = "%s" % opt
                    if "transactionid" in opt:
                        param["transactionid"] = opt["transactionid"]
                    return sendQRImageResult(response, dataobj, param)
                except Exception as exc:
                    log.warning("failed to send QRImage: %r ", exc)
                    return sendQRImageResult(response, opt, param)
            else:
                return sendResult(response, ok, 0, opt=opt)

        except Exception as exx:
            log.error("[check_s] validate/check_s failed: %r", exx)
            g.audit["info"] = str(exx)
            db.session.rollback()
            return sendResult(response, False, id=0, status=False)
Exemplo n.º 49
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()
            vh = ValidationHandler()
            if same_user is True:
                (ok, opt) = vh.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)
Exemplo n.º 50
0
    def create_context(self, request, environment):
        """
        create the request context for all controllers
        """

        linotp_config = getLinotpConfig()

        # make the request id available in the request context
        request_context['RequestId'] = environment['REQUEST_ID']

        # a request local cache to get the user info from the resolver
        request_context['UserLookup'] = {}

        # a request local cache to get the resolver from user and realm
        request_context['UserRealmLookup'] = {}

        request_context['Config'] = linotp_config
        request_context['Policies'] = parse_policies(linotp_config)
        request_context['translate'] = translate
        request_context['CacheManager'] = environment['beaker.cache']

        routes = environment.get('pylons.routes_dict', {})
        path = "/%s/%s" % (routes['controller'], routes['action'])
        request_context['Path'] = path

        request_context['hsm'] = self.hsm

        initResolvers()

        client = None
        try:
            client = get_client(request=request)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)

        request_context['Client'] = client

        request_context['Audit'] = Audit
        request_context['audit'] = Audit.initialize(request, client=client)

        authUser = None
        try:
            authUser = getUserFromRequest(request)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)

        request_context['AuthUser'] = authUser
        request_context['UserLookup'] = {}

        # ------------------------------------------------------------------ --
        # get the current resolvers

        resolvers = []
        try:
            resolvers = getResolverList(config=linotp_config)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)

        request_context['Resolvers'] = resolvers

        # ------------------------------------------------------------------ --
        # get the current realms

        realms = {}
        try:
            realms = getRealms()
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)

        request_context['Realms'] = realms

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

        defaultRealm = ""
        try:
            defaultRealm = getDefaultRealm(linotp_config)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)

        request_context['defaultRealm'] = defaultRealm

        # ------------------------------------------------------------------ --
        # load the requesting user

        from linotp.useridresolver.UserIdResolver import (
            ResolverNotAvailable)

        requestUser = None
        try:
            requestUser = getUserFromParam(self.request_params)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r", exx)
        except (ResolverNotAvailable, NoResolverFound) as exx:
            log.error("Failed to connect to server %r", exx)

        request_context['RequestUser'] = requestUser

        # ------------------------------------------------------------------ --
        # load the providers

        from linotp.provider import Provider_types
        from linotp.provider import getProvider

        provider = {}
        for provider_type in Provider_types.keys():
            provider[provider_type] = getProvider(provider_type)

        request_context['Provider'] = provider

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

        # for the setup of encrypted data, we require the hsm is instatiated
        # and available in the request context

        if not self.secret_key:
            init_key_partition(linotp_config, partition=0)

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

        # copy some system entries from pylons
        syskeys = {
            "radius.nas_identifier": "LinOTP",
            "radius.dictfile": "/etc/linotp2/dictionary"
        }

        sysconfig = {}
        for key, default in syskeys.items():
            sysconfig[key] = config.get(key, default)

        request_context['SystemConfig'] = sysconfig
Exemplo n.º 51
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 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 = param.get("pass")
        user = getUserFromParam(param)

        # support for ocra application challenge verification
        challenge = param.get("challenge")
        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() is True:
            initTime = param.get("init")
            if initTime is not None:
                if options is None:
                    options = {}
                options['initTime'] = initTime
        vh = ValidationHandler()
        (ok, opt) = vh.checkUserPass(user, passw, options=options)

        c.audit.update(request_context.get('audit'))
        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 is 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)
Exemplo n.º 52
0
    def create_context(self, request, environment):
        """
        create the request context for all controllers
        """

        linotp_config = getLinotpConfig()

        request_context['Config'] = linotp_config
        request_context['Policies'] = parse_policies(linotp_config)
        request_context['translate'] = translate
        request_context['CacheManager'] = environment['beaker.cache']
        request_context['Path'] = environment.get("PATH_INFO", "") or ""
        request_context['hsm'] = self.hsm

        request_params = {}

        try:
            request_params.update(request.params)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)

        request_context['Params'] = request_params

        initResolvers()

        client = None
        try:
            client = get_client(request=request)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)

        request_context['Client'] = client

        request_context['Audit'] = Audit
        request_context['audit'] = Audit.initialize(request, client=client)

        authUser = None
        try:
            authUser = getUserFromRequest(request)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)

        request_context['AuthUser'] = authUser
        request_context['UserLookup'] = {}

        requestUser = None
        try:
            requestUser = getUserFromParam(request_params)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)
        request_context['RequestUser'] = requestUser


        defaultRealm = ""
        try:
            defaultRealm = getDefaultRealm(linotp_config)
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)

        request_context['defaultRealm'] = defaultRealm

        realms = None
        try:
            realms = getRealms()
        except UnicodeDecodeError as exx:
            log.error("Failed to decode request parameters %r" % exx)

        request_context['Realms'] = realms

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

        # for the setup of encrypted data, we require the hsm is instatiated
        # and available in the request context

        if not self.secret_key:
            init_key_partition(linotp_config, partition=0)

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

        # copy some system entries from pylons
        syskeys = {
                   "radius.nas_identifier": "LinOTP",
                   "radius.dictfile": "/etc/linotp2/dictionary"
        }

        sysconfig = {}
        for key, default in syskeys.items():
            sysconfig[key] = config.get(key, default)

        request_context['SystemConfig'] = sysconfig
Exemplo n.º 53
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()

            if same_user is True:
                (ok, opt) = 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.error("[check] openid/check failed: %r" % exx)
            log.error("[__before__] %s" % traceback.format_exc())
            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)
Exemplo n.º 54
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() is True:
            initTime = getParam(param, "init", optional)
            if initTime is not None:
                if options is None:
                    options = {}
                options['initTime'] = initTime
        vh = ValidationHandler()
        (ok, opt) = vh.checkUserPass(user, passw, options=options)

        c.audit.update(request_context.get('audit'))
        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 is 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)