change log updated
[public/netxms.git] / include / nxcpapi.h
CommitLineData
9fa031cd 1/*
0d9c1b96 2** NetXMS - Network Management System
9f2ad16c 3** NXCP API
68f384ea 4** Copyright (C) 2003-2010 Victor Kirhenshtein
0d9c1b96
VK
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
0d9c1b96
VK
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**
68f384ea 16** You should have received a copy of the GNU Lesser General Public License
0d9c1b96
VK
17** along with this program; if not, write to the Free Software
18** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19**
9f2ad16c 20** File: nxcpapi.h
0d9c1b96
VK
21**
22**/
23
9f2ad16c
VK
24#ifndef _nxcpapi_h_
25#define _nxcpapi_h_
0d9c1b96 26
b50f1100 27#include <nms_threads.h>
9f2ad16c 28#include <nms_util.h>
8c290af0 29
bb8136f7
VK
30#ifdef _WIN32
31#include <wincrypt.h>
32#endif
33
4af351c7 34/**
b368969c 35 * Temporary buffer structure for RecvNXCPMessage() function
4af351c7 36 */
0d9c1b96
VK
37typedef struct
38{
b368969c
VK
39 UINT32 bufferSize;
40 UINT32 bufferPos;
41 char buffer[CSCP_TEMP_BUF_SIZE];
42} NXCP_BUFFER;
0d9c1b96
VK
43
44
9f2ad16c
VK
45#ifdef __cplusplus
46
5c44534b
VK
47struct MessageField;
48
4af351c7
VK
49/**
50 * Parsed NXCP message
51 */
b368969c 52class LIBNETXMS_EXPORTABLE NXCPMessage
0d9c1b96
VK
53{
54private:
b368969c
VK
55 UINT16 m_code;
56 UINT16 m_flags;
5c44534b 57 UINT32 m_id;
6be0a20b
VK
58 MessageField *m_fields; // Message fields
59 int m_version; // Protocol version
60 BYTE *m_data; // binary data
61 size_t m_dataSize; // binary data size
0d9c1b96 62
712b2760 63 void *set(UINT32 fieldId, BYTE type, const void *value, bool isSigned = false, size_t size = 0);
8f238fd7 64 void *get(UINT32 fieldId, BYTE requiredType, BYTE *fieldType = NULL);
b368969c 65 NXCP_MESSAGE_FIELD *find(UINT32 fieldId);
0d9c1b96
VK
66
67public:
b368969c
VK
68 NXCPMessage(int version = NXCP_VERSION);
69 NXCPMessage(NXCPMessage *msg);
70 NXCPMessage(NXCP_MESSAGE *rawMag, int version = NXCP_VERSION);
71 ~NXCPMessage();
0d9c1b96 72
b368969c 73 NXCP_MESSAGE *createMessage();
0d9c1b96 74
b368969c
VK
75 UINT16 getCode() { return m_code; }
76 void setCode(UINT16 code) { m_code = code; }
0d9c1b96 77
b368969c
VK
78 UINT32 getId() { return m_id; }
79 void setId(UINT32 id) { m_id = id; }
0d9c1b96 80
6be0a20b 81 bool isEndOfFile() { return (m_flags & MF_END_OF_FILE) ? true : false; }
5c44534b
VK
82 bool isEndOfSequence() { return (m_flags & MF_END_OF_SEQUENCE) ? true : false; }
83 bool isReverseOrder() { return (m_flags & MF_REVERSE_ORDER) ? true : false; }
6be0a20b
VK
84 bool isBinary() { return (m_flags & MF_BINARY) ? true : false; }
85
86 BYTE *getBinaryData() { return m_data; }
87 size_t getBinaryDataSize() { return m_dataSize; }
4af351c7 88
4101571e
VK
89 bool isFieldExist(UINT32 fieldId) { return find(fieldId) != NULL; }
90 int getFieldType(UINT32 fieldId);
91
712b2760
VK
92 void setField(UINT32 fieldId, INT16 value) { set(fieldId, NXCP_DT_INT16, &value, true); }
93 void setField(UINT32 fieldId, UINT16 value) { set(fieldId, NXCP_DT_INT16, &value, false); }
94 void setField(UINT32 fieldId, INT32 value) { set(fieldId, NXCP_DT_INT32, &value, true); }
95 void setField(UINT32 fieldId, UINT32 value) { set(fieldId, NXCP_DT_INT32, &value, false); }
96 void setField(UINT32 fieldId, INT64 value) { set(fieldId, NXCP_DT_INT64, &value, true); }
97 void setField(UINT32 fieldId, UINT64 value) { set(fieldId, NXCP_DT_INT64, &value, false); }
b368969c
VK
98 void setField(UINT32 fieldId, double value) { set(fieldId, NXCP_DT_FLOAT, &value); }
99 void setField(UINT32 fieldId, const TCHAR *value) { if (value != NULL) set(fieldId, NXCP_DT_STRING, value); }
712b2760
VK
100 void setField(UINT32 fieldId, const TCHAR *value, size_t maxLen) { if (value != NULL) set(fieldId, NXCP_DT_STRING, value, false, maxLen); }
101 void setField(UINT32 fieldId, BYTE *value, size_t size) { set(fieldId, NXCP_DT_BINARY, value, false, size); }
102 void setField(UINT32 fieldId, const InetAddress &value) { set(fieldId, NXCP_DT_INETADDR, (void *)&value); }
35f836fe 103#ifdef UNICODE
b368969c 104 void setFieldFromMBString(UINT32 fieldId, const char *value);
35f836fe 105#else
b368969c 106 void setFieldFromMBString(UINT32 fieldId, const char *value) { set(fieldId, NXCP_DT_STRING, value); }
35f836fe 107#endif
b368969c
VK
108 void setFieldFromTime(UINT32 fieldId, time_t value) { UINT64 t = (UINT64)value; set(fieldId, NXCP_DT_INT64, &t); }
109 void setFieldFromInt32Array(UINT32 fieldId, UINT32 dwNumElements, const UINT32 *pdwData);
110 void setFieldFromInt32Array(UINT32 fieldId, IntegerArray<UINT32> *data);
8f238fd7 111 bool setFieldFromFile(UINT32 fieldId, const TCHAR *pszFileName);
967893bb 112
4101571e 113 INT16 getFieldAsInt16(UINT32 fieldId);
b368969c 114 UINT16 getFieldAsUInt16(UINT32 fieldId);
4101571e 115 INT32 getFieldAsInt32(UINT32 fieldId);
b368969c 116 UINT32 getFieldAsUInt32(UINT32 fieldId);
4101571e 117 INT64 getFieldAsInt64(UINT32 fieldId);
b368969c 118 UINT64 getFieldAsUInt64(UINT32 fieldId);
4101571e 119 double getFieldAsDouble(UINT32 fieldId);
d6bbfa4e 120 bool getFieldAsBoolean(UINT32 fieldId);
8f238fd7 121 time_t getFieldAsTime(UINT32 fieldId);
9a68ca24
VK
122 UINT32 getFieldAsInt32Array(UINT32 fieldId, UINT32 numElements, UINT32 *buffer);
123 UINT32 getFieldAsInt32Array(UINT32 fieldId, IntegerArray<UINT32> *data);
ac14e3e6 124 BYTE *getBinaryFieldPtr(UINT32 fieldId, size_t *size);
b368969c
VK
125 TCHAR *getFieldAsString(UINT32 fieldId, TCHAR *buffer = NULL, size_t bufferSize = 0);
126 char *getFieldAsMBString(UINT32 fieldId, char *buffer = NULL, size_t bufferSize = 0);
127 char *getFieldAsUtf8String(UINT32 fieldId, char *buffer = NULL, size_t bufferSize = 0);
128 UINT32 getFieldAsBinary(UINT32 fieldId, BYTE *buffer, size_t bufferSize);
712b2760 129 InetAddress getFieldAsInetAddress(UINT32 fieldId);
4101571e 130
b368969c 131 void deleteAllFields();
e44ac467 132
5c44534b
VK
133 void disableEncryption() { m_flags |= MF_DONT_ENCRYPT; }
134 void setEndOfSequence() { m_flags |= MF_END_OF_SEQUENCE; }
135 void setReverseOrderFlag() { m_flags |= MF_REVERSE_ORDER; }
934f53da 136
b368969c 137 static String dump(NXCP_MESSAGE *msg, int version);
0d9c1b96
VK
138};
139
4af351c7
VK
140/**
141 * Message waiting queue element structure
142 */
deaa4491
VK
143typedef struct
144{
b368969c 145 void *msg; // Pointer to message, either to NXCPMessage object or raw message
f128c07c
VK
146 UINT32 id; // Message ID
147 UINT32 ttl; // Message time-to-live in milliseconds
148 UINT16 code; // Message code
149 UINT16 isBinary; // 1 for binary (raw) messages
deaa4491
VK
150} WAIT_QUEUE_ELEMENT;
151
4af351c7 152/**
f128c07c
VK
153 * Max number of waiting threads in message queue
154 */
155#define MAX_MSGQUEUE_WAITERS 32
156
157/**
4af351c7
VK
158 * Message waiting queue class
159 */
9f2ad16c 160class LIBNETXMS_EXPORTABLE MsgWaitQueue
deaa4491 161{
deaa4491 162private:
f128c07c
VK
163#ifdef _WIN32
164 CRITICAL_SECTION m_mutex;
165 HANDLE m_wakeupEvents[MAX_MSGQUEUE_WAITERS];
166 BYTE m_waiters[MAX_MSGQUEUE_WAITERS];
167#else
168 pthread_mutex_t m_mutex;
169 pthread_cond_t m_wakeupCondition;
170#endif
171 CONDITION m_stopCondition;
172 UINT32 m_holdTime;
173 int m_size;
174 int m_allocated;
175 WAIT_QUEUE_ELEMENT *m_elements;
ccdbbb52 176 THREAD m_hHkThread;
deaa4491 177
c17f6cbc 178 void housekeeperThread();
f128c07c
VK
179 void *waitForMessageInternal(UINT16 isBinary, UINT16 code, UINT32 id, UINT32 timeout);
180
181 void lock()
182 {
183#ifdef _WIN32
184 EnterCriticalSection(&m_mutex);
185#else
186 pthread_mutex_lock(&m_mutex);
187#endif
188 }
189
190 void unlock()
191 {
192#ifdef _WIN32
193 LeaveCriticalSection(&m_mutex);
194#else
195 pthread_mutex_unlock(&m_mutex);
196#endif
197 }
cc022855 198
c17f6cbc 199 static THREAD_RESULT THREAD_CALL mwqThreadStarter(void *);
deaa4491
VK
200
201public:
202 MsgWaitQueue();
203 ~MsgWaitQueue();
204
b368969c
VK
205 void put(NXCPMessage *pMsg);
206 void put(NXCP_MESSAGE *pMsg);
207 NXCPMessage *waitForMessage(WORD wCode, UINT32 dwId, UINT32 dwTimeOut)
deaa4491 208 {
b368969c 209 return (NXCPMessage *)waitForMessageInternal(0, wCode, dwId, dwTimeOut);
deaa4491 210 }
b368969c 211 NXCP_MESSAGE *waitForRawMessage(WORD wCode, UINT32 dwId, UINT32 dwTimeOut)
deaa4491 212 {
b368969c 213 return (NXCP_MESSAGE *)waitForMessageInternal(1, wCode, dwId, dwTimeOut);
deaa4491 214 }
cc022855 215
c17f6cbc 216 void clear();
f128c07c 217 void setHoldTime(UINT32 holdTime) { m_holdTime = holdTime; }
deaa4491
VK
218};
219
b549a0f8
VK
220/**
221 * NXCP encryption context
222 */
98abc9f1
VK
223class LIBNETXMS_EXPORTABLE NXCPEncryptionContext : public RefCountObject
224{
225private:
226 int m_cipher;
227 BYTE *m_sessionKey;
228 int m_keyLength;
229 BYTE m_iv[EVP_MAX_IV_LENGTH];
e4e091f0 230#ifdef _WITH_ENCRYPTION
e6336a90
VK
231 EVP_CIPHER_CTX m_encryptor;
232 EVP_CIPHER_CTX m_decryptor;
db05c2af 233 MUTEX m_encryptorLock;
e4e091f0 234#endif
98abc9f1
VK
235
236 NXCPEncryptionContext();
e6336a90 237 bool initCipher(int cipher);
98abc9f1
VK
238
239public:
b368969c 240 static NXCPEncryptionContext *create(NXCPMessage *msg, RSA *privateKey);
967893bb 241 static NXCPEncryptionContext *create(UINT32 ciphers);
98abc9f1
VK
242
243 virtual ~NXCPEncryptionContext();
244
b368969c 245 NXCP_ENCRYPTED_MESSAGE *encryptMessage(NXCP_MESSAGE *msg);
6be0a20b 246 bool decryptMessage(NXCP_ENCRYPTED_MESSAGE *msg, BYTE *decryptionBuffer);
e6336a90 247
98abc9f1
VK
248 int getCipher() { return m_cipher; }
249 BYTE *getSessionKey() { return m_sessionKey; }
250 int getKeyLength() { return m_keyLength; }
251 BYTE *getIV() { return m_iv; }
252};
253
6be0a20b
VK
254/**
255 * Message receiver result codes
256 */
257enum MessageReceiverResult
258{
259 MSGRECV_SUCCESS = 0,
260 MSGRECV_CLOSED = 1,
261 MSGRECV_TIMEOUT = 2,
262 MSGRECV_COMM_FAILURE = 3,
263 MSGRECV_DECRYPTION_FAILURE = 4
264};
265
266/**
267 * Message receiver - abstract base class
268 */
269class LIBNETXMS_EXPORTABLE AbstractMessageReceiver
270{
271private:
272 BYTE *m_buffer;
273 BYTE *m_decryptionBuffer;
274 NXCPEncryptionContext *m_encryptionContext;
275 size_t m_initialSize;
276 size_t m_size;
277 size_t m_maxSize;
278 size_t m_dataSize;
279 size_t m_bytesToSkip;
280
b368969c 281 NXCPMessage *getMessageFromBuffer();
6be0a20b
VK
282
283protected:
284 virtual int readBytes(BYTE *buffer, size_t size, UINT32 timeout) = 0;
285
286public:
287 AbstractMessageReceiver(size_t initialSize, size_t maxSize);
288 virtual ~AbstractMessageReceiver();
289
290 void setEncryptionContext(NXCPEncryptionContext *ctx) { m_encryptionContext = ctx; }
291
b368969c
VK
292 NXCPMessage *readMessage(UINT32 timeout, MessageReceiverResult *result);
293 NXCP_MESSAGE *getRawMessageBuffer() { return (NXCP_MESSAGE *)m_buffer; }
294
295 static const TCHAR *resultToText(MessageReceiverResult result);
6be0a20b
VK
296};
297
298/**
299 * Message receiver - socket implementation
300 */
301class LIBNETXMS_EXPORTABLE SocketMessageReceiver : public AbstractMessageReceiver
302{
303private:
304 SOCKET m_socket;
305
306protected:
307 virtual int readBytes(BYTE *buffer, size_t size, UINT32 timeout);
308
309public:
310 SocketMessageReceiver(SOCKET socket, size_t initialSize, size_t maxSize);
311 virtual ~SocketMessageReceiver();
312};
313
314/**
315 * Message receiver - UNIX socket/named pipe implementation
316 */
317class LIBNETXMS_EXPORTABLE PipeMessageReceiver : public AbstractMessageReceiver
318{
319private:
320 HPIPE m_pipe;
321#ifdef _WIN32
322 HANDLE m_readEvent;
323#endif
324
325protected:
326 virtual int readBytes(BYTE *buffer, size_t size, UINT32 timeout);
327
328public:
329 PipeMessageReceiver(HPIPE pipe, size_t initialSize, size_t maxSize);
330 virtual ~PipeMessageReceiver();
331};
332
9f2ad16c
VK
333#else /* __cplusplus */
334
b368969c 335typedef void NXCPMessage;
98abc9f1 336typedef void NXCPEncryptionContext;
9f2ad16c
VK
337
338#endif
339
deaa4491
VK
340
341//
0d9c1b96
VK
342// Functions
343//
344
345#ifdef __cplusplus
0d9c1b96 346
b368969c
VK
347int LIBNETXMS_EXPORTABLE RecvNXCPMessage(SOCKET hSocket, NXCP_MESSAGE *pMsg,
348 NXCP_BUFFER *pBuffer, UINT32 dwMaxMsgSize,
98abc9f1 349 NXCPEncryptionContext **ppCtx,
967893bb 350 BYTE *pDecryptionBuffer, UINT32 dwTimeout);
b368969c
VK
351int LIBNETXMS_EXPORTABLE RecvNXCPMessageEx(SOCKET hSocket, NXCP_MESSAGE **msgBuffer,
352 NXCP_BUFFER *nxcpBuffer, UINT32 *bufferSize,
cc022855 353 NXCPEncryptionContext **ppCtx,
967893bb
VK
354 BYTE **decryptionBuffer, UINT32 dwTimeout,
355 UINT32 maxMsgSize);
b368969c 356NXCP_MESSAGE LIBNETXMS_EXPORTABLE *CreateRawNXCPMessage(WORD wCode, UINT32 dwId, WORD flags,
967893bb 357 UINT32 dwDataSize, void *pData,
b368969c
VK
358 NXCP_MESSAGE *pBuffer);
359TCHAR LIBNETXMS_EXPORTABLE *NXCPMessageCodeName(WORD wCode, TCHAR *buffer);
967893bb 360BOOL LIBNETXMS_EXPORTABLE SendFileOverNXCP(SOCKET hSocket, UINT32 dwId, const TCHAR *pszFile,
cc022855 361 NXCPEncryptionContext *pCtx, long offset,
7b8b337e
VK
362 void (* progressCallback)(INT64, void *), void *cbArg,
363 MUTEX mutex);
364BOOL LIBNETXMS_EXPORTABLE NXCPGetPeerProtocolVersion(SOCKET hSocket, int *pnVersion, MUTEX mutex);
cc022855 365
6468147c 366BOOL LIBNETXMS_EXPORTABLE InitCryptoLib(UINT32 dwEnabledCiphers, void (*debugCallback)(int, const TCHAR *, va_list args));
967893bb 367UINT32 LIBNETXMS_EXPORTABLE CSCPGetSupportedCiphers();
b368969c
VK
368NXCP_ENCRYPTED_MESSAGE LIBNETXMS_EXPORTABLE *NXCPEncryptMessage(NXCPEncryptionContext *pCtx, NXCP_MESSAGE *pMsg);
369BOOL LIBNETXMS_EXPORTABLE NXCPDecryptMessage(NXCPEncryptionContext *pCtx,
6be0a20b 370 NXCP_ENCRYPTED_MESSAGE *pMsg,
e44ac467 371 BYTE *pDecryptionBuffer);
b368969c 372UINT32 LIBNETXMS_EXPORTABLE SetupEncryptionContext(NXCPMessage *pMsg,
98abc9f1 373 NXCPEncryptionContext **ppCtx,
b368969c 374 NXCPMessage **ppResponse,
4bd3d6c5 375 RSA *pPrivateKey, int nNXCPVersion);
b368969c 376void LIBNETXMS_EXPORTABLE PrepareKeyRequestMsg(NXCPMessage *pMsg, RSA *pServerKey, bool useX509Format);
3aa0061c 377RSA LIBNETXMS_EXPORTABLE *LoadRSAKeys(const TCHAR *pszKeyFile);
15cf5acc 378
bb8136f7 379#ifdef _WIN32
967893bb 380BOOL LIBNETXMS_EXPORTABLE SignMessageWithCAPI(BYTE *pMsg, UINT32 dwMsgLen, const CERT_CONTEXT *pCert,
b368969c 381 BYTE *pBuffer, size_t bufferSize, UINT32 *pdwSigLen);
bb8136f7
VK
382#endif
383
0d9c1b96
VK
384#endif
385
9f2ad16c 386#endif /* _nxcpapi_h_ */