errorCodeToMsg

This commit is contained in:
maxdcb
2026-04-30 14:17:48 +02:00
parent 853edb4d33
commit 2458165b9f
28 changed files with 2754 additions and 2391 deletions
File diff suppressed because it is too large Load Diff
+1
View File
@@ -19,6 +19,7 @@ public:
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int initConfig(const nlohmann::json &config);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int errorCodeToMsg(const C2Message& c2RetMessage, std::string& errorMsg) override;
int osCompatibility()
{
return OS_WINDOWS;
@@ -183,6 +183,25 @@ int main()
ok &= expect(module.init(cmd, message) == 0, "dummy exe should be accepted in spoofed-parent mode");
ok &= expectAssemblyMessage(message, dummyPath, "2", "--flag", "dummy exe spoofed-parent mode");
}
{
AssemblyExec module;
nlohmann::json config;
config["process"] = "Z:\\c2core_missing_assemblyexec_target.exe";
ok &= expect(module.initConfig(config) == 0, "initConfig should accept a custom process path");
C2Message message;
message.set_args("1");
message.set_data("raw-bytes");
C2Message retMessage;
ok &= expect(module.process(message, retMessage) == 0, "missing process target should return through C2Message");
ok &= expect(retMessage.errorCode() > 0, "missing process target should set an error code");
ok &= expect(retMessage.returnvalue().find("Error: Process failed to start") != std::string::npos, "missing process target should explain the failure");
std::string errorMsg;
ok &= expect(module.errorCodeToMsg(retMessage, errorMsg) == 0, "missing process target should map error text");
ok &= expect(errorMsg == retMessage.returnvalue(), "missing process target error text should come from returnvalue");
}
}
return ok ? 0 : 1;
+29 -2
View File
@@ -12,6 +12,12 @@ constexpr unsigned long long moduleHash = djb2(moduleName);
#define BUFSIZE 512
namespace
{
constexpr int ERROR_OPEN_PROCESS = 1;
constexpr int ERROR_CREATE_PROCESS = 2;
}
#ifdef _WIN32
__declspec(dllexport) Chisel* A_ChiselConstructor()
@@ -189,13 +195,22 @@ int Chisel::process(C2Message &c2Message, C2Message &c2RetMessage)
{
pid = c2Message.pid();
HANDLE hProc=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);
TerminateProcess(hProc,9);
if(hProc == NULL)
{
c2RetMessage.set_errorCode(ERROR_OPEN_PROCESS);
result = "OpenProcess failed.";
}
else
{
TerminateProcess(hProc,9);
CloseHandle(hProc);
result="Chisel stoped.\n";
}
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_pid(pid);
c2RetMessage.set_cmd("stop");
result="Chisel stoped.\n";
c2RetMessage.set_returnvalue(result);
return 0;
}
@@ -226,6 +241,7 @@ int Chisel::process(C2Message &c2Message, C2Message &c2RetMessage)
else
{
result += "CreateProcess failed.";
c2RetMessage.set_errorCode(ERROR_CREATE_PROCESS);
}
#endif
@@ -238,6 +254,17 @@ int Chisel::process(C2Message &c2Message, C2Message &c2RetMessage)
return 0;
}
int Chisel::errorCodeToMsg(const C2Message &c2RetMessage, std::string &errorMsg)
{
#if defined(BUILD_TEAMSERVER) || defined(C2CORE_BUILD_TESTS) || defined(C2CORE_BUILD_FUNCTIONAL_TESTS)
if (c2RetMessage.errorCode() > 0)
{
errorMsg = c2RetMessage.returnvalue();
}
#endif
return 0;
}
int Chisel::followUp(const C2Message &c2RetMessage)
{
int pid = c2RetMessage.pid();
+1
View File
@@ -15,6 +15,7 @@ public:
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int followUp(const C2Message &c2RetMessage);
int errorCodeToMsg(const C2Message& c2RetMessage, std::string& errorMsg) override;
int osCompatibility()
{
return OS_WINDOWS;
+15
View File
@@ -39,6 +39,21 @@ int main()
ok &= expect(message.pid() == 0, "non-numeric pid should map to zero with current parser");
}
{
Chisel module;
C2Message message;
message.set_cmd("stop");
message.set_pid(2147483647);
C2Message ret;
ok &= expect(module.process(message, ret) == 0, "missing chisel pid should return through C2Message");
ok &= expect(ret.errorCode() > 0, "missing chisel pid should set an error code");
ok &= expect(ret.returnvalue().find("OpenProcess failed") != std::string::npos, "missing chisel pid should explain the failure");
std::string errorMsg;
ok &= expect(module.errorCodeToMsg(ret, errorMsg) == 0, "missing chisel pid should map error text");
ok &= expect(errorMsg == ret.returnvalue(), "missing chisel pid error text should come from returnvalue");
}
{
Chisel module;
std::vector<std::string> cmd = {"chisel", "missing.exe", "client", "host:8000", "R:socks"};
+21 -1
View File
@@ -25,6 +25,11 @@ using namespace std;
constexpr std::string_view moduleName = "coffLoader";
constexpr unsigned long long moduleHash = djb2(moduleName);
namespace
{
constexpr int ERROR_COFF_EXECUTION = 1;
}
#ifdef _WIN32
@@ -130,11 +135,26 @@ int CoffLoader::process(C2Message &c2Message, C2Message &c2RetMessage)
std::string result = coffLoader(payload, functionName, args);
c2RetMessage.set_instruction(c2RetMessage.instruction());
if (result.find("Failed") != std::string::npos)
{
c2RetMessage.set_errorCode(ERROR_COFF_EXECUTION);
}
c2RetMessage.set_returnvalue(result);
return 0;
}
int CoffLoader::errorCodeToMsg(const C2Message &c2RetMessage, std::string &errorMsg)
{
#if defined(BUILD_TEAMSERVER) || defined(C2CORE_BUILD_TESTS) || defined(C2CORE_BUILD_FUNCTIONAL_TESTS)
if (c2RetMessage.errorCode() > 0)
{
errorMsg = c2RetMessage.returnvalue();
}
#endif
return 0;
}
std::string CoffLoader::coffLoader(std::string& payload, std::string& functionName, std::string& args)
{
@@ -193,4 +213,4 @@ std::string CoffLoader::coffLoader(std::string& payload, std::string& functionNa
#endif
return result;
}
}
+1
View File
@@ -14,6 +14,7 @@ public:
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int errorCodeToMsg(const C2Message& c2RetMessage, std::string& errorMsg) override;
int osCompatibility()
{
return OS_WINDOWS;
@@ -35,5 +35,16 @@ int main()
std::filesystem::remove(coff);
}
{
CoffLoader module;
C2Message ret;
ret.set_errorCode(1);
ret.set_returnvalue("Failed to run/parse the COFF file\n");
std::string errorMsg;
ok &= expect(module.errorCodeToMsg(ret, errorMsg) == 0, "COFF execution failure should map error text");
ok &= expect(errorMsg == ret.returnvalue(), "COFF execution error text should come from returnvalue");
}
return ok ? 0 : 1;
}
+1474 -1426
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -14,6 +14,7 @@ public:
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int errorCodeToMsg(const C2Message& c2RetMessage, std::string& errorMsg) override;
int osCompatibility()
{
return OS_WINDOWS;
+11
View File
@@ -39,5 +39,16 @@ int main()
ok &= expect(module.init(cmd, message) == -1, "ReadMemory should reject missing size");
}
{
Evasion module;
C2Message ret;
ret.set_errorCode(1);
ret.set_returnvalue("Error opening remote process and thread.");
std::string errorMsg;
ok &= expect(module.errorCodeToMsg(ret, errorMsg) == 0, "evasion execution failure should map error text");
ok &= expect(errorMsg == ret.returnvalue(), "evasion execution error text should come from returnvalue");
}
return ok ? 0 : 1;
}
+25
View File
@@ -11,6 +11,12 @@ using namespace std;
constexpr std::string_view moduleName = "inject";
constexpr unsigned long long moduleHash = djb2(moduleName);
namespace
{
constexpr int ERROR_OPEN_PROCESS = 1;
constexpr int ERROR_CREATE_PROCESS = 2;
}
#ifdef _WIN32
#include <tlhelp32.h>
@@ -423,8 +429,27 @@ int Inject::process(C2Message &c2Message, C2Message &c2RetMessage)
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_cmd(c2Message.cmd());
if (result.find("OpenProcess failed.") != std::string::npos)
{
c2RetMessage.set_errorCode(ERROR_OPEN_PROCESS);
}
else if (result.find("CreateProcess failed.") != std::string::npos)
{
c2RetMessage.set_errorCode(ERROR_CREATE_PROCESS);
}
c2RetMessage.set_returnvalue(result);
return 0;
}
int Inject::errorCodeToMsg(const C2Message &c2RetMessage, std::string &errorMsg)
{
#if defined(BUILD_TEAMSERVER) || defined(C2CORE_BUILD_TESTS) || defined(C2CORE_BUILD_FUNCTIONAL_TESTS)
if (c2RetMessage.errorCode() > 0)
{
errorMsg = c2RetMessage.returnvalue();
}
#endif
return 0;
}
+1
View File
@@ -18,6 +18,7 @@ public:
int initConfig(const nlohmann::json &config);
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int errorCodeToMsg(const C2Message& c2RetMessage, std::string& errorMsg) override;
int osCompatibility()
{
return OS_WINDOWS;
+8
View File
@@ -239,7 +239,11 @@ int main()
C2Message retMessage;
ok &= expect(module.process(message, retMessage) == 0, "process should return normally for an invalid pid");
ok &= expect(retMessage.errorCode() > 0, "invalid pid should set an error code");
ok &= expect(retMessage.returnvalue() == "OpenProcess failed.", "invalid pid should report OpenProcess failure");
std::string errorMsg;
ok &= expect(module.errorCodeToMsg(retMessage, errorMsg) == 0, "invalid pid should map error text");
ok &= expect(errorMsg == retMessage.returnvalue(), "invalid pid error text should come from returnvalue");
}
{
@@ -255,7 +259,11 @@ int main()
C2Message retMessage;
ok &= expect(module.process(message, retMessage) == 0, "spawn injection failure path should return normally");
ok &= expect(retMessage.errorCode() > 0, "invalid spawn target should set an error code");
ok &= expect(retMessage.returnvalue() == "CreateProcess failed.", "invalid spawn target should report CreateProcess failure");
std::string errorMsg;
ok &= expect(module.errorCodeToMsg(retMessage, errorMsg) == 0, "invalid spawn target should map error text");
ok &= expect(errorMsg == retMessage.returnvalue(), "invalid spawn target error text should come from returnvalue");
}
{
+30 -2
View File
@@ -13,6 +13,11 @@ using namespace std;
constexpr std::string_view moduleName = "ls";
constexpr unsigned long long moduleHash = djb2(moduleName);
namespace
{
constexpr int ERROR_LIST_DIRECTORY = 1;
}
#ifdef _WIN32
@@ -83,11 +88,26 @@ int ListDirectory::process(C2Message &c2Message, C2Message &c2RetMessage)
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_cmd(path);
if (outCmd.find("Error:") == 0)
{
c2RetMessage.set_errorCode(ERROR_LIST_DIRECTORY);
}
c2RetMessage.set_returnvalue(outCmd);
return 0;
}
int ListDirectory::errorCodeToMsg(const C2Message &c2RetMessage, std::string &errorMsg)
{
#if defined(BUILD_TEAMSERVER) || defined(C2CORE_BUILD_TESTS) || defined(C2CORE_BUILD_FUNCTIONAL_TESTS)
if (c2RetMessage.errorCode() > 0)
{
errorMsg = c2RetMessage.returnvalue();
}
#endif
return 0;
}
struct HumanReadable {
std::uintmax_t size{};
private: friend
@@ -127,10 +147,18 @@ std::string ListDirectory::listDirectory(const std::string& path)
if(actualPath.empty())
actualPath=std::filesystem::current_path().string();
std::error_code e;
if (!std::filesystem::exists(actualPath, e))
{
result += "Error: ";
result += e ? e.message() : "path does not exist";
result += "\n";
return result;
}
result += actualPath;
result += ":\n";
std::error_code e;
for (const filesystem::directory_entry& file : filesystem::directory_iterator(actualPath, e))
{
try
@@ -188,4 +216,4 @@ std::string ListDirectory::listDirectory(const std::string& path)
}
return result;
}
}
+1
View File
@@ -14,6 +14,7 @@ public:
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int errorCodeToMsg(const C2Message& c2RetMessage, std::string& errorMsg) override;
int osCompatibility()
{
return OS_LINUX | OS_WINDOWS;
@@ -72,7 +72,11 @@ bool testListDirectory()
c2Message.set_cmd(invalidPath);
listDirectory->process(c2Message, c2RetMessage);
std::cout << "invalid result: \n" << c2RetMessage.returnvalue() << std::endl;
if (c2RetMessage.returnvalue() != invalidPath + ":\n") {
std::string errorMsg;
listDirectory->errorCodeToMsg(c2RetMessage, errorMsg);
if (c2RetMessage.errorCode() <= 0
|| c2RetMessage.returnvalue().find("Error:") != 0
|| errorMsg != c2RetMessage.returnvalue()) {
ok = false;
}
}
+46 -7
View File
@@ -42,6 +42,14 @@ __attribute__((visibility("default"))) Script * ScriptConstructor()
namespace
{
constexpr int ERROR_SCRIPT_EXECUTION = 1;
constexpr int ERROR_UNSUPPORTED_SCRIPT_TYPE = 2;
constexpr int ERROR_TEMP_SCRIPT_PATH = 3;
constexpr int ERROR_TEMP_SCRIPT_WRITE = 4;
constexpr int ERROR_CREATE_PIPE = 5;
constexpr int ERROR_SET_HANDLE_INFO = 6;
constexpr int ERROR_CREATE_PROCESS = 7;
#ifdef _WIN32
bool hasWindowsScriptExtension(const std::string& path)
{
@@ -75,7 +83,7 @@ namespace
return tempPath.string();
}
std::string runWindowsScriptFile(const std::string& scriptPath)
std::string runWindowsScriptFile(const std::string& scriptPath, int& errorCode)
{
std::string result;
@@ -88,12 +96,14 @@ namespace
HANDLE pipeWrite = nullptr;
if (!CreatePipe(&pipeRead, &pipeWrite, &securityAttributes, 0))
{
errorCode = ERROR_CREATE_PIPE;
return "CreatePipe failed.";
}
if (!SetHandleInformation(pipeRead, HANDLE_FLAG_INHERIT, 0))
{
CloseHandle(pipeRead);
CloseHandle(pipeWrite);
errorCode = ERROR_SET_HANDLE_INFO;
return "SetHandleInformation failed.";
}
@@ -135,6 +145,7 @@ namespace
if (!created)
{
CloseHandle(pipeRead);
errorCode = ERROR_CREATE_PROCESS;
return "CreateProcess failed.";
}
@@ -221,6 +232,7 @@ int Script::process(C2Message &c2Message, C2Message &c2RetMessage)
const std::string script = c2Message.data();
std::string result;
int errorCode = 0;
#ifdef __linux__
@@ -229,11 +241,15 @@ int Script::process(C2Message &c2Message, C2Message &c2RetMessage)
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(script.c_str(), "r"), pclose);
if (!pipe)
{
throw std::runtime_error("popen() filed!");
result = "popen() failed.";
errorCode = ERROR_SCRIPT_EXECUTION;
}
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr)
else
{
result += buffer.data();
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr)
{
result += buffer.data();
}
}
#elif _WIN32
@@ -241,6 +257,7 @@ int Script::process(C2Message &c2Message, C2Message &c2RetMessage)
if (!hasWindowsScriptExtension(c2Message.inputfile()))
{
result = "Unsupported script type on Windows. Use .bat or .cmd.";
errorCode = ERROR_UNSUPPORTED_SCRIPT_TYPE;
}
else
{
@@ -248,21 +265,28 @@ int Script::process(C2Message &c2Message, C2Message &c2RetMessage)
if (tempScriptPath.empty())
{
result = "Failed to create temporary script path.";
errorCode = ERROR_TEMP_SCRIPT_PATH;
}
else
{
{
std::ofstream tempScript(tempScriptPath, std::ios::binary);
tempScript.write(script.data(), static_cast<std::streamsize>(script.size()));
if (!tempScript.good())
{
result = "Failed to write temporary script.";
errorCode = ERROR_TEMP_SCRIPT_WRITE;
}
}
if (!std::filesystem::exists(tempScriptPath))
if (errorCode == 0 && !std::filesystem::exists(tempScriptPath))
{
result = "Failed to write temporary script.";
errorCode = ERROR_TEMP_SCRIPT_WRITE;
}
else
else if (errorCode == 0)
{
result = runWindowsScriptFile(tempScriptPath);
result = runWindowsScriptFile(tempScriptPath, errorCode);
std::error_code ignored;
std::filesystem::remove(tempScriptPath, ignored);
}
@@ -272,7 +296,22 @@ int Script::process(C2Message &c2Message, C2Message &c2RetMessage)
#endif
c2RetMessage.set_instruction(c2Message.instruction());
if (errorCode > 0)
{
c2RetMessage.set_errorCode(errorCode);
}
c2RetMessage.set_returnvalue(result);
return 0;
}
int Script::errorCodeToMsg(const C2Message &c2RetMessage, std::string &errorMsg)
{
#if defined(BUILD_TEAMSERVER) || defined(C2CORE_BUILD_TESTS) || defined(C2CORE_BUILD_FUNCTIONAL_TESTS)
if (c2RetMessage.errorCode() > 0)
{
errorMsg = c2RetMessage.returnvalue();
}
#endif
return 0;
}
+1
View File
@@ -14,6 +14,7 @@ public:
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int errorCodeToMsg(const C2Message& c2RetMessage, std::string& errorMsg) override;
int osCompatibility()
{
return OS_LINUX | OS_WINDOWS;
+4
View File
@@ -98,7 +98,11 @@ int main()
ok &= expect(module.init(cmd, message) == 0, "unsupported Windows script extension should still be transportable");
ok &= expect(module.process(message, ret) == 0, "unsupported Windows script extension should return cleanly");
ok &= expect(ret.errorCode() > 0, "unsupported Windows script extension should set an error code");
ok &= expectContains(ret.returnvalue(), "Unsupported script type on Windows", "unsupported Windows script extension should explain the rule");
std::string errorMsg;
ok &= expect(module.errorCodeToMsg(ret, errorMsg) == 0, "unsupported Windows script extension should map error text");
ok &= expect(errorMsg == ret.returnvalue(), "unsupported Windows script error text should come from returnvalue");
std::filesystem::remove(script);
}
#endif
+8
View File
@@ -94,6 +94,12 @@ int Shell::followUp(const C2Message &c2RetMessage)
int Shell::errorCodeToMsg(const C2Message &c2RetMessage, std::string &errorMsg)
{
if(c2RetMessage.errorCode() > 0)
{
errorMsg = c2RetMessage.returnvalue().empty()
? "Failed to start shell."
: c2RetMessage.returnvalue();
}
return 0;
}
@@ -211,6 +217,7 @@ int Shell::process(C2Message &c2Message, C2Message &c2RetMessage)
if(startShell() != 0)
{
c2RetMessage.set_errorCode(1);
c2RetMessage.set_returnvalue("Failed to start shell.");
return 0;
}
if(cmd.empty())
@@ -279,6 +286,7 @@ int Shell::process(C2Message &c2Message, C2Message &c2RetMessage)
if(startShell() != 0)
{
c2RetMessage.set_errorCode(1);
c2RetMessage.set_returnvalue("Failed to start shell.");
return 0;
}
if(cmd.empty())
+3
View File
@@ -108,6 +108,9 @@ int main()
C2Message ret;
branchOk &= test_helpers::expect(shell.process(message, ret) == 0, "missing shell process should return through C2Message");
branchOk &= test_helpers::expect(ret.errorCode() == 1, "missing shell program should set error code 1");
std::string errorMsg;
branchOk &= test_helpers::expect(shell.errorCodeToMsg(ret, errorMsg) == 0, "missing shell program should map error text");
branchOk &= test_helpers::expect(errorMsg.find("Failed to start shell") != std::string::npos, "missing shell program should expose process error text");
ok &= branchOk;
}
#endif
+12
View File
@@ -119,6 +119,14 @@ namespace
constexpr std::string_view moduleName = "spawnAs";
constexpr unsigned long long moduleHash = djb2(moduleName);
namespace
{
constexpr int ERROR_INVALID_PARAMETERS = 1;
constexpr int ERROR_MISSING_COMMAND = 2;
constexpr int ERROR_UNSUPPORTED_PLATFORM = 3;
constexpr int ERROR_PROCESS_CREATION = 4;
}
#ifdef _WIN32
@@ -417,6 +425,7 @@ int SpawnAs::process(C2Message &c2Message, C2Message &c2RetMessage)
if (splitedList.size() < 3)
{
c2RetMessage.set_returnvalue("Invalid command parameters received.\n");
c2RetMessage.set_errorCode(ERROR_INVALID_PARAMETERS);
return -1;
}
@@ -431,6 +440,7 @@ int SpawnAs::process(C2Message &c2Message, C2Message &c2RetMessage)
#ifdef __linux__
result = "Only supported on Windows.\n";
c2RetMessage.set_errorCode(ERROR_UNSUPPORTED_PLATFORM);
#elif _WIN32
@@ -442,6 +452,7 @@ int SpawnAs::process(C2Message &c2Message, C2Message &c2RetMessage)
if (commandLineW.empty())
{
c2RetMessage.set_returnvalue("Missing command to execute.\n");
c2RetMessage.set_errorCode(ERROR_MISSING_COMMAND);
return -1;
}
@@ -680,6 +691,7 @@ int SpawnAs::process(C2Message &c2Message, C2Message &c2RetMessage)
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_cmd(cmd);
c2RetMessage.set_returnvalue(result);
c2RetMessage.set_errorCode(ERROR_PROCESS_CREATION);
return 0;
}
+14
View File
@@ -57,5 +57,19 @@ int main()
ok &= expect(module.init(cmd, message) == -1, "missing command should be rejected");
}
{
SpawnAs module;
C2Message message;
message.set_cmd("alice");
C2Message ret;
ok &= expect(module.process(message, ret) == -1, "invalid packed parameters should be rejected");
ok &= expect(ret.errorCode() > 0, "invalid packed parameters should set an error code");
ok &= expect(ret.returnvalue().find("Invalid command parameters") != std::string::npos, "invalid packed parameters should explain the error");
std::string errorMsg;
ok &= expect(module.errorCodeToMsg(ret, errorMsg) == 0, "invalid packed parameters should map error text");
ok &= expect(errorMsg == ret.returnvalue(), "invalid packed parameter error text should come from returnvalue");
}
return ok ? 0 : 1;
}
+29 -1
View File
@@ -14,6 +14,11 @@ using namespace std;
constexpr std::string_view moduleName = "tree";
constexpr unsigned long long moduleHash = djb2(moduleName);
namespace
{
constexpr int ERROR_TREE_DIRECTORY = 1;
}
#ifdef _WIN32
@@ -84,11 +89,26 @@ int Tree::process(C2Message &c2Message, C2Message &c2RetMessage)
c2RetMessage.set_instruction(c2RetMessage.instruction());
c2RetMessage.set_cmd(path);
if (outCmd.find("Error:") == 0)
{
c2RetMessage.set_errorCode(ERROR_TREE_DIRECTORY);
}
c2RetMessage.set_returnvalue(outCmd);
return 0;
}
int Tree::errorCodeToMsg(const C2Message &c2RetMessage, std::string &errorMsg)
{
#if defined(BUILD_TEAMSERVER) || defined(C2CORE_BUILD_TESTS) || defined(C2CORE_BUILD_FUNCTIONAL_TESTS)
if (c2RetMessage.errorCode() > 0)
{
errorMsg = c2RetMessage.returnvalue();
}
#endif
return 0;
}
std::string Tree::iterProcess(const std::string& path, int depth)
{
@@ -104,6 +124,14 @@ std::string Tree::iterProcess(const std::string& path, int depth)
actualPath=std::filesystem::current_path().string();
std::error_code e;
if (!std::filesystem::exists(actualPath, e))
{
result += "Error: ";
result += e ? e.message() : "path does not exist";
result += "\n";
return result;
}
for (const filesystem::directory_entry& file : filesystem::directory_iterator(actualPath, e))
{
try
@@ -144,4 +172,4 @@ std::string Tree::iterProcess(const std::string& path, int depth)
}
return result;
}
}
+1
View File
@@ -14,6 +14,7 @@ public:
int init(std::vector<std::string>& splitedCmd, C2Message& c2Message);
int process(C2Message& c2Message, C2Message& c2RetMessage);
int errorCodeToMsg(const C2Message& c2RetMessage, std::string& errorMsg) override;
int osCompatibility()
{
return OS_LINUX | OS_WINDOWS;
+5 -1
View File
@@ -79,7 +79,11 @@ bool testTree()
tree->init(cmd, msg);
msg.set_cmd(invalid.string());
tree->process(msg, ret);
ok &= ret.returnvalue().empty();
std::string errorMsg;
tree->errorCodeToMsg(ret, errorMsg);
ok &= ret.errorCode() > 0;
ok &= ret.returnvalue().find("Error:") == 0;
ok &= errorMsg == ret.returnvalue();
}
// ----- no argument -----