Example #1
0
    def authenticate(self, passw, user, options=None):
        """
        This is the method that verifies single shot authentication like
        they are done with push button tokens.

        It is a high level interface to support as well other tokens, which
        do not have a pin and otp seperation - they could overwrite
        this method

        **remarks:** we have to call the global methods (check_pin,++) as they
        take the pin policies into account

        :param passw: the passw which could be pin+otp
        :type passw: string
        :param user: The authenticating user
        :type user: User object
        :param options: dictionary of additional request parameters
        :type options: (dict)

        :return: returns tuple true or false for the pin match, the otpcounter
                 (int) and the reply (dict) that will be added as additional
                 information in the JSON response of ``/validate/check``.
        """

        pin_match = False
        otp_counter = -1
        reply = None

        (res, pin, otpval) = split_pin_otp(self, passw, user, options=options)
        if res != -1:
            pin_policies = get_pin_policies(user)
            if 1 in pin_policies:
                otp_counter = check_otp(self, otpval, options=options)
                if otp_counter >= 0:
                    pin_match = check_pin(self,
                                          pin,
                                          user=user,
                                          options=options)
                    if not pin_match:
                        otp_counter = -1
            else:
                pin_match = check_pin(self, pin, user=user, options=options)
                if pin_match is True:
                    otp_counter = check_otp(self, otpval, options=options)

        # for special token that have no otp like passwordtoken
        if not self.auth_info and pin_match is True and otp_counter == 0:
            self.auth_info = {"auth_info": [("pin_length", len(passw))]}

        return (pin_match, otp_counter, reply)
Example #2
0
    def authenticate(self, passw, user, options=None):
        '''
        This is the method that verifies single shot authentication like
        they are done with push button tokens.

        It is a high level interface to support as well other tokens, which
        do not have a pin and otp seperation - they could overwrite
        this method

        **remarks:** we have to call the global methods (check_pin,++) as they
        take the pin policies into account

        :param passw: the passw which could be pin+otp
        :type passw: string
        :param user: The authenticating user
        :type user: User object
        :param options: dictionary of additional request parameters
        :type options: (dict)

        :return: returns tuple true or false for the pin match, the otpcounter
                 (int) and the reply (dict) that will be added as additional
                 information in the JSON response of ``/validate/check``.
        '''

        pin_match = False
        otp_counter = -1
        reply = None

        (res, pin, otpval) = split_pin_otp(self, passw, user, options=options)
        if res != -1:
            pin_policies = get_pin_policies(user)
            if 1 in pin_policies:
                otp_counter = check_otp(self, otpval, options=options)
                if otp_counter >= 0:
                    pin_match = check_pin(
                        self, pin, user=user, options=options)
                    if not pin_match:
                        otp_counter = -1
            else:
                pin_match = check_pin(self, pin, user=user, options=options)
                if pin_match is True:
                    otp_counter = check_otp(self, otpval, options=options)

        # for special token that have no otp like passwordtoken
        if not self.auth_info and pin_match is True and otp_counter == 0:
            self.auth_info = {'auth_info': [('pin_length', len(passw))]}

        return (pin_match, otp_counter, reply)
Example #3
0
def split_pin_otp(token, passw, user=None, options=None):
    """
    split the pin and the otp fron the given password

    :param token: the corresponding token
    :param passw: the to be splitted password
    :param user: the tokenuser
    :param options: currently not used, but might be forwarded to the
                    token.splitPinPass
    :return: tuple of (split status, pin and otpval)
    """
    pin_policies = get_pin_policies(user)

    policy = 0

    if 0 in pin_policies or "token_pin" in pin_policies:
        # old stuff: We check The fixed OTP PIN
        log.debug('pin policy=0: checkin the PIN')
        (pin, otp) = token.splitPinPass(passw)

    elif 1 in pin_policies or "password" in pin_policies:
        log.debug('pin policy=1: checking the users password as pin')
        # split the passw into password and otp value
        (pin, otp) = token.splitPinPass(passw)
        policy = 1

    elif 2 in pin_policies or "only_otp" in pin_policies:
        # NO PIN should be entered at all
        log.debug('pin policy=2: checking no pin')
        (pin, otp) = ('', passw)
        token.auth_info = {
            'auth_info': [('pin_length', 0), ('otp_length', len(passw))]
        }
        policy = 2

    else:
        # old stuff: We check The fixed OTP PIN
        log.debug('pin policy=0: checkin the PIN')
        (pin, otp) = token.splitPinPass(passw)

    res = policy
    return (res, pin, otp)
Example #4
0
def split_pin_otp(token, passw, user=None, options=None):
    """
    split the pin and the otp from the given password

    :param token: the corresponding token
    :param passw: the to be split password
    :param user: the token user
    :param options: currently not used, but might be forwarded to the
                    token.splitPinPass
    :return: tuple of (split status, pin and otpval)
    """

    otppin_mode = _get_otppin_mode(get_pin_policies(user))

    if 0 == otppin_mode:
        # old stuff: We check The fixed OTP PIN
        log.debug('pin policy=0: checking the PIN')
        (pin, otp) = token.splitPinPass(passw)
        return 0, pin, otp

    elif 1 == otppin_mode:
        log.debug('pin policy=1: checking the users password as pin')
        # split the passw into password and otp value
        (pin, otp) = token.splitPinPass(passw)
        return 1, pin, otp

    elif 2 == otppin_mode:
        # NO PIN should be entered at all
        log.debug('pin policy=2: checking no pin')
        (pin, otp) = ('', passw)
        token.auth_info = {
            'auth_info': [('pin_length', 0), ('otp_length', len(passw))]
        }
        return 2, pin, otp

    elif 3 == otppin_mode:
        # no pin should be checked
        log.debug('pin policy=3: ignoring the pin')
        (pin, otp) = token.splitPinPass(passw)

        return 3, pin, otp
Example #5
0
def split_pin_otp(token, passw, user=None, options=None):
    """
    split the pin and the otp from the given password

    :param token: the corresponding token
    :param passw: the to be split password
    :param user: the token user
    :param options: currently not used, but might be forwarded to the
                    token.splitPinPass
    :return: tuple of (split status, pin and otpval)
    """

    otppin_mode = _get_otppin_mode(get_pin_policies(user))

    if 0 == otppin_mode:
        # old stuff: We check The fixed OTP PIN
        log.debug('pin policy=0: checking the PIN')
        (pin, otp) = token.splitPinPass(passw)
        return 0, pin, otp

    elif 1 == otppin_mode:
        log.debug('pin policy=1: checking the users password as pin')
        # split the passw into password and otp value
        (pin, otp) = token.splitPinPass(passw)
        return 1, pin, otp

    elif 2 == otppin_mode:
        # NO PIN should be entered at all
        log.debug('pin policy=2: checking no pin')
        (pin, otp) = ('', passw)
        token.auth_info = {'auth_info': [('pin_length', 0),
                                         ('otp_length', len(passw))]}
        return 2, pin, otp

    elif 3 == otppin_mode:
        # no pin should be checked
        log.debug('pin policy=3: ignoring the pin')
        (pin, otp) = token.splitPinPass(passw)

        return 3, pin, otp
Example #6
0
    def finish_invalid_tokens(self):
        """"""
        invalid_tokens = self.invalid_tokens
        user = self.user

        for tok in invalid_tokens:

            # count all token accesses
            if tok.count_auth_max > 0:
                tok.inc_count_auth()

            tok.statusValidationFail()

            Challenges.finish_challenges(tok, success=False)

        pin_policies = get_pin_policies(user) or []

        if 1 in pin_policies:
            action_detail = "wrong user password -1"
        else:
            action_detail = "wrong otp pin -1"

        return (False, None, action_detail)
Example #7
0
    def finish_invalid_tokens(self):
        """
        """
        invalid_tokens = self.invalid_tokens
        user = self.user

        for tok in invalid_tokens:

            # count all token accesses
            if tok.count_auth_max > 0:
                tok.inc_count_auth()

            tok.statusValidationFail()

            Challenges.finish_challenges(tok, success=False)

        pin_policies = get_pin_policies(user) or []

        if 1 in pin_policies:
            action_detail = "wrong user password -1"
        else:
            action_detail = "wrong otp pin -1"

        return (False, None, action_detail)
Example #8
0
def check_pin(token, passw, user=None, options=None):
    '''
    check the provided pin w.r.t. the policy definition

    :param passw: the to be checked pass
    :param user: if otppin==1, this is the user, which resolver should
                 be checked
    :param options: the optional request parameters

    :return: boolean, if pin matched True
    '''
    res = False

    otppin_mode = _get_otppin_mode(get_pin_policies(user))

    if 1 == otppin_mode:
        # We check the Users Password as PIN
        log.debug("pin policy=1: checking the users password as pin")
        # this should not be the case
        if not options:
            options = {}

        selfservice_state = context.get('selfservice', {}).get('state', '')
        if selfservice_state in ['credentials_verified', 'challenge_triggered']:
            return True

        if 'pin_match' not in options:
            options['pin_match'] = {}

        hashed_passw = sha256(passw.encode('utf-8')).hexdigest()

        # if password already found, we can return result again
        if hashed_passw in options['pin_match']:
            log.debug("check if password already checked! %r " %
                      options['pin_match'][hashed_passw])
            return options['pin_match'][hashed_passw]

        # if a password already matched, this one will fail
        if 'found' in options['pin_match']:
            log.debug("check if password already found but its not this one!")
            return False

        if user is None or not user.login:
            log.info("fail for pin policy == 1 with user = None")
            res = False
        else:
            (uid, _resolver, resolver_class) = getUserId(user)
            resolver = getResolverObject(resolver_class)
            if resolver.checkPass(uid, passw):
                log.debug("Successfully authenticated user %r." % uid)
                res = True
            else:
                log.info("user %r failed to authenticate." % uid)

        # we register our result
        key = sha256(passw.encode('utf-8')).hexdigest()
        options['pin_match'][key] = res
        # and register the success, to shorten lookups after
        # already one positive was found
        if res is True:
            options['pin_match']['found'] = True

        return res

    elif otppin_mode == 2:
        # NO PIN should be entered atall
        log.debug("[__checkToken] pin policy=2: checking no pin")
        return len(passw) == 0

    elif otppin_mode == 3:
        # ignore pin or password

        log.debug("[__checkToken] pin policy=3: ignoreing pin")

        if token.type in ['spass']:
            return token.checkPin(passw, options=options)

        return True

    else:
        # old stuff: We check The fixed OTP PIN
        log.debug("[__checkToken] pin policy=0: checkin the PIN")
        return token.checkPin(passw, options=options)
Example #9
0
    def check_status(self,
                     transid=None,
                     user=None,
                     serial=None,
                     password=None,
                     use_offline=False):
        """
        check for open transactions - for polling support

        :param transid: the transaction id where we request the status from
        :param user: the token owner user
        :param serial: or the serial we are searching for
        :param password: the pin/password for authorization the request
        :param use_offline: on success the offline info is returned

        :return: tuple of success and detail dict
        """

        expired, challenges = Challenges.get_challenges(None, transid=transid)

        # remove all expired challenges
        if expired:
            Challenges.delete_challenges(None, expired)

        if not challenges:
            return False, None

        # there is only one challenge per transaction id
        # if not multiple challenges, where transaction id is the parent one
        reply = {}

        pin_policies = get_pin_policies(user)
        if 1 in pin_policies:
            pin_match = check_pin(None, password, user=user, options=None)
            if not pin_match:
                return False, None

        involved_tokens = []

        transactions = {}
        for ch in challenges:

            # only look for challenges that are not compromised
            if not Challenges.verify_checksum(ch):
                continue

            # is the requester authorized
            serial = ch.getTokenSerial()
            tokens = getTokens4UserOrSerial(serial=serial)
            if not tokens:
                continue
            involved_tokens.extend(tokens)

            # as one challenge belongs exactly to only one token,
            # we take this one as the token
            token = tokens[0]

            if 1 not in pin_policies:
                pin_match = check_pin(token, password, user=user, options=None)
                if not pin_match:
                    ret = False
                    continue

            ret = True

            trans_dict = {}

            trans_dict['received_count'] = ch.received_count
            trans_dict['received_tan'] = ch.received_tan
            trans_dict['valid_tan'] = ch.valid_tan
            trans_dict['message'] = ch.challenge
            trans_dict['status'] = ch.getStatus()

            token_dict = {'serial': serial, 'type': token.type}

            # 1. check if token supports offline at all
            supports_offline_at_all = token.supports_offline_mode

            # 2. check if policy allows to use offline authentication
            if user is not None and user.login and user.realm:
                realms = [user.realm]
            else:
                realms = token.getRealms()

            offline_is_allowed = supports_offline(realms, token)

            if not ch.is_open() and ch.valid_tan and \
               supports_offline_at_all and \
               offline_is_allowed and \
               use_offline:
                token_dict['offline_info'] = token.getOfflineInfo()

            trans_dict['token'] = token_dict
            transactions[ch.transid] = trans_dict

        if transactions:
            reply['transactions'] = transactions

        return ret, reply
Example #10
0
def check_pin(token, passw, user=None, options=None):
    '''
    check the provided pin w.r.t. the policy definition

    :param passw: the to be checked pass
    :param user: if otppin==1, this is the user, which resolver should
                 be checked
    :param options: the optional request parameters

    :return: boolean, if pin matched True
    '''
    res = False

    otppin_mode = _get_otppin_mode(get_pin_policies(user))

    if 1 == otppin_mode:
        # We check the Users Password as PIN
        log.debug("pin policy=1: checking the users password as pin")
        # this should not be the case
        if not options:
            options = {}

        if 'pin_match' not in options:
            options['pin_match'] = {}

        hashed_passw = sha256(passw.encode('utf-8')).hexdigest()

        # if password already found, we can return result again
        if hashed_passw in options['pin_match']:
            log.debug("check if password already checked! %r " %
                      options['pin_match'][hashed_passw])
            return options['pin_match'][hashed_passw]

        # if a password already matched, this one will fail
        if 'found' in options['pin_match']:
            log.debug("check if password already found but its not this one!")
            return False

        if user is None or not user.login:
            log.info("fail for pin policy == 1 with user = None")
            res = False
        else:
            (uid, _resolver, resolver_class) = getUserId(user)
            resolver = getResolverObject(resolver_class)
            if resolver.checkPass(uid, passw):
                log.debug("Successfully authenticated user %r." % uid)
                res = True
            else:
                log.info("user %r failed to authenticate." % uid)

        # we register our result
        key = sha256(passw.encode('utf-8')).hexdigest()
        options['pin_match'][key] = res
        # and register the success, to shorten lookups after
        # already one positive was found
        if res is True:
            options['pin_match']['found'] = True

        return res

    elif otppin_mode == 2:
        # NO PIN should be entered atall
        log.debug("[__checkToken] pin policy=2: checking no pin")
        return len(passw) == 0

    elif otppin_mode == 3:
        # ignore pin or password

        log.debug("[__checkToken] pin policy=3: ignoreing pin")

        if token.type in ['spass']:
            return token.checkPin(passw, options=options)

        return True

    else:
        # old stuff: We check The fixed OTP PIN
        log.debug("[__checkToken] pin policy=0: checkin the PIN")
        return token.checkPin(passw, options=options)