source: nscp/modules/NRPEListener/NRPEListener.cpp @ 1e62ed5

0.4.00.4.10.4.2stable
Last change on this file since 1e62ed5 was 1e62ed5, checked in by Michael Medin <michael@…>, 8 years ago

2005-05-15 MickeM

+ Added NRPE support for checkCounter
+ Updated documentation

  • Make check commands ignore case + Added CheckHelpers module to alter the result of various check and similar things

2005-05-14 MickeM

+ Added support for Volumes (CheckDisk)
+ Added support for checking all drives of a certain kind
+ Added support for altering filter (makes it posible to check removale drives)
+ Created webpage and better documentation

  • Property mode set to 100644
File size: 9.6 KB
Line 
1// CheckEventLog.cpp : Defines the entry point for the DLL application.
2//
3
4#include "stdafx.h"
5#include "NRPEListener.h"
6#include <strEx.h>
7#include <time.h>
8#include <config.h>
9#include "NRPEPacket.h"
10
11NRPEListener gNRPEListener;
12
13BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
14{
15        NSCModuleWrapper::wrapDllMain(hModule, ul_reason_for_call);
16        return TRUE;
17}
18
19NRPEListener::NRPEListener() {
20}
21NRPEListener::~NRPEListener() {
22}
23
24
25
26bool NRPEListener::loadModule() {
27        bUseSSL_ = NSCModuleHelper::getSettingsInt(NRPE_SECTION_TITLE, NRPE_SETTINGS_USE_SSL ,NRPE_SETTINGS_USE_SSL_DEFAULT)==1;
28        timeout = NSCModuleHelper::getSettingsInt(NRPE_SECTION_TITLE, NRPE_SETTINGS_TIMEOUT ,NRPE_SETTINGS_TIMEOUT_DEFAULT);
29        std::list<std::string> commands = NSCModuleHelper::getSettingsSection(NRPE_HANDLER_SECTION_TITLE);
30        std::list<std::string>::iterator it;
31        for (it = commands.begin(); it != commands.end(); it++) {
32                strEx::token t = strEx::getToken(*it, '=');
33                if (t.first.substr(0,7) == "command") {
34                        strEx::token t2 = strEx::getToken(t.first, '[');
35                        t2 = strEx::getToken(t2.second, ']');
36                        t.first = t2.first;
37                }
38                if (t.first.empty() || t.second.empty()) {
39                        NSC_LOG_ERROR_STD("Invalid command definition: " + (*it));
40                } else {
41                        addCommand(t.first.c_str(), t.second);
42                }
43        }
44
45        allowedHosts.setAllowedHosts(strEx::splitEx(NSCModuleHelper::getSettingsString(NRPE_SECTION_TITLE, NRPE_SETTINGS_ALLOWED, NRPE_SETTINGS_ALLOWED_DEFAULT), ","));
46        try {
47                if (bUseSSL_) {
48                        socket_ssl_.setHandler(this);
49                        socket_ssl_.StartListener(NSCModuleHelper::getSettingsInt(NRPE_SECTION_TITLE, NRPE_SETTINGS_PORT, NRPE_SETTINGS_PORT_DEFAULT));
50                } else {
51                        socket_.setHandler(this);
52                        socket_.StartListener(NSCModuleHelper::getSettingsInt(NRPE_SECTION_TITLE, NRPE_SETTINGS_PORT, NRPE_SETTINGS_PORT_DEFAULT));
53                }
54        } catch (simpleSocket::SocketException e) {
55                NSC_LOG_ERROR_STD("Exception caught: " + e.getMessage());
56                return false;
57        } catch (simpleSSL::SSLException e) {
58                NSC_LOG_ERROR_STD("Exception caught: " + e.getMessage());
59                return false;
60        }
61
62        return true;
63}
64bool NRPEListener::unloadModule() {
65        try {
66                if (bUseSSL_) {
67                        socket_ssl_.removeHandler(this);
68                        socket_ssl_.StopListener();
69                } else {
70                        socket_.removeHandler(this);
71                        socket_.StopListener();
72                }
73        } catch (simpleSocket::SocketException e) {
74                NSC_LOG_ERROR_STD("Exception caught: " + e.getMessage());
75                return false;
76        } catch (simpleSSL::SSLException e) {
77                NSC_LOG_ERROR_STD("Exception caught: " + e.getMessage());
78                return false;
79        }
80        return true;
81}
82
83std::string NRPEListener::getModuleName() {
84        return "NRPE module.";
85}
86NSCModuleWrapper::module_version NRPEListener::getModuleVersion() {
87        NSCModuleWrapper::module_version version = {0, 0, 1 };
88        return version;
89}
90
91bool NRPEListener::hasCommandHandler() {
92        return true;
93}
94bool NRPEListener::hasMessageHandler() {
95        return false;
96}
97
98
99NSCAPI::nagiosReturn NRPEListener::handleCommand(const strEx::blindstr command, const unsigned int argLen, char **char_args, std::string &message, std::string &perf) {
100        commandList::iterator it = commands.find(command);
101        if (it == commands.end())
102                return NSCAPI::returnIgnored;
103
104        std::string str = (*it).second;
105        if (NSCModuleHelper::getSettingsInt(NRPE_SECTION_TITLE, NRPE_SETTINGS_ALLOW_ARGUMENTS, NRPE_SETTINGS_ALLOW_ARGUMENTS_DEFAULT) == 1) {
106                arrayBuffer::arrayList arr = arrayBuffer::arrayBuffer2list(argLen, char_args);
107                arrayBuffer::arrayList::const_iterator cit = arr.begin();
108                int i=1;
109
110                for (;cit!=arr.end();cit++,i++) {
111                        if (NSCModuleHelper::getSettingsInt(NRPE_SECTION_TITLE, NRPE_SETTINGS_ALLOW_NASTY_META, NRPE_SETTINGS_ALLOW_NASTY_META_DEFAULT) == 0) {
112                                if ((*cit).find_first_of(NASTY_METACHARS) != std::string::npos) {
113                                        NSC_LOG_ERROR("Request string contained illegal metachars!");
114                                        return NSCAPI::returnIgnored;
115                                }
116                        }
117                        strEx::replace(str, "$ARG" + strEx::itos(i) + "$", (*cit));
118                }
119        }
120
121        if ((str.substr(0,6) == "inject")&&(str.length() > 7)) {
122                strEx::token t = strEx::getToken(str.substr(7), ' ');
123                return NSCModuleHelper::InjectSplitAndCommand(t.first, t.second, ' ', message, perf);
124        }
125
126        return executeNRPECommand(str, message, perf);
127}
128#define MAX_INPUT_BUFFER 1024
129
130int NRPEListener::executeNRPECommand(std::string command, std::string &msg, std::string &perf)
131{
132        NSCAPI::nagiosReturn result;
133        PROCESS_INFORMATION pi;
134        STARTUPINFO si;
135        HANDLE hChildOutR, hChildOutW, hChildInR, hChildInW;
136        SECURITY_ATTRIBUTES sec;
137        DWORD dwstate, dwexitcode;
138        int retval;
139
140
141        // Set up members of SECURITY_ATTRIBUTES structure.
142
143        sec.nLength = sizeof(SECURITY_ATTRIBUTES);
144        sec.bInheritHandle = TRUE;
145        sec.lpSecurityDescriptor = NULL;
146
147        // Create Pipes
148        CreatePipe(&hChildInR, &hChildInW, &sec, 0);
149        CreatePipe(&hChildOutR, &hChildOutW, &sec, 0);
150
151        // Set up members of STARTUPINFO structure.
152
153        ZeroMemory(&si, sizeof(STARTUPINFO));
154        si.cb = sizeof(STARTUPINFO);
155        si.dwFlags = STARTF_USESTDHANDLES;
156        si.hStdInput = hChildInR;
157        si.hStdOutput = hChildOutW;
158        si.hStdError = hChildOutW;
159
160
161        // CreateProcess doesn't work with a const command
162        char *cmd = new char[command.length()+1];
163        strncpy(cmd, command.c_str(), command.length());
164        cmd[command.length()] = 0;
165
166        // Create the child process.
167        BOOL processOK = CreateProcess(NULL, cmd,        // command line
168                NULL, // process security attributes
169                NULL, // primary thread security attributes
170                TRUE, // handles are inherited
171                0,    // creation flags
172                NULL, // use parent's environment
173                NULL, // use parent's current directory
174                &si,  // STARTUPINFO pointer
175                &pi); // receives PROCESS_INFORMATION
176        delete [] cmd;
177
178        if (processOK) {
179                dwstate = WaitForSingleObject(pi.hProcess, 1000*timeout);
180                CloseHandle(hChildInR);
181                CloseHandle(hChildInW);
182                CloseHandle(hChildOutW);
183
184                if (dwstate == WAIT_TIMEOUT) {
185                        TerminateProcess(pi.hProcess, 5);
186                        msg = "The check didn't respond within the timeout period!";
187                        result = NSCAPI::returnUNKNOWN;
188                } else {
189                        DWORD dwread;
190                        char *buf = new char[MAX_INPUT_BUFFER+1];
191                        retval = ReadFile(hChildOutR, buf, MAX_INPUT_BUFFER, &dwread, NULL);
192                        if (!retval || dwread == 0) {
193                                msg = "No output available from command...";
194                        } else {
195                                buf[dwread] = 0;
196                                msg = buf;
197                                strEx::token t = strEx::getToken(msg, '\n');
198                                t = strEx::getToken(t.first, '|');
199                                msg = t.first;
200                                perf = t.second;
201                        }
202                        delete [] buf;
203                        result = NSCHelper::int2nagios(GetExitCodeProcess(pi.hProcess, &dwexitcode));
204                }
205                CloseHandle(pi.hThread);
206                CloseHandle(pi.hProcess);
207                CloseHandle(hChildOutR);
208        }
209        else {
210                msg = "NRPE_NT failed to create process, exiting...";
211                result = NSCAPI::returnUNKNOWN;
212                CloseHandle(hChildInR);
213                CloseHandle(hChildInW);
214                CloseHandle(hChildOutW);
215                CloseHandle(pi.hThread);
216                CloseHandle(pi.hProcess);
217                CloseHandle(hChildOutR);
218        }
219        return result;
220}
221void NRPEListener::onClose()
222{}
223
224void NRPEListener::onAccept(simpleSocket::Socket *client)
225{
226        if (!allowedHosts.inAllowedHosts(client->getAddrString())) {
227                NSC_LOG_ERROR("Unothorized access from: " + client->getAddrString());
228                client->close();
229                return;
230        }
231        try {
232                simpleSocket::DataBuffer block;
233
234                for (int i=0;i<100;i++) {
235                        client->readAll(block, 1048);
236                        if (block.getLength() >= NRPEPacket::getBufferLength())
237                                break;
238                        Sleep(100);
239                }
240                if (i == 100) {
241                        NSC_LOG_ERROR_STD("Could not retrieve NRPE packet.");
242                        client->close();
243                        return;
244                }
245                if (block.getLength() == NRPEPacket::getBufferLength()) {
246                        try {
247                                NRPEPacket out = handlePacket(NRPEPacket(block.getBuffer(), block.getLength()));
248                                block.copyFrom(out.getBuffer(), out.getBufferLength());
249                        } catch (NRPEPacket::NRPEPacketException e) {
250                                NSC_LOG_ERROR_STD("NRPESocketException: " + e.getMessage());
251                                client->close();
252                                return;
253                        }
254                        client->send(block);
255                }
256        } catch (simpleSocket::SocketException e) {
257                NSC_LOG_ERROR_STD("SocketException: " + e.getMessage());
258        } catch (NRPEException e) {
259                NSC_LOG_ERROR_STD("NRPEException: " + e.getMessage());
260        }
261        client->close();
262}
263
264NRPEPacket NRPEListener::handlePacket(NRPEPacket p) {
265        if (p.getType() != NRPEPacket::queryPacket) {
266                NSC_LOG_ERROR("Request is not a query.");
267                throw NRPEException("Invalid query type");
268        }
269        if (p.getVersion() != NRPEPacket::version2) {
270                NSC_LOG_ERROR("Request had unsupported version.");
271                throw NRPEException("Invalid version");
272        }
273        if (!p.verifyCRC()) {
274                NSC_LOG_ERROR("Request had invalid checksum.");
275                throw NRPEException("Invalid checksum");
276        }
277        strEx::token cmd = strEx::getToken(p.getPayload(), '!');
278        std::string msg, perf;
279
280        if (NSCModuleHelper::getSettingsInt(NRPE_SECTION_TITLE, NRPE_SETTINGS_ALLOW_ARGUMENTS, NRPE_SETTINGS_ALLOW_ARGUMENTS_DEFAULT) == 0) {
281                if (!cmd.second.empty()) {
282                        NSC_LOG_ERROR("Request contained arguments (not currently allowed).");
283                        throw NRPEException("Request contained arguments (not currently allowed).");
284                }
285        }
286        if (NSCModuleHelper::getSettingsInt(NRPE_SECTION_TITLE, NRPE_SETTINGS_ALLOW_NASTY_META, NRPE_SETTINGS_ALLOW_NASTY_META_DEFAULT) == 0) {
287                if (cmd.first.find_first_of(NASTY_METACHARS) != std::string::npos) {
288                        NSC_LOG_ERROR("Request command contained illegal metachars!");
289                        throw NRPEException("Request command contained illegal metachars!");
290                }
291                if (cmd.second.find_first_of(NASTY_METACHARS) != std::string::npos) {
292                        NSC_LOG_ERROR("Request arguments contained illegal metachars!");
293                        throw NRPEException("Request command contained illegal metachars!");
294                }
295        }
296
297        NSCAPI::nagiosReturn ret = NSCModuleHelper::InjectSplitAndCommand(cmd.first, cmd.second, '!', msg, perf);
298        if (perf.empty()) {
299                return NRPEPacket(NRPEPacket::responsePacket, NRPEPacket::version2, ret, msg);
300        } else {
301                return NRPEPacket(NRPEPacket::responsePacket, NRPEPacket::version2, ret, msg + "|" + perf);
302        }
303}
304
305NSC_WRAPPERS_MAIN_DEF(gNRPEListener);
306NSC_WRAPPERS_IGNORE_MSG_DEF();
307NSC_WRAPPERS_HANDLE_CMD_DEF(gNRPEListener);
Note: See TracBrowser for help on using the repository browser.