コード例 #1
0
def search_policy(param, only_active=True):
    """
    migration stub for the new policy engine
    """

    use_new_one = boolean(context['Config'].get(
                                    'NewPolicyEvaluation', False))
    compare = boolean(context['Config'].get(
                                    'NewPolicyEvaluation.compare', False))

    if use_new_one or compare:
        pols_new = new_search_policy(param,
                                     only_active=only_active)

    if not use_new_one or compare:
        pols_old = legacy_getPolicy(param,
                                    only_active=only_active)

    if use_new_one:
        return_policies = pols_new
    else:
        return_policies = pols_old

    if not compare:
        return return_policies

    if not are_the_same(pols_old, pols_new):

        LOG.error('PolicyEvaluation is not the same for params %r', param)
        LOG.error('old: new %r <> %r', pols_old, pols_new)

    return return_policies
コード例 #2
0
def _getAuthorization(scope, action):
    """
    migration stub for the new policy engine
    """

    use_new_one = boolean(context['Config'].get(
                                    'NewPolicyEvaluation', False))
    compare = boolean(context['Config'].get(
                                    'NewPolicyEvaluation.compare', False))

    if use_new_one or compare:
        new_pols = new_getAuthorization(scope, action)

    if not use_new_one or compare:
        old_pols = legacy_getAuthorization(scope, action)

    if use_new_one:
        return_policies = new_pols
    else:
        return_policies = old_pols

    if not compare:
        return return_policies

    if not are_the_same(old_pols, new_pols):

        LOG.error('PolicyEvaluation is not the same for params %r,%r',
                  scope, action)
        LOG.error('old: new %r <> %r', old_pols, new_pols)

    return return_policies
コード例 #3
0
def has_client_policy(client, scope=None, action=None, realm=None, user=None,
                      find_resolver=True, userObj=None, active_only=True):
    """
    migration stub for the new policy engine

    Remark:
    has_client_policy is different to the method get_client_policy
    as the filters for the has_client_policy are reseted after usage
    """

    use_new_one = boolean(context['Config'].get(
                                    'NewPolicyEvaluation', False))
    compare = boolean(context['Config'].get(
                                    'NewPolicyEvaluation.compare', False))

    if use_new_one or compare:
        new_pols = new_has_client_policy(client, scope=scope,
                                         action=action,
                                         realm=realm, user=user,
                                         find_resolver=find_resolver,
                                         userObj=userObj,
                                         active_only=active_only)

    if not use_new_one or compare:
        old_pols = legacy_get_client_policy(client, scope=scope,
                                            action=action,
                                            realm=realm, user=user,
                                            find_resolver=find_resolver,
                                            userObj=userObj)

    if use_new_one:
        return_policies = new_pols
    else:
        return_policies = old_pols

    if not compare:
        return return_policies

    if not are_the_same(old_pols, new_pols):

        LOG.error('PolicyEvaluation is not the same for params %r', client)
        LOG.error('old: new %r <> %r', old_pols, new_pols)

    return return_policies
コード例 #4
0
def get_client_policy(client, scope=None, action=None, realm=None, user=None,
                      find_resolver=True, userObj=None, active_only=True):
    """
    migration stub for the new policy engine
    """
    use_new_one = boolean(context['Config'].get(
                                    'NewPolicyEvaluation', False))
    compare = boolean(context['Config'].get(
                                    'NewPolicyEvaluation.compare', False))

    if use_new_one or compare:
        pols_new = new_get_client_policy(client, scope=scope,
                                         action=action,
                                         realm=realm, user=user,
                                         find_resolver=find_resolver,
                                         userObj=userObj,
                                         active_only=active_only)

    if not use_new_one or compare:
        pols_old = legacy_get_client_policy(client, scope=scope,
                                            action=action,
                                            realm=realm, user=user,
                                            find_resolver=find_resolver,
                                            userObj=userObj)

    if use_new_one:
        return_policies = pols_new
    else:
        return_policies = pols_old

    if not compare:
        return return_policies

    if not are_the_same(pols_old, pols_new):

        LOG.error('PolicyEvaluation is not the same for params %r', client)
        LOG.error('old: new %r <> %r', pols_old, pols_new)

    return return_policies
コード例 #5
0
    def __before__(self, action, **params):

        try:
            c.audit = request_context['audit']
            c.audit['success'] = False
            c.audit['client'] = get_client(request)

            c.version = get_version()
            c.version_ref = base64.encodestring(c.version)[:6]

            c.licenseinfo = get_copyright_info()
            c.polDefs = getPolicyDefinitions()

            c.display_provider = boolean(
                    request_context['Config'].get('display_provider', True))

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

            # check for support of setting admin password

            c.admin_can_change_password = False
            if ('linotpadmin.user' in config and
                'linotpadmin.password' in config):
                c.admin_can_change_password = True

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

            # Session handling for the functions, that show data:
            # Also exclude custom-style.css, since the CSRF check
            # will always fail and return a HTTP 401 anyway.
            # A HTTP 404 makes more sense.
            if request.path.lower() in ['/manage/', '/manage',
                                        '/manage/logout',
                                        '/manage/audittrail',
                                        '/manage/policies',
                                        '/manage/tokenview',
                                        '/manage/userview',
                                        '/manage/help',
                                        '/manage/custom-style.css']:
                pass
            else:
                check_session(request)

        except Exception as exx:
            log.exception("[__before__::%r] exception %r" % (action, exx))
            Session.rollback()
            Session.close()
            return sendError(response, exx, context='before')

        finally:
            log.debug("[__before__::%r] done" % (action))
コード例 #6
0
    def import_users(self):
        """
        import users from a csv file into an dedicated sql resolver
        """

        try:

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

            # -------------------------------------------------------------- --
            # processing required arguments
            try:

                data_file = request.POST['file']
                resolver_name = params['resolver']

            except KeyError as exx:

                log.exception("Missing parameter: %r", exx)
                raise ParameterError("Missing parameter: %r" % exx)

            groupid = resolver_name

            # process file upload data

            data = data_file

            # -- ----------------------------------------------------------- --
            # In case of form post requests, it is a "instance" of FieldStorage
            # i.e. the Filename is selected in the browser and the data is
            # transferred in an iframe.
            #     see: http://jquery.malsup.com/form/#sample4
            # -- ----------------------------------------------------------- --

            if isinstance(data_file, FieldStorage):
                data = data_file.value

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

            # process the other arguments
            dryrun = boolean(params.get('dryrun', False))

            passwords_in_plaintext = boolean(params.get(
                                                'passwords_in_plaintext',
                                                False))

            file_format = params.get('format', "csv")

            if file_format in ('password', 'passwd'):

                column_mapping = {
                        "userid": 2,
                        "username": 0,
                        "phone": 8,
                        "mobile": 7,
                        "email": 9,
                        "surname": 5,
                        "givenname": 4,
                        "password": 1}

                format_reader = PasswdFormatReader()

            elif file_format in ('csv'):

                skip_header = boolean(params.get('skip_header', False))
                if skip_header:
                    data = '\n'.join(data.split('\n')[1:])

                column_mapping = {
                        "username": 0,
                        "userid": 1,
                        "surname": 2,
                        "givenname": 3,
                        "email": 4,
                        "phone": 5,
                        "mobile": 6,
                        "password": 7}

                delimiter = str(params.get('delimiter', ","))
                quotechar = str(params.get('quotechar', '"'))

                format_reader = DefaultFormatReader()
                format_reader.delimiter = delimiter
                format_reader.quotechar = quotechar

                column_mapping = params.get('column_mapping', column_mapping)

            else:

                raise Exception('unspecified file foramt')

            # we have to convert the column_mapping back into an dict

            if (isinstance(column_mapping, str) or
                isinstance(column_mapping, unicode)):
                column_mapping = json.loads(column_mapping)

            # prevent overwrite of existing unmanaged resolver

            resolvers = getResolverList()
            if resolver_name in resolvers:
                if not resolvers[resolver_name].get('readonly', False):
                    raise Exception("Unmanged resolver with same name: %r"
                                    " already exists!" % resolver_name)
            # -------------------------------------------------------------- --

            # feed the engine :)

            # use a LinOTP Database context for Sessions and Engine

            db_context = LinOTP_DatabaseContext(
                                        SqlSession=Session,
                                        SqlEngine=linotp.model.meta.engine)

            # define the import into an SQL database + resolver

            import_handler = SQLImportHandler(
                                        groupid=groupid,
                                        resolver_name=resolver_name,
                                        database_context=db_context)

            # create the UserImporter with the required mapping

            user_import = UserImport(import_handler)

            user_import.set_mapping(column_mapping)

            # and run the data processing

            result = user_import.import_csv_users(
                                data,
                                dryrun=dryrun,
                                format_reader=format_reader,
                                passwords_in_plaintext=passwords_in_plaintext
                                )

            if dryrun:

                return sendResult(response, result)

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

            # create / extend target realm for the resolver

            resolver_spec = import_handler.get_resolver_spec()

            Session.commit()

            return sendResult(response, result)

        except PolicyException as pexx:

            log.exception("Error during user import: %r", pexx)

            Session.rollback()

            return sendError(response, "%r" % pexx, 1)

        except Exception as exx:

            log.exception("Error during user import: %r" % exx)

            Session.rollback()

            return sendError(response, "%r" % exx)

        finally:
            Session.close()
            log.debug('done')
コード例 #7
0
ファイル: tools.py プロジェクト: soitun/LinOTP
    def import_users(self):
        """
        import users from a csv file into an dedicated sql resolver
        """

        try:

            params = self.request_params

            # -------------------------------------------------------------- --
            # processing required arguments
            try:

                data_file = request.files["file"]
                resolver_name = params["resolver"]

            except KeyError as exx:

                log.error("Missing parameter: %r", exx)
                raise ParameterError("Missing parameter: %r" % exx)

            if resolver_name == current_app.config["ADMIN_RESOLVER_NAME"]:
                raise DeleteForbiddenError(
                    f"default admin resolver {resolver_name} is not allowed "
                    "to be overwritten!")

            groupid = resolver_name

            # process file upload data

            data = data_file

            # -- ----------------------------------------------------------- --
            # In case of form post requests, it is a "instance" of FileStorage
            # i.e. the Filename is selected in the browser and the data is
            # transferred in an iframe.
            #     see: http://jquery.malsup.com/form/#sample4
            # -- ----------------------------------------------------------- --

            if isinstance(data_file, FileStorage):
                data = data_file.read()

            data = data.decode()

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

            # process the other arguments
            dryrun = boolean(params.get("dryrun", False))

            passwords_in_plaintext = boolean(
                params.get("passwords_in_plaintext", False))

            file_format = params.get("format", "csv")

            if file_format in ("password", "passwd"):

                column_mapping = {
                    "userid": 2,
                    "username": 0,
                    "phone": 8,
                    "mobile": 7,
                    "email": 9,
                    "surname": 5,
                    "givenname": 4,
                    "password": 1,
                }

                format_reader = PasswdFormatReader()

            elif file_format in ("csv"):

                skip_header = boolean(params.get("skip_header", False))
                if skip_header:
                    data = "\n".join(data.split("\n")[1:])

                column_mapping = {
                    "username": 0,
                    "userid": 1,
                    "surname": 2,
                    "givenname": 3,
                    "email": 4,
                    "phone": 5,
                    "mobile": 6,
                    "password": 7,
                }

                delimiter = str(params.get("delimiter", ","))
                quotechar = str(params.get("quotechar", '"'))

                format_reader = DefaultFormatReader()
                format_reader.delimiter = delimiter
                format_reader.quotechar = quotechar

                column_mapping = params.get("column_mapping", column_mapping)

            else:

                raise Exception("unspecified file foramt")

            # we have to convert the column_mapping back into an dict

            if isinstance(column_mapping, str):
                column_mapping = json.loads(column_mapping)

            # prevent overwrite of existing unmanaged resolver

            checkPolicyPre("system", "setResolver")

            resolvers = getResolverList()
            if resolver_name in resolvers:
                if not resolvers[resolver_name].get("readonly", False):
                    raise Exception("Unmanged resolver with same name: %r"
                                    " already exists!" % resolver_name)
            # -------------------------------------------------------------- --

            # feed the engine :)

            # use a LinOTP Database context for Sessions and Engine

            db_context = LinOTP_DatabaseContext(SqlSession=db.session,
                                                SqlEngine=db.engine)

            # define the import into an SQL database + resolver

            import_handler = SQLImportHandler(
                groupid=groupid,
                resolver_name=resolver_name,
                database_context=db_context,
            )

            # create the UserImporter with the required mapping

            user_import = UserImport(import_handler)

            user_import.set_mapping(column_mapping)

            # and run the data processing

            result = user_import.import_csv_users(
                data,
                dryrun=dryrun,
                format_reader=format_reader,
                passwords_in_plaintext=passwords_in_plaintext,
            )

            if dryrun:

                return sendResult(response, result)

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

            # create / extend target realm for the resolver

            resolver_spec = import_handler.get_resolver_spec()

            db.session.commit()

            return sendResult(response, result)

        except PolicyException as pexx:

            log.error("Error during user import: %r", pexx)

            db.session.rollback()

            return sendError(response, "%r" % pexx, 1)

        except Exception as exx:

            log.error("Error during user import: %r", exx)

            db.session.rollback()

            return sendError(response, exx)

        finally:
            log.debug("done")
コード例 #8
0
ファイル: tools.py プロジェクト: wjbailey/LinOTP
    def import_users(self):
        """
        import users from a csv file into an dedicated sql resolver
        """

        try:

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

            # -------------------------------------------------------------- --
            # processing required arguments
            try:

                data_file = request.POST['file']
                resolver_name = params['resolver']

            except KeyError as exx:

                log.exception("Missing parameter: %r", exx)
                raise ParameterError("Missing parameter: %r" % exx)

            groupid = resolver_name

            # process file upload data

            data = data_file

            # -- ----------------------------------------------------------- --
            # In case of form post requests, it is a "instance" of FieldStorage
            # i.e. the Filename is selected in the browser and the data is
            # transferred in an iframe.
            #     see: http://jquery.malsup.com/form/#sample4
            # -- ----------------------------------------------------------- --

            if isinstance(data_file, FieldStorage):
                data = data_file.value

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

            # process the other arguments
            dryrun = boolean(params.get('dryrun', False))

            passwords_in_plaintext = boolean(
                params.get('passwords_in_plaintext', False))

            file_format = params.get('format', "csv")

            if file_format in ('password', 'passwd'):

                column_mapping = {
                    "userid": 2,
                    "username": 0,
                    "phone": 8,
                    "mobile": 7,
                    "email": 9,
                    "surname": 5,
                    "givenname": 4,
                    "password": 1
                }

                format_reader = PasswdFormatReader()

            elif file_format in ('csv'):

                skip_header = boolean(params.get('skip_header', False))
                if skip_header:
                    data = '\n'.join(data.split('\n')[1:])

                column_mapping = {
                    "username": 0,
                    "userid": 1,
                    "surname": 2,
                    "givenname": 3,
                    "email": 4,
                    "phone": 5,
                    "mobile": 6,
                    "password": 7
                }

                delimiter = str(params.get('delimiter', ","))
                quotechar = str(params.get('quotechar', '"'))

                format_reader = DefaultFormatReader()
                format_reader.delimiter = delimiter
                format_reader.quotechar = quotechar

                column_mapping = params.get('column_mapping', column_mapping)

            else:

                raise Exception('unspecified file foramt')

            # we have to convert the column_mapping back into an dict

            if (isinstance(column_mapping, str)
                    or isinstance(column_mapping, unicode)):
                column_mapping = json.loads(column_mapping)

            # prevent overwrite of existing unmanaged resolver

            resolvers = getResolverList()
            if resolver_name in resolvers:
                if not resolvers[resolver_name].get('readonly', False):
                    raise Exception("Unmanged resolver with same name: %r"
                                    " already exists!" % resolver_name)
            # -------------------------------------------------------------- --

            # feed the engine :)

            # use a LinOTP Database context for Sessions and Engine

            db_context = LinOTP_DatabaseContext(
                SqlSession=Session, SqlEngine=linotp.model.meta.engine)

            # define the import into an SQL database + resolver

            import_handler = SQLImportHandler(groupid=groupid,
                                              resolver_name=resolver_name,
                                              database_context=db_context)

            # create the UserImporter with the required mapping

            user_import = UserImport(import_handler)

            user_import.set_mapping(column_mapping)

            # and run the data processing

            result = user_import.import_csv_users(
                data,
                dryrun=dryrun,
                format_reader=format_reader,
                passwords_in_plaintext=passwords_in_plaintext)

            if dryrun:

                return sendResult(response, result)

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

            # create / extend target realm for the resolver

            resolver_spec = import_handler.get_resolver_spec()

            Session.commit()

            return sendResult(response, result)

        except PolicyException as pexx:

            log.exception("Error during user import: %r", pexx)

            Session.rollback()

            return sendError(response, "%r" % pexx, 1)

        except Exception as exx:

            log.exception("Error during user import: %r" % exx)

            Session.rollback()

            return sendError(response, "%r" % exx)

        finally:
            Session.close()
            log.debug('done')
コード例 #9
0
    def autosync(self, hmac2Otp, anOtpVal):
        '''
        auto - sync the token based on two otp values
        - internal method to realize the autosync within the
        checkOtp method

        :param hmac2Otp: the hmac object (with reference to the token secret)
        :type hmac2Otp: hmac object

        :param anOtpVal: the actual otp value
        :type anOtpVal: string

        :return: counter or -1 if otp does not exist
        :rtype:  int

        '''

        if not boolean(getFromConfig("AutoResync", False)):
            log.info('autosync is not enabled')
            return -1

        info = self.getTokenInfo()
        syncWindow = self.getSyncWindow()

        # check if the otpval is valid in the sync scope
        otp_counter = hmac2Otp.checkOtp(anOtpVal, syncWindow, symetric=True)

        if otp_counter == -1:
            log.info('no valid otp in auto resync window')
            return -1

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

        # protect against a replay

        # if the counter belonging to the provided otp is lower than the
        # stored counter (which is the next expected counter), then we deny
        # the resync as it might be replay

        if otp_counter < self.getOtpCount():
            log.info('otp before the last verified valid otp!')
            return -1

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

        # taken from the tokeninfo:
        # check if we have the first otp for the auto resync

        if "otp1c" not in info:

            info["otp1c"] = otp_counter
            self.setTokenInfo(info)

            log.info('preserved the first otp counter for resync')
            return -1

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

        # now we have 2 otps - the first from the former request,
        # the second otp from the current auto sync request

        otp1c = info["otp1c"]
        otp2c = otp_counter

        if otp2c <= otp1c:
            # the otps are not in right order
            log.info('OTP values are not in the right order!')
            return -1

        if (otp2c - otp1c) > self.resyncDiffLimit:
            # assert that the otps are not too far apart
            log.info('the otps are too far apart for resync!')

            # if so, we take the new one as the auto sync base
            info["otp1c"] = otp2c
            self.setTokenInfo(info)
            return -1

        # reset the resync info
        self.removeFromTokenInfo("otp1c")

        return otp_counter
コード例 #10
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 = boolean(getFromConfig("linotpGetotp.active", False))
        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.error("[getotp] gettoken/getotp policy failed: %r", pe)
            db.session.rollback()
            return sendError(response, pe, 1)

        except Exception as exx:
            log.error("[getotp] gettoken/getotp failed: %r", exx)
            db.session.rollback()
            return sendError(response, "gettoken/getotp failed: %s" % exx, 0)
コード例 #11
0
def prepare_resolver_parameter(new_resolver_name, param, previous_name=None):
    """
    prepare the create/update/rename of a resolver
    used in system/setResolver and admin/testresolver

    :param new_resolver_name: the name of the new/current resolver
    :param param: the new set of parameters
    :param previous_name: the previous name of the resolver

    :return: tuple of set of potential extended parameters and
             the list of the missing parameters
    """
    primary_key_changed = False

    resolver_cls = get_resolver_class(param['type'])

    if resolver_cls is None:
        raise Exception("no such resolver type '%r' defined!" % param['type'])

    # for rename and update, we support the merge with previous parameters
    if previous_name:

        # get the parameters of the previous resolver
        previous_resolver = getResolverInfo(previous_name, passwords=True)

        previous_param = previous_resolver['data']
        previous_readonly = boolean(previous_resolver.get('readonly', False))

        # get the critical parameters for this resolver type
        # and check if these parameters have changed

        is_critical = resolver_cls.is_change_critical(
            new_params=param, previous_params=previous_param)

        # if there are no critical changes, we can transfer
        # the encrypted parameters from previous resolver

        if not is_critical:

            merged_params = resolver_cls.merge_crypted_parameters(
                new_params=param, previous_params=previous_param)

            param.update(merged_params)

        # in case of a readonly resolver, no changes beneath a rename
        # is allowed

        if previous_readonly:
            for key, p_value in previous_param.items():

                # we inherit the readonly parameter if it is
                # not provided by the ui

                if key == 'readonly':
                    param['readonly'] = boolean(p_value)
                    continue

                if p_value != param.get(key, ''):
                    raise Exception('Readonly Resolver Change not allowed!')

        # check if the primary key changed - if so, we need
        # to migrate the resolver

        primary_key_changed = resolver_cls.primary_key_changed(
            new_params=param, previous_params=previous_param)

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

    # check if all crypted parameters are included

    missing = resolver_cls.missing_crypted_parameters(param)

    return param, missing, primary_key_changed
コード例 #12
0
def getResolverInfo(resolvername, passwords=False):
    """
    return the resolver info of the given resolvername

    :param resolvername: the requested resolver
    :type  resolvername: string

    :return : dict of resolver description
    """

    result = {"type": None, "data": {}, "resolver": resolvername}

    linotp_config = context.get("Config")
    resolver_types = get_resolver_types()

    local_admin_resolver = current_app.config["ADMIN_RESOLVER_NAME"]

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

    # lookup, which resolver type is associated with this resolver name

    for config_entry in linotp_config:

        if config_entry.endswith("." + resolvername):

            # check if this is a resolver definition, starting with linotp.
            # and continuing with a resolver type

            part = config_entry.split(".")

            if (
                len(part) > 3
                and part[0] == "linotp"
                and part[1] in resolver_types
            ):

                resolver_type = part[1]
                break

    else:
        return result

    # now we can load the resolver config unsing the resolver class

    resolver_cls = get_resolver_class(resolver_type)

    if resolver_cls is None:
        raise Exception("no such resolver type '%r' defined!" % resolver_type)

    result["spec"] = resolver_cls.db_prefix + "." + resolvername

    res_conf, _missing = resolver_cls.filter_config(
        linotp_config, resolvername
    )

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

    # now prepare the resolver config output, which should contain
    #
    # - no global entries, starting with 'linotp.'
    # - adjusted passwords
    # - all values as text

    for key in list(res_conf.keys()):

        # suppress global config entries

        if key.startswith("linotp."):
            del res_conf[key]
            continue

        # should passwords be displayed?
        if key in resolver_cls.crypted_parameters:

            # we have to be sure that we only have encrypted data objects for
            # secret data
            if not isinstance(res_conf[key], EncryptedData):
                raise Exception("Encrypted Data Object expected")

            # if parameter password is True, we need to unencrypt
            if passwords:
                res_conf[key] = res_conf[key].get_unencrypted()

        # as we have in the resolver config typed values, this might
        # lead to some trouble. so we prepare for output comparison
        # the string representation

        if not isinstance(res_conf[key], str):
            res_conf[key] = "%r" % res_conf[key]

    if "readonly" in res_conf:
        readonly = False
        try:
            readonly = boolean(res_conf["readonly"])
        except Exception:
            log.info(
                "Failed to convert 'readonly' attribute %r:%r",
                resolvername,
                res_conf["readonly"],
            )

        if readonly:
            result["readonly"] = True

    result["type"] = resolver_type
    result["data"] = res_conf
    result["admin"] = resolvername in get_admin_resolvers()

    # set the immutable flag if its the local_admin_resolver
    result["immutable"] = local_admin_resolver == resolvername

    return result
コード例 #13
0
def getResolverList(filter_resolver_type=None, config=None):
    """
    Gets the list of configured resolvers

    :param filter_resolver_type: Only resolvers of the given type are returned
    :type filter_resolver_type: string
    :rtype: Dictionary of the resolvers and their configuration
    """
    Resolvers = {}
    resolvertypes = get_resolver_types()

    local_admin_resolver = current_app.config["ADMIN_RESOLVER_NAME"]

    admin_resolvers = get_admin_resolvers()

    if not config:
        conf = context.get("Config")
    else:
        conf = config

    for entry in conf:

        for typ in resolvertypes:
            if entry.startswith("linotp." + typ):
                # the resolver might contain dots "." so take
                # all after the 3rd dot for the resolver name
                r = {}
                resolver = entry.split(".", 3)

                # An old entry without resolver name
                if len(resolver) <= 3:
                    break
                r["resolvername"] = resolver[3]
                r["entry"] = entry
                r["type"] = typ

                # return the resolver spec, which is required to define a realm
                resolver_cls = get_resolver_class(typ)
                r["spec"] = resolver_cls.db_prefix + "." + resolver[3]
                r["admin"] = resolver[3] in admin_resolvers

                # set the immutable flag if its the local_admin_resolver
                r["immutable"] = local_admin_resolver == resolver[3]

                readonly_entry = ".".join(
                    [resolver[0], resolver[1], "readonly", resolver[3]]
                )

                if readonly_entry in conf:
                    readonly = False
                    try:
                        readonly = boolean(conf[readonly_entry])
                    except Exception as _exx:
                        log.info(
                            "Failed to convert 'readonly' attribute %r:%r",
                            readonly_entry,
                            conf[readonly_entry],
                        )

                    if readonly:
                        r["readonly"] = True
                #
                # this is a patch for a hack:
                #
                # as entry, the first found resolver is shown
                # as the PasswdResolver only has one entry, this always
                # has been 'fileName', which now as could be 'readonly'
                # thus we skip the readonly entry:

                key = resolver[2]
                if key == "readonly":
                    continue

                if (filter_resolver_type is None) or (
                    filter_resolver_type and filter_resolver_type == typ
                ):
                    Resolvers[resolver[3]] = r
                # Dont check the other resolver types
                break

    return Resolvers
コード例 #14
0
def getResolverList(filter_resolver_type=None):
    '''
    Gets the list of configured resolvers

    :param filter_resolver_type: Only resolvers of the given type are returned
    :type filter_resolver_type: string
    :rtype: Dictionary of the resolvers and their configuration
    '''
    Resolvers = {}
    resolvertypes = get_resolver_types()

    conf = context.get('Config')
    # conf = getLinotpConfig()
    for entry in conf:

        for typ in resolvertypes:
            if entry.startswith("linotp." + typ):
                # the realm might contain dots "."
                # so take all after the 3rd dot for realm
                r = {}
                resolver = entry.split(".", 3)

                # An old entry without resolver name
                if len(resolver) <= 3:
                    break
                r["resolvername"] = resolver[3]
                r["entry"] = entry
                r["type"] = typ

                readonly_entry = '.'.join(
                    [resolver[0], resolver[1], 'readonly', resolver[3]])

                if readonly_entry in conf:
                    readonly = False
                    try:
                        readonly = boolean(conf[readonly_entry])
                    except Exception as _exx:
                        log.info(
                            "Failed to convert 'readonly' attribute"
                            " %r:%r", readonly_entry, conf[readonly_entry])

                    if readonly:
                        r["readonly"] = True
                #
                # this is a patch for a hack:
                #
                # as entry, the first found resolver is shown
                # as the PasswdResolver only has one entry, this always
                # has been 'fileName', which now as could be 'readonly'
                # thus we skip the readonly entry:

                key = resolver[2]
                if key == "readonly":
                    continue

                if ((filter_resolver_type is None) or
                    (filter_resolver_type and filter_resolver_type == typ)):
                    Resolvers[resolver[3]] = r
                # Dont check the other resolver types
                break

    return Resolvers
コード例 #15
0
def _get_client_from_request(request=None):
    '''
    This function returns the client as it is passed in the HTTP Request.
    This is the very HTTP client, that contacts the LinOTP server.
    '''

    client = request.environ.get(
                    'REMOTE_ADDR', request.environ.get(
                        'HTTP_REMOTE_ADDR', None))

    x_forwarded_for = boolean(config.get(
                        'client.X_FORWARDED_FOR',  getFromConfig(
                            'client.X_FORWARDED_FOR', 'False')))

    if x_forwarded_for:
        # check, if the request passed by a qualified proxy

        remote_addr = client
        x_forwarded_proxies = config.get(
                    'client.FORWARDED_PROXY', getFromConfig(
                        'client.FORWARDED_PROXY', '')).split(',')

        for x_forwarded_proxy in x_forwarded_proxies:
            if _is_addr_in_network(remote_addr, x_forwarded_proxy):

                ref_clients = request.environ.get('HTTP_X_FORWARDED_FOR', '')
                for ref_client in ref_clients.split(','):

                    # the first ip in the list is the originator
                    client = ref_client.strip()
                    break

    # "Forwarded" Header
    #
    # In 2014 RFC 7239 standardized a new Forwarded header with similar purpose
    # but more features compared to XFF.[28] An example of a Forwarded header
    # syntax:
    #
    # Forwarded: for=192.0.2.60; proto=http; by=203.0.113.43

    forwarded = boolean(config.get(
                    'client.FORWARDED', getFromConfig(
                        'client.FORWARDED', 'false')))

    if forwarded:
        # check, if the request passed by a qaulified proxy

        remote_addr = client
        forwarded_proxies = config.get(
                    'client.FORWARDED_PROXY', getFromConfig(
                            'client.FORWARDED_PROXY', '').split(','))

        for forwarded_proxy in forwarded_proxies:
            if _is_addr_in_network(remote_addr, forwarded_proxy):

                # example is:
                # "Forwarded: for=192.0.2.43, for=198.51.100.17"

                entries = request.environ.get(
                    'HTTP_FORWARDED', request.environ.get(
                        'Forwarded', ''))

                forwarded_set = []
                entries = entries.replace("Forwarded:", "")
                for entry in entries.split(','):
                    if entry.lower().startswith('for'):
                        value = entry.split('=')[1]
                        value = value.split(';')[0].strip()
                        if ']' in value:
                            ipvalue = value.split(']')[0].split('[')[1]
                        elif ':' in value:
                            ipvalue = value.split(':')[0]
                        else:
                            ipvalue = value
                        forwarded_set.append(ipvalue.strip('"'))

                for originator in forwarded_set:
                    client = originator
                    break

    log.debug("got the client %s" % client)
    return client
コード例 #16
0
def getResolverInfo(resolvername, passwords=False):
    '''
    return the resolver info of the given resolvername

    :param resolvername: the requested resolver
    :type  resolvername: string

    :return : dict of resolver description
    '''

    result = {"type": None, "data": {}, "resolver": resolvername}

    linotp_config = context.get('Config')
    resolver_types = get_resolver_types()

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

    # lookup, which resolver type is associated with this resolver name

    for config_entry in linotp_config:

        if config_entry.endswith("." + resolvername):

            # check if this is a resolver definition, starting with linotp.
            # and continuing with a resolver type

            part = config_entry.split('.')

            if (len(part) > 3 and part[0] == 'linotp'
                    and part[1] in resolver_types):

                resolver_type = part[1]
                break

    else:
        return result

    # now we can load the resolver config unsing the resolver class

    resolver_cls = get_resolver_class(resolver_type)

    if resolver_cls is None:
        raise Exception("no such resolver type '%r' defined!" % resolver_type)

    res_conf, _missing = resolver_cls.filter_config(linotp_config,
                                                    resolvername)

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

    # now prepare the resolver config output, which should contain
    #
    # - no global entries, starting with 'linotp.'
    # - adjusted passwords
    # - all values as text

    for key in res_conf.keys():

        # suppress global config entries

        if key.startswith("linotp."):
            del res_conf[key]
            continue

        # should passwords be displayed?
        if key in resolver_cls.crypted_parameters:
            if not passwords:
                res_conf[key] = encryptPassword(res_conf[key])

        # as we have in the resolver config typed values, this might
        # lead to some trouble. so we prepare for output comparison
        # the string representation

        if (not isinstance(res_conf[key], str)
                and not isinstance(res_conf[key], unicode)):
            res_conf[key] = "%r" % res_conf[key]

    if 'readonly' in res_conf:
        readonly = False
        try:
            readonly = boolean(res_conf['readonly'])
        except Exception:
            log.info("Failed to convert 'readonly' attribute %r:%r",
                     resolvername, res_conf['readonly'])

        if readonly:
            result["readonly"] = True

    result["type"] = resolver_type
    result["data"] = res_conf

    return result
コード例 #17
0
    def __before__(self, **params):
        """
        __before__ is called before every action

        :param params: list of named arguments
        :return: -nothing- or in case of an error a Response
                created by sendError with the context info 'before'
        """

        action = request_context["action"]

        try:
            g.audit["success"] = False
            g.audit["client"] = get_client(request)

            c.version = get_version()
            c.version_ref = base64.encodebytes(c.version.encode())[:6]

            c.licenseinfo = get_copyright_info()
            c.polDefs = get_policy_definitions()

            c.display_provider = boolean(
                request_context["Config"].get("display_provider", True)
            )

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

            # check for support of setting admin password

            c.admin_can_change_password = False
            if (
                "linotpadmin.user" in config
                and "linotpadmin.password" in config
            ):
                c.admin_can_change_password = True

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

            # Session handling for the functions, that show data:
            # Also exclude custom-style.css, since the CSRF check
            # will always fail and return a HTTP 401 anyway.
            # A HTTP 404 makes more sense.
            if request.path.lower() in [
                "/manage/",
                "/manage",
                "/manage/login",
                "/manage/audittrail",
                "/manage/policies",
                "/manage/tokenview",
                "/manage/userview",
                "/manage/help",
                "/manage/custom-style.css",
            ]:
                pass
            else:
                check_session(request)

        except Exception as exx:
            log.error("[__before__::%r] exception %r", action, exx)
            db.session.rollback()
            return sendError(response, exx, context="before")

        finally:
            log.debug("[__before__::%r] done", action)
コード例 #18
0
    def getmultiotp(self):
        """
        This function is used to retrieve multiple otp values 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/getmultiotp

        arguments:
            serial  - the serial number of the token
            count   - number of otp values to return
            curTime - used ONLY for internal testing: datetime.datetime object

        returns:
            JSON response
        """

        getotp_active = boolean(getFromConfig("linotpGetotp.active", False))
        if not getotp_active:
            return sendError(response, "getotp is not activated.", 0)

        param = self.request_params
        ret = {}

        try:
            serial = getParam(param, "serial", required)
            count = int(getParam(param, "count", required))
            curTime = getParam(param, "curTime", optional)
            view = getParam(param, "view", optional)

            r1 = checkPolicyPre("admin", "getotp", param)
            log.debug("[getmultiotp] admin-getotp policy: %s", r1)

            max_count = checkPolicyPre("gettoken", "max_count", param)
            log.debug("[getmultiotp] maxcount policy: %s", max_count)
            if count > max_count:
                count = max_count

            log.debug("[getmultiotp] retrieving OTP value for token %s",
                      serial)
            ret = get_multi_otp(serial, count=int(count), curTime=curTime)
            ret["serial"] = serial

            g.audit["success"] = True
            db.session.commit()

            if view:
                c.ret = ret
                return render("/selfservice/multiotp_view.mako").decode(
                    "utf-8")
            else:
                return sendResult(response, ret, 0)

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

        except Exception as exx:
            log.error("[getmultiotp] gettoken/getmultiotp failed: %r", exx)
            db.session.rollback()
            return sendError(response, "gettoken/getmultiotp failed: %r" % exx,
                             0)
コード例 #19
0
def getResolverList(filter_resolver_type=None, config=None):
    '''
    Gets the list of configured resolvers

    :param filter_resolver_type: Only resolvers of the given type are returned
    :type filter_resolver_type: string
    :rtype: Dictionary of the resolvers and their configuration
    '''
    Resolvers = {}
    resolvertypes = get_resolver_types()

    if not config:
        conf = context.get('Config')
    else:
        conf = config

    for entry in conf:

        for typ in resolvertypes:
            if entry.startswith("linotp." + typ):
                # the realm might contain dots "."
                # so take all after the 3rd dot for realm
                r = {}
                resolver = entry.split(".", 3)

                # An old entry without resolver name
                if len(resolver) <= 3:
                    break
                r["resolvername"] = resolver[3]
                r["entry"] = entry
                r["type"] = typ

                readonly_entry = '.'.join([resolver[0], resolver[1],
                                           'readonly', resolver[3]])

                if readonly_entry in conf:
                    readonly = False
                    try:
                        readonly = boolean(conf[readonly_entry])
                    except Exception as _exx:
                        log.info("Failed to convert 'readonly' attribute"
                                 " %r:%r",
                                 readonly_entry, conf[readonly_entry])

                    if readonly:
                        r["readonly"] = True
                #
                # this is a patch for a hack:
                #
                # as entry, the first found resolver is shown
                # as the PasswdResolver only has one entry, this always
                # has been 'fileName', which now as could be 'readonly'
                # thus we skip the readonly entry:

                key = resolver[2]
                if key == "readonly":
                    continue

                if ((filter_resolver_type is None) or
                        (filter_resolver_type and
                         filter_resolver_type == typ)):
                    Resolvers[resolver[3]] = r
                # Dont check the other resolver types
                break

    return Resolvers
コード例 #20
0
ファイル: util.py プロジェクト: sisalehiskandar/LinOTP
def _get_client_from_request(request=None):
    '''
    This function returns the client as it is passed in the HTTP Request.
    This is the very HTTP client, that contacts the LinOTP server.
    '''

    client = request.environ.get('REMOTE_ADDR',
                                 request.environ.get('HTTP_REMOTE_ADDR', None))

    x_forwarded_for = boolean(
        config.get('client.X_FORWARDED_FOR',
                   getFromConfig('client.X_FORWARDED_FOR', 'False')))

    if x_forwarded_for:
        # check, if the request passed by a qualified proxy

        remote_addr = client
        x_forwarded_proxies = config.get(
            'client.FORWARDED_PROXY',
            getFromConfig('client.FORWARDED_PROXY', '')).split(',')

        for x_forwarded_proxy in x_forwarded_proxies:
            if _is_addr_in_network(remote_addr, x_forwarded_proxy):

                ref_clients = request.environ.get('HTTP_X_FORWARDED_FOR', '')
                for ref_client in ref_clients.split(','):

                    # the first ip in the list is the originator
                    client = ref_client.strip()
                    break

    # "Forwarded" Header
    #
    # In 2014 RFC 7239 standardized a new Forwarded header with similar purpose
    # but more features compared to XFF.[28] An example of a Forwarded header
    # syntax:
    #
    # Forwarded: for=192.0.2.60; proto=http; by=203.0.113.43

    forwarded = boolean(
        config.get('client.FORWARDED',
                   getFromConfig('client.FORWARDED', 'false')))

    if forwarded:
        # check, if the request passed by a qaulified proxy

        remote_addr = client
        forwarded_proxies = config.get(
            'client.FORWARDED_PROXY',
            getFromConfig('client.FORWARDED_PROXY', '').split(','))

        for forwarded_proxy in forwarded_proxies:
            if _is_addr_in_network(remote_addr, forwarded_proxy):

                # example is:
                # "Forwarded: for=192.0.2.43, for=198.51.100.17"

                entries = request.environ.get(
                    'HTTP_FORWARDED', request.environ.get('Forwarded', ''))

                forwarded_set = []
                entries = entries.replace("Forwarded:", "")
                for entry in entries.split(','):
                    if entry.lower().startswith('for'):
                        value = entry.split('=')[1]
                        value = value.split(';')[0].strip()
                        if ']' in value:
                            ipvalue = value.split(']')[0].split('[')[1]
                        elif ':' in value:
                            ipvalue = value.split(':')[0]
                        else:
                            ipvalue = value
                        forwarded_set.append(ipvalue.strip('"'))

                for originator in forwarded_set:
                    client = originator
                    break

    log.debug("got the client %s" % client)
    return client
コード例 #21
0
def getResolverInfo(resolvername, passwords=False):
    '''
    return the resolver info of the given resolvername

    :param resolvername: the requested resolver
    :type  resolvername: string

    :return : dict of resolver description
    '''

    result = {"type": None, "data": {}, "resolver": resolvername}

    linotp_config = context.get('Config')
    resolver_types = get_resolver_types()

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

    # lookup, which resolver type is associated with this resolver name

    for config_entry in linotp_config:

        if config_entry.endswith("." + resolvername):

            # check if this is a resolver definition, starting with linotp.
            # and continuing with a resolver type

            part = config_entry.split('.')

            if (len(part) > 3 and part[0] == 'linotp' and
                part[1] in resolver_types):

                resolver_type = part[1]
                break

    else:
        return result

    # now we can load the resolver config unsing the resolver class

    resolver_cls = get_resolver_class(resolver_type)

    if resolver_cls is None:
        raise Exception("no such resolver type '%r' defined!" %
                        resolver_type)

    res_conf, _missing = resolver_cls.filter_config(linotp_config,
                                                    resolvername)

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

    # now prepare the resolver config output, which should contain
    #
    # - no global entries, starting with 'linotp.'
    # - adjusted passwords
    # - all values as text

    for key in res_conf.keys():

        # suppress global config entries

        if key.startswith("linotp."):
            del res_conf[key]
            continue

        # should passwords be displayed?
        if key in resolver_cls.crypted_parameters:
            if not passwords:
                res_conf[key] = encryptPassword(res_conf[key])

        # as we have in the resolver config typed values, this might
        # lead to some trouble. so we prepare for output comparison
        # the string representation

        if (not isinstance(res_conf[key], str) and
            not isinstance(res_conf[key], unicode)):
            res_conf[key] = "%r" % res_conf[key]

    if 'readonly' in res_conf:
        readonly = False
        try:
            readonly = boolean(res_conf['readonly'])
        except Exception:
            log.info("Failed to convert 'readonly' attribute %r:%r",
                     resolvername, res_conf['readonly'])

        if readonly:
            result["readonly"] = True

    result["type"] = resolver_type
    result["data"] = res_conf

    return result
コード例 #22
0
    def _submitMessage(self, phone, message):
        '''
        Submits the message for phone to the email gateway.

        Returns true in case of success
        '''
        ret = False
        if ('mailserver' not in self.config or
                'mailsender' not in self.config or 'mailto' not in self.config):
            log.error("[submitMessage] incomplete config: %s. mailserver, "
                      "mailsender and mailto needed." % self.config)
            return ret

        # prepare the phone number
        msisdn = 'true' in ("%r" % self.config.get('MSISDN', "false")).lower()
        if msisdn:
            phone = self._get_msisdn_phonenumber(phone)

        # prepare the smtp server connection parameters
        default_port = 25

        start_tls_params = {}
        start_tls = str(self.config.get("start_tls", False)).lower() == 'true'
        if start_tls:
            default_port = 587
            start_tls_params_keyfile = self.config.get("keyfile", None)
            start_tls_params_certfile = self.config.get("certfile", None)

        use_ssl = str(self.config.get("use_ssl", False)).lower() == 'true'
        if use_ssl:
            default_port = 465

        server = self.config.get("mailserver")
        port = int(self.config.get("mailserver_port", default_port))

        # support for mailserver syntax like server:port
        # if port is not explicit defined
        if "mailserver_port" not in self.config and ':' in server:
            server, _sep, port = server.rpartition(':')

        user = self.config.get("mailuser")
        password = self.config.get("mailpassword")

        fromaddr = self.config.get("mailsender", "linotp@localhost")
        toaddr = self.config.get("mailto")
        subject = self.config.get("subject", "")
        body = self.config.get("body", "")

        log.debug("[submitMessage] submitting message %s to %s",
                  message, phone)

        toaddr = string.replace(toaddr, PHONE_TAG, phone)

        if not subject:
            subject = "[LinOTP]"
        subject = string.replace(subject, PHONE_TAG, phone)
        subject = string.replace(subject, MSG_TAG, message)

        if not body:
            body = "<otp>"
        body = string.replace(body, PHONE_TAG, phone)
        body = string.replace(body, MSG_TAG, message)

        msg = ("From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n%s"
               % (fromaddr, toaddr, subject, body))

        serv = None
        try:
            # if SSL is defined, we require a different base class
            if not use_ssl:
                serv = smtplib.SMTP(server, port)
            else:
                serv = smtplib.SMTP_SSL(server, port)
            serv.set_debuglevel(1)

            serv.ehlo()
            if start_tls and not use_ssl:
                if serv.has_extn('STARTTLS'):
                    serv.starttls(start_tls_params_keyfile,
                                  start_tls_params_certfile)
                    serv.ehlo()
                else:
                    log.error("Start_TLS not supported:")
                    raise Exception("Start_TLS requested but not supported"
                                    " by server %r" % server)
            if user:
                if serv.has_extn('AUTH'):
                    log.debug("authenticating to mailserver, user: %s, "
                              "pass: %r", user, sha256(password).hexdigest())
                    serv.login(user, password)
                else:
                    log.error("AUTH not supported:")

            data_dict = serv.sendmail(fromaddr, toaddr, msg)
            log.debug("sendmail: %r", data_dict)

            (code, response) = serv.quit()
            log.debug("quit: (%r) %r", code, response)
            ret = True

        except smtplib.socket.error as exc:
            log.exception('Error: could not connect to server')
            if boolean(self.config.get('raise_exception', True)):
                raise ProviderNotAvailable('Error: could not connect '
                                           'to server: %r' % exc)
            ret = False

        except Exception as exx:
            log.exception("[submitMessage] %s", exx)
            if boolean(self.config.get('raise_exception', False)):
                raise Exception(exx)
            ret = False

        finally:
            if serv:
                serv.close()

        return ret
コード例 #23
0
def prepare_resolver_parameter(new_resolver_name, param,
                               previous_name=None):
    """
    prepare the create/update/rename of a resolver
    used in system/setResolver and admin/testresolver

    :param new_resolver_name: the name of the new/current resolver
    :param param: the new set of parameters
    :param previous_name: the previous name of the resolver

    :return: tuple of set of potential extended parameters and
             the list of the missing parameters
    """
    primary_key_changed = False

    resolver_cls = get_resolver_class(param['type'])

    if resolver_cls is None:
        raise Exception("no such resolver type '%r' defined!" %
                        param['type'])

    # for rename and update, we support the merge with previous parameters
    if previous_name:

        # get the parameters of the previous resolver
        previous_resolver = getResolverInfo(previous_name,
                                            passwords=True)

        previous_param = previous_resolver['data']
        previous_readonly = boolean(previous_resolver.get('readonly', False))

        # get the critical parameters for this resolver type
        # and check if these parameters have changed

        is_critical = resolver_cls.is_change_critical(
                                    new_params=param,
                                    previous_params=previous_param)

        # if there are no critical changes, we can transfer
        # the encrypted parameters from previous resolver

        if not is_critical:

            merged_params = resolver_cls.merge_crypted_parameters(
                                    new_params=param,
                                    previous_params=previous_param)

            param.update(merged_params)

        # in case of a readonly resolver, no changes beneath a rename
        # is allowed

        if previous_readonly:
            for key, p_value in previous_param.items():

                # we inherit the readonly parameter if it is
                # not provided by the ui

                if key == 'readonly':
                    param['readonly'] = boolean(p_value)
                    continue

                if p_value != param.get(key, ''):
                    raise Exception('Readonly Resolver Change not allowed!')

        # check if the primary key changed - if so, we need
        # to migrate the resolver

        primary_key_changed = resolver_cls.primary_key_changed(
                                    new_params=param,
                                    previous_params=previous_param)

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

    # check if all crypted parameters are included

    missing = resolver_cls.missing_crypted_parameters(param)

    return param, missing, primary_key_changed
コード例 #24
0
ファイル: cache.py プロジェクト: smartree/LinOTP
def get_cache(cache_name: str, scope: str=None) -> Optional[Cache]:
    """
    load the cache with cache_name and scope

    Each cache defines the following configuration parameters:

        linotp.{cache_name}_cache.enabled
            Whether the cache is enabled. Defaults to True
        linotp.{cache_name}_cache.expiration
            How long the entries are cached for in seconds. Defaults to 3 days.

    :remark: This cache is only enabled, if the configuration entry 'enabled'
             evaluates to True and the expiration is of a valid format.
             Expiration format is defined linotp.lib.type_utils

    :param cache_name: the name of the cache
    :param scope: there are related caches, which names are extended by scope
                  used for realm specific caches e.g. for users

    :return: the cache or None if not enabled, 
    
             wrt to typing the cache is not deterministic as the cache type
             is returned by the app.getCacheManager() which could be a beaker
             or something else
    """

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

    # evaluate the config lookup keys

    config = context['Config']

    config_basename = "linotp." + cache_name + "_cache"
    enabled_entry = config_basename + ".enabled"
    expiration_entry = config_basename + ".expiration"

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

    enabled = boolean(config.get(enabled_entry, True))

    if not enabled:
        return None

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

    # handle expiration format

    expiration_conf = config.get(expiration_entry, 36 * 3600)

    try:
        expiration = get_duration(expiration_conf)

    except ValueError:
        log.info("caching is disabled due to a value error for expiration "
                 "definition %r" % expiration_conf)
        return None

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

    # retrieve the cache from the cache manager

    cache_manager = current_app.getCacheManager()

    if not cache_manager:
        log.info('No Cache Manager found!')
        return None

    cache_fullname = cache_name
    if scope:
        cache_fullname = "%s::%s" % (cache_name, scope)

    resolver_config_cache = cache_manager.get_cache(
                        cache_fullname, type="memory", expiretime=expiration)

    return resolver_config_cache
コード例 #25
0
    def initToken(self):
        """
        init one DPW token
        """

        self.createDPWToken("dpw1", "12341234123412341234123412341234")
        """
        curTime = datetime.datetime(2012, 5, 16, 9, 0, 52, 227413)
            "12-05-22": "202690",
            "12-05-23": "252315",
            "12-05-20": "6",
            "12-05-21": "325819",
            "12-05-24": "263973",
            "12-05-25": "321965",
            "12-05-17": "028193",
            "12-05-16": "427701",
            "12-05-19": "167074",
            "12-05-18": "857788"
        """
        self.createHOTPToken("hotp1", "12341234123412341234123412341234")
        """
            "0": "819132",
            "1": "301156",
            "2": "586172",
            "3": "720026",
            "4": "062511",
            "5": "598723",
            "6": "770725",
            "7": "596337",
            "8": "647211",
            "9": "294016",
            "10": "161051",
            "11": "886458"
        """
        self.createTOTPToken("totp1", self.seed, timeStep=30)
        """
        T0=44576428.686175205 (*30)
            "44576428": "33726427",
            "44576429": "84341529",
            "44576430": "35692495",
            "44576431": "70995873",
            "44576432": "12048114",
            "44576433": "06245460",
            "44576434": "10441015",
            "44576435": "50389782",
            "44576436": "78905052",
            "44576437": "52978758",
            "44576438": "90386435",
            "44576439": "76892112"

        """

        response = self.setTokenRealm("dpw1", "mydefrealm")
        assert '"status": true' in response, response

        response = self.setTokenRealm("hotp1", "mydefrealm")
        assert '"status": true' in response, response

        response = self.setTokenRealm("totp1", "mydefrealm")
        assert '"status": true' in response, response

        params = {"user": "******", "serial": "totp1"}
        response = self.make_admin_request(action="assign", params=params)
        assert '"status": true' in response, response

        parameters = {}
        response = self.make_system_request(
            action="getRealms", params=parameters
        )

        assert '"status": true' in response, response

        parameters = {
            "name": "getmultitoken",
            "scope": "gettoken",
            "realm": "mydefrealm",
            "action": (
                "max_count_dpw=10, max_count_hotp=10, max_count_totp=10"
            ),
            "user": "******",
        }
        response = self.make_system_request(
            action="setPolicy", params=parameters
        )
        assert '"status": true' in response, response

        response = self.make_system_request(action="getConfig", params={})

        assert response.json["result"]["status"], response
        config = response.json["result"]["value"]

        assert "linotpGetotp.active" in config, response
        assert boolean(config["linotpGetotp.active"]) is True

        return