summaryrefslogtreecommitdiff
path: root/src/server/authserver/Server/AuthSocket.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/authserver/Server/AuthSocket.cpp')
-rw-r--r--src/server/authserver/Server/AuthSocket.cpp178
1 files changed, 83 insertions, 95 deletions
diff --git a/src/server/authserver/Server/AuthSocket.cpp b/src/server/authserver/Server/AuthSocket.cpp
index 3a17dd7c21..c8c6eb0d7c 100644
--- a/src/server/authserver/Server/AuthSocket.cpp
+++ b/src/server/authserver/Server/AuthSocket.cpp
@@ -165,6 +165,8 @@ private:
Patches _patches;
};
+std::array<uint8, 16> VersionChallenge = { { 0xBA, 0xA3, 0x1E, 0x99, 0xA0, 0x0B, 0x21, 0x57, 0xFC, 0x37, 0x3F, 0xB3, 0x69, 0xCD, 0xD2, 0xF1 } };
+
const AuthHandler table[] =
{
{ AUTH_LOGON_CHALLENGE, STATUS_CHALLENGE, &AuthSocket::_HandleLogonChallenge },
@@ -366,6 +368,10 @@ bool AuthSocket::_HandleLogonChallenge()
// Restore string order as its byte order is reversed
std::reverse(_os.begin(), _os.end());
+ _localizationName.resize(4);
+ for (int i = 0; i < 4; ++i)
+ _localizationName[i] = ch->country[4 - i - 1];
+
ByteBuffer pkt;
pkt << uint8(AUTH_LOGON_CHALLENGE);
pkt << uint8(0x00);
@@ -487,9 +493,6 @@ bool AuthSocket::_HandleLogonChallenge()
fields[10].GetBinary<acore::Crypto::SRP6::SALT_LENGTH>(),
fields[11].GetBinary<acore::Crypto::SRP6::VERIFIER_LENGTH>());
- BigNumber unk3;
- unk3.SetRand(16 * 8);
-
// Fill the response packet with the result
if (!AuthHelper::IsAcceptedClientBuild(_build))
{
@@ -507,8 +510,7 @@ bool AuthSocket::_HandleLogonChallenge()
pkt << uint8(32);
pkt.append(_srp6->N);
pkt.append(_srp6->s);
- pkt.append(unk3.ToByteArray<16>());
-
+ pkt.append(VersionChallenge.data(), VersionChallenge.size());
pkt << uint8(securityFlags); // security flags (0x0...0x04)
if (securityFlags & 0x01) // PIN input
@@ -529,11 +531,7 @@ bool AuthSocket::_HandleLogonChallenge()
if (securityFlags & 0x04) // Security token input
pkt << uint8(1);
- _localizationName.resize(4);
- for (int i = 0; i < 4; ++i)
- _localizationName[i] = ch->country[4 - i - 1];
-
- LOG_DEBUG("network", "'%s:%d' [AuthChallenge] account %s is using locale (%u)",
+ LOG_DEBUG("server.authserver", "'%s:%d' [AuthChallenge] account %s is using locale (%u)",
ipAddress.c_str(), port, _accountInfo.Login.c_str(), GetLocaleByName(_localizationName));
///- All good, await client's proof
@@ -546,9 +544,8 @@ bool AuthSocket::_HandleLogonChallenge()
// Logon Proof command handler
bool AuthSocket::_HandleLogonProof()
{
-#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
- LOG_DEBUG("network", "Entering _HandleLogonProof");
-#endif
+ LOG_TRACE("server.authserver", "Entering _HandleLogonProof");
+
// Read the packet
sAuthLogonProof_C lp;
@@ -571,20 +568,6 @@ bool AuthSocket::_HandleLogonProof()
if (std::optional<SessionKey> K = _srp6->VerifyChallengeResponse(lp.A, lp.clientM))
{
_sessionKey = *K;
- LOG_DEBUG("network", "'%s:%d' User '%s' successfully authenticated", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _accountInfo.Login.c_str());
-
- // Update the sessionkey, last_ip, last login time and reset number of failed logins in the account table for this account
- // No SQL injection (escaped user name) and IP address as received by socket
- PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_LOGONPROOF);
- stmt->setBinary(0, _sessionKey);
- stmt->setString(1, socket().getRemoteAddress().c_str());
- stmt->setUInt32(2, GetLocaleByName(_localizationName));
- stmt->setString(3, _os);
- stmt->setString(4, _accountInfo.Login);
- LoginDatabase.DirectExecute(stmt);
-
- // Finish SRP6 and send the final result to the client
- acore::Crypto::SHA1::Digest M2 = acore::Crypto::SRP6::GetSessionVerifier(lp.A, lp.clientM, _sessionKey);
// Check auth token
bool tokenSuccess = false;
@@ -613,6 +596,21 @@ bool AuthSocket::_HandleLogonProof()
socket().send(data, sizeof(data));
}
+ LOG_DEBUG("network", "'%s:%d' User '%s' successfully authenticated", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _accountInfo.Login.c_str());
+
+ // Update the sessionkey, last_ip, last login time and reset number of failed logins in the account table for this account
+ // No SQL injection (escaped user name) and IP address as received by socket
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_LOGONPROOF);
+ stmt->setBinary(0, _sessionKey);
+ stmt->setString(1, socket().getRemoteAddress().c_str());
+ stmt->setUInt32(2, GetLocaleByName(_localizationName));
+ stmt->setString(3, _os);
+ stmt->setString(4, _accountInfo.Login);
+ LoginDatabase.DirectExecute(stmt);
+
+ // Finish SRP6 and send the final result to the client
+ acore::Crypto::SHA1::Digest M2 = acore::Crypto::SRP6::GetSessionVerifier(lp.A, lp.clientM, _sessionKey);
+
if (_expversion & POST_BC_EXP_FLAG) // 2.x and 3.x clients
{
sAuthLogonProof_S proof;
@@ -621,7 +619,7 @@ bool AuthSocket::_HandleLogonProof()
proof.error = 0;
proof.unk1 = 0x00800000; // Accountflags. 0x01 = GM, 0x08 = Trial, 0x00800000 = Pro pass (arena tournament)
proof.unk2 = 0x00; // SurveyId
- proof.unk3 = 0x00;
+ proof.unk3 = 0x00; // 0x1 = has account message
socket().send((char*)&proof, sizeof(proof));
}
else
@@ -642,9 +640,8 @@ bool AuthSocket::_HandleLogonProof()
char data[4] = { AUTH_LOGON_PROOF, WOW_FAIL_UNKNOWN_ACCOUNT, 3, 0 };
socket().send(data, sizeof(data));
-#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
- LOG_DEBUG("network", "'%s:%d' [AuthChallenge] account %s tried to login with invalid password!", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _accountInfo.Login.c_str());
-#endif
+ LOG_INFO("server.authserver.hack", "'%s:%d' [AuthChallenge] account %s tried to login with invalid password!",
+ socket().getRemoteAddress().c_str(), socket().getRemotePort(), _accountInfo.Login.c_str());
uint32 MaxWrongPassCount = sConfigMgr->GetOption<int32>("WrongPass.MaxCount", 0);
@@ -666,42 +663,30 @@ bool AuthSocket::_HandleLogonProof()
stmt->setString(0, _accountInfo.Login);
LoginDatabase.Execute(stmt);
- stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_FAILEDLOGINS);
- stmt->setString(0, _accountInfo.Login);
-
- if (PreparedQueryResult loginfail = LoginDatabase.Query(stmt))
+ if (++_accountInfo.FailedLogins >= MaxWrongPassCount)
{
- uint32 failed_logins = (*loginfail)[1].GetUInt32();
+ uint32 WrongPassBanTime = sConfigMgr->GetOption<int32>("WrongPass.BanTime", 600);
+ bool WrongPassBanType = sConfigMgr->GetOption<bool>("WrongPass.BanType", false);
- if (failed_logins >= MaxWrongPassCount)
+ if (WrongPassBanType)
{
- uint32 WrongPassBanTime = sConfigMgr->GetOption<int32>("WrongPass.BanTime", 600);
- bool WrongPassBanType = sConfigMgr->GetOption<bool>("WrongPass.BanType", false);
-
- if (WrongPassBanType)
- {
- uint32 acc_id = (*loginfail)[0].GetUInt32();
- stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_ACCOUNT_AUTO_BANNED);
- stmt->setUInt32(0, acc_id);
- stmt->setUInt32(1, WrongPassBanTime);
- LoginDatabase.Execute(stmt);
+ stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_ACCOUNT_AUTO_BANNED);
+ stmt->setUInt32(0, _accountInfo.Id);
+ stmt->setUInt32(1, WrongPassBanTime);
+ LoginDatabase.Execute(stmt);
-#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
- LOG_DEBUG("network", "'%s:%d' [AuthChallenge] account %s got banned for '%u' seconds because it failed to authenticate '%u' times", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _accountInfo.Login.c_str(), WrongPassBanTime, failed_logins);
-#endif
- }
- else
- {
- stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_IP_AUTO_BANNED);
- stmt->setString(0, socket().getRemoteAddress());
- stmt->setUInt32(1, WrongPassBanTime);
- LoginDatabase.Execute(stmt);
+ LOG_DEBUG("network", "'%s:%d' [AuthChallenge] account %s got banned for '%u' seconds because it failed to authenticate '%u' times",
+ socket().getRemoteAddress().c_str(), socket().getRemotePort(), _accountInfo.Login.c_str(), WrongPassBanTime, _accountInfo.FailedLogins);
+ }
+ else
+ {
+ stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_IP_AUTO_BANNED);
+ stmt->setString(0, socket().getRemoteAddress());
+ stmt->setUInt32(1, WrongPassBanTime);
+ LoginDatabase.Execute(stmt);
-#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
- LOG_DEBUG("network", "'%s:%d' [AuthChallenge] IP %s got banned for '%u' seconds because account %s failed to authenticate '%u' times",
- socket().getRemoteAddress().c_str(), socket().getRemotePort(), socket().getRemoteAddress().c_str(), WrongPassBanTime, _accountInfo.Login.c_str(), failed_logins);
-#endif
- }
+ LOG_DEBUG("network", "'%s:%d' [AuthChallenge] IP %s got banned for '%u' seconds because account %s failed to authenticate '%u' times",
+ socket().getRemoteAddress().c_str(), socket().getRemotePort(), socket().getRemoteAddress().c_str(), WrongPassBanTime, _accountInfo.Login.c_str(), _accountInfo.FailedLogins);
}
}
}
@@ -713,9 +698,8 @@ bool AuthSocket::_HandleLogonProof()
// Reconnect Challenge command handler
bool AuthSocket::_HandleReconnectChallenge()
{
-#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
- LOG_DEBUG("network", "Entering _HandleReconnectChallenge");
-#endif
+ LOG_TRACE("network", "Entering _HandleReconnectChallenge");
+
if (socket().recv_len() < sizeof(sAuthLogonChallenge_C))
return false;
@@ -751,6 +735,15 @@ bool AuthSocket::_HandleReconnectChallenge()
#endif
std::string login((char const*)ch->I, ch->I_len);
+ LOG_DEBUG("server.authserver", "[ReconnectChallenge] '%s'", login.c_str());
+
+ // Reinitialize build, expansion and the account securitylevel
+ _build = ch->build;
+ _expversion = uint8(AuthHelper::IsPostBCAcceptedClientBuild(_build) ? POST_BC_EXP_FLAG : (AuthHelper::IsPreBCAcceptedClientBuild(_build) ? PRE_BC_EXP_FLAG : NO_VALID_EXP_FLAG));
+ _os = (const char*)ch->os;
+
+ if (_os.size() > 4)
+ return false;
auto* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_RECONNECTCHALLENGE);
stmt->setString(0, login);
@@ -768,14 +761,6 @@ bool AuthSocket::_HandleReconnectChallenge()
Field* fields = result->Fetch();
_accountInfo.LoadResult(fields);
- // Reinitialize build, expansion and the account securitylevel
- _build = ch->build;
- _expversion = uint8(AuthHelper::IsPostBCAcceptedClientBuild(_build) ? POST_BC_EXP_FLAG : (AuthHelper::IsPreBCAcceptedClientBuild(_build) ? PRE_BC_EXP_FLAG : NO_VALID_EXP_FLAG));
- _os = (const char*)ch->os;
-
- if (_os.size() > 4)
- return false;
-
// Restore string order as its byte order is reversed
std::reverse(_os.begin(), _os.end());
@@ -788,9 +773,9 @@ bool AuthSocket::_HandleReconnectChallenge()
// Sending response
ByteBuffer pkt;
pkt << uint8(AUTH_RECONNECT_CHALLENGE);
- pkt << uint8(0x00);
+ pkt << uint8(WOW_SUCCESS);
pkt.append(_reconnectProof); // 16 bytes random
- pkt << uint64(0x00) << uint64(0x00); // 16 bytes zeros
+ pkt.append(VersionChallenge.data(), VersionChallenge.size());
socket().send((char const*)pkt.contents(), pkt.size());
return true;
}
@@ -837,7 +822,8 @@ bool AuthSocket::_HandleReconnectProof()
}
else
{
- LOG_ERROR("server", "'%s:%d' [ERROR] user %s tried to login, but session is invalid.", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _accountInfo.Login.c_str());
+ LOG_ERROR("server.authserver.hack", "'%s:%d' [ERROR] user %s tried to login, but session is invalid.",
+ socket().getRemoteAddress().c_str(), socket().getRemotePort(), _accountInfo.Login.c_str());
socket().shutdown();
return false;
}
@@ -849,20 +835,22 @@ ACE_INET_Addr const& AuthSocket::GetAddressForClient(Realm const& realm, ACE_INE
if (clientAddr.is_loopback())
{
// Try guessing if realm is also connected locally
- if (realm.LocalAddress.is_loopback() || realm.ExternalAddress.is_loopback())
+ if (realm.LocalAddress->is_loopback() || realm.ExternalAddress->is_loopback())
return clientAddr;
// Assume that user connecting from the machine that authserver is located on
// has all realms available in his local network
- return realm.LocalAddress;
+ return *realm.LocalAddress;
}
// Check if connecting client is in the same network
- if (IsIPAddrInNetwork(realm.LocalAddress, clientAddr, realm.LocalSubnetMask))
- return realm.LocalAddress;
+ if (IsIPAddrInNetwork(*realm.LocalAddress, clientAddr, *realm.LocalSubnetMask))
+ {
+ return *realm.LocalAddress;
+ }
// Return external IP
- return realm.ExternalAddress;
+ return *realm.ExternalAddress;
}
// Realm List command handler
@@ -900,17 +888,17 @@ bool AuthSocket::_HandleRealmList()
// Circle through realms in the RealmList and construct the return packet (including # of user characters in each realm)
ByteBuffer pkt;
-
size_t RealmListSize = 0;
- for (RealmList::RealmMap::const_iterator i = sRealmList->begin(); i != sRealmList->end(); ++i)
+
+ for (auto& [realmHandle, realm] : sRealmList->GetRealms())
{
- const Realm& realm = i->second;
// don't work with realms which not compatible with the client
- bool okBuild = ((_expversion & POST_BC_EXP_FLAG) && realm.gamebuild == _build) || ((_expversion & PRE_BC_EXP_FLAG) && !AuthHelper::IsPreBCAcceptedClientBuild(realm.gamebuild));
+ bool okBuild = ((_expversion & POST_BC_EXP_FLAG) && realm.Build == _build) || ((_expversion & PRE_BC_EXP_FLAG) && !AuthHelper::IsPreBCAcceptedClientBuild(realm.Build));
// No SQL injection. id of realm is controlled by the database.
- uint32 flag = realm.flag;
- RealmBuildInfo const* buildInfo = AuthHelper::GetBuildInfo(realm.gamebuild);
+ uint32 flag = realm.Flags;
+
+ RealmBuildInfo const* buildInfo = sRealmList->GetBuildInfo(realm.Build);
if (!okBuild)
{
if (!buildInfo)
@@ -922,7 +910,7 @@ bool AuthSocket::_HandleRealmList()
if (!buildInfo)
flag &= ~REALM_FLAG_SPECIFYBUILD;
- std::string name = i->first;
+ std::string name = realm.Name;
if (_expversion & PRE_BC_EXP_FLAG && flag & REALM_FLAG_SPECIFYBUILD)
{
std::ostringstream ss;
@@ -931,29 +919,29 @@ bool AuthSocket::_HandleRealmList()
}
// We don't need the port number from which client connects with but the realm's port
- clientAddr.set_port_number(realm.ExternalAddress.get_port_number());
+ clientAddr.set_port_number(realm.ExternalAddress->get_port_number());
- uint8 lock = (realm.allowedSecurityLevel > _accountInfo.SecurityLevel) ? 1 : 0;
+ uint8 lock = (realm.AllowedSecurityLevel > _accountInfo.SecurityLevel) ? 1 : 0;
uint8 AmountOfCharacters = 0;
stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_NUM_CHARS_ON_REALM);
- stmt->setUInt32(0, realm.m_ID);
+ stmt->setUInt32(0, realm.Id.Realm);
stmt->setUInt32(1, id);
result = LoginDatabase.Query(stmt);
if (result)
AmountOfCharacters = (*result)[0].GetUInt8();
- pkt << realm.icon; // realm type
+ pkt << realm.Type; // realm type
if (_expversion & POST_BC_EXP_FLAG) // only 2.x and 3.x clients
pkt << lock; // if 1, then realm locked
pkt << uint8(flag); // RealmFlags
pkt << name;
pkt << GetAddressString(GetAddressForClient(realm, clientAddr));
- pkt << realm.populationLevel;
+ pkt << realm.PopulationLevel;
pkt << AmountOfCharacters;
- pkt << realm.timezone; // realm category
+ pkt << realm.Timezone; // realm category
if (_expversion & POST_BC_EXP_FLAG) // 2.x and 3.x clients
- pkt << uint8(realm.m_ID);
+ pkt << uint8(realm.Id.Realm);
else
pkt << uint8(0x0); // 1.12.1 and 1.12.2 clients