def getUserInfo(self, resolver=None): userInfo = {} lookup_resolvers = None if resolver: lookup_resolvers = [resolver] userid, resolver_spec = self.get_uid_resolver(lookup_resolvers) if not userid: return {} try: y = getResolverObject(resolver_spec) log.debug("[getUserInfo] Getting user info for userid " ">%r< in resolver" % userid) userInfo = y.getUserInfo(userid) self.info[resolver_spec] = userInfo except Exception as e: log.exception('[getUserInfo][ resolver with specification %r ' 'not found: %r ]' % (resolver_spec, e)) return userInfo
def exists(self): """ check if a user exists in the given realm """ if self._exists in [True, False]: return self._exists self._exists = False realms = getRealms(self.realm) if not realms: return self._exists found = [] for realm_name, definition in realms.items(): resolvers = definition.get('useridresolver', []) for realm_resolver in resolvers: log.debug("checking in %r" % realm_resolver) y = getResolverObject(realm_resolver) if y: log.debug("checking in module %r" % y) uid = y.getUserId(self.login) found.append((self.login, realm_name, uid, realm_resolver)) log.debug("type of uid: %s" % type(uid)) log.debug("type of realm_resolver: %s" % type(realm_resolver)) else: log.error("module %r not found!" % (realm_resolver)) if found: self._exists = True (self.login, self.realm, self.uid, self.resolver) = found[0] return self._exists
def getSearchFields(user): searchFields = {} log.debug("[getSearchFields] entering function getSearchFields") for resolver_spec in getResolvers(User): """ """ _cls_identifier, config_identifier = parse_resolver_spec(resolver_spec) if len(user.resolver_config_identifier) > 0: lower_config_id = user.resolver_config_identifier.lower() if config_identifier.lower() != lower_config_id: continue # try to load the UserIdResolver Class try: y = getResolverObject(resolver_spec) sf = y.getSearchFields() searchFields[resolver_spec] = sf except Exception as exx: log.warning('[getSearchField][ resolver spec %s: %r ]', resolver_spec, exx) continue return searchFields
def getUserInfo(self, resolver=None): userInfo = {} lookup_resolvers = None if resolver: lookup_resolvers = [resolver] userid, resolverC = self.get_uid_resolver(lookup_resolvers) if not userid: return {} try: (package, module, _class, _conf) = splitResolver(resolverC) module = package + "." + module y = getResolverObject(resolverC) log.debug("[getUserInfo] Getting user info for userid " ">%r< in resolver" % userid) userInfo = y.getUserInfo(userid) self.info[resolverC] = userInfo except Exception as e: log.exception("[getUserInfo][ module %r notfound! :%r ]" % (module, e)) return userInfo
def exists(self): """ check if a user exists in the given realm """ if self._exists in [True, False]: return self._exists self._exists = False realms = getRealms(self.realm) if not realms: return self._exists found = [] for realm_name, definition in realms.items(): resolvers = definition.get('useridresolver', []) for realm_resolver in resolvers: log.debug("checking in %r", realm_resolver) y = getResolverObject(realm_resolver) if y: log.debug("checking in module %r" % y) uid = y.getUserId(self.login) found.append((self.login, realm_name, uid, realm_resolver)) log.debug("type of uid: %s", type(uid)) log.debug("type of realm_resolver: %s", type(realm_resolver)) else: log.error("module %r not found!", realm_resolver) if found: self._exists = True (self.login, self.realm, self.uid, self.resolver) = found[0] return self._exists
def _lookup_user_in_resolver(login, user_id, resolver_spec, user_info=None): # if we already have an user_info, all is defined # - this is used to fill up the cache, eg. from getUserList if user_info: if not login: login = user_info['username'] if not user_id: user_id = user_info['userid'] return login, user_id, user_info log.info("cache miss %r::%r", login, resolver_spec) y = getResolverObject(resolver_spec) if not y: log.error('[resolver with spec %r not found!]', resolver_spec) return None, None, None if login: user_id = y.getUserId(login) if user_id: user_info = y.getUserInfo(user_id) else: user_info = None return login, user_id, user_info if user_id: user_info = y.getUserInfo(user_id) if user_info: login = user_info.get('username') else: login = None return login, user_id, user_info return None, None, None
def getSearchFields(user): searchFields = {} log.debug("[getSearchFields] entering function getSearchFields") for resolver_spec in getResolvers(User): """ """ cls_identifier, config_identifier = parse_resolver_spec(resolver_spec) if len(user.resolver_config_identifier) > 0: lower_config_id = user.resolver_config_identifier.lower() if config_identifier.lower() != lower_config_id: continue # try to load the UserIdResolver Class try: y = getResolverObject(resolver_spec) sf = y.getSearchFields() searchFields[resolver_spec] = sf except Exception as e: log.warning('[getSearchField][ resolver spec %s: %r ]' % (resolver_spec, e)) continue return searchFields
def getSearchFields(User): searchFields = {} log.debug("[getSearchFields] entering function getSearchFields") for reso in getResolvers(User): """ """ (_package, module, class_, conf) = splitResolver(reso) if len(User.conf) > 0: if conf.lower() != User.conf.lower(): continue ## try to load the UserIdResolver Class try: y = getResolverObject(reso) sf = y.getSearchFields() searchFields[reso] = sf except Exception as e: log.warning("[getSearchField][ module %r: %r ]" % (module, e)) continue return searchFields
def check_user_password(username, realm, password): ''' This is a helper function to check the username and password against a userstore. return success --- This is the username of the authenticated user. If unsuccessful, returns None ''' success = None try: log.info("[check_user_password] User %r from realm %r tries to " "authenticate to selfservice" % (username, realm)) if type(username) != unicode: username = username.decode(ENCODING) u = User(username, realm, "") res = getResolversOfUser(u) # Now we know, the resolvers of this user and we can verify the password if (len(res) == 1): (uid, resolver, resolverC) = getUserId(u) log.info("[check_user_password] the user resolves to %r" % uid) log.info("[check_user_password] The username is found within the " "resolver %r" % resolver) # Authenticate user try: (package, module, class_, conf) = splitResolver(resolverC) module = package + "." + module y = getResolverObject(resolverC) except Exception as e: log.error("[check_user_password] [ module %r notfound! :%r ]" % (module, e)) try: if y.checkPass(uid, password): log.debug("[check_user_password] Successfully " "authenticated user %r." % username) # try: #identity = self.add_metadata( environ, identity ) success = username + '@' + realm else: log.info("[check_user_password] user %r failed " "to authenticate." % username) except Exception as e: log.error("[check_user_password] Error checking password " "within module %r:%r" % (module, e)) log.error("[check_user_password] %s" % traceback.format_exc()) elif (len(res) == 0): log.error("[check_user_password] The username %r exists in NO " "resolver within the realm %r." % (username, realm)) else: log.error("[check_user_password] The username %r exists in more " "than one resolver within the realm %r" % (username, realm)) log.error(res) except UserError as e: log.error("[check_user_password] Error while trying to verify " "the username: %r" % e.description) return success
def get_uid_resolver(self, resolvers=None): """ generator to get the uid and resolver info of the user :param resolvers: provide the resolver, where to check for the user :return: the tuple of uid and resolver """ uid = None resolvers_list = [] # if the resolver is not provided, we make a lookup for all resolvers # in the user realm if not resolvers: if self.realm: realms = getRealms() if self.realm.lower() in realms: resolvers_list = realms.get(self.realm.lower(), {}).\ get('useridresolver', []) else: resolvers_list = [] for search_resolver in resolvers: fq_resolver = User.get_fq_resolver(search_resolver) if fq_resolver: resolvers_list.append(fq_resolver) if not resolvers_list: return for resolver_spec in resolvers_list: try: y = getResolverObject(resolver_spec) uid = y.getUserId(self.login) if not uid: uid = None continue # we add the gathered resolver info to our self for later usage # 1. to the resolver uid list self.resolverUid[resolver_spec] = uid # 2. the resolver spec list resId = y.getResolverId() resCId = resolver_spec __, conf = parse_resolver_spec(resolver_spec) self.resolverConf[resolver_spec] = (resId, resCId, conf) # remember that we identified the user self.exist = True yield uid, resolver_spec except Exception as exx: log.exception("Error while accessing resolver %r", exx)
def login(self): """Checks a user's credentials and issues them a JWT access token if their credentials are valid. We're using cookies to store the access token plus a double-submit token for CSRF protection, which makes it easy to refresh access tokens transparently if they are nearing expiry. """ username = self.request_params.get("username") password = self.request_params.get("password") # Search for the user in the admin realm and check the # given password. admin_realm_name = current_app.config["ADMIN_REALM_NAME"] admin_realm = getRealms(admin_realm_name) admin_resolvers = admin_realm[admin_realm_name]["useridresolver"] for resolver_specification in admin_resolvers: resolver = getResolverObject(resolver_specification) uid = resolver.getUserId(username) if not uid: continue if not resolver.checkPass(uid, password): continue response = sendResult( None, True, opt={"message": f"Login successful for {username}"}, ) access_token = create_access_token(identity={ "username": username, "realm": current_app.config["ADMIN_REALM_NAME"], "resolver": resolver_specification, }, ) set_access_cookies(response, access_token) return response response = sendResult( None, False, opt={"message": "Bad username or password"}, ) response.status_code = 401 return response
def getUserList(param, User): users = [] searchDict = {} log.debug("[getUserList] entering function getUserList") ## we have to recreate a new searchdict without the realm key ## as delete does not work for key in param: lval = param[key] if key == "realm": continue if key == "resConf": continue searchDict[key] = lval log.debug("[getUserList] Parameter key:%r=%r" % (key, lval)) resolverrrs = getResolvers(User) for reso in resolverrrs: (package, module, class_, conf) = splitResolver(reso) module = package + "." + module if len(User.conf) > 0: if conf.lower() != User.conf.lower(): continue ## try to load the UserIdResolver Class try: log.debug("[getUserList] Check for resolver class: %r" % reso) y = getResolverObject(reso) log.debug("[getUserList] with this search dictionary: %r " % searchDict) ulist = y.getUserList(searchDict) log.debug("[getUserList] setting the resolver <%r> for each user" % reso) for u in ulist: u["useridresolver"] = reso log.debug("[getUserList] Found this userlist: %r" % ulist) users.extend(ulist) except KeyError as exx: log.error("[getUserList][ module %r:%r ]" % (module, exx)) log.error("[getUserList] %s" % traceback.format_exc()) raise exx except Exception as exx: log.error("[getUserList][ module %r:%r ]" % (module, exx)) log.error("[getUserList] %s" % traceback.format_exc()) continue return users
def getUserId(user): """ getUserId (userObject) return (uid,resId,resIdC) """ uid = "" loginUser = u"" loginUser = user.login resolvers = getResolversOfUser(user) for reso in resolvers: resId = "" resIdC = "" conf = "" uid = user.getResolverUId(reso) if uid != "": (resId, resIdC, conf) = user.getResolverConf(reso) break (package, module, class_, conf) = splitResolver(reso) if len(user.conf) > 0: if conf.lower() != user.conf.lower(): continue # try to load the UserIdResolver Class try: module = package + "." + module log.debug("[getUserId] Getting resolver class: [%r] [%r]" % (module, class_)) y = getResolverObject(reso) log.debug("[getUserId] Getting UserID for user %r" % loginUser) uid = y.getUserId(loginUser) log.debug("[getUserId] Got UserId for user %r: %r" % (loginUser, uid)) log.debug("[getUserId] Retrieving ResolverID...") resId = y.getResolverId() resIdC = reso log.debug("[getUserId] Got ResolverID: %r, Loginuser: %r, " "Uid: %r ]" % (resId, loginUser, uid)) if uid != "": break except Exception as e: log.exception("[getUserId] module %r: %r ]" % (module, e)) continue if uid == "": log.warning("[getUserId] No uid found for the user >%r< in realm %r" % (loginUser, user.realm)) raise UserError(u"getUserId failed: no user >%s< found!" % unicode(loginUser), id=1205) log.debug("[getUserId] we are done!") return (unicode(uid), unicode(resId), unicode(resIdC))
def get_authenticated_user(username, realm, password): ''' check the username and password against a userstore. :param username: the user login name :param realm: the realm, where the user belongs to :param password: the to be checked userstore password :return: None or user@realm of the authenticated user. ''' auth_user = None try: log.info("User %r from realm %r tries to authenticate to selfservice" % (username, realm)) if type(username) != unicode: username = username.decode(ENCODING) u = User(username, realm, "") res = getResolversOfUser(u) # Now we know, the resolvers of this user and we can verify the password if (len(res) == 1): (uid, resolver, resolverC) = getUserId(u) log.info("the user resolves to %r" % uid) log.info("The username is found within the resolver %r" % resolver) # Authenticate user try: (package, module, class_, conf) = splitResolver(resolverC) module = package + "." + module y = getResolverObject(resolverC) except Exception as e: log.error("[ module %r notfound! :%r ]" % (module, e)) try: if y.checkPass(uid, password): log.debug("Successfully authenticated user %r." % username) # try: #identity = self.add_metadata( environ, identity ) auth_user = username + '@' + realm else: log.info("user %r failed to authenticate." % username) except Exception as e: log.error("Error checking password within module %r:%r" % (module, e)) log.error("%s" % traceback.format_exc()) elif (len(res) == 0): log.error("The username %r exists in NO resolver within the " "realm %r." % (username, realm)) else: log.error("The username %r exists in more than one resolver " "within the realm %r" % (username, realm)) log.error(res) except UserError as exx: log.error("Error while trying to verify the username: %r" % exx) return auth_user
def get_authenticated_user(username, realm, password): ''' check the username and password against a userstore. :param username: the user login name :param realm: the realm, where the user belongs to :param password: the to be checked userstore password :return: None or user@realm of the authenticated user. ''' auth_user = None try: log.info("User %r from realm %r tries to authenticate to selfservice" % (username, realm)) if type(username) != unicode: username = username.decode(ENCODING) u = User(username, realm, "") res = getResolversOfUser(u) # Now we know, the resolvers of this user and we can verify the password if (len(res) == 1): (uid, resolver, resolverC) = getUserId(u) log.info("the user resolves to %r" % uid) log.info("The username is found within the resolver %r" % resolver) # Authenticate user try: (package, module, class_, conf) = splitResolver(resolverC) module = package + "." + module y = getResolverObject(resolverC) except Exception as e: log.error("[ module %r notfound! :%r ]" % (module, e)) try: if y.checkPass(uid, password): log.debug("Successfully authenticated user %r." % username) # try: # identity = self.add_metadata( environ, identity ) auth_user = username + '@' + realm else: log.info("user %r failed to authenticate." % username) except Exception as e: log.error("Error checking password within module %r:%r" % (module, e)) log.error("%s" % traceback.format_exc()) elif (len(res) == 0): log.error("The username %r exists in NO resolver within the " "realm %r." % (username, realm)) else: log.error("The username %r exists in more than one resolver " "within the realm %r" % (username, realm)) log.error(res) except UserError as exx: log.error("Error while trying to verify the username: %r" % exx) return auth_user
def checkPass(self, password): if self.exists() == False: return False res = False try: y = getResolverObject(self.resolver) res = y.checkPass(self.uid, password) except: pass return res
def checkPass(self, password): if self.exists() is False: return False res = False try: y = getResolverObject(self.resolver) res = y.checkPass(self.uid, password) except: pass return res
def getUserList(param, User): users = [] searchDict = {} log.debug("[getUserList] entering function getUserList") ## we have to recreate a new searchdict without the realm key ## as delete does not work for key in param: lval = param[key] if key == "realm": continue if key == "resConf": continue searchDict[key] = lval log.debug("[getUserList] Parameter key:%r=%r" % (key, lval)) resolverrrs = getResolvers(User) for reso in resolverrrs: (package, module, class_, conf) = splitResolver(reso) module = package + "." + module if len(User.conf) > 0: if conf.lower() != User.conf.lower(): continue ## try to load the UserIdResolver Class try: log.debug("[getUserList] Check for resolver class: %r" % reso) y = getResolverObject(reso) log.debug("[getUserList] with this search dictionary: %r " % searchDict) ulist = y.getUserList(searchDict) log.debug("[getUserList] setting the resolver <%r> for each user" % reso) for u in ulist: u["useridresolver"] = reso log.debug("[getUserList] Found this userlist: %r" % ulist) users.extend (ulist) except KeyError as exx: log.error("[getUserList][ module %r:%r ]" % (module, exx)) log.error("[getUserList] %s" % traceback.format_exc()) raise exx except Exception as exx: log.error("[getUserList][ module %r:%r ]" % (module, exx)) log.error("[getUserList] %s" % traceback.format_exc()) continue return users
def getResolversOfUser(user): ''' getResolversOfUser returns the list of the Resolvers of a user in a given realm. A user can be be in more than one resolver if the login name is the same and if the user has the same id. The usecase behind this constrain is that an user for example could be ldap wise in a group which could be addressed by two queries. :param user: userobject with user.login, user.realm :returns: array of resolvers, the user was found in ''' login = user.login realm = user.realm if not realm: realm = getDefaultRealm() realm = realm.lower() # calling the worker which stores resolver in the cache resolvers = get_resolvers_of_user(login, realm) # -- ------------------------------------------------------------------ -- # below we adjust the legacy stuff and put the resolver info into the user # -- ------------------------------------------------------------------ -- for resolver_spec in resolvers: # this is redundant but cached login, uid, _user_info = lookup_user_in_resolver( login, None, resolver_spec) if not uid: continue try: # we require the resId y = getResolverObject(resolver_spec) resId = y.getResolverId() resCId = resolver_spec except Exception as exx: log.exception("Failed to establish resolver %r: %r", resolver_spec, exx) continue __, config_identifier = parse_resolver_spec(resolver_spec) user.addResolverUId(resolver_spec, uid, config_identifier, resId, resCId) return resolvers
def getUserListIterators(param, search_user): """ return a list of iterators for all userid resolvers :param param: request params (dict), which might be realm or resolver conf :param search_user: restrict the resolvers to those of the search_user """ user_iters = [] searchDict = {} log.debug("Entering function getUserListIterator") searchDict.update(param) if 'realm' in searchDict: del searchDict['realm'] if 'resConf' in searchDict: del searchDict['resConf'] log.debug("searchDict %r" % searchDict) resolverrrs = getResolvers(search_user) for reso in resolverrrs: (package, module, _class, conf) = splitResolver(reso) module = package + "." + module if len(search_user.conf) > 0: if conf.lower() != search_user.conf.lower(): continue # try to load the UserIdResolver Class try: log.debug("Check for resolver class: %r" % reso) y = getResolverObject(reso) log.debug("With this search dictionary: %r " % searchDict) if hasattr(y, 'getUserListIterator'): uit = y.getUserListIterator(searchDict, limit_size=False) else: uit = iter(y.getUserList(searchDict)) user_iters.append((uit, reso)) except KeyError as exx: log.error("[ module %r:%r ]" % (module, exx)) log.error("%s" % traceback.format_exc()) raise exx except Exception as exx: log.error("[ module %r:%r ]" % (module, exx)) log.error("%s" % traceback.format_exc()) continue return user_iters
def getUserListIterators(param, search_user): """ return a list of iterators for all userid resolvers :param param: request params (dict), which might be realm or resolver conf :param search_user: restrict the resolvers to those of the search_user """ user_iters = [] searchDict = {} log.debug("Entering function getUserListIterator") searchDict.update(param) if "realm" in searchDict: del searchDict["realm"] if "resConf" in searchDict: del searchDict["resConf"] log.debug("searchDict %r" % searchDict) resolverrrs = getResolvers(search_user) for reso in resolverrrs: (package, module, _class, conf) = splitResolver(reso) module = package + "." + module if len(search_user.conf) > 0: if conf.lower() != search_user.conf.lower(): continue # try to load the UserIdResolver Class try: log.debug("Check for resolver class: %r" % reso) y = getResolverObject(reso) log.debug("With this search dictionary: %r " % searchDict) if hasattr(y, "getUserListIterator"): uit = y.getUserListIterator(searchDict, limit_size=False) else: uit = iter(y.getUserList(searchDict)) user_iters.append((uit, reso)) except KeyError as exx: log.error("[ module %r:%r ]" % (module, exx)) log.error("%s" % traceback.format_exc()) raise exx except Exception as exx: log.error("[ module %r:%r ]" % (module, exx)) log.error("%s" % traceback.format_exc()) continue return user_iters
def getUserListIterators(param, search_user): """ return a list of iterators for all userid resolvers :param param: request params (dict), which might be realm or resolver conf :param search_user: restrict the resolvers to those of the search_user """ user_iters = [] searchDict = {} log.debug("Entering function getUserListIterator") searchDict.update(param) if 'realm' in searchDict: del searchDict['realm'] if 'resConf' in searchDict: del searchDict['resConf'] log.debug("searchDict %r", searchDict) resolverrrs = getResolvers(search_user) for resolver_spec in resolverrrs: cls_identifier, config_identifier = parse_resolver_spec(resolver_spec) if len(search_user.resolver_config_identifier) > 0: lower_config_id = search_user.resolver_config_identifier.lower() if config_identifier.lower() != lower_config_id: continue # try to load the UserIdResolver Class try: log.debug('Check for resolver: %r', resolver_spec) y = getResolverObject(resolver_spec) log.debug("With this search dictionary: %r ", searchDict) if hasattr(y, 'getUserListIterator'): uit = y.getUserListIterator(searchDict, limit_size=False) else: uit = iter(y.getUserList(searchDict)) user_iters.append((uit, resolver_spec)) except KeyError as exx: log.exception('[ resolver class %r:%r ]', cls_identifier, exx) raise exx except Exception as exx: log.exception('[ resolver class %r:%r ]', cls_identifier, exx) continue return user_iters
def getUserListIterators(param, search_user): """ return a list of iterators for all userid resolvers :param param: request params (dict), which might be realm or resolver conf :param search_user: restrict the resolvers to those of the search_user """ user_iters = [] searchDict = {} log.debug("Entering function getUserListIterator") searchDict.update(param) if 'realm' in searchDict: del searchDict['realm'] if 'resConf' in searchDict: del searchDict['resConf'] log.debug("searchDict %r" % searchDict) resolverrrs = getResolvers(search_user) for resolver_spec in resolverrrs: cls_identifier, config_identifier = parse_resolver_spec(resolver_spec) if len(search_user.resolver_config_identifier) > 0: lower_config_id = search_user.resolver_config_identifier.lower() if config_identifier.lower() != lower_config_id: continue # try to load the UserIdResolver Class try: log.debug('Check for resolver: %r' % resolver_spec) y = getResolverObject(resolver_spec) log.debug("With this search dictionary: %r " % searchDict) if hasattr(y, 'getUserListIterator'): uit = y.getUserListIterator(searchDict, limit_size=False) else: uit = iter(y.getUserList(searchDict)) user_iters.append((uit, resolver_spec)) except KeyError as exx: log.exception('[ resolver class %r:%r ]' % (cls_identifier, exx)) raise exx except Exception as exx: log.exception('[ resolver class %r:%r ]' % (cls_identifier, exx)) continue return user_iters
def getUserId(user, check_existance=False): """ getUserId (userObject) :param user: user object :return: (uid,resId,resIdC) """ uid = None resId = '' uids = set() resolvers = getResolversOfUser(user) for resolver_spec in resolvers: _login, uid, _user_info = lookup_user_in_resolver( user.login, None, resolver_spec) if not uid: continue y = getResolverObject(resolver_spec) resId = y.getResolverId() if check_existance: uinfo = y.getUserInfo(uid) if not uinfo: uid = None if not uid: continue uids.add(uid) user.resolverUid[resolver_spec] = uid if not uid: log.warning("No uid found for the user >%r< in realm %r" % (user.login, user.realm)) raise UserError("getUserId failed: no user >%s< found!" % user.login, id=1205) if len(uids) > 1: log.warning("multiple uid s found for the user >%r< in realm %r" % (user.login, user.realm)) raise UserError( "getUserId failed: multiple uids for user >%s< found!" % user.login, id=1205) log.debug("we are done!") return (uid, resId, resolver_spec)
def check_pin(token, passw, user=None, options=None): """ check the provided pin w.r.t. the policy definition :param token: the token to be checked :param passw: the to be checked pass :param user: if otppin==1, this is the user, which resolver should be checked :param options: the optional request parameters :return: boolean, if pin matched True """ res = False pin_policies = linotp.lib.policy.get_pin_policies(user) if 0 in pin_policies or "token_pin" in pin_policies: # old stuff: We check The fixed OTP PIN log.debug('[__checkToken] pin policy=0: checkin the PIN') res = token.checkPin(passw, options=options) elif 1 in pin_policies or "password" in pin_policies: # We check the Users Password as PIN log.debug('pin policy=1: checking the users password as pin') if user is None or not user.login: log.info('- fail for pin policy == 1 with user = None') return False (uid, _resolver, resolver_class) = getUserId(user) r_obj = getResolverObject(resolver_class) if r_obj.checkPass(uid, passw): log.debug('[__checkToken] Successfully authenticated user %r.' % uid) res = True else: log.info('[__checkToken] user %r failed to auth.' % uid) elif 2 in pin_policies or "only_otp" in pin_policies: # NO PIN should be entered at all log.debug('[__checkToken] pin policy=2: checking no pin') if len(passw) == 0: res = True else: # old stuff: We check The fixed OTP PIN log.debug('[__checkToken] pin policy=0: checkin the PIN') res = token.checkPin(passw, options=options) return res
def check_pin(token, passw, user=None, options=None): ''' check the provided pin w.r.t. the policy definition :param passw: the to be checked pass :param user: if otppin==1, this is the user, which resolver should be checked :param options: the optional request parameters :return: boolean, if pin matched True ''' res = False context = token.context pin_policies = linotp.lib.policy.get_pin_policies(user, context=context) if 1 in pin_policies: # We check the Users Password as PIN log.debug("[check_pin] pin policy=1: checking the users" " password as pin") if (user is None or not user.login): log.info("[check_pin] - fail for pin policy == 1 " "with user = None") return False (uid, _resolver, resolver_class) = getUserId(user) r_obj = getResolverObject(resolver_class) if r_obj.checkPass(uid, passw): log.debug("[__checkToken] Successfully authenticated user %r." % uid) res = True else: log.info("[__checkToken] user %r failed to authenticate." % uid) elif 2 in pin_policies: # NO PIN should be entered atall log.debug("[__checkToken] pin policy=2: checking no pin") if len(passw) == 0: res = True else: # old stuff: We check The fixed OTP PIN log.debug("[__checkToken] pin policy=0: checkin the PIN") res = token.checkPin(passw, options=options) return res
def check_pin(token, passw, user=None, options=None): ''' check the provided pin w.r.t. the policy definition :param passw: the to be checked pass :param user: if otppin==1, this is the user, which resolver should be checked :param options: the optional request parameters :return: boolean, if pin matched True ''' res = False pin_policies = linotp.lib.policy.get_pin_policies(user) if 1 in pin_policies: # We check the Users Password as PIN LOG.debug("[check_pin] pin policy=1: checking the users" " password as pin") if (user is None): raise Exception("[check_pin] - fail for pin policy == 1 " "with user = None") (uid, _resolver, resolver_class) = getUserId(user) r_obj = getResolverObject(resolver_class) if r_obj.checkPass(uid, passw): LOG.debug("[__checkToken] Successfully authenticated user %r." % uid) res = True else: LOG.info("[__checkToken] user %r failed to authenticate." % uid) elif 2 in pin_policies: # NO PIN should be entered atall LOG.debug("[__checkToken] pin policy=2: checking no pin") if len(passw) == 0: res = True else: # old stuff: We check The fixed OTP PIN LOG.debug("[__checkToken] pin policy=0: checkin the PIN") res = token.checkPin(passw, options=options) return res
def getUserInfo(userid, resolver, resolver_spec): log.debug("[getUserInfo] uid:%r resolver:%r class:%r", userid, resolver, resolver_spec) userInfo = {} if not(userid): return userInfo try: y = getResolverObject(resolver_spec) log.debug("[getUserInfo] Getting user info for userid " ">%r< in resolver", userid) userInfo = y.getUserInfo(userid) except Exception as exx: log.exception('[getUserInfo][ resolver %s notfound: %r ]', resolver_spec, exx) return userInfo
def getUserInfo(userid, resolver, resolverC): log.debug("[getUserInfo] uid:%r resolver:%r class:%r" % (userid, resolver, resolverC)) # [PasswdIdResolver] [IdResolver] userInfo = {} module = "" if not (userid): return userInfo try: (package, module, _class, _conf) = splitResolver(resolverC) module = package + "." + module y = getResolverObject(resolverC) log.debug("[getUserInfo] Getting user info for userid " ">%r< in resolver" % userid) userInfo = y.getUserInfo(userid) except Exception as e: log.error("[getUserInfo][ module %r notfound! :%r ]" % (module, e)) return userInfo
def getUserInfo(userid, resolver, resolverC): log.debug("[getUserInfo] uid:%r resolver:%r class:%r" % (userid, resolver, resolverC)) ## [PasswdIdResolver] [IdResolver] userInfo = {} module = "" if not(userid): return userInfo try: (package, module, class_, conf) = splitResolver(resolverC) module = package + "." + module y = getResolverObject(resolverC) log.debug("[getUserInfo] Getting user info for userid " ">%r< in resolver" % userid) userInfo = y.getUserInfo(userid) except Exception as e: log.error("[getUserInfo][ module %r notfound! :%r ]" % (module, e)) return userInfo
def get_uid_resolver(self, resolvers=None): uid = None resolver = None resolvers_list = [] if not resolvers: if self.realm: realms = getRealms() if self.realm.lower() in realms: resolvers_list = realms.get(self.realm.lower(), {}).\ get('useridresolver', []) else: resolvers_list = [] for search_resolver in resolvers: fq_resolver = User.get_fq_resolver(search_resolver) if fq_resolver: resolvers_list.append(fq_resolver) if not resolvers_list: return None, None for resolver in resolvers_list: try: y = getResolverObject(resolver) uid = y.getUserId(self.login) if not uid: uid = None continue self.resolverUid[resolver] = uid self.exist = True break except Exception as exx: log.exception("Error while accessing resolver %r", exx) return (uid, resolver)
def get_uid_resolver(self, resolvers=None): uid = None resolver_spec = None resolver_specs = [] if not resolvers: if self.realm: realms = getRealms() if self.realm.lower() in realms: resolver_specs = realms.get(self.realm.lower(), {}).\ get('useridresolver', []) else: resolver_specs = [] for search_resolver in resolvers: fq_resolver = User.get_fq_resolver(search_resolver) if fq_resolver: resolver_specs.append(fq_resolver) if not resolver_specs: return None, None for resolver_spec in resolver_specs: try: y = getResolverObject(resolver_spec) uid = y.getUserId(self.login) if not uid: uid = None continue self.resolverUid[resolver_spec] = uid self.exist = True break except Exception as exx: log.exception("Error while accessing resolver %r", exx) return (uid, resolver_spec)
def getUserList(param, search_user): users = [] searchDict = {} log.debug("[getUserList] entering function getUserList") # we have to recreate a new searchdict without the realm key # as delete does not work for key in param: lval = param[key] if key == "realm": continue if key == "resConf": continue searchDict[key] = lval log.debug("[getUserList] Parameter key:%r=%r" % (key, lval)) resolverrrs = getResolvers(search_user) for resolver_spec in resolverrrs: cls_identifier, config_identifier = parse_resolver_spec(resolver_spec) if len(search_user.resolver_config_identifier) > 0: lower_config_id = search_user.resolver_config_identifier.lower() if config_identifier.lower() != lower_config_id: continue # try to load the UserIdResolver Class try: log.debug("[getUserList] Check for resolver: %r" % resolver_spec) y = getResolverObject(resolver_spec) log.debug("[getUserList] with this search dictionary: %r " % searchDict) if hasattr(y, 'getUserListIterator'): try: ulist_gen = y.getUserListIterator(searchDict) while True: ulist = ulist_gen.next() log.debug("[getUserList] setting the resolver <%r> " "for each user" % resolver_spec) for u in ulist: u["useridresolver"] = resolver_spec log.debug("[getUserList] Found this userlist: %r" % ulist) users.extend(ulist) except StopIteration as exx: # we are done: all users are fetched or # page size limit reached pass else: ulist = y.getUserList(searchDict) for u in ulist: u["useridresolver"] = resolver_spec log.debug("[getUserList] Found this userlist: %r" % ulist) users.extend(ulist) except KeyError as exx: log.exception('[getUserList][ resolver class identifier %s:%r ]' % (cls_identifier, exx)) raise exx except Exception as exx: log.exception('[getUserList][ resolver class identifier %s:%r ]' % (cls_identifier, exx)) continue return users
def getUserList(param, search_user): users = [] searchDict = {} log.debug("[getUserList] entering function getUserList") # we have to recreate a new searchdict without the realm key # as delete does not work for key in param: lval = param[key] if key == "realm": continue if key == "resConf": continue searchDict[key] = lval log.debug("[getUserList] Parameter key:%r=%r" % (key, lval)) resolverrrs = getResolvers(search_user) for reso in resolverrrs: (package, module, _class, conf) = splitResolver(reso) module = package + "." + module if len(search_user.conf) > 0: if conf.lower() != search_user.conf.lower(): continue # try to load the UserIdResolver Class try: log.debug("[getUserList] Check for resolver class: %r" % reso) y = getResolverObject(reso) log.debug("[getUserList] with this search dictionary: %r " % searchDict) if hasattr(y, "getUserListIterator"): try: ulist_gen = y.getUserListIterator(searchDict) while True: ulist = ulist_gen.next() log.debug("[getUserList] setting the resolver <%r> " "for each user" % reso) for u in ulist: u["useridresolver"] = reso log.debug("[getUserList] Found this userlist: %r" % ulist) users.extend(ulist) except StopIteration as exx: # we are done: all users are fetched or # page size limit reached pass else: ulist = y.getUserList(searchDict) for u in ulist: u["useridresolver"] = reso log.debug("[getUserList] Found this userlist: %r" % ulist) users.extend(ulist) except KeyError as exx: log.error("[getUserList][ module %r:%r ]" % (module, exx)) log.error("[getUserList] %s" % traceback.format_exc()) raise exx except Exception as exx: log.error("[getUserList][ module %r:%r ]" % (module, exx)) log.error("[getUserList] %s" % traceback.format_exc()) continue return users
def getUserId(user, resolvers=None): """ getUserId (userObject) return (uid,resId,resIdC) """ uid = '' loginUser = u'' loginUser = user.login; if not resolvers: resolvers = getResolversOfUser(user) for resolver_spec in resolvers: resId = "" resIdC = "" conf = "" uid = user.getResolverUId(resolver_spec) if uid != '': (resId, resIdC, conf) = user.getResolverConf(resolver_spec) break cls_identifier, config_identifier = parse_resolver_spec(resolver_spec) if user.resolver_config_identifier: lower_config_id = user.resolver_config_identifier.lower() if config_identifier.lower() != lower_config_id: continue # try to load the UserIdResolver Class try: log.debug('[getUserId] Getting resolver class: [%s]' % cls_identifier) y = getResolverObject(resolver_spec) log.debug("[getUserId] Getting UserID for user %r" % loginUser) uid = y.getUserId(loginUser) log.debug("[getUserId] Got UserId for user %r: %r" % (loginUser, uid)) log.debug("[getUserId] Retrieving ResolverID...") resId = y.getResolverId() resIdC = resolver_spec log.debug("[getUserId] Got ResolverID: %r, Loginuser: %r, " "Uid: %r ]" % (resId, loginUser, uid)) if uid != "": break; except Exception as e: log.exception("[getUserId] resolver class identifier %s: %r ]" % (cls_identifier, e)) continue if (uid == ''): log.warning("[getUserId] No uid found for the user >%r< in realm %r" % (loginUser, user.realm)) raise UserError(u"getUserId failed: no user >%s< found!" % unicode(loginUser), id=1205) log.debug("[getUserId] we are done!") return (unicode(uid), unicode(resId), unicode(resIdC))
def getResolversOfUser(user, use_default_realm=True, allRealms=None, defaultRealm=None): ''' This returns the list of the Resolvers of a user in a given realm. Usually this should only return one resolver input: user.login, user.realm returns: array of resolvers, the user was found in ''' login = user.login realm = user.realm if not defaultRealm: defaultRealm = getDefaultRealm() Resolvers = user.getResolvers() if len(Resolvers) > 0: return Resolvers if not login: return Resolvers if realm is None or realm == "": if use_default_realm: realm = defaultRealm if not allRealms: allRealms = getRealms() realms = allRealms if user.resolver_config_identifier != "": resolver_spec = find_resolver_spec_for_config_identifier(realms, user.resolver_config_identifier) if resolver_spec is not None: Resolvers.append(resolver_spec) else: Realm_resolvers = getResolvers(User("", realm, "")) log.debug("[getResolversOfUser] check if user %r is in resolver %r" % (login, Realm_resolvers)) # Search for user in each resolver in the realm_ for resolver_spec in Realm_resolvers: log.debug("[getResolversOfUser] checking in %r" % resolver_spec) y = getResolverObject(resolver_spec) if y is None: log.error('[getResolversOfUser] [resolver with spec %r ' 'not found!]' % (resolver_spec)) try: log.debug("[getResolversOfUser] checking in module %r" % y) uid = y.getUserId(login) log.debug("[getResolversOfUser] type of uid: %s" % type(uid)) log.debug("[getResolversOfUser] type of resolver_spec: %s" % type(resolver_spec)) log.debug("[getResolversOfUser] type of login: %s" % type(login)) if uid not in ["", None]: log.info("[getResolversOfUser] user %r found in resolver %r" % (login, resolver_spec)) log.info("[getResolversOfUser] userid resolved to %r " % uid) # Unicode Madness: # This will break as soon as the unicode "uid" is put into a tuple # v = (login, realm_resolver, uid) # log.info("[getResolversOfUser] %s %s %s" % v) resId = y.getResolverId(); resCId = resolver_spec Resolvers.append(resolver_spec) __, config_identifier = parse_resolver_spec(resolver_spec) user.addResolverUId(resolver_spec, uid, config_identifier, resId, resCId) else: log.debug("[getResolversOfUser] user %r not found" " in resolver %r" % (login, resolver_spec)) except Exception as e: log.exception('[getResolversOfUser] error searching user in ' 'resolver with spec %r:%r' % (resolver_spec, e)) log.debug("[getResolversOfUser] Resolvers: %r" % Resolvers) log.debug("[getResolversOfUser] Found the user %r in %r" % (login, Resolvers)) return Resolvers
def getUserId(user): """ getUserId (userObject) return (uid,resId,resIdC) """ uid = '' loginUser = u'' loginUser = user.login; resolvers = ''; realms = getRealms(); # Get the first resolver they're present in, because UID is independent of realm. for key, v in realms.items(): resolvers = getResolversOfUser(User(user.login, v['realmname'], "")) if (resolvers): break; for reso in resolvers: resId = "" resIdC = "" conf = "" uid = user.getResolverUId(reso) if uid != '': (resId, resIdC, conf) = user.getResolverConf(reso) break (package, module, class_, conf) = splitResolver(reso) if len(user.conf) > 0: if conf.lower() != user.conf.lower(): continue ## try to load the UserIdResolver Class try: module = package + "." + module log.debug("[getUserId] Getting resolver class: [%r] [%r]" % (module, class_)) y = getResolverObject(reso) log.debug("[getUserId] Getting UserID for user %r" % loginUser) uid = y.getUserId(loginUser) log.debug("[getUserId] Got UserId for user %r: %r" % (loginUser, uid)) log.debug("[getUserId] Retrieving ResolverID...") resId = y.getResolverId() resIdC = reso log.debug("[getUserId] Got ResolverID: %r, Loginuser: %r, " "Uid: %r ]" % (resId, loginUser, uid)) if uid != "": break; except Exception as e: log.error("[getUserId] module %r: %r ]" % (module, e)) continue if (uid == ''): log.warning("[getUserId] No uid found for the user >%r< in realm %r" % (loginUser, user.realm)) raise UserError(u"getUserId failed: no user >%s< found!" % unicode(loginUser), id=1205) log.debug("[getUserId] we are done!") return (unicode(uid), unicode(resId), unicode(resIdC))
def migrate_resolver(self, src=None, target=None, filter_serials=None): """ support the migration of owned tokens from one resolver to a new one the idea is: - get all tokens from one resolver - for each token, the the owner - from the owner get the login name - with the login name get the uid from the target resolver - update the new_id in the token """ _ = context['translate'] ret = {} if not src or not target: raise Exception("Missing src or target resolver defintion!") audit = context.get('audit') now = datetime.now() stime = now.strftime("%s") audit['action_detail'] = ("migration from %s to %s" % (src['resolvername'], target['resolvername'])) ret['src'] = src ret['target'] = target ret['value'] = False ret['message'] = '' search = getResolverClassName(src['type'], src['resolvername']) target_resolver = getResolverClassName(target['type'], target['resolvername']) # get all tokens of src resolver tokens = self._get_tokens_for_resolver(search, serials=filter_serials) num_migration = 0 serials = set() for token in tokens: serial = token.get('LinOtpTokenSerialnumber') userid = token.get('LinOtpUserid') resolverC = token.get('LinOtpIdResClass') # now do the lookup of the uid in the # src resolver to get the login uInfo = getUserInfo(userid, '', resolverC) login = uInfo.get('username') try: y = getResolverObject(target_resolver) uid = y.getUserId(login) if not uid: log.warning("User %s not found in target resolver %r", login, target_resolver) continue token.LinOtpIdResClass = target_resolver token.LinOtpUserid = uid # TODO: adjust token.LinOtpIdResolver = target['type'] Session.add(token) num_migration += 1 serials.add(serial) except Exception as exx: log.exception("Faild to set new resolver data for token %s: %r" % (serial, exx)) ret['value'] = True ret['message'] = (_("%d tokens of %d migrated") % (num_migration, len(tokens))) log.info(ret['message']) audit['info'] = "[%s] %s" % (stime, ret['message']) audit['serial'] = ",".join(list(serials)) audit['success'] = True context['audit'] = audit return ret
def get_authenticated_user(username, realm, password=None, realm_box=False, authenticate=True, options=None): ''' check the username and password against a userstore. remark: the method is called in the context of repoze.who during authentication and during auto_enrollToken/auto_assignToken :param username: the user login name :param realm: the realm, where the user belongs to :param password: the to be checked userstore password :param realm_box: take the information, if realmbox is displayed :parm authenticate: for the selftest, we skip the authentication :return: None or authenticated user object ''' log.info("User %r from realm %r tries to authenticate to selfservice" % (username, realm)) if type(username) != unicode: username = username.decode(ENCODING) # ease the handling of options if not options: options = {} users = [] uid = None resolver = None resolverC = None # if we have an realmbox, we take the user as it is # - the realm is always given # - appended realms result in error if realm_box: user = User(username, realm, "") users.append(user) # else if no realm box is given # and realm is not empty: # - create the user from the values (as we are in auto_assign, etc) # and the realm is empty! (s. login.mako # - the user either appends his realm # - or will get the realm appended # else: if realm: user = User(username, realm, "") users.append(user) else: def_realm = options.get('defaultRealm', getDefaultRealm()) if def_realm: user = User(username, def_realm, "") users.append(user) if '@' in username: u_name, u_realm = username.rsplit('@', 1) user = User(u_name, u_realm, "") users.append(user) identified_users = [] for user in users: username = user.login realm = user.realm res = getResolversOfUser(user, use_default_realm=False) if not res: log.info("The username %r exists in NO resolver within the " "realm %r.", username, realm) continue # fill in the set of resolvers getUserId(user) for resolverClass, uid in user.resolverUid.items(): identified_users.append((user, uid, resolverClass, resolverClass)) log.info("the user resolves to %r", uid) log.info("The username is found within the resolver %r", resolver) if not identified_users: log.info("The username %s could not be found." % username) return None if not authenticate: (user, uid, resolver, resolverC) = identified_users[0] return user # Authenticate user auth_user = None for identified_user in identified_users: (user, uid, resolver, resolverC) = identified_user try: y = getResolverObject(resolverC) if y.checkPass(uid, password): # we stop with the first successful authenticated user log.debug("Successfully authenticated user %r.", username) auth_user = user break else: log.info("user %r failed to authenticate.", username) except UserError as exx: log.info("failed to verify the username: %s@%s: %r", user.login, user.realm, exx) if not auth_user: log.error("Error while trying to verify the username: %s", username) return auth_user
def checkUserPass(self, user, passw, options=None): """ :param user: the to be identified user :param passw: the identification pass :param options: optional parameters, which are provided to the token checkOTP / checkPass :return: tuple of True/False and optional information """ # the upper layer will catch / at least should ;-) opt = None serial = None resolverClass = None uid = None user_exists = False if user is not None and not user.is_empty: # the upper layer will catch / at least should try: (uid, _resolver, resolverClass) = getUserId( user, check_existance=True) user_exists = True except Exception as _exx: pass_on = context.get('Config').get( 'linotp.PassOnUserNotFound', False) if pass_on and 'true' == pass_on.lower(): g.audit['action_detail'] = ( 'authenticated by PassOnUserNotFound') return (True, opt) else: g.audit['action_detail'] = 'User not found' return (False, opt) # if we have an user, check if we forward the request to another server if user_exists and get_auth_forward_on_no_token(user) is False: servers = get_auth_forward(user) if servers: res, opt = ForwardServerPolicy.do_request(servers, env, user, passw, options) return res, opt # ------------------------------------------------------------------ -- th = TokenHandler() # ------------------------------------------------------------------ -- # auto asignement with otp only if user has no active token auto_assign_otp_return = th.auto_assign_otp_only( otp=passw, user=user, options=options) if auto_assign_otp_return is True: return (True, None) # ------------------------------------------------------------------ -- token_type = None if options: token_type = options.get('token_type', None) # ------------------------------------------------------------------ -- # if there is a serial provided in the parameters, it overwrites the # token selection by user query_user = user if options and 'serial' in options and options['serial']: serial = options['serial'] query_user = None # ------------------------------------------------------------------ -- tokenList = getTokens4UserOrSerial( query_user, serial, token_type=token_type, read_for_update=True ) if len(tokenList) == 0: g.audit['action_detail'] = 'User has no tokens assigned' # here we check if we should to autoassign and try to do it auto_assign_return = th.auto_assignToken(passw, user) if auto_assign_return is True: # We can not check the token, as the OTP value is already used! # but we will auth the user.... return (True, opt) auto_enroll_return, opt = th.auto_enrollToken(passw, user, options=options) if auto_enroll_return is True: # we always have to return a false, as # we have a challenge tiggered return (False, opt) pass_on = context.get('Config').get('linotp.PassOnUserNoToken', False) if pass_on and 'true' == pass_on.lower(): g.audit['action_detail'] = 'authenticated by PassOnUserNoToken' return (True, opt) # Check if there is an authentication policy passthru if get_auth_passthru(user): log.debug('user %r has no token. Checking for ' 'passthru in realm %r' % (user.login, user.realm)) y = getResolverObject(resolverClass) g.audit['action_detail'] = 'Authenticated against Resolver' if y.checkPass(uid, passw): return (True, opt) # Check alternatively if there is an authentication # policy passOnNoToken elif get_auth_passOnNoToken(user): log.info('user %r has not token. PassOnNoToken' ' set - authenticated!') g.audit['action_detail'] = ( 'Authenticated by passOnNoToken policy') return (True, opt) # if we have an user, check if we forward the request to another server elif get_auth_forward_on_no_token(user) is True: servers = get_auth_forward(user) if servers: res, opt = ForwardServerPolicy.do_request( servers, env, user, passw, options) return res, opt return False, opt if passw is None: raise ParameterError("Missing parameter:pass", id=905) (res, opt) = self.checkTokenList( tokenList, passw, user, options=options) return (res, opt)
def checkUserPass(self, user, passw, options=None): """ :param user: the to be identified user :param passw: the identifiaction pass :param options: optional parameters, which are provided to the token checkOTP / checkPass :return: tuple of True/False and optional information """ log.debug('entering function checkUserPass(%r)' % user.login) # the upper layer will catch / at least should ;-) opt = None serial = None resolverClass = None uid = None audit = context['audit'] user_exists = False if user is not None and (user.isEmpty() == False): # the upper layer will catch / at least should try: (uid, _resolver, resolverClass) = getUserId(user) user_exists = True except: pass_on = context.get('Config').get( 'linotp.PassOnUserNotFound', False) if pass_on and 'true' == pass_on.lower(): audit['action_detail'] = ( 'authenticated by PassOnUserNotFound') return (True, opt) else: audit['action_detail'] = 'User not found' return (False, opt) # if we have an user, check if we forward the request to another server if user_exists: from linotp.lib.policy import get_auth_forward servers = get_auth_forward(user) if servers: if 'radius://' in servers: rad = RadiusRequest(servers=servers) res, opt = rad.do_request(servers, user, passw, options) return res, opt elif 'http://' in servers or 'https://' in servers: http = HttpRequest(servers=servers) res, opt = http.do_request(user, passw, options) return res, opt tokenList = linotp.lib.token.getTokens4UserOrSerial(user, serial) if len(tokenList) == 0: audit['action_detail'] = 'User has no tokens assigned' # here we check if we should to autoassign and try to do it log.debug('about to check auto_assigning') th = TokenHandler() auto_assign_return = th.auto_assignToken(passw, user) if auto_assign_return is True: # We can not check the token, as the OTP value is already used! # but we will auth the user.... return (True, opt) auto_enroll_return, opt = th.auto_enrollToken(passw, user, options=options) if auto_enroll_return is True: # we always have to return a false, as # we have a challenge tiggered return (False, opt) pass_on = context.get('Config').get('linotp.PassOnUserNoToken', False) if pass_on and 'true' == pass_on.lower(): audit['action_detail'] = 'authenticated by PassOnUserNoToken' return (True, opt) # Check if there is an authentication policy passthru from linotp.lib.policy import get_auth_passthru if get_auth_passthru(user): log.debug('user %r has no token. Checking for ' 'passthru in realm %r' % (user.login, user.realm)) y = getResolverObject(resolverClass) audit['action_detail'] = 'Authenticated against Resolver' if y.checkPass(uid, passw): return (True, opt) # Check if there is an authentication policy passOnNoToken from linotp.lib.policy import get_auth_passOnNoToken if get_auth_passOnNoToken(user): log.info('user %r has not token. PassOnNoToken' ' set - authenticated!') audit['action_detail'] = ( 'Authenticated by passOnNoToken policy') return (True, opt) return (False, opt) if passw is None: raise ParameterError(u"Missing parameter:pass", id=905) (res, opt) = self.checkTokenList( tokenList, passw, user, options=options) log.debug('return of __checkTokenList: %r ' % (res,)) return (res, opt)
def get_authenticated_user(username, realm, password=None, realm_box=False, authenticate=True, options=None): ''' check the username and password against a userstore. remark: the method is called in the context of repoze.who during authentication and during auto_enrollToken/auto_assignToken :param username: the user login name :param realm: the realm, where the user belongs to :param password: the to be checked userstore password :param realm_box: take the information, if realmbox is displayed :parm authenticate: for the selftest, we skip the authentication :return: None or authenticated user object ''' log.info("User %r from realm %r tries to authenticate to selfservice", username, realm) if type(username) != unicode: username = username.decode(ENCODING) # ease the handling of options if not options: options = {} users = [] uid = None # if we have an realmbox, we take the user as it is # - the realm is always given # - appended realms result in error if realm_box: user = User(username, realm, "") users.append(user) # else if no realm box is given # and realm is not empty: # - create the user from the values (as we are in auto_assign, etc) # and the realm is empty! (s. login.mako # - the user either appends his realm # - or will get the realm appended # else: if realm: user = User(username, realm, "") users.append(user) else: def_realm = options.get('defaultRealm', getDefaultRealm()) if def_realm: user = User(username, def_realm, "") users.append(user) if '@' in username: u_name, u_realm = username.rsplit('@', 1) user = User(u_name, u_realm, "") users.append(user) # Authenticate user auth_user = None for user in users: resolvers = [] username = user.login realm = user.realm realm_info = getRealms(user.realm) if realm_info and realm in realm_info: resolvers = realm_info.get(user.realm).get('useridresolver', []) found_uid = None for resolver_spec in resolvers: y = getResolverObject(resolver_spec) if y is None: log.error("[getResolversOfUser] [ module %r not found!]", resolver_spec) continue uid = y.getUserId(user.login) if not uid: log.debug("user %r not in resolver %r.", username, resolver_spec) continue if found_uid and uid != found_uid: raise Exception('user login %r : missmatch for userid: ' '%r:%r', user.login, found_uid, uid) if authenticate: if y.checkPass(uid, password): log.debug("Successfully authenticated user %r.", username) else: log.info("user %r failed to authenticate.", username) if found_uid: raise Exception('previous authenticated user mismatch' ' - password missmatch!') continue # add the fully qualified resolver to the resolver list user.resolvers_list.append(resolver_spec) if not found_uid: found_uid = uid auth_user = user if not auth_user: log.error("Error while trying to verify the username: %s", username) return auth_user
def getUserList(param, search_user): users = [] searchDict = {} log.debug("[getUserList] entering function getUserList") # we have to recreate a new searchdict without the realm key # as delete does not work for key in param: lval = param[key] if key == "realm": continue if key == "resConf": continue searchDict[key] = lval log.debug("[getUserList] Parameter key:%r=%r", key, lval) resolverrrs = getResolvers(search_user) for resolver_spec in resolverrrs: cls_identifier, config_identifier = parse_resolver_spec(resolver_spec) if len(search_user.resolver_config_identifier) > 0: lower_config_id = search_user.resolver_config_identifier.lower() if config_identifier.lower() != lower_config_id: continue # try to load the UserIdResolver Class try: log.debug("[getUserList] Check for resolver: %r", resolver_spec) y = getResolverObject(resolver_spec) log.debug("[getUserList] with this search dictionary: %r ", searchDict) try: ulist_gen = y.getUserListIterator(searchDict) while True: ulist = ulist_gen.next() log.debug("[getUserList] setting the resolver <%r> " "for each user", resolver_spec) for u in ulist: u["useridresolver"] = resolver_spec log.debug("[getUserList] Found this userlist: %r", ulist) users.extend(ulist) except StopIteration as exx: # we are done: all users are fetched or # page size limit reached pass except Exception as exc: log.info("Getting userlist using iterator not possible. " "Falling back to fetching userlist without iterator. " "Reason: %r", exc) ulist = y.getUserList(searchDict) for u in ulist: u["useridresolver"] = resolver_spec log.debug("[getUserList] Found this userlist: %r", ulist) users.extend(ulist) except KeyError as exx: log.exception('[getUserList][ resolver class identifier %s:%r ]', cls_identifier, exx) raise exx except Exception as exx: log.exception('[getUserList][ resolver class identifier %s:%r ]', cls_identifier, exx) continue return users
def getUserId(user, resolvers=None): """ getUserId (userObject) return (uid,resId,resIdC) """ uid = '' loginUser = user.login if not resolvers: resolvers = getResolversOfUser(user) for resolver_spec in resolvers: resId = "" resIdC = "" uid = user.getResolverUId(resolver_spec) if uid != '': (resId, resIdC, _conf) = user.getResolverConf(resolver_spec) break cls_identifier, config_identifier = parse_resolver_spec(resolver_spec) if user.resolver_config_identifier: lower_config_id = user.resolver_config_identifier.lower() if config_identifier.lower() != lower_config_id: continue # try to load the UserIdResolver Class try: log.debug('[getUserId] Getting resolver class: [%s]', cls_identifier) y = getResolverObject(resolver_spec) log.debug("[getUserId] Getting UserID for user %r", loginUser) uid = y.getUserId(loginUser) log.debug("[getUserId] Got UserId for user %r: %r", loginUser, uid) log.debug("[getUserId] Retrieving ResolverID...") resId = y.getResolverId() resIdC = resolver_spec log.debug("[getUserId] Got ResolverID: %r, Loginuser: %r, " "Uid: %r ]", resId, loginUser, uid) if uid != "": break except Exception as exx: log.exception("[getUserId] resolver class identifier %s: %r ]", cls_identifier, exx) continue if (uid == ''): log.warning("[getUserId] No uid found for the user >%r< in realm %r" % (loginUser, user.realm)) raise UserError("getUserId failed: no user >%s< found!" % unicode(loginUser), id=1205) log.debug("[getUserId] we are done!") return (unicode(uid), unicode(resId), unicode(resIdC))
def getResolversOfUser(user, use_default_realm=True, allRealms=None, defaultRealm=None): ''' This returns the list of the Resolvers of a user in a given realm. Usually this should only return one resolver input: user.login, user.realm returns: array of resolvers, the user was found in ''' login = user.login realm = user.realm if not defaultRealm: defaultRealm = getDefaultRealm() Resolvers = user.getResolvers() if len(Resolvers) > 0: return Resolvers if not login: return Resolvers if realm is None or realm == "": if use_default_realm: realm = defaultRealm if not allRealms: allRealms = getRealms() realms = allRealms if user.resolver_config_identifier != "": resolver_spec = find_resolver_spec_for_config_identifier(realms, user.resolver_config_identifier) if resolver_spec is not None: Resolvers.append(resolver_spec) else: Realm_resolvers = getResolvers(User("", realm, "")) log.debug("[getResolversOfUser] check if user %r is in resolver %r", login, Realm_resolvers) # Search for user in each resolver in the realm_ for resolver_spec in Realm_resolvers: log.debug("[getResolversOfUser] checking in %r", resolver_spec) y = getResolverObject(resolver_spec) if y is None: log.error('[getResolversOfUser] [resolver with spec %r ' 'not found!]', resolver_spec) try: log.debug("[getResolversOfUser] checking in module %r", y) uid = y.getUserId(login) log.debug("[getResolversOfUser] type of uid: %s", type(uid)) log.debug("[getResolversOfUser] type of resolver_spec: %s", type(resolver_spec)) log.debug("[getResolversOfUser] type of login: %s", type(login)) if uid not in ["", None]: log.info("[getResolversOfUser] user %r found in resolver " "%r", login, resolver_spec) log.info("[getResolversOfUser] userid resolved to %r ", uid) # Unicode Madness: # This will break as soon as the unicode "uid" is put into # a tuple # v = (login, realm_resolver, uid) # log.info("[getResolversOfUser] %s %s %s" % v) resId = y.getResolverId() resCId = resolver_spec Resolvers.append(resolver_spec) __, config_identifier = parse_resolver_spec(resolver_spec) user.addResolverUId(resolver_spec, uid, config_identifier, resId, resCId) else: log.debug("[getResolversOfUser] user %r not found" " in resolver %r", login, resolver_spec) except Exception as exx: log.exception('[getResolversOfUser] error searching user in ' 'resolver with spec %r:%r', resolver_spec, exx) log.debug("[getResolversOfUser] Resolvers: %r", Resolvers) log.debug("[getResolversOfUser] Found the user %r in %r", login, Resolvers) return Resolvers
def getUserList(param, search_user): users = [] searchDict = {} log.debug("[getUserList] entering function getUserList") # we have to recreate a new searchdict without the realm key # as delete does not work for key in param: lval = param[key] if key == "realm": continue if key == "resConf": continue searchDict[key] = lval log.debug("[getUserList] Parameter key:%r=%r" % (key, lval)) resolverrrs = getResolvers(search_user) for reso in resolverrrs: (package, module, _class, conf) = splitResolver(reso) module = package + "." + module if len(search_user.conf) > 0: if conf.lower() != search_user.conf.lower(): continue # try to load the UserIdResolver Class try: log.debug("[getUserList] Check for resolver class: %r" % reso) y = getResolverObject(reso) log.debug("[getUserList] with this search dictionary: %r " % searchDict) if hasattr(y, 'getUserListIterator'): try: ulist_gen = y.getUserListIterator(searchDict) while True: ulist = ulist_gen.next() log.debug("[getUserList] setting the resolver <%r> " "for each user" % reso) for u in ulist: u["useridresolver"] = reso log.debug("[getUserList] Found this userlist: %r" % ulist) users.extend(ulist) except StopIteration as exx: # we are done: all users are fetched or # page size limit reached pass else: ulist = y.getUserList(searchDict) for u in ulist: u["useridresolver"] = reso log.debug("[getUserList] Found this userlist: %r" % ulist) users.extend(ulist) except KeyError as exx: log.error("[getUserList][ module %r:%r ]" % (module, exx)) log.error("[getUserList] %s" % traceback.format_exc()) raise exx except Exception as exx: log.error("[getUserList][ module %r:%r ]" % (module, exx)) log.error("[getUserList] %s" % traceback.format_exc()) continue return users
def get_authenticated_user(username, realm, password=None, realm_box=False, authenticate=True, options=None): """ check the username and password against a userstore. remark: the method is called in the context of repoze.who during authentication and during auto_enrollToken/auto_assignToken :param username: the user login name :param realm: the realm, where the user belongs to :param password: the to be checked userstore password :param realm_box: take the information, if realmbox is displayed :parm authenticate: for the selftest, we skip the authentication :return: None or authenticated user object """ log.info("User %r from realm %r tries to authenticate to selfservice" % (username, realm)) if type(username) != unicode: username = username.decode(ENCODING) # ease the handling of options if not options: options = {} users = [] uid = None resolver = None resolverC = None # if we have an realmbox, we take the user as it is # - the realm is always given # - appended realms result in error if realm_box: user = User(username, realm, "") users.append(user) # else if no realm box is given # and realm is not empty: # - create the user from the values (as we are in auto_assign, etc) # and the realm is empty! (s. login.mako # - the user either appends his realm # - or will get the realm appended # else: if realm: user = User(username, realm, "") users.append(user) else: def_realm = options.get("defaultRealm", getDefaultRealm()) if def_realm: user = User(username, def_realm, "") users.append(user) if "@" in username: u_name, u_realm = username.rsplit("@", 1) user = User(u_name, u_realm, "") users.append(user) identified_users = [] for user in users: username = user.login realm = user.realm res = getResolversOfUser(user, use_default_realm=False) if len(res) != 1: if len(res) == 0: log.info("The username %r exists in NO resolver within the " "realm %r." % (username, realm)) else: log.info("The username %r exists in more than one resolver " "within the realm %r" % (username, realm)) continue # we got one resolver, so lets check if user exists (uid, resolver, resolverC) = getUserId(user) identified_users.append((user, uid, resolver, resolverC)) log.info("the user resolves to %r" % uid) log.info("The username is found within the resolver %r" % resolver) ide_user = len(identified_users) if ide_user != 1: if ide_user > 1: log.info("The username %s could not be identified uniquely" % username) if ide_user == 0: log.info("The username %s could not be found." % username) return None (user, uid, resolver, resolverC) = identified_users[0] if not authenticate: return user # Authenticate user auth_user = None try: (package, module, class_, conf) = splitResolver(resolverC) module = package + "." + module y = getResolverObject(resolverC) if y.checkPass(uid, password): log.debug("Successfully authenticated user %r." % username) auth_user = user else: log.info("user %r failed to authenticate." % username) except UserError as exx: log.info("failed to verify the username: %s@%s" % (user.login, user.realm)) if not auth_user: log.error("Error while trying to verify the username: %s" % username) return auth_user
def migrate_resolver(self, src=None, target=None, filter_serials=None): """ support the migration of owned tokens from one resolver to a new one the idea is: - get all tokens from one resolver - for each token, the the owner - from the owner get the login name - with the login name get the uid from the target resolver - update the new_id in the token """ _ = context['translate'] ret = {} if not src or not target: raise Exception("Missing src or target resolver defintion!") audit = context.get('audit') now = datetime.now() stime = now.strftime("%s") audit['action_detail'] = ( "migration from %s to %s" % (src['resolvername'], target['resolvername'])) ret['src'] = src ret['target'] = target ret['value'] = False ret['message'] = '' search = getResolverClassName(src['type'], src['resolvername']) target_resolver = getResolverClassName(target['type'], target['resolvername']) # get all tokens of src resolver tokens = self._get_tokens_for_resolver(search, serials=filter_serials) num_migration = 0 serials = set() for token in tokens: serial = token.get('LinOtpTokenSerialnumber') userid = token.get('LinOtpUserid') resolverC = token.get('LinOtpIdResClass') # now do the lookup of the uid in the # src resolver to get the login uInfo = getUserInfo(userid, '', resolverC) login = uInfo.get('username') try: y = getResolverObject(target_resolver) uid = y.getUserId(login) if not uid: log.warning("User %s not found in target resolver %r", login, target_resolver) continue token.LinOtpIdResClass = target_resolver token.LinOtpUserid = uid # TODO: adjust token.LinOtpIdResolver = target['type'] Session.add(token) num_migration += 1 serials.add(serial) except Exception as exx: log.exception( "Faild to set new resolver data for token %s: %r" % (serial, exx)) ret['value'] = True ret['message'] = (_("%d tokens of %d migrated") % (num_migration, len(tokens))) log.info(ret['message']) audit['info'] = "[%s] %s" % (stime, ret['message']) audit['serial'] = ",".join(list(serials)) audit['success'] = True context['audit'] = audit return ret
def getResolversOfUser(user): ''' This returns the list of the Resolvers of a user in a given realm. Usually this should only return one resolver input: user.login, user.realm returns: array of resolvers, the user was found in ''' login = user.login realm = user.realm Resolvers = user.getResolvers() if len(Resolvers) > 0: return Resolvers if realm is None or realm == "": realm = getDefaultRealm() #if realm is None or realm=="" or login is None or login == "": # log.error("[getResolversOfUser] You need to specify the name ( %s) and the realm (%s) of a user with conf %s" % (login, realm, user.conf)) realms = getRealms(); if user.conf != "": reso = getConf(realms, user.conf) if len(reso) > 0: Resolvers.append(reso) else: Realm_resolvers = getResolvers(User("", realm, "")) log.debug("[getResolversOfUser] check if user %r is in resolver %r" % (login, Realm_resolvers)) # Search for user in each resolver in the realm_ for realm_resolver in Realm_resolvers: log.debug("[getResolversOfUser] checking in %r" % realm_resolver) (package, module, class_, conf) = splitResolver(realm_resolver) module = package + "." + module y = getResolverObject(realm_resolver) if y is None: log.error("[getResolversOfUser] [ module %r not found!]" % (module)) try: log.debug("[getResolversOfUser] checking in module %r" % y) uid = y.getUserId(login) log.debug("[getResolversOfUser] type of uid: %s" % type(uid)) log.debug("[getResolversOfUser] type of realm_resolver: %s" % type(realm_resolver)) log.debug("[getResolversOfUser] type of login: %s" % type(login)) if uid not in ["", None]: log.debug("[getResolversOfUser] user %r found in resolver %r" % (login, realm_resolver)) log.debug("[getResolversOfUser] userid resolved to %r " % uid) ## Unicode Madness: ## This will break as soon as the unicode "uid" is put into a tuple ## v = (login, realm_resolver, uid) ## log.info("[getResolversOfUser] %s %s %s" % v) resId = y.getResolverId(); resCId = realm_resolver Resolvers.append(realm_resolver) user.addResolverUId(realm_resolver, uid, conf, resId, resCId) else: log.debug("[getResolversOfUser] user %r not found" " in resolver %r" % (login, realm_resolver)) except Exception as e: log.error("[getResolversOfUser] error searching user in" " module %r:%r" % (module, e)) log.error("[getResolversOfUser] %s" % traceback.format_exc()) log.debug("[getResolversOfUser] Resolvers: %r" % Resolvers) log.debug("[getResolversOfUser] Found the user %r in %r" % (login, Resolvers)) return Resolvers
def checkUserPass(self, user, passw, options=None): """ :param user: the to be identified user :param passw: the identification pass :param options: optional parameters, which are provided to the token checkOTP / checkPass :return: tuple of True/False and optional information """ # the upper layer will catch / at least should ;-) opt = None serial = None resolverClass = None uid = None user_exists = False if user: # the upper layer will catch / at least should try: (uid, _resolver, resolverClass) = getUserId(user, check_existance=True) user_exists = True except Exception as _exx: pass_on = context.get("Config").get( "linotp.PassOnUserNotFound", False) if pass_on and pass_on.lower() == "true": g.audit[ "action_detail"] = "authenticated by PassOnUserNotFound" return (True, opt) else: g.audit["action_detail"] = "User not found" return (False, opt) # if we have an user, check if we forward the request to another server if user_exists and not get_auth_forward_on_no_token(user): servers = get_auth_forward(user) if servers: log.info("forwarding auth request for user {} to {}".format( user, servers)) res, opt = ForwardServerPolicy.do_request( servers, env, user, passw, options) log.info("result of auth request for user {}: ({}, {})".format( user, res, opt)) g.audit["action_detail"] = "Forwarded, result {}".format(res) return res, opt else: log.info( "NOT forwarding auth request for user {} (no servers)". format(user)) g.audit["action_detail"] = "Not forwarded (no servers)" else: log.info( "NOT forwarding auth request for user {} " "(get_auth_forward_on_no_token returned False)".format(user)) # ------------------------------------------------------------------ -- th = TokenHandler() # ------------------------------------------------------------------ -- # auto asignement with otp only if user has no active token auto_assign_otp_return = th.auto_assign_otp_only(otp=passw, user=user, options=options) if auto_assign_otp_return: return (True, None) # ------------------------------------------------------------------ -- token_type = None if options: token_type = options.get("token_type", None) # ------------------------------------------------------------------ -- # if there is a serial provided in the parameters, it overwrites the # token selection by user query_user = user if options and "serial" in options and options["serial"]: serial = options["serial"] query_user = None # ------------------------------------------------------------------ -- tokenList = getTokens4UserOrSerial(query_user, serial, token_type=token_type, read_for_update=True) if len(tokenList) == 0: g.audit["action_detail"] = "User has no tokens assigned" # here we check if we should to autoassign and try to do it auto_assign_return = th.auto_assignToken(passw, user) if auto_assign_return: # We can not check the token, as the OTP value is already used! # but we will auth the user.... return (True, opt) auto_enroll_return, opt = th.auto_enrollToken(passw, user, options=options) if auto_enroll_return: # we always have to return a false, as # we have a challenge tiggered return (False, opt) pass_on = context.get("Config").get("linotp.PassOnUserNoToken", False) if pass_on and pass_on.lower() == "true": g.audit["action_detail"] = "authenticated by PassOnUserNoToken" return (True, opt) # Check if there is an authentication policy passthru if get_auth_passthru(user): log.debug( "user %r has no token. Checking for passthru in realm %r", user.login, user.realm, ) y = getResolverObject(resolverClass) g.audit["action_detail"] = "Authenticated against Resolver" if y.checkPass(uid, passw): return (True, opt) # Check alternatively if there is an authentication # policy passOnNoToken elif get_auth_passOnNoToken(user): log.info("user %r has not token. PassOnNoToken" " set - authenticated!") g.audit[ "action_detail"] = "Authenticated by passOnNoToken policy" return (True, opt) # if we have an user, check if we forward the request to another # server elif get_auth_forward_on_no_token(user): servers = get_auth_forward(user) if servers: log.info( "forwarding auth request for user {} to {}".format( user, servers)) res, opt = ForwardServerPolicy.do_request( servers, env, user, passw, options) log.info( "result of auth request for user {}: ({}, {})".format( user, res, opt)) g.audit["action_detail"] = "Forwarded, result {}".format( res) return res, opt else: log.info( "NOT forwarding auth request for user {} (no servers)". format(user)) g.audit["action_detail"] = "Not forwarded (no servers)" return False, opt if passw is None: raise ParameterError("Missing parameter:pass", id=905) (res, opt) = self.checkTokenList(tokenList, passw, user, options=options) return (res, opt)
def check_pin(token, passw, user=None, options=None): ''' check the provided pin w.r.t. the policy definition :param passw: the to be checked pass :param user: if otppin==1, this is the user, which resolver should be checked :param options: the optional request parameters :return: boolean, if pin matched True ''' res = False pin_policies = linotp.lib.policy.get_pin_policies(user) if 1 in pin_policies: # We check the Users Password as PIN log.debug("pin policy=1: checking the users password as pin") # this should not be the case if not options: options = {} if 'pin_match' not in options: options['pin_match'] = {} hashed_passw = sha256(passw.encode('utf-8')).hexdigest() # if password already found, we can return result again if hashed_passw in options['pin_match']: log.debug("check if password already checked! %r " % options['pin_match'][hashed_passw]) return options['pin_match'][hashed_passw] # if a password already matched, this one will fail if 'found' in options['pin_match']: log.debug("check if password already found but its not this one!") return False if user is None or not user.login: log.info("fail for pin policy == 1 with user = None") res = False else: (uid, _resolver, resolver_class) = getUserId(user) resolver = getResolverObject(resolver_class) if resolver.checkPass(uid, passw): log.debug("Successfully authenticated user %r." % uid) res = True else: log.info("user %r failed to authenticate." % uid) # we register our result key = sha256(passw.encode('utf-8')).hexdigest() options['pin_match'][key] = res # and register the success, to shorten lookups after # already one positive was found if res is True: options['pin_match']['found'] = True elif 2 in pin_policies: # NO PIN should be entered atall log.debug("[__checkToken] pin policy=2: checking no pin") if len(passw) == 0: res = True else: # old stuff: We check The fixed OTP PIN log.debug("[__checkToken] pin policy=0: checkin the PIN") res = token.checkPin(passw, options=options) return res
def check_pin(token, passw, user=None, options=None): ''' check the provided pin w.r.t. the policy definition :param passw: the to be checked pass :param user: if otppin==1, this is the user, which resolver should be checked :param options: the optional request parameters :return: boolean, if pin matched True ''' res = False otppin_mode = _get_otppin_mode(get_pin_policies(user)) if 1 == otppin_mode: # We check the Users Password as PIN log.debug("pin policy=1: checking the users password as pin") # this should not be the case if not options: options = {} selfservice_state = context.get('selfservice', {}).get('state', '') if selfservice_state in ['credentials_verified', 'challenge_triggered']: return True if 'pin_match' not in options: options['pin_match'] = {} hashed_passw = sha256(passw.encode('utf-8')).hexdigest() # if password already found, we can return result again if hashed_passw in options['pin_match']: log.debug("check if password already checked! %r " % options['pin_match'][hashed_passw]) return options['pin_match'][hashed_passw] # if a password already matched, this one will fail if 'found' in options['pin_match']: log.debug("check if password already found but its not this one!") return False if user is None or not user.login: log.info("fail for pin policy == 1 with user = None") res = False else: (uid, _resolver, resolver_class) = getUserId(user) resolver = getResolverObject(resolver_class) if resolver.checkPass(uid, passw): log.debug("Successfully authenticated user %r." % uid) res = True else: log.info("user %r failed to authenticate." % uid) # we register our result key = sha256(passw.encode('utf-8')).hexdigest() options['pin_match'][key] = res # and register the success, to shorten lookups after # already one positive was found if res is True: options['pin_match']['found'] = True return res elif otppin_mode == 2: # NO PIN should be entered atall log.debug("[__checkToken] pin policy=2: checking no pin") return len(passw) == 0 elif otppin_mode == 3: # ignore pin or password log.debug("[__checkToken] pin policy=3: ignoreing pin") if token.type in ['spass']: return token.checkPin(passw, options=options) return True else: # old stuff: We check The fixed OTP PIN log.debug("[__checkToken] pin policy=0: checkin the PIN") return token.checkPin(passw, options=options)
def checkUserPass(self, user, passw, options=None): """ :param user: the to be identified user :param passw: the identification pass :param options: optional parameters, which are provided to the token checkOTP / checkPass :return: tuple of True/False and optional information """ # the upper layer will catch / at least should ;-) opt = None serial = None resolverClass = None uid = None audit = context['audit'] user_exists = False if user is not None and not user.is_empty: # the upper layer will catch / at least should try: (uid, _resolver, resolverClass) = getUserId( user, check_existance=True) user_exists = True except Exception as _exx: pass_on = context.get('Config').get( 'linotp.PassOnUserNotFound', False) if pass_on and 'true' == pass_on.lower(): audit['action_detail'] = ( 'authenticated by PassOnUserNotFound') return (True, opt) else: audit['action_detail'] = 'User not found' return (False, opt) # if we have an user, check if we forward the request to another server if user_exists and get_auth_forward_on_no_token(user) is False: servers = get_auth_forward(user) if servers: res, opt = ForwardServerPolicy.do_request(servers, env, user, passw, options) return res, opt # ------------------------------------------------------------------ -- th = TokenHandler() # ------------------------------------------------------------------ -- # auto asignement with otp only if user has no active token auto_assign_otp_return = th.auto_assign_otp_only( otp=passw, user=user, options=options) if auto_assign_otp_return is True: return (True, None) # ------------------------------------------------------------------ -- token_type = None if options: token_type = options.get('token_type', None) # ------------------------------------------------------------------ -- # if there is a serial provided in the parameters, it overwrites the # token selection by user query_user = user if options and 'serial' in options and options['serial']: serial = options['serial'] query_user = None # ------------------------------------------------------------------ -- tokenList = getTokens4UserOrSerial( query_user, serial, token_type=token_type, read_for_update=True ) if len(tokenList) == 0: audit['action_detail'] = 'User has no tokens assigned' # here we check if we should to autoassign and try to do it auto_assign_return = th.auto_assignToken(passw, user) if auto_assign_return is True: # We can not check the token, as the OTP value is already used! # but we will auth the user.... return (True, opt) auto_enroll_return, opt = th.auto_enrollToken(passw, user, options=options) if auto_enroll_return is True: # we always have to return a false, as # we have a challenge tiggered return (False, opt) pass_on = context.get('Config').get('linotp.PassOnUserNoToken', False) if pass_on and 'true' == pass_on.lower(): audit['action_detail'] = 'authenticated by PassOnUserNoToken' return (True, opt) # Check if there is an authentication policy passthru if get_auth_passthru(user): log.debug('user %r has no token. Checking for ' 'passthru in realm %r' % (user.login, user.realm)) y = getResolverObject(resolverClass) audit['action_detail'] = 'Authenticated against Resolver' if y.checkPass(uid, passw): return (True, opt) # Check alternatively if there is an authentication # policy passOnNoToken elif get_auth_passOnNoToken(user): log.info('user %r has not token. PassOnNoToken' ' set - authenticated!') audit['action_detail'] = ( 'Authenticated by passOnNoToken policy') return (True, opt) # if we have an user, check if we forward the request to another server elif get_auth_forward_on_no_token(user) is True: servers = get_auth_forward(user) if servers: res, opt = ForwardServerPolicy.do_request( servers, env, user, passw, options) return res, opt return False, opt if passw is None: raise ParameterError(u"Missing parameter:pass", id=905) (res, opt) = self.checkTokenList( tokenList, passw, user, options=options) return (res, opt)