diff --git a/Source/BNetServer/Server.cs b/Source/BNetServer/Server.cs index 526fd49ab..4ced36d5d 100644 --- a/Source/BNetServer/Server.cs +++ b/Source/BNetServer/Server.cs @@ -27,8 +27,6 @@ namespace BNetServer if (!StartDB()) ExitNow(); - FixLegacyAuthHashes(); - string bindIp = ConfigMgr.GetDefaultValue("BindIP", "0.0.0.0"); var restSocketServer = new SocketManager(); @@ -89,47 +87,6 @@ namespace BNetServer Environment.Exit(-1); } - static void FixLegacyAuthHashes() - { - Log.outInfo(LogFilter.Server, "Updating password hashes..."); - uint start = Time.GetMSTime(); - // the auth update query nulls salt/verifier if they cannot be converted - // if they are non-null but s/v have been cleared, that means a legacy tool touched our auth DB (otherwise, the core might've done it itself, it used to use those hacks too) - SQLResult result = DB.Login.Query("SELECT id, sha_pass_hash, IF((salt IS null) AND (verifier IS null), 0, 1) AS shouldWarn FROM account WHERE s != DEFAULT(s) OR v != DEFAULT(v) OR salt IS NULL OR verifier IS NULL"); - if (result.IsEmpty()) - { - Log.outInfo(LogFilter.Server, $"No password hashes to update - this took us {Time.GetMSTimeDiffToNow(start)} ms to realize"); - return; - } - - bool hadWarning = false; - uint count = 0; - SQLTransaction trans = new(); - do - { - uint id = result.Read(0); - (byte[] salt, byte[] verifier) = SRP6.MakeRegistrationDataFromHash(result.Read(1).ToByteArray()); - - if (result.Read(2) != 0 && !hadWarning) - { - hadWarning = true; - Log.outWarn(LogFilter.Server, "(!) You appear to be using an outdated external account management tool.\n(!!) This is INSECURE, has been deprecated, and will cease to function entirely in the near future.\n(!) Update your external tool.\n(!!) If no update is available, refer your tool's developer to https://github.com/TrinityCore/TrinityCore/issues/25157."); - } - - PreparedStatement stmt = DB.Login.GetPreparedStatement(LoginStatements.UPD_LOGON); - stmt.AddValue(0, salt); - stmt.AddValue(1, verifier); - stmt.AddValue(2, id); - trans.Append(stmt); - - ++count; - } while (result.NextRow()); - - DB.Login.CommitTransaction(trans); - - Log.outInfo(LogFilter.Server, $"{count} password hashes updated in {Time.GetMSTimeDiffToNow(start)} ms"); - } - static void BanExpiryCheckTimer_Elapsed(object sender, ElapsedEventArgs e) { DB.Login.Execute(DB.Login.GetPreparedStatement(LoginStatements.DelExpiredIpBans)); diff --git a/Source/Framework/Cryptography/SRP6.cs b/Source/Framework/Cryptography/SRP6.cs index 92cf38faf..f24da042c 100644 --- a/Source/Framework/Cryptography/SRP6.cs +++ b/Source/Framework/Cryptography/SRP6.cs @@ -44,25 +44,11 @@ namespace Framework.Cryptography var salt = new byte[0].GenerateRandomKey(32); // random salt return (salt, CalculateVerifier(username, password, salt)); } - - [Obsolete] - public static (byte[] Salt, byte[] Verifier) MakeRegistrationDataFromHash(byte[] hash) - { - var salt = new byte[0].GenerateRandomKey(32); // random salt - return (salt, CalculateVerifierFromHash(hash, salt)); - } public static byte[] CalculateVerifier(string username, string password, byte[] salt) { // v = g ^ H(s || H(u || ':' || p)) mod N - return CalculateVerifierFromHash(_sha1.ComputeHash(Encoding.UTF8.GetBytes(username.ToUpperInvariant() + ":" + password.ToUpperInvariant())), salt); - } - - // merge this into CalculateVerifier once the sha_pass hack finally gets nuked from orbit - public static byte[] CalculateVerifierFromHash(byte[] hash, byte[] salt) - { - // v = BigInteger.ModPow(gBN, x, BN); - return BigInteger.ModPow(_g, new BigInteger(_sha1.ComputeHash(salt.Combine(hash)), true), _N).ToByteArray(); + return BigInteger.ModPow(_g, new BigInteger(_sha1.ComputeHash(salt.Combine(_sha1.ComputeHash(Encoding.UTF8.GetBytes(username.ToUpperInvariant() + ":" + password.ToUpperInvariant())))), true), _N).ToByteArray(); } public static bool CheckLogin(string username, string password, byte[] salt, byte[] verifier) diff --git a/Source/Framework/Database/Databases/LoginDatabase.cs b/Source/Framework/Database/Databases/LoginDatabase.cs index 037ce4a15..32fe7984f 100644 --- a/Source/Framework/Database/Databases/LoginDatabase.cs +++ b/Source/Framework/Database/Databases/LoginDatabase.cs @@ -38,8 +38,7 @@ namespace Framework.Database PrepareStatement(LoginStatements.DEL_ACCOUNT_BANNED, "DELETE FROM account_banned WHERE id = ?"); PrepareStatement(LoginStatements.UPD_ACCOUNT_INFO_CONTINUED_SESSION, "UPDATE account SET session_key_bnet = ? WHERE id = ?"); PrepareStatement(LoginStatements.SEL_ACCOUNT_INFO_CONTINUED_SESSION, "SELECT username, session_key_bnet FROM account WHERE id = ? AND LENGTH(session_key_bnet) = 40"); - PrepareStatement(LoginStatements.UPD_LOGON, "UPDATE account SET salt = ?, verifier = ?, s = DEFAULT, v = DEFAULT WHERE id = ?"); - PrepareStatement(LoginStatements.UPD_LOGON_LEGACY, "UPDATE account SET sha_pass_hash = ? WHERE id = ?"); + PrepareStatement(LoginStatements.UPD_LOGON, "UPDATE account SET salt = ?, verifier = ? WHERE id = ?"); PrepareStatement(LoginStatements.SEL_ACCOUNT_ID_BY_NAME, "SELECT id FROM account WHERE username = ?"); PrepareStatement(LoginStatements.SEL_ACCOUNT_LIST_BY_NAME, "SELECT id, username FROM account WHERE username = ?"); PrepareStatement(LoginStatements.SEL_ACCOUNT_INFO_BY_NAME, "SELECT a.id, a.session_key_bnet, ba.last_ip, ba.locked, ba.lock_country, a.expansion, a.mutetime, ba.locale, a.recruiter, a.os, ba.id, aa.SecurityLevel, " + @@ -81,8 +80,8 @@ namespace Framework.Database PrepareStatement(LoginStatements.GET_ACCOUNT_ID_BY_USERNAME, "SELECT id FROM account WHERE username = ?"); PrepareStatement(LoginStatements.GET_GMLEVEL_BY_REALMID, "SELECT SecurityLevel FROM account_access WHERE AccountID = ? AND (RealmID = ? OR RealmID = -1) ORDER BY RealmID DESC"); PrepareStatement(LoginStatements.GET_USERNAME_BY_ID, "SELECT username FROM account WHERE id = ?"); - PrepareStatement(LoginStatements.SEL_CHECK_PASSWORD, "SELECT salt, verifier FROM account WHERE id = ? AND salt IS NOT NULL AND verifier IS NOT NULL"); - PrepareStatement(LoginStatements.SEL_CHECK_PASSWORD_BY_NAME, "SELECT salt, verifier FROM account WHERE username = ? AND salt IS NOT NULL AND verifier IS NOT NULL"); + PrepareStatement(LoginStatements.SEL_CHECK_PASSWORD, "SELECT salt, verifier FROM account WHERE id = ?"); + PrepareStatement(LoginStatements.SEL_CHECK_PASSWORD_BY_NAME, "SELECT salt, verifier FROM account WHERE username = ?"); PrepareStatement(LoginStatements.SEL_PINFO, "SELECT a.username, aa.SecurityLevel, a.email, a.reg_mail, a.last_ip, DATE_FORMAT(a.last_login, '%Y-%m-%d %T'), a.mutetime, a.mutereason, a.muteby, a.failed_logins, a.locked, a.OS FROM account a LEFT JOIN account_access aa ON (a.id = aa.AccountID AND (aa.RealmID = ? OR aa.RealmID = -1)) WHERE a.id = ?"); PrepareStatement(LoginStatements.SEL_PINFO_BANS, "SELECT unbandate, bandate = unbandate, bannedby, banreason FROM account_banned WHERE id = ? AND active ORDER BY bandate ASC LIMIT 1"); PrepareStatement(LoginStatements.SEL_GM_ACCOUNTS, "SELECT a.username, aa.SecurityLevel FROM account a, account_access aa WHERE a.id = aa.AccountID AND aa.SecurityLevel >= ? AND (aa.RealmID = -1 OR aa.RealmID = ?)"); @@ -193,7 +192,6 @@ namespace Framework.Database UPD_ACCOUNT_INFO_CONTINUED_SESSION, SEL_ACCOUNT_INFO_CONTINUED_SESSION, UPD_LOGON, - UPD_LOGON_LEGACY, SEL_ACCOUNT_ID_BY_NAME, SEL_ACCOUNT_LIST_BY_NAME, SEL_ACCOUNT_INFO_BY_NAME, diff --git a/Source/Game/Accounts/AccountManager.cs b/Source/Game/Accounts/AccountManager.cs index d27e2dd9a..2104beecd 100644 --- a/Source/Game/Accounts/AccountManager.cs +++ b/Source/Game/Accounts/AccountManager.cs @@ -173,11 +173,6 @@ namespace Game stmt.AddValue(2, accountId); DB.Login.Execute(stmt); - stmt = DB.Login.GetPreparedStatement(LoginStatements.UPD_LOGON_LEGACY); - stmt.AddValue(0, CalculateShaPassHash(newUsername, newPassword)); - stmt.AddValue(1, accountId); - DB.Login.Execute(stmt); - return AccountOpResult.Ok; } @@ -199,11 +194,6 @@ namespace Game stmt.AddValue(2, accountId); DB.Login.Execute(stmt); - stmt = DB.Login.GetPreparedStatement(LoginStatements.UPD_LOGON_LEGACY); - stmt.AddValue(0, CalculateShaPassHash(username, newPassword)); - stmt.AddValue(1, accountId); - DB.Login.Execute(stmt); - return AccountOpResult.Ok; } @@ -341,12 +331,6 @@ namespace Game return result.IsEmpty() ? 0 : (uint)result.Read(0); } - string CalculateShaPassHash(string name, string password) - { - SHA1 sha = SHA1.Create(); - return sha.ComputeHash(Encoding.UTF8.GetBytes(name + ":" + password)).ToHexString(); - } - public bool IsBannedAccount(string name) { PreparedStatement stmt = DB.Login.GetPreparedStatement(LoginStatements.SEL_ACCOUNT_BANNED_BY_USERNAME);