def __init__(self, host, user_id, password=None, key_file=None): self.user_id = user_id self.transport = paramiko.Transport(sock="{}:{}".format(host, 22)) sshuser = SshUser.objects.filter(username_id=user_id).first() self.username = sshuser.username.username passwd = sshuser.password if passwd: password = base64.b64decode(passwd).decode('utf-8') else: password = None if sshuser.is_key: string_io = StringIO() string_io.write(sshuser.ssh_key) string_io.flush() string_io.seek(0) ssh_key = string_io key = get_key_obj(paramiko.RSAKey, pkey_obj=ssh_key, password=password) or \ get_key_obj(paramiko.DSSKey, pkey_obj=ssh_key, password=password) or \ get_key_obj(paramiko.ECDSAKey, pkey_obj=ssh_key, password=password) or \ get_key_obj(paramiko.Ed25519Key, pkey_obj=ssh_key, password=password) self.transport.connect(username=self.username, pkey=key) else: self.transport.connect(username=self.username, password=password) self.sftp = paramiko.SFTPClient.from_transport(self.transport)
def connect(self): try: self.accept() query_string = self.scope['query_string'] connet_argv = QueryDict(query_string=query_string, encoding='utf-8') unique = connet_argv.get('unique') width = connet_argv.get('width') height = connet_argv.get('height') width = int(width) height = int(height) connect_info = models.HostTmp.objects.get(unique=unique) host = connect_info.host port = connect_info.port user = connect_info.user auth = connect_info.auth pwd = connect_info.password pkey = connect_info.pkey connect_info.delete() if pwd: password = base64.b64decode(pwd).decode('utf-8') else: password = None self.ssh = SSH(websocker=self, message=self.message) if auth == 'key': pkey = pkey obj = StringIO() obj.write(pkey) obj.flush() obj.seek(0) self.pkey = obj self.ssh.connect(host=host, user=user, password=password, pkey=self.pkey, port=port, pty_width=width, pty_height=height) else: self.ssh.connect(host=host, user=user, password=password, port=port, pty_width=width, pty_height=height) except Exception as e: self.message['status'] = 1 self.message['message'] = str(e) message = json.dumps(self.message) self.send(message) self.close()
def connect(self): """ 打开 websocket 连接, 通过前端传入的参数尝试连接 ssh 主机 :return: """ self.accept() query_string = self.scope.get('query_string') ssh_args = QueryDict(query_string=query_string, encoding='utf-8') width = ssh_args.get('width') height = ssh_args.get('height') port = ssh_args.get('port') width = int(width) height = int(height) port = int(port) auth = ssh_args.get('auth') ssh_key_name = ssh_args.get('ssh_key') passwd = ssh_args.get('password') host = ssh_args.get('host') user = ssh_args.get('user') if passwd: passwd = base64.b64decode(passwd).decode('utf-8') else: passwd = None self.ssh = SSH(websocker=self, message=self.message) ssh_connect_dict = { 'host': host, 'user': user, 'port': port, 'timeout': 30, 'pty_width': width, 'pty_height': height, 'password': passwd } if auth == 'key': # ssh_key_file = os.path.join(settings.MEDIA_ROOT, ssh_key_name) # with open(ssh_key_file, 'r') as f: # ssh_key = f.read() #从数据库获取秘钥信息 ssh_key = SshUser.objects.filter(username=user).values_list( 'ssh_key', flat=True)[0] string_io = StringIO() string_io.write(ssh_key) string_io.flush() string_io.seek(0) ssh_connect_dict['ssh_key'] = string_io # os.remove(ssh_key_file) self.ssh.connect(**ssh_connect_dict)
def connect(self): """ 打开 websocket 连接, 通过前端传入的参数尝试连接 ssh 主机 :return: """ self.accept() query_string = self.scope.get('query_string') ssh_args = QueryDict(query_string=query_string, encoding='utf-8') width = ssh_args.get('width') height = ssh_args.get('height') port = ssh_args.get('port') width = int(width) height = int(height) port = int(port) auth = ssh_args.get('auth') ssh_key_name = ssh_args.get('ssh_key') passwd = ssh_args.get('password') host = ssh_args.get('host') user = ssh_args.get('user') terminal_id = ssh_args.get("terminal_id") if passwd: passwd = base64.b64decode(passwd).decode('utf-8') else: passwd = None self.ssh = SSH(websocker=self, message=self.message) ssh_connect_dict = { 'host': host, 'user': user, 'port': port, 'timeout': 30, 'pty_width': width, 'pty_height': height, 'password': passwd, 'terminal_id': terminal_id } if auth == 'key': ssh_key_file = os.path.join(TMP_DIR, ssh_key_name) with open(ssh_key_file, 'r') as f: ssh_key = f.read() string_io = StringIO() string_io.write(ssh_key) string_io.flush() string_io.seek(0) ssh_connect_dict['ssh_key'] = string_io os.remove(ssh_key_file) self.ssh.connect(**ssh_connect_dict)
def connect(self): self.accept() query_string = self.scope.get('query_string') # print(query_string) ssh_args = QueryDict(query_string=query_string, encoding='utf-8') width = int(ssh_args.get('width')) height = int(ssh_args.get('height')) port = int(ssh_args.get('port')) auth = ssh_args.get('auth') ssh_key_name = ssh_args.get('ssh_key') passwd = ssh_args.get('password') host = ssh_args.get('host') user = ssh_args.get('user') if passwd: passwd = base64.b64decode(passwd).decode('utf-8') # password = password else: passwd = None self.ssh = SSH(websocket=self, message=self.message) ssh_connect_dict = { 'host': host, 'user': user, 'port': port, 'timeout': 30, 'pty_width': width, 'pty_height': height, 'password': passwd } if auth == 'key': ssh_key_file = os.path.join(TMP_DIR, ssh_key_name) with open(ssh_key_file, 'r') as fp: ssh_key = fp.read() string_io = StringIO() string_io.write(ssh_key) string_io.flush() string_io.seek() ssh_connect_dict['ssh_key'] = string_io os.remove(ssh_key_file) # print(ssh_connect_dict) self.ssh.connect(**ssh_connect_dict)
def connect(self): self.accept() print(self.user) # user = SshUser.objects.get(username =self.user) user = User.objects.filter(username=self.user).first() # print(user) sshuser = SshUser.objects.filter(username_id=user.id).first() # print(sshuser) try: self.ssh.load_system_host_keys() self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) if sshuser.is_key: string_io = StringIO() string_io.write(sshuser.ssh_key) string_io.flush() string_io.seek(0) ssh_key = string_io passwd = sshuser.password if passwd: password = base64.b64decode(passwd).decode('utf-8') else: password = None key = get_key_obj(paramiko.RSAKey, pkey_obj=ssh_key, password=password) or \ get_key_obj(paramiko.DSSKey, pkey_obj=ssh_key, password=password) or \ get_key_obj(paramiko.ECDSAKey, pkey_obj=ssh_key, password=password) or \ get_key_obj(paramiko.Ed25519Key, pkey_obj=ssh_key, password=password) self.ssh.connect(username=user.username, hostname=self.ssh_server_ip, port=22, pkey=key,timeout=5) else: self.ssh.connect(username=user.username, hostname=self.ssh_server_ip, port=22, password=user.password,timeout=5) transport = self.ssh.get_transport() self.chan = transport.open_session() self.chan.get_pty(term='xterm', width=1400, height=self.height) self.chan.invoke_shell() # 设置如果3分钟没有任何输入,就断开连接 self.chan.settimeout(60 * 3) except Exception as e: print('用户{}通过webssh连接{}失败!原因:{}'.format(user.username, self.ssh_server_ip, e)) self.send('用户{}通过webssh连接{}失败!原因:{}'.format(user.username, self.ssh_server_ip, e)) self.close() self.t1.setDaemon(True) self.t1.start()
class RetrieveCategoriesTest(unittest.TestCase): def setUp(self): self.out = StringIO() self.out.flush() self.derr = StringIO() self.derr.flush() def test_executeFilepathsEmpty_regresaException(self): self.assertRaises(CommandError, call_command, 'retrieve_categories', stdout=self.out, stderr=self.derr) def test_executeInvalidFilePath_regresaLog(self): call_command('retrieve_categories', 'file1', stderr=self.out, stdio=self.derr) self.assertIn('An error occurred while processing this file: file1', self.out.getvalue())
class ImportTests(TestCase): def setUp(self): self.data_dir = os.path.abspath( os.path.join(dashboard.__path__[0], "../../test_data")) self.out = StringIO() self.args = [] self.options = { 'user_data_loc': os.path.join(self.data_dir, "user_data.csv"), 'user_consumption_loc': os.path.join(self.data_dir, "consumption") } def test_import_function_and_append(self): """ Check basic import functioning. """ self.out.flush() call_command('import', *self.args, **self.options, stdout=self.out) self.assertEquals(UserData.objects.all().count(), 3) self.assertEquals(ConsumptionTimePoint.objects.all().count(), 9) self.assertEquals(TimePointAggregateData.objects.all().count(), 3) self.assertIn("Import completed.", self.out.getvalue()) """ Check append a doesn't add additional objects that already exist. """ self.out.flush() self.options['append'] = True call_command('import', *self.args, **self.options, stdout=self.out) self.assertEquals(UserData.objects.all().count(), 3) self.assertEquals(ConsumptionTimePoint.objects.all().count(), 9) self.assertEquals(TimePointAggregateData.objects.all().count(), 3) self.assertIn("Import completed.", self.out.getvalue()) def test_import_invalid_file_path(self): """ Check invalid filepath. """ self.out.flush() options = { 'user_data_loc': os.path.join(self.data_dir, "user_data567.csv"), 'user_consumption_loc': os.path.join(self.data_dir, "consumption") } call_command('import', *self.args, **options, stdout=self.out) self.assertIn("is not a valid file path.", self.out.getvalue()) def test_malformed_header(self): """ Checks a malformed header. """ self.out.flush() options = { 'user_data_loc': os.path.join(self.data_dir, "user_data_fail.csv"), 'user_consumption_loc': os.path.join(self.data_dir, "consumption") } call_command('import', *self.args, **options, stdout=self.out) self.assertIn("malformed header", self.out.getvalue())
class LoadProductsManageTest(unittest.TestCase): def setUp(self): self.out = StringIO() self.out.flush() self.derr = StringIO() self.derr.flush() def test_executeFilepathsEmpty_regresaException(self): call_command('load_products', '', stdout=self.out, stderr=self.derr) self.assertIn('No products were created', self.out.getvalue()) def test_executeInvalidSeveralFilePaths_regresaLog(self): call_command('load_products', 'file1', stderr=self.out, stdout=self.derr) self.assertIn('An error occurred while processing this file: file1', self.out.getvalue()) def test_execWithCatBase_regresaStringCatBase(self): call_command('load_products', 'file1', 'file2', stdout=self.out, cat_base='Prueba', stderr=self.derr) self.assertIn('Using base category: Prueba.', self.out.getvalue()) def test_execWithCatBase_regresaStringLog(self): call_command('load_products', 'file1', 'file2', stdout=self.out, cat_base='Prueba', log=True, stderr=self.derr) self.assertIn('Log mode on.', self.out.getvalue())
def connect(self): """ 打开 websocket 连接, 通过前端传入的参数尝试连接 ssh 主机 :return: """ self.accept() self.start_time = timezone.now() self.session = self.scope.get('session', None) if not self.session.get('islogin', None): # 未登录直接断开 websocket 连接 self.message['status'] = 2 self.message['message'] = 'You are not login in...' message = json.dumps(self.message) self.send(message) self.close(3001) self.check_login() query_string = self.scope.get('query_string').decode() ssh_args = QueryDict(query_string=query_string, encoding='utf-8') width = ssh_args.get('width') height = ssh_args.get('height') width = int(width) height = int(height) auth = None ssh_key_name = '123456' hostid = int(ssh_args.get('hostid')) try: if not self.session['issuperuser']: # 普通用户判断是否有相关主机或者权限 hosts = RemoteUserBindHost.objects.filter( Q(id=hostid), Q(user__username=self.session['username']) | Q(group__user__username=self.session['username']), ).distinct() if not hosts: self.message['status'] = 2 self.message['message'] = 'Host is not exist...' message = json.dumps(self.message) self.send(message) self.close(3001) self.remote_host = RemoteUserBindHost.objects.get(id=hostid) if not self.remote_host.enabled: try: self.message['status'] = 2 self.message['message'] = 'Host is disabled...' message = json.dumps(self.message) self.send(message) self.close(3001) except BaseException: pass except BaseException: self.message['status'] = 2 self.message['message'] = 'Host is not exist...' message = json.dumps(self.message) self.send(message) self.close(3001) host = self.remote_host.ip port = self.remote_host.port user = self.remote_host.remote_user.username passwd = self.remote_host.remote_user.password timeout = 15 self.ssh = SSH(websocker=self, message=self.message) ssh_connect_dict = { 'host': host, 'user': user, 'port': port, 'timeout': timeout, 'pty_width': width, 'pty_height': height, 'password': passwd, } if auth == 'key': ssh_key_file = os.path.join(TMP_DIR, ssh_key_name) with open(ssh_key_file, 'r') as f: ssh_key = f.read() string_io = StringIO() string_io.write(ssh_key) string_io.flush() string_io.seek(0) ssh_connect_dict['ssh_key'] = string_io os.remove(ssh_key_file) self.ssh.connect(**ssh_connect_dict) if self.remote_host.remote_user.enabled: if self.session.get('issuperuser', None): # 超级管理员才能使用 su 跳转功能 if self.remote_host.remote_user.superusername: self.ssh.su_root( self.remote_host.remote_user.superusername, self.remote_host.remote_user.superpassword, 0.3, )
class UnitTestLoadProdsExcel(test.TestCase): def setUp(self): self.out = StringIO() self.out.flush() self.derr = StringIO() self.derr.flush() self.command = TestCommand() def test_executeCatArgNoPresent_regresaException(self): self.assertRaises(CommandError, call_command, 'self.command', '', 'stdout=self.out', 'stderr=self.derr') def test_executeManufacturerArgNoPresent_regresaException(self): self.assertRaises(CommandError, call_command, 'self.command', 'cat=Prueba', 'stdout=self.out', 'stderr=self.derr') def test_executeOriginArgNoPresent_regresaException(self): self.assertRaises(CommandError, call_command, 'self.command', 'cat=Prueba', 'manufacturer=Manu', 'stdout=self.out', 'stderr=self.derr') def test_executeFilepathsEmptyWithDefaultCatbase_regresaException(self): call_command(self.command, '', '--cat=Prueba', '--manufacturer=Manu', '--origin=Origin', stdout=self.out, stderr=self.derr) self.assertIn('No products were created', self.out.getvalue()) self.assertIn('Using base category: Best Sellers > Extension Kits.', self.out.getvalue()) def test_executeWithoutCatArg_returns1(self): self.command.nro = 1 call_command(self.command, '/path/Brand.xls', '--manufacturer=Manu', '--origin=Origin', stdout=self.out, stderr=self.derr) self.assertIn('Category name: Brand.', self.out.getvalue()) def test_executeWithoutCatArgFilenameWithoutExtension_returns1(self): self.command.nro = 1 call_command(self.command, 'path/Brand', '--manufacturer=Manu', '--origin=Origin', stdout=self.out, stderr=self.derr) self.assertIn('Category name: Brand.', self.out.getvalue()) def test_executeWithDefaultCatbase_returns1(self): self.command.nro = 1 call_command(self.command, 'file', '--cat=Prueba', '--manufacturer=Manu', '--origin=Origin', stdout=self.out, stderr=self.derr) self.assertIn( '%s products were created in DB from %s' % (self.command.nro, 'file'), self.out.getvalue()) self.assertIn('Using base category: Best Sellers > Extension Kits.', self.out.getvalue()) def test_executeInvalidSeveralFilePaths_regresaLog(self): self.command.raise_exp = True call_command(self.command, 'file1', '--cat=Prueba', '--manufacturer=Manu', '--origin=Origin', stderr=self.derr, stdout=self.out) self.assertIn( 'An error occurred while processing this file: file1. Skipping...', self.derr.getvalue()) def test_execWithCatBase_regresaLog(self): call_command(self.command, 'file1', '--cat_base=Prueba', '--cat=Ext', '--manufacturer=Manu', '--origin=Origin', stdout=self.out, stderr=self.derr) self.assertIn('Using base category: Prueba.', self.out.getvalue()) # def test_execWithCatManuOrig_regresaLog(self): call_command(self.command, 'file1', '--cat_base=Prueba', '--cat=Ext', '--manufacturer=Manu', '--origin=Origin', stdout=self.out, stderr=self.derr) self.assertIn('Using base category: Prueba.', self.out.getvalue()) self.assertIn('Category name: Ext.', self.out.getvalue()) self.assertIn('Manufacturer name: Manu.', self.out.getvalue()) self.assertIn('Origin name: Origin.', self.out.getvalue())
def connect(self): """ 打开 websocket 连接, 通过前端传入的参数尝试连接 ssh 主机 :return: """ self.accept() async_to_sync(self.channel_layer.group_add)(self.group, self.channel_name) # 加入组 self.start_time = timezone.now() self.session = self.scope.get('session', None) if not self.session.get('islogin', None): # 未登录直接断开 websocket 连接 self.message['status'] = 2 self.message['message'] = 'You are not login in...' message = json.dumps(self.message) if self.send_flag == 0: self.send(message) elif self.send_flag == 1: async_to_sync(self.channel_layer.group_send)(self.group, { "type": "chat.message", "text": message, }) self.close(3001) if 'webssh终端' not in self.session[ settings.INIT_PERMISSION]['titles']: # 判断权限 self.message['status'] = 2 self.message['message'] = '无权限' message = json.dumps(self.message) if self.send_flag == 0: self.send(message) elif self.send_flag == 1: async_to_sync(self.channel_layer.group_send)(self.group, { "type": "chat.message", "text": message, }) self.close(3001) self.check_login() query_string = self.scope.get('query_string').decode() ssh_args = QueryDict(query_string=query_string, encoding='utf-8') width = ssh_args.get('width') height = ssh_args.get('height') width = int(width) height = int(height) auth = None ssh_key_name = '123456' hostid = int(ssh_args.get('hostid')) try: if not self.session['issuperuser']: # 普通用户判断是否有相关主机或者权限 hosts = RemoteUserBindHost.objects.filter( Q(id=hostid), Q(enabled=True), Q(user__username=self.session['username']) | Q(group__user__username=self.session['username']), ).distinct() else: hosts = RemoteUserBindHost.objects.filter( Q(id=hostid), Q(enabled=True), ).distinct() if not hosts: self.message['status'] = 2 self.message['message'] = 'Host is not exist...' message = json.dumps(self.message) if self.send_flag == 0: self.send(message) elif self.send_flag == 1: async_to_sync(self.channel_layer.group_send)( self.group, { "type": "chat.message", "text": message, }) self.close(3001) self.remote_host = RemoteUserBindHost.objects.get(id=hostid) except Exception: print(traceback.format_exc()) self.message['status'] = 2 self.message['message'] = 'Host is not exist...' message = json.dumps(self.message) if self.send_flag == 0: self.send(message) elif self.send_flag == 1: async_to_sync(self.channel_layer.group_send)(self.group, { "type": "chat.message", "text": message, }) self.close(3001) host = self.remote_host.ip port = self.remote_host.port user = self.remote_host.remote_user.username passwd = decrypt(self.remote_host.remote_user.password) timeout = 15 self.ssh = SSH(websocker=self, message=self.message) ssh_connect_dict = { 'host': host, 'user': user, 'port': port, 'timeout': timeout, 'pty_width': width, 'pty_height': height, 'password': passwd, } if auth == 'key': ssh_key_file = os.path.join(TMP_DIR, ssh_key_name) with open(ssh_key_file, 'r') as f: ssh_key = f.read() string_io = StringIO() string_io.write(ssh_key) string_io.flush() string_io.seek(0) ssh_connect_dict['ssh_key'] = string_io os.remove(ssh_key_file) self.ssh.connect(**ssh_connect_dict) if self.remote_host.remote_user.enabled: if self.remote_host.remote_user.superusername: if '登陆后su跳转超级用户' in self.session[ settings.INIT_PERMISSION]['titles']: # 判断权限 self.ssh.su_root( self.remote_host.remote_user.superusername, decrypt(self.remote_host.remote_user.superpassword), 1, ) for i in self.scope['headers']: if i[0].decode('utf-8') == 'user-agent': self.user_agent = i[1].decode('utf-8') break for i in self.scope['headers']: if i[0].decode('utf-8') == 'x-real-ip': self.client = i[1].decode('utf-8') break if i[0].decode('utf-8') == 'x-forwarded-for': self.client = i[1].decode('utf-8').split(',')[0] break self.client = self.scope['client'][0] data = { 'name': self.channel_name, 'group': self.group, 'user': self.session.get('username'), 'host': host, 'username': user, 'protocol': self.remote_host.protocol, 'port': port, 'type': 1, # 1 webssh 'address': self.client, 'useragent': self.user_agent, } TerminalSession.objects.create(**data)
def connect(self): try: self.accept() query_string = self.scope['query_string'] connet_argv = QueryDict(query_string=query_string, encoding='utf-8') unique = connet_argv.get('unique') width = connet_argv.get('width') height = connet_argv.get('height') width = int(width) height = int(height) connect_info = models.HostTmp.objects.get(unique=unique) host = connect_info.host port = connect_info.port user = connect_info.user auth = connect_info.auth pwd = connect_info.password pkey = connect_info.pkey #print("web=============================pkey:",pkey) connect_info.delete() if pwd: password = base64.b64decode(pwd).decode('utf-8') #这里解编码密码 else: password = None self.ssh = SSH(websocker=self, message=self.message) if auth == 'key': pkey = pkey obj = StringIO() obj.write(pkey) obj.flush() obj.seek(0) self.pkey = obj #print("web=============================pkey:",self.pkey) self.ssh.connect(host=host, user=user, password=password, pkey=self.pkey, port=port, pty_width=width, pty_height=height) else: self.ssh.connect(host=host, user=user, password=password, port=port, pty_width=width, pty_height=height) except Exception as e: #因为上面解码时:base64.b64decode(pwd).decode('utf-8'),字符串原本没有编码, # 所以导致binascii.Error: Incorrect padding报错,所以后面添加密码时需要进行 # 编码:base64.b64encode(b"root123456."),修改后,密钥登陆的密码也需要编码 # 原因是在webssh.js中编码了一下密钥登陆的password字段:var password = window.btoa(pwd); 已修改 # 而使用密码登陆的没有经过此步骤,直接由后端查询数据库得到了 print(e) self.message['status'] = 1 self.message['message'] = str(e) message = json.dumps(self.message) self.send(message) self.close()
def connect(self): """ 打开 websocket 连接, 通过前端传入的参数尝试连接 ssh 主机 :return: """ self.accept() query_string = self.scope.get('query_string') ssh_args = QueryDict(query_string=query_string, encoding='utf-8') width = ssh_args.get('width') height = ssh_args.get('height') port = ssh_args.get('port') width = int(width) height = int(height) port = int(port) auth = ssh_args.get('auth') ssh_key_name = ssh_args.get('ssh_key') passwd = ssh_args.get('password') host = ssh_args.get('host') user = ssh_args.get('user') connect_time = time.time() filename = '%s.%s.%d.cast' % (host, user, connect_time) # 文件名 # 构建录像文件header record_log( type = 'header', data = { "version": 2, "width": width, "height": height, "timestamp": connect_time, "env": { "SHELL": "/bin/bash", "TERM": 'xterm-256color' }, "title": "zili-webssh" }, connect_time = connect_time, host = host, user = user, filename = filename ) if passwd: passwd = base64.b64decode(passwd).decode('utf-8') else: passwd = None self.ssh = SSH(websocker=self, message=self.message) ssh_connect_dict = { 'host': host, 'user': user, 'port': port, 'timeout': 30, 'pty_width': width, 'pty_height': height, 'password': passwd, 'filename':filename, 'connect_time':connect_time } if auth == 'key': ssh_key_file = os.path.join(TMP_DIR, ssh_key_name) with open(ssh_key_file, 'r') as f: ssh_key = f.read() string_io = StringIO() string_io.write(ssh_key) string_io.flush() string_io.seek(0) ssh_connect_dict['ssh_key'] = string_io os.remove(ssh_key_file) self.ssh.connect(**ssh_connect_dict)
def connect(self): """ 建立WebSocket连接,并实例化SSHBridge类,在这个对象中建立SSH连接,放在 self.ssh_channel 通道中 :return: """ self.host_id = self.scope['url_route']['kwargs'].get('host_id') # 获取session中的值 self.simple_user = self.scope["user"].username # print('【Web --websocket--> WS】建立WebSocket通道,当前连接用户:', self.simple_user) host_obj = Host.objects.get(id=self.host_id) self.accept() # WebSocket连接成功后,连接ssh query_string = self.scope.get('query_string') ws_args = QueryDict(query_string=query_string, encoding='utf-8') # # print(ws_args) # <QueryDict: {'user': ['admin'], 'host': ['192.168.96.20'], 'port': ['22'], 'auth': ['pwd'], 'pwd': ['ZGphbmdvYWRtaW4='], 'key': [''], 'width': ['113'], 'height': ['43']}> # 根据参数判断是否是协作 team = ws_args.get('team') if team: self.is_team = True self.team_name = "team_{}".format(self.host_id) # 加到这个通道组 async_to_sync(self.channel_layer.group_add)( self.team_name, self.channel_name ) # 用户连接时,同一群组发送消息 self.send_message_or_team(json.dumps( {'flag': 'user', 'message': '用户 {} 已连接本终端'.format(self.simple_user)})) width = ws_args.get('width') height = ws_args.get('height') width = int(width) height = int(height) # ssh连接要求int类型:required argument is an integer ssh_connect_dict = {} user = self.simple_user host = host_obj.ip port = host_obj.ssh_port port = int(port) auth = host_obj.ssh_user pwd = host_obj.ssh_passwd # if pwd: # pwd = base64.b64decode(pwd).decode('utf-8') sshkey_filename_path = host_obj.ssh_key.ssh_key.path if host_obj.ssh_key else None ssh_connect_dict = { 'host': host, 'user': auth, 'port': port, 'timeout': 30, 'pty_width': width, 'pty_height': height, 'pwd': pwd } if sshkey_filename_path: if not os.path.exists(sshkey_filename_path): self.send(json.dumps( {'flag': 'error', 'message': '密钥文件不存在'})) else: try: f = open(sshkey_filename_path, 'r', encoding='utf-8') key = f.read() string_io = StringIO() string_io.write(key) string_io.flush() string_io.seek(0) ssh_connect_dict['key'] = string_io # os.remove(sshkey_filename_path) # 用完之后删除key文件 except BaseException as e: # print('打开密钥文件出错', e) pass # 建立SSH连接 self.ssh = SSHBridge(websocket=self, simpleuser=self.simple_user) # print('【WS --SSHBridge--> SSH】连接SSH参数:', ssh_connect_dict) self.ssh.connect(**ssh_connect_dict)