def test_04_get_rand_digit_str(self): self.assertRaises(ValueError, get_rand_digit_str, 1) r = get_rand_digit_str(2) self.assertTrue(len(r) == 2, r) r = get_rand_digit_str(1001) self.assertTrue(len(r) == 1001, r) r = get_rand_digit_str(19182) self.assertTrue(len(r) == 19182)
def test_04_get_rand_digit_str(self): self.assertRaises(ValueError, get_rand_digit_str, 1) r = get_rand_digit_str(2) self.assertTrue(len(r) == 2, r) r = get_rand_digit_str(1001) self.assertTrue(len(r) == 1001, r) r = get_rand_digit_str(19182) self.assertTrue(len(r) == 19182)
def create_challenge(self): """ Depending on the self.challenge_type and the self.challenge_length we create a challenge :return: a challenge string """ ret = None if self.challenge_type == "QH": ret = geturandom(length=self.challenge_length, hex=True) elif self.challenge_type == "QA": ret = get_alphanum_str(self.challenge_length) elif self.challenge_type == "QN": ret = get_rand_digit_str(length=self.challenge_length) if not ret: # pragma: no cover raise Exception("OCRA.create_challenge failed. Obviously no good " "challenge_type!") return ret
def create_challenge(self): """ Depending on the self.challenge_type and the self.challenge_length we create a challenge :return: a challenge string """ ret = None if self.challenge_type == "QH": ret = geturandom(length=self.challenge_length, hex=True) elif self.challenge_type == "QA": ret = get_alphanum_str(self.challenge_length) elif self.challenge_type == "QN": ret = get_rand_digit_str(length=self.challenge_length) if not ret: # pragma: no cover raise Exception("OCRA.create_challenge failed. Obviously no good " "challenge_type!") return ret
def createTransactionId(cls, length=20): return get_rand_digit_str(length)
def generic_challenge_response_reset_pin(wrapped_function, *args, **kwds): """ Check if the authentication was successful, but if the token needs to reset its PIN. Conditions: To do so we check for "next_pin_change" in the tokeninfo data. This is however easily done using token.is_pin_change(). Policies: A policy defines, if this PIN reset functionality should be active at all. scope=AUTH, action=CHANGE_PIN_VIA_VALIDATE args are: :param tokenobject_list: The list of all the tokens of the user, that will be checked :param passw: The password presented in the authentication. We need this for the PIN reset. kwds are: :param options: options dictionary containing g :param user: The user_obj """ # Before we call the wrapped function, we need to check, if we have a generic challenge # for the given transaction_id and if the token serial matches a given token options = kwds.get("options") or {} user_obj = kwds.get("user") transaction_id = options.get("transaction_id") or options.get("state") if transaction_id: challenges = get_challenges(transaction_id=transaction_id, challenge=CHALLENGE_TYPE.PIN_RESET) if len(challenges) == 1: challenge = challenges[0] # check if challenge matches a token and if it is valid token_obj = next(t for t in args[0] if t.token.serial == challenge.serial) if token_obj: # Then either verify the PIN or set the PIN the first time. The # PIN from the 1st response is stored in challenge.data if challenge.data: # Verify the password if verify_pass_hash(args[1], challenge.data): g = options.get("g") challenge.set_otp_status(True) token_obj.challenge_janitor() # Success, set new PIN and return success token_obj.set_pin(args[1]) pinpol = Match.token( g, scope=SCOPE.ENROLL, action=ACTION.CHANGE_PIN_EVERY, token_obj=token_obj).action_values(unique=True) # Set a new next_pin_change if pinpol: # Set a new next pin change token_obj.set_next_pin_change(diff=list(pinpol)[0]) else: # Obviously the admin removed the policy for changing pins, # so we will not require to change the PIN again token_obj.del_tokeninfo("next_pin_change") return True, { "message": "PIN successfully set.", "serial": token_obj.token.serial } else: return False, { "serial": token_obj.token.serial, "message": "PINs do not match" } else: # The PIN is presented the first time. # Verify if the PIN adheres to the PIN policies. This is always in the normal user context g = options.get("g") g.logged_in_user = {"role": SCOPE.USER} if user_obj: # check_pin below originally works for logged in users, since only logged in users # are allowed to change the pin. So we need to construct a logged_in_user object, otherwise # check_pin would fail. g.logged_in_user["username"] = user_obj.login g.logged_in_user["realm"] = user_obj.realm check_pin(g, args[1], token_obj.token.tokentype, user_obj) # We need to ask for a 2nd time challenge.set_otp_status(True) seed = get_rand_digit_str(SEED_LENGTH) reply_dict = _create_pin_reset_challenge( token_obj, _("Please enter the new PIN again"), pass_hash(args[1])) return False, reply_dict success, reply_dict = wrapped_function(*args, **kwds) # After a successful authentication, we might start the PIN change process if success and reply_dict.get("pin_change"): g = options.get("g") # Determine the realm by the serial serial = reply_dict.get("serial") # The tokenlist can contain more than one token. So we get the matching token object token_obj = next(t for t in args[0] if t.token.serial == serial) if g and Match.token(g, scope=SCOPE.AUTH, action=ACTION.CHANGE_PIN_VIA_VALIDATE, token_obj=token_obj).any(): reply_dict = _create_pin_reset_challenge( token_obj, _("Please enter a new PIN")) return False, reply_dict return success, reply_dict