diff --git a/source/agent-remote/common.sh b/source/agent-remote/common.sh index a93815f..554d7db 100755 --- a/source/agent-remote/common.sh +++ b/source/agent-remote/common.sh @@ -153,7 +153,7 @@ _get_container_logs() { _check_required_env_vars() { local required_vars=("$@") for var in "${required_vars[@]}"; do - if [ -z "${!var}" ]; then + if [ -z "${!var:-}" ]; then _die "Required environment variable $var is not set" fi done diff --git a/source/agent-remote/datacommands.sh b/source/agent-remote/datacommands.sh index 12a1087..d006710 100755 --- a/source/agent-remote/datacommands.sh +++ b/source/agent-remote/datacommands.sh @@ -118,8 +118,8 @@ _autocommandrun_file() { echo "Restoring file ${filepath}" local file_name; file_name=$(basename "${filepath}") - rm -f "${filepath}" || die "Unable to remove existing file ${filepath}, restore failed." - cp "${backup_folder}/${file_name}" "${filepath}" || die "Unable to copy file ${backup_folder}/${file_name} to ${filepath}, restore failed." + rm -f "${filepath}" || return_die "Unable to remove existing file ${filepath}, restore failed." + cp "${backup_folder}/${file_name}" "${filepath}" || return_die "Unable to copy file ${backup_folder}/${file_name} to ${filepath}, restore failed." ;; esac } diff --git a/source/install_build_prerequisites.sh b/source/install_build_prerequisites.sh index 63d1bb1..8c051a3 100755 --- a/source/install_build_prerequisites.sh +++ b/source/install_build_prerequisites.sh @@ -64,7 +64,9 @@ esac # Function to check if a package is installed is_package_installed() { if [ "$OS" = "Alpine Linux" ]; then - apk info | grep -q "^$1$" + # Use apk info and check exit status + apk info "$1" >/dev/null 2>&1 + return $? else dpkg -l "$1" 2>/dev/null | grep -q "^ii" fi diff --git a/source/src/commands/create-service.cpp b/source/src/commands/create-service.cpp index 1ab81a7..6d51cc2 100644 --- a/source/src/commands/create-service.cpp +++ b/source/src/commands/create-service.cpp @@ -103,6 +103,11 @@ namespace dropshell if (server_name.empty() || template_name.empty() || service_name.empty()) return false; + if (!legal_service_name(service_name)) { + error << "Service name contains illegal characters: " << service_name << std::endl; + return false; + } + ServerConfig server_info(server_name); if (!server_info.is_valid()) { diff --git a/source/src/commands/edit.cpp b/source/src/commands/edit.cpp index 312bd9c..968bcc0 100644 --- a/source/src/commands/edit.cpp +++ b/source/src/commands/edit.cpp @@ -94,11 +94,11 @@ int edit_config() std::string config_file = localfile::dropshell_json(); if (!edit_file(config_file, false) || !std::filesystem::exists(config_file)) - return die("Failed to edit config file."); + return return_die("Failed to edit config file."); gConfig().load_config(); if (!gConfig().is_config_set()) - return die("Failed to load and parse edited config file!"); + return return_die("Failed to load and parse edited config file!"); gConfig().save_config(true); diff --git a/source/src/commands/ssh.cpp b/source/src/commands/ssh.cpp index f2361b6..b411f25 100644 --- a/source/src/commands/ssh.cpp +++ b/source/src/commands/ssh.cpp @@ -61,6 +61,12 @@ namespace dropshell return false; } + if (!legal_service_name(service)) + { + error << "Service name contains illegal characters: " << service << std::endl; + return false; + } + LocalServiceInfo sinfo = get_service_info(server, service); if (!SIvalid(sinfo)) { diff --git a/source/src/commands/start.cpp b/source/src/commands/start.cpp index 8720422..1dd09f4 100644 --- a/source/src/commands/start.cpp +++ b/source/src/commands/start.cpp @@ -51,6 +51,12 @@ namespace dropshell return false; } + if (!legal_service_name(service)) + { + error << "Service name contains illegal characters: " << service << std::endl; + return false; + } + // run the start script. bool started = server_env.run_remote_template_command(service, "start", {}, false, {}); diff --git a/source/src/commands/stop.cpp b/source/src/commands/stop.cpp index 039a932..13f4cfe 100644 --- a/source/src/commands/stop.cpp +++ b/source/src/commands/stop.cpp @@ -51,6 +51,12 @@ namespace dropshell return false; } + if (!legal_service_name(service)) + { + error << "Service name contains illegal characters: " << service << std::endl; + return false; + } + // run the stop script. bool stopped = server_env.run_remote_template_command(service, "stop", {}, false, {}); diff --git a/source/src/servers.cpp b/source/src/servers.cpp index cd78781..39aaf38 100644 --- a/source/src/servers.cpp +++ b/source/src/servers.cpp @@ -149,12 +149,20 @@ namespace dropshell std::string get_user_for_service(const std::string &server, const std::string &service) { + if (!legal_service_name(service)) + { + error << "Service name contains illegal characters: " + service << std::endl; + return ""; + } + auto services_info = get_server_services_info(server); auto it = std::find_if(services_info.begin(), services_info.end(), [&service](const LocalServiceInfo &si) { return si.service_name == service; }); if (it != services_info.end() && SIvalid(*it)) return it->user; + + debug << "Couldn't find user for service \"" << service << "\" on server \"" << server << "\"" << std::endl; return ""; } diff --git a/source/src/services.cpp b/source/src/services.cpp index 0e79267..114a865 100644 --- a/source/src/services.cpp +++ b/source/src/services.cpp @@ -80,6 +80,9 @@ namespace dropshell if (server_name.empty() || service_name.empty()) return LocalServiceInfo(); + if (!legal_service_name(service_name)) + return LocalServiceInfo(); + service.service_name = service_name; service.local_service_path = localpath::service(server_name, service_name); diff --git a/source/src/templates.cpp b/source/src/templates.cpp index 5c803db..4073f70 100644 --- a/source/src/templates.cpp +++ b/source/src/templates.cpp @@ -171,6 +171,11 @@ bool template_manager::create_template(const std::string &template_name) const { + if (!legal_service_name(template_name)) { + error << "Template name contains illegal characters: " << template_name << std::endl; + return false; + } + // 1. Create a new directory in the user templates directory std::vector local_server_definition_paths = gConfig().get_local_server_definition_paths(); diff --git a/source/src/utils/utils.cpp b/source/src/utils/utils.cpp index bd5373c..77f9444 100644 --- a/source/src/utils/utils.cpp +++ b/source/src/utils/utils.cpp @@ -312,7 +312,7 @@ std::string requote(std::string str) { } -int die(const std::string & msg) { +int return_die(const std::string & msg) { error << "Fatal error:" << std::endl; error << msg << std::endl; return 1; @@ -650,4 +650,11 @@ bool file_replace_or_add_segment(std::string filepath, std::string segment) return true; } +bool legal_service_name(const std::string &service_name) +{ + // legal characters are alphanumeric, and - and _ + std::regex legal_chars("^[a-zA-Z0-9_-]+$"); + return std::regex_match(service_name, legal_chars); +} + } // namespace dropshell \ No newline at end of file diff --git a/source/src/utils/utils.hpp b/source/src/utils/utils.hpp index a97d5c7..a2c56e6 100644 --- a/source/src/utils/utils.hpp +++ b/source/src/utils/utils.hpp @@ -45,7 +45,7 @@ int count_substring(const std::string &substring, const std::string &text); std::string random_alphanumeric_string(int length); -int die(const std::string & msg); +int return_die(const std::string & msg); std::string safearg(int argc, char *argv[], int index); std::string safearg(const std::vector & args, int index); @@ -75,4 +75,7 @@ constexpr unsigned int switchhash(const char *s, int off = 0) return !s[off] ? 5381 : (switchhash(s, off + 1) * 33) ^ s[off]; } +bool legal_service_name(const std::string & service_name); + + } // namespace dropshell \ No newline at end of file