def is_challenge_response(self, passw, user, options=None, challenges=None): ''' check, if the request contains the result of a challenge :param passw: password, which might be pin or pin+otp :param user: the requesting user :param options: dictionary of additional request parameters :return: returns true or false ''' challenge_response = False if "state" in options or "transactionid" in options: challenge_response = True # # it as well might be a challenge response, # # if the passw is longer than the pin if challenge_response == False: (res, pin, otpval) = split_pin_otp(self, passw, user=user, options=options) if res >= 0: res = check_pin(self, pin, user=user, options=options) if res == True and len(otpval) > 0: challenge_response = True return challenge_response
def is_challenge_response(self, passw, user, options=None, challenges=None): ''' check, if the request contains the result of a challenge :param passw: password, which might be pin or pin+otp :param user: the requesting user :param options: dictionary of additional request parameters :return: returns true or false ''' challenge_response = False if "state" in options or "transactionid" in options: challenge_response = True ## it as well might be a challenge response, ## if the passw is longer than the pin if challenge_response == False: (res, pin, otpval) = split_pin_otp(self, passw, user=user, options=options) if res >= 0 : res = check_pin(self, pin, user=user, options=options) if res == True and len(otpval) > 0: challenge_response = True return challenge_response
def authenticate(self, passw, user, options=None): """ do the authentication on base of password / otp and user and options, the request parameters. Here we contact the other LinOTP server to validate the OtpVal. :param passw: the password / otp :param user: the requesting user :param options: the additional request parameters :return: tupple of (success, otp_count - 0 or -1, reply) """ log.debug("authenticate") res = False otp_counter = -1 reply = None otpval = passw ## should we check the pin localy?? if self.check_pin_local(): (res, pin, otpval) = split_pin_otp(self, passw, user, options=options) res = check_pin(self, pin, user=user, options=options) if res is False: return (res, otp_counter, reply) (res, otp_count, reply) = self.do_request(otpval, user=user) return (res, otp_count, reply)
def checkResponse4Challenge(self, user, passw, options=None, challenges=None): """ verify the response of a previous challenge :param user: the requesting user :param passw: the to be checked pass (pin+otp) :param options: options an additional argument, which could be token specific :param challenges: the list of challenges, where each challenge is described as dict :return: tuple of (otpcounter and the list of matching challenges) do the standard check for the response of the challenge + change the tokeninfo data of the last challenge """ log.debug("[checkResponse4Challenge] entering function") otp_count = -1 matching = [] tok = super(SmsTokenClass, self) counter = self.getOtpCount() window = self.getOtpCountWindow() now = datetime.datetime.now() timeScope = self.loadLinOtpSMSValidTime() otp_val = passw # # fallback: do we have pin+otp ?? (res, pin, otp) = split_pin_otp(self, passw, user=user, options=options) if res >= 0: res = check_pin(self, pin, user=user, options=options) if res == True: otp_val = otp for challenge in challenges: otp_count = self.checkOtp(otp_val, counter, window, options=options, pin=pin) if otp_count > 0: matching.append(challenge) break return (otp_count, matching)
def checkResponse4Challenge(self, user, passw, options=None, challenges=None): """ verify the response of a previous challenge There are two possible cases: 1) The 'transaction_id' (also know as 'state', which has the same value) is available in options 2) No 'transaction_id' In the first case we can safely assume that the passw only contains the OTP (no pin). In the second case passw will contain both and we split to get the OTP. :param user: the requesting user :param passw: the to be checked pass (pin+otp) :param options: options an additional argument, which could be token specific :param challenges: the list of challenges, where each challenge is described as dict :return: tuple of (otpcounter and the list of matching challenges) """ transaction_id = None otp_counter = -1 matching_challenges = [] if challenges is None or len(challenges) == 0: # There are no challenges for this token return -1, [] if options and ('transactionid' in options or 'state' in options): ## fetch the transactionid transaction_id = options.get('transactionid', None) if transaction_id is None: transaction_id = options.get('state', None) if transaction_id: otp = passw # if the transaction_id is set we can assume that we have only received a single # challenge with that transaction_id thanks to # linotp.lib.validate.ValidateToken.get_challenges() assert (len(challenges) == 1) assert (transaction_id == challenges[0].getTransactionId()) else: # If no transaction_id is set the request came through the WebUI and # we have to check all challenges split_status, _, otp = split_pin_otp(self, passw, user, options) if split_status < 0: raise Exception("Could not split passw") window = self.getOtpCountWindow() for challenge in challenges: challenge_data = challenge.getData() stored_counter = challenge_data.get("counter_value") temp_otp_counter = self.checkOtp(otp, int(stored_counter), window, options) if temp_otp_counter > 0: otp_counter = temp_otp_counter matching_challenges = [challenge] break # The matching_challenges list will either contain a single challenge or will be empty. # Returning multiple challenges is not useful in this case because all older challenges are # cleaned up anyway. return otp_counter, matching_challenges
def checkResponse4Challenge(self, user, passw, options=None, challenges=None): """ verify the response of a previous challenge There are two possible cases: 1) The 'transaction_id' (also know as 'state', which has the same value) is available in options 2) No 'transaction_id' In the first case we can safely assume that the passw only contains the OTP (no pin). In the second case passw will contain both and we split to get the OTP. :param user: the requesting user :param passw: the to be checked pass (pin+otp) :param options: options an additional argument, which could be token specific :param challenges: the list of challenges, where each challenge is described as dict :return: tuple of (otpcounter and the list of matching challenges) """ transaction_id = None otp_counter = -1 matching_challenges = [] if challenges is None or len(challenges) == 0: # There are no challenges for this token return -1, [] if options and ('transactionid' in options or 'state' in options): ## fetch the transactionid transaction_id = options.get('transactionid', None) if transaction_id is None: transaction_id = options.get('state', None) if transaction_id: otp = passw # if the transaction_id is set we can assume that we have only received a single # challenge with that transaction_id thanks to # linotp.lib.validate.ValidateToken.get_challenges() assert(len(challenges) == 1) assert(is_same_transaction(challenges[0], transaction_id)) else: # If no transaction_id is set the request came through the WebUI and # we have to check all challenges split_status, _, otp = split_pin_otp(self, passw, user, options) if split_status < 0: raise Exception("Could not split passw") window = self.getOtpCountWindow() for challenge in challenges: challenge_data = challenge.getData() stored_counter = challenge_data.get("counter_value") temp_otp_counter = self.checkOtp(otp, int(stored_counter), window, options) if temp_otp_counter > 0: otp_counter = temp_otp_counter matching_challenges = [challenge] break # The matching_challenges list will either contain a single challenge or will be empty. # Returning multiple challenges is not useful in this case because all older challenges are # cleaned up anyway. return otp_counter, matching_challenges