#!/usr/bin/python
# coding: utf-8

import os, sys, public
import re

_title = '检查nginx配置文件是否被挂马'
_version = 1.0  # 版本
_ps = "检查nginx配置文件是否被挂马"  # 描述
_level = 3  # 风险级别： 1.提示(低)  2.警告(中)  3.危险(高)
_date = '2023-11-21'  # 最后更新时间
_ignore = os.path.exists("data/warning/ignore/sw_nginx_malware.pl")
_tips = [
    "根据提示,找到nginx配置文件，删除js挂马内容,或点击【修复】按钮",
    "重启nginx服务"
]
_help = ''
_remind = '手动修复之前建议先把该配置文件做备份，以防操作失误导致服务无法启动；或者使用一键修复'


def check_run():
    '''
        @name 开始检测
        @author lwh<2023-11-21>
        @return tuple (status<bool>,msg<string>)
    '''
    try:
        import glob
        path = '/www/server/panel/vhost/nginx/'
        if not os.path.exists(path):
            return True, '无风险'
        risk_files = []
        # 检测规则
        malware_patterns = [
            r'sub_filter\s+[^;]+;',  # 检测可疑的sub_filter指令
        ]
        patterns = [re.compile(pattern) for pattern in malware_patterns]

        for filename in glob.glob(os.path.join(path, '*.conf')):
            try:
                if os.path.isdir(filename):
                    continue
                content = public.ReadFile(filename)
                if not content:
                    continue
                # 检查文件大小 10MB
                if len(content) > 10 * 1024 * 1024:
                    continue
                # 检测恶意文件特征
                for pattern in patterns:
                    matches = pattern.findall(content)
                    if matches:
                        risk_files.append({
                            'file': filename,
                            'content': matches[0].strip()
                        })
                        break
                # 原
                # if "sub_filter" in output:
                #     risk_file.append(filename)
            except Exception as e:
                continue
        if risk_files:
            # 生成简单的报告
            report = ["发现{}个配置文件存在可疑内容:".format(len(risk_files))]

            for i, risk in enumerate(risk_files, 1):
                report.append("{}. 文件: {} ".format(
                    i,
                    risk['file']
                    # risk['content']
                ))

            return False, '<br />' + ('<br />'.join(report))

        # if len(risk_file) > 0:
        #     return False, '以下nginx文件存在挂马内容：{}'.format('、'.join(risk_file))
        return True, '无风险'
    except Exception as e:
        return True, '无风险'


def _get_context(content, match, context_lines=2):
    """获取匹配内容的上下文"""
    try:
        lines = content.split('\n')
        for i, line in enumerate(lines):
            if match in line:
                start = max(0, i - context_lines)
                end = min(len(lines), i + context_lines + 1)
                return '\n'.join(lines[start:end])
    except:
        return match
    return match