Commit ce7bd5d1 authored by jose's avatar jose

File management adds video playback

File sharing adds directory sharing and video playback functions
Optimize file sharing UI
Publish system firewall plugin
Release Amazon storage plugin
Other details adjustment
parent ce695101
This diff is collapsed.
......@@ -1137,10 +1137,8 @@ html .menu .menu_exit:hover {
border-bottom: 1px solid #e6e6e6;
color: #666;
font-weight: normal;
padding: 5px 10px;
height: 35px;
padding: 8px;
font-size: 12.5px;
box-sizing: content-box;
}
.divtable .table_toolbar{
left: 8px;
......@@ -6697,4 +6695,41 @@ select[disabled]{
}
.php_info_group:last-child{
margin-bottom: 15px;
}
#btvideo{
display: inline-block;
height: 360px;
}
.video-list{
display: inline-block;
width: 250px;
height: 360px;
overflow: auto;
}
.video-list .video-avt{
background-color: #e8e8e8;
}
.movie_pay .layui-layer-content{
overflow: hidden !important;
}
.video-list .video-avt td a,
.video-list .video-avt td{
color: #20a53a;
}
.video-list tr td{
border-top: 0px;
border-bottom: 1px solid #ddd;
}
.video-list tr:hover{
cursor: pointer;
}
#btvideo video{
outline: none;
padding: 0;
display: block;
background-color: #000;
}
.minText{
white-space: nowrap;
}
\ No newline at end of file
This diff is collapsed.
......@@ -1175,7 +1175,7 @@ var aceEditor = {
_this = this;
var loadT = layer.open({
type: 1,
area: ['400px', '180px'],
area: ['400px', '200px'],
title: lan.public.restore_history_files,
content: '<div class="ace-clear-form">\
<div class="clear-icon"></div>\
......
......@@ -2016,7 +2016,7 @@ var soft = {
{
field: 'opt',
title: lan.public.action,
width: 50,
width: 60,
templet: function(item) {
var opt = '<a class="btlink lib-install" data-name="' + item.name + '" data-title="' + item.title + '" href="javascript:;">' + lan.soft.install + '</a>'
if (item['task'] == '-1' && item.phpversions.indexOf(version) != -1) {
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
......@@ -666,9 +666,6 @@ class ajax:
else:
conf_file = "/www/server/panel/vhost/apache/phpmyadmin.conf"
rep = "Listen\s*(\d+)"
# else:
# conf_file = "/www/server/panel/vhost/openlitespeed/listen/888.conf"
# rep = "address\s+\*:(\d+)"
return {"conf_file":conf_file,"rep":rep}
# 设置phpmyadmin路径
......@@ -1063,15 +1060,29 @@ class ajax:
#取PHP-FPM日志
def GetFpmLogs(self,get):
path = '/www/server/php/' + get.version + '/var/log/php-fpm.log'
if not os.path.exists(path): return public.returnMsg(False,'AJAX_LOG_FILR_NOT_EXISTS')
return public.returnMsg(True,public.GetNumLines(path,1000))
import re
fpm_path = '/www/server/php/' + get.version + '/etc/php-fpm.conf'
if not os.path.exists(fpm_path): return public.returnMsg(False,'AJAX_LOG_FILR_NOT_EXISTS')
fpm_conf = public.readFile(fpm_path)
log_tmp = re.findall(r"error_log\s*=\s*(.+)",fpm_conf)
if not log_tmp: return public.returnMsg(False,'AJAX_LOG_FILR_NOT_EXISTS')
log_file = log_tmp[0].strip()
if log_file.find('var/log') == 0:
log_file = '/www/server/php/' +get.version + '/'+ log_file
return public.returnMsg(True,public.GetNumLines(log_file,1000))
#取PHP慢日志
def GetFpmSlowLogs(self,get):
path = '/www/server/php/' + get.version + '/var/log/slow.log'
if not os.path.exists(path): return public.returnMsg(False,'AJAX_LOG_FILR_NOT_EXISTS')
return public.returnMsg(True,public.GetNumLines(path,1000))
import re
fpm_path = '/www/server/php/' + get.version + '/etc/php-fpm.conf'
if not os.path.exists(fpm_path): return public.returnMsg(False,'AJAX_LOG_FILR_NOT_EXISTS')
fpm_conf = public.readFile(fpm_path)
log_tmp = re.findall(r"slowlog\s*=\s*(.+)",fpm_conf)
if not log_tmp: return public.returnMsg(False,'AJAX_LOG_FILR_NOT_EXISTS')
log_file = log_tmp[0].strip()
if log_file.find('var/log') == 0:
log_file = '/www/server/php/' +get.version + '/'+ log_file
return public.returnMsg(True,public.GetNumLines(log_file,1000))
#取指定日志
def GetOpeLogs(self,get):
......
......@@ -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.6.9'
g.version = '6.7.0'
g.title = public.GetConfigValue('title')
g.uri = request.path
if not os.path.exists('data/debug.pl'):
......
......@@ -103,7 +103,7 @@ class Sql():
i=0
tmp1 = {}
for key in fields:
tmp1[key] = row[i]
tmp1[key.strip('`')] = row[i]
i += 1
tmp.append(tmp1)
del(tmp1)
......@@ -127,7 +127,7 @@ class Sql():
import re
fields = []
for key in field:
s_as = re.search('\s+as\s+',key,flags=re.IGNORECASE)
s_as = re.search(r'\s+as\s+',key,flags=re.IGNORECASE)
if s_as:
as_tip = s_as.group()
key = key.split(as_tip)[1]
......@@ -139,13 +139,13 @@ class Sql():
tmp_cols = self.query('PRAGMA table_info('+self.__DB_TABLE+')',())
cols = []
for col in tmp_cols:
if len(col) > 2: cols.append(col[1])
if len(col) > 2: cols.append('`' + col[1] + '`')
if len(cols) > 0: self.__OPT_FIELD = ','.join(cols)
def getField(self,keyName):
#取回指定字段
try:
result = self.field(keyName).select();
result = self.field(keyName).select()
if len(result) != 0:
return result[0][keyName]
return result
......
......@@ -353,7 +353,7 @@ session.save_handler = files'''.format(path, sess_path, sess_path)
size = str(stat.st_size)
if os.path.isdir(filePath):
dirnames.append(filename+';'+size+';' +
mtime+';'+accept+';'+user+';'+link + ';0;' + self.is_composer_json(filePath))
mtime+';'+accept+';'+user+';'+link + ';' +self.get_download_id(filePath)+';'+ self.is_composer_json(filePath))
else:
filenames.append(filename+';'+size+';'+mtime+';'+accept+';'+user+';'+link+';'+self.get_download_id(filePath))
n += 1
......@@ -502,6 +502,27 @@ session.save_handler = files'''.format(path, sess_path, sess_path)
filename = filename.replace(tmp_path, '')
return filename + ';' + size + ';' + mtime + ';' + accept + ';' + user + ';' + link+';'+ down_url
#获取指定目录下的所有视频或音频文件
def get_videos(self,args):
path = args.path.strip()
v_data = []
if not os.path.exists(path): return v_data
import mimetypes
for fname in os.listdir(path):
try:
filename = os.path.join(path,fname)
if not os.path.exists(filename): continue
if not os.path.isfile(filename): continue
v_tmp = {}
v_tmp['name'] = fname
v_tmp['type'] = mimetypes.guess_type(filename)[0]
v_tmp['size'] = os.path.getsize(filename)
if not v_tmp['type'].split('/')[0] in ['video']:
continue
v_data.append(v_tmp)
except:continue
return sorted(v_data,key=lambda x:x['name'])
# 计算文件数量
def GetFilesCount(self, path, search):
if os.path.isfile(path):
......@@ -1814,19 +1835,17 @@ cd %s
# 生成下载地址
def create_download_url(self, get):
if not os.path.exists(get.filename):
return public.returnMsg(False, 'The specified file does not exist!')
if not os.path.isfile(get.filename):
return public.returnMsg(False, 'Cannot generate download address for directory!')
return public.returnMsg(False,'The specified file does not exist!')
my_table = 'download_token'
mtime = int(time.time())
pdata = {
"filename": get.filename, # 文件名
"token": public.GetRandomString(12), # 12位随机密钥,用于URL
"expire": mtime + (int(get.expire) * 3600), # 过期时间
"ps": get.ps, # 备注
"total": 0, # 下载计数
"password": get.password, # 提取密码
"addtime": mtime # 添加时间
"filename": get.filename, #文件名
"token": public.GetRandomString(12), #12位随机密钥,用于URL
"expire": mtime + (int(get.expire) * 3600), #过期时间
"ps":get.ps, #备注
"total":0, #下载计数
"password":str(get.password), #提取密码
"addtime": mtime #添加时间
}
# 更新 or 插入
token = public.M(my_table).where('filename=?', (get.filename,)).getField('token')
......
......@@ -46,6 +46,18 @@ def control_init():
`password` REAL,
`ps` REAL,
`addtime` INTEGER
)'''
sql.execute(csql,())
if not sql.table('sqlite_master').where('type=? AND name=?', ('table', 'messages')).count():
csql = '''CREATE TABLE IF NOT EXISTS `messages` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`level` TEXT,
`msg` TEXT,
`state` INTEGER DEFAULT 0,
`expire` INTEGER,
`addtime` INTEGER
)'''
sql.execute(csql,())
......
......@@ -19,7 +19,7 @@ import time
os.chdir('/www/server/panel')
sys.path.insert(0,'class/')
import public
_VERSION = 1.3
_VERSION = 1.4
class backup:
_path = None
......@@ -28,8 +28,7 @@ class backup:
_inode_min = 10
_db_mysql = None
_cloud = None
_local_backdir = None
_is_save_local = not os.path.exists('data/is_save_local_backup.pl')
_is_save_local = os.path.exists('data/is_save_local_backup.pl')
def __init__(self,cloud_object = None):
'''
@name 数据备份对象
......@@ -196,7 +195,7 @@ class backup:
num = len(backups) - int(save)
if num > 0:
self._get_local_backdir()
self.echo_info('-' * 90)
self.echo_info('-' * 88)
for backup in backups:
#处理目录备份到远程的情况
if backup['filename'].find('|') != -1:
......@@ -305,7 +304,7 @@ class backup:
filename = dfile
if self._cloud:
filename = self._cloud._name
filename = dfile + '|' + self._cloud._name + '|' + fname
pdata = {
'type': 0,
......@@ -326,7 +325,7 @@ class backup:
if not self._cloud:
backups = public.M('backup').where("type=? and pid=? and filename LIKE '%/%'",('0',pid)).field('id,name,filename').select()
else:
backups = public.M('backup').where('type=? and pid=? and filename=?',('0',pid,filename)).field('id,name,filename').select()
backups = public.M('backup').where('type=? and pid=? and filename LIKE "%{}%"'.format(self._cloud._name),('0',pid)).field('id,name,filename').select()
self.delete_old(backups,save,'site')
self.echo_end()
......@@ -425,7 +424,7 @@ class backup:
filename = dfile
if self._cloud:
filename = self._cloud._name
filename = dfile + '|' + self._cloud._name + '|' + fname
self.echo_info("Database has been backed up to: {}".format(dfile))
if os.path.exists(self._err_log):
os.remove(self._err_log)
......@@ -452,9 +451,7 @@ class backup:
if not self._cloud:
backups = public.M('backup').where("type=? and pid=? and filename LIKE '%/%'",('1',pid)).field('id,name,filename').select()
else:
backups = public.M('backup').where('type=? and pid=? and filename=?',('1',pid,filename)).field('id,name,filename').select()
self.echo_info(str(backups))
backups = public.M('backup').where('type=? and pid=? and filename LIKE "%{}%"'.format(self._cloud._name),('1',pid)).field('id,name,filename').select()
self.delete_old(backups,save,'database')
self.echo_end()
return dfile
......
#coding: utf-8
# +-------------------------------------------------------------------
# | 宝塔Linux面板
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <2020-05-18>
# +-------------------------------------------------------------------
# +-------------------------------------------------------------------
# | 消息提醒
# +-------------------------------------------------------------------
import os,sys,time
import public
class panelMessage:
def __init__(self):
pass
def get_messages(self,args = None):
'''
@name 获取消息列表
@author 黄文良 <2020-05-18>
@return list
'''
data = public.M('messages').where('state=? and expire>?',(1,int(time.time()))).order("id desc").select()
return data
def get_messages_all(self,args = None):
'''
@name 获取所有消息列表
@author 黄文良 <2020-05-18>
@return list
'''
data = public.M('messages').order("id desc").select()
return data
def get_message_find(self,args = None,id = None):
'''
@name 获取指定消息
@author 黄文良 <2020-05-18>
@param args dict_obj{
id: 消息标识
}
@return dict
'''
if args:
id = int(args.id)
data = public.M('messages').where('id=?',id).find()
return data
def create_message(self,args = None,level=None,msg=None,expire=None):
'''
@name 创建新的消息
@author 黄文良 <2020-05-18>
@param args dict_obj{
level: 消息级别(info/warning/danger/error),
msg: 消息内容
expire: 过期时间
}
@return dict
'''
if args:
level = args.level
msg = args.msg
expire = args.expire
pdata = {
"level":level,
"msg":msg,
"state":1,
"expire":int(time.time()) + (int(expire) * 86400),
"addtime": int(time.time())
}
public.M('messages').insert(pdata)
return public.returnMsg(True,'Created successfully!')
def status_message(self,args = None,id = None,state = None):
'''
@name 设置消息状态
@author 黄文良 <2020-05-18>
@param args dict_obj{
id: 消息标识,
state: 消息状态(0.已忽略, 1.正常)
}
@return dict
'''
if args:
id = int(args.id)
state = int(args.state)
public.M('messages').where('id=?',id).setField('state',state)
return public.returnMsg(True,'Set up successfully!')
def remove_message(self,args = None,id = None):
'''
@name 删除指定消息
@author 黄文良 <2020-05-18>
@param args dict_obj{
id: 消息标识
}
@return dict
'''
if args:
id = int(args.id)
public.M('messages').where('id=?',id).delete()
return public.returnMsg(True,'Successfully deleted!')
def remove_message_level(self,level):
'''
@name 删除指定消息
@author 黄文良 <2020-05-18>
@param level string(指定级别或标识)
@return bool
'''
public.M('messages').where('(level=? or level=? or level=? or level=?) and state=?',(level,level+'15',level+'7',level+'3',1)).delete()
return True
def is_level(self,level):
'''
@name 指定消息是否忽略
@author 黄文良 <2020-05-18>
@param level string(指定级别或标识)
@return bool
'''
if public.M('messages').where('level=? and state=?',(level,0)).count():
return False
else:
return True
......@@ -82,6 +82,7 @@ class panelPlugin:
names = dep.split('|')
for name in names:
pluginInfo = self.get_soft_find(name)
if not pluginInfo: return True
if pluginInfo['setup'] == True:
status = True
break
......@@ -330,6 +331,7 @@ class panelPlugin:
if softList: public.writeFile(lcoalTmp,json.dumps(softList))
public.ExecShell('rm -f /tmp/bmac_*')
self.getCloudPHPExt(get)
self.expire_msg(softList)
try:
public.writeFile("/tmp/" + cache.get('p_token'),str(softList['pro']))
except:pass
......@@ -353,6 +355,78 @@ class panelPlugin:
softList['list'] = tmpList
return softList
#取提醒标记
def get_level_msg(self,level,s_time,endtime):
'''
level 提醒标记
s_time 当前时间戳
endtime 到期时间戳
'''
expire_day = (endtime - s_time) / 86400
if expire_day < 15 and expire_day > 7:
level = level + '15'
elif expire_day < 7 and expire_day > 3:
level = level + '7'
elif expire_day < 3 and expire_day > 0:
level = level + '3'
return level,expire_day
#添加到期提醒
def add_expire_msg(self,title,level,name,expire_day,pid,endtime):
'''
title 软件标题
level 提醒标记
name 软件名称
expire_day 剩余天数
'''
import panelMessage #引用消息提醒模块
pm = panelMessage.panelMessage()
pm.remove_message_level(level) #删除旧的提醒
if expire_day > 15: return False
if pm.is_level(level): #是否忽略
if level != name: #到期还是即将到期
msg_last = '您的【{}】授权还有{}天到期'.format(title,int(expire_day))
else:
msg_last = '您的【{}】授权已到期'.format(title)
pl_msg = 'true'
if name in ['pro','ltd']:
pl_msg = 'false'
renew_msg = '<a class="btlink" onclick="bt.soft.product_pay_view({name:\'%s\',pid:%s,limit:\'%s\',plugin:%s,renew:%s});">立即续费</a>' % (title,pid,name,pl_msg,endtime)
pm.create_message(level=level,expire=7,msg="{},为了不影响您正常使用【{}】功能,请及时续费,{}".format(msg_last,title,renew_msg))
return True
return False
#到期提醒
def expire_msg(self,data):
'''
data 插件列表
'''
s_time = time.time()
is_plugin = True
#企业版到期提醒
if not data['ltd'] in [-1]:
level,expire_day = self.get_level_msg('ltd',s_time,data['ltd'])
self.add_expire_msg('企业版',level,'ltd',expire_day,100000032,data['ltd'])
return True
#专业版到期提醒
if not data['pro'] in [-1,0]:
level,expire_day = self.get_level_msg('pro',s_time,data['pro'])
self.add_expire_msg('专业版',level,'pro',expire_day,100000011,data['pro'])
is_plugin = False
#单独购买的插件到期提醒
for p in data['list']:
#跳过非企业版或专业版插件
if not p['type'] in [8,12]: continue
#已经是专业版的情况下跳过专业版插件
if not is_plugin and p['type'] == 8: continue
if not p['endtime'] in [-1,0]:
level,expire_day = self.get_level_msg(p['name'],s_time,p['endtime'])
self.add_expire_msg(p['title'],level,p['name'],expire_day,p['pid'],p['endtime'])
return True
#提交用户评分
def set_score(self,args):
try:
......@@ -1484,7 +1558,7 @@ class panelPlugin:
phpport = '888'
if os.path.exists(configFile):
conf = public.readFile(configFile)
rep = "listen\s+([0-9]+)\s*;"
rep = r"listen\s+([0-9]+)\s*;"
rtmp = re.search(rep,conf)
if rtmp:
phpport = rtmp.groups()[0]
......@@ -1494,23 +1568,23 @@ class panelPlugin:
configFile = setupPath + '/nginx/conf/enable-php.conf'
if not os.path.exists(configFile): public.writeFile(configFile,public.readFile(setupPath + '/nginx/conf/enable-php-54.conf'))
conf = public.readFile(configFile)
rep = "php-cgi-([0-9]+)\.sock"
rep = r"php-cgi-([0-9]+)\.sock"
rtmp = re.search(rep,conf)
if rtmp:
phpversion = rtmp.groups()[0]
else:
rep = "php-cgi.*\.sock"
rep = r"php-cgi.*\.sock"
public.writeFile(configFile,conf)
phpversion = '54'
configFile = setupPath + '/apache/conf/extra/httpd-vhosts.conf'
if os.path.exists(configFile):
conf = public.readFile(configFile)
rep = "php-cgi-([0-9]+)\.sock"
rep = r"php-cgi-([0-9]+)\.sock"
rtmp = re.search(rep,conf)
if rtmp:
phpversion = rtmp.groups()[0]
rep = "Listen\s+([0-9]+)\s*\n"
rep = r"Listen\s+([0-9]+)\s*\n"
rtmp = re.search(rep,conf)
if rtmp:
phpport = rtmp.groups()[0]
......@@ -1572,20 +1646,20 @@ class panelPlugin:
phpfpm = public.readFile(file)
data = {}
try:
rep = "upload_max_filesize\s*=\s*([0-9]+)M"
rep = r"upload_max_filesize\s*=\s*([0-9]+)M"
tmp = re.search(rep,phpini).groups()
data['max'] = tmp[0]
except:
data['max'] = '50'
try:
rep = "request_terminate_timeout\s*=\s*([0-9]+)\n"
rep = r"request_terminate_timeout\s*=\s*([0-9]+)\n"
tmp = re.search(rep,phpfpm).groups()
data['maxTime'] = tmp[0]
except:
data['maxTime'] = 0
try:
rep = u"\n;*\s*cgi\.fix_pathinfo\s*=\s*([0-9]+)\s*\n"
rep = r"\n;*\s*cgi\.fix_pathinfo\s*=\s*([0-9]+)\s*\n"
tmp = re.search(rep,phpini).groups()
if tmp[0] == '1':
......
......@@ -226,6 +226,8 @@ class panelSite(panelRedirect):
urlrewriteFile = urlrewritePath+'/'+self.siteName+'.conf'
if not os.path.exists(urlrewritePath): os.makedirs(urlrewritePath)
open(urlrewriteFile,'w+').close()
if not os.path.exists(urlrewritePath):
public.writeFile(urlrewritePath,'')
return True
#重新生成nginx配置文件
......
#coding: utf-8
# +-------------------------------------------------------------------
# | 宝塔Linux面板
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <2020-05-18>
# +-------------------------------------------------------------------
# +-------------------------------------------------------------------
# | 流媒体模块
# +-------------------------------------------------------------------
import os,sys,re
import mimetypes
import public
from BTPanel import Response
def get_buff_size(file_size):
buff_size = 2097152
if file_size < 104857600:
buff_size = 2097152
elif file_size < 524288000:
buff_size = 4194304
elif file_size < 1073741824:
buff_size = 8388608
else:
buff_size = 10485760
return buff_size
def partial_response(path, start, end=None):
if not os.path.exists(path):
return Response("file not fount!",404)
file_size = os.path.getsize(path)
buff_size = get_buff_size(file_size)
if end is None:
end = start + buff_size - 1
end = min(end, file_size - 1)
end = min(end, start + buff_size - 1)
length = end - start + 1
with open(path, 'rb') as fd:
fd.seek(start)
bytes = fd.read(length)
assert len(bytes) == length
response = Response(bytes,206,mimetype=mimetypes.guess_type(path)[0],direct_passthrough=True,)
response.headers.add('Content-Range', 'bytes {0}-{1}/{2}'.format(start, end, file_size,),)
response.headers.add('Accept-Ranges', 'bytes')
return response
def get_range(request):
range = request.headers.get('Range')
m = None
if range:
m = re.match(r'bytes=(?P<start>\d+)-(?P<end>\d+)?', range)
if m:
start = m.group('start')
end = m.group('end')
start = int(start)
if end is not None:
end = int(end)
return start, end
else:
return 0, None
#!/usr/bin/python
#coding: utf-8
# Author: <梁凯强>1249648969@qq.com
# panelWaf.py
# code: 面板基础安全类
# +-------------------------------------------------------------------
# | 宝塔Linux面板
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2017 宝塔软件(http:#bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# +-------------------------------------------------------------------
import re,json,sys,public,os
flag_file='/www/server/panel/data/tmp1.json'
try:
import libinjection
except:
if not os.path.exists(flag_file):
public.WriteFile(flag_file,'1')
else:
count_size=public.ReadFile(flag_file)
if count_size.strip().isdigit():
if int(count_size.strip())>= 5:
exit(False)
else:
public.WriteFile(flag_file, str(int(count_size.strip())+1))
else:public.WriteFile(flag_file,'1')
if os.path.exists('/www/server/panel/pyenv/bin/python3'):
public.ExecShell('/www/server/panel/pyenv/bin/pip install Cython')
public.ExecShell('/www/server/panel/pyenv/bin/pip install libinjection-python')
else:
public.ExecShell('pip install Cython')
public.ExecShell('pip install libinjection-python')
class panelWaf:
__ConfigFile = '/www/server/nginx/waf/config.lua'
__WafConfigPath = '/www/server/panel/vhost/wafconf'
#获取配置项
def GetConfig(self,get):
data = {}
try:
conf = public.readFile(self.__ConfigFile);
configs = ["attacklog","UrlDeny","Redirect","CookieMatch","postMatch","whiteModule","CCDeny","CCrate"];
#遍历单一配置
for key in configs:
rep = key + "\s*=\s*\"([\w\/]+)\"\s*\n"
data[key] = re.search(rep,conf).groups()[0]
#遍历列表
configs = ["black_fileExt","ipWhitelist","ipBlocklist"];
for key in configs:
rep = key + "\s*=\s*(.+)\n";
data[key] = json.loads(re.search(rep,conf).groups()[0].replace("{","[").replace("}","]"));
get.name = 'whiteurl';
data['uriWhite'] = self.GetWafConf(get);
except:
pass;
data['status'] = self.GetStatus();
return data;
#取状态
def GetStatus(self):
path = "/www/server/nginx/conf/nginx.conf";
if not os.path.exists(path): return public.returnMsg(False,'WAF_NOT_NGINX');
conf = public.readFile(path);
status = 1;
if conf.find("#include luawaf.conf;") != -1: status = 0;
if conf.find("luawaf.conf;") == -1: status = -1;
return status;
#更新规则
def updateWaf(self,get):
names = ['args','cookie','post','url','user-agent'];
furl = 'http://download.bt.cn/install/waf/wafconf'
fpath = '/www/server/panel/vhost/wafconf'
for name in names:
public.downloadFile(furl + '/' + name,fpath + '/' + name);
public.serviceReload();
return public.returnMsg(True,'WAF_UPDATE')
#设置状态
def SetStatus(self,get):
path = "/www/server/nginx/conf/nginx.conf";
if not os.path.exists(path): return public.returnMsg(False,'WAF_NOT_NGINX');
conf = public.readFile(path);
status = self.GetStatus()
if status == -1: return public.returnMsg(False,'WAF_NOT_NGINX_VERSION');
if status == 0:
conf = conf.replace('#include luawaf.conf;',"include luawaf.conf;");
else:
conf = conf.replace('include luawaf.conf;',"#include luawaf.conf;");
public.writeFile(path,conf);
public.serviceReload();
return public.returnMsg(True,"SET_SUCCESS");
#设置配置项
def SetConfigString(self,get):
conf = public.readFile(self.__ConfigFile);
rep = get.name + "\s*=\s*\"[\w\/]+\"\s*\n"
conf = re.sub(rep,get.name + '="' + get.value.strip() + '"\n',conf)
public.writeFile(self.__ConfigFile,conf);
public.serviceReload();
return public.returnMsg(True,"SET_SUCCESS");
#设置配置项列表
def SetConfigList(self,get):
conf = public.readFile(self.__ConfigFile);
rep = get.name + "\s*=\s*(.+)\n";
keyList = json.loads(re.search(rep,conf).groups()[0].replace("{","[").replace("}","]"));
if get.name != 'black_fileExt':
rep2 = "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}";
if not re.search(rep2,get.value): return public.returnMsg(False,"WAF_CONF_ERR");
if get.act == 'del':
if not get.value in keyList: return public.returnMsg(False,"WAF_CONF_NOT_EXISTS");
tmp = []
for t in keyList:
if t == get.value: continue;
tmp.append(t);
keyList = tmp;
else:
if get.value in keyList:return public.returnMsg(False,"WAF_CONF_EXISTS");
keyList.append(get.value.strip());
keyStr = json.dumps(keyList).replace("[","{").replace("]","}");
conf = re.sub(rep,get.name + "=" + keyStr + "\n",conf);
public.writeFile(self.__ConfigFile,conf);
public.serviceReload();
return public.returnMsg(True,"SUCCESS");
#获取指定规则列表
def GetWafConf(self,get):
path = self.__WafConfigPath + '/' + get.name;
if not os.path.exists(path): return public.returnMsg(False,"WAF_CONF_NOT_EXISTS");
data = public.readFile(path).split("\n")
return data;
#设置指定规则列表
def SetWafConf(self,get):
path = self.__WafConfigPath + '/' + get.name;
if not os.path.exists(path): return public.returnMsg(False,"WAF_CONF_NOT_EXISTS");
data = public.readFile(path).split("\n")
if get.act == "del":
if not get.value in data: return public.returnMsg(False,"WAF_CONF_NOT_EXISTS");
tmp = []
for t in data:
if get.value == t: continue;
tmp.append(t);
data = tmp;
else:
if get.value in data: return public.returnMsg(False,"WAF_CONF_EXISTS");
data.append(get.value);
conf = ""
for v in data:
conf += v + "\n";
public.writeFile(path,conf[:-1]);
public.serviceReload();
return public.returnMsg(True,"SUCCESS");
#取日志
##json_data => {"username":"admin","password":"123456!@#$%%^"}
def is_sql(self,json_data):
for i in json_data:
try:
if type(json_data[i])==str:
if libinjection.is_sql_injection(json_data[i])['is_sqli']:
return True
except:continue
else:return False
if __name__ == "__main__":
if len(sys.argv) > 1:
p = panelWaf();
if sys.argv[1] == 'add' or sys.argv[1] == 'del':
print p.SetConfigList(sys.argv[2],sys.argv[3],sys.argv[1]);
else:
print p.SetConfigString(sys.argv[1],sys.argv[2]);
print GetConfig();
\ No newline at end of file
##json_data => {"username":"admin","password":"123456!@#$%%^"}
def is_xss(self,json_data):
for i in json_data:
try:
if type(json_data[i]) == str:
if libinjection.is_xss(json_data[i])['is_xss']:
return True
except:continue
else:return False
\ No newline at end of file
......@@ -40,7 +40,7 @@ function get_info(){
//文件与字符串处理库
$data['5io_string'] = array();
$data['5io_string']['Xmlrpc'] = get_extension_funcs('xmlrpc')?true:false;
$data['5io_string']['FileInfo'] = get_extension_funcs('fileinfo')?true:false;
$data['5io_string']['FileInfo'] = in_array('fileinfo',$data['modules'])?true:false;
$data['5io_string']['Ftp'] = get_extension_funcs('ftp')?true:false;
$data['5io_string']['Mbstring'] = get_extension_funcs('mbstring')?true:false;
$data['5io_string']['bz2'] = in_array('bz2',$data['modules']);
......
......@@ -239,7 +239,7 @@ def GetJson(data):
from json import dumps
if data == bytes: data = data.decode('utf-8')
try:
return dumps(data)
return dumps(data,ensure_ascii=False)
except:
return dumps(returnMsg(False,"Wrong response: %s" % str(data)))
......@@ -665,6 +665,7 @@ def getPanelAddr():
# 字节单位转换
def to_size(size):
if not size: return '0.00 b'
size = float(size)
d = ('b','KB','MB','GB','TB')
s = d[0]
......@@ -1307,12 +1308,13 @@ def set_own(filename, user, group=None):
return True
#校验路径安全
def path_safe_check(path):
checks = ['..', './', '\\', '%', '$', '^', '&', '*', '~', '@', '#']
def path_safe_check(path,force=True):
checks = ['..','./','\\','%','$','^','&','*','~','#','"',"'",';','|','{','}','`']
for c in checks:
if path.find(c) != -1: return False
rep = r"^[\w\s\.\/-]+$"
if not re.match(rep,path): return False
if force:
rep = r"^[\w\s\.\/-]+$"
if not re.match(rep,path): return False
return True
#取数据库字符集
......@@ -1629,9 +1631,12 @@ def import_cdn_plugin():
def get_cdn_hosts():
if import_cdn_plugin(): return []
import static_cdn_main
return static_cdn_main.static_cdn_main().get_hosts(None)
try:
if import_cdn_plugin(): return []
import static_cdn_main
return static_cdn_main.static_cdn_main().get_hosts(None)
except:
return []
def get_cdn_url():
try:
......
......@@ -203,6 +203,6 @@ class setPanelLets:
self.__save_cert_source(domain, get.email)
return public.returnMsg(True, 'Panel lets set successfully')
else:
return create_lets
return public.returnMsg(False, create_lets)
else:
return create_site
return public.returnMsg(False, create_site)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment