Skip to content

Commit b258a11

Browse files
authored
Added multi-account support & system proxy support (#52)
1 parent 86c06f9 commit b258a11

25 files changed

Lines changed: 1312 additions & 569 deletions

DiscordTokenProtector/Context.cpp

Lines changed: 414 additions & 0 deletions
Large diffs are not rendered by default.

DiscordTokenProtector/Context.h

Lines changed: 16 additions & 348 deletions
Large diffs are not rendered by default.

DiscordTokenProtector/Crypto/Crypto.cpp

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,41 @@ namespace Crypto {
140140
}
141141

142142
#ifdef YUBIKEYSUPPORT
143+
YubiKeyFile g_yubiFile;
144+
145+
YubiKeyFile::YubiKeyFile() {
146+
if (!std::filesystem::exists(Config::getConfigPath() + YUBIKEY_KEY_FILE)) {
147+
//create an empty file so that openFile doesn't fail (due to the std::ios::in flag)
148+
std::ofstream(Config::getConfigPath() + YUBIKEY_KEY_FILE).close();
149+
}
150+
m_file.open(Config::getConfigPath() + YUBIKEY_KEY_FILE,
151+
std::ios::in | std::ios::out | std::ios::binary,
152+
_SH_DENYRW
153+
);
154+
if (!m_file.is_open())
155+
throw std::runtime_error("Failed to open yubikey file!");
156+
}
157+
158+
YubiKeyFile::~YubiKeyFile() {
159+
m_file.close();
160+
}
161+
162+
CryptoPP::SecByteBlock YubiKeyFile::generateKeyFile() {
163+
CryptoPP::SecByteBlock keydata = CryptoUtils::randomSBB(YUBIKEY_DATA_LEN);
164+
m_file.seekp(0);
165+
m_file.write(reinterpret_cast<const char*>(keydata.data()), keydata.size());
166+
m_file << std::flush;
167+
return keydata;
168+
}
169+
170+
CryptoPP::SecByteBlock YubiKeyFile::readKeyFile() {
171+
std::ifstream file(Config::getConfigPath() + YUBIKEY_KEY_FILE, std::ios::binary);
172+
CryptoPP::SecByteBlock keydata(YUBIKEY_DATA_LEN);
173+
m_file.seekg(0);
174+
m_file.read(reinterpret_cast<char*>(keydata.data()), YUBIKEY_DATA_LEN);
175+
return keydata;
176+
}
177+
143178
Yubi::Yubi() {
144179
throwOnError(ykpiv_init(&m_state, true), "ykpiv_init");
145180
throwOnError(ykpiv_connect(m_state, NULL), "ykpiv_connect");
@@ -200,27 +235,6 @@ namespace Crypto {
200235
return "Unknown";
201236
}
202237

203-
CryptoPP::SecByteBlock Yubi::generateKeyFile() {
204-
CryptoPP::SecByteBlock keydata = CryptoUtils::randomSBB(YUBIKEY_DATA_LEN);
205-
std::ofstream file(Config::getConfigPath() + YUBIKEY_KEY_FILE, std::ios::binary);
206-
if (!file.is_open())
207-
throw std::runtime_error("generateKeyFile : Failed to open YubiKey data file");
208-
209-
file.write(reinterpret_cast<const char*>(keydata.data()), keydata.size());
210-
return keydata;
211-
}
212-
213-
CryptoPP::SecByteBlock Yubi::readKeyFile() {
214-
std::ifstream file(Config::getConfigPath() + YUBIKEY_KEY_FILE, std::ios::binary);
215-
if (!file.is_open())
216-
throw std::runtime_error("readKeyFile : Failed to open YubiKey data file");
217-
218-
CryptoPP::SecByteBlock keydata(YUBIKEY_DATA_LEN);
219-
file.read(reinterpret_cast<char*>(keydata.data()), YUBIKEY_DATA_LEN);
220-
221-
return keydata;
222-
}
223-
224238
void Yubi::throwOnError(ykpiv_rc err, const std::string& action) {
225239
m_err = err;
226240
if (err == YKPIV_OK) return;

DiscordTokenProtector/Crypto/Crypto.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,20 @@ namespace Crypto {
3636
constexpr auto YUBIKEY_KEY_FILE = L"yk.dat";
3737
constexpr auto YUBIKEY_DATA_LEN = 256;
3838

39+
class YubiKeyFile {
40+
public:
41+
YubiKeyFile();
42+
~YubiKeyFile();
43+
44+
CryptoPP::SecByteBlock generateKeyFile();
45+
CryptoPP::SecByteBlock readKeyFile();
46+
47+
private:
48+
std::fstream m_file;
49+
};
50+
51+
extern YubiKeyFile g_yubiFile;
52+
3953
class Yubi {
4054
public:
4155
Yubi();
@@ -52,9 +66,6 @@ namespace Crypto {
5266

5367
std::string getModelName() const;
5468

55-
static CryptoPP::SecByteBlock generateKeyFile();
56-
static CryptoPP::SecByteBlock readKeyFile();
57-
5869
private:
5970
void throwOnError(ykpiv_rc err, const std::string& action);
6071

DiscordTokenProtector/Crypto/CryptoUtils.h

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <cryptopp/hex.h>
55
#include <cryptopp/osrng.h>
66
#include <cryptopp/sha.h>
7+
#include <cryptopp/base64.h>
78

89
enum class EncryptionType {
910
HWID,
@@ -27,7 +28,7 @@ struct KeyData {
2728
bool isEncrypted = false;
2829

2930
/*
30-
Note: the size of key and iv won't be changed since they are should be multiples of CRYPTPROTECTMEMORY_BLOCK_SIZE (16)
31+
Note: the size of key and iv won't be changed since they should be multiples of CRYPTPROTECTMEMORY_BLOCK_SIZE (16)
3132
*/
3233
void encrypt() {
3334
if (isEncrypted) return;
@@ -54,6 +55,9 @@ namespace CryptoUtils {
5455
constexpr auto ALPHANUM = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
5556
constexpr auto ALPHANUM_LEN = 26 * 2 + 10;
5657

58+
constexpr auto PASSCHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!/:.;,?*$%-_()[]{}";
59+
constexpr auto PASSCHARS_LEN = 80;
60+
5761
inline secure_string secureRandomString(size_t len, const char* charRange = ALPHANUM, size_t charRangeLen = ALPHANUM_LEN) {
5862
using namespace CryptoPP;
5963

@@ -111,4 +115,64 @@ namespace CryptoUtils {
111115

112116
return toHex(digest);
113117
}
118+
119+
inline secure_string KD_encrypt(const secure_string& data, KeyData keydata) {
120+
if (keydata.type == EncryptionType::HWID)
121+
return Crypto::encryptHWID(data);
122+
else if (keydata.type == EncryptionType::Password || keydata.type == EncryptionType::Yubi)
123+
return Crypto::encrypt(data, keydata.key, keydata.iv);
124+
else if (keydata.type == EncryptionType::HWIDAndPassword)
125+
return Crypto::encrypt(Crypto::encryptHWID(data), keydata.key, keydata.iv);
126+
else
127+
throw std::runtime_error("unknown encryption type");
128+
}
129+
130+
inline secure_string KD_decrypt(const secure_string& data, KeyData keydata) {
131+
if (keydata.type == EncryptionType::HWID)
132+
return Crypto::decryptHWID(data);
133+
else if (keydata.type == EncryptionType::Password || keydata.type == EncryptionType::Yubi)
134+
return Crypto::decrypt(data, keydata.key, keydata.iv);
135+
else if (keydata.type == EncryptionType::HWIDAndPassword)
136+
return Crypto::decryptHWID(Crypto::decrypt(data, keydata.key, keydata.iv));
137+
else
138+
throw std::runtime_error("unknown encryption type");
139+
}
140+
141+
inline secure_string toBase64(const secure_string& in) {
142+
using namespace CryptoPP;
143+
secure_string out;
144+
145+
Base64Encoder encoder;
146+
encoder.Put(reinterpret_cast<const byte*>(in.data()), in.size());
147+
encoder.MessageEnd();
148+
149+
auto size = encoder.MaxRetrievable();
150+
out.resize(size);
151+
encoder.Get(reinterpret_cast<byte*>(out.data()), out.size());
152+
153+
return out;
154+
}
155+
156+
inline secure_string fromBase64(const secure_string& in) {
157+
using namespace CryptoPP;
158+
159+
secure_string out;
160+
161+
Base64Decoder decoder;
162+
decoder.Put(reinterpret_cast<const byte*>(in.data()), in.size());
163+
decoder.MessageEnd();
164+
165+
auto size = decoder.MaxRetrievable();
166+
out.resize(size);
167+
decoder.Get(reinterpret_cast<byte*>(out.data()), out.size());
168+
169+
return out;
170+
}
171+
172+
inline void printSecByteBlock(const CryptoPP::SecByteBlock& data) {
173+
for (const auto& c : data) {
174+
std::cout << std::hex << std::setfill('0') << std::setw(2) << static_cast<uint16_t>(c) << " ";
175+
}
176+
std::cout << std::dec << std::endl;
177+
}
114178
}

DiscordTokenProtector/Discord.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,6 @@ enum class DiscordType {
1010
DiscordCanary
1111
};
1212

13-
//No need to store more info
14-
struct DiscordUserInfo {
15-
std::string fullUsername = "";//username#discriminator
16-
std::string username = "";
17-
std::string discriminator = "";
18-
std::string id = "";
19-
bool mfa = false;
20-
};
21-
2213
class Discord {
2314
private:
2415
typedef LONG(NTAPI* NtResumeProcess)(HANDLE ProcessHandle);

DiscordTokenProtector/DiscordTokenProtector.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
#include "Menu/Menu.h"
77
#include "Context.h"
88

9+
#include "Utils/CurlUtils.h"
10+
11+
#include "Storage/TokenManager.h"
12+
913
void mainInit() {
1014
try {
1115
#ifdef _PROD

DiscordTokenProtector/DiscordTokenProtector.rc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ MAINICON ICON "512x icon.ico"
6464

6565
VS_VERSION_INFO VERSIONINFO
6666
FILEVERSION 1,0,0,0
67-
PRODUCTVERSION 0,0,0,9
67+
PRODUCTVERSION 0,0,0,10
6868
FILEFLAGSMASK 0x3fL
6969
#ifdef _DEBUG
7070
FILEFLAGS 0x1L
@@ -86,7 +86,7 @@ BEGIN
8686
VALUE "LegalCopyright", "Copyright (C) 2021"
8787
VALUE "OriginalFilename", "DiscordTokenProtector.exe"
8888
VALUE "ProductName", "Discord Token Protector"
89-
VALUE "ProductVersion", "0.0.0.9"
89+
VALUE "ProductVersion", "0.0.0.10"
9090
END
9191
END
9292
BLOCK "VarFileInfo"

DiscordTokenProtector/DiscordTokenProtector.vcxproj

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -61,82 +61,82 @@
6161
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
6262
<ConfigurationType>Application</ConfigurationType>
6363
<UseDebugLibraries>true</UseDebugLibraries>
64-
<PlatformToolset>v142</PlatformToolset>
64+
<PlatformToolset>v143</PlatformToolset>
6565
<CharacterSet>Unicode</CharacterSet>
6666
</PropertyGroup>
6767
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
6868
<ConfigurationType>Application</ConfigurationType>
6969
<UseDebugLibraries>false</UseDebugLibraries>
70-
<PlatformToolset>v142</PlatformToolset>
70+
<PlatformToolset>v143</PlatformToolset>
7171
<WholeProgramOptimization>true</WholeProgramOptimization>
7272
<CharacterSet>Unicode</CharacterSet>
7373
</PropertyGroup>
7474
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='PROD|Win32'" Label="Configuration">
7575
<ConfigurationType>Application</ConfigurationType>
7676
<UseDebugLibraries>false</UseDebugLibraries>
77-
<PlatformToolset>v142</PlatformToolset>
77+
<PlatformToolset>v143</PlatformToolset>
7878
<WholeProgramOptimization>true</WholeProgramOptimization>
7979
<CharacterSet>Unicode</CharacterSet>
8080
</PropertyGroup>
8181
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='PROD-YUBI|Win32'" Label="Configuration">
8282
<ConfigurationType>Application</ConfigurationType>
8383
<UseDebugLibraries>false</UseDebugLibraries>
84-
<PlatformToolset>v142</PlatformToolset>
84+
<PlatformToolset>v143</PlatformToolset>
8585
<WholeProgramOptimization>true</WholeProgramOptimization>
8686
<CharacterSet>Unicode</CharacterSet>
8787
</PropertyGroup>
8888
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='PROD-NOSTARTUP|Win32'" Label="Configuration">
8989
<ConfigurationType>Application</ConfigurationType>
9090
<UseDebugLibraries>false</UseDebugLibraries>
91-
<PlatformToolset>v142</PlatformToolset>
91+
<PlatformToolset>v143</PlatformToolset>
9292
<WholeProgramOptimization>true</WholeProgramOptimization>
9393
<CharacterSet>Unicode</CharacterSet>
9494
</PropertyGroup>
9595
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='PROD-YUBI-NOSTARTUP|Win32'" Label="Configuration">
9696
<ConfigurationType>Application</ConfigurationType>
9797
<UseDebugLibraries>false</UseDebugLibraries>
98-
<PlatformToolset>v142</PlatformToolset>
98+
<PlatformToolset>v143</PlatformToolset>
9999
<WholeProgramOptimization>true</WholeProgramOptimization>
100100
<CharacterSet>Unicode</CharacterSet>
101101
</PropertyGroup>
102102
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
103103
<ConfigurationType>Application</ConfigurationType>
104104
<UseDebugLibraries>true</UseDebugLibraries>
105-
<PlatformToolset>v142</PlatformToolset>
105+
<PlatformToolset>v143</PlatformToolset>
106106
<CharacterSet>Unicode</CharacterSet>
107107
</PropertyGroup>
108108
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
109109
<ConfigurationType>Application</ConfigurationType>
110110
<UseDebugLibraries>false</UseDebugLibraries>
111-
<PlatformToolset>v142</PlatformToolset>
111+
<PlatformToolset>v143</PlatformToolset>
112112
<WholeProgramOptimization>true</WholeProgramOptimization>
113113
<CharacterSet>Unicode</CharacterSet>
114114
</PropertyGroup>
115115
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='PROD|x64'" Label="Configuration">
116116
<ConfigurationType>Application</ConfigurationType>
117117
<UseDebugLibraries>false</UseDebugLibraries>
118-
<PlatformToolset>v142</PlatformToolset>
118+
<PlatformToolset>v143</PlatformToolset>
119119
<WholeProgramOptimization>true</WholeProgramOptimization>
120120
<CharacterSet>Unicode</CharacterSet>
121121
</PropertyGroup>
122122
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='PROD-YUBI|x64'" Label="Configuration">
123123
<ConfigurationType>Application</ConfigurationType>
124124
<UseDebugLibraries>false</UseDebugLibraries>
125-
<PlatformToolset>v142</PlatformToolset>
125+
<PlatformToolset>v143</PlatformToolset>
126126
<WholeProgramOptimization>true</WholeProgramOptimization>
127127
<CharacterSet>Unicode</CharacterSet>
128128
</PropertyGroup>
129129
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='PROD-NOSTARTUP|x64'" Label="Configuration">
130130
<ConfigurationType>Application</ConfigurationType>
131131
<UseDebugLibraries>false</UseDebugLibraries>
132-
<PlatformToolset>v142</PlatformToolset>
132+
<PlatformToolset>v143</PlatformToolset>
133133
<WholeProgramOptimization>true</WholeProgramOptimization>
134134
<CharacterSet>Unicode</CharacterSet>
135135
</PropertyGroup>
136136
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='PROD-YUBI-NOSTARTUP|x64'" Label="Configuration">
137137
<ConfigurationType>Application</ConfigurationType>
138138
<UseDebugLibraries>false</UseDebugLibraries>
139-
<PlatformToolset>v142</PlatformToolset>
139+
<PlatformToolset>v143</PlatformToolset>
140140
<WholeProgramOptimization>true</WholeProgramOptimization>
141141
<CharacterSet>Unicode</CharacterSet>
142142
</PropertyGroup>
@@ -478,7 +478,9 @@
478478
<ClCompile Include="Menu\ImGuiAddon.cpp" />
479479
<ClCompile Include="Menu\Menu.cpp" />
480480
<ClCompile Include="Storage\Config.cpp" />
481+
<ClCompile Include="Context.cpp" />
481482
<ClCompile Include="Storage\SecureKV.cpp" />
483+
<ClCompile Include="Storage\TokenManager.cpp" />
482484
<ClCompile Include="Utils\Logger.cpp" />
483485
<ClCompile Include="Network\NetworkManager.cpp" />
484486
<ClCompile Include="Protection\FileCert.cpp" />
@@ -489,6 +491,8 @@
489491
<ClInclude Include="Context.h" />
490492
<ClInclude Include="Crypto\Crypto.h" />
491493
<ClInclude Include="Crypto\CryptoUtils.h" />
494+
<ClInclude Include="Utils\Structs.h" />
495+
<ClInclude Include="Storage\TokenManager.h" />
492496
<ClInclude Include="Utils\Exceptions.h" />
493497
<ClInclude Include="Protection\IntegrityCheck.h" />
494498
<ClInclude Include="Menu\Colors.h" />

DiscordTokenProtector/DiscordTokenProtector.vcxproj.filters

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,12 @@
9090
<ClCompile Include="Protection\IntegrityCheck.cpp">
9191
<Filter>Fichiers sources\Protection</Filter>
9292
</ClCompile>
93+
<ClCompile Include="Storage\TokenManager.cpp">
94+
<Filter>Fichiers sources\Storage</Filter>
95+
</ClCompile>
96+
<ClCompile Include="Context.cpp">
97+
<Filter>Fichiers sources</Filter>
98+
</ClCompile>
9399
</ItemGroup>
94100
<ItemGroup>
95101
<ClInclude Include="Includes.h">
@@ -161,6 +167,12 @@
161167
<ClInclude Include="Utils\Exceptions.h">
162168
<Filter>Fichiers d%27en-tête\Utils</Filter>
163169
</ClInclude>
170+
<ClInclude Include="Storage\TokenManager.h">
171+
<Filter>Fichiers d%27en-tête\Storage</Filter>
172+
</ClInclude>
173+
<ClInclude Include="Utils\Structs.h">
174+
<Filter>Fichiers d%27en-tête\Utils</Filter>
175+
</ClInclude>
164176
</ItemGroup>
165177
<ItemGroup>
166178
<ResourceCompile Include="DiscordTokenProtector.rc">

0 commit comments

Comments
 (0)