| 1 | // CheckEventLog.cpp : Defines the entry point for the DLL application. |
|---|
| 2 | // |
|---|
| 3 | |
|---|
| 4 | #include "stdafx.h" |
|---|
| 5 | #include "NSClientListener.h" |
|---|
| 6 | #include <strEx.h> |
|---|
| 7 | #include <time.h> |
|---|
| 8 | #include <config.h> |
|---|
| 9 | |
|---|
| 10 | NSClientListener gNSClientListener; |
|---|
| 11 | |
|---|
| 12 | |
|---|
| 13 | #define REQ_CLIENTVERSION 1 // Works fine! |
|---|
| 14 | #define REQ_CPULOAD 2 // Quirks |
|---|
| 15 | #define REQ_UPTIME 3 // Works fine! |
|---|
| 16 | #define REQ_USEDDISKSPACE 4 // Works fine! |
|---|
| 17 | #define REQ_SERVICESTATE 5 // Works fine! |
|---|
| 18 | #define REQ_PROCSTATE 6 // Works fine! |
|---|
| 19 | #define REQ_MEMUSE 7 // Works fine! |
|---|
| 20 | #define REQ_COUNTER 8 // ... in the works ... |
|---|
| 21 | //#define REQ_FILEAGE 9 // ! - not implemented Dont know how to use |
|---|
| 22 | //#define REQ_INSTANCES 10 // ! - not implemented Dont know how to use |
|---|
| 23 | |
|---|
| 24 | BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) |
|---|
| 25 | { |
|---|
| 26 | NSCModuleWrapper::wrapDllMain(hModule, ul_reason_for_call); |
|---|
| 27 | return TRUE; |
|---|
| 28 | } |
|---|
| 29 | |
|---|
| 30 | NSClientListener::NSClientListener() { |
|---|
| 31 | } |
|---|
| 32 | NSClientListener::~NSClientListener() { |
|---|
| 33 | } |
|---|
| 34 | |
|---|
| 35 | bool NSClientListener::loadModule() { |
|---|
| 36 | allowedHosts.setAllowedHosts(strEx::splitEx(NSCModuleHelper::getSettingsString(NSCLIENT_SECTION_TITLE, NSCLIENT_SETTINGS_ALLOWED, NSCLIENT_SETTINGS_ALLOWED_DEFAULT), ",")); |
|---|
| 37 | try { |
|---|
| 38 | socket.setHandler(this); |
|---|
| 39 | socket.StartListener(NSCModuleHelper::getSettingsInt(NSCLIENT_SECTION_TITLE, NSCLIENT_SETTINGS_PORT, NSCLIENT_SETTINGS_PORT_DEFAULT)); |
|---|
| 40 | } catch (simpleSocket::SocketException e) { |
|---|
| 41 | NSC_LOG_ERROR_STD("Exception caught: " + e.getMessage()); |
|---|
| 42 | return false; |
|---|
| 43 | } |
|---|
| 44 | return true; |
|---|
| 45 | } |
|---|
| 46 | bool NSClientListener::unloadModule() { |
|---|
| 47 | try { |
|---|
| 48 | socket.removeHandler(this); |
|---|
| 49 | socket.StopListener(); |
|---|
| 50 | } catch (simpleSocket::SocketException e) { |
|---|
| 51 | NSC_LOG_ERROR_STD("Exception caught: " + e.getMessage()); |
|---|
| 52 | return false; |
|---|
| 53 | } |
|---|
| 54 | return true; |
|---|
| 55 | } |
|---|
| 56 | |
|---|
| 57 | std::string NSClientListener::getModuleName() { |
|---|
| 58 | return "NSClient Listener."; |
|---|
| 59 | } |
|---|
| 60 | NSCModuleWrapper::module_version NSClientListener::getModuleVersion() { |
|---|
| 61 | NSCModuleWrapper::module_version version = {0, 0, 1 }; |
|---|
| 62 | return version; |
|---|
| 63 | } |
|---|
| 64 | |
|---|
| 65 | /** |
|---|
| 66 | * Main command parser and delegator. |
|---|
| 67 | * This also handles a lot of the simpler responses (though some are deferred to other helper functions) |
|---|
| 68 | * |
|---|
| 69 | #define REQ_CLIENTVERSION 1 // Works fine! |
|---|
| 70 | #define REQ_CPULOAD 2 // Quirks |
|---|
| 71 | - Needs settings for default buffer size (backlog) and possibly other things. |
|---|
| 72 | - Buffer needs to be synced with the client (don't know the size of that) |
|---|
| 73 | - I think the idea was that the buffer would recursive to make a smaller memory footprint. |
|---|
| 74 | (ie. the first level buffer have samples from every second, next level samples from every minute, next level hours etc...) |
|---|
| 75 | (and I don't know the status of this, doesn't seem to be that way) |
|---|
| 76 | #define REQ_UPTIME 3 // Works fine! |
|---|
| 77 | #define REQ_USEDDISKSPACE 4 // Works fine! |
|---|
| 78 | #define REQ_SERVICESTATE 5 // Works fine! |
|---|
| 79 | #define REQ_PROCSTATE 6 // Works fine! |
|---|
| 80 | #define REQ_MEMUSE 7 // Works fine! |
|---|
| 81 | //#define REQ_COUNTER 8 // ! - not implemented Have to look at this, if anyone has a sample let me know... |
|---|
| 82 | //#define REQ_FILEAGE 9 // ! - not implemented Don't know how to use |
|---|
| 83 | //#define REQ_INSTANCES 10 // ! - not implemented Don't know how to use |
|---|
| 84 | * |
|---|
| 85 | */ |
|---|
| 86 | |
|---|
| 87 | std::string NSClientListener::parseRequest(std::string buffer) { |
|---|
| 88 | strEx::token pwd = strEx::getToken(buffer, '&'); |
|---|
| 89 | if ( (pwd.first.empty()) || (pwd.first != NSCModuleHelper::getSettingsString(NSCLIENT_SECTION_TITLE, NSCLIENT_SETTINGS_PWD, NSCLIENT_SETTINGS_PWD_DEFAULT)) ) |
|---|
| 90 | return "ERROR: Invalid password."; |
|---|
| 91 | if (pwd.second.empty()) |
|---|
| 92 | return "ERRRO: No command specified."; |
|---|
| 93 | strEx::token cmd = strEx::getToken(pwd.second, '&'); |
|---|
| 94 | if (cmd.first.empty()) |
|---|
| 95 | return "ERRRO: No command specified."; |
|---|
| 96 | |
|---|
| 97 | int c = atoi(cmd.first.c_str()); |
|---|
| 98 | |
|---|
| 99 | // prefix various commands |
|---|
| 100 | switch (c) { |
|---|
| 101 | case REQ_CPULOAD: |
|---|
| 102 | cmd.first = "checkCPU"; |
|---|
| 103 | cmd.second += "&nsclient"; |
|---|
| 104 | break; |
|---|
| 105 | case REQ_UPTIME: |
|---|
| 106 | cmd.first = "checkUpTime"; |
|---|
| 107 | cmd.second = "nsclient"; |
|---|
| 108 | break; |
|---|
| 109 | case REQ_USEDDISKSPACE: |
|---|
| 110 | cmd.first = "CheckDriveSize"; |
|---|
| 111 | cmd.second += "&nsclient"; |
|---|
| 112 | break; |
|---|
| 113 | case REQ_CLIENTVERSION: |
|---|
| 114 | { |
|---|
| 115 | std::string v = NSCModuleHelper::getSettingsString("nsclient compat", "version", "modern"); |
|---|
| 116 | if (v == "modern") |
|---|
| 117 | return NSCModuleHelper::getApplicationName() + " " + NSCModuleHelper::getApplicationVersionString(); |
|---|
| 118 | return NSCModuleHelper::getSettingsString("nsclient compat", "version", "modern"); |
|---|
| 119 | } |
|---|
| 120 | case REQ_SERVICESTATE: |
|---|
| 121 | cmd.first = "checkServiceState"; |
|---|
| 122 | break; |
|---|
| 123 | case REQ_PROCSTATE: |
|---|
| 124 | cmd.first = "checkProcState"; |
|---|
| 125 | break; |
|---|
| 126 | case REQ_MEMUSE: |
|---|
| 127 | cmd.first = "checkMem"; |
|---|
| 128 | cmd.second = "nsclient"; |
|---|
| 129 | break; |
|---|
| 130 | case REQ_COUNTER: |
|---|
| 131 | cmd.first = "checkCounter"; |
|---|
| 132 | cmd.second += "&nsclient"; |
|---|
| 133 | break; |
|---|
| 134 | } |
|---|
| 135 | |
|---|
| 136 | std::string message, perf; |
|---|
| 137 | NSCAPI::nagiosReturn ret = NSCModuleHelper::InjectSplitAndCommand(cmd.first.c_str(), cmd.second.c_str(), '&', message, perf); |
|---|
| 138 | if (!NSCHelper::isNagiosReturnCode(ret)) { |
|---|
| 139 | if (message.empty()) |
|---|
| 140 | return "ERROR: Could not complete the request check log file for more information."; |
|---|
| 141 | return "ERROR: " + message; |
|---|
| 142 | } |
|---|
| 143 | switch (c) { |
|---|
| 144 | case REQ_UPTIME: // Some check_nt commands has no return code syntax |
|---|
| 145 | case REQ_MEMUSE: |
|---|
| 146 | case REQ_CPULOAD: |
|---|
| 147 | case REQ_CLIENTVERSION: |
|---|
| 148 | case REQ_USEDDISKSPACE: |
|---|
| 149 | case REQ_COUNTER: |
|---|
| 150 | return message; |
|---|
| 151 | |
|---|
| 152 | case REQ_SERVICESTATE: // Some check_nt commands return the return code (coded as a string) |
|---|
| 153 | case REQ_PROCSTATE: |
|---|
| 154 | return NSCHelper::translateReturn(ret) + "&" + message; |
|---|
| 155 | |
|---|
| 156 | default: // "New" check_nscp also returns performance data |
|---|
| 157 | if (perf.empty()) |
|---|
| 158 | return NSCHelper::translateReturn(ret) + "&" + message; |
|---|
| 159 | return NSCHelper::translateReturn(ret) + "&" + message + "|" + perf; |
|---|
| 160 | } |
|---|
| 161 | } |
|---|
| 162 | |
|---|
| 163 | void NSClientListener::onClose() |
|---|
| 164 | {} |
|---|
| 165 | |
|---|
| 166 | void NSClientListener::onAccept(simpleSocket::Socket *client) { |
|---|
| 167 | if (!allowedHosts.inAllowedHosts(client->getAddrString())) { |
|---|
| 168 | NSC_LOG_ERROR("Unothorized access from: " + client->getAddrString()); |
|---|
| 169 | client->close(); |
|---|
| 170 | return; |
|---|
| 171 | } |
|---|
| 172 | simpleSocket::DataBuffer db; |
|---|
| 173 | |
|---|
| 174 | |
|---|
| 175 | |
|---|
| 176 | for (int i=0;i<100;i++) { |
|---|
| 177 | client->readAll(db); |
|---|
| 178 | // @todo Make this check if a pcket is read instead of just if we have data |
|---|
| 179 | if (db.getLength() > 0) |
|---|
| 180 | break; |
|---|
| 181 | Sleep(100); |
|---|
| 182 | } |
|---|
| 183 | if (i == 100) { |
|---|
| 184 | NSC_LOG_ERROR_STD("Could not retrieve NSClient packet."); |
|---|
| 185 | client->close(); |
|---|
| 186 | return; |
|---|
| 187 | } |
|---|
| 188 | |
|---|
| 189 | |
|---|
| 190 | |
|---|
| 191 | // client->readAll(db); |
|---|
| 192 | if (db.getLength() > 0) { |
|---|
| 193 | std::string incoming(db.getBuffer(), db.getLength()); |
|---|
| 194 | // NSC_DEBUG_MSG_STD("Incoming data: " + incoming); |
|---|
| 195 | std::string response = parseRequest(incoming); |
|---|
| 196 | // NSC_DEBUG_MSG("Outgoing data: " + response); |
|---|
| 197 | client->send(response.c_str(), static_cast<int>(response.length()), 0); |
|---|
| 198 | } |
|---|
| 199 | client->close(); |
|---|
| 200 | } |
|---|
| 201 | |
|---|
| 202 | NSC_WRAPPERS_MAIN_DEF(gNSClientListener); |
|---|
| 203 | NSC_WRAPPERS_IGNORE_MSG_DEF(); |
|---|
| 204 | NSC_WRAPPERS_IGNORE_CMD_DEF(); |
|---|