fixed build error; fixed compilation warnings
[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
VK
34/**
35 * Temporary buffer structure for RecvCSCPMessage() function
36 */
0d9c1b96
VK
37typedef struct
38{
967893bb
VK
39 UINT32 dwBufSize;
40 UINT32 dwBufPos;
0d9c1b96
VK
41 char szBuffer[CSCP_TEMP_BUF_SIZE];
42} CSCP_BUFFER;
43
44
9f2ad16c
VK
45#ifdef __cplusplus
46
5c44534b
VK
47struct MessageField;
48
4af351c7
VK
49/**
50 * Parsed NXCP message
51 */
9f2ad16c 52class LIBNETXMS_EXPORTABLE CSCPMessage
0d9c1b96
VK
53{
54private:
5c44534b
VK
55 WORD m_code;
56 WORD m_flags;
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
5c44534b 63 void *set(UINT32 fieldId, BYTE type, const void *value, UINT32 size = 0);
8f238fd7 64 void *get(UINT32 fieldId, BYTE requiredType, BYTE *fieldType = NULL);
5c44534b 65 CSCP_DF *find(UINT32 fieldId);
0d9c1b96
VK
66
67public:
4bd3d6c5 68 CSCPMessage(int nVersion = NXCP_VERSION);
30639d32 69 CSCPMessage(CSCPMessage *pMsg);
4bd3d6c5 70 CSCPMessage(CSCP_MESSAGE *pMsg, int nVersion = NXCP_VERSION);
ff175e91 71 CSCPMessage(const char *xml);
0d9c1b96
VK
72 ~CSCPMessage();
73
5c44534b 74 CSCP_MESSAGE *createMessage();
4af351c7
VK
75 char *createXML();
76 void processXMLToken(void *state, const char **attrs);
77 void processXMLData(void *state);
0d9c1b96 78
5c44534b
VK
79 WORD GetCode() { return m_code; }
80 void SetCode(WORD code) { m_code = code; }
0d9c1b96 81
5c44534b
VK
82 UINT32 GetId() { return m_id; }
83 void SetId(UINT32 id) { m_id = id; }
0d9c1b96 84
6be0a20b 85 bool isEndOfFile() { return (m_flags & MF_END_OF_FILE) ? true : false; }
5c44534b
VK
86 bool isEndOfSequence() { return (m_flags & MF_END_OF_SEQUENCE) ? true : false; }
87 bool isReverseOrder() { return (m_flags & MF_REVERSE_ORDER) ? true : false; }
6be0a20b
VK
88 bool isBinary() { return (m_flags & MF_BINARY) ? true : false; }
89
90 BYTE *getBinaryData() { return m_data; }
91 size_t getBinaryDataSize() { return m_dataSize; }
4af351c7 92
4101571e
VK
93 bool isFieldExist(UINT32 fieldId) { return find(fieldId) != NULL; }
94 int getFieldType(UINT32 fieldId);
95
8f238fd7
VK
96 void SetVariable(UINT32 fieldId, INT16 wValue) { set(fieldId, CSCP_DT_INT16, &wValue); }
97 void SetVariable(UINT32 fieldId, UINT16 wValue) { set(fieldId, CSCP_DT_INT16, &wValue); }
98 void SetVariable(UINT32 fieldId, INT32 dwValue) { set(fieldId, CSCP_DT_INT32, &dwValue); }
99 void SetVariable(UINT32 fieldId, UINT32 dwValue) { set(fieldId, CSCP_DT_INT32, &dwValue); }
100 void SetVariable(UINT32 fieldId, INT64 qwValue) { set(fieldId, CSCP_DT_INT64, &qwValue); }
101 void SetVariable(UINT32 fieldId, UINT64 qwValue) { set(fieldId, CSCP_DT_INT64, &qwValue); }
102 void SetVariable(UINT32 fieldId, double dValue) { set(fieldId, CSCP_DT_FLOAT, &dValue); }
103 void SetVariable(UINT32 fieldId, const TCHAR *value) { if (value != NULL) set(fieldId, CSCP_DT_STRING, value); }
104 void SetVariable(UINT32 fieldId, const TCHAR *value, UINT32 maxLen) { if (value != NULL) set(fieldId, CSCP_DT_STRING, value, maxLen); }
105 void SetVariable(UINT32 fieldId, BYTE *pValue, UINT32 dwSize) { set(fieldId, CSCP_DT_BINARY, pValue, dwSize); }
35f836fe 106#ifdef UNICODE
8f238fd7 107 void SetVariableFromMBString(UINT32 fieldId, const char *pszValue);
35f836fe 108#else
8f238fd7 109 void SetVariableFromMBString(UINT32 fieldId, const char *pszValue) { set(fieldId, CSCP_DT_STRING, pszValue); }
35f836fe 110#endif
8f238fd7
VK
111 void setField(UINT32 fieldId, time_t value) { UINT64 t = (UINT64)value; set(fieldId, CSCP_DT_INT64, &t); }
112 void setFieldInt32Array(UINT32 fieldId, UINT32 dwNumElements, const UINT32 *pdwData);
113 void setFieldInt32Array(UINT32 fieldId, IntegerArray<UINT32> *data);
114 bool setFieldFromFile(UINT32 fieldId, const TCHAR *pszFileName);
967893bb 115
4101571e
VK
116 INT16 getFieldAsInt16(UINT32 fieldId);
117 INT32 getFieldAsInt32(UINT32 fieldId);
118 INT64 getFieldAsInt64(UINT32 fieldId);
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);
4101571e 125
8f238fd7
VK
126 UINT32 GetVariableLong(UINT32 fieldId);
127 UINT64 GetVariableInt64(UINT32 fieldId);
128 UINT16 GetVariableShort(UINT32 fieldId);
129 TCHAR *GetVariableStr(UINT32 fieldId, TCHAR *szBuffer = NULL, UINT32 dwBufSize = 0);
130 char *GetVariableStrA(UINT32 fieldId, char *pszBuffer = NULL, UINT32 dwBufSize = 0);
131 char *GetVariableStrUTF8(UINT32 fieldId, char *pszBuffer = NULL, UINT32 dwBufSize = 0);
132 UINT32 GetVariableBinary(UINT32 fieldId, BYTE *pBuffer, UINT32 dwBufSize);
0d9c1b96 133
4af351c7 134 void deleteAllVariables();
e44ac467 135
5c44534b
VK
136 void disableEncryption() { m_flags |= MF_DONT_ENCRYPT; }
137 void setEndOfSequence() { m_flags |= MF_END_OF_SEQUENCE; }
138 void setReverseOrderFlag() { m_flags |= MF_REVERSE_ORDER; }
934f53da
VK
139
140 static String dump(CSCP_MESSAGE *msg, int version);
0d9c1b96
VK
141};
142
4af351c7
VK
143/**
144 * Message waiting queue element structure
145 */
deaa4491
VK
146typedef struct
147{
f128c07c
VK
148 void *msg; // Pointer to message, either to CSCPMessage object or raw message
149 UINT32 id; // Message ID
150 UINT32 ttl; // Message time-to-live in milliseconds
151 UINT16 code; // Message code
152 UINT16 isBinary; // 1 for binary (raw) messages
deaa4491
VK
153} WAIT_QUEUE_ELEMENT;
154
4af351c7 155/**
f128c07c
VK
156 * Max number of waiting threads in message queue
157 */
158#define MAX_MSGQUEUE_WAITERS 32
159
160/**
4af351c7
VK
161 * Message waiting queue class
162 */
9f2ad16c 163class LIBNETXMS_EXPORTABLE MsgWaitQueue
deaa4491 164{
deaa4491 165private:
f128c07c
VK
166#ifdef _WIN32
167 CRITICAL_SECTION m_mutex;
168 HANDLE m_wakeupEvents[MAX_MSGQUEUE_WAITERS];
169 BYTE m_waiters[MAX_MSGQUEUE_WAITERS];
170#else
171 pthread_mutex_t m_mutex;
172 pthread_cond_t m_wakeupCondition;
173#endif
174 CONDITION m_stopCondition;
175 UINT32 m_holdTime;
176 int m_size;
177 int m_allocated;
178 WAIT_QUEUE_ELEMENT *m_elements;
ccdbbb52 179 THREAD m_hHkThread;
deaa4491 180
c17f6cbc 181 void housekeeperThread();
f128c07c
VK
182 void *waitForMessageInternal(UINT16 isBinary, UINT16 code, UINT32 id, UINT32 timeout);
183
184 void lock()
185 {
186#ifdef _WIN32
187 EnterCriticalSection(&m_mutex);
188#else
189 pthread_mutex_lock(&m_mutex);
190#endif
191 }
192
193 void unlock()
194 {
195#ifdef _WIN32
196 LeaveCriticalSection(&m_mutex);
197#else
198 pthread_mutex_unlock(&m_mutex);
199#endif
200 }
cc022855 201
c17f6cbc 202 static THREAD_RESULT THREAD_CALL mwqThreadStarter(void *);
deaa4491
VK
203
204public:
205 MsgWaitQueue();
206 ~MsgWaitQueue();
207
c17f6cbc
VK
208 void put(CSCPMessage *pMsg);
209 void put(CSCP_MESSAGE *pMsg);
967893bb 210 CSCPMessage *waitForMessage(WORD wCode, UINT32 dwId, UINT32 dwTimeOut)
deaa4491 211 {
c17f6cbc 212 return (CSCPMessage *)waitForMessageInternal(0, wCode, dwId, dwTimeOut);
deaa4491 213 }
967893bb 214 CSCP_MESSAGE *waitForRawMessage(WORD wCode, UINT32 dwId, UINT32 dwTimeOut)
deaa4491 215 {
c17f6cbc 216 return (CSCP_MESSAGE *)waitForMessageInternal(1, wCode, dwId, dwTimeOut);
deaa4491 217 }
cc022855 218
c17f6cbc 219 void clear();
f128c07c 220 void setHoldTime(UINT32 holdTime) { m_holdTime = holdTime; }
deaa4491
VK
221};
222
b549a0f8
VK
223/**
224 * NXCP encryption context
225 */
98abc9f1
VK
226class LIBNETXMS_EXPORTABLE NXCPEncryptionContext : public RefCountObject
227{
228private:
229 int m_cipher;
230 BYTE *m_sessionKey;
231 int m_keyLength;
232 BYTE m_iv[EVP_MAX_IV_LENGTH];
e4e091f0 233#ifdef _WITH_ENCRYPTION
e6336a90
VK
234 EVP_CIPHER_CTX m_encryptor;
235 EVP_CIPHER_CTX m_decryptor;
db05c2af 236 MUTEX m_encryptorLock;
e4e091f0 237#endif
98abc9f1
VK
238
239 NXCPEncryptionContext();
e6336a90 240 bool initCipher(int cipher);
98abc9f1
VK
241
242public:
243 static NXCPEncryptionContext *create(CSCPMessage *msg, RSA *privateKey);
967893bb 244 static NXCPEncryptionContext *create(UINT32 ciphers);
98abc9f1
VK
245
246 virtual ~NXCPEncryptionContext();
247
6be0a20b
VK
248 NXCP_ENCRYPTED_MESSAGE *encryptMessage(CSCP_MESSAGE *msg);
249 bool decryptMessage(NXCP_ENCRYPTED_MESSAGE *msg, BYTE *decryptionBuffer);
e6336a90 250
98abc9f1
VK
251 int getCipher() { return m_cipher; }
252 BYTE *getSessionKey() { return m_sessionKey; }
253 int getKeyLength() { return m_keyLength; }
254 BYTE *getIV() { return m_iv; }
255};
256
6be0a20b
VK
257/**
258 * Message receiver result codes
259 */
260enum MessageReceiverResult
261{
262 MSGRECV_SUCCESS = 0,
263 MSGRECV_CLOSED = 1,
264 MSGRECV_TIMEOUT = 2,
265 MSGRECV_COMM_FAILURE = 3,
266 MSGRECV_DECRYPTION_FAILURE = 4
267};
268
269/**
270 * Message receiver - abstract base class
271 */
272class LIBNETXMS_EXPORTABLE AbstractMessageReceiver
273{
274private:
275 BYTE *m_buffer;
276 BYTE *m_decryptionBuffer;
277 NXCPEncryptionContext *m_encryptionContext;
278 size_t m_initialSize;
279 size_t m_size;
280 size_t m_maxSize;
281 size_t m_dataSize;
282 size_t m_bytesToSkip;
283
284 CSCPMessage *getMessageFromBuffer();
285
286protected:
287 virtual int readBytes(BYTE *buffer, size_t size, UINT32 timeout) = 0;
288
289public:
290 AbstractMessageReceiver(size_t initialSize, size_t maxSize);
291 virtual ~AbstractMessageReceiver();
292
293 void setEncryptionContext(NXCPEncryptionContext *ctx) { m_encryptionContext = ctx; }
294
295 CSCPMessage *readMessage(UINT32 timeout, MessageReceiverResult *result);
296 CSCP_MESSAGE *getRawMessageBuffer() { return (CSCP_MESSAGE *)m_buffer; }
297};
298
299/**
300 * Message receiver - socket implementation
301 */
302class LIBNETXMS_EXPORTABLE SocketMessageReceiver : public AbstractMessageReceiver
303{
304private:
305 SOCKET m_socket;
306
307protected:
308 virtual int readBytes(BYTE *buffer, size_t size, UINT32 timeout);
309
310public:
311 SocketMessageReceiver(SOCKET socket, size_t initialSize, size_t maxSize);
312 virtual ~SocketMessageReceiver();
313};
314
315/**
316 * Message receiver - UNIX socket/named pipe implementation
317 */
318class LIBNETXMS_EXPORTABLE PipeMessageReceiver : public AbstractMessageReceiver
319{
320private:
321 HPIPE m_pipe;
322#ifdef _WIN32
323 HANDLE m_readEvent;
324#endif
325
326protected:
327 virtual int readBytes(BYTE *buffer, size_t size, UINT32 timeout);
328
329public:
330 PipeMessageReceiver(HPIPE pipe, size_t initialSize, size_t maxSize);
331 virtual ~PipeMessageReceiver();
332};
333
9f2ad16c
VK
334#else /* __cplusplus */
335
336typedef void CSCPMessage;
98abc9f1 337typedef void NXCPEncryptionContext;
9f2ad16c
VK
338
339#endif
340
deaa4491
VK
341
342//
0d9c1b96
VK
343// Functions
344//
345
346#ifdef __cplusplus
0d9c1b96 347
9f2ad16c 348int LIBNETXMS_EXPORTABLE RecvNXCPMessage(SOCKET hSocket, CSCP_MESSAGE *pMsg,
967893bb 349 CSCP_BUFFER *pBuffer, UINT32 dwMaxMsgSize,
98abc9f1 350 NXCPEncryptionContext **ppCtx,
967893bb 351 BYTE *pDecryptionBuffer, UINT32 dwTimeout);
b9b2b87b 352int LIBNETXMS_EXPORTABLE RecvNXCPMessageEx(SOCKET hSocket, CSCP_MESSAGE **msgBuffer,
967893bb 353 CSCP_BUFFER *nxcpBuffer, UINT32 *bufferSize,
cc022855 354 NXCPEncryptionContext **ppCtx,
967893bb
VK
355 BYTE **decryptionBuffer, UINT32 dwTimeout,
356 UINT32 maxMsgSize);
357CSCP_MESSAGE LIBNETXMS_EXPORTABLE *CreateRawNXCPMessage(WORD wCode, UINT32 dwId, WORD wFlags,
358 UINT32 dwDataSize, void *pData,
0d9c1b96 359 CSCP_MESSAGE *pBuffer);
9f2ad16c 360TCHAR LIBNETXMS_EXPORTABLE *NXCPMessageCodeName(WORD wCode, TCHAR *pszBuffer);
967893bb 361BOOL LIBNETXMS_EXPORTABLE SendFileOverNXCP(SOCKET hSocket, UINT32 dwId, const TCHAR *pszFile,
cc022855 362 NXCPEncryptionContext *pCtx, long offset,
7b8b337e
VK
363 void (* progressCallback)(INT64, void *), void *cbArg,
364 MUTEX mutex);
365BOOL LIBNETXMS_EXPORTABLE NXCPGetPeerProtocolVersion(SOCKET hSocket, int *pnVersion, MUTEX mutex);
cc022855 366
6468147c 367BOOL LIBNETXMS_EXPORTABLE InitCryptoLib(UINT32 dwEnabledCiphers, void (*debugCallback)(int, const TCHAR *, va_list args));
967893bb 368UINT32 LIBNETXMS_EXPORTABLE CSCPGetSupportedCiphers();
6be0a20b 369NXCP_ENCRYPTED_MESSAGE LIBNETXMS_EXPORTABLE *CSCPEncryptMessage(NXCPEncryptionContext *pCtx, CSCP_MESSAGE *pMsg);
98abc9f1 370BOOL LIBNETXMS_EXPORTABLE CSCPDecryptMessage(NXCPEncryptionContext *pCtx,
6be0a20b 371 NXCP_ENCRYPTED_MESSAGE *pMsg,
e44ac467 372 BYTE *pDecryptionBuffer);
cc022855 373UINT32 LIBNETXMS_EXPORTABLE SetupEncryptionContext(CSCPMessage *pMsg,
98abc9f1 374 NXCPEncryptionContext **ppCtx,
1a17feb0 375 CSCPMessage **ppResponse,
4bd3d6c5 376 RSA *pPrivateKey, int nNXCPVersion);
9e9d631e 377void LIBNETXMS_EXPORTABLE PrepareKeyRequestMsg(CSCPMessage *pMsg, RSA *pServerKey, bool useX509Format);
3aa0061c 378RSA LIBNETXMS_EXPORTABLE *LoadRSAKeys(const TCHAR *pszKeyFile);
15cf5acc 379
bb8136f7 380#ifdef _WIN32
967893bb
VK
381BOOL LIBNETXMS_EXPORTABLE SignMessageWithCAPI(BYTE *pMsg, UINT32 dwMsgLen, const CERT_CONTEXT *pCert,
382 BYTE *pBuffer, UINT32 dwBufSize, UINT32 *pdwSigLen);
bb8136f7
VK
383#endif
384
0d9c1b96
VK
385#endif
386
9f2ad16c 387#endif /* _nxcpapi_h_ */