From a142eb9f7a9683f98fe1e9153f6958f80d374c9d Mon Sep 17 00:00:00 2001 From: Shauren Date: Wed, 30 Apr 2014 20:16:08 +0200 Subject: Core/Auth: Battle.net stuff --- src/server/authserver/Authentication/AuthCodes.h | 51 ++++++ src/server/authserver/Main.cpp | 26 ++- src/server/authserver/Server/BattlenetBitStream.h | 189 +++++++++++++++++++ .../authserver/Server/BattlenetPacketCrypt.cpp | 39 ++++ .../authserver/Server/BattlenetPacketCrypt.h | 36 ++++ src/server/authserver/Server/BattlenetPackets.cpp | 170 +++++++++++++++++ src/server/authserver/Server/BattlenetPackets.h | 202 +++++++++++++++++++++ src/server/authserver/Server/BattlenetSocket.cpp | 124 +++++++++++++ src/server/authserver/Server/BattlenetSocket.h | 54 ++++++ src/server/authserver/Server/RealmAcceptor.h | 4 +- src/server/game/Server/WorldSocket.h | 4 +- src/server/game/Warden/WardenWin.cpp | 4 +- .../Cryptography/Authentication/AuthCrypt.cpp | 73 -------- .../shared/Cryptography/Authentication/AuthCrypt.h | 42 ----- .../Cryptography/Authentication/PacketCrypt.cpp | 39 ++++ .../Cryptography/Authentication/PacketCrypt.h | 43 +++++ .../Authentication/WorldPacketCrypt.cpp | 51 ++++++ .../Cryptography/Authentication/WorldPacketCrypt.h | 34 ++++ src/server/shared/Cryptography/HMACSHA1.cpp | 57 ------ src/server/shared/Cryptography/HMACSHA1.h | 47 ----- src/server/shared/Cryptography/HmacHash.cpp | 59 ++++++ src/server/shared/Cryptography/HmacHash.h | 48 +++++ 22 files changed, 1163 insertions(+), 233 deletions(-) create mode 100644 src/server/authserver/Server/BattlenetBitStream.h create mode 100644 src/server/authserver/Server/BattlenetPacketCrypt.cpp create mode 100644 src/server/authserver/Server/BattlenetPacketCrypt.h create mode 100644 src/server/authserver/Server/BattlenetPackets.cpp create mode 100644 src/server/authserver/Server/BattlenetPackets.h create mode 100644 src/server/authserver/Server/BattlenetSocket.cpp create mode 100644 src/server/authserver/Server/BattlenetSocket.h delete mode 100644 src/server/shared/Cryptography/Authentication/AuthCrypt.cpp delete mode 100644 src/server/shared/Cryptography/Authentication/AuthCrypt.h create mode 100644 src/server/shared/Cryptography/Authentication/PacketCrypt.cpp create mode 100644 src/server/shared/Cryptography/Authentication/PacketCrypt.h create mode 100644 src/server/shared/Cryptography/Authentication/WorldPacketCrypt.cpp create mode 100644 src/server/shared/Cryptography/Authentication/WorldPacketCrypt.h delete mode 100644 src/server/shared/Cryptography/HMACSHA1.cpp delete mode 100644 src/server/shared/Cryptography/HMACSHA1.h create mode 100644 src/server/shared/Cryptography/HmacHash.cpp create mode 100644 src/server/shared/Cryptography/HmacHash.h diff --git a/src/server/authserver/Authentication/AuthCodes.h b/src/server/authserver/Authentication/AuthCodes.h index 5e6522f8981..e844863e4b1 100644 --- a/src/server/authserver/Authentication/AuthCodes.h +++ b/src/server/authserver/Authentication/AuthCodes.h @@ -70,6 +70,57 @@ enum LoginResult LOGIN_LOCKED_ENFORCED = 0x10 }; +namespace Battlenet +{ + enum AuthResult + { + AUTH_OK = 0, + AUTH_BAD_SERVER_PROOF = 103, + AUTH_UNKNOWN_ACCOUNT = 104, + AUTH_CLOSED = 105, + AUTH_LOGIN_TIMEOUT = 106, + AUTH_NO_GAME_ACCOUNTS = 107, + AUTH_INVALID_TOKEN = 108, + AUTH_INVALID_PROGRAM = 109, + AUTH_INVALID_OS = 110, + AUTH_UNSUPPORTED_LANGUAGE = 111, + AUTH_REGION_BAD_VERSION = 112, + AUTH_TEMP_OUTAGE = 113, + AUTH_CANT_DOWNLOAD_MODULE = 114, + AUTH_DUPLICATE_LOGON = 115, + AUTH_BAD_CREDENTIALS_2 = 116, + AUTH_VERSION_CHECK_SUCCEEDED = 117, + AUTH_BAD_VERSION_HASH = 118, + AUTH_CANT_RETRIEVE_PORTAL_LIST = 119, + AUTH_DARK_PORTAL_DOES_NOT_EXIST = 120, + AUTH_DARK_PORTAL_FILE_CORRUPTED = 121, + AUTH_BATTLENET_MAINTENANCE = 122, + AUTH_LOGON_TOO_FAST = 123, + AUTH_USE_GRUNT_LOGON = 124, + + LOGIN_NO_GAME_ACCOUNT = 201, + LOGIN_BANNED = 202, + LOGIN_SUSPENDED = 203, + LOGIN_GAME_ACCOUNT_LOCKED = 204, + LOGIN_ALREADY_ONLINE = 205, + LOGIN_NOTIME = 206, + LOGIN_EXPIRED = 207, + LOGIN_EXPIRED_2 = 208, + LOGIN_PARENTALCONTROL = 209, + LOGIN_TRIAL_EXPIRED = 210, + LOGIN_ANTI_INDULGENCE = 211, + LOGIN_INCORRECT_REGION = 212, + LOGIN_CHARGEBACK = 213, + LOGIN_IGR_WITHOUT_BNET = 214, + LOGIN_LOCKED_ENFORCED = 215, + LOGIN_UNLOCKABLE_LOCK = 216, + LOGIN_IGR_REQUIRED = 217, + LOGIN_PAYMENT_CHANGED = 218, + LOGIN_INVALID_PAYMENT = 219, + LOGIN_INVALID_ACCOUNT_STATE = 220 + }; +} + enum ExpansionFlags { POST_BC_EXP_FLAG = 0x2, diff --git a/src/server/authserver/Main.cpp b/src/server/authserver/Main.cpp index d1b2b614037..0e23dd99ba8 100644 --- a/src/server/authserver/Main.cpp +++ b/src/server/authserver/Main.cpp @@ -151,7 +151,8 @@ extern int main(int argc, char** argv) } // Launch the listening network socket - RealmAcceptor acceptor; + RealmAcceptor acceptor; + RealmAcceptor bnetacceptor; int32 rmport = sConfigMgr->GetIntDefault("RealmServerPort", 3724); if (rmport < 0 || rmport > 0xFFFF) @@ -170,6 +171,13 @@ extern int main(int argc, char** argv) return 1; } + bind_addr.set_port_number(1119); + if (bnetacceptor.open(bind_addr, ACE_Reactor::instance(), ACE_NONBLOCK) == -1) + { + TC_LOG_ERROR("server.authserver", "Auth server can not bind to %s:%d", bind_ip.c_str(), 1119); + return 1; + } + // Initialize the signal handlers AuthServerSignalHandler SignalINT, SignalTERM; @@ -179,24 +187,24 @@ extern int main(int argc, char** argv) Handler.register_handler(SIGTERM, &SignalTERM); #if defined(_WIN32) || defined(__linux__) - + ///- Handle affinity for multiple processors and process priority uint32 affinity = sConfigMgr->GetIntDefault("UseProcessors", 0); bool highPriority = sConfigMgr->GetBoolDefault("ProcessPriority", false); #ifdef _WIN32 // Windows - + HANDLE hProcess = GetCurrentProcess(); if (affinity > 0) { ULONG_PTR appAff; ULONG_PTR sysAff; - + if (GetProcessAffinityMask(hProcess, &appAff, &sysAff)) { // remove non accessible processors ULONG_PTR currentAffinity = affinity & appAff; - + if (!currentAffinity) TC_LOG_ERROR("server.authserver", "Processors marked in UseProcessors bitmask (hex) %x are not accessible for the authserver. Accessible processors bitmask (hex): %x", affinity, appAff); else if (SetProcessAffinityMask(hProcess, currentAffinity)) @@ -205,7 +213,7 @@ extern int main(int argc, char** argv) TC_LOG_ERROR("server.authserver", "Can't set used processors (hex): %x", currentAffinity); } } - + if (highPriority) { if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS)) @@ -213,9 +221,9 @@ extern int main(int argc, char** argv) else TC_LOG_ERROR("server.authserver", "Can't set authserver process priority class."); } - + #else // Linux - + if (affinity > 0) { cpu_set_t mask; @@ -242,7 +250,7 @@ extern int main(int argc, char** argv) else TC_LOG_INFO("server.authserver", "authserver process priority class set to %i", getpriority(PRIO_PROCESS, 0)); } - + #endif #endif 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 + * + * 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 . + */ + +#ifndef __BATTLENETBITSTREAM_H__ +#define __BATTLENETBITSTREAM_H__ + +#include "ByteConverter.h" +#include +#include +#include + +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(bitCount) + baseLength; + AlignToNextByte(); + std::string str(reinterpret_cast(&_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(32); + return *reinterpret_cast(&val); + } + + std::string ReadFourCC() + { + uint32 fcc = Read(32); + EndianConvertReverse(fcc); + size_t len = 4; + while (!(fcc & 0xFF)) + { + fcc >>= 8; + --len; + } + + return std::string(reinterpret_cast(&fcc), len); + } + + template + 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((uint64)(_buffer[_readPos >> 3] >> bitPos & (uint32)((uint8)(1 << bitsLeftInByte) - 1)) << bitCount); + _readPos += bitsLeftInByte; + } + return ret; + } + + //WriteString + + template + 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 + 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 _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 + * + * 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 . + */ + +#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 + * + * 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 . + */ + +#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 + * + * 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 . + */ + +#include "Common.h" +#include "BattlenetBitStream.h" +#include "BattlenetPackets.h" +#include "Util.h" +#include +#include + +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(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(32); + } + + if (_stream.Read(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(3)); + for (size_t i = 0; i < Modules.size(); ++i) + { + ModuleData& data = Modules[i]; + data.Size = _stream.Read(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::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 + * + * 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 . + */ + +#ifndef __BATTLENETPACKETS_H__ +#define __BATTLENETPACKETS_H__ + +#include "Define.h" +#include "Errors.h" +#include + +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 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 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 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 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 + * + * 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 . + */ + +#include "AuthCodes.h" +#include "BattlenetBitStream.h" +#include "BattlenetPackets.h" +#include "BattlenetSocket.h" +#include + +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 InitHandlers() +{ + std::map 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 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(6); + if (packet.Read(1)) + _currentChannel = header.Channel = packet.Read(4); + + printf("Battlenet::Socket::OnRead %s\n", header.ToString().c_str()); + std::map::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 + * + * 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 . + */ + +#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 RealmAcceptor : public ACE_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; } diff --git a/src/server/game/Server/WorldSocket.h b/src/server/game/Server/WorldSocket.h index 4ccacd05c7e..306a50c083a 100644 --- a/src/server/game/Server/WorldSocket.h +++ b/src/server/game/Server/WorldSocket.h @@ -39,7 +39,7 @@ #endif /* ACE_LACKS_PRAGMA_ONCE */ #include "Common.h" -#include "AuthCrypt.h" +#include "WorldPacketCrypt.h" class ACE_Message_Block; class WorldPacket; @@ -176,7 +176,7 @@ class WorldSocket : public WorldHandler std::string m_Address; /// Class used for managing encryption of the headers - AuthCrypt m_Crypt; + WorldPacketCrypt m_Crypt; /// Mutex lock to protect m_Session LockType m_SessionLock; diff --git a/src/server/game/Warden/WardenWin.cpp b/src/server/game/Warden/WardenWin.cpp index 18bf2897358..3014fcfb993 100644 --- a/src/server/game/Warden/WardenWin.cpp +++ b/src/server/game/Warden/WardenWin.cpp @@ -16,7 +16,7 @@ * with this program. If not, see . */ -#include "Cryptography/HMACSHA1.h" +#include "Cryptography/HmacHash.h" #include "Cryptography/WardenKeyGeneration.h" #include "Common.h" #include "WorldPacket.h" @@ -283,7 +283,7 @@ void WardenWin::RequestData() { uint32 seed = static_cast(rand32()); buff << uint32(seed); - HmacHash hmac(4, (uint8*)&seed); + HmacHash hmac(4, (uint8*)&seed, EVP_sha1(), SHA_DIGEST_LENGTH); hmac.UpdateData(wd->Str); hmac.Finalize(); buff.append(hmac.GetDigest(), hmac.GetLength()); diff --git a/src/server/shared/Cryptography/Authentication/AuthCrypt.cpp b/src/server/shared/Cryptography/Authentication/AuthCrypt.cpp deleted file mode 100644 index ff94f307254..00000000000 --- a/src/server/shared/Cryptography/Authentication/AuthCrypt.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * Copyright (C) 2005-2009 MaNGOS - * - * 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 . - */ - -#include "AuthCrypt.h" -#include "Cryptography/HMACSHA1.h" -#include "Cryptography/BigNumber.h" - -AuthCrypt::AuthCrypt() : - _clientDecrypt(SHA_DIGEST_LENGTH), _serverEncrypt(SHA_DIGEST_LENGTH), - _initialized(false) -{ } - -void AuthCrypt::Init(BigNumber* K) -{ - uint8 ServerEncryptionKey[SEED_KEY_SIZE] = { 0xCC, 0x98, 0xAE, 0x04, 0xE8, 0x97, 0xEA, 0xCA, 0x12, 0xDD, 0xC0, 0x93, 0x42, 0x91, 0x53, 0x57 }; - HmacHash serverEncryptHmac(SEED_KEY_SIZE, (uint8*)ServerEncryptionKey); - uint8 *encryptHash = serverEncryptHmac.ComputeHash(K); - - uint8 ServerDecryptionKey[SEED_KEY_SIZE] = { 0xC2, 0xB3, 0x72, 0x3C, 0xC6, 0xAE, 0xD9, 0xB5, 0x34, 0x3C, 0x53, 0xEE, 0x2F, 0x43, 0x67, 0xCE }; - HmacHash clientDecryptHmac(SEED_KEY_SIZE, (uint8*)ServerDecryptionKey); - uint8 *decryptHash = clientDecryptHmac.ComputeHash(K); - - //ARC4 _serverDecrypt(encryptHash); - _clientDecrypt.Init(decryptHash); - _serverEncrypt.Init(encryptHash); - //ARC4 _clientEncrypt(decryptHash); - - // Drop first 1024 bytes, as WoW uses ARC4-drop1024. - uint8 syncBuf[1024]; - memset(syncBuf, 0, 1024); - - _serverEncrypt.UpdateData(1024, syncBuf); - //_clientEncrypt.UpdateData(1024, syncBuf); - - memset(syncBuf, 0, 1024); - - //_serverDecrypt.UpdateData(1024, syncBuf); - _clientDecrypt.UpdateData(1024, syncBuf); - - _initialized = true; -} - -void AuthCrypt::DecryptRecv(uint8 *data, size_t len) -{ - if (!_initialized) - return; - - _clientDecrypt.UpdateData(len, data); -} - -void AuthCrypt::EncryptSend(uint8 *data, size_t len) -{ - if (!_initialized) - return; - - _serverEncrypt.UpdateData(len, data); -} - diff --git a/src/server/shared/Cryptography/Authentication/AuthCrypt.h b/src/server/shared/Cryptography/Authentication/AuthCrypt.h deleted file mode 100644 index 8fa150068a2..00000000000 --- a/src/server/shared/Cryptography/Authentication/AuthCrypt.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * Copyright (C) 2005-2009 MaNGOS - * - * 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 . - */ - -#ifndef _AUTHCRYPT_H -#define _AUTHCRYPT_H - -#include "Cryptography/ARC4.h" - -class BigNumber; - -class AuthCrypt -{ - public: - AuthCrypt(); - - void Init(BigNumber* K); - void DecryptRecv(uint8 *, size_t); - void EncryptSend(uint8 *, size_t); - - bool IsInitialized() const { return _initialized; } - - private: - ARC4 _clientDecrypt; - ARC4 _serverEncrypt; - bool _initialized; -}; -#endif diff --git a/src/server/shared/Cryptography/Authentication/PacketCrypt.cpp b/src/server/shared/Cryptography/Authentication/PacketCrypt.cpp new file mode 100644 index 00000000000..7fac311b8a2 --- /dev/null +++ b/src/server/shared/Cryptography/Authentication/PacketCrypt.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * 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 . + */ + +#include "PacketCrypt.h" + +PacketCrypt::PacketCrypt(uint32 rc4InitSize) + : _clientDecrypt(rc4InitSize), _serverEncrypt(rc4InitSize), _initialized(false) +{ +} + +void PacketCrypt::DecryptRecv(uint8* data, size_t len) +{ + if (!_initialized) + return; + + _clientDecrypt.UpdateData(len, data); +} + +void PacketCrypt::EncryptSend(uint8* data, size_t len) +{ + if (!_initialized) + return; + + _serverEncrypt.UpdateData(len, data); +} diff --git a/src/server/shared/Cryptography/Authentication/PacketCrypt.h b/src/server/shared/Cryptography/Authentication/PacketCrypt.h new file mode 100644 index 00000000000..36f3b81fb53 --- /dev/null +++ b/src/server/shared/Cryptography/Authentication/PacketCrypt.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * + * 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 . + */ + +#ifndef _PACKETCRYPT_H +#define _PACKETCRYPT_H + +#include "Cryptography/ARC4.h" + +class BigNumber; + +class PacketCrypt +{ + public: + PacketCrypt(uint32 rc4InitSize); + virtual ~PacketCrypt() { } + + virtual void Init(BigNumber* K) = 0; + void DecryptRecv(uint8* data, size_t length); + void EncryptSend(uint8* data, size_t length); + + bool IsInitialized() const { return _initialized; } + + protected: + ARC4 _clientDecrypt; + ARC4 _serverEncrypt; + bool _initialized; +}; + +#endif // _PACKETCRYPT_H diff --git a/src/server/shared/Cryptography/Authentication/WorldPacketCrypt.cpp b/src/server/shared/Cryptography/Authentication/WorldPacketCrypt.cpp new file mode 100644 index 00000000000..c6b283d9961 --- /dev/null +++ b/src/server/shared/Cryptography/Authentication/WorldPacketCrypt.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * Copyright (C) 2005-2009 MaNGOS + * + * 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 . + */ + +#include "WorldPacketCrypt.h" +#include "Cryptography/HmacHash.h" +#include "Cryptography/BigNumber.h" + +WorldPacketCrypt::WorldPacketCrypt() : PacketCrypt(SHA_DIGEST_LENGTH) +{ +} + +void WorldPacketCrypt::Init(BigNumber* K) +{ + uint8 ServerEncryptionKey[SEED_KEY_SIZE] = { 0xCC, 0x98, 0xAE, 0x04, 0xE8, 0x97, 0xEA, 0xCA, 0x12, 0xDD, 0xC0, 0x93, 0x42, 0x91, 0x53, 0x57 }; + HmacHash serverEncryptHmac(SEED_KEY_SIZE, (uint8*)ServerEncryptionKey, EVP_sha1(), SHA_DIGEST_LENGTH); + uint8 *encryptHash = serverEncryptHmac.ComputeHash(K); + + uint8 ServerDecryptionKey[SEED_KEY_SIZE] = { 0xC2, 0xB3, 0x72, 0x3C, 0xC6, 0xAE, 0xD9, 0xB5, 0x34, 0x3C, 0x53, 0xEE, 0x2F, 0x43, 0x67, 0xCE }; + HmacHash clientDecryptHmac(SEED_KEY_SIZE, (uint8*)ServerDecryptionKey, EVP_sha1(), SHA_DIGEST_LENGTH); + uint8 *decryptHash = clientDecryptHmac.ComputeHash(K); + + _clientDecrypt.Init(decryptHash); + _serverEncrypt.Init(encryptHash); + + // Drop first 1024 bytes, as WoW uses ARC4-drop1024. + uint8 syncBuf[1024]; + memset(syncBuf, 0, 1024); + + _serverEncrypt.UpdateData(1024, syncBuf); + + memset(syncBuf, 0, 1024); + + _clientDecrypt.UpdateData(1024, syncBuf); + + _initialized = true; +} diff --git a/src/server/shared/Cryptography/Authentication/WorldPacketCrypt.h b/src/server/shared/Cryptography/Authentication/WorldPacketCrypt.h new file mode 100644 index 00000000000..7ccca11f09d --- /dev/null +++ b/src/server/shared/Cryptography/Authentication/WorldPacketCrypt.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * Copyright (C) 2005-2009 MaNGOS + * + * 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 . + */ + +#ifndef _WORLDPACKETCRYPT_H +#define _WORLDPACKETCRYPT_H + +#include "PacketCrypt.h" + +class BigNumber; + +class WorldPacketCrypt : public PacketCrypt +{ + public: + WorldPacketCrypt(); + + void Init(BigNumber* K) override; +}; + +#endif // _WORLDPACKETCRYPT_H diff --git a/src/server/shared/Cryptography/HMACSHA1.cpp b/src/server/shared/Cryptography/HMACSHA1.cpp deleted file mode 100644 index 2148a3b8a7b..00000000000 --- a/src/server/shared/Cryptography/HMACSHA1.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * Copyright (C) 2005-2009 MaNGOS - * - * 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 . - */ - -#include "HMACSHA1.h" -#include "BigNumber.h" -#include "Common.h" - -HmacHash::HmacHash(uint32 len, uint8 *seed) -{ - HMAC_CTX_init(&m_ctx); - HMAC_Init_ex(&m_ctx, seed, len, EVP_sha1(), NULL); - memset(m_digest, 0, sizeof(m_digest)); -} - -HmacHash::~HmacHash() -{ - HMAC_CTX_cleanup(&m_ctx); -} - -void HmacHash::UpdateData(const std::string &str) -{ - HMAC_Update(&m_ctx, (uint8 const*)str.c_str(), str.length()); -} - -void HmacHash::UpdateData(const uint8* data, size_t len) -{ - HMAC_Update(&m_ctx, data, len); -} - -void HmacHash::Finalize() -{ - uint32 length = 0; - HMAC_Final(&m_ctx, (uint8*)m_digest, &length); - ASSERT(length == SHA_DIGEST_LENGTH); -} - -uint8 *HmacHash::ComputeHash(BigNumber* bn) -{ - HMAC_Update(&m_ctx, bn->AsByteArray().get(), bn->GetNumBytes()); - Finalize(); - return (uint8*)m_digest; -} diff --git a/src/server/shared/Cryptography/HMACSHA1.h b/src/server/shared/Cryptography/HMACSHA1.h deleted file mode 100644 index de1556d3c98..00000000000 --- a/src/server/shared/Cryptography/HMACSHA1.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore - * Copyright (C) 2005-2009 MaNGOS - * - * 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 . - */ - -#ifndef _AUTH_HMAC_H -#define _AUTH_HMAC_H - -#include "Define.h" -#include -#include -#include - -class BigNumber; - -#define SEED_KEY_SIZE 16 - -class HmacHash -{ - public: - HmacHash(uint32 len, uint8 *seed); - ~HmacHash(); - void UpdateData(const std::string &str); - void UpdateData(const uint8* data, size_t len); - void Finalize(); - uint8 *ComputeHash(BigNumber* bn); - uint8 *GetDigest() { return (uint8*)m_digest; } - int GetLength() const { return SHA_DIGEST_LENGTH; } - private: - HMAC_CTX m_ctx; - uint8 m_digest[SHA_DIGEST_LENGTH]; -}; -#endif - diff --git a/src/server/shared/Cryptography/HmacHash.cpp b/src/server/shared/Cryptography/HmacHash.cpp new file mode 100644 index 00000000000..7a365ade457 --- /dev/null +++ b/src/server/shared/Cryptography/HmacHash.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * Copyright (C) 2005-2009 MaNGOS + * + * 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 . + */ + +#include "HmacHash.h" +#include "BigNumber.h" +#include "Common.h" + +HmacHash::HmacHash(uint32 len, uint8 *seed, EVP_MD const* hasher, uint32 digestLength) +{ + HMAC_CTX_init(&_ctx); + HMAC_Init_ex(&_ctx, seed, len, hasher, NULL); + _digest = new uint8[digestLength]; + memset(_digest, 0, digestLength); +} + +HmacHash::~HmacHash() +{ + HMAC_CTX_cleanup(&_ctx); + delete[] _digest; +} + +void HmacHash::UpdateData(const std::string &str) +{ + HMAC_Update(&_ctx, (uint8 const*)str.c_str(), str.length()); +} + +void HmacHash::UpdateData(const uint8* data, size_t len) +{ + HMAC_Update(&_ctx, data, len); +} + +void HmacHash::Finalize() +{ + uint32 length = 0; + HMAC_Final(&_ctx, _digest, &length); + ASSERT(length == _digestLength); +} + +uint8* HmacHash::ComputeHash(BigNumber* bn) +{ + HMAC_Update(&_ctx, bn->AsByteArray().get(), bn->GetNumBytes()); + Finalize(); + return _digest; +} diff --git a/src/server/shared/Cryptography/HmacHash.h b/src/server/shared/Cryptography/HmacHash.h new file mode 100644 index 00000000000..cf59e16f08e --- /dev/null +++ b/src/server/shared/Cryptography/HmacHash.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2008-2014 TrinityCore + * Copyright (C) 2005-2009 MaNGOS + * + * 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 . + */ + +#ifndef _AUTH_HMAC_H +#define _AUTH_HMAC_H + +#include "Define.h" +#include +#include +#include + +class BigNumber; + +#define SEED_KEY_SIZE 16 + +class HmacHash +{ + public: + HmacHash(uint32 len, uint8 *seed, EVP_MD const* hasher, uint32 digestLength); + ~HmacHash(); + void UpdateData(const std::string &str); + void UpdateData(const uint8* data, size_t len); + void Finalize(); + uint8* ComputeHash(BigNumber* bn); + uint8* GetDigest() { return _digest; } + int GetLength() const { return SHA_DIGEST_LENGTH; } + private: + HMAC_CTX _ctx; + uint8* _digest; + uint32 _digestLength; +}; + +#endif -- cgit v1.2.3