Exemple #1
0
    def _setup(self):
        """
        尝试获取当前主机的主机名称、MAC地址、联网IP地址
        :return:
        """
        self.host_name = hostname()

        if LOCAL_MAC:  # 如果没有指定本机MAC,尝试自动获取
            self.mac = bytes().fromhex(LOCAL_MAC)
        else:
            self.mac = bytes().fromhex(mac())

        if LOCAL_IP:  # 如果没有指定本机IP,尝试自动获取
            self.ip = LOCAL_IP
        else:
            self.ip = ipaddress()

        if not self.host_name or not self.mac or not self.ip:
            raise DrCOMException(
                "[DrCOM.__init__]:Can not fetch NIC info, please raise a issues @ github"
            )

        self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM,
                                    socket.IPPROTO_UDP)
        self.socket.settimeout(3)
        try:
            self.socket.bind(("", 61440))
        except socket.error:
            raise DrCOMException(
                "[DrCOM.__init__]:Can not bind 61440 port,please retry after a while"
            )
Exemple #2
0
    def __initialise__(self):
        """
        尝试获取当前主机的主机名称、MAC地址、联网IP地址
        :return:
        """
        self.host_name = hostname()

        if LOCAL_MAC:  # 如果没有指定本机MAC,尝试自动获取
            self.mac = bytes().fromhex(LOCAL_MAC)
        else:
            self.mac = bytes().fromhex(mac())

        if LOCAL_IP:  # 如果没有指定本机IP,尝试自动获取
            self.ip = LOCAL_IP
        else:
            self.ip = ipaddress()

        if not self.host_name or not self.mac or not self.ip:
            Log(logging.ERROR, 10,
                "[DrCOM.__init__]:无法获取本机的NIC信息,请直接提交到该项目issues")
            raise DrCOMException("无法获取本机的NIC信息")

        self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM,
                                    socket.IPPROTO_UDP)
        self.socket.settimeout(3)
        try:
            self.socket.bind(("", 61440))
        except socket.error:
            Log(logging.ERROR, 10,
                "[DrCOM.__init__]:无法绑定61440端口,请检查是否有其他进程占据了该端口")
            raise DrCOMException("无法绑定本机61440端口")
Exemple #3
0
    def send_alive_pkg1(self):
        """
        发送类型一的心跳包
        :return:
        """
        pkg = b'\xff'
        pkg += md5(b'\x03\x01' + self.salt + self.pwd.encode('ascii'))  # MD5_A
        pkg += b'\x00' * 3
        pkg += self.auth_info
        pkg += struct.pack('!H', int(time.time()) % 0xFFFF)
        pkg += b'\x00' * 3

        data, address = self._send_package(pkg, (self.server_ip, 61440))

        if data[0] == 0x07:
            Log(
                logging.DEBUG, 0,
                "[DrCOM.send_alive_pkg1]:Successful sending heartbeat package type 1..."
            )
        else:
            # 当收到的数据包没法识别的时候
            exception = DrCOMException(
                "[DrCOM.send_alive_pkg1]:Receive unknown packages content...")
            exception.last_pkg = data
            raise exception
Exemple #4
0
    def _setup(self):
        """
        尝试获取当前主机的主机名称、MAC地址、联网IP地址
        :return:
        """
        self.host_name = hostname()

        if LOCAL_MAC:  # 如果没有指定本机MAC,尝试自动获取
            self.mac = bytes().fromhex(LOCAL_MAC)
        else:
            self.mac = bytes().fromhex(mac())

        if LOCAL_IP:  # 如果没有指定本机IP,尝试自动获取
            self.ip = LOCAL_IP
        else:
            self.ip = ipaddress()

        if not self.host_name or not self.mac or not self.ip:
            raise DrCOMException("请确保已经接入有线网")

        self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM,
                                    socket.IPPROTO_UDP)
        self.socket.settimeout(3)
        try:
            self.socket.bind(("", 61440))
        except (OSError, socket.error):
            raise DrCOMException("检测到重复启动客户端")
Exemple #5
0
    def login(self):
        """
        登录到目标服务器方法
        :return:
        """
        pkg = self._make_login_package()

        data, address = self._send_package(pkg, (self.server_ip, 61440))

        if data[0] == 0x04:
            self.auth_info = data[23:39]
            # 在这里设置当前为登录状态
            self.login_flag = True
            res = DrCOMResponse()
            res.msg = "已经连接上校园网络"
            return res

        elif data[0] == 0x05:
            if len(data) > 32:
                if data[32] == 0x31:
                    raise DrCOMException(
                        "Failure on login because the wrong username...")
                if data[32] == 0x33:
                    raise DrCOMException(
                        "Failure on login because the wrong password...")

        else:
            exception = DrCOMException("Receive unknown packages content...")
            exception.last_pkg = data
            raise exception
Exemple #6
0
    def prepare(self):
        """
        获取服务器IP和Salt
        :return:
        """
        self._setup()
        random_value = struct.pack(
            "<H",
            int(time.time() + random.randint(0xF, 0xFF)) % 0xFFFF)
        pkg = b'\x01\x02' + random_value + b'\x0a' + b'\x00' * 15

        # 尝试目前已知的学校认证服务器地址
        for _ in [(SERVER_IP, 61440), ("1.1.1.1", 61440),
                  ("202.1.1.1", 61440)]:
            data, address = self._send_package(pkg, _)

            # 未获取合理IP地址则进行下一个服务器地址尝试
            if data[0:4] == b'\x02\x02' + random_value:
                self.server_ip = address[0]
                self.salt = data[4:8]

                self.ready_flag = True
                res = DrCOMResponse()
                res.msg = "已做好接入有线网的准备"
                return res

        if not self.server_ip or not self.salt:
            exception = DrCOMException("无法检测到验证服务器")
            exception.last_pkg = pkg
            raise exception
Exemple #7
0
    def logout(self):
        """
        登出,仅测试了BISTU版本
        登出过程一共会有6个包,分3组,每组2个
        第一组同alive_pkg1的发送与确认
        第二组似乎是用于告知网关准备登出
        第三组会发送登出的详细信息包括用户名等
        """
        # 第一组 初步判断是为了判断当前网络是否联通
        # 发送的数据包的最后两个字节可能有验证功能
        self.send_alive_pkg1()

        # 第二组 登出准备
        # 与alive_pkg1的最后两个字节相同
        pkg = b'\x01\x03'
        pkg += b'\x00\x00'
        pkg += b'\x0a'
        pkg += b'\x00' * 15

        data, address = self._send_package(pkg, (self.server_ip, 61440))

        if data[0:2] != b'\x02\x03':
            Log(
                logging.ERROR, 70,
                "[DrCOM.login]:Receive unknown packages content: {}".format(
                    data))

        # 第三组
        pkg = self._make_logout_package()

        data, address = self._send_package(pkg, (self.server_ip, 61440))

        if data[0] == 0x04:
            self.login_flag = False
        else:
            Log(
                logging.ERROR, 71,
                "[DrCOM.logout]:Receive unknown packages content: {}".format(
                    data))

        if self.login_flag:
            exception = DrCOMException("Failure on logout to DrCOM...")
            exception.last_pkg = pkg
            raise exception
Exemple #8
0
    def login(self):
        """
        登录到目标服务器方法
        :return:
        """
        pkg = self._make_login_package()

        data, address = self._send_package(pkg, (self.server_ip, 61440))

        Log(logging.DEBUG, 0,
            "[DrCOM.login]:Receive PKG content: {}".format(data))
        if data[0] == 0x04:
            self.auth_info = data[23:39]
            # 在这里设置当前为登录状态并且也处于在线状态
            self.login_flag = True
            self.alive_flag = True
            Log(logging.INFO, 0,
                "[DrCOM.login]:Successfully login to DrCOM Server...")
        elif data[0] == 0x05:
            if len(data) > 32:
                if data[32] == 0x31:
                    Log(
                        logging.ERROR, 31,
                        "[DrCOM.login]:Failure on login because the wrong username..."
                    )
                if data[32] == 0x33:
                    Log(
                        logging.ERROR, 32,
                        "[DrCOM.login]:Failure on login because the wrong password..."
                    )
        else:
            Log(
                logging.ERROR, 30,
                "[DrCOM.login]:Receive unknown packages content: {}".format(
                    data))

        if not self.login_flag:
            exception = DrCOMException("Failure on login to DrCOM...")
            exception.last_pkg = pkg
            raise exception
Exemple #9
0
    def logout(self):
        """
        登出,仅测试了BISTU版本
        登出过程一共会有6个包,分3组,每组2个
        第一组同alive_pkg1的发送与确认
        第二组似乎是用于告知网关准备登出
        第三组会发送登出的详细信息包括用户名等
        """
        # 与alive_pkg1的最后两个字节相同
        pkg = b'\x01\x03'
        pkg += b'\x00\x00'
        pkg += b'\x0a'
        pkg += b'\x00' * 15

        data, address = self._send_package(pkg, (self.server_ip, 61440))

        if data[0:2] != b'\x02\x03':
            exception = DrCOMException(
                "[DrCOM.logout]:Receive unknown packages content...")
            exception.last_pkg = data
            raise exception

        # 第三组
        pkg = self._make_logout_package()

        data, address = self._send_package(pkg, (self.server_ip, 61440))

        if data[0] != 0x04:
            exception = DrCOMException(
                "[DrCOM.logout]:Receive unknown packages content...")
            exception.last_pkg = data
            raise exception

        self.login_flag = False
Exemple #10
0
    def send_alive_pkg2(self, num, key, cls):
        """
        发送类型二的心跳包
        :return:
        """
        pkg = self._make_alive_package(num=num, key=key, cls=cls)

        data, address = self._send_package(pkg, (self.server_ip, 61440))

        if data[0] == 0x07:
            Log(
                logging.DEBUG, 0,
                "[DrCOM.send_alive_pkg2]:Successful sending heartbeat package 2[{}]..."
                .format(cls))
            response = data[16:20]
            return response
        else:
            # 当收到的数据包没法识别的时候
            exception = DrCOMException(
                "[DrCOM.send_alive_pkg2]:Receive unknown packages content...")
            exception.last_pkg = data
            raise exception
Exemple #11
0
    def prepare(self):
        """
        获取服务器IP和Salt
        :return:
        """
        random_value = struct.pack(
            "<H",
            int(time.time() + random.randint(0xF, 0xFF)) % 0xFFFF)
        pkg = b'\x01\x02' + random_value + b'\x0a' + b'\x00' * 15

        # 尝试目前已知的学校认证服务器地址
        for _ in [(SERVER_IP, 61440), ("1.1.1.1", 61440),
                  ("202.1.1.1", 61440)]:
            data, address = self._send_package(pkg, _)

            # 未获取合理IP地址则进行下一个服务器地址尝试
            Log(logging.DEBUG, 0,
                "[DrCOM.prepare]:Receive PKG content: {}".format(data))
            if data[0:4] == b'\x02\x02' + random_value:
                self.server_ip = address[0]
                self.salt = data[4:8]
                Log(
                    logging.DEBUG, 0,
                    "[DrCOM.prepare]:Server IP: {}, Salt: {}".format(
                        self.server_ip, self.salt))
                return
            else:
                Log(
                    logging.WARNING, 20,
                    "[DrCOM.prepare]:Receive unknown packages content: {}".
                    format(data))

        if not self.server_ip or not self.salt:
            exception = DrCOMException(
                "[DrCOM.prepare]:Cannot find any available server...")
            exception.last_pkg = pkg
            raise exception