aboutsummaryrefslogtreecommitdiff
path: root/src/server/authserver/Server
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2014-04-30 20:16:08 +0200
committerShauren <shauren.trinity@gmail.com>2014-04-30 20:50:15 +0200
commita142eb9f7a9683f98fe1e9153f6958f80d374c9d (patch)
tree5522fe49d1628ed6969b1bd6393b9e36b6b2f10b /src/server/authserver/Server
parentcdae208b9a47cf056330b4ded6b0f8201a7ad9e6 (diff)
Core/Auth: Battle.net stuff
Diffstat (limited to 'src/server/authserver/Server')
-rw-r--r--src/server/authserver/Server/BattlenetBitStream.h189
-rw-r--r--src/server/authserver/Server/BattlenetPacketCrypt.cpp39
-rw-r--r--src/server/authserver/Server/BattlenetPacketCrypt.h36
-rw-r--r--src/server/authserver/Server/BattlenetPackets.cpp170
-rw-r--r--src/server/authserver/Server/BattlenetPackets.h202
-rw-r--r--src/server/authserver/Server/BattlenetSocket.cpp124
-rw-r--r--src/server/authserver/Server/BattlenetSocket.h54
-rw-r--r--src/server/authserver/Server/RealmAcceptor.h4
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;
}