mirror of
https://github.com/thunderbrewhq/thunderbrew
synced 2025-04-15 17:46:03 +03:00
feat(net): handle realm server auth challenge
This commit is contained in:
parent
0b7970101a
commit
5d11881372
@ -140,7 +140,7 @@ void NetClient::Connect(const char* addrStr) {
|
||||
port = atoi(portDelim + 1);
|
||||
}
|
||||
|
||||
this->m_serverConnection->SetEncryptionType(WC_ENCRYPT_0);
|
||||
this->m_serverConnection->SetEncryption(false);
|
||||
this->m_netState = NS_INITIALIZED;
|
||||
this->ConnectInternal(host, port);
|
||||
}
|
||||
@ -166,6 +166,21 @@ void NetClient::DelRef() {
|
||||
}
|
||||
}
|
||||
|
||||
void NetClient::EnableEncryption(WowConnection* conn, uint8_t* seed, uint8_t seedLen) {
|
||||
conn->SetEncryptionKey(
|
||||
this->m_loginData.m_sessionKey,
|
||||
sizeof(this->m_loginData.m_sessionKey),
|
||||
1,
|
||||
seed,
|
||||
seedLen
|
||||
);
|
||||
|
||||
conn->uint375 = 4;
|
||||
conn->uint376 = 2;
|
||||
|
||||
conn->SetEncryption(true);
|
||||
}
|
||||
|
||||
bool NetClient::GetDelete() {
|
||||
return this->m_deleteMe;
|
||||
}
|
||||
@ -261,6 +276,12 @@ void NetClient::Send(CDataStore* msg) {
|
||||
this->m_serverConnection->Send(msg, 0);
|
||||
|
||||
// TODO
|
||||
|
||||
this->m_bytesSent += v4;
|
||||
|
||||
if (!this->m_serverConnection->m_encrypt) {
|
||||
this->EnableEncryption(this->m_serverConnection, nullptr, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,6 +64,7 @@ class NetClient : public WowConnectionResponse {
|
||||
void Connect(const char* addrStr);
|
||||
int32_t ConnectInternal(const char* host, uint16_t port);
|
||||
void DelRef();
|
||||
void EnableEncryption(WowConnection* conn, uint8_t* seed, uint8_t seedLen);
|
||||
bool GetDelete();
|
||||
const LoginData& GetLoginData();
|
||||
NETSTATE GetState();
|
||||
|
@ -1,5 +1,8 @@
|
||||
#include "net/connection/RealmConnection.hpp"
|
||||
#include "net/Types.hpp"
|
||||
#include <common/DataStore.hpp>
|
||||
#include <common/SHA1.hpp>
|
||||
#include <storm/String.hpp>
|
||||
|
||||
SCritSect RealmConnection::s_AllRealmConnectionsCrit;
|
||||
STORM_LIST(RealmConnection::REALMCONNECTIONNODE) RealmConnection::s_AllRealmConnections;
|
||||
@ -46,6 +49,53 @@ RealmConnection::RealmConnection(RealmResponse* realmResponse) {
|
||||
|
||||
int32_t RealmConnection::HandleAuthChallenge(AuthenticationChallenge* challenge) {
|
||||
// TODO
|
||||
|
||||
// TODO switch to WDataStore
|
||||
CDataStore msg;
|
||||
|
||||
uint32_t localChallenge;
|
||||
|
||||
msg.Put(static_cast<uint32_t>(CMSG_AUTH_SESSION));
|
||||
|
||||
msg.Put(static_cast<uint32_t>(12340));
|
||||
msg.Put(static_cast<uint32_t>(this->GetLoginData().m_loginServerID));
|
||||
msg.PutString(this->GetLoginData().m_account);
|
||||
msg.Put(static_cast<uint32_t>(this->GetLoginData().m_loginServerType));
|
||||
|
||||
// TODO
|
||||
msg.Put(localChallenge);
|
||||
|
||||
// TODO
|
||||
msg.Put(static_cast<uint32_t>(0));
|
||||
msg.Put(static_cast<uint32_t>(0));
|
||||
msg.Put(static_cast<uint32_t>(1));
|
||||
|
||||
// TODO
|
||||
msg.Put(static_cast<uint64_t>(0));
|
||||
|
||||
uint32_t msgId = 0;
|
||||
|
||||
SHA1_CONTEXT ctx;
|
||||
SHA1_Init(&ctx);
|
||||
|
||||
SHA1_Update(&ctx, reinterpret_cast<const uint8_t*>(this->GetLoginData().m_account), SStrLen(this->GetLoginData().m_account));
|
||||
SHA1_Update(&ctx, reinterpret_cast<uint8_t*>(&msgId), sizeof(msgId));
|
||||
SHA1_Update(&ctx, reinterpret_cast<uint8_t*>(&localChallenge), sizeof(localChallenge));
|
||||
SHA1_Update(&ctx, reinterpret_cast<uint8_t*>(&challenge->uint0), sizeof(challenge->uint0));
|
||||
SHA1_Update(&ctx, this->GetLoginData().m_sessionKey, sizeof(this->GetLoginData().m_sessionKey));
|
||||
|
||||
uint8_t clientProof[SHA1_DIGEST_SIZE];
|
||||
SHA1_Final(clientProof, &ctx);
|
||||
|
||||
msg.PutData(clientProof, sizeof(clientProof));
|
||||
|
||||
// TODO addons
|
||||
msg.Put(static_cast<uint32_t>(0));
|
||||
|
||||
msg.Finalize();
|
||||
|
||||
this->Send(&msg);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "net/connection/WowConnection.hpp"
|
||||
#include "net/connection/WowConnectionNet.hpp"
|
||||
#include "net/connection/WowConnectionResponse.hpp"
|
||||
#include "util/HMAC.hpp"
|
||||
#include <common/DataStore.hpp>
|
||||
#include <common/Time.hpp>
|
||||
#include <storm/Error.hpp>
|
||||
@ -33,6 +34,15 @@ WowConnectionNet* WowConnection::s_network;
|
||||
ATOMIC32 WowConnection::s_numWowConnections;
|
||||
bool (*WowConnection::s_verifyAddr)(const NETADDR*);
|
||||
|
||||
static uint8_t s_arc4drop1024[1024] = { 0x00 };
|
||||
static uint8_t s_arc4seed[] = {
|
||||
// Receive key
|
||||
0xCC, 0x98, 0xAE, 0x04, 0xE8, 0x97, 0xEA, 0xCA, 0x12, 0xDD, 0xC0, 0x93, 0x42, 0x91, 0x53, 0x57,
|
||||
|
||||
// Send key
|
||||
0xC2, 0xB3, 0x72, 0x3C, 0xC6, 0xAE, 0xD9, 0xB5, 0x34, 0x3C, 0x53, 0xEE, 0x2F, 0x43, 0x67, 0xCE,
|
||||
};
|
||||
|
||||
WowConnection::SENDNODE::SENDNODE(void* data, int32_t size, uint8_t* buf, bool raw) : TSLinkedNode<WowConnection::SENDNODE>() {
|
||||
if (data) {
|
||||
this->data = buf;
|
||||
@ -451,7 +461,18 @@ void WowConnection::DoMessageReads() {
|
||||
}
|
||||
|
||||
if (this->m_encrypt) {
|
||||
// TODO encryption
|
||||
auto v22 = headerSize + this->uint376 - this->m_readBytes;
|
||||
auto v23 = v22 <= 0 ? 0 : v22;
|
||||
if (v23 >= bytesRead) {
|
||||
v23 = bytesRead;
|
||||
}
|
||||
|
||||
SARC4ProcessBuffer(
|
||||
&this->m_readBuffer[this->m_readBytes],
|
||||
v23,
|
||||
&this->m_receiveKey,
|
||||
&this->m_receiveKey
|
||||
);
|
||||
}
|
||||
|
||||
this->m_readBytes += bytesRead;
|
||||
@ -832,8 +853,43 @@ WC_SEND_RESULT WowConnection::SendRaw(uint8_t* data, int32_t len, bool a4) {
|
||||
return WC_SEND_ERROR;
|
||||
}
|
||||
|
||||
void WowConnection::SetEncryptionType(WC_ENCRYPT_TYPE encryptType) {
|
||||
// TODO
|
||||
void WowConnection::SetEncryption(bool enabled) {
|
||||
this->m_lock.Enter();
|
||||
|
||||
this->m_encrypt = enabled;
|
||||
|
||||
SARC4PrepareKey(this->m_sendKeyInit, sizeof(this->m_sendKeyInit), &this->m_sendKey);
|
||||
SARC4PrepareKey(this->m_receiveKeyInit, sizeof(this->m_receiveKeyInit), &this->m_receiveKey);
|
||||
|
||||
SARC4ProcessBuffer(s_arc4drop1024, sizeof(s_arc4drop1024), &this->m_sendKey, &this->m_sendKey);
|
||||
SARC4ProcessBuffer(s_arc4drop1024, sizeof(s_arc4drop1024), &this->m_receiveKey, &this->m_receiveKey);
|
||||
|
||||
this->m_lock.Leave();
|
||||
}
|
||||
|
||||
void WowConnection::SetEncryptionKey(const uint8_t* key, uint8_t keyLen, uint8_t a4, const uint8_t* seedData, uint8_t seedLen) {
|
||||
if (!seedData) {
|
||||
seedData = s_arc4seed;
|
||||
seedLen = sizeof(s_arc4seed);
|
||||
}
|
||||
|
||||
const uint8_t* seeds[] = {
|
||||
seedData,
|
||||
&seedData[seedLen / 2]
|
||||
};
|
||||
|
||||
// Note: The original HMAC-SHA1 implementation uses a second SHA1 implementation shipped in
|
||||
// the client. For simplicity's sake, we're currently using a custom util function built on
|
||||
// top of the SHA1 implementation used for SRP6 authentication.
|
||||
|
||||
HMAC_SHA1(seeds[a4], seedLen / 2, key, keyLen, this->m_sendKeyInit);
|
||||
HMAC_SHA1(seeds[a4 ^ 1], seedLen / 2, key, keyLen, this->m_receiveKeyInit);
|
||||
|
||||
SARC4PrepareKey(this->m_sendKeyInit, sizeof(this->m_sendKeyInit), &this->m_sendKey);
|
||||
SARC4PrepareKey(this->m_receiveKeyInit, sizeof(this->m_receiveKeyInit), &this->m_receiveKey);
|
||||
|
||||
SARC4ProcessBuffer(s_arc4drop1024, sizeof(s_arc4drop1024), &this->m_sendKey, &this->m_sendKey);
|
||||
SARC4ProcessBuffer(s_arc4drop1024, sizeof(s_arc4drop1024), &this->m_receiveKey, &this->m_receiveKey);
|
||||
}
|
||||
|
||||
void WowConnection::SetState(WOW_CONN_STATE state) {
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "net/Types.hpp"
|
||||
#include <cstdint>
|
||||
#include <storm/Atomic.hpp>
|
||||
#include <storm/Crypto.hpp>
|
||||
#include <storm/List.hpp>
|
||||
#include <storm/Thread.hpp>
|
||||
|
||||
@ -70,7 +71,13 @@ class WowConnection {
|
||||
ATOMIC32 m_serviceCount;
|
||||
void* m_event;
|
||||
WOWC_TYPE m_type;
|
||||
SARC4Key m_sendKey;
|
||||
SARC4Key m_receiveKey;
|
||||
uint8_t m_sendKeyInit[20];
|
||||
uint8_t m_receiveKeyInit[20];
|
||||
bool m_encrypt;
|
||||
uint8_t uint375;
|
||||
uint8_t uint376;
|
||||
|
||||
// Member functions
|
||||
WowConnection(WowConnectionResponse* response, void (*func)(void));
|
||||
@ -97,7 +104,8 @@ class WowConnection {
|
||||
void ReleaseResponseRef();
|
||||
WC_SEND_RESULT Send(CDataStore* msg, int32_t a3);
|
||||
WC_SEND_RESULT SendRaw(uint8_t* data, int32_t len, bool a4);
|
||||
void SetEncryptionType(WC_ENCRYPT_TYPE encryptType);
|
||||
void SetEncryption(bool enabled);
|
||||
void SetEncryptionKey(const uint8_t* key, uint8_t keyLen, uint8_t a4, const uint8_t* seed, uint8_t seedLen);
|
||||
void SetState(WOW_CONN_STATE state);
|
||||
void SetType(WOWC_TYPE type);
|
||||
void StartConnect();
|
||||
|
Loading…
Reference in New Issue
Block a user