import os.path import argparse from pyftpdlib.authorizers import DummyAuthorizer from pyftpdlib.handlers import FTPHandler from pyftpdlib.servers import FTPServer import pickle import sys import getpass import os from termcolor import colored import shutil import subprocess from base64 import b64encode from cryptography.fernet import Fernet FTP_ROOT = '../ftp_root' CONFIG = '../ftp_root/.config.ppi' ############################################################################################## SECRET_KEY = '3ZUFfXlEWyzKrMC1JwNa2qNU5SfOfZyjy7gedd8bBgo=' # NO CAMBIAR BAJO NINGUN CONCEPTO, ############################################################# LOS TOKENS ANTERIORES AL CAMBIO DEJARAN DE FUNCIONAR NotUsers = type('NotUsers', (Exception, ), {}) NameExists = type('NameExists', (Exception, ), {}) UserDoesNotExists = type('UserDoesNotExists', (Exception, ), {}) credentials_formats = {'video_server' : lambda user, password: b64encode(b"{}:{}".format(user, password)())} def run_ftpd(anon): if not os.path.exists(CONFIG): raise NotUsers('There are not users registered!') config = pickle.load(open(CONFIG, 'rb')) if len(config)==0: raise NotUsers('There are not users registered!') authorizer = DummyAuthorizer() for user in [user for user in config if config[user]['enabled']]: user_dir = os.path.join(FTP_ROOT, user) if not os.path.isdir(user_dir): os.mkdir(user_dir) authorizer.add_user(user, config[user]['password'], user_dir, perm="elradfmw") if anon: anon_dir = os.path.join(FTP_ROOT, 'anonymous') if not os.path.isdir(anon_dir): os.mkdir(anon_dir) authorizer.add_anonymous(anon_dir) handler = FTPHandler handler.authorizer = authorizer handler.permit_foreign_addresses = True port=os.environ['PORT'] out = subprocess.Popen('hostname -i', stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True) host, _ = out.communicate() host = host.decode().replace('\n', '') passive = "30017-30018" passive_ports = list(map(int, passive.split('-'))) handler.passive_ports = range(passive_ports[0], passive_ports[1]) server = FTPServer(('0.0.0.0', port), handler) server.serve_forever() def disable(user): config_file = open(CONFIG, 'rb') config = pickle.load(config_file) config_file.close() config[user]['enabled'] = False config_file = open(CONFIG, 'wb') pickle.dump(config, config_file) config_file.close() print(colored('User {} disabled'.format(user), 'green')) def enable(user): config_file = open(CONFIG, 'rb') config = pickle.load(config_file) config_file.close() config[user]['enabled'] = True user_pass = config[user]['password'] # Writing_credentials ############################### credentials_file = os.path.join(FTP_ROOT, user, '.token.txt') with open(credentials_file, 'w') as cred_file: cred_file.write(Fernet(SECRET_KEY.encode()).encrypt('{}:{}'.format(user, user_pass).encode()).decode('ascii')) ##################################################### config_file = open(CONFIG, 'wb') pickle.dump(config, config_file) config_file.close() print(colored('User {} enabled'.format(user), 'green')) def delete(user): config_file = open(CONFIG, 'rb') config = pickle.load(config_file) config_file.close() if user not in config: raise UserDoesNotExists('User {} does not exists'.format(user)) delete_str = input(colored('All saved data from user {} will be deleted: Are you sure?[default=no] (yes/no) '.format(user), 'yellow')) if delete_str == 'yes': del config[user] user_dir = os.path.join(FTP_ROOT, user) config_file = open(CONFIG, 'wb') pickle.dump(config, config_file) config_file.close() shutil.rmtree(user_dir) print(colored('User {} deleted'.format(user), 'green')) else: print(colored('User deletion canceled'.format(user), 'green')) def add(user): user_dir = os.path.join(FTP_ROOT, user) if os.path.exists(user_dir): raise NameExists('Change to other name, please!') try: p = getpass.getpass("Password for user {}: ".format(user)) except Exception as error: print('ERROR', error) try: config_file = open(CONFIG, 'rb+') config = pickle.load(config_file) config_file.close() except FileNotFoundError: config = {} if user in list(config.keys()): raise NameExists('Change to other name, please!') config.update({user: {'password': p, 'enabled':False}}) os.system("mkdir -p {}".format(user_dir)) config_file = open(CONFIG, 'wb') pickle.dump(config, config_file) config_file.close() print(colored('User {} added'.format(user), 'green')) enable(user) def main(): # PARENT PARSER parser = argparse.ArgumentParser( formatter_class=argparse.ArgumentDefaultsHelpFormatter ) subparsers = parser.add_subparsers() # RUN PARSER ########################## parser_run = subparsers.add_parser('run', help='Start ftp server') parser_run.add_argument( '--anon', default=False, help="Allow anonymous users") parser_run.set_defaults(func=run_ftpd) ####################################### # DISABLE PARSER ########################## parser_disable = subparsers.add_parser('disable', help='Disable user') parser_disable.add_argument( 'user', help="User name to disable it") parser_disable.set_defaults(func=disable) ####################################### # ENABLE PARSER ########################## parser_enable = subparsers.add_parser('enable', help='Enable user') parser_enable.add_argument( 'user', help="User name to enable it") parser_enable.set_defaults(func=enable) ####################################### # DELETE PARSER ########################## parser_delete = subparsers.add_parser('delete', help='Delete user') parser_delete.add_argument( 'user', help="User to delete") parser_delete.set_defaults(func=delete) ####################################### # ADD PARSER ########################## parser_add = subparsers.add_parser('add', help='Add user') parser_add.add_argument( 'user', help="Username to add") parser_add.set_defaults(func=add) ####################################### if not sys.argv[1:]: parser.parse_args(['--help']) args = parser.parse_args(sys.argv[1:]) # args = parser_run.parse_args() parameters = vars(args).copy() del parameters['func'] args.func(**parameters) if __name__ == '__main__': main()