Пример #1
0
    def resync(self, otp1, otp2, options=None):
        """
        resync the token based on two otp values
        - external method to do the resync of the token

        :param otp1: the first otp value
        :type otp1: string

        :param otp2: the second otp value
        :type otp2: string

        :param options: optional token specific parameters
        :type options:  dict or None

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

        """

        ret = False

        try:
            otplen = int(self.token.LinOtpOtpLen)
        except ValueError as ex:
            log.debug("[resync] otplen ValueError: %r ret: %r ", ex, ret)
            raise

        self.hashlibStr = self.getFromTokenInfo("hashlib", "sha1")

        secObj = self._get_secret_object()
        counter = self.token.getOtpCounter()
        syncWindow = self.token.getSyncWindow()
        # log.debug("serial: %s",serialNum)
        hmac2Otp = HmacOtp(secObj, counter, otplen,
                           self.getHashlib(self.hashlibStr))
        counter = hmac2Otp.checkOtp(otp1, syncWindow)

        if counter == -1:
            log.debug("[resync] exit. First counter (-1) not found  ret: %r",
                      ret)
            return ret

        nextOtp = hmac2Otp.generate(counter + 1)

        if nextOtp != otp2:
            log.debug(
                "[resync] exit. Failed to verify second otp: nextOtp:"
                " %r != otp2: %r ret: %r",
                nextOtp,
                otp2,
                ret,
            )
            return ret

        ret = True
        self.incOtpCounter(counter + 1, True)

        log.debug("Resync was successful")
        return ret
Пример #2
0
    def resync(self, otp1, otp2, options=None, pin=None):
        '''
        resync the token based on two otp values
        - external method to do the resync of the token

        :param otp1: the first otp value
        :type otp1: string

        :param otp2: the second otp value
        :type otp2: string

        :param options: optional token specific parameters
        :type options:  dict or None

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

        '''
        log.debug(
            "[resync] .begin. Resync the token based on: %r, anOtpVal: %r, options: %r"
            % (otp1, otp2, options))

        ret = False

        try:
            otplen = int(self.token.LinOtpOtpLen)
        except ValueError as ex:
            log.debug("[resync] otplen ValueError: %r ret: %r " % (ex, ret))
            raise Exception(ex)

        self.hashlibStr = self.getFromTokenInfo("hashlib", 'sha1')

        secretHOtp = self.token.getHOtpKey(pin)
        counter = self.token.getOtpCounter()
        syncWindow = self.token.getSyncWindow()
        #log.debug("serial: %s",serialNum)
        hmac2Otp = HmacOtp(secretHOtp, counter, otplen,
                           self.getHashlib(self.hashlibStr))
        counter = hmac2Otp.checkOtp(otp1, syncWindow)

        if counter == -1:
            log.debug("[resync] exit. First counter (-1) not found  ret: %r" %
                      (ret))
            return ret

        nextOtp = hmac2Otp.generate(counter + 1)

        if nextOtp != otp2:
            log.debug(
                "[resync] exit. Failed to verify second otp: nextOtp: %r != otp2: %r ret: %r"
                % (nextOtp, otp2, ret))
            return ret

        ret = True
        self.incOtpCounter(counter + 1, True)

        log.debug("[resync] end. resync was successful: ret: %r" % (ret))
        return ret
Пример #3
0
    def checkOtp(self, anOtpVal, counter, window, options=None):
        '''
        checkOtp - validate the token otp against a given otpvalue

        :param anOtpVal: the to be verified otpvalue
        :type anOtpVal:  string

        :param counter: the counter state, that should be verified
        :type counter: int

        :param window: the counter +window, which should be checked
        :type window: int

        :param options: the dict, which could contain token specific info
        :type options: dict

        :return: the counter state or -1
        :rtype: int

        '''
        log.debug(
            "[checkOtp] begin. Validate the token otp: anOtpVal: %r ,counter: %r,window: %r, options: %r "
            % (anOtpVal, counter, window, options))
        res = -1

        try:
            otplen = int(self.getOtpLen())
        except ValueError as ex:
            log.exception(
                '[checkOtp] failed to initialize otplen: ValueError %r %r' %
                (ex, self.token.LinOtpOtpLen))
            raise Exception(ex)

        try:
            self.hashlibStr = self.getFromTokenInfo("hashlib", 'sha1')
        except Exception as ex:
            log.exception('[checkOtp] failed to initialize hashlibStr: %r' %
                          (ex))
            raise Exception(ex)

        secretHOtp = self.token.getHOtpKey()
        #serialNum   = self.token.LinOtpTokenSerialnumber
        #log.debug("serial: %s",serialNum)

        hmac2Otp = HmacOtp(secretHOtp, counter, otplen,
                           self.getHashlib(self.hashlibStr))
        res = hmac2Otp.checkOtp(anOtpVal, window)

        if -1 == res:
            res = self.autosync(hmac2Otp, anOtpVal)

        log.debug("[checkOtp] end. otp verification result was: res %r" %
                  (res))
        return res
Пример #4
0
    def resync(self, otp1, otp2, options=None):
        '''
        resync the token based on two otp values
        - external method to do the resync of the token

        :param otp1: the first otp value
        :type otp1: string

        :param otp2: the second otp value
        :type otp2: string

        :param options: optional token specific parameters
        :type options:  dict or None

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

        '''
        log.debug("[resync] .begin. Resync the token based on: %r, anOtpVal: %r, options: %r" % (otp1, otp2, options))

        ret = False

        try:
            otplen = int(self.token.LinOtpOtpLen)
        except ValueError as ex:
            log.debug("[resync] otplen ValueError: %r ret: %r " % (ex, ret))
            raise Exception(ex)

        self.hashlibStr = self.getFromTokenInfo("hashlib", 'sha1')

        secretHOtp = self.token.getHOtpKey()
        counter = self.token.getOtpCounter()
        syncWindow = self.token.getSyncWindow()
        #log.debug("serial: %s",serialNum)
        hmac2Otp = HmacOtp(secretHOtp, counter, otplen, self.getHashlib(self.hashlibStr))
        counter = hmac2Otp.checkOtp(otp1, syncWindow)

        if counter == -1:
            log.debug("[resync] exit. First counter (-1) not found  ret: %r" % (ret))
            return ret

        nextOtp = hmac2Otp.generate(counter + 1)

        if nextOtp != otp2:
            log.debug("[resync] exit. Failed to verify second otp: nextOtp: %r != otp2: %r ret: %r" % (nextOtp, otp2, ret))
            return ret

        ret = True
        self.incOtpCounter(counter + 1, True)

        log.debug("[resync] end. resync was successful: ret: %r" % (ret))
        return ret
Пример #5
0
    def check_otp_exist(self, otp, window=10, user=None, autoassign=False):
        """
        checks if the given OTP value is/are values of this very token.
        This is used to autoassign and to determine the serial number of
        a token.

        :param otp: the to be verified otp value
        :type otp: string

        :param window: the lookahead window for the counter
        :type window: int

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

        """

        res = -1

        try:
            otplen = int(self.token.LinOtpOtpLen)
            counter = int(self.token.LinOtpCount)
        except ValueError as ex:
            log.warning(
                "[check_otp_exist] a value error occurred while converting: "
                "otplen %r, counter %r : ValueError: %r ret: %r ",
                self.token.LinOtpOtpLen,
                self.token.LinOtpCount,
                ex,
                res,
            )
            return res

        self.hashlibStr = self.getFromTokenInfo("hashlib", "sha1")

        secObj = self._get_secret_object()
        hmac2Otp = HmacOtp(secObj, counter, otplen,
                           self.getHashlib(self.hashlibStr))
        res = hmac2Otp.checkOtp(otp, window)

        if res >= 0:

            # As usually the counter is increased in auth.validate.checkUserPass, we
            # need to do this manually here:
            self.incOtpCounter(res)
        if res == -1:
            msg = "otp counter %r was not found" % otp
        else:
            msg = "otp counter %r was found" % otp
        return res
Пример #6
0
    def checkOtp(self, anOtpVal, counter, window, options=None):
        '''
        checkOtp - validate the token otp against a given otpvalue

        :param anOtpVal: the to be verified otpvalue
        :type anOtpVal:  string

        :param counter: the counter state, that should be verified
        :type counter: int

        :param window: the counter +window, which should be checked
        :type window: int

        :param options: the dict, which could contain token specific info
        :type options: dict

        :return: the counter state or -1
        :rtype: int

        '''
        log.debug("[checkOtp] begin. Validate the token otp: anOtpVal: %r ,counter: %r,window: %r, options: %r " % (anOtpVal, counter, window, options))
        res = -1

        try:
            otplen = int(self.getOtpLen())
        except ValueError as ex:
            log.exception('[checkOtp] failed to initialize otplen: ValueError %r %r' % (ex, self.token.LinOtpOtpLen))
            raise Exception(ex)

        try:
            self.hashlibStr = self.getFromTokenInfo("hashlib", 'sha1')
        except Exception as ex:
            log.exception('[checkOtp] failed to initialize hashlibStr: %r' % (ex))
            raise Exception(ex)

        secretHOtp = self.token.getHOtpKey()
        #serialNum   = self.token.LinOtpTokenSerialnumber
        #log.debug("serial: %s",serialNum)

        hmac2Otp = HmacOtp(secretHOtp, counter, otplen,
                           self.getHashlib(self.hashlibStr))
        res = hmac2Otp.checkOtp(anOtpVal, window)

        if -1 == res:
            res = self.autosync(hmac2Otp, anOtpVal)

        log.debug("[checkOtp] end. otp verification result was: res %r" % (res))
        return res
Пример #7
0
    def checkOtp(self, anOtpVal, counter, window, options=None):
        """
        checkOtp - validate the token otp against a given otpvalue

        :param anOtpVal: the to be verified otpvalue
        :type anOtpVal:  string

        :param counter: the counter state, that should be verified
        :type counter: int

        :param window: the counter +window, which should be checked
        :type window: int

        :param options: the dict, which could contain token specific info
        :type options: dict

        :return: the counter state or -1
        :rtype: int

        """
        res = -1

        try:
            otplen = int(self.getOtpLen())
        except ValueError as ex:
            log.error(
                "[checkOtp] failed to initialize otplen: ValueError %r %r",
                ex,
                self.token.LinOtpOtpLen,
            )
            raise

        try:
            self.hashlibStr = self.getFromTokenInfo("hashlib", "sha1")
        except Exception as ex:
            log.error("[checkOtp] failed to initialize hashlibStr: %r", ex)
            raise

        secObj = self._get_secret_object()

        hmac2Otp = HmacOtp(secObj, counter, otplen,
                           self.getHashlib(self.hashlibStr))
        res = hmac2Otp.checkOtp(anOtpVal, window)

        if -1 == res:
            res = self.autosync(hmac2Otp, anOtpVal)

        return res
Пример #8
0
    def check_otp_exist(self, otp, window=10):
        '''
        checks if the given OTP value is/are values of this very token.
        This is used to autoassign and to determine the serial number of
        a token.

        :param otp: the to be verified otp value
        :type otp: string

        :param window: the lookahead window for the counter
        :type window: int

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

        '''

        log.debug(
            "[check_otp_exist] begin. checks if the given OTP value exists: otp %r, window %r "
            % (otp, window))
        res = -1

        try:
            otplen = int(self.token.LinOtpOtpLen)
            counter = int(self.token.LinOtpCount)
        except ValueError as ex:
            log.warning(
                "[check_otp_exist] a value error occurred while converting: otplen %r, counter %r : ValueError: %r ret: %r "
                % (self.token.LinOtpOtpLen, self.token.LinOtpCount, ex, res))
            return res

        self.hashlibStr = self.getFromTokenInfo("hashlib", "sha1")

        secretHOtp = self.token.getHOtpKey()
        hmac2Otp = HmacOtp(secretHOtp, counter, otplen,
                           self.getHashlib(self.hashlibStr))
        res = hmac2Otp.checkOtp(otp, window)

        if res >= 0:
            # As usually the counter is increased in lib.token.checkUserPass, we
            # need to do this manually here:
            self.incOtpCounter(res)
        if res == -1:
            msg = "otp counter %r was not found" % otp
        else:
            msg = "otp counter %r was found" % otp
        log.debug("[check_otp_exist] end. %r: res %r" % (msg, res))
        return res
Пример #9
0
    def check_otp_exist(self, otp, window=10, user=None, autoassign=False):
        '''
        checks if the given OTP value is/are values of this very token.
        This is used to autoassign and to determine the serial number of
        a token.

        :param otp: the to be verified otp value
        :type otp: string

        :param window: the lookahead window for the counter
        :type window: int

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

        '''

        log.debug("[check_otp_exist] begin. checks if the given OTP value exists: otp %r, window %r " %
                  (otp, window))
        res = -1

        try:
            otplen = int(self.token.LinOtpOtpLen)
            counter = int(self.token.LinOtpCount)
        except ValueError as ex:
            log.warning("[check_otp_exist] a value error occurred while converting: otplen %r, counter %r : ValueError: %r ret: %r "
                      % (self.token.LinOtpOtpLen, self.token.LinOtpCount, ex, res))
            return res

        self.hashlibStr = self.getFromTokenInfo("hashlib", "sha1")

        secObj = self._get_secret_object()
        hmac2Otp = HmacOtp(secObj, counter, otplen,
                           self.getHashlib(self.hashlibStr))
        res = hmac2Otp.checkOtp(otp, window)

        if res >= 0:

            # As usually the counter is increased in auth.validate.checkUserPass, we
            # need to do this manually here:
            self.incOtpCounter(res)
        if res == -1:
            msg = "otp counter %r was not found" % otp
        else:
            msg = "otp counter %r was found" % otp
        log.debug("[check_otp_exist] end. %r: res %r" % (msg, res))
        return res
Пример #10
0
    def resync(self, otp1, otp2, options=None):
        '''
        resync the token based on two otp values
        - external method to do the resync of the token

        :param otp1: the first otp value
        :type otp1: string

        :param otp2: the second otp value
        :type otp2: string

        :param options: optional token specific parameters
        :type options:  dict or None

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

        '''

        ret = False

        try:
            otplen = int(self.token.LinOtpOtpLen)
        except ValueError:
            return ret

        secObj = self._get_secret_object()

        self.hashlibStr = self.getFromTokenInfo("hashlib", 'sha1')
        timeStepping = int(self.getFromTokenInfo("timeStep", 30))
        shift = int(self.getFromTokenInfo("timeShift", 0))

        try:
            window = int(self.token.LinOtpSyncWindow) * timeStepping
        except:
            window = 10 * timeStepping

        log.debug("[resync] timestep: %r, syncWindow: %r, timeShift: %r" %
                  (timeStepping, window, shift))

        T0 = time.time() + shift

        log.debug("[resync] T0 : %i" % T0)
        counter = int((T0 / timeStepping) +
                      0.5)  # T = (Current Unix time - T0) / timeStepping
        log.debug("[resync] counter (current time): %i" % counter)

        oCount = self.getOtpCount()

        log.debug("[resync] tokenCounter: %r" % oCount)
        log.debug("[resync] now checking window %s, timeStepping %s" %
                  (window, timeStepping))
        # check 2nd value
        hmac2Otp = HmacOtp(secObj, counter, otplen,
                           self.getHashlib(self.hashlibStr))
        log.debug("[resync] %s in otpkey: %s " % (otp2, secObj))
        res2 = hmac2Otp.checkOtp(otp2,
                                 int(window / timeStepping),
                                 symetric=True)  #TEST -remove the 10
        log.debug("[resync] res 2: %r" % res2)
        # check 1st value
        hmac2Otp = HmacOtp(secObj, counter - 1, otplen,
                           self.getHashlib(self.hashlibStr))
        log.debug("[resync] %s in otpkey: %s " % (otp1, secObj))
        res1 = hmac2Otp.checkOtp(otp1,
                                 int(window / timeStepping),
                                 symetric=True)  #TEST -remove the 10
        log.debug("[resync] res 1: %r" % res1)

        if res1 < oCount:
            # A previous OTP value was used again!
            log.warning(
                "[resync] a previous OTP value was used again! tokencounter: %i, presented counter %i"
                % (oCount, res1))
            res1 = -1

        if res1 != -1 and res1 + 1 == res2:
            # here we calculate the new drift/shift between the server time and the tokentime
            tokentime = (res2 + 0.5) * timeStepping
            currenttime = T0 - shift
            new_shift = (tokentime - currenttime)
            log.debug(
                "[resync] the counters %r and %r matched. New shift: %r" %
                (res1, res2, new_shift))
            self.addToTokenInfo('timeShift', new_shift)

            # The OTP value that was used for resync must not be used again!
            self.setOtpCount(res2 + 1)

            ret = True

        if ret is True:
            msg = "resync was successful"
        else:
            msg = "resync was not successful"

        log.debug(msg)
        return ret
Пример #11
0
    def checkOtp(self, anOtpVal, counter, window, options=None):
        '''
        checkOtp - validate the token otp against a given otpvalue

        :param anOtpVal: the to be verified otpvalue
        @type anOtpVal:  string

        :param counter: the counter state, that should be verified
        :type counter: int

        :param window: the counter +window, which should be checked
        :type window: int

        :param options: the dict, which could contain token specific info
        :type options: dict

        :return: the counter state or -1
        :rtype: int

        '''

        try:
            otplen = int(self.token.LinOtpOtpLen)
        except ValueError as e:
            raise e

        secObj = self._get_secret_object()
        self.hashlibStr = self.getFromTokenInfo("hashlib",
                                                self.hashlibStr) or 'sha1'

        timeStepping = int(
            self.getFromTokenInfo("timeStep", self.timeStep) or 30)
        window = int(
            self.getFromTokenInfo("timeWindow", self.timeWindow) or 180)
        shift = int(self.getFromTokenInfo("timeShift", self.timeShift) or 0)

        ## oldCounter we have to remove one, as the normal otp handling will increment
        oCount = self.getOtpCount() - 1

        initTime = -1
        if options is not None and type(options) == dict:
            initTime = int(options.get('initTime', -1))

        if oCount < 0: oCount = 0
        log.debug("[checkOTP] timestep: %i, timeWindow: %i, timeShift: %i" %
                  (timeStepping, window, shift))
        inow = int(time.time())

        T0 = time.time() + shift
        if initTime != -1: T0 = int(initTime)

        counter = self._time2counter_(T0, timeStepping=timeStepping)

        hmac2Otp = HmacOtp(secObj, counter, otplen,
                           self.getHashlib(self.hashlibStr))
        res = hmac2Otp.checkOtp(anOtpVal,
                                int(window / timeStepping),
                                symetric=True)

        if res != -1 and oCount != 0 and res <= oCount:
            if initTime == -1:
                log.warning(
                    "[checkOTP] a previous OTP value was used again!\n former tokencounter: %i, presented counter %i"
                    % (oCount, res))
                res = -1
                return res

        if -1 == res:
            ## autosync: test if two consecutive otps have been provided
            res = self.autosync(hmac2Otp, anOtpVal)

        if res != -1:
            ## on success, we have to save the last attempt
            self.setOtpCount(counter)

            #
            # here we calculate the new drift/shift between the server time and the tokentime
            #
            tokentime = self._counter2time_(res, timeStepping)
            tokenDt = datetime.datetime.fromtimestamp(tokentime / 1.0)

            nowDt = datetime.datetime.fromtimestamp(inow / 1.0)

            # reverse time mapping:
            # from time to counter to timeStepping mapped timeslot

            lastauth = self._counter2time_(oCount, timeStepping)
            lastauthDt = datetime.datetime.fromtimestamp(lastauth / 1.0)

            log.debug("[checkOTP] last auth : %r" % (lastauthDt))
            log.debug("[checkOTP] tokentime : %r" % (tokenDt))
            log.debug("[checkOTP] now       : %r" % (nowDt))
            log.debug("[checkOTP] delta     : %r" % (tokentime - inow))

            inow_counter = self._time2counter_(inow, timeStepping)
            inow_token_time = self._counter2time_(inow_counter, timeStepping)

            new_shift = (tokentime - inow_token_time)

            log.debug("[checkOTP] the counter %r matched. New shift: %r" %
                      (res, new_shift))

            self.addToTokenInfo('timeShift', new_shift)

        log.debug("[checkOtp] end. otp verification result was: res %r" %
                  (res))
        return res
Пример #12
0
    def resync(self, otp1, otp2, options=None):
        '''
        resync the token based on two otp values
        - external method to do the resync of the token

        :param otp1: the first otp value
        :type otp1: string

        :param otp2: the second otp value
        :type otp2: string

        :param options: optional token specific parameters
        :type options:  dict or None

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

        '''
        log.debug("[resync] .begin. Resync the token based on: %r, anOtpVal: %r, options: %r" % (otp1, otp2, options))

        ret = False

        try:
            otplen = int(self.token.LinOtpOtpLen)
        except ValueError:
            return ret


        secretHOtp = self.token.getHOtpKey()

        self.hashlibStr = self.getFromTokenInfo("hashlib", 'sha1')
        timeStepping = int(self.getFromTokenInfo("timeStep", 30))
        shift = int(self.getFromTokenInfo("timeShift", 0))

        try:
            window = int(self.token.LinOtpSyncWindow) * timeStepping
        except:
            window = 10 * timeStepping

        log.debug("[resync] timestep: %r, syncWindow: %r, timeShift: %r"
                  % (timeStepping, window, shift))


        T0 = time.time() + shift

        log.debug("[resync] T0 : %i" % T0)
        counter = int((T0 / timeStepping) + 0.5)  # T = (Current Unix time - T0) / timeStepping
        log.debug("[resync] counter (current time): %i" % counter)

        oCount = self.getOtpCount()

        log.debug("[resync] tokenCounter: %r" % oCount)
        log.debug("[resync] now checking window %s, timeStepping %s" % (window, timeStepping))
        # check 2nd value
        hmac2Otp = HmacOtp(secretHOtp, counter, otplen, self.getHashlib(self.hashlibStr))
        log.debug("[resync] %s in otpkey: %s " % (otp2, secretHOtp))
        res2 = hmac2Otp.checkOtp(otp2, int (window / timeStepping), symetric=True)  #TEST -remove the 10
        log.debug("[resync] res 2: %r" % res2)
        # check 1st value
        hmac2Otp = HmacOtp(secretHOtp, counter - 1, otplen, self.getHashlib(self.hashlibStr))
        log.debug("[resync] %s in otpkey: %s " % (otp1, secretHOtp))
        res1 = hmac2Otp.checkOtp(otp1, int (window / timeStepping), symetric=True)  #TEST -remove the 10
        log.debug("[resync] res 1: %r" % res1)

        if res1 < oCount:
            # A previous OTP value was used again!
            log.warning("[resync] a previous OTP value was used again! tokencounter: %i, presented counter %i" %
                        (oCount, res1))
            res1 = -1

        if res1 != -1 and res1 + 1 == res2:
            # here we calculate the new drift/shift between the server time and the tokentime
            tokentime = (res2 + 0.5) * timeStepping
            currenttime = T0 - shift
            new_shift = (tokentime - currenttime)
            log.debug("[resync] the counters %r and %r matched. New shift: %r"
                       % (res1, res2, new_shift))
            self.addToTokenInfo('timeShift', new_shift)

            # The OTP value that was used for resync must not be used again!
            self.setOtpCount(res2 + 1)

            ret = True

        if ret == True:
            msg = "resync was successful"
        else:
            msg = "resync was not successful"

        log.debug("[resync] end. %s: ret: %r" % (msg, ret))
        return ret
Пример #13
0
    def checkOtp(self, anOtpVal, counter, window, options=None):
        '''
        checkOtp - validate the token otp against a given otpvalue

        :param anOtpVal: the to be verified otpvalue
        @type anOtpVal:  string

        :param counter: the counter state, that should be verified
        :type counter: int

        :param window: the counter +window, which should be checked
        :type window: int

        :param options: the dict, which could contain token specific info
        :type options: dict

        :return: the counter state or -1
        :rtype: int

        '''

        log.debug("[checkOtp] begin. Validate the token otp: anOtpVal: %r ,\
                    counter: %r,window: %r, options: %r " %
                    (anOtpVal, counter, window, options))

        try:
            otplen = int(self.token.LinOtpOtpLen)
        except ValueError as e:
            raise e

        secretHOtp = self.token.getHOtpKey()
        self.hashlibStr = self.getFromTokenInfo("hashlib", self.hashlibStr)

        timeStepping = int(self.getFromTokenInfo("timeStep", self.timeStep))
        window = int(self.getFromTokenInfo("timeWindow", self.timeWindow))
        shift = int(self.getFromTokenInfo("timeShift", self.timeShift))

        ## oldCounter we have to remove one, as the normal otp handling will increment
        oCount = self.getOtpCount() - 1

        initTime = -1
        if options != None and type(options) == dict:
            initTime = int(options.get('initTime', -1))

        if oCount < 0: oCount = 0
        log.debug("[checkOTP] timestep: %i, timeWindow: %i, timeShift: %i" %
                  (timeStepping, window, shift))
        inow = int(time.time())

        T0 = time.time() + shift
        if initTime != -1: T0 = int(initTime)


        log.debug("[checkOTP] T0 : %i" % T0)
        counter = self._time2counter_(T0, timeStepping=timeStepping)


        otime = self._getTimeFromCounter(oCount, timeStepping=timeStepping)
        ttime = self._getTimeFromCounter(counter, timeStepping=timeStepping)

        log.debug("[checkOTP] last log: %r :: %r" % (oCount, otime))
        log.debug("[checkOTP] counter : %r :: %r <==> %r" %
                  (counter, ttime, datetime.datetime.now()))


        log.debug("[checkOTP] shift   : %r " % (shift))

        hmac2Otp = HmacOtp(secretHOtp, counter, otplen, self.getHashlib(self.hashlibStr))
        res = hmac2Otp.checkOtp(anOtpVal, int (window / timeStepping), symetric=True)

        log.debug("[checkOTP] comparing the result %i to the old counter %i." % (res, oCount))
        if res != -1 and oCount != 0 and res <= oCount:
            if initTime == -1:
                log.warning("[checkOTP] a previous OTP value was used again!\n former tokencounter: %i, presented counter %i" %
                        (oCount, res))
                res = -1
                return res

        if -1 == res :
            ## autosync: test if two consecutive otps have been provided
            res = self.autosync(hmac2Otp, anOtpVal)


        if res != -1:
            ## on success, we have to save the last attempt
            self.setOtpCount(counter)

            #
            # here we calculate the new drift/shift between the server time and the tokentime
            #
            tokentime = self._counter2time_(res, timeStepping)
            tokenDt = datetime.datetime.fromtimestamp(tokentime / 1.0)

            nowDt = datetime.datetime.fromtimestamp(inow / 1.0)

            lastauth = self._counter2time_(oCount, timeStepping)
            lastauthDt = datetime.datetime.fromtimestamp(lastauth / 1.0)

            log.debug("[checkOTP] last auth : %r" % (lastauthDt))
            log.debug("[checkOTP] tokentime : %r" % (tokenDt))
            log.debug("[checkOTP] now       : %r" % (nowDt))
            log.debug("[checkOTP] delta     : %r" % (tokentime - inow))

            new_shift = (tokentime - inow)
            log.debug("[checkOTP] the counter %r matched. New shift: %r" %
                      (res, new_shift))
            self.addToTokenInfo('timeShift', new_shift)

        log.debug("[checkOtp] end. otp verification result was: res %r" % (res))
        return res
Пример #14
0
    def get_otp_detail(self, otp, window='24h'):
        """
        provide information belonging to one otp

        :param otp: the otp for which the timestamp is searched
        :param window: string, in human readable '2h' or iso8601 format 'PT2H'
        """

        from linotp.lib.type_utils import parse_duration
        window = parse_duration(window).total_seconds()

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

        time_step = self.timeStepping

        T0 = time.time() + self.shift
        counter = time2counter(T0, timeStepping=time_step)

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

        # prepare the hmac operation

        secObj = self._get_secret_object()
        hmac2Otp = HmacOtp(
            secObj, counter, self.otplen, self.getHashlib(self.hashlibStr))
        matching_counter = hmac2Otp.checkOtp(
                                otp, int(window // time_step), symetric=True)


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

        # matching_counter =-1 : no otp found in the current time frame

        if matching_counter == -1:
            log.info('no matching otp found in window: %r', window)
            return False, None

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

        # do not provide information of otps in the future

        if matching_counter >= counter:
            log.info('otp is in future - no info for future otps')
            return False, None


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

        # all fine - now return the time stamp and the utc time format

        time_stamp = counter2time(
            matching_counter, timeStepping=time_step)

        time_info = datetime.datetime.utcfromtimestamp(time_stamp)

        return True, {
            'serial' : self.getSerial(),
            'otp': otp,
            'counter': matching_counter,
            'time': time_info.isoformat(),
            'seconds': int(time_stamp),
            'span': time_step,
        }
Пример #15
0
    def checkOtp(self, anOtpVal, counter, window, options=None):
        '''
        checkOtp - validate the token otp against a given otpvalue

        :param anOtpVal: the to be verified otpvalue
        @type anOtpVal:  string

        :param counter: the counter state, that should be verified
        :type counter: int

        :param window: the counter +window, which should be checked
        :type window: int

        :param options: the dict, which could contain token specific info
        :type options: dict

        :return: the counter state or -1
        :rtype: int

        '''

        # convert the window counter into seconds
        totp_window = window * self.timeStepping

        T0 = time.time() + self.shift

        counter = time2counter(T0, timeStepping=self.timeStepping)

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

        # setup the hmac object, which encapsulates the secret context

        secObj = self._get_secret_object()
        hmac2Otp = HmacOtp(
            secObj, counter, self.otplen, self.getHashlib(self.hashlibStr))

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

        otp_match_counter = hmac2Otp.checkOtp(
            anOtpVal, int(totp_window // self.timeStepping), symetric=True)

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

        # 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
        # as it might be replay

        if otp_match_counter != -1 and otp_match_counter < self.getOtpCount():
            log.warning("a previous OTP value was used again!")
            return -1

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

        # the otp might be out of the test window so we try to autosync:
        # look if two consecutive otps has been provided

        if otp_match_counter == -1:
            otp_match_counter = self.autosync(hmac2Otp, anOtpVal)

        if otp_match_counter == -1:
            log.debug("otp verification failed!")
            return -1

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

        # on success, we have to save the timeshift and matching otp counter
        self.set_new_timeshift(otp_match_counter)

        # and the matching otp counter
        self.setOtpCount(otp_match_counter)

        log.debug("otp verification result was: res %r", otp_match_counter)
        return otp_match_counter
Пример #16
0
    def checkOtp(self, anOtpVal, counter, window, options=None, pin=None):
        '''
        checkOtp - validate the token otp against a given otpvalue

        :param anOtpVal: the to be verified otpvalue
        @type anOtpVal:  string

        :param counter: the counter state, that should be verified
        :type counter: int

        :param window: the counter +window, which should be checked
        :type window: int

        :param options: the dict, which could contain token specific info
        :type options: dict

        :return: the counter state or -1
        :rtype: int

        '''

        log.debug("[checkOtp] begin. Validate the token otp: anOtpVal: %r ,\
                    counter: %r,window: %r, options: %r " %
                  (anOtpVal, counter, window, options))

        try:
            otplen = int(self.token.LinOtpOtpLen)
        except ValueError as e:
            raise e

        secretHOtp = self.token.getHOtpKey(pin)
        self.hashlibStr = self.getFromTokenInfo("hashlib", self.hashlibStr)

        timeStepping = int(self.getFromTokenInfo("timeStep", self.timeStep))
        window = int(self.getFromTokenInfo("timeWindow", self.timeWindow))
        shift = int(self.getFromTokenInfo("timeShift", self.timeShift))

        ## oldCounter we have to remove one, as the normal otp handling will increment
        oCount = self.getOtpCount() - 1

        initTime = -1
        if options != None and type(options) == dict:
            initTime = int(options.get('initTime', -1))

        if oCount < 0: oCount = 0
        log.debug("[checkOTP] timestep: %i, timeWindow: %i, timeShift: %i" %
                  (timeStepping, window, shift))
        inow = int(time.time())

        T0 = time.time() + shift
        if initTime != -1: T0 = int(initTime)

        log.debug("[checkOTP] T0 : %i" % T0)
        counter = self._time2counter_(T0, timeStepping=timeStepping)

        otime = self._getTimeFromCounter(oCount, timeStepping=timeStepping)
        ttime = self._getTimeFromCounter(counter, timeStepping=timeStepping)

        log.debug("[checkOTP] last log: %r :: %r" % (oCount, otime))
        log.debug("[checkOTP] counter : %r :: %r <==> %r" %
                  (counter, ttime, datetime.datetime.now()))

        log.debug("[checkOTP] shift   : %r " % (shift))

        hmac2Otp = HmacOtp(secretHOtp, counter, otplen,
                           self.getHashlib(self.hashlibStr))

        log.debug("got hmac")
        res = hmac2Otp.checkOtp(anOtpVal,
                                int(window / timeStepping),
                                symetric=True)

        log.warning(
            "[checkOTP] comparing the result %i to the old counter %i." %
            (res, oCount))
        if res != -1 and oCount != 0 and res <= oCount:
            if initTime == -1:
                log.warning(
                    "[checkOTP] a previous OTP value was used again!\n former tokencounter: %i, presented counter %i"
                    % (oCount, res))
                res = -2  # return something different so we can tell them their code is being reused
                return res

        if -1 == res:
            ## autosync: test if two consecutive otps have been provided
            res = self.autosync(hmac2Otp, anOtpVal)

        if res != -1:
            ## on success, we have to save the last attempt
            self.setOtpCount(counter)

            #
            # here we calculate the new drift/shift between the server time and the tokentime
            #
            tokentime = self._counter2time_(res, timeStepping)
            tokenDt = datetime.datetime.fromtimestamp(tokentime / 1.0)

            nowDt = datetime.datetime.fromtimestamp(inow / 1.0)

            lastauth = self._counter2time_(oCount, timeStepping)
            lastauthDt = datetime.datetime.fromtimestamp(lastauth / 1.0)

            log.debug("[checkOTP] last auth : %r" % (lastauthDt))
            log.debug("[checkOTP] tokentime : %r" % (tokenDt))
            log.debug("[checkOTP] now       : %r" % (nowDt))
            log.debug("[checkOTP] delta     : %r" % (tokentime - inow))

            new_shift = (tokentime - inow)
            log.debug("[checkOTP] the counter %r matched. New shift: %r" %
                      (res, new_shift))
            self.addToTokenInfo('timeShift', new_shift)

        log.debug("[checkOtp] end. otp verification result was: res %r" %
                  (res))
        return res