Exemple #1
0
    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)
Exemple #2
0
    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()
Exemple #3
0
    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)
Exemple #4
0
    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)
Exemple #5
0
    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)
Exemple #6
0
    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()
Exemple #7
0
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())
Exemple #9
0
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())
Exemple #10
0
    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,
                    )
Exemple #11
0
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())
Exemple #12
0
    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)
Exemple #13
0
    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()
Exemple #14
0
    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)