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 | |