Skip to content

Commit

Permalink
Fixed JobManager crash with nested tasks
Browse files Browse the repository at this point in the history
jwtVerify now takes a callback function
  • Loading branch information
Stefan Kürzeder committed Jul 25, 2019
1 parent 7dc8615 commit d376021
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 31 deletions.
82 changes: 56 additions & 26 deletions module/CFunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,21 +114,26 @@ int CFunctions::sign_jwt_token(lua_State* lua_vm)
int CFunctions::verify_jwt_token(lua_State* lua_vm)
{
// bool jwtVerify(string token, string secret/public_key_path, bool is_file_path = false)
if (lua_type(lua_vm, 1) != LUA_TSTRING || lua_type(lua_vm, 2) != LUA_TSTRING ||
(lua_type(lua_vm, 3) != LUA_TNONE && lua_type(lua_vm, 3) != LUA_TBOOLEAN))
if (lua_type(lua_vm, 1) != LUA_TFUNCTION || lua_type(lua_vm, 2) != LUA_TSTRING || lua_type(lua_vm, 3) != LUA_TSTRING ||
(lua_type(lua_vm, 4) != LUA_TNONE && lua_type(lua_vm, 4) != LUA_TBOOLEAN))
{
pModuleManager->ErrorPrintf("Bad argument @ jwtVerify\n");
lua_pushboolean(lua_vm, false);
return 1;
}

// Read arguments
const auto token = lua_tostring(lua_vm, 1);
const auto public_key_path = lua_tostring(lua_vm, 2);
// Save reference of the Lua callback function
// See: http://lua-users.org/lists/lua-l/2008-12/msg00193.html
lua_pushvalue(lua_vm, 1);
const auto func_ref = luaL_ref(lua_vm, LUA_REGISTRYINDEX);

// Read other arguments
const auto token = lua_tostring(lua_vm, 2);
const auto public_key_path = lua_tostring(lua_vm, 3);
std::string public_key = public_key_path;

// Read public- and private key from files
const auto is_file_path = lua_type(lua_vm, 3) != LUA_TNONE && lua_toboolean(lua_vm, 3);
const auto is_file_path = lua_type(lua_vm, 4) != LUA_TNONE && lua_toboolean(lua_vm, 4);
if (is_file_path)
{
if (!Crypto::read_key(lua_vm, public_key_path, public_key))
Expand All @@ -139,31 +144,56 @@ int CFunctions::verify_jwt_token(lua_State* lua_vm)
}
}

// Process verification
try {
const auto decoded_jwt = jwt::decode(token);
const auto algorithm = decoded_jwt.get_algorithm().c_str();
auto verifier = jwt::verify();
g_Module->GetJobManager().PushTask([/* lua_vm, */ token, public_key]() -> const std::optional<std::any>
{
// Process verification
try {
const auto decoded_jwt = jwt::decode(token);
const auto algorithm = decoded_jwt.get_algorithm().c_str();
auto verifier = jwt::verify();

// set verifier algorithm
if (std::strcmp(algorithm, "HS256") == 0)
verifier.allow_algorithm(jwt::algorithm::hs256{ public_key });
else if (std::strcmp(algorithm, "RS256") == 0)
verifier.allow_algorithm(jwt::algorithm::rs256{ public_key });
// set verifier algorithm
if (std::strcmp(algorithm, "HS256") == 0)
verifier.allow_algorithm(jwt::algorithm::hs256{ public_key });
else if (std::strcmp(algorithm, "RS256") == 0)
verifier.allow_algorithm(jwt::algorithm::rs256{ public_key });

verifier.verify(decoded_jwt);
verifier.verify(decoded_jwt);

lua_pushboolean(lua_vm, true);
return 1;
} catch (exception& e)
return true;
} catch (exception& e)
{
std::stringstream ss;
ss << "Bad Argument @ jwtVerify, " << e.what();
pModuleManager->ErrorPrintf(ss.str().c_str());

return false;
}
}, [lua_vm = lua_getmainstate(lua_vm), func_ref](const std::optional<std::any>& result)
{
std::stringstream ss;
ss << "Bad Argument @ jwtVerify, " << e.what();
pModuleManager->ErrorPrintf(ss.str().c_str());
// Validate LuaVM (use ResourceStart/-Stop to manage valid lua states)
if (!g_Module->HasLuaVM(lua_vm))
return;

lua_pushboolean(lua_vm, false);
return 1;
}
// Push stored reference to callback function to the stack
lua_rawgeti(lua_vm, LUA_REGISTRYINDEX, func_ref);

// Push token
try {
lua_pushboolean(lua_vm, result.has_value() && std::any_cast<bool>(result.value())); // might throw bad_any_cast
} catch (exception& e)
{
lua_pushboolean(lua_vm, false);
}

// Finally, call the function
const auto err = lua_pcall(lua_vm, 1, 0, 0);
if (err != 0)
pModuleManager->ErrorPrintf("%s\n", lua_tostring(lua_vm, -1));
});

lua_pushboolean(lua_vm, true);
return 1;
}

int CFunctions::get_jwt_claims(lua_State* lua_vm)
Expand Down
10 changes: 5 additions & 5 deletions module/JobManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class JobManager

void PushTask(Task task, TaskCompleteCallback completeCallback)
{
std::lock_guard<std::mutex> lock{ _mutex };
std::lock_guard<std::recursive_mutex> lock{ _mutex };

_tasks.push({ task, completeCallback });
}
Expand All @@ -60,22 +60,22 @@ class JobManager
}

// Get next task
auto& [task, completed_callback] = _tasks.front();
auto [task, completed_callback] = _tasks.front();
_tasks.pop();
_mutex.unlock();

// Run task
TaskResult result = task();

// Put result into completed tasks list
std::lock_guard<std::mutex> lock{ _mutex };
std::lock_guard<std::recursive_mutex> lock{ _mutex };
_completedTasks.push_back({ result, completed_callback });
}
}

void SpreadResults()
{
std::lock_guard<std::mutex> lock{ _mutex };
std::lock_guard<std::recursive_mutex> lock{ _mutex };
if (_completedTasks.empty())
return;

Expand All @@ -95,5 +95,5 @@ class JobManager
std::queue<std::pair<Task, TaskCompleteCallback>> _tasks;
std::list<std::pair<TaskResult, TaskCompleteCallback>> _completedTasks;

std::mutex _mutex;
std::recursive_mutex _mutex;
};

0 comments on commit d376021

Please sign in to comment.