From 27c43d08fc64caad5ad85d2081e440511cd9cd04 Mon Sep 17 00:00:00 2001
From: jose <627622230@qq.com>
Date: Thu, 18 Jul 2019 14:54:41 +0800
Subject: [PATCH] 6.1.4
---
BTPanel/__init__.py | 50 ++++----------------------
BTPanel/static/js/config.js | 2 +-
BTPanel/static/js/public.js | 3 +-
BTPanel/static/js/public_backup.js | 3 +-
BTPanel/static/js/site.js | 26 +++++++++-----
class/common.py | 2 +-
class/config.py | 5 ++-
class/crontab.py | 20 ++++-------
class/database.py | 3 +-
class/jobs.py | 58 ++++++++++++++++++++++++++++--
class/panelLets.py | 55 ++++++++++++++++++----------
class/panelMysql.py | 5 ++-
class/panelPlugin.py | 1 +
class/panelSite.py | 1 +
class/panelTask.py | 7 +++-
class/plugin_deployment.py | 18 +++++++---
class/public.py | 52 +++++++++++++++++++++++++++
17 files changed, 210 insertions(+), 101 deletions(-)
diff --git a/BTPanel/__init__.py b/BTPanel/__init__.py
index e8678dfb..f9840470 100644
--- a/BTPanel/__init__.py
+++ b/BTPanel/__init__.py
@@ -80,7 +80,7 @@ cache.set('p_token','bmac_' + public.Md5(public.get_mac_address()))
admin_path_file = 'data/admin_path.pl'
admin_path = '/'
if os.path.exists(admin_path_file): admin_path = public.readFile(admin_path_file).strip()
-admin_path_checks = ['/','/close','/task','/login','/config','/site','/sites','ftp','/public','/database','/data','/download_file','/control','/crontab','/firewall','/files','config','/soft','/ajax','/system','/panel_data','/code','/ssl','/plugin','/wxapp','/hook','/safe','/yield','/downloadApi','/pluginApi','/auth','/download','/cloud','/webssh','/connect_event','/panel']
+admin_path_checks = ['/','/san','/monitor','/abnormal','/close','/task','/login','/config','/site','/sites','ftp','/public','/database','/data','/download_file','/control','/crontab','/firewall','/files','config','/soft','/ajax','/system','/panel_data','/code','/ssl','/plugin','/wxapp','/hook','/safe','/yield','/downloadApi','/pluginApi','/auth','/download','/cloud','/webssh','/connect_event','/panel']
if admin_path in admin_path_checks: admin_path = '/bt'
@app.route('/service_status',methods = method_get)
@@ -115,6 +115,7 @@ def home():
data['ftpCount'] = public.M('ftps').count()
data['databaseCount'] = public.M('databases').count()
data['lan'] = public.GetLan('index')
+ data['724'] = public.format_date("%m%d") == '0724'
return render_template( 'index.html',data = data)
@app.route('/close',methods=method_get)
@@ -321,7 +322,7 @@ def panel_monitor(pdata=None):
if comReturn: return comReturn
import monitor
dataObject = monitor.Monitor()
- defs = ('get_access_ip', 'get_exception', 'get_exception_logs', 'get_attack_nums', 'php_count', 'return_php', 'mysql_client_count')
+ defs = ('get_spider', 'get_exception', 'get_request_count_qps', 'load_and_up_flow', 'get_request_count_by_hour')
return publicObject(dataObject, defs, None, pdata)
@@ -331,7 +332,7 @@ def san_baseline(pdata=None):
if comReturn: return comReturn
import san_baseline
dataObject = san_baseline.san_baseline()
- defs = ('start', 'get_api_log', 'get_resut', 'get_ssh_errorlogin')
+ defs = ('start', 'get_api_log', 'get_resut', 'get_ssh_errorlogin','repair','repair_all')
return publicObject(dataObject, defs, None, pdata)
@@ -341,7 +342,7 @@ def abnormal(pdata=None):
if comReturn: return comReturn
import abnormal
dataObject = abnormal.abnormal()
- defs = ( 'mysql_server', 'mysql_cpu', 'mysql_count', 'php_server', 'php_conn_max', 'php_cpu', 'CPU', 'Memory', 'disk', 'not_root_user','start')
+ defs = ('mysql_server', 'mysql_cpu', 'mysql_count', 'php_server', 'php_conn_max', 'php_cpu', 'CPU', 'Memory', 'disk', 'not_root_user', 'start')
return publicObject(dataObject, defs, None, pdata)
@app.route('/files',methods=method_all)
@@ -513,7 +514,7 @@ def plugin(pdata = None):
def panel_public():
get = get_input();
get.client_ip = public.GetClientIp();
-
+ if not public.path_safe_check("%s/%s" % (get.name,get.fun)): return abort(404)
if get.fun in ['scan_login','login_qrcode','set_login','is_scan_ok','blind']:
#检查是否验证过安全入口
if get.fun in ['login_qrcode','is_scan_ok']:
@@ -529,7 +530,6 @@ def panel_public():
import panelPlugin
plu = panelPlugin.panelPlugin()
get.s = '_check';
-
checks = plu.a(get)
if type(checks) != bool or not checks: return public.getJson(checks),json_header
get.s = get.fun
@@ -756,44 +756,6 @@ def check_token(data):
if result['token'] != token: return False;
return result;
-@app.route('/yield',methods=method_all)
-def panel_yield():
- get = get_input()
- import panelPlugin
- plu = panelPlugin.panelPlugin()
- get.s = '_check';
- get.client_ip = public.GetClientIp()
- checks = plu.a(get)
- if type(checks) != bool or not checks: return
- get.s = get.fun
- filename = plu.a(get);
- mimetype = 'application/octet-stream'
- return send_file(filename,mimetype=mimetype, as_attachment=True,attachment_filename=os.path.basename(filename))
-
-@app.route('/downloadApi',methods=method_all)
-def panel_downloadApi():
- get = get_input()
- if not public.checkToken(get): get.filename = str(time.time());
- filename = 'plugin/psync/backup/' + get.filename.encode('utf-8');
- mimetype = 'application/octet-stream'
- return send_file(filename,mimetype=mimetype, as_attachment=True,attachment_filename=os.path.basename(filename))
-
-
-@app.route('/pluginApi',methods=method_all)
-def panel_pluginApi():
- get = get_input()
- if not public.checkToken(get): return public.returnJson(False,'INIT_TOKEN_ERR');
- infoFile = 'plugin/' + get.name + '/info.json';
- if not os.path.exists(infoFile): return False;
- import json
- info = json.loads(public.readFile(infoFile));
- if not info['api']: return public.returnJson(False,'INIT_PLU_ACC_ERR');
-
- import panelPlugin
- pluginObject = panelPlugin.panelPlugin()
-
- defs = ('install','unInstall','getPluginList','getPluginInfo','getPluginStatus','setPluginStatus','a','getCloudPlugin','getConfigHtml','savePluginSort')
- return publicObject(pluginObject,defs);
@app.route('/auth',methods=method_all)
def auth(pdata = None):
diff --git a/BTPanel/static/js/config.js b/BTPanel/static/js/config.js
index 84f2eaa4..2580eb15 100644
--- a/BTPanel/static/js/config.js
+++ b/BTPanel/static/js/config.js
@@ -468,7 +468,7 @@ function GetPanelApi() {
\
diff --git a/BTPanel/static/js/public.js b/BTPanel/static/js/public.js
index c1cbd539..ef80b369 100644
--- a/BTPanel/static/js/public.js
+++ b/BTPanel/static/js/public.js
@@ -1,4 +1,3 @@
-
$(document).ready(function() {
$(".sub-menu a.sub-menu-a").click(function() {
$(this).next(".sub").slideToggle("slow").siblings(".sub:visible").slideUp("slow");
@@ -1632,7 +1631,7 @@ function ssh_login_def() {
pdata_socket['data'] = {};
pdata_socket['data']['ssh_user'] = $("input[name='ssh_user']").val();
pdata_socket['data']['ssh_passwd'] = $("input[name='ssh_passwd']").val();
- if (!pdata_socket.ssh_user || !pdata_socket.ssh_passwd) {
+ if (!pdata_socket.data.ssh_user || !pdata_socket.data.ssh_passwd) {
layer.msg('The SSH username and password cannot be empty!');
return;
}
diff --git a/BTPanel/static/js/public_backup.js b/BTPanel/static/js/public_backup.js
index c153aaf6..c8e7bd1d 100644
--- a/BTPanel/static/js/public_backup.js
+++ b/BTPanel/static/js/public_backup.js
@@ -4653,7 +4653,8 @@ bt.site = {
set_cert_ssl:function(certName,siteName,callback){
var loadT = bt.load(lan.public_backup.deploy_cert);
bt.send('SetCertToSite','ssl/SetCertToSite',{certName:certName,siteName:siteName},function(rdata){
- loadT.close();
+ loadT.close();
+ site.reload();
if(callback) callback(rdata);
bt.msg(rdata);
})
diff --git a/BTPanel/static/js/site.js b/BTPanel/static/js/site.js
index 065c06cd..0993ad02 100644
--- a/BTPanel/static/js/site.js
+++ b/BTPanel/static/js/site.js
@@ -66,7 +66,7 @@ var site = {
var opt = '';
var _check = ' onclick="site.site_waf(\'' + item.name + '\')"';
- //if (bt.os == 'Linux') opt += ''+lan.site.firewalld+' | ';
+ if (bt.os == 'Linux') opt += ''+lan.site.firewalld+' | ';
opt += ''+lan.site.set+' | ';
opt += ''+lan.site.del+'';
return opt;
@@ -1490,15 +1490,23 @@ var site = {
})
if (ret.dns_names.length == 0) ret.dns_names.append('_acme-challenge.bt.cn')
$('.div_txt_jx').append(bt.render_help([lan.site.dns_resolve_tips4, lan.site.dns_resolve_tips2 + ret.dns_names[0].acme_name, lan.site.dns_resolve_tips3]));
+
$('.btn_check_txt').click(function () {
- ddata['renew'] = 'True'
- site.create_let(ddata, function (ldata) {
- if (ldata.status) {
- b_load.close();
- site.reload()
- }
- });
- })
+ var new_data = {
+ siteName: web.name,
+ domains: ddata.domains,
+ updateOf: 1,
+ email: ldata.email,
+ renew: 'True',
+ dnsapi:'dns'
+ }
+ site.create_let(new_data, function (ldata) {
+ if (ldata.status) {
+ b_load.close();
+ site.ssl.reload(1);
+ }
+ });
+ })
}, 100)
}
else {
diff --git a/class/common.py b/class/common.py
index 070e76a2..ae50a4fd 100644
--- a/class/common.py
+++ b/class/common.py
@@ -27,7 +27,7 @@ class panelSetup:
if ua:
ua = ua.lower();
if ua.find('spider') != -1 or ua.find('bot') != -1: return redirect('https://www.baidu.com');
- g.version = '6.1.3'
+ g.version = '6.1.4'
g.title = public.GetConfigValue('title')
g.uri = request.path
session['version'] = g.version;
diff --git a/class/config.py b/class/config.py
index 26195d2c..57307fb8 100644
--- a/class/config.py
+++ b/class/config.py
@@ -421,6 +421,9 @@ class config:
os.system('rm -f ' + sslConf);
return public.returnMsg(True,'PANEL_SSL_CLOSE');
else:
+ os.system('pip install cffi');
+ os.system('pip install cryptography');
+ os.system('pip install pyOpenSSL');
try:
if not self.CreateSSL(): return public.returnMsg(False,'PANEL_SSL_ERR');
public.writeFile(sslConf,'True')
@@ -435,7 +438,7 @@ class config:
key.generate_key(OpenSSL.crypto.TYPE_RSA, 2048)
cert = OpenSSL.crypto.X509()
cert.set_serial_number(0)
- cert.get_subject().CN = '120.27.27.98';
+ cert.get_subject().CN = public.GetLocalIp()
cert.set_issuer(cert.get_subject())
cert.gmtime_adj_notBefore( 0 )
cert.gmtime_adj_notAfter(86400 * 3650)
diff --git a/class/crontab.py b/class/crontab.py
index 4170e453..61a002f4 100644
--- a/class/crontab.py
+++ b/class/crontab.py
@@ -259,26 +259,20 @@ class crontab:
def GetDataList(self,get):
data = {}
data['data'] = public.M(get['type']).field('name,ps').select()
- data['orderOpt'] = []
+ data['orderOpt'] = [];
import json
- tmp = public.readFile('data/libList.conf')
+ tmp = public.readFile('data/libList.conf');
libs = json.loads(tmp)
- import imp
+ import imp;
for lib in libs:
try:
- imp.find_module(lib['module'])
+ imp.find_module(lib['module']);
tmp = {}
- tmp['name'] = lib['name']
+ tmp['name'] = lib['name'];
tmp['value']= lib['opt']
- data['orderOpt'].append(tmp)
+ data['orderOpt'].append(tmp);
except:
- import sys
- if lib['module'] == "google.cloud" and "google.cloud" in sys.modules.keys():
- tmp1 = {}
- tmp1['name'] = lib['name']
- tmp1['value'] = lib['opt']
- data['orderOpt'].append(tmp1)
- continue
+ continue;
return data
#取任务日志
diff --git a/class/database.py b/class/database.py
index 62a1d104..41405c79 100644
--- a/class/database.py
+++ b/class/database.py
@@ -391,7 +391,7 @@ SetLink
fileName = name + '_' + time.strftime('%Y%m%d_%H%M%S',time.localtime()) + '.sql.gz'
backupName = session['config']['backup_path'] + '/database/' + fileName
- public.ExecShell("/www/server/mysql/bin/mysqldump --force --opt \"" + name + "\" | gzip > " + backupName)
+ public.ExecShell("/www/server/mysql/bin/mysqldump --default-character-set="+ public.get_database_character(name) +" --force --opt \"" + name + "\" | gzip > " + backupName)
if not os.path.exists(backupName): return public.returnMsg(False,'BACKUP_ERROR');
self.mypass(False, root);
@@ -769,6 +769,7 @@ SetLink
if not os.path.exists(path): return public.returnMsg(False,'AJAX_LOG_FILR_NOT_EXISTS');
return public.returnMsg(True,public.GetNumLines(path,1000));
+
# 获取当前数据库信息
def GetInfo(self,get):
info=self.GetdataInfo(get)
diff --git a/class/jobs.py b/class/jobs.py
index 70250de2..c6fbce96 100644
--- a/class/jobs.py
+++ b/class/jobs.py
@@ -6,7 +6,7 @@
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# +-------------------------------------------------------------------
-import system,psutil,time,public,db,os,sys,json,py_compile
+import system,psutil,time,public,db,os,sys,json,py_compile,re
os.chdir('/www/server/panel')
sm = system.system();
taskConfig = json.loads(public.ReadFile('config/task.json'))
@@ -61,9 +61,61 @@ def control_init():
public.ExecShell("chmod -R 600 /www/server/cron/*.log")
public.ExecShell("chown -R root:root /www/server/panel/data")
public.ExecShell("chown -R root:root /www/server/panel/config")
-
-
+ #disable_putenv('putenv')
clean_session()
+ set_crond()
+
+#默认禁用指定PHP函数
+def disable_putenv(fun_name):
+ try:
+ is_set_disable = '/www/server/panel/data/disable_%s' % fun_name
+ if os.path.exists(is_set_disable): return True
+ php_vs = ('52','53','54','55','56','70','71','72','73','74')
+ php_ini = "/www/server/php/{0}/etc/php.ini"
+ rep = "disable_functions\s*=\s*.*"
+ for pv in php_vs:
+ php_ini_path = php_ini.format(pv)
+ if not os.path.exists(php_ini_path): continue
+ php_ini_body = public.readFile(php_ini_path)
+ tmp = re.search(rep,php_ini_body)
+ if not tmp: continue
+ disable_functions = tmp.group()
+ if disable_functions.find(fun_name) != -1: continue
+ print(disable_functions)
+ php_ini_body = php_ini_body.replace(disable_functions,disable_functions+',%s' % fun_name)
+ php_ini_body.find(fun_name)
+ public.writeFile(php_ini_path,php_ini_body)
+ public.phpReload(pv)
+ public.writeFile(is_set_disable,'True')
+ return True
+ except: return False
+
+
+#创建计划任务
+def set_crond():
+ try:
+ echo = public.md5(public.md5('renew_lets_ssl_bt'))
+ cron_id = public.M('crontab').where('echo=?',(echo,)).getField('id')
+
+ import crontab
+ args_obj = public.dict_obj()
+ if not cron_id:
+ cronPath = public.GetConfigValue('setup_path') + '/cron/' + echo
+ shell = 'python /www/server/panel/class/panelLets.py renew_lets_ssl'
+ public.writeFile(cronPath,shell)
+ args_obj.id = public.M('crontab').add('name,type,where1,where_hour,where_minute,echo,addtime,status,save,backupTo,sType,sName,sBody,urladdress',("续签Let's Encrypt证书",'day','','0','10',echo,time.strftime('%Y-%m-%d %X',time.localtime()),0,'','localhost','toShell','',shell,''))
+ crontab.crontab().set_cron_status(args_obj)
+ else:
+ cron_path = public.get_cron_path()
+ if os.path.exists(cron_path):
+ cron_s = public.readFile(cron_path)
+ if cron_s.find(echo) == -1:
+ public.M('crontab').where('echo=?',(echo,)).setField('status',0)
+ args_obj.id = cron_id
+ crontab.crontab().set_cron_status(args_obj)
+ except:
+ print(public.get_error_info())
+
#清理多余的session文件
def clean_session():
diff --git a/class/panelLets.py b/class/panelLets.py
index a035dcf5..6c0d8f06 100644
--- a/class/panelLets.py
+++ b/class/panelLets.py
@@ -15,7 +15,8 @@ from OpenSSL import crypto
try:
requests.packages.urllib3.disable_warnings()
except:pass
-import BTPanel
+if __name__ != '__main__':
+ import BTPanel
try:
import dns.resolver
except:
@@ -93,6 +94,9 @@ class panelLets:
return 'The signing failed, and the number of attempts to apply for a certificate today has reached the limit!
'
elif "DNS problem: NXDOMAIN looking up A for" in error or "No valid IP addresses found for" in error or "Invalid response from" in error:
return 'The signing failed, the domain name resolution error, or the resolution is not valid, or the domain name is not filed!
'
+ elif error.find('TLS Web Server Authentication') != -1:
+ public.restart_panel()
+ return "Failed to connect to the CA server, please try again later."
else:
return error;
@@ -100,6 +104,7 @@ class panelLets:
def get_dns_class(self,data):
if data['dnsapi'] == 'dns_ali':
import panelDnsapi
+ public.mod_reload(panelDnsapi)
dns_class = panelDnsapi.AliyunDns(key = data['dns_param'][0], secret = data['dns_param'][1])
return dns_class
elif data['dnsapi'] == 'dns_dp':
@@ -107,12 +112,14 @@ class panelLets:
return dns_class
elif data['dnsapi'] == 'dns_cx':
import panelDnsapi
+ public.mod_reload(panelDnsapi)
dns_class = panelDnsapi.CloudxnsDns(key = data['dns_param'][0] ,secret =data['dns_param'][1])
result = dns_class.get_domain_list()
if result['code'] == 1:
return dns_class
elif data['dnsapi'] == 'dns_bt':
import panelDnsapi
+ public.mod_reload(panelDnsapi)
dns_class = panelDnsapi.Dns_com()
return dns_class
return False
@@ -202,12 +209,10 @@ class panelLets:
#手动解析提前返回
result = self.crate_let_by_oper(data)
if 'status' in result and not result['status']: return result
-
result['status'] = True
public.writeFile(domain_path, json.dumps(result))
result['msg'] = 'Get successful, please manually resolve the domain name'
result['code'] = 2;
-
return result
elif get.dnsapi == 'dns_bt':
data['dnsapi'] = get.dnsapi
@@ -244,19 +249,32 @@ class panelLets:
public.writeFile(path + "/README","let")
#计划任务续签
- echo = public.md5(public.md5('renew_lets_ssl_bt'))
- crontab = public.M('crontab').where('echo=?',(echo,)).find()
- if not crontab:
- cronPath = public.GetConfigValue('setup_path') + '/cron/' + echo
- shell = 'python %s/panel/class/panelLets.py renew_lets_ssl ' % (self.setupPath)
- public.writeFile(cronPath,shell)
- public.M('crontab').add('name,type,where1,where_hour,where_minute,echo,addtime,status,save,backupTo,sType,sName,sBody,urladdress',("Renew the Letter's Encrypt certificate",'day','','0','10',echo,time.strftime('%Y-%m-%d %X',time.localtime()),1,'','localhost','toShell','',shell,''))
-
+ self.set_crond()
return public.returnMsg(True, 'Successful application.')
+ #创建计划任务
+ def set_crond(self):
+ try:
+ echo = public.md5(public.md5('renew_lets_ssl_bt'))
+ cron_id = public.M('crontab').where('echo=?',(echo,)).getField('id')
-
-
+ import crontab
+ args_obj = public.dict_obj()
+ if not cron_id:
+ cronPath = public.GetConfigValue('setup_path') + '/cron/' + echo
+ shell = 'python %s/panel/class/panelLets.py renew_lets_ssl ' % (self.setupPath)
+ public.writeFile(cronPath,shell)
+ args_obj.id = public.M('crontab').add('name,type,where1,where_hour,where_minute,echo,addtime,status,save,backupTo,sType,sName,sBody,urladdress',("续签Let's Encrypt证书",'day','','0','10',echo,time.strftime('%Y-%m-%d %X',time.localtime()),0,'','localhost','toShell','',shell,''))
+ crontab.crontab().set_cron_status(args_obj)
+ else:
+ cron_path = public.get_cron_path()
+ if os.path.exists(cron_path):
+ cron_s = public.readFile(cron_path)
+ if cron_s.find(echo) == -1:
+ public.M('crontab').where('echo=?',(echo,)).setField('status',0)
+ args_obj.id = cron_id
+ crontab.crontab().set_cron_status(args_obj)
+ except:pass
#手动解析
def crate_let_by_oper(self,data):
@@ -285,7 +303,7 @@ class panelLets:
acme_keyauthorization, domain_dns_value = BTPanel.dns_client.get_keyauthorization(dns_token)
acme_name = self.get_acme_name(dns_name)
- dns_names_to_delete.append({"dns_name": dns_name,"acme_name":acme_name, "domain_dns_value": domain_dns_value})
+ dns_names_to_delete.append({"dns_name": public.de_punycode(dns_name),"acme_name":acme_name, "domain_dns_value": domain_dns_value})
responders.append(
{
"authorization_url": authorization_url,
@@ -359,9 +377,9 @@ class panelLets:
dns_challenge_url = identifier_auth["dns_challenge_url"]
acme_keyauthorization, domain_dns_value = client.get_keyauthorization(dns_token)
- dns_class.create_dns_record(dns_name, domain_dns_value)
+ dns_class.create_dns_record(public.de_punycode(dns_name), domain_dns_value)
self.check_dns(self.get_acme_name(dns_name),domain_dns_value)
- dns_names_to_delete.append({"dns_name": dns_name, "domain_dns_value": domain_dns_value})
+ dns_names_to_delete.append({"dns_name": public.de_punycode(dns_name), "domain_dns_value": domain_dns_value})
responders.append({"authorization_url": authorization_url, "acme_keyauthorization": acme_keyauthorization,"dns_challenge_url": dns_challenge_url} )
n = 0
while n<2:
@@ -433,6 +451,7 @@ class panelLets:
wellknown_path = acme_dir + '/' + http_token
public.writeFile(wellknown_path,acme_keyauthorization)
wellknown_url = "http://{0}/.well-known/acme-challenge/{1}".format(http_name, http_token)
+
result['clecks'].append({'wellknown_url':wellknown_url,'http_token':http_token});
is_check = False
n = 0
@@ -446,6 +465,7 @@ class panelLets:
except :
pass
n += 1
+ time.sleep(1)
if is_check:
sucess_domains.append(http_name)
responders.append({"authorization_url": authorization_url, "acme_keyauthorization": acme_keyauthorization,"http_challenge_url": http_challenge_url})
@@ -517,9 +537,8 @@ class panelLets:
for j in ns.response.answer:
for i in j.items:
txt_value = i.to_text().replace('"','').strip()
- print(txt_value)
if txt_value == value:
- print("Successful verification:",txt_value)
+ print("Successful verification:%s" % txt_value)
return True
except:
try:
diff --git a/class/panelMysql.py b/class/panelMysql.py
index 838f41da..2296943d 100644
--- a/class/panelMysql.py
+++ b/class/panelMysql.py
@@ -88,7 +88,10 @@ class panelMysql:
self.__DB_CUR.execute(sql)
result = self.__DB_CUR.fetchall()
#将元组转换成列表
- data = map(list,result)
+ if sys.version_info[0] == 2:
+ data = map(list,result)
+ else:
+ data = list(map(list,result))
self.__Close()
return data
except Exception as ex:
diff --git a/class/panelPlugin.py b/class/panelPlugin.py
index e90a4958..94ce27a2 100644
--- a/class/panelPlugin.py
+++ b/class/panelPlugin.py
@@ -1552,6 +1552,7 @@ class panelPlugin:
def a(self,get):
if not hasattr(get,'name'): return public.returnMsg(False,'PLUGIN_INPUT_A');
try:
+ if not public.path_safe_check("%s/%s" % (get.name,get.s)): return public.returnMsg(False,'PLUGIN_INPUT_C');
path = self.__install_path + '/' + get.name
if not os.path.exists(path + '/'+get.name+'_main.py'): return public.returnMsg(False,'PLUGIN_INPUT_B');
if not self.check_accept(get):return public.returnMsg(False,public.to_string([24744, 26410, 36141, 20080, 91, 37, 115, 93, 25110, 25480, 26435, 24050, 21040, 26399, 33]) % (self.get_title_byname(get),))
diff --git a/class/panelSite.py b/class/panelSite.py
index aea6405b..a4884f2a 100644
--- a/class/panelSite.py
+++ b/class/panelSite.py
@@ -884,6 +884,7 @@ class panelSite(panelRedirect):
self.check_ssl_pack()
import panelLets
+ public.mod_reload(panelLets)
lets = panelLets.panelLets()
result = lets.apple_lest_cert(get)
if result['status'] and not 'code' in result:
diff --git a/class/panelTask.py b/class/panelTask.py
index 6e7ef97d..9e4bfdde 100644
--- a/class/panelTask.py
+++ b/class/panelTask.py
@@ -199,12 +199,17 @@ class bt_task:
#清理任务日志
def clean_log(self):
+ import shutil
s_time = int(time.time())
timeout = 86400
for f in os.listdir(self.__task_path):
filename = self.__task_path + f
c_time = os.stat(filename).st_ctime
- if s_time - c_time > timeout: os.remove(filename)
+ if s_time - c_time > timeout:
+ if os.path.isdir(filename):
+ shutil.rmtree(filename)
+ else:
+ os.remove(filename)
return True
#文件压缩
diff --git a/class/plugin_deployment.py b/class/plugin_deployment.py
index 54ae54a4..d6e2cf0f 100644
--- a/class/plugin_deployment.py
+++ b/class/plugin_deployment.py
@@ -70,11 +70,12 @@ class plugin_deployment:
def get_icon(self,pinfo):
path = '/www/server/panel/BTPanel/static/img/dep_ico'
if not os.path.exists(path): os.makedirs(path,384)
- filename = path + '/' + pinfo['name'] + '.png'
+ filename = "%s/%s.png" % (path, pinfo['name'])
m_uri = pinfo['min_image']
- pinfo['min_image'] = '/static/img/dep_ico/' + pinfo['name'] + '.png'
+ pinfo['min_image'] = '/static/img/dep_ico/%s.png' % pinfo['name']
+ if sys.version_info[0] == 2: filename = filename.encode('utf-8')
if os.path.exists(filename):
- if os.path.getsize(filename) > 1024: return pinfo
+ if os.path.getsize(filename) > 100: return pinfo
os.system("wget -O " + filename + ' http://www.bt.cn' + m_uri + " &")
return pinfo
@@ -347,6 +348,13 @@ class plugin_deployment:
dwfile = self.__panelPath + '/vhost/rewrite/' + site_name + '.conf';
public.writeFile(dwfile,rewriteConf);
+ swfile = path + '/.htaccess';
+ if os.path.exists(swfile):
+ swpath = (path + '/'+ pinfo['run_path'] + '/.htaccess').replace('//','/')
+ if pinfo['run_path'] != '/' and not os.path.exists(swpath):
+ public.writeFile(swpath, public.readFile(swfile))
+
+
#删除伪静态文件
public.ExecShell("rm -f " + path + '/*.rewrite')
@@ -428,9 +436,9 @@ class plugin_deployment:
os.remove(p_info)
i_ndex_html = path + '/index.html'
if os.path.exists(i_ndex_html): os.remove(i_ndex_html)
- public.ExecShell("\cp -a -r " + p_tmp + '/* ' + path + '/')
+ os.system("\cp -arf " + p_tmp + '/. ' + path + '/')
except: pass
- public.ExecShell("rm -rf " + self.__tmp + '/*')
+ os.system("rm -rf " + self.__tmp + '/*')
return p_config
diff --git a/class/public.py b/class/public.py
index aed39145..4523ffb1 100644
--- a/class/public.py
+++ b/class/public.py
@@ -1274,3 +1274,55 @@ def path_safe_check(path):
if not re.match(rep,path): return False
return True
+#取数据库字符集
+def get_database_character(db_name):
+ try:
+ import panelMysql
+ tmp = panelMysql.panelMysql().query("show create database `%s`" % db_name.strip())
+ return str(re.findall("SET\s+(.+)\s",tmp[0][1])[0])
+ except:
+ return 'utf8'
+
+def en_punycode(domain):
+ tmp = domain.split('.');
+ newdomain = '';
+ for dkey in tmp:
+ #匹配非ascii字符
+ match = re.search(u"[\x80-\xff]+",dkey);
+ if not match: match = re.search(u"[\u4e00-\u9fa5]+",dkey);
+ if not match:
+ newdomain += dkey + '.';
+ else:
+ newdomain += 'xn--' + dkey.encode('punycode').decode('utf-8') + '.'
+ return newdomain[0:-1];
+
+#punycode 转中文
+def de_punycode(domain):
+ tmp = domain.split('.');
+ newdomain = '';
+ for dkey in tmp:
+ if dkey.find('xn--') >=0:
+ newdomain += dkey.replace('xn--','').encode('utf-8').decode('punycode') + '.'
+ else:
+ newdomain += dkey + '.'
+ return newdomain[0:-1];
+
+#取计划任务文件路径
+def get_cron_path():
+ u_file = '/var/spool/cron/crontabs/root'
+ if not os.path.exists(u_file):
+ file='/var/spool/cron/root'
+ else:
+ file=u_file
+ return file
+
+#取通用对象
+class dict_obj:
+ def __contains__(self, key):
+ return getattr(self,key,None)
+ def __setitem__(self, key, value): setattr(self,key,value)
+ def __getitem__(self, key): return getattr(self,key,None)
+ def __delitem__(self,key): delattr(self,key)
+ def __delattr__(self, key): delattr(self,key)
+ def get_items(self): return self
+