mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-21 09:44:45 +01:00
Core/Networking: Added safety checks against linking instance socket with incorrect/old session
Ref #15892
This commit is contained in:
@@ -146,6 +146,7 @@ WorldSession::WorldSession(uint32 id, std::string&& name, uint32 battlenetAccoun
|
||||
}
|
||||
|
||||
m_Socket[CONNECTION_TYPE_REALM] = sock;
|
||||
_instanceConnectKey.Raw = UI64LIT(0);
|
||||
|
||||
InitializeQueryCallbackParameters();
|
||||
}
|
||||
@@ -716,8 +717,12 @@ void WorldSession::SendConnectToInstance(WorldPackets::Auth::ConnectToSerial ser
|
||||
boost::asio::ip::tcp::endpoint instanceAddress = realm.GetAddressForClient(boost::asio::ip::address::from_string(GetRemoteAddress(), ignored_error));
|
||||
instanceAddress.port(sWorld->getIntConfig(CONFIG_PORT_INSTANCE));
|
||||
|
||||
_instanceConnectKey.Fields.AccountId = GetAccountId();
|
||||
_instanceConnectKey.Fields.ConnectionType = CONNECTION_TYPE_INSTANCE;
|
||||
_instanceConnectKey.Fields.Key = urand(0, 0x7FFFFFFF);
|
||||
|
||||
WorldPackets::Auth::ConnectTo connectTo;
|
||||
connectTo.Key = MAKE_PAIR64(GetAccountId(), CONNECTION_TYPE_INSTANCE);
|
||||
connectTo.Key = _instanceConnectKey.Raw;
|
||||
connectTo.Serial = serial;
|
||||
connectTo.Payload.Where = instanceAddress;
|
||||
connectTo.Con = CONNECTION_TYPE_INSTANCE;
|
||||
|
||||
@@ -1634,6 +1634,19 @@ class WorldSession
|
||||
void HandleBattlePetSummon(WorldPackets::BattlePet::BattlePetSummon& battlePetSummon);
|
||||
void HandleCageBattlePet(WorldPackets::BattlePet::CageBattlePet& cageBattlePet);
|
||||
|
||||
union ConnectToKey
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint64 AccountId : 32;
|
||||
uint64 ConnectionType : 1;
|
||||
uint64 Key : 31;
|
||||
} Fields;
|
||||
|
||||
uint64 Raw;
|
||||
};
|
||||
|
||||
uint64 GetConnectToInstanceKey() const { return _instanceConnectKey.Raw; }
|
||||
private:
|
||||
void InitializeQueryCallbackParameters();
|
||||
void ProcessQueryCallbacks();
|
||||
@@ -1750,6 +1763,8 @@ class WorldSession
|
||||
|
||||
std::unique_ptr<CollectionMgr> _collectionMgr;
|
||||
|
||||
ConnectToKey _instanceConnectKey;
|
||||
|
||||
WorldSession(WorldSession const& right) = delete;
|
||||
WorldSession& operator=(WorldSession const& right) = delete;
|
||||
};
|
||||
|
||||
@@ -782,7 +782,10 @@ void WorldSocket::LoadSessionPermissionsCallback(PreparedQueryResult result)
|
||||
|
||||
void WorldSocket::HandleAuthContinuedSession(std::shared_ptr<WorldPackets::Auth::AuthContinuedSession> authSession)
|
||||
{
|
||||
_type = ConnectionType(PAIR64_HIPART(authSession->Key));
|
||||
WorldSession::ConnectToKey key;
|
||||
key.Raw = authSession->Key;
|
||||
|
||||
_type = ConnectionType(key.Fields.ConnectionType);
|
||||
if (_type != CONNECTION_TYPE_INSTANCE)
|
||||
{
|
||||
SendAuthResponseError(AUTH_UNKNOWN_ACCOUNT);
|
||||
@@ -793,7 +796,7 @@ void WorldSocket::HandleAuthContinuedSession(std::shared_ptr<WorldPackets::Auth:
|
||||
// Client switches packet headers after sending CMSG_AUTH_CONTINUED_SESSION
|
||||
_headerBuffer.Resize(SizeOfClientHeader[1][1]);
|
||||
|
||||
uint32 accountId = PAIR64_LOPART(authSession->Key);
|
||||
uint32 accountId = uint32(key.Fields.AccountId);
|
||||
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_INFO_CONTINUED_SESSION);
|
||||
stmt->setUInt32(0, accountId);
|
||||
|
||||
@@ -813,7 +816,10 @@ void WorldSocket::HandleAuthContinuedSessionCallback(std::shared_ptr<WorldPacket
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 accountId = PAIR64_LOPART(authSession->Key);
|
||||
WorldSession::ConnectToKey key;
|
||||
key.Raw = authSession->Key;
|
||||
|
||||
uint32 accountId = uint32(key.Fields.AccountId);
|
||||
Field* fields = result->Fetch();
|
||||
std::string login = fields[0].GetString();
|
||||
BigNumber k;
|
||||
@@ -835,7 +841,7 @@ void WorldSocket::HandleAuthContinuedSessionCallback(std::shared_ptr<WorldPacket
|
||||
return;
|
||||
}
|
||||
|
||||
sWorld->AddInstanceSocket(shared_from_this(), accountId);
|
||||
sWorld->AddInstanceSocket(shared_from_this(), authSession->Key);
|
||||
AsyncRead();
|
||||
}
|
||||
|
||||
|
||||
@@ -227,9 +227,9 @@ void World::AddSession(WorldSession* s)
|
||||
addSessQueue.add(s);
|
||||
}
|
||||
|
||||
void World::AddInstanceSocket(std::shared_ptr<WorldSocket> sock, uint32 sessionAccountId)
|
||||
void World::AddInstanceSocket(std::shared_ptr<WorldSocket> sock, uint64 connectToKey)
|
||||
{
|
||||
_linkSocketQueue.add(std::make_pair(sock, sessionAccountId));
|
||||
_linkSocketQueue.add(std::make_pair(sock, connectToKey));
|
||||
}
|
||||
|
||||
void World::AddSession_(WorldSession* s)
|
||||
@@ -298,10 +298,16 @@ void World::AddSession_(WorldSession* s)
|
||||
}
|
||||
}
|
||||
|
||||
void World::ProcessLinkInstanceSocket(std::pair<std::shared_ptr<WorldSocket>, uint32> linkInfo)
|
||||
void World::ProcessLinkInstanceSocket(std::pair<std::shared_ptr<WorldSocket>, uint64> linkInfo)
|
||||
{
|
||||
WorldSession* session = FindSession(linkInfo.second);
|
||||
if (!session)
|
||||
if (!linkInfo.first->IsOpen())
|
||||
return;
|
||||
|
||||
WorldSession::ConnectToKey key;
|
||||
key.Raw = linkInfo.second;
|
||||
|
||||
WorldSession* session = FindSession(uint32(key.Fields.AccountId));
|
||||
if (!session || session->GetConnectToInstanceKey() != linkInfo.second)
|
||||
{
|
||||
linkInfo.first->SendAuthResponseError(AUTH_SESSION_EXPIRED);
|
||||
linkInfo.first->DelayedCloseSocket();
|
||||
@@ -2811,7 +2817,7 @@ void World::SendServerMessage(ServerMessageType messageID, std::string stringPar
|
||||
|
||||
void World::UpdateSessions(uint32 diff)
|
||||
{
|
||||
std::pair<std::shared_ptr<WorldSocket>, uint32> linkInfo;
|
||||
std::pair<std::shared_ptr<WorldSocket>, uint64> linkInfo;
|
||||
while (_linkSocketQueue.next(linkInfo))
|
||||
ProcessLinkInstanceSocket(std::move(linkInfo));
|
||||
|
||||
|
||||
@@ -564,7 +564,7 @@ class World
|
||||
|
||||
WorldSession* FindSession(uint32 id) const;
|
||||
void AddSession(WorldSession* s);
|
||||
void AddInstanceSocket(std::shared_ptr<WorldSocket> sock, uint32 sessionAccountId);
|
||||
void AddInstanceSocket(std::shared_ptr<WorldSocket> sock, uint64 connectToKey);
|
||||
void SendAutoBroadcast();
|
||||
bool RemoveSession(uint32 id);
|
||||
/// Get the number of current active sessions
|
||||
@@ -874,8 +874,8 @@ class World
|
||||
void AddSession_(WorldSession* s);
|
||||
LockedQueue<WorldSession*> addSessQueue;
|
||||
|
||||
void ProcessLinkInstanceSocket(std::pair<std::shared_ptr<WorldSocket>, uint32> linkInfo);
|
||||
LockedQueue<std::pair<std::shared_ptr<WorldSocket>, uint32>> _linkSocketQueue;
|
||||
void ProcessLinkInstanceSocket(std::pair<std::shared_ptr<WorldSocket>, uint64> linkInfo);
|
||||
LockedQueue<std::pair<std::shared_ptr<WorldSocket>, uint64>> _linkSocketQueue;
|
||||
|
||||
// used versions
|
||||
std::string m_DBVersion;
|
||||
|
||||
Reference in New Issue
Block a user