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']) log.debug("[update] end. Processing the initialization parameters done.") return
def update(self, param): # cko: changed for backward compat getParam(param, "pin", optional) if not param.has_key('otpkey'): param['genkey'] = 1 TokenClass.update(self, param)
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): ## check for the required parameters if (self.hKeyRequired == True): getParam(param, "otpkey", required) TokenClass.update(self, param)
def __init__(self, a_token): ''' constructor - create a token object :param aToken: instance of the orm db object :type aToken: orm object ''' log.debug("[init] begin. Create a token object with: a_token %r" % (a_token)) TokenClass.__init__(self, a_token) self.setType(u"HMAC") self.hKeyRequired = True # we support various hashlib methods, but only on create # which is effectively set in the update self.hashlibStr = u"sha1" try: self.hashlibStr = getFromConfig("hotp.hashlib", u'sha1') except Exception as ex: log.error('[init] Failed to get the hotp.hashlib (%r)' % (ex)) raise Exception(ex) log.debug("[init] end. Token object created") return
def update(self, param, reset_failcount=True): ''' update - process the initialization parameters :param param: dict of initialization parameters :type param: dict :return: nothing ''' log.debug("[update] begin. Process the initialization parameters: param %r" % (param)) ## Remark: the otpKey is handled in the parent class val = getParam(param, "hashlib", optional) if val is not None: self.hashlibStr = val else: self.hashlibStr = 'sha1' ## check if the key_size id provided ## if not, we could derive it from the hashlib key_size = getParam(param, 'key_size', optional) if key_size == None: param['key_size'] = keylen.get(self.hashlibStr) param['hashlib'] = self.hashlibStr self.addToTokenInfo("hashlib", self.hashlibStr) TokenClass.update(self, param, reset_failcount) log.debug("[update] end. Processing the initialization parameters done.") return
def update(self, param): self.radiusServer = getParam(param, "radius.server", required) # 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 = getParam(param, "radius.local_checkpin", optional) if val is not None: self.radiusLocal_checkpin = val val = getParam(param, "radius.user", required) if val is not None: self.radiusUser = val val = getParam(param, "radius.secret", required) if val is not None: self.radiusSecret = val 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.token.setHKey(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 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()) log.debug("[setOtpLen] setting otplen to %d" % pw_len) TokenClass.setOtpLen(self, pw_len) return
def update(self, param, reset_failcount=False): self.setSyncWindow(0) self.setOtpLen(32) self.setCounterWindow(0) tdesc = getParam(param, "description", optional) 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 = getParam(param, "phase", optional) 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 = getParam(param, "pin", optional) 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 = getParam(param, "pin", optional) if pin is None: pin = "" if check_pin(self, pin) is False: log.error("Wrong token pin!") 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: log.error("Wrong phase parameter!") 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: log.error("Wrong phase parameter!") raise Exception("Wrong phase parameter!") # only allow "registration2" if the token already completed "registration1" elif current_phase != "registration" and requested_phase == "registration2": log.error( "Phase 'registration2' requested but we are not in the correct phase \ to process the request." ) raise Exception( "Phase 'registration2' requested but we are not in the correct phase \ to process the request." ) else: log.error('Unknown "phase" and "current_phase" parameter combination!') raise Exception('Unknown "phase" and "current_phase" parameter combination!')
def update(self, param): # cko: changed for backward compat getParam(param, "pin", optional) if not param.has_key("otpkey"): param["genkey"] = 1 ## mark this spass token as usable exactly once if param.has_key("onetime"): TokenClass.set_count_auth_success_max(self, 1) TokenClass.update(self, param)
def __init__(self, a_token, context=None): ''' constructor - create a token object :param a_token: instance of the orm db object :type a_token: orm object ''' log.debug("[__init__] begin. entering constructor with param: a_token %r" % (a_token)) TokenClass.__init__(self, a_token, context=context) self.setType(u"mOTP") return
def update(self, param): ## check for the required parameters if (self.hKeyRequired == True): getParam(param, "otpkey", required) TokenClass.update(self, param, reset_failcount=False) for key in ["vasco_appl", "vasco_type", "vasco_auth"]: val = getParam(param, key, optional) 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(u"forward") self.forwardSerial = None self.mode = ['authenticate', 'challenge'] self.targetToken = None self.target_otp_count = -1
def __init__(self, aToken): """ constructor - create a token object :param aToken: instance of the orm db object :type aToken: orm object """ log.debug("Create a token object with: aToken %r", (aToken)) TokenClass.__init__(self, aToken) self.setType(u"u2f") self.mode = ['challenge'] # This is a challenge response token log.debug("Token object created")
def update(self, params, reset_failcount=True): ''' update: add further definition for token from param in case of init ''' log.debug('[update] %r: %r: ' % (params, reset_failcount)) if params.has_key('ocrasuite'): 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 params.has_key('otpkey') == False and params.has_key('genkey') == False: log.warning('[Ocra2TokenClass: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.token.setUserPin(ocraPin) if params.has_key('otpkey'): self.setOtpKey(params.get('otpkey')) self._rollout_1(params) self._rollout_2(params) log.debug('[update]:') 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']
def __init__(self, aToken): ''' getInfo - return the status of the token rollout :return: info of the ocra token state :rtype: dict ''' log.debug('[__init__]') TokenClass.__init__(self, aToken) self.setType(u"ocra2") self.transId = 0 self.mode = ['challenge'] log.debug('[__init__]:') return
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 = TokenClass.checkPin(self, pin) 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 update(self, param): tokenid = getParam(param, "yubico.tokenid", required) if len(tokenid) < YUBICO_LEN_ID: log.error("[update] The tokenid needs to be %i characters long!" % 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 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_challenge_sent'
def update(self, param): """ second phase of the init process - updates parameters :param param: the request parameters :return: - nothing - """ self.remoteServer = getParam(param, "remote.server", required) # 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 = getParam(param, "remote.local_checkpin", optional) if val is not None: self.remoteLocalCheckpin = val val = getParam(param, "remote.serial", optional) if val is not None: self.remoteSerial = val val = getParam(param, "remote.user", optional) if val is not None: self.remoteUser = val val = getParam(param, "remote.realm", optional) if val is not None: self.remoteRealm = val val = getParam(param, "remote.resConf", optional) 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): """ 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, context=None): """ constructor - create a token class object with it's db token binding :param aToken: the db bound token """ TokenClass.__init__(self, aToken, context=context) 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): param_keys = set(params.keys()) init_rollout_state_keys = set(['type', 'hashlib', 'serial', '::scope::', 'key_size', 'user.login', 'description', 'user.realm', 'session', 'otplen', 'resConf', 'user', 'realm', 'qr', '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 qr') # if param keys are in {'type', 'hashlib'} 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: they data for # the rollout state doesn't exist yet) self.ensure_state(None) # ------------------------------------------------------------------ # 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 # ------------------------------------------------------------------ if 'otplen' not in params: params['otplen'] = getFromConfig("QRTokenDefault.otplen", 8) # -------------------------------------------------------------- -- TokenClass.update(self, params, reset_failcount=True)
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, reset_failcount=True): ''' update - process initialization parameters :param param: dict of initialization parameters :type param: dict :return: nothing ''' log.debug("[update] begin. adjust the token class with: param %r" % (param)) getParam(param, "otpkey", required) ## motp token specific otpPin = getParam(param, "otppin", required) self.token.setUserPin(otpPin) TokenClass.update(self, param, reset_failcount) log.debug("[update] all token parameters are set.") return
def __init__(self, aToken, context=None): ''' constructor - create a token object :param aToken: instance of the orm db object :type aToken: orm object ''' log.debug("[init] begin. Create a token object with: a_token %r" % (aToken)) TokenClass.__init__(self, aToken, context=context) self.setType(u"TOTP") self.hKeyRequired = True ''' timeStep defines the granularity: ''' self.timeStep = getFromConfig("totp.timeStep", 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) '''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') log.debug("[init] end. Token object created") return
def is_challenge_request(self, passw, user, options=None): """ check, if the request would start a challenge :param passw: password, which might be pin or pin+otp :param options: dictionary of additional request parameters :return: returns true or false """ if not passw and \ ('data' in options or 'challenge' in options): return True else: return TokenClass.is_challenge_request(self, passw, user, options) return False
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() log.debug("[splitPinPass] [radiustoken] local checking pin? %r" % local_check) 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 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.hKeyRequired = True self.setType(u"pw")
def reset(self): TokenClass.reset(self)
def __init__(self, token_model_object): TokenClass.__init__(self, token_model_object) self.setType(u'qr') self.mode = ['challenge'] self.supports_offline_mode = True
def __init__(self, aToken): TokenClass.__init__(self, aToken) self.setType(u"yubico") self.tokenid = ""
def __init__(self, aToken): TokenClass.__init__(self, aToken) self.setType(u"spass") self.mode = ['authenticate']
def __init__(self, aToken): TokenClass.__init__(self, aToken) self.setType(u"yubikey") self.hKeyRequired = True return
def __init__(self, aToken, context=None): TokenClass.__init__(self, aToken, context=context) self.setType(u"DPW") self.hKeyRequired = True
def update(self, params): param_keys = set(params.keys()) init_rollout_state_keys = set(['type', 'hashlib', 'serial', '::scope::', 'key_size', 'user.login', 'description', 'user.realm', 'session', 'otplen', 'resConf', 'user', 'realm', 'qr', '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 qr') # if param keys are in {'type', 'hashlib'} 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: they 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() pairing_policies = ['qrtoken_pairing_callback_url', 'qrtoken_pairing_callback_sms'] cb_url = get_single_auth_policy(pairing_policies[0], user=owner, realms=realms) cb_sms = get_single_auth_policy(pairing_policies[1], user=owner, realms=realms) if not cb_url and not cb_sms: raise Exception(_('Policy %s must have a value') % _(" or ").join(pairing_policies)) challenge_policies = ['qrtoken_challenge_callback_url', 'qrtoken_challenge_callback_sms'] cb_url = get_single_auth_policy(challenge_policies[0], user=owner, realms=realms) cb_sms = get_single_auth_policy(challenge_policies[1], user=owner, realms=realms) if not cb_url and not cb_sms: raise Exception(_('Policy %s must have a value') % _(" or ").join(challenge_policies)) 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 # --------------------------------------------------------------- -- if 'otplen' not in params: params['otplen'] = getFromConfig("QRTokenOtpLen", 8) # -------------------------------------------------------------- -- TokenClass.update(self, params, reset_failcount=True)