This commit is contained in:
jose
2020-07-06 10:33:41 +08:00
parent f1746060ed
commit 5949d7624f
26 changed files with 730 additions and 549 deletions
+15 -5
View File
@@ -304,6 +304,7 @@ def login():
if session['login'] != False:
session['login'] = False
cache.set('dologin',True)
public.WriteLog('User LogOut','Client: {}, has manually exited the panel'.format(public.GetClientIp()+ ":" + str(request.environ.get('REMOTE_PORT'))))
session.clear()
session_path = r'/dev/shm/session_py' + str(sys.version_info[0])
if os.path.exists(session_path): public.ExecShell("rm -f " + session_path + '/*')
@@ -337,6 +338,7 @@ def login():
data['hosts'] = '[]'
else:
data['hosts'] = json.dumps(data['hosts'])
data['app_login'] = os.path.exists('data/app_login.pl')
return render_template(
'login.html',
data=data
@@ -435,10 +437,10 @@ def database(pdata = None):
def get_phpmyadmin_dir():
path = public.GetConfigValue('setup_path') + '/phpmyadmin'
if not os.path.exists(path): return None
phpport = '888'
try:
import re;
import re
if session['webserver'] == 'nginx':
filename =public.GetConfigValue('setup_path') + '/nginx/conf/nginx.conf'
conf = public.readFile(filename)
@@ -446,13 +448,21 @@ def get_phpmyadmin_dir():
rtmp = re.search(rep,conf)
if rtmp:
phpport = rtmp.groups()[0]
else:
if session['webserver'] == 'apache':
filename = public.GetConfigValue('setup_path') + '/apache/conf/extra/httpd-vhosts.conf'
conf = public.readFile(filename)
rep = "Listen\s+([0-9]+)\s*\n"
rtmp = re.search(rep,conf)
if rtmp:
phpport = rtmp.groups()[0]
if session['webserver'] == 'openlitespeed':
filename = public.GetConfigValue('setup_path') + '/panel/vhost/openlitespeed/listen/888.conf'
public.writeFile('/tmp/2',filename)
conf = public.readFile(filename)
rep = "address\s*\*\:\s*(\d+)"
rtmp = re.search(rep,conf)
if rtmp:
phpport = rtmp.groups()[0]
except:
pass
@@ -488,7 +498,7 @@ def api(pdata = None):
if comReturn: return comReturn
import panelApi
api_object = panelApi.panelApi()
defs = ('get_token','check_bind','get_bind_status','get_apps','add_bind_app','remove_bind_app','set_token','get_tmp_token','get_app_bind_status')
defs = ('get_token','check_bind','get_bind_status','get_apps','add_bind_app','remove_bind_app','set_token','get_tmp_token','get_app_bind_status','login_for_app')
return publicObject(api_object,defs,None,pdata)
@app.route('/get_app_bind_status',methods=method_all)
@@ -1309,7 +1319,7 @@ def get_pd():
34, 98, 116, 46, 115, 111, 102, 116, 46, 117, 112, 100, 97, 116, 97, 95,
112, 114, 111, 40, 41, 34, 62, 32493, 36153, 60, 47, 97, 62, 60,
47, 115, 112, 97, 110, 62])
elif tmp >= 0:
if tmp >= 0 and ltd in [-1,-2]:
if tmp == 0:
tmp2 = public.to_string([27704,20037,25480,26435])
tmp3 = public.to_string([60, 115, 112, 97, 110, 32, 99, 108, 97, 115, 115, 61, 34, 98, 116,
+7 -8
View File
@@ -4925,11 +4925,11 @@ select[disabled]{
::-webkit-scrollbar {
/*滚动条整体样式*/
width : 10px; /*高宽分别对应横竖滚动条的尺寸*/
height: 1px;
height: 10px;
}
::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
border-radius: 10px;
border-radius: 0;
box-shadow : inset 0 0 5px rgba(0, 0, 0, 0.2);
background : #999;
}
@@ -5382,7 +5382,7 @@ select[disabled]{
.ace_catalogue_list::-webkit-scrollbar {
/*滚动条整体样式*/
width: 9px; /*高宽分别对应横竖滚动条的尺寸*/
height: 1px;
height: 10px;
}
.ace_catalogue_list::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
@@ -5466,18 +5466,17 @@ select[disabled]{
.ace_scrollbar::-webkit-scrollbar {
/*滚动条整体样式*/
width : 10px; /*高宽分别对应横竖滚动条的尺寸*/
height: 1px;
height: 10px;
}
.ace_scrollbar::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
background: #999;
border-radius: 10px;
background: #777;
}
.ace_scrollbar::-webkit-scrollbar-track{
/*滚动条里面轨道*/
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
background: #ededed;
background: #333;
border-radius: 10px;
}
.ace_editors.active {
@@ -6769,7 +6768,7 @@ select[disabled]{
.dropUpLoadFile::-webkit-scrollbar {
/*滚动条整体样式*/
width : 15px; /*高宽分别对应横竖滚动条的尺寸*/
height: 1px;
height: 10px;
}
.dropUpLoadFile::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
+7 -7
View File
@@ -87,7 +87,7 @@ var fileDrop = {
clearTimeout(time);
return false;
}
if(/^\.\w*/.test(filesAndDirs[i].name) ||/\/\.\w*/g.test(path)) continue; //排查隐藏文件目录和文件
// if(/^\.\w*/.test(filesAndDirs[i].name) ||/\/\.\w*/g.test(path)) continue; //排查隐藏文件目录和文件
fileDrop.filesList.push({
file:filesAndDirs[i],
path:bt.get_file_path(path +'/'+ filesAndDirs[i].name).replace('//','/'),
@@ -160,7 +160,7 @@ var fileDrop = {
$('<input type="file" multiple="true" autocomplete="off" '+ (type == 'dir'?'webkitdirectory=""':'') +' />').change(function(e){
var files = e.target.files,arry = [];
for(var i=0;i<files.length;i++){
if(/^\.\w*/.test(files[i].name) || /\/\.\w*/g.test(files[i].webkitRelativePath)) continue;
// if(/^\.\w*/.test(files[i].name) || /\/\.\w*/g.test(files[i].webkitRelativePath)) continue;
var config = {
file:files[i],
path: bt.get_file_path('/' + files[i].webkitRelativePath).replace('//','/') ,
@@ -928,7 +928,7 @@ function GetFiles(Path, sort) {
if (getCookie("rank") == "a") {
$("#set_list").addClass("active");
$("#set_icon").removeClass("active");
if (rdata.PATH=='/') rdata.PATH = '';
//if (rdata.PATH=='/') rdata.PATH = '';
Body += "<tr class='folderBoxTr' fileshare='"+ fmp[6] +"' data-composer='"+fmp[7]+"' data-path='" + rdata.PATH + "/" + fmp[0] + "' filetype='dir'>\
<td><input type='checkbox' name='id' value='" + fmp[0] + "'></td>\
<td class='column-name'><span class='cursor' onclick=\"GetFiles('" + rdata.PATH + "/" + fmp[0] + "')\"><span class='ico ico-folder'></span><a class='text' title='" + fmp[0] + fmp[5] + "'>" + cnametext + fileMsg + "</a></span></td>\
@@ -2037,7 +2037,7 @@ function UnZip(fileName, type) {
type = (type == 1) ? 'tar' : 'zip'
var umpass = '';
if (type == 'zip') {
umpass = '<div class="line"><span class="tname">' + lan.files.zip_pass_title + '</span><input type="text" class="bt-input-text" id="unpass" value="" placeholder="' + lan.files.zip_pass_msg + '" style="width:330px" /></div>'
umpass = '<div class="line"><span class="tname" style="width:110px">' + lan.files.zip_pass_title + '</span><input type="text" class="bt-input-text" id="unpass" value="" placeholder="' + lan.files.zip_pass_msg + '" style="width:330px" /></div>'
}
var layers = layer.open({
type: 1,
@@ -2047,9 +2047,9 @@ function UnZip(fileName, type) {
title: lan.files.unzip_title,
content: '<div class="bt-form pd20 pb70">' +
'<div class="line unzipdiv">' +
'<span class="tname">' + lan.files.unzip_name + '</span><input type="text" class="bt-input-text" id="sfile" value="' + fileName + '" placeholder="' + lan.files.unzip_name_title + '" style="width:330px" /></div>' +
'<div class="line"><span class="tname">' + lan.files.unzip_to + '</span><input type="text" class="bt-input-text" id="dfile" value="' + path + '" placeholder="' + lan.files.unzip_to + '" style="width:330px" /></div>' + umpass +
'<div class="line"><span class="tname">' + lan.files.unzip_coding + '</span><select class="bt-input-text" name="coding">' +
'<span class="tname" style="width:110px">' + lan.files.unzip_name + '</span><input type="text" class="bt-input-text" id="sfile" value="' + fileName + '" placeholder="' + lan.files.unzip_name_title + '" style="width:330px" /></div>' +
'<div class="line"><span class="tname" style="width:110px">' + lan.files.unzip_to + '</span><input type="text" class="bt-input-text" id="dfile" value="' + path + '" placeholder="' + lan.files.unzip_to + '" style="width:330px" /></div>' + umpass +
'<div class="line"><span class="tname" style="width:110px">' + lan.files.unzip_coding + '</span><select class="bt-input-text" name="coding">' +
'<option value="UTF-8">UTF-8</option>' +
'<option value="gb18030">GBK</option>' +
'</select>' +
+1 -1
View File
@@ -651,7 +651,7 @@ var aceEditor = {
$('.ace_dir_tools').on('click','.upper_level',function(){
var _paths = $(this).attr('data-menu-path');
_this.reader_file_dir_menu({path:_paths,is_empty:true});
$('.ace_catalogue_title').html('目录:'+ _paths).attr('title',_paths);
$('.ace_catalogue_title').html('Directory: '+ _paths).attr('title',_paths);
});
// 新建文件(文件目录主菜单)
$('.ace_dir_tools').on('click','.new_folder',function(e){
+7 -6
View File
@@ -1404,11 +1404,11 @@ var site = {
}
});
$('#ols').on('click', function() {
private.toggle();
checked = private.is(':hidden') ? false : true;
var loadT = bt.load();
bt.send('switch_ols_private_cache', 'config/switch_ols_private_cache', { id: web.id }, function(res) {
var loadT = bt.load();
loadT.close();
private.toggle();
checked = private.is(':hidden') ? false : true;
bt.msg(res);
if (checked) {
bt.send('get_ols_private_cache', 'config/get_ols_private_cache', { id: web.id }, function(fdata) {
@@ -1514,7 +1514,7 @@ var site = {
callback: function(obj) {
if (bt.os == 'Linux') {
var spath = filename;
if (obj.val() != lan.site.rewritename) spath = '/www/server/panel/rewrite/' + webserver + '/' + obj.val() + '.conf';
if (obj.val() != lan.site.rewritename) spath = '/www/server/panel/rewrite/' + (webserver == 'openlitespeed'?'apache':webserver) + '/' + obj.val() + '.conf';
bt.files.get_file_body(spath, function(ret) {
editor.setValue(ret.data);
})
@@ -1635,7 +1635,8 @@ var site = {
<li>This is primary configuration file of the site, do NOT modify it at will if you do not know configuration rules.</li>\
</ul>';
$("#webedit-con").html(con);
var config = bt.aceEditor({ el: 'siteConfigBody', path: '/www/server/panel/vhost/' + bt.get_cookie('serverType') + '/' + web.name + '.conf' })
var webserve = bt.get_cookie('serverType'),
config = bt.aceEditor({ el: 'siteConfigBody', path: '/www/server/panel/vhost/' + (webserve == 'openlitespeed' ? (webserve + '/detail') : webserve) + '/' + web.name + '.conf' });
$("#OnlineEditFileBtn").click(function(e) {
bt.saveEditor(config);
});
@@ -3141,7 +3142,7 @@ var site = {
content: "<div class='bt-form'><div class='bt-w-menu site-menu pull-left' style='height: 100%;'></div><div id='webedit-con' class='bt-w-con webedit-con pd15'></div></div>"
})
setTimeout(function() {
var webcache = bt.get_cookie('serverType') == 'openlitespeed' ? { title: 'LSCache', callback: site.edit.ols_cache } : '';
var webcache = bt.get_cookie('serverType') == 'openlitespeed' ? { title: 'LS-Cache', callback: site.edit.ols_cache } : '';
var menus = [
{ title: lan.site.domain_man, callback: site.edit.set_domains },
{ title: lan.site.site_menu_1, callback: site.edit.set_dirbind },
+128 -59
View File
@@ -98,7 +98,31 @@ var soft = {
click_opt += ' onclick="soft.set_soft_config(\'' + item.name + '\')" ';
}
}
if (rdata.apache22 && item.name.indexOf('php-') >= 0 && $.inArray(item.name, phps) == -1) click_opt = ' title="' + lan.soft.ap2_2_not_support + '"';
var is_php5 = item.name.indexOf('php-5') >= 0,
webcache = bt.get_cookie('serverType') == 'openlitespeed' ? true : false,
distribution = bt.get_cookie('distribution');
if (webcache) {
switch (distribution) {
case 'centos8':
if (is_php5 || item.name == 'php-7.0') {
click_opt = ' title="' + lan.soft.ap2_2_not_support + '"';
}
break;
case 'centos7':
if (item.name == 'php-5.2') {
click_opt = ' title="' + lan.soft.ap2_2_not_support + '"';
}
break;
default:
if (is_php5) {
click_opt = ' title="' + lan.soft.ap2_2_not_support + '"';
}
break;
}
}else if (rdata.apache22 && item.name.indexOf('php-') >= 0 && $.inArray(item.name, phps) == -1){
click_opt = ' title="' + lan.soft.ap2_2_not_support + '"';
}
//if (rdata.apache22 && item.name.indexOf('php-') >= 0 && $.inArray(item.name, phps) == -1) click_opt = ' title="' + lan.soft.ap2_2_not_support + '"';
return '<span ' + click_opt + ' ' + sStyle + ' ><img src="/static/img/soft_ico/ico-' + fName + '.png">' + item.title + ' ' + version + '</span>';
}
},
@@ -254,73 +278,116 @@ var soft = {
var is_php = item.name.indexOf('php-') >= 0,
is_php5 = item.name.indexOf('php-5') >= 0,
webcache = bt.get_cookie('serverType') == 'openlitespeed' ? true : false,
distribution = bt.get_cookie('distribution'),
redhat = rdata.Redhat;
if (rdata.apache22 && is_php && $.inArray(item.name, phps) == -1) {
if (item.setup) {
option = '<a class="btlink" onclick="bt.soft.un_install(\'' + item.name + '\')" >' + lan.soft.uninstall + '</a>';
} else {
distribution = bt.get_cookie('distribution');
if (webcache && is_php) {
if ((is_php5 || item.name == 'php-7.0') && distribution=='centos8') {
option = '<span title="\' + lan.soft.ap2_2_not_support + \'">' + lan.soft.not_comp + '</span>';
}
} else if (rdata.apache24 && item.name == 'php-5.2') {
if (item.setup) {
option = '<a class="btlink" onclick="bt.soft.un_install(\'' + item.name + '\')" >' + lan.soft.uninstall + '</a>';
} else {
}else if (distribution=='centos7'&&item.name == 'php-5.2') {
option = '<span title="\' + lan.soft.ap2_2_not_support + \'">' + lan.soft.not_comp + '</span>';
}
} else {
if (item.setup && item.task == '1') {
if (pay_opt == '') {
if (item.versions.length > 1) {
for (var i = 0; i < item.versions.length; i++) {
var min_version = item.versions[i]
var ret = bt.check_version(item.version, min_version.m_version + '.' + min_version.version);
if (ret > 0) {
if (ret == 2) option += '<a class="btlink" onclick="bt.soft.update_soft(\'' + item.name + '\',\'' + item.title + '\',\'' + min_version.m_version + '\',\'' + min_version.version + '\',\'' + min_version.update_msg.replace(/\n/g, "_bt_") + '\')" >' + lan.soft.update + '</a> | ';
break;
}else{
if (is_php5) {
option = '<span title="\' + lan.soft.ap2_2_not_support + \'">' + lan.soft.not_comp + '</span>';
} else {
if (item.setup && item.task == '1') {
if (pay_opt == '') {
if (item.versions.length > 1) {
for (var i = 0; i < item.versions.length; i++) {
var min_version = item.versions[i]
var ret = bt.check_version(item.version, min_version.m_version + '.' + min_version.version);
if (ret > 0) {
if (ret == 2) option += '<a class="btlink" onclick="bt.soft.update_soft(\'' + item.name + '\',\'' + item.title + '\',\'' + min_version.m_version + '\',\'' + min_version.version + '\',\'' + min_version.update_msg.replace(/\n/g, "_bt_") + '\')" >' + lan.soft.update + '</a> | ';
break;
}
}
} else {
var min_version = item.versions[0];
var cloud_version = min_version.m_version + '.' + min_version.version;
if (item.version != cloud_version) option += '<a class="btlink" onclick="bt.soft.update_soft(\'' + item.name + '\',\'' + item.title + '\',\'' + min_version.m_version + '\',\'' + min_version.version + '\',\'' + min_version.update_msg.replace(/\n/g, "_bt_") + '\')" >' + lan.soft.update + '</a> | ';
}
if (item.admin) {
option += '<a class="btlink" onclick="bt.soft.set_lib_config(\'' + item.name + '\',\'' + item.title + '\')">' + lan.soft.setup + '</a> | ';
} else {
option += '<a class="btlink" onclick="soft.set_soft_config(\'' + item.name + '\')">' + lan.soft.setup + '</a> | ';
}
} else {
option = pay_opt + ' | ' + option;
}
option += '<a class="btlink" onclick="bt.soft.un_install(\'' + item.name + '\')" >' + lan.soft.uninstall + '</a>';
} else if (item.task == '-1') {
option = '<a class="btlink" onclick="messagebox()" >' + lan.soft.installing + '</a>';
soft.is_install = true;
} else if (item.task == '0') {
option = '<a class="btlink" onclick="messagebox()" >' + lan.soft.wait_install + '</a>';
soft.is_install = true;
} else if (item.task == '-2') {
option = '<a class="btlink" onclick="messagebox()" >Updating</a>';
soft.is_install = true;
} else {
if (pay_opt) {
option = pay_opt;
} else {
option = '<a class="btlink" onclick="bt.soft.install(\'' + item.name + '\')" >' + lan.soft.install + '</a>';
}
}
}
}
}else {
if (rdata.apache22 && is_php && $.inArray(item.name, phps) == -1) {
if (item.setup) {
option = '<a class="btlink" onclick="bt.soft.un_install(\'' + item.name + '\')" >' + lan.soft.uninstall + '</a>';
} else {
option = '<span title="\' + lan.soft.ap2_2_not_support + \'">' + lan.soft.not_comp + '</span>';
}
} else if (rdata.apache24 && item.name == 'php-5.2') {
if (item.setup) {
option = '<a class="btlink" onclick="bt.soft.un_install(\'' + item.name + '\')" >' + lan.soft.uninstall + '</a>';
} else {
option = '<span title="\' + lan.soft.ap2_2_not_support + \'">' + lan.soft.not_comp + '</span>';
}
} else {
if (item.setup && item.task == '1') {
if (pay_opt == '') {
if (item.versions.length > 1) {
for (var i = 0; i < item.versions.length; i++) {
var min_version = item.versions[i]
var ret = bt.check_version(item.version, min_version.m_version + '.' + min_version.version);
if (ret > 0) {
if (ret == 2) option += '<a class="btlink" onclick="bt.soft.update_soft(\'' + item.name + '\',\'' + item.title + '\',\'' + min_version.m_version + '\',\'' + min_version.version + '\',\'' + min_version.update_msg.replace(/\n/g, "_bt_") + '\')" >' + lan.soft.update + '</a> | ';
break;
}
}
} else {
var min_version = item.versions[0];
var cloud_version = min_version.m_version + '.' + min_version.version;
if (item.version != cloud_version) option += '<a class="btlink" onclick="bt.soft.update_soft(\'' + item.name + '\',\'' + item.title + '\',\'' + min_version.m_version + '\',\'' + min_version.version + '\',\'' + min_version.update_msg.replace(/\n/g, "_bt_") + '\')" >' + lan.soft.update + '</a> | ';
}
if (item.admin) {
option += '<a class="btlink" onclick="bt.soft.set_lib_config(\'' + item.name + '\',\'' + item.title + '\')">' + lan.soft.setup + '</a> | ';
} else {
option += '<a class="btlink" onclick="soft.set_soft_config(\'' + item.name + '\')">' + lan.soft.setup + '</a> | ';
}
} else {
var min_version = item.versions[0];
var cloud_version = min_version.m_version + '.' + min_version.version;
if (item.version != cloud_version) option += '<a class="btlink" onclick="bt.soft.update_soft(\'' + item.name + '\',\'' + item.title + '\',\'' + min_version.m_version + '\',\'' + min_version.version + '\',\'' + min_version.update_msg.replace(/\n/g, "_bt_") + '\')" >' + lan.soft.update + '</a> | ';
option = pay_opt + ' | ' + option;
}
if (item.admin) {
option += '<a class="btlink" onclick="bt.soft.set_lib_config(\'' + item.name + '\',\'' + item.title + '\')">' + lan.soft.setup + '</a> | ';
option += '<a class="btlink" onclick="bt.soft.un_install(\'' + item.name + '\')" >' + lan.soft.uninstall + '</a>';
} else if (item.task == '-1') {
option = '<a class="btlink" onclick="messagebox()" >' + lan.soft.installing + '</a>';
soft.is_install = true;
} else if (item.task == '0') {
option = '<a class="btlink" onclick="messagebox()" >' + lan.soft.wait_install + '</a>';
soft.is_install = true;
} else if (item.task == '-2') {
option = '<a class="btlink" onclick="messagebox()" >Updating</a>';
soft.is_install = true;
} else {
if (pay_opt) {
option = pay_opt;
} else {
option += '<a class="btlink" onclick="soft.set_soft_config(\'' + item.name + '\')">' + lan.soft.setup + '</a> | ';
option = '<a class="btlink" onclick="bt.soft.install(\'' + item.name + '\')" >' + lan.soft.install + '</a>';
}
} else {
option = pay_opt + ' | ' + option;
}
option += '<a class="btlink" onclick="bt.soft.un_install(\'' + item.name + '\')" >' + lan.soft.uninstall + '</a>';
} else if (item.task == '-1') {
option = '<a class="btlink" onclick="messagebox()" >' + lan.soft.installing + '</a>';
soft.is_install = true;
} else if (item.task == '0') {
option = '<a class="btlink" onclick="messagebox()" >' + lan.soft.wait_install + '</a>';
soft.is_install = true;
} else if (item.task == '-2') {
option = '<a class="btlink" onclick="messagebox()" >Updating</a>';
soft.is_install = true;
} else {
if (pay_opt) {
option = pay_opt;
} else {
option = '<a class="btlink" onclick="bt.soft.install(\'' + item.name + '\')" >' + lan.soft.install + '</a>';
}
}
}
if (webcache && is_php5) {
if (!redhat) {
option = '<span title="\' + lan.soft.ap2_2_not_support + \'">' + lan.soft.not_comp + '</span>';
} else if (item.name == 'php-5.2'){
option = '<span title="\' + lan.soft.ap2_2_not_support + \'">' + lan.soft.not_comp + '</span>';
}
}
if (distribution=='centos8' && item.name == 'php-7.0') {
option = '<span title="\' + lan.soft.ap2_2_not_support + \'">' + lan.soft.not_comp + '</span>';
}
return option;
}
}
@@ -2747,13 +2814,15 @@ var soft = {
type: 'button',
width: '62px',
callback: function(ldata) {
var datal = {};
var datal = {},
loadP = bt.load();
delete ldata.btn_fresh;
delete ldata.btn_save;
ldata['enableGzipCompress']=$("#enableGzipCompress").prop('checked')?1:0;
ldata = JSON.stringify(ldata);
datal = { array: ldata };
bt.send('set_ols_value', 'config/set_ols_value', datal, function(res) {
loadP.close();
soft.get_tab_contents(key, obj);
bt.msg(res);
});
@@ -2877,7 +2946,7 @@ function soft_td_width_auto() {
} else {
thead_width = winWidth / 3.5;
}
$('#softList thead th:eq(2)').width(thead_width);
//$('#softList thead th:eq(2)').width(thead_width);
$('#softList tbody tr td:nth-child(8n+2)>span').width(thead_width + 75);
}
+1 -1
View File
@@ -89,7 +89,7 @@
<a style="display: none;" id="defaultPath">{{session['config']['sites_path']}}</a> {% block content %}{% endblock %}
<div class="footer bgw">{{session['brand']}}{{session['product']}} &copy;2014-{{session['yaer']}} {{session['brand']}} (bt.cn)
<!--<a style="margin-left:20px;color:#20a53a;" href="http://www.bt.cn/bbs" target="_blank">求助|建议请上宝塔论坛</a>-->
<a style="margin-left:20px;color:#20a53a;" href="http://forum.aapanel.com" target="_blank">{{session['bt_help']}}</a>
<a style="margin-left:20px;color:#20a53a;" href="https://forum.aapanel.com" target="_blank">{{session['bt_help']}}</a>
<a style="margin-left:20px;color:#20a53a;" href="https://doc.aapanel.com/web/#/3?page_id=117" target="_blank">User manual</a>
</div>
</div>
+3 -3
View File
@@ -654,7 +654,7 @@ class ajax:
public.writeFile(p_file,'<?php phpinfo(); ?>')
phpinfo = public.request_php(get.version,'/phpinfo.php',p_file,'')
if os.path.exists(p_file): os.remove(p_file)
return phpinfo.decode();
return phpinfo.decode()
#清理日志
def delClose(self,get):
@@ -868,7 +868,7 @@ class ajax:
if get.port in rulePort:
return public.returnMsg(False,'AJAX_PHPMYADMIN_PORT_ERR')
if public.get_webserver() == 'nginx':
rep = "listen\s+([0-9]+)\s*;"
rep = r"listen\s+([0-9]+)\s*;"
oldPort = re.search(rep,conf).groups()[0]
conf = re.sub(rep,'listen ' + get.port + ';\n',conf)
elif public.get_webserver() == 'apache':
@@ -937,7 +937,7 @@ class ajax:
return public.returnMsg(True,'SOFT_PHPMYADMIN_STATUS',(msg,))
#except:
#return public.returnMsg(False,'ERROR');
def ToPunycode(self,get):
import re;
get.domain = get.domain.encode('utf8')
+1 -1
View File
@@ -34,7 +34,7 @@ class panelSetup:
ua = ua.lower()
if ua.find('spider') != -1 or ua.find('bot') != -1:
return redirect('https://www.google.com')
g.version = '6.7.2'
g.version = '6.7.5'
g.title = public.GetConfigValue('title')
g.uri = request.path
if not os.path.exists('data/debug.pl'):
+2
View File
@@ -415,6 +415,8 @@ class config:
ols_php_path = '/usr/local/lsws/lsphp' + get.version + '/etc/php.ini'
if not os.path.exists(filename): return public.returnMsg(False,'PHP_NOT_EXISTS')
for file in [filename,ols_php_path]:
if not os.path.exists(file):
continue
phpini = public.readFile(file)
rep = r"disable_functions\s*=\s*.*\n"
phpini = re.sub(rep, 'disable_functions = ' + get.disable_functions + "\n", phpini)
+28 -26
View File
@@ -45,34 +45,36 @@ class data:
return result
def get_site_ssl_info(self,siteName):
s_file = 'vhost/nginx/{}.conf'.format(siteName)
is_apache = False
if not os.path.exists(s_file):
s_file = 'vhost/apache/{}.conf'.format(siteName)
is_apache = True
try:
s_file = 'vhost/nginx/{}.conf'.format(siteName)
is_apache = False
if not os.path.exists(s_file):
s_file = 'vhost/apache/{}.conf'.format(siteName)
is_apache = True
if not os.path.exists(s_file):
return -1
if not os.path.exists(s_file):
return -1
s_conf = public.readFile(s_file)
if not s_conf: return -1
ssl_file = None
if is_apache:
if s_conf.find('SSLCertificateFile') == -1:
return -1
s_tmp = re.findall(r"SSLCertificateFile\s+(.+\.pem)",s_conf)
if not s_tmp: return -1
ssl_file = s_tmp[0]
else:
if s_conf.find('ssl_certificate') == -1:
return -1
s_tmp = re.findall(r"ssl_certificate\s+(.+\.pem);",s_conf)
if not s_tmp: return -1
ssl_file = s_tmp[0]
ssl_info = public.get_cert_data(ssl_file)
if not ssl_info: return -1
ssl_info['endtime'] = int(int(time.mktime(time.strptime(ssl_info['notAfter'], "%Y-%m-%d")) - time.time()) / 86400)
return ssl_info
s_conf = public.readFile(s_file)
if not s_conf: return -1
ssl_file = None
if is_apache:
if s_conf.find('SSLCertificateFile') == -1:
return -1
s_tmp = re.findall(r"SSLCertificateFile\s+(.+\.pem)",s_conf)
if not s_tmp: return -1
ssl_file = s_tmp[0]
else:
if s_conf.find('ssl_certificate') == -1:
return -1
s_tmp = re.findall(r"ssl_certificate\s+(.+\.pem);",s_conf)
if not s_tmp: return -1
ssl_file = s_tmp[0]
ssl_info = public.get_cert_data(ssl_file)
if not ssl_info: return -1
ssl_info['endtime'] = int(int(time.mktime(time.strptime(ssl_info['notAfter'], "%Y-%m-%d")) - time.time()) / 86400)
return ssl_info
except: return -1
#return "{}:{}".format(ssl_info['issuer'],ssl_info['notAfter'])
+6 -3
View File
@@ -118,6 +118,7 @@ ssl-key=/www/server/data/server-key.pem
if "ssl-ca" not in conf:
conf = re.sub('\[mysqld\]','[mysqld]'+ssl_conf,conf)
public.writeFile(conf_file,conf)
public.ExecShell('chown mysql.mysql /www/server/data/*.pem')
return public.returnMsg(True,"Open successfully, take effect after manually restarting the database")
# 检查mysqlssl状态
@@ -646,6 +647,11 @@ SetLink
#设置数据库权限
def SetDatabaseAccess(self,get):
ssl = ""
if hasattr(get,'ssl'):
ssl = get.ssl
if ssl == "REQUIRE SSL" and not self.check_mysql_ssl_status(get):
return public.returnMsg(False,'SSL is not enabled in the database, please open it in the Mysql manager first')
name = get['name']
db_name = public.M('databases').where('username=?',(name,)).getField('name')
access = get['access']
@@ -657,9 +663,6 @@ SetLink
users = mysql_obj.query("select Host from mysql.user where User='" + name + "' AND Host!='localhost'")
for us in users:
mysql_obj.execute("drop user '" + name + "'@'" + us[0] + "'")
ssl = ""
if hasattr(get,'ssl'):
ssl = get.ssl
self.__CreateUsers(db_name,name,password,access,ssl)
return public.returnMsg(True, 'SET_SUCCESS')
+21 -21
View File
@@ -1742,27 +1742,27 @@ cd %s
self.set_store_data(data)
return public.returnMsg(True,'Successfully deleted!')
#单文件木马扫描
def file_webshell_check(self,get):
if not 'filename' in get: return public.returnMsg(True, 'file does not exist!')
import webshell_check
if webshell_check.webshell_check().upload_file_url(get.filename.strip()):
return public.returnMsg(False,'This file is webshell [ %s ]'%get.filename.strip().split('/')[-1])
else:
return public.returnMsg(True, 'no risk')
#目录扫描木马
def dir_webshell_check(self,get):
if not 'path' in get: return public.returnMsg(False, 'Please enter a valid directory!')
path=get.path.strip()
if os.path.exists(path):
#启动消息队列
exec_shell = public.get_python_bin() + ' /www/server/panel/class/webshell_check.py dir %s mail'%path
task_name = "Scan Trojan files for directory %s"%path
import panelTask
task_obj = panelTask.bt_task()
task_obj.create_task(task_name, 0, exec_shell)
return public.returnMsg(True, 'Starting Trojan killing process. Details will be in the panel security log')
# #单文件木马扫描
# def file_webshell_check(self,get):
# if not 'filename' in get: return public.returnMsg(True, 'file does not exist!')
# import webshell_check
# if webshell_check.webshell_check().upload_file_url(get.filename.strip()):
# return public.returnMsg(False,'This file is webshell [ %s ]'%get.filename.strip().split('/')[-1])
# else:
# return public.returnMsg(True, 'no risk')
#
# #目录扫描木马
# def dir_webshell_check(self,get):
# if not 'path' in get: return public.returnMsg(False, 'Please enter a valid directory!')
# path=get.path.strip()
# if os.path.exists(path):
# #启动消息队列
# exec_shell = public.get_python_bin() + ' /www/server/panel/class/webshell_check.py dir %s mail'%path
# task_name = "Scan Trojan files for directory %s"%path
# import panelTask
# task_obj = panelTask.bt_task()
# task_obj.create_task(task_name, 0, exec_shell)
# return public.returnMsg(True, 'Starting Trojan killing process. Details will be in the panel security log')
# 获取下载地址列表
def get_download_url_list(self, get):
+1 -1
View File
@@ -100,7 +100,7 @@ def control_init():
public.ExecShell(c)
p_file = 'class/plugin2.so'
if os.path.exists(p_file): public.ExecShell("rm -f class/*.so")
public.ExecShell("chmod -R 600 /www/server/panel/data;chmod -R 600 /www/server/panel/config;chmod -R 700 /www/server/cron;chmod -R 600 /www/server/cron/*.log;chown -R root:root /www/server/panel/data;chown -R root:root /www/server/panel/config")
public.ExecShell("chmod -R 600 /www/server/panel/data;chmod -R 600 /www/server/panel/config;chmod -R 700 /www/server/cron;chmod -R 600 /www/server/cron/*.log;chown -R root:root /www/server/panel/data;chown -R root:root /www/server/panel/config;chown -R root:root /www/server/phpmyadmin;chmod -R 755 /www/server/phpmyadmin")
#disable_putenv('putenv')
clean_session()
#set_crond()
+11
View File
@@ -30,6 +30,17 @@ class panelApi:
del(data['key'])
return data
def login_for_app(self,get):
from BTPanel import cache
tid = get.tid
if(len(tid) != 12): return public.returnMsg(False,'Invalid login key')
session_id = cache.get(tid)
if not session_id: return public.returnMsg(False,'The specified key does not exist or has expired')
if(len(session_id) != 64): return public.returnMsg(False,'Invalid login key')
cache.set(session_id,'True',120)
return public.returnMsg(True,'Scan code successfully, log in!')
def get_api_config(self):
tmp = public.ReadFile(self.save_path)
if not tmp or not os.path.exists(self.save_path):
+2 -1
View File
@@ -90,7 +90,8 @@ class panelPHP:
shutil.copy(src_php_ini,php_ini)
#解除所有禁用函数
php_ini_body = public.readFile(php_ini)
php_ini_body = re.sub("disable_functions\s*=.*","disable_functions = ",php_ini_body)
php_ini_body = re.sub(r"disable_functions\s*=.*","disable_functions = ",php_ini_body)
php_ini_body = re.sub(r".*bt_filter.+","",php_ini_body)
public.writeFile(php_ini,php_ini_body)
return php_path + php_v + '/bin/php -c ' + php_ini
+9 -24
View File
@@ -153,26 +153,6 @@ class panelPlugin:
check_result = self.check_install_limit(get)
if check_result:
return check_result
# p_node = '/www/server/panel/install/public.sh'
# if os.path.exists(p_node):
# if len(public.readFile(p_node)) < 100: os.remove(p_node)
# if not pluginInfo: return public.returnMsg(False,'INIT_PLUGIN_NOT_EXISTS')
# if not self.check_mutex(pluginInfo['mutex']): return public.returnMsg(False,'UNINSTALL_FIRST' , (pluginInfo['mutex'],))
# if not hasattr(get,'id'):
# if not self.check_dependnet(pluginInfo['dependnet']): return public.returnMsg(False,'DEP_PAGE' , (pluginInfo['dependnet'],))
# if 'version' in get:
# for versionInfo in pluginInfo['versions']:
# if versionInfo['m_version'] != get.version: continue
# if not 'type' in get: get.type = '0'
# if int(get.type) > 4: get.type = '0'
# if get.type == '0':
# if not self.check_cpu_limit(versionInfo['cpu_limit']): return public.returnMsg(False,'At least [{0}] CPU cores are required to install'.format(versionInfo['cpu_limit']))
# if not self.check_mem_limit(versionInfo['mem_limit']): return public.returnMsg(False,'At least [{0} MB] memory is required to install'.format(versionInfo['mem_limit']))
# if not self.check_os_limit(versionInfo['os_limit']):
# m_ps = {0:public.GetMsg("ALL"),1:"Centos",2:"Ubuntu/Debian"}
# return public.returnMsg(False,'ONLY_SUP_SYS' , (m_ps[int(versionInfo['os_limit'])],))
# if not hasattr(get,'id'):
# if not self.check_dependnet(versionInfo['dependnet']): return public.returnMsg(False,'DEP_PAGE' , (versionInfo['dependnet'],))
if pluginInfo['type'] != 5:
result = self.install_sync(pluginInfo,get)
@@ -235,7 +215,7 @@ class panelPlugin:
if get.version == '1.8': return public.returnMsg(False,'NOT_SUP_NG1.8')
if get.sName.find('php-') != -1:get.sName = get.sName.split('-')[0]
ols_execstr = ""
if "php" == get.sName:
if "php" == get.sName and os.path.exists('/usr/local/lsws'):
ols_sName = 'php-ols'
ols_version = get.version.replace('.','')
ols_execstr = " &> /tmp/panelExec.log && /bin/bash install_soft.sh {} {} " + ols_sName + " " + ols_version
@@ -255,7 +235,7 @@ class panelPlugin:
ols_execstr = ols_execstr.format(get.type,mtype)
execstr = "cd /www/server/panel/install && /bin/bash install_soft.sh {} {} {} {} {}".format(get.type,mtype,get.sName,get.version,ols_execstr)
if get.sName == "phpmyadmin":
execstr += "&> /tmp/panelExec.log && /usr/local/lsws/bin/lswsctrl restart"
execstr += "&> /tmp/panelExec.log && sleep 1 && /usr/local/lsws/bin/lswsctrl restart"
public.M('tasks').add('id,name,type,status,addtime,execstr',(None, mmsg + '['+get.sName+'-'+get.version+']','execshell','0',time.strftime('%Y-%m-%d %H:%M:%S'),execstr))
cache.delete('install_task')
public.writeFile('/tmp/panelTask.pl','True')
@@ -700,16 +680,21 @@ class panelPlugin:
if not os.path.exists(self.__index): public.writeFile(self.__index,'[]')
indexList = json.loads(public.ReadFile(self.__index))
if sName in indexList: return public.returnMsg(False,'DONT_ADD_AGAIN')
if len(indexList) >= 12:
softList = self.get_cloud_list(get)['list']
for softInfo in softList:
# return softList
if softInfo['name'] == 'php':
for i in softInfo['versions']:
php_v = 'php-'+ i['m_version']
if not os.path.exists('/www/server/php/{}'.format(i['m_version']))\
and php_v in indexList:
indexList.remove(php_v)
if softInfo['name'] in indexList:
new_softInfo = self.check_status(softInfo)
if not new_softInfo['setup']: indexList.remove(softInfo['name'])
public.writeFile(self.__index,json.dumps(indexList))
if len(indexList) >= 12: return public.returnMsg(False,'HP_DIS_MOST')
indexList.append(sName)
public.writeFile(self.__index,json.dumps(indexList))
return public.returnMsg(True,'ADD_SUCCESS')
-2
View File
@@ -154,11 +154,9 @@ class panelRedirect:
#检测名称是否重复
if sys.version_info.major < 3:
if len(get.redirectname) < 3 or len(get.redirectname) > 15:
print("NAME_LEN")
return public.returnMsg(False, 'NAME_LEN')
else:
if len(get.redirectname.encode("utf-8")) < 3 or len(get.redirectname.encode("utf-8")) > 15:
print("NAME_LEN")
return public.returnMsg(False, 'NAME_LEN')
if self.__CheckRedirect(get.sitename,get.redirectname):
return public.returnMsg(False, 'REDIRECT_EXIST')
+10 -33
View File
@@ -329,7 +329,7 @@ extprocessor BTSITENAME {
}
phpIniOverride {
php_admin_value open_basedir "/tmp:$VH_ROOT"
php_admin_value open_basedir "/tmp/:BT_RUN_PATH"
}
expires {
@@ -346,6 +346,10 @@ rewrite {
}
include /www/server/panel/vhost/openlitespeed/proxy/BTSITENAME/*.conf
'''
open_base_path = self.sitePath
if self.sitePath[-1] != '/':
open_base_path = self.sitePath + '/'
conf = conf.replace('BT_RUN_PATH',open_base_path)
conf = conf.replace('BT_EXTP_NAME',self.siteName)
conf = conf.replace('BTPHPV',self.phpVersion)
conf = conf.replace('BTSITENAME',self.siteName)
@@ -1128,7 +1132,7 @@ listener Default%s{
result = self.GetSiteRunPath(get)
if 'runPath' in result:
return result['runPath']
return False
return result
# 创建Let's Encrypt免费证书
@@ -2109,20 +2113,6 @@ listener SSL443 {
public.writeFile(file,conf301)
else:
public.ExecShell('rm -f {}*'.format(file))
# mconf = public.readFile(filename)
# if mconf == False: return public.returnMsg(False,'The specified configuration file does not exist!')
# if type == '1':
# if(srcDomain == 'all'):
# conf301 = "\n\t#301-START\n\tRewriteEngine on\n\tRewriteRule ^(.*)$ "+toDomain+"$1 [L,R=301]\n\t#301-END\n"
# else:
# conf301 = "\n\t#301-START\n\tRewriteEngine on\n\tRewriteCond %{HTTP_HOST} ^"+srcDomain+" [NC]\n\tRewriteRule ^(.*) "+toDomain+"$1 [L,R=301]\n\t#301-END\n"
# rep = "autoLoadHtaccess\s*1"
# mconf = mconf.replace(rep,rep + "\n\t" + conf301)
# else:
# rep = "\n\s+#301-START(.|\n){1,300}#301-END\n*"
# mconf = re.sub(rep, '\n\n', mconf,1)
# mconf = re.sub(rep, '\n\n', mconf,1)
# public.writeFile(filename,mconf)
isError = public.checkWebConfig()
if(isError != True):
@@ -2501,10 +2491,12 @@ server
public.writeFile(file,conf)
# OLS
file = self.setupPath + '/panel/vhost/apache/' + Name + '.conf'
file = self.setupPath + '/panel/vhost/openlitespeed/' + Name + '.conf'
conf = public.readFile(file)
if conf:
sitname = Path.split('/')[-2]
reg = 'vhRoot.*'
conf = re.sub(reg,'vhRoot '+Path,conf)
public.writeFile(file,conf)
#创建basedir
userIni = Path + '/.user.ini'
@@ -3026,11 +3018,6 @@ extprocessor %s {
}
""" % (get.proxyname,get.proxysite)
public.writeFile(file_path,reverse_proxy_conf)
# detail_file = "%s/panel/vhost/openlitespeed/detail/%s.conf" % (self.setupPath,get.sitename)
# detail_conf = public.readFile(detail_file)
# if detail_conf:
# include_conf = "\ninclude %s/panel/vhost/openlitespeed/proxy/%s/*.conf" % (self.setupPath,get.sitename)
# public.writeFile(detail_file,include_conf,"a+")
# 添加urlrewrite
dir_path = "%s/panel/vhost/openlitespeed/proxy/%s/urlrewrite/" % (self.setupPath, get.sitename)
if not os.path.exists(dir_path):
@@ -3040,16 +3027,6 @@ extprocessor %s {
RewriteRule ^%s(.*)$ http://%s/$1 [P,E=Proxy-Host:%s]
""" % (get.proxydir,get.proxyname,get.todomain)
public.writeFile(file_path,reverse_urlrewrite_conf)
# detail_file = "%s/panel/vhost/openlitespeed/detail/%s.conf" % (self.setupPath,get.sitename)
# detail_conf = public.readFile(detail_file)
# if detail_conf:
# include_conf = "\n include %s/panel/vhost/openlitespeed/proxy/%s/urlrewrite/*.conf" % (self.setupPath,get.sitename)
# rep = "autoLoadHtaccess\s+1"
# tmp = re.search(rep,detail_conf).group()
# tmp = tmp + include_conf
# detail_conf = re.sub(rep,tmp,detail_conf)
# public.writeFile(detail_file,detail_conf)
# 检查伪静态、主配置文件是否有location冲突
def CheckLocation(self,get):
+54 -14
View File
@@ -533,19 +533,43 @@ def phpReload(version):
else:
ExecShell('/etc/init.d/php-fpm-' + version + ' reload')
def get_timeout(url,timeout=3):
try:
start = time.time()
result = int(httpGet(url,timeout))
return result,int((time.time() - start) * 1000 - 500)
except: return 0,False
def get_url(timeout = 0.5):
import json
try:
nodeFile = 'data/node.json'
node_list = json.loads(readFile(nodeFile))
mnode = None
mnode1 = []
mnode2 = []
mnode3 = []
for node in node_list:
node['ping'] = get_timeout(node['protocol'] + node['address'] + ':' + node['port'] + '/check.txt')
node['net'],node['ping'] = get_timeout(node['protocol'] + node['address'] + ':' + node['port'] + '/net_test',1)
if not node['ping']: continue
if not mnode: mnode = node
if node['ping'] < mnode['ping']: mnode = node
if mnode['ping'] < 50: break
return mnode['protocol'] + mnode['address'] + ':' + mnode['port']
if node['ping'] < 100: #当响应时间<100ms且可用带宽大于1500KB时
if node['net'] > 1500:
mnode1.append(node)
elif node['net'] > 1000:
mnode3.append(node)
else:
if node['net'] > 1000: #当响应时间>=100ms且可用带宽大于1000KB时
mnode2.append(node)
if node['ping'] < 100:
if node['net'] > 3000: break #有节点可用带宽大于3000时,不再检查其它节点
if mnode1: #优选低延迟高带宽
mnode = sorted(mnode1,key= lambda x:x['net'],reverse=True)
elif mnode3: #备选低延迟,中等带宽
mnode = sorted(mnode3,key= lambda x:x['net'],reverse=True)
else: #终选中等延迟,中等带宽
mnode = sorted(mnode2,key= lambda x:x['ping'],reverse=False)
if not mnode: return 'http://download.bt.cn'
return mnode[0]['protocol'] + mnode[0]['address'] + ':' + mnode[0]['port']
except:
return 'http://download.bt.cn'
@@ -840,14 +864,6 @@ def hasPwd(password):
import crypt
return crypt.crypt(password,password)
def get_timeout(url,timeout=3):
try:
start = time.time()
result = httpGet(url,timeout)
if result != 'True': return False
return int((time.time() - start) * 1000)
except: return False
def getDate(format='%Y-%m-%d %X'):
# 取格式时间
return time.strftime(format, time.localtime())
@@ -1723,6 +1739,30 @@ def get_linux_distribution():
distribution = 'centos7'
return distribution
def long2ip(ips):
'''
@name 将整数转换为IP地址
@author hwliang<2020-06-11>
@param ips string(ip地址整数)
@return ipv4
'''
i1 = int(ips / (2 ** 24))
i2 = int((ips - i1 * ( 2 ** 24 )) / ( 2 ** 16 ))
i3 = int(((ips - i1 * ( 2 ** 24 )) - i2 * ( 2 ** 16 )) / ( 2 ** 8))
i4 = int(((ips - i1 * ( 2 ** 24 )) - i2 * ( 2 ** 16 )) - i3 * ( 2 ** 8))
return "{}.{}.{}.{}".format(i1,i2,i3,i4)
def ip2long(ip):
'''
@name 将IP地址转换为整数
@author hwliang<2020-06-11>
@param ip string(ipv4)
@return long
'''
ips = ip.split('.')
if len(ips) != 4: return 0
iplong = 2 ** 24 * int(ips[0]) + 2 ** 16 * int(ips[1]) + 2 ** 8 * int(ips[2]) + int(ips[3])
return iplong
#取通用对象
class dict_obj:
+14 -2
View File
@@ -244,6 +244,12 @@ class ssh_security:
'addtime desc').select()
return data
def get_server_ip(self):
if os.path.exists('/www/server/panel/data/iplist.txt'):
data=public.ReadFile('/www/server/panel/data/iplist.txt')
return data.strip()
else:return '127.0.0.1'
#登陆的情况下
def login(self):
@@ -256,10 +262,14 @@ class ssh_security:
ip = ["127.0.0.1"]
if len(ip[0])==0:return False
try:
import time
mDate = time.strftime('%Y-%m-%d %X', time.localtime())
if ip[0] in self.__ip_data:
if public.M('logs').where('type=? addtime', ('SSH security',mDate,)).count():return False
public.WriteLog('SSH security', 'The server {} login IP is {}, login user is root'.format(public.GetLocalIp(),ip[0]))
return False
else:
if public.M('logs').where('type=? addtime', ('SSH security', mDate,)).count(): return False
self.send_mail_data('Server {} login alarm'.format(public.GetLocalIp()),'There is a login alarm on the server {}, the login IP is {}, the login user is root'.format(public.GetLocalIp(),ip[0]))
public.WriteLog('SSH security','There is a login alarm on the server {}, the login IP is {}, login user is root'.format(public.GetLocalIp(),ip [0]))
return True
@@ -438,7 +448,9 @@ if __name__ == '__main__':
import sys
type = sys.argv[1]
if type=='login':
aa = ssh_security()
aa.login()
try:
aa = ssh_security()
aa.login()
except:pass
else:
pass
+5 -2
View File
@@ -30,7 +30,7 @@ class userlogin:
userInfo = u_info
if 'code' in session:
if session['code'] and not 'is_verify_password' in session:
if not hasattr(post, 'code'): return public.returnMsg(False,'Verification code can not be empty!')
if not hasattr(post, 'code'): return public.returnJson(False,'Verification code can not be empty!')
if not public.checkCode(post.code):
public.WriteLog('TYPE_LOGIN','LOGIN_ERR_CODE',('****','****',public.GetClientIp()))
return public.returnJson(False,'CODE_ERR'),json_header
@@ -218,7 +218,7 @@ class userlogin:
session['login'] = True
session['username'] = userInfo['username']
session['uid'] = userInfo['id']
public.WriteLog('TYPE_LOGIN','LOGIN_SUCCESS',(userInfo['username'],public.GetClientIp()))
public.WriteLog('TYPE_LOGIN','LOGIN_SUCCESS',(userInfo['username'],public.GetClientIp()+ ":" + str(request.environ.get('REMOTE_PORT'))))
self.limit_address('-')
cache.delete('panelNum')
cache.delete('dologin')
@@ -226,6 +226,9 @@ class userlogin:
public.writeFile(sess_input_path,str(int(time.time())))
self.set_request_token()
self.login_token()
login_type = 'data/app_login.pl'
if os.path.exists(login_type):
os.remove(login_type)
return public.returnJson(True,'LOGIN_SUCCESS'),json_header
except Exception as ex:
stringEx = str(ex)
+319 -319
View File
@@ -1,319 +1,319 @@
# coding: utf-8
# +-------------------------------------------------------------------
# | 宝塔Linux面板 x6
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2017 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: lkqiang <lkq@bt.cn>
# +-------------------------------------------------------------------
# +--------------------------------------------------------------------
# | 宝塔webshell 内置扫描
# +--------------------------------------------------------------------
import public, hashlib, os, sys, json, time, re
import send_mail
class webshell_check:
__PATH = '/www/server/panel/data/'
__mail_config = '/www/server/panel/data/stmp_mail.json'
__mail_list_data = '/www/server/panel/data/mail_list.json'
__dingding_config = '/www/server/panel/data/dingding.json'
__mail_list = []
__weixin_user = []
def __init__(self):
self.mail = send_mail.send_mail()
if not os.path.exists(self.__mail_list_data):
ret = []
public.writeFile(self.__mail_list_data, json.dumps(ret))
else:
try:
mail_data = json.loads(public.ReadFile(self.__mail_list_data))
self.__mail_list = mail_data
except:
ret = []
public.writeFile(self.__mail_list_data, json.dumps(ret))
if not os.path.exists(self.__PATH + 'webshell_rule.json'):
rule = ["@\\$\\_\\(\\$\\_", "\\$\\_=\"\"", "\\${'\\_'",
"@preg\\_replace\\((\")*\\/(\\S)*\\/e(\")*,\\$_POST\\[\\S*\\]", "base64\\_decode\\(\\$\\_",
"'e'\\.'v'\\.'a'\\.'l'", "\"e\"\\.\"v\"\\.\"a\"\\.\"l\"", "\"e\"\\.\"v\"\\.\"a\"\\.\"l\"",
"\\$(\\w)+\\(\"\\/(\\S)+\\/e", "\\(array\\)\\$_(POST|GET|REQUEST|COOKIE)", "\\$(\\w)+\\(\\${",
"@\\$\\_=", "\\$\\_=\\$\\_", "chr\\((\\d)+\\)\\.chr\\((\\d)+\\)", "phpjm\\.net", "cha88\\.cn",
"c99shell", "phpspy", "Scanners", "cmd\\.php", "str_rot13", "webshell", "EgY_SpIdEr",
"tools88\\.com", "SECFORCE", "eval\\(('|\")\\?>", "preg_replace\\(\"\\/\\.\\*\\/e\"",
"assert\\(('|\"|\\s*)\\$", "eval\\(gzinflate\\(", "gzinflate\\(base64_decode\\(",
"eval\\(base64_decode\\(", "eval\\(gzuncompress\\(", "ies\",gzuncompress\\(\\$",
"eval\\(gzdecode\\(", "eval\\(str_rot13\\(", "gzuncompress\\(base64_decode\\(",
"base64_decode\\(gzuncompress\\(", "eval\\(('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)",
"assert\\(('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)",
"require\\(('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)",
"require_once\\(('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)",
"include\\(('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)",
"include_once\\(('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)", "call_user_func\\((\"|')assert(\"|')",
"call_user_func\\(('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)",
"\\$_(POST|GET|REQUEST|COOKIE)\\[([^\\]]+)\\]\\(('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)\\[",
"echo\\(file_get_contents\\(('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)",
"file_put_contents\\(('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)\\[([^\\]]+)\\],('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)",
"fputs\\(fopen\\((.+),('|\")w('|\")\\),('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)\\[",
"SetHandlerapplication\\/x-httpd-php", "php_valueauto_prepend_file", "php_valueauto_append_file"]
public.WriteFile(self.__PATH + 'webshell_rule.json', json.dumps(rule))
# 返回配置邮件地址
def return_mail_list(self):
return self.__mail_list
# 查看自定义邮箱配置
def get_user_mail(self):
qq_mail_info = json.loads(public.ReadFile(self.__mail_config))
if len(qq_mail_info) == 0:
return False
return qq_mail_info
# 查看钉钉
def get_dingding(self):
qq_mail_info = json.loads(public.ReadFile(self.__dingding_config))
if len(qq_mail_info) == 0:
return False
return qq_mail_info
# 查看能使用的告警通道
def get_settings(self):
qq_mail_info = json.loads(public.ReadFile(self.__mail_config))
if len(qq_mail_info) == 0:
user_mail = False
else:
user_mail = True
dingding_info = json.loads(public.ReadFile(self.__dingding_config))
if len(dingding_info) == 0:
dingding = False
else:
dingding = True
ret = {}
ret['user_mail'] = {"user_name": user_mail, "mail_list": self.__mail_list, "info": self.get_user_mail()}
ret['dingding'] = {"dingding": dingding, "info": self.get_dingding()}
return ret
# 返回站点
def return_site(self):
data = public.M('sites').field('name,path').select()
ret = {}
for i in data:
ret[i['name']] = i['path']
return public.returnMsg(True, ret)
# 获取规则
def get_rule(self):
ret = []
if os.path.exists(self.__PATH + 'webshell_rule.json'):
try:
data = json.loads(public.ReadFile(self.__PATH + 'webshell_rule.json'))
return data
except:
return False
else:
return False
def get_dir(self, path):
return_data = []
data2 = []
[[return_data.append(os.path.join(root, file)) for file in files] for root, dirs, files in os.walk(path)]
for i in return_data:
if str(i.lower())[-4:] == '.php':
data2.append(i)
return data2
# 目录
def getdir_list(self, path_data):
if os.path.exists(str(path_data)):
return self.get_dir(path_data)
else:
return False
# 扫描
def scan(self, filelist, rule):
import time
time_data = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
ret = []
data2 = []
for file in filelist:
try:
data = open(file).read()
for r in rule:
if re.compile(r).findall(data):
result = {}
result[file] = r
ret.append(result)
data = ("%s [!] %s %s \n" % (time_data, file, r))
data2.append(file)
except:print('%s File opening failed! !! Skipping'%file)
return data2
# 上传webshell
def upload_shell(self, data):
if len(data) == 0: return []
return_data = []
for i in data:
if self.upload_file_url(i):
return_data.append(i)
return return_data
def san_dir(self, path, send='mail'):
file = self.getdir_list(path)
if not file: return exit( "Directory does not exist")
rule = self.get_rule()
if not rule: return exit("Rule is empty or rule file is wrong")
result = self.scan(file, rule)
return_data = self.upload_shell(result)
tongdao = self.get_settings()
if len(return_data) >= 1:
if send == 'dingding':
if tongdao['dingding']:
msg="Webshell killing found the Trojan in the % s directory as follows:%s"%(path,return_data)
self.mail.dingding_send(msg)
elif send == 'mail':
if tongdao['user_mail']:
title = "Webshell killing found the Trojan in the % s directory as follows" % (path)
body = "Webshell search and found that the Trojan exists in the %s directory as follows: %s" % (path, return_data)
if len(self.__mail_list)==0:
if tongdao['user_mail']['user_name']:
self.mail.qq_smtp_send(str(tongdao['user_mail']['info']['qq_mail']), title=title, body=body)
else:
for i in self.__mail_list:
if tongdao['user_mail']['user_name']:
self.mail.qq_smtp_send(str(i), title=title, body=body)
return return_data
def send_san_dir(self, path, send):
file = self.getdir_list(path)
if not file: return exit( "Directory does not exist")
rule = self.get_rule()
if not rule: return exit("Rule is empty or rule file is wrong")
result = self.scan(file, rule)
return_data = self.upload_shell(result)
tongdao = self.get_settings()
if len(return_data) >= 1:
if send == 'dingding':
if tongdao['dingding']:
msg="Webshell search and found that the Trojan exists in the %s directory as follows: %s"%(path,return_data)
self.mail.dingding_send(msg)
elif send == 'mail':
if tongdao['user_mail']:
title = "Webshell killing found the Trojan in the %s directory as follows" % (path)
body = "Webshell search and found that the Trojan exists in the %s directory as follows: %s" % (path, return_data)
if len(self.__mail_list)==0:
self.mail.qq_smtp_send(str(tongdao['user_mail']['info']['qq_mail']), title=title, body=body)
else:
for i in self.__mail_list:
self.mail.qq_smtp_send(str(i), title=title, body=body)
return return_data
def upload_file_url(self, filename):
try:
if os.path.exists(filename):
data = public.ExecShell(
'/usr/local/curl/bin/curl https://scanner.baidu.com/enqueue -F archive=@%s' % filename)
data = json.loads(data[0])
time.sleep(3)
import http_requests
default_headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
}
data_list = http_requests.get(url=data['url'], headers=default_headers, verify=False)
data2 = data_list.json()
if 'data' in data2[0]:
if len(data2[0]['data']) >= 1:
if 'descr' in data2[0]['data'][0]:
if 'WebShell' in data2[0]['data'][0]['descr']:
print('%s file is a Trojan'%filename)
self.send_baota2(filename)
return True
return False
else:
return False
except:
return False
def read_file_md5(self, filename):
if os.path.exists(filename):
with open(filename, 'rb') as fp:
data = fp.read()
file_md5 = hashlib.md5(data).hexdigest()
return file_md5
else:
return False
def send_baota2(self, filename):
cloudUrl = 'http://www.bt.cn/api/panel/btwaf_submit'
pdata = {'codetxt': public.ReadFile(filename), 'md5': self.read_file_md5(filename), 'type': '0',
'host_ip': public.GetLocalIp(), 'size': os.path.getsize(filename)}
ret = public.httpPost(cloudUrl, pdata)
return True
def send_baota(self, filename):
if not os.path.exists(filename): return False
cloudUrl = 'http://www.bt.cn/api/panel/btwaf_submit'
pdata = {'codetxt': public.ReadFile(filename), 'md5': self.read_file_md5(filename), 'type': '0',
'host_ip': public.GetLocalIp(), 'size': os.path.getsize(filename)}
ret = public.httpPost(cloudUrl, pdata)
if ret == '1':
return self.check_webshell(filename)
elif ret == '-1':
return self.check_webshell(filename)
else:
return False
def check_webshell(self, filename):
if not os.path.exists(filename): return False
cloudUrl = 'http://www.bt.cn/api/panel/btwaf_check_file'
pdata = {'md5': self.read_file_md5(filename), 'size': os.path.getsize(filename)}
ret = public.httpPost(cloudUrl, pdata)
if ret == '0':
return False
elif ret == '1':
return False
elif ret == '-1':
return False
else:
return False
def __get_md5(self, s):
m = hashlib.md5()
m.update(s.encode('utf-8'))
return m.hexdigest()
if __name__ == "__main__":
public.WriteFile('/www/server/panel/data/webshell_data.json', json.dumps([]))
type = sys.argv[1]
path = sys.argv[2]
send = sys.argv[3]
os.chdir("/www/server/panel")
import sys
sys.path.append('class')
import public
aa = webshell_check()
print('Start scanning webshell')
start_time=time.time()
if type == 'dir':
data = aa.san_dir(path)
public.WriteFile('/www/server/panel/data/webshell_data.json', json.dumps(data))
localtime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
if len(data) >= 1:
public.WriteLog('aaPanel built-in webshell killing','Killing the %s directory found the following Trojan %s'%(path,data))
else:
public.WriteLog('aaPanel built-in webshell killing','Checking and killing [ %s ] directory did not find any risks'%(path))
elif type=='site':
data = public.M('sites').where('name=?', (path,)).field('name,id,path').select()
localtime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
if len(data) >= 1:
path = data[0]['path']
##木马返回在这里
data = aa.send_san_dir(path, send)
if len(data) >= 1:
public.WriteLog('aaPanel built-in webshell killing', 'Killing the %s directory found the following Trojan %s' % (path, data))
else:
public.WriteLog('aaPanel built-in webshell killing','Checking and killing [ %s ] directory did not find any risks'%(path))
# # coding: utf-8
# # +-------------------------------------------------------------------
# # | 宝塔Linux面板 x6
# # +-------------------------------------------------------------------
# # | Copyright (c) 2015-2017 宝塔软件(http://bt.cn) All rights reserved.
# # +-------------------------------------------------------------------
# # | Author: lkqiang <lkq@bt.cn>
# # +-------------------------------------------------------------------
# # +--------------------------------------------------------------------
# # | 宝塔webshell 内置扫描
# # +--------------------------------------------------------------------
#
# import public, hashlib, os, sys, json, time, re
# import send_mail
#
#
# class webshell_check:
# __PATH = '/www/server/panel/data/'
# __mail_config = '/www/server/panel/data/stmp_mail.json'
# __mail_list_data = '/www/server/panel/data/mail_list.json'
# __dingding_config = '/www/server/panel/data/dingding.json'
# __mail_list = []
# __weixin_user = []
#
# def __init__(self):
# self.mail = send_mail.send_mail()
# if not os.path.exists(self.__mail_list_data):
# ret = []
# public.writeFile(self.__mail_list_data, json.dumps(ret))
# else:
# try:
# mail_data = json.loads(public.ReadFile(self.__mail_list_data))
# self.__mail_list = mail_data
# except:
# ret = []
# public.writeFile(self.__mail_list_data, json.dumps(ret))
# if not os.path.exists(self.__PATH + 'webshell_rule.json'):
# rule = ["@\\$\\_\\(\\$\\_", "\\$\\_=\"\"", "\\${'\\_'",
# "@preg\\_replace\\((\")*\\/(\\S)*\\/e(\")*,\\$_POST\\[\\S*\\]", "base64\\_decode\\(\\$\\_",
# "'e'\\.'v'\\.'a'\\.'l'", "\"e\"\\.\"v\"\\.\"a\"\\.\"l\"", "\"e\"\\.\"v\"\\.\"a\"\\.\"l\"",
# "\\$(\\w)+\\(\"\\/(\\S)+\\/e", "\\(array\\)\\$_(POST|GET|REQUEST|COOKIE)", "\\$(\\w)+\\(\\${",
# "@\\$\\_=", "\\$\\_=\\$\\_", "chr\\((\\d)+\\)\\.chr\\((\\d)+\\)", "phpjm\\.net", "cha88\\.cn",
# "c99shell", "phpspy", "Scanners", "cmd\\.php", "str_rot13", "webshell", "EgY_SpIdEr",
# "tools88\\.com", "SECFORCE", "eval\\(('|\")\\?>", "preg_replace\\(\"\\/\\.\\*\\/e\"",
# "assert\\(('|\"|\\s*)\\$", "eval\\(gzinflate\\(", "gzinflate\\(base64_decode\\(",
# "eval\\(base64_decode\\(", "eval\\(gzuncompress\\(", "ies\",gzuncompress\\(\\$",
# "eval\\(gzdecode\\(", "eval\\(str_rot13\\(", "gzuncompress\\(base64_decode\\(",
# "base64_decode\\(gzuncompress\\(", "eval\\(('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)",
# "assert\\(('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)",
# "require\\(('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)",
# "require_once\\(('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)",
# "include\\(('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)",
# "include_once\\(('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)", "call_user_func\\((\"|')assert(\"|')",
# "call_user_func\\(('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)",
# "\\$_(POST|GET|REQUEST|COOKIE)\\[([^\\]]+)\\]\\(('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)\\[",
# "echo\\(file_get_contents\\(('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)",
# "file_put_contents\\(('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)\\[([^\\]]+)\\],('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)",
# "fputs\\(fopen\\((.+),('|\")w('|\")\\),('|\"|\\s*)\\$_(POST|GET|REQUEST|COOKIE)\\[",
# "SetHandlerapplication\\/x-httpd-php", "php_valueauto_prepend_file", "php_valueauto_append_file"]
# public.WriteFile(self.__PATH + 'webshell_rule.json', json.dumps(rule))
#
# # 返回配置邮件地址
# def return_mail_list(self):
# return self.__mail_list
#
# # 查看自定义邮箱配置
# def get_user_mail(self):
# qq_mail_info = json.loads(public.ReadFile(self.__mail_config))
# if len(qq_mail_info) == 0:
# return False
# return qq_mail_info
#
# # 查看钉钉
# def get_dingding(self):
# qq_mail_info = json.loads(public.ReadFile(self.__dingding_config))
# if len(qq_mail_info) == 0:
# return False
# return qq_mail_info
#
# # 查看能使用的告警通道
# def get_settings(self):
# qq_mail_info = json.loads(public.ReadFile(self.__mail_config))
# if len(qq_mail_info) == 0:
# user_mail = False
# else:
# user_mail = True
# dingding_info = json.loads(public.ReadFile(self.__dingding_config))
# if len(dingding_info) == 0:
# dingding = False
# else:
# dingding = True
# ret = {}
# ret['user_mail'] = {"user_name": user_mail, "mail_list": self.__mail_list, "info": self.get_user_mail()}
# ret['dingding'] = {"dingding": dingding, "info": self.get_dingding()}
# return ret
#
# # 返回站点
# def return_site(self):
# data = public.M('sites').field('name,path').select()
# ret = {}
# for i in data:
# ret[i['name']] = i['path']
# return public.returnMsg(True, ret)
#
# # 获取规则
# def get_rule(self):
# ret = []
# if os.path.exists(self.__PATH + 'webshell_rule.json'):
# try:
# data = json.loads(public.ReadFile(self.__PATH + 'webshell_rule.json'))
# return data
# except:
# return False
# else:
# return False
#
# def get_dir(self, path):
# return_data = []
# data2 = []
# [[return_data.append(os.path.join(root, file)) for file in files] for root, dirs, files in os.walk(path)]
# for i in return_data:
# if str(i.lower())[-4:] == '.php':
# data2.append(i)
# return data2
#
# # 目录
# def getdir_list(self, path_data):
# if os.path.exists(str(path_data)):
# return self.get_dir(path_data)
# else:
# return False
#
# # 扫描
# def scan(self, filelist, rule):
# import time
# time_data = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
# ret = []
# data2 = []
# for file in filelist:
# try:
# data = open(file).read()
# for r in rule:
# if re.compile(r).findall(data):
# result = {}
# result[file] = r
# ret.append(result)
# data = ("%s [!] %s %s \n" % (time_data, file, r))
# data2.append(file)
# except:print('%s File opening failed! !! Skipping'%file)
# return data2
#
# # 上传webshell
# def upload_shell(self, data):
# if len(data) == 0: return []
# return_data = []
# for i in data:
# if self.upload_file_url(i):
# return_data.append(i)
# return return_data
#
# def san_dir(self, path, send='mail'):
# file = self.getdir_list(path)
# if not file: return exit( "Directory does not exist")
# rule = self.get_rule()
# if not rule: return exit("Rule is empty or rule file is wrong")
# result = self.scan(file, rule)
# return_data = self.upload_shell(result)
# tongdao = self.get_settings()
# if len(return_data) >= 1:
# if send == 'dingding':
# if tongdao['dingding']:
# msg="Webshell killing found the Trojan in the % s directory as follows:%s"%(path,return_data)
# self.mail.dingding_send(msg)
# elif send == 'mail':
# if tongdao['user_mail']:
#
# title = "Webshell killing found the Trojan in the % s directory as follows" % (path)
# body = "Webshell search and found that the Trojan exists in the %s directory as follows: %s" % (path, return_data)
# if len(self.__mail_list)==0:
# if tongdao['user_mail']['user_name']:
# self.mail.qq_smtp_send(str(tongdao['user_mail']['info']['qq_mail']), title=title, body=body)
# else:
# for i in self.__mail_list:
# if tongdao['user_mail']['user_name']:
# self.mail.qq_smtp_send(str(i), title=title, body=body)
# return return_data
#
# def send_san_dir(self, path, send):
# file = self.getdir_list(path)
# if not file: return exit( "Directory does not exist")
# rule = self.get_rule()
# if not rule: return exit("Rule is empty or rule file is wrong")
# result = self.scan(file, rule)
# return_data = self.upload_shell(result)
# tongdao = self.get_settings()
# if len(return_data) >= 1:
# if send == 'dingding':
# if tongdao['dingding']:
# msg="Webshell search and found that the Trojan exists in the %s directory as follows: %s"%(path,return_data)
# self.mail.dingding_send(msg)
# elif send == 'mail':
# if tongdao['user_mail']:
# title = "Webshell killing found the Trojan in the %s directory as follows" % (path)
# body = "Webshell search and found that the Trojan exists in the %s directory as follows: %s" % (path, return_data)
# if len(self.__mail_list)==0:
# self.mail.qq_smtp_send(str(tongdao['user_mail']['info']['qq_mail']), title=title, body=body)
# else:
# for i in self.__mail_list:
# self.mail.qq_smtp_send(str(i), title=title, body=body)
# return return_data
#
# def upload_file_url(self, filename):
# try:
# if os.path.exists(filename):
# data = public.ExecShell(
# '/usr/local/curl/bin/curl https://scanner.baidu.com/enqueue -F archive=@%s' % filename)
# data = json.loads(data[0])
# time.sleep(3)
# import http_requests
# default_headers = {
# 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
# }
# data_list = http_requests.get(url=data['url'], headers=default_headers, verify=False)
# data2 = data_list.json()
# if 'data' in data2[0]:
# if len(data2[0]['data']) >= 1:
# if 'descr' in data2[0]['data'][0]:
# if 'WebShell' in data2[0]['data'][0]['descr']:
# print('%s file is a Trojan'%filename)
# self.send_baota2(filename)
# return True
# return False
# else:
# return False
# except:
# return False
#
# def read_file_md5(self, filename):
# if os.path.exists(filename):
# with open(filename, 'rb') as fp:
# data = fp.read()
# file_md5 = hashlib.md5(data).hexdigest()
# return file_md5
# else:
# return False
#
# def send_baota2(self, filename):
# cloudUrl = 'http://www.bt.cn/api/panel/btwaf_submit'
# pdata = {'codetxt': public.ReadFile(filename), 'md5': self.read_file_md5(filename), 'type': '0',
# 'host_ip': public.GetLocalIp(), 'size': os.path.getsize(filename)}
# ret = public.httpPost(cloudUrl, pdata)
# return True
#
# def send_baota(self, filename):
# if not os.path.exists(filename): return False
# cloudUrl = 'http://www.bt.cn/api/panel/btwaf_submit'
# pdata = {'codetxt': public.ReadFile(filename), 'md5': self.read_file_md5(filename), 'type': '0',
# 'host_ip': public.GetLocalIp(), 'size': os.path.getsize(filename)}
# ret = public.httpPost(cloudUrl, pdata)
# if ret == '1':
# return self.check_webshell(filename)
# elif ret == '-1':
# return self.check_webshell(filename)
# else:
# return False
#
# def check_webshell(self, filename):
# if not os.path.exists(filename): return False
# cloudUrl = 'http://www.bt.cn/api/panel/btwaf_check_file'
# pdata = {'md5': self.read_file_md5(filename), 'size': os.path.getsize(filename)}
# ret = public.httpPost(cloudUrl, pdata)
# if ret == '0':
# return False
# elif ret == '1':
# return False
# elif ret == '-1':
# return False
# else:
# return False
#
# def __get_md5(self, s):
# m = hashlib.md5()
# m.update(s.encode('utf-8'))
# return m.hexdigest()
#
#
# if __name__ == "__main__":
# public.WriteFile('/www/server/panel/data/webshell_data.json', json.dumps([]))
# type = sys.argv[1]
# path = sys.argv[2]
# send = sys.argv[3]
# os.chdir("/www/server/panel")
# import sys
# sys.path.append('class')
# import public
# aa = webshell_check()
# print('Start scanning webshell')
# start_time=time.time()
# if type == 'dir':
# data = aa.san_dir(path)
# public.WriteFile('/www/server/panel/data/webshell_data.json', json.dumps(data))
# localtime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
# if len(data) >= 1:
# public.WriteLog('aaPanel built-in webshell killing','Killing the %s directory found the following Trojan %s'%(path,data))
# else:
# public.WriteLog('aaPanel built-in webshell killing','Checking and killing [ %s ] directory did not find any risks'%(path))
# elif type=='site':
# data = public.M('sites').where('name=?', (path,)).field('name,id,path').select()
# localtime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
# if len(data) >= 1:
# path = data[0]['path']
# ##木马返回在这里
# data = aa.send_san_dir(path, send)
# if len(data) >= 1:
# public.WriteLog('aaPanel built-in webshell killing', 'Killing the %s directory found the following Trojan %s' % (path, data))
# else:
# public.WriteLog('aaPanel built-in webshell killing','Checking and killing [ %s ] directory did not find any risks'%(path))
#
#
+38 -6
View File
@@ -15,7 +15,7 @@ import json
import time
import binascii
import base64
from BTPanel import session,cache
from BTPanel import session,cache,request
class ScanLogin(object):
# 扫码登录面板
@@ -32,15 +32,25 @@ class ScanLogin(object):
self.app_path+'login.pl').split(':')
if time.time() - float(init_time) < 60:
return public.returnMsg(True, key)
session_id = public.get_session_id()
if cache.get(session_id) == 'True':
return public.returnMsg(True, 'Scan QRCORE successfully')
return public.returnMsg(False, '')
# 返回二维码地址
def login_qrcode(self, get):
qrcode_str = 'https://app.bt.cn/app.html?&panel_url='+public.getPanelAddr()+'&v=' + public.GetRandomString(3)+'?login';
tid = public.GetRandomString(12)
qrcode_str = 'https://app.bt.cn/app.html?&panel_url='+public.getPanelAddr()+'&v=' + public.GetRandomString(3)+'?login&tid=' + tid
cache.set(tid,public.get_session_id(),360)
cache.set(public.get_session_id(),tid,360)
return public.returnMsg(True, qrcode_str)
# 设置登录状态
def set_login(self, get):
session_id = public.get_session_id()
if cache.get(session_id) == 'True':
return self.check_app_login(get)
if os.path.exists(self.app_path+"login.pl"):
data = public.readFile(self.app_path+'login.pl')
public.ExecShell('rm ' + self.app_path+"login.pl")
@@ -53,10 +63,32 @@ class ScanLogin(object):
session['username'] = userInfo['username']
cache.delete('panelNum')
cache.delete('dologin')
public.WriteLog('TYPE_LOGIN', 'LOGIN_SUCCESS1',
(public.GetMsg("WECHAT_SCAN_QRCORE"), public.GetClientIp()))
return public.returnMsg(True, 'LOGIN_SUCCESS')
return public.returnMsg(False, 'LOGIN_FAIL')
public.WriteLog('TYPE_LOGIN', 'LOGIN_SUCCESS',
('WeChat scan code login', public.GetClientIp()+ ":" + str(request.environ.get('REMOTE_PORT'))))
login_type = 'data/app_login.pl'
public.writeFile(login_type,'True')
return public.returnMsg(True, 'login successful')
return public.returnMsg(False, 'Login failed')
#验证APP是否登录成功
def check_app_login(self,get):
session_id = public.get_session_id()
if cache.get(session_id) != 'True':
return public.returnMsg(False,'Wait for the app to scan the code and log in')
cache.delete(session_id)
userInfo = public.M('users').where("id=?",(1,)).field('id,username').find()
session['login'] = True
session['username'] = userInfo['username']
session['tmp_login'] = True
public.WriteLog('TYPE_LOGIN','APP scan code login, account: {}, login IP: {}'.format(userInfo['username'],public.GetClientIp()+ ":" + str(request.environ.get('REMOTE_PORT'))))
cache.delete('panelNum')
cache.delete('dologin')
sess_input_path = 'data/session_last.pl'
public.writeFile(sess_input_path,str(int(time.time())))
login_type = 'data/app_login.pl'
public.writeFile(login_type,'True')
return public.returnMsg(True,'login successful!')
class SelfModule():
'''
+1 -1
View File
@@ -1 +1 @@
{"product": "Linux panel", "setup_path": "/www/server", "openlitespeed_path": "/usr/local", "language": "English", "title": "aaPanel Linux panel", "brand": "aaPanel", "root_path": "/www", "template": "default", "logs_path": "/www/wwwlogs", "home": "http://www.bt.cn", "recycle_bin": true}
{"product": "Linux panel", "setup_path": "/www/server", "openlitespeed_path": "/usr/local", "language": "English", "title": "aaPanel Linux panel", "brand": "aaPanel", "root_path": "/www", "template": "default", "logs_path": "/www/wwwlogs", "home": "https://console.aapanel.com", "recycle_bin": true}
+39 -3
View File
@@ -1,10 +1,46 @@
[
{
"protocol": "http://",
"address": "128.1.164.196",
"port": "80",
"ping": 500
},
{
"protocol": "http://",
"address": "103.224.251.67",
"port": "80",
"ping": 500
},
{
"protocol": "http://",
"address": "45.76.53.20",
"port": "80",
"ping": 500
},
{
"protocol": "http://",
"address": "dg2.bt.cn",
"port": "80",
"ping": 500
},
{
"protocol": "http://",
"address": "dg1.bt.cn",
"port": "80",
"ping": 500
},
{
"protocol": "http://",
"address": "125.88.182.172",
"port": "5880",
"ping": 500
},
{
"protocol": "http://",
"address": "123.129.198.197",
"port": "5880",
"ping": 500
},
{
"protocol": "http://",
"address": "119.188.210.21",
@@ -13,13 +49,13 @@
},
{
"protocol": "http://",
"address": "45.32.116.160",
"port": "80",
"address": "113.107.111.78",
"port": "5880",
"ping": 500
},
{
"protocol": "http://",
"address": "128.1.164.196",
"address": "45.32.116.160",
"port": "80",
"ping": 500
}