Fix: Don't shell-escape macros by default.

This commit is contained in:
Gunnar Beutner 2013-09-09 13:44:18 +02:00
parent a695d8cdd6
commit ec0a32380e
8 changed files with 36 additions and 11 deletions

View File

@ -44,6 +44,11 @@ Array::Ptr Command::GetExportMacros(void) const
return m_ExportMacros; return m_ExportMacros;
} }
Array::Ptr Command::GetEscapeMacros(void) const
{
return m_EscapeMacros;
}
bool Command::ResolveMacro(const String& macro, const Dictionary::Ptr&, String *result) const bool Command::ResolveMacro(const String& macro, const Dictionary::Ptr&, String *result) const
{ {
Dictionary::Ptr macros = GetMacros(); Dictionary::Ptr macros = GetMacros();
@ -65,6 +70,7 @@ void Command::InternalSerialize(const Dictionary::Ptr& bag, int attributeTypes)
bag->Set("timeout", m_Timeout); bag->Set("timeout", m_Timeout);
bag->Set("macros", m_Macros); bag->Set("macros", m_Macros);
bag->Set("export_macros", m_ExportMacros); bag->Set("export_macros", m_ExportMacros);
bag->Set("escape_macros", m_EscapeMacros);
} }
} }
@ -78,5 +84,6 @@ void Command::InternalDeserialize(const Dictionary::Ptr& bag, int attributeTypes
m_Macros = bag->Get("macros"); m_Macros = bag->Get("macros");
m_Macros = bag->Get("macros"); m_Macros = bag->Get("macros");
m_ExportMacros = bag->Get("export_macros"); m_ExportMacros = bag->Get("export_macros");
m_EscapeMacros = bag->Get("escape_macros");
} }
} }

View File

@ -47,6 +47,7 @@ public:
Dictionary::Ptr GetMacros(void) const; Dictionary::Ptr GetMacros(void) const;
Array::Ptr GetExportMacros(void) const; Array::Ptr GetExportMacros(void) const;
Array::Ptr GetEscapeMacros(void) const;
virtual bool ResolveMacro(const String& macro, const Dictionary::Ptr& cr, String *result) const; virtual bool ResolveMacro(const String& macro, const Dictionary::Ptr& cr, String *result) const;
protected: protected:
@ -58,6 +59,7 @@ private:
Value m_Timeout; Value m_Timeout;
Dictionary::Ptr m_Macros; Dictionary::Ptr m_Macros;
Array::Ptr m_ExportMacros; Array::Ptr m_ExportMacros;
Array::Ptr m_EscapeMacros;
}; };
} }

View File

@ -368,6 +368,9 @@ type Command {
%attribute array "export_macros" { %attribute array "export_macros" {
%attribute string "*" %attribute string "*"
}, },
%attribute array "escape_macros" {
%attribute string "*"
},
%attribute dictionary "macros" { %attribute dictionary "macros" {
%attribute string "*" %attribute string "*"
}, },

View File

@ -30,12 +30,12 @@
using namespace icinga; using namespace icinga;
Value MacroProcessor::ResolveMacros(const Value& str, const std::vector<MacroResolver::Ptr>& resolvers, Value MacroProcessor::ResolveMacros(const Value& str, const std::vector<MacroResolver::Ptr>& resolvers,
const Dictionary::Ptr& cr, const MacroProcessor::EscapeCallback& escapeFn) const Dictionary::Ptr& cr, const MacroProcessor::EscapeCallback& escapeFn, const Array::Ptr& escapeMacros)
{ {
Value result; Value result;
if (str.IsScalar()) { if (str.IsScalar()) {
result = InternalResolveMacros(str, resolvers, cr, escapeFn); result = InternalResolveMacros(str, resolvers, cr, escapeFn, escapeMacros);
} else if (str.IsObjectType<Array>()) { } else if (str.IsObjectType<Array>()) {
Array::Ptr resultArr = boost::make_shared<Array>(); Array::Ptr resultArr = boost::make_shared<Array>();
Array::Ptr arr = str; Array::Ptr arr = str;
@ -44,7 +44,7 @@ Value MacroProcessor::ResolveMacros(const Value& str, const std::vector<MacroRes
BOOST_FOREACH(const Value& arg, arr) { BOOST_FOREACH(const Value& arg, arr) {
/* Note: don't escape macros here. */ /* Note: don't escape macros here. */
resultArr->Add(InternalResolveMacros(arg, resolvers, cr, EscapeCallback())); resultArr->Add(InternalResolveMacros(arg, resolvers, cr, EscapeCallback(), Array::Ptr()));
} }
result = resultArr; result = resultArr;
@ -68,7 +68,7 @@ bool MacroProcessor::ResolveMacro(const String& macro, const std::vector<MacroRe
String MacroProcessor::InternalResolveMacros(const String& str, const std::vector<MacroResolver::Ptr>& resolvers, String MacroProcessor::InternalResolveMacros(const String& str, const std::vector<MacroResolver::Ptr>& resolvers,
const Dictionary::Ptr& cr, const MacroProcessor::EscapeCallback& escapeFn) const Dictionary::Ptr& cr, const MacroProcessor::EscapeCallback& escapeFn, const Array::Ptr& escapeMacros)
{ {
size_t offset, pos_first, pos_second; size_t offset, pos_first, pos_second;
offset = 0; offset = 0;
@ -94,8 +94,20 @@ String MacroProcessor::InternalResolveMacros(const String& str, const std::vecto
if (!found) if (!found)
Log(LogWarning, "icinga", "Macro '" + name + "' is not defined."); Log(LogWarning, "icinga", "Macro '" + name + "' is not defined.");
if (escapeFn) if (escapeFn && escapeMacros) {
bool escape = false;
ObjectLock olock(escapeMacros);
BOOST_FOREACH(const String& escapeMacro, escapeMacros) {
if (escapeMacro == name) {
escape = true;
break;
}
}
if (escape)
resolved_macro = escapeFn(resolved_macro); resolved_macro = escapeFn(resolved_macro);
}
result.Replace(pos_first, pos_second - pos_first + 1, resolved_macro); result.Replace(pos_first, pos_second - pos_first + 1, resolved_macro);
offset = pos_first + resolved_macro.GetLength(); offset = pos_first + resolved_macro.GetLength();

View File

@ -23,6 +23,7 @@
#include "icinga/i2-icinga.h" #include "icinga/i2-icinga.h"
#include "icinga/macroresolver.h" #include "icinga/macroresolver.h"
#include "base/dictionary.h" #include "base/dictionary.h"
#include "base/array.h"
#include <boost/function.hpp> #include <boost/function.hpp>
#include <vector> #include <vector>
@ -40,7 +41,7 @@ public:
typedef boost::function<String (const String&)> EscapeCallback; typedef boost::function<String (const String&)> EscapeCallback;
static Value ResolveMacros(const Value& str, const std::vector<MacroResolver::Ptr>& resolvers, static Value ResolveMacros(const Value& str, const std::vector<MacroResolver::Ptr>& resolvers,
const Dictionary::Ptr& cr, const EscapeCallback& escapeFn = EscapeCallback()); const Dictionary::Ptr& cr, const EscapeCallback& escapeFn = EscapeCallback(), const Array::Ptr& escapeMacros = Array::Ptr());
static bool ResolveMacro(const String& macro, const std::vector<MacroResolver::Ptr>& resolvers, static bool ResolveMacro(const String& macro, const std::vector<MacroResolver::Ptr>& resolvers,
const Dictionary::Ptr& cr, String *result); const Dictionary::Ptr& cr, String *result);
@ -49,7 +50,7 @@ private:
static String InternalResolveMacros(const String& str, static String InternalResolveMacros(const String& str,
const std::vector<MacroResolver::Ptr>& resolvers, const Dictionary::Ptr& cr, const std::vector<MacroResolver::Ptr>& resolvers, const Dictionary::Ptr& cr,
const EscapeCallback& escapeFn); const EscapeCallback& escapeFn, const Array::Ptr& escapeMacros);
}; };
} }

View File

@ -46,7 +46,7 @@ Dictionary::Ptr PluginCheckTask::ScriptFunc(const Service::Ptr& service)
resolvers.push_back(service->GetHost()); resolvers.push_back(service->GetHost());
resolvers.push_back(IcingaApplication::GetInstance()); resolvers.push_back(IcingaApplication::GetInstance());
Value command = MacroProcessor::ResolveMacros(raw_command, resolvers, Dictionary::Ptr(), Utility::EscapeShellCmd); Value command = MacroProcessor::ResolveMacros(raw_command, resolvers, Dictionary::Ptr(), Utility::EscapeShellCmd, commandObj->GetEscapeMacros());
Dictionary::Ptr envMacros = boost::make_shared<Dictionary>(); Dictionary::Ptr envMacros = boost::make_shared<Dictionary>();

View File

@ -44,7 +44,7 @@ void PluginEventTask::ScriptFunc(const Service::Ptr& service)
resolvers.push_back(service->GetHost()); resolvers.push_back(service->GetHost());
resolvers.push_back(IcingaApplication::GetInstance()); resolvers.push_back(IcingaApplication::GetInstance());
Value command = MacroProcessor::ResolveMacros(raw_command, resolvers, Dictionary::Ptr(), Utility::EscapeShellCmd); Value command = MacroProcessor::ResolveMacros(raw_command, resolvers, Dictionary::Ptr(), Utility::EscapeShellCmd, commandObj->GetEscapeMacros());
Dictionary::Ptr envMacros = boost::make_shared<Dictionary>(); Dictionary::Ptr envMacros = boost::make_shared<Dictionary>();

View File

@ -56,7 +56,7 @@ void PluginNotificationTask::ScriptFunc(const Notification::Ptr& notification, c
resolvers.push_back(service->GetHost()); resolvers.push_back(service->GetHost());
resolvers.push_back(IcingaApplication::GetInstance()); resolvers.push_back(IcingaApplication::GetInstance());
Value command = MacroProcessor::ResolveMacros(raw_command, resolvers, cr, Utility::EscapeShellCmd); Value command = MacroProcessor::ResolveMacros(raw_command, resolvers, cr, Utility::EscapeShellCmd, commandObj->GetEscapeMacros());
Dictionary::Ptr envMacros = boost::make_shared<Dictionary>(); Dictionary::Ptr envMacros = boost::make_shared<Dictionary>();