feat(net): process CMD_AUTH_LOGON_CHALLENGE command

This commit is contained in:
fallenoak 2023-01-08 22:40:29 -06:00 committed by GitHub
parent 4d63d1ea8b
commit 59a0883529
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 232 additions and 1 deletions

View File

@ -2,6 +2,8 @@
#include "net/connection/WowConnection.hpp"
#include "net/grunt/ClientResponse.hpp"
#include "net/grunt/Command.hpp"
#include "net/srp/SRP6_Random.hpp"
#include <cstring>
#include <new>
#include <storm/Memory.hpp>
#include <storm/String.hpp>
@ -45,8 +47,160 @@ void Grunt::ClientLink::Call() {
}
int32_t Grunt::ClientLink::CmdAuthLogonChallenge(CDataStore& msg) {
if (msg.m_read > msg.m_size || msg.m_size - msg.m_read < 2) {
return 0;
}
uint8_t v30;
msg.Get(v30);
if (v30 != 0) {
return 1;
}
uint8_t result;
msg.Get(result);
// Auth failure (success == 0)
if (result != 0) {
if (msg.m_read > msg.m_size) {
return 1;
}
this->SetState(2);
if (result >= GRUNT_RESULT_LAST) {
// TODO WLog error
}
this->m_clientResponse->LogonResult(static_cast<Grunt::Result>(result), nullptr, 0, 0);
return 2;
}
if (msg.m_read > msg.m_size) {
return 0;
}
if (msg.m_size - msg.m_read < 33) {
return 0;
}
uint8_t* serverPublicKey;
msg.GetDataInSitu(reinterpret_cast<void*&>(serverPublicKey), 32);
uint8_t generatorLen;
msg.Get(generatorLen);
// TODO
return 0;
// if (!msg.Sub8CBBF0(v31 + 1)) {
// return 0;
// }
uint8_t* generator;
msg.GetDataInSitu(reinterpret_cast<void*&>(generator), generatorLen);
uint8_t largeSafePrimeLen;
msg.Get(largeSafePrimeLen);
// TODO
// if (!msg.sub_8CBBF0(v32 + 48)) {
// return 0;
// }
uint8_t* largeSafePrime;
msg.GetDataInSitu(reinterpret_cast<void*&>(largeSafePrime), largeSafePrimeLen);
uint8_t* salt;
msg.GetDataInSitu(reinterpret_cast<void*&>(salt), 32);
uint8_t* crcSalt;
msg.GetDataInSitu(reinterpret_cast<void*&>(crcSalt), 16);
// TODO
// if (!msg.Sub8CBBF0(1)) {
// return 0;
// }
uint8_t logonFlags;
msg.Get(logonFlags);
uint32_t pinGridSeed = 0;
uint8_t* pinSalt = nullptr;
uint8_t matrixWidth = 0;
uint8_t matrixHeight = 0;
uint8_t matrixDigitCount = 0;
uint8_t matrixChallengeCount = 0;
uint64_t matrixSeed = 0;
uint8_t tokenRequired = 0;
// PIN
if (logonFlags & 0x1) {
// TODO
// if (!msg.Sub8CBBF0(20)) {
// return 0;
// }
msg.Get(pinGridSeed);
msg.GetDataInSitu(reinterpret_cast<void*&>(pinSalt), 16);
}
// MATRIX
if (logonFlags & 0x2) {
// TODO
/*
if (msg.Sub8CBBF0(12)) {
msg.Get(matrixWidth);
msg.Get(matrixHeight);
msg.Get(matrixDigitCount);
msg.Get(matrixChallengeCount);
msg.Get(matrixSeed);
if ((logonFlags & 0x2) && matrixChallengeCount == 0) {
return 1;
}
} else {
return 0;
}
*/
}
// TOKEN (authenticator)
if (logonFlags & 0x4) {
// TODO
// if (!msg.Sub8CBBF0(1)) {
// return 0;
// }
msg.Get(tokenRequired);
}
if (msg.m_read > msg.m_size) {
return 1;
}
memcpy(this->m_serverPublicKey, serverPublicKey, sizeof(this->m_serverPublicKey));
char randomSeed[16];
// TODO
// OsSecureRandom(randomSeed, sizeof(randomSeed));
SRP6_Random srpRandom(randomSeed, sizeof(randomSeed));
if (this->m_srpClient.CalculateProof(largeSafePrime, largeSafePrimeLen, generator, generatorLen, salt, 32, serverPublicKey, 32, srpRandom)) {
this->SetState(2);
this->m_clientResponse->LogonResult(GRUNT_RESULT_5, nullptr, 0, 0);
} else {
this->SetState(4);
this->m_clientResponse->SetPinInfo(logonFlags & 0x1, pinGridSeed, pinSalt);
// TODO
// this->m_clientResponse->SetMatrixInfo(logonFlags & 0x2, matrixWidth, matrixHeight, matrixDigitCount, matrixDigitCount, 0, matrixChallengeCount, matrixSeed, this->m_srpClient.buf20, 40);
this->m_clientResponse->SetTokenInfo(logonFlags & 0x4, tokenRequired);
this->m_clientResponse->GetVersionProof(crcSalt);
}
return 2;
}
int32_t Grunt::ClientLink::CmdAuthLogonProof(CDataStore& msg) {

View File

@ -48,6 +48,7 @@ class Grunt::ClientLink : public WowConnectionResponse, Grunt::Pending, Grunt::T
WowConnection* m_connection = nullptr;
ClientResponse* m_clientResponse;
char m_accountName[1280];
char m_serverPublicKey[32];
// Virtual member functions
virtual void WCConnected(WowConnection* conn, WowConnection* inbound, uint32_t timeStamp, const NETCONNADDR* addr);

View File

@ -11,6 +11,11 @@ class Grunt::ClientResponse {
virtual bool Connected(const NETADDR& addr) = 0;
virtual bool OnlineIdle() = 0;
virtual void GetLogonMethod() = 0;
virtual void GetVersionProof(const uint8_t* a2) = 0;
virtual void SetPinInfo(bool enabled, uint32_t a3, const uint8_t* a4) = 0;
virtual void SetMatrixInfo(bool enabled, uint8_t a3, uint8_t a4, uint8_t a5, uint8_t a6, bool a7, uint8_t a8, uint64_t a9, const uint8_t* a10, uint32_t a11) = 0;
virtual void SetTokenInfo(bool enabled, uint8_t required) = 0;
virtual void LogonResult(Result result, const uint8_t* a3, uint32_t a4, uint16_t a5) = 0;
virtual void GetRealmList() = 0;
virtual void Logon(const char* a2, const char* a3) = 0;
virtual void Logoff() = 0;

View File

@ -10,6 +10,43 @@ namespace Grunt {
class Timer;
extern Command<ClientLink> s_clientCommands[];
enum Result {
GRUNT_RESULT_0 = 0,
GRUNT_RESULT_1 = 1,
GRUNT_RESULT_2 = 2,
GRUNT_RESULT_3 = 3,
GRUNT_RESULT_4 = 4,
GRUNT_RESULT_5 = 5,
GRUNT_RESULT_6 = 6,
GRUNT_RESULT_7 = 7,
GRUNT_RESULT_8 = 8,
GRUNT_RESULT_9 = 9,
GRUNT_RESULT_10 = 10,
GRUNT_RESULT_11 = 11,
GRUNT_RESULT_12 = 12,
GRUNT_RESULT_13 = 13,
GRUNT_RESULT_14 = 14,
GRUNT_RESULT_15 = 15,
GRUNT_RESULT_16 = 16,
GRUNT_RESULT_17 = 17,
GRUNT_RESULT_18 = 18,
GRUNT_RESULT_19 = 19,
GRUNT_RESULT_20 = 20,
GRUNT_RESULT_21 = 21,
GRUNT_RESULT_22 = 22,
GRUNT_RESULT_23 = 23,
GRUNT_RESULT_24 = 24,
GRUNT_RESULT_25 = 25,
GRUNT_RESULT_26 = 26,
GRUNT_RESULT_27 = 27,
GRUNT_RESULT_28 = 28,
GRUNT_RESULT_29 = 29,
GRUNT_RESULT_30 = 30,
GRUNT_RESULT_31 = 31,
GRUNT_RESULT_32 = 32,
GRUNT_RESULT_LAST,
};
}
#endif

View File

@ -88,6 +88,10 @@ void GruntLogin::GetRealmList() {
// TODO
}
void GruntLogin::GetVersionProof(const uint8_t* a2) {
// TODO
}
void GruntLogin::Init(LoginResponse* loginResponse) {
this->m_loginResponse = loginResponse;
@ -124,3 +128,19 @@ void GruntLogin::Logon(const char* a2, const char* a3) {
this->m_clientLink->Connect(a2);
}
void GruntLogin::LogonResult(Grunt::Result result, const uint8_t* a3, uint32_t a4, uint16_t a5) {
// TODO
}
void GruntLogin::SetMatrixInfo(bool enabled, uint8_t a3, uint8_t a4, uint8_t a5, uint8_t a6, bool a7, uint8_t a8, uint64_t a9, const uint8_t* a10, uint32_t a11) {
// TODO
}
void GruntLogin::SetPinInfo(bool enabled, uint32_t a3, const uint8_t* a4) {
// TODO
}
void GruntLogin::SetTokenInfo(bool enabled, uint8_t tokenRequired) {
// TODO
}

View File

@ -14,6 +14,11 @@ class GruntLogin : public Login {
virtual ~GruntLogin();
virtual bool Connected(const NETADDR& addr);
virtual void GetLogonMethod();
virtual void GetVersionProof(const uint8_t* a2);
virtual void SetPinInfo(bool enabled, uint32_t a3, const uint8_t* a4);
virtual void SetMatrixInfo(bool enabled, uint8_t a3, uint8_t a4, uint8_t a5, uint8_t a6, bool a7, uint8_t a8, uint64_t a9, const uint8_t* a10, uint32_t a11);
virtual void SetTokenInfo(bool enabled, uint8_t tokenRequired);
virtual void LogonResult(Grunt::Result result, const uint8_t* a3, uint32_t a4, uint16_t a5);
virtual void GetRealmList();
virtual void Logon(const char* a2, const char* a3);
virtual void Logoff();

View File

@ -22,3 +22,9 @@ int32_t SRP6_Client::BeginAuthentication(const char* accountName, const char* pa
return 0;
}
int32_t SRP6_Client::CalculateProof(const uint8_t* largeSafePrime, uint32_t largeSafePrimeLen, const uint8_t* generator, uint32_t generatorLen, const uint8_t* salt, uint32_t saltLen, const uint8_t* publicKey, uint32_t publicKeyLen, SRP6_Random& random) {
// TODO
return 0;
}

View File

@ -3,6 +3,8 @@
#include <common/SHA1.hpp>
class SRP6_Random;
class SRP6_Client {
public:
// Member variables
@ -12,6 +14,7 @@ class SRP6_Client {
// Member functions
int32_t BeginAuthentication(const char* accountName, const char* password);
int32_t CalculateProof(const uint8_t* largeSafePrime, uint32_t largeSafePrimeLen, const uint8_t* generator, uint32_t generatorLen, const uint8_t* salt, uint32_t saltLen, const uint8_t* publicKey, uint32_t publicKeyLen, SRP6_Random& random);
};
#endif