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

# ssh信息
#------------------------------
import os,re,json,time
from safeModel.base import safeBase
import public,winreg


class main(safeBase):

    def __init__(self):
        pass


    def SetPing(self,get):
        """
        设置禁ping开关

        """
        path = 'data/ping.pl'
        if get.status == '1':
            if int(self.__version[0]) == 6:
                public.ExecShell('netsh advfirewall firewall delete rule name="禁PING"')
            public.ExecShell("netsh firewall set service fileandprint enable")
            public.ExecShell('netsh ipsec static delete rule name =禁止PING Policy = "宝塔IP安全策略"')
            public.ExecShell('netsh ipsec static delete filterlist name =PortList');
            if os.path.exists(path): os.remove(path)

            return public.returnMsg(True,'解除禁PING成功！')
        else:
             result = public.ExecShell('Netsh ipsec static show filterlist name=PortList')
             if result[0].find('ERR')!=-1:
                public.ExecShell("Netsh ipsec static add filteraction name = 阻止 action =block")
                public.ExecShell('Netsh ipsec static add filter filterlist=PortList srcaddr=122.226.158.132 srcport=0 dstaddr=me dstport=0 protocol=ANY mirrored=no description="初始化"')
             public.ExecShell("netsh ipsec static add rule name =禁止PING Policy = 宝塔IP安全策略 filterlist =PortList filteraction = 阻止")
             public.ExecShell("netsh ipsec static add filter filterlist=PortList srcaddr=any dstaddr=me protocol=icmp  description=禁止PING mirrored=yes")
             public.writeFile(path,'True')
             return public.returnMsg(True,'禁PING成功！')



    def SetSshPort(self,get):
        """
        修改远程桌面端口
        """
        port = get.port
        if not public.checkPort(port): return public.returnMsg(False,'FIREWALL_SSH_PORT_ERR');

        ports = ['21','25','80','443','8080','888','8888'];
        if port in ports: return public.returnMsg(False,'');

        for x in [0,1,2,3,4,5,6,7,8,9,10]:
            public.ExecShell("ECHO Y|logoff " + str(x))
        regPath = r'SYSTEM\CurrentControlSet\Control\Terminal Server';
        public.WriteReg(regPath,'fDenyTSConnections',1)
        public.WriteReg(r"SYSTEM\CurrentControlSet\Control\Terminal Server\Wds\rdpwd\Tds\tcp",'PortNumber',int(port))
        public.WriteReg(r'SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp','PortNumber',int(port))
        time.sleep(0.5)
        public.WriteReg(regPath,'fDenyTSConnections',0)

        old_port = public.M('firewall').where("ps=?",('远程桌面管理服务',)).getField('port')
        if old_port != port:
            public.M('firewall').where("ps=?",('远程桌面管理服务',)).delete()
            get['ps'] = "远程桌面管理服务"
            self.AddAcceptPort(get)

            public.set_func("SetSshPort") #记录修改时间


        public.WriteLog("TYPE_FIREWALL", "FIREWALL_SSH_PORT",(port,))
        return public.returnMsg(True,'EDIT_SUCCESS')

    def SetSshStatus(self,get):
        """
        设置远程端口状态
        @get.status 远程桌面状态
        """
        try:
            status = int(get['status'])
            if int(status) == 1:
                if os.path.exists('data/close.pl'):
                    return public.returnMsg(False,'请勿同时关闭远程桌面和面板！')
                msg = public.getMsg('FIREWALL_SSH_STOP')
            else:
                msg = public.getMsg('FIREWALL_SSH_START')

            for x in [0,1,2,3,4,5,6,7,8,9,10]:
                public.ExecShell("ECHO Y|logoff " + str(x))

            public.WriteReg(r'SYSTEM\CurrentControlSet\Control\Terminal Server','fDenyTSConnections',status)
            public.WriteLog("TYPE_FIREWALL", msg)
            return public.returnMsg(True,'SUCCESS')
        except :
            error =  public.get_error_info()
            if error.find('PermissionError') >= 0:
                return public.returnMsg(False, '拒绝访问，请检查是否被安全软件拦截!')
            return public.returnMsg(False, error)

    def get_ssh_intrusion(self,get):
        """
        @获取SSH爆破次数
        @param get:
        """
        result = {}

        result['error'] = self.get_err_count(4625,365 * 2)
        result['success'] = self.get_err_count(4624,365 * 2)
        return result


    def GetSshInfo(self,get):
        """
        取远程桌面信息
        """
        # ssh状态 1：关闭 0：开启
        port = public.get_ssh_port()
        keys = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE ,r"SYSTEM\CurrentControlSet\Control\Terminal Server")
        status,type = winreg.QueryValueEx(keys, "fDenyTSConnections")

        if int(status) == 1:
            status = False
        else:
            status = True
        ping = True
        if os.path.exists("data/ping.pl"): ping = False
        data = { "ping":ping,"status":status,"port":port }
        # data['error'] = self.get_ssh_intrusion(get)

        return data


    #改远程端口
    def SetSshPort(self,get):
        port = get.port
        if int(port) < 22 or int(port) > 65535: return public.returnMsg(False,'FIREWALL_SSH_PORT_ERR')
        ports = ['21','25','80','443','8080','888','8888']
        if port in ports: return public.returnMsg(False,'请不要使用常用程序的默认端口!')
        file = '/etc/ssh/sshd_config'
        conf = public.readFile(file)

        rep = r"#*Port\s+([0-9]+)\s*\n"
        conf = re.sub(rep, "Port "+port+"\n", conf)
        public.writeFile(file,conf)

        if self.__isFirewalld:
            public.ExecShell('firewall-cmd --permanent --zone=public --add-port='+port+'/tcp')
            public.ExecShell('setenforce 0')
            public.ExecShell('sed -i "s#SELINUX=enforcing#SELINUX=disabled#" /etc/selinux/config')
            public.ExecShell("systemctl restart sshd.service")
        elif self.__isUfw:
            public.ExecShell('ufw allow ' + port + '/tcp')
            public.ExecShell("service ssh restart")
        else:
            public.ExecShell('iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport '+port+' -j ACCEPT')
            public.ExecShell("/etc/init.d/sshd restart")

        self.FirewallReload()
        public.M('firewall').where("ps=? or ps=? or port=?",('SSH远程管理服务','SSH远程服务',port)).delete()
        public.M('firewall').add('port,ps,addtime',(port,'SSH远程服务',time.strftime('%Y-%m-%d %X',time.localtime())))
        public.WriteLog("TYPE_FIREWALL", "FIREWALL_SSH_PORT",(port,))
        return public.returnMsg(True,'EDIT_SUCCESS')



    def SetSshStatus(self,get):
        """
        @设置SSH状态
        """
        if int(get['status'])==1:
            msg = public.getMsg('FIREWALL_SSH_STOP')
            act = 'stop'
        else:
            msg = public.getMsg('FIREWALL_SSH_START')
            act = 'start'

        public.ExecShell("/etc/init.d/sshd "+act)
        public.ExecShell('service ssh ' + act)
        public.ExecShell("systemctl "+act+" sshd")
        public.ExecShell("systemctl "+act+" ssh")

        public.WriteLog("TYPE_FIREWALL", msg)
        return public.returnMsg(True,'SUCCESS')


