Esempio n. 1
0
    def _handle_start_versioning(self, pid, pak):
        pak.get_dword()
        self.product = pak.get_dword(True)
        if self.product not in products:
            self.disconnect("Unsupported product (%s)" % self.product)
            return

        # Send SID_CLIENTID
        pak = buffer.DataBuffer()
        pak.insert_dword(0)
        pak.insert_dword(0)
        pak.insert_dword(0)
        pak.insert_dword(0)
        self.send(SID_CLIENTID, pak)

        # Send SID_LOGONCHALLENGEEX2
        pak = buffer.DataBuffer()
        pak.insert_dword(0)  # UDP Value
        pak.insert_dword(self._server_token)  # Server token
        self.send(SID_LOGONCHALLENGEEX, pak)

        pak = buffer.DataBuffer()
        if self.parent.server.do_version_check:
            # Send SID_STARTVERSIONING
            pi = check_revision_data
            pak.insert_long(pi[0])  # MPQ filetime
            pak.insert_string(pi[1])  # MPQ filename
            pak.insert_string(pi[2])  # Value string
            self.send(SID_STARTVERSIONING, pak)
        else:
            # Skip the version check
            pak.insert_dword(0x02)  # Result: success
            pak.insert_string('')
            self.send(SID_REPORTVERSION, pak)
Esempio n. 2
0
    def send_logon_response(self, status=0, proof=None):
        # Status can be a number (0 = success, 2 = fail) or custom error message string.
        is_str = isinstance(status, str)

        pak = buffer.DataBuffer()
        if self.logon_type == -1:
            # Legacy login
            # The result for this packet is flipped. 0 = failure, 1 = success
            pak.insert_dword(0x01 if status == 0x00 else 0x00)
            self.send(SID_LOGONRESPONSE, pak)
        if self.logon_type == 0:
            # Old login (OLS)
            pak.insert_dword(0x06 if is_str else status)
            if is_str:
                pak.insert_string(status)
            self.send(SID_LOGONRESPONSE2, pak)
        elif self.logon_type in [1, 2]:
            # New login (NLS)
            pak.insert_dword(0x0F if is_str else status)
            pak.insert_raw(proof or (b'\0' * 20))
            pak.insert_string(status if is_str else '')
            self.send(SID_AUTH_ACCOUNTLOGONPROOF, pak)

        if status == 0x00:
            self.parent.print(
                "BNCS login complete - authenticated to chat API")
            self.logged_on = True
Esempio n. 3
0
    def _handle_cd_key2(self, pid, pak):
        pak.get_raw(20)  # Key properties and server token
        self._client_token = pak.get_dword()

        pak = buffer.DataBuffer()
        pak.insert_dword(0x01)  # Result: OK
        pak.insert_string('')
        self.send(SID_CDKEY2, pak)
Esempio n. 4
0
    def _handle_auth_check(self, pid, pak):
        self._client_token = pak.get_dword()

        # Send auth check response
        pak = buffer.DataBuffer()
        pak.insert_dword(0x00)  # Success
        pak.insert_string('')
        self.send(SID_AUTH_CHECK, pak)
Esempio n. 5
0
 def send_chat(self, eid, username, text, flags=0, ping=0):
     pak = buffer.DataBuffer()
     pak.insert_dword(eid)
     pak.insert_dword(flags)
     pak.insert_dword(ping)
     pak.insert_dword(0)  # IP Address
     pak.insert_dword(0xbaadf00d)  # Account number
     pak.insert_dword(0xbaadf00d)  # Registration authority
     pak.insert_string(username)
     pak.insert_string(text)
     self.send(SID_CHATEVENT, pak)
Esempio n. 6
0
    def _handle_report_version(self, pid, pak):
        pak.get_dword()
        self.product = pak.get_dword(True)
        if self.product not in products:
            self.disconnect("Unsupported product (%s)" % self.product)
            return

        # Send version response
        pak = buffer.DataBuffer()
        pak.insert_dword(0x02)  # Result: success
        pak.insert_string('')  # Patch path
        self.send(SID_REPORTVERSION, pak)
Esempio n. 7
0
    def _handle_get_filetime(self, pid, pak):
        req_id = pak.get_dword()
        unknown = pak.get_dword()
        filename = pak.get_string()

        # No files ever exist.
        pak = buffer.DataBuffer()
        pak.insert_dword(req_id)
        pak.insert_dword(unknown)
        pak.insert_long(0)
        pak.insert_string(filename)
        self.send(SID_GETFILETIME, pak)
Esempio n. 8
0
    def enter_chat(self, username, stats, account=None):
        self.username = username
        if account is None:
            account = username
            if username.startswith("[B]"):
                account = username[3:]

        pak = buffer.DataBuffer()
        pak.insert_string(username)
        pak.insert_string(stats)
        pak.insert_string(account)
        self.send(SID_ENTERCHAT, pak)
Esempio n. 9
0
    def _handle_auth_info(self, pid, pak):
        if self.product:
            self.disconnect("Sent repeat client auth.")
            return

        pak.get_raw(8)  # First 8 bytes not needed
        self.product = pak.get_dword(True)
        if self.product not in products:
            self.disconnect("Unsupported product (%s)" % self.product)
            return

        # Send ping packet
        pak = buffer.DataBuffer()
        pak.insert_dword(random.getrandbits(32))
        self.send(SID_PING, pak)

        pak = buffer.DataBuffer()
        if self.parent.server.do_version_check:
            # Send version check request
            pi = check_revision_data
            pak.insert_dword(self.logon_type)  # Logon type
            pak.insert_dword(self._server_token)  # Server token
            pak.insert_dword(0)  # UDP value
            pak.insert_long(pi[0])  # CRev archive filetime
            pak.insert_string(pi[1])  # CRev archive filename
            pak.insert_string(pi[2])  # CRev formula

            if self.product in ["WAR3", "W3XP"]:
                pak.insert_raw(b'\0' * 128)  # W3 server signature

            self.send(SID_AUTH_INFO, pak)
        else:
            # Skip sending the request and immediately send the result.
            pak.insert_dword(0x00)  # Success
            pak.insert_string('')
            self.send(SID_AUTH_CHECK, pak)
Esempio n. 10
0
    def _handle_auth_accountlogon(self, pid, pak):
        if self.logged_on:
            self.disconnect("Attempt to login again")
            return

        pak.get_raw(32)  # Client key
        self.logon_type = 2

        # Start the CAPI login process
        self.parent.capi.authenticate(pak.get_string())

        # Send login response
        pak = buffer.DataBuffer()
        pak.insert_dword(0)  # Logon accepted
        pak.insert_raw(b'\0' * 32)  # Account salt
        pak.insert_raw(b'\0' * 32)  # Server key
        self.send(SID_AUTH_ACCOUNTLOGON, pak)
Esempio n. 11
0
    def send(self, pid, payload=None):
        if not self.connected:
            return

        pak = buffer.DataBuffer()
        pak.insert_byte(0xFF)
        pak.insert_byte(pid)

        if payload:
            pak.insert_word(len(payload) + 4)
            pak.insert_raw(payload.data if isinstance(payload, buffer.
                                                      DataBuffer) else payload)
        else:
            pak.insert_word(4)

        self.socket.sendall(pak.data)
        self.parent.debug("Sent BNCS packet 0x%02x (len: %i)" %
                          (pid, len(pak)))
Esempio n. 12
0
 def _handle_get_icon_data(self, pid, pak):
     # Packet has no contents
     pak = buffer.DataBuffer()
     pak.insert_long(0)
     pak.insert_string('icons.bni')
     self.send(SID_GETICONDATA, pak)
Esempio n. 13
0
 def _handle_query_realms2(self, pid, pak):
     pak = buffer.DataBuffer()
     pak.insert_dword(0)
     pak.insert_dword(0)
     self.send(SID_QUERYREALMS2, pak)