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

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

+ NRPE Support (very basic, no encryption, and nothing fancy)

  • Socket classes rewritten + Added NSCModuleHelper::getSettingsSection to the API
  • Property mode set to 100644
File size: 5.2 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
9NRPEListener gNRPEListener;
10
11BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
12{
13        NSCModuleWrapper::wrapDllMain(hModule, ul_reason_for_call);
14        return TRUE;
15}
16
17NRPEListener::NRPEListener() {
18}
19NRPEListener::~NRPEListener() {
20}
21
22#define DEFAULT_NRPE_PORT 5666
23
24
25bool NRPEListener::loadModule() {
26        timeout = NSCModuleHelper::getSettingsInt("NRPE", "commandTimeout", 60);
27        std::list<std::string> commands = NSCModuleHelper::getSettingsSection("NRPE Handlers");
28        std::list<std::string>::iterator it;
29        for (it = commands.begin(); it != commands.end(); it++) {
30                strEx::token t = strEx::getToken(*it, '=');
31                if (t.first.substr(0,7) == "command") {
32                        strEx::token t2 = strEx::getToken(t.first, '[');
33                        t2 = strEx::getToken(t2.second, ']');
34                        t.first = t2.first;
35                }
36                if (t.first.empty() || t.second.empty()) {
37                        NSC_LOG_ERROR_STD("Invalid command definition: " + (*it));
38                } else
39                        addCommand(t.first, t.second);
40        }
41
42        simpleSocket::Socket::WSAStartup();
43        socket.StartListen(NSCModuleHelper::getSettingsInt("NRPE", "port", DEFAULT_NRPE_PORT));
44        return true;
45}
46bool NRPEListener::unloadModule() {
47        socket.close();
48        simpleSocket::Socket::WSACleanup();
49        return true;
50}
51
52std::string NRPEListener::getModuleName() {
53        return "NRPE module.";
54}
55NSCModuleWrapper::module_version NRPEListener::getModuleVersion() {
56        NSCModuleWrapper::module_version version = {0, 0, 1 };
57        return version;
58}
59
60bool NRPEListener::hasCommandHandler() {
61        return true;
62}
63bool NRPEListener::hasMessageHandler() {
64        return false;
65}
66
67
68NSCAPI::nagiosReturn NRPEListener::handleCommand(const std::string command, const unsigned int argLen, char **char_args, std::string &message, std::string &perf) {
69        commandList::iterator it = commands.find(command);
70        if (it == commands.end())
71                return NSCAPI::returnIgnored;
72
73        std::string str = (*it).second;
74        if (NSCModuleHelper::getSettingsInt("NRPE", "AllowArguments", 0) == 0) {
75                arrayBuffer::arrayList arr = arrayBuffer::arrayBuffer2list(argLen, char_args);
76                arrayBuffer::arrayList::const_iterator cit = arr.begin();
77                int i=0;
78
79                for (;cit!=arr.end();it++,i++) {
80                        strEx::replace(str, "ARG" + strEx::itos(i), (*cit));
81                }
82        }
83
84        if (NSCModuleHelper::getSettingsInt("NRPE", "AllowNastyMetaChars", 0) == 0) {
85                if (str.find_first_of(NASTY_METACHARS) != std::string::npos) {
86                        NSC_LOG_ERROR("Request command contained illegal metachars!");
87                        return NSCAPI::returnIgnored;
88                }
89        }
90
91        return executeNRPECommand(str, message, perf);
92}
93#define MAX_INPUT_BUFFER 1024
94
95int NRPEListener::executeNRPECommand(std::string command, std::string &msg, std::string &perf)
96{
97        NSCAPI::nagiosReturn result;
98        PROCESS_INFORMATION pi;
99        STARTUPINFO si;
100        HANDLE hChildOutR, hChildOutW, hChildInR, hChildInW;
101        SECURITY_ATTRIBUTES sec;
102        DWORD dwstate, dwexitcode;
103        int retval;
104
105
106        // Set up members of SECURITY_ATTRIBUTES structure.
107
108        sec.nLength = sizeof(SECURITY_ATTRIBUTES);
109        sec.bInheritHandle = TRUE;
110        sec.lpSecurityDescriptor = NULL;
111
112        // Create Pipes
113        CreatePipe(&hChildInR, &hChildInW, &sec, 0);
114        CreatePipe(&hChildOutR, &hChildOutW, &sec, 0);
115
116        // Set up members of STARTUPINFO structure.
117
118        ZeroMemory(&si, sizeof(STARTUPINFO));
119        si.cb = sizeof(STARTUPINFO);
120        si.dwFlags = STARTF_USESTDHANDLES;
121        si.hStdInput = hChildInR;
122        si.hStdOutput = hChildOutW;
123        si.hStdError = hChildOutW;
124
125
126        // CreateProcess doesn't work with a const command
127        char *cmd = new char[command.length()+1];
128        strncpy(cmd, command.c_str(), command.length());
129        cmd[command.length()] = 0;
130
131        // Create the child process.
132        BOOL processOK = CreateProcess(NULL, cmd,        // command line
133                NULL, // process security attributes
134                NULL, // primary thread security attributes
135                TRUE, // handles are inherited
136                0,    // creation flags
137                NULL, // use parent's environment
138                NULL, // use parent's current directory
139                &si,  // STARTUPINFO pointer
140                &pi); // receives PROCESS_INFORMATION
141        delete [] cmd;
142
143        if (processOK) {
144                dwstate = WaitForSingleObject(pi.hProcess, 1000*timeout);
145                CloseHandle(hChildInR);
146                CloseHandle(hChildInW);
147                CloseHandle(hChildOutW);
148
149                if (dwstate == WAIT_TIMEOUT) {
150                        TerminateProcess(pi.hProcess, 5);
151                        msg = "The check didn't respond within the timeout period!";
152                        result = NSCAPI::returnUNKNOWN;
153                } else {
154                        DWORD dwread;
155                        char *buf = new char[MAX_INPUT_BUFFER+1];
156                        retval = ReadFile(hChildOutR, buf, MAX_INPUT_BUFFER, &dwread, NULL);
157                        if (!retval || dwread == 0) {
158                                msg = "No output available from command...";
159                        } else {
160                                buf[dwread] = 0;
161                                msg = buf;
162                                strEx::token t = strEx::getToken(msg, '\n');
163                                t = strEx::getToken(t.first, '|');
164                                msg = t.first;
165                                perf = t.second;
166                        }
167                        delete [] buf;
168                        result = NSCHelper::int2nagios(GetExitCodeProcess(pi.hProcess, &dwexitcode));
169                }
170                CloseHandle(pi.hThread);
171                CloseHandle(pi.hProcess);
172                CloseHandle(hChildOutR);
173        }
174        else {
175                msg = "NRPE_NT failed to create process, exiting...";
176                result = NSCAPI::returnUNKNOWN;
177                CloseHandle(hChildInR);
178                CloseHandle(hChildInW);
179                CloseHandle(hChildOutW);
180                CloseHandle(pi.hThread);
181                CloseHandle(pi.hProcess);
182                CloseHandle(hChildOutR);
183        }
184        return result;
185}
186
187
188NSC_WRAPPERS_MAIN_DEF(gNRPEListener);
189NSC_WRAPPERS_IGNORE_MSG_DEF();
190NSC_WRAPPERS_HANDLE_CMD_DEF(gNRPEListener);
Note: See TracBrowser for help on using the repository browser.