From 19a7e1997b1084da82e30d2581dfe3bf5889a1fa Mon Sep 17 00:00:00 2001 From: fallenoak Date: Mon, 9 Jan 2023 17:52:54 -0600 Subject: [PATCH] feat(net): hook up prove version for grunt logins --- src/net/grunt/ClientLink.cpp | 37 +++++++++++++++++++++++++++++--- src/net/grunt/ClientLink.hpp | 1 + src/net/grunt/ClientResponse.hpp | 3 ++- src/net/login/GruntLogin.cpp | 30 ++++++++++++++++++++++++-- src/net/login/GruntLogin.hpp | 5 +++-- src/net/srp/SRP6_Client.hpp | 2 ++ 6 files changed, 70 insertions(+), 8 deletions(-) diff --git a/src/net/grunt/ClientLink.cpp b/src/net/grunt/ClientLink.cpp index cad47e5..ad548ad 100644 --- a/src/net/grunt/ClientLink.cpp +++ b/src/net/grunt/ClientLink.cpp @@ -114,8 +114,8 @@ int32_t Grunt::ClientLink::CmdAuthLogonChallenge(CDataStore& msg) { uint8_t* salt; msg.GetDataInSitu(reinterpret_cast(salt), 32); - uint8_t* crcSalt; - msg.GetDataInSitu(reinterpret_cast(crcSalt), 16); + uint8_t* versionChallenge; + msg.GetDataInSitu(reinterpret_cast(versionChallenge), 16); // TODO // if (!msg.Sub8CBBF0(1)) { @@ -197,7 +197,7 @@ int32_t Grunt::ClientLink::CmdAuthLogonChallenge(CDataStore& msg) { // 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); + this->m_clientResponse->GetVersionProof(versionChallenge); } return 2; @@ -321,6 +321,37 @@ void Grunt::ClientLink::PackLogon(CDataStore& msg, const Logon& logon) { msg.Set(startPos, msg.m_size - startPos - 2); } +void Grunt::ClientLink::ProveVersion(const uint8_t* versionChecksum) { + CDataStoreCache<1024> command; + + // TODO cd keys + // Grunt::CdKey cdKeys; + // if (!this->m_loginResponse->GetCdKeys(cdKeys)) { + // cdKeys.int0 = 0; + // } + + if (this->m_state == 4) { + command.Put(static_cast(CMD_AUTH_LOGON_PROOF)); + command.PutData(this->m_srpClient.clientPublicKey, sizeof(this->m_srpClient.clientPublicKey)); + command.PutData(this->m_srpClient.clientProof, sizeof(this->m_srpClient.clientProof)); + + uint8_t versionProof[SHA1_DIGEST_SIZE]; + SHA1_CONTEXT ctx; + SHA1_Init(&ctx); + SHA1_Update(&ctx, this->m_srpClient.clientPublicKey, sizeof(this->m_srpClient.clientPublicKey)); + SHA1_Update(&ctx, versionChecksum, 20); + SHA1_Final(versionProof, &ctx); + command.PutData(versionProof, sizeof(versionProof)); + + // TODO cd keys + command.Put(static_cast(0)); + } else { + // TODO + } + + this->Send(command); +} + void Grunt::ClientLink::Send(CDataStore& msg) { this->m_critSect.Enter(); diff --git a/src/net/grunt/ClientLink.hpp b/src/net/grunt/ClientLink.hpp index 2fa7d7a..bab12b5 100644 --- a/src/net/grunt/ClientLink.hpp +++ b/src/net/grunt/ClientLink.hpp @@ -69,6 +69,7 @@ class Grunt::ClientLink : public WowConnectionResponse, Grunt::Pending, Grunt::T void Disconnect(); void LogonNewSession(const Logon& logon); void PackLogon(CDataStore& msg, const Logon& logon); + void ProveVersion(const uint8_t* versionChecksum); void Send(CDataStore& msg); void SetState(int32_t state); }; diff --git a/src/net/grunt/ClientResponse.hpp b/src/net/grunt/ClientResponse.hpp index e36b413..2274978 100644 --- a/src/net/grunt/ClientResponse.hpp +++ b/src/net/grunt/ClientResponse.hpp @@ -11,7 +11,7 @@ class Grunt::ClientResponse { virtual bool Connected(const NETADDR& addr) = 0; virtual bool OnlineIdle() = 0; virtual void GetLogonMethod() = 0; - virtual void GetVersionProof(const uint8_t* crcSalt) = 0; + virtual void GetVersionProof(const uint8_t* versionChallenge) = 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; @@ -19,6 +19,7 @@ class Grunt::ClientResponse { virtual LOGIN_STATE NextSecurityState(LOGIN_STATE state) = 0; virtual void GetRealmList() = 0; virtual void Logon(const char* a2, const char* a3) = 0; + virtual void ProveVersion(const uint8_t* versionChecksum) = 0; virtual void Logoff() = 0; virtual void Init(LoginResponse* loginResponse) = 0; }; diff --git a/src/net/login/GruntLogin.cpp b/src/net/login/GruntLogin.cpp index 194c37f..b52fef7 100644 --- a/src/net/login/GruntLogin.cpp +++ b/src/net/login/GruntLogin.cpp @@ -88,11 +88,11 @@ void GruntLogin::GetRealmList() { // TODO } -void GruntLogin::GetVersionProof(const uint8_t* crcSalt) { +void GruntLogin::GetVersionProof(const uint8_t* versionChallenge) { if (this->IsReconnect()) { // TODO } else { - memcpy(this->m_crcSalt, crcSalt, sizeof(this->m_crcSalt)); + memcpy(this->m_versionChallenge, versionChallenge, sizeof(this->m_versionChallenge)); LOGIN_STATE nextState = this->NextSecurityState(LOGIN_STATE_FIRST_SECURITY); this->m_loginResponse->UpdateLoginStatus(nextState, LOGIN_OK, nullptr, 0); } @@ -144,6 +144,32 @@ LOGIN_STATE GruntLogin::NextSecurityState(LOGIN_STATE state) { return LOGIN_STATE_CHECKINGVERSIONS; } +void GruntLogin::ProveVersion(const uint8_t* versionChecksum) { + if (!this->m_loggedOn) { + return; + } + + this->m_clientLink->ProveVersion(versionChecksum); + + this->m_loginResponse->m_loginState = LOGIN_STATE_HANDSHAKING; + this->m_loginResponse->m_loginResult = LOGIN_OK; + + char stateStr[64]; + SStrCopy(stateStr, Grunt::g_LoginStateStringNames[LOGIN_STATE_HANDSHAKING], sizeof(stateStr)); + + char resultStr[64]; + SStrCopy(resultStr, Grunt::g_LoginResultStringNames[LOGIN_OK], sizeof(resultStr)); + + this->m_loginResponse->LoginServerStatus( + LOGIN_STATE_HANDSHAKING, + LOGIN_OK, + nullptr, + stateStr, + resultStr, + 0 + ); +} + 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 } diff --git a/src/net/login/GruntLogin.hpp b/src/net/login/GruntLogin.hpp index 10af702..29fb2fb 100644 --- a/src/net/login/GruntLogin.hpp +++ b/src/net/login/GruntLogin.hpp @@ -8,14 +8,14 @@ class GruntLogin : public Login { public: // Member variables - uint8_t m_crcSalt[16]; + uint8_t m_versionChallenge[16]; Grunt::ClientLink* m_clientLink = nullptr; // Virtual member functions virtual ~GruntLogin(); virtual bool Connected(const NETADDR& addr); virtual void GetLogonMethod(); - virtual void GetVersionProof(const uint8_t* crcSalt); + virtual void GetVersionProof(const uint8_t* versionChallenge); 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); @@ -23,6 +23,7 @@ class GruntLogin : public Login { virtual LOGIN_STATE NextSecurityState(LOGIN_STATE state); virtual void GetRealmList(); virtual void Logon(const char* a2, const char* a3); + virtual void ProveVersion(const uint8_t* versionChecksum); virtual void Logoff(); virtual void Init(LoginResponse* loginResponse); }; diff --git a/src/net/srp/SRP6_Client.hpp b/src/net/srp/SRP6_Client.hpp index 53269dc..4ff0ea2 100644 --- a/src/net/srp/SRP6_Client.hpp +++ b/src/net/srp/SRP6_Client.hpp @@ -8,6 +8,8 @@ class SRP6_Random; class SRP6_Client { public: // Member variables + uint8_t clientPublicKey[32]; + uint8_t clientProof[20]; uint8_t accountNameDigest[SHA1_DIGEST_SIZE]; uint8_t interimDigest[SHA1_DIGEST_SIZE]; SHA1_CONTEXT ctx;