Changeset 96c1461 in nscp for modules/NRPEClient
- Timestamp:
- 11/27/11 22:04:35 (18 months ago)
- Branches:
- master, 0.4.0, 0.4.1, 0.4.2
- Children:
- 9853bc3
- Parents:
- 16198e3
- Location:
- modules/NRPEClient
- Files:
-
- 4 edited
-
CMakeLists.txt (modified) (2 diffs)
-
NRPEClient.cpp (modified) (5 diffs)
-
NRPEClient.def (modified) (1 diff)
-
NRPEClient.h (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
modules/NRPEClient/CMakeLists.txt
r2b2e9b8 r96c1461 10 10 ${NSCP_INCLUDEDIR}/nrpe/packet.cpp 11 11 ${NSCP_INCLUDEDIR}/socket/socket_helpers.cpp 12 ${NSCP_INCLUDEDIR}/client/command_line_parser.cpp 12 13 13 14 ${NSCP_DEF_PLUGIN_CPP} … … 28 29 ${NSCP_INCLUDEDIR}/swap_bytes.hpp 29 30 ${NSCP_INCLUDEDIR}/socket/socket_helpers.hpp 31 ${NSCP_INCLUDEDIR}/client/command_line_parser.hpp 30 32 31 33 ${NSCP_DEF_PLUGIN_HPP} -
modules/NRPEClient/NRPEClient.cpp
rf7a074d r96c1461 21 21 #include "stdafx.h" 22 22 #include "NRPEClient.h" 23 24 #include <time.h> 23 25 #include <strEx.h> 24 #include <time.h> 25 //#include <config.h> 26 26 27 #include <strEx.h> 27 28 #include <nrpe/client/socket.hpp> … … 29 30 #include <settings/client/settings_client.hpp> 30 31 31 32 namespace setting_keys {33 34 // NSClient Setting headlines35 namespace nrpe {36 DEFINE_PATH(SECTION, NRPE_SECTION_PROTOCOL);37 //DESCRIBE_SETTING(SECTION, "NRPE SECTION", "Section for NRPE (NRPEListener.dll) (check_nrpe) protocol options.");38 39 40 DEFINE_PATH(CH_SECTION, NRPE_CLIENT_HANDLER_SECTION);41 //DESCRIBE_SETTING(CH_SECTION, "CLIENT HANDLER SECTION", "...");42 43 DEFINE_SETTING_S(ALLOWED_HOSTS, NRPE_SECTION_PROTOCOL, GENERIC_KEY_ALLOWED_HOSTS, "");44 DESCRIBE_SETTING(ALLOWED_HOSTS, "ALLOWED HOST ADDRESSES", "This is a comma-delimited list of IP address of hosts that are allowed to talk to NSClient deamon. If you leave this blank the global version will be used instead.");45 46 DEFINE_SETTING_I(PORT, NRPE_SECTION_PROTOCOL, "port", 5666);47 //DESCRIBE_SETTING(PORT, "NSCLIENT PORT NUMBER", "This is the port the NSClientListener.dll will listen to.");48 49 DEFINE_SETTING_S(BINDADDR, NRPE_SECTION_PROTOCOL, GENERIC_KEY_BIND_TO, "");50 //DESCRIBE_SETTING(BINDADDR, "BIND TO ADDRESS", "Allows you to bind server to a specific local address. This has to be a dotted ip adress not a hostname. Leaving this blank will bind to all avalible IP adresses.");51 52 DEFINE_SETTING_I(READ_TIMEOUT, NRPE_SECTION_PROTOCOL, GENERIC_KEY_SOCK_READ_TIMEOUT, 30);53 //DESCRIBE_SETTING(READ_TIMEOUT, "SOCKET TIMEOUT", "Timeout when reading packets on incoming sockets. If the data has not arrived withint this time we will bail out.");54 55 DEFINE_SETTING_I(LISTENQUE, NRPE_SECTION_PROTOCOL, GENERIC_KEY_SOCK_LISTENQUE, 0);56 //DESCRIBE_SETTING_ADVANCED(LISTENQUE, "LISTEN QUEUE", "Number of sockets to queue before starting to refuse new incoming connections. This can be used to tweak the amount of simultaneous sockets that the server accepts.");57 58 DEFINE_SETTING_I(THREAD_POOL, NRPE_SECTION_PROTOCOL, "thread pool", 10);59 //DESCRIBE_SETTING_ADVANCED(THREAD_POOL, "THREAD POOL", "");60 61 62 63 DEFINE_SETTING_B(CACHE_ALLOWED, NRPE_SECTION_PROTOCOL, GENERIC_KEY_SOCK_CACHE_ALLOWED, false);64 DESCRIBE_SETTING_ADVANCED(CACHE_ALLOWED, "ALLOWED HOSTS CACHING", "Used to cache looked up hosts if you check dynamic/changing hosts set this to false.");65 66 //DEFINE_SETTING_B(KEYUSE_SSL, NRPE_SECTION_PROTOCOL, GENERIC_KEY_USE_SSL, true);67 //DESCRIBE_SETTING(KEYUSE_SSL, "USE SSL SOCKET", "This option controls if SSL should be used on the socket.");68 69 DEFINE_SETTING_I(PAYLOAD_LENGTH, NRPE_SECTION_PROTOCOL, "payload length", 1024);70 //DESCRIBE_SETTING_ADVANCED(PAYLOAD_LENGTH, "PAYLOAD LENGTH", "Length of payload to/from the NRPE agent. This is a hard specific value so you have to \"configure\" (read recompile) your NRPE agent to use the same value for it to work.");71 72 //DEFINE_SETTING_B(ALLOW_PERFDATA, NRPE_SECTION, "performance data", true);73 //DESCRIBE_SETTING_ADVANCED(ALLOW_PERFDATA, "PERFORMANCE DATA", "Send performance data back to nagios (set this to 0 to remove all performance data).");74 75 //DEFINE_SETTING_I(CMD_TIMEOUT, NRPE_SECTION, "command timeout", 60);76 //DESCRIBE_SETTING(CMD_TIMEOUT, "COMMAND TIMEOUT", "This specifies the maximum number of seconds that the NRPE daemon will allow plug-ins to finish executing before killing them off.");77 78 DEFINE_SETTING_B(ALLOW_ARGS, NRPE_SECTION, "allow arguments", false);79 //DESCRIBE_SETTING(ALLOW_ARGS, "COMMAND ARGUMENT PROCESSING", "This option determines whether or not the NRPE daemon will allow clients to specify arguments to commands that are executed.");80 81 DEFINE_SETTING_B(ALLOW_NASTY, NRPE_SECTION, "allow nasy characters", false);82 //DESCRIBE_SETTING(ALLOW_NASTY, "COMMAND ALLOW NASTY META CHARS", "This option determines whether or not the NRPE daemon will allow clients to specify nasty (as in |`&><'\"\\[]{}) characters in arguments.");83 84 }85 }86 32 namespace sh = nscapi::settings_helper; 87 33 88 NRPEClient::NRPEClient() : buffer_length_(0) { 89 } 90 91 NRPEClient::~NRPEClient() { 92 } 93 34 /** 35 * Default c-tor 36 * @return 37 */ 38 NRPEClient::NRPEClient() {} 39 40 /** 41 * Default d-tor 42 * @return 43 */ 44 NRPEClient::~NRPEClient() {} 45 46 /** 47 * Load (initiate) module. 48 * Start the background collector thread and let it run until unloadModule() is called. 49 * @return true 50 */ 94 51 bool NRPEClient::loadModule() { 95 52 return false; … … 99 56 std::map<std::wstring,std::wstring> commands; 100 57 101 try { 102 103 //"/settings/NRPE/client/handlers" 58 std::wstring certificate; 59 unsigned int timeout = 30, buffer_length = 1024; 60 bool use_ssl = true; 61 try { 62 104 63 sh::settings_registry settings(get_settings_proxy()); 105 64 settings.set_alias(_T("NRPE"), alias, _T("client")); 106 65 66 target_path = settings.alias().get_settings_path(_T("targets")); 67 107 68 settings.alias().add_path_to_settings() 69 (_T("NRPE CLIENT SECTION"), _T("Section for NRPE active/passive check module.")) 108 70 109 71 (_T("handlers"), sh::fun_values_path(boost::bind(&NRPEClient::add_command, this, _1, _2)), 110 72 _T("CLIENT HANDLER SECTION"), _T("")) 111 73 112 (_T("servers"), sh::fun_values_path(boost::bind(&NRPEClient::add_server, this, _1, _2)), 113 _T("REMOTE SERVER DEFINITIONS"), _T("")) 114 74 (_T("targets"), sh::fun_values_path(boost::bind(&NRPEClient::add_target, this, _1, _2)), 75 _T("REMOTE TARGET DEFINITIONS"), _T("")) 115 76 ; 116 77 117 78 settings.alias().add_key_to_settings() 118 119 (_T("payload length"), sh::uint_key(&buffer_length_, 1024), 79 (_T("channel"), sh::wstring_key(&channel_, _T("NRPE")), 80 _T("CHANNEL"), _T("The channel to listen to.")) 81 82 ; 83 84 settings.alias(_T("/targets/default")).add_key_to_settings() 85 86 (_T("timeout"), sh::uint_key(&timeout, 30), 87 _T("TIMEOUT"), _T("Timeout when reading/writing packets to/from sockets.")) 88 89 (_T("use ssl"), sh::bool_key(&use_ssl, true), 90 _T("ENABLE SSL ENCRYPTION"), _T("This option controls if SSL should be enabled.")) 91 92 (_T("certificate"), sh::wpath_key(&certificate, _T("${certificate-path}/nrpe_dh_512.pem")), 93 _T("SSL CERTIFICATE"), _T("")) 94 95 (_T("payload length"), sh::uint_key(&buffer_length, 1024), 120 96 _T("PAYLOAD LENGTH"), _T("Length of payload to/from the NRPE agent. This is a hard specific value so you have to \"configure\" (read recompile) your NRPE agent to use the same value for it to work.")) 121 122 97 ; 123 124 98 125 99 settings.register_all(); 126 100 settings.notify(); 127 101 102 get_core()->registerSubmissionListener(get_id(), channel_); 103 104 if (!targets.has_target(_T("default"))) { 105 add_target(_T("default"), _T("default")); 106 targets.rebuild(); 107 } 108 nscapi::target_handler::optarget t = targets.find_target(_T("default")); 109 if (t) { 110 if (!t->has_option("certificate")) 111 t->options[_T("certificate")] = certificate; 112 if (!t->has_option("timeout")) 113 t->options[_T("timeout")] = strEx::itos(timeout); 114 if (!t->has_option("payload length")) 115 t->options[_T("payload length")] = strEx::itos(buffer_length); 116 if (!t->has_option("ssl")) 117 t->options[_T("ssl")] = use_ssl?_T("true"):_T("false"); 118 targets.add(*t); 119 } else { 120 NSC_LOG_ERROR(_T("Default target not found!")); 121 } 122 123 } catch (nscapi::nscapi_exception &e) { 124 NSC_LOG_ERROR_STD(_T("NSClient API exception: ") + utf8::to_unicode(e.what())); 125 return false; 126 } catch (std::exception &e) { 127 NSC_LOG_ERROR_STD(_T("Exception caught: ") + utf8::to_unicode(e.what())); 128 return false; 128 129 } catch (...) { 129 130 NSC_LOG_ERROR_STD(_T("Exception caught: <UNKNOWN EXCEPTION>")); 130 131 return false; 131 132 } 132 133 boost::filesystem::wpath p = GET_CORE()->getBasePath() + std::wstring(_T("/security/nrpe_dh_512.pem"));134 cert_ = p.string();135 if (boost::filesystem::is_regular(p)) {136 NSC_DEBUG_MSG_STD(_T("Using certificate: ") + cert_);137 } else {138 NSC_LOG_ERROR_STD(_T("Certificate not found: ") + cert_);139 }140 141 133 return true; 142 134 } 143 144 void NRPEClient::add_options(po::options_description &desc, nrpe_connection_data &command_data) { 145 desc.add_options() 146 ("host,H", po::wvalue<std::wstring>(&command_data.host), "The address of the host running the NRPE daemon") 147 ("port,p", po::value<int>(&command_data.port), "The port on which the daemon is running (default=5666)") 148 ("command,c", po::wvalue<std::wstring>(&command_data.command), "The name of the command that the remote daemon should run") 149 ("timeout,t", po::value<int>(&command_data.timeout), "Number of seconds before connection times out (default=10)") 150 ("buffer-length,l", po::value<unsigned int>(&command_data.buffer_length), std::string("Length of payload (has to be same as on the server (default=" + to_string(buffer_length_) + ")").c_str()) 151 ("no-ssl,n", po::value<bool>(&command_data.no_ssl)->zero_tokens()->default_value(false), "Do not initial an ssl handshake with the server, talk in plaintext.") 152 ("arguments,a", po::wvalue<std::vector<std::wstring> >(&command_data.argument_vector), "list of arguments") 153 ; 154 } 155 156 void NRPEClient::add_server(std::wstring key, std::wstring args) { 157 } 158 159 void NRPEClient::add_command(std::wstring key, std::wstring args) { 160 try { 161 162 NRPEClient::nrpe_connection_data command_data; 163 boost::program_options::variables_map vm; 164 165 po::options_description desc("Allowed options"); 166 buffer_length_ = SETTINGS_GET_INT(nrpe::PAYLOAD_LENGTH); 167 add_options(desc, command_data); 168 169 po::positional_options_description p; 170 p.add("arguments", -1); 171 172 std::vector<std::wstring> list; 173 //explicit escaped_list_separator(Char e = '\\', Char c = ',',Char q = '\"') 174 boost::escaped_list_separator<wchar_t> sep(L'\\', L' ', L'\"'); 175 typedef boost::tokenizer<boost::escaped_list_separator<wchar_t>,std::wstring::const_iterator, std::wstring > tokenizer_t; 176 tokenizer_t tok(args, sep); 177 for(tokenizer_t::iterator beg=tok.begin(); beg!=tok.end();++beg){ 178 list.push_back(*beg); 179 } 180 181 po::wparsed_options parsed = po::basic_command_line_parser<wchar_t>(list).options(desc).positional(p).run(); 182 po::store(parsed, vm); 183 po::notify(vm); 184 command_data.parse_arguments(); 185 186 NSC_DEBUG_MSG_STD(_T("Added NRPE Client: ") + key.c_str() + _T(" = ") + command_data.toString()); 187 commands[key.c_str()] = command_data; 188 189 register_command(key.c_str(), command_data.toString()); 190 135 std::string get_command(std::string alias, std::string command = "") { 136 if (!alias.empty()) 137 return alias; 138 if (!command.empty()) 139 return command; 140 return "_NRPE_CHECK"; 141 } 142 143 ////////////////////////////////////////////////////////////////////////// 144 // Settings helpers 145 // 146 147 void NRPEClient::add_target(std::wstring key, std::wstring arg) { 148 try { 149 nscapi::target_handler::target t = targets.add(get_settings_proxy(), target_path , key, arg); 150 if (t.has_option(_T("certificate"))) { 151 boost::filesystem::wpath p = t.options[_T("certificate")]; 152 if (!boost::filesystem::is_regular(p)) { 153 p = get_core()->getBasePath() / p; 154 t.options[_T("certificate")] = utf8::cvt<std::wstring>(p.string()); 155 targets.add(t); 156 } 157 if (boost::filesystem::is_regular(p)) { 158 NSC_DEBUG_MSG_STD(_T("Using certificate: ") + p.string()); 159 } else { 160 NSC_LOG_ERROR_STD(_T("Certificate not found: ") + p.string()); 161 } 162 } 163 } catch (...) { 164 NSC_LOG_ERROR_STD(_T("Failed to add target: ") + key); 165 } 166 } 167 168 void NRPEClient::add_command(std::wstring name, std::wstring args) { 169 try { 170 std::wstring key = commands.add_command(name, args); 171 if (!key.empty()) 172 register_command(key.c_str(), _T("NRPE relay for: ") + name); 191 173 } catch (boost::program_options::validation_error &e) { 192 NSC_LOG_ERROR_STD(_T("Could not parse: ") + key.c_str() + strEx::string_to_wstring(e.what()));174 NSC_LOG_ERROR_STD(_T("Could not add command ") + name + _T(": ") + utf8::to_unicode(e.what())); 193 175 } catch (...) { 194 NSC_LOG_ERROR_STD(_T("Could not parse: ") + key.c_str()); 195 } 196 } 197 176 NSC_LOG_ERROR_STD(_T("Could not add command ") + name); 177 } 178 } 179 180 /** 181 * Unload (terminate) module. 182 * Attempt to stop the background processing thread. 183 * @return true if successfully, false if not (if not things might be bad) 184 */ 198 185 bool NRPEClient::unloadModule() { 199 186 return true; 200 187 } 201 188 202 bool NRPEClient::hasCommandHandler() {203 return true;204 }205 bool NRPEClient::hasMessageHandler() {206 return false;207 }208 189 NSCAPI::nagiosReturn NRPEClient::handleCommand(const std::wstring &target, const std::wstring &command, std::list<std::wstring> &arguments, std::wstring &message, std::wstring &perf) { 209 command_list::const_iterator cit = commands.find(strEx::blindstr(command.c_str())); 210 if (cit == commands.end()) 190 std::wstring cmd = client::command_line_parser::parse_command(command, _T("nrpe")); 191 192 client::configuration config; 193 setup(config); 194 if (cmd == _T("query")) 195 return client::command_line_parser::query(config, cmd, arguments, message, perf); 196 if (cmd == _T("submit")) { 197 boost::tuple<int,std::wstring> result = client::command_line_parser::simple_submit(config, cmd, arguments); 198 message = result.get<1>(); 199 return result.get<0>(); 200 } 201 if (cmd == _T("exec")) { 202 return client::command_line_parser::exec(config, cmd, arguments, message); 203 } 204 return commands.exec_simple(config, target, command, arguments, message, perf); 205 } 206 207 int NRPEClient::commandLineExec(const std::wstring &command, std::list<std::wstring> &arguments, std::wstring &result) { 208 std::wstring cmd = client::command_line_parser::parse_command(command, _T("nrpe")); 209 if (!client::command_line_parser::is_command(cmd)) 211 210 return NSCAPI::returnIgnored; 212 211 213 std::wstring args = (*cit).second.arguments; 214 if (SETTINGS_GET_BOOL(nrpe::ALLOW_ARGS) == 1) { 215 int i=1; 216 BOOST_FOREACH(std::wstring arg, arguments) 217 { 218 if (SETTINGS_GET_INT(nrpe::ALLOW_NASTY) == 0) { 219 if (arg.find_first_of(NASTY_METACHARS_W) != std::wstring::npos) { 220 NSC_LOG_ERROR(_T("Request string contained illegal metachars!")); 221 return NSCAPI::returnIgnored; 222 } 212 client::configuration config; 213 setup(config); 214 return client::command_line_parser::commandLineExec(config, cmd, arguments, result); 215 } 216 217 NSCAPI::nagiosReturn NRPEClient::handleRAWNotification(const wchar_t* channel, std::string request, std::string &response) { 218 try { 219 client::configuration config; 220 setup(config); 221 222 if (!client::command_line_parser::relay_submit(config, request, response)) { 223 NSC_LOG_ERROR_STD(_T("Failed to submit message...")); 224 return NSCAPI::hasFailed; 225 } 226 return NSCAPI::isSuccess; 227 } catch (std::exception &e) { 228 NSC_LOG_ERROR_STD(_T("Failed to send data: ") + utf8::to_unicode(e.what())); 229 return NSCAPI::hasFailed; 230 } catch (...) { 231 NSC_LOG_ERROR_STD(_T("Failed to send data: UNKNOWN")); 232 return NSCAPI::hasFailed; 233 } 234 } 235 236 ////////////////////////////////////////////////////////////////////////// 237 // Parser setup/Helpers 238 // 239 240 void NRPEClient::add_local_options(po::options_description &desc, client::configuration::data_type data) { 241 desc.add_options() 242 ("certificate,c", po::value<std::string>()->notifier(boost::bind(&nscapi::functions::destination_container::set_string_data, &data->recipient, "certificate", _1)), 243 "Length of payload (has to be same as on the server)") 244 245 ("buffer-length,l", po::value<unsigned int>()->notifier(boost::bind(&nscapi::functions::destination_container::set_int_data, &data->recipient, "payload length", _1)), 246 "Length of payload (has to be same as on the server)") 247 248 ("no-ssl,n", po::value<bool>()->zero_tokens()->default_value(false)->notifier(boost::bind(&nscapi::functions::destination_container::set_bool_data, &data->recipient, "no ssl", _1)), 249 "Do not initial an ssl handshake with the server, talk in plaintext.") 250 ; 251 } 252 253 void NRPEClient::setup(client::configuration &config) { 254 boost::shared_ptr<clp_handler_impl> handler = boost::shared_ptr<clp_handler_impl>(new clp_handler_impl(this)); 255 add_local_options(config.local, config.data); 256 257 net::wurl url; 258 url.protocol = _T("nrpe"); 259 url.port = 5666; 260 nscapi::target_handler::optarget opt = targets.find_target(_T("default")); 261 if (opt) { 262 nscapi::target_handler::target t = *opt; 263 url.host = t.host; 264 if (t.has_option("port")) { 265 try { 266 url.port = strEx::stoi(t.options[_T("port")]); 267 } catch (...) {} 268 } 269 std::string keys[] = {"certificate", "timeout", "payload length", "ssl"}; 270 BOOST_FOREACH(std::string s, keys) { 271 config.data->recipient.data[s] = utf8::cvt<std::string>(t.options[utf8::cvt<std::wstring>(s)]); 272 } 273 } 274 config.data->recipient.id = "default"; 275 config.data->recipient.address = utf8::cvt<std::string>(url.to_string()); 276 config.data->host_self.id = "self"; 277 //config.data->host_self.host = hostname_; 278 279 config.target_lookup = handler; 280 config.handler = handler; 281 } 282 283 NRPEClient::connection_data NRPEClient::parse_header(const ::Plugin::Common_Header &header) { 284 nscapi::functions::destination_container recipient; 285 nscapi::functions::parse_destination(header, header.recipient_id(), recipient, true); 286 return connection_data(recipient); 287 } 288 289 ////////////////////////////////////////////////////////////////////////// 290 // Parser implementations 291 // 292 293 int NRPEClient::clp_handler_impl::query(client::configuration::data_type data, ::Plugin::Common_Header* header, const std::string &request, std::string &reply) { 294 NSCAPI::nagiosReturn ret = NSCAPI::returnOK; 295 try { 296 Plugin::QueryRequestMessage request_message; 297 request_message.ParseFromString(request); 298 connection_data con = parse_header(*header); 299 300 Plugin::QueryResponseMessage response_message; 301 nscapi::functions::create_simple_header(response_message.mutable_header()); // TODO copy request header (inverted) 302 303 for (int i=0;i<request_message.payload_size();i++) { 304 std::string command = get_command(request_message.payload(i).alias(), request_message.payload(i).command()); 305 std::string data = command; 306 for (int a=0;a<request_message.payload(i).arguments_size();a++) { 307 data += "!" + request_message.payload(i).arguments(a); 223 308 } 224 strEx::replace(args, _T("$ARG") + strEx::itos(i++) + _T("$"), arg); 225 } 226 } 227 228 NSC_DEBUG_MSG_STD(_T("Rewrote command arguments: ") + args); 229 nrpe_result_data r = execute_nrpe_command((*cit).second, args); 230 message = r.text; 231 return r.result; 232 } 233 234 int NRPEClient::commandLineExec(const std::wstring &command, std::list<std::wstring> &arguments, std::wstring &result) { 235 if (command != _T("query_nrpe") && command != _T("help")) 236 return NSCAPI::returnIgnored; 237 try { 238 NRPEClient::nrpe_connection_data command_data; 239 boost::program_options::variables_map vm; 240 241 po::options_description desc("Allowed options"); 242 buffer_length_ = SETTINGS_GET_INT(nrpe::PAYLOAD_LENGTH); 243 add_options(desc, command_data); 244 245 std::vector<std::wstring> vargs(arguments.begin(), arguments.end()); 246 po::positional_options_description p; 247 p.add("arguments", -1); 248 po::wparsed_options parsed = po::basic_command_line_parser<wchar_t>(vargs).options(desc).positional(p).run(); 249 po::store(parsed, vm); 250 po::notify(vm); 251 command_data.parse_arguments(); 252 if (command == _T("help")) { 253 std::stringstream ss; 254 ss << "NRPEClient Command line syntax for command: query" << std::endl;; 255 ss << desc; 256 result = utf8::cvt<std::wstring>(ss.str()); 257 return NSCAPI::returnOK; 258 } 259 260 nrpe_result_data res = execute_nrpe_command(command_data, command_data.arguments); 261 result = res.text; 262 return res.result; 263 } catch (boost::program_options::validation_error &e) { 264 result = _T("Error: ") + utf8::cvt<std::wstring>(e.what()); 309 boost::tuple<int,std::wstring> ret = instance->send(con, data); 310 std::pair<std::wstring,std::wstring> rdata = strEx::split(ret.get<1>(), _T("|")); 311 nscapi::functions::append_simple_query_response_payload(response_message.add_payload(), utf8::cvt<std::wstring>(command), ret.get<0>(), rdata.first, rdata.second); 312 } 313 response_message.SerializeToString(&reply); 314 return NSCAPI::isSuccess; 315 } catch (std::exception &e) { 316 NSC_LOG_ERROR_STD(_T("Exception: ") + utf8::to_unicode(e.what())); 317 nscapi::functions::create_simple_query_response(_T("command"), NSCAPI::returnUNKNOWN, _T("Exception: ") + utf8::to_unicode(e.what()), _T(""), reply); 265 318 return NSCAPI::returnUNKNOWN; 266 } catch (...) { 267 result = _T("Unknown exception parsing command line"); 268 return NSCAPI::returnUNKNOWN; 269 } 270 return NSCAPI::returnUNKNOWN; 271 } 272 NRPEClient::nrpe_result_data NRPEClient::execute_nrpe_command(nrpe_connection_data con, std::wstring arguments) { 273 try { 319 } 320 } 321 322 int NRPEClient::clp_handler_impl::submit(client::configuration::data_type data, ::Plugin::Common_Header* header, const std::string &request, std::string &reply) { 323 std::wstring channel; 324 try { 325 Plugin::SubmitRequestMessage message; 326 message.ParseFromString(request); 327 connection_data con = parse_header(*header); 328 channel = utf8::cvt<std::wstring>(message.channel()); 329 330 for (int i=0;i<message.payload_size();++i) { 331 std::string command = get_command(message.payload(i).alias(), message.payload(i).command()); 332 std::string data = command; 333 for (int a=0;a<message.payload(i).arguments_size();a++) { 334 data += "!" + message.payload(i).arguments(i); 335 } 336 boost::tuple<int,std::wstring> ret = instance->send(con, data); 337 // TODO: Change this to append! 338 nscapi::functions::create_simple_submit_response(channel, utf8::cvt<std::wstring>(command), ret.get<0>(), _T("Message submitted successfully: ") + ret.get<1>(), reply); 339 return NSCAPI::isSuccess; 340 } 341 nscapi::functions::create_simple_submit_response(channel, _T("UNKNOWN"), NSCAPI::returnUNKNOWN, _T("Empty message was submitted"), reply); 342 return NSCAPI::isSuccess; 343 } catch (std::exception &e) { 344 NSC_LOG_ERROR_STD(_T("Exception: ") + utf8::to_unicode(e.what())); 345 nscapi::functions::create_simple_submit_response(channel, _T("UNKNOWN"), NSCAPI::returnUNKNOWN, utf8::to_unicode(e.what()), reply); 346 return NSCAPI::hasFailed; 347 } 348 } 349 350 int NRPEClient::clp_handler_impl::exec(client::configuration::data_type data, ::Plugin::Common_Header* header, const std::string &request, std::string &reply) { 351 NSCAPI::nagiosReturn ret = NSCAPI::returnOK; 352 try { 353 Plugin::ExecuteRequestMessage request_message; 354 request_message.ParseFromString(request); 355 connection_data con = parse_header(*header); 356 357 for (int i=0;i<request_message.payload_size();i++) { 358 std::string command = get_command(request_message.payload(i).command()); 359 std::string data = command; 360 for (int a=0;a<request_message.payload(i).arguments_size();a++) { 361 data += "!" + request_message.payload(i).arguments(a); 362 } 363 boost::tuple<int,std::wstring> ret = instance->send(con, data); 364 nscapi::functions::create_simple_exec_response(utf8::cvt<std::wstring>(command), ret.get<0>(), ret.get<1>(), reply); 365 } 366 return NSCAPI::isSuccess; 367 } catch (std::exception &e) { 368 NSC_LOG_ERROR_STD(_T("Exception: ") + utf8::to_unicode(e.what())); 369 nscapi::functions::create_simple_exec_response(_T("command"), NSCAPI::returnUNKNOWN, _T("Exception: ") + utf8::to_unicode(e.what()), reply); 370 return NSCAPI::hasFailed; 371 } 372 } 373 374 ////////////////////////////////////////////////////////////////////////// 375 // Protocol implementations 376 // 377 378 boost::tuple<int,std::wstring> NRPEClient::send(connection_data con, const std::string data) { 379 try { 380 NSC_DEBUG_MSG_STD(_T("NRPE Connection details: ") + con.to_wstring()); 381 NSC_DEBUG_MSG_STD(_T("NRPE data: ") + utf8::cvt<std::wstring>(data)); 274 382 nrpe::packet packet; 275 if ( !con.no_ssl) {383 if (con.use_ssl) { 276 384 #ifdef USE_SSL 277 packet = send_ssl(con. host, con.port, con.timeout, nrpe::packet::make_request(con.get_cli(arguments), con.buffer_length));385 packet = send_ssl(con.cert, con.host, con.port, con.timeout, nrpe::packet::make_request(utf8::cvt<std::wstring>(data), con.buffer_length)); 278 386 #else 279 NSC_LOG_ERROR_STD(_T("SSL not avalible ( not compiled withUSE_SSL)"));280 return nrpe_result_data(NSCAPI::returnUNKNOWN, _T("SSL support not available (compiled without USE_SSL)!"));387 NSC_LOG_ERROR_STD(_T("SSL not avalible (compiled without USE_SSL)")); 388 return boost::tie(NSCAPI::returnUNKNOWN, _T("SSL support not available (compiled without USE_SSL)")); 281 389 #endif 282 390 } else 283 packet = send_nossl(con.host, con.port, con.timeout, nrpe::packet::make_request( con.get_cli(arguments), con.buffer_length));284 return nrpe_result_data(packet.getResult(), packet.getPayload());391 packet = send_nossl(con.host, con.port, con.timeout, nrpe::packet::make_request(utf8::cvt<std::wstring>(data), con.buffer_length)); 392 return boost::make_tuple(static_cast<int>(packet.getResult()), packet.getPayload()); 285 393 } catch (nrpe::nrpe_packet_exception &e) { 286 return nrpe_result_data(NSCAPI::returnUNKNOWN, _T("NRPE Packet errro: ") + e.wwhat());394 return boost::tie(NSCAPI::returnUNKNOWN, _T("NRPE Packet errro: ") + e.wwhat()); 287 395 } catch (std::runtime_error &e) { 288 NSC_LOG_ERROR_STD(_T("Socket error: ") + utf8::cvt<std::wstring>(e.what())); 289 return nrpe_result_data(NSCAPI::returnUNKNOWN, _T("Socket error: ") + utf8::cvt<std::wstring>(e.what())); 396 NSC_LOG_ERROR_STD(_T("Socket error: ") + utf8::to_unicode(e.what())); 397 return boost::tie(NSCAPI::returnUNKNOWN, _T("Socket error: ") + utf8::to_unicode(e.what())); 398 } catch (std::exception &e) { 399 NSC_LOG_ERROR_STD(_T("Error: ") + utf8::to_unicode(e.what())); 400 return boost::tie(NSCAPI::returnUNKNOWN, _T("Error: ") + utf8::to_unicode(e.what())); 290 401 } catch (...) { 291 return nrpe_result_data(NSCAPI::returnUNKNOWN, _T("Unknown error -- REPORT THIS!"));402 return boost::tie(NSCAPI::returnUNKNOWN, _T("Unknown error -- REPORT THIS!")); 292 403 } 293 404 } … … 295 406 296 407 #ifdef USE_SSL 297 nrpe::packet NRPEClient::send_ssl(std:: wstring host, intport, int timeout, nrpe::packet packet) {408 nrpe::packet NRPEClient::send_ssl(std::string cert, std::string host, std::string port, int timeout, nrpe::packet packet) { 298 409 boost::asio::io_service io_service; 299 410 boost::asio::ssl::context ctx(io_service, boost::asio::ssl::context::sslv23); 300 411 SSL_CTX_set_cipher_list(ctx.impl(), "ADH"); 301 ctx.use_tmp_dh_file(to_string(cert _));412 ctx.use_tmp_dh_file(to_string(cert)); 302 413 ctx.set_verify_mode(boost::asio::ssl::context::verify_none); 303 414 nrpe::client::ssl_socket socket(io_service, ctx, host, port); 304 415 socket.send(packet, boost::posix_time::seconds(timeout)); 305 nrpe::packet ret = socket.recv(packet, boost::posix_time::seconds(timeout)); 306 return ret; 416 return socket.recv(packet, boost::posix_time::seconds(timeout)); 307 417 } 308 418 #endif 309 419 310 nrpe::packet NRPEClient::send_nossl(std:: wstring host, intport, int timeout, nrpe::packet packet) {420 nrpe::packet NRPEClient::send_nossl(std::string host, std::string port, int timeout, nrpe::packet packet) { 311 421 boost::asio::io_service io_service; 312 422 nrpe::client::socket socket(io_service, host, port); … … 320 430 NSC_WRAPPERS_HANDLE_CMD_DEF(); 321 431 NSC_WRAPPERS_CLI_DEF(); 322 432 NSC_WRAPPERS_HANDLE_NOTIFICATION_DEF(); 433 -
modules/NRPEClient/NRPEClient.def
r291548e r96c1461 15 15 NSCommandLineExec 16 16 NSDeleteBuffer 17 NSHandleNotification 18 NSHasNotificationHandler -
modules/NRPEClient/NRPEClient.h
ra78a985 r96c1461 19 19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 20 20 ***************************************************************************/ 21 #pragma once 22 23 #include <boost/tuple/tuple.hpp> 24 25 #include <client/command_line_parser.hpp> 26 #include <nscapi/targets.hpp> 27 28 #include <nrpe/packet.hpp> 21 29 22 30 NSC_WRAPPERS_MAIN(); 23 31 NSC_WRAPPERS_CLI(); 24 25 26 #include <map> 27 #include <nrpe/packet.hpp> 32 NSC_WRAPPERS_CHANNELS(); 28 33 29 34 namespace po = boost::program_options; … … 31 36 class NRPEClient : public nscapi::impl::simple_command_handler, public nscapi::impl::simple_plugin, public nscapi::impl::simple_command_line_exec { 32 37 private: 33 typedef enum { 34 inject, script, script_dir, 35 } command_type; 36 struct nrpe_connection_data { 37 std::wstring host; 38 std::wstring command; 39 std::wstring arguments; 40 std::wstring command_line; 41 std::vector<std::wstring> argument_vector; 42 int port; 38 39 std::wstring channel_; 40 std::wstring target_path; 41 42 nscapi::target_handler targets; 43 client::command_manager commands; 44 45 struct connection_data { 46 std::string cert; 47 std::string host; 48 std::string port; 43 49 int timeout; 44 unsigned int buffer_length; 45 bool no_ssl; 46 nrpe_connection_data(unsigned int buffer_length_ = 1024) 47 : host(_T("127.0.0.1")), 48 port(5666), 49 timeout(10), 50 no_ssl(false), 51 buffer_length(buffer_length_) 52 {} 53 void parse_arguments() { 54 for (std::vector<std::wstring>::const_iterator cit = argument_vector.begin(); cit != argument_vector.end(); ++cit) { 55 if (!arguments.empty()) 56 arguments += _T("!"); 57 arguments += *cit; 58 } 50 int buffer_length; 51 bool use_ssl; 52 53 connection_data(nscapi::functions::destination_container recipient) { 54 cert = recipient.get_string_data("certificate"); 55 timeout = recipient.get_int_data("timeout", 30); 56 buffer_length = recipient.get_int_data("payload length", 1024); 57 use_ssl = recipient.get_bool_data("ssl"); 58 if (recipient.has_data("no ssl")) 59 use_ssl = !recipient.get_bool_data("no ssl"); 60 61 net::url url = recipient.get_url(5666); 62 host = url.host; 63 port = url.get_port(); 59 64 } 60 std::wstring get_cli(std::wstring arguments_) { 61 if (command_line.empty()) { 62 command_line = command; 63 if (command_line.empty()) 64 command_line = _T("_NRPE_CHECK"); 65 if (!arguments_.empty()) 66 command_line += _T("!") + arguments_; 67 else if (!arguments.empty()) 68 command_line += _T("!") + arguments; 69 } 70 return command_line; 71 } 72 std::wstring toString() { 65 66 std::wstring to_wstring() const { 73 67 std::wstringstream ss; 74 ss << _T("host: ") << host;75 ss << _T(", port: ") << port;68 ss << _T("host: ") << utf8::cvt<std::wstring>(host); 69 ss << _T(", port: ") << utf8::cvt<std::wstring>(port); 76 70 ss << _T(", timeout: ") << timeout; 77 ss << _T(", no_ssl: ") << no_ssl;78 71 ss << _T(", buffer_length: ") << buffer_length; 79 ss << _T(", command: ") << command;80 ss << _T(", argument: ") << arguments;72 ss << _T(", use_ssl: ") << use_ssl; 73 ss << _T(", certificate: ") << utf8::cvt<std::wstring>(cert); 81 74 return ss.str(); 82 75 } 83 76 }; 84 struct nrpe_result_data { 85 nrpe_result_data() {} 86 nrpe_result_data(int result_, std::wstring text_) : result(result_), text(text_) {} 87 std::wstring text; 88 int result; 77 78 struct clp_handler_impl : public client::clp_handler, client::target_lookup_interface { 79 80 NRPEClient *instance; 81 clp_handler_impl(NRPEClient *instance) : instance(instance) {} 82 83 int query(client::configuration::data_type data, ::Plugin::Common_Header* header, const std::string &request, std::string &reply); 84 int submit(client::configuration::data_type data, ::Plugin::Common_Header* header, const std::string &request, std::string &reply); 85 int exec(client::configuration::data_type data, ::Plugin::Common_Header* header, const std::string &request, std::string &reply); 86 87 virtual nscapi::functions::destination_container lookup_target(std::wstring &id) { 88 nscapi::functions::destination_container ret; 89 nscapi::target_handler::optarget t = instance->targets.find_target(id); 90 if (t) { 91 if (!t->alias.empty()) 92 ret.id = utf8::cvt<std::string>(t->alias); 93 if (!t->host.empty()) 94 ret.host = utf8::cvt<std::string>(t->host); 95 if (t->has_option("address")) 96 ret.address = utf8::cvt<std::string>(t->options[_T("address")]); 97 else 98 ret.address = utf8::cvt<std::string>(t->host); 99 BOOST_FOREACH(const nscapi::target_handler::target::options_type::value_type &kvp, t->options) { 100 ret.data[utf8::cvt<std::string>(kvp.first)] = utf8::cvt<std::string>(kvp.second); 101 } 102 } 103 return ret; 104 } 89 105 }; 90 typedef std::map<strEx::blindstr, nrpe_connection_data> command_list; 91 command_list commands; 92 unsigned int buffer_length_; 93 std::wstring cert_; 106 94 107 95 108 public: … … 101 114 bool unloadModule(); 102 115 103 116 /** 117 * Return the module name. 118 * @return The module name 119 */ 104 120 static std::wstring getModuleName() { 105 121 #ifdef USE_SSL … … 109 125 #endif 110 126 } 127 /** 128 * Module version 129 * @return module version 130 */ 111 131 static nscapi::plugin_wrapper::module_version getModuleVersion() { 112 nscapi::plugin_wrapper::module_version version = {0, 0, 1};132 nscapi::plugin_wrapper::module_version version = {0, 4, 0 }; 113 133 return version; 114 134 } 115 135 static std::wstring getModuleDescription() { 116 136 return _T("A simple client for checking remote NRPE servers (think proxy).\n") 117 #ifndef USE_BOOST118 _T("BOOST support is missing (this is probably very bad)!\n")119 #endif120 137 #ifndef USE_SSL 121 138 _T("SSL support is missing (so you cant use encryption)!") … … 124 141 } 125 142 126 bool hasCommandHandler(); 127 bool hasMessageHandler(); 143 bool hasCommandHandler() { return true; }; 144 bool hasMessageHandler() { return true; }; 145 bool hasNotificationHandler() { return true; }; 146 NSCAPI::nagiosReturn handleRAWNotification(const wchar_t* channel, std::string request, std::string &response); 128 147 NSCAPI::nagiosReturn handleCommand(const std::wstring &target, const std::wstring &command, std::list<std::wstring> &arguments, std::wstring &message, std::wstring &perf); 129 148 int commandLineExec(const std::wstring &command, std::list<std::wstring> &arguments, std::wstring &result); 130 std::wstring getConfigurationMeta();131 149 132 150 private: 133 nrpe_result_data execute_nrpe_command(nrpe_connection_data con, std::wstring arguments); 134 nrpe::packet send_nossl(std::wstring host, int port, int timeout, nrpe::packet packet); 135 nrpe::packet send_ssl(std::wstring host, int port, int timeout, nrpe::packet packet); 136 void add_options(po::options_description &desc, nrpe_connection_data &command_data); 151 boost::tuple<int,std::wstring> send(connection_data con, std::string data); 152 static nrpe::packet send_nossl(std::string host, std::string port, int timeout, nrpe::packet packet); 153 static nrpe::packet send_ssl(std::string cert, std::string host, std::string port, int timeout, nrpe::packet packet); 154 155 static connection_data parse_header(const ::Plugin::Common_Header &header); 137 156 138 157 private: 158 void add_local_options(po::options_description &desc, client::configuration::data_type data); 159 void setup(client::configuration &config); 139 160 void add_command(std::wstring key, std::wstring args); 140 void add_ server(std::wstring key, std::wstring args);161 void add_target(std::wstring key, std::wstring args); 141 162 142 163 };
Note: See TracChangeset
for help on using the changeset viewer.








