def get_userinfo(self, username, password, command): """Authenticate user against user DB. Returns 1 on success and None otherwise. """ refresh_users(configuration, 'davs') usermap = {} for user_obj in self.server_conf.daemon_conf['users']: if not usermap.has_key(user_obj.username): usermap[user_obj.username] = [] usermap[user_obj.username].append(user_obj) self.users = usermap logger.debug("get_userinfo found users: %s" % self.users) host = configuration.daemon_conf.get('address') port = configuration.daemon_conf.get('port') verbose = self._config.DAV.getboolean('verbose') if 'password' in self.server_conf.user_davs_auth and \ self._check_auth_password(username, password): logger.info("Authenticated %s" % username) # dispatch directory and host to the filesystem handler # responsible for deciding where to take the data from self._chroot_user(username, host, port, verbose) return 1 else: err_msg = "Password authentication failed for %s" % username logger.error(err_msg) print err_msg return None
def update_users(configuration, user_map, username=None): """Update dict with username password pairs. The optional username argument limits the update to that particular user with aliases. """ if username is not None: refresh_user_creds(configuration, 'davs', username) else: refresh_users(configuration, 'davs') domain_map = user_map.get(dav_domain, {}) for user_obj in configuration.daemon_conf['users']: # print "DEBUG: user %s : %s" % (user_obj.username, user_obj.digest) user_dict = domain_map.get(user_obj.username, {}) if user_obj.password: user_dict['password_hash'] = user_obj.password if user_obj.digest: user_dict['password'] = user_obj.digest domain_map[user_obj.username] = user_dict daemon_conf = configuration.daemon_conf if username is None and daemon_conf.get('enable_litmus', False): litmus_name = 'litmus' litmus_user = {} litmus_home = os.path.join(configuration.user_home, litmus_name) try: os.makedirs(litmus_home) except: pass for auth in ('basic', 'digest'): if not daemon_conf.get('accept%s' % auth, False): continue logger.info("enabling litmus %s test accounts" % auth) if auth == 'basic': litmus_user['password_hash'] = generate_password_hash('test') else: litmus_user['password'] = generate_password_digest( dav_domain, litmus_name, 'test', configuration.site_digest_salt) domain_map[litmus_name] = litmus_user user_map[dav_domain] = domain_map
def update_logins(self, username): """Update login DB""" # We don't have a handle_request for server so expire here instead if self.last_expire + self.min_expire_delay < time.time(): self.last_expire = time.time() expired = expire_rate_limit(configuration, "ftps") logger.debug("expired rate limit entries: %s" % expired) # TODO: only refresh for username? daemon_conf = configuration.daemon_conf logger.debug("update user list") # automatic reload of users if more than refresh_delay seconds old refresh_delay = 5 if daemon_conf['time_stamp'] + refresh_delay < time.time(): daemon_conf = refresh_users(configuration, 'ftps') logger.debug("update usermap") usermap = {} for user_obj in daemon_conf['users']: if not usermap.has_key(user_obj.username): usermap[user_obj.username] = [] usermap[user_obj.username].append(user_obj) self.users = usermap logger.info("updated usermap: %s" % self.users) logger.debug("update user_table") # Fill users in dictionary for fast lookup. We create a list of # matching User objects since each user may have multiple logins (e.g. # public keys) for (username, user_obj_list) in self.users.items(): if self.has_user(username): self.remove_user(username) # We prefer last entry with password but fall back to any entry # to assure at least a hit user_obj = (user_obj_list + [i for i in user_obj_list \ if i.password is not None])[-1] home_path = os.path.join(daemon_conf['root_dir'], user_obj.home) logger.debug("add user to user_table: %s" % user_obj) # The add_user format and perm string meaning is explained at: # http://code.google.com/p/pyftpdlib/wiki/Tutorial#2.2_-_Users self.add_user(username, user_obj.password, home_path, perm='elradfmwM') logger.debug("updated user_table: %s" % self.user_table)
# accept may return None or tuple with None part in corner cases if client_tuple == None or None in client_tuple: raise Exception('got empty bogus request') (client, addr) = client_tuple except KeyboardInterrupt: # forward KeyboardInterrupt to main thread server_socket.close() raise except Exception, err: logger.warning('ignoring failed client connection for %s: %s' % \ (client_tuple, err)) continue # automatic reload of users if more than refresh_delay seconds old refresh_delay = 5 if daemon_conf['time_stamp'] + refresh_delay < time.time(): daemon_conf = refresh_users(configuration, 'sftp') daemon_conf = refresh_jobs(configuration, 'sftp') logger.info("Handling session from %s %s" % (client, addr)) worker = threading.Thread(target=accept_client, args=[client, addr, daemon_conf['root_dir'], daemon_conf['users'], daemon_conf['jobs'], daemon_conf['host_rsa_key'], daemon_conf,]) worker.start() if last_expire + min_expire_delay < time.time(): last_expire = time.time() expired = expire_rate_limit(configuration, "sftp-*") logger.debug("Expired rate limit entries: %s" % expired)