def update(self, param, reset_failcount=True): ''' update - process the initialization parameters :param param: dict of initialization parameters :type param: dict :return: nothing ''' # Remark: the otpKey is handled in the parent class self.hashlibStr = param.get("hashlib", 'sha1') # check if the key_size id provided # if not, we could derive it from the hashlib key_size = param.get('key_size') if not key_size and self.hashlibStr in keylen: key_size = keylen.get(self.hashlibStr) param['key_size'] = key_size param['hashlib'] = self.hashlibStr self.addToTokenInfo("hashlib", self.hashlibStr) TokenClass.update(self, param, reset_failcount) return
def __init__(self, aToken): ''' constructor - create a token object :param aToken: instance of the orm db object :type aToken: orm object ''' TokenClass.__init__(self, aToken) self.setType(u"TOTP") self.hKeyRequired = True ''' timeStep defines the granularity: ''' self.timeStep = getFromConfig("totp.timeStep", 30) or 30 ''' window size in seconds: 30 seconds with as step width of 30 seconds results in a window of 1 which is one attempt ''' self.timeWindow = getFromConfig("totp.timeWindow", 180) or 180 '''the time shift is specified in seconds - and could be positive and negative ''' self.timeShift = getFromConfig("totp.timeShift", 0) '''we support various hashlib methods, but only on create which is effectively set in the update ''' self.hashlibStr = getFromConfig("totp.hashlib", u'sha1') or 'sha1' return
def update(self, param, reset_failcount=True): ''' update - process the initialization parameters :param param: dict of initialization parameters :type param: dict :return: nothing ''' # we use the public_uid to calculate the otplen which is at 48 or 32 # the public_uid is stored and used in validation if 'public_uid' in param: otplen = 32 + len(param['public_uid']) else: otplen = 48 if 'otplen' not in param: param['otplen'] = otplen TokenClass.update(self, param, reset_failcount) if 'public_uid' in param: self.addToTokenInfo('public_uid', param['public_uid']) return
def update(self, param): try: self.radiusServer = param["radius.server"] except KeyError: raise ParameterError("Missing parameter: 'radius.server'") # if another OTP length would be specified in /admin/init this would # be overwritten by the parent class, which is ok. self.setOtpLen(6) val = param.get("radius.local_checkpin") if val is not None: self.radiusLocal_checkpin = val try: self.radiusUser = param["radius.user"] except KeyError: raise ParameterError("Missing parameter: 'radius.user'") try: self.radiusSecret = param["radius.secret"] except KeyError: raise ParameterError("Missing parameter: 'radius.secret'") if self.radiusSecret == VOID_RADIUS_SECRET: log.warning("Usage of default radius secret is not recomended!!") TokenClass.update(self, param) # We need to write the secret! self.setOtpKey(binascii.hexlify(self.radiusSecret)) self.addToTokenInfo("radius.server", self.radiusServer) self.addToTokenInfo("radius.local_checkpin", self.radiusLocal_checkpin) self.addToTokenInfo("radius.user", self.radiusUser)
def update(self, param, reset_failcount=True): ''' update - process initialization parameters :param param: dict of initialization parameters :type param: dict :return: nothing ''' if 'otpkey' not in param: raise ParameterError("Missing parameter: 'otpkey'") # motp token specific try: otpPin = param['otppin'] except KeyError: raise ParameterError("Missing parameter: 'otppin'") self.setUserPin(otpPin) TokenClass.update(self, param, reset_failcount) return
def update(self, param, reset_failcount=True): """ update - process the initialization parameters :param param: dict of initialization parameters :type param: dict :return: nothing """ # we use the public_uid to calculate the otplen which is at 48 or 32 # the public_uid is stored and used in validation if "public_uid" in param: otplen = 32 + len(param["public_uid"]) else: otplen = 48 if "otplen" not in param: param["otplen"] = otplen TokenClass.update(self, param, reset_failcount) if "public_uid" in param: self.addToTokenInfo("public_uid", param["public_uid"]) return
def update(self, param): TokenClass.update(self, param) # The otplen is determined by the otpkey. So we # call the setOtpLen after the parents update, to overwrite # specified OTP lengths with the length of the password self.setOtpLen(0)
def update(self, param, reset_failcount=False): self.setSyncWindow(0) self.setOtpLen(32) self.setCounterWindow(0) tdesc = param.get("description") if tdesc is not None: self.token.setDescription(tdesc) # requested_phase must be either "registration1" or "registration2" # current_phase is either "registration" or "authentication" requested_phase = param.get("phase") current_phase = self.getFromTokenInfo("phase", None) if requested_phase == "registration1" and current_phase is None: # This initial registration phase triggers a challenge # which is sent to the FIDO U2F compatible client device # Set the optional token pin in this first phase pin = param.get("pin") if pin is not None: TokenClass.setPin(self, pin) # preserve the registration state self.addToTokenInfo("phase", "registration") self.token.LinOtpIsactive = False elif ( requested_phase == "registration2" and current_phase == "registration" ): # Check the token pin pin = param.get("pin") if pin is None: pin = "" if check_pin(self, pin) is False: raise ValueError("Wrong token pin!") # check for set phases which are not "registration1" or "registration2" elif ( requested_phase != "registration2" and requested_phase is not None ): raise Exception("Wrong phase parameter!") # only allow empty phase parameters once the token is registered # successfully elif current_phase != "authentication" and requested_phase is None: raise Exception("Wrong phase parameter!") # only allow "registration2" if the token already completed # "registration1" elif ( current_phase != "registration" and requested_phase == "registration2" ): raise Exception( "Phase 'registration2' requested but we are not in the correct phase \ to process the request." ) else: raise Exception( 'Unknown "phase" and "current_phase" parameter combination!' )
def update(self, param): # check for the required parameters if (self.hKeyRequired is True): if "otpkey" not in param: raise ParameterError("Missing parameter: 'otpkey'", id=905) TokenClass.update(self, param)
def __init__(self, aToken): """ constructor - create a token object :param aToken: instance of the orm db object :type aToken: orm object """ TokenClass.__init__(self, aToken) self.setType("TOTP") self.hKeyRequired = True # timeStep defines the granularity: self._timeStep = getFromConfig("totp.timeStep", 30) or 30 # window size in seconds: # 30 seconds with as step width of 30 seconds results # in a window of 1 which is one attempt self.timeWindow = getFromConfig("totp.timeWindow", 180) or 180 # the time shift is specified in seconds - and could be # positive and negative self.timeShift = getFromConfig("totp.timeShift", 0) # we support various hashlib methods, but only on create # which is effectively set in the update self.hashlibStr = getFromConfig("totp.hashlib", "sha1") or "sha1" self.otplen = int(self.token.LinOtpOtpLen) # ------------------------------------------------------------------ -- # load token settings from the token info if available info = self.getTokenInfo() if info: self.hashlibStr = info.get("hashlib", self.hashlibStr) or "sha1" self.timeStepping = int(info.get("timeStep", self._timeStep) or 30) self.window = int(info.get("timeWindow", self.timeWindow) or 180) self.shift = int(info.get("timeShift", self.timeShift) or 0) log.debug( "[checkOTP] timestep: %i, timeWindow: %i, timeShift: %i", self.timeStepping, self.window, self.shift, ) return
def setOtpLen(self, otplen): ''' sets the OTP length to the length of the password ''' secObj = self._get_secret_object() sp = PasswordTokenClass.__secretPassword__(secObj) pw_len = len(sp.getPassword()) TokenClass.setOtpLen(self, pw_len) return
def update(self, param): if 'otpkey' not in param: param['genkey'] = 1 # mark this spass token as usable exactly once if 'onetime' in param: self.count_auth_success_max = 1 TokenClass.update(self, param)
def __init__(self, aToken): ''' getInfo - return the status of the token rollout :return: info of the ocra token state :rtype: dict ''' TokenClass.__init__(self, aToken) self.setType(u"ocra") self.transId = 0 return
def __init__(self, a_token): ''' constructor - create a token object :param a_token: instance of the orm db object :type a_token: orm object ''' TokenClass.__init__(self, a_token) self.setType(u"mOTP") return
def __init__(self, aToken): """ constructor - create a token object :param aToken: instance of the orm db object :type aToken: orm object """ TokenClass.__init__(self, aToken) self.setType(u"u2f") self.mode = ['challenge'] # This is a challenge response token self.supports_offline_mode = True
def update(self, param, reset_failcount=True): # check for the required parameters if self.hKeyRequired is True: if "otpkey" not in param: raise ParameterError("Missing parameter: 'otpkey'") TokenClass.update(self, param, reset_failcount=False) for key in ["vasco_appl", "vasco_type", "vasco_auth"]: val = param.get(key) if val is not None: self.addToTokenInfo(key, val)
def __init__(self, aToken): """ constructor - create a token class object with it's db token binding :param aToken: the db bound token """ TokenClass.__init__(self, aToken) self.setType("forward") self.forwardSerial = None self.mode = ["authenticate", "challenge"] self.targetToken = None self.target_otp_count = -1
def __init__(self, aToken): """ constructor - create a token class object with it's db token binding :param aToken: the db bound token """ TokenClass.__init__(self, aToken) self.setType(u"forward") self.forwardSerial = None self.mode = ['authenticate', 'challenge'] self.targetToken = None self.target_otp_count = -1
def update(self, param): """ second phase of the init process - updates parameters :param param: the request parameters :return: - nothing - """ try: self.remoteServer = param["remote.server"] except KeyError: raise ParameterError("Missing parameter: 'remote.server'") # if another OTP length would be specified in /admin/init this would # be overwritten by the parent class, which is ok. self.setOtpLen(6) val = param.get("remote.local_checkpin", optional) if val is not None: self.remoteLocalCheckpin = val val = param.get("remote.serial") if val is not None: self.remoteSerial = val val = param.get("remote.user") if val is not None: self.remoteUser = val val = param.get("remote.realm") if val is not None: self.remoteRealm = val val = param.get("remote.resConf") if val is not None: self.remoteResConf = val TokenClass.update(self, param) self.addToTokenInfo("remote.server", self.remoteServer) self.addToTokenInfo("remote.serial", self.remoteSerial) self.addToTokenInfo("remote.user", self.remoteUser) self.addToTokenInfo("remote.local_checkpin", self.remoteLocalCheckpin) self.addToTokenInfo("remote.realm", self.remoteRealm) self.addToTokenInfo("remote.resConf", self.remoteResConf) return
def update(self, param, reset_failcount=False): self.setSyncWindow(0) self.setOtpLen(32) self.setCounterWindow(0) tdesc = param.get("description") if tdesc is not None: self.token.setDescription(tdesc) # requested_phase must be either "registration1" or "registration2" # current_phase is either "registration" or "authentication" requested_phase = param.get("phase") current_phase = self.getFromTokenInfo('phase', None) if requested_phase == "registration1" and current_phase is None: # This initial registration phase triggers a challenge # which is sent to the FIDO U2F compatible client device # Set the optional token pin in this first phase pin = param.get("pin") if pin is not None: TokenClass.setPin(self, pin) # preserve the registration state self.addToTokenInfo('phase', 'registration') self.token.LinOtpIsactive = False elif requested_phase == "registration2" and current_phase == "registration": # Check the token pin pin = param.get("pin") if pin is None: pin = '' if check_pin(self, pin) is False: raise ValueError("Wrong token pin!") # check for set phases which are not "registration1" or "registration2" elif requested_phase != "registration2" and requested_phase is not None: raise Exception('Wrong phase parameter!') # only allow empty phase parameters once the token is registered successfully elif current_phase != "authentication" and requested_phase is None: raise Exception('Wrong phase parameter!') # only allow "registration2" if the token already completed "registration1" elif current_phase != "registration" and requested_phase == "registration2": raise Exception( "Phase 'registration2' requested but we are not in the correct phase \ to process the request.") else: raise Exception('Unknown "phase" and "current_phase" parameter combination!')
def get_enrollment_status(self): """ provide token enrollment status""" is_completely_finished = TokenClass.isActive(self) if is_completely_finished: return {'status': 'completed'} else: return {'status': 'not completed', 'detail': self.current_state}
def isActive(self): # overwritten, because QrTokenClass can receive validate # requests in 2 different states: pairing_finished (active # flag is 1) and pairing_challenge_sent (active flag is 0) is_completely_finished = TokenClass.isActive(self) return is_completely_finished or \ self.current_state == 'pairing_response_received' or \ self.current_state == 'pairing_challenge_sent'
def update(self, param): """ second phase of the init process - updates token specific parameters :param param: the request parameters :return: - nothing - """ self.forwardSerial = param["forward.serial"] # get the otplen of the target token targetToken = self._getTargetToken(self.forwardSerial) TokenClass.update(self, param) self.setOtpLen(targetToken.getOtpLen()) self.addToTokenInfo("forward.serial", self.forwardSerial) return
def __init__(self, aToken): """ constructor - create a token class object with it's db token binding :param aToken: the db bound token """ TokenClass.__init__(self, aToken) self.setType(u"remote") self.remoteServer = "" self.remoteLocalCheckpin = None self.remoteSerial = None self.remoteUser = None self.remoteRealm = None self.remoteResConf = None self.mode = ['authenticate', 'challenge'] self.isRemoteChallengeRequest = False self.local_pin_check = None
def update(self, params, reset_failcount=True): ''' update: add further defintion for token from param in case of init ''' if 'ocrasuite' in params: self.ocraSuite = params.get('ocrasuite') else: activationcode = params.get('activationcode', None) sharedSecret = params.get('sharedsecret', None) if activationcode is None and sharedSecret is None: self.ocraSuite = self.getOcraSuiteSuite() else: self.ocraSuite = self.getQROcraSuiteSuite() if params.get('activationcode', None): # due to changes in the tokenclass parameter handling # we have to add for compatibility a genkey parameter if 'otpkey' not in params and 'genkey' not in params: log.warning('[OcraTokenClass:update] missing parameter genkey' ' to complete the rollout 2!') params['genkey'] = 1 TokenClass.update(self, params, reset_failcount=reset_failcount) self.addToTokenInfo('ocrasuite', self.ocraSuite) ocraSuite = OcraSuite(self.ocraSuite) otplen = ocraSuite.truncation self.setOtpLen(otplen) ocraPin = params.get('ocrapin', None) if ocraPin is not None: self.setUserPin(ocraPin) if 'otpkey' in params: self.setOtpKey(params.get('otpkey')) self._rollout_1(params) self._rollout_2(params) return
def __init__(self, a_token): ''' constructor - create a token object :param aToken: instance of the orm db object :type aToken: orm object ''' TokenClass.__init__(self, a_token) self.setType("HMAC") self.hKeyRequired = True self.authenticated = None # we support various hashlib methods, but only on create # which is effectively set in the update self.hashlibStr = self.getFromTokenInfo( "hashlib", getFromConfig("hotp.hashlib", 'sha1'))
def update(self, param): """ update - the api, which is called during the token enrollment we have to make sure that the otpkey, which carries our password is encoded as utf-8 to not break the storing :raises: otpkey contains the password and is required therefore otherewise raises ParameterError """ if "otpkey" not in param: raise ParameterError("Missing Parameter 'otpkey'!") TokenClass.update(self, param) TokenClass.setOtpLen(self, len(param["otpkey"]))
def update(self, param): """ update - the api, which is called during the token enrollment we have to make sure that the otpkey, which carries our password is encoded as utf-8 to not break the storing :raises: otpkey contains the password and is required therefore otherewise raises ParameterError """ if 'otpkey' not in param: raise ParameterError("Missing Parameter 'otpkey'!") TokenClass.update(self, param) TokenClass.setOtpLen(self, len(param['otpkey']))
def isActive(self): # overwritten, because PushTokenClass can receive validate # requests in 3 different states: active (active flag is 1) # pairing_response_received and pairing_challenge_sent # (both with active flag 0) is_completely_finished = TokenClass.isActive(self) return is_completely_finished or \ self.current_state == 'pairing_response_received' or \ self.current_state == 'pairing_challenge_sent'
def update(self, param): try: tokenid = param['yubico.tokenid'] except KeyError: raise ParameterError("Missing parameter: 'yubico.tokenid'") if len(tokenid) < YUBICO_LEN_ID: raise Exception("The YubiKey token ID needs to be %i characters long!" % YUBICO_LEN_ID) if len(tokenid) > YUBICO_LEN_ID: tokenid = tokenid[:YUBICO_LEN_ID] self.tokenid = tokenid self.setOtpLen(44) TokenClass.update(self, param) self.addToTokenInfo("yubico.tokenid", self.tokenid) return
def checkPin(self, pin, options=None): """ check the pin - either remote or localy - in case of remote, we return true, as the the splitPinPass will put the passw then in the otpVal """ res = True # only, if pin should be checked localy if self.check_pin_local(): res = TokenClass.checkPin(self, pin) return res
def update(self, param): try: tokenid = param['yubico.tokenid'] except KeyError: raise ParameterError("Missing parameter: 'yubico.tokenid'") if len(tokenid) < YUBICO_LEN_ID: raise Exception("The YubiKey token ID needs to be %i characters " "long!" % YUBICO_LEN_ID) if len(tokenid) > YUBICO_LEN_ID: tokenid = tokenid[:YUBICO_LEN_ID] self.tokenid = tokenid self.setOtpLen(44) TokenClass.update(self, param) self.addToTokenInfo("yubico.tokenid", self.tokenid) return
def update(self, param, reset_failcount=True): """ update - process the initialization parameters :param param: dict of initialization parameters :type param: dict :return: nothing """ # Remark: the otpKey is handled in the parent class self.hashlibStr = param.get("hashlib", "sha1") or "sha1" # check if the key_size id provided # if not, we could derive it from the hashlib key_size = param.get("key_size") if not key_size and self.hashlibStr in keylen: key_size = keylen.get(self.hashlibStr) param["key_size"] = key_size param["hashlib"] = self.hashlibStr self.addToTokenInfo("hashlib", self.hashlibStr) # ------------------------------------------------------------------ -- # for usability reason we can accept otpkeys with white spaces or # separators like '-', we just replace them before storing it if "otpkey" in param: otpkey = param["otpkey"] param["otpkey"] = otpkey.replace(" ", "").replace("-", "") # ------------------------------------------------------------------ -- TokenClass.update(self, param, reset_failcount) return
def update(self, param, reset_failcount=True): ''' update - process the initialization parameters :param param: dict of initialization parameters :type param: dict :return: nothing ''' # Remark: the otpKey is handled in the parent class self.hashlibStr = param.get("hashlib", 'sha1') or 'sha1' # check if the key_size id provided # if not, we could derive it from the hashlib key_size = param.get('key_size') if not key_size and self.hashlibStr in keylen: key_size = keylen.get(self.hashlibStr) param['key_size'] = key_size param['hashlib'] = self.hashlibStr self.addToTokenInfo("hashlib", self.hashlibStr) # ------------------------------------------------------------------ -- # for usability reason we can accept otpkeys with white spaces or # separators like '-', we just replace them before storing it if 'otpkey' in param: otpkey = param['otpkey'] param['otpkey'] = otpkey.replace(' ', '').replace('-', '') # ------------------------------------------------------------------ -- TokenClass.update(self, param, reset_failcount) return
def splitPinPass(self, passw): """ Split the PIN and the OTP value. Only if it is locally checked and not remotely. :param passw: the password with pin and otp :return: tupple of the (success, pin and otpvalue) """ local_check = self.check_pin_local() if local_check: (pin, otpval) = TokenClass.splitPinPass(self, passw) else: pin = "" otpval = passw log.debug("[splitPinPass] [remotetoken] returnung (len:%r) (len:%r)" % (len(pin), len(otpval))) return pin, otpval
def splitPinPass(self, passw): ''' Split the PIN and the OTP value. Only if it is locally checked and not remotely. ''' pin = "" otpval = "" local_check = self.check_pin_local() if self.check_pin_local(): log.debug("[splitPinPass] [radiustoken] locally checked") (pin, otpval) = TokenClass.splitPinPass(self, passw) else: log.debug("[splitPinPass] [radiustoken] remotely checked") pin = "" otpval = passw log.debug("[splitPinPass] [radiustoken] returning (len:%s) (len:%s)", len(pin), len(otpval)) return pin, otpval
def __init__(self, token_model_object): TokenClass.__init__(self, token_model_object) self.setType(u'push') self.mode = ['challenge'] self.supports_offline_mode = False
def update(self, params): """ initialization entry hook for the enrollment process. :param params: parameters provided by the client :raises Exception: If the client supplied unrecognized configuration parameters for this token type :raises Exception: If the policy 'pushtoken_pairing_callback_url' was not set. :raises TokenStateError: If token state is not None (default pre-enrollment state) """ param_keys = set(params.keys()) init_rollout_state_keys = set(['type', 'serial', '::scope::', 'user.login', 'description', 'user.realm', 'session', 'key_size', 'resConf', 'user', 'realm', 'pin']) # ------------------------------------------------------------------- -- if not param_keys.issubset(init_rollout_state_keys): # make sure the call aborts, if request # type wasn't recognized raise Exception('Unknown request type for token type pushtoken') # if param keys are in above set, the token is # initialized for the first time. this is e.g. done on the # manage web ui. since the token doesn't exist in the database # yet, its rollout state must be None (that is: the data for # the rollout state doesn't exist yet) self.ensure_state(None) # --------------------------------------------------------------- -- # we check if callback policies are set. this must be done here # because the token gets saved directly after the update method # in the TokenHandler _ = context['translate'] owner = get_token_owner(self) if owner and owner.login and owner.realm: realms = [owner.realm] else: realms = self.getRealms() cb_url = get_single_auth_policy('pushtoken_pairing_callback_url', user=owner, realms=realms) if not cb_url: raise Exception(_('Policy pushtoken_pairing_callback_url must ' 'have a value')) partition = get_partition(realms, owner) self.addToTokenInfo('partition', partition) # --------------------------------------------------------------- -- # we set the the active state of the token to False, because # it should not be allowed to use it for validation before the # pairing process is done self.token.LinOtpIsactive = False # -------------------------------------------------------------- -- TokenClass.update(self, params, reset_failcount=True) # -------------------------------------------------------------- -- self.change_state('initialized')
def __init__(self, aToken): TokenClass.__init__(self, aToken) self.setType(u"yubikey") self.hKeyRequired = True return
def __init__(self, aToken): TokenClass.__init__(self, aToken) self.setType(u"yubico") self.tokenid = ""
def reset(self): TokenClass.reset(self)
def __init__(self, aToken): TokenClass.__init__(self, aToken) self.setType(u"vasco") self.hKeyRequired = True
def __init__(self, aToken): TokenClass.__init__(self, aToken) self.setType(u"spass") self.mode = ['authenticate']