diff options
Diffstat (limited to 'src')
6 files changed, 361 insertions, 26 deletions
diff --git a/src/server/authserver/Server/BattlenetPackets.cpp b/src/server/authserver/Server/BattlenetPackets.cpp index 99e3fa10b14..471a6128c4c 100644 --- a/src/server/authserver/Server/BattlenetPackets.cpp +++ b/src/server/authserver/Server/BattlenetPackets.cpp @@ -57,9 +57,6 @@ void Battlenet::AuthChallenge::Read() if (_stream.Read<uint32>(1)) Login = _stream.ReadString(9, 3); - - if (GetHeader().Opcode == CMSG_AUTH_CHALLENGE_NEW) - _stream.FinishReading(); } std::string Battlenet::AuthChallenge::ToString() const @@ -75,6 +72,40 @@ std::string Battlenet::AuthChallenge::ToString() const return stream.str(); } +void Battlenet::AuthResumeInfo::Read() +{ + Program = _stream.ReadFourCC(); + Platform = _stream.ReadFourCC(); + Locale = _stream.ReadFourCC(); + + Components.resize(_stream.Read<uint32>(6)); + for (size_t i = 0; i < Components.size(); ++i) + { + Component& component = Components[i]; + component.Program = _stream.ReadFourCC(); + component.Platform = _stream.ReadFourCC(); + component.Build = _stream.Read<uint32>(32); + } + + Login = _stream.ReadString(9, 3); + Region = _stream.Read<uint8>(8); + GameAccountName = _stream.ReadString(5, 1); +} + +std::string Battlenet::AuthResumeInfo::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::AuthReconnect Program: " << Program << ", Platform: " << Platform << ", Locale: " << Locale; + for (Component const& component : Components) + stream << std::endl << "Battlenet::Component Program: " << component.Program << ", Platform: " << component.Platform << ", Build: " << component.Build; + + stream << std::endl << "Battlenet::AuthReconnect Login: " << Login; + stream << std::endl << "Battlenet::AuthReconnect Region: " << uint32(Region); + stream << std::endl << "Battlenet::AuthReconnect GameAccountName: " << GameAccountName; + + return stream.str(); +} + Battlenet::ProofRequest::~ProofRequest() { for (size_t i = 0; i < Modules.size(); ++i) @@ -134,6 +165,12 @@ std::string Battlenet::ProofResponse::ToString() const return stream.str(); } +Battlenet::AuthComplete::~AuthComplete() +{ + for (ModuleInfo* m : Modules) + delete m; +} + void Battlenet::AuthComplete::Write() { _stream.Write(Result != 0, 1); @@ -142,12 +179,12 @@ void Battlenet::AuthComplete::Write() _stream.Write(Modules.size(), 3); for (size_t i = 0; i < Modules.size(); ++i) { - ModuleInfo& info = Modules[i]; - _stream.WriteBytes(info.Type.c_str(), 4); - _stream.WriteFourCC(info.Region); - _stream.WriteBytes(info.ModuleId, 32); - _stream.Write(info.DataSize, 10); - _stream.WriteBytes(info.Data, info.DataSize); + ModuleInfo* info = Modules[i]; + _stream.WriteBytes(info->Type.c_str(), 4); + _stream.WriteFourCC(info->Region); + _stream.WriteBytes(info->ModuleId, 32); + _stream.Write(info->DataSize, 10); + _stream.WriteBytes(info->Data, info->DataSize); } _stream.Write(PingTimeout + std::numeric_limits<int32>::min(), 32); @@ -168,10 +205,10 @@ void Battlenet::AuthComplete::Write() _stream.Write(GameAccountId, 32); _stream.Write(2, 8); _stream.Write(0, 64); - _stream.Write(2, 8); + _stream.Write(2, 8); _stream.WriteString(GameAccountName, 5, -1); - _stream.Write(AccountFlags, 64); + _stream.Write(GameAccountFlags, 64); _stream.Write(0, 32); } @@ -180,12 +217,10 @@ void Battlenet::AuthComplete::Write() _stream.Write(!Modules.empty(), 1); if (!Modules.empty()) { - ModuleInfo& info = Modules[0]; - _stream.WriteBytes(info.Type.c_str(), 4); - _stream.WriteFourCC(info.Region); - _stream.WriteBytes(info.ModuleId, 32); - _stream.Write(info.DataSize, 10); - _stream.WriteBytes(info.Data, info.DataSize); + ModuleInfo* info = Modules[0]; + _stream.WriteBytes(info->Type.c_str(), 4); + _stream.WriteFourCC(info->Region); + _stream.WriteBytes(info->ModuleId, 32); } _stream.Write(ErrorType, 2); @@ -199,7 +234,15 @@ void Battlenet::AuthComplete::Write() std::string Battlenet::AuthComplete::ToString() const { - return "Battlenet::AuthComplete"; + std::ostringstream stream; + stream << "Battlenet::AuthComplete AuthResult " << Result << " PingTimeout " << PingTimeout << " Threshold " << Threshold << " Rate " << Rate + << " FirstName " << FirstName << " LastName " << LastName << " GameAccountId " << GameAccountId << " GameAccountName " << GameAccountName + << " GameAccountFlags " << GameAccountFlags << " Modules " << Modules.size(); + + for (ModuleInfo const* module : Modules) + stream << std::endl << "Battlenet::ModuleInfo Locale " << module->Region.c_str() << ", ModuleId " << ByteArrayToHexStr(module->ModuleId, 32) << ", DataSize " << module->DataSize << ", Data " << ByteArrayToHexStr(module->Data, module->DataSize); + + return stream.str(); } void Battlenet::AuthComplete::SetAuthResult(AuthResult result) @@ -208,6 +251,76 @@ void Battlenet::AuthComplete::SetAuthResult(AuthResult result) Result = result; } +Battlenet::AuthResume::~AuthResume() +{ + for (ModuleInfo* m : Modules) + delete m; +} + +void Battlenet::AuthResume::Write() +{ + _stream.Write(Result != 0, 1); + if (Result == 0) + { + _stream.Write(Modules.size(), 3); + for (size_t i = 0; i < Modules.size(); ++i) + { + ModuleInfo* info = Modules[i]; + _stream.WriteBytes(info->Type.c_str(), 4); + _stream.WriteFourCC(info->Region); + _stream.WriteBytes(info->ModuleId, 32); + _stream.Write(info->DataSize, 10); + _stream.WriteBytes(info->Data, info->DataSize); + } + + _stream.Write(PingTimeout + std::numeric_limits<int32>::min(), 32); + _stream.Write(1, 1); + // if written == 1 + { + _stream.Write(1, 1); + // if written == 1 + { + _stream.Write(Threshold, 32); + _stream.Write(Rate, 32); + } + } + } + else + { + _stream.Write(!Modules.empty(), 1); + if (!Modules.empty()) + { + ModuleInfo* info = Modules[0]; + _stream.WriteBytes(info->Type.c_str(), 4); + _stream.WriteFourCC(info->Region); + _stream.WriteBytes(info->ModuleId, 32); + } + + _stream.Write(ErrorType, 2); + if (ErrorType == 1) + { + _stream.Write(Result, 16); + _stream.Write(0x80000000, 32); + } + } +} + +std::string Battlenet::AuthResume::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::AuthResume AuthResult " << Result << " PingTimeout " << PingTimeout << " Threshold " << Threshold << " Rate " << Rate << " Modules " << Modules.size(); + for (ModuleInfo const* module : Modules) + stream << std::endl << "Battlenet::ModuleInfo Locale " << module->Region.c_str() << ", ModuleId " << ByteArrayToHexStr(module->ModuleId, 32) << ", DataSize " << module->DataSize << ", Data " << ByteArrayToHexStr(module->Data, module->DataSize); + + return stream.str(); +} + +void Battlenet::AuthResume::SetAuthResult(AuthResult result) +{ + ErrorType = result != AUTH_OK ? 1 : 0; + Result = result; +} + Battlenet::RealmCharacterCounts::~RealmCharacterCounts() { for (ServerPacket* realmData : RealmData) diff --git a/src/server/authserver/Server/BattlenetPackets.h b/src/server/authserver/Server/BattlenetPackets.h index 9acc707bd10..d790760ea24 100644 --- a/src/server/authserver/Server/BattlenetPackets.h +++ b/src/server/authserver/Server/BattlenetPackets.h @@ -41,9 +41,9 @@ namespace Battlenet CMSG_AUTH_CHALLENGE = 0x0, CMSG_AUTH_RECONNECT = 0x1, CMSG_AUTH_PROOF_RESPONSE = 0x2, - CMSG_AUTH_CHALLENGE_NEW = 0x9, // MoP SMSG_AUTH_COMPLETE = 0x0, + SMSG_AUTH_RESUME = 0x1, SMSG_AUTH_PROOF_REQUEST = 0x2 }; @@ -51,6 +51,7 @@ namespace Battlenet { CMSG_PING = 0x0, CMSG_ENABLE_ENCRYPTION = 0x5, + CMSG_DISCONNECT = 0x6, CMSG_INVALID_PACKET = 0x9, SMSG_PONG = 0x0 @@ -141,7 +142,7 @@ namespace Battlenet public: AuthChallenge(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) { - ASSERT(header.Channel == AUTHENTICATION && (header.Opcode == CMSG_AUTH_CHALLENGE || header.Opcode == CMSG_AUTH_CHALLENGE_NEW) && "Invalid packet header for AuthChallenge"); + ASSERT(header == PacketHeader(CMSG_AUTH_CHALLENGE, AUTHENTICATION) && "Invalid packet header for AuthChallenge"); } void Read() override; @@ -154,6 +155,26 @@ namespace Battlenet std::string Login; }; + class AuthResumeInfo final : public ClientPacket + { + public: + AuthResumeInfo(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_AUTH_RECONNECT, AUTHENTICATION) && "Invalid packet header for AuthResumeInfo"); + } + + void Read() override; + std::string ToString() const override; + + std::string Program; + std::string Platform; + std::string Locale; + std::vector<Component> Components; + std::string Login; + uint8 Region; + std::string GameAccountName; + }; + class ProofRequest final : public ServerPacket { public: @@ -191,10 +212,12 @@ namespace Battlenet { } + ~AuthComplete(); + void Write() override; std::string ToString() const override; - std::vector<ModuleInfo> Modules; + std::vector<ModuleInfo*> Modules; void SetAuthResult(AuthResult result); AuthResult Result; uint32 ErrorType; @@ -206,7 +229,30 @@ namespace Battlenet std::string LastName; uint32 GameAccountId; std::string GameAccountName; - uint64 AccountFlags; + uint64 GameAccountFlags; + }; + + class AuthResume final : public ServerPacket + { + public: + AuthResume() : ServerPacket(PacketHeader(SMSG_AUTH_RESUME, AUTHENTICATION)), + Result(AUTH_OK), ErrorType(0), PingTimeout(120000), Threshold(25000000), Rate(1000) + { + } + + ~AuthResume(); + + void Write() override; + std::string ToString() const override; + + std::vector<ModuleInfo*> Modules; + void SetAuthResult(AuthResult result); + AuthResult Result; + uint32 ErrorType; + + int32 PingTimeout; + uint32 Threshold; + uint32 Rate; }; class Pong final : public ServerPacket diff --git a/src/server/authserver/Server/BattlenetSocket.cpp b/src/server/authserver/Server/BattlenetSocket.cpp index 258ae371075..119fccd9abb 100644 --- a/src/server/authserver/Server/BattlenetSocket.cpp +++ b/src/server/authserver/Server/BattlenetSocket.cpp @@ -33,11 +33,12 @@ std::map<Battlenet::PacketHeader, Battlenet::Socket::PacketHandler> InitHandlers std::map<Battlenet::PacketHeader, Battlenet::Socket::PacketHandler> handlers; handlers[Battlenet::PacketHeader(Battlenet::CMSG_AUTH_CHALLENGE, Battlenet::AUTHENTICATION)] = &Battlenet::Socket::HandleAuthChallenge; - handlers[Battlenet::PacketHeader(Battlenet::CMSG_AUTH_CHALLENGE_NEW, Battlenet::AUTHENTICATION)] = &Battlenet::Socket::HandleAuthChallenge; + handlers[Battlenet::PacketHeader(Battlenet::CMSG_AUTH_RECONNECT, Battlenet::AUTHENTICATION)] = &Battlenet::Socket::HandleAuthReconnect; handlers[Battlenet::PacketHeader(Battlenet::CMSG_AUTH_PROOF_RESPONSE, Battlenet::AUTHENTICATION)] = &Battlenet::Socket::HandleAuthProofResponse; handlers[Battlenet::PacketHeader(Battlenet::CMSG_PING, Battlenet::CREEP)] = &Battlenet::Socket::HandlePing; handlers[Battlenet::PacketHeader(Battlenet::CMSG_ENABLE_ENCRYPTION, Battlenet::CREEP)] = &Battlenet::Socket::HandleEnableEncryption; + handlers[Battlenet::PacketHeader(Battlenet::CMSG_DISCONNECT, Battlenet::CREEP)] = &Battlenet::Socket::HandleDisconnect; handlers[Battlenet::PacketHeader(Battlenet::CMSG_REALM_UPDATE_SUBSCRIBE, Battlenet::WOW)] = &Battlenet::Socket::HandleRealmUpdateSubscribe; handlers[Battlenet::PacketHeader(Battlenet::CMSG_JOIN_REQUEST, Battlenet::WOW)] = &Battlenet::Socket::HandleRealmJoinRequest; @@ -54,10 +55,12 @@ Battlenet::Socket::ModuleHandler const Battlenet::Socket::ModuleHandlers[MODULE_ &Battlenet::Socket::UnhandledModule, &Battlenet::Socket::HandleSelectGameAccountModule, &Battlenet::Socket::HandleRiskFingerprintModule, + &Battlenet::Socket::HandleResumeModule, }; Battlenet::Socket::Socket(RealmSocket& socket) : _socket(socket), _accountId(0), _accountName(), _locale(), - _os(), _build(0), _gameAccountId(0), _accountSecurityLevel(SEC_PLAYER) + _os(), _build(0), _gameAccountId(0), _accountSecurityLevel(SEC_PLAYER), I(), s(), v(), b(), B(), K(), + _reconnectProof(), _crypt(), _authed(false) { static uint8 const N_Bytes[] = { @@ -304,6 +307,61 @@ bool Battlenet::Socket::HandleAuthChallenge(PacketHeader& header, BitStream& pac return true; } +bool Battlenet::Socket::HandleAuthReconnect(PacketHeader& header, BitStream& packet) +{ + AuthResumeInfo reconnect(header, packet); + reconnect.Read(); + + TC_LOG_DEBUG("server.battlenet", "%s", reconnect.ToString().c_str()); + + _accountName = reconnect.Login; + _locale = reconnect.Locale; + _os = reconnect.Platform; + auto baseComponent = std::find_if(reconnect.Components.begin(), reconnect.Components.end(), [](Component const& c) { return c.Program == "base"; }); + if (baseComponent != reconnect.Components.end()) + _build = baseComponent->Build; + + Utf8ToUpperOnlyLatin(_accountName); + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_RECONNECT_INFO); + stmt->setString(0, _accountName); + stmt->setString(1, reconnect.GameAccountName.c_str()); + PreparedQueryResult result = LoginDatabase.Query(stmt); + if (!result) + { + AuthResume resume; + resume.SetAuthResult(AUTH_UNKNOWN_ACCOUNT); + Send(resume); + return false; + } + + Field* fields = result->Fetch(); + + _accountId = fields[0].GetUInt32(); + K.SetHexStr(fields[1].GetString().c_str()); + _gameAccountId = fields[2].GetUInt32(); + + ModuleInfo* thumbprint = sBattlenetMgr->CreateModule(_os, "Thumbprint"); + ModuleInfo* resume = sBattlenetMgr->CreateModule(_os, "Resume"); + BitStream resumeData; + uint8 state = 0; + _reconnectProof.SetRand(16 * 8); + + resumeData.WriteBytes(&state, 1); + resumeData.WriteBytes(_reconnectProof.AsByteArray().get(), 16); + + resume->DataSize = resumeData.GetSize(); + resume->Data = new uint8[resume->DataSize]; + memcpy(resume->Data, resumeData.GetBuffer(), resume->DataSize); + + _modulesWaitingForData.push(MODULE_RESUME); + + ProofRequest request; + request.Modules.push_back(thumbprint); + request.Modules.push_back(resume); + Send(request); + return true; +} + bool Battlenet::Socket::HandleAuthProofResponse(PacketHeader& header, BitStream& packet) { ProofResponse proof(header, packet); @@ -350,6 +408,15 @@ bool Battlenet::Socket::HandleEnableEncryption(PacketHeader& /*header*/, BitStre return true; } +bool Battlenet::Socket::HandleDisconnect(PacketHeader& /*header*/, BitStream& /*packet*/) +{ + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_SESSION_KEY); + stmt->setString(0, ""); + stmt->setUInt32(1, _accountId); + LoginDatabase.Execute(stmt); + return true; +} + bool Battlenet::Socket::HandleRealmUpdateSubscribe(PacketHeader& /*header*/, BitStream& /*packet*/) { sRealmList->UpdateIfNeed(); @@ -484,6 +551,13 @@ void Battlenet::Socket::OnRead() if (packet.Read<bool>(1)) header.Channel = packet.Read<int32>(4); + if (header.Channel != AUTHENTICATION && !_authed) + { + TC_LOG_DEBUG("server.battlenet", "Battlenet::Socket::OnRead Received not allowed packet %s", header.ToString().c_str()); + _socket.shutdown(); + return; + } + TC_LOG_TRACE("server.battlenet", "Battlenet::Socket::OnRead %s", header.ToString().c_str()); std::map<PacketHeader, PacketHandler>::const_iterator itr = Handlers.find(header); if (itr != Handlers.end()) @@ -796,14 +870,25 @@ bool Battlenet::Socket::HandleRiskFingerprintModule(BitStream* dataStream, Serve complete->GameAccountId = _gameAccountId; complete->GameAccountName = str.str(); - complete->AccountFlags = 0x800000; // 0x1 IsGMAccount, 0x8 IsTrialAccount, 0x800000 IsProPassAccount + complete->GameAccountFlags = 1; + + SQLTransaction trans = LoginDatabase.BeginTransaction(); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_LAST_LOGIN_INFO); stmt->setString(0, _socket.getRemoteAddress()); stmt->setUInt8(1, GetLocaleByName(_locale)); stmt->setString(2, _os); stmt->setUInt32(3, _accountId); - LoginDatabase.Execute(stmt); + trans->Append(stmt); + + stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_SESSION_KEY); + stmt->setString(0, K.AsHexStr()); + stmt->setUInt32(1, _accountId); + trans->Append(stmt); + + LoginDatabase.CommitTransaction(trans); + + _authed = true; } else complete->SetAuthResult(AUTH_BAD_VERSION_HASH); @@ -812,6 +897,86 @@ bool Battlenet::Socket::HandleRiskFingerprintModule(BitStream* dataStream, Serve return true; } +bool Battlenet::Socket::HandleResumeModule(BitStream* dataStream, ServerPacket** response) +{ + if (dataStream->Read<uint8>(8) != 1) + { + AuthResume* complete = new AuthResume(); + complete->SetAuthResult(AUTH_CORRUPTED_MODULE); + ReplaceResponse(response, complete); + return false; + } + + static uint8 const ResumeClient = 0; + static uint8 const ResumeServer = 1; + + ACE_Auto_Array_Ptr<uint8>&& clientChallenge = dataStream->ReadBytes(16); + ACE_Auto_Array_Ptr<uint8>&& clientProof = dataStream->ReadBytes(32); + ACE_Auto_Array_Ptr<uint8>&& serverChallenge = _reconnectProof.AsByteArray(); + ACE_Auto_Array_Ptr<uint8>&& sessionKey = K.AsByteArray(); + + HmacHash clientPart(64, sessionKey.get(), EVP_sha256(), SHA256_DIGEST_LENGTH); + clientPart.UpdateData(&ResumeClient, 1); + clientPart.UpdateData(clientChallenge.get(), 16); + clientPart.UpdateData(serverChallenge.get(), 16); + clientPart.Finalize(); + + HmacHash serverPart(64, sessionKey.get(), EVP_sha256(), SHA256_DIGEST_LENGTH); + serverPart.UpdateData(&ResumeServer, 1); + serverPart.UpdateData(serverChallenge.get(), 16); + serverPart.UpdateData(clientChallenge.get(), 16); + serverPart.Finalize(); + + uint8 newSessionKey[64]; + memcpy(&newSessionKey[0], clientPart.GetDigest(), clientPart.GetLength()); + memcpy(&newSessionKey[32], serverPart.GetDigest(), serverPart.GetLength()); + + K.SetBinary(newSessionKey, 64); + + HmacHash proof(64, newSessionKey, EVP_sha256(), SHA256_DIGEST_LENGTH); + proof.UpdateData(&ResumeClient, 1); + proof.UpdateData(clientChallenge.get(), 16); + proof.UpdateData(serverChallenge.get(), 16); + proof.Finalize(); + + if (memcmp(proof.GetDigest(), clientProof.get(), serverPart.GetLength())) + { + TC_LOG_DEBUG("server.battlenet", "[Battlenet::Resume] Invalid proof!"); + AuthResume* result = new AuthResume(); + result->SetAuthResult(AUTH_UNKNOWN_ACCOUNT); + ReplaceResponse(response, result); + return false; + } + + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_SESSION_KEY); + stmt->setString(0, K.AsHexStr()); + stmt->setUInt32(1, _accountId); + LoginDatabase.Execute(stmt); + + HmacHash serverProof(64, newSessionKey, EVP_sha256(), SHA256_DIGEST_LENGTH); + serverProof.UpdateData(&ResumeServer, 1); + serverProof.UpdateData(serverChallenge.get(), 16); + serverProof.UpdateData(clientChallenge.get(), 16); + serverProof.Finalize(); + + ModuleInfo* resume = sBattlenetMgr->CreateModule(_os, "Resume"); + + BitStream resumeData; + uint8 state = 2; + resumeData.WriteBytes(&state, 1); + resumeData.WriteBytes(serverProof.GetDigest(), serverProof.GetLength()); + + resume->DataSize = resumeData.GetSize(); + resume->Data = new uint8[resume->DataSize]; + memcpy(resume->Data, resumeData.GetBuffer(), resume->DataSize); + + AuthResume* result = new AuthResume(); + result->Modules.push_back(resume); + ReplaceResponse(response, result); + _authed = true; + return true; +} + bool Battlenet::Socket::UnhandledModule(BitStream* /*dataStream*/, ServerPacket** response) { AuthComplete* complete = new AuthComplete(); diff --git a/src/server/authserver/Server/BattlenetSocket.h b/src/server/authserver/Server/BattlenetSocket.h index ff441b19cdd..c634a81b517 100644 --- a/src/server/authserver/Server/BattlenetSocket.h +++ b/src/server/authserver/Server/BattlenetSocket.h @@ -37,6 +37,7 @@ namespace Battlenet MODULE_THUMBPRINT, MODULE_SELECT_GAME_ACCOUNT, MODULE_RISK_FINGERPRINT, + MODULE_RESUME, MODULE_COUNT }; @@ -53,11 +54,13 @@ namespace Battlenet // Auth bool HandleAuthChallenge(PacketHeader& header, BitStream& packet); + bool HandleAuthReconnect(PacketHeader& header, BitStream& packet); bool HandleAuthProofResponse(PacketHeader& header, BitStream& packet); // Creep bool HandlePing(PacketHeader& header, BitStream& packet); bool HandleEnableEncryption(PacketHeader& header, BitStream& packet); + bool HandleDisconnect(PacketHeader& header, BitStream& packet); // WoW bool HandleRealmUpdateSubscribe(PacketHeader& header, BitStream& packet); @@ -78,6 +81,7 @@ namespace Battlenet bool HandlePasswordModule(BitStream* dataStream, ServerPacket** response); bool HandleSelectGameAccountModule(BitStream* dataStream, ServerPacket** response); bool HandleRiskFingerprintModule(BitStream* dataStream, ServerPacket** response); + bool HandleResumeModule(BitStream* dataStream, ServerPacket** response); bool UnhandledModule(BitStream* dataStream, ServerPacket** response); RealmSocket& _socket; @@ -102,9 +106,12 @@ namespace Battlenet BigNumber B; BigNumber K; // session key + BigNumber _reconnectProof; + std::queue<ModuleType> _modulesWaitingForData; PacketCrypt _crypt; + bool _authed; }; } diff --git a/src/server/shared/Database/Implementation/LoginDatabase.cpp b/src/server/shared/Database/Implementation/LoginDatabase.cpp index a54557310e1..abe733e55e2 100644 --- a/src/server/shared/Database/Implementation/LoginDatabase.cpp +++ b/src/server/shared/Database/Implementation/LoginDatabase.cpp @@ -107,6 +107,8 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_DEL_BNET_EXPIRED_BANS, "UPDATE battlenet_account_bans SET active = 0 WHERE active = 1 AND unbandate <> bandate AND unbandate <= UNIX_TIMESTAMP()", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_BNET_ACTIVE_ACCOUNT_BAN, "SELECT bandate, unbandate FROM battlenet_account_bans WHERE id = ? AND active = 1", CONNECTION_SYNCH); PrepareStatement(LOGIN_UPD_BNET_VS_FIELDS, "UPDATE battlenet_accounts SET v = ?, s = ? WHERE email = ?", CONNECTION_ASYNC); + PrepareStatement(LOGIN_UPD_BNET_SESSION_KEY, "UPDATE battlenet_accounts SET sessionKey = ? WHERE id = ?", CONNECTION_ASYNC); + PrepareStatement(LOGIN_SEL_BNET_RECONNECT_INFO, "SELECT ba.id, ba.sessionKey, a.id FROM battlenet_accounts ba LEFT JOIN account a ON ba.id = a.battlenet_account WHERE ba.email = ? AND a.id = SUBSTRING_INDEX(?, '#', 1)", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_BNET_GAME_ACCOUNTS, "SELECT a.username, a.id, ab.bandate, ab.unbandate, ab.active FROM account a LEFT JOIN account_banned ab ON a.id = ab.id WHERE battlenet_account = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_SEL_BNET_GAME_ACCOUNT, "SELECT a.id, ab.bandate, ab.unbandate, ab.active FROM account a LEFT JOIN account_banned ab ON a.id = ab.id WHERE username = ? AND battlenet_account = ?", CONNECTION_SYNCH); PrepareStatement(LOGIN_UPD_BNET_LAST_LOGIN_INFO, "UPDATE battlenet_accounts SET last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ? WHERE id = ?", CONNECTION_ASYNC); diff --git a/src/server/shared/Database/Implementation/LoginDatabase.h b/src/server/shared/Database/Implementation/LoginDatabase.h index fff7a36766c..64264984e29 100644 --- a/src/server/shared/Database/Implementation/LoginDatabase.h +++ b/src/server/shared/Database/Implementation/LoginDatabase.h @@ -126,6 +126,8 @@ enum LoginDatabaseStatements LOGIN_DEL_BNET_EXPIRED_BANS, LOGIN_SEL_BNET_ACTIVE_ACCOUNT_BAN, LOGIN_UPD_BNET_VS_FIELDS, + LOGIN_UPD_BNET_SESSION_KEY, + LOGIN_SEL_BNET_RECONNECT_INFO, LOGIN_SEL_BNET_GAME_ACCOUNTS, LOGIN_SEL_BNET_GAME_ACCOUNT, LOGIN_UPD_BNET_LAST_LOGIN_INFO, |