void os_path_join(ByteBuffer &out, ByteBuffer left, ByteBuffer right) { const char *fmt_str = (left.at(left.length() - 1) == '/') ? "%s%s" : "%s/%s"; out.format(fmt_str, left.raw(), right.raw()); }
/// %Realm List command handler bool AuthSocket::_HandleRealmList() { sLog->outStaticDebug("Entering _HandleRealmList"); if (socket().recv_len() < 5) return false; socket().recv_skip(5); // Get the user id (else close the connection) PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_ACCIDBYNAME); stmt->setString(0, _login); PreparedQueryResult result = LoginDatabase.Query(stmt); if (!result) { sLog->outError("[ERROR] user %s tried to login and we cannot find him in the database.", _login.c_str()); socket().shutdown(); return false; } Field* fields = result->Fetch(); uint32 id = fields[0].GetUInt32(); // Update realm list if need sRealmList->UpdateIfNeed(); // Circle through realms in the RealmList and construct the return packet (including # of user characters in each realm) ByteBuffer pkt; size_t RealmListSize = 0; for (RealmList::RealmMap::const_iterator i = sRealmList->begin(); i != sRealmList->end(); ++i) { // don't work with realms which not compatible with the client if ((_expversion & POST_BC_EXP_FLAG) || (_expversion & POST_WOTLK_EXP_FLAG)) { if (i->second.gamebuild != _build) { sLog->outStaticDebug("Realm not added because of not correct build : %u != %u", i->second.gamebuild, _build); continue; } } else if (_expversion & PRE_BC_EXP_FLAG) // 1.12.1 and 1.12.2 clients are compatible with eachother if (!AuthHelper::IsPreBCAcceptedClientBuild(i->second.gamebuild)) continue; uint8 AmountOfCharacters; stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_NUMCHARSONREALM); stmt->setUInt32(0, i->second.m_ID); stmt->setUInt32(1, id); result = LoginDatabase.Query(stmt); if (result) AmountOfCharacters = (*result)[0].GetUInt8(); else AmountOfCharacters = 0; uint8 lock = (i->second.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0; pkt << i->second.icon; if (_expversion & (POST_BC_EXP_FLAG | POST_WOTLK_EXP_FLAG)) pkt << lock; pkt << i->second.color; pkt << i->first; pkt << i->second.address; pkt << i->second.populationLevel; pkt << AmountOfCharacters; pkt << i->second.timezone; if (_expversion & (POST_BC_EXP_FLAG | POST_WOTLK_EXP_FLAG)) pkt << (uint8) 0x2C; else pkt << (uint8) 0x0; ++RealmListSize; } if ((_expversion & POST_BC_EXP_FLAG) || (_expversion & POST_WOTLK_EXP_FLAG)) { pkt << (uint8) 0x10; pkt << (uint8) 0x00; } else { pkt << (uint8) 0x00; pkt << (uint8) 0x02; } // make a ByteBuffer which stores the RealmList's size ByteBuffer RealmListSizeBuffer; RealmListSizeBuffer << (uint32)0; if ((_expversion & POST_BC_EXP_FLAG) || (_expversion & POST_WOTLK_EXP_FLAG)) RealmListSizeBuffer << (uint16)RealmListSize; else RealmListSizeBuffer << (uint32)RealmListSize; ByteBuffer hdr; hdr << (uint8) REALM_LIST; hdr << (uint16)(pkt.size() + RealmListSizeBuffer.size()); hdr.append(RealmListSizeBuffer); // append RealmList's size buffer hdr.append(pkt); // append realms in the realmlist socket().send((char const*)hdr.contents(), hdr.size()); return true; }
void WardenMac::HandleHashResult(ByteBuffer &buff) { // test int keyIn[4]; uint8 mod_seed[16] = { 0x4D, 0x80, 0x8D, 0x2C, 0x77, 0xD9, 0x05, 0xC4, 0x1A, 0x63, 0x80, 0xEC, 0x08, 0x58, 0x6A, 0xFE }; for(int i = 0; i < 4; ++i) { keyIn[i] = *(int*)(&mod_seed[0] + i * 4); } int keyOut[4]; int keyIn1, keyIn2; keyOut[0] = keyIn[0]; keyIn[0] ^= 0xDEADBEEFu; keyIn1 = keyIn[1]; keyIn[1] -= 0x35014542u; keyIn2 = keyIn[2]; keyIn[2] += 0x5313F22u; keyIn[3] *= 0x1337F00Du; keyOut[1] = keyIn1 - 0x6A028A84; keyOut[2] = keyIn2 + 0xA627E44; keyOut[3] = 0x1337F00D * keyIn[3]; // end test buff.rpos(buff.wpos()); Sha1Hash sha1; sha1.UpdateData((uint8*)keyIn, 16); sha1.Finalize(); //const uint8 validHash[20] = { 0x56, 0x8C, 0x05, 0x4C, 0x78, 0x1A, 0x97, 0x2A, 0x60, 0x37, 0xA2, 0x29, 0x0C, 0x22, 0xB5, 0x25, 0x71, 0xA0, 0x6F, 0x4E }; // verify key not equal kick player if (memcmp(buff.contents() + 1, sha1.GetDigest(), 20) != 0) { sLog.outWarden("Request hash reply: failed"); sWorld.SendAntiCheatMessageToGMs(Client->GetPlayerName(), "A Warden check for MAC has failed! More info is available in the log."); if (sWorld.getConfig(CONFIG_FLOAT_WARDEN_KICK_BAN) == 1) { Client->KickPlayer(); } if (sWorld.getConfig(CONFIG_FLOAT_WARDEN_KICK_BAN) == 2) { sWorld.BanAccount(BAN_CHARACTER, Client->GetPlayerName(), sWorld.getConfig(CONFIG_UINT32_WARDEN_BAN_TIME) * 900000 * IN_MILLISECONDS, "Cheating software usage", "Warden System"); } return; } sLog.outDebug("Request hash reply: succeed"); // client 7F96EEFDA5B63D20A4DF8E00CBF48304 //const uint8 client_key[16] = { 0x7F, 0x96, 0xEE, 0xFD, 0xA5, 0xB6, 0x3D, 0x20, 0xA4, 0xDF, 0x8E, 0x00, 0xCB, 0xF4, 0x83, 0x04 }; // server C2B7ADEDFCCCA9C2BFB3F85602BA809B //const uint8 server_key[16] = { 0xC2, 0xB7, 0xAD, 0xED, 0xFC, 0xCC, 0xA9, 0xC2, 0xBF, 0xB3, 0xF8, 0x56, 0x02, 0xBA, 0x80, 0x9B }; // change keys here memcpy(InputKey, keyIn, 16); memcpy(OutputKey, keyOut, 16); iCrypto.Init(InputKey); oCrypto.Init(OutputKey); m_initialized = true; m_WardenTimer = WorldTimer::getMSTime(); }
GptPartitionTable::GptHeaderData GptPartitionTable::bb_to_gpt_header(const ByteBuffer& bb) { GptHeaderData gpt{}; gpt.signature = bb.get_le64(0); gpt.revision = bb.get_le32(8); gpt.header_size = bb.get_le32(12); gpt.header_crc = bb.get_le32(16); // omitted reserved 4 bytes gpt.current_lba = bb.get_le64(24); gpt.backup_lba = bb.get_le64(32); gpt.first_usable_lba = bb.get_le64(40); gpt.last_usable_lba = bb.get_le64(48); gpt.disk_guid = get_guid(bb, 56); gpt.partition_table_lba = bb.get_le64(72); gpt.num_of_partitions = bb.get_le32(80); gpt.partition_entry_size = bb.get_le32(84); gpt.partition_table_crc = bb.get_le32(88); return gpt; }
/// Logon Challenge command handler bool AuthSocket::_HandleLogonChallenge() { sLog->outStaticDebug("Entering _HandleLogonChallenge"); if (socket().recv_len() < sizeof(sAuthLogonChallenge_C)) return false; ///- Read the first 4 bytes (header) to get the length of the remaining of the packet std::vector<uint8> buf; buf.resize(4); socket().recv((char *)&buf[0], 4); #if TRINITY_ENDIAN == TRINITY_BIGENDIAN EndianConvert(*((uint16*)(buf[0]))); #endif uint16 remaining = ((sAuthLogonChallenge_C *)&buf[0])->size; sLog->outStaticDebug("[AuthChallenge] got header, body is %#04x bytes", remaining); if ((remaining < sizeof(sAuthLogonChallenge_C) - buf.size()) || (socket().recv_len() < remaining)) return false; //No big fear of memory outage (size is int16, i.e. < 65536) buf.resize(remaining + buf.size() + 1); buf[buf.size() - 1] = 0; sAuthLogonChallenge_C *ch = (sAuthLogonChallenge_C*)&buf[0]; ///- Read the remaining of the packet socket().recv((char *)&buf[4], remaining); sLog->outStaticDebug("[AuthChallenge] got full packet, %#04x bytes", ch->size); sLog->outStaticDebug("[AuthChallenge] name(%d): '%s'", ch->I_len, ch->I); #if TRINITY_ENDIAN == TRINITY_BIGENDIAN // BigEndian code, nop in little endian case // size already converted EndianConvert(*((uint32*)(&ch->gamename[0]))); EndianConvert(ch->build); EndianConvert(*((uint32*)(&ch->platform[0]))); EndianConvert(*((uint32*)(&ch->os[0]))); EndianConvert(*((uint32*)(&ch->country[0]))); EndianConvert(ch->timezone_bias); EndianConvert(ch->ip); #endif ByteBuffer pkt; _login = (const char*)ch->I; _build = ch->build; _expversion = (AuthHelper::IsPostWotLKAcceptedClientBuild(_build) ? POST_WOTLK_EXP_FLAG : NO_VALID_EXP_FLAG) | (AuthHelper::IsPostBCAcceptedClientBuild(_build) ? POST_BC_EXP_FLAG : NO_VALID_EXP_FLAG) | (AuthHelper::IsPreBCAcceptedClientBuild(_build) ? PRE_BC_EXP_FLAG : NO_VALID_EXP_FLAG); pkt << (uint8) AUTH_LOGON_CHALLENGE; pkt << (uint8) 0x00; // Verify that this IP is not in the ip_banned table LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_SET_EXPIREDIPBANS)); const std::string& ip_address = socket().get_remote_address(); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_IPBANNED); stmt->setString(0, ip_address); PreparedQueryResult result = LoginDatabase.Query(stmt); if (result) { pkt << (uint8)WOW_FAIL_BANNED; sLog->outBasic("[AuthChallenge] Banned ip %s tries to login!", ip_address.c_str()); } else { ///- Get the account details from the account table stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_LOGONCHALLENGE); stmt->setString(0, _login); PreparedQueryResult res2 = LoginDatabase.Query(stmt); if (res2) { Field* fields = res2->Fetch(); //- If the IP is 'locked', check that the player comes indeed from the correct IP address bool locked = false; if (fields[2].GetUInt8() == 1) // if ip is locked { sLog->outStaticDebug("[AuthChallenge] Account '%s' is locked to IP - '%s'", _login.c_str(), fields[3].GetCString()); sLog->outStaticDebug("[AuthChallenge] Player address is '%s'", ip_address.c_str()); if (strcmp(fields[3].GetCString(), ip_address.c_str())) { sLog->outStaticDebug("[AuthChallenge] Account IP differs"); pkt << (uint8) WOW_FAIL_SUSPENDED; locked=true; } else sLog->outStaticDebug("[AuthChallenge] Account IP matches"); } else sLog->outStaticDebug("[AuthChallenge] Account '%s' is not locked to ip", _login.c_str()); if (!locked) { //set expired bans to inactive LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_SET_EXPIREDACCBANS)); // If the account is banned, reject the logon attempt stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_ACCBANNED); stmt->setUInt32(0, fields[1].GetUInt32()); PreparedQueryResult banresult = LoginDatabase.Query(stmt); if (banresult) { if ((*banresult)[0].GetUInt64() == (*banresult)[1].GetUInt64()) { pkt << (uint8) WOW_FAIL_BANNED; sLog->outBasic("[AuthChallenge] Banned account %s tries to login!", _login.c_str()); } else { pkt << (uint8) WOW_FAIL_SUSPENDED; sLog->outBasic("[AuthChallenge] Temporarily banned account %s tries to login!", _login.c_str()); } } else { ///- Get the password from the account table, upper it, and make the SRP6 calculation std::string rI = fields[0].GetString(); ///- Don't calculate (v, s) if there are already some in the database std::string databaseV = fields[5].GetString(); std::string databaseS = fields[6].GetString(); sLog->outDebug("database authentication values: v='%s' s='%s'", databaseV.c_str(), databaseS.c_str()); // multiply with 2, bytes are stored as hexstring if (databaseV.size() != s_BYTE_SIZE*2 || databaseS.size() != s_BYTE_SIZE*2) _SetVSFields(rI); else { s.SetHexStr(databaseS.c_str()); v.SetHexStr(databaseV.c_str()); } b.SetRand(19 * 8); BigNumber gmod = g.ModExp(b, N); B = ((v * 3) + gmod) % N; ASSERT(gmod.GetNumBytes() <= 32); BigNumber unk3; unk3.SetRand(16 * 8); ///- Fill the response packet with the result pkt << uint8(WOW_SUCCESS); // B may be calculated < 32B so we force minimal length to 32B pkt.append(B.AsByteArray(32), 32); // 32 bytes pkt << uint8(1); pkt.append(g.AsByteArray(), 1); pkt << uint8(32); pkt.append(N.AsByteArray(32), 32); pkt.append(s.AsByteArray(), s.GetNumBytes()); // 32 bytes pkt.append(unk3.AsByteArray(16), 16); uint8 securityFlags = 0; pkt << uint8(securityFlags); // security flags (0x0...0x04) if (securityFlags & 0x01) // PIN input { pkt << uint32(0); pkt << uint64(0) << uint64(0); // 16 bytes hash? } if (securityFlags & 0x02) // Matrix input { pkt << uint8(0); pkt << uint8(0); pkt << uint8(0); pkt << uint8(0); pkt << uint64(0); } if (securityFlags & 0x04) // Security token input pkt << uint8(1); uint8 secLevel = fields[4].GetUInt8(); _accountSecurityLevel = secLevel <= SEC_ADMINISTRATOR ? AccountTypes(secLevel) : SEC_ADMINISTRATOR; _localizationName.resize(4); for (int i = 0; i < 4; ++i) _localizationName[i] = ch->country[4-i-1]; sLog->outBasic("[AuthChallenge] account %s is using '%c%c%c%c' locale (%u)", _login.c_str (), ch->country[3], ch->country[2], ch->country[1], ch->country[0], GetLocaleByName(_localizationName)); } } } else //no account pkt << (uint8)WOW_FAIL_UNKNOWN_ACCOUNT; } socket().send((char const*)pkt.contents(), pkt.size()); return true; }
bool AddonHandler::BuildAddonPacket(WorldPacket* Source, WorldPacket* Target) { ByteBuffer AddOnPacked; uLongf AddonRealSize; uint32 CurrentPosition; uint32 TempValue; // broken addon packet, can't be received from real client if (Source->rpos() + 4 > Source->size()) return false; *Source >> TempValue; // get real size of the packed structure // empty addon packet, nothing process, can't be received from real client if (!TempValue) return false; AddonRealSize = TempValue; // temp value because ZLIB only excepts uLongf CurrentPosition = Source->rpos(); // get the position of the pointer in the structure AddOnPacked.resize(AddonRealSize); // resize target for zlib action if (uncompress(const_cast<uint8*>(AddOnPacked.contents()), &AddonRealSize, const_cast<uint8*>((*Source).contents() + CurrentPosition), (*Source).size() - CurrentPosition)== Z_OK) { Target->Initialize(SMSG_ADDON_INFO); uint32 addonsCount; AddOnPacked >> addonsCount; // addons count? for (uint32 i = 0; i < addonsCount; ++i) { std::string addonName; uint8 enabled; uint32 crc, unk2; // check next addon data format correctness if (AddOnPacked.rpos()+1 > AddOnPacked.size()) return false; AddOnPacked >> addonName; // recheck next addon data format correctness if (AddOnPacked.rpos()+1+4+4 > AddOnPacked.size()) return false; AddOnPacked >> enabled >> crc >> unk2; #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) sLog->outDebug(LOG_FILTER_NETWORKIO, "ADDON: Name: %s, Enabled: 0x%x, CRC: 0x%x, Unknown2: 0x%x", addonName.c_str(), enabled, crc, unk2); #endif uint8 state = (enabled ? 2 : 1); *Target << uint8(state); uint8 unk1 = (enabled ? 1 : 0); *Target << uint8(unk1); if (unk1) { uint8 unk = (crc != 0x4c1c776d); // If addon is Standard addon CRC *Target << uint8(unk); if (unk) { unsigned char tdata[256] = { 0xC3, 0x5B, 0x50, 0x84, 0xB9, 0x3E, 0x32, 0x42, 0x8C, 0xD0, 0xC7, 0x48, 0xFA, 0x0E, 0x5D, 0x54, 0x5A, 0xA3, 0x0E, 0x14, 0xBA, 0x9E, 0x0D, 0xB9, 0x5D, 0x8B, 0xEE, 0xB6, 0x84, 0x93, 0x45, 0x75, 0xFF, 0x31, 0xFE, 0x2F, 0x64, 0x3F, 0x3D, 0x6D, 0x07, 0xD9, 0x44, 0x9B, 0x40, 0x85, 0x59, 0x34, 0x4E, 0x10, 0xE1, 0xE7, 0x43, 0x69, 0xEF, 0x7C, 0x16, 0xFC, 0xB4, 0xED, 0x1B, 0x95, 0x28, 0xA8, 0x23, 0x76, 0x51, 0x31, 0x57, 0x30, 0x2B, 0x79, 0x08, 0x50, 0x10, 0x1C, 0x4A, 0x1A, 0x2C, 0xC8, 0x8B, 0x8F, 0x05, 0x2D, 0x22, 0x3D, 0xDB, 0x5A, 0x24, 0x7A, 0x0F, 0x13, 0x50, 0x37, 0x8F, 0x5A, 0xCC, 0x9E, 0x04, 0x44, 0x0E, 0x87, 0x01, 0xD4, 0xA3, 0x15, 0x94, 0x16, 0x34, 0xC6, 0xC2, 0xC3, 0xFB, 0x49, 0xFE, 0xE1, 0xF9, 0xDA, 0x8C, 0x50, 0x3C, 0xBE, 0x2C, 0xBB, 0x57, 0xED, 0x46, 0xB9, 0xAD, 0x8B, 0xC6, 0xDF, 0x0E, 0xD6, 0x0F, 0xBE, 0x80, 0xB3, 0x8B, 0x1E, 0x77, 0xCF, 0xAD, 0x22, 0xCF, 0xB7, 0x4B, 0xCF, 0xFB, 0xF0, 0x6B, 0x11, 0x45, 0x2D, 0x7A, 0x81, 0x18, 0xF2, 0x92, 0x7E, 0x98, 0x56, 0x5D, 0x5E, 0x69, 0x72, 0x0A, 0x0D, 0x03, 0x0A, 0x85, 0xA2, 0x85, 0x9C, 0xCB, 0xFB, 0x56, 0x6E, 0x8F, 0x44, 0xBB, 0x8F, 0x02, 0x22, 0x68, 0x63, 0x97, 0xBC, 0x85, 0xBA, 0xA8, 0xF7, 0xB5, 0x40, 0x68, 0x3C, 0x77, 0x86, 0x6F, 0x4B, 0xD7, 0x88, 0xCA, 0x8A, 0xD7, 0xCE, 0x36, 0xF0, 0x45, 0x6E, 0xD5, 0x64, 0x79, 0x0F, 0x17, 0xFC, 0x64, 0xDD, 0x10, 0x6F, 0xF3, 0xF5, 0xE0, 0xA6, 0xC3, 0xFB, 0x1B, 0x8C, 0x29, 0xEF, 0x8E, 0xE5, 0x34, 0xCB, 0xD1, 0x2A, 0xCE, 0x79, 0xC3, 0x9A, 0x0D, 0x36, 0xEA, 0x01, 0xE0, 0xAA, 0x91, 0x20, 0x54, 0xF0, 0x72, 0xD8, 0x1E, 0xC7, 0x89, 0xD2 }; Target->append(tdata, sizeof(tdata)); } *Target << uint32(0); } uint8 unk3 = (enabled ? 0 : 1); *Target << uint8(unk3); if (unk3) { // String, 256 (null terminated?) *Target << uint8(0); } } uint32 unk4; AddOnPacked >> unk4; uint32 count = 0; *Target << uint32(count); #if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS) if (AddOnPacked.rpos() != AddOnPacked.size()) sLog->outDebug(LOG_FILTER_NETWORKIO, "packet under read!"); #endif }
void WorldSession::HandleCalendarGetCalendar(WorldPacket& /*recv_data*/) { ObjectGuid guid = _player->GetObjectGuid(); DEBUG_LOG("WORLD: Received opcode CMSG_CALENDAR_GET_CALENDAR [%s]", guid.GetString().c_str()); time_t currTime = time(nullptr); WorldPacket data(SMSG_CALENDAR_SEND_CALENDAR); CalendarInvitesList invites; sCalendarMgr.GetPlayerInvitesList(guid, invites); data << uint32(invites.size()); DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "Sending > %u invites", uint32(invites.size())); for (CalendarInvitesList::const_iterator itr = invites.begin(); itr != invites.end(); ++itr) { CalendarEvent const* event = (*itr)->GetCalendarEvent(); MANGOS_ASSERT(event); // TODO: be sure no way to have a null event data << uint64(event->EventId); data << uint64((*itr)->InviteId); data << uint8((*itr)->Status); data << uint8((*itr)->Rank); data << uint8(event->IsGuildEvent()); data << event->CreatorGuid.WriteAsPacked(); DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "invite> EventId[" UI64FMTD "], InviteId[" UI64FMTD "], status[%u], rank[%u]", event->EventId, (*itr)->InviteId, uint32((*itr)->Status), uint32((*itr)->Rank)); } CalendarEventsList events; sCalendarMgr.GetPlayerEventsList(guid, events); data << uint32(events.size()); DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "Sending > %u events", uint32(events.size())); for (CalendarEventsList::const_iterator itr = events.begin(); itr != events.end(); ++itr) { CalendarEvent const* event = *itr; data << uint64(event->EventId); data << event->Title; data << uint32(event->Type); data << secsToTimeBitFields(event->EventTime); data << uint32(event->Flags); data << int32(event->DungeonId); data << event->CreatorGuid.WriteAsPacked(); std::string timeStr = TimeToTimestampStr(event->EventTime); DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "Events> EventId[" UI64FMTD "], Title[%s], Time[%s], Type[%u], Flag[%u], DungeonId[%d], CreatorGuid[%s]", event->EventId, event->Title.c_str(), timeStr.c_str(), uint32(event->Type), uint32(event->Flags), event->DungeonId, event->CreatorGuid.GetString().c_str()); } data << uint32(currTime); // server time data << secsToTimeBitFields(currTime); // zone time ?? ByteBuffer dataBuffer; uint32 boundCounter = 0; for (uint8 i = 0; i < MAX_DIFFICULTY; ++i) { Player::BoundInstancesMap boundInstances = _player->GetBoundInstances(Difficulty(i)); for (Player::BoundInstancesMap::const_iterator itr = boundInstances.begin(); itr != boundInstances.end(); ++itr) { if (itr->second.perm) { DungeonPersistentState const* state = itr->second.state; dataBuffer << uint32(state->GetMapId()); dataBuffer << uint32(state->GetDifficulty()); dataBuffer << uint32(state->GetResetTime() - currTime); dataBuffer << uint64(state->GetInstanceId()); // instance save id as unique instance copy id ++boundCounter; } } } data << uint32(boundCounter); data.append(dataBuffer); data << uint32(1135753200); // Constant date, unk (28.12.2005 07:00) // Reuse variables boundCounter = 0; std::set<uint32> sentMaps; dataBuffer.clear(); for (MapDifficultyMap::const_iterator itr = sMapDifficultyMap.begin(); itr != sMapDifficultyMap.end(); ++itr) { uint32 map_diff_pair = itr->first; uint32 mapId = PAIR32_LOPART(map_diff_pair); Difficulty difficulty = Difficulty(PAIR32_HIPART(map_diff_pair)); MapDifficultyEntry const* mapDiff = itr->second; // skip mapDiff without global reset time if (!mapDiff->resetTime) continue; // skip non raid map MapEntry const* mapEntry = sMapStore.LookupEntry(mapId); if (!mapEntry || !mapEntry->IsRaid()) continue; // skip already sent map (not same difficulty?) if (sentMaps.find(mapId) != sentMaps.end()) continue; uint32 resetTime = sMapPersistentStateMgr.GetScheduler().GetMaxResetTimeFor(mapDiff); sentMaps.insert(mapId); dataBuffer << mapId; dataBuffer << resetTime; DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "MapId [%u] -> Reset Time: %u", mapId, resetTime); dataBuffer << int32(0); // showed 68400 on map 509 must investigate more ++boundCounter; } DEBUG_FILTER_LOG(LOG_FILTER_CALENDAR, "Map sent [%u]", boundCounter); data << uint32(boundCounter); data.append(dataBuffer); // TODO: Fix this, how we do know how many and what holidays to send? uint32 holidayCount = 0; data << uint32(holidayCount); /*for (uint32 i = 0; i < holidayCount; ++i) { HolidaysEntry const* holiday = sHolidaysStore.LookupEntry(666); data << uint32(holiday->Id); // m_ID data << uint32(holiday->Region); // m_region, might be looping data << uint32(holiday->Looping); // m_looping, might be region data << uint32(holiday->Priority); // m_priority data << uint32(holiday->CalendarFilterType); // m_calendarFilterType for (uint8 j = 0; j < MAX_HOLIDAY_DATES; ++j) data << uint32(holiday->Date[j]); // 26 * m_date -- WritePackedTime ? for (uint8 j = 0; j < MAX_HOLIDAY_DURATIONS; ++j) data << uint32(holiday->Duration[j]); // 10 * m_duration for (uint8 j = 0; j < MAX_HOLIDAY_FLAGS; ++j) data << uint32(holiday->CalendarFlags[j]); // 10 * m_calendarFlags data << holiday->TextureFilename; // m_textureFilename (holiday name) }*/ SendPacket(&data); }
/// Logon Proof command handler bool AuthSocket::_HandleLogonProof() { DEBUG_LOG("Entering _HandleLogonProof"); ///- Read the packet if (ibuf.GetLength() < sizeof(sAuthLogonProof_C)) return false; sAuthLogonProof_C lp; ibuf.Read((char *)&lp, sizeof(sAuthLogonProof_C)); ///- Check if the client has one of the expected version numbers bool valid_version = false; int accepted_versions[] = EXPECTED_REALMD_CLIENT_BUILD; if (_build >= accepted_versions[0]) // first build is low bound of always accepted range valid_version = true; else { // continue from 1 with explict equal check for(int i = 1; accepted_versions[i]; ++i) { if(_build == accepted_versions[i]) { valid_version = true; break; } } } /// <ul><li> If the client has no valid version if(!valid_version) { ///- Check if we have the apropriate patch on the disk // 24 = len("./patches/65535enGB.mpq")+1 char tmp[24]; // No buffer overflow (fixed length of arguments) sprintf(tmp, "./patches/%d%s.mpq", _build, _localizationName.c_str()); // This will be closed at the destruction of the AuthSocket (client disconnection) FILE *pFile = fopen(tmp, "rb"); if(!pFile) { ByteBuffer pkt; pkt << (uint8) AUTH_LOGON_CHALLENGE; pkt << (uint8) 0x00; pkt << (uint8) REALM_AUTH_WRONG_BUILD_NUMBER; DEBUG_LOG("[AuthChallenge] %u is not a valid client version!", _build); DEBUG_LOG("[AuthChallenge] Patch %s not found", tmp); SendBuf((char const*)pkt.contents(), pkt.size()); return true; } else // have patch { pPatch = pFile; XFER_INIT xferh; ///- Get the MD5 hash of the patch file (get it from preloaded Patcher cache or calculate it) if(PatchesCache.GetHash(tmp, (uint8*)&xferh.md5)) { DEBUG_LOG("\n[AuthChallenge] Found precached patch info for patch %s", tmp); } else { // calculate patch md5 printf("\n[AuthChallenge] Patch info for %s was not cached.", tmp); PatchesCache.LoadPatchMD5(tmp); PatchesCache.GetHash(tmp, (uint8*)&xferh.md5); } ///- Send a packet to the client with the file length and MD5 hash uint8 data[2] = { AUTH_LOGON_PROOF, REALM_AUTH_UPDATE_CLIENT }; SendBuf((const char*)data, sizeof(data)); memcpy(&xferh, "0\x05Patch", 7); xferh.cmd = XFER_INITIATE; fseek(pPatch, 0, SEEK_END); xferh.file_size = ftell(pPatch); SendBuf((const char*)&xferh, sizeof(xferh)); return true; } } /// </ul> ///- Continue the SRP6 calculation based on data received from the client BigNumber A; A.SetBinary(lp.A, 32); // SRP safeguard: abort if A==0 if (A.isZero()) return false; Sha1Hash sha; sha.UpdateBigNumbers(&A, &B, NULL); sha.Finalize(); BigNumber u; u.SetBinary(sha.GetDigest(), 20); BigNumber S = (A * (v.ModExp(u, N))).ModExp(b, N); uint8 t[32]; uint8 t1[16]; uint8 vK[40]; memcpy(t, S.AsByteArray(32), 32); for (int i = 0; i < 16; ++i) { t1[i] = t[i * 2]; } sha.Initialize(); sha.UpdateData(t1, 16); sha.Finalize(); for (int i = 0; i < 20; ++i) { vK[i * 2] = sha.GetDigest()[i]; } for (int i = 0; i < 16; ++i) { t1[i] = t[i * 2 + 1]; } sha.Initialize(); sha.UpdateData(t1, 16); sha.Finalize(); for (int i = 0; i < 20; ++i) { vK[i * 2 + 1] = sha.GetDigest()[i]; } K.SetBinary(vK, 40); uint8 hash[20]; sha.Initialize(); sha.UpdateBigNumbers(&N, NULL); sha.Finalize(); memcpy(hash, sha.GetDigest(), 20); sha.Initialize(); sha.UpdateBigNumbers(&g, NULL); sha.Finalize(); for (int i = 0; i < 20; ++i) { hash[i] ^= sha.GetDigest()[i]; } BigNumber t3; t3.SetBinary(hash, 20); sha.Initialize(); sha.UpdateData(_login); sha.Finalize(); uint8 t4[SHA_DIGEST_LENGTH]; memcpy(t4, sha.GetDigest(), SHA_DIGEST_LENGTH); sha.Initialize(); sha.UpdateBigNumbers(&t3, NULL); sha.UpdateData(t4, SHA_DIGEST_LENGTH); sha.UpdateBigNumbers(&s, &A, &B, &K, NULL); sha.Finalize(); BigNumber M; M.SetBinary(sha.GetDigest(), 20); ///- Check if SRP6 results match (password is correct), else send an error if (!memcmp(M.AsByteArray(), lp.M1, 20)) { sLog.outBasic("User '%s' successfully authenticated", _login.c_str()); ///- Update the sessionkey, last_ip, last login time and reset number of failed logins in the account table for this account // No SQL injection (escaped user name) and IP address as received by socket const char* K_hex = K.AsHexStr(); loginDatabase.PExecute("UPDATE account SET sessionkey = '%s', last_ip = '%s', last_login = NOW(), locale = '%u', failed_logins = 0 WHERE username = '******'", K_hex, GetRemoteAddress().c_str(), GetLocaleByName(_localizationName), _safelogin.c_str() ); OPENSSL_free((void*)K_hex); ///- Finish SRP6 and send the final result to the client sha.Initialize(); sha.UpdateBigNumbers(&A, &M, &K, NULL); sha.Finalize(); SendProof(sha); ///- Set _authed to true! _authed = true; } else { char data[4]= { AUTH_LOGON_PROOF, REALM_AUTH_NO_MATCH, 3, 0}; SendBuf(data, sizeof(data)); sLog.outBasic("[AuthChallenge] account %s tried to login with wrong password!",_login.c_str ()); uint32 MaxWrongPassCount = sConfig.GetIntDefault("WrongPass.MaxCount", 0); if(MaxWrongPassCount > 0) { //Increment number of failed logins by one and if it reaches the limit temporarily ban that account or IP loginDatabase.PExecute("UPDATE account SET failed_logins = failed_logins + 1 WHERE username = '******'",_safelogin.c_str()); if(QueryResult *loginfail = loginDatabase.PQuery("SELECT id, failed_logins FROM account WHERE username = '******'", _safelogin.c_str())) { Field* fields = loginfail->Fetch(); uint32 failed_logins = fields[1].GetUInt32(); if( failed_logins >= MaxWrongPassCount ) { uint32 WrongPassBanTime = sConfig.GetIntDefault("WrongPass.BanTime", 600); bool WrongPassBanType = sConfig.GetBoolDefault("WrongPass.BanType", false); if(WrongPassBanType) { uint32 acc_id = fields[0].GetUInt32(); loginDatabase.PExecute("INSERT INTO account_banned VALUES ('%u',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','MaNGOS realmd','Failed login autoban',1)", acc_id, WrongPassBanTime); sLog.outBasic("[AuthChallenge] account %s got banned for '%u' seconds because it failed to authenticate '%u' times", _login.c_str(), WrongPassBanTime, failed_logins); } else { std::string current_ip = GetRemoteAddress(); loginDatabase.escape_string(current_ip); loginDatabase.PExecute("INSERT INTO ip_banned VALUES ('%s',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','MaNGOS realmd','Failed login autoban')", current_ip.c_str(), WrongPassBanTime); sLog.outBasic("[AuthChallenge] IP %s got banned for '%u' seconds because account %s failed to authenticate '%u' times", current_ip.c_str(), WrongPassBanTime, _login.c_str(), failed_logins); } } delete loginfail; } } } return true; }
/// Logon Challenge command handler bool AuthSocket::_HandleLogonChallenge() { DEBUG_LOG("Entering _HandleLogonChallenge"); if (recv_len() < sizeof(sAuthLogonChallenge_C)) { return false; } ///- Read the first 4 bytes (header) to get the length of the remaining of the packet std::vector<uint8> buf; buf.resize(4); recv((char*)&buf[0], 4); #ifdef MANGOS_BIGENDIAN EndianConvert(*((uint16*)(buf[0]))); #endif uint16 remaining = ((sAuthLogonChallenge_C*)&buf[0])->size; DEBUG_LOG("[AuthChallenge] got header, body is %#04x bytes", remaining); if ((remaining < sizeof(sAuthLogonChallenge_C) - buf.size()) || (recv_len() < remaining)) { return false; } // No big fear of memory outage (size is int16, i.e. < 65536) buf.resize(remaining + buf.size() + 1); buf[buf.size() - 1] = 0; sAuthLogonChallenge_C* ch = (sAuthLogonChallenge_C*)&buf[0]; ///- Read the remaining of the packet recv((char*)&buf[4], remaining); DEBUG_LOG("[AuthChallenge] got full packet, %#04x bytes", ch->size); DEBUG_LOG("[AuthChallenge] name(%d): '%s'", ch->I_len, ch->I); // BigEndian code, nop in little endian case // size already converted EndianConvert(*((uint32*)(&ch->gamename[0]))); EndianConvert(ch->build); EndianConvert(*((uint32*)(&ch->platform[0]))); EndianConvert(*((uint32*)(&ch->os[0]))); EndianConvert(*((uint32*)(&ch->country[0]))); EndianConvert(ch->timezone_bias); EndianConvert(ch->ip); ByteBuffer pkt; _login = (const char*)ch->I; _build = ch->build; ///- Normalize account name // utf8ToUpperOnlyLatin(_login); -- client already send account in expected form // Escape the user login to avoid further SQL injection // Memory will be freed on AuthSocket object destruction _safelogin = _login; LoginDatabase.escape_string(_safelogin); pkt << (uint8) CMD_AUTH_LOGON_CHALLENGE; pkt << (uint8) 0x00; ///- Verify that this IP is not in the ip_banned table // No SQL injection possible (paste the IP address as passed by the socket) std::string address = get_remote_address(); LoginDatabase.escape_string(address); QueryResult* result = LoginDatabase.PQuery("SELECT unbandate FROM ip_banned WHERE " // permanent still banned "(unbandate = bandate OR unbandate > UNIX_TIMESTAMP()) AND ip = '%s'", address.c_str()); if (result) { pkt << (uint8)WOW_FAIL_BANNED; BASIC_LOG("[AuthChallenge] Banned ip %s tries to login!", get_remote_address().c_str()); delete result; } else { ///- Get the account details from the account table // No SQL injection (escaped user name) result = LoginDatabase.PQuery("SELECT sha_pass_hash,id,locked,last_ip,gmlevel,v,s FROM account WHERE username = '******'", _safelogin.c_str()); if (result) { ///- If the IP is 'locked', check that the player comes indeed from the correct IP address bool locked = false; if ((*result)[2].GetUInt8() == 1) // if ip is locked { DEBUG_LOG("[AuthChallenge] Account '%s' is locked to IP - '%s'", _login.c_str(), (*result)[3].GetString()); DEBUG_LOG("[AuthChallenge] Player address is '%s'", get_remote_address().c_str()); if (strcmp((*result)[3].GetString(), get_remote_address().c_str())) { DEBUG_LOG("[AuthChallenge] Account IP differs"); pkt << (uint8) WOW_FAIL_SUSPENDED; locked = true; } else { DEBUG_LOG("[AuthChallenge] Account IP matches"); } } else { DEBUG_LOG("[AuthChallenge] Account '%s' is not locked to ip", _login.c_str()); } if (!locked) { ///- If the account is banned, reject the logon attempt QueryResult* banresult = LoginDatabase.PQuery("SELECT bandate,unbandate FROM account_banned WHERE " "id = %u AND active = 1 AND (unbandate > UNIX_TIMESTAMP() OR unbandate = bandate)", (*result)[1].GetUInt32()); if (banresult) { if ((*banresult)[0].GetUInt64() == (*banresult)[1].GetUInt64()) { pkt << (uint8) WOW_FAIL_BANNED; BASIC_LOG("[AuthChallenge] Banned account %s tries to login!", _login.c_str()); } else { pkt << (uint8) WOW_FAIL_SUSPENDED; BASIC_LOG("[AuthChallenge] Temporarily banned account %s tries to login!", _login.c_str()); } delete banresult; } else { ///- Get the password from the account table, upper it, and make the SRP6 calculation std::string rI = (*result)[0].GetCppString(); ///- Don't calculate (v, s) if there are already some in the database std::string databaseV = (*result)[5].GetCppString(); std::string databaseS = (*result)[6].GetCppString(); DEBUG_LOG("database authentication values: v='%s' s='%s'", databaseV.c_str(), databaseS.c_str()); // multiply with 2, bytes are stored as hexstring if (databaseV.size() != s_BYTE_SIZE * 2 || databaseS.size() != s_BYTE_SIZE * 2) { _SetVSFields(rI); } else { s.SetHexStr(databaseS.c_str()); v.SetHexStr(databaseV.c_str()); } b.SetRand(19 * 8); BigNumber gmod = g.ModExp(b, N); B = ((v * 3) + gmod) % N; MANGOS_ASSERT(gmod.GetNumBytes() <= 32); BigNumber unk3; unk3.SetRand(16 * 8); ///- Fill the response packet with the result pkt << uint8(WOW_SUCCESS); // B may be calculated < 32B so we force minimal length to 32B pkt.append(B.AsByteArray(32), 32); // 32 bytes pkt << uint8(1); pkt.append(g.AsByteArray(), 1); pkt << uint8(32); pkt.append(N.AsByteArray(32), 32); pkt.append(s.AsByteArray(), s.GetNumBytes());// 32 bytes pkt.append(unk3.AsByteArray(16), 16); uint8 securityFlags = 0; pkt << uint8(securityFlags); // security flags (0x0...0x04) if (securityFlags & 0x01) // PIN input { pkt << uint32(0); pkt << uint64(0) << uint64(0); // 16 bytes hash? } if (securityFlags & 0x02) // Matrix input { pkt << uint8(0); pkt << uint8(0); pkt << uint8(0); pkt << uint8(0); pkt << uint64(0); } if (securityFlags & 0x04) // Security token input { pkt << uint8(1); } uint8 secLevel = (*result)[4].GetUInt8(); _accountSecurityLevel = secLevel <= SEC_ADMINISTRATOR ? AccountTypes(secLevel) : SEC_ADMINISTRATOR; _localizationName.resize(4); for (int i = 0; i < 4; ++i) { _localizationName[i] = ch->country[4 - i - 1]; } BASIC_LOG("[AuthChallenge] account %s is using '%c%c%c%c' locale (%u)", _login.c_str(), ch->country[3], ch->country[2], ch->country[1], ch->country[0], GetLocaleByName(_localizationName)); } } delete result; } else // no account { pkt << (uint8) WOW_FAIL_UNKNOWN_ACCOUNT; } } send((char const*)pkt.contents(), pkt.size()); return true; }
void AuthSocket::HandleReconnectChallenge() { // No header if(GetReadBufferSize() < 4) return; // Check the rest of the packet is complete. uint8 * ReceiveBuffer = GetReadBuffer(0); uint16 full_size = *(uint16*)&ReceiveBuffer[2]; sLog.outDetail("[AuthChallenge] got header, body is 0x%02X bytes", full_size); if(GetReadBufferSize() < (uint32)full_size+4) return; // Copy the data into our cached challenge structure if(full_size > sizeof(sAuthLogonChallenge_C)) { Disconnect(); return; } sLog.outDebug("[AuthChallenge] got full packet."); memcpy(&m_challenge, ReceiveBuffer, full_size + 4); RemoveReadBufferBytes(full_size + 4, false); // Check client build. if(m_challenge.build > LogonServer::getSingleton().max_build || m_challenge.build < LogonServer::getSingleton().min_build) { SendChallengeError(CE_WRONG_BUILD_NUMBER); return; } // Check for a possible IP ban on this client. BAN_STATUS ipb = IPBanner::getSingleton().CalculateBanStatus(GetRemoteAddress()); switch(ipb) { case BAN_STATUS_PERMANENT_BAN: SendChallengeError(CE_ACCOUNT_CLOSED); return; case BAN_STATUS_TIME_LEFT_ON_BAN: SendChallengeError(CE_ACCOUNT_FREEZED); return; } // Null-terminate the account string m_challenge.I[m_challenge.I_len] = 0; // Look up the account information string AccountName = (char*)&m_challenge.I; sLog.outDebug("[AuthChallenge] Account Name: \"%s\"", AccountName.c_str()); m_account = AccountMgr::getSingleton().GetAccount(AccountName); if(m_account == 0) { sLog.outDebug("[AuthChallenge] Invalid account."); // Non-existant account SendChallengeError(CE_NO_ACCOUNT); return; } sLog.outDebug("[AuthChallenge] Account banned state = %u", m_account->Banned); // Check that the account isn't banned. if(m_account->Banned == 1) { SendChallengeError(CE_ACCOUNT_CLOSED); return; } else if(m_account->Banned > 0) { SendChallengeError(CE_ACCOUNT_FREEZED); return; } if(!m_account->SessionKey) { SendChallengeError(CE_SERVER_FULL); return; } /** burlex: this is pure speculation, I really have no idea what this does :p * just guessed the md5 because it was 16 byte blocks. */ MD5_CTX ctx; MD5_Init(&ctx); MD5_Update(&ctx, m_account->SessionKey, 40); uint8 buffer[20]; MD5_Final(buffer, &ctx); ByteBuffer buf; buf << uint16(2); buf.append(buffer, 20); buf << uint64(0); buf << uint64(0); Send(buf.contents(), 34); }
Type deserialize(const ByteBuffer & buffer, std::size_t offset) { return deserialize<Type>(buffer.data() + offset); }
void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacket* data, uint32 mask, ObjectGuid guid, bool full /*= false*/) { // Prevent sending an empty packet if (mask == GROUP_UPDATE_FLAG_NONE) return; std::set<uint32> phases; if (player) player->GetPhaseMgr().GetActivePhases(phases); ByteBuffer dataBuffer; if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) // if update power type, update current/max power also mask |= (GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER); if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) // same for pets mask |= (GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER); Pet* pet = NULL; if (!player) mask &= ~GROUP_UPDATE_FULL; else if (!(pet = player->GetPet())) mask &= ~GROUP_UPDATE_PET; mask |= GROUP_UPDATE_FLAG_STATUS; //if (player && (mask & GROUP_UPDATE_FLAG_STATUS)) // mask |= GROUP_UPDATE_PLAYER_BASE; data->Initialize(SMSG_PARTY_MEMBER_STATS, 200); // average value data->WriteBit(guid[5]); data->WriteBit(guid[2]); data->WriteBit(false); data->WriteBit(guid[6]); data->WriteBit(guid[4]); data->WriteBit(guid[7]); data->WriteBit(guid[3]); data->WriteBit(false); data->WriteBit(guid[0]); data->WriteBit(guid[1]); data->FlushBits(); data->WriteByteSeq(guid[4]); data->WriteByteSeq(guid[6]); if (mask & GROUP_UPDATE_FLAG_STATUS) { uint16 status = MEMBER_STATUS_OFFLINE; if (player) { status |= MEMBER_STATUS_ONLINE; if (player->IsPvP()) status |= MEMBER_STATUS_PVP; if (player->isDead()) status |= MEMBER_STATUS_DEAD; if (player->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) status |= MEMBER_STATUS_GHOST; if (player->IsFFAPvP()) status |= MEMBER_STATUS_PVP_FFA; if (player->isAFK()) status |= MEMBER_STATUS_AFK; if (player->isDND()) status |= MEMBER_STATUS_DND; } dataBuffer << uint16(status); } if (mask & GROUP_UPDATE_FLAG_MOP_UNK) { dataBuffer << uint8(1); // Same realms ? dataBuffer << uint8(0); // in lfg } if (mask & GROUP_UPDATE_FLAG_CUR_HP) dataBuffer << uint32(player->GetHealth()); if (mask & GROUP_UPDATE_FLAG_MAX_HP) dataBuffer << uint32(player->GetMaxHealth()); Powers powerType = POWER_MANA; if (player) powerType = player->getPowerType(); if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) dataBuffer << uint8(powerType); if (mask & GROUP_UPDATE_FLAG_UNK_20) dataBuffer << uint16(0); if (mask & GROUP_UPDATE_FLAG_CUR_POWER) dataBuffer << uint16(player->GetPower(powerType)); if (mask & GROUP_UPDATE_FLAG_MAX_POWER) dataBuffer << uint16(player->GetMaxPower(powerType)); if (mask & GROUP_UPDATE_FLAG_LEVEL) dataBuffer << uint16(player->getLevel()); if (mask & GROUP_UPDATE_FLAG_ZONE) dataBuffer << uint16(player->GetZoneId()); if (mask & GROUP_UPDATE_FLAG_UNK400) dataBuffer << uint16(player->GetAreaId()); if (mask & GROUP_UPDATE_FLAG_POSITION) dataBuffer << uint16(player->GetPositionX()) << uint16(player->GetPositionY()) << uint16(player->GetPositionZ()); if (mask & GROUP_UPDATE_FLAG_AURAS) { uint64 auramask = player->GetAuraUpdateMaskForRaid(); dataBuffer << uint8(1); dataBuffer << uint64(auramask); dataBuffer << uint32(MAX_AURAS); for (uint32 i = 0; i < MAX_AURAS; ++i) { if (!(auramask & (UI64LIT(1) << i))) continue; AuraApplication const* aurApp = player->GetVisibleAura(i); if (!aurApp) { dataBuffer << uint32(0); dataBuffer << uint8(0); dataBuffer << uint32(0); continue; } dataBuffer << uint32(aurApp->GetBase()->GetId()); dataBuffer << uint8(aurApp->GetFlags()); dataBuffer << uint32(aurApp->GetBase()->GetEffectMask()); if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT) { uint32 auraEffectMask = aurApp->GetBase()->GetEffectMask(); size_t pos = dataBuffer.wpos(); uint8 amount_count = 0; dataBuffer << uint8(0); for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j) { if (!(auraEffectMask & (1 << j))) continue; if (constAuraEffectPtr eff = aurApp->GetBase()->GetEffect(j)) // NULL if effect flag not set dataBuffer << float(eff->GetAmount()); else dataBuffer << float(0.0f); ++amount_count; } dataBuffer.put(pos, amount_count); } } } if (mask & GROUP_UPDATE_FLAG_PET_GUID) { if (pet) dataBuffer << uint64(pet->GetGUID()); else dataBuffer << uint64(0); } if (mask & GROUP_UPDATE_FLAG_PET_NAME) { if (pet) dataBuffer << pet->GetName(); else dataBuffer << uint8(0); } if (mask & GROUP_UPDATE_FLAG_PET_MODEL_ID) { if (pet) dataBuffer << uint16(pet->GetDisplayId()); else dataBuffer << uint16(0); } if (mask & GROUP_UPDATE_FLAG_PET_CUR_HP) { if (pet) dataBuffer << uint32(pet->GetHealth()); else dataBuffer << uint32(0); } if (mask & GROUP_UPDATE_FLAG_PET_MAX_HP) { if (pet) dataBuffer << uint32(pet->GetMaxHealth()); else dataBuffer << uint32(0); } if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) { if (pet) dataBuffer << uint8(pet->getPowerType()); else dataBuffer << uint8(0); } if (mask & GROUP_UPDATE_FLAG_MOP_UNK_2) dataBuffer << uint16(0); // Unk if (mask & GROUP_UPDATE_FLAG_PET_CUR_POWER) { if (pet) dataBuffer << uint16(pet->GetPower(pet->getPowerType())); else dataBuffer << uint16(0); } if (mask & GROUP_UPDATE_FLAG_PET_MAX_POWER) { if (pet) dataBuffer << uint16(pet->GetMaxPower(pet->getPowerType())); else dataBuffer << uint16(0); } if (mask & GROUP_UPDATE_FLAG_PET_AURAS) { if (pet) { uint64 auramask = pet->GetAuraUpdateMaskForRaid(); dataBuffer << uint8(1); dataBuffer << uint64(auramask); dataBuffer << uint32(MAX_AURAS); for (uint32 i = 0; i < MAX_AURAS; ++i) { if (!(auramask & (UI64LIT(1) << i))) continue; AuraApplication const* aurApp = pet->GetVisibleAura(i); if (!aurApp) { dataBuffer << uint32(0); dataBuffer << uint8(0); dataBuffer << uint32(0); continue; } dataBuffer << uint32(aurApp->GetBase()->GetId()); dataBuffer << uint8(aurApp->GetFlags()); dataBuffer << uint32(aurApp->GetBase()->GetEffectMask()); if (aurApp->GetFlags() & AFLAG_ANY_EFFECT_AMOUNT_SENT) { uint32 auraEffectMask = aurApp->GetBase()->GetEffectMask(); size_t pos = dataBuffer.wpos(); uint8 count = 0; dataBuffer << uint8(0); for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j) { if (!(auraEffectMask & (1 << j))) continue; if (constAuraEffectPtr eff = aurApp->GetBase()->GetEffect(j)) // NULL if effect flag not set dataBuffer << float(eff->GetAmount()); else dataBuffer << float(0.0f); ++count; } dataBuffer.put(pos, count); } } } else { dataBuffer << uint8(0); dataBuffer << uint64(0); dataBuffer << uint32(0); } } if (mask & GROUP_UPDATE_FLAG_VEHICLE_SEAT) { if (Vehicle* veh = player->GetVehicle()) dataBuffer << uint32(veh->GetVehicleInfo()->m_seatID[player->m_movementInfo.t_seat]); else dataBuffer << uint32(0); } if (mask & GROUP_UPDATE_FLAG_PHASE) { dataBuffer << uint32(phases.empty() ? 0x8 : 0x10); // Same as found in SMSG_SET_PHASE_SHIFT. dataBuffer.WriteBits(phases.size(), 23); // Phases Count. dataBuffer.FlushBits(); for (std::set<uint32>::const_iterator itr = phases.begin(); itr != phases.end(); ++itr) *data << uint16(*itr); } if (mask & GROUP_UPDATE_FLAG_UNK_2000000) dataBuffer << uint16(0); if (mask & GROUP_UPDATE_FLAG_UNK_4000000) dataBuffer << uint32(0); /* this flags are not handled by client */ /*if (mask & GROUP_UPDATE_FLAG_UNK_8000000) dataBuffer << uint8(0); if (mask & GROUP_UPDATE_FLAG_UNK_10000000) dataBuffer << uint8(0); if (mask & GROUP_UPDATE_FLAG_UNK_20000000) dataBuffer << uint8(253); if (mask & GROUP_UPDATE_FLAG_UNK_40000000) dataBuffer << uint8(0);*/ *data << uint32(dataBuffer.size()); data->append(dataBuffer); data->WriteByteSeq(guid[3]); data->WriteByteSeq(guid[5]); *data << uint32(mask); data->WriteByteSeq(guid[0]); data->WriteByteSeq(guid[1]); data->WriteByteSeq(guid[2]); data->WriteByteSeq(guid[7]); }
void PacketBuilder::WriteStopMovement(Vector3 const& pos, uint32 splineId, ByteBuffer& data, Unit* unit) { ObjectGuid guid = unit->GetGUID(); ObjectGuid transport = unit->GetTransGUID(); data << float(0.f); data << uint32(getMSTime()); data << float(0.f); data << float(0.f); data << float(unit->GetPositionX()); data << float(unit->GetPositionY()); data << float(unit->GetPositionZ()); data.WriteBit(guid[3]); data.WriteBit(!unit->movespline->splineflags.raw()); data.WriteBit(guid[6]); data.WriteBit(1); data.WriteBit(1); data.WriteBits(0, 3); data.WriteBit(1); data.WriteBit(guid[2]); data.WriteBit(guid[7]); data.WriteBit(guid[5]); data.WriteBit(1); data.WriteBit(guid[4]); data.WriteBits(0, 22); // WP count data.WriteBit(1); data.WriteBit(0); data.WriteBit(guid[0]); data.WriteBit(transport[3]); data.WriteBit(transport[6]); data.WriteBit(transport[5]); data.WriteBit(transport[0]); data.WriteBit(transport[1]); data.WriteBit(transport[2]); data.WriteBit(transport[4]); data.WriteBit(transport[7]); data.WriteBit(1); data.WriteBit(1); // Parabolic speed // esi+4Ch data.WriteBit(1); data.WriteBits(0, 20); data.WriteBit(guid[1]); data.WriteBit(0); data.WriteBit(0); data.WriteBit(0); data.FlushBits(); data.WriteByteSeq(guid[3]); data.WriteByteSeq(transport[7]); data.WriteByteSeq(transport[3]); data.WriteByteSeq(transport[2]); data.WriteByteSeq(transport[0]); data.WriteByteSeq(transport[6]); data.WriteByteSeq(transport[5]); data.WriteByteSeq(transport[4]); data.WriteByteSeq(transport[1]); if (unit->movespline->splineflags.raw()) data << uint32(unit->movespline->splineflags.raw()); data.WriteByteSeq(guid[7]); data.WriteByteSeq(guid[5]); data.WriteByteSeq(guid[1]); data.WriteByteSeq(guid[2]); data.WriteByteSeq(guid[6]); data.WriteByteSeq(guid[0]); data.WriteByteSeq(guid[4]); }
void PacketBuilder::WriteCreateBits(MoveSpline const& moveSpline, ByteBuffer& data) { if (!data.WriteBit(!moveSpline.Finalized())) return; data.WriteBits(uint8(moveSpline.spline.mode()), 2); data.WriteBit(moveSpline.splineflags & (MoveSplineFlag::Parabolic | MoveSplineFlag::Animation)); data.WriteBits(moveSpline.getPath().size(), 22); switch (moveSpline.splineflags & MoveSplineFlag::Mask_Final_Facing) { case MoveSplineFlag::Final_Target: { ObjectGuid targetGuid = moveSpline.facing.target; data.WriteBits(2, 2); data.WriteBit(targetGuid[4]); data.WriteBit(targetGuid[3]); data.WriteBit(targetGuid[7]); data.WriteBit(targetGuid[2]); data.WriteBit(targetGuid[6]); data.WriteBit(targetGuid[1]); data.WriteBit(targetGuid[0]); data.WriteBit(targetGuid[5]); break; } case MoveSplineFlag::Final_Angle: data.WriteBits(0, 2); break; case MoveSplineFlag::Final_Point: data.WriteBits(1, 2); break; default: data.WriteBits(3, 2); break; } data.WriteBit((moveSpline.splineflags & MoveSplineFlag::Parabolic) && moveSpline.effect_start_time < moveSpline.Duration()); data.WriteBits(moveSpline.splineflags.raw(), 25); }
void WardenWin::RequestData() { sLog->outWarden("Request data"); // If all checks were done, fill the todo list again if (_memChecksTodo.empty()) _memChecksTodo.assign(sWardenCheckMgr->MemChecksIdPool.begin(), sWardenCheckMgr->MemChecksIdPool.end()); if (_otherChecksTodo.empty()) _otherChecksTodo.assign(sWardenCheckMgr->OtherChecksIdPool.begin(), sWardenCheckMgr->OtherChecksIdPool.end()); _serverTicks = getMSTime(); uint32 id; uint8 type; WardenCheck* wd; _currentChecks.clear(); // Build check request (3 mem checks + 7 other checks) for (int i = 0; i < 3; ++i) { // If todo list is done break loop (will be filled on next Update() run) if (_memChecksTodo.empty()) break; // Get check id from the end and remove it from todo id = _memChecksTodo.back(); _memChecksTodo.pop_back(); // Add the id to the list sent in this cycle _currentChecks.push_back(id); } ByteBuffer buff; buff << uint8(WARDEN_SMSG_CHEAT_CHECKS_REQUEST); for (int i = 0; i < 7; ++i) { // If todo list is done break loop (will be filled on next Update() run) if (_otherChecksTodo.empty()) break; // Get check id from the end and remove it from todo id = _otherChecksTodo.back(); _otherChecksTodo.pop_back(); // Add the id to the list sent in this cycle _currentChecks.push_back(id); wd = sWardenCheckMgr->GetWardenDataById(id); // Skip if checks aren't in the stores anymore (e.g. by database edit & reload during runtime) if (!wd) continue; switch (wd->Type) { case MPQ_CHECK: case LUA_STR_CHECK: case DRIVER_CHECK: buff << uint8(wd->Str.size()); buff.append(wd->Str.c_str(), wd->Str.size()); break; default: break; } } uint8 xorByte = _inputKey[0]; buff << uint8(0x00); buff << uint8(TIMING_CHECK ^ xorByte); // check TIMING_CHECK uint8 index = 1; for (std::list<uint32>::iterator itr = _currentChecks.begin(); itr != _currentChecks.end(); ++itr) { // Skip if checks aren't in the stores anymore (e.g. by database edit & reload during runtime) wd = sWardenCheckMgr->GetWardenDataById(*itr); if (!wd) continue; type = wd->Type; buff << uint8(type ^ xorByte); switch (type) { case MEM_CHECK: { buff << uint8(0x00); buff << uint32(wd->Address); buff << uint8(wd->Length); break; } case PAGE_CHECK_A: case PAGE_CHECK_B: { buff.append(wd->Data.AsByteArray(0, false), wd->Data.GetNumBytes()); buff << uint32(wd->Address); buff << uint8(wd->Length); break; } case MPQ_CHECK: case LUA_STR_CHECK: { buff << uint8(index++); break; } case DRIVER_CHECK: { buff.append(wd->Data.AsByteArray(0, false), wd->Data.GetNumBytes()); buff << uint8(index++); break; } case MODULE_CHECK: { uint32 seed = static_cast<uint32>(rand32()); buff << uint32(seed); HmacHash hmac(4, (uint8*)&seed); hmac.UpdateData(wd->Str); hmac.Finalize(); buff.append(hmac.GetDigest(), hmac.GetLength()); break; } /*case PROC_CHECK: { buff.append(wd->i.AsByteArray(0, false), wd->i.GetNumBytes()); buff << uint8(index++); buff << uint8(index++); buff << uint32(wd->Address); buff << uint8(wd->Length); break; }*/ default: break; // Should never happen } } buff << uint8(xorByte); buff.hexlike(); // Encrypt with warden RC4 key. EncryptData(const_cast<uint8*>(buff.contents()), buff.size()); WorldPacket pkt(SMSG_WARDEN_DATA, buff.size()); pkt.append(buff); _session->SendPacket(&pkt); // DEBUG CODE: Save time the request was sent for later comparison _requestSent = time(NULL); _dataSent = true; std::stringstream stream; stream << "Sent check id's: "; for (std::list<uint32>::iterator itr = _currentChecks.begin(); itr != _currentChecks.end(); ++itr) stream << *itr << " "; sLog->outWarden(stream.str().c_str()); }
/// Logon Proof command handler bool AuthSocket::_HandleLogonProof() { DEBUG_LOG("Entering _HandleLogonProof"); ///- Read the packet sAuthLogonProof_C lp; if (!recv((char*)&lp, sizeof(sAuthLogonProof_C))) { return false; } ///- Check if the client has one of the expected version numbers bool valid_version = FindBuildInfo(_build) != NULL; /// <ul><li> If the client has no valid version if (!valid_version) { if (this->patch_ != ACE_INVALID_HANDLE) { return false; } ///- Check if we have the apropriate patch on the disk // file looks like: 65535enGB.mpq char tmp[64]; snprintf(tmp, 24, "./patches/%d%s.mpq", _build, _localizationName.c_str()); char filename[PATH_MAX]; if (ACE_OS::realpath(tmp, filename) != NULL) { patch_ = ACE_OS::open(filename, GENERIC_READ | FILE_FLAG_SEQUENTIAL_SCAN); } if (patch_ == ACE_INVALID_HANDLE) { // no patch found ByteBuffer pkt; pkt << (uint8) CMD_AUTH_LOGON_CHALLENGE; pkt << (uint8) 0x00; pkt << (uint8) WOW_FAIL_VERSION_INVALID; DEBUG_LOG("[AuthChallenge] %u is not a valid client version!", _build); DEBUG_LOG("[AuthChallenge] Patch %s not found", tmp); send((char const*)pkt.contents(), pkt.size()); return true; } XFER_INIT xferh; ACE_OFF_T file_size = ACE_OS::filesize(this->patch_); if (file_size == -1) { close_connection(); return false; } if (!PatchCache::instance()->GetHash(tmp, (uint8*)&xferh.md5)) { // calculate patch md5, happens if patch was added while realmd was running PatchCache::instance()->LoadPatchMD5(tmp); PatchCache::instance()->GetHash(tmp, (uint8*)&xferh.md5); } uint8 data[2] = { CMD_AUTH_LOGON_PROOF, WOW_FAIL_VERSION_UPDATE}; send((const char*)data, sizeof(data)); memcpy(&xferh, "0\x05Patch", 7); xferh.cmd = CMD_XFER_INITIATE; xferh.file_size = file_size; send((const char*)&xferh, sizeof(xferh)); return true; } /// </ul> ///- Continue the SRP6 calculation based on data received from the client BigNumber A; A.SetBinary(lp.A, 32); // SRP safeguard: abort if A==0 if (A.isZero()) { return false; } Sha1Hash sha; sha.UpdateBigNumbers(&A, &B, NULL); sha.Finalize(); BigNumber u; u.SetBinary(sha.GetDigest(), 20); BigNumber S = (A * (v.ModExp(u, N))).ModExp(b, N); uint8 t[32]; uint8 t1[16]; uint8 vK[40]; memcpy(t, S.AsByteArray(32), 32); for (int i = 0; i < 16; ++i) { t1[i] = t[i * 2]; } sha.Initialize(); sha.UpdateData(t1, 16); sha.Finalize(); for (int i = 0; i < 20; ++i) { vK[i * 2] = sha.GetDigest()[i]; } for (int i = 0; i < 16; ++i) { t1[i] = t[i * 2 + 1]; } sha.Initialize(); sha.UpdateData(t1, 16); sha.Finalize(); for (int i = 0; i < 20; ++i) { vK[i * 2 + 1] = sha.GetDigest()[i]; } K.SetBinary(vK, 40); uint8 hash[20]; sha.Initialize(); sha.UpdateBigNumbers(&N, NULL); sha.Finalize(); memcpy(hash, sha.GetDigest(), 20); sha.Initialize(); sha.UpdateBigNumbers(&g, NULL); sha.Finalize(); for (int i = 0; i < 20; ++i) { hash[i] ^= sha.GetDigest()[i]; } BigNumber t3; t3.SetBinary(hash, 20); sha.Initialize(); sha.UpdateData(_login); sha.Finalize(); uint8 t4[SHA_DIGEST_LENGTH]; memcpy(t4, sha.GetDigest(), SHA_DIGEST_LENGTH); sha.Initialize(); sha.UpdateBigNumbers(&t3, NULL); sha.UpdateData(t4, SHA_DIGEST_LENGTH); sha.UpdateBigNumbers(&s, &A, &B, &K, NULL); sha.Finalize(); BigNumber M; M.SetBinary(sha.GetDigest(), 20); ///- Check if SRP6 results match (password is correct), else send an error if (!memcmp(M.AsByteArray(), lp.M1, 20)) { BASIC_LOG("User '%s' successfully authenticated", _login.c_str()); ///- Update the sessionkey, last_ip, last login time and reset number of failed logins in the account table for this account // No SQL injection (escaped user name) and IP address as received by socket const char* K_hex = K.AsHexStr(); LoginDatabase.PExecute("UPDATE account SET sessionkey = '%s', last_ip = '%s', last_login = NOW(), locale = '%u', failed_logins = 0 WHERE username = '******'", K_hex, get_remote_address().c_str(), GetLocaleByName(_localizationName), _safelogin.c_str()); OPENSSL_free((void*)K_hex); ///- Finish SRP6 and send the final result to the client sha.Initialize(); sha.UpdateBigNumbers(&A, &M, &K, NULL); sha.Finalize(); SendProof(sha); ///- Set _authed to true! _authed = true; } else { if (_build > 6005) // > 1.12.2 { char data[4] = { CMD_AUTH_LOGON_PROOF, WOW_FAIL_UNKNOWN_ACCOUNT, 3, 0}; send(data, sizeof(data)); } else { // 1.x not react incorrectly at 4-byte message use 3 as real error char data[2] = { CMD_AUTH_LOGON_PROOF, WOW_FAIL_UNKNOWN_ACCOUNT}; send(data, sizeof(data)); } BASIC_LOG("[AuthChallenge] account %s tried to login with wrong password!", _login.c_str()); uint32 MaxWrongPassCount = sConfig.GetIntDefault("WrongPass.MaxCount", 0); if (MaxWrongPassCount > 0) { // Increment number of failed logins by one and if it reaches the limit temporarily ban that account or IP LoginDatabase.PExecute("UPDATE account SET failed_logins = failed_logins + 1 WHERE username = '******'", _safelogin.c_str()); if (QueryResult* loginfail = LoginDatabase.PQuery("SELECT id, failed_logins FROM account WHERE username = '******'", _safelogin.c_str())) { Field* fields = loginfail->Fetch(); uint32 failed_logins = fields[1].GetUInt32(); if (failed_logins >= MaxWrongPassCount) { uint32 WrongPassBanTime = sConfig.GetIntDefault("WrongPass.BanTime", 600); bool WrongPassBanType = sConfig.GetBoolDefault("WrongPass.BanType", false); if (WrongPassBanType) { uint32 acc_id = fields[0].GetUInt32(); LoginDatabase.PExecute("INSERT INTO account_banned VALUES ('%u',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','MaNGOS realmd','Failed login autoban',1)", acc_id, WrongPassBanTime); BASIC_LOG("[AuthChallenge] account %s got banned for '%u' seconds because it failed to authenticate '%u' times", _login.c_str(), WrongPassBanTime, failed_logins); } else { std::string current_ip = get_remote_address(); LoginDatabase.escape_string(current_ip); LoginDatabase.PExecute("INSERT INTO ip_banned VALUES ('%s',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','MaNGOS realmd','Failed login autoban')", current_ip.c_str(), WrongPassBanTime); BASIC_LOG("[AuthChallenge] IP %s got banned for '%u' seconds because account %s failed to authenticate '%u' times", current_ip.c_str(), WrongPassBanTime, _login.c_str(), failed_logins); } } delete loginfail; } } } return true; }
void WardenWin::HandleData(ByteBuffer &buff) { sLog->outWarden("Handle data"); _dataSent = false; _clientResponseTimer = 0; /* DEBUG CODE if (_requestSent < time(NULL) - 30) { sLog->outError("WARDEN: Player %s (guid: %u, account: %u) took %s to respond to warden check request", _session->GetPlayerName(), _session->GetGuidLow(), _session->GetAccountId(), secsToTimeString(uint32(time(NULL)- _requestSent), true).c_str()); }*/ uint16 Length; buff >> Length; uint32 Checksum; buff >> Checksum; if (!IsValidCheckSum(Checksum, buff.contents() + buff.rpos(), Length)) { buff.rpos(buff.wpos()); sLog->outWarden("CHECKSUM FAIL"); sLog->outError("WARDEN: Player %s (guid: %u, account: %u) failed checksum. Action: %s", _session->GetPlayerName(), _session->GetGuidLow(), _session->GetAccountId(), Penalty().c_str()); return; } // TIMING_CHECK { uint8 result; buff >> result; // TODO: test it. if (result == 0x00) { sLog->outWarden("TIMING CHECK FAIL result 0x00"); sLog->outError("WARDEN: Player %s (guid: %u, account: %u) failed timing check. Action: %s", _session->GetPlayerName(), _session->GetGuidLow(), _session->GetAccountId(), Penalty().c_str()); return; } uint32 newClientTicks; buff >> newClientTicks; uint32 ticksNow = getMSTime(); uint32 ourTicks = newClientTicks + (ticksNow - _serverTicks); sLog->outWarden("ServerTicks %u", ticksNow); // Now sLog->outWarden("RequestTicks %u", _serverTicks); // At request sLog->outWarden("Ticks %u", newClientTicks); // At response sLog->outWarden("Ticks diff %u", ourTicks - newClientTicks); } WardenCheckResult *rs; WardenCheck *rd; uint8 type; uint32 checkFailed = 0; for (std::list<uint32>::iterator itr = _currentChecks.begin(); itr != _currentChecks.end(); ++itr) { rd = sWardenCheckMgr->GetWardenDataById(*itr); rs = sWardenCheckMgr->GetWardenResultById(*itr); // Skip if checks aren't in the stores anymore (e.g. by database edit & reload during runtime) if (!rd) { buff.read_skip(1); continue; } type = rd->Type; switch (type) { case MEM_CHECK: { uint8 Mem_Result; buff >> Mem_Result; if (Mem_Result != 0) { sLog->outWarden("RESULT MEM_CHECK not 0x00, CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; continue; } if (memcmp(buff.contents() + buff.rpos(), rs->Result.AsByteArray(0, false), rd->Length) != 0) { sLog->outWarden("RESULT MEM_CHECK fail CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; buff.rpos(buff.rpos() + rd->Length); continue; } buff.rpos(buff.rpos() + rd->Length); sLog->outWarden("RESULT MEM_CHECK passed CheckId %u account Id %u", *itr, _session->GetAccountId()); break; } case PAGE_CHECK_A: case PAGE_CHECK_B: case DRIVER_CHECK: case MODULE_CHECK: { const uint8 byte = 0xE9; if (memcmp(buff.contents() + buff.rpos(), &byte, sizeof(uint8)) != 0) { if (type == PAGE_CHECK_A || type == PAGE_CHECK_B) sLog->outWarden("RESULT PAGE_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId()); if (type == MODULE_CHECK) sLog->outWarden("RESULT MODULE_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId()); if (type == DRIVER_CHECK) sLog->outWarden("RESULT DRIVER_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; buff.rpos(buff.rpos() + 1); continue; } buff.rpos(buff.rpos() + 1); if (type == PAGE_CHECK_A || type == PAGE_CHECK_B) sLog->outWarden("RESULT PAGE_CHECK passed CheckId %u account Id %u", *itr, _session->GetAccountId()); else if (type == MODULE_CHECK) sLog->outWarden("RESULT MODULE_CHECK passed CheckId %u account Id %u", *itr, _session->GetAccountId()); else if (type == DRIVER_CHECK) sLog->outWarden("RESULT DRIVER_CHECK passed CheckId %u account Id %u", *itr, _session->GetAccountId()); break; } case LUA_STR_CHECK: { uint8 Lua_Result; buff >> Lua_Result; if (Lua_Result != 0) { sLog->outWarden("RESULT LUA_STR_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; continue; } uint8 luaStrLen; buff >> luaStrLen; if (luaStrLen != 0) { char *str = new char[luaStrLen + 1]; memset(str, 0, luaStrLen + 1); memcpy(str, buff.contents() + buff.rpos(), luaStrLen); sLog->outWarden("Lua string: %s", str); delete[] str; } buff.rpos(buff.rpos() + luaStrLen); // Skip string sLog->outWarden("RESULT LUA_STR_CHECK passed, CheckId %u account Id %u", *itr, _session->GetAccountId()); break; } case MPQ_CHECK: { uint8 Mpq_Result; buff >> Mpq_Result; if (Mpq_Result != 0) { sLog->outWarden("RESULT MPQ_CHECK not 0x00 account id %u", _session->GetAccountId()); checkFailed = *itr; continue; } if (memcmp(buff.contents() + buff.rpos(), rs->Result.AsByteArray(0, false), 20) != 0) // SHA1 { sLog->outWarden("RESULT MPQ_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; buff.rpos(buff.rpos() + 20); // 20 bytes SHA1 continue; } buff.rpos(buff.rpos() + 20); // 20 bytes SHA1 sLog->outWarden("RESULT MPQ_CHECK passed, CheckId %u account Id %u", *itr, _session->GetAccountId()); break; } default: // Should never happen break; } } if (checkFailed > 0) { sLog->outError("WARDEN: Player %s (guid: %u, account: %u) failed Warden check %u. Action: %s", _session->GetPlayerName(), _session->GetGuidLow(), _session->GetAccountId(), checkFailed, Penalty().c_str()); } }
/// Reconnect Challenge command handler bool AuthSocket::_HandleReconnectChallenge() { DEBUG_LOG("Entering _HandleReconnectChallenge"); if (recv_len() < sizeof(sAuthLogonChallenge_C)) { return false; } ///- Read the first 4 bytes (header) to get the length of the remaining of the packet std::vector<uint8> buf; buf.resize(4); recv((char*)&buf[0], 4); EndianConvert(*((uint16*)(buf[0]))); uint16 remaining = ((sAuthLogonChallenge_C*)&buf[0])->size; DEBUG_LOG("[ReconnectChallenge] got header, body is %#04x bytes", remaining); if ((remaining < sizeof(sAuthLogonChallenge_C) - buf.size()) || (recv_len() < remaining)) { return false; } // No big fear of memory outage (size is int16, i.e. < 65536) buf.resize(remaining + buf.size() + 1); buf[buf.size() - 1] = 0; sAuthLogonChallenge_C* ch = (sAuthLogonChallenge_C*)&buf[0]; ///- Read the remaining of the packet recv((char*)&buf[4], remaining); DEBUG_LOG("[ReconnectChallenge] got full packet, %#04x bytes", ch->size); DEBUG_LOG("[ReconnectChallenge] name(%d): '%s'", ch->I_len, ch->I); _login = (const char*)ch->I; _safelogin = _login; LoginDatabase.escape_string(_safelogin); EndianConvert(ch->build); _build = ch->build; QueryResult* result = LoginDatabase.PQuery("SELECT sessionkey FROM account WHERE username = '******'", _safelogin.c_str()); // Stop if the account is not found if (!result) { sLog.outError("[ERROR] user %s tried to login and we can not find his session key in the database.", _login.c_str()); close_connection(); return false; } Field* fields = result->Fetch(); K.SetHexStr(fields[0].GetString()); delete result; ///- Sending response ByteBuffer pkt; pkt << (uint8) CMD_AUTH_RECONNECT_CHALLENGE; pkt << (uint8) 0x00; _reconnectProof.SetRand(16 * 8); pkt.append(_reconnectProof.AsByteArray(16), 16); // 16 bytes random pkt << (uint64) 0x00 << (uint64) 0x00; // 16 bytes zeros send((char const*)pkt.contents(), pkt.size()); return true; }
void ConnectedClientTransport::onReadCompleted( const ByteBuffer &byteBuffer) { onTransitionCompleted(byteBuffer.getLength()); }
void DataSink::_ReadCallback(ev::io &watcher, int revents) { if (EV_ERROR & revents) { LOG(WARNING) << "got invalid event"; return; } ByteBuffer *buf = (ByteBuffer *) watcher.data; buf->Defragment(); int len = buf->GetContinuousBytesLeft(); unsigned int numBytesReceived = recv(watcher.fd, buf->GetWriteReference(), len, MSG_NOSIGNAL); buf->BytesWritten(numBytesReceived); if (numBytesReceived < 0) { LOG(ERROR) << "failed reading socket - client probably disconnected"; return; } if (numBytesReceived <= 0) { // Stop and free watcher if client socket is closing LOG(INFO) << "client disconnected: " << _watcherMap[&watcher] << " -> " << --_numConnectedClients << " client(s) connected"; _DeleteAndCleanupWatcher(watcher); return; } while (buf->GetBytesAvailable() > 4) { // As long as there are more than 4 bytes available there could be // (at least) one more full message in the buffer int messageLength = ntohl(*((unsigned int *) buf->GetReadReference())); if (messageLength > buf->GetCapacity() - 4) { // Current buffer too small, double the capacity at a minimum // and wait until next read on socket if (messageLength > buf->GetCapacity() * 2) buf->Resize(messageLength); else buf->Resize(buf->GetCapacity() * 2); LOG(INFO) << "Buffer resized, new capacity: " << buf->GetCapacity(); break; } if (buf->GetBytesAvailable() - 4 < messageLength) // Fragmented packet, wait until next event. // Note that the same message length header will be read over again break; // There is still at least one more full message available buf->BytesRead(4); _router->Route(buf->GetReadReference(), messageLength); buf->BytesRead(messageLength); } _ioLogger->Read(numBytesReceived); }
int CFriendBoss::DeSeriliazeDB(ByteBuffer &by) { if (by.size() == 0) return 0; by >> m_BossIndex; by >> m_StartTime; by >> m_BossHealth; by >> m_Level; uint32_t number, key, val; SRecord tmp; by >> number; for (int i = 0; i < number; i++) { by >> key; by >> val; m_mapActiveBoss[key] = val; } by >> number; for (int i = 0; i < number; i++) { by >> tmp.userid; by >> tmp.username; by >> tmp.time; by >> tmp.skillindex; by >> tmp.skilllevel; by >> tmp.totalharm; m_listRecord.push_back(tmp); } Prize tmpp; by >> number; for (int i = 0; i < number; i++) { by >> key; tmpp.key = key; by >> tmpp.userid; by >> tmpp.username; by >> tmpp.masterindex; by >> tmpp.viewlv; by >> tmpp.lv; by >> tmpp.t; by >> tmpp.number; by >> tmpp.time; m_mapPrize[key] = tmpp; } Attacked tmpa; by >> number; for (int i = 0; i < number; i++) { by >> key; tmpa.key = key; by >> tmpa.userid; by >> tmpa.username; by >> tmpa.masterindex; by >> tmpa.lv; by >> tmpa.time; m_mapAttacked[key] = tmpa; } by >> number; for (int i = 0; i < number; i++) { by >> val; m_vecUserId.push_back(val); } by >> m_ActiveFlushTime; by >> m_FirstPrize; return 0; }
void WardenMac::HandleHashResult(ByteBuffer &buff) { // test int keyIn[4]; uint8 mod_seed[16] = { 0x4D, 0x80, 0x8D, 0x2C, 0x77, 0xD9, 0x05, 0xC4, 0x1A, 0x63, 0x80, 0xEC, 0x08, 0x58, 0x6A, 0xFE }; for(int i = 0; i < 4; ++i) { keyIn[i] = *(int*)(&mod_seed[0] + i * 4); } int keyOut[4]; int keyIn1, keyIn2; keyOut[0] = keyIn[0]; keyIn[0] ^= 0xDEADBEEFu; keyIn1 = keyIn[1]; keyIn[1] -= 0x35014542u; keyIn2 = keyIn[2]; keyIn[2] += 0x5313F22u; keyIn[3] *= 0x1337F00Du; keyOut[1] = keyIn1 - 0x6A028A84; keyOut[2] = keyIn2 + 0xA627E44; keyOut[3] = 0x1337F00D * keyIn[3]; // end test buff.rpos(buff.wpos()); SHA1Hash sha1; sha1.UpdateData((uint8*)keyIn, 16); sha1.Finalize(); //const uint8 validHash[20] = { 0x56, 0x8C, 0x05, 0x4C, 0x78, 0x1A, 0x97, 0x2A, 0x60, 0x37, 0xA2, 0x29, 0x0C, 0x22, 0xB5, 0x25, 0x71, 0xA0, 0x6F, 0x4E }; // verify key not equal kick player if (memcmp(buff.contents() + 1, sha1.GetDigest(), 20) != 0) { sLog->outWarden("Request hash reply: failed"); if (sWorld->getConfig(CONFIG_WARDEN_KICK)) Client->KickPlayer(); return; } sLog->outDebug (LOG_FILTER_NETWORKIO, "Request hash reply: succeed"); // client 7F96EEFDA5B63D20A4DF8E00CBF48304 //const uint8 client_key[16] = { 0x7F, 0x96, 0xEE, 0xFD, 0xA5, 0xB6, 0x3D, 0x20, 0xA4, 0xDF, 0x8E, 0x00, 0xCB, 0xF4, 0x83, 0x04 }; // server C2B7ADEDFCCCA9C2BFB3F85602BA809B //const uint8 server_key[16] = { 0xC2, 0xB7, 0xAD, 0xED, 0xFC, 0xCC, 0xA9, 0xC2, 0xBF, 0xB3, 0xF8, 0x56, 0x02, 0xBA, 0x80, 0x9B }; // change keys here memcpy(InputKey, keyIn, 16); memcpy(OutputKey, keyOut, 16); iCrypto.Init(InputKey); oCrypto.Init(OutputKey); m_initialized = true; m_WardenTimer = getMSTime(); }
bool SmsNobreak::SendNobreakInitCommands() { // first of all, open the communication port, of course if (!_serial.Open()) { return false; } // send the bytes the nobreak expects at startup, // just as seen on the serial communication logs ByteBuffer buffer; buffer.push_back(0x49); buffer.push_back(0); buffer.push_back(0); buffer.push_back(0); buffer.push_back(0); buffer.push_back(0xB7); buffer.push_back(0x0D); if (!_serial.SendData(buffer)) { return false; } sleep_ms(200); buffer.clear(); buffer.push_back(0x49); buffer.push_back(0); buffer.push_back(0); buffer.push_back(0); buffer.push_back(0); buffer.push_back(0xB7); buffer.push_back(0x0D); if (!_serial.SendData(buffer)) { return false; } sleep_ms(200); buffer.clear(); buffer.push_back(0x46); buffer.push_back(0); buffer.push_back(0); buffer.push_back(0); buffer.push_back(0); buffer.push_back(0xBA); buffer.push_back(0x0D); if (!_serial.SendData(buffer)) { return false; } sleep_ms(200); buffer.clear(); if (_serial.ReadData(buffer, 2000)) { if (buffer.size() == 0) { return false; } sleep_ms(2000); } return true; }
void PacketBuilder::WriteStopMovement(Vector3 const& pos, uint32 splineId, ByteBuffer& data, Unit* unit) { ObjectGuid guid = unit->GetGUID(); ObjectGuid transport = unit->GetTransGUID(); data << float(0.f); // Most likely transport Y data << uint32(splineId); data << float(0.f); // Most likely transport Z data << float(0.f); // Most likely transport X data << float(pos.x); data << float(pos.y); data << float(pos.z); data.WriteBit(guid[3]); data.WriteBit(1); data.WriteBit(guid[6]); data.WriteBit(1); data.WriteBit(1); data.WriteBits(MonsterMoveStop, 3); data.WriteBit(1); data.WriteBit(guid[2]); data.WriteBit(guid[7]); data.WriteBit(guid[5]); data.WriteBit(1); data.WriteBit(guid[4]); data.WriteBits(0, 22); // WP count data.WriteBit(1); data.WriteBit(0); data.WriteBit(guid[0]); uint8 transportBitsOrder[8] = {3, 6, 5, 0, 1, 2, 4, 7}; uint8 transportBytesOrder[8] = {7, 3, 2, 0, 6, 4, 5, 1}; data.WriteBitInOrder(transport, transportBitsOrder); data.WriteBit(1); data.WriteBit(1); // Parabolic speed // esi+4Ch data.WriteBit(1); data.WriteBits(0, 20); data.WriteBit(guid[1]); data.WriteBit(0); data.WriteBit(0); data.WriteBit(1); data.FlushBits(); data.WriteByteSeq(guid[3]); data.WriteBytesSeq(transport, transportBytesOrder); data.WriteByteSeq(guid[7]); data.WriteByteSeq(guid[5]); data.WriteByteSeq(guid[1]); data.WriteByteSeq(guid[2]); data.WriteByteSeq(guid[6]); data.WriteByteSeq(guid[0]); data.WriteByteSeq(guid[4]); }
/// Reconnect Challenge command handler bool AuthSocket::_HandleReconnectChallenge() { sLog->outStaticDebug("Entering _HandleReconnectChallenge"); if (socket().recv_len() < sizeof(sAuthLogonChallenge_C)) return false; // Read the first 4 bytes (header) to get the length of the remaining of the packet std::vector<uint8> buf; buf.resize(4); socket().recv((char *)&buf[0], 4); #if TRINITY_ENDIAN == TRINITY_BIGENDIAN EndianConvert(*((uint16*)(buf[0]))); #endif //TRINITY_ENDIAN uint16 remaining = ((sAuthLogonChallenge_C *)&buf[0])->size; sLog->outStaticDebug("[ReconnectChallenge] got header, body is %#04x bytes", remaining); if ((remaining < sizeof(sAuthLogonChallenge_C) - buf.size()) || (socket().recv_len() < remaining)) return false; // No big fear of memory outage (size is int16, i.e. < 65536) buf.resize(remaining + buf.size() + 1); buf[buf.size() - 1] = 0; sAuthLogonChallenge_C *ch = (sAuthLogonChallenge_C*)&buf[0]; // Read the remaining of the packet socket().recv((char *)&buf[4], remaining); sLog->outStaticDebug("[ReconnectChallenge] got full packet, %#04x bytes", ch->size); sLog->outStaticDebug("[ReconnectChallenge] name(%d): '%s'", ch->I_len, ch->I); _login = (const char*)ch->I; PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_SESSIONKEY); stmt->setString(0, _login); PreparedQueryResult result = LoginDatabase.Query(stmt); // Stop if the account is not found if (!result) { sLog->outError("[ERROR] user %s tried to login and we cannot find his session key in the database.", _login.c_str()); socket().shutdown(); return false; } // Reinitialize build, expansion and the account securitylevel _build = ch->build; _expversion = (AuthHelper::IsPostBCAcceptedClientBuild(_build) ? POST_BC_EXP_FLAG : NO_VALID_EXP_FLAG) | (AuthHelper::IsPreBCAcceptedClientBuild(_build) ? PRE_BC_EXP_FLAG : NO_VALID_EXP_FLAG); Field* fields = result->Fetch(); uint8 secLevel = fields[2].GetUInt8(); _accountSecurityLevel = secLevel <= SEC_ADMINISTRATOR ? AccountTypes(secLevel) : SEC_ADMINISTRATOR; K.SetHexStr ((*result)[0].GetCString()); // Sending response ByteBuffer pkt; pkt << (uint8)AUTH_RECONNECT_CHALLENGE; pkt << (uint8)0x00; _reconnectProof.SetRand(16 * 8); pkt.append(_reconnectProof.AsByteArray(16), 16); // 16 bytes random pkt << (uint64)0x00 << (uint64)0x00; // 16 bytes zeros socket().send((char const*)pkt.contents(), pkt.size()); return true; }
void WorldSession::ReadAddonsInfo(WorldPacket &data) { if (data.rpos() + 4 > data.size()) return; uint32 size; data >> size; if (!size) return; if (size > 0xFFFFF) { sLog->outError(LOG_FILTER_GENERAL, "WorldSession::ReadAddonsInfo addon info too big, size %u", size); return; } uLongf uSize = size; uint32 pos = data.rpos(); ByteBuffer addonInfo; addonInfo.resize(size); if (uncompress(addonInfo.contents(), &uSize, data.contents() + pos, data.size() - pos) == Z_OK) { uint32 addonsCount; addonInfo >> addonsCount; // addons count for (uint32 i = 0; i < addonsCount; ++i) { std::string addonName; uint8 enabled; uint32 crc, unk1; // check next addon data format correctness if (addonInfo.rpos() + 1 > addonInfo.size()) return; addonInfo >> addonName; addonInfo >> enabled >> crc >> unk1; sLog->outInfo(LOG_FILTER_GENERAL, "ADDON: Name: %s, Enabled: 0x%x, CRC: 0x%x, Unknown2: 0x%x", addonName.c_str(), enabled, crc, unk1); AddonInfo addon(addonName, enabled, crc, 2, true); SavedAddon const* savedAddon = AddonMgr::GetAddonInfo(addonName); if (savedAddon) { bool match = true; if (addon.CRC != savedAddon->CRC) match = false; if (!match) sLog->outInfo(LOG_FILTER_GENERAL, "ADDON: %s was known, but didn't match known CRC (0x%x)!", addon.Name.c_str(), savedAddon->CRC); else sLog->outInfo(LOG_FILTER_GENERAL, "ADDON: %s was known, CRC is correct (0x%x)", addon.Name.c_str(), savedAddon->CRC); } else { AddonMgr::SaveAddon(addon); sLog->outInfo(LOG_FILTER_GENERAL, "ADDON: %s (0x%x) was not known, saving...", addon.Name.c_str(), addon.CRC); } /// @todo Find out when to not use CRC/pubkey, and other possible states. m_addonsList.push_back(addon); } uint32 currentTime; addonInfo >> currentTime; sLog->outDebug(LOG_FILTER_NETWORKIO, "ADDON: CurrentTime: %u", currentTime); if (addonInfo.rpos() != addonInfo.size()) sLog->outDebug(LOG_FILTER_NETWORKIO, "packet under-read!"); }
void testBasicOperations(std::ostream& ofile) { ofile<<"Basic operation tests...\n"; ByteBuffer* buff = new ByteBuffer(32); assert(buff->getSize()==32); // assert(buff->getByteOrder()==EPICS_BYTE_ORDER); assert(buff->getPosition()==0); assert(buff->getLimit()==32); assert(buff->getRemaining()==32); buff->putBoolean(true); assert(buff->getPosition()==1); assert(buff->getRemaining()==31); buff->putByte(-12); assert(buff->getPosition()==2); assert(buff->getRemaining()==30); buff->putShort(10516); assert(buff->getPosition()==4); assert(buff->getRemaining()==28); buff->putInt(0x1937628B); assert(buff->getPosition()==8); assert(buff->getRemaining()==24); buff->putLong(2345678123LL); assert(buff->getPosition()==16); assert(buff->getRemaining()==16); float testFloat = 34.67; buff->putFloat(testFloat); assert(buff->getPosition()==20); assert(buff->getRemaining()==12); double testDouble = -512.23974; buff->putDouble(testDouble); assert(buff->getPosition()==28); assert(buff->getRemaining()==4); // testing direct reads assert(buff->getBoolean(0)==true); assert(buff->getByte(1)==-12); assert(buff->getShort(2)==10516); assert(buff->getInt(4)==0x1937628B); assert(buff->getLong(8)==2345678123LL); assert(buff->getFloat(16)==testFloat); assert(buff->getDouble(20)==testDouble); /* std::size_t sp = buff->getPosition(); buff->setPosition(0); assert(buff->getBoolean()==true); assert(buff->getByte()==-12); assert(buff->getShort()==10516); assert(buff->getInt()==0x1937628B); assert(buff->getLong()==2345678123LL); assert(buff->getFloat()==testFloat); assert(buff->getDouble()==testDouble); buff->setPosition(sp); */ buff->flip(); assert(buff->getLimit()==28); assert(buff->getPosition()==0); assert(buff->getRemaining()==28); assert(buff->getBoolean()==true); assert(buff->getPosition()==1); assert(buff->getByte()==-12); assert(buff->getPosition()==2); assert(buff->getShort()==10516); assert(buff->getPosition()==4); assert(buff->getInt()==0x1937628B); assert(buff->getPosition()==8); assert(buff->getLong()==2345678123LL); assert(buff->getPosition()==16); assert(buff->getFloat()==testFloat); assert(buff->getPosition()==20); assert(buff->getDouble()==testDouble); assert(buff->getPosition()==28); buff->clear(); assert(buff->getPosition()==0); assert(buff->getLimit()==32); assert(buff->getRemaining()==32); buff->setPosition(4); assert(buff->getPosition()==4); assert(buff->getLimit()==32); assert(buff->getRemaining()==(32-4)); buff->setPosition(13); assert(buff->getPosition()==13); assert(buff->getLimit()==32); assert(buff->getRemaining()==(32-13)); // testing absolute puts buff->clear(); buff->setPosition(28); buff->putBoolean(0, true); buff->putByte(1, -12); buff->putShort(2, 10516); buff->putInt(4, 0x1937628B); buff->putLong(8, 2345678123LL); buff->putFloat(16, testFloat); buff->putDouble(20, testDouble); /* buff->clear(); buff->setPosition(28); sp = buff->getPosition(); buff->putBoolean(true); buff->putByte(-12); buff->putShort(10516); buff->putInt(0x1937628B); buff->putLong(2345678123LL); buff->putFloat(testFloat); buff->putDouble(testDouble); buff->setPosition(sp); */ buff->flip(); assert(buff->getLimit()==28); assert(buff->getPosition()==0); assert(buff->getRemaining()==28); assert(buff->getBoolean()==true); assert(buff->getPosition()==1); assert(buff->getByte()==-12); assert(buff->getPosition()==2); assert(buff->getShort()==10516); assert(buff->getPosition()==4); assert(buff->getInt()==0x1937628B); assert(buff->getPosition()==8); assert(buff->getLong()==2345678123LL); assert(buff->getPosition()==16); assert(buff->getFloat()==testFloat); assert(buff->getPosition()==20); assert(buff->getDouble()==testDouble); assert(buff->getPosition()==28); buff->clear(); assert(buff->getPosition()==0); assert(buff->getLimit()==32); assert(buff->getRemaining()==32); char src[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm' }; char dst[] = { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }; buff->put(src, 2, 6); assert(buff->getPosition()==6); assert(strncmp(buff->getArray(),&src[2],6)==0); buff->flip(); assert(buff->getLimit()==6); assert(buff->getPosition()==0); assert(buff->getRemaining()==6); buff->get(dst, 2, 6); assert(buff->getLimit()==6); assert(buff->getPosition()==6); assert(strncmp(&src[2],&dst[2],6)==0); ofile<<" First 10 characters of destination: >>"<<String(dst, 10)<<"<<\n"; delete buff; ofile<<"!!! PASSED\n"; }
void FastGUIDPack(ByteBuffer & buf, const uint64 & oldguid) { if( &oldguid == NULL ) return; // hehe speed freaks uint8 guidmask = 0; uint8 guidfields[9] = {0,0,0,0,0,0,0,0}; int j = 1; uint8 * test = (uint8*)&oldguid; if (*test) //7*8 { guidfields[j] = *test; guidmask |= 1; j++; } if (*(test+1)) //6*8 { guidfields[j] = *(test+1); guidmask |= 2; j++; } if (*(test+2)) //5*8 { guidfields[j] = *(test+2); guidmask |= 4; j++; } if (*(test+3)) //4*8 { guidfields[j] = *(test+3); guidmask |= 8; j++; } if (*(test+4)) //3*8 { guidfields[j] = *(test+4); guidmask |= 16; j++; } if (*(test+5))//2*8 { guidfields[j] = *(test+5); guidmask |= 32; j++; } if (*(test+6))//1*8 { guidfields[j] = *(test+6); guidmask |= 64; j++; } if (*(test+7)) //0*8 { guidfields[j] = *(test+7); guidmask |= 128; j++; } guidfields[0] = guidmask; buf.append(guidfields,j); }
void WardenMac::HandleData(ByteBuffer &buff) { sLog.outDebug("Handle data"); m_WardenDataSent = false; m_WardenKickTimer = 0; /*uint16 Length; buff >> Length; uint32 Checksum; buff >> Checksum; if (!IsValidCheckSum(Checksum, buff.contents() + buff.rpos(), Length)) { buff.rpos(buff.wpos()); if (sWorld.getConfig(CONFIG_BOOL_WARDEN_KICK)) Client->KickPlayer(); return; }*/ bool found = false; std::string str = "Test string!"; Sha1Hash sha1; sha1.UpdateData(str); uint32 magic = 0xFEEDFACE; // unsure sha1.UpdateData((uint8*)&magic, 4); sha1.Finalize(); uint8 sha1Hash[20]; buff.read(sha1Hash, 20); if (memcmp(sha1Hash, sha1.GetDigest(), 20)) { sLog.outWarden("Handle data failed: SHA1 hash is wrong!"); found = true; } MD5_CTX ctx; MD5_Init(&ctx); MD5_Update(&ctx, str.c_str(), str.size()); uint8 ourMD5Hash[16]; MD5_Final(ourMD5Hash, &ctx); uint8 theirsMD5Hash[16]; buff.read(theirsMD5Hash, 16); if (memcmp(ourMD5Hash, theirsMD5Hash, 16)) { sLog.outWarden("Handle data failed: MD5 hash is wrong!"); found = true; } if (found) { sWorld.SendAntiCheatMessageToGMs(Client->GetPlayerName(), "A Warden check for MAC has failed! More info is available in the log."); if (sWorld.getConfig(CONFIG_FLOAT_WARDEN_KICK_BAN) == 1) { Client->KickPlayer(); } if (sWorld.getConfig(CONFIG_FLOAT_WARDEN_KICK_BAN) == 2) { sWorld.BanAccount(BAN_CHARACTER, Client->GetPlayerName(), sWorld.getConfig(CONFIG_UINT32_WARDEN_BAN_TIME) * 900000 * IN_MILLISECONDS, "Cheating software usage", "Warden System"); } } }
void WardenWin::HandleData(ByteBuffer &buff) { sLog->outDebug(LOG_FILTER_WARDEN, "Handle data"); _dataSent = false; _clientResponseTimer = 0; uint16 Length; buff >> Length; uint32 Checksum; buff >> Checksum; if (!IsValidCheckSum(Checksum, buff.contents() + buff.rpos(), Length)) { buff.rpos(buff.wpos()); sLog->outWarn(LOG_FILTER_WARDEN, "%s failed checksum. Action: %s", _session->GetPlayerInfo().c_str(), Penalty().c_str()); return; } // TIMING_CHECK { uint8 result; buff >> result; // TODO: test it. if (result == 0x00) { sLog->outWarn(LOG_FILTER_WARDEN, "%s failed timing check. Action: %s", _session->GetPlayerInfo().c_str(), Penalty().c_str()); return; } uint32 newClientTicks; buff >> newClientTicks; uint32 ticksNow = getMSTime(); uint32 ourTicks = newClientTicks + (ticksNow - _serverTicks); sLog->outDebug(LOG_FILTER_WARDEN, "ServerTicks %u", ticksNow); // Now sLog->outDebug(LOG_FILTER_WARDEN, "RequestTicks %u", _serverTicks); // At request sLog->outDebug(LOG_FILTER_WARDEN, "Ticks %u", newClientTicks); // At response sLog->outDebug(LOG_FILTER_WARDEN, "Ticks diff %u", ourTicks - newClientTicks); } WardenCheckResult *rs; WardenCheck *rd; uint8 type; uint16 checkFailed = 0; ACE_READ_GUARD(ACE_RW_Mutex, g, sWardenCheckMgr->_checkStoreLock); for (std::list<uint16>::iterator itr = _currentChecks.begin(); itr != _currentChecks.end(); ++itr) { rd = sWardenCheckMgr->GetWardenDataById(*itr); rs = sWardenCheckMgr->GetWardenResultById(*itr); type = rd->Type; switch (type) { case MEM_CHECK: { uint8 Mem_Result; buff >> Mem_Result; if (Mem_Result != 0) { sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MEM_CHECK not 0x00, CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; continue; } if (memcmp(buff.contents() + buff.rpos(), rs->Result.AsByteArray(0, false), rd->Length) != 0) { sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MEM_CHECK fail CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; buff.rpos(buff.rpos() + rd->Length); continue; } buff.rpos(buff.rpos() + rd->Length); sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MEM_CHECK passed CheckId %u account Id %u", *itr, _session->GetAccountId()); break; } case PAGE_CHECK_A: case PAGE_CHECK_B: case DRIVER_CHECK: case MODULE_CHECK: { const uint8 byte = 0xE9; if (memcmp(buff.contents() + buff.rpos(), &byte, sizeof(uint8)) != 0) { if (type == PAGE_CHECK_A || type == PAGE_CHECK_B) sLog->outDebug(LOG_FILTER_WARDEN, "RESULT PAGE_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId()); if (type == MODULE_CHECK) sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MODULE_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId()); if (type == DRIVER_CHECK) sLog->outDebug(LOG_FILTER_WARDEN, "RESULT DRIVER_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; buff.rpos(buff.rpos() + 1); continue; } buff.rpos(buff.rpos() + 1); if (type == PAGE_CHECK_A || type == PAGE_CHECK_B) sLog->outDebug(LOG_FILTER_WARDEN, "RESULT PAGE_CHECK passed CheckId %u account Id %u", *itr, _session->GetAccountId()); else if (type == MODULE_CHECK) sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MODULE_CHECK passed CheckId %u account Id %u", *itr, _session->GetAccountId()); else if (type == DRIVER_CHECK) sLog->outDebug(LOG_FILTER_WARDEN, "RESULT DRIVER_CHECK passed CheckId %u account Id %u", *itr, _session->GetAccountId()); break; } case LUA_STR_CHECK: { uint8 Lua_Result; buff >> Lua_Result; if (Lua_Result != 0) { sLog->outDebug(LOG_FILTER_WARDEN, "RESULT LUA_STR_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; continue; } uint8 luaStrLen; buff >> luaStrLen; if (luaStrLen != 0) { char *str = new char[luaStrLen + 1]; memcpy(str, buff.contents() + buff.rpos(), luaStrLen); str[luaStrLen] = '\0'; // null terminator sLog->outDebug(LOG_FILTER_WARDEN, "Lua string: %s", str); delete[] str; } buff.rpos(buff.rpos() + luaStrLen); // Skip string sLog->outDebug(LOG_FILTER_WARDEN, "RESULT LUA_STR_CHECK passed, CheckId %u account Id %u", *itr, _session->GetAccountId()); break; } case MPQ_CHECK: { uint8 Mpq_Result; buff >> Mpq_Result; if (Mpq_Result != 0) { sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MPQ_CHECK not 0x00 account id %u", _session->GetAccountId()); checkFailed = *itr; continue; } if (memcmp(buff.contents() + buff.rpos(), rs->Result.AsByteArray(0, false), 20) != 0) // SHA1 { sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MPQ_CHECK fail, CheckId %u account Id %u", *itr, _session->GetAccountId()); checkFailed = *itr; buff.rpos(buff.rpos() + 20); // 20 bytes SHA1 continue; } buff.rpos(buff.rpos() + 20); // 20 bytes SHA1 sLog->outDebug(LOG_FILTER_WARDEN, "RESULT MPQ_CHECK passed, CheckId %u account Id %u", *itr, _session->GetAccountId()); break; } default: // Should never happen break; } } if (checkFailed > 0) { WardenCheck* check = sWardenCheckMgr->GetWardenDataById(checkFailed); sLog->outWarn(LOG_FILTER_WARDEN, "%s failed Warden check %u. Action: %s", _session->GetPlayerInfo().c_str(), checkFailed, Penalty(check).c_str()); } // Set hold off timer, minimum timer should at least be 1 second uint32 holdOff = sWorld->getIntConfig(CONFIG_WARDEN_CLIENT_CHECK_HOLDOFF); _checkTimer = (holdOff < 1 ? 1 : holdOff) * IN_MILLISECONDS; }