From a4697b61c600e6b85402d0f91173e252b2784d1e Mon Sep 17 00:00:00 2001 From: Michael Friedrich Date: Thu, 30 Oct 2014 20:34:33 +0100 Subject: [PATCH] Cli: Chown certificate dirs/files to the icinga user in agent setup/wizard fixes #7476 refs #7465 refs #7423 --- lib/cli/agentsetupcommand.cpp | 75 +++++++++++++++++++++- lib/cli/agentwizardcommand.cpp | 113 ++++++++++++++++++++++++++++++--- lib/cli/agentwizardcommand.hpp | 2 + 3 files changed, 177 insertions(+), 13 deletions(-) diff --git a/lib/cli/agentsetupcommand.cpp b/lib/cli/agentsetupcommand.cpp index 5c7221125..2c4dbf4fa 100644 --- a/lib/cli/agentsetupcommand.cpp +++ b/lib/cli/agentsetupcommand.cpp @@ -21,6 +21,7 @@ #include "cli/agentutility.hpp" #include "cli/featureutility.hpp" #include "cli/pkiutility.hpp" +#include "cli/variableutility.hpp" #include "base/logger.hpp" #include "base/console.hpp" #include "base/application.hpp" @@ -132,6 +133,14 @@ int AgentSetupCommand::SetupMaster(const boost::program_options::variables_map& return 1; } + String user = VariableUtility::GetVariable("RunAsUser"); + String group = VariableUtility::GetVariable("RunAsUser"); + + if (!Utility::SetFileOwnership(pki_path, user, group)) { + Log(LogWarning, "cli") + << "Cannot set ownership for user '" << user << "' group '" << group << "' on file '" << pki_path << "'. Verify it yourself!"; + } + String cn = Utility::GetFQDN(); if (vm.count("cn")) @@ -155,8 +164,9 @@ int AgentSetupCommand::SetupMaster(const boost::program_options::variables_map& } /* Copy CA certificate to /etc/icinga2/pki */ - - String ca = PkiUtility::GetLocalCaPath() + "/ca.crt"; + String ca_path = PkiUtility::GetLocalCaPath(); + String ca = ca_path + "/ca.crt"; + String ca_key = ca_path + "/ca.key"; String target_ca = pki_path + "/ca.crt"; Log(LogInformation, "cli") @@ -165,7 +175,31 @@ int AgentSetupCommand::SetupMaster(const boost::program_options::variables_map& /* does not overwrite existing files! */ Utility::CopyFile(ca, target_ca); - //TODO: Fix permissions for CA dir (root -> icinga) + /* fix permissions: root -> icinga daemon user */ + if (!Utility::SetFileOwnership(ca_path, user, group)) { + Log(LogWarning, "cli") + << "Cannot set ownership for user '" << user << "' group '" << group << "' on file '" << ca_path << "'. Verify it yourself!"; + } + if (!Utility::SetFileOwnership(ca, user, group)) { + Log(LogWarning, "cli") + << "Cannot set ownership for user '" << user << "' group '" << group << "' on file '" << ca << "'. Verify it yourself!"; + } + if (!Utility::SetFileOwnership(ca_key, user, group)) { + Log(LogWarning, "cli") + << "Cannot set ownership for user '" << user << "' group '" << group << "' on file '" << ca_key << "'. Verify it yourself!"; + } + if (!Utility::SetFileOwnership(target_ca, user, group)) { + Log(LogWarning, "cli") + << "Cannot set ownership for user '" << user << "' group '" << group << "' on file '" << target_ca << "'. Verify it yourself!"; + } + if (!Utility::SetFileOwnership(key, user, group)) { + Log(LogWarning, "cli") + << "Cannot set ownership for user '" << user << "' group '" << group << "' on file '" << key << "'. Verify it yourself!"; + } + if (!Utility::SetFileOwnership(csr, user, group)) { + Log(LogWarning, "cli") + << "Cannot set ownership for user '" << user << "' group '" << group << "' on file '" << csr << "'. Verify it yourself!"; + } /* read zones.conf and update with zone + endpoint information */ @@ -324,11 +358,40 @@ int AgentSetupCommand::SetupAgent(const boost::program_options::variables_map& v String cert = pki_path + "/" + cn + ".crt"; String ca = pki_path + "/ca.crt"; + + if (!Utility::MkDirP(pki_path, 0700)) { + Log(LogCritical, "cli") + << "Could not create local pki directory '" << pki_path << "'."; + return 1; + } + + String user = VariableUtility::GetVariable("RunAsUser"); + String group = VariableUtility::GetVariable("RunAsUser"); + + if (!Utility::SetFileOwnership(pki_path, user, group)) { + Log(LogWarning, "cli") + << "Cannot set ownership for user '" << user << "' group '" << group << "' on file '" << pki_path << "'. Verify it yourself!"; + } + if (PkiUtility::NewCert(cn, key, String(), cert) != 0) { Log(LogCritical, "cli", "Failed to generate new self-signed certificate."); return 1; } + /* fix permissions: root -> icinga daemon user */ + if (!Utility::SetFileOwnership(ca, user, group)) { + Log(LogWarning, "cli") + << "Cannot set ownership for user '" << user << "' group '" << group << "' on file '" << ca << "'. Verify it yourself!"; + } + if (!Utility::SetFileOwnership(cert, user, group)) { + Log(LogWarning, "cli") + << "Cannot set ownership for user '" << user << "' group '" << group << "' on file '" << cert << "'. Verify it yourself!"; + } + if (!Utility::SetFileOwnership(key, user, group)) { + Log(LogWarning, "cli") + << "Cannot set ownership for user '" << user << "' group '" << group << "' on file '" << key << "'. Verify it yourself!"; + } + Log(LogInformation, "cli", "Requesting a signed certificate from the master."); if (PkiUtility::RequestCertificate(master_host, master_port, key, cert, ca, trustedcert, ticket) != 0) { @@ -336,6 +399,12 @@ int AgentSetupCommand::SetupAgent(const boost::program_options::variables_map& v return 1; } + /* fix permissions (again) when updating the signed certificate */ + if (!Utility::SetFileOwnership(cert, user, group)) { + Log(LogWarning, "cli") + << "Cannot set ownership for user '" << user << "' group '" << group << "' on file '" << cert << "'. Verify it yourself!"; + } + /* enable the ApiListener config */ Log(LogInformation, "cli", "Updating the APIListener feature."); diff --git a/lib/cli/agentwizardcommand.cpp b/lib/cli/agentwizardcommand.cpp index df79c56a9..0aa18cae3 100644 --- a/lib/cli/agentwizardcommand.cpp +++ b/lib/cli/agentwizardcommand.cpp @@ -21,6 +21,7 @@ #include "cli/agentutility.hpp" #include "cli/pkiutility.hpp" #include "cli/featureutility.hpp" +#include "cli/variableutility.hpp" #include "base/logger.hpp" #include "base/console.hpp" #include "base/application.hpp" @@ -49,6 +50,16 @@ String AgentWizardCommand::GetShortDescription(void) const return "wizard for agent setup"; } +ImpersonationLevel AgentWizardCommand::GetImpersonationLevel(void) const +{ + return ImpersonateRoot; +} + +int AgentWizardCommand::GetMaxArguments(void) const +{ + return -1; +} + /** * The entry point for the "agent wizard" CLI command. * @@ -115,7 +126,6 @@ int AgentWizardCommand::Run(const boost::program_options::variables_map& vm, con String cn = answer; cn.Trim(); - //TODO: Ask for endpoint config instead, and use that for master_host/port std::vector endpoints; String endpoint_buffer; @@ -202,13 +212,28 @@ wizard_master_host: String master_port = answer; master_port.Trim(); - /* workaround for fetching the master cert - TODO */ - String agent_cert = PkiUtility::GetPkiPath() + "/" + cn + ".crt"; - String agent_key = PkiUtility::GetPkiPath() + "/" + cn + ".key"; + /* workaround for fetching the master cert */ + String pki_path = PkiUtility::GetPkiPath(); + String agent_cert = pki_path + "/" + cn + ".crt"; + String agent_key = pki_path + "/" + cn + ".key"; //new-ca, new-cert PkiUtility::NewCa(); + if (!Utility::MkDirP(pki_path, 0700)) { + Log(LogCritical, "cli") + << "Could not create local pki directory '" << pki_path << "'."; + return 1; + } + + String user = VariableUtility::GetVariable("RunAsUser"); + String group = VariableUtility::GetVariable("RunAsUser"); + + if (!Utility::SetFileOwnership(pki_path, user, group)) { + Log(LogWarning, "cli") + << "Cannot set ownership for user '" << user << "' group '" << group << "' on file '" << pki_path << "'. Verify it yourself!"; + } + if (PkiUtility::NewCert(cn, agent_key, Empty, agent_cert) > 0) { Log(LogCritical, "cli") << "Failed to create new self-signed certificate for CN '" << cn << "'. Please try again."; @@ -216,14 +241,42 @@ wizard_master_host: } /* store ca in /etc/icinga2/pki */ - //TODO FIX chown - String ca = PkiUtility::GetLocalCaPath() + "/ca.crt"; - String pki_path = PkiUtility::GetPkiPath(); + String ca_path = PkiUtility::GetLocalCaPath(); + String ca_key = ca_path + "/ca.key"; + String ca = ca_path + "/ca.crt"; + + /* fix permissions: root -> icinga daemon user */ + if (!Utility::SetFileOwnership(ca_path, user, group)) { + Log(LogWarning, "cli") + << "Cannot set ownership for user '" << user << "' group '" << group << "' on file '" << ca_path << "'. Verify it yourself!"; + } + if (!Utility::SetFileOwnership(ca, user, group)) { + Log(LogWarning, "cli") + << "Cannot set ownership for user '" << user << "' group '" << group << "' on file '" << ca << "'. Verify it yourself!"; + } + if (!Utility::SetFileOwnership(ca_key, user, group)) { + Log(LogWarning, "cli") + << "Cannot set ownership for user '" << user << "' group '" << group << "' on file '" << ca_key << "'. Verify it yourself!"; + } + if (!Utility::SetFileOwnership(agent_cert, user, group)) { + Log(LogWarning, "cli") + << "Cannot set ownership for user '" << user << "' group '" << group << "' on file '" << agent_cert << "'. Verify it yourself!"; + } + if (!Utility::SetFileOwnership(agent_key, user, group)) { + Log(LogWarning, "cli") + << "Cannot set ownership for user '" << user << "' group '" << group << "' on file '" << agent_key << "'. Verify it yourself!"; + } String target_ca = pki_path + "/ca.crt"; Utility::CopyFile(ca, target_ca); + /* fix permissions: root -> icinga daemon user */ + if (!Utility::SetFileOwnership(target_ca, user, group)) { + Log(LogWarning, "cli") + << "Cannot set ownership for user '" << user << "' group '" << group << "' on file '" << target_ca << "'. Verify it yourself!"; + } + //save-cert and store the master certificate somewhere std::cout << "Generating self-signed certifiate:\n"; @@ -264,6 +317,12 @@ wizard_ticket: return 1; } + /* fix permissions (again) when updating the signed certificate */ + if (!Utility::SetFileOwnership(agent_cert, user, group)) { + Log(LogWarning, "cli") + << "Cannot set ownership for user '" << user << "' group '" << group << "' on file '" << agent_cert << "'. Verify it yourself!"; + } + /* apilistener config */ std::cout << "Please specify the API bind host/port (optional):\n"; std::cout << "Bind Host []: "; @@ -347,7 +406,7 @@ wizard_ticket: std::cout << "Starting the Master setup routine...\n"; /* CN */ - std::cout << "Please specifiy the common name (CN) (leave blank for default FQDN): "; + std::cout << "Please specifiy the common name (CN) [" << Utility::GetFQDN() << "]: "; std::getline(std::cin, answer); boost::algorithm::to_lower(answer); @@ -370,6 +429,14 @@ wizard_ticket: return 1; } + String user = VariableUtility::GetVariable("RunAsUser"); + String group = VariableUtility::GetVariable("RunAsUser"); + + if (!Utility::SetFileOwnership(pki_path, user, group)) { + Log(LogWarning, "cli") + << "Cannot set ownership for user '" << user << "' group '" << group << "' on file '" << pki_path << "'. Verify it yourself!"; + } + String key = pki_path + "/" + cn + ".key"; String csr = pki_path + "/" + cn + ".csr"; @@ -389,7 +456,9 @@ wizard_ticket: /* Copy CA certificate to /etc/icinga2/pki */ - String ca = PkiUtility::GetLocalCaPath() + "/ca.crt"; + String ca_path = PkiUtility::GetLocalCaPath(); + String ca = ca_path + "/ca.crt"; + String ca_key = ca_path + "/ca.key"; String target_ca = pki_path + "/ca.crt"; Log(LogInformation, "cli") @@ -398,7 +467,31 @@ wizard_ticket: /* does not overwrite existing files! */ Utility::CopyFile(ca, target_ca); - //TODO: Fix permissions for CA dir (root -> icinga) + /* fix permissions: root -> icinga daemon user */ + if (!Utility::SetFileOwnership(ca_path, user, group)) { + Log(LogWarning, "cli") + << "Cannot set ownership for user '" << user << "' group '" << group << "' on file '" << ca_path << "'. Verify it yourself!"; + } + if (!Utility::SetFileOwnership(ca, user, group)) { + Log(LogWarning, "cli") + << "Cannot set ownership for user '" << user << "' group '" << group << "' on file '" << ca << "'. Verify it yourself!"; + } + if (!Utility::SetFileOwnership(ca_key, user, group)) { + Log(LogWarning, "cli") + << "Cannot set ownership for user '" << user << "' group '" << group << "' on file '" << ca_key << "'. Verify it yourself!"; + } + if (!Utility::SetFileOwnership(target_ca, user, group)) { + Log(LogWarning, "cli") + << "Cannot set ownership for user '" << user << "' group '" << group << "' on file '" << target_ca << "'. Verify it yourself!"; + } + if (!Utility::SetFileOwnership(key, user, group)) { + Log(LogWarning, "cli") + << "Cannot set ownership for user '" << user << "' group '" << group << "' on file '" << key << "'. Verify it yourself!"; + } + if (!Utility::SetFileOwnership(csr, user, group)) { + Log(LogWarning, "cli") + << "Cannot set ownership for user '" << user << "' group '" << group << "' on file '" << csr << "'. Verify it yourself!"; + } AgentUtility::GenerateAgentMasterIcingaConfig(cn); diff --git a/lib/cli/agentwizardcommand.hpp b/lib/cli/agentwizardcommand.hpp index 5ae25878d..69df8a3da 100644 --- a/lib/cli/agentwizardcommand.hpp +++ b/lib/cli/agentwizardcommand.hpp @@ -37,7 +37,9 @@ public: virtual String GetDescription(void) const; virtual String GetShortDescription(void) const; + virtual int GetMaxArguments(void) const; virtual int Run(const boost::program_options::variables_map& vm, const std::vector& ap) const; + virtual ImpersonationLevel GetImpersonationLevel(void) const; }; }