54uint8 const WorldSocket::AuthCheckSeed[16] = { 0xC5, 0xC6, 0x98, 0x95, 0x76, 0x3F, 0x1D, 0xCD, 0xB6, 0xA1, 0x37, 0x28, 0xB3, 0x12, 0xFF, 0x8A };
55uint8 const WorldSocket::SessionKeySeed[16] = { 0x58, 0xCB, 0xCF, 0x40, 0xFE, 0x2E, 0xCE, 0xA6, 0x5A, 0x90, 0xB8, 0x01, 0x68, 0x6C, 0x28, 0x0B };
56uint8 const WorldSocket::ContinuedSessionSeed[16] = { 0x16, 0xAD, 0x0C, 0xD4, 0x46, 0xF9, 0x4F, 0xB2, 0xEF, 0x7D, 0xEA, 0x2A, 0x17, 0x66, 0x4D, 0x2F };
57uint8 const WorldSocket::EncryptionKeySeed[16] = { 0xE9, 0x75, 0x3C, 0x50, 0x90, 0x93, 0x61, 0xDA, 0x3B, 0x07, 0xEE, 0xFA, 0xFF, 0x9D, 0x41, 0xB8 };
61 _worldSession(nullptr), _authed(false), _canRequestHotfixes(true), _sendBufferSize(4096), _compressionStream(nullptr)
86 self->CheckIpCallback(std::move(result));
97 Field* fields = result->Fetch();
98 if (fields[0].GetUInt64() != 0)
101 }
while (result->NextRow());
117 initializer.
Write(
"\n", 1);
162 buffer >> terminator;
163 if (terminator !=
'\n')
171 TC_LOG_ERROR(
"network",
"WorldSocket::InitializeHandler ByteBufferException {} occured while parsing initial packet from {}",
187 TC_LOG_ERROR(
"network",
"Can't initialize packet compression (zlib: deflateInit) Error code: {} ({})", z_res, zError(z_res));
245 memcpy(challenge.
DosChallenge.data(), Trinity::Crypto::GetRandomBytes<32>().data(), 32);
341 TC_LOG_ERROR(
"network",
"WorldSocket::ReadHeaderHandler(): client {} sent malformed packet (size: {}, opcode {})",
358 TC_LOG_ERROR(
"network",
"WorldSocket::ReadHeaderHandler(): client {} failed to decrypt packet (size: {})",
367 TC_LOG_ERROR(
"network",
"WorldSocket::ReadHeaderHandler(): client {} sent wrong opcode (opcode: {})",
400 if (sessionGuard.try_lock())
405 std::shared_ptr<WorldPackets::Auth::AuthSession> authSession = std::make_shared<WorldPackets::Auth::AuthSession>(std::move(packet));
406 if (!authSession->ReadNoThrow())
420 if (sessionGuard.try_lock())
425 std::shared_ptr<WorldPackets::Auth::AuthContinuedSession> authSession = std::make_shared<WorldPackets::Auth::AuthContinuedSession>(std::move(packet));
426 if (!authSession->ReadNoThrow())
428 TC_LOG_ERROR(
"network",
"WorldSocket::ReadDataHandler(): client {} sent malformed CMSG_AUTH_CONTINUED_SESSION",
GetRemoteIpAddress().to_string());
442 TC_LOG_ERROR(
"network",
"WorldSocket::ReadDataHandler: client {} sent CMSG_KEEP_ALIVE without being authenticated",
GetRemoteIpAddress().to_string());
484 TC_LOG_ERROR(
"network.opcode",
"ProcessIncoming: Client not authed opcode = {}",
uint32(opcode));
568 else if (!packet.
empty())
571 memcpy(dataPos, &opcode,
sizeof(opcode));
575 header.
Size = packetSize;
594 TC_LOG_ERROR(
"network",
"Can't compress packet opcode (zlib: deflate) Error code: {} ({}, msg: {})", z_res, zError(z_res),
_compressionStream->msg);
604 TC_LOG_ERROR(
"network",
"Can't compress packet data (zlib: deflate) Error code: {} ({}, msg: {})", z_res, zError(z_res),
_compressionStream->msg);
659 Game.TimezoneOffset =
Minutes(fields[10].GetInt16());
676 stmt->
setString(1, authSession->RealmJoinTicket);
680 HandleAuthSessionCallback(std::move(authSession), std::move(result));
690 TC_LOG_ERROR(
"network",
"WorldSocket::HandleAuthSession: Sent Auth Response (unknown account).");
711 if (account.
Game.
OS ==
"Wn64")
713 else if (account.
Game.
OS ==
"Mc64")
725 if (memcmp(hmac.
GetDigest().data(), authSession->Digest.data(), authSession->Digest.size()) != 0)
727 TC_LOG_ERROR(
"network",
"WorldSocket::HandleAuthSession: Authentication failed for account: {} ('{}') address: {}", account.
Game.
Id, authSession->RealmJoinTicket, address);
738 sessionKeyHmac.
UpdateData(authSession->LocalChallenge);
746 encryptKeyGen.
UpdateData(authSession->LocalChallenge);
761 stmt->
setString(1, authSession->RealmJoinTicket);
783 TC_LOG_ERROR(
"network",
"WorldSocket::HandleAuthSession: Client {} requested connecting with realm id {} but this realm has id {} set in config.",
791 if (wardenActive && account.
Game.
OS !=
"Win" && account.
Game.
OS !=
"Wn64" && account.
Game.
OS !=
"Mc64")
794 TC_LOG_ERROR(
"network",
"WorldSocket::HandleAuthSession: Client {} attempted to log in using invalid client OS ({}).", address, account.
Game.
OS);
808 TC_LOG_DEBUG(
"network",
"WorldSocket::HandleAuthSession: Sent Auth Response (Account IP differs. Original IP: {}, new IP: {}).", account.
BattleNet.
LastIP, address);
843 TC_LOG_ERROR(
"network",
"WorldSocket::HandleAuthSession: Sent Auth Response (Account banned).");
855 TC_LOG_DEBUG(
"network",
"WorldSocket::HandleAuthSession: User tries to login but his security level is not enough");
861 TC_LOG_DEBUG(
"network",
"WorldSocket::HandleAuthSession: Client '{}' authenticated successfully from {}.", authSession->RealmJoinTicket, address);
869 stmt->
setString(1, authSession->RealmJoinTicket);
887 LoadSessionPermissionsCallback(std::move(result));
903 key.
Raw = authSession->Key;
919 HandleAuthContinuedSessionCallback(std::move(authSession), std::move(result));
933 _key = key.
Raw = authSession->Key;
936 Field* fields = result->Fetch();
937 std::string login = fields[0].
GetString();
941 hmac.UpdateData(
reinterpret_cast<uint8 const*
>(&authSession->Key),
sizeof(authSession->Key));
942 hmac.UpdateData(authSession->LocalChallenge);
947 if (memcmp(hmac.GetDigest().data(), authSession->Digest.data(), authSession->Digest.size()))
949 TC_LOG_ERROR(
"network",
"WorldSocket::HandleAuthContinuedSession: Authentication failed for account: {} ('{}') address: {}", accountId, login,
GetRemoteIpAddress().to_string());
955 encryptKeyGen.
UpdateData(authSession->LocalChallenge);
973 switch (connectToFailed.
Serial)
1011 sWorld->AddInstanceSocket(shared_from_this(),
_key);
1023 using namespace std::chrono;
1031 steady_clock::time_point now = steady_clock::now();
1037 if (diff < seconds(27))
1049 TC_LOG_ERROR(
"network",
"WorldSocket::HandlePing: {} kicked for over-speed pings (address: {})",
1067 TC_LOG_ERROR(
"network",
"WorldSocket::HandlePing: peer sent CMSG_PING, but is not authenticated or got recently kicked, address = {}",
GetRemoteIpAddress().to_string());
constexpr size_t SESSION_KEY_LENGTH
@ ERROR_GAME_ACCOUNT_BANNED
@ ERROR_RISK_ACCOUNT_LOCKED
@ ERROR_SERVER_IS_PRIVATE
std::shared_ptr< PreparedResultSet > PreparedQueryResult
DatabaseWorkerPool< LoginDatabaseConnection > LoginDatabase
Accessor to the realm/login database.
std::chrono::minutes Minutes
Minutes shorthand typedef.
#define TC_LOG_DEBUG(filterType__,...)
#define TC_LOG_TRACE(filterType__,...)
#define TC_LOG_ERROR(filterType__,...)
@ LOGIN_UPD_MUTE_TIME_LOGIN
@ LOGIN_UPD_ACCOUNT_INFO_CONTINUED_SESSION
@ LOGIN_UPD_LAST_ATTEMPT_IP
@ LOGIN_SEL_ACCOUNT_INFO_CONTINUED_SESSION
@ LOGIN_SEL_ACCOUNT_INFO_BY_NAME
Role Based Access Control related classes definition.
struct z_stream_s z_stream
T & AddCallback(T &&query)
void ProcessReadyCallbacks()
char const * what() const noexcept override
std::string ReadString(uint32 length, bool requireValidUtf8=true)
bool NeedsEncryption() const
Class used to access individual fields of database query result.
std::string GetString() const
std::vector< uint8 > GetBinary() const
void Resize(size_type bytes)
size_type GetRemainingSpace() const
void ReadCompleted(size_type bytes)
void WriteCompleted(size_type bytes)
size_type GetActiveSize() const
uint8 * GetWritePointer()
void Write(void const *data, std::size_t size)
void setInt32(const uint8 index, const int32 value)
void setInt64(const uint8 index, const int64 value)
void setBinary(const uint8 index, const std::vector< uint8 > &value)
void setUInt32(const uint8 index, const uint32 value)
void setString(const uint8 index, const std::string &value)
QueryCallback && WithPreparedCallback(std::function< void(PreparedQueryResult)> &&callback)
void Generate(uint8 *buf, uint32 sz)
MessageBuffer & GetReadBuffer()
void AsyncReadWithCallback(void(T::*callback)(boost::system::error_code const &, std::size_t))
void DelayedCloseSocket()
Marks the socket for closing after write buffer becomes empty.
boost::asio::ip::address GetRemoteIpAddress() const
void QueuePacket(MessageBuffer &&buffer)
void SetNoDelay(bool enable)
uint16 GetRemotePort() const
void UpdateData(uint8 const *data, size_t len)
Digest const & GetDigest() const
void UpdateData(uint8 const *data, size_t len)
Digest const & GetDigest() const
bool IsInitialized() const
bool PeekDecryptRecv(uint8 *data, size_t length)
void Init(Trinity::Crypto::AES::Key const &key)
bool EncryptSend(uint8 *data, size_t length, Trinity::Crypto::AES::Tag &tag)
bool DecryptRecv(uint8 *data, size_t length, Trinity::Crypto::AES::Tag &tag)
void SetReceiveTime(TimePoint receivedTime)
void SetOpcode(uint32 opcode)
WorldPacket const * Write() override
std::array< uint8, 16 > Challenge
std::array< uint32, 8 > DosChallenge
uint32 Result
the result of the authentication process, possible values are BattlenetRpcErrorCode
WorldPacket const * Write() override
WorldPacket const * Write() override
Player session in the World.
void AbortLogin(WorldPackets::Character::LoginFailureReason reason)
void SendConnectToInstance(WorldPackets::Auth::ConnectToSerial serial)
void QueuePacket(WorldPacket *new_packet)
Add an incoming packet to the queue.
void InitWarden(SessionKey const &k)
std::string GetPlayerInfo() const
bool PlayerLoading() const
QueryCallback LoadPermissionsAsync()
bool HasPermission(uint32 permissionId)
void ResetTimeOutTime(bool onlyActive)
void SetLatency(uint32 latency)
rbac::RBACData * GetRBACData()
void CheckIpCallback(PreparedQueryResult result)
MessageBuffer _headerBuffer
void HandleAuthContinuedSessionCallback(std::shared_ptr< WorldPackets::Auth::AuthContinuedSession > authSession, PreparedQueryResult result)
void HandleAuthContinuedSession(std::shared_ptr< WorldPackets::Auth::AuthContinuedSession > authSession)
void LogOpcodeText(OpcodeClient opcode, std::unique_lock< std::mutex > const &guard) const
void InitializeHandler(boost::system::error_code const &error, std::size_t transferedBytes)
static uint8 const SessionKeySeed[16]
ConnectionType GetConnectionType() const
static std::string const ClientConnectionInitialize
void HandleConnectToFailed(WorldPackets::Auth::ConnectToFailed &connectToFailed)
static uint8 const ContinuedSessionSeed[16]
void HandleAuthSessionCallback(std::shared_ptr< WorldPackets::Auth::AuthSession > authSession, PreparedQueryResult result)
void LoadSessionPermissionsCallback(PreparedQueryResult result)
MessageBuffer _packetBuffer
void SendAuthResponseError(uint32 code)
QueryCallbackProcessor _queryProcessor
WorldPacketCrypt _authCrypt
WorldSocket(boost::asio::ip::tcp::socket &&socket)
std::size_t _sendBufferSize
void SetWorldSession(WorldSession *session)
void HandleAuthSession(std::shared_ptr< WorldPackets::Auth::AuthSession > authSession)
void HandleSendAuthSession()
WorldSession * _worldSession
uint32 CompressPacket(uint8 *buffer, WorldPacket const &packet)
z_stream * _compressionStream
static uint8 const EncryptionKeySeed[16]
void SendPacket(WorldPacket const &packet)
static uint8 const AuthCheckSeed[16]
MPSCQueue< EncryptablePacket, &EncryptablePacket::SocketQueueLink > _bufferQueue
void SendPacketAndLogOpcode(WorldPacket const &packet)
sends and logs network.opcode without accessing WorldSession
void HandleEnterEncryptedModeAck()
bool HandlePing(WorldPackets::Auth::Ping &ping)
static std::string const ServerConnectionInitialize
std::array< uint8, 16 > _encryptKey
void WritePacketToBuffer(EncryptablePacket const &packet, MessageBuffer &buffer)
void ReadHandler() override
std::array< uint8, 16 > _serverChallenge
std::mutex _worldSessionLock
ReadDataHandlerResult ReadDataHandler()
static uint32 const MinSizeForCompression
void LoadFromDBCallback(PreparedQueryResult result)
std::string GetOpcodeNameForLogging(OpcodeClient opcode)
Lookup opcode name for human understandable logging.
@ CONNECTION_TYPE_INSTANCE
@ CMSG_TIME_SYNC_RESPONSE
@ CMSG_AUTH_CONTINUED_SESSION
@ CMSG_ENTER_ENCRYPTED_MODE_ACK
@ CONFIG_MAX_OVERSPEED_PINGS
@ CONFIG_ALLOW_LOGGING_IP_ADDRESSES_IN_DATABASE
void TC_COMMON_API GetRandomBytes(uint8 *buf, size_t len)
@ RBAC_PERM_SKIP_CHECK_OVERSPEED_PING
struct AccountInfo::@331 BattleNet
struct AccountInfo::@332 Game
AccountInfo(Field const *fields)
std::array< uint8, 64 > KeyData
std::array< uint8, 16 > Mac64AuthSeed
std::array< uint8, 16 > Win64AuthSeed
Battlenet::RealmHandle Id
struct WorldSession::ConnectToKey::@330 Fields