#coding: utf-8
#-------------------------------------------------------------------
# 宝塔Linux面板
#-------------------------------------------------------------------
# Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
#-------------------------------------------------------------------
# Author: cjxin <cjxin@bt.cn>
#-------------------------------------------------------------------

# 商用IP库
#------------------------------
import os,re,json,time
import subprocess

from safeModel.base import safeBase
import public
try:
    from BTPanel import session,cache
except:pass

class main(safeBase):
    __version = []
    __is_v6 = False #是否2008系统
    def __init__(self):
        self.__version = public.get_sys_version()
        if self.__version[0] == '6' and self.__version[1] == '1':
            __is_v6 = True
        try:
            if not cache.get('firewall_init'):
                self.firewall_init()
        except:pass


    #初始化IP安全策略
    def firewall_init(self):
        public.ExecShell('Netsh ipsec static add policy name =宝塔IP安全策略 description="用于过滤IP,禁PING,请不要删除"')
        result = public.ExecShell("Netsh ipsec static show filterlist name=IpList")
        if result[0].find('ERR')!=-1:
            public.ExecShell("Netsh ipsec static add filteraction name = 阻止IP访问 action =block")
            public.ExecShell('Netsh ipsec static add filterlist name=IpList description="禁止列表内的IP访问这台服务器"')
            public.ExecShell('Netsh ipsec static add filter filterlist=IpList srcaddr=122.226.158.132 srcport=0 dstaddr=me dstport=0 protocol=ANY mirrored=no description="初始化"')
        public.ExecShell("netsh ipsec static add rule name =屏蔽IP Policy = 宝塔IP安全策略 filterlist =IpList filteraction =  阻止IP访问")
        public.ExecShell("Netsh ipsec static set policy name = 宝塔IP安全策略 assign = y")
        cache.set('firewall_init',1)
        return True


    def get_firewall_info(self,get):

        data = {}
        ret = public.ExecShell("netsh advfirewall firewall show rule name=all type=dynamic ",None,None,None,True)[0]
        tmps = re.findall("\s?.+?:(.+)\n----.+\n.+?:(.+)\n.+?:(.+)\n.+?:(.+)\n.+?:(.+)\n.+?:(.+)\n.+?:(.+)\n.+?:(.+)\n.+?:(.+)\n.+?:(.+)\n.+?:(.+)\n.+?:(.+)",ret)
        data['prot'] = 0
        for x in tmps:
            if not x[4].strip():
                data['prot'] += 1

        return data



    #添加入站规则
    def add_rules(self,get):
        rule_name = get.rule_name
        if not rule_name: return public.returnMsg(False,'缺少必要参数 rule_name.')
        rule_name = rule_name.replace(' ','')

        if not hasattr(get, 'rule_action'): return public.returnMsg(False,'缺少必要参数 rule_action.')
        protocol = get.protocol #tcp/udp

        port = get.port
        for x in port.split(','):
            if not re.search('^\d+$',x) and not re.search('^\d+\-\d+$',x): return public.returnMsg(False,'参数传递错误，格式应为：80,443,500-600')

        remoteip ='any'
        if hasattr(get, 'remoteip'):
            remoteip = get.remoteip
            for x in remoteip.split(','):
                if not re.search('^\d+\.\d+\.\d+\.\d+$',x) and not re.search('^\d+\.\d+\.\d+\.\d+/\d+$',x) and not re.search('^\d+\.\d+\.\d+\.\d+-\d+\.\d+\.\d+\.\d+$',x):
                    return public.returnMsg(False,'参数传递错误，格式应为：127.0.0.1 \r\n 192.168.1.1/24 \r\n192.168.1.1-192.168.1.255')

        status = 'yes'
        if hasattr(get, 'status'): status = get.status

        #if not self.__is_v6:
        shell = 'netsh advfirewall firewall add rule name="{}" dir="{}" enable="{}" action="{}" protocol={} localport="{}" remoteip="{}"'.format(rule_name,get.dir,status,get.rule_action,protocol,port,remoteip)
        public.ExecShell(shell)
        return public.returnMsg(True,'添加规则【{}】成功.'.format(rule_name))

    #导入规则
    def import_rules(self,get):
        data = json.loads(get.data)
        if not data or type(data) != list: return public.returnMsg(False,'导入JSON格式错误，请确认后重新操作。')

        rdata = self.get_all_rules(None)
        n = 0
        for x in data:
            is_add = True
            for rule in rdata:
                if rule['name'] == x['name'] and rule['handle'] == x['handle'] and rule['port'] == x['port']:
                    is_add = False
                    break
            if is_add:
                nget = public.dict_obj()
                nget.rule_name = x['name']
                nget.rule_action = x['handle']
                nget.port = x['port']
                nget.protocol = x['protocol']
                nget.dir = x['dir']
                nget.status = 'yes'

                if not x['status']: nget.status = 'no'
                if x['ip'] != 'all': nget.remoteip = x['ip']

                ret = self.add_rules(nget)
                print(ret,x['port'])
                if ret['status']: n +=1
        return public.returnMsg(True,'导入成功，已成功导入【{}】条规则.'.format(n))

    #修改规则状态
    def set_rule_status(self,get):

        name = str(get.rule_name).replace(' ','')

        status = get.status
        shell = 'netsh advfirewall firewall set rule name="{}" new enable={}'.format(name,status)
        public.ExecShell(shell)
        return public.returnMsg(True,'修改【{}】规则状态成功.'.format(name))

    #修改规则
    def set_rules(self,get):
        rule_name = get.rule_name
        if not rule_name: return public.returnMsg(False,'缺少必要参数 rule_name.')

        rule_name = rule_name.replace(' ','')
        if not hasattr(get, 'rule_action'): return public.returnMsg(False,'缺少必要参数 rule_action.')
        protocol = get.protocol #tcp/udp

        port = get.port
        for x in port.split(','):
            if not re.search('^\d+$',x) and not re.search('^\d+\-\d+$',x): return public.returnMsg(False,'参数传递错误，格式应为：80,443,500-600')

        remoteip ='any'
        if hasattr(get, 'remoteip'):
            remoteip = get.remoteip
            for x in remoteip.split(','):
                if not re.search('^\d+\.\d+\.\d+\.\d+$',x) and not re.search('^\d+\.\d+\.\d+\.\d+/\d+$',x) and not re.search('^\d+\.\d+\.\d+\.\d+-\d+\.\d+\.\d+\.\d+$',x):
                    return public.returnMsg(False,'参数传递错误，格式应为：127.0.0.1 \r\n 192.168.1.1/24 \r\n192.168.1.1-192.168.1.255')
        #if not self.__is_v6:
        shell = 'netsh advfirewall firewall set rule name="{}" new dir="{}" action="{}" protocol={} localport="{}" remoteip="{}"'.format(rule_name,get.dir,get.rule_action,protocol,port,remoteip)
        public.ExecShell(shell)
        return public.returnMsg(True,'修改规则【{}】成功.'.format(rule_name))

    #删除规则
    def del_rules(self,get):
        rule_name = get.rule_name
        if not rule_name: return public.returnMsg(False,'缺少必要参数 rule_name.')

        #if not self.__is_v6:
        shell = ' netsh advfirewall firewall delete rule name="{}"'.format(get.rule_name)


        if shell: public.ExecShell(shell)
        return public.returnMsg(True,'删除规则【{}】成功.'.format(rule_name))

    #遍历查找
    def __search_rules(self,data,search):
        if search:
            for x in data.keys():
                if type(data[x]) == str:
                    if data[x].lower().find(search.lower()) >= 0:
                        return data
            return False
        else:
            return data

    #获取所有规则
    def get_all_rules(self, get):

        if public.get_server_status("MpsSvc") <= 0:
            return public.returnMsg(
                False,
                "系统防火墙被服务商停用，请通过服务商控制台放行端口或启用系统防火墙服务(服务名称MpsSvc).",
            )

        ret = public.ExecShell(
            "netsh advfirewall firewall show rule name=all type=dynamic ",
            None,
            None,
            None,
            True,
        )[0]
        tmps = re.findall(
            "\s?.+?:(.+)\n----.+\n.+?:(.+)\n.+?:(.+)\n.+?:(.+)\n.+?:(.+)\n.+?:(.+)\n.+?:(.+)\n.+?:(.+)\n.+?:(.+)\n.+?:(.+)\n.+?:(.+)\n.+?:(.+)",
            ret,
        )
        data = []

        search = None
        p, count = 1, 1000
        if hasattr(get, "search"):
            search = get.search
        if hasattr(get, "p"):
            p = int(get.seaprch)
        if hasattr(get, "count"):
            count = int(get.count)

        min_num, max_num = (p - 1) * count, p * count

        dir = None
        if hasattr(get, "dir"):
            dir = get.dir
            if dir.strip() == "all":
                dir = None

        idx = 0

        port_process_infos = self.get_port_status_info()

        for x in tmps:
            if not x[4].strip():
                item = {}

                item["port"] = x[8].strip()
                if x[8].strip().find("任何") >= 0 or x[8].strip().find("Any") >= 0:
                    item["port"] = "all"

                item["protocol"] = x[7].strip()
                item["dir"] = "in"
                if x[2].strip().find("出") >= 0 or x[2].strip().find("Out") >= 0:
                    item["dir"] = "out"

                item["status"] = False
                if x[1].strip().find("是") >= 0 or x[1].strip().find("Yes") >= 0:
                    item["status"] = True
                    
                item["detail"] = [] # 添加默认字段
                
                if item["status"]:
                    detail = port_process_infos.get(item["port"], [])
                    item["detail"] = detail

                item["ip"] = x[6].strip()
                if item["ip"].find("任何") >= 0 or item["ip"].find("Any") >= 0:
                    item["ip"] = "all"

                item["handle"] = "block"
                if x[11].strip().find("允许") >= 0 or x[11].strip().find("Allow") >= 0:
                    item["handle"] = "allow"

                item["name"] = x[0].strip()
                item = self.__search_rules(item, search)

                if item:
                    if dir:
                        if item["dir"].strip() != dir:
                            continue
                    if not item in data:
                        if idx >= min_num and idx < max_num:
                            data.append(item)
                        idx += 1
        return data
    
    def get_port_status_info(self) -> dict:
        import psutil

        pid_process_infos = {}

        for proc in psutil.process_iter(["pid", "name", "exe"]):
            try:
                pid = proc.pid
                name = proc.name()
                addr = proc.exe()
                pid_process_infos[pid] = (pid, name, addr)
            except (psutil.NoSuchProcess, psutil.AccessDenied):
                continue

        pid_ports_l = {}
        pid_ports_r = {}
        
        for i in psutil.net_connections():
            pid = i.pid
            if len(i.laddr) >= 2:
                lport = i.laddr[1]
                pid_ports_l[pid] = lport
            if len(i.raddr) >= 2:
                rport = i.raddr[1]
                pid_ports_r[pid] = rport

        port_process_infos = {}
        for k, v in pid_ports_l.items():
            info = pid_process_infos.get(k, ())
            port_process_infos[str(v)] = info

        for k, v in pid_ports_r.items():
            info = pid_process_infos.get(k, ())
            port_process_infos[str(v)] = info
        
        return port_process_infos
    
    #添加端口转发
    def add_portproxy(self,get):

        if not hasattr(public,"is_ipv4"):
            return public.returnMsg(False,'请将面板升级到最新版后重试.')

        if not self.__check_port(get.local_port):
            return public.returnMsg(False,'源端口填写不正确，应为：1 - 65535')

        if not self.__check_port(get.remote_port):
            return public.returnMsg(False,'远程端口填写不正确，应为：1 - 65535')

        if not public.check_ip(get.remote_ip):
            return public.returnMsg(False,'远程IP格式不正确，应为ipv4/ipv6格式.')

        dst = 'tov4'
        if public.is_ipv6(get.remote_ip): dst = 'tov6'

        shell = 'netsh interface portproxy add {} listenaddress="{}" listenport="{}" connectaddress="{}" connectport="{}"'
        s_type = get.s_type
        if s_type == 'all':
            public.ExecShell(shell.format("v4"+ dst,"0.0.0.0",get.local_port,get.remote_ip,get.remote_port))
            public.ExecShell(shell.format("v6"+ dst,"::",get.local_port,get.remote_ip,get.remote_port))
        else:
            local_ip = '0.0.0.0'
            if s_type == 'v6':local_ip = '::'
            public.ExecShell(shell.format(s_type + dst,local_ip,get.local_port,get.remote_ip,get.remote_port))

        print(shell.format("v4"+ dst,"0.0.0.0",get.local_port,get.remote_ip,get.remote_port))
        public.WriteLog("系统防火墙","添加端口转发本地端口【{}】转发到【{}:{}】".format(get.local_port,get.remote_ip,get.remote_port))
        return public.returnMsg(True,"添加端口转发本地端口【{}】转发到【{}:{}】成功".format(get.local_port,get.remote_ip,get.remote_port))

    def __check_port(self,port):
        try:
            if not re.match('^\d+$',port):  return False

            intport = int(port)
            if intport < 1 or intport > 65535: return False
            return True
        except :
            return False

    #修改端口转发
    def set_portproxy(self,get):

        if not hasattr(public,"is_ipv4"):
            return public.returnMsg(False,'请将面板升级到最新版后重试.')

        if not self.__check_port(get.local_port):
            return public.returnMsg(False,'源端口填写不正确，应为：1 - 65535')

        if not public.check_ip(get.local_ip):
            return public.returnMsg(False,'源IP格式不正确，应为ipv4/ipv6格式.')

        if not self.__check_port(get.remote_port):
            return public.returnMsg(False,'远程端口填写不正确，应为：1 - 65535')

        if not public.check_ip(get.remote_ip):
            return public.returnMsg(False,'远程IP格式不正确，应为ipv4/ipv6格式.')


        dst = 'tov4'
        if public.is_ipv6(get.remote_ip): dst = 'tov6'

        src = 'v4'
        if public.is_ipv6(get.local_ip): src = 'v6'

        public.ExecShell('netsh interface portproxy set {} listenaddress="{}" listenport="{}" connectaddress="{}" connectport="{}"'.format(src + dst,get.local_ip,get.local_port,get.remote_ip,get.remote_port))

        public.WriteLog("系统防火墙","修改端口转发本地端口【{}】转发到【{}:{}】".format(get.local_port,get.remote_ip,get.remote_port))
        return public.returnMsg(True,"修改端口转发本地端口【{}】转发到【{}:{}】成功".format(get.local_port,get.remote_ip,get.remote_port))


    #删除转发规则
    def del_portproxy(self,get):
        if not hasattr(public,"is_ipv4"):
            return public.returnMsg(False,'请将面板升级到最新版后重试.')

        if not self.__check_port(get.local_port):
            return public.returnMsg(False,'源端口填写不正确，应为：1 - 65535')

        if not public.check_ip(get.local_ip):
            return public.returnMsg(False,'源IP格式不正确，应为ipv4/ipv6格式.')

        dst = 'tov4'
        if public.is_ipv6(get.remote_ip): dst = 'tov6'

        src = 'v4'
        if public.is_ipv6(get.local_ip): src = 'v6'

        public.ExecShell('netsh interface portproxy delete {} listenaddress="{}"  listenport="{}"'.format(src + dst,get.local_ip,get.local_port))
        public.WriteLog("系统防火墙","删除端口转发本地端口【{}】".format(get.local_port))

        return public.returnMsg(True,"删除端口转发本地端口【{}】".format(get.local_port))

    #获取所有端口转发列表
    def get_portproxys(self,get):
        ret = public.ExecShell('netsh interface portproxy show all')[0]
        tmps = re.findall("(.+?)\s+(\d+?)\s+(.+?)\s+(\d+)",ret)
        data = []

        search = None
        if hasattr(get,'search'): search = get.search

        for x in tmps:
            item = {}
            item['local_ip'] = x[0].strip()
            item['local_port'] = x[1].strip()
            item['remote_ip'] = x[2].strip()
            item['remote_port'] = x[3].strip()

            item = self.__search_rules(item,search)
            if item:  data.append(item)
        return data


    #获取掩码
    def cidr(self,ipn):
        import socket,struct
        data = {}
        arrs = ipn.split('/')
        if len(arrs) == 2:
            try:
                data['ip'] = arrs[0]
                data['mask'] = socket.inet_ntoa(struct.pack(">I", (0xffffffff << (32 - int(arrs[1]))) & 0xffffffff))
            except :data = {}
        return data

    #获取所有屏蔽IP列表
    def get_drop_ips(self, get):

        if not hasattr(public, "is_ipv4"):
            return public.returnMsg(False, "请将面板升级到最新版后重试.")

        try:
            import IPy
        except:
            os.system(
                public.get_run_pip(
                    "[PIP] install IPy -i https://pypi.doubanio.com/simple"
                )
            )
            import IPy

        search = None
        if hasattr(get, "search"):
            search = get.search

        ret = public.ExecShell(
            "netsh ipsec static show filterlist IpList verbose", None, None, None, True
        )[0]
        tmps = re.findall(
            "[\n-]\s+.+:\s+(.+)\s+.+:(.+)\s+.+:\s+(.+)\s+.+:(.+)\s+.+:(.+)\s+.+:(.+)\s+.+:(.+)\s+.+:(.+)\s+.+:(.+)",
            ret,
        )
        data = []
        for x in tmps:
            item = {}
            item["ps"] = x[0].strip()

            ip = x[2].strip()
            if public.is_ipv4(ip):
                mask = x[3].strip()
                if mask == "255.255.255.255":
                    item["ip"] = ip
                else:
                    ip_str = str(IPy.IP(ip).make_net(mask))
                    item["ip"] = "{}/{}".format(ip, ip_str.split("/")[1])
            else:
                item["ip"] = ip
                if ip.find("IP") >= 0:
                    item["ip"] = "0.0.0.0/24"
            addr = public.get_free_ip_info(ip)
            item["area"] = addr["info"]
            item["type"] = "drop"

            item = self.__search_rules(item, search)
            if item:
                data.append(item)
        return data

    #添加拦截ip
    def add_drop_ip(self,get):
        ips = get.ip.split('/')
        if len(ips) > 1:
            if not public.check_ip(ips[0]): return public.returnMsg(False,'IP格式错误，不是有效的IPV4/IPV6。')
            try:
                mask = int(ips[1])
                if mask < 0 or mask > 32:  return public.returnMsg(False,'不是有效的子网地址，应为：1-32。')
            except :
                return public.returnMsg(True,'不是有效的子网地址，应为：1-32。')
            public.ExecShell('netsh ipsec static add filter filterlist=IpList srcaddr="{}" srcmask="{}" srcport=0 dstaddr=me dstport=0 protocol=any mirrored=no description="{}"'.format(ips[0],ips[1],get.ps));
        else:
            if not public.check_ip(get.ip): return public.returnMsg(False,'IP格式错误，不是有效的IPV4/IPV6。')
            public.ExecShell('netsh ipsec static add filter filterlist=IpList srcaddr="{}" srcport=0 dstaddr=me dstport=0 protocol=any mirrored=no description="{}"'.format(get.ip,get.ps));

        public.WriteLog("系统防火墙", 'FIREWALL_DROP_IP',(get.ip,))
        return public.returnMsg(True,'ADD_SUCCESS')

    #导入拦截ip
    def import_drop_ip(self,get):
        data = get.data.split('\n')

        rdata = self.get_drop_ips(None)
        n = 0
        for x in data:
            if not x: continue;
            is_add = True
            for rule in rdata:
                if rule['ip'].strip() == x.strip():
                    is_add = False
                    break;
            if is_add:
                nget = public.dict_obj()
                nget.ip = x.strip()
                nget.ps = "批量导入IP【{}】".format(x.strip())
                ret = self.add_drop_ip(nget)
                if ret['status']: n+=1

        return public.returnMsg(True,'导入成功，共导入【{}】条规则。'.format(n))

    #删除拦截ip
    def del_drop_ip(self,get):
        ips = get.ip.split('/')
        if len(ips) > 1:
            ret = public.ExecShell('netsh ipsec static delete filter filterlist=IpList srcaddr="{}"  srcmask="{}" srcport=0 dstaddr=me dstport=0 protocol=any mirrored=no'.format(ips[0],ips[1]));
            print(ret)
        else:
            if public.is_ipv6(get.ip): return public.returnMsg(False,'暂不支持自动删除IPV6功能，请手动删除。 <a href="https://www.bt.cn/bbs/thread-13647-1-1.html" target="_blank" class="btlink">如何删除？</a>')
            public.ExecShell('netsh ipsec static delete filter filterlist=IpList srcaddr="{}" srcport=0 dstaddr=me dstport=0 protocol=any mirrored=no'.format(get.ip));

        public.WriteLog("系统防火墙",'删除屏蔽IP【{}】'.format(get.ip))
        return public.returnMsg(True,'删除成功。')


    #ip白名单放行
    def init_white_ip(self):
        result = public.ExecShell("Netsh ipsec static show filterlist name=WhiteList")
        if result[0].find('ERR')!=-1:
            public.ExecShell("Netsh ipsec static add filteraction name = 允许特定IP访问 action =permit")
            public.ExecShell('Netsh ipsec static add filterlist name=WhiteList description="允许列表内的IP访问这台服务器"')
            public.ExecShell('Netsh ipsec static add filter filterlist=WhiteList srcaddr=127.0.0.1 srcport=0 dstaddr=me dstport=0 protocol=ANY mirrored=no description="初始化"')
        public.ExecShell("netsh ipsec static add rule name =放行IP Policy = 宝塔IP安全策略 filterlist =WhiteList filteraction =  允许特定IP访问")


    #获取所有白名单IP列表
    def get_white_ips(self, get):
        self.init_white_ip()

        if not hasattr(public, "is_ipv4"):
            return public.returnMsg(False, "请将面板升级到最新版后重试.")

        try:
            import IPy
        except:
            os.system(
                public.get_run_pip(
                    "[PIP] install IPy -i https://pypi.doubanio.com/simple"
                )
            )
            import IPy

        search = None
        if hasattr(get, "search"):
            search = get.search

        ret = public.ExecShell(
            "netsh ipsec static show filterlist WhiteList verbose",
            None,
            None,
            None,
            True,
        )[0]
        tmps = re.findall(
            "[\n-]\s+.+:\s+(.+)\s+.+:(.+)\s+.+:\s+(.+)\s+.+:(.+)\s+.+:(.+)\s+.+:(.+)\s+.+:(.+)\s+.+:(.+)\s+.+:(.+)",
            ret,
        )
        print(len(tmps))
        data = []
        for x in tmps:
            item = {}
            item["ps"] = x[0].strip()

            ip = x[2].strip()
            if public.is_ipv4(ip):
                mask = x[3].strip()
                if mask == "255.255.255.255":
                    item["ip"] = ip
                else:
                    ip_str = str(IPy.IP(ip).make_net(mask))
                    item["ip"] = "{}/{}".format(ip, ip_str.split("/")[1])
            else:
                item["ip"] = ip
            addr = public.get_free_ip_info(ip)
            item["area"] = addr["info"]
            item["type"] = "allow"

            item = self.__search_rules(item, search)
            if item:
                data.append(item)
        return data

    #添加ip白名单
    def add_white_ip(self,get):
        self.init_white_ip()

        ips = get.ip.split('/')
        if len(ips) > 1:
            if not public.check_ip(ips[0]): return public.returnMsg(False,'IP格式错误，不是有效的IPV4/IPV6。')
            try:
                mask = int(ips[1])
                if mask < 0 or mask > 32:  return public.returnMsg(False,'不是有效的子网地址，应为：1-32。')
            except :
                return public.returnMsg(True,'不是有效的子网地址，应为：1-32。')
            public.ExecShell('netsh ipsec static add filter filterlist=WhiteList srcaddr="{}" srcmask="{}" srcport=0 dstaddr=me dstport=0 protocol=any mirrored=no description="{}"'.format(ips[0],ips[1],get.ps));
        else:
            if not public.check_ip(get.ip): return public.returnMsg(False,'IP格式错误，不是有效的IPV4/IPV6。')
            public.ExecShell('netsh ipsec static add filter filterlist=WhiteList srcaddr="{}" srcport=0 dstaddr=me dstport=0 protocol=any mirrored=no description="{}"'.format(get.ip,get.ps));

        public.WriteLog("系统防火墙", '添加IP白名单{}'.format(get.ip))
        return public.returnMsg(True,'ADD_SUCCESS')

    #导入拦截ip
    def import_white_ip(self,get):
        data = get.data.split('\n')

        rdata = self.get_white_ips(None)
        n = 0
        for x in data:
            if not x: continue;
            is_add = True
            for rule in rdata:
                if rule['ip'].strip() == x.strip():
                    is_add = False
                    break;
            if is_add:
                nget = public.dict_obj()
                nget.ip = x.strip()
                nget.ps = "批量导入IP【{}】".format(x.strip())
                ret = self.add_white_ip(nget)
                if ret['status']: n+=1

        return public.returnMsg(True,'导入成功，共导入【{}】条规则。'.format(n))

    #删除ip白名单
    def del_white_ip(self,get):
        self.init_white_ip()
        ips = get.ip.split('/')
        if len(ips) > 1:
            ret = public.ExecShell('netsh ipsec static delete filter filterlist=WhiteList srcaddr="{}"  srcmask="{}" srcport=0 dstaddr=me dstport=0 protocol=any mirrored=no'.format(ips[0],ips[1]));
            print(ret)
            print('netsh ipsec static delete filter filterlist=WhiteList srcaddr="{}"  srcmask="{}" srcport=0 dstaddr=me dstport=0 protocol=any mirrored=no'.format(ips[0],ips[1]))
        else:
            if public.is_ipv6(get.ip): return public.returnMsg(False,'暂不支持自动删除IPV6功能，请手动删除。 <a href="https://www.bt.cn/bbs/thread-13647-1-1.html" target="_blank" class="btlink">如何删除？</a>')

            public.ExecShell('netsh ipsec static delete filter filterlist=WhiteList srcaddr="{}" srcport=0 dstaddr=me dstport=0 protocol=any mirrored=no'.format(get.ip));

        public.WriteLog("系统防火墙",'删除白名单IP【{}】'.format(get.ip))
        return public.returnMsg(True,'删除成功。')


    def check_port_rule(self,get):

        port = get.port
        slist = self.get_all_rules(get)
        for x in slist:
           if x['port'] == port:
               return True

        return False


    def get_firewall_status(self, get = None):
        """
        @name 获取Windows系统防火墙状态
        @return 防火墙状态 True表示开启，False表示关闭
        """
        try:
            command = 'Get-NetFirewallProfile -Name \'Private\',\'Public\' | Select-Object -ExpandProperty Enabled'
            startupinfo = subprocess.STARTUPINFO()
            startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
            result = subprocess.Popen(['powershell', '-Command', command], stdout=subprocess.PIPE,
                                      stderr=subprocess.PIPE, startupinfo=startupinfo)
            output, _ = result.communicate()

            if result.returncode == 0:
                output = output.decode().strip().split('\n')
                output = [line.strip().lower() for line in output if line.strip()]

                if 'false' in output:
                    return False

        except subprocess.CalledProcessError:
            pass

        return True

    def enable_firewall(self, get = None):
        try:
            command = 'Set-NetFirewallProfile -Name "Private","Public" -Enabled True'
            subprocess.run(['powershell', '-Command', command], check=True)
            return True

        except subprocess.CalledProcessError:
            return False

    def disable_firewall(self, get = None):
        try:
            command = 'Set-NetFirewallProfile -Name "Private","Public" -Enabled False'
            subprocess.run(['powershell', '-Command', command], check=True)
            return True

        except subprocess.CalledProcessError:
            return False

    def set_firewall(self, get):
        order = ['stop', 'start']
        if get.status not in order:
            return public.returnMsg(False, '未知控制命令!')

        firewall_status = self.get_firewall_status()

        if not firewall_status:
            if self.enable_firewall():
                return public.returnMsg(True, "开启防火墙成功")
            else:
                return public.returnMsg(False, "开启防火墙失败")

        if firewall_status and self.disable_firewall():
            return public.returnMsg(True, "关闭防火墙成功")
        else:
            return public.returnMsg(False, "关闭防火墙失败")
