license changed to LGPL for libnxcl, libnxsnmp, libnxlp, libnxsl, and libnxmap
[public/netxms.git] / src / libnxcl / main.cpp
CommitLineData
5039dede
AK
1/*
2** NetXMS - Network Management System
3** Client Library
65d2c384 4** Copyright (C) 2003-2010 Victor Kirhenshtein
5039dede
AK
5**
6** This program is free software; you can redistribute it and/or modify
65d2c384
VK
7** it under the terms of the GNU Lesser General Public License as published by
8** the Free Software Foundation; either version 3 of the License, or
5039dede
AK
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**
65d2c384 16** You should have received a copy of the GNU Lesser General Public License
5039dede
AK
17** along with this program; if not, write to the Free Software
18** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19**
20** File: main.cpp
21**
22**/
23
24#include "libnxcl.h"
25
26
27//
28// Global variables
29//
30
31NXC_DEBUG_CALLBACK g_pDebugCallBack = NULL;
32
33
34//
35// Print debug messages
36//
37
c5c0f362 38void DebugPrintf(const TCHAR *format, ...)
5039dede
AK
39{
40 va_list args;
c5c0f362 41 TCHAR buffer[4096];
5039dede
AK
42
43 if (g_pDebugCallBack == NULL)
44 return;
45
c5c0f362
VK
46 va_start(args, format);
47 _vsntprintf(buffer, 4096, format, args);
5039dede 48 va_end(args);
c5c0f362 49 g_pDebugCallBack(buffer);
5039dede
AK
50}
51
52
53//
54// Initialization function
55//
56
57BOOL LIBNXCL_EXPORTABLE NXCInitialize(void)
58{
59 return InitCryptoLib(0xFFFF);
60}
61
62
63//
64// Shutdown function
65//
66
67void LIBNXCL_EXPORTABLE NXCShutdown(void)
68{
69}
70
71
72//
73// Get library version
74//
75
76DWORD LIBNXCL_EXPORTABLE NXCGetVersion(void)
77{
78 return (NETXMS_VERSION_MAJOR << 24) | (NETXMS_VERSION_MINOR << 16) | NETXMS_VERSION_BUILD;
79}
80
81
82//
83// Set event handler
84//
85
86void LIBNXCL_EXPORTABLE NXCSetEventHandler(NXC_SESSION hSession, NXC_EVENT_HANDLER pHandler)
87{
88 ((NXCL_Session *)hSession)->m_pEventHandler = pHandler;
89}
90
91
92//
93// Set callback for debug messages
94//
95
96void LIBNXCL_EXPORTABLE NXCSetDebugCallback(NXC_DEBUG_CALLBACK pFunc)
97{
98 g_pDebugCallBack = pFunc;
99}
100
101
102//
103// Set command timeout
104//
105
106void LIBNXCL_EXPORTABLE NXCSetCommandTimeout(NXC_SESSION hSession, DWORD dwTimeout)
107{
108 if ((dwTimeout >= 1000) && (dwTimeout <= 60000))
109 ((NXCL_Session *)hSession)->m_dwCommandTimeout = dwTimeout;
110}
111
112
113//
114// Get server ID
115//
116
117void LIBNXCL_EXPORTABLE NXCGetServerID(NXC_SESSION hSession, BYTE *pbsId)
118{
119 memcpy(pbsId, ((NXCL_Session *)hSession)->m_bsServerId, 8);
120}
121
122
123//
124// Subscribe to channel
125//
126
127DWORD LIBNXCL_EXPORTABLE NXCSubscribe(NXC_SESSION hSession, DWORD dwChannels)
128{
129 return ((NXCL_Session *)hSession)->SetSubscriptionStatus(dwChannels, 1);
130}
131
132
133//
134// Unsubscribe from channel
135//
136
137DWORD LIBNXCL_EXPORTABLE NXCUnsubscribe(NXC_SESSION hSession, DWORD dwChannels)
138{
139 return ((NXCL_Session *)hSession)->SetSubscriptionStatus(dwChannels, 0);
140}
141
142
143//
144// Set client data
145//
146
147void LIBNXCL_EXPORTABLE NXCSetClientData(NXC_SESSION hSession, void *pData)
148{
67a736f0
VK
149 if (hSession != NULL)
150 ((NXCL_Session *)hSession)->SetClientData(pData);
5039dede
AK
151}
152
153
154//
155// Get client data
156//
157
158void LIBNXCL_EXPORTABLE *NXCGetClientData(NXC_SESSION hSession)
159{
67a736f0 160 return (hSession != NULL) ? ((NXCL_Session *)hSession)->GetClientData() : NULL;
5039dede
AK
161}
162
163
164//
165// Check if password needs to be changed
166//
167
168BOOL LIBNXCL_EXPORTABLE NXCNeedPasswordChange(NXC_SESSION hSession)
169{
170 return ((NXCL_Session *)hSession)->NeedPasswordChange();
171}
172
173
174//
175// Check if server has problems with backend database connection
176//
177
178BOOL LIBNXCL_EXPORTABLE NXCIsDBConnLost(NXC_SESSION hSession)
179{
180 return ((NXCL_Session *)hSession)->IsDBConnLost();
181}
182
183
184//
185// Check if password needs to be changed
186//
187
188void LIBNXCL_EXPORTABLE NXCStartWatchdog(NXC_SESSION hSession)
189{
67a736f0 190 ((NXCL_Session *)hSession)->StartWatchdogThread();
5039dede
AK
191}
192
193
194//
195// Get last lock information (owner of already locked component)
196//
197
198void LIBNXCL_EXPORTABLE NXCGetLastLockOwner(NXC_SESSION hSession, TCHAR *pszBuffer,
199 int nBufSize)
200{
201 if (hSession != NULL)
67a736f0 202 nx_strncpy(pszBuffer, ((NXCL_Session *)hSession)->getLastLock(), nBufSize);
5039dede
AK
203 else
204 nx_strncpy(pszBuffer, _T("INVALID SESSION HANDLE"), nBufSize);
205}
206
207
208//
209// Send SMS via server
210//
211
212DWORD LIBNXCL_EXPORTABLE NXCSendSMS(NXC_SESSION hSession, TCHAR *phone, TCHAR *message)
213{
214 CSCPMessage msg;
215 DWORD dwRqId;
216
67a736f0
VK
217 CHECK_SESSION_HANDLE();
218
5039dede
AK
219 dwRqId = ((NXCL_Session *)hSession)->CreateRqId();
220
221 msg.SetCode(CMD_SEND_SMS);
222 msg.SetId(dwRqId);
223 msg.SetVariable(VID_RCPT_ADDR, phone);
224 msg.SetVariable(VID_MESSAGE, message);
225 ((NXCL_Session *)hSession)->SendMsg(&msg);
226
227 return ((NXCL_Session *)hSession)->WaitForRCC(dwRqId);
228}
229
230
231//
5b0fa340
VK
232// Check connection status by sending keepalive message
233//
234
235DWORD LIBNXCL_EXPORTABLE NXCCheckConnection(NXC_SESSION hSession)
236{
237 CSCPMessage msg;
238 DWORD dwRqId;
239
67a736f0
VK
240 CHECK_SESSION_HANDLE();
241
5b0fa340
VK
242 dwRqId = ((NXCL_Session *)hSession)->CreateRqId();
243
244 msg.SetCode(CMD_KEEPALIVE);
245 msg.SetId(dwRqId);
246 if (!((NXCL_Session *)hSession)->SendMsg(&msg))
247 return RCC_COMM_FAILURE;
248
249 return ((NXCL_Session *)hSession)->WaitForRCC(dwRqId);
250}
251
252
253//
5039dede
AK
254// Get server's time zone
255//
256
257const TCHAR LIBNXCL_EXPORTABLE *NXCGetServerTimeZone(NXC_SESSION hSession)
258{
67a736f0 259 const TCHAR *ptr;
5039dede 260
67a736f0 261 ptr = ((NXCL_Session *)hSession)->getServerTimeZone();
5039dede
AK
262 return (*ptr == 0) ? NULL : ptr;
263}
264
265
266//
267// Generate Message ID
268//
269
270DWORD LIBNXCL_EXPORTABLE NXCGenerateMessageId(NXC_SESSION hSession)
271{
272 return ((NXCL_Session *)hSession)->CreateRqId();
273}
274
275
276//
277// Send prepared NXCP message
278//
279
280BOOL LIBNXCL_EXPORTABLE NXCSendMessage(NXC_SESSION hSession, CSCPMessage *msg)
281{
67a736f0 282 CHECK_SESSION_HANDLE();
5039dede
AK
283 return ((NXCL_Session *)hSession)->SendMsg(msg);
284}
285
286
287//
288// Wait for message
289//
290
291CSCPMessage LIBNXCL_EXPORTABLE *NXCWaitForMessage(NXC_SESSION hSession, WORD wCode, DWORD dwRqId)
292{
67a736f0 293 return (hSession != NULL) ? ((NXCL_Session *)hSession)->WaitForMessage(wCode, dwRqId) : NULL;
5039dede
AK
294}
295
296
297//
298// Wait for CMD_REQUEST_COMPLETED message and return value of VID_RCC
299//
300
301DWORD LIBNXCL_EXPORTABLE NXCWaitForRCC(NXC_SESSION hSession, DWORD dwRqId)
302{
67a736f0
VK
303 CHECK_SESSION_HANDLE();
304 return ((NXCL_Session *)hSession)->WaitForRCC(dwRqId);
5039dede
AK
305}
306
307
308//
309// Get text for error
310//
311
312const TCHAR LIBNXCL_EXPORTABLE *NXCGetErrorText(DWORD dwError)
313{
314 static const TCHAR *pszErrorText[] =
315 {
316 _T("Request completed successfully"),
317 _T("Component locked"),
318 _T("Access denied"),
319 _T("Invalid request"),
320 _T("Request timed out"),
321 _T("Request is out of state"),
322 _T("Database failure"),
323 _T("Invalid object ID"),
324 _T("Object already exist"),
325 _T("Communication failure"),
326 _T("System failure"),
327 _T("Invalid user ID"),
328 _T("Invalid argument"),
329 _T("Duplicate DCI"),
330 _T("Invalid DCI ID"),
331 _T("Out of memory"),
332 _T("Input/Output error"),
333 _T("Incompatible operation"),
334 _T("Object creation failed"),
335 _T("Loop in object relationship detected"),
336 _T("Invalid object name"),
337 _T("Invalid alarm ID"),
338 _T("Invalid action ID"),
339 _T("Operation in progress"),
340 _T("Copy operation failed for one or more DCI(s)"),
341 _T("Invalid or unknown event code"),
342 _T("No interfaces suitable for sending magic packet"),
343 _T("No MAC address on interface"),
344 _T("Command not implemented"),
345 _T("Invalid trap configuration record ID"),
346 _T("Requested data collection item is not supported by agent"),
347 _T("Client and server versions mismatch"),
348 _T("Error parsing package information file"),
349 _T("Package with specified properties already installed on server"),
350 _T("Package file already exist on server"),
351 _T("Server resource busy"),
352 _T("Invalid package ID"),
353 _T("Invalid IP address"),
354 _T("Action is used in event processing policy"),
355 _T("Variable not found"),
356 _T("Server uses incompatible version of communication protocol"),
357 _T("Address already in use"),
358 _T("Unable to select cipher"),
359 _T("Invalid public key"),
360 _T("Invalid session key"),
361 _T("Encryption is not supported by peer"),
362 _T("Server internal error"),
363 _T("Execution of external command failed"),
364 _T("Invalid object tool ID"),
365 _T("SNMP protocol error"),
366 _T("Incorrect regular expression"),
367 _T("Parameter is not supported by agent"),
368 _T("File I/O operation failed"),
369 _T("MIB file is corrupted"),
370 _T("File transfer operation already in progress"),
f40831eb 371 _T("Invalid job ID"),
5039dede
AK
372 _T("Invalid script ID"),
373 _T("Invalid script name"),
374 _T("Unknown map name"),
375 _T("Invalid map ID"),
376 _T("Account disabled"),
377 _T("No more grace logins"),
378 _T("Server connection broken"),
379 _T("Invalid agent configuration ID"),
380 _T("Server has lost connection with backend database"),
381 _T("Alarm is still open in helpdesk system"),
382 _T("Alarm is not in \"outstanding\" state"),
383 _T("DCI data source is not a push agent"),
86920454
VK
384 _T("Error parsing configuration import file"),
385 _T("Configuration cannot be imported because of validation errors"),
5039dede
AK
386 _T("Invalid graph ID"),
387 _T("Local cryptographic provider failure"),
388 _T("Unsupported authentication type"),
389 _T("Bad certificate"),
390 _T("Invalid certificate ID"),
391 _T("SNMP failure"),
392 _T("Node has no support for layer 2 topology discovery"),
393 _T("Invalid situation ID"),
394 _T("Named instance not found"),
395 _T("Invalid event ID"),
396 _T("Operation cannot be completed due to agent error"),
397 _T("Unknown variable"),
f40831eb 398 _T("Requested resource not available"),
45d84f8a 399 _T("Job cannot be cancelled"),
e05b1945
VK
400 _T("Invalid policy ID"),
401 _T("Unknown log name"),
ab185583
VK
402 _T("Invalid log handle"),
403 _T("New password is too weak"),
67a736f0
VK
404 _T("Password was used before"),
405 _T("Invalid session handle")
5039dede 406 };
67a736f0 407 return ((dwError >= 0) && (dwError <= RCC_INVALID_SESSION_HANDLE)) ? pszErrorText[dwError] : _T("No text message for this error");
5039dede
AK
408}
409
410
411//
4e2debcc
VK
412// Decrypt password
413//
414
415BOOL LIBNXCL_EXPORTABLE NXCDecryptPassword(const TCHAR *login, const TCHAR *encryptedPasswd, TCHAR *decryptedPasswd)
416{
417 if (_tcslen(encryptedPasswd) != 44)
418 return FALSE;
419
420#ifdef UNICODE
421 char *mbencrypted = MBStringFromWideString(encryptedPasswd);
422 char *mblogin = MBStringFromWideString(login);
423#else
424 const char *mbencrypted = encryptedPasswd;
425 const char *mblogin = login;
426#endif
427
428 BYTE encrypted[32], decrypted[32], key[16];
429 size_t encSize;
430 base64_decode(mbencrypted, strlen(mbencrypted), (char *)encrypted, &encSize);
431 if (encSize != 32)
432 return FALSE;
433
434 CalculateMD5Hash((BYTE *)mblogin, strlen(mblogin), key);
435 ICEDecryptData(encrypted, 32, decrypted, key);
436 decrypted[31] = 0;
437
438#ifdef UNICODE
439 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (char *)decrypted, -1, decryptedPasswd, 32);
440 decryptedPasswd[31] = 0;
441 free(mbencrypted);
442 free(mblogin);
443#else
444 nx_strncpy(decryptedPasswd, (char *)decrypted, 32);
445#endif
446
447 return TRUE;
448}
449
450
451//
5039dede
AK
452// DLL entry point
453//
454
455#if defined(_WIN32) && !defined(UNDER_CE)
456
457BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
458{
459 if (dwReason == DLL_PROCESS_ATTACH)
460 DisableThreadLibraryCalls(hInstance);
461 return TRUE;
462}
463
464#endif /* _WIN32 */