[8450] Prevented using of plaintext passwords in sql queries

This commit is contained in:
arrai 2009-09-02 01:51:26 +02:00
parent c8b717ab7d
commit 9c5f85d309
7 changed files with 62 additions and 28 deletions

View file

@ -22,6 +22,7 @@
#include "Player.h"
#include "Policies/SingletonImp.h"
#include "Util.h"
#include "Auth/Sha1.h"
extern DatabaseType loginDatabase;
@ -41,17 +42,12 @@ AccountOpResult AccountMgr::CreateAccount(std::string username, std::string pass
normalizeString(username);
normalizeString(password);
loginDatabase.escape_string(username);
loginDatabase.escape_string(password);
QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE username = '%s'", username.c_str());
if(result)
if(GetId(username))
{
delete result;
return AOR_NAME_ALREDY_EXIST; // username does already exist
}
if(!loginDatabase.PExecute("INSERT INTO account(username,sha_pass_hash,joindate) VALUES('%s',SHA1("_CONCAT3_("'%s'","':'","'%s'")"),NOW())", username.c_str(), username.c_str(), password.c_str()))
if(!loginDatabase.PExecute("INSERT INTO account(username,sha_pass_hash,joindate) VALUES('%s','%s',NOW())", username.c_str(), CalculateShaPassHash(username, password).c_str()))
return AOR_DB_INTERNAL_ERROR; // unexpected error
loginDatabase.Execute("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");
@ -121,9 +117,11 @@ AccountOpResult AccountMgr::ChangeUsername(uint32 accid, std::string new_uname,
normalizeString(new_uname);
normalizeString(new_passwd);
loginDatabase.escape_string(new_uname);
loginDatabase.escape_string(new_passwd);
if(!loginDatabase.PExecute("UPDATE account SET username='%s',sha_pass_hash=SHA1("_CONCAT3_("'%s'","':'","'%s'")") WHERE id='%d'", new_uname.c_str(), new_uname.c_str(), new_passwd.c_str(), accid))
std::string safe_new_uname = new_uname;
loginDatabase.escape_string(safe_new_uname);
if(!loginDatabase.PExecute("UPDATE account SET v='0',s='0',username='%s',sha_pass_hash='%s' WHERE id='%d'", safe_new_uname.c_str(),
CalculateShaPassHash(new_uname, new_passwd).c_str(), accid))
return AOR_DB_INTERNAL_ERROR; // unexpected error
return AOR_OK;
@ -131,19 +129,19 @@ AccountOpResult AccountMgr::ChangeUsername(uint32 accid, std::string new_uname,
AccountOpResult AccountMgr::ChangePassword(uint32 accid, std::string new_passwd)
{
QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d'", accid);
if(!result)
std::string username;
if(!GetName(accid, username))
return AOR_NAME_NOT_EXIST; // account doesn't exist
delete result;
if (utf8length(new_passwd) > MAX_ACCOUNT_STR)
return AOR_PASS_TOO_LONG;
normalizeString(new_passwd);
loginDatabase.escape_string(new_passwd);
// also reset s and v to force update at next realmd login
if(!loginDatabase.PExecute("UPDATE account SET v='0', s='0', sha_pass_hash=SHA1("_CONCAT3_("username","':'","'%s'")") WHERE id='%d'", new_passwd.c_str(), accid))
if(!loginDatabase.PExecute("UPDATE account SET v='0', s='0', sha_pass_hash='%s' WHERE id='%d'",
CalculateShaPassHash(username, new_passwd).c_str(), accid))
return AOR_DB_INTERNAL_ERROR; // unexpected error
return AOR_OK;
@ -191,10 +189,13 @@ bool AccountMgr::GetName(uint32 acc_id, std::string &name)
bool AccountMgr::CheckPassword(uint32 accid, std::string passwd)
{
normalizeString(passwd);
loginDatabase.escape_string(passwd);
std::string username;
if(!GetName(accid, username))
return false;
QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d' AND sha_pass_hash=SHA1("_CONCAT3_("username","':'","'%s'")")", accid, passwd.c_str());
normalizeString(passwd);
QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d' AND sha_pass_hash='%s'", accid, CalculateShaPassHash(username, passwd).c_str());
if (result)
{
delete result;
@ -216,3 +217,19 @@ bool AccountMgr::normalizeString(std::string& utf8str)
return WStrToUtf8(wstr_buf,wstr_len,utf8str);
}
std::string AccountMgr::CalculateShaPassHash(std::string& name, std::string& password)
{
Sha1Hash sha;
sha.Initialize();
sha.UpdateData(name);
sha.UpdateData(":");
sha.UpdateData(password);
sha.Finalize();
std::string encoded;
hexEncodeByteArray(sha.GetDigest(), sha.GetLength(), encoded);
return encoded;
}

View file

@ -50,6 +50,7 @@ class AccountMgr
uint32 GetId(std::string username);
uint32 GetSecurity(uint32 acc_id);
bool GetName(uint32 acc_id, std::string &name);
std::string CalculateShaPassHash(std::string& name, std::string& password);
static bool normalizeString(std::string& utf8str);
};

View file

@ -865,13 +865,10 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
// Re-check account ban (same check as in realmd)
QueryResult *banresult =
loginDatabase.PQuery ("SELECT "
"bandate, "
"unbandate "
"FROM account_banned "
"WHERE id = '%u' "
"AND active = 1",
id);
loginDatabase.PQuery ("SELECT 1 FROM account_banned WHERE id = %u AND active = 1 "
"UNION "
"SELECT 1 FROM ip_banned WHERE ip = '%s'",
id, GetRemoteAddress().c_str());
if (banresult) // if account banned
{

View file

@ -42,8 +42,6 @@ class Sha1Hash
uint8 *GetDigest(void) { return mDigest; };
int GetLength(void) { return SHA_DIGEST_LENGTH; };
BigNumber GetBigNumber();
private:
SHA_CTX mC;
uint8 mDigest[SHA_DIGEST_LENGTH];

View file

@ -441,3 +441,23 @@ void vutf8printf(FILE *out, const char *str, va_list* ap)
vfprintf(out, str, *ap);
#endif
}
void hexEncodeByteArray(uint8* bytes, uint32 arrayLen, std::string& result)
{
std::ostringstream ss;
for(uint32 i=0; i<arrayLen; ++i)
{
for(uint8 j=0; j<2; ++j)
{
unsigned char nibble = 0x0F & (bytes[i]>>((1-j)*4));
char encodedNibble;
if(nibble < 0x0A)
encodedNibble = '0'+nibble;
else
encodedNibble = 'A'+nibble-0x0A;
ss << encodedNibble;
}
}
result = ss.str();
}

View file

@ -289,4 +289,5 @@ void vutf8printf(FILE *out, const char *str, va_list* ap);
bool IsIPAddress(char const* ipaddress);
uint32 CreatePIDFile(const std::string& filename);
void hexEncodeByteArray(uint8* bytes, uint32 arrayLen, std::string& result);
#endif

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "8449"
#define REVISION_NR "8450"
#endif // __REVISION_NR_H__