| 201 | | { AUTH_LOGON_CHALLENGE, STATUS_CONNECTED, &AuthSocket::_HandleLogonChallenge}, |
| 202 | | { AUTH_LOGON_PROOF, STATUS_CONNECTED, &AuthSocket::_HandleLogonProof }, |
| 203 | | { REALM_LIST, STATUS_AUTHED, &AuthSocket::_HandleRealmList }, |
| 204 | | { XFER_ACCEPT, STATUS_CONNECTED, &AuthSocket::_HandleXferAccept }, |
| 205 | | { XFER_RESUME, STATUS_CONNECTED, &AuthSocket::_HandleXferResume }, |
| 206 | | { XFER_CANCEL, STATUS_CONNECTED, &AuthSocket::_HandleXferCancel } |
| | 201 | { AUTH_LOGON_CHALLENGE, STATUS_CONNECTED, &AuthSocket::_HandleLogonChallenge }, |
| | 202 | { AUTH_LOGON_PROOF, STATUS_CONNECTED, &AuthSocket::_HandleLogonProof }, |
| | 203 | { AUTH_RECONNECT_CHALLENGE, STATUS_CONNECTED, &AuthSocket::_HandleReconnectChallenge}, |
| | 204 | { AUTH_RECONNECT_PROOF, STATUS_CONNECTED, &AuthSocket::_HandleReconnectProof }, |
| | 205 | { REALM_LIST, STATUS_AUTHED, &AuthSocket::_HandleRealmList }, |
| | 206 | { XFER_ACCEPT, STATUS_CONNECTED, &AuthSocket::_HandleXferAccept }, |
| | 207 | { XFER_RESUME, STATUS_CONNECTED, &AuthSocket::_HandleXferResume }, |
| | 208 | { XFER_CANCEL, STATUS_CONNECTED, &AuthSocket::_HandleXferCancel } |
| | 714 | /// Reconnect Challenge command handler |
| | 715 | bool AuthSocket::_HandleReconnectChallenge() |
| | 716 | { |
| | 717 | DEBUG_LOG("Entering _HandleReconnectChallenge"); |
| | 718 | if (ibuf.GetLength() < sizeof(sAuthLogonChallenge_C)) |
| | 719 | return false; |
| | 720 | |
| | 721 | ///- Read the first 4 bytes (header) to get the length of the remaining of the packet |
| | 722 | std::vector<uint8> buf; |
| | 723 | buf.resize(4); |
| | 724 | |
| | 725 | ibuf.Read((char *)&buf[0], 4); |
| | 726 | |
| | 727 | EndianConvert(*((uint16*)(buf[0]))); |
| | 728 | uint16 remaining = ((sAuthLogonChallenge_C *)&buf[0])->size; |
| | 729 | DEBUG_LOG("[ReconnectChallenge] got header, body is %#04x bytes", remaining); |
| | 730 | |
| | 731 | if ((remaining < sizeof(sAuthLogonChallenge_C) - buf.size()) || (ibuf.GetLength() < remaining)) |
| | 732 | return false; |
| | 733 | |
| | 734 | //No big fear of memory outage (size is int16, i.e. < 65536) |
| | 735 | buf.resize(remaining + buf.size() + 1); |
| | 736 | buf[buf.size() - 1] = 0; |
| | 737 | sAuthLogonChallenge_C *ch = (sAuthLogonChallenge_C*)&buf[0]; |
| | 738 | |
| | 739 | ///- Read the remaining of the packet |
| | 740 | ibuf.Read((char *)&buf[4], remaining); |
| | 741 | DEBUG_LOG("[ReconnectChallenge] got full packet, %#04x bytes", ch->size); |
| | 742 | DEBUG_LOG("[ReconnectChallenge] name(%d): '%s'", ch->I_len, ch->I); |
| | 743 | |
| | 744 | _login = (const char*)ch->I; |
| | 745 | _safelogin = _login; |
| | 746 | |
| | 747 | QueryResult *result = dbRealmServer.PQuery ("SELECT sessionkey FROM account WHERE username = '%s'", _safelogin.c_str ()); |
| | 748 | |
| | 749 | // Stop if the account is not found |
| | 750 | if (!result) |
| | 751 | { |
| | 752 | sLog.outError("[ERROR] user %s tried to login and we cannot find his session key in the database.", _login.c_str()); |
| | 753 | SetCloseAndDelete(); |
| | 754 | return false; |
| | 755 | } |
| | 756 | |
| | 757 | Field* fields = result->Fetch (); |
| | 758 | K.SetHexStr (fields[0].GetString ()); |
| | 759 | delete result; |
| | 760 | |
| | 761 | ///- Sending response |
| | 762 | ByteBuffer pkt; |
| | 763 | pkt << (uint8) AUTH_RECONNECT_CHALLENGE; |
| | 764 | pkt << (uint8) 0x00; |
| | 765 | _reconnectProof.SetRand(16*8); |
| | 766 | pkt.append(_reconnectProof.AsByteBuffer()); // 16 bytes random |
| | 767 | pkt << (uint64) 0x00 << (uint64) 0x00; // 16 bytes zeros |
| | 768 | SendBuf((char const*)pkt.contents(), pkt.size()); |
| | 769 | return true; |
| | 770 | } |
| | 771 | |
| | 772 | /// Reconnect Proof command handler |
| | 773 | bool AuthSocket::_HandleReconnectProof() |
| | 774 | { |
| | 775 | DEBUG_LOG("Entering _HandleReconnectProof"); |
| | 776 | ///- Read the packet |
| | 777 | if (ibuf.GetLength() < sizeof(sAuthReconnectProof_C)) |
| | 778 | return false; |
| | 779 | if (_login.empty() || !_reconnectProof.GetNumBytes() || !K.GetNumBytes()) |
| | 780 | return false; |
| | 781 | sAuthReconnectProof_C lp; |
| | 782 | ibuf.Read((char *)&lp, sizeof(sAuthReconnectProof_C)); |
| | 783 | |
| | 784 | BigNumber t1; |
| | 785 | t1.SetBinary(lp.R1, 16); |
| | 786 | |
| | 787 | Sha1Hash sha; |
| | 788 | sha.Initialize(); |
| | 789 | sha.UpdateData(_login); |
| | 790 | sha.UpdateBigNumbers(&t1, &_reconnectProof, &K, NULL); |
| | 791 | sha.Finalize(); |
| | 792 | |
| | 793 | if (!memcmp(sha.GetDigest(), lp.R2, SHA_DIGEST_LENGTH)) |
| | 794 | { |
| | 795 | ///- Sending response |
| | 796 | ByteBuffer pkt; |
| | 797 | pkt << (uint8) AUTH_RECONNECT_PROOF; |
| | 798 | pkt << (uint8) 0x00; |
| | 799 | pkt << (uint16) 0x00; // 2 bytes zeros |
| | 800 | SendBuf((char const*)pkt.contents(), pkt.size()); |
| | 801 | |
| | 802 | ///- Set _authed to true! |
| | 803 | _authed = true; |
| | 804 | |
| | 805 | return true; |
| | 806 | } |
| | 807 | else |
| | 808 | { |
| | 809 | sLog.outError("[ERROR] user %s tried to login, but session invalid.", _login.c_str()); |
| | 810 | SetCloseAndDelete(); |
| | 811 | return false; |
| | 812 | } |
| | 813 | } |
| | 814 | |