From d182736bd7f079157683c4f11f8c965919897f7e Mon Sep 17 00:00:00 2001 From: kelianchun_miller <360271747@qq.com> Date: Wed, 4 Nov 2015 14:50:47 +0800 Subject: [PATCH] update api.py --- jumpserver/api.py | 124 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 118 insertions(+), 6 deletions(-) diff --git a/jumpserver/api.py b/jumpserver/api.py index f693832f6..b50a3e242 100644 --- a/jumpserver/api.py +++ b/jumpserver/api.py @@ -94,6 +94,110 @@ def pages(post_objects, request): # 所有对象, 分页器, 本页对象, 所有页码, 本页页码,是否显示第一页,是否显示最后一页 return post_objects, paginator, page_objects, page_range, current_page, show_first, show_end +def check_vim_status(command, ssh): + global SSH_TTY + print command + if command == '': + return True + else: + command_str= 'ps -ef |grep "%s" | grep "%s"|grep -v grep |wc -l' % (command,SSH_TTY) + print command_str + stdin, stdout, stderr = ssh.exec_command(command_str) + ps_num = stdout.read() + print ps_num + if int(ps_num) == 0: + return True + else: + return False + + +def deal_command(str_r, ssh): + + """ + 处理命令中特殊字符 + """ + str_r = re.sub('\x07','',str_r) #删除响铃 + patch_char = re.compile('\x08\x1b\[C') #删除方向左右一起的按键 + while patch_char.search(str_r): + str_r = patch_char.sub('', str_r.rstrip()) + + result_command = '' #最后的结果 + pattern_str = '' #模式中间中的字符串 + backspace_num = 0 #光标移动的个数 + reach_backspace_flag = False #没有检测到光标键则为true + end_flag = False + while str_r: + tmp = re.match(r'\w', str_r) + if tmp: + if reach_backspace_flag: + pattern_str += str(tmp.group(0)) + str_r = str_r[1:] + continue + else: + result_command += str(tmp.group(0)) + str_r = str_r[1:] + continue + + tmp = re.match(r'\x1b\[K[\x08]*', str_r) + if tmp: + if backspace_num > 0: + if backspace_num > len(result_command) : + result_command += pattern_str + result_command = result_command[0:-backspace_num] + else: + result_command = result_command[0:-backspace_num] + result_command += pattern_str + del_len = len(str(tmp.group(0)))-3 + if del_len > 0: + result_command = result_command[0:-del_len] + reach_backspace_flag = False + backspace_num =0 + pattern_str='' + str_r = str_r[len(str(tmp.group(0))):] + continue + if re.match(r'\x08', str_r): + backspace_num += 1 + reach_backspace_flag = True + str_r = str_r[1:] + if len(str_r) == 0: + end_flag = True + continue + if reach_backspace_flag : + pattern_str += str_r[0] + else : + result_command += str_r[0] + str_r = str_r[1:] + + if backspace_num > 0 and not end_flag: + result_command = result_command[:-backspace_num] + result_command += pattern_str + + + + control_char = re.compile(r""" + \x1b[ #%()*+\-.\/]. | + \r | #匹配 回车符(CR) + (?:\x1b\[|\x9b) [ -?]* [@-~] | #匹配 控制顺序描述符(CSI)... Cmd + (?:\x1b\]|\x9d) .*? (?:\x1b\\|[\a\x9c]) | \x07 | #匹配 操作系统指令(OSC)...终止符或振铃符(ST|BEL) + (?:\x1b[P^_]|[\x90\x9e\x9f]) .*? (?:\x1b\\|\x9c) | #匹配 设备控制串或私讯或应用程序命令(DCS|PM|APC)...终止符(ST) + \x1b. #匹配 转义过后的字符 + [\x80-\x9f] #匹配 所有控制字符 + """, re.X) + result_command = control_char.sub('', result_command.strip()) + global VIM_FLAG + global VIM_COMMAND + if not VIM_FLAG: + if result_command.startswith('vim'): + VIM_FLAG = True + VIM_COMMAND = result_command + return result_command.decode('utf8',"ignore") + else: + if check_vim_status(VIM_COMMAND, ssh): + VIM_FLAG = False + VIM_COMMAND='' + return result_command.decode('utf8',"ignore") + else: + return '' def remove_control_char(str_r): """ @@ -194,7 +298,7 @@ class Jtty(object): log.save() return log_file_f, log_time_f, ip_list, log - def posix_shell(self): + def posix_shell(self,ssh): """ Use paramiko channel connect server interactive. 使用paramiko模块的channel,连接后端,进入交互式 @@ -242,7 +346,7 @@ class Jtty(object): input_mode = True if str(x) in ['\r', '\n', '\r\n']: - input_r = remove_control_char(input_r) + input_r = deal_command(input_r,ssh) TtyLog(log=log, datetime=datetime.datetime.now(), cmd=input_r).save() input_r = '' input_mode = False @@ -316,11 +420,19 @@ class Jtty(object): pass # 设置PS1并提示 Set PS1 and msg it - channel.send(ps1) - channel.send(login_msg) - + #channel.send(ps1) + #channel.send(login_msg) + channel.send('echo ${SSH_TTY}\n') + global SSH_TTY + while not channel.recv_ready(): + time.sleep(1) + tmp = channel.recv(1024) + #print 'ok'+tmp+'ok' + SSH_TTY = re.search(r'(?<=/dev/).*', tmp).group().strip() + + channel.send('clear\n') # Make ssh interactive tunnel - self.posix_shell() + self.posix_shell(ssh) # Shutdown channel socket channel.close()