LocaleConstant GetLocaleByName(const std::string& name) { for (uint32 i = 0; i < TOTAL_LOCALES; ++i) if (name == localeNames[i]) return LocaleConstant(i); return LOCALE_enUS; // including enGB case }
void CreatureTextMgr::LoadCreatureTextLocales() { uint32 oldMSTime = getMSTime(); mLocaleTextMap.clear(); // for reload case QueryResult result = WorldDatabase.Query("SELECT entry, textGroup, id, text_loc1, text_loc2, text_loc3, text_loc4, text_loc5, text_loc6, text_loc7, text_loc8 FROM locales_creature_text"); if (!result) return; uint32 textCount = 0; do { Field* fields = result->Fetch(); CreatureTextLocale& loc = mLocaleTextMap[CreatureTextId(fields[0].GetUInt32(), uint32(fields[1].GetUInt8()), fields[2].GetUInt32())]; for (uint8 i = 1; i < TOTAL_LOCALES; ++i) { LocaleConstant locale = LocaleConstant(i); ObjectMgr::AddLocaleString(fields[3 + i - 1].GetString(), locale, loc.Text); } ++textCount; } while (result->NextRow()); sLog->outString(">> Loaded %u creature localized texts in %u ms", textCount, GetMSTimeDiffToNow(oldMSTime)); sLog->outString(); }
void LoadDB2Stores(const std::string& dataPath) { std::string db2Path = dataPath + "dbc/"; LocaleNameStr const* defaultLocaleNameStr = NULL; StoreProblemList1 bad_db2_files; LocalDB2Data availableDb2Locales(LocaleConstant(0));//defaultLocaleNameStr->locale)); LoadDB2(availableDb2Locales,bad_db2_files,sItemStore, db2Path,"Item.db2"); LoadDB2(availableDb2Locales,bad_db2_files,sItemCurrencyCostStore, db2Path,"ItemCurrencyCost.db2"); LoadDB2(availableDb2Locales,bad_db2_files,sItemExtendedCostStore, db2Path,"ItemExtendedCost.db2"); LoadDB2(availableDb2Locales,bad_db2_files,sSpellReagentsStore, db2Path,"SpellReagents.db2"); LoadDB2(availableDb2Locales,bad_db2_files,sSceneScriptStore, db2Path, "SceneScript.db2"); // error checks if (bad_db2_files.size() >= DB2FileCount) { sLog.outError("Incorrect DataDir value in worldserver.conf or ALL required *.db2 files (%d) not found by path: %sdb2", DB2FileCount, dataPath.c_str()); exit(1); } else if (!bad_db2_files.empty()) { std::string str; for (StoreProblemList1::iterator i = bad_db2_files.begin(); i != bad_db2_files.end(); ++i) str += *i + "\n"; sLog.outError("Some required *.db2 files (%u from %d) not found or not compatible:\n%s",(uint32)bad_db2_files.size(), DB2FileCount, str.c_str()); exit(1); } // Check loaded DB2 files proper version if (!sItemStore.LookupEntry(112353) || // last item added in 5.4.8 (18414) !sItemExtendedCostStore.LookupEntry(5280) || // last item extended cost added in 5.4.8 (18414) !sSceneScriptStore.LookupEntry(11156) ) // last scene script added in 5.4.8 (18414) { sLog.outString(""); sLog.outError("Please extract correct db2 files from build %s", AcceptableClientBuildsListStr().c_str()); exit(1); } sLog.outString(); sLog.outString( ">> Initialized %d db2 stores", DB2FileCount ); }
void PlayerBot::InitializeSession(uint32 accountId) { QueryResult* result = LoginDatabase.PQuery("SELECT " "gmlevel, " //1 "expansion, " //7 "mutetime, " //8 "locale " //9 "FROM account " "WHERE id = '%u'", accountId); // Stop if the account is not found if (!result) { return; } Field* fields = result->Fetch(); uint32 security = fields[0].GetUInt16(); uint8 expansion = fields[1].GetUInt8(); time_t mutetime = time_t(fields[2].GetUInt64()); LocaleConstant locale = LocaleConstant(fields[3].GetUInt8()); WorldSocket* sock = nullptr; WorldSession* session = new WorldSession(accountId, sock, AccountTypes(security), expansion, mutetime, locale); if (!session) { return; } session->SetPlayerBot(true); session->SetPlayerBotActive(true); sWorld.AddSession(session); m_session = session; }
bool WorldSocket::HandleAuthSession(WorldPacket &recvPacket) { // NOTE: ATM the socket is singlethread, have this in mind ... uint8 digest[20]; uint32 clientSeed, id, security; uint32 ClientBuild; LocaleConstant locale; std::string account; Sha1Hash sha1; BigNumber v, s, g, N, K; WorldPacket packet, SendAddonPacked; // Read the content of the packet recvPacket >> ClientBuild; recvPacket.read_skip<uint32>(); recvPacket >> account; recvPacket >> clientSeed; recvPacket.read(digest, 20); DEBUG_LOG("WorldSocket::HandleAuthSession: client build %u, account %s, clientseed %X", ClientBuild, account.c_str(), clientSeed); // Check the version of client trying to connect if (!IsAcceptableClientBuild(ClientBuild)) { packet.Initialize(SMSG_AUTH_RESPONSE, 1); packet << uint8(AUTH_VERSION_MISMATCH); SendPacket(packet); sLog.outError("WorldSocket::HandleAuthSession: Sent Auth Response (version mismatch)."); return false; } // Get the account information from the realmd database std::string safe_account = account; // Duplicate, else will screw the SHA hash verification below LoginDatabase.escape_string(safe_account); // No SQL injection, username escaped. QueryResult* result = LoginDatabase.PQuery("SELECT " "id, " //0 "gmlevel, " //1 "sessionkey, " //2 "last_ip, " //3 "locked, " //4 "v, " //5 "s, " //6 "mutetime, " //7 "locale " //8 "FROM account " "WHERE username = '******'", safe_account.c_str()); // Stop if the account is not found if (!result) { packet.Initialize(SMSG_AUTH_RESPONSE, 1); packet << uint8(AUTH_UNKNOWN_ACCOUNT); SendPacket(packet); sLog.outError("WorldSocket::HandleAuthSession: Sent Auth Response (unknown account)."); return false; } Field* fields = result->Fetch(); N.SetHexStr("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7"); g.SetDword(7); v.SetHexStr(fields[5].GetString()); s.SetHexStr(fields[6].GetString()); m_s = s; const char* sStr = s.AsHexStr(); // Must be freed by OPENSSL_free() const char* vStr = v.AsHexStr(); // Must be freed by OPENSSL_free() DEBUG_LOG("WorldSocket::HandleAuthSession: (s,v) check s: %s v: %s", sStr, vStr); OPENSSL_free((void*) sStr); OPENSSL_free((void*) vStr); ///- Re-check ip locking (same check as in realmd). if (fields[4].GetUInt8() == 1) // if ip is locked { if (strcmp(fields[3].GetString(), GetRemoteAddress().c_str())) { packet.Initialize(SMSG_AUTH_RESPONSE, 1); packet << uint8(AUTH_FAILED); SendPacket(packet); delete result; BASIC_LOG("WorldSocket::HandleAuthSession: Sent Auth Response (Account IP differs)."); return false; } } id = fields[0].GetUInt32(); security = fields[1].GetUInt16(); if (security > SEC_ADMINISTRATOR) // prevent invalid security settings in DB security = SEC_ADMINISTRATOR; K.SetHexStr(fields[2].GetString()); time_t mutetime = time_t (fields[7].GetUInt64()); uint8 tempLoc = LocaleConstant(fields[8].GetUInt8()); if (tempLoc >= static_cast<uint8>(MAX_LOCALE)) locale = LOCALE_enUS; else locale = LocaleConstant(tempLoc); delete result; // Re-check account ban (same check as in realmd) QueryResult* banresult = LoginDatabase.PQuery("SELECT 1 FROM account_banned WHERE id = %u AND active = 1 AND (unbandate > UNIX_TIMESTAMP() OR unbandate = bandate)" "UNION " "SELECT 1 FROM ip_banned WHERE (unbandate = bandate OR unbandate > UNIX_TIMESTAMP()) AND ip = '%s'", id, GetRemoteAddress().c_str()); if (banresult) // if account banned { packet.Initialize(SMSG_AUTH_RESPONSE, 1); packet << uint8(AUTH_BANNED); SendPacket(packet); delete banresult; sLog.outError("WorldSocket::HandleAuthSession: Sent Auth Response (Account banned)."); return false; } // Check locked state for server AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit(); if (allowedAccountType > SEC_PLAYER && AccountTypes(security) < allowedAccountType) { WorldPacket Packet(SMSG_AUTH_RESPONSE, 1); Packet << uint8(AUTH_UNAVAILABLE); SendPacket(packet); BASIC_LOG("WorldSocket::HandleAuthSession: User tries to login but his security level is not enough"); return false; } // Check that Key and account name are the same on client and server Sha1Hash sha; uint32 t = 0; uint32 seed = m_seed; sha.UpdateData(account); sha.UpdateData((uint8*) & t, 4); sha.UpdateData((uint8*) & clientSeed, 4); sha.UpdateData((uint8*) & seed, 4); sha.UpdateBigNumbers(&K, nullptr); sha.Finalize(); if (memcmp(sha.GetDigest(), digest, 20)) { packet.Initialize(SMSG_AUTH_RESPONSE, 1); packet << uint8(AUTH_FAILED); SendPacket(packet); sLog.outError("WorldSocket::HandleAuthSession: Sent Auth Response (authentification failed)."); return false; } const std::string &address = GetRemoteAddress(); DEBUG_LOG("WorldSocket::HandleAuthSession: Client '%s' authenticated successfully from %s.", account.c_str(), address.c_str()); // Update the last_ip in the database // No SQL injection, username escaped. static SqlStatementID updAccount; SqlStatement stmt = LoginDatabase.CreateStatement(updAccount, "UPDATE account SET last_ip = ? WHERE username = ?"); stmt.PExecute(address.c_str(), account.c_str()); if (!(m_session = new WorldSession(id, this, AccountTypes(security), mutetime, locale))) return false; m_crypt.Init(&K); m_session->LoadTutorialsData(); sWorld.AddSession(m_session); // Create and send the Addon packet if (sAddOnHandler.BuildAddonPacket(recvPacket, SendAddonPacked)) SendPacket(SendAddonPacked); return true; }
void AchievementGlobalMgr::LoadRewardLocales() { m_achievementRewardLocales.clear(); // need for reload case QueryResult *result = WorldDatabase.Query("SELECT entry,subject_loc1,text_loc1,subject_loc2,text_loc2,subject_loc3,text_loc3,subject_loc4,text_loc4,subject_loc5,text_loc5,subject_loc6,text_loc6,subject_loc7,text_loc7,subject_loc8,text_loc8 FROM locales_achievement_reward"); if(!result) { barGoLink bar(1); bar.step(); sLog.outString(""); sLog.outString(">> Loaded 0 achievement reward locale strings. DB table `locales_achievement_reward` is empty."); return; } barGoLink bar(result->GetRowCount()); do { Field *fields = result->Fetch(); bar.step(); uint32 entry = fields[0].GetUInt32(); if(m_achievementRewards.find(entry)==m_achievementRewards.end()) { sLog.outErrorDb( "Table `locales_achievement_reward` (Entry: %u) has locale strings for not existed achievement reward .", entry); continue; } AchievementRewardLocale& data = m_achievementRewardLocales[entry]; for(int i = 1; i < MAX_LOCALE; ++i) { std::string str = fields[1+2*(i-1)].GetCppString(); if(!str.empty()) { int idx = objmgr.GetOrNewIndexForLocale(LocaleConstant(i)); if(idx >= 0) { if(data.subject.size() <= idx) data.subject.resize(idx+1); data.subject[idx] = str; } } str = fields[1+2*(i-1)+1].GetCppString(); if(!str.empty()) { int idx = objmgr.GetOrNewIndexForLocale(LocaleConstant(i)); if(idx >= 0) { if(data.text.size() <= idx) data.text.resize(idx+1); data.text[idx] = str; } } } } while (result->NextRow()); delete result; sLog.outString(); sLog.outString( ">> Loaded %u achievement reward locale strings", m_achievementRewardLocales.size() ); }
int WorldSocket::HandleAuthSession (WorldPacket& recvPacket) { // NOTE: ATM the socket is singlethread, have this in mind ... uint8 digest[20]; uint32 clientSeed; uint32 unk2; uint32 BuiltNumberClient; uint32 id, security; //uint8 expansion = 0; LocaleConstant locale; std::string account; Sha1Hash sha1; BigNumber v, s, g, N; WorldPacket packet, SendAddonPacked; BigNumber K; // Read the content of the packet recvPacket >> BuiltNumberClient; recvPacket >> unk2; recvPacket >> account; recvPacket >> clientSeed; recvPacket.read (digest, 20); DEBUG_LOG ("WorldSocket::HandleAuthSession: client %u, unk2 %u, account %s, clientseed %u", BuiltNumberClient, unk2, account.c_str (), clientSeed); // Check the version of client trying to connect if (!IsAcceptableClientBuild(BuiltNumberClient)) { packet.Initialize (SMSG_AUTH_RESPONSE, 1); packet << uint8 (AUTH_VERSION_MISMATCH); SendPacket (packet); sLog.outError ("WorldSocket::HandleAuthSession: Sent Auth Response (version mismatch)."); return -1; } // Get the account information from the realmd database std::string safe_account = account; // Duplicate, else will screw the SHA hash verification below LoginDatabase.escape_string (safe_account); // No SQL injection, username escaped. QueryResult_AutoPtr result = LoginDatabase.PQuery ("SELECT " "id, " //0 "gmlevel, " //1 "sessionkey, " //2 "last_ip, " //3 "locked, " //4 "v, " //5 "s, " //6 "expansion, " //7 "mutetime, " //8 "locale " //9 "FROM account " "WHERE username = '******'", safe_account.c_str ()); // Stop if the account is not found if (!result) { packet.Initialize (SMSG_AUTH_RESPONSE, 1); packet << uint8 (AUTH_UNKNOWN_ACCOUNT); SendPacket (packet); sLog.outError ("WorldSocket::HandleAuthSession: Sent Auth Response (unknown account)."); return -1; } Field* fields = result->Fetch (); uint8 expansion = fields[7].GetUInt8(); uint32 world_expansion = sWorld.getConfig(CONFIG_EXPANSION); if (expansion > world_expansion) expansion = world_expansion; //expansion = ((sWorld.getConfig(CONFIG_EXPANSION) > fields[7].GetUInt8()) ? fields[7].GetUInt8() : sWorld.getConfig(CONFIG_EXPANSION)); N.SetHexStr ("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7"); g.SetDword (7); v.SetHexStr(fields[5].GetString()); s.SetHexStr (fields[6].GetString ()); const char* sStr = s.AsHexStr (); //Must be freed by OPENSSL_free() const char* vStr = v.AsHexStr (); //Must be freed by OPENSSL_free() DEBUG_LOG ("WorldSocket::HandleAuthSession: (s,v) check s: %s v: %s", sStr, vStr); OPENSSL_free ((void*) sStr); OPENSSL_free ((void*) vStr); // Re-check ip locking (same check as in realmd). if (fields[4].GetUInt8 () == 1) // if ip is locked { if (strcmp (fields[3].GetString (), GetRemoteAddress ().c_str ())) { packet.Initialize (SMSG_AUTH_RESPONSE, 1); packet << uint8 (AUTH_FAILED); SendPacket (packet); sLog.outBasic ("WorldSocket::HandleAuthSession: Sent Auth Response (Account IP differs)."); return -1; } } id = fields[0].GetUInt32 (); security = fields[1].GetUInt16 (); K.SetHexStr (fields[2].GetString ()); time_t mutetime = time_t (fields[8].GetUInt64 ()); locale = LocaleConstant (fields[9].GetUInt8 ()); if (locale >= MAX_LOCALE) locale = LOCALE_enUS; // Re-check account ban (same check as in realmd) QueryResult_AutoPtr banresult = LoginDatabase.PQuery ("SELECT " "bandate, " "unbandate " "FROM account_banned " "WHERE id = '%u' " "AND active = 1", id); if (banresult) // if account banned { packet.Initialize (SMSG_AUTH_RESPONSE, 1); packet << uint8 (AUTH_BANNED); SendPacket (packet); sLog.outError ("WorldSocket::HandleAuthSession: Sent Auth Response (Account banned)."); return -1; } // Check locked state for server sWorld.UpdateAllowedSecurity(); AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit (); sLog.outDebug("Allowed Level: %u Player Level %u", allowedAccountType, AccountTypes(security)); if (allowedAccountType > SEC_PLAYER && security < allowedAccountType) { WorldPacket Packet (SMSG_AUTH_RESPONSE, 1); Packet << uint8 (AUTH_UNAVAILABLE); SendPacket (packet); sLog.outDetail ("WorldSocket::HandleAuthSession: User tries to login but his security level is not enough"); return -1; } // Check that Key and account name are the same on client and server Sha1Hash sha; uint32 t = 0; uint32 seed = m_Seed; sha.UpdateData (account); sha.UpdateData ((uint8 *) & t, 4); sha.UpdateData ((uint8 *) & clientSeed, 4); sha.UpdateData ((uint8 *) & seed, 4); sha.UpdateBigNumbers (&K, NULL); sha.Finalize (); if (memcmp (sha.GetDigest (), digest, 20)) { packet.Initialize (SMSG_AUTH_RESPONSE, 1); packet << uint8 (AUTH_FAILED); SendPacket (packet); sLog.outError ("WorldSocket::HandleAuthSession: Sent Auth Response (authentification failed)."); return -1; } std::string address = GetRemoteAddress(); DEBUG_LOG ("WorldSocket::HandleAuthSession: Client '%s' authenticated successfully from %s.", account.c_str(), address.c_str()); // Update the last_ip in the database // No SQL injection, username escaped. LoginDatabase.escape_string (address); LoginDatabase.PExecute ("UPDATE account " "SET last_ip = '%s' " "WHERE username = '******'", address.c_str(), safe_account.c_str()); // NOTE ATM the socket is single-threaded, have this in mind ... ACE_NEW_RETURN (m_Session, WorldSession (id, this, security, expansion, mutetime, locale), -1); m_Crypt.SetKey(&K); m_Crypt.Init(); // Sleep this Network thread for uint32 sleepTime = sWorld.getConfig(CONFIG_SESSION_ADD_DELAY); ACE_OS::sleep(ACE_Time_Value (0, sleepTime)); sWorld.AddSession (m_Session); // Create and send the Addon packet if (sAddOnHandler.BuildAddonPacket (&recvPacket, &SendAddonPacked)) SendPacket(SendAddonPacked); return 0; }
int WorldSocket::HandleAuthSession (WorldPacket& recvPacket) { // NOTE: ATM the socket is singlethread, have this in mind ... uint8 digest[20]; uint32 clientSeed; uint32 unk2; uint32 BuiltNumberClient; uint32 id, security; uint8 expansion = 0; LocaleConstant locale; std::string account; Sha1Hash sha1; BigNumber v, s, g, N, x, I; WorldPacket packet, SendAddonPacked; BigNumber K; if (recvPacket.size () < (4 + 4 + 1 + 4 + 20)) { sLog.outError ("WorldSocket::HandleAuthSession: wrong packet size"); return -1; } // Read the content of the packet recvPacket >> BuiltNumberClient; // for now no use recvPacket >> unk2; recvPacket >> account; if (recvPacket.size () < (4 + 4 + (account.size () + 1) + 4 + 20)) { sLog.outError ("WorldSocket::HandleAuthSession: wrong packet size second check"); return -1; } recvPacket >> clientSeed; recvPacket.read (digest, 20); DEBUG_LOG ("WorldSocket::HandleAuthSession: client %u, unk2 %u, account %s, clientseed %u", BuiltNumberClient, unk2, account.c_str (), clientSeed); // Get the account information from the realmd database std::string safe_account = account; // Duplicate, else will screw the SHA hash verification below loginDatabase.escape_string (safe_account); // No SQL injection, username escaped. QueryResult *result = loginDatabase.PQuery ("SELECT " "id, " //0 "gmlevel, " //1 "sessionkey, " //2 "last_ip, " //3 "locked, " //4 "sha_pass_hash, " //5 "v, " //6 "s, " //7 "expansion, " //8 "mutetime, " //9 "locale " //10 "FROM account " "WHERE username = '******'", safe_account.c_str ()); // Stop if the account is not found if (!result) { packet.Initialize (SMSG_AUTH_RESPONSE, 1); packet << uint8 (AUTH_UNKNOWN_ACCOUNT); SendPacket (packet); sLog.outError ("WorldSocket::HandleAuthSession: Sent Auth Response (unknown account)."); return -1; } Field* fields = result->Fetch (); expansion = fields[8].GetUInt8 () && sWorld.getConfig (CONFIG_EXPANSION) > 0; N.SetHexStr ("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7"); g.SetDword (7); I.SetHexStr (fields[5].GetString ()); //In case of leading zeros in the I hash, restore them uint8 mDigest[SHA_DIGEST_LENGTH]; memset (mDigest, 0, SHA_DIGEST_LENGTH); if (I.GetNumBytes () <= SHA_DIGEST_LENGTH) memcpy (mDigest, I.AsByteArray (), I.GetNumBytes ()); std::reverse (mDigest, mDigest + SHA_DIGEST_LENGTH); s.SetHexStr (fields[7].GetString ()); sha1.UpdateData (s.AsByteArray (), s.GetNumBytes ()); sha1.UpdateData (mDigest, SHA_DIGEST_LENGTH); sha1.Finalize (); x.SetBinary (sha1.GetDigest (), sha1.GetLength ()); v = g.ModExp (x, N); const char* sStr = s.AsHexStr (); //Must be freed by OPENSSL_free() const char* vStr = v.AsHexStr (); //Must be freed by OPENSSL_free() const char* vold = fields[6].GetString (); DEBUG_LOG ("WorldSocket::HandleAuthSession: (s,v) check s: %s v_old: %s v_new: %s", sStr, vold, vStr); loginDatabase.PExecute ("UPDATE account " "SET " "v = '0', " "s = '0' " "WHERE username = '******'", safe_account.c_str ()); if (!vold || strcmp (vStr, vold)) { packet.Initialize (SMSG_AUTH_RESPONSE, 1); packet << uint8 (AUTH_UNKNOWN_ACCOUNT); SendPacket (packet); delete result; OPENSSL_free ((void*) sStr); OPENSSL_free ((void*) vStr); sLog.outBasic ("WorldSocket::HandleAuthSession: User not logged."); return -1; } OPENSSL_free ((void*) sStr); OPENSSL_free ((void*) vStr); ///- Re-check ip locking (same check as in realmd). if (fields[4].GetUInt8 () == 1) // if ip is locked { if (strcmp (fields[3].GetString (), GetRemoteAddress ().c_str ())) { packet.Initialize (SMSG_AUTH_RESPONSE, 1); packet << uint8 (AUTH_FAILED); SendPacket (packet); delete result; sLog.outBasic ("WorldSocket::HandleAuthSession: Sent Auth Response (Account IP differs)."); return -1; } } id = fields[0].GetUInt32 (); security = fields[1].GetUInt16 (); K.SetHexStr (fields[2].GetString ()); time_t mutetime = time_t (fields[9].GetUInt64 ()); locale = LocaleConstant (fields[10].GetUInt8 ()); if (locale >= MAX_LOCALE) locale = LOCALE_enUS; delete result; // Re-check account ban (same check as in realmd) QueryResult *banresult = loginDatabase.PQuery ("SELECT " "bandate, " "unbandate " "FROM account_banned " "WHERE id = '%u' " "AND active = 1", id); if (banresult) // if account banned { packet.Initialize (SMSG_AUTH_RESPONSE, 1); packet << uint8 (AUTH_BANNED); SendPacket (packet); delete banresult; sLog.outError ("WorldSocket::HandleAuthSession: Sent Auth Response (Account banned)."); return -1; } // Check locked state for server AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit (); if (allowedAccountType > SEC_PLAYER && security < allowedAccountType) { WorldPacket Packet (SMSG_AUTH_RESPONSE, 1); Packet << uint8 (AUTH_UNAVAILABLE); SendPacket (packet); sLog.outBasic ("WorldSocket::HandleAuthSession: User tryes to login but his security level is not enough"); return -1; } // Check that Key and account name are the same on client and server Sha1Hash sha; uint32 t = 0; uint32 seed = m_Seed; sha.UpdateData (account); sha.UpdateData ((uint8 *) & t, 4); sha.UpdateData ((uint8 *) & clientSeed, 4); sha.UpdateData ((uint8 *) & seed, 4); sha.UpdateBigNumbers (&K, NULL); sha.Finalize (); if (memcmp (sha.GetDigest (), digest, 20)) { packet.Initialize (SMSG_AUTH_RESPONSE, 1); packet << uint8 (AUTH_FAILED); SendPacket (packet); sLog.outError ("WorldSocket::HandleAuthSession: Sent Auth Response (authentification failed)."); return -1; } std::string address = GetRemoteAddress (); DEBUG_LOG ("WorldSocket::HandleAuthSession: Client '%s' authenticated successfully from %s.", account.c_str (), address.c_str ()); // Update the last_ip in the database // No SQL injection, username escaped. loginDatabase.escape_string (address); loginDatabase.PExecute ("UPDATE account " "SET last_ip = '%s' " "WHERE username = '******'", address.c_str (), safe_account.c_str ()); // NOTE ATM the socket is singlethreaded, have this in mind ... ACE_NEW_RETURN (m_Session, WorldSession (id, this, security, expansion, mutetime, locale), -1); m_Crypt.SetKey (&K); m_Crypt.Init (); // In case needed sometime the second arg is in microseconds 1 000 000 = 1 sec ACE_OS::sleep (ACE_Time_Value (0, 10000)); sWorld.AddSession (m_Session); // Create and send the Addon packet if (sAddOnHandler.BuildAddonPacket (&recvPacket, &SendAddonPacked)) SendPacket (SendAddonPacked); return 0; }
int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) { // NOTE: ATM the socket is singlethread, have this in mind ... uint8 digest[20]; uint32 clientSeed, id, security; uint32 unk2; uint32 BuiltNumberClient; uint8 expansion = 0; uint8 xp_rate = 0; LocaleConstant locale; std::string account; Sha1Hash sha1; BigNumber v, s, g, N, K; WorldPacket packet, SendAddonPacked; // Read the content of the packet recvPacket >> BuiltNumberClient; recvPacket >> unk2; recvPacket >> account; recvPacket >> clientSeed; recvPacket.read(digest, 20); DEBUG_LOG("WorldSocket::HandleAuthSession: client %u, unk2 %u, account %s, clientseed %u", BuiltNumberClient, unk2, account.c_str(), clientSeed); // Check the version of client trying to connect if (!IsAcceptableClientBuild(BuiltNumberClient)) { packet.Initialize(SMSG_AUTH_RESPONSE, 1); packet << uint8(AUTH_VERSION_MISMATCH); SendPacket(packet); sLog.outError("WorldSocket::HandleAuthSession: Sent Auth Response (version mismatch)."); return -1; } // Get the account information from the realmd database std::string safe_account = account; // Duplicate, else will screw the SHA hash verification below LoginDatabase.escape_string(safe_account); // No SQL injection, username escaped. QueryResult* result = LoginDatabase.PQuery("SELECT " "id, " //0 "gmlevel, " //1 "sessionkey, " //2 "last_ip, " //3 "locked, " //4 "v, " //5 "s, " //6 "expansion, " //7 "mutetime, " //8 "locale, " //9 "os " //10 "FROM account " "WHERE username = '******'", safe_account.c_str()); // Stop if the account is not found if (!result) { packet.Initialize(SMSG_AUTH_RESPONSE, 1); packet << uint8(AUTH_UNKNOWN_ACCOUNT); SendPacket(packet); sLog.outError("WorldSocket::HandleAuthSession: Sent Auth Response (unknown account)."); return -1; } Field* fields = result->Fetch(); expansion = ((sWorld.getConfig(CONFIG_UINT32_EXPANSION) > fields[7].GetUInt8()) ? fields[7].GetUInt8() : sWorld.getConfig(CONFIG_UINT32_EXPANSION)); N.SetHexStr("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7"); g.SetDword(7); v.SetHexStr(fields[5].GetString()); s.SetHexStr(fields[6].GetString()); const char* sStr = s.AsHexStr(); // Must be freed by OPENSSL_free() const char* vStr = v.AsHexStr(); // Must be freed by OPENSSL_free() DEBUG_LOG("WorldSocket::HandleAuthSession: (s,v) check s: %s v: %s", sStr, vStr); OPENSSL_free((void*) sStr); OPENSSL_free((void*) vStr); ///- Re-check ip locking (same check as in realmd). if (fields[4].GetUInt8() == 1) // if ip is locked { if (strcmp(fields[3].GetString(), GetRemoteAddress().c_str())) { packet.Initialize(SMSG_AUTH_RESPONSE, 1); packet << uint8(AUTH_FAILED); SendPacket(packet); delete result; BASIC_LOG("WorldSocket::HandleAuthSession: Sent Auth Response (Account IP differs)."); return -1; } } id = fields[0].GetUInt32(); security = fields[1].GetUInt16(); if (security > SEC_ADMINISTRATOR) // prevent invalid security settings in DB security = SEC_ADMINISTRATOR; K.SetHexStr(fields[2].GetString()); time_t mutetime = time_t (fields[8].GetUInt64()); locale = LocaleConstant(fields[9].GetUInt8()); if (locale >= MAX_LOCALE) locale = LOCALE_enUS; std::string os = fields[10].GetString(); delete result; // Re-check account ban (same check as in realmd) QueryResult* banresult = LoginDatabase.PQuery("SELECT 1 FROM account_banned WHERE id = %u AND active = 1 AND (unbandate > UNIX_TIMESTAMP() OR unbandate = bandate)" "UNION " "SELECT 1 FROM ip_banned WHERE (unbandate = bandate OR unbandate > UNIX_TIMESTAMP()) AND ip = '%s'", id, GetRemoteAddress().c_str()); if (banresult) // if account banned { packet.Initialize(SMSG_AUTH_RESPONSE, 1); packet << uint8(AUTH_BANNED); SendPacket(packet); delete banresult; sLog.outError("WorldSocket::HandleAuthSession: Sent Auth Response (Account banned)."); return -1; } // Check for custom xp rate QueryResult* customXpResult = CharacterDatabase.PQuery ("SELECT xp_rate FROM account_xp_rates WHERE id = '%u'", id); if (customXpResult) { Field* xpFields = customXpResult->Fetch(); xp_rate = xpFields[0].GetUInt8(); } // Check locked state for server AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit(); if (allowedAccountType > SEC_PLAYER && AccountTypes(security) < allowedAccountType) { WorldPacket Packet(SMSG_AUTH_RESPONSE, 1); Packet << uint8(AUTH_UNAVAILABLE); SendPacket(packet); BASIC_LOG("WorldSocket::HandleAuthSession: User tries to login but his security level is not enough"); return -1; } // Check that Key and account name are the same on client and server Sha1Hash sha; uint32 t = 0; uint32 seed = m_Seed; sha.UpdateData(account); sha.UpdateData((uint8*) & t, 4); sha.UpdateData((uint8*) & clientSeed, 4); sha.UpdateData((uint8*) & seed, 4); sha.UpdateBigNumbers(&K, NULL); sha.Finalize(); if (memcmp(sha.GetDigest(), digest, 20)) { packet.Initialize(SMSG_AUTH_RESPONSE, 1); packet << uint8(AUTH_FAILED); SendPacket(packet); sLog.outError("WorldSocket::HandleAuthSession: Sent Auth Response (authentification failed)."); return -1; } std::string address = GetRemoteAddress(); DEBUG_LOG("WorldSocket::HandleAuthSession: Client '%s' authenticated successfully from %s.", account.c_str(), address.c_str()); // Update the last_ip in the database // No SQL injection, username escaped. static SqlStatementID updAccount; SqlStatement stmt = LoginDatabase.CreateStatement(updAccount, "UPDATE account SET last_ip = ? WHERE username = ?"); stmt.PExecute(address.c_str(), account.c_str()); // NOTE ATM the socket is single-threaded, have this in mind ... ACE_NEW_RETURN(m_Session, WorldSession(id, this, AccountTypes(security), expansion, xp_rate, mutetime, locale), -1); m_Crypt.Init(&K); m_Session->LoadTutorialsData(); m_Session->InitWarden(&K, os); // In case needed sometime the second arg is in microseconds 1 000 000 = 1 sec ACE_OS::sleep(ACE_Time_Value(0, 10000)); sWorld.AddSession(m_Session); // Create and send the Addon packet if (sAddOnHandler.BuildAddonPacket(&recvPacket, &SendAddonPacked)) SendPacket(SendAddonPacked); return 0; }
int WorldSocket::HandleAuthSession (WorldPacket& recvPacket) { // NOTE: ATM the socket is singlethread, have this in mind ... std::string account; uint32 id, security; bool authed, forceTele; //uint8 expansion = 0; LocaleConstant locale; WorldPacket packet, SendAddonPacked; if (sWorld->IsClosed()) { packet.Initialize(SMSG_AUTH_RESPONSE, 1); packet << uint8(AUTH_REJECT); SendPacket (packet); sLog->outError ("WorldSocket::HandleAuthSession: World closed, denying client (%s).", GetRemoteAddress().c_str()); return -1; } // Read the content of the packet recvPacket >> account; // for now no use recvPacket >> id; recvPacket >> security; recvPacket >> authed; recvPacket >> forceTele; // Get the account information from the realmd database std::string safe_account = account; // Duplicate, else will screw the SHA hash verification below LoginDatabase.EscapeString (safe_account); // No SQL injection, username escaped. QueryResult result = LoginDatabase.PQuery ("SELECT " "id, " //0 "sessionkey, " //1 "last_ip, " //2 "locked, " //3 "v, " //4 "s, " //5 "expansion, " //6 "mutetime, " //7 "locale, " //8 "recruiter " //9 "FROM account " "WHERE username = '******'", safe_account.c_str()); // Stop if the account is not found if (!result) { packet.Initialize (SMSG_AUTH_RESPONSE, 1); packet << uint8 (AUTH_UNKNOWN_ACCOUNT); SendPacket (packet); sLog->outError ("WorldSocket::HandleAuthSession: Sent Auth Response (unknown account)."); return -1; } Field* fields = result->Fetch(); uint8 expansion = fields[6].GetUInt8(); uint32 world_expansion = sWorld->getIntConfig(CONFIG_EXPANSION); if (expansion > world_expansion) expansion = world_expansion; //expansion = ((sWorld->getIntConfig(CONFIG_EXPANSION) > fields[6].GetUInt8()) ? fields[6].GetUInt8() : sWorld->getIntConfig(CONFIG_EXPANSION)); m_Address = fields[2].GetCString(); id = fields[0].GetUInt32(); time_t mutetime = time_t (fields[7].GetUInt64()); locale = LocaleConstant (fields[8].GetUInt8()); if (locale >= TOTAL_LOCALES) locale = LOCALE_enUS; uint32 recruiter = fields[9].GetUInt32(); // Re-check account ban (same check as in realmd) QueryResult banresult = LoginDatabase.PQuery ("SELECT 1 FROM account_banned WHERE id = %u AND active = 1 " "UNION " "SELECT 1 FROM ip_banned WHERE ip = '%s'", id, GetRemoteAddress().c_str()); if (banresult) // if account banned { packet.Initialize (SMSG_AUTH_RESPONSE, 1); packet << uint8 (AUTH_BANNED); SendPacket (packet); sLog->outError ("WorldSocket::HandleAuthSession: Sent Auth Response (Account banned)."); return -1; } // Check locked state for server AccountTypes allowedAccountType = sWorld->GetPlayerSecurityLimit(); sLog->outDebug(LOG_FILTER_NETWORKIO, "Allowed Level: %u Player Level %u", allowedAccountType, AccountTypes(security)); if (allowedAccountType > SEC_PLAYER && AccountTypes(security) < allowedAccountType) { WorldPacket Packet (SMSG_AUTH_RESPONSE, 1); Packet << uint8 (AUTH_UNAVAILABLE); SendPacket (packet); sLog->outDetail ("WorldSocket::HandleAuthSession: User tries to login but his security level is not enough"); return -1; } /*if (memcmp (sha.GetDigest(), digest, 20)) { packet.Initialize (SMSG_AUTH_RESPONSE, 1); packet << uint8 (AUTH_FAILED); SendPacket (packet); sLog->outError ("WorldSocket::HandleAuthSession: Sent Auth Response (authentification failed)."); return -1; }*/ std::string address = GetRemoteAddress(); sLog->outDetail ("WorldSocket::HandleAuthSession: Client '%s' authenticated successfully from %s.", account.c_str(), address.c_str()); result = LoginDatabase.PQuery ("SELECT 1 FROM account WHERE recruiter = %u", id); bool isRecruiter = false; if (result) isRecruiter = true; // NOTE ATM the socket is single-threaded, have this in mind ... ACE_NEW_RETURN (m_Session, WorldSession (id, this, AccountTypes(security), expansion, mutetime, locale, recruiter, isRecruiter), -1); m_Session->LoadGlobalAccountData(); m_Session->LoadTutorialsData(); m_Session->SetAuthed(authed); m_Session->SetForceTele(forceTele); sWorld->AddSession (m_Session); return 0; }
int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) { // NOTE: ATM the socket is singlethread, have this in mind ... uint8 digest[20]; uint32 clientSeed; uint32 serverId; uint32 BuiltNumberClient; uint32 id, security; LocaleConstant locale; std::string account, os; BigNumber v, s, g, N, K; WorldPacket packet, SendAddonPacked; // Read the content of the packet recvPacket >> BuiltNumberClient; recvPacket >> serverId; recvPacket >> account; recvPacket >> clientSeed; recvPacket.read(digest, 20); DEBUG_LOG("WorldSocket::HandleAuthSession: client %u, serverId %u, account %s, clientseed %u", BuiltNumberClient, serverId, account.c_str(), clientSeed); // Check the version of client trying to connect if (!IsAcceptableClientBuild(BuiltNumberClient)) { packet.Initialize(SMSG_AUTH_RESPONSE, 1); packet << uint8(AUTH_VERSION_MISMATCH); SendPacket(packet); sLog.outError("WorldSocket::HandleAuthSession: Sent Auth Response (version mismatch)."); return -1; } // Get the account information from the realmd database std::string safe_account = account; // Duplicate, else will screw the SHA hash verification below LoginDatabase.escape_string(safe_account); // No SQL injection, username escaped. QueryResult *result = LoginDatabase.PQuery("SELECT a.id, aa.gmLevel, a.sessionkey, a.last_ip, a.locked, a.v, a.s, a.mutetime, a.locale, a.os, a.flags, " "ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate FROM account a LEFT JOIN account_access aa ON a.id = aa.id AND aa.RealmID IN (-1, %u) " "LEFT JOIN account_banned ab ON a.id = ab.id AND ab.active = 1 WHERE a.username = '******' ORDER BY aa.RealmID DESC LIMIT 1", realmID, safe_account.c_str()); // Stop if the account is not found if (!result) { packet.Initialize(SMSG_AUTH_RESPONSE, 1); packet << uint8(AUTH_UNKNOWN_ACCOUNT); SendPacket(packet); sLog.outError("WorldSocket::HandleAuthSession: Sent Auth Response (unknown account)."); return -1; } Field* fields = result->Fetch(); N.SetHexStr("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7"); g.SetDword(7); v.SetHexStr(fields[5].GetString()); s.SetHexStr(fields[6].GetString()); const char* sStr = s.AsHexStr(); //Must be freed by OPENSSL_free() const char* vStr = v.AsHexStr(); //Must be freed by OPENSSL_free() DEBUG_LOG("WorldSocket::HandleAuthSession: (s,v) check s: %s v: %s", sStr, vStr); OPENSSL_free((void*) sStr); OPENSSL_free((void*) vStr); ///- Re-check ip locking (same check as in realmd). if (fields[4].GetUInt8() == 1) // if ip is locked { if (strcmp(fields[3].GetString(), GetRemoteAddress().c_str())) { packet.Initialize(SMSG_AUTH_RESPONSE, 1); packet << uint8(AUTH_FAILED); SendPacket(packet); delete result; BASIC_LOG("WorldSocket::HandleAuthSession: Sent Auth Response (Account IP differs)."); return -1; } } id = fields[0].GetUInt32(); security = sAccountMgr.GetSecurity(id); //fields[1].GetUInt16 (); if (security > SEC_ADMINISTRATOR) // prevent invalid security settings in DB security = SEC_ADMINISTRATOR; K.SetHexStr(fields[2].GetString()); time_t mutetime = time_t (fields[7].GetUInt64()); locale = LocaleConstant(fields[8].GetUInt8()); if (locale >= MAX_LOCALE) locale = LOCALE_enUS; os = fields[9].GetString(); uint32 accFlags = fields[10].GetUInt32(); delete result; bool isBanned = fields[11].GetBool(); if (isBanned || sAccountMgr.IsIPBanned(GetRemoteAddress())) { packet.Initialize(SMSG_AUTH_RESPONSE, 1); packet << uint8(AUTH_BANNED); SendPacket(packet); sLog.outError("WorldSocket::HandleAuthSession: Sent Auth Response (Account banned)."); return -1; } // Check locked state for server AccountTypes allowedAccountType = sWorld.GetPlayerSecurityLimit(); if (allowedAccountType > SEC_PLAYER && AccountTypes(security) < allowedAccountType) { WorldPacket Packet(SMSG_AUTH_RESPONSE, 1); Packet << uint8(AUTH_UNAVAILABLE); SendPacket(packet); BASIC_LOG("WorldSocket::HandleAuthSession: User tries to login but his security level is not enough"); return -1; } // Check that Key and account name are the same on client and server Sha1Hash sha; uint32 t = 0; uint32 seed = m_Seed; sha.UpdateData(account); sha.UpdateData((uint8 *) & t, 4); sha.UpdateData((uint8 *) & clientSeed, 4); sha.UpdateData((uint8 *) & seed, 4); sha.UpdateBigNumbers(&K, NULL); sha.Finalize(); if (memcmp(sha.GetDigest(), digest, 20)) { packet.Initialize(SMSG_AUTH_RESPONSE, 1); packet << uint8(AUTH_FAILED); SendPacket(packet); sLog.outError("WorldSocket::HandleAuthSession: Sent Auth Response (authentification failed)."); return -1; } std::string address = GetRemoteAddress(); DEBUG_LOG("WorldSocket::HandleAuthSession: Client '%s' authenticated successfully from %s.", account.c_str(), address.c_str()); // Update the last_ip in the database // No SQL injection, username escaped. static SqlStatementID updAccount; SqlStatement stmt = LoginDatabase.CreateStatement(updAccount, "UPDATE account SET last_ip = ? WHERE username = ?"); stmt.PExecute(address.c_str(), account.c_str()); // NOTE ATM the socket is single-threaded, have this in mind ... ACE_NEW_RETURN(m_Session, WorldSession(id, this, AccountTypes(security), mutetime, locale), -1); m_Crypt.SetKey(K.AsByteArray()); m_Crypt.Init(); m_Session->SetUsername(account); m_Session->SetGameBuild(BuiltNumberClient); m_Session->SetAccountFlags(accFlags); ClientOSType clientOs; if (os == "niW") clientOs = CLIENT_OS_WIN; else if (os == "XSO") clientOs = CLIENT_OS_MAC; else { sLog.outError("WorldSocket::HandleAuthSession: Unrecognized OS '%s' for account '%s' from %s", os.c_str(), account.c_str(), address.c_str()); return -1; } m_Session->SetOS(clientOs); m_Session->LoadTutorialsData(); m_Session->InitWarden(&K); // In case needed sometime the second arg is in microseconds 1 000 000 = 1 sec ACE_OS::sleep(ACE_Time_Value(0, 10000)); sWorld.AddSession(m_Session); // Create and send the Addon packet if (sAddOnHandler.BuildAddonPacket(&recvPacket, &SendAddonPacked)) SendPacket(SendAddonPacked); return 0; }