diff options
author | Shauren <shauren.trinity@gmail.com> | 2014-06-08 16:14:24 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2014-06-08 16:14:24 +0200 |
commit | 7dd552c8261be9d1c9c8e45628e5aca5cdae405d (patch) | |
tree | 1b84d014b52f5fe638a9bde1494cbb2e88de0c91 /src/server/game | |
parent | e1e5f2a196240707f1671a02df6bd4966fed67f3 (diff) | |
parent | 9f69eda67f7fad50553f8d569851a5005437e677 (diff) |
Merge branch 'battle.net' into 4.3.4
Diffstat (limited to 'src/server/game')
-rw-r--r-- | src/server/game/Accounts/AccountMgr.cpp | 81 | ||||
-rw-r--r-- | src/server/game/Accounts/AccountMgr.h | 6 | ||||
-rw-r--r-- | src/server/game/Accounts/BattlenetAccountMgr.cpp | 144 | ||||
-rw-r--r-- | src/server/game/Accounts/BattlenetAccountMgr.h | 45 | ||||
-rw-r--r-- | src/server/game/Server/WorldSocket.cpp | 17 | ||||
-rw-r--r-- | src/server/game/Server/WorldSocket.h | 4 | ||||
-rw-r--r-- | src/server/game/Warden/WardenWin.cpp | 4 |
7 files changed, 244 insertions, 57 deletions
diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp index 773e169e5c2..59a8f046a6b 100644 --- a/src/server/game/Accounts/AccountMgr.cpp +++ b/src/server/game/Accounts/AccountMgr.cpp @@ -32,17 +32,17 @@ AccountMgr::~AccountMgr() ClearRBAC(); } -AccountOpResult AccountMgr::CreateAccount(std::string username, std::string password, std::string email = "") +AccountOpResult AccountMgr::CreateAccount(std::string username, std::string password, std::string email /*= ""*/) { if (utf8length(username) > MAX_ACCOUNT_STR) - return AOR_NAME_TOO_LONG; // username's too long + return AccountOpResult::AOR_NAME_TOO_LONG; // username's too long - normalizeString(username); - normalizeString(password); - normalizeString(email); + Utf8ToUpperOnlyLatin(username); + Utf8ToUpperOnlyLatin(password); + Utf8ToUpperOnlyLatin(email); if (GetId(username)) - return AOR_NAME_ALREADY_EXIST; // username does already exist + return AccountOpResult::AOR_NAME_ALREADY_EXIST; // username does already exist PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_ACCOUNT); @@ -56,7 +56,7 @@ AccountOpResult AccountMgr::CreateAccount(std::string username, std::string pass stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_REALM_CHARACTERS_INIT); LoginDatabase.Execute(stmt); - return AOR_OK; // everything's fine + return AccountOpResult::AOR_OK; // everything's fine } AccountOpResult AccountMgr::DeleteAccount(uint32 accountId) @@ -67,7 +67,7 @@ AccountOpResult AccountMgr::DeleteAccount(uint32 accountId) PreparedQueryResult result = LoginDatabase.Query(stmt); if (!result) - return AOR_NAME_NOT_EXIST; + return AccountOpResult::AOR_NAME_NOT_EXIST; // Obtain accounts characters stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARS_BY_ACCOUNT_ID); @@ -128,7 +128,7 @@ AccountOpResult AccountMgr::DeleteAccount(uint32 accountId) LoginDatabase.CommitTransaction(trans); - return AOR_OK; + return AccountOpResult::AOR_OK; } AccountOpResult AccountMgr::ChangeUsername(uint32 accountId, std::string newUsername, std::string newPassword) @@ -139,16 +139,16 @@ AccountOpResult AccountMgr::ChangeUsername(uint32 accountId, std::string newUser PreparedQueryResult result = LoginDatabase.Query(stmt); if (!result) - return AOR_NAME_NOT_EXIST; + return AccountOpResult::AOR_NAME_NOT_EXIST; if (utf8length(newUsername) > MAX_ACCOUNT_STR) - return AOR_NAME_TOO_LONG; + return AccountOpResult::AOR_NAME_TOO_LONG; if (utf8length(newPassword) > MAX_ACCOUNT_STR) - return AOR_PASS_TOO_LONG; + return AccountOpResult::AOR_PASS_TOO_LONG; - normalizeString(newUsername); - normalizeString(newPassword); + Utf8ToUpperOnlyLatin(newUsername); + Utf8ToUpperOnlyLatin(newPassword); stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_USERNAME); @@ -158,7 +158,7 @@ AccountOpResult AccountMgr::ChangeUsername(uint32 accountId, std::string newUser LoginDatabase.Execute(stmt); - return AOR_OK; + return AccountOpResult::AOR_OK; } AccountOpResult AccountMgr::ChangePassword(uint32 accountId, std::string newPassword) @@ -166,13 +166,13 @@ AccountOpResult AccountMgr::ChangePassword(uint32 accountId, std::string newPass std::string username; if (!GetName(accountId, username)) - return AOR_NAME_NOT_EXIST; // account doesn't exist + return AccountOpResult::AOR_NAME_NOT_EXIST; // account doesn't exist if (utf8length(newPassword) > MAX_ACCOUNT_STR) - return AOR_PASS_TOO_LONG; + return AccountOpResult::AOR_PASS_TOO_LONG; - normalizeString(username); - normalizeString(newPassword); + Utf8ToUpperOnlyLatin(username); + Utf8ToUpperOnlyLatin(newPassword); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_PASSWORD); @@ -189,7 +189,7 @@ AccountOpResult AccountMgr::ChangePassword(uint32 accountId, std::string newPass LoginDatabase.Execute(stmt); - return AOR_OK; + return AccountOpResult::AOR_OK; } AccountOpResult AccountMgr::ChangeEmail(uint32 accountId, std::string newEmail) @@ -197,13 +197,13 @@ AccountOpResult AccountMgr::ChangeEmail(uint32 accountId, std::string newEmail) std::string username; if (!GetName(accountId, username)) - return AOR_NAME_NOT_EXIST; // account doesn't exist + return AccountOpResult::AOR_NAME_NOT_EXIST; // account doesn't exist if (utf8length(newEmail) > MAX_EMAIL_STR) - return AOR_EMAIL_TOO_LONG; + return AccountOpResult::AOR_EMAIL_TOO_LONG; - normalizeString(username); - normalizeString(newEmail); + Utf8ToUpperOnlyLatin(username); + Utf8ToUpperOnlyLatin(newEmail); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_EMAIL); @@ -212,7 +212,7 @@ AccountOpResult AccountMgr::ChangeEmail(uint32 accountId, std::string newEmail) LoginDatabase.Execute(stmt); - return AOR_OK; + return AccountOpResult::AOR_OK; } AccountOpResult AccountMgr::ChangeRegEmail(uint32 accountId, std::string newEmail) @@ -220,13 +220,13 @@ AccountOpResult AccountMgr::ChangeRegEmail(uint32 accountId, std::string newEmai std::string username; if (!GetName(accountId, username)) - return AOR_NAME_NOT_EXIST; // account doesn't exist + return AccountOpResult::AOR_NAME_NOT_EXIST; // account doesn't exist if (utf8length(newEmail) > MAX_EMAIL_STR) - return AOR_EMAIL_TOO_LONG; + return AccountOpResult::AOR_EMAIL_TOO_LONG; - normalizeString(username); - normalizeString(newEmail); + Utf8ToUpperOnlyLatin(username); + Utf8ToUpperOnlyLatin(newEmail); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_REG_EMAIL); @@ -235,7 +235,7 @@ AccountOpResult AccountMgr::ChangeRegEmail(uint32 accountId, std::string newEmai LoginDatabase.Execute(stmt); - return AOR_OK; + return AccountOpResult::AOR_OK; } uint32 AccountMgr::GetId(std::string const& username) @@ -303,8 +303,8 @@ bool AccountMgr::CheckPassword(uint32 accountId, std::string password) if (!GetName(accountId, username)) return false; - normalizeString(username); - normalizeString(password); + Utf8ToUpperOnlyLatin(username); + Utf8ToUpperOnlyLatin(password); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_CHECK_PASSWORD); stmt->setUInt32(0, accountId); @@ -322,8 +322,8 @@ bool AccountMgr::CheckEmail(uint32 accountId, std::string newEmail) if (!GetEmail(accountId, oldEmail)) return false; - normalizeString(oldEmail); - normalizeString(newEmail); + Utf8ToUpperOnlyLatin(oldEmail); + Utf8ToUpperOnlyLatin(newEmail); if (strcmp(oldEmail.c_str(), newEmail.c_str()) == 0) return true; @@ -341,19 +341,6 @@ uint32 AccountMgr::GetCharactersCount(uint32 accountId) return (result) ? (*result)[0].GetUInt64() : 0; } -bool AccountMgr::normalizeString(std::string& utf8String) -{ - wchar_t buffer[MAX_ACCOUNT_STR+1]; - - size_t maxLength = MAX_ACCOUNT_STR; - if (!Utf8toWStr(utf8String, buffer, maxLength)) - return false; - - std::transform(&buffer[0], buffer+maxLength, &buffer[0], wcharToUpperOnlyLatin); - - return WStrToUtf8(buffer, maxLength, utf8String); -} - std::string AccountMgr::CalculateShaPassHash(std::string const& name, std::string const& password) { SHA1Hash sha; diff --git a/src/server/game/Accounts/AccountMgr.h b/src/server/game/Accounts/AccountMgr.h index b3012ace177..f39873f0ebf 100644 --- a/src/server/game/Accounts/AccountMgr.h +++ b/src/server/game/Accounts/AccountMgr.h @@ -22,7 +22,7 @@ #include "RBAC.h" #include <ace/Singleton.h> -enum AccountOpResult +enum class AccountOpResult : uint8 { AOR_OK, AOR_NAME_TOO_LONG, @@ -40,6 +40,7 @@ enum PasswordChangeSecurity PW_RBAC }; +#define MAX_PASS_STR 16 #define MAX_ACCOUNT_STR 16 #define MAX_EMAIL_STR 64 @@ -58,7 +59,7 @@ class AccountMgr ~AccountMgr(); public: - AccountOpResult CreateAccount(std::string username, std::string password, std::string email); + AccountOpResult CreateAccount(std::string username, std::string password, std::string email = ""); static AccountOpResult DeleteAccount(uint32 accountId); static AccountOpResult ChangeUsername(uint32 accountId, std::string newUsername, std::string newPassword); static AccountOpResult ChangePassword(uint32 accountId, std::string newPassword); @@ -75,7 +76,6 @@ class AccountMgr static uint32 GetCharactersCount(uint32 accountId); static std::string CalculateShaPassHash(std::string const& name, std::string const& password); - static bool normalizeString(std::string& utf8String); static bool IsPlayerAccount(uint32 gmlevel); static bool IsAdminAccount(uint32 gmlevel); static bool IsConsoleAccount(uint32 gmlevel); diff --git a/src/server/game/Accounts/BattlenetAccountMgr.cpp b/src/server/game/Accounts/BattlenetAccountMgr.cpp new file mode 100644 index 00000000000..8b73ba19a97 --- /dev/null +++ b/src/server/game/Accounts/BattlenetAccountMgr.cpp @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "AccountMgr.h" +#include "BattlenetAccountMgr.h" +#include "DatabaseEnv.h" +#include "Util.h" +#include "SHA256.h" + +AccountOpResult Battlenet::AccountMgr::CreateBattlenetAccount(std::string email, std::string password) +{ + if (utf8length(email) > 64) + return AccountOpResult::AOR_NAME_TOO_LONG; + + Utf8ToUpperOnlyLatin(email); + Utf8ToUpperOnlyLatin(password); + + if (GetId(email)) + return AccountOpResult::AOR_NAME_ALREADY_EXIST; + + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_BNET_ACCOUNT); + stmt->setString(0, email); + stmt->setString(1, CalculateShaPassHash(email, password)); + LoginDatabase.Execute(stmt); + + return AccountOpResult::AOR_OK; +} + +AccountOpResult Battlenet::AccountMgr::ChangeUsername(uint32 accountId, std::string newUsername, std::string newPassword) +{ + // Check if accounts exists + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ACCOUNT_EMAIL_BY_ID); + stmt->setUInt32(0, accountId); + PreparedQueryResult result = LoginDatabase.Query(stmt); + + if (!result) + return AccountOpResult::AOR_NAME_NOT_EXIST; + + Utf8ToUpperOnlyLatin(newUsername); + if (utf8length(newUsername) > MAX_ACCOUNT_STR) + return AccountOpResult::AOR_NAME_TOO_LONG; + + Utf8ToUpperOnlyLatin(newPassword); + if (utf8length(newPassword) > MAX_PASS_STR) + return AccountOpResult::AOR_PASS_TOO_LONG; + + stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_PASSWORD); + stmt->setString(0, newUsername); + stmt->setString(1, CalculateShaPassHash(newUsername, newPassword)); + stmt->setUInt32(2, accountId); + LoginDatabase.Execute(stmt); + + return AccountOpResult::AOR_OK; +} + +AccountOpResult Battlenet::AccountMgr::ChangePassword(uint32 accountId, std::string newPassword) +{ + std::string username; + if (!GetName(accountId, username)) + return AccountOpResult::AOR_NAME_NOT_EXIST; // account doesn't exist + + Utf8ToUpperOnlyLatin(username); + Utf8ToUpperOnlyLatin(newPassword); + if (utf8length(newPassword) > MAX_PASS_STR) + return AccountOpResult::AOR_PASS_TOO_LONG; + + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_BNET_PASSWORD); + stmt->setString(0, username); + stmt->setString(1, CalculateShaPassHash(username, newPassword)); + stmt->setUInt32(2, accountId); + LoginDatabase.Execute(stmt); + + return AccountOpResult::AOR_OK; +} + +uint32 Battlenet::AccountMgr::GetId(std::string const& username) +{ + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ACCOUNT_ID_BY_EMAIL); + stmt->setString(0, username); + if (PreparedQueryResult result = LoginDatabase.Query(stmt)) + return (*result)[0].GetUInt32(); + + return 0; +} + +bool Battlenet::AccountMgr::GetName(uint32 accountId, std::string& name) +{ + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ACCOUNT_EMAIL_BY_ID); + stmt->setUInt32(0, accountId); + if (PreparedQueryResult result = LoginDatabase.Query(stmt)) + { + name = (*result)[0].GetString(); + return true; + } + + return false; +} + +bool Battlenet::AccountMgr::CheckPassword(uint32 accountId, std::string password) +{ + std::string username; + + if (!GetName(accountId, username)) + return false; + + Utf8ToUpperOnlyLatin(username); + Utf8ToUpperOnlyLatin(password); + + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_CHECK_PASSWORD); + stmt->setUInt32(0, accountId); + stmt->setString(1, CalculateShaPassHash(username, password)); + PreparedQueryResult result = LoginDatabase.Query(stmt); + + return !result.null(); +} + +std::string Battlenet::AccountMgr::CalculateShaPassHash(std::string const& name, std::string const& password) +{ + SHA256Hash email; + email.UpdateData(name); + email.Finalize(); + + SHA256Hash sha; + sha.UpdateData(ByteArrayToHexStr(email.GetDigest(), email.GetLength())); + sha.UpdateData(":"); + sha.UpdateData(password); + sha.Finalize(); + + return ByteArrayToHexStr(sha.GetDigest(), sha.GetLength(), true); +} diff --git a/src/server/game/Accounts/BattlenetAccountMgr.h b/src/server/game/Accounts/BattlenetAccountMgr.h new file mode 100644 index 00000000000..07191d24313 --- /dev/null +++ b/src/server/game/Accounts/BattlenetAccountMgr.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef BattlenetAccountMgr_h__ +#define BattlenetAccountMgr_h__ + +#include "Define.h" +#include <string> +#include <ace/Singleton.h> + +enum class AccountOpResult : uint8; + +#define MAX_BNET_EMAIL_STR 320 + +namespace Battlenet +{ + namespace AccountMgr + { + AccountOpResult CreateBattlenetAccount(std::string email, std::string password); + AccountOpResult ChangeUsername(uint32 accountId, std::string newUsername, std::string newPassword); + AccountOpResult ChangePassword(uint32 accountId, std::string newPassword); + bool CheckPassword(uint32 accountId, std::string password); + + uint32 GetId(std::string const& username); + bool GetName(uint32 accountId, std::string& name); + + std::string CalculateShaPassHash(std::string const& name, std::string const& password); + } +} + +#endif // BattlenetAccountMgr_h__ diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index 737a2f8cbf1..1a93e7ae1d5 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -856,9 +856,20 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket) // Get the account information from the realmd database // 0 1 2 3 4 5 6 7 8 // SELECT id, sessionkey, last_ip, locked, expansion, mutetime, locale, recruiter, os FROM account WHERE username = ? - PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME); - - stmt->setString(0, account); + size_t hashPos = account.find_last_of('#'); + PreparedStatement* stmt; + if (hashPos != std::string::npos) + { + Tokenizer tokens(account, '#', 2); + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_INFO_BY_BNET); + stmt->setUInt32(0, atol(tokens[0])); + stmt->setUInt8(1, atol(tokens[1])); + } + else + { + stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME); + stmt->setString(0, account); + } PreparedQueryResult result = LoginDatabase.Query(stmt); diff --git a/src/server/game/Server/WorldSocket.h b/src/server/game/Server/WorldSocket.h index 4ccacd05c7e..306a50c083a 100644 --- a/src/server/game/Server/WorldSocket.h +++ b/src/server/game/Server/WorldSocket.h @@ -39,7 +39,7 @@ #endif /* ACE_LACKS_PRAGMA_ONCE */ #include "Common.h" -#include "AuthCrypt.h" +#include "WorldPacketCrypt.h" class ACE_Message_Block; class WorldPacket; @@ -176,7 +176,7 @@ class WorldSocket : public WorldHandler std::string m_Address; /// Class used for managing encryption of the headers - AuthCrypt m_Crypt; + WorldPacketCrypt m_Crypt; /// Mutex lock to protect m_Session LockType m_SessionLock; diff --git a/src/server/game/Warden/WardenWin.cpp b/src/server/game/Warden/WardenWin.cpp index 18bf2897358..3428708ed69 100644 --- a/src/server/game/Warden/WardenWin.cpp +++ b/src/server/game/Warden/WardenWin.cpp @@ -16,7 +16,7 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Cryptography/HMACSHA1.h" +#include "Cryptography/HmacHash.h" #include "Cryptography/WardenKeyGeneration.h" #include "Common.h" #include "WorldPacket.h" @@ -283,7 +283,7 @@ void WardenWin::RequestData() { uint32 seed = static_cast<uint32>(rand32()); buff << uint32(seed); - HmacHash hmac(4, (uint8*)&seed); + HmacSha1 hmac(4, (uint8*)&seed); hmac.UpdateData(wd->Str); hmac.Finalize(); buff.append(hmac.GetDigest(), hmac.GetLength()); |