mirror of
https://github.com/mangosfour/server.git
synced 2025-12-16 22:37:02 +00:00
[8450] Prevented using of plaintext passwords in sql queries
This commit is contained in:
parent
c8b717ab7d
commit
9c5f85d309
7 changed files with 62 additions and 28 deletions
|
|
@ -22,6 +22,7 @@
|
||||||
#include "Player.h"
|
#include "Player.h"
|
||||||
#include "Policies/SingletonImp.h"
|
#include "Policies/SingletonImp.h"
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
|
#include "Auth/Sha1.h"
|
||||||
|
|
||||||
extern DatabaseType loginDatabase;
|
extern DatabaseType loginDatabase;
|
||||||
|
|
||||||
|
|
@ -41,17 +42,12 @@ AccountOpResult AccountMgr::CreateAccount(std::string username, std::string pass
|
||||||
normalizeString(username);
|
normalizeString(username);
|
||||||
normalizeString(password);
|
normalizeString(password);
|
||||||
|
|
||||||
loginDatabase.escape_string(username);
|
if(GetId(username))
|
||||||
loginDatabase.escape_string(password);
|
|
||||||
|
|
||||||
QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE username = '%s'", username.c_str());
|
|
||||||
if(result)
|
|
||||||
{
|
{
|
||||||
delete result;
|
|
||||||
return AOR_NAME_ALREDY_EXIST; // username does already exist
|
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
|
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");
|
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_uname);
|
||||||
normalizeString(new_passwd);
|
normalizeString(new_passwd);
|
||||||
|
|
||||||
loginDatabase.escape_string(new_uname);
|
std::string safe_new_uname = new_uname;
|
||||||
loginDatabase.escape_string(new_passwd);
|
loginDatabase.escape_string(safe_new_uname);
|
||||||
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))
|
|
||||||
|
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_DB_INTERNAL_ERROR; // unexpected error
|
||||||
|
|
||||||
return AOR_OK;
|
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)
|
AccountOpResult AccountMgr::ChangePassword(uint32 accid, std::string new_passwd)
|
||||||
{
|
{
|
||||||
QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d'", accid);
|
std::string username;
|
||||||
if(!result)
|
|
||||||
|
if(!GetName(accid, username))
|
||||||
return AOR_NAME_NOT_EXIST; // account doesn't exist
|
return AOR_NAME_NOT_EXIST; // account doesn't exist
|
||||||
delete result;
|
|
||||||
|
|
||||||
if (utf8length(new_passwd) > MAX_ACCOUNT_STR)
|
if (utf8length(new_passwd) > MAX_ACCOUNT_STR)
|
||||||
return AOR_PASS_TOO_LONG;
|
return AOR_PASS_TOO_LONG;
|
||||||
|
|
||||||
normalizeString(new_passwd);
|
normalizeString(new_passwd);
|
||||||
|
|
||||||
loginDatabase.escape_string(new_passwd);
|
|
||||||
// also reset s and v to force update at next realmd login
|
// 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_DB_INTERNAL_ERROR; // unexpected error
|
||||||
|
|
||||||
return AOR_OK;
|
return AOR_OK;
|
||||||
|
|
@ -191,10 +189,13 @@ bool AccountMgr::GetName(uint32 acc_id, std::string &name)
|
||||||
|
|
||||||
bool AccountMgr::CheckPassword(uint32 accid, std::string passwd)
|
bool AccountMgr::CheckPassword(uint32 accid, std::string passwd)
|
||||||
{
|
{
|
||||||
normalizeString(passwd);
|
std::string username;
|
||||||
loginDatabase.escape_string(passwd);
|
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)
|
if (result)
|
||||||
{
|
{
|
||||||
delete result;
|
delete result;
|
||||||
|
|
@ -216,3 +217,19 @@ bool AccountMgr::normalizeString(std::string& utf8str)
|
||||||
|
|
||||||
return WStrToUtf8(wstr_buf,wstr_len,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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ class AccountMgr
|
||||||
uint32 GetId(std::string username);
|
uint32 GetId(std::string username);
|
||||||
uint32 GetSecurity(uint32 acc_id);
|
uint32 GetSecurity(uint32 acc_id);
|
||||||
bool GetName(uint32 acc_id, std::string &name);
|
bool GetName(uint32 acc_id, std::string &name);
|
||||||
|
std::string CalculateShaPassHash(std::string& name, std::string& password);
|
||||||
|
|
||||||
static bool normalizeString(std::string& utf8str);
|
static bool normalizeString(std::string& utf8str);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -865,13 +865,10 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
|
||||||
|
|
||||||
// Re-check account ban (same check as in realmd)
|
// Re-check account ban (same check as in realmd)
|
||||||
QueryResult *banresult =
|
QueryResult *banresult =
|
||||||
loginDatabase.PQuery ("SELECT "
|
loginDatabase.PQuery ("SELECT 1 FROM account_banned WHERE id = %u AND active = 1 "
|
||||||
"bandate, "
|
"UNION "
|
||||||
"unbandate "
|
"SELECT 1 FROM ip_banned WHERE ip = '%s'",
|
||||||
"FROM account_banned "
|
id, GetRemoteAddress().c_str());
|
||||||
"WHERE id = '%u' "
|
|
||||||
"AND active = 1",
|
|
||||||
id);
|
|
||||||
|
|
||||||
if (banresult) // if account banned
|
if (banresult) // if account banned
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,6 @@ class Sha1Hash
|
||||||
uint8 *GetDigest(void) { return mDigest; };
|
uint8 *GetDigest(void) { return mDigest; };
|
||||||
int GetLength(void) { return SHA_DIGEST_LENGTH; };
|
int GetLength(void) { return SHA_DIGEST_LENGTH; };
|
||||||
|
|
||||||
BigNumber GetBigNumber();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SHA_CTX mC;
|
SHA_CTX mC;
|
||||||
uint8 mDigest[SHA_DIGEST_LENGTH];
|
uint8 mDigest[SHA_DIGEST_LENGTH];
|
||||||
|
|
|
||||||
|
|
@ -441,3 +441,23 @@ void vutf8printf(FILE *out, const char *str, va_list* ap)
|
||||||
vfprintf(out, str, *ap);
|
vfprintf(out, str, *ap);
|
||||||
#endif
|
#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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -289,4 +289,5 @@ void vutf8printf(FILE *out, const char *str, va_list* ap);
|
||||||
bool IsIPAddress(char const* ipaddress);
|
bool IsIPAddress(char const* ipaddress);
|
||||||
uint32 CreatePIDFile(const std::string& filename);
|
uint32 CreatePIDFile(const std::string& filename);
|
||||||
|
|
||||||
|
void hexEncodeByteArray(uint8* bytes, uint32 arrayLen, std::string& result);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "8449"
|
#define REVISION_NR "8450"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue