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)
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)
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)
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')))
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')))
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')))
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
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