Fix a vulnerability in password encryption

* There was an error in the encryption used to save passwords,
  now it's really harder to decrypt the password from the config file
* Other minor changes
This commit is contained in:
Eduardo Bart
2013-01-26 14:38:48 -02:00
parent 18af9a45ee
commit 07959ddc04
11 changed files with 72 additions and 20 deletions

View File

@@ -349,6 +349,7 @@ namespace Otc
GameLoginPending = 35,
GameNewSpeedLaw = 36,
GameForceFirstAutoWalkStep = 37,
GameLoginUUID = 38,
// 51-100 reserved to be defined in lua
LastGameFeature = 101
};

View File

@@ -24,6 +24,8 @@
#include "game.h"
#include "client.h"
#include <framework/core/application.h>
#include <framework/platform/platform.h>
#include <framework/util/crypt.h>
void ProtocolGame::send(const OutputMessagePtr& outputMessage)
{
@@ -97,6 +99,12 @@ void ProtocolGame::sendLoginPacket(uint challengeTimestamp, uint8 challengeRando
paddingBytes -= 8 + m_characterName.length() + m_accountPassword.length();
}
if(g_game.getFeature(Otc::GameLoginUUID)) {
std::string uuid = g_crypt.getMachineUUID();
msg->addString(uuid);
paddingBytes -= 2 + uuid.length();
}
if(g_game.getFeature(Otc::GameChallengeOnLogin)) {
msg->addU32(challengeTimestamp);
msg->addU8(challengeRandom);

View File

@@ -68,7 +68,7 @@ bool ResourceManager::discoverWorkDir(const std::string& existentFile)
bool ResourceManager::setupUserWriteDir(const std::string& appWriteDirName)
{
std::string userDir = PHYSFS_getUserDir();
std::string userDir = getUserDir();
std::string dirName;
#ifndef WIN32
dirName = stdext::format(".%s", appWriteDirName);
@@ -306,6 +306,11 @@ std::string ResourceManager::getBaseDir()
return PHYSFS_getBaseDir();
}
std::string ResourceManager::getUserDir()
{
return PHYSFS_getUserDir();
}
std::string ResourceManager::guessFileType(const std::string& filename, const std::string& type)
{
if(g_resources.fileExists(filename))

View File

@@ -66,6 +66,7 @@ public:
std::string getRealDir(const std::string& path);
std::string getCurrentDir();
std::string getBaseDir();
std::string getUserDir();
std::string getWriteDir() { return m_writeDir; }
std::string getWorkDir() { return m_workDir; }
std::deque<std::string> getSearchPaths() { return m_searchPaths; }

View File

@@ -111,6 +111,8 @@ void Application::registerLuaFunctions()
// Crypt
g_lua.registerSingletonClass("g_crypt");
g_lua.bindSingletonFunction("g_crypt", "genUUID", &Crypt::genUUID, &g_crypt);
g_lua.bindSingletonFunction("g_crypt", "setMachineUUID", &Crypt::setMachineUUID, &g_crypt);
g_lua.bindSingletonFunction("g_crypt", "getMachineUUID", &Crypt::getMachineUUID, &g_crypt);
g_lua.bindSingletonFunction("g_crypt", "encrypt", &Crypt::encrypt, &g_crypt);
g_lua.bindSingletonFunction("g_crypt", "decrypt", &Crypt::decrypt, &g_crypt);
g_lua.bindSingletonFunction("g_crypt", "sha1Encode", &Crypt::sha1Encode, &g_crypt);

View File

@@ -23,8 +23,9 @@
#include "crypt.h"
#include <framework/stdext/math.h>
#include <framework/core/logger.h>
#include <framework/core/resourcemanager.h>
#include <framework/platform/platform.h>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
@@ -157,10 +158,28 @@ std::string Crypt::genUUID()
return boost::uuids::to_string(u);
}
std::string Crypt::genUUIDKey()
bool Crypt::setMachineUUID(const std::string& uuidstr)
{
if(uuidstr.empty())
return false;
std::stringstream ss;
ss << uuidstr;
ss >> m_machineUUID;
return !m_machineUUID.is_nil();
}
std::string Crypt::getMachineUUID()
{
return boost::uuids::to_string(m_machineUUID);
}
std::string Crypt::getMachineKey()
{
boost::hash<boost::uuids::uuid> uuid_hasher;
std::size_t hash = uuid_hasher(boost::uuids::uuid());
boost::uuids::name_generator gen(m_machineUUID);
boost::uuids::uuid u = gen(g_platform.getCPUName() + g_platform.getOSName() + g_resources.getUserDir());
std::size_t hash = uuid_hasher(u);
std::string key;
key.assign((const char *)&hash, sizeof(hash));
return key;
@@ -171,14 +190,14 @@ std::string Crypt::encrypt(const std::string& decrypted_string)
std::string tmp = "0000" + decrypted_string;
uint32 sum = stdext::adler32((const uint8*)decrypted_string.c_str(), decrypted_string.size());
stdext::writeLE32((uint8*)&tmp[0], sum);
std::string encrypted = base64Encode(xorCrypt(tmp, genUUIDKey()));
std::string encrypted = base64Encode(xorCrypt(tmp, getMachineKey()));
return encrypted;
}
std::string Crypt::decrypt(const std::string& encrypted_string)
{
std::string decoded = base64Decode(encrypted_string);
std::string tmp = xorCrypt(base64Decode(encrypted_string), genUUIDKey());
std::string tmp = xorCrypt(base64Decode(encrypted_string), getMachineKey());
if(tmp.length() >= 4) {
uint32 readsum = stdext::readLE32((const uint8*)tmp.c_str());
std::string decrypted_string = tmp.substr(4);

View File

@@ -26,6 +26,8 @@
#include "../stdext/types.h"
#include <string>
#include <boost/uuid/uuid.hpp>
typedef struct rsa_st RSA;
class Crypt
@@ -38,6 +40,8 @@ public:
std::string base64Decode(const std::string& encoded_string);
std::string xorCrypt(const std::string& buffer, const std::string& key);
std::string genUUID();
bool setMachineUUID(const std::string& uuidstr);
std::string getMachineUUID();
std::string encrypt(const std::string& decrypted_string);
std::string decrypt(const std::string& encrypted_string);
std::string md5Encode(const std::string& decoded_string, bool upperCase);
@@ -52,7 +56,8 @@ public:
bool rsaDecrypt(unsigned char *msg, int size);
private:
std::string genUUIDKey();
std::string getMachineKey();
boost::uuids::uuid m_machineUUID;
RSA *m_rsa;
};