Last active
December 15, 2015 02:59
-
-
Save Bezo/5190738 to your computer and use it in GitHub Desktop.
account lock.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/sql/updates/2013_03_xx_xx_auth_misc.sql b/sql/updates/2013_03_xx_xx_auth_misc.sql | |
new file mode 100644 | |
index 0000000..31c50e7 | |
--- /dev/null | |
+++ b/sql/updates/2013_03_xx_xx_auth_misc.sql | |
@@ -0,0 +1,43 @@ | |
+ALTER TABLE `account` | |
+ DROP COLUMN `lock_country`; | |
+ | |
+ALTER TABLE `account` | |
+ ADD COLUMN `lock_country` CHAR(2) NOT NULL DEFAULT '' AFTER `locked`; | |
+ | |
+-- add ip2nation to auth/releam db | |
+-- Table structure for table `ip2nation` | |
+DROP TABLE IF EXISTS `ip2nation`; | |
+/*!40101 SET @saved_cs_client = @@character_set_client */; | |
+/*!40101 SET character_set_client = utf8 */; | |
+CREATE TABLE `ip2nation` ( | |
+ `ip` int(10) unsigned NOT NULL DEFAULT '0', | |
+ `country` char(2) NOT NULL DEFAULT '', | |
+ KEY `ip` (`ip`) | |
+) ENGINE=InnoDB DEFAULT CHARSET=utf8; | |
+/*!40101 SET character_set_client = @saved_cs_client */; | |
+-- Dumping data for table `ip2nation` | |
+LOCK TABLES `ip2nation` WRITE; | |
+/*!40000 ALTER TABLE `ip2nation` DISABLE KEYS */; | |
+/*!40000 ALTER TABLE `ip2nation` ENABLE KEYS */; | |
+UNLOCK TABLES; | |
+-- Table structure for table `ip2nationCountries` | |
+DROP TABLE IF EXISTS `ip2nationCountries`; | |
+/*!40101 SET @saved_cs_client = @@character_set_client */; | |
+/*!40101 SET character_set_client = utf8 */; | |
+CREATE TABLE `ip2nationCountries` ( | |
+ `code` varchar(4) NOT NULL DEFAULT '', | |
+ `iso_code_2` varchar(2) NOT NULL DEFAULT '', | |
+ `iso_code_3` varchar(3) DEFAULT '', | |
+ `iso_country` varchar(255) NOT NULL DEFAULT '', | |
+ `country` varchar(255) NOT NULL DEFAULT '', | |
+ `lat` float NOT NULL DEFAULT '0', | |
+ `lon` float NOT NULL DEFAULT '0', | |
+ PRIMARY KEY (`code`), | |
+ KEY `code` (`code`) | |
+) ENGINE=InnoDB DEFAULT CHARSET=utf8; | |
+/*!40101 SET character_set_client = @saved_cs_client */; | |
+-- Dumping data for table `ip2nationCountries` | |
+LOCK TABLES `ip2nationCountries` WRITE; | |
+/*!40000 ALTER TABLE `ip2nationCountries` DISABLE KEYS */; | |
+/*!40000 ALTER TABLE `ip2nationCountries` ENABLE KEYS */; | |
+UNLOCK TABLES; | |
diff --git a/sql/updates/2013_03_xx_xx_world_command.sql b/sql/updates/2013_03_xx_xx_world_command.sql | |
new file mode 100644 | |
index 0000000..c76736c | |
--- /dev/null | |
+++ b/sql/updates/2013_03_xx_xx_world_command.sql | |
@@ -0,0 +1,4 @@ | |
+DELETE FROM `command` WHERE `name` in ('account lock', 'account lock ip', 'account lock country'); | |
+INSERT INTO `command` (`name`,`security`,`help`) VALUES | |
+('account lock ip', 0, 'Syntax: .account lock ip [on|off]\nAllow login from account only from current used IP or remove this requirement.'), | |
+('account lock country', 0, 'Syntax: .account lock country [on|off]\nAllow login from account only from current used Country or remove this requirement.'); | |
diff --git a/src/server/authserver/Server/AuthSocket.cpp b/src/server/authserver/Server/AuthSocket.cpp | |
index 32ddf02..4076ae3 100644 | |
--- a/src/server/authserver/Server/AuthSocket.cpp | |
+++ b/src/server/authserver/Server/AuthSocket.cpp | |
@@ -386,7 +386,7 @@ bool AuthSocket::_HandleLogonChallenge() | |
sLog->outDebug(LOG_FILTER_AUTHSERVER, "[AuthChallenge] Account '%s' is locked to IP - '%s'", _login.c_str(), fields[3].GetCString()); | |
sLog->outDebug(LOG_FILTER_AUTHSERVER, "[AuthChallenge] Player address is '%s'", ip_address.c_str()); | |
- if (strcmp(fields[3].GetCString(), ip_address.c_str())) | |
+ if (strcmp(fields[4].GetCString(), ip_address.c_str())) | |
{ | |
sLog->outDebug(LOG_FILTER_AUTHSERVER, "[AuthChallenge] Account IP differs"); | |
pkt << (uint8) WOW_FAIL_SUSPENDED; | |
@@ -396,7 +396,54 @@ bool AuthSocket::_HandleLogonChallenge() | |
sLog->outDebug(LOG_FILTER_AUTHSERVER, "[AuthChallenge] Account IP matches"); | |
} | |
else | |
+ { | |
sLog->outDebug(LOG_FILTER_AUTHSERVER, "[AuthChallenge] Account '%s' is not locked to ip", _login.c_str()); | |
+ std::string contry = fields[3].GetString(); | |
+ if (contry == "00") | |
+ sLog->outDebug(LOG_FILTER_AUTHSERVER, "[AuthChallenge] Account '%s' is not locked to country", _login.c_str()); | |
+ else if (!contry.empty()) | |
+ { | |
+ stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_LOGON_COUNTRY); | |
+ uint32 ip = inet_addr(ip_address.c_str()); | |
+ EndianConvertReverse(ip); | |
+ stmt->setUInt32(0, ip); | |
+ PreparedQueryResult placontres = LoginDatabase.Query(stmt); | |
+ if (placontres) | |
+ { | |
+ std::string contry2 = (*placontres)[0].GetString(); | |
+ sLog->outDebug(LOG_FILTER_AUTHSERVER, "[AuthChallenge] Account '%s' is locked to country: '%s' Player country is '%s'", _login.c_str(), contry.c_str(), contry2.c_str()); | |
+ if (contry2 != contry) | |
+ { | |
+ sLog->outDebug(LOG_FILTER_AUTHSERVER, "[AuthChallenge] Account country diff."); | |
+ pkt << (uint8) WOW_FAIL_UNLOCKABLE_LOCK; | |
+ locked = true; | |
+ } | |
+ else | |
+ sLog->outDebug(LOG_FILTER_AUTHSERVER, "[AuthChallenge] Account country matches"); | |
+ } | |
+ else | |
+ sLog->outDebug(LOG_FILTER_AUTHSERVER, "[AuthChallenge]IP2NATION Table empty"); | |
+ } | |
+ else // if null then insert country as default lock. | |
+ { | |
+ stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_LOGON_COUNTRY); | |
+ uint32 ip = inet_addr(ip_address.c_str()); | |
+ EndianConvertReverse(ip); | |
+ stmt->setUInt32(0, ip); | |
+ PreparedQueryResult placontres = LoginDatabase.Query(stmt); | |
+ if (placontres) | |
+ { | |
+ std::string contry2 = (*placontres)[0].GetString(); | |
+ stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_ACCOUNT_LOCK_CONTRY); | |
+ stmt->setString(0, contry2); | |
+ stmt->setUInt32(1, fields[1].GetUInt32()); | |
+ LoginDatabase.Execute(stmt); | |
+ sLog->outDebug(LOG_FILTER_AUTHSERVER, "[AuthChallenge] Country: '%s' set for account: '%s'", contry2.c_str(), _login.c_str()); | |
+ } | |
+ else | |
+ sLog->outDebug(LOG_FILTER_AUTHSERVER, "[AuthChallenge]IP2NATION Table empty"); | |
+ } | |
+ } | |
if (!locked) | |
{ | |
@@ -426,8 +473,8 @@ bool AuthSocket::_HandleLogonChallenge() | |
std::string rI = fields[0].GetString(); | |
// Don't calculate (v, s) if there are already some in the database | |
- std::string databaseV = fields[5].GetString(); | |
- std::string databaseS = fields[6].GetString(); | |
+ std::string databaseV = fields[6].GetString(); | |
+ std::string databaseS = fields[7].GetString(); | |
sLog->outDebug(LOG_FILTER_NETWORKIO, "database authentication values: v='%s' s='%s'", databaseV.c_str(), databaseS.c_str()); | |
@@ -484,7 +531,7 @@ bool AuthSocket::_HandleLogonChallenge() | |
if (securityFlags & 0x04) // Security token input | |
pkt << uint8(1); | |
- uint8 secLevel = fields[4].GetUInt8(); | |
+ uint8 secLevel = fields[5].GetUInt8(); | |
_accountSecurityLevel = secLevel <= SEC_ADMINISTRATOR ? AccountTypes(secLevel) : SEC_ADMINISTRATOR; | |
_localizationName.resize(4); | |
diff --git a/src/server/scripts/Commands/cs_account.cpp b/src/server/scripts/Commands/cs_account.cpp | |
index 3953bea..cf2816c 100644 | |
--- a/src/server/scripts/Commands/cs_account.cpp | |
+++ b/src/server/scripts/Commands/cs_account.cpp | |
@@ -42,13 +42,19 @@ class account_commandscript : public CommandScript | |
{ "password", SEC_CONSOLE, true, &HandleAccountSetPasswordCommand, "", NULL }, | |
{ NULL, SEC_PLAYER, false, NULL, "", NULL } | |
}; | |
+ static ChatCommand accountLockCommandTable[] = | |
+ { | |
+ { "country", SEC_PLAYER, true, &HandleAccountLockCountryCommand, "", NULL }, | |
+ { "ip", SEC_PLAYER, true, &HandleAccountLockIpCommand, "", NULL }, | |
+ { NULL, SEC_PLAYER, false, NULL, "", NULL }, | |
+ }; | |
static ChatCommand accountCommandTable[] = | |
{ | |
{ "addon", SEC_MODERATOR, false, &HandleAccountAddonCommand, "", NULL }, | |
{ "create", SEC_CONSOLE, true, &HandleAccountCreateCommand, "", NULL }, | |
{ "delete", SEC_CONSOLE, true, &HandleAccountDeleteCommand, "", NULL }, | |
{ "onlinelist", SEC_CONSOLE, true, &HandleAccountOnlineListCommand, "", NULL }, | |
- { "lock", SEC_PLAYER, false, &HandleAccountLockCommand, "", NULL }, | |
+ { "lock", SEC_PLAYER, false, NULL, "", accountLockCommandTable }, | |
{ "set", SEC_ADMINISTRATOR, true, NULL, "", accountSetCommandTable }, | |
{ "password", SEC_PLAYER, false, &HandleAccountPasswordCommand, "", NULL }, | |
{ "", SEC_PLAYER, false, &HandleAccountCommand, "", NULL }, | |
@@ -245,7 +251,57 @@ class account_commandscript : public CommandScript | |
return true; | |
} | |
- static bool HandleAccountLockCommand(ChatHandler* handler, char const* args) | |
+ static bool HandleAccountLockCountryCommand(ChatHandler* handler, char const* args) | |
+ { | |
+ if (!*args) | |
+ { | |
+ handler->SendSysMessage(LANG_USE_BOL); | |
+ handler->SetSentErrorMessage(true); | |
+ return false; | |
+ } | |
+ std::string param = (char*)args; | |
+ | |
+ if (!param.empty()) | |
+ { | |
+ if (param == "on") | |
+ { | |
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_LOGON_COUNTRY); | |
+ uint32 ip = inet_addr(handler->GetSession()->GetRemoteAddress().c_str()); | |
+ EndianConvertReverse(ip); | |
+ stmt->setUInt32(0, ip); | |
+ PreparedQueryResult result = LoginDatabase.Query(stmt); | |
+ if (result) | |
+ { | |
+ Field* fields = result->Fetch(); | |
+ std::string country = fields[0].GetString(); | |
+ stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_ACCOUNT_LOCK_CONTRY); | |
+ stmt->setString(0, country); | |
+ stmt->setUInt32(1, handler->GetSession()->GetAccountId()); | |
+ LoginDatabase.Execute(stmt); | |
+ handler->PSendSysMessage(LANG_COMMAND_ACCLOCKLOCKED); | |
+ } | |
+ else | |
+ { | |
+ handler->PSendSysMessage("[IP2NATION] Table empty"); | |
+ sLog->outDebug(LOG_FILTER_AUTHSERVER, "[IP2NATION] Table empty"); | |
+ } | |
+ } | |
+ else if (param == "off") | |
+ { | |
+ PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_ACCOUNT_LOCK_CONTRY); | |
+ stmt->setString(0, "00"); | |
+ stmt->setUInt32(1, handler->GetSession()->GetAccountId()); | |
+ LoginDatabase.Execute(stmt); | |
+ handler->PSendSysMessage(LANG_COMMAND_ACCLOCKUNLOCKED); | |
+ } | |
+ return true; | |
+ } | |
+ handler->SendSysMessage(LANG_USE_BOL); | |
+ handler->SetSentErrorMessage(true); | |
+ return false; | |
+ } | |
+ | |
+ static bool HandleAccountLockIpCommand(ChatHandler* handler, char const* args) | |
{ | |
if (!*args) | |
{ | |
diff --git a/src/server/shared/Database/Implementation/LoginDatabase.cpp b/src/server/shared/Database/Implementation/LoginDatabase.cpp | |
index a23294a..ab6df25 100644 | |
--- a/src/server/shared/Database/Implementation/LoginDatabase.cpp | |
+++ b/src/server/shared/Database/Implementation/LoginDatabase.cpp | |
@@ -37,7 +37,8 @@ void LoginDatabaseConnection::DoPrepareStatements() | |
PrepareStatement(LOGIN_SEL_SESSIONKEY, "SELECT a.sessionkey, a.id, aa.gmlevel FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE username = ?", CONNECTION_SYNCH); | |
PrepareStatement(LOGIN_UPD_VS, "UPDATE account SET v = ?, s = ? WHERE username = ?", CONNECTION_ASYNC); | |
PrepareStatement(LOGIN_UPD_LOGONPROOF, "UPDATE account SET sessionkey = ?, last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ? WHERE username = ?", CONNECTION_ASYNC); | |
- PrepareStatement(LOGIN_SEL_LOGONCHALLENGE, "SELECT a.sha_pass_hash, a.id, a.locked, a.last_ip, aa.gmlevel, a.v, a.s FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE a.username = ?", CONNECTION_SYNCH); | |
+ PrepareStatement(LOGIN_SEL_LOGONCHALLENGE, "SELECT a.sha_pass_hash, a.id, a.locked, a.lock_country, a.last_ip, aa.gmlevel, a.v, a.s FROM account a LEFT JOIN account_access aa ON (a.id = aa.id) WHERE a.username = ?", CONNECTION_SYNCH); | |
+ PrepareStatement(LOGIN_SEL_LOGON_COUNTRY, "SELECT country FROM ip2nation WHERE ip < ? ORDER BY ip DESC LIMIT 0,1", CONNECTION_SYNCH); | |
PrepareStatement(LOGIN_UPD_FAILEDLOGINS, "UPDATE account SET failed_logins = failed_logins + 1 WHERE username = ?", CONNECTION_ASYNC); | |
PrepareStatement(LOGIN_SEL_FAILEDLOGINS, "SELECT id, failed_logins FROM account WHERE username = ?", CONNECTION_SYNCH); | |
PrepareStatement(LOGIN_SEL_ACCOUNT_ID_BY_NAME, "SELECT id FROM account WHERE username = ?", CONNECTION_SYNCH); | |
@@ -59,6 +60,7 @@ void LoginDatabaseConnection::DoPrepareStatements() | |
PrepareStatement(LOGIN_INS_REALM_CHARACTERS_INIT, "INSERT INTO realmcharacters (realmid, acctid, numchars) SELECT realmlist.id, account.id, 0 FROM realmlist, account LEFT JOIN realmcharacters ON acctid=account.id WHERE acctid IS NULL", CONNECTION_ASYNC); | |
PrepareStatement(LOGIN_UPD_EXPANSION, "UPDATE account SET expansion = ? WHERE id = ?", CONNECTION_ASYNC); | |
PrepareStatement(LOGIN_UPD_ACCOUNT_LOCK, "UPDATE account SET locked = ? WHERE id = ?", CONNECTION_ASYNC); | |
+ PrepareStatement(LOGIN_UPD_ACCOUNT_LOCK_CONTRY, "UPDATE account SET lock_country = ? WHERE id = ?", CONNECTION_ASYNC); | |
PrepareStatement(LOGIN_INS_LOG, "INSERT INTO logs (time, realm, type, level, string) VALUES (?, ?, ?, ?, ?)", CONNECTION_ASYNC); | |
PrepareStatement(LOGIN_UPD_USERNAME, "UPDATE account SET v = 0, s = 0, username = ?, sha_pass_hash = ? WHERE id = ?", CONNECTION_ASYNC); | |
PrepareStatement(LOGIN_UPD_PASSWORD, "UPDATE account SET v = 0, s = 0, sha_pass_hash = ? WHERE id = ?", CONNECTION_ASYNC); | |
diff --git a/src/server/shared/Database/Implementation/LoginDatabase.h b/src/server/shared/Database/Implementation/LoginDatabase.h | |
index 939cc4b..a12282e 100644 | |
--- a/src/server/shared/Database/Implementation/LoginDatabase.h | |
+++ b/src/server/shared/Database/Implementation/LoginDatabase.h | |
@@ -56,6 +56,7 @@ enum LoginDatabaseStatements | |
LOGIN_UPD_VS, | |
LOGIN_UPD_LOGONPROOF, | |
LOGIN_SEL_LOGONCHALLENGE, | |
+ LOGIN_SEL_LOGON_COUNTRY, | |
LOGIN_UPD_FAILEDLOGINS, | |
LOGIN_SEL_FAILEDLOGINS, | |
LOGIN_SEL_ACCOUNT_ID_BY_NAME, | |
@@ -79,6 +80,7 @@ enum LoginDatabaseStatements | |
LOGIN_INS_REALM_CHARACTERS_INIT, | |
LOGIN_UPD_EXPANSION, | |
LOGIN_UPD_ACCOUNT_LOCK, | |
+ LOGIN_UPD_ACCOUNT_LOCK_CONTRY, | |
LOGIN_INS_LOG, | |
LOGIN_UPD_USERNAME, | |
LOGIN_UPD_PASSWORD, |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment