Skip to content

Commit

Permalink
[Core/Packets] Split SMSG_AUTH_CHALLENGE, SMSG_PONG, CMSG_PING to Aut…
Browse files Browse the repository at this point in the history
…henticationPackets (#324)
  • Loading branch information
leelf00 authored Aug 14, 2024
1 parent 9b96e8f commit 66ecf89
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 32 deletions.
3 changes: 2 additions & 1 deletion src/server/game/Server/Packets/AllPackets.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* This file is part of the Pandaria 5.4.8 Project. See THANKS file for Copyright information
* This file is part of the Legends of Azeroth Pandaria Project. See THANKS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
Expand All @@ -18,6 +18,7 @@
#ifndef AllPackets_h__
#define AllPackets_h__

#include "AuthenticationPackets.h"
#include "CharacterPackets.h"
#include "MiscPackets.h"
#include "QueryPackets.h"
Expand Down
52 changes: 52 additions & 0 deletions src/server/game/Server/Packets/AuthenticationPackets.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* This file is part of the Legends of Azeroth Pandaria Project. See THANKS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "AuthenticationPackets.h"

bool WorldPackets::Auth::EarlyProcessClientPacket::ReadNoThrow()
{
try
{
Read();
return true;
}
catch (ByteBufferPositionException const& /*ex*/)
{
}

return false;
}

void WorldPackets::Auth::Ping::Read()
{
_worldPacket >> Latency;
_worldPacket >> Serial;
}

WorldPacket const* WorldPackets::Auth::Pong::Write()
{
_worldPacket << uint32(Serial);
return &_worldPacket;
}

WorldPacket const* WorldPackets::Auth::AuthChallenge::Write()
{
_worldPacket<< uint16(0); // header?
_worldPacket.append(DosChallenge.data(), DosChallenge.size());
_worldPacket << uint8(DosZeroBits);
_worldPacket.append(Challenge.data(), Challenge.size());
return &_worldPacket;
}
78 changes: 78 additions & 0 deletions src/server/game/Server/Packets/AuthenticationPackets.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* This file is part of the Legends of Azeroth Pandaria Project. See THANKS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef AuthenticationPacketsWorld_h__
#define AuthenticationPacketsWorld_h__

#include "Packet.h"
#include "ObjectMgr.h"
#include "Util.h"
#include "BigNumber.h"
#include <array>
#include <boost/asio/ip/tcp.hpp>

using boost::asio::ip::tcp;

namespace WorldPackets
{
namespace Auth
{
class EarlyProcessClientPacket : public ClientPacket
{
public:
EarlyProcessClientPacket(OpcodeClient opcode, WorldPacket&& packet) : ClientPacket(opcode, std::move(packet)) { }

bool ReadNoThrow();
};

class Ping final : public EarlyProcessClientPacket
{
public:
Ping(WorldPacket&& packet) : EarlyProcessClientPacket(CMSG_PING, std::move(packet)) { }

uint32 Latency = 0;
uint32 Serial = 0;

private:
void Read();
};

class Pong final : public ServerPacket
{
public:
Pong(uint32 serial) : ServerPacket(SMSG_PONG, 4), Serial(serial) { }

WorldPacket const* Write() override;

uint32 Serial = 0;
};

class AuthChallenge final : public ServerPacket
{
public:
AuthChallenge() : ServerPacket(SMSG_AUTH_CHALLENGE, 32 + 4 + 1) { }

WorldPacket const* Write() override;

std::array<uint32, 8> DosChallenge = { };
std::array<uint8, 4> Challenge = { };
uint8 DosZeroBits = 0;
};

}
}

#endif // AuthenticationPacketsWorld_h__
48 changes: 19 additions & 29 deletions src/server/game/Server/WorldSocket.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* This file is part of the Pandaria 5.4.8 Project. See THANKS file for Copyright information
* This file is part of the Legends of Azeroth Pandaria Project. See THANKS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
Expand All @@ -16,6 +16,7 @@
*/

#include "WorldSocket.h"
#include "AuthenticationPackets.h"
#include "BigNumber.h"
#include "DatabaseEnv.h"
#include "GameTime.h"
Expand Down Expand Up @@ -245,14 +246,12 @@ bool WorldSocket::Update()

void WorldSocket::HandleSendAuthSession()
{
WorldPacket packet(SMSG_AUTH_CHALLENGE, 37);
packet << uint16(0); // header?
WorldPackets::Auth::AuthChallenge challenge;
challenge.Challenge = _authSeed;
memcpy(challenge.DosChallenge.data(), Trinity::Crypto::GetRandomBytes<32>().data(), 32);
challenge.DosZeroBits = 1;

packet.append(Trinity::Crypto::GetRandomBytes<32>()); // new encryption seeds
packet << uint8(1);
packet.append(_authSeed);

SendPacketAndLogOpcode(packet);
SendPacketAndLogOpcode(*challenge.Write());
}

void WorldSocket::OnClose()
Expand Down Expand Up @@ -529,15 +528,15 @@ WorldSocket::ReadDataHandlerResult WorldSocket::ReadDataHandler()
case CMSG_PING:
{
LogOpcodeText(opcode, sessionGuard);
try
{
return HandlePing(packet) ? ReadDataHandlerResult::Ok : ReadDataHandlerResult::Error;
}
catch (ByteBufferException const&)
{
}
TC_LOG_ERROR("network", "WorldSocket::ReadDataHandler(): client %s sent malformed CMSG_PING", GetRemoteIpAddress().to_string().c_str());
return ReadDataHandlerResult::Error;
WorldPackets::Auth::Ping ping(std::move(packet));
if (!ping.ReadNoThrow())
{
TC_LOG_ERROR("network", "WorldSocket::ReadDataHandler(): client %s sent malformed CMSG_PING", GetRemoteIpAddress().to_string().c_str());
return ReadDataHandlerResult::Error;
}
if (!HandlePing(ping))
return ReadDataHandlerResult::Error;
return ReadDataHandlerResult::Ok;
}
case CMSG_AUTH_SESSION:
{
Expand Down Expand Up @@ -1126,17 +1125,10 @@ void WorldSocket::SendAuthResponseError(uint8 code)
SendPacketAndLogOpcode(packet);
}

bool WorldSocket::HandlePing(WorldPacket& recvPacket)
bool WorldSocket::HandlePing(WorldPackets::Auth::Ping& ping)
{
using namespace std::chrono;

uint32 ping;
uint32 latency;

// Get the ping packet content
recvPacket >> latency;
recvPacket >> ping;

if (_LastPingTime == steady_clock::time_point())
{
_LastPingTime = steady_clock::now();
Expand Down Expand Up @@ -1177,16 +1169,14 @@ bool WorldSocket::HandlePing(WorldPacket& recvPacket)
std::lock_guard<std::mutex> sessionGuard(_worldSessionLock);

if (_worldSession)
_worldSession->SetLatency(latency);
_worldSession->SetLatency(ping.Latency);
else
{
TC_LOG_ERROR("network", "WorldSocket::HandlePing: peer sent CMSG_PING, but is not authenticated or got recently kicked, address = %s", GetRemoteIpAddress().to_string().c_str());
return false;
}
}

WorldPacket packet(SMSG_PONG, 4);
packet << ping;
SendPacketAndLogOpcode(packet);
SendPacketAndLogOpcode(*WorldPackets::Auth::Pong(ping.Serial).Write());
return true;
}
10 changes: 8 additions & 2 deletions src/server/game/Server/WorldSocket.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* This file is part of the Pandaria 5.4.8 Project. See THANKS file for Copyright information
* This file is part of the Legends of Azeroth Pandaria Project. See THANKS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
Expand Down Expand Up @@ -53,7 +53,13 @@ class EncryptablePacket : public WorldPacket
namespace WorldPackets
{
class ServerPacket;
namespace Auth
{
class AuthSession;
class Ping;
}
}

#pragma pack(push, 1)

struct ClientPktHeader
Expand Down Expand Up @@ -140,7 +146,7 @@ class TC_GAME_API WorldSocket : public Socket<WorldSocket>
void HandleAuthContinuedSessionCallback(WorldSession::ConnectToKey key, PreparedQueryResult result);
void SendAuthResponseError(uint8 code);

bool HandlePing(WorldPacket& recvPacket);
bool HandlePing(WorldPackets::Auth::Ping& ping);

std::array<uint8, 4> _authSeed;
AuthCrypt _authCrypt;
Expand Down

0 comments on commit 66ecf89

Please sign in to comment.