pull/350/head
midoks 2 years ago
parent 17a92518b4
commit c952be4e45
  1. 1
      class/core/mw.py
  2. 29
      class/core/ssh_terminal.py
  3. 27
      plugins/webssh/index.py
  4. 75
      plugins/webssh/js/webssh.js

@ -1503,6 +1503,7 @@ def getSshDir():
def createRsa(): def createRsa():
# ssh-keygen -t rsa -P "" -C "midoks@163.com"
ssh_dir = getSshDir() ssh_dir = getSshDir()
# mw.execShell("rm -f /root/.ssh/*") # mw.execShell("rm -f /root/.ssh/*")
if not os.path.exists(ssh_dir + '/authorized_keys'): if not os.path.exists(ssh_dir + '/authorized_keys'):

@ -37,6 +37,7 @@ class ssh_terminal:
__sid = '' __sid = ''
__host = None __host = None
__type = '0'
__port = 22 __port = 22
__user = None __user = None
__pass = None __pass = None
@ -243,28 +244,24 @@ class ssh_terminal:
if not self.__pass and not self.__pkey: if not self.__pass and not self.__pkey:
return self.returnMsg(False, '密码或私钥不能都为空: {}:{}'.format(self.__host, self.__port)) return self.returnMsg(False, '密码或私钥不能都为空: {}:{}'.format(self.__host, self.__port))
if self.__pkey: if self.__pkey != '' and self.__type != '0':
self.debug('正在认证私钥') self.debug('正在认证私钥')
if sys.version_info[0] == 2: p_file = StringIO(str(self.__pkey.replace('\\n', '\n')))
try: # p_file = "/tmp/t_ssh_pkey.txt"
self.__pkey = self.__pkey.encode('utf-8') # mw.writeFile(p_file, self.__pkey.replace('\\n', '\n'))
except: # mw.execShell('chmod 600 ' + p_file)
pass
p_file = BytesIO(self.__pkey)
else:
p_file = StringIO(self.__pkey)
try: try:
p_file.seek(0)
pkey = paramiko.RSAKey.from_private_key(p_file) pkey = paramiko.RSAKey.from_private_key(p_file)
except: except:
try: try:
p_file.seek(0) # 重置游标 p_file.seek(0) # 重置游标
pkey = paramiko.Ed25519Key.from_private_key(p_file) pkey = paramiko.Ed25519Key.from_private_key(
p_file)
except: except:
try: try:
p_file.seek(0) p_file.seek(0)
pkey = paramiko.ECDSAKey.from_private_key( pkey = paramiko.ECDSAKey.from_private_key(p_file)
p_file)
except: except:
p_file.seek(0) p_file.seek(0)
pkey = paramiko.DSSKey.from_private_key(p_file) pkey = paramiko.DSSKey.from_private_key(p_file)
@ -285,8 +282,7 @@ class ssh_terminal:
self.setSshdConfig(True) self.setSshdConfig(True)
self.__tp.close() self.__tp.close()
e = str(e) e = str(e)
if e.find('websocket error!') != -1: # print(e)
return self.returnMsg(True, '连接成功')
if e.find('Authentication timeout') != -1: if e.find('Authentication timeout') != -1:
self.debug("认证超时{}".format(e)) self.debug("认证超时{}".format(e))
return self.returnMsg(False, '认证超时,请按回车重试!{}'.format(e)) return self.returnMsg(False, '认证超时,请按回车重试!{}'.format(e))
@ -332,6 +328,9 @@ class ssh_terminal:
_t = mw.readFile(dst_info) _t = mw.readFile(dst_info)
info = json.loads(_t) info = json.loads(_t)
if 'type' in info:
self.__type = info['type']
if 'port' in info: if 'port' in info:
self.__port = int(info['port']) self.__port = int(info['port'])
if 'username' in info: if 'username' in info:

@ -112,6 +112,33 @@ class App():
rdata = mw.readFile(file) rdata = mw.readFile(file)
return json.loads(rdata) return json.loads(rdata)
def get_server_by_host(self):
args = self.getArgs()
check = self.checkArgs(args, ['host'])
if not check[0]:
return check[1]
info_file = self.__host_dir + '/' + args['host'] + '/info.json'
if os.path.exists(info_file):
try:
info_tmp = self.getSshInfo(info_file)
host_info = {}
host_info['host'] = args['host']
host_info['port'] = info_tmp['port']
host_info['ps'] = info_tmp['ps']
host_info['type'] = info_tmp['type']
if 'password' in info_tmp:
host_info['password'] = info_tmp['password']
if 'pkey' in info_tmp:
host_info['pkey'] = info_tmp['pkey']
if 'pkey_passwd' in info_tmp:
host_info['pkey_passwd'] = info_tmp['pkey_passwd']
except Exception as e:
return mw.returnJson(False, '错误:' + str(e))
return mw.returnJson(True, 'ok!', host_info)
return mw.returnJson(False, '不存在此配置')
def get_server_list(self): def get_server_list(self):
host_list = [] host_list = []
for name in os.listdir(self.__host_dir): for name in os.listdir(self.__host_dir):

@ -354,7 +354,7 @@ function webShell_getHostList(info){
for (var i = 0; i < alist.length; i++) { for (var i = 0; i < alist.length; i++) {
tli+='<li class="data-host-list" data-index="'+i+'" data-host="'+alist[i]['host']+'">\ tli+='<li class="data-host-list" data-index="'+i+'" data-host="'+alist[i]['host']+'">\
<i></i>\ <i></i>\
<span>'+alist[i]['host']+'</span>\ <span class="host">'+alist[i]['host']+'</span>\
<span class="tootls">\ <span class="tootls">\
<span class="glyphicon glyphicon-edit" aria-hidden="true" title="编辑常用命令信息"></span>\ <span class="glyphicon glyphicon-edit" aria-hidden="true" title="编辑常用命令信息"></span>\
<span class="glyphicon glyphicon-trash" aria-hidden="true" title="删除常用命令信息"></span>\ <span class="glyphicon glyphicon-trash" aria-hidden="true" title="删除常用命令信息"></span>\
@ -364,13 +364,13 @@ function webShell_getHostList(info){
$('.tootls_host_list').html(tli); $('.tootls_host_list').html(tli);
$('.data-host-list .glyphicon-edit').click(function(){ $('.data-host-list .glyphicon-edit').click(function(e){
var index = $(this).parent().parent().attr('data-index'); var index = $(this).parent().parent().attr('data-index');
var info = alist[index]; var info = alist[index];
webShell_addServer(info); webShell_addServer(info);
}); });
$('.data-host-list .glyphicon-trash').click(function(){ $('.data-host-list .glyphicon-trash').click(function(e){
var index = $(this).parent().parent().attr('data-index'); var index = $(this).parent().parent().attr('data-index');
var t = alist[index]; var t = alist[index];
appPost('del_server', {host:t['host']}, function(rdata){ appPost('del_server', {host:t['host']}, function(rdata){
@ -382,16 +382,17 @@ function webShell_getHostList(info){
}); });
$('.tootls_host_list').on('click', 'li', function (e) { $('.tootls_host_list .host').on('click', function (e) {
var index = $(this).index(); var _this = $(this).parent();
var host = $(this).data('host'); var index = $(_this).index();
$(this).find('i').addClass('active'); var host = $(_this).data('host');
$(_this).find('i').addClass('active');
if ($('.item[data-host="' + host + '"]').length > 0) { if ($('.item[data-host="' + host + '"]').length > 0) {
layer.msg('已经打开!', { icon: 0, time: 3000 }) layer.msg('已经打开!', { icon: 0, time: 3000 });
// layer.msg('如需多会话窗口,请右键终端标题复制会话!', { icon: 0, time: 3000 });
} else { } else {
webShell_openTermView(alist[index]); webShell_openTermView(alist[index]);
} }
e.preventDefault();
}); });
}); });
} }
@ -420,7 +421,7 @@ function webShell_addServer(info=[]){
<span class="tname">验证方式</span>\ <span class="tname">验证方式</span>\
<div class="info-r">\ <div class="info-r">\
<div class="btn-group">\ <div class="btn-group">\
<button type="button" tabindex="-1" class="btn btn-sm auth_type_checkbox btn-success" data-ctype="0">密码验证</button>\ <button type="button" tabindex="-1" class="btn btn-sm auth_type_checkbox btn-default btn-success" data-ctype="0">密码验证</button>\
<button type="button" tabindex="-1" class="btn btn-sm auth_type_checkbox btn-default" data-ctype="1">私钥验证\ <button type="button" tabindex="-1" class="btn btn-sm auth_type_checkbox btn-default" data-ctype="1">私钥验证\
</button>\ </button>\
</div>\ </div>\
@ -452,6 +453,38 @@ function webShell_addServer(info=[]){
</div>\ </div>\
</div>', </div>',
success:function(){ success:function(){
if (typeof(info['host'])!='undefined'){
$('input[name="host"]').val(info['host']);
appPost('get_server_by_host',{host:info['host']},function(rdata){
var rdata = $.parseJSON(rdata.data);
var jdata = rdata.data;
if (jdata['type'] == 0){
$('input[name="password"]').val(jdata['password']);
} else{
$('textarea[name="pkey"]').val(jdata['pkey']);
$('input[name="pkey_passwd"]').val(jdata['pkey_passwd']);
}
$('input[name="ps"]').val(jdata['ps']);
$('.auth_type_checkbox').each(function(){
if ($(this).data('ctype') == jdata['type']){
$(this).addClass('btn-success');
} else {
$(this).removeClass('btn-success');
}
});
if (jdata['type'] == 0){
$('.c_password_view').removeClass('show').addClass('show');
$('.c_pkey_view').removeClass('show').addClass('hide');
$('.key_pwd_line').removeClass('show').addClass('hide');
}else{
$('.c_password_view').removeClass('show').addClass('hide');
$('.c_pkey_view').removeClass('show').addClass('show');
$('.key_pwd_line').removeClass('show').addClass('show');
}
});
}
$('.auth_type_checkbox').click(function(){ $('.auth_type_checkbox').click(function(){
var ctype = $(this).attr('data-ctype'); var ctype = $(this).attr('data-ctype');
$('.auth_type_checkbox').removeClass('btn-success'); $('.auth_type_checkbox').removeClass('btn-success');
@ -473,18 +506,20 @@ function webShell_addServer(info=[]){
var host = $('input[name="host"]').val(); var host = $('input[name="host"]').val();
var port = $('input[name="port"]').val(); var port = $('input[name="port"]').val();
var username = $('input[name="username"]').val(); var username = $('input[name="username"]').val();
var password = '';
var type = $('.auth_type_checkbox').attr('data-ctype'); var pkey = '';
var pkey_passwd = '';
var type = $('.btn-group .btn-success').attr('data-ctype');
if (type == "0"){ if (type == "0"){
var password = $('input[name="password"]').val(); password = $('input[name="password"]').val();
} else{ } else{
var pkey = $('input[name="pkey"]').val(); pkey = $('textarea[name="pkey"]').val();
var pkey_passwd = $('input[name="pkey_passwd"]').val(); pkey_passwd = $('input[name="pkey_passwd"]').val();
} }
var ps = $('input[name="ps"]').val(); var ps = $('input[name="ps"]').val();
appPost('add_server',{ var req_data = {
type:type, type:type,
host:host, host:host,
port:port, port:port,
@ -492,8 +527,12 @@ function webShell_addServer(info=[]){
password:password, password:password,
pkey:pkey, pkey:pkey,
pkey_passwd:pkey_passwd, pkey_passwd:pkey_passwd,
ps ps:ps,
},function(rdata){ };
console.log(req_data);
appPost('add_server',req_data,function(rdata){
layer.close(l); layer.close(l);
var rdata = $.parseJSON(rdata.data); var rdata = $.parseJSON(rdata.data);
showMsg(rdata.msg, function(){ showMsg(rdata.msg, function(){

Loading…
Cancel
Save