Пример #1
0
    def search_and_proxy(self, option, from_result=False):
        """搜索并登录资产"""
        self.search_assets(option=option, from_result=from_result)
        if len(self.search_result) == 1:
            request.asset = asset = self.search_result[0]
            if len(asset.system_users) == 1:
                system_user = asset.system_users[0]
            else:
                self.client_channel.send(
                    wr(primary('More than one system user granted, select one')))
                system_user = self.choose_system_user(asset.system_users)
                if system_user is None:
                    return self.dispatch()

            request.system_user = system_user
            self.return_to_proxy(asset, system_user)
        elif len(self.search_result) == 0:
            self.client_channel.send(
                wr(warning('No asset match, please input again')))
            return self.dispatch()
        else:
            self.client_channel.send(
                wr(primary('Search result is not unique, '
                           'select below or search again'), after=2))
            self.display_search_result()
            self.dispatch(twice=True)
Пример #2
0
    def search_and_proxy(self, option, from_result=False):
        """搜索并登录资产"""
        self.search_assets(option=option, from_result=from_result)
        if len(self.search_result) == 1:
            request.asset = asset = self.search_result[0]
            if len(asset.system_users) == 1:
                system_user = asset.system_users[0]
            else:
                self.client_channel.send(
                    wr(primary(
                        'More than one system user granted, select one')))
                system_user = self.choose_system_user(asset.system_users)
                if system_user is None:
                    return self.dispatch()

            request.system_user = system_user
            self.return_to_proxy(asset, system_user)
        elif len(self.search_result) == 0:
            self.client_channel.send(
                wr(warning('No asset match, please input again')))
            return self.dispatch()
        else:
            self.client_channel.send(
                wr(primary('Search result is not unique, '
                           'select below or search again'),
                   after=2))
            self.display_search_result()
            self.dispatch(twice=True)
Пример #3
0
    def process_request(self, client, addr):
        rc = self.request_context({'REMOTE_ADDR': addr[0]})
        rc.push()
        logger.info("Get ssh request from %s" % request.environ['REMOTE_ADDR'])
        transport = paramiko.Transport(client, gss_kex=False)
        try:
            transport.load_server_moduli()
        except:
            logger.warning('Failed to load moduli -- gex will be unsupported.')
            raise

        transport.add_server_key(SSHInterface.get_host_key())
        # 将app和请求上下文传递过去, ssh_interface 处理ssh认证和建立连接
        ssh_interface = SSHInterface(self, rc)

        try:
            transport.start_server(server=ssh_interface)
        except paramiko.SSHException:
            logger.warning('SSH negotiation failed.')
            sys.exit(1)

        _client_channel = transport.accept(20)
        g.client_channel = _client_channel
        if _client_channel is None:
            logger.warning('No ssh channel get.')
            sys.exit(1)

        if request.method == 'shell':
            logger.info('Client asked for a shell.')
            InteractiveServer(self).run()
        elif request.method == 'command':
            _client_channel.send(wr(warning('We are not support command now')))
            _client_channel.close()
            sys.exit(2)
        else:
            _client_channel.send(wr(warning('Not support the request method')))
            _client_channel.close()
            sys.exit(2)

        while True:
            if request.user is not None:
                break
            else:
                time.sleep(0.2)
Пример #4
0
 def display_asset_group_asset(self, option):
     """打印资产组下的资产"""
     match = re.match(r'g(\d+)', option)
     if match:
         index = match.groups()[0]
         if index.isdigit() and len(self.asset_groups) > int(index):
             asset_group = self.asset_groups[int(index)]
             self.search_result = self.user_service.\
                 get_assets_in_group(asset_group.id)
             self.display_search_result()
             self.dispatch(twice=True)
     self.client_channel.send(
         wr(warning('No asset group match, please input again')))
Пример #5
0
 def display_asset_group_asset(self, option):
     """打印资产组下的资产"""
     match = re.match(r'g(\d+)', option)
     if match:
         index = match.groups()[0]
         if index.isdigit() and len(self.asset_groups) > int(index):
             asset_group = self.asset_groups[int(index)]
             self.search_result = self.user_service.\
                 get_assets_in_group(asset_group.id)
             self.display_search_result()
             self.dispatch(twice=True)
     self.client_channel.send(wr(warning(
         'No asset group match, please input again')))
Пример #6
0
    def choose_system_user(self, system_users):
        """当资产上有多个授权系统用户时, 让用户二次选择"""
        while True:
            for index, system_user in enumerate(system_users):
                self.client_channel.send(wr('[%s] %s' % (index, system_user.username)))

            option = self.get_input(prompt='System user> ')
            if option.isdigit() and int(option) < len(system_users):
                system_user = system_users[int(option)]
                return system_user
            elif option in ['q', 'Q']:
                return None
            else:
                self.client_channel.send(
                    wr(warning('No system user match, please input again')))
Пример #7
0
    def choose_system_user(self, system_users):
        """当资产上有多个授权系统用户时, 让用户二次选择"""
        while True:
            for index, system_user in enumerate(system_users):
                self.client_channel.send(wr('[%s] %s' % (index, system_user.username)))

            option = self.get_input(prompt='System user> ')
            if option.isdigit() and int(option) < len(system_users):
                system_user = system_users[int(option)]
                return system_user
            elif option in ['q', 'Q']:
                return None
            else:
                self.client_channel.send(
                    wr(warning('No system user match, please input again')))
Пример #8
0
    def connect(self, term=b'xterm', width=80, height=24, timeout=10):
        user = self.user
        asset = self.asset
        system_user = self.system_user
        client_channel = self.client_channel
        try:
            # Todo: win_width in request or client_channel
            width = int(client_channel.win_width)
            height = int(client_channel.win_height)
        except TypeError:
            pass
        if not self.validate_user_asset_permission():
            logger.warning('User %s have no permission connect %s with %s' %
                           (user.username, asset.ip, system_user.username))
            return None
        self.ssh = ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        password, private_key = self.get_asset_auth(system_user)

        data = {
            "user": user.username,
            "asset": asset.ip,
            "system_user": system_user.username,
            "login_type": "ST",
            "date_start": time.time(),
            "is_failed": 0
        }
        self.proxy_log_id = proxy_log_id = self.service.send_proxy_log(data)
        self.app.proxy_list[
            proxy_log_id] = self.client_channel, self.backend_channel
        try:
            client_channel.send(
                wr('Connecting %s@%s:%s ... ' %
                   (system_user.username, asset.ip, asset.port)))
            ssh.connect(hostname=asset.ip,
                        port=asset.port,
                        username=system_user.username,
                        password=password,
                        pkey=private_key,
                        look_for_keys=False,
                        allow_agent=True,
                        compress=True,
                        timeout=timeout)

        except (paramiko.AuthenticationException,
                paramiko.ssh_exception.SSHException):
            msg = 'Connect backend server %s failed: %s' \
                  % (asset.ip, 'Auth failed')
            logger.warning(msg)
            failed = True

        except socket.error:
            msg = 'Connect asset %s failed: %s' % (asset.ip, 'Timeout')
            logger.warning(msg)
            failed = True
        else:
            msg = 'Connect asset %(username)s@%(host)s:%(port)s successfully' % {
                'username': system_user.username,
                'host': asset.ip,
                'port': asset.port
            }
            failed = False
            logger.info(msg)

        if failed:
            client_channel.send(wr(warning(msg + '\r\n')))
            data = {
                "proxy_log_id": proxy_log_id,
                "date_finished": time.time(),
                "was_failed": 1
            }
            self.service.finish_proxy_log(data)
            return None

        self.backend_channel = channel = ssh.invoke_shell(term=term,
                                                          width=width,
                                                          height=height)
        channel.settimeout(100)
        return channel
Пример #9
0
    def connect(self, term='xterm', width=80, height=24, timeout=10):
        user = self.user
        asset = self.asset
        system_user = self.system_user
        try:
            # Todo: win_width in request or client_channel
            width = int(self.client_channel.win_width)
            height = int(self.client_channel.win_height)
        except TypeError:
            pass
        if not self.validate_user_asset_permission():
            logger.warning('User %s have no permission connect %s with %s' %
                           (user.username, asset.ip, system_user.username))
            return None
        self.ssh = ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        password, private_key = self.get_asset_auth(system_user)

        data = {"user": user.username, "asset": asset.ip,
                "system_user": system_user.username,  "login_type": "ST",
                "date_start": time.time(), "is_failed": 0}
        self.proxy_log_id = proxy_log_id = self.service.send_proxy_log(data)
        self.app.proxy_list[proxy_log_id] = self.client_channel, self.backend_channel
        try:
            self.client_channel.send(
                wr('Connecting %s@%s:%s ... ' %
                   (system_user.username, asset.ip, asset.port)))
            ssh.connect(hostname=asset.ip, port=asset.port,
                        username=system_user.username,
                        password=password, pkey=private_key,
                        look_for_keys=False, allow_agent=True,
                        compress=True, timeout=timeout)

        except (paramiko.AuthenticationException,
                paramiko.ssh_exception.SSHException):
            msg = 'Connect backend server %s failed: %s' \
                  % (asset.ip, 'Auth failed')
            logger.warning(msg)
            failed = True

        except socket.error:
            msg = 'Connect asset %s failed: %s' % (asset.ip, 'Timeout')
            logger.warning(msg)
            failed = True
        else:
            msg = 'Connect asset %(username)s@%(host)s:%(port)s successfully' % {
                       'username': system_user.username,
                       'host': asset.ip,
                       'port': asset.port}
            failed = False
            logger.info(msg)

        if failed:
            self.client_channel.send(wr(warning(msg+'\r\n')))
            data = {
                "proxy_log_id": proxy_log_id,
                "date_finished": time.time(),
                "is_failed": 1
            }
            self.service.finish_proxy_log(data)
            return None

        self.backend_channel = channel = ssh.invoke_shell(
            term=term, width=width, height=height)
        channel.settimeout(100)
        return channel