def check_otp(self, anOtpVal, counter=None, window=None, options=None): """ check the otpval of a token against a given counter and the window :param passw: the to be verified passw/pin :type passw: string :return: counter if found, -1 if not found :rtype: int """ options = options or {} ret = HotpTokenClass.check_otp(self, anOtpVal, counter, window, options) if ret < 0 and is_true(get_from_config("sms.concurrent_challenges")): if safe_compare(options.get("data"), anOtpVal): # We authenticate from the saved challenge ret = 1 if ret >= 0 and self._get_auto_sms(options): # get message template from user specific policies message = self._get_sms_text(options) self.inc_otp_counter(ret, reset=False) success, message = self._send_sms(message=message, options=options) log.debug("AutoSMS: send new SMS: {0!s}".format(success)) log.debug("AutoSMS: {0!r}".format(message)) return ret
def check_otp(self, anOtpVal, counter=None, window=None, options=None): """ check the otpval of a token against a given counter and the window :param passw: the to be verified passw/pin :type passw: string :return: counter if found, -1 if not found :rtype: int """ options = options or {} ret = HotpTokenClass.check_otp(self, anOtpVal, counter, window, options) if ret < 0 and is_true(get_from_config("email.concurrent_challenges")): if safe_compare(options.get("data"), anOtpVal): # We authenticate from the saved challenge ret = 1 if ret >= 0 and self._get_auto_email(options): message, mimetype = self._get_email_text_or_subject(options) subject, _ = self._get_email_text_or_subject( options, action=EMAILACTION.EMAILSUBJECT, default="Your OTP") self.inc_otp_counter(ret, reset=False) success, message = self._compose_email(message=message, subject=subject, mimetype=mimetype) log.debug("AutoEmail: send new SMS: {0!s}".format(success)) log.debug("AutoEmail: {0!r}".format(message)) return ret
def checkOtp(self, anOtpVal, window, symetric=False): """ :param anOtpVal: The OTP value to check :type anOtpVal: str :param window: :param symetric: :return: -1 if the OTP doesn't match or the current counter :rtype: int """ res = -1 start = self.counter end = self.counter + window if symetric is True: # changed window/2 to window for TOTP start = self.counter - (window) start = 0 if (start < 0) else start end = self.counter + (window) log.debug("OTP range counter: {0!r} - {1!r}".format(start, end)) for c in range(start, end): otpval = self.generate(c) #log.debug("calculating counter {0!r}".format(c)) if safe_compare(otpval, anOtpVal): res = c break # return -1 or the counter return res
def checkOtp(self, anOtpVal, window=10, options=None): ''' check a provided otp value :param anOtpVal: the to be tested otp value :type anOtpVal: str :param window: the +/- window around the test time :param options: generic container for additional values \ here only used for seltest: setting the initTime :return: -1 for fail else the identified counter/time ''' res = -1 window = window * 2 initTime = 0 if options is not None and type(options) == dict: initTime = int(options.get('initTime', 0)) if initTime == 0: otime = int(time.time() // 10) else: otime = initTime if self.secretObject is None: key = self.key pin = self.pin else: key = self.secretObject.getKey() pin = self.secPin.getKey() for i in range(otime - window, otime + window): otp = self.calcOtp(i, to_unicode(key), to_unicode(pin)) if safe_compare(anOtpVal, otp): res = i log.debug("otpvalue {0!r} found at: {1!r}".format( anOtpVal, res)) break if self.secretObject is not None: zerome(key) zerome(pin) del key del pin ## prevent access twice with last motp if res <= self.oldtime: log.warning( "otpvalue {0!s} checked once before ({1!r}<={2!r})".format( anOtpVal, res, self.oldtime)) res = -1 if res == -1: msg = 'checking motp failed' else: msg = 'checking motp sucess' log.debug("end. {0!s} : returning result: {1!r}, ".format(msg, res)) return res
def check_password(self, password): """ :param password: :type password: str :return: result of password check: 0 if success, -1 if failed :rtype: int """ res = -1 key = self.secretObject.getKey() # getKey() returns bytes and since we can not assume, that the # password only contains printable characters, we need to compare # bytes strings here. This also avoids making another copy of 'key'. if safe_compare(key, password): res = 0 zerome(key) del key return res
def check_answer(self, given_answer, challenge_object): """ Check if the given answer is the answer to the sent question. The question for this challenge response was stored in the challenge_object. Then we get the answer from the tokeninfo. :param given_answer: The answer given by the user :param challenge_object: The challenge object as stored in the database :return: in case of success: 1 """ res = -1 question = challenge_object.challenge answer = self.get_tokeninfo(question) # We need to compare two unicode strings if safe_compare(answer, given_answer): res = 1 else: log.debug("The answer for token {0!s} does not match.".format( self.get_serial())) return res
def check_challenge_response(self, user=None, passw=None, options=None): """ This method verifies if there is a matching challenge for the given passw and also verifies if the response is correct. It then returns 1 in case of success In case of failure it returns -1 :param user: the requesting user :type user: User object :param passw: the password (pin+otp) :type passw: string :param options: additional arguments from the request, which could be token specific. Usually "transactionid" :type options: dict :return: return success :rtype: int """ options = options or {} r_success = -1 # fetch the transaction_id transaction_id = options.get('transaction_id') if transaction_id is None: transaction_id = options.get('state') # get the challenges for this transaction ID if transaction_id is not None: challengeobject_list = get_challenges( serial=self.token.serial, transaction_id=transaction_id) for challengeobject in challengeobject_list: if challengeobject.is_valid(): # challenge is still valid # Add the challenge to the options for check_otp options["challenge"] = challengeobject.challenge options["data"] = [ int(c) for c in challengeobject.data.split(",") ] # Now see if the answer is the right indexes secret_string = to_unicode( self.token.get_otpkey().getKey()) if len(options["data"]) == len(passw): expected_answer = "".join( [secret_string[x - 1] for x in options["data"]]) if safe_compare(passw, expected_answer): r_success = 1 # Set valid OTP to true. We must not delete the challenge now, # Since we need it for further mutlichallenges challengeobject.set_otp_status(True) log.debug("The presented answer was correct.") break else: log.debug("The presented answer was wrong.") # increase the received_count challengeobject.set_otp_status() else: log.debug( "Length of password does not match the requested number of positions." ) # increase the received_count challengeobject.set_otp_status() self.challenge_janitor() return r_success