version = (1, 0, 0) # meta developer: @RUIS_VlP import random from datetime import timedelta from telethon import TelegramClient, events from telethon import functions from telethon.tl.types import Message import os from .. import loader, utils import paramiko def upload_file_sftp(host, port, username, password, local_file, remote_file): try: # Создаем экземпляр SSHClient client = paramiko.SSHClient() # Загружаем параметры по умолчанию client.load_system_host_keys() # Разрешаем соединение с сервером, если ключа нет в системе client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # Подключаемся к серверу client.connect(hostname=host, port=port, username=username, password=password) # Открываем SFTP сессию sftp = client.open_sftp() try: sftp.listdir("sshmod") except IOError: sftp.mkdir("sshmod") # Загружаем файл sftp.put(local_file, remote_file) print(f'Файл {local_file} успешно загружен на {remote_file}') except Exception as e: print(f'Произошла ошибка: {e}') finally: # Закрываем SFTP сессию и SSH соединение if 'sftp' in locals(): sftp.close() client.close() def execute_ssh_command(host, port, username, password, command): try: # Создаем экземпляр SSHClient client = paramiko.SSHClient() # Загружаем параметры по умолчанию client.load_system_host_keys() # Разрешаем соединение с сервером, если ключа нет в системе client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # Подключаемся к серверу client.connect(hostname=host, port=port, username=username, password=password) # Выполняем команду stdin, stdout, stderr = client.exec_command(command) # Получаем вывод и ошибки output = stdout.read().decode() error = stderr.read().decode() exit_code = stdout.channel.recv_exit_status() return exit_code, output, error except Exception as e: print(f'Произошла ошибка: {e}') return None, None, str(e) finally: # Закрываем SSH соединение client.close() @loader.tds class SSHMod(loader.Module): """SSH module for uploading files and executing commands""" strings = { "name": "SSHMod", "cfg_host": "IP address or domain", "cfg_username": "SSH username", "cfg_password": "SSH password", "cfg_port": "SSH port", "save_description": " - saves the file to the ~/sshmod directory", "save_uploading": "Starting upload....", "save_success": "File uploaded to SSH server, file location: ~/sshmod/{}", "save_no_file": "No files found in the message!", "save_reply_required": "The command must be a reply to a message!", "sterminal_description": " - executes a command on the SSH server", "sterminal_no_command": "No command specified!", "sterminal_output": "⌨️ System command\n
{}
\nExit code: {}\n📼 Output:\n
{}
", "sterminal_error": "⌨️ System command\n
{}
\nExit code: {}\n🚫 Errors:\n
{}
", "sterminal_output_and_error": "⌨️ System command\n
{}
\nExit code: {}\n📼 Output:\n
{}
\n🚫 Errors:\n
{}
", "config_not_set": "Values are not set. Set them using the command:\n.config SSHMod", } strings_ru = { "name": "SSHMod", "cfg_host": "IP-адрес или домен", "cfg_username": "Имя пользователя SSH", "cfg_password": "Пароль SSH", "cfg_port": "Порт SSH", "save_description": " - сохраняет файл в директорию ~/sshmod", "save_uploading": "Начинаю загрузку....", "save_success": "Файл загружен на SSH сервер, расположение файла: ~/sshmod/{}", "save_no_file": "В сообщении не найдены файлы!", "save_reply_required": "Команда должна быть ответом на сообщение!", "sterminal_description": " - выполняет команду на SSH сервере", "sterminal_no_command": "Не указана команда для выполнения!", "sterminal_output": "⌨️ Системная команда\n
{}
\nКод выхода: {}\n📼 Вывод:\n
{}
", "sterminal_error": "⌨️ Системная команда\n
{}
\nКод выхода: {}\n🚫 Ошибки:\n
{}
", "sterminal_output_and_error": "⌨️ Системная команда\n
{}
\nКод выхода: {}\n📼 Вывод:\n
{}
\n🚫 Ошибки:\n
{}
", "config_not_set": "Значения не указаны. Укажите их через команду:\n.config SSHMod", } def __init__(self): self.config = loader.ModuleConfig( loader.ConfigValue( "host", "None", lambda: self.strings["cfg_host"], validator=loader.validators.String(), ), loader.ConfigValue( "username", "None", lambda: self.strings["cfg_username"], validator=loader.validators.String(), ), loader.ConfigValue( "password", "None", lambda: self.strings["cfg_password"], validator=loader.validators.Hidden(), ), loader.ConfigValue( "Port", 22, lambda: self.strings["cfg_port"], validator=loader.validators.String(), ), ) @loader.command(alias="save") async def save(self, message): """ - saves the file to the ~/sshmod directory""" host = self.config["host"] or "None" username = self.config["username"] or "None" password = self.config["password"] or "None" port = self.config["Port"] or "None" if host == "None" or username == "None" or password == "None" or port == "None": await utils.answer(message, self.strings["config_not_set"]) return reply = await message.get_reply_message() if reply: if reply.media: await utils.answer(message, self.strings["save_uploading"]) file_path = await message.client.download_media(reply.media) sftp_path = f"sshmod/{os.path.basename(file_path)}" upload_file_sftp(host, port, username, password, file_path, sftp_path) os.remove(file_path) await utils.answer( message, self.strings["save_success"].format(os.path.basename(file_path)), ) else: await utils.answer(message, self.strings["save_no_file"]) else: await utils.answer(message, self.strings["save_reply_required"]) @loader.command(alias="sterminal") async def sterminal(self, message): """ - executes a command on the SSH server""" host = self.config["host"] or "None" username = self.config["username"] or "None" password = self.config["password"] or "None" port = self.config["Port"] or "None" if host == "None" or username == "None" or password == "None" or port == "None": await utils.answer(message, self.strings["config_not_set"]) return command = utils.get_args_raw(message) if not command: await utils.answer(message, self.strings["sterminal_no_command"]) return # Выполняем команду на SSH сервере exit_code, output, error = execute_ssh_command(host, port, username, password, command) # Формируем ответ в зависимости от наличия вывода и ошибок if output and not error: response = self.strings["sterminal_output"].format(command, exit_code, output) elif error and not output: response = self.strings["sterminal_error"].format(command, exit_code, error) elif output and error: response = self.strings["sterminal_output_and_error"].format(command, exit_code, output, error) else: response = f"⌨️ System command\n
{command}
\nExit code: {exit_code}" await utils.answer(message, response)