Fixed ssh commands.
This commit is contained in:
parent
bcf0f18006
commit
1d2e223547
@ -12,28 +12,34 @@
|
|||||||
#include "contrib/base64.hpp"
|
#include "contrib/base64.hpp"
|
||||||
#include "utils/utils.hpp"
|
#include "utils/utils.hpp"
|
||||||
|
|
||||||
|
bool EXITSTATUSCHECK(int ret)
|
||||||
bool EXITSTATUSCHECK(int ret) {
|
{
|
||||||
return (ret != -1 && WIFEXITED(ret) && (WEXITSTATUS(ret) == 0)); // ret is -1 if the command failed to execute.
|
return (ret != -1 && WIFEXITED(ret) && (WEXITSTATUS(ret) == 0)); // ret is -1 if the command failed to execute.
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace dropshell {
|
namespace dropshell
|
||||||
bool execute_local_command_interactive(const sCommand &command)
|
|
||||||
{
|
{
|
||||||
|
bool execute_local_command_interactive(const sCommand &command)
|
||||||
|
{
|
||||||
if (command.get_command_to_run().empty())
|
if (command.get_command_to_run().empty())
|
||||||
return false;
|
return false;
|
||||||
std::string full_command = command.construct_cmd(cStyle::Raw); // Get the command string
|
std::string full_command = command.construct_cmd(cStyle::Raw); // Get the command string
|
||||||
|
|
||||||
pid_t pid = fork();
|
pid_t pid = fork();
|
||||||
|
|
||||||
if (pid == -1) {
|
if (pid == -1)
|
||||||
|
{
|
||||||
// Fork failed
|
// Fork failed
|
||||||
perror("fork failed");
|
perror("fork failed");
|
||||||
return false;
|
return false;
|
||||||
} else if (pid == 0) {
|
}
|
||||||
|
else if (pid == 0)
|
||||||
|
{
|
||||||
int rval = system(full_command.c_str());
|
int rval = system(full_command.c_str());
|
||||||
exit(rval);
|
exit(rval);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Parent process
|
// Parent process
|
||||||
int ret;
|
int ret;
|
||||||
// Wait for the child process to complete
|
// Wait for the child process to complete
|
||||||
@ -41,40 +47,44 @@ bool execute_local_command_interactive(const sCommand &command)
|
|||||||
|
|
||||||
return EXITSTATUSCHECK(ret);
|
return EXITSTATUSCHECK(ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool execute_local_command_and_capture_output(const sCommand& command, std::string * output)
|
bool execute_local_command_and_capture_output(const sCommand &command, std::string *output)
|
||||||
{
|
{
|
||||||
ASSERT(output != nullptr, "Output string must be provided");
|
ASSERT(output != nullptr, "Output string must be provided");
|
||||||
if (command.get_command_to_run().empty())
|
if (command.get_command_to_run().empty())
|
||||||
return false;
|
return false;
|
||||||
cStyle style = cStyle::Raw;
|
cStyle style = cStyle::Raw;
|
||||||
std::string full_cmd = command.construct_cmd(style) + " 2>&1";
|
std::string full_cmd = command.construct_cmd(style) + " 2>&1";
|
||||||
FILE *pipe = popen(full_cmd.c_str(), "r");
|
FILE *pipe = popen(full_cmd.c_str(), "r");
|
||||||
if (!pipe) {
|
if (!pipe)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
while (fgets(buffer, sizeof(buffer), pipe) != nullptr) {
|
while (fgets(buffer, sizeof(buffer), pipe) != nullptr)
|
||||||
|
{
|
||||||
(*output) += buffer;
|
(*output) += buffer;
|
||||||
}
|
}
|
||||||
int ret = pclose(pipe);
|
int ret = pclose(pipe);
|
||||||
return EXITSTATUSCHECK(ret);
|
return EXITSTATUSCHECK(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool execute_local_command(const sCommand & command, std::string * output /* = nullptr */, cMode mode /* = cMode::None */)
|
bool execute_local_command(const sCommand &command, std::string *output /* = nullptr */, cMode mode /* = cMode::None */)
|
||||||
{
|
{
|
||||||
ASSERT(hasFlag(mode, cMode::RawCommand), "Raw command mode is required for local command execution");
|
ASSERT(hasFlag(mode, cMode::RawCommand), "Raw command mode is required for local command execution");
|
||||||
|
|
||||||
if (hasFlag(mode, cMode::Interactive)) {
|
if (hasFlag(mode, cMode::Interactive))
|
||||||
ASSERT(! hasFlag(mode, cMode::CaptureOutput), "Interactive mode and capture output mode cannot be used together");
|
{
|
||||||
|
ASSERT(!hasFlag(mode, cMode::CaptureOutput), "Interactive mode and capture output mode cannot be used together");
|
||||||
ASSERT(output == nullptr, "Interactive mode and an output string cannot be used together");
|
ASSERT(output == nullptr, "Interactive mode and an output string cannot be used together");
|
||||||
ASSERT(is_raw(mode), "Interactive mode requires raw command mode");
|
ASSERT(is_raw(mode), "Interactive mode requires raw command mode");
|
||||||
|
|
||||||
return execute_local_command_interactive(command);
|
return execute_local_command_interactive(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasFlag(mode, cMode::CaptureOutput)) {
|
if (hasFlag(mode, cMode::CaptureOutput))
|
||||||
|
{
|
||||||
ASSERT(output != nullptr, "Capture output mode requires an output string to be provided");
|
ASSERT(output != nullptr, "Capture output mode requires an output string to be provided");
|
||||||
ASSERT(is_raw(mode), "Capture output mode requires raw command mode");
|
ASSERT(is_raw(mode), "Capture output mode requires raw command mode");
|
||||||
ASSERT(!hasFlag(mode, cMode::Silent), "Silent mode is not allowed with capture output mode");
|
ASSERT(!hasFlag(mode, cMode::Silent), "Silent mode is not allowed with capture output mode");
|
||||||
@ -90,15 +100,16 @@ bool execute_local_command(const sCommand & command, std::string * output /* = n
|
|||||||
int ret = system(full_cmd.c_str());
|
int ret = system(full_cmd.c_str());
|
||||||
|
|
||||||
bool ok = EXITSTATUSCHECK(ret);
|
bool ok = EXITSTATUSCHECK(ret);
|
||||||
if (!ok) {
|
if (!ok)
|
||||||
|
{
|
||||||
std::cerr << "Error: Failed to execute command: " << std::endl;
|
std::cerr << "Error: Failed to execute command: " << std::endl;
|
||||||
std::cerr << full_cmd << std::endl;
|
std::cerr << full_cmd << std::endl;
|
||||||
}
|
}
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool execute_ssh_command(const sSSHInfo &ssh_info, const sCommand &command, cMode mode, std::string *output)
|
bool execute_ssh_command(const sSSHInfo &ssh_info, const sCommand &command, cMode mode, std::string *output)
|
||||||
{
|
{
|
||||||
if (command.get_command_to_run().empty())
|
if (command.get_command_to_run().empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -115,47 +126,54 @@ bool execute_ssh_command(const sSSHInfo &ssh_info, const sCommand &command, cMod
|
|||||||
cMode localmode = mode + cMode::RawCommand;
|
cMode localmode = mode + cMode::RawCommand;
|
||||||
bool rval = execute_local_command(ssh_command, output, localmode);
|
bool rval = execute_local_command(ssh_command, output, localmode);
|
||||||
|
|
||||||
if (!rval) {
|
if (!rval)
|
||||||
std::cerr <<std::endl<<std::endl;
|
{
|
||||||
|
std::cerr << std::endl
|
||||||
|
<< std::endl;
|
||||||
std::cerr << "Error: Failed to execute ssh command:" << std::endl;
|
std::cerr << "Error: Failed to execute ssh command:" << std::endl;
|
||||||
std::cerr << "\033[90m" << ssh_command.get_command_to_run() << "\033[0m" << std::endl;
|
std::cerr << "\033[90m" << ssh_command.get_command_to_run() << "\033[0m" << std::endl;
|
||||||
std::cerr <<std::endl<<std::endl;
|
std::cerr << std::endl
|
||||||
|
<< std::endl;
|
||||||
}
|
}
|
||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string makesafecmd(const std::string &command)
|
std::string makesafecmd(const std::string &command)
|
||||||
{
|
{
|
||||||
if (command.empty())
|
if (command.empty())
|
||||||
return "";
|
return "";
|
||||||
std::string encoded = base64_encode(dequote(trim(command)));
|
std::string encoded = base64_encode(dequote(trim(command)));
|
||||||
std::string commandstr = "echo " + encoded + " | base64 -d | bash";
|
std::string commandstr = "echo " + encoded + " | base64 -d | bash";
|
||||||
return commandstr;
|
return commandstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string sCommand::construct_cmd(cStyle style) const
|
std::string sCommand::construct_cmd(cStyle style) const
|
||||||
{
|
{
|
||||||
if (mCmd.empty())
|
if (mCmd.empty())
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
|
if (mDir.empty() && mVars.empty())
|
||||||
|
return (is_safe(style) ? makesafecmd(mCmd) : mCmd);
|
||||||
|
|
||||||
|
|
||||||
|
// need to construct to change directory and set environment variables
|
||||||
std::string cmdstr;
|
std::string cmdstr;
|
||||||
cmdstr += "bash -c '";
|
|
||||||
|
|
||||||
if (!mDir.empty())
|
if (!mDir.empty())
|
||||||
cmdstr += "cd " + quote(mDir) + " && ";
|
cmdstr += "cd " + quote(mDir) + " ; ";
|
||||||
|
|
||||||
for (const auto& env_var : mVars) {
|
if (!mVars.empty())
|
||||||
|
for (const auto &env_var : mVars)
|
||||||
cmdstr += env_var.first + "=" + quote(dequote(trim(env_var.second))) + " ";
|
cmdstr += env_var.first + "=" + quote(dequote(trim(env_var.second))) + " ";
|
||||||
}
|
|
||||||
|
|
||||||
cmdstr += mCmd;
|
cmdstr += mCmd;
|
||||||
|
|
||||||
cmdstr += "'";
|
|
||||||
|
|
||||||
if (is_safe(style))
|
if (is_safe(style))
|
||||||
cmdstr = makesafecmd(cmdstr);
|
cmdstr = makesafecmd(cmdstr);
|
||||||
|
else
|
||||||
|
cmdstr = "bash -c '" + cmdstr + "'";
|
||||||
|
|
||||||
return cmdstr;
|
return cmdstr;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace dropshell
|
} // namespace dropshell
|
Loading…
x
Reference in New Issue
Block a user