Updated Bnet Server.
Port From (https://github.com/TrinityCore/TrinityCore)
This commit is contained in:
@@ -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.Cryptography;
|
||||
using Framework.Database;
|
||||
using System;
|
||||
using System.Security.Cryptography;
|
||||
@@ -10,24 +11,32 @@ namespace Game
|
||||
{
|
||||
public sealed class BNetAccountManager : Singleton<BNetAccountManager>
|
||||
{
|
||||
static int MAX_BNET_EMAIL_STR = 320;
|
||||
static int MAX_BNET_PASS_STR = 128;
|
||||
|
||||
BNetAccountManager() { }
|
||||
|
||||
public AccountOpResult CreateBattlenetAccount(string email, string password, bool withGameAccount, out string gameAccountName)
|
||||
{
|
||||
gameAccountName = "";
|
||||
|
||||
if (email.IsEmpty() || email.Length > 320)
|
||||
if (email.IsEmpty() || email.Length > MAX_BNET_EMAIL_STR)
|
||||
return AccountOpResult.NameTooLong;
|
||||
|
||||
if (password.IsEmpty() || password.Length > 16)
|
||||
if (password.IsEmpty() || password.Length > MAX_BNET_PASS_STR)
|
||||
return AccountOpResult.PassTooLong;
|
||||
|
||||
if (GetId(email) != 0)
|
||||
return AccountOpResult.NameAlreadyExist;
|
||||
|
||||
string srpUsername = GetSrpUsername(email);
|
||||
var (salt, verifier) = SRP6.MakeBNetRegistrationData<BnetSRP6v2Hash256>(srpUsername, password);
|
||||
|
||||
PreparedStatement stmt = LoginDatabase.GetPreparedStatement(LoginStatements.INS_BNET_ACCOUNT);
|
||||
stmt.AddValue(0, email);
|
||||
stmt.AddValue(1, CalculateShaPassHash(email.ToUpper(), password.ToUpper()));
|
||||
stmt.AddValue(1, (sbyte)SrpVersion.v2);
|
||||
stmt.AddValue(2, salt);
|
||||
stmt.AddValue(3, verifier);
|
||||
DB.Login.DirectExecute(stmt);
|
||||
|
||||
uint newAccountId = GetId(email);
|
||||
@@ -36,7 +45,8 @@ namespace Game
|
||||
if (withGameAccount)
|
||||
{
|
||||
gameAccountName = newAccountId + "#1";
|
||||
Global.AccountMgr.CreateAccount(gameAccountName, password, email, newAccountId, 1);
|
||||
string gameAccountPassword = password.Substring(0, 16);
|
||||
Global.AccountMgr.CreateAccount(gameAccountName, gameAccountPassword.ToUpper(), email, newAccountId, 1);
|
||||
}
|
||||
|
||||
return AccountOpResult.Ok;
|
||||
@@ -48,12 +58,17 @@ namespace Game
|
||||
if (!GetName(accountId, out username))
|
||||
return AccountOpResult.NameNotExist;
|
||||
|
||||
if (newPassword.Length > 16)
|
||||
if (newPassword.Length > MAX_BNET_PASS_STR)
|
||||
return AccountOpResult.PassTooLong;
|
||||
|
||||
PreparedStatement stmt = LoginDatabase.GetPreparedStatement(LoginStatements.UPD_BNET_PASSWORD);
|
||||
stmt.AddValue(0, CalculateShaPassHash(username, newPassword));
|
||||
stmt.AddValue(1, accountId);
|
||||
string srpUsername = GetSrpUsername(username);
|
||||
var (salt, verifier) = SRP6.MakeBNetRegistrationData<BnetSRP6v2Hash256>(srpUsername, newPassword);
|
||||
|
||||
PreparedStatement stmt = LoginDatabase.GetPreparedStatement(LoginStatements.UPD_BNET_LOGON);
|
||||
stmt.AddValue(0, (sbyte)SrpVersion.v2);
|
||||
stmt.AddValue(1, salt);
|
||||
stmt.AddValue(2, verifier);
|
||||
stmt.AddValue(3, accountId);
|
||||
DB.Login.Execute(stmt);
|
||||
|
||||
return AccountOpResult.Ok;
|
||||
@@ -67,9 +82,23 @@ namespace Game
|
||||
|
||||
PreparedStatement stmt = LoginDatabase.GetPreparedStatement(LoginStatements.SEL_BNET_CHECK_PASSWORD);
|
||||
stmt.AddValue(0, accountId);
|
||||
stmt.AddValue(1, CalculateShaPassHash(username, password));
|
||||
SQLResult result = DB.Login.Query(stmt);
|
||||
if (!result.IsEmpty())
|
||||
{
|
||||
var salt = result.Read<byte[]>(1);
|
||||
var verifier = result.Read<byte[]>(2);
|
||||
switch ((SrpVersion)result.Read<sbyte>(0))
|
||||
{
|
||||
case SrpVersion.v1:
|
||||
return new BnetSRP6v1Hash256(username, salt, verifier).CheckCredentials(username, password);
|
||||
case SrpVersion.v2:
|
||||
return new BnetSRP6v2Hash256(username, salt, verifier).CheckCredentials(username, password);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return !DB.Login.Query(stmt).IsEmpty();
|
||||
return false;
|
||||
}
|
||||
|
||||
public AccountOpResult LinkWithGameAccount(string email, string gameAccountName)
|
||||
@@ -165,11 +194,15 @@ namespace Game
|
||||
return 0;
|
||||
}
|
||||
|
||||
public string CalculateShaPassHash(string name, string password)
|
||||
public string GetSrpUsername(string name)
|
||||
{
|
||||
SHA256 sha256 = SHA256.Create();
|
||||
var i = sha256.ComputeHash(Encoding.UTF8.GetBytes(name));
|
||||
return sha256.ComputeHash(Encoding.UTF8.GetBytes(i.ToHexString() + ":" + password)).ToHexString(true);
|
||||
return SHA256.HashData(Encoding.UTF8.GetBytes(name)).ToHexString();
|
||||
}
|
||||
}
|
||||
|
||||
enum SrpVersion
|
||||
{
|
||||
v1 = 1, // password length limit 16 characters, case-insensitive, uses SHA256 to generate verifier
|
||||
v2 = 2 // password length limit 128 characters, case-sensitive, uses PBKDF2 with SHA512 to generate verifier
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user