Core/Auth: Refactor client auth key storage to support more future client variants and preserve more information about client version
Port From (https://github.com/TrinityCore/TrinityCore/commit/8e1595265925e0840d07e943b8c9ff1e906d4719)
This commit is contained in:
@@ -5,6 +5,7 @@ using Bgs.Protocol;
|
||||
using Bgs.Protocol.Authentication.V1;
|
||||
using Bgs.Protocol.Challenge.V1;
|
||||
using Framework;
|
||||
using Framework.ClientBuild;
|
||||
using Framework.Constants;
|
||||
using Framework.Database;
|
||||
using Framework.Realm;
|
||||
@@ -25,7 +26,7 @@ namespace BNetServer.Networking
|
||||
return BattlenetRpcErrorCode.BadProgram;
|
||||
}
|
||||
|
||||
if (logonRequest.Platform != "Win" && logonRequest.Platform != "Wn64" && logonRequest.Platform != "Mc64" && logonRequest.Platform != "MacA")
|
||||
if (!ClientBuildHelper.IsValid(logonRequest.Platform))
|
||||
{
|
||||
Log.outDebug(LogFilter.Session, $"Battlenet.LogonRequest: {GetClientInfo()} attempted to log in from an unsupported platform (using {logonRequest.Platform})!");
|
||||
return BattlenetRpcErrorCode.BadPlatform;
|
||||
|
||||
@@ -115,6 +115,8 @@ namespace BNetServer.Networking
|
||||
int i = 0;
|
||||
foreach (byte b in realmListTicketClientInformation.Info.Secret)
|
||||
clientSecret[i++] = b;
|
||||
|
||||
_clientInfo = new() { Platform = realmListTicketClientInformation.Info.PlatformType, Arch = realmListTicketClientInformation.Info.ClientArch, Type = realmListTicketClientInformation.Info.Type };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,7 +229,7 @@ namespace BNetServer.Networking
|
||||
{
|
||||
Variant realmAddress = Params.LookupByKey("Param_RealmAddress");
|
||||
if (realmAddress != null)
|
||||
return Global.RealmMgr.JoinRealm((uint)realmAddress.UintValue, build, GetRemoteIpAddress(), clientSecret, (Locale)Enum.Parse(typeof(Locale), locale), os, _timezoneOffset, gameAccountInfo.Name, gameAccountInfo.SecurityLevel, response);
|
||||
return Global.RealmMgr.JoinRealm((uint)realmAddress.UintValue, build, _clientInfo, GetRemoteIpAddress(), clientSecret, (Locale)Enum.Parse(typeof(Locale), locale), os, _timezoneOffset, gameAccountInfo.Name, gameAccountInfo.SecurityLevel, response);
|
||||
|
||||
return BattlenetRpcErrorCode.WowServicesInvalidJoinTicket;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace BNetServer.Networking
|
||||
string locale;
|
||||
string os;
|
||||
uint build;
|
||||
Framework.ClientBuild.ClientBuildVariantId _clientInfo;
|
||||
TimeSpan _timezoneOffset;
|
||||
string ipCountry;
|
||||
|
||||
|
||||
@@ -24,6 +24,11 @@ namespace Framework.Database
|
||||
return WithChainingCallback((queryCallback, result) => callback(obj, result));
|
||||
}
|
||||
|
||||
public QueryCallback WithCallback<T, U>(Action<T, U, SQLResult> callback, T obj, U obj2)
|
||||
{
|
||||
return WithChainingCallback((queryCallback, result) => callback(obj, obj2, result));
|
||||
}
|
||||
|
||||
public QueryCallback WithChainingCallback(Action<QueryCallback, SQLResult> callback)
|
||||
{
|
||||
_callbacks.Enqueue(new QueryCallbackData(callback));
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Framework.ClientBuild
|
||||
{
|
||||
struct ClientBuildPlatformType
|
||||
{
|
||||
public static int Windows = "Win".fourcc();
|
||||
public static int macOS = "Mac".fourcc();
|
||||
}
|
||||
|
||||
struct ClientBuildArch
|
||||
{
|
||||
public static int x86 = "x86".fourcc();
|
||||
public static int x64 = "x64".fourcc();
|
||||
public static int Arm32 = "A32".fourcc();
|
||||
public static int Arm64 = "A64".fourcc();
|
||||
public static int WA32 = "WA32".fourcc();
|
||||
}
|
||||
|
||||
struct ClientBuildType
|
||||
{
|
||||
public static int Retail = "WoW".fourcc();
|
||||
public static int RetailChina = "WoWC".fourcc();
|
||||
public static int Beta = "WoWB".fourcc();
|
||||
public static int BetaRelease = "WoWE".fourcc();
|
||||
public static int Ptr = "WoWT".fourcc();
|
||||
public static int PtrRelease = "WoWR".fourcc();
|
||||
}
|
||||
|
||||
public class ClientBuildHelper
|
||||
{
|
||||
public static bool IsValid(string platform)
|
||||
{
|
||||
switch (platform)
|
||||
{
|
||||
case "Win":
|
||||
case "Wn64":
|
||||
case "WinA":
|
||||
case "Mac":
|
||||
case "Mc64":
|
||||
case "MacA":
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public class ClientBuildVariantId
|
||||
{
|
||||
public int Platform;
|
||||
public int Arch;
|
||||
public int Type;
|
||||
}
|
||||
|
||||
public class ClientBuildAuthKey
|
||||
{
|
||||
public static int Size = 16;
|
||||
|
||||
public ClientBuildVariantId Variant;
|
||||
public byte[] Key = new byte[Size];
|
||||
}
|
||||
|
||||
public class ClientBuildInfo
|
||||
{
|
||||
public uint Build;
|
||||
public uint MajorVersion;
|
||||
public uint MinorVersion;
|
||||
public uint BugfixVersion;
|
||||
public char[] HotfixVersion = new char[4];
|
||||
public List<ClientBuildAuthKey> AuthKeys = new();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Framework.ClientBuild;
|
||||
using Framework.Constants;
|
||||
using Framework.Database;
|
||||
using Framework.IO;
|
||||
@@ -36,13 +37,15 @@ public class RealmManager : Singleton<RealmManager>
|
||||
|
||||
void LoadBuildInfo()
|
||||
{
|
||||
_builds.Clear();
|
||||
|
||||
// 0 1 2 3 4 5 6 7
|
||||
SQLResult result = DB.Login.Query("SELECT majorVersion, minorVersion, bugfixVersion, hotfixVersion, build, win64AuthSeed, mac64AuthSeed, macArmAuthSeed FROM build_info ORDER BY build ASC");
|
||||
if (!result.IsEmpty())
|
||||
{
|
||||
do
|
||||
{
|
||||
RealmBuildInfo build = new();
|
||||
ClientBuildInfo build = new();
|
||||
build.MajorVersion = result.Read<uint>(0);
|
||||
build.MinorVersion = result.Read<uint>(1);
|
||||
build.BugfixVersion = result.Read<uint>(2);
|
||||
@@ -51,17 +54,33 @@ public class RealmManager : Singleton<RealmManager>
|
||||
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();
|
||||
if (win64AuthSeedHexStr.Length == ClientBuildAuthKey.Size * 2)
|
||||
{
|
||||
ClientBuildAuthKey buildKey = new();
|
||||
buildKey.Variant = new() { Platform = ClientBuildPlatformType.Windows, Arch = ClientBuildArch.x64, Type = ClientBuildType.Retail };
|
||||
buildKey.Key = win64AuthSeedHexStr.ToByteArray();
|
||||
build.AuthKeys.Add(buildKey);
|
||||
}
|
||||
|
||||
string mac64AuthSeedHexStr = result.Read<string>(6);
|
||||
if (!mac64AuthSeedHexStr.IsEmpty() && mac64AuthSeedHexStr.Length == build.Mac64AuthSeed.Length * 2)
|
||||
build.Mac64AuthSeed = mac64AuthSeedHexStr.ToByteArray();
|
||||
if (mac64AuthSeedHexStr.Length == ClientBuildAuthKey.Size * 2)
|
||||
{
|
||||
ClientBuildAuthKey buildKey = new();
|
||||
buildKey.Variant = new() { Platform = ClientBuildPlatformType.macOS, Arch = ClientBuildArch.x64, Type = ClientBuildType.Retail };
|
||||
buildKey.Key = mac64AuthSeedHexStr.ToByteArray();
|
||||
build.AuthKeys.Add(buildKey);
|
||||
}
|
||||
|
||||
string macArmAuthSeedHexStr = result.Read<string>(7);
|
||||
if (macArmAuthSeedHexStr.IsEmpty() && mac64AuthSeedHexStr.Length == build.MacArmAuthSeed.Length * 2)
|
||||
build.MacArmAuthSeed = macArmAuthSeedHexStr.ToByteArray();
|
||||
if (macArmAuthSeedHexStr.Length == ClientBuildAuthKey.Size * 2)
|
||||
{
|
||||
ClientBuildAuthKey buildKey = new();
|
||||
buildKey.Variant = new() { Platform = ClientBuildPlatformType.macOS, Arch = ClientBuildArch.Arm64, Type = ClientBuildType.Retail };
|
||||
buildKey.Key = macArmAuthSeedHexStr.ToByteArray();
|
||||
build.AuthKeys.Add(buildKey);
|
||||
}
|
||||
|
||||
_builds.Add(build);
|
||||
|
||||
@@ -199,7 +218,7 @@ public class RealmManager : Singleton<RealmManager>
|
||||
}
|
||||
}
|
||||
|
||||
public RealmBuildInfo GetBuildInfo(uint build)
|
||||
public ClientBuildInfo GetBuildInfo(uint build)
|
||||
{
|
||||
foreach (var clientBuild in _builds)
|
||||
if (clientBuild.Build == build)
|
||||
@@ -210,7 +229,7 @@ public class RealmManager : Singleton<RealmManager>
|
||||
|
||||
public uint GetMinorMajorBugfixVersionForBuild(uint build)
|
||||
{
|
||||
RealmBuildInfo buildInfo = _builds.FirstOrDefault(p => p.Build < build);
|
||||
ClientBuildInfo buildInfo = _builds.FirstOrDefault(p => p.Build < build);
|
||||
return buildInfo != null ? (buildInfo.MajorVersion * 10000 + buildInfo.MinorVersion * 100 + buildInfo.BugfixVersion) : 0;
|
||||
}
|
||||
|
||||
@@ -226,7 +245,7 @@ public class RealmManager : Singleton<RealmManager>
|
||||
realmEntry.CfgCategoriesID = realm.Timezone;
|
||||
|
||||
ClientVersion version = new();
|
||||
RealmBuildInfo buildInfo = GetBuildInfo(realm.Build);
|
||||
ClientBuildInfo buildInfo = GetBuildInfo(realm.Build);
|
||||
if (buildInfo != null)
|
||||
{
|
||||
version.Major = (int)buildInfo.MajorVersion;
|
||||
@@ -302,7 +321,7 @@ public class RealmManager : Singleton<RealmManager>
|
||||
return BitConverter.GetBytes(jsonData.Length).Combine(ZLib.Compress(jsonData));
|
||||
}
|
||||
|
||||
public BattlenetRpcErrorCode JoinRealm(uint realmAddress, uint build, IPAddress clientAddress, byte[] clientSecret, Locale locale, string os, TimeSpan timezoneOffset, string accountName, AccountTypes accountSecurityLevel, Bgs.Protocol.GameUtilities.V1.ClientResponse response)
|
||||
public BattlenetRpcErrorCode JoinRealm(uint realmAddress, uint build, ClientBuildVariantId buildVariant, IPAddress clientAddress, byte[] clientSecret, Locale locale, string os, TimeSpan timezoneOffset, string accountName, AccountTypes accountSecurityLevel, Bgs.Protocol.GameUtilities.V1.ClientResponse response)
|
||||
{
|
||||
Realm realm = GetRealm(new RealmId(realmAddress));
|
||||
if (realm != null)
|
||||
@@ -336,10 +355,16 @@ public class RealmManager : Singleton<RealmManager>
|
||||
stmt.AddValue(6, accountName);
|
||||
DB.Login.DirectExecute(stmt);
|
||||
|
||||
RealmJoinTicket joinTicket = new();
|
||||
joinTicket.GameAccount = accountName;
|
||||
joinTicket.Platform = buildVariant.Platform;
|
||||
joinTicket.ClientArch = buildVariant.Arch;
|
||||
joinTicket.Type = buildVariant.Type;
|
||||
|
||||
Bgs.Protocol.Attribute attribute = new();
|
||||
attribute.Name = "Param_RealmJoinTicket";
|
||||
attribute.Value = new Bgs.Protocol.Variant();
|
||||
attribute.Value.BlobValue = Google.Protobuf.ByteString.CopyFrom(accountName, Encoding.UTF8);
|
||||
attribute.Value.BlobValue = Google.Protobuf.ByteString.CopyFromUtf8(JsonSerializer.Serialize(joinTicket));
|
||||
response.Attribute.Add(attribute);
|
||||
|
||||
attribute = new Bgs.Protocol.Attribute();
|
||||
@@ -369,7 +394,7 @@ public class RealmManager : Singleton<RealmManager>
|
||||
|
||||
RealmPopulationState ConvertLegacyPopulationState(LegacyRealmFlags legacyRealmFlags, float population)
|
||||
{
|
||||
if (legacyRealmFlags .HasAnyFlag(LegacyRealmFlags.Offline))
|
||||
if (legacyRealmFlags.HasAnyFlag(LegacyRealmFlags.Offline))
|
||||
return RealmPopulationState.Offline;
|
||||
if (legacyRealmFlags.HasAnyFlag(LegacyRealmFlags.Recommended))
|
||||
return RealmPopulationState.Recommended;
|
||||
@@ -387,22 +412,10 @@ public class RealmManager : Singleton<RealmManager>
|
||||
public ICollection<Realm> GetRealms() { return _realms.Values; }
|
||||
List<string> GetSubRegions() { return _subRegions; }
|
||||
|
||||
List<RealmBuildInfo> _builds = new();
|
||||
List<ClientBuildInfo> _builds = new();
|
||||
ConcurrentDictionary<RealmId, Realm> _realms = new();
|
||||
Dictionary<RealmId, string> _removedRealms = new();
|
||||
List<string> _subRegions = new();
|
||||
Timer _updateTimer;
|
||||
RealmId? _currentRealmId;
|
||||
}
|
||||
|
||||
public class RealmBuildInfo
|
||||
{
|
||||
public uint Build;
|
||||
public uint MajorVersion;
|
||||
public uint MinorVersion;
|
||||
public uint BugfixVersion;
|
||||
public char[] HotfixVersion = new char[4];
|
||||
public byte[] Win64AuthSeed = new byte[16];
|
||||
public byte[] Mac64AuthSeed = new byte[16];
|
||||
public byte[] MacArmAuthSeed = new byte[16];
|
||||
}
|
||||
|
||||
@@ -438,6 +438,21 @@ namespace System
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
public static int fourcc(this string str)
|
||||
{
|
||||
//if (length > sizeof(uint))
|
||||
// throw "Text can only be max 4 characters long";
|
||||
|
||||
int intValue = 0;
|
||||
foreach (char c in str.ToCharArray())
|
||||
{
|
||||
intValue <<= 8;
|
||||
intValue |= c;
|
||||
}
|
||||
|
||||
return intValue;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region BinaryReader
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Framework.Web.Rest.Realmlist;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using Framework.Web.Rest.Realmlist;
|
||||
|
||||
namespace Framework.Web
|
||||
{
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Framework.Web
|
||||
{
|
||||
public class RealmJoinTicket
|
||||
{
|
||||
[JsonPropertyName("gameAccount")]
|
||||
public string GameAccount { get; set; }
|
||||
|
||||
[JsonPropertyName("platform")]
|
||||
public int Platform { get; set; }
|
||||
|
||||
[JsonPropertyName("type")]
|
||||
public int Type { get; set; }
|
||||
|
||||
[JsonPropertyName("clientArch")]
|
||||
public int ClientArch { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,8 @@
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
using Framework.Web.Rest.Realmlist;
|
||||
|
||||
namespace Framework.Web.Rest.Realmlist
|
||||
namespace Framework.Web
|
||||
{
|
||||
internal class RealmListRAFInfo
|
||||
{
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Framework.Web.Rest.Realmlist;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
using Framework.Web.Rest.Realmlist;
|
||||
|
||||
namespace Framework.Web
|
||||
{
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Framework.Constants;
|
||||
using System.Numerics;
|
||||
using System;
|
||||
using System.Numerics;
|
||||
|
||||
namespace Game.DataStorage
|
||||
{
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
// Copyright (c) CypherCore <http://github.com/CypherCore> All rights reserved.
|
||||
// Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information.
|
||||
|
||||
using Framework.ClientBuild;
|
||||
using Framework.Constants;
|
||||
using Framework.Cryptography;
|
||||
using Framework.Database;
|
||||
using Framework.IO;
|
||||
using Framework.Networking;
|
||||
using Framework.Web;
|
||||
using Game.Networking.Packets;
|
||||
using System;
|
||||
using System.Net.Sockets;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Game.Networking
|
||||
@@ -451,15 +454,23 @@ namespace Game.Networking
|
||||
|
||||
void HandleAuthSession(AuthSession authSession)
|
||||
{
|
||||
RealmJoinTicket joinTicket = JsonSerializer.Deserialize<RealmJoinTicket>(authSession.RealmJoinTicket);
|
||||
if (joinTicket == null)
|
||||
{
|
||||
SendAuthResponseError(BattlenetRpcErrorCode.WowServicesInvalidJoinTicket);
|
||||
CloseSocket();
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the account information from the realmd database
|
||||
PreparedStatement stmt = LoginDatabase.GetPreparedStatement(LoginStatements.SEL_ACCOUNT_INFO_BY_NAME);
|
||||
stmt.AddValue(0, Global.RealmMgr.GetCurrentRealmId().Index);
|
||||
stmt.AddValue(1, authSession.RealmJoinTicket);
|
||||
stmt.AddValue(1, joinTicket.GameAccount);
|
||||
|
||||
_queryProcessor.AddCallback(DB.Login.AsyncQuery(stmt).WithCallback(HandleAuthSessionCallback, authSession));
|
||||
_queryProcessor.AddCallback(DB.Login.AsyncQuery(stmt).WithCallback(HandleAuthSessionCallback, authSession, joinTicket));
|
||||
}
|
||||
|
||||
async void HandleAuthSessionCallback(AuthSession authSession, SQLResult result)
|
||||
async void HandleAuthSessionCallback(AuthSession authSession, RealmJoinTicket joinTicket, SQLResult result)
|
||||
{
|
||||
// Stop if the account is not found
|
||||
if (result.IsEmpty())
|
||||
@@ -471,11 +482,21 @@ namespace Game.Networking
|
||||
|
||||
AccountInfo account = new(result.GetFields());
|
||||
|
||||
RealmBuildInfo buildInfo = Global.RealmMgr.GetBuildInfo(account.game.Build);
|
||||
ClientBuildInfo buildInfo = Global.RealmMgr.GetBuildInfo(account.game.Build);
|
||||
if (buildInfo == null)
|
||||
{
|
||||
SendAuthResponseError(BattlenetRpcErrorCode.BadVersion);
|
||||
Log.outError(LogFilter.Network, $"WorldSocket.HandleAuthSessionCallback: Missing auth seed for realm build {account.game.Build} ({GetRemoteIpAddress()}).");
|
||||
Log.outError(LogFilter.Network, $"WorldSocket.HandleAuthSessionCallback: Missing client build info for realm build {account.game.Build} ({GetRemoteIpAddress()}).");
|
||||
CloseSocket();
|
||||
return;
|
||||
}
|
||||
|
||||
ClientBuildVariantId buildVariant = new() { Platform = joinTicket.Platform, Arch = joinTicket.ClientArch, Type = joinTicket.Type };
|
||||
var clientBuildAuthKey = buildInfo.AuthKeys.Find(p => p.Variant == buildVariant);
|
||||
if (clientBuildAuthKey == null)
|
||||
{
|
||||
SendAuthResponseError(BattlenetRpcErrorCode.BadVersion);
|
||||
Log.outError(LogFilter.Network, $"WorldSocket::HandleAuthSession: Missing client build auth key for build {account.game.Build} variant {buildVariant.Platform}-{buildVariant.Arch}-{buildVariant.Type} ({GetRemoteIpAddress()}).");
|
||||
CloseSocket();
|
||||
return;
|
||||
}
|
||||
@@ -485,18 +506,7 @@ namespace Game.Networking
|
||||
|
||||
Sha256 digestKeyHash = new();
|
||||
digestKeyHash.Process(account.game.KeyData, account.game.KeyData.Length);
|
||||
if (account.game.OS == "Wn64")
|
||||
digestKeyHash.Finish(buildInfo.Win64AuthSeed);
|
||||
else if (account.game.OS == "Mc64")
|
||||
digestKeyHash.Finish(buildInfo.Mac64AuthSeed);
|
||||
else if (account.game.OS == "MacA")
|
||||
digestKeyHash.Finish(buildInfo.MacArmAuthSeed);
|
||||
else
|
||||
{
|
||||
Log.outError(LogFilter.Network, "WorldSocket.HandleAuthSession: Authentication failed for account: {0} ('{1}') address: {2}", account.game.Id, authSession.RealmJoinTicket, address);
|
||||
CloseSocket();
|
||||
return;
|
||||
}
|
||||
digestKeyHash.Finish(clientBuildAuthKey.Key);
|
||||
|
||||
HmacSha256 hmac = new(digestKeyHash.Digest);
|
||||
hmac.Process(authSession.LocalChallenge, authSession.LocalChallenge.Count);
|
||||
@@ -507,7 +517,7 @@ namespace Game.Networking
|
||||
if (!hmac.Digest.Compare(authSession.Digest))
|
||||
{
|
||||
SendAuthResponseError(BattlenetRpcErrorCode.Denied);
|
||||
Log.outError(LogFilter.Network, "WorldSocket.HandleAuthSession: Authentication failed for account: {0} ('{1}') address: {2}", account.game.Id, authSession.RealmJoinTicket, address);
|
||||
Log.outError(LogFilter.Network, $"WorldSocket.HandleAuthSession: Authentication failed for account: {account.game.Id} ('{joinTicket.GameAccount}') address: {address}");
|
||||
CloseSocket();
|
||||
return;
|
||||
}
|
||||
@@ -539,7 +549,7 @@ namespace Game.Networking
|
||||
// As we don't know if attempted login process by ip works, we update last_attempt_ip right away
|
||||
stmt = LoginDatabase.GetPreparedStatement(LoginStatements.UPD_LAST_ATTEMPT_IP);
|
||||
stmt.AddValue(0, address.ToString());
|
||||
stmt.AddValue(1, authSession.RealmJoinTicket);
|
||||
stmt.AddValue(1, joinTicket.GameAccount);
|
||||
DB.Login.Execute(stmt);
|
||||
// This also allows to check for possible "hack" attempts on account
|
||||
}
|
||||
@@ -569,10 +579,10 @@ namespace Game.Networking
|
||||
|
||||
// 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" && account.game.OS != "MacA")
|
||||
if (wardenActive && !ClientBuildHelper.IsValid(account.game.OS))
|
||||
{
|
||||
SendAuthResponseError(BattlenetRpcErrorCode.Denied);
|
||||
Log.outError(LogFilter.Network, "WorldSocket.HandleAuthSession: Client {0} attempted to log in using invalid client OS ({1}).", address, account.game.OS);
|
||||
Log.outError(LogFilter.Network, $"WorldSocket.HandleAuthSession: Client {address} attempted to log in using invalid client OS ({account.game.OS}).");
|
||||
CloseSocket();
|
||||
return;
|
||||
}
|
||||
@@ -635,22 +645,22 @@ namespace Game.Networking
|
||||
return;
|
||||
}
|
||||
|
||||
Log.outDebug(LogFilter.Network, "WorldSocket:HandleAuthSession: Client '{0}' authenticated successfully from {1}.", authSession.RealmJoinTicket, address);
|
||||
Log.outDebug(LogFilter.Network, $"WorldSocket:HandleAuthSession: Client '{joinTicket.GameAccount}' authenticated successfully from {address}.");
|
||||
|
||||
if (WorldConfig.GetBoolValue(WorldCfg.AllowLogginIpAddressesInDatabase))
|
||||
{
|
||||
// Update the last_ip in the database
|
||||
stmt = LoginDatabase.GetPreparedStatement(LoginStatements.UPD_LAST_IP);
|
||||
stmt.AddValue(0, address.ToString());
|
||||
stmt.AddValue(1, authSession.RealmJoinTicket);
|
||||
stmt.AddValue(1, joinTicket.GameAccount);
|
||||
DB.Login.Execute(stmt);
|
||||
}
|
||||
|
||||
// At this point, we can safely hook a successful login
|
||||
Global.ScriptMgr.OnAccountLogin(account.game.Id);
|
||||
|
||||
_worldSession = new WorldSession(account.game.Id, authSession.RealmJoinTicket, account.battleNet.Id, this, account.game.Security, (Expansion)account.game.Expansion,
|
||||
mutetime, account.game.OS, account.game.TimezoneOffset, account.game.Build, account.game.Locale, account.game.Recruiter, account.game.IsRectuiter);
|
||||
_worldSession = new WorldSession(account.game.Id, joinTicket.GameAccount, account.battleNet.Id, this, account.game.Security, (Expansion)account.game.Expansion,
|
||||
mutetime, account.game.OS, account.game.TimezoneOffset, account.game.Build, buildVariant, account.game.Locale, account.game.Recruiter, account.game.IsRectuiter);
|
||||
|
||||
// Initialize Warden system only if it is enabled by config
|
||||
//if (wardenActive)
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace Game
|
||||
{
|
||||
public partial class WorldSession : IDisposable
|
||||
{
|
||||
public WorldSession(uint id, string name, uint battlenetAccountId, WorldSocket sock, AccountTypes sec, Expansion expansion, long mute_time, string os, TimeSpan timezoneOffset, uint build, Locale locale, uint recruiter, bool isARecruiter)
|
||||
public WorldSession(uint id, string name, uint battlenetAccountId, WorldSocket sock, AccountTypes sec, Expansion expansion, long mute_time, string os, TimeSpan timezoneOffset, uint build, Framework.ClientBuild.ClientBuildVariantId clientBuildVariant, Locale locale, uint recruiter, bool isARecruiter)
|
||||
{
|
||||
m_muteTime = mute_time;
|
||||
AntiDOS = new DosProtection(this);
|
||||
@@ -38,6 +38,7 @@ namespace Game
|
||||
m_expansion = (Expansion)Math.Min((byte)expansion, WorldConfig.GetIntValue(WorldCfg.Expansion));
|
||||
_os = os;
|
||||
_clientBuild = build;
|
||||
_clientBuildVariant = clientBuildVariant;
|
||||
m_sessionDbcLocale = Global.WorldMgr.GetAvailableDbcLocale(locale);
|
||||
m_sessionDbLocaleIndex = locale;
|
||||
_timezoneOffset = timezoneOffset;
|
||||
@@ -686,6 +687,7 @@ namespace Game
|
||||
public Expansion GetExpansion() { return m_expansion; }
|
||||
public string GetOS() { return _os; }
|
||||
public uint GetClientBuild() { return _clientBuild; }
|
||||
public Framework.ClientBuild.ClientBuildVariantId GetClientBuildVariant() { return _clientBuildVariant; }
|
||||
public void SetInQueue(bool state) { m_inQueue = state; }
|
||||
|
||||
public bool IsLogingOut() { return _logoutTime != 0 || m_playerLogout; }
|
||||
@@ -953,6 +955,7 @@ namespace Game
|
||||
Expansion m_expansion;
|
||||
string _os;
|
||||
uint _clientBuild;
|
||||
Framework.ClientBuild.ClientBuildVariantId _clientBuildVariant;
|
||||
|
||||
uint expireTime;
|
||||
bool forceExit;
|
||||
|
||||
@@ -112,8 +112,8 @@ namespace Game
|
||||
{
|
||||
var realmAddress = Params.LookupByKey("Param_RealmAddress");
|
||||
if (realmAddress != null)
|
||||
return Global.RealmMgr.JoinRealm((uint)realmAddress.UintValue, GetClientBuild(), System.Net.IPAddress.Parse(GetRemoteAddress()), GetRealmListSecret(),
|
||||
GetSessionDbcLocale(), GetOS(), GetTimezoneOffset(), GetAccountName(), GetSecurity(), response);
|
||||
return Global.RealmMgr.JoinRealm((uint)realmAddress.UintValue, GetClientBuild(), GetClientBuildVariant(),
|
||||
System.Net.IPAddress.Parse(GetRemoteAddress()), GetRealmListSecret(), GetSessionDbcLocale(), GetOS(), GetTimezoneOffset(), GetAccountName(), GetSecurity(), response);
|
||||
|
||||
return BattlenetRpcErrorCode.Ok;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user