pull/350/head
midoks 2 years ago
parent 832f3b45eb
commit 1c74ce3c58
  1. 82
      class/core/ssh_terminal.py
  2. 5
      plugins/webssh/js/webssh.js
  3. 2
      route/__init__.py
  4. 55
      route/static/js/term-websocketio.js

@ -52,13 +52,18 @@ class ssh_terminal:
__tp = None
__ps = None
__ssh_list = {}
def __init__(self):
pass
ht = threading.Thread(target=self.heartbeat)
ht.start()
ht.join()
def debug(self, msg):
msg = "{} - {}:{} => {} \n".format(mw.formatDate(),
self.__host, self.__port, msg)
# self.history_send(msg)
if not mw.isDebugMode():
return
mw.writeFile(self.__debug_file, msg, 'a+')
def returnMsg(self, status, msg):
@ -193,10 +198,15 @@ class ssh_terminal:
return self.returnMsg(False, "未知错误: {}".format(err))
self.debug('local-ssh:认证成功,正在构建会话通道')
self.__ssh = self.__ps.invoke_shell(term='xterm', width=83, height=21)
self.__ssh.setblocking(0)
self.__connect_time = time.time()
self.__last_send = []
# self.__ssh = self.__ps.invoke_shell(term='xterm', width=83, height=21)
# self.__ssh.setblocking(0)
# self.__connect_time = time.time()
# self.__last_send = []
ssh = self.__ps.invoke_shell(
term='xterm', width=83, height=21)
ssh.setblocking(0)
self.__ssh_list[self.__sid] = ssh
mw.writeLog(self.__log_type, '成功登录到SSH服务器 [{}:{}]'.format(
self.__host, self.__port))
self.debug('local-ssh:通道已构建')
@ -210,9 +220,6 @@ class ssh_terminal:
if not self.__port:
self.__port = 22
if self.__host in ['127.0.0.1', 'localhost']:
self.__port = mw.getSSHPort()
self.setSshdConfig(True)
num = 0
while num < 5:
@ -230,18 +237,16 @@ class ssh_terminal:
if num == 5:
self.setSshdConfig(True)
self.debug('重试连接失败,{}'.format(e))
if self.__host in ['127.0.0.1', 'localhost']:
return self.returnMsg(False, '连接目标服务器失败: {}'.format("Authentication failed ," + self.__user + "@" + self.__host + ":" + str(self.__port)))
return self.returnMsg(False, '连接目标服务器失败, {}:{}'.format(self.__host, self.__port))
else:
time.sleep(0.2)
# print(sock)
# print(self.__host, sock)
self.__tp = paramiko.Transport(sock)
try:
self.__tp.start_client()
self.__tp.banner_timeout = 60
if not self.__pass or not self.__pkey:
if not self.__pass and not self.__pkey:
return self.returnMsg(False, '密码或私钥不能都为空: {}:{}'.format(self.__host, self.__port))
if self.__pkey:
@ -313,11 +318,16 @@ class ssh_terminal:
return self.returnMsg(False, "未知错误: {}".format(err))
self.debug('认证成功,正在构建会话通道')
self.__ssh = self.__tp.open_session()
self.__ssh.get_pty(term='xterm', width=100, height=34)
self.__ssh.invoke_shell()
self.__connect_time = time.time()
self.__last_send = []
# self.__ssh = self.__tp.open_session()
# self.__ssh.get_pty(term='xterm', width=100, height=34)
# self.__ssh.invoke_shell()
# self.__connect_time = time.time()
# self.__last_send = []
ssh = self.__tp.open_session()
ssh.get_pty(term='xterm', width=100, height=34)
ssh.invoke_shell()
self.__ssh_list[self.__sid] = ssh
mw.writeLog(self.__log_type, '成功登录到SSH服务器 [{}:{}]'.format(
self.__host, self.__port))
self.debug('通道已构建')
@ -326,6 +336,13 @@ class ssh_terminal:
def setAttr(self, info):
self.__host = info['host'].strip()
# 外部连接获取
if not self.__host in ['127.0.0.1', 'localhost']:
dst_info = mw.getServerDir() + '/webssh/host/' + self.__host + '/info.json'
if os.path.exists(dst_info):
_t = mw.readFile(dst_info)
info = json.loads(_t)
if 'port' in info:
self.__port = int(info['port'])
if 'username' in info:
@ -336,8 +353,11 @@ class ssh_terminal:
self.__pass = info['password']
if 'pkey_passwd' in info:
self.__key_passwd = info['pkey_passwd']
print(self.__host, self.__pass, self.__key_passwd)
try:
result = self.connect()
print(result)
except Exception as ex:
if str(ex).find("NoneType") == -1:
raise ex
@ -359,7 +379,8 @@ class ssh_terminal:
def heartbeat(self):
while True:
time.sleep(0.1)
time.sleep(1)
print("heartbeat:__ssh_list:", len(self.__ssh_list))
if self.__tp and self.__tp.is_active():
self.__tp.send_ignore()
else:
@ -378,6 +399,7 @@ class ssh_terminal:
return emit('server_response', {'data': recv})
def run(self, sid, info):
# sid = mw.md5(sid)
self.__sid = sid
if not self.__sid:
return self.wsSend('WebSocketIO无效')
@ -385,21 +407,27 @@ class ssh_terminal:
if self.__connecting and not 'host' in info:
return
if not self.__ssh:
self.__connecting = True
result = self.setAttr(info)
self.__connecting = False
else:
result = self.returnMsg(False, '')
if not sid in self.__ssh_list:
if type(info) == dict:
self.__connecting = True
result = self.setAttr(info)
self.__connecting = False
if sid in self.__ssh_list:
result = self.returnMsg(True, '已连接')
if result['status']:
if type(info) == str:
time.sleep(0.1)
self.__ssh.send(info)
if self.__ssh_list[sid].exit_status_ready():
self.wsSend("已关闭!\r\n")
del(self.__ssh_list[sid])
return
self.__ssh_list[sid].send(info)
try:
time.sleep(0.005)
recv = self.__ssh.recv(8192)
recv = self.__ssh_list[sid].recv(8192)
return self.wsSend(recv)
except Exception as ex:
return self.wsSend('')

@ -154,7 +154,7 @@ function webShell_Load(){
}
});
webShell_Menu2();
webShell_Menu();
}
@ -264,8 +264,9 @@ function webShell_getCmdList(){
}
function webShell_Menu2(){
function webShell_Menu(){
var random = 'localhost';
// host_ssh_list[random] = new Terms_WebSocketIO('#'+random, { ssh_info: { host: "38.6.224.67", ps: "22", id: random } });
host_ssh_list[random] = new Terms_WebSocketIO('#'+random, { ssh_info: { host: "127.0.0.1", ps: "22", id: random } });
}

@ -660,7 +660,7 @@ def webssh_websocketio(data):
import ssh_terminal
shell_client = ssh_terminal.ssh_terminal()
print("request.sid", request.sid)
# print("request.sid", request.sid)
shell_client.run(request.sid, data)
return

@ -1,6 +1,4 @@
function Terms_WebSocketIO (el, config) {
console.log(config);
if (typeof config == "undefined") {
config = {};
}
@ -17,9 +15,12 @@ function Terms_WebSocketIO (el, config) {
this.run();
}
var socket, gterm;
Terms_WebSocketIO.prototype = {
registerCloseCallBack:function(callback){
this.callback_close = callback;
},
// websocket持久化连接
connect: function (callback) {
if(!this.ws){
@ -29,64 +30,35 @@ Terms_WebSocketIO.prototype = {
//连接服务器成功
on_open: function (ws_event) {
var http_token = $("#request_token_head").attr('token');
this.ssh_info['x-http-token'] = http_token;
this.send(JSON.stringify(this.ssh_info || { 'x-http-token': http_token }))
this.term.FitAddon.fit();
this.resize({ cols: this.term.cols, rows: this.term.rows });
},
//服务器消息事件
on_message: function (ws_event) {
// console.log(ws_event.data);
this.term.write(ws_event.data);
if (ws_event.data == '\r\n登出\r\n' || ws_event.data == '登出\r\n' ||
ws_event.data == '\r\nlogout\r\n' || ws_event.data == 'logout\r\n'||
ws_event.data == '\r\nexit\r\n' || ws_event.data == 'exit\r\n') {
this.term.destroy();
clearInterval(this.term_timer);
this.ws.disconnect();
this.ws.close();
if (this.callback_close){
this.callback_close();
}
}
},
//websocket关闭事件
on_close: function (ws_event) {
this.ws = null;
},
//websocket错误事件
on_error: function (ws_event) {
if (ws_event.target.readyState === 3) {
// var msg = '错误: 无法创建WebSocket连接,请在面板设置页面关闭【开发者模式】';
// layer.msg(msg,{time:5000})
// if(Term.state === 3) return
// Term.term.write(msg)
// Term.state = 3;
} else {
console.log(ws_event)
}
},
//发送数据
//@param event 唯一事件名称
//@param data 发送的数据
//@param callback 服务器返回结果时回调的函数,运行完后将被回收
send: function (data, num) {
var that = this;
//如果没有连接,则尝试连接服务器
if (!this.ws || this.bws.readyState == 3 || this.bws.readyState == 2) {
this.connect();
}
//判断当前连接状态,如果!=1,则100ms后尝试重新发送
if (this.ws.readyState === 1) {
this.ws.send(data);
} else {
if (this.state === 3) return;
if (!num) num = 0;
if (num < 5) {
num++;
setTimeout(function () { that.send(data, num++); }, 100)
}
}
},
//关闭连接
@ -134,8 +106,7 @@ Terms_WebSocketIO.prototype = {
this.term.on('data', function (data) {
that.ws.emit('webssh_websocketio', data);
});
// $('.terminal').detach().appendTo('#'+this.id);
this.ws.emit('webssh_websocketio', this.ssh_info);
this.ws.emit('webssh_websocketio', '\n');
this.term.focus();

Loading…
Cancel
Save