Skip to content

Commit 3027499

Browse files
sbx320patrikjuvonenPirulax
authored
Refactor passwordHash to use the new argument parser (#2040)
* Fix #1984 CLuaFunctionRef not working in new parser * Update passwordHash to use the new argument parser * Trigger CI * Update Shared/mods/deathmatch/logic/luadefs/CLuaCryptDefs.cpp Co-authored-by: patrikjuvonen <22572159+patrikjuvonen@users.noreply.github.com> Co-authored-by: Pirulax <patrikjankovics7@gmail.com>
1 parent fd228c3 commit 3027499

File tree

2 files changed

+56
-79
lines changed

2 files changed

+56
-79
lines changed

Shared/mods/deathmatch/logic/luadefs/CLuaCryptDefs.cpp

Lines changed: 54 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*
99
*****************************************************************************/
1010
#include "StdInc.h"
11+
#include <charconv>
1112
#include <SharedUtil.Crypto.h>
1213
#include <lua/CLuaFunctionParser.h>
1314

@@ -21,7 +22,7 @@ void CLuaCryptDefs::LoadFunctions()
2122
{"teaDecode", ArgumentParserWarn<false, TeaDecode>},
2223
{"base64Encode", ArgumentParserWarn<false, Base64encode>},
2324
{"base64Decode", ArgumentParserWarn<false, Base64decode>},
24-
{"passwordHash", PasswordHash},
25+
{"passwordHash", ArgumentParserWarn<false, PasswordHash>},
2526
{"passwordVerify", PasswordVerify},
2627
{"encodeString", EncodeString},
2728
{"decodeString", DecodeString},
@@ -77,100 +78,75 @@ std::string CLuaCryptDefs::Base64decode(std::string str)
7778
return SharedUtil::Base64decode(str);
7879
}
7980

80-
int CLuaCryptDefs::PasswordHash(lua_State* luaVM)
81+
std::variant<std::string, bool> CLuaCryptDefs::PasswordHash(lua_State* luaVM, std::string password, PasswordHashFunction algorithm, std::unordered_map<std::string, std::string> options, std::optional<CLuaFunctionRef> callback)
8182
{
82-
// string password_hash(string password, string algorithm, table options = {} [, function callback])
83-
SString password;
84-
PasswordHashFunction algorithm;
85-
CStringMap options;
86-
CLuaFunctionRef luaFunctionRef;
87-
88-
CScriptArgReader argStream(luaVM);
89-
argStream.ReadString(password);
90-
argStream.ReadEnumString(algorithm);
91-
argStream.ReadStringMap(options);
92-
93-
if (argStream.NextIsFunction())
94-
{
95-
argStream.ReadFunction(luaFunctionRef);
96-
argStream.ReadFunctionComplete();
97-
}
98-
99-
if (!argStream.HasErrors())
83+
switch (algorithm)
10084
{
101-
if (algorithm == PasswordHashFunction::Bcrypt)
85+
case PasswordHashFunction::Bcrypt:
10286
{
103-
// Set default value to 10
104-
if (options["cost"].empty())
105-
options["cost"] = "10";
87+
std::size_t cost = 10;
10688

107-
std::stringstream ss(options["cost"]);
108-
std::size_t cost;
109-
ss >> cost;
89+
if (auto it = options.find("cost"); it != options.end())
90+
{
91+
auto [__, err] = std::from_chars(it->second.data(), it->second.data() + it->second.length(), cost);
92+
if (err != std::errc{})
93+
throw std::invalid_argument("Invalid value for field 'cost'");
94+
}
11095

111-
if (!ss.fail())
96+
if (auto it = options.find("salt"); it != options.end())
11297
{
113-
// Using custom salts are deprecated (Luxy.c)
98+
// Using custom salts is deprecated
11499
// See: https://stackoverflow.com/questions/40993645/understanding-bcrypt-salt-as-used-by-php-password-hash
115-
if (options["salt"].length() > 0)
116-
{
117-
m_pScriptDebugging->LogWarning(luaVM, "Custom generated salts are deprecated and will be removed in the future.");
118-
}
100+
m_pScriptDebugging->LogWarning(luaVM, "Custom generated salts are deprecated and will be removed in the future.");
101+
}
119102

120-
// Sync
121-
if (luaFunctionRef == CLuaFunctionRef{})
122-
{
123-
SString hash = SharedUtil::BcryptHash(password, options["salt"], cost);
124-
if (!hash.empty())
125-
{
126-
lua_pushstring(luaVM, hash);
127-
return 1;
128-
}
129-
else
130-
m_pScriptDebugging->LogCustom(luaVM, "Invalid value for field 'salt'");
131-
}
132-
else // Async
103+
if (callback.has_value())
104+
{
105+
// Async
106+
CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM);
107+
if (pLuaMain)
133108
{
134-
CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaVM);
135-
if (pLuaMain)
136-
{
137-
CLuaShared::GetAsyncTaskScheduler()->PushTask<SString>(
138-
[password, salt = options["salt"], cost] {
139-
// Execute time-consuming task
140-
return SharedUtil::BcryptHash(password, salt, cost);
141-
},
142-
[luaFunctionRef](const SString& hash) {
143-
CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaFunctionRef.GetLuaVM());
144-
if (pLuaMain)
145-
{
146-
CLuaArguments arguments;
147-
148-
if (hash.empty())
149-
{
150-
m_pScriptDebugging->LogCustom(pLuaMain->GetVM(), "Invalid value for field 'salt'");
151-
arguments.PushBoolean(false);
152-
}
153-
else
154-
arguments.PushString(hash);
109+
CLuaShared::GetAsyncTaskScheduler()->PushTask<SString>(
110+
[password, salt = options["salt"], cost] {
111+
// Execute time-consuming task
112+
return SharedUtil::BcryptHash(password, salt, cost);
113+
},
114+
[luaFunctionRef = callback.value()](const SString& hash) {
115+
CLuaMain* pLuaMain = m_pLuaManager->GetVirtualMachine(luaFunctionRef.GetLuaVM());
116+
if (pLuaMain)
117+
{
118+
CLuaArguments arguments;
155119

156-
arguments.Call(pLuaMain, luaFunctionRef);
120+
if (hash.empty())
121+
{
122+
m_pScriptDebugging->LogCustom(pLuaMain->GetVM(), "Invalid value for field 'salt'");
123+
arguments.PushBoolean(false);
157124
}
158-
});
125+
else
126+
arguments.PushString(hash);
159127

160-
lua_pushboolean(luaVM, true);
161-
return 1;
162-
}
128+
arguments.Call(pLuaMain, luaFunctionRef);
129+
}
130+
});
163131
}
164132
}
165133
else
166-
m_pScriptDebugging->LogWarning(luaVM, "Invalid value for field 'cost'");
134+
{
135+
// Sync
136+
SString hash = SharedUtil::BcryptHash(password, options["salt"], cost);
137+
if (!hash.empty())
138+
{
139+
return hash;
140+
}
141+
else
142+
throw std::invalid_argument("Invalid value for field 'salt'");
143+
}
144+
return true;
167145
}
168-
}
169-
else
170-
m_pScriptDebugging->LogCustom(luaVM, argStream.GetFullErrorMessage());
171146

172-
lua_pushboolean(luaVM, false);
173-
return 1;
147+
default:
148+
throw std::invalid_argument("Unknown algorithm");
149+
}
174150
}
175151

176152

Shared/mods/deathmatch/logic/luadefs/CLuaCryptDefs.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ class CLuaCryptDefs : public CLuaDefs
2626
static std::string TeaDecode(std::string str, std::string key);
2727
static std::string Base64encode(std::string str);
2828
static std::string Base64decode(std::string str);
29-
LUA_DECLARE(PasswordHash);
29+
static std::variant<std::string, bool> PasswordHash(lua_State* luaVM, std::string password, PasswordHashFunction algorithm,
30+
std::unordered_map<std::string, std::string> options, std::optional<CLuaFunctionRef> callback);
3031
static std::string Sha256(std::string strSourceData);
3132
LUA_DECLARE(PasswordVerify);
3233
LUA_DECLARE(EncodeString);

0 commit comments

Comments
 (0)