diff --git a/connect.py b/connect.py index 2731e358e..4c7989614 100755 --- a/connect.py +++ b/connect.py @@ -92,11 +92,20 @@ class Tty(object): self.remote_ip = '' self.login_type = login_type self.vim_flag = False - self.ps1_pattern = re.compile('\[.*@.*\][\$#]\s') - self.vim_pattern = re.compile(r'\Wvi[m]+\s.* | \Wfg\s.*', re.X) + self.ps1_pattern = re.compile('\[?.*@.*\]?[\$#]\s') + self.vim_pattern = re.compile(r'\W?vi[m]?\s.* | \W?fg\s.*', re.X) self.vim_data = '' - self.stream = pyte.ByteStream() + self.stream = None self.screen = None + self.__init_screen_stream() + + def __init_screen_stream(self): + """ + 初始化虚拟屏幕和字符流 + """ + self.stream = pyte.ByteStream() + self.screen = pyte.Screen(80, 24) + self.stream.attach(self.screen) @staticmethod def is_output(strings): @@ -125,30 +134,35 @@ class Tty(object): result = match[-1].strip() return result - def deal_command(self): + def deal_command(self, data): """ 处理截获的命令 + :param data: 要处理的命令 :return:返回最后的处理结果 """ command = '' - # 从虚拟屏幕中获取处理后的数据 - for line in reversed(self.screen.buffer): - line_data = "".join(map(operator.attrgetter("data"), line)).strip() - if len(line_data) > 0: - parser_result = self.command_parser(line_data) - if parser_result is not None: - # 2个条件写一起会有错误的数据 - if len(parser_result) > 0: - command = parser_result - else: - command = line_data - break - if command != '': - # 判断用户输入的是否是vim 或者fg命令 - if self.vim_pattern.search(command): - self.vim_flag = True - # 虚拟屏幕清空 - self.screen.reset() + try: + self.stream.feed(data) + # 从虚拟屏幕中获取处理后的数据 + for line in reversed(self.screen.buffer): + line_data = "".join(map(operator.attrgetter("data"), line)).strip() + if len(line_data) > 0: + parser_result = self.command_parser(line_data) + if parser_result is not None: + # 2个条件写一起会有错误的数据 + if len(parser_result) > 0: + command = parser_result + else: + command = line_data + break + if command != '': + # 判断用户输入的是否是vim 或者fg命令 + if self.vim_pattern.search(command): + self.vim_flag = True + # 虚拟屏幕清空 + self.screen.reset() + except Exception: + pass return command def get_log(self): @@ -348,16 +362,15 @@ class SshTty(Tty): # 这个是用来处理用户的复制操作 if input_str != x: data += input_str - self.stream.feed(data) if self.vim_flag: match = self.ps1_pattern.search(self.vim_data) if match: self.vim_flag = False - data = self.deal_command()[0:200] + data = self.deal_command(data)[0:200] if len(data) > 0: TtyLog(log=log, datetime=datetime.datetime.now(), cmd=data).save() else: - data = self.deal_command()[0:200] + data = self.deal_command(data)[0:200] if len(data) > 0: TtyLog(log=log, datetime=datetime.datetime.now(), cmd=data).save() data = '' @@ -393,10 +406,8 @@ class SshTty(Tty): # 获取连接的隧道并设置窗口大小 Make a channel and set windows size global channel win_size = self.get_win_size() - #self.channel = channel = ssh.invoke_shell(height=win_size[0], width=win_size[1], term='xterm') + # self.channel = channel = ssh.invoke_shell(height=win_size[0], width=win_size[1], term='xterm') self.channel = channel = transport.open_session() - self.screen = pyte.Screen(win_size[1], win_size[0]) - self.stream.attach(self.screen) channel.get_pty(term='xterm', height=win_size[0], width=win_size[1]) channel.invoke_shell() try: diff --git a/install/requirements.txt b/install/requirements.txt index 23ab9d3b0..5035a6995 100644 --- a/install/requirements.txt +++ b/install/requirements.txt @@ -14,4 +14,4 @@ ansible==1.9.4 pyinotify==0.9.6 passlib==1.6.5 argparse==1.4.0 -django_crontab==0.6.0 \ No newline at end of file +django_crontab==0.6.0 diff --git a/jperm/models.py b/jperm/models.py index 425d01410..0ba12354a 100644 --- a/jperm/models.py +++ b/jperm/models.py @@ -26,7 +26,7 @@ class PermSudo(models.Model): class PermRole(models.Model): name = models.CharField(max_length=100, unique=True) comment = models.CharField(max_length=100, null=True, blank=True, default='') - password = models.CharField(max_length=100) + password = models.CharField(max_length=128) key_path = models.CharField(max_length=100) date_added = models.DateTimeField(auto_now=True) sudo = models.ManyToManyField(PermSudo, related_name='perm_role') diff --git a/jperm/perm_api.py b/jperm/perm_api.py index de5cbcdb7..fb020ea07 100644 --- a/jperm/perm_api.py +++ b/jperm/perm_api.py @@ -182,8 +182,9 @@ def gen_resource(ob, perm=None): info = {'hostname': asset.hostname, 'ip': asset.ip, 'port': asset_info.get('port', 22), + 'ansible_ssh_private_key_file': role_key, 'username': role.name, - 'password': CRYPTOR.decrypt(role.password) + # 'password': CRYPTOR.decrypt(role.password) } if os.path.isfile(role_key): diff --git a/jperm/views.py b/jperm/views.py index b4eb6a1c1..7ff572bcf 100644 --- a/jperm/views.py +++ b/jperm/views.py @@ -519,12 +519,12 @@ def perm_role_push(request): ret["pass_push"] = task.add_user(role.name) ret["key_push"] = task.push_key(role.name, os.path.join(role.key_path, 'id_rsa.pub')) - # 2. 推送账号密码 - elif password_push: - ret["pass_push"] = task.add_user(role.name, CRYPTOR.decrypt(role.password)) + # 2. 推送账号密码 <为了安全 系统用户统一使用秘钥进行通信, 不再提供密码方式的推送> + # elif password_push: + # ret["pass_push"] = task.add_user(role.name, CRYPTOR.decrypt(role.password)) # 3. 推送sudo配置文件 - if password_push or key_push: + if key_push: sudo_list = set([sudo for sudo in role.sudo.all()]) # set(sudo1, sudo2, sudo3) if sudo_list: ret['sudo'] = task.push_sudo_file([role], sudo_list) diff --git a/jumpserver.conf b/jumpserver.conf index cee5fd8e5..9f16edfc9 100644 --- a/jumpserver.conf +++ b/jumpserver.conf @@ -1,6 +1,6 @@ [base] -url = http://192.168.244.129 -key = i6k2zeu8x6mncl76 +url = http://192.168.10.165 +key = 941enj9neshd1wes ip = 0.0.0.0 port = 80 log = debug @@ -14,9 +14,9 @@ database = jumpserver [mail] mail_enable = 1 -email_host = smtp.exmail.qq.com -email_port = 25 -email_host_user = noreply@jumpserver.org -email_host_password = xxxxxxxxxx +email_host = +email_port = 587 +email_host_user = +email_host_password = email_use_tls = True diff --git a/run_server.py b/run_server.py index 6c85d2dc6..88e0bc625 100755 --- a/run_server.py +++ b/run_server.py @@ -10,7 +10,6 @@ import os.path import threading import re import functools - from django.core.signals import request_started, request_finished import tornado.ioloop @@ -371,9 +370,10 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler): vim_data = self.term.deal_command(self.term.vim_data)[0:200] if len(data) > 0: TtyLog(log=self.log, datetime=datetime.datetime.now(), cmd=vim_data).save() - - TtyLog(log=self.log, datetime=datetime.datetime.now(), - cmd=self.term.deal_command(self.term.data)[0:200]).save() + vim_data = self.term.deal_command(self.term.vim_data)[0:200] + if len(vim_data) > 0: + TtyLog(log=self.log, datetime=datetime.datetime.now(), + cmd=vim_data).save() self.term.vim_data = '' self.term.data = '' self.term.input_mode = False @@ -412,7 +412,7 @@ class WebTerminalHandler(tornado.websocket.WebSocketHandler): if self.term.vim_flag: self.term.vim_data += recv try: - self.write_message(json.dumps({'data': data})) + self.write_message(data.decode('utf-8', 'replace')) now_timestamp = time.time() self.log_time_f.write('%s %s\n' % (round(now_timestamp-pre_timestamp, 4), len(data))) self.log_file_f.write(data) @@ -460,7 +460,7 @@ def main(): } tornado_app = tornado.web.Application( [ - (r'/monitor', MonitorHandler), + (r'/ws/monitor', MonitorHandler), (r'/ws/terminal', WebTerminalHandler), (r'/kill', WebTerminalKillHandler), (r'/ws/exec', ExecHandler), diff --git a/static/js/webterminal.js b/static/js/webterminal.js index 8d6942d9b..e5ea997f2 100644 --- a/static/js/webterminal.js +++ b/static/js/webterminal.js @@ -1,3 +1,4 @@ + /** * Created by liuzheng on 3/3/16. */ @@ -35,13 +36,12 @@ WSSHClient.prototype.connect = function (options) { }; this._connection.onmessage = function (evt) { - var data = JSON.parse(evt.data.toString()); - if (data.error !== undefined) { + try{ + options.onData(evt.data); + } catch (e) { + var data = JSON.parse(evt.data.toString()); options.onError(data.error); } - else { - options.onData(data.data); - } }; this._connection.onclose = function (evt) { diff --git a/templates/jlog/log_online.html b/templates/jlog/log_online.html index 3e8898b79..ae2a80f52 100644 --- a/templates/jlog/log_online.html +++ b/templates/jlog/log_online.html @@ -136,7 +136,7 @@ var protocol = 'ws://'; } - var endpoint = protocol + document.URL.match(RegExp('//(.*?)/'))[1] + '/monitor'; + var endpoint = protocol + document.URL.match(RegExp('//(.*?)/'))[1] + '/ws/monitor'; var file_path = obj.attr('file_path'); var socket = new WebSocket(endpoint + '?file_path=' + file_path); diff --git a/templates/jlog/static.jinja2 b/templates/jlog/static.jinja2 index 6e41b7ee5..069f41685 100644 --- a/templates/jlog/static.jinja2 +++ b/templates/jlog/static.jinja2 @@ -1,7 +1,7 @@ {% extends "base.jinja2" %} {% block head %} - +