public uint GetMinorMajorBugfixVersionForBuild(uint build) { RealmBuildInfo buildInfo = ClientBuilds.FirstOrDefault(p => { return(p.Build < build); }); return(buildInfo != null ? (buildInfo.MajorVersion * 10000 + buildInfo.MinorVersion * 100 + buildInfo.BugfixVersion) : 0); }
public byte[] GetRealmList(uint build, string subRegion) { var realmList = new RealmListUpdates(); foreach (var realm in _realms) { if (realm.Value.Id.GetSubRegionAddress() != subRegion) { continue; } RealmFlags flag = realm.Value.Flags; if (realm.Value.Build != build) { flag |= RealmFlags.VersionMismatch; } RealmListUpdate realmListUpdate = new RealmListUpdate(); realmListUpdate.Update.WowRealmAddress = (int)realm.Value.Id.GetAddress(); realmListUpdate.Update.CfgTimezonesID = 1; realmListUpdate.Update.PopulationState = (realm.Value.Flags.HasAnyFlag(RealmFlags.Offline) ? 0 : Math.Max((int)realm.Value.PopulationLevel, 1)); realmListUpdate.Update.CfgCategoriesID = realm.Value.Timezone; RealmBuildInfo buildInfo = GetBuildInfo(realm.Value.Build); if (buildInfo != null) { realmListUpdate.Update.Version.Major = (int)buildInfo.MajorVersion; realmListUpdate.Update.Version.Minor = (int)buildInfo.MinorVersion; realmListUpdate.Update.Version.Revision = (int)buildInfo.BugfixVersion; realmListUpdate.Update.Version.Build = (int)buildInfo.Build; } else { realmListUpdate.Update.Version.Major = 7; realmListUpdate.Update.Version.Minor = 1; realmListUpdate.Update.Version.Revision = 0; realmListUpdate.Update.Version.Build = (int)realm.Value.Build; } realmListUpdate.Update.CfgRealmsID = (int)realm.Value.Id.Realm; realmListUpdate.Update.Flags = (int)flag; realmListUpdate.Update.Name = realm.Value.Name; realmListUpdate.Update.CfgConfigsID = (int)realm.Value.GetConfigId(); realmListUpdate.Update.CfgLanguagesID = 1; realmListUpdate.Deleting = false; realmList.Updates.Add(realmListUpdate); } return(Json.Deflate("JSONRealmListUpdates", realmList)); }
public byte[] GetRealmEntryJSON(RealmHandle id, uint build) { byte[] compressed = new byte[0]; Realm realm = GetRealm(id); if (realm != null) { if (!realm.Flags.HasAnyFlag(RealmFlags.Offline) && realm.Build == build) { var realmEntry = new RealmEntry(); realmEntry.WowRealmAddress = (int)realm.Id.GetAddress(); realmEntry.CfgTimezonesID = 1; realmEntry.PopulationState = Math.Max((int)realm.PopulationLevel, 1); realmEntry.CfgCategoriesID = realm.Timezone; ClientVersion version = new ClientVersion(); RealmBuildInfo buildInfo = GetBuildInfo(realm.Build); if (buildInfo != null) { version.Major = (int)buildInfo.MajorVersion; version.Minor = (int)buildInfo.MinorVersion; version.Revision = (int)buildInfo.BugfixVersion; version.Build = (int)buildInfo.Build; } else { version.Major = 6; version.Minor = 2; version.Revision = 4; version.Build = (int)realm.Build; } realmEntry.Version = version; realmEntry.CfgRealmsID = (int)realm.Id.Realm; realmEntry.Flags = (int)realm.Flags; realmEntry.Name = realm.Name; realmEntry.CfgConfigsID = (int)realm.GetConfigId(); realmEntry.CfgLanguagesID = 1; compressed = Json.Deflate("JamJSONRealmEntry", realmEntry); } } return(compressed); }
void LoadBuildInfo() { // 0 1 2 3 4 5 6 SQLResult result = DB.Login.Query("SELECT majorVersion, minorVersion, bugfixVersion, hotfixVersion, build, win64AuthSeed, mac64AuthSeed FROM build_info ORDER BY build ASC"); if (!result.IsEmpty()) { do { RealmBuildInfo build = new RealmBuildInfo(); build.MajorVersion = result.Read <uint>(0); build.MinorVersion = result.Read <uint>(1); build.BugfixVersion = result.Read <uint>(2); string hotfixVersion = result.Read <string>(3); if (!hotfixVersion.IsEmpty() && hotfixVersion.Length < build.HotfixVersion.Length) { build.HotfixVersion = hotfixVersion.ToCharArray(); } build.Build = result.Read <uint>(4); string win64AuthSeedHexStr = result.Read <string>(5); if (!win64AuthSeedHexStr.IsEmpty() && win64AuthSeedHexStr.Length == build.Win64AuthSeed.Length * 2) { build.Win64AuthSeed = win64AuthSeedHexStr.ToByteArray(); } string mac64AuthSeedHexStr = result.Read <string>(6); if (!mac64AuthSeedHexStr.IsEmpty() && mac64AuthSeedHexStr.Length == build.Mac64AuthSeed.Length * 2) { build.Mac64AuthSeed = mac64AuthSeedHexStr.ToByteArray(); } _builds.Add(build); } while (result.NextRow()); } }
void HandleAuthSessionCallback(AuthSession authSession, SQLResult result) { // Stop if the account is not found if (result.IsEmpty()) { Log.outError(LogFilter.Network, "HandleAuthSession: Sent Auth Response (unknown account)."); CloseSocket(); return; } RealmBuildInfo buildInfo = Global.RealmMgr.GetBuildInfo(Global.WorldMgr.GetRealm().Build); if (buildInfo == null) { SendAuthResponseError(BattlenetRpcErrorCode.BadVersion); Log.outError(LogFilter.Network, $"WorldSocket.HandleAuthSessionCallback: Missing auth seed for realm build {Global.WorldMgr.GetRealm().Build} ({GetRemoteIpAddress().ToString()})."); CloseSocket(); return; } AccountInfo account = new AccountInfo(result.GetFields()); // For hook purposes, we get Remoteaddress at this point. string address = GetRemoteIpAddress().ToString(); Sha256 digestKeyHash = new Sha256(); digestKeyHash.Process(account.game.SessionKey, account.game.SessionKey.Length); if (account.game.OS == "Wn64") { digestKeyHash.Finish(buildInfo.Win64AuthSeed); } else if (account.game.OS == "Mc64") { digestKeyHash.Finish(buildInfo.Mac64AuthSeed); } else { Log.outError(LogFilter.Network, "WorldSocket.HandleAuthSession: Authentication failed for account: {0} ('{1}') address: {2}", account.game.Id, authSession.RealmJoinTicket, address); CloseSocket(); return; } HmacSha256 hmac = new HmacSha256(digestKeyHash.Digest); hmac.Process(authSession.LocalChallenge, authSession.LocalChallenge.Count); hmac.Process(_serverChallenge, 16); hmac.Finish(AuthCheckSeed, 16); // Check that Key and account name are the same on client and server if (!hmac.Digest.Compare(authSession.Digest)) { Log.outError(LogFilter.Network, "WorldSocket.HandleAuthSession: Authentication failed for account: {0} ('{1}') address: {2}", account.game.Id, authSession.RealmJoinTicket, address); CloseSocket(); return; } Sha256 keyData = new Sha256(); keyData.Finish(account.game.SessionKey); HmacSha256 sessionKeyHmac = new HmacSha256(keyData.Digest); sessionKeyHmac.Process(_serverChallenge, 16); sessionKeyHmac.Process(authSession.LocalChallenge, authSession.LocalChallenge.Count); sessionKeyHmac.Finish(SessionKeySeed, 16); _sessionKey = new byte[40]; var sessionKeyGenerator = new SessionKeyGenerator(sessionKeyHmac.Digest, 32); sessionKeyGenerator.Generate(_sessionKey, 40); HmacSha256 encryptKeyGen = new HmacSha256(_sessionKey); encryptKeyGen.Process(authSession.LocalChallenge, authSession.LocalChallenge.Count); encryptKeyGen.Process(_serverChallenge, 16); encryptKeyGen.Finish(EncryptionKeySeed, 16); // only first 16 bytes of the hmac are used Buffer.BlockCopy(encryptKeyGen.Digest, 0, _encryptKey, 0, 16); // As we don't know if attempted login process by ip works, we update last_attempt_ip right away PreparedStatement stmt = DB.Login.GetPreparedStatement(LoginStatements.UPD_LAST_ATTEMPT_IP); stmt.AddValue(0, address); stmt.AddValue(1, authSession.RealmJoinTicket); DB.Login.Execute(stmt); // This also allows to check for possible "hack" attempts on account stmt = DB.Login.GetPreparedStatement(LoginStatements.UPD_ACCOUNT_INFO_CONTINUED_SESSION); stmt.AddValue(0, _sessionKey.ToHexString()); stmt.AddValue(1, account.game.Id); DB.Login.Execute(stmt); // First reject the connection if packet contains invalid data or realm state doesn't allow logging in if (Global.WorldMgr.IsClosed()) { SendAuthResponseError(BattlenetRpcErrorCode.Denied); Log.outError(LogFilter.Network, "WorldSocket.HandleAuthSession: World closed, denying client ({0}).", GetRemoteIpAddress()); CloseSocket(); return; } if (authSession.RealmID != Global.WorldMgr.GetRealm().Id.Realm) { SendAuthResponseError(BattlenetRpcErrorCode.Denied); Log.outError(LogFilter.Network, "WorldSocket.HandleAuthSession: Client {0} requested connecting with realm id {1} but this realm has id {2} set in config.", GetRemoteIpAddress().ToString(), authSession.RealmID, Global.WorldMgr.GetRealm().Id.Realm); CloseSocket(); return; } // Must be done before WorldSession is created bool wardenActive = WorldConfig.GetBoolValue(WorldCfg.WardenEnabled); if (wardenActive && account.game.OS != "Win" && account.game.OS != "Wn64" && account.game.OS != "Mc64") { SendAuthResponseError(BattlenetRpcErrorCode.Denied); Log.outError(LogFilter.Network, "WorldSocket.HandleAuthSession: Client {0} attempted to log in using invalid client OS ({1}).", address, account.game.OS); CloseSocket(); return; } //Re-check ip locking (same check as in auth). if (account.battleNet.IsLockedToIP) // if ip is locked { if (account.battleNet.LastIP != address) { SendAuthResponseError(BattlenetRpcErrorCode.RiskAccountLocked); Log.outDebug(LogFilter.Network, "HandleAuthSession: Sent Auth Response (Account IP differs)."); CloseSocket(); return; } } else if (!account.battleNet.LockCountry.IsEmpty() && account.battleNet.LockCountry != "00" && !_ipCountry.IsEmpty()) { if (account.battleNet.LockCountry != _ipCountry) { SendAuthResponseError(BattlenetRpcErrorCode.RiskAccountLocked); Log.outDebug(LogFilter.Network, "WorldSocket.HandleAuthSession: Sent Auth Response (Account country differs. Original country: {0}, new country: {1}).", account.battleNet.LockCountry, _ipCountry); CloseSocket(); return; } } long mutetime = account.game.MuteTime; //! Negative mutetime indicates amount of seconds to be muted effective on next login - which is now. if (mutetime < 0) { mutetime = Time.UnixTime + mutetime; stmt = DB.Login.GetPreparedStatement(LoginStatements.UPD_MUTE_TIME_LOGIN); stmt.AddValue(0, mutetime); stmt.AddValue(1, account.game.Id); DB.Login.Execute(stmt); } if (account.IsBanned()) // if account banned { SendAuthResponseError(BattlenetRpcErrorCode.GameAccountBanned); Log.outError(LogFilter.Network, "WorldSocket:HandleAuthSession: Sent Auth Response (Account banned)."); CloseSocket(); return; } // Check locked state for server AccountTypes allowedAccountType = Global.WorldMgr.GetPlayerSecurityLimit(); if (allowedAccountType > AccountTypes.Player && account.game.Security < allowedAccountType) { SendAuthResponseError(BattlenetRpcErrorCode.ServerIsPrivate); Log.outInfo(LogFilter.Network, "WorldSocket:HandleAuthSession: User tries to login but his security level is not enough"); CloseSocket(); return; } Log.outDebug(LogFilter.Network, "WorldSocket:HandleAuthSession: Client '{0}' authenticated successfully from {1}.", authSession.RealmJoinTicket, address); // Update the last_ip in the database stmt = DB.Login.GetPreparedStatement(LoginStatements.UPD_LAST_IP); stmt.AddValue(0, address); stmt.AddValue(1, authSession.RealmJoinTicket); DB.Login.Execute(stmt); _worldSession = new WorldSession(account.game.Id, authSession.RealmJoinTicket, account.battleNet.Id, this, account.game.Security, (Expansion)account.game.Expansion, mutetime, account.game.OS, account.battleNet.Locale, account.game.Recruiter, account.game.IsRectuiter); // Initialize Warden system only if it is enabled by config //if (wardenActive) //_worldSession.InitWarden(_sessionKey); _queryProcessor.AddQuery(_worldSession.LoadPermissionsAsync().WithCallback(LoadSessionPermissionsCallback)); }