Core/Accounts: sessionkey field in account table is only a temporary storage to pass data from authserver to worldserver and should only be used as such. Clearing sessionkey from database after a successful login to prevent possible exploits.

This commit is contained in:
Shauren
2013-02-07 16:15:23 +01:00
parent 5b45a87da5
commit fb43a92cc2
6 changed files with 28 additions and 24 deletions

View File

@@ -26,7 +26,7 @@ CREATE TABLE `account` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Identifier',
`username` varchar(32) NOT NULL DEFAULT '',
`sha_pass_hash` varchar(40) NOT NULL DEFAULT '',
`sessionkey` varchar(80) NOT NULL DEFAULT '',
`sessionkey` varchar(80) NOT NULL DEFAULT '' COMMENT 'Temporary storage of session key used to pass data from authserver to worldserver',
`v` varchar(64) NOT NULL DEFAULT '',
`s` varchar(64) NOT NULL DEFAULT '',
`email` varchar(254) NOT NULL DEFAULT '',

View File

@@ -0,0 +1,3 @@
UPDATE `account` SET `sessionkey`='';
ALTER TABLE `account`
CHANGE `sessionkey` `sessionkey` varchar(80) NOT NULL DEFAULT '' COMMENT 'Temporary storage of session key used to pass data from authserver to worldserver' AFTER `sha_pass_hash`;

View File

@@ -187,6 +187,14 @@ AccountOpResult AccountMgr::ChangePassword(uint32 accountId, std::string newPass
LoginDatabase.Execute(stmt);
stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_VS);
stmt->setString(0, "");
stmt->setString(1, "");
stmt->setString(2, username);
LoginDatabase.Execute(stmt);
return AOR_OK;
}

View File

@@ -750,7 +750,6 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
uint32 clientBuild;
uint32 unk2, unk3, unk5, unk6, unk7;
uint64 unk4;
BigNumber v, s, g, N;
WorldPacket packet, SendAddonPacked;
BigNumber k;
@@ -779,6 +778,8 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
clientSeed);
// 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);
@@ -795,27 +796,11 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
Field* fields = result->Fetch();
uint8 expansion = fields[6].GetUInt8();
uint8 expansion = fields[4].GetUInt8();
uint32 world_expansion = sWorld->getIntConfig(CONFIG_EXPANSION);
if (expansion > world_expansion)
expansion = world_expansion;
N.SetHexStr ("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7");
g.SetDword (7);
v.SetHexStr(fields[4].GetCString());
s.SetHexStr (fields[5].GetCString());
const char* sStr = s.AsHexStr(); // Must be freed by OPENSSL_free()
const char* vStr = v.AsHexStr(); // Must be freed by OPENSSL_free()
sLog->outDebug(LOG_FILTER_NETWORKIO, "WorldSocket::HandleAuthSession: (s, v) check s: %s v: %s",
sStr,
vStr);
OPENSSL_free((void*)sStr);
OPENSSL_free((void*)vStr);
///- Re-check ip locking (same check as in realmd).
if (fields[3].GetUInt8() == 1) // if ip is locked
{
@@ -831,7 +816,7 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
k.SetHexStr(fields[1].GetCString());
int64 mutetime = fields[7].GetInt64();
int64 mutetime = fields[5].GetInt64();
//! Negative mutetime indicates amount of seconds to be muted effective on next login - which is now.
if (mutetime < 0)
{
@@ -845,12 +830,12 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
LoginDatabase.Execute(stmt);
}
locale = LocaleConstant (fields[8].GetUInt8());
locale = LocaleConstant (fields[6].GetUInt8());
if (locale >= TOTAL_LOCALES)
locale = LOCALE_enUS;
uint32 recruiter = fields[9].GetUInt32();
std::string os = fields[10].GetString();
uint32 recruiter = fields[7].GetUInt32();
std::string os = fields[8].GetString();
// Must be done before WorldSession is created
if (sWorld->getBoolConfig(CONFIG_WARDEN_ENABLED) && os != "Win" && os != "OSX")
@@ -948,6 +933,12 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
// NOTE ATM the socket is single-threaded, have this in mind ...
ACE_NEW_RETURN(m_Session, WorldSession(id, this, AccountTypes(security), expansion, mutetime, locale, recruiter, isRecruiter), -1);
stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_CLEAR_SESSIONKEY);
stmt->setUInt32(0, id);
LoginDatabase.Execute(stmt);
m_Crypt.Init(&k);
m_Session->LoadGlobalAccountData();

View File

@@ -35,6 +35,7 @@ void LoginDatabaseConnection::DoPrepareStatements()
PrepareStatement(LOGIN_INS_ACCOUNT_AUTO_BANNED, "INSERT INTO account_banned VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, 'Trinity realmd', 'Failed login autoban', 1)", CONNECTION_ASYNC);
PrepareStatement(LOGIN_DEL_ACCOUNT_BANNED, "DELETE FROM account_banned WHERE id = ?", CONNECTION_ASYNC);
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_CLEAR_SESSIONKEY, "UPDATE account SET sessionkey = '' WHERE id = ?", CONNECTION_ASYNC);
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);
@@ -42,7 +43,7 @@ void LoginDatabaseConnection::DoPrepareStatements()
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);
PrepareStatement(LOGIN_SEL_ACCOUNT_LIST_BY_NAME, "SELECT id, username FROM account WHERE username = ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME, "SELECT id, sessionkey, last_ip, locked, v, s, expansion, mutetime, locale, recruiter, os FROM account WHERE username = ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME, "SELECT id, sessionkey, last_ip, locked, expansion, mutetime, locale, recruiter, os FROM account WHERE username = ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_ACCOUNT_LIST_BY_EMAIL, "SELECT id, username FROM account WHERE email = ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_NUM_CHARS_ON_REALM, "SELECT numchars FROM realmcharacters WHERE realmid = ? AND acctid= ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_ACCOUNT_BY_IP, "SELECT id, username FROM account WHERE last_ip = ?", CONNECTION_SYNCH);

View File

@@ -53,6 +53,7 @@ enum LoginDatabaseStatements
LOGIN_INS_ACCOUNT_AUTO_BANNED,
LOGIN_DEL_ACCOUNT_BANNED,
LOGIN_SEL_SESSIONKEY,
LOGIN_UPD_CLEAR_SESSIONKEY,
LOGIN_UPD_VS,
LOGIN_UPD_LOGONPROOF,
LOGIN_SEL_LOGONCHALLENGE,