mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
Auth: include CRC in legacy proof; extend Turtle integrity set
This commit is contained in:
parent
5435796a98
commit
492703be36
5 changed files with 48 additions and 13 deletions
|
|
@ -64,6 +64,9 @@ public:
|
|||
// Legacy (protocol < 8): A(32) + M1(20) + crc(20) + number_of_keys(1). No securityFlags byte.
|
||||
static network::Packet buildLegacy(const std::vector<uint8_t>& A,
|
||||
const std::vector<uint8_t>& M1);
|
||||
static network::Packet buildLegacy(const std::vector<uint8_t>& A,
|
||||
const std::vector<uint8_t>& M1,
|
||||
const std::array<uint8_t, 20>* crcHash);
|
||||
static network::Packet build(const std::vector<uint8_t>& A,
|
||||
const std::vector<uint8_t>& M1,
|
||||
uint8_t securityFlags,
|
||||
|
|
|
|||
|
|
@ -283,14 +283,20 @@ void AuthHandler::sendLogonProof() {
|
|||
}
|
||||
}
|
||||
|
||||
auto packet = LogonProofPacket::build(A, M1, securityFlags_, crcHashPtr, pinClientSaltPtr, pinHashPtr);
|
||||
socket->send(packet);
|
||||
if (clientInfo.protocolVersion < 8) {
|
||||
// Legacy proof format: no securityFlags byte on the wire, but CRC/integrity hash still applies.
|
||||
auto packet = LogonProofPacket::buildLegacy(A, M1, crcHashPtr);
|
||||
socket->send(packet);
|
||||
} else {
|
||||
auto packet = LogonProofPacket::build(A, M1, securityFlags_, crcHashPtr, pinClientSaltPtr, pinHashPtr);
|
||||
socket->send(packet);
|
||||
|
||||
if ((securityFlags_ & 0x04) && clientInfo.protocolVersion >= 8) {
|
||||
// TrinityCore-style Google Authenticator token: send immediately after proof.
|
||||
const std::string token = pendingSecurityCode_;
|
||||
auto tokPkt = AuthenticatorTokenPacket::build(token);
|
||||
socket->send(tokPkt);
|
||||
if (securityFlags_ & 0x04) {
|
||||
// TrinityCore-style Google Authenticator token: send immediately after proof.
|
||||
const std::string token = pendingSecurityCode_;
|
||||
auto tokPkt = AuthenticatorTokenPacket::build(token);
|
||||
socket->send(tokPkt);
|
||||
}
|
||||
}
|
||||
|
||||
setState(AuthState::PROOF_SENT);
|
||||
|
|
|
|||
|
|
@ -167,6 +167,12 @@ network::Packet LogonProofPacket::build(const std::vector<uint8_t>& A,
|
|||
|
||||
network::Packet LogonProofPacket::buildLegacy(const std::vector<uint8_t>& A,
|
||||
const std::vector<uint8_t>& M1) {
|
||||
return buildLegacy(A, M1, nullptr);
|
||||
}
|
||||
|
||||
network::Packet LogonProofPacket::buildLegacy(const std::vector<uint8_t>& A,
|
||||
const std::vector<uint8_t>& M1,
|
||||
const std::array<uint8_t, 20>* crcHash) {
|
||||
if (A.size() != 32) {
|
||||
LOG_ERROR("Invalid A size: ", A.size(), " (expected 32)");
|
||||
}
|
||||
|
|
@ -177,7 +183,11 @@ network::Packet LogonProofPacket::buildLegacy(const std::vector<uint8_t>& A,
|
|||
network::Packet packet(static_cast<uint16_t>(AuthOpcode::LOGON_PROOF));
|
||||
packet.writeBytes(A.data(), A.size());
|
||||
packet.writeBytes(M1.data(), M1.size());
|
||||
for (int i = 0; i < 20; ++i) packet.writeUInt8(0); // CRC hash
|
||||
if (crcHash) {
|
||||
packet.writeBytes(crcHash->data(), crcHash->size());
|
||||
} else {
|
||||
for (int i = 0; i < 20; ++i) packet.writeUInt8(0); // CRC hash
|
||||
}
|
||||
packet.writeUInt8(0); // number of keys
|
||||
return packet;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,19 +36,35 @@ bool computeIntegrityHashWin32WithExe(const std::array<uint8_t, 16>& checksumSal
|
|||
std::string& outError) {
|
||||
// Files expected by 1.12.x Windows clients for the integrity check.
|
||||
// If this needs to vary by build, make it data-driven in expansion.json later.
|
||||
const char* kFiles[] = {
|
||||
//
|
||||
// Turtle WoW ships a custom loader DLL. Some Turtle auth servers appear to validate integrity against
|
||||
// that distribution rather than a stock 1.12.1 client, so when using Turtle's executable we include
|
||||
// Turtle-specific DLLs as well.
|
||||
const bool isTurtleExe = (exeName == "TurtleWoW.exe");
|
||||
const char* kFilesBase[] = {
|
||||
nullptr, // exeName
|
||||
"fmod.dll",
|
||||
"ijl15.dll",
|
||||
"dbghelp.dll",
|
||||
"unicows.dll",
|
||||
};
|
||||
const char* kFilesTurtleExtra[] = {
|
||||
"twloader.dll",
|
||||
"twdiscord.dll",
|
||||
};
|
||||
|
||||
std::vector<std::string> files;
|
||||
files.reserve(1 + 4 + (isTurtleExe ? (sizeof(kFilesTurtleExtra) / sizeof(kFilesTurtleExtra[0])) : 0));
|
||||
for (const char* f : kFilesBase) {
|
||||
files.push_back(f ? std::string(f) : exeName);
|
||||
}
|
||||
if (isTurtleExe) {
|
||||
for (const char* f : kFilesTurtleExtra) files.push_back(std::string(f));
|
||||
}
|
||||
|
||||
std::vector<uint8_t> allFiles;
|
||||
std::string err;
|
||||
for (size_t idx = 0; idx < (sizeof(kFiles) / sizeof(kFiles[0])); ++idx) {
|
||||
const char* name = kFiles[idx];
|
||||
std::string nameStr = name ? std::string(name) : exeName;
|
||||
for (const auto& nameStr : files) {
|
||||
std::vector<uint8_t> bytes;
|
||||
std::string path = miscDir;
|
||||
if (!path.empty() && path.back() != '/') path += '/';
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
|
||||
if (fmt == ProofFormat::Legacy) {
|
||||
auto pkt = auth::LogonProofPacket::buildLegacy(A, M1);
|
||||
auto pkt = auth::LogonProofPacket::buildLegacy(A, M1, crcHashPtr);
|
||||
sock.send(pkt);
|
||||
std::cerr << "Sent LOGON_PROOF legacy (proto=" << (int)info.protocolVersion << ")\n";
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue