Skip to content

Commit

Permalink
update v/s srp values in AccountMgr commands
Browse files Browse the repository at this point in the history
to drop `sha_pass_hash` it is necesary to update
the srp values 'v' and 's' in the AccountMgr commands
otherwise modified/created accounts cannot login anymore

this commit introduces a basic SRP class to handle
the customized SRP calculation properly
  • Loading branch information
esno committed Jul 10, 2019
1 parent 2900d04 commit 62b5e82
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 10 deletions.
8 changes: 4 additions & 4 deletions sql/base/realmd.sql
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,10 @@ CREATE TABLE `account` (
LOCK TABLES `account` WRITE;
/*!40000 ALTER TABLE `account` DISABLE KEYS */;
INSERT INTO `account` VALUES
(1,'ADMINISTRATOR','a34b29541b87b7e4823683ce6c7bf6ae68beaaac',3,'','0','0','','2006-04-25 10:18:56','127.0.0.1',0,0,'0000-00-00 00:00:00',0,0,0,0, NULL),
(2,'GAMEMASTER','7841e21831d7c6bc0b57fbe7151eb82bd65ea1f9',2,'','0','0','','2006-04-25 10:18:56','127.0.0.1',0,0,'0000-00-00 00:00:00',0,0,0,0, NULL),
(3,'MODERATOR','a7f5fbff0b4eec2d6b6e78e38e8312e64d700008',1,'','0','0','','2006-04-25 10:19:35','127.0.0.1',0,0,'0000-00-00 00:00:00',0,0,0,0, NULL),
(4,'PLAYER','3ce8a96d17c5ae88a30681024e86279f1a38c041',0,'','0','0','','2006-04-25 10:19:35','127.0.0.1',0,0,'0000-00-00 00:00:00',0,0,0,0, NULL);
(1,'ADMINISTRATOR','a34b29541b87b7e4823683ce6c7bf6ae68beaaac',3,'','312B99EEF1C0196BB73B79D114CE161C5D089319E6EF54FAA6117DAB8B672C14','8EB5DE915AA3D805FA7099CF61C0BB8A77990EA869078A0C5B9EEE55828F4505','','2006-04-25 10:18:56','127.0.0.1',0,0,'0000-00-00 00:00:00',0,0,0,0, NULL),
(2,'GAMEMASTER','7841e21831d7c6bc0b57fbe7151eb82bd65ea1f9',2,'','681F5A7D4DE26DBFD3060EE37E03B79FD154875FB18F44DBF843963F193FC1AC','8873CD861DEFBF124232D6A29E4884E34C73385304A8AC44175976B1003DCFD7','','2006-04-25 10:18:56','127.0.0.1',0,0,'0000-00-00 00:00:00',0,0,0,0, NULL),
(3,'MODERATOR','a7f5fbff0b4eec2d6b6e78e38e8312e64d700008',1,'','2CA85C9853E44A6DCE09FC92EBDE57EF20975281EB7604326E25751AF8576859','AD68B088D7BCE5E4B734495A7A956F1D5DD1BAB61FB0FEE46C737D93EC166DF5','','2006-04-25 10:19:35','127.0.0.1',0,0,'0000-00-00 00:00:00',0,0,0,0, NULL),
(4,'PLAYER','3ce8a96d17c5ae88a30681024e86279f1a38c041',0,'','3738EC7E7C731FD431C716990C6D97CA5C1D50EF0DA7DE9819076DE1D03AA891','EBA23AF194D89B8061CA7FEBA06D336B1C38D8FBDABA76F2C51D45141362D881','','2006-04-25 10:19:35','127.0.0.1',0,0,'0000-00-00 00:00:00',0,0,0,0, NULL);
/*!40000 ALTER TABLE `account` ENABLE KEYS */;
UNLOCK TABLES;

Expand Down
39 changes: 33 additions & 6 deletions src/game/Accounts/AccountMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "Policies/Singleton.h"
#include "Util.h"
#include "Auth/Sha1.h"
#include "SRP6/SRP6.h"

extern DatabaseType LoginDatabase;

Expand All @@ -48,9 +49,19 @@ AccountOpResult AccountMgr::CreateAccount(std::string username, std::string pass
return AOR_NAME_ALREADY_EXIST; // username does already exist
}

if (!LoginDatabase.PExecute("INSERT INTO account(username,sha_pass_hash,joindate) VALUES('%s','%s',NOW())", username.c_str(), CalculateShaPassHash(username, password).c_str()))
std::string sha_pass_hash = CalculateShaPassHash(username, password);

SRP6 srp;
srp.CalculateVerifier(sha_pass_hash);

bool update_sv = LoginDatabase.PExecute(
"INSERT INTO account(username,sha_pass_hash,v,s,joindate) VALUES('%s','%s','%s','%s',NOW())",
username.c_str(), sha_pass_hash.c_str(), srp.GetVerifier(), srp.GetSalt());

if (!update_sv)
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");

return AOR_OK; // everything's fine
}
Expand Down Expand Up @@ -114,11 +125,19 @@ AccountOpResult AccountMgr::ChangeUsername(uint32 accid, std::string new_uname,
normalizeString(new_uname);
normalizeString(new_passwd);

std::string sha_pass_hash = CalculateShaPassHash(new_uname, new_passwd);

SRP6 srp;
srp.CalculateVerifier(sha_pass_hash);

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='%u'", safe_new_uname.c_str(),
CalculateShaPassHash(new_uname, new_passwd).c_str(), accid))
bool update_sv = LoginDatabase.PExecute(
"UPDATE account SET v='%s',s='%s',username='%s',sha_pass_hash='%s' WHERE id='%u'",
srp.GetVerifier(), srp.GetSalt(), safe_new_uname.c_str(), sha_pass_hash.c_str(), accid);

if (!update_sv)
return AOR_DB_INTERNAL_ERROR; // unexpected error

return AOR_OK;
Expand All @@ -137,9 +156,17 @@ AccountOpResult AccountMgr::ChangePassword(uint32 accid, std::string new_passwd)
normalizeString(username);
normalizeString(new_passwd);

std::string sha_pass_hash = CalculateShaPassHash(username, new_passwd);

SRP6 srp;
srp.CalculateVerifier(sha_pass_hash);

bool update_sv = LoginDatabase.PExecute(
"UPDATE account SET v='%s', s='%s', sha_pass_hash='%s' WHERE id='%u'",
srp.GetVerifier(), srp.GetSalt(), sha_pass_hash.c_str(), accid);

// 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='%s' WHERE id='%u'",
CalculateShaPassHash(username, new_passwd).c_str(), accid))
if (!update_sv)
return AOR_DB_INTERNAL_ERROR; // unexpected error

return AOR_OK;
Expand Down
11 changes: 11 additions & 0 deletions src/shared/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,19 @@ set(SRC_GRP_UTIL
WorldPacket.h
)

set(SRC_GRP_SRP
SRP6/SRP6.cpp
SRP6/SRP6.h
)

set(LIBRARY_SRCS
${SRC_GRP_AUTH}
${SRC_GRP_CONFIG}
${SRC_GRP_DATABASE}
${SRC_GRP_DATABASE_DBC}
${SRC_GRP_LOG}
${SRC_GRP_UTIL}
${SRC_GRP_SRP}
${SRC_GRP_NETWORK}
Common.cpp
Common.h
Expand Down Expand Up @@ -143,6 +149,11 @@ source_group("Util"
${SRC_GRP_UTIL}
)

source_group("SRP"
FILES
${SRC_GRP_SRP}
)

# OS specific files
if(WIN32)
set(LIBRARY_SRCS
Expand Down
64 changes: 64 additions & 0 deletions src/shared/SRP6/SRP6.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* This file is part of the CMaNGOS Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#include "Common.h"
#include "Auth/HMACSHA1.h"
#include "Auth/base32.h"
#include "SRP6.h"

SRP6::SRP6()
{
N.SetHexStr("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7");
g.SetDword(7);
v_hex = NULL;
s_hex = NULL;
}

SRP6::~SRP6()
{
if (v_hex != NULL)
OPENSSL_free((void*)v_hex);
if (s_hex != NULL)
OPENSSL_free((void*)s_hex);
}

void SRP6::CalculateVerifier(const std::string& rI)
{
s.SetRand(s_BYTE_SIZE * 8);

BigNumber I;
I.SetHexStr(rI.c_str());

// in case of leading zeros in the rI hash, restore them
uint8 mDigest[SHA_DIGEST_LENGTH];
memset(mDigest, 0, SHA_DIGEST_LENGTH);
if (I.GetNumBytes() <= SHA_DIGEST_LENGTH)
memcpy(mDigest, I.AsByteArray(), I.GetNumBytes());

std::reverse(mDigest, mDigest + SHA_DIGEST_LENGTH);

Sha1Hash sha;
sha.UpdateData(s.AsByteArray(), s.GetNumBytes());
sha.UpdateData(mDigest, SHA_DIGEST_LENGTH);
sha.Finalize();
BigNumber x;
x.SetBinary(sha.GetDigest(), Sha1Hash::GetLength());
v = g.ModExp(x, N);
v_hex = v.AsHexStr();
s_hex = s.AsHexStr();
}
48 changes: 48 additions & 0 deletions src/shared/SRP6/SRP6.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* This file is part of the CMaNGOS Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

#ifndef _SRP6_H
#define _SRP6_H

#include "Common.h"
#include "Auth/BigNumber.h"
#include "Auth/Sha1.h"
#include "ByteBuffer.h"

#define HMAC_RES_SIZE 20

class SRP6
{
public:
const static int s_BYTE_SIZE = 32;

SRP6(void);
~SRP6(void);

void CalculateVerifier(const std::string& rI);

const char* GetSalt(void) { return s_hex; };
const char* GetVerifier(void) { return v_hex; };

private:
BigNumber N, s, g, v;

const char* v_hex;
const char* s_hex;
};
#endif

0 comments on commit 62b5e82

Please sign in to comment.