diff options
| author | Shauren <shauren.trinity@gmail.com> | 2014-04-30 20:16:08 +0200 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2014-04-30 20:50:15 +0200 |
| commit | a142eb9f7a9683f98fe1e9153f6958f80d374c9d (patch) | |
| tree | 5522fe49d1628ed6969b1bd6393b9e36b6b2f10b /src/server/authserver/Server | |
| parent | cdae208b9a47cf056330b4ded6b0f8201a7ad9e6 (diff) | |
Core/Auth: Battle.net stuff
Diffstat (limited to 'src/server/authserver/Server')
| -rw-r--r-- | src/server/authserver/Server/BattlenetBitStream.h | 189 | ||||
| -rw-r--r-- | src/server/authserver/Server/BattlenetPacketCrypt.cpp | 39 | ||||
| -rw-r--r-- | src/server/authserver/Server/BattlenetPacketCrypt.h | 36 | ||||
| -rw-r--r-- | src/server/authserver/Server/BattlenetPackets.cpp | 170 | ||||
| -rw-r--r-- | src/server/authserver/Server/BattlenetPackets.h | 202 | ||||
| -rw-r--r-- | src/server/authserver/Server/BattlenetSocket.cpp | 124 | ||||
| -rw-r--r-- | src/server/authserver/Server/BattlenetSocket.h | 54 | ||||
| -rw-r--r-- | src/server/authserver/Server/RealmAcceptor.h | 4 |
8 files changed, 817 insertions, 1 deletions
diff --git a/src/server/authserver/Server/BattlenetBitStream.h b/src/server/authserver/Server/BattlenetBitStream.h new file mode 100644 index 00000000000..fa09b24b204 --- /dev/null +++ b/src/server/authserver/Server/BattlenetBitStream.h @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * 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 __BATTLENETBITSTREAM_H__ +#define __BATTLENETBITSTREAM_H__ + +#include "ByteConverter.h" +#include <exception> +#include <string> +#include <vector> + +namespace Battlenet +{ + class BitStreamPositionException : public std::exception + { + public: + char const* what() const + { + return ""; + } + }; + + class BitStream + { + public: + static uint32 const MaxSize = 0x1000; + + // length : The maximum number of bytes to read + BitStream(uint32 length) : _numBits(length * 8), _readPos(0), _writePos(0) + { + _buffer.resize(length, 0); + } + + BitStream() : _numBits(0), _readPos(0), _writePos(0) + { + _buffer.reserve(0x1000); + } + + void AlignToNextByte() + { + _readPos = (_readPos + 7) & ~7; + _writePos = (_writePos + 7) & ~7; + } + + std::string ReadString(uint32 bitCount, uint32 baseLength = 0) + { + uint32 len = Read<uint32>(bitCount) + baseLength; + AlignToNextByte(); + std::string str(reinterpret_cast<char*>(&_buffer[_readPos >> 3]), len); + _readPos += len * 8; + return str; + } + + uint8* ReadBytes(uint32 count) + { + AlignToNextByte(); + if (_readPos + count * 8 > _numBits) + throw BitStreamPositionException(); + + uint8* buf = new uint8[count]; + memcpy(buf, &_buffer[_readPos >> 3], count); + _readPos += count * 8; + return buf; + } + + float ReadFloat() + { + uint32 val = Read<uint32>(32); + return *reinterpret_cast<float*>(&val); + } + + std::string ReadFourCC() + { + uint32 fcc = Read<uint32>(32); + EndianConvertReverse(fcc); + size_t len = 4; + while (!(fcc & 0xFF)) + { + fcc >>= 8; + --len; + } + + return std::string(reinterpret_cast<char*>(&fcc), len); + } + + template<typename T> + T Read(uint32 bitCount) + { + T ret = 0; + while (bitCount != 0) + { + uint32 bitPos = (_readPos & 7); + uint32 bitsLeftInByte = 8 - bitPos; + if (bitsLeftInByte >= bitCount) + bitsLeftInByte = bitCount; + + bitCount -= bitsLeftInByte; + ret |= static_cast<T>((uint64)(_buffer[_readPos >> 3] >> bitPos & (uint32)((uint8)(1 << bitsLeftInByte) - 1)) << bitCount); + _readPos += bitsLeftInByte; + } + return ret; + } + + //WriteString + + template<typename T> + void WriteBytes(T* data, uint32 count) + { + AlignToNextByte(); + if (_writePos + 8 * count > MaxSize) + throw BitStreamPositionException(); + + _buffer.resize(_buffer.size() + count); + memcpy(&_buffer[_writePos >> 3], data, count); + _writePos += count * 8; + } + + //WriteFloat + void WriteFourCC(char const* fcc) + { + uint32 intVal = *(uint32*)fcc; + EndianConvertReverse(intVal); + Write(intVal, 32); + } + + template<typename T> + void Write(T value, uint32 bitCount) + { + if (_writePos + bitCount >= 8 * MaxSize) + throw BitStreamPositionException(); + + while (bitCount != 0) + { + uint32 bitPos = (_writePos & 7); + uint32 bitsLeftInByte = 8 - bitPos; + if (bitsLeftInByte >= bitCount) + bitsLeftInByte = bitCount; + + bitCount -= bitsLeftInByte; + + uint8 firstHalf = (uint8)(~(((uint8)(1 << bitsLeftInByte) - 1) << bitPos)); + uint8 secondHalf = (uint8)((((uint8)(1 << bitsLeftInByte) - 1) & (uint8)(value >> bitCount)) << bitPos); + + if (_buffer.size() > (_writePos >> 3)) + _buffer[_writePos >> 3] = (uint8)(_buffer[_writePos >> 3] & firstHalf | secondHalf); + else + _buffer.push_back(secondHalf); + + _writePos += bitsLeftInByte; + } + } + + void SetReadPos(uint32 bits) + { + if (bits >= _numBits) + throw BitStreamPositionException(); + + _readPos = bits; + } + + bool IsRead() const { return _readPos >= _numBits; } + + uint8* GetBuffer() { return _buffer.data(); } + + size_t GetSize() const { return _buffer.size(); } + + private: + std::vector<uint8> _buffer; + uint32 _numBits; + uint32 _readPos; + uint32 _writePos; + }; +} + +#endif // __BATTLENETBITSTREAM_H__ diff --git a/src/server/authserver/Server/BattlenetPacketCrypt.cpp b/src/server/authserver/Server/BattlenetPacketCrypt.cpp new file mode 100644 index 00000000000..10aa684e10a --- /dev/null +++ b/src/server/authserver/Server/BattlenetPacketCrypt.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * 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 "BattlenetPacketCrypt.h" +#include "Cryptography/HmacHash.h" +#include "Cryptography/BigNumber.h" + +Battlenet::PacketCrypt::PacketCrypt() : ::PacketCrypt(SHA256_DIGEST_LENGTH) +{ +} + +void Battlenet::PacketCrypt::Init(BigNumber* K) +{ + uint8 ServerEncryptionKey[SEED_KEY_SIZE] = { 0x68, 0xE0, 0xC7, 0x2E, 0xDD, 0xD6, 0xD2, 0xF3, 0x1E, 0x5A, 0xB1, 0x55, 0xB1, 0x8B, 0x63, 0x1E }; + HmacHash serverEncryptHmac(SEED_KEY_SIZE, ServerEncryptionKey, EVP_sha256(), SHA256_DIGEST_LENGTH); + uint8 *encryptHash = serverEncryptHmac.ComputeHash(K); + + uint8 ClientDecryptionKey[SEED_KEY_SIZE] = { 0xDE, 0xA9, 0x65, 0xAE, 0x54, 0x3A, 0x1E, 0x93, 0x9E, 0x69, 0x0C, 0xAA, 0x68, 0xDE, 0x78, 0x39 }; + HmacHash clientDecryptHmac(SEED_KEY_SIZE, ClientDecryptionKey, EVP_sha256(), SHA256_DIGEST_LENGTH); + uint8 *decryptHash = clientDecryptHmac.ComputeHash(K); + + _clientDecrypt.Init(decryptHash); + _serverEncrypt.Init(encryptHash); + _initialized = true; +} diff --git a/src/server/authserver/Server/BattlenetPacketCrypt.h b/src/server/authserver/Server/BattlenetPacketCrypt.h new file mode 100644 index 00000000000..dde687651d3 --- /dev/null +++ b/src/server/authserver/Server/BattlenetPacketCrypt.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * 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 __BATTLENETPACKETCRYPT_H__ +#define __BATTLENETPACKETCRYPT_H__ + +#include "PacketCrypt.h" + +class BigNumber; + +namespace Battlenet +{ + class PacketCrypt : public ::PacketCrypt + { + public: + PacketCrypt(); + + void Init(BigNumber* K) override; + }; +} + +#endif // __BATTLENETPACKETCRYPT_H__ diff --git a/src/server/authserver/Server/BattlenetPackets.cpp b/src/server/authserver/Server/BattlenetPackets.cpp new file mode 100644 index 00000000000..37040fa6d6e --- /dev/null +++ b/src/server/authserver/Server/BattlenetPackets.cpp @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * 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 "Common.h" +#include "BattlenetBitStream.h" +#include "BattlenetPackets.h" +#include "Util.h" +#include <limits> +#include <sstream> + +std::string Battlenet::PacketHeader::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::PacketHeader opcode: " << Opcode << ", channel: " << Channel; + return stream.str(); +} + +Battlenet::ServerPacket::ServerPacket(PacketHeader const& header) : Packet(header, *new BitStream()) +{ + _stream.Write(header.Opcode, 6); + _stream.Write(1, 1); + _stream.Write(header.Channel, 4); +} + +Battlenet::ServerPacket::~ServerPacket() +{ + delete &_stream; +} + +void Battlenet::AuthChallenge::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); + } + + if (_stream.Read<uint32>(1)) + Login = _stream.ReadString(9, 3); +} + +std::string Battlenet::AuthChallenge::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::AuthChallenge Program: " << Program << ", Platform: " << Platform << ", Locale: " << Locale; + for (uint32 i = 0; i < Components.size(); ++i) + stream << std::endl << "Battlenet::AuthChallenge::Component Program: " << Components[i].Program << ", Platform: " << Components[i].Platform << ", Build: " << Components[i].Build; + + if (!Login.empty()) + stream << std::endl << "Battlenet::AuthChallenge Login: " << Login; + + return stream.str(); +} + +void Battlenet::ProofRequest::Write() +{ + _stream.Write(Modules.size(), 3); + for (size_t i = 0; i < Modules.size(); ++i) + { + ModuleInfo& info = Modules[i]; + _stream.WriteBytes(info.AuthString.c_str(), 4); + _stream.WriteFourCC(info.Locale.c_str()); + _stream.WriteBytes(info.ModuleId, 32); + _stream.Write(info.BlobSize, 10); + _stream.WriteBytes(info.Blob, info.BlobSize); + } +} + +Battlenet::ProofResponse::~ProofResponse() +{ + for (size_t i = 0; i < Modules.size(); ++i) + delete[] Modules[i].Data; +} + +void Battlenet::ProofResponse::Read() +{ + Modules.resize(_stream.Read<uint32>(3)); + for (size_t i = 0; i < Modules.size(); ++i) + { + ModuleData& data = Modules[i]; + data.Size = _stream.Read<uint32>(10); + data.Data = _stream.ReadBytes(data.Size); + } +} + +std::string Battlenet::ProofResponse::ToString() const +{ + std::ostringstream stream; + stream << "Battlenet::ProofResponse Modules " << Modules.size(); + for (size_t i = 0; i < Modules.size(); ++i) + { + std::string hexStr = ByteArrayToHexStr(Modules[i].Data, Modules[i].Size); + stream << std::endl << "Battlenet::ProofResponse::ModuleData Size: " << Modules[i].Size << ", Data: " << hexStr; + } + + return stream.str(); +} + +void Battlenet::AuthComplete::Write() +{ + _stream.Write(AuthResult != 0, 1); + if (AuthResult == 0) + { + _stream.Write(Modules.size(), 3); + for (size_t i = 0; i < Modules.size(); ++i) + { + ModuleInfo& info = Modules[i]; + _stream.WriteBytes(info.AuthString.c_str(), 4); + _stream.WriteFourCC(info.Locale.c_str()); + _stream.WriteBytes(info.ModuleId, 32); + _stream.Write(info.BlobSize, 10); + _stream.WriteBytes(info.Blob, info.BlobSize); + } + + _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); + } + } + + // todo more + } + else + { + _stream.Write(!Modules.empty(), 1); + if (!Modules.empty()) + { + ModuleInfo& info = Modules[0]; + _stream.WriteBytes(info.AuthString.c_str(), 4); + _stream.WriteFourCC(info.Locale.c_str()); + _stream.WriteBytes(info.ModuleId, 32); + _stream.Write(info.BlobSize, 10); + _stream.WriteBytes(info.Blob, info.BlobSize); + } + + _stream.Write(ErrorType, 2); + if (ErrorType == 1) + { + _stream.Write(AuthResult, 16); + _stream.Write(0, 32); + } + } +} diff --git a/src/server/authserver/Server/BattlenetPackets.h b/src/server/authserver/Server/BattlenetPackets.h new file mode 100644 index 00000000000..23625e30d2b --- /dev/null +++ b/src/server/authserver/Server/BattlenetPackets.h @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * 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 __BATTLENETPACKETS_H__ +#define __BATTLENETPACKETS_H__ + +#include "Define.h" +#include "Errors.h" +#include <string> + +namespace Battlenet +{ + class BitStream; + + enum Channel + { + NOT_SPECIFIED = -1, + + AUTHENTICATION = 0, + CREEP = 1, + WOW = 2 + }; + + enum AuthOpcode + { + CMSG_AUTH_CHALLENGE = 0x0, + CMSG_AUTH_PROOF_RESPONSE = 0x2, + + SMSG_AUTH_COMPLETE = 0x0, + SMSG_AUTH_PROOF_REQUEST = 0x2, + }; + + struct PacketHeader + { + PacketHeader(uint32 opcode, uint32 channel) : Opcode(opcode), Channel(channel) { } + PacketHeader() : Opcode(0), Channel(NOT_SPECIFIED) { } + + uint32 Opcode; + int32 Channel; + + bool operator<(PacketHeader const& right) const + { + return Opcode < right.Opcode || Channel < right.Channel; + } + + bool operator==(PacketHeader const& right) const + { + return Opcode == right.Opcode && Channel == right.Channel; + } + + std::string ToString() const; + }; + + class Packet + { + public: + Packet(PacketHeader const& header, BitStream& stream) : _header(header), _stream(stream) { } + virtual ~Packet() { } + + PacketHeader const& GetHeader() const { return _header; } + + virtual void Write() = 0; + virtual void Read() = 0; + + virtual std::string ToString() const = 0; + + protected: + PacketHeader _header; + BitStream& _stream; + + private: + Packet(Packet const& right); + Packet& operator=(Packet const& right); + }; + + class ClientPacket : public Packet + { + public: + ClientPacket(PacketHeader const& header, BitStream& stream) : Packet(header, stream) { } + + void Write() override { ASSERT(!"Write not implemented for this packet."); } + + virtual std::string ToString() const override { return "Battenet::ClientPacket"; }; + }; + + class ServerPacket : public Packet + { + public: + ServerPacket(PacketHeader const& header); + ~ServerPacket(); + + void Read() override { ASSERT(!"Read not implemented for server packets."); } + + virtual std::string ToString() const override { return "Battenet::ServerPacket"; }; + + uint8 const* GetData() const { return _stream.GetBuffer(); } + size_t GetSize() const { return _stream.GetSize(); } + }; + + class AuthChallenge final : public ClientPacket + { + public: + AuthChallenge(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_AUTH_CHALLENGE, AUTHENTICATION) && "Invalid packet header for AuthChallenge"); + } + + struct Component + { + std::string Program; + std::string Platform; + uint32 Build; + }; + + void Read() override; + std::string ToString() const override; + + std::string Program; + std::string Platform; + std::string Locale; + std::vector<Component> Components; + std::string Login; + }; + + struct ModuleInfo + { + std::string AuthString; + std::string Locale; + uint8 ModuleId[32]; + uint32 BlobSize; + uint8* Blob; + }; + + class ProofRequest final : public ServerPacket + { + public: + ProofRequest() : ServerPacket(PacketHeader(SMSG_AUTH_PROOF_REQUEST, AUTHENTICATION)) { } + + void Write() override; + + std::vector<ModuleInfo> Modules; + }; + + class ProofResponse final : public ClientPacket + { + public: + ProofResponse(PacketHeader const& header, BitStream& stream) : ClientPacket(header, stream) + { + ASSERT(header == PacketHeader(CMSG_AUTH_PROOF_RESPONSE, AUTHENTICATION) && "Invalid packet header for ProofResponse"); + } + + ~ProofResponse(); + + struct ModuleData + { + uint32 Size; + uint8* Data; + }; + + void Read() override; + std::string ToString() const override; + + std::vector<ModuleData> Modules; + }; + + class AuthComplete final : public ServerPacket + { + public: + AuthComplete() : ServerPacket(PacketHeader(SMSG_AUTH_COMPLETE, AUTHENTICATION)), + AuthResult(0), ErrorType(0), PingTimeout(120000), Threshold(1000000), Rate(1000) + { + } + + void Write() override; + + uint32 AuthResult; + std::vector<ModuleInfo> Modules; + uint32 ErrorType; + + int32 PingTimeout; + uint32 Threshold; + uint32 Rate; + std::string FirstName; + std::string LastName; + }; +} + +#endif // __BATTLENETPACKETS_H__ diff --git a/src/server/authserver/Server/BattlenetSocket.cpp b/src/server/authserver/Server/BattlenetSocket.cpp new file mode 100644 index 00000000000..fb9ca008e8b --- /dev/null +++ b/src/server/authserver/Server/BattlenetSocket.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * 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 "AuthCodes.h" +#include "BattlenetBitStream.h" +#include "BattlenetPackets.h" +#include "BattlenetSocket.h" +#include <map> + +bool Battlenet::Socket::HandleAuthChallenge(PacketHeader& header, BitStream& packet) +{ + AuthChallenge info(header, packet); + info.Read(); + + printf("%s\n", info.ToString().c_str()); + + _accountName = info.Login; + + ProofRequest request; + request.Write(); + _socket.send((char const*)request.GetData(), request.GetSize()); + return true; +} + +bool Battlenet::Socket::HandleAuthProofResponse(PacketHeader& header, BitStream& packet) +{ + ProofResponse response(header, packet); + response.Read(); + + printf("%s\n", response.ToString().c_str()); + + AuthComplete complete; + complete.ErrorType = 1; + complete.AuthResult = AUTH_USE_GRUNT_LOGON; + complete.Write(); + _socket.send((char const*)complete.GetData(), complete.GetSize()); + return true; +} + +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_PROOF_RESPONSE, Battlenet::AUTHENTICATION)] = &Battlenet::Socket::HandleAuthProofResponse; + + return handlers; +} + +std::map<Battlenet::PacketHeader, Battlenet::Socket::PacketHandler> Handlers = InitHandlers(); + +Battlenet::Socket::Socket(RealmSocket& socket) : _socket(socket), _currentChannel(0) +{ +} + +void Battlenet::Socket::OnRead() +{ + while (1) + { + size_t length = _socket.recv_len(); + if (!length) + return; + + BitStream packet(length); + if (!_socket.recv((char*)packet.GetBuffer(), length)) + return; + + while (!packet.IsRead()) + { + try + { + PacketHeader header; + header.Opcode = packet.Read<uint32>(6); + if (packet.Read<uint32>(1)) + _currentChannel = header.Channel = packet.Read<int32>(4); + + printf("Battlenet::Socket::OnRead %s\n", header.ToString().c_str()); + std::map<PacketHeader, PacketHandler>::const_iterator itr = Handlers.find(header); + if (itr != Handlers.end()) + { + if (!(this->*(itr->second))(header, packet)) + { + _socket.shutdown(); + return; + } + } + else + printf("Battlenet::Socket::OnRead Unhandled opcode %s\n", header.ToString().c_str()); + + packet.AlignToNextByte(); + } + catch (BitStreamPositionException const& e) + { + printf("Battlenet::Socket::OnRead Exception: %s\n", e.what()); + _socket.shutdown(); + return; + } + } + } +} + +void Battlenet::Socket::OnAccept() +{ + printf("Battlenet::Socket::OnAccept\n"); +} + +void Battlenet::Socket::OnClose() +{ + printf("Battlenet::Socket::OnClose\n"); +} diff --git a/src/server/authserver/Server/BattlenetSocket.h b/src/server/authserver/Server/BattlenetSocket.h new file mode 100644 index 00000000000..f7cc59d7e97 --- /dev/null +++ b/src/server/authserver/Server/BattlenetSocket.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * 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 _BATTLENETSOCKET_H +#define _BATTLENETSOCKET_H + +#include "RealmSocket.h" +#include "BattlenetPacketCrypt.h" + +namespace Battlenet +{ + struct PacketHeader; + class BitStream; + + class Socket : public RealmSocket::Session + { + public: + Socket(RealmSocket& socket); + + typedef bool(Socket::*PacketHandler)(PacketHeader& socket, BitStream& packet); + + bool HandleAuthChallenge(PacketHeader& header, BitStream& packet); + bool HandleAuthProofResponse(PacketHeader& header, BitStream& packet); + + void OnRead() override; + void OnAccept() override; + void OnClose() override; + + private: + RealmSocket& _socket; + uint32 _currentChannel; + + std::string _accountName; + + PacketCrypt _crypt; + }; + +} + +#endif // _BATTLENETSOCKET_H diff --git a/src/server/authserver/Server/RealmAcceptor.h b/src/server/authserver/Server/RealmAcceptor.h index e89135c4896..2089b0c7a22 100644 --- a/src/server/authserver/Server/RealmAcceptor.h +++ b/src/server/authserver/Server/RealmAcceptor.h @@ -24,7 +24,9 @@ #include "RealmSocket.h" #include "AuthSocket.h" +#include "BattlenetSocket.h" +template<class LoginType> class RealmAcceptor : public ACE_Acceptor<RealmSocket, ACE_SOCK_Acceptor> { public: @@ -42,7 +44,7 @@ protected: ACE_NEW_RETURN(sh, RealmSocket, -1); sh->reactor(reactor()); - sh->set_session(new AuthSocket(*sh)); + sh->set_session(new LoginType(*sh)); return 0; } |
