source: nscp/modules/NRPEServer/NRPEServer.cpp @ 291548e

0.4.00.4.10.4.2
Last change on this file since 291548e was 291548e, checked in by Michael Medin <michael@…>, 3 years ago

Tweaks to the settings subsystem (thread safeness) as well as additions to the command line client and such...

  • Property mode set to 100644
File size: 14.1 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 "NRPEServer.h"
23#include <strEx.h>
24#include <time.h>
25#include <config.h>
26#include <msvc_wrappers.h>
27#include "handler_impl.hpp"
28
29namespace sh = nscapi::settings_helper;
30
31NRPEListener gNRPEListener;
32
33NRPEListener::NRPEListener() : info_(boost::shared_ptr<nrpe::server::handler>(new handler_impl(1024))) {
34}
35NRPEListener::~NRPEListener() {}
36
37std::wstring getAllowedHosts() {
38        return SETTINGS_GET_STRING_FALLBACK(nrpe::ALLOWED_HOSTS, protocol_def::ALLOWED_HOSTS);
39}
40bool getCacheAllowedHosts() {
41        return SETTINGS_GET_BOOL_FALLBACK(nrpe::CACHE_ALLOWED, protocol_def::CACHE_ALLOWED);
42}
43
44
45
46bool NRPEListener::loadModule() {
47        return false;
48}
49
50bool NRPEListener::loadModuleEx(std::wstring alias, NSCAPI::moduleLoadMode mode) {
51
52/*
53DEFINE_SETTING_S(ALLOWED_HOSTS, NRPE_SECTION_PROTOCOL, GENERIC_KEY_ALLOWED_HOSTS, "");
54DESCRIBE_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.");
55
56DEFINE_SETTING_B(CACHE_ALLOWED, NRPE_SECTION_PROTOCOL, GENERIC_KEY_SOCK_CACHE_ALLOWED, false);
57DESCRIBE_SETTING_ADVANCED(CACHE_ALLOWED, "ALLOWED HOSTS CACHING", "Used to cache looked up hosts if you check dynamic/changing hosts set this to false.");
58*/
59        try {
60
61                sh::settings_registry settings(nscapi::plugin_singleton->get_core());
62                settings.set_alias(_T("NRPE"), alias, _T("server"));
63
64                settings.add_path_to_settings()
65                        (_T("NRPE SERVER SECTION"), _T("Section for NRPE (NRPEListener.dll) (check_nrpe) protocol options."))
66                        ;
67
68                settings.add_key_to_settings()
69                        (_T("port"), sh::uint_key(&info_.port, 5666),
70                        _T("PORT NUMBER"), _T("Port to use for NRPE."))
71
72                        (_T("bind to"), sh::string_key(&info_.address),
73                        _T("BIND TO ADDRESS"), _T("Allows you to bind server to a specific local address. This has to be a dotted ip address not a host name. Leaving this blank will bind to all available IP addresses."))
74
75                        (_T("socket queue size"), sh::int_key(&info_.back_log, 0),
76                        _T("LISTEN QUEUE"), _T("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."))
77
78                        (_T("thread pool"), sh::uint_key(&info_.thread_pool_size, 10),
79                        _T("THREAD POOL"), _T(""))
80
81                        (_T("timeout"), sh::uint_key(&info_.timeout, 30),
82                        _T("TIMEOUT"), _T("Timeout when reading packets on incoming sockets. If the data has not arrived within this time we will bail out."))
83
84                        (_T("use ssl"), sh::bool_key(&info_.use_ssl, true),
85                        _T("ENABLE SSL ENCRYPTION"), _T("This option controls if SSL should be enabled."))
86
87                        (_T("payload length"), sh::int_fun_key<unsigned int>(boost::bind(&nrpe::server::handler::set_payload_length, info_.request_handler, _1), 1024),
88                        _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."))
89
90                        (_T("allow arguments"), sh::bool_fun_key<bool>(boost::bind(&nrpe::server::handler::set_allow_arguments, info_.request_handler, _1), false),
91                        _T("COMMAND ARGUMENT PROCESSING"), _T("This option determines whether or not the we will allow clients to specify arguments to commands that are executed."))
92
93                        (_T("allow nasty characters"), sh::bool_fun_key<bool>(boost::bind(&nrpe::server::handler::set_allow_nasty_arguments, info_.request_handler, _1), false),
94                        _T("COMMAND ALLOW NASTY META CHARS"), _T("This option determines whether or not the we will allow clients to specify nasty (as in |`&><'\"\\[]{}) characters in arguments."))
95
96                        (_T("performance data"), sh::bool_fun_key<bool>(boost::bind(&nrpe::server::handler::set_perf_data, info_.request_handler, _1), true),
97                        _T("PERFORMANCE DATA"), _T("Send performance data back to nagios (set this to 0 to remove all performance data)."))
98
99                        (_T("certificate"), sh::wpath_key(&info_.certificate, _T("${certificate-path}/nrpe_dh_512.pem")),
100                        _T("SSL CERTIFICATE"), _T(""))
101                        ;
102
103                settings.register_all();
104                settings.notify();
105
106
107#ifndef USE_SSL
108                if (info_.use_ssl) {
109                        NSC_LOG_ERROR_STD(_T("SSL not avalible! (not compiled with openssl support)"));
110                }
111#endif
112                if (info_.request_handler->get_payload_length() != 1024)
113                        NSC_DEBUG_MSG_STD(_T("Non-standard buffer length (hope you have recompiled check_nrpe changing #define MAX_PACKETBUFFER_LENGTH = ") + strEx::itos(info_.request_handler->get_payload_length()));
114                if (!boost::filesystem::is_regular(info_.certificate))
115                        NSC_LOG_ERROR_STD(_T("Certificate not found: ") + info_.certificate);
116
117                boost::asio::io_service io_service_;
118
119                allowedHosts.setAllowedHosts(strEx::splitEx(getAllowedHosts(), _T(",")), getCacheAllowedHosts(), io_service_);
120                NSC_DEBUG_MSG_STD(_T("Allowed hosts: ") + allowedHosts.to_string());
121
122                if (mode == NSCAPI::normalStart) {
123                        if (info_.use_ssl) {
124#ifdef USE_SSL
125                                server_.reset(new nrpe::server::server(info_));
126#else
127                                NSC_LOG_ERROR_STD(_T("SSL is not supported (not compiled with openssl)"));
128                                return false;
129#endif
130                        } else {
131                                server_.reset(new nrpe::server::server(info_));
132                        }
133                        if (!server_) {
134                                NSC_LOG_ERROR_STD(_T("Failed to create server instance!"));
135                                return false;
136                        }
137                        server_->start();
138                }
139        } catch (nrpe::server::nrpe_exception &e) {
140                NSC_LOG_ERROR_STD(_T("Exception caught: ") + e.what());
141                return false;
142        } catch (std::exception &e) {
143                NSC_LOG_ERROR_STD(_T("Exception caught: ") + to_wstring(e.what()));
144                return false;
145        } catch (...) {
146                NSC_LOG_ERROR_STD(_T("Exception caught: <UNKNOWN EXCEPTION>"));
147                return false;
148        }
149
150
151        return true;
152}
153
154bool NRPEListener::unloadModule() {
155        try {
156                if (server_) {
157                        server_->stop();
158                        server_.reset();
159                }
160        } catch (...) {
161                NSC_LOG_ERROR_STD(_T("Exception caught: <UNKNOWN>"));
162                return false;
163        }
164        return true;
165}
166
167
168bool NRPEListener::hasCommandHandler() {
169        return false;
170}
171bool NRPEListener::hasMessageHandler() {
172        return false;
173}
174
175
176
177
178// void NRPEListener::onAccept(simpleSocket::Socket *client)
179// {
180//      if (!allowedHosts.inAllowedHosts(client->getAddr())) {
181//              NSC_LOG_ERROR(_T("Unauthorize access from: ") + client->getAddrString());
182//              client->close();
183//              return;
184//      }
185//      try {
186//              simpleSocket::DataBuffer block;
187//              int i;
188//              int maxWait = socketTimeout_*10;
189//              for (i=0;i<maxWait;i++) {
190//                      bool lastReadHasMore = false;
191//                      try {
192//                              lastReadHasMore = client->readAll(block, 1048);
193//                      } catch (simpleSocket::SocketException e) {
194//                              NSC_LOG_MESSAGE(_T("Could not read NRPE packet from socket :") + e.getMessage());
195//                              client->close();
196//                              return;
197//                      }
198//                      if (block.getLength() >= NRPEPacket::getBufferLength(buffer_length_))
199//                              break;
200//                      if (!lastReadHasMore) {
201//                              NSC_LOG_MESSAGE(_T("Could not read a full NRPE packet from socket, only got: ") + strEx::itos(block.getLength()));
202//                              client->close();
203//                              return;
204//                      }
205//                      Sleep(100);
206//              }
207//              if (i >= maxWait) {
208//                      NSC_LOG_ERROR_STD(_T("Timeout reading NRPE-packet (increase socket_timeout), we only got: ") + strEx::itos(block.getLength()));
209//                      client->close();
210//                      return;
211//              }
212//              if (block.getLength() == NRPEPacket::getBufferLength(buffer_length_)) {
213//                      try {
214//                              NRPEPacket out = handlePacket(NRPEPacket(block.getBuffer(), block.getLength(), buffer_length_));
215//                              block.copyFrom(out.getBuffer(), out.getBufferLength());
216//                      } catch (NRPEPacket::NRPEPacketException e) {
217//                              NSC_LOG_ERROR_STD(_T("NRPESocketException: ") + e.getMessage());
218//                              try {
219//                                      NRPEPacket err(NRPEPacket::responsePacket, NRPEPacket::version2, NSCAPI::returnUNKNOWN, _T("Could not construct return paket in NRPE handler check clientside (nsclient.log) logs..."), buffer_length_);
220//                                      block.copyFrom(err.getBuffer(), err.getBufferLength());
221//                              } catch (NRPEPacket::NRPEPacketException e) {
222//                                      NSC_LOG_ERROR_STD(_T("NRPESocketException (again): ") + e.getMessage());
223//                                      client->close();
224//                                      return;
225//                              }
226//                      }
227//                      int maxWait = socketTimeout_*10;
228//                      for (i=0;i<maxWait;i++) {
229//                              bool lastReadHasMore = false;
230//                              try {
231//                                      if (client->canWrite())
232//                                              lastReadHasMore = client->sendAll(block);
233//                              } catch (simpleSocket::SocketException e) {
234//                                      NSC_LOG_MESSAGE(_T("Could not send NRPE packet from socket :") + e.getMessage());
235//                                      client->close();
236//                                      return;
237//                              }
238//                              if (!lastReadHasMore) {
239//                                      client->close();
240//                                      return;
241//                              }
242//                              Sleep(100);
243//                      }
244//                      if (i >= maxWait) {
245//                              NSC_LOG_ERROR_STD(_T("Timeout reading NRPE-packet (increase socket_timeout)"));
246//                              client->close();
247//                              return;
248//                      }
249//              } else {
250//                      NSC_LOG_ERROR_STD(_T("We got more then we wanted ") + strEx::itos(NRPEPacket::getBufferLength(buffer_length_)) + _T(", we only got: ") + strEx::itos(block.getLength()));
251//                      client->close();
252//                      return;
253//              }
254//      } catch (simpleSocket::SocketException e) {
255//              NSC_LOG_ERROR_STD(_T("SocketException: ") + e.getMessage());
256//      } catch (NRPEException e) {
257//              NSC_LOG_ERROR_STD(_T("NRPEException: ") + e.getMessage());
258//      } catch (...) {
259//              NSC_LOG_ERROR_STD(_T("Unhandled Exception in NRPE listner..."));
260//      }
261//      client->close();
262// }
263//
264// NRPEPacket NRPEListener::handlePacket(NRPEPacket p) {
265//      if (p.getType() != NRPEPacket::queryPacket) {
266//              NSC_LOG_ERROR(_T("Request is not a query."));
267//              throw NRPEException(_T("Invalid query type: ") + strEx::itos(p.getType()));
268//      }
269//      if (p.getVersion() != NRPEPacket::version2) {
270//              NSC_LOG_ERROR(_T("Request had unsupported version."));
271//              throw NRPEException(_T("Invalid version"));
272//      }
273//      if (!p.verifyCRC()) {
274//              NSC_LOG_ERROR(_T("Request had invalid checksum."));
275//              throw NRPEException(_T("Invalid checksum"));
276//      }
277//      strEx::token cmd = strEx::getToken(p.getPayload(), '!');
278//      if (cmd.first == _T("_NRPE_CHECK")) {
279//              return NRPEPacket(NRPEPacket::responsePacket, NRPEPacket::version2, NSCAPI::returnOK, _T("I (") + NSCModuleHelper::getApplicationVersionString() + _T(") seem to be doing fine..."), buffer_length_);
280//      }
281//      std::wstring msg, perf;
282//
283//      if (allowArgs_) {
284//              if (!cmd.second.empty()) {
285//                      NSC_LOG_ERROR(_T("Request contained arguments (not currently allowed, check the allow_arguments option)."));
286//                      throw NRPEException(_T("Request contained arguments (not currently allowed, check the allow_arguments option)."));
287//              }
288//      }
289//      if (allowNasty_) {
290//              if (cmd.first.find_first_of(NASTY_METACHARS) != std::wstring::npos) {
291//                      NSC_LOG_ERROR(_T("Request command contained illegal metachars!"));
292//                      throw NRPEException(_T("Request command contained illegal metachars!"));
293//              }
294//              if (cmd.second.find_first_of(NASTY_METACHARS) != std::wstring::npos) {
295//                      NSC_LOG_ERROR(_T("Request arguments contained illegal metachars!"));
296//                      throw NRPEException(_T("Request command contained illegal metachars!"));
297//              }
298//      }
299//      //TODO REMOVE THIS
300//      //return NRPEPacket(NRPEPacket::responsePacket, NRPEPacket::version2, NSCAPI::returnUNKNOWN, _T("TEST TEST TEST"), buffer_length_);
301//
302//      NSCAPI::nagiosReturn ret = -3;
303//      try {
304//              ret = NSCModuleHelper::InjectSplitAndCommand(cmd.first, cmd.second, '!', msg, perf);
305//      } catch (...) {
306//              return NRPEPacket(NRPEPacket::responsePacket, NRPEPacket::version2, NSCAPI::returnUNKNOWN, _T("UNKNOWN: Internal exception"), buffer_length_);
307//      }
308//      switch (ret) {
309//              case NSCAPI::returnInvalidBufferLen:
310//                      msg = _T("UNKNOWN: Return buffer to small to handle this command.");
311//                      ret = NSCAPI::returnUNKNOWN;
312//                      break;
313//              case NSCAPI::returnIgnored:
314//                      msg = _T("UNKNOWN: No handler for that command");
315//                      ret = NSCAPI::returnUNKNOWN;
316//                      break;
317//              case NSCAPI::returnOK:
318//              case NSCAPI::returnWARN:
319//              case NSCAPI::returnCRIT:
320//              case NSCAPI::returnUNKNOWN:
321//                      break;
322//              default:
323//                      msg = _T("UNKNOWN: Internal error.");
324//                      ret = NSCAPI::returnUNKNOWN;
325//      }
326//      if (msg.length() >= buffer_length_-1) {
327//              NSC_LOG_ERROR(_T("Truncating returndata as it is bigger then NRPE allowes :("));
328//              msg = msg.substr(0,buffer_length_-2);
329//      }
330//      if (perf.empty()||noPerfData_) {
331//              return NRPEPacket(NRPEPacket::responsePacket, NRPEPacket::version2, ret, msg, buffer_length_);
332//      } else {
333//              return NRPEPacket(NRPEPacket::responsePacket, NRPEPacket::version2, ret, msg + _T("|") + perf, buffer_length_);
334//      }
335// }
336
337NSC_WRAP_DLL();
338NSC_WRAPPERS_MAIN_DEF(gNRPEListener);
339NSC_WRAPPERS_IGNORE_MSG_DEF();
340NSC_WRAPPERS_IGNORE_CMD_DEF();
Note: See TracBrowser for help on using the repository browser.