source: nscp/modules/NRPEClient/NRPEClient.cpp @ 252c016

0.4.00.4.10.4.2stable
Last change on this file since 252c016 was 252c016, checked in by Michael Medin <michael@…>, 5 years ago

removed some debug logs

  • Property mode set to 100644
File size: 11.2 KB
Line 
1/**************************************************************************
2*   Copyright (C) 2004-2007 by Michael Medin <michael@medin.name>         *
3*                                                                         *
4*   This code is part of NSClient++ - http://trac.nakednuns.org/nscp      *
5*                                                                         *
6*   This program is free software; you can redistribute it and/or modify  *
7*   it under the terms of the GNU General Public License as published by  *
8*   the Free Software Foundation; either version 2 of the License, or     *
9*   (at your option) any later version.                                   *
10*                                                                         *
11*   This program is distributed in the hope that it will be useful,       *
12*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14*   GNU General Public License for more details.                          *
15*                                                                         *
16*   You should have received a copy of the GNU General Public License     *
17*   along with this program; if not, write to the                         *
18*   Free Software Foundation, Inc.,                                       *
19*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
20***************************************************************************/
21#include "stdafx.h"
22#include "NRPEClient.h"
23#include <strEx.h>
24#include <time.h>
25#include <config.h>
26#include <msvc_wrappers.h>
27#include <execute_process.hpp>
28#include <program_options_ex.hpp>
29
30NRPEClient gNRPEClient;
31
32BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
33{
34        NSCModuleWrapper::wrapDllMain(hModule, ul_reason_for_call);
35        return TRUE;
36}
37
38NRPEClient::NRPEClient() : buffer_length_(0) {
39}
40
41NRPEClient::~NRPEClient() {
42}
43
44bool NRPEClient::loadModule() {
45        buffer_length_ = NSCModuleHelper::getSettingsInt(NRPE_SECTION_TITLE, NRPE_SETTINGS_STRLEN, NRPE_SETTINGS_STRLEN_DEFAULT);
46
47        std::list<std::wstring> commands = NSCModuleHelper::getSettingsSection(NRPE_CLIENT_HANDLER_SECTION_TITLE);
48        NSC_DEBUG_MSG_STD(_T("humm..."));
49        for (std::list<std::wstring>::const_iterator it = commands.begin(); it != commands.end(); ++it) {
50                NSC_DEBUG_MSG_STD(*it);
51                std::wstring s = NSCModuleHelper::getSettingsString(NRPE_CLIENT_HANDLER_SECTION_TITLE, (*it), _T(""));
52                if (s.empty()) {
53                        NSC_LOG_ERROR_STD(_T("Invalid NRPE-client entry: ") + (*it));
54                } else {
55                        addCommand((*it).c_str(), s);
56                }
57        }
58        return true;
59}
60
61void NRPEClient::addCommand(strEx::blindstr key, std::wstring args) {
62        try {
63                boost::program_options::options_description desc = get_optionDesc();
64                boost::program_options::positional_options_description p = get_optionsPositional();
65
66                boost::program_options::variables_map vm;
67                boost::program_options::store(
68                        basic_command_line_parser_ex<TCHAR>(args).options(desc).positional(p).run()
69                        , vm);
70                boost::program_options::notify(vm);
71                nrpe_connection_data cd = get_ConectionData(vm);
72                NSC_DEBUG_MSG_STD(_T("Added NRPE Client: ") + key.c_str() + _T(" = ") + cd.toString());
73                commands[key] = cd;
74        } catch (boost::program_options::validation_error &e) {
75                NSC_LOG_ERROR_STD(_T("Could not parse: ") + key.c_str() + strEx::string_to_wstring(e.what()));
76        } catch (...) {
77                NSC_LOG_ERROR_STD(_T("Could not parse: ") + key.c_str());
78        }
79}
80
81bool NRPEClient::unloadModule() {
82        return true;
83}
84
85bool NRPEClient::hasCommandHandler() {
86        return true;
87}
88bool NRPEClient::hasMessageHandler() {
89        return false;
90}
91NSCAPI::nagiosReturn NRPEClient::handleCommand(const strEx::blindstr command, const unsigned int argLen, TCHAR **char_args, std::wstring &message, std::wstring &perf)
92{
93        command_list::const_iterator cit = commands.find(command);
94        if (cit == commands.end())
95                return NSCAPI::returnIgnored;
96        nrpe_result_data r = execute_nrpe_command((*cit).second);
97        message = r.text;
98        return r.result;
99}
100
101
102boost::program_options::options_description NRPEClient::get_optionDesc() {
103        boost::program_options::options_description desc("Allowed options");
104        buffer_length_ = NSCModuleHelper::getSettingsInt(NRPE_SECTION_TITLE, NRPE_SETTINGS_STRLEN, NRPE_SETTINGS_STRLEN_DEFAULT);
105        desc.add_options()
106                ("help,h", "Show this help message.")
107                ("host,H", boost::program_options::wvalue<std::wstring>(), "The address of the host running the NRPE daemon")
108                ("port,p", boost::program_options::value<int>(), "The port on which the daemon is running (default=5666)")
109                ("command,c", boost::program_options::wvalue<std::wstring>(), "The name of the command that the remote daemon should run")
110                ("timeout,t", boost::program_options::value<int>(), "Number of seconds before connection times out (default=10)")
111                ("buffer-length,l", boost::program_options::value<int>(), std::string("Length of payload (has to be same as on the server (default=" + strEx::s::itos(buffer_length_) + ")").c_str())
112                ("no-ssl,n", "Do not initial an ssl handshake with the server, talk in plaintext.")
113                ("arguments,a", boost::program_options::wvalue<std::vector<std::wstring>>(), "list of arguments")
114                ;
115        return desc;
116}
117boost::program_options::positional_options_description NRPEClient::get_optionsPositional() {
118        boost::program_options::positional_options_description p;
119        p.add("arguments", -1);
120        return p;
121}
122NRPEClient::nrpe_connection_data NRPEClient::get_ConectionData(boost::program_options::variables_map &vm) {
123        nrpe_connection_data ret(buffer_length_);
124        if (vm.count("host"))
125                ret.host = vm["host"].as<std::wstring>();
126        if (vm.count("port"))
127                ret.port = vm["port"].as<int>();
128        if (vm.count("timeout"))
129                ret.timeout = vm["timeout"].as<int>();
130        if (vm.count("buffer-length"))
131                ret.buffer_length = vm["buffer-length"].as<int>();
132        if (vm.count("command"))
133                ret.command = vm["command"].as<std::wstring>();
134        if (vm.count("arguments")) {
135                std::vector<std::wstring> v = vm["arguments"].as<std::vector<std::wstring>>();
136                for (std::vector<std::wstring>::const_iterator cit = v.begin(); cit != v.end(); ++cit) {
137                        if (!ret.arguments.empty())
138                                ret.arguments += _T("!");
139                        ret.arguments += *cit;
140                }
141        }
142        if (vm.count("no-ssl"))
143                ret.ssl = false;
144        return ret;
145}
146int NRPEClient::commandLineExec(const TCHAR* command, const unsigned int argLen, TCHAR** args) {
147        try {
148                boost::program_options::options_description desc = get_optionDesc();
149                boost::program_options::positional_options_description p = get_optionsPositional();
150               
151                boost::program_options::variables_map vm;
152                boost::program_options::store(
153                        basic_command_line_parser_ex<TCHAR>(command, argLen, args).options(desc).positional(p).run()
154                        , vm);
155                boost::program_options::notify(vm);   
156
157                if (vm.count("help")) {
158                        std::cout << desc << "\n";
159                        return 1;
160                }
161
162                nrpe_result_data result = execute_nrpe_command(get_ConectionData(vm));
163                std::wcout << result.text << std::endl;
164                return result.result;
165        } catch (boost::program_options::validation_error &e) {
166                std::cout << e.what() << std::endl;
167        } catch (...) {
168                std::cout << "Unknown exception parsing command line" << std::endl;
169        }
170        return NSCAPI::returnUNKNOWN;
171}
172NRPEClient::nrpe_result_data NRPEClient::execute_nrpe_command(nrpe_connection_data con) {
173        try {
174                NRPEPacket packet;
175                if (con.ssl)
176                        packet = send_ssl(con.host, con.port, con.timeout, NRPEPacket::make_request(con.get_cli(), con.buffer_length));
177                else
178                        packet = send_nossl(con.host, con.port, con.timeout, NRPEPacket::make_request(con.get_cli(), con.buffer_length));
179                return nrpe_result_data(packet.getResult(), packet.getPayload());
180        } catch (simpleSocket::SocketException &e) {
181                return nrpe_result_data(NSCAPI::returnUNKNOWN, _T("Socket error: ") + e.getMessage());
182        } catch (simpleSSL::SSLException &e) {
183                return nrpe_result_data(NSCAPI::returnUNKNOWN, _T("SSL Socket error: ") + e.getMessage());
184        } catch (...) {
185                return nrpe_result_data(NSCAPI::returnUNKNOWN, _T("Unknown error"));
186        }
187}
188NRPEPacket NRPEClient::send_ssl(std::wstring host, int port, int timeout, NRPEPacket packet)
189{
190        simpleSSL::Socket socket(true);
191        socket.connect(host, port);
192        socket.sendAll(packet.getBuffer(), packet.getBufferLength());
193        simpleSocket::DataBuffer buffer;
194        socket.readAll(buffer);
195        packet.readFrom(buffer.getBuffer(), buffer.getLength());
196        return packet;
197}
198NRPEPacket NRPEClient::send_nossl(std::wstring host, int port, int timeout, NRPEPacket packet)
199{
200        simpleSocket::Socket socket(true);
201        socket.connect(host, port);
202        socket.sendAll(packet.getBuffer(), packet.getBufferLength());
203        simpleSocket::DataBuffer buffer;
204        socket.readAll(buffer);
205        packet.readFrom(buffer.getBuffer(), buffer.getLength());
206        return packet;
207}
208
209
210
211
212
213
214NSC_WRAPPERS_MAIN_DEF(gNRPEClient);
215NSC_WRAPPERS_IGNORE_MSG_DEF();
216NSC_WRAPPERS_HANDLE_CMD_DEF(gNRPEClient);
217NSC_WRAPPERS_HANDLE_CONFIGURATION(gNRPEClient);
218NSC_WRAPPERS_CLI_DEF(gNRPEClient);
219
220
221MODULE_SETTINGS_START(NRPEClient, _T("NRPE Listener configuration"), _T("..."))
222
223PAGE(_T("NRPE Listsner configuration"))
224
225ITEM_EDIT_TEXT(_T("port"), _T("This is the port the NRPEClient.dll will listen to."))
226ITEM_MAP_TO(_T("basic_ini_text_mapper"))
227OPTION(_T("section"), _T("NRPE"))
228OPTION(_T("key"), _T("port"))
229OPTION(_T("default"), _T("5666"))
230ITEM_END()
231
232ITEM_CHECK_BOOL(_T("allow_arguments"), _T("This option determines whether or not the NRPE daemon will allow clients to specify arguments to commands that are executed."))
233ITEM_MAP_TO(_T("basic_ini_bool_mapper"))
234OPTION(_T("section"), _T("NRPE"))
235OPTION(_T("key"), _T("allow_arguments"))
236OPTION(_T("default"), _T("false"))
237OPTION(_T("true_value"), _T("1"))
238OPTION(_T("false_value"), _T("0"))
239ITEM_END()
240
241ITEM_CHECK_BOOL(_T("allow_nasty_meta_chars"), _T("This might have security implications (depending on what you do with the options)"))
242ITEM_MAP_TO(_T("basic_ini_bool_mapper"))
243OPTION(_T("section"), _T("NRPE"))
244OPTION(_T("key"), _T("allow_nasty_meta_chars"))
245OPTION(_T("default"), _T("false"))
246OPTION(_T("true_value"), _T("1"))
247OPTION(_T("false_value"), _T("0"))
248ITEM_END()
249
250ITEM_CHECK_BOOL(_T("use_ssl"), _T("This option will enable SSL encryption on the NRPE data socket (this increases security somwhat."))
251ITEM_MAP_TO(_T("basic_ini_bool_mapper"))
252OPTION(_T("section"), _T("NRPE"))
253OPTION(_T("key"), _T("use_ssl"))
254OPTION(_T("default"), _T("true"))
255OPTION(_T("true_value"), _T("1"))
256OPTION(_T("false_value"), _T("0"))
257ITEM_END()
258
259PAGE_END()
260ADVANCED_PAGE(_T("Access configuration"))
261
262ITEM_EDIT_OPTIONAL_LIST(_T("Allow connection from:"), _T("This is the hosts that will be allowed to poll performance data from the NRPE server."))
263OPTION(_T("disabledCaption"), _T("Use global settings (defined previously)"))
264OPTION(_T("enabledCaption"), _T("Specify hosts for NRPE server"))
265OPTION(_T("listCaption"), _T("Add all IP addresses (not hosts) which should be able to connect:"))
266OPTION(_T("separator"), _T(","))
267OPTION(_T("disabled"), _T(""))
268ITEM_MAP_TO(_T("basic_ini_text_mapper"))
269OPTION(_T("section"), _T("NRPE"))
270OPTION(_T("key"), _T("allowed_hosts"))
271OPTION(_T("default"), _T(""))
272ITEM_END()
273
274PAGE_END()
275MODULE_SETTINGS_END()
Note: See TracBrowser for help on using the repository browser.