uint32_t pnAuthClient::sendAcctLoginRequest(uint32_t serverChallenge, uint32_t clientChallenge, const plString& acctName, const plString& password, const plString& authToken, const plString& os) { const pnNetMsg* desc = GET_Cli2Auth(kCli2Auth_AcctLoginRequest); msgparm_t* msg = NCAllocMessage(desc); uint32_t transId = nextTransId(); msg[0].fUint = transId; msg[1].fUint = clientChallenge; msg[2].fString = plwcsdup(acctName.wstr()); pnSha1Hash hash; if (acctName.find('@') != -1 && acctName.find("@gametap") == -1 && acctName.find("@magiquest") == -1) { hash = NCHashLoginInfo(acctName, password, serverChallenge, clientChallenge); } else { hash = pnSha1Hash::Sha1(password.cstr(), password.len()); hash.swapBytes(); // Cyan uses a different byte order for this case } memcpy(msg[3].fData, &hash, sizeof(hash)); msg[4].fString = plwcsdup(authToken.wstr()); msg[5].fString = plwcsdup(os.wstr()); fSock->sendMsg(msg, desc); NCFreeMessage(msg, desc); return transId; }
plMD5Hash plMD5::hashString(const plString& str) { plMD5 ctx; size_t size = str.len(); unsigned char buf[64]; size_t pos = 0; while (pos + 64 <= size) { memcpy(buf, str.cstr() + pos, 64); ctx.processBlock(buf); pos += 64; } // Final block size_t lastSize = size - pos; memcpy(buf, str.cstr() + pos, lastSize); if (lastSize >= 56) { memcpy(buf + lastSize, kPadArray, 64 - lastSize); ctx.processBlock(buf); memset(buf, 0, sizeof(buf)); } else { unsigned int padBytes = 56 - lastSize; memcpy(buf + lastSize, kPadArray, padBytes); } unsigned int bitSize[2]; bitSize[0] = LESWAP32((size << 3)); bitSize[1] = LESWAP32((size >> 29)); memcpy(buf + 56, bitSize, sizeof(bitSize)); ctx.processBlock(buf); plMD5Hash hash; hash.fHash[0] = ctx.fA; hash.fHash[1] = ctx.fB; hash.fHash[2] = ctx.fC; hash.fHash[3] = ctx.fD; return hash; };
bool UpdateSums(const plString& filename) { bool isUpdated = false; printf("%s:\n", filename.cstr()); try { SumFile sum; plEncryptedStream S; plEncryptedStream::EncryptionType eType = plEncryptedStream::kEncXtea; if (!s_createFile) { if (!S.open(filename, fmRead, plEncryptedStream::kEncAuto)) { fprintf(stderr, "Could not open file %s\n", filename.cstr()); return false; } eType = S.getEncType(); sum.read(&S); S.close(); } std::vector<SumEntry>::iterator it = sum.fEntries.begin(); while (it != sum.fEntries.end()) { hsFileStream* IS = FindFilePath(it->fPath, cdUp(filename)); if (IS == NULL) { if (s_autoYes) { PrintFile(*it, '-'); it = sum.fEntries.erase(it); isUpdated = true; } else { fprintf(stderr, "File %s not found. Remove it? [y/N] ", it->fPath.cstr()); char buf[256]; fgets(buf, 256, stdin); if (strcmp(buf, "y\n") == 0 || strcmp(buf, "Y\n") == 0) { PrintFile(*it, '-'); it = sum.fEntries.erase(it); isUpdated = true; } else { PrintFile(*it, '!'); ++it; } } continue; } plMD5Hash hash = plMD5::hashStream(IS); it->fTimestamp = IS->getModTime(); if (it->fHash != hash) { it->fHash = hash; PrintFile(*it, '*'); isUpdated = true; } else { PrintFile(*it, ' '); } if (IS != NULL) delete IS; ++it; } if (isUpdated) { if (!S.open(filename, fmCreate, eType)) { fprintf(stderr, "Error: Could not open %s for writing!\n", filename.cstr()); return false; } sum.write(&S); S.close(); } printf("\n"); } catch (hsException& e) { fprintf(stderr, "%s:%ld: %s\n", e.File(), e.Line(), e.what()); } catch (...) { fprintf(stderr, "An unknown error occured\n"); } return isUpdated; }