added client protocol component versions
authorVictor Kirhenshtein <victor@netxms.org>
Tue, 14 Apr 2015 08:59:39 +0000 (11:59 +0300)
committerVictor Kirhenshtein <victor@netxms.org>
Tue, 14 Apr 2015 08:59:39 +0000 (11:59 +0300)
16 files changed:
include/netxms-version.h
include/nms_cscp.h
include/nms_util.h
include/nxclient.h
include/nxcpapi.h
src/client/libnxclient/session.cpp
src/client/nxalarm/nxalarm.cpp
src/client/nxevent/nxevent.cpp
src/client/nxpush/nxpush.cpp
src/java/client/netxms-base/src/main/java/org/netxms/base/NXCPCodes.java
src/java/client/netxms-base/src/main/java/org/netxms/base/NXCommon.java
src/java/client/netxms-client/src/main/java/org/netxms/client/NXCSession.java
src/java/client/netxms-client/src/main/java/org/netxms/client/ProtocolVersion.java [new file with mode: 0644]
src/libnetxms/crypto.cpp
src/server/core/session.cpp
src/server/netxmsd/netxmsd.cpp

index 196572a..4444836 100644 (file)
 #endif
 
 /**
- * Current client-server protocol version
+ * Current client-server protocol versions
  */
-#define CLIENT_PROTOCOL_VERSION           46
+#define CLIENT_PROTOCOL_VERSION_BASE      47    /* Base protocol version - must match for all clients */
+#define CLIENT_PROTOCOL_VERSION_ALARMS    1     /* Alarm management API */
+#define CLIENT_PROTOCOL_VERSION_PUSH      1     /* Data push API */
+#define CLIENT_PROTOCOL_VERSION_TRAP      1     /* Event (trap) sending API */
+#define CLIENT_PROTOCOL_VERSION_MOBILE    1     /* All functionality relevant for mobile client */
+#define CLIENT_PROTOCOL_VERSION_FULL      1     /* All functionality */
+
+/**
+ * Protocol version positions
+ */
+#define CPV_INDEX_BASE     0
+#define CPV_INDEX_ALARMS   1
+#define CPV_INDEX_PUSH     2
+#define CPV_INDEX_TRAP     3
+#define CPV_INDEX_MOBILE   4
+#define CPV_INDEX_FULL     5
 
 /**
  * Current mobile device protocol version
index d82d982..3c15574 100644 (file)
@@ -1041,6 +1041,7 @@ typedef struct
 #define VID_MTU                     ((UINT32)493)
 #define VID_ALIAS                   ((UINT32)494)
 #define VID_AP_INDEX                ((UINT32)495)
+#define VID_PROTOCOL_VERSION_EX     ((UINT32)496)
 
 // Base variabe for single threshold in message
 #define VID_THRESHOLD_BASE          ((UINT32)0x00800000)
index a71258a..d4635ec 100644 (file)
@@ -427,7 +427,7 @@ public:
        virtual ~IntegerArray() { }
 
    int add(T value) { return Array::add(m_storePointers ? CAST_TO_POINTER(value, void *) : &value); }
-   T get(int index) const { return m_storePointers ? CAST_FROM_POINTER(Array::get(index), T) : *((T*)Array::get(index)); }
+   T get(int index) const { if (m_storePointers) return CAST_FROM_POINTER(Array::get(index), T); T *p = (T*)Array::get(index); return (p != NULL) ? *p : 0; }
    int indexOf(T value) const { return Array::indexOf(m_storePointers ? CAST_TO_POINTER(value, void *) : &value); }
    bool contains(T value) const { return indexOf(value) >= 0; }
    void set(int index, T value) { Array::set(index, m_storePointers ? CAST_TO_POINTER(value, void *) : &value); }
index 28f4df6..6a4ec74 100644 (file)
@@ -269,6 +269,7 @@ protected:
    // server information
    BYTE m_serverId[8];
    TCHAR m_serverVersion[64];
+   IntegerArray<UINT32> *m_protocolVersions;
    TCHAR m_serverTimeZone[MAX_TZ_LEN];
    UINT32 m_userId;
    UINT64 m_systemRights;
@@ -286,7 +287,9 @@ public:
    NXCSession();
    virtual ~NXCSession();
 
-   UINT32 connect(const TCHAR *host, const TCHAR *login, const TCHAR *password, UINT32 flags = NXCF_DEFAULT, const TCHAR *clientInfo = NULL);
+   UINT32 connect(const TCHAR *host, const TCHAR *login, const TCHAR *password, 
+      UINT32 flags = NXCF_DEFAULT, const TCHAR *clientInfo = NULL, 
+      const UINT32 *cpvIndexList = NULL, size_t cpvIndexListSize = 0);
    void disconnect();
 
    UINT32 createMessageId() { return InterlockedIncrement(&m_msgId); }
@@ -299,6 +302,7 @@ public:
 
    const TCHAR *getServerVersion() { return m_serverVersion; }
    const TCHAR *getServerTimeZone() { return m_serverTimeZone; }
+   UINT32 getProtocolVersion(int index) { return m_protocolVersions->get(index); }
    UINT32 getUserId() { return m_userId; }
    UINT64 getSystemRights() { return m_systemRights; }
    bool isPasswordChangeNeeded() { return m_passwordChangeNeeded; }
index b7ae865..35ff5c0 100644 (file)
@@ -366,7 +366,8 @@ BOOL LIBNETXMS_EXPORTABLE SendFileOverNXCP(SOCKET hSocket, UINT32 dwId, const TC
 BOOL LIBNETXMS_EXPORTABLE NXCPGetPeerProtocolVersion(SOCKET hSocket, int *pnVersion, MUTEX mutex);
 
 bool LIBNETXMS_EXPORTABLE InitCryptoLib(UINT32 dwEnabledCiphers, void (*debugCallback)(int, const TCHAR *, va_list args));
-UINT32 LIBNETXMS_EXPORTABLE CSCPGetSupportedCiphers();
+UINT32 LIBNETXMS_EXPORTABLE NXCPGetSupportedCiphers();
+String LIBNETXMS_EXPORTABLE NXCPGetSupportedCiphersAsText();
 NXCP_ENCRYPTED_MESSAGE LIBNETXMS_EXPORTABLE *NXCPEncryptMessage(NXCPEncryptionContext *pCtx, NXCP_MESSAGE *pMsg);
 bool LIBNETXMS_EXPORTABLE NXCPDecryptMessage(NXCPEncryptionContext *pCtx,
                                              NXCP_ENCRYPTED_MESSAGE *pMsg,
index 4ed2762..cefcd9b 100644 (file)
@@ -63,6 +63,7 @@ NXCSession::NXCSession()
    m_userId = 0;
    m_systemRights = 0;
    m_commandTimeout = 60000;  // 60 seconds
+   m_protocolVersions = new IntegerArray<UINT32>(8, 8);
 }
 
 /**
@@ -74,6 +75,7 @@ NXCSession::~NXCSession()
    delete m_controllers;
    MutexDestroy(m_dataLock);
    MutexDestroy(m_msgSendLock);
+   delete m_protocolVersions;
 }
 
 /**
@@ -131,7 +133,8 @@ void NXCSession::disconnect()
 /**
  * Connect to server
  */
-UINT32 NXCSession::connect(const TCHAR *host, const TCHAR *login, const TCHAR *password, UINT32 flags, const TCHAR *clientInfo)
+UINT32 NXCSession::connect(const TCHAR *host, const TCHAR *login, const TCHAR *password, UINT32 flags, 
+                           const TCHAR *clientInfo, const UINT32 *cpvIndexList, size_t cpvIndexListSize)
 {
    if (m_connected || m_disconnected)
       return RCC_OUT_OF_STATE_REQUEST;
@@ -224,16 +227,41 @@ UINT32 NXCSession::connect(const TCHAR *host, const TCHAR *login, const TCHAR *p
             response->getFieldAsString(VID_SERVER_VERSION, m_serverVersion, 64);
                                response->getFieldAsString(VID_TIMEZONE, m_serverTimeZone, MAX_TZ_LEN);
 
-            if (flags & NXCF_EXACT_VERSION_MATCH)
-            {
-               if (_tcsncmp(m_serverVersion, NETXMS_VERSION_STRING, 64))
-                  rcc = RCC_VERSION_MISMATCH;
-            }
                                if (!(flags & NXCF_IGNORE_PROTOCOL_VERSION))
                                {
-                                       if (response->getFieldAsUInt32(VID_PROTOCOL_VERSION) != CLIENT_PROTOCOL_VERSION)
+                                       if (response->getFieldAsUInt32(VID_PROTOCOL_VERSION) != CLIENT_PROTOCOL_VERSION_BASE)
                                                rcc = RCC_BAD_PROTOCOL;
                                }
+            if ((rcc == RCC_SUCCESS) && (flags & NXCF_EXACT_VERSION_MATCH))
+            {
+               if (_tcsncmp(m_serverVersion, NETXMS_VERSION_STRING, 64))
+                  rcc = RCC_VERSION_MISMATCH;
+            }
+            if (rcc == RCC_SUCCESS)
+            {
+               response->getFieldAsInt32Array(VID_PROTOCOL_VERSION_EX, m_protocolVersions);
+               if (cpvIndexList != NULL)
+               {
+                  static UINT32 currentProtocolVersions[] = {
+                     CLIENT_PROTOCOL_VERSION_BASE,
+                     CLIENT_PROTOCOL_VERSION_ALARMS,
+                     CLIENT_PROTOCOL_VERSION_PUSH,
+                     CLIENT_PROTOCOL_VERSION_TRAP,
+                     CLIENT_PROTOCOL_VERSION_MOBILE,
+                     CLIENT_PROTOCOL_VERSION_FULL
+                  };
+
+                  for(int i = 0; i < (int)cpvIndexListSize; i++)
+                  {
+                     int idx = cpvIndexList[i];
+                     if ((idx >= sizeof(currentProtocolVersions) / sizeof(UINT32)) || (m_protocolVersions->get(idx) != currentProtocolVersions[idx]))
+                     {
+                                               rcc = RCC_BAD_PROTOCOL;
+                        break;
+                     }
+                  }
+               }
+            }
          }
          delete response;
       }
index c330dfe..0c9bf7c 100644 (file)
@@ -244,7 +244,9 @@ int main(int argc, char *argv[])
 #endif
 
    NXCSession *session = new NXCSession();
-   rcc = session->connect(_HOST, login, password, isEncrypt ? NXCF_ENCRYPT : 0, _T("nxalarm/") NETXMS_VERSION_STRING);
+   static UINT32 protocolVersions[] = { CPV_INDEX_ALARMS };
+   rcc = session->connect(_HOST, login, password, isEncrypt ? NXCF_ENCRYPT : 0, _T("nxalarm/") NETXMS_VERSION_STRING, 
+                          protocolVersions, sizeof(protocolVersions) / sizeof(UINT32));
        if (rcc != RCC_SUCCESS)
        {
                _tprintf(_T("Unable to connect to server: %s\n"), NXCGetErrorText(rcc));
index 6ddeee4..9e7dc8a 100644 (file)
@@ -61,7 +61,9 @@ static DWORD SendEvent(int iNumArgs, char **pArgList, BOOL bEncrypt)
          NXCSetDebugCallback(DebugCallback);
 
       NXCSession *session = new NXCSession();
-      dwResult = session->connect(m_szServer, m_szLogin, m_szPassword, bEncrypt ? NXCF_ENCRYPT : 0, _T("nxevent/") NETXMS_VERSION_STRING);
+      static UINT32 protocolVersions[] = { CPV_INDEX_TRAP };
+      dwResult = session->connect(m_szServer, m_szLogin, m_szPassword, bEncrypt ? NXCF_ENCRYPT : 0, _T("nxevent/") NETXMS_VERSION_STRING,
+                                  protocolVersions, sizeof(protocolVersions) / sizeof(UINT32));
       if (dwResult != RCC_SUCCESS)
       {
          _tprintf(_T("Unable to connect to server: %s\n"), NXCGetErrorText(dwResult));
index c4ce99f..d3a83af 100644 (file)
@@ -464,7 +464,9 @@ static BOOL Startup()
 #endif
 
       session = new NXCSession();
-      dwResult = session->connect(_HOST, _USER, _PASSWD, optEncrypt ? NXCF_ENCRYPT : 0, _T("nxpush/") NETXMS_VERSION_STRING);
+      static UINT32 protocolVersions[] = { CPV_INDEX_PUSH };
+      dwResult = session->connect(_HOST, _USER, _PASSWD, optEncrypt ? NXCF_ENCRYPT : 0, _T("nxpush/") NETXMS_VERSION_STRING,
+                                  protocolVersions, sizeof(protocolVersions) / sizeof(UINT32));
 
 #ifdef UNICODE
                free(wHost);
index 7853292..f0991e2 100644 (file)
@@ -838,6 +838,7 @@ public class NXCPCodes
    public static final long VID_MTU = 493;
    public static final long VID_ALIAS = 494;
    public static final long VID_AP_INDEX = 495;
+   public static final long VID_PROTOCOL_VERSION_EX = 496;
 
        public static final long VID_ACL_USER_BASE = 0x00001000L;
        public static final long VID_ACL_USER_LAST = 0x00001FFFL;
index 4da60a7..e7142e7 100644 (file)
@@ -26,7 +26,7 @@ import java.util.UUID;
 public final class NXCommon
 {
        // Version information
-       public static final String VERSION = "2.0-M3";
+       public static final String VERSION = "2.0-M4";
        
        public static final UUID EMPTY_GUID = UUID.fromString("00000000-0000-0000-0000-000000000000");
 }
index 3a68d8a..f2b6301 100644 (file)
@@ -185,7 +185,6 @@ public class NXCSession implements Session, ScriptLibraryManager, UserManager, S
 {
    // Various public constants
    public static final int DEFAULT_CONN_PORT = 4701;
-   public static final int CLIENT_PROTOCOL_VERSION = 46;
 
    // Authentication types
    public static final int AUTH_TYPE_PASSWORD = 0;
@@ -286,6 +285,7 @@ public class NXCSession implements Session, ScriptLibraryManager, UserManager, S
    private Map<String, String> recievedUpdates = new HashMap<String, String>();
 
    // Server information
+   private ProtocolVersion protocolVersion;
    private String serverVersion = "(unknown)";
    private byte[] serverId = new byte[8];
    private String serverTimeZone;
@@ -1693,9 +1693,10 @@ public class NXCSession implements Session, ScriptLibraryManager, UserManager, S
          sendMessage(request);
          NXCPMessage response = waitForMessage(NXCPCodes.CMD_REQUEST_COMPLETED, request.getMessageId());
 
-         if ((response.getFieldAsInt32(NXCPCodes.VID_PROTOCOL_VERSION) != CLIENT_PROTOCOL_VERSION) && !ignoreProtocolVersion)
+         protocolVersion = new ProtocolVersion(response);
+         if (!protocolVersion.isCorrectVersion(ProtocolVersion.INDEX_BASE) && !ignoreProtocolVersion)
          {
-            Logger.warning("NXCSession.connect", "connection failed, server protocol version is " + 
+            Logger.warning("NXCSession.connect", "connection failed, server protocol version (BASE) is " + 
                response.getFieldAsInt32(NXCPCodes.VID_PROTOCOL_VERSION));
             throw new NXCException(RCC.BAD_PROTOCOL);
          }
@@ -1910,6 +1911,22 @@ public class NXCSession implements Session, ScriptLibraryManager, UserManager, S
    {
       this.ignoreProtocolVersion = ignoreProtocolVersion;
    }
+   
+   /**
+    * Validate protocol versions
+    * 
+    * @param versions
+    * @return
+    */
+   public boolean validateProtocolVersions(int[] versions)
+   {
+      if (protocolVersion == null)
+         return false;
+      for(int index : versions)
+         if (!protocolVersion.isCorrectVersion(index))
+            return false;
+      return true;
+   }
 
    /* (non-Javadoc)
     * @see org.netxms.api.client.Session#getDefaultRecvBufferSize()
diff --git a/src/java/client/netxms-client/src/main/java/org/netxms/client/ProtocolVersion.java b/src/java/client/netxms-client/src/main/java/org/netxms/client/ProtocolVersion.java
new file mode 100644 (file)
index 0000000..2abbae2
--- /dev/null
@@ -0,0 +1,87 @@
+/**
+ * NetXMS - open source network management system
+ * Copyright (C) 2003-2015 Victor Kirhenshtein
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+package org.netxms.client;
+
+import org.netxms.base.NXCPCodes;
+import org.netxms.base.NXCPMessage;
+
+/**
+ * NetXMS client protocol version
+ */
+public final class ProtocolVersion
+{
+   // Versions
+   public static final int BASE = 47;
+   public static final int ALARMS = 1;
+   public static final int PUSH = 1;
+   public static final int TRAP = 1;
+   public static final int MOBILE = 1;
+   public static final int FULL = 1;
+   
+   // Indexes
+   public static final int INDEX_BASE = 0;
+   public static final int INDEX_ALARMS = 1;
+   public static final int INDEX_PUSH = 2;
+   public static final int INDEX_TRAP = 3;
+   public static final int INDEX_MOBILE = 4;
+   public static final int INDEX_FULL = 5;
+   
+   private static final int[] CURRENT_VERSION = { BASE, ALARMS, PUSH, TRAP, MOBILE, FULL };
+   
+   private long versions[];
+   
+   /**
+    * Create protocol version information from NXCP message
+    * 
+    * @param msg
+    */
+   protected ProtocolVersion(NXCPMessage msg)
+   {
+      versions = msg.getFieldAsUInt32Array(NXCPCodes.VID_PROTOCOL_VERSION_EX);
+      if (versions == null)
+      {
+         versions = new long[1];
+         versions[0] = msg.getFieldAsInt32(NXCPCodes.VID_PROTOCOL_VERSION);
+      }
+   }
+   
+   /**
+    * Get version of given component
+    * 
+    * @param index
+    * @return
+    */
+   public int getVersion(int index)
+   {
+      return (index >= 0) && (index < versions.length) ? (int)versions[index] : 0;
+   }
+   
+   /**
+    * Check if version of given component match current version
+    * 
+    * @param index
+    * @return
+    */
+   public boolean isCorrectVersion(int index)
+   {
+      if ((index < 0) || (index >= CURRENT_VERSION.length))
+         return false;
+      return getVersion(index) == CURRENT_VERSION[index];
+   }
+}
index 7e19dad..f399bbc 100644 (file)
@@ -1,7 +1,7 @@
 /* 
 ** NetXMS - Network Management System
 ** NetXMS Foundation Library
-** Copyright (C) 2003-2014 Victor Kirhenshtein
+** Copyright (C) 2003-2015 Victor Kirhenshtein
 **
 ** This program is free software; you can redistribute it and/or modify
 ** it under the terms of the GNU Lesser General Public License as published
@@ -33,7 +33,7 @@
  * Supported ciphers. By default, we support all ciphers compiled
  * into OpenSSL library.
  */
-static UINT32 m_dwSupportedCiphers = 
+static UINT32 s_supportedCiphers = 
 #ifdef _WITH_ENCRYPTION
 #ifndef OPENSSL_NO_AES
    NXCP_SUPPORT_AES_256 |
@@ -168,11 +168,11 @@ bool LIBNETXMS_EXPORTABLE InitCryptoLib(UINT32 dwEnabledCiphers, void (*debugCal
 
    // validate supported ciphers
    CryptoDbgPrintf(1, _T("Validating ciphers"));
-   m_dwSupportedCiphers &= dwEnabledCiphers;
+   s_supportedCiphers &= dwEnabledCiphers;
    UINT32 cipherBit = 1;
    for(i = 0; i < NETXMS_MAX_CIPHERS; i++, cipherBit = cipherBit << 1)
    {
-      if ((m_dwSupportedCiphers & cipherBit) == 0)
+      if ((s_supportedCiphers & cipherBit) == 0)
       {
          CryptoDbgPrintf(1, _T("   %s disabled (config)"), s_cipherNames[i]);
          continue;
@@ -185,7 +185,7 @@ bool LIBNETXMS_EXPORTABLE InitCryptoLib(UINT32 dwEnabledCiphers, void (*debugCal
       }
       else
       {
-         m_dwSupportedCiphers &= ~cipherBit;
+         s_supportedCiphers &= ~cipherBit;
          CryptoDbgPrintf(1, _T("   %s disabled (validation failed)"), s_cipherNames[i]);
       }
    }
@@ -201,9 +201,34 @@ bool LIBNETXMS_EXPORTABLE InitCryptoLib(UINT32 dwEnabledCiphers, void (*debugCal
 /**
  * Get supported ciphers
  */
-UINT32 LIBNETXMS_EXPORTABLE CSCPGetSupportedCiphers()
+UINT32 LIBNETXMS_EXPORTABLE NXCPGetSupportedCiphers()
 {
-   return m_dwSupportedCiphers;
+   return s_supportedCiphers;
+}
+
+/**
+ * Get supported ciphers as text
+ */
+String LIBNETXMS_EXPORTABLE NXCPGetSupportedCiphersAsText()
+{
+   String s;
+   UINT32 cipherBit = 1;
+   for(int i = 0; i < NETXMS_MAX_CIPHERS; i++, cipherBit = cipherBit << 1)
+   {
+      if ((s_supportedCiphers & cipherBit) == 0)
+      {
+         continue;
+      }
+      NXCPEncryptionContext *ctx = NXCPEncryptionContext::create(cipherBit);
+      if (ctx != NULL)
+      {
+         delete ctx;
+         if (s.length() > 0)
+            s.append(_T(", "));
+         s.append(s_cipherNames[i]);
+      }
+   }
+   return s;
 }
 
 /**
@@ -246,7 +271,7 @@ UINT32 LIBNETXMS_EXPORTABLE SetupEncryptionContext(NXCPMessage *msg,
       (*ppResponse)->setId(msg->getId());
       (*ppResponse)->disableEncryption();
 
-      dwCiphers = msg->getFieldAsUInt32(VID_SUPPORTED_ENCRYPTION) & m_dwSupportedCiphers;
+      dwCiphers = msg->getFieldAsUInt32(VID_SUPPORTED_ENCRYPTION) & s_supportedCiphers;
       if (dwCiphers == 0)
       {
          (*ppResponse)->setField(VID_RCC, RCC_NO_CIPHERS);
@@ -331,7 +356,7 @@ void LIBNETXMS_EXPORTABLE PrepareKeyRequestMsg(NXCPMessage *msg, RSA *pServerKey
    BYTE *pKeyBuffer, *pBufPos;
 
    msg->setCode(CMD_REQUEST_SESSION_KEY);
-   msg->setField(VID_SUPPORTED_ENCRYPTION, m_dwSupportedCiphers);
+   msg->setField(VID_SUPPORTED_ENCRYPTION, s_supportedCiphers);
 
        if (useX509Format)
        {
index 3ca4632..4ad67f8 100644 (file)
@@ -1581,6 +1581,14 @@ BOOL ClientSession::sendFile(const TCHAR *file, UINT32 dwRqId, long ofset)
  */
 void ClientSession::sendServerInfo(UINT32 dwRqId)
 {
+   static UINT32 protocolVersions[] = {
+      CLIENT_PROTOCOL_VERSION_BASE,
+      CLIENT_PROTOCOL_VERSION_ALARMS,
+      CLIENT_PROTOCOL_VERSION_PUSH,
+      CLIENT_PROTOCOL_VERSION_TRAP,
+      CLIENT_PROTOCOL_VERSION_MOBILE,
+      CLIENT_PROTOCOL_VERSION_FULL
+   };
    NXCPMessage msg;
        TCHAR szBuffer[1024];
        String strURL;
@@ -1601,7 +1609,8 @@ void ClientSession::sendServerInfo(UINT32 dwRqId)
    msg.setField(VID_SERVER_VERSION, NETXMS_VERSION_STRING);
    msg.setField(VID_SERVER_ID, (BYTE *)&g_qwServerId, sizeof(QWORD));
    msg.setField(VID_SUPPORTED_ENCRYPTION, (UINT32)0);
-   msg.setField(VID_PROTOCOL_VERSION, (UINT32)CLIENT_PROTOCOL_VERSION);
+   msg.setField(VID_PROTOCOL_VERSION, (UINT32)CLIENT_PROTOCOL_VERSION_BASE);
+   msg.setFieldFromInt32Array(VID_PROTOCOL_VERSION_EX, sizeof(protocolVersions) / sizeof(UINT32), protocolVersions);
        msg.setField(VID_CHALLENGE, m_challenge, CLIENT_CHALLENGE_SIZE);
    msg.setField(VID_TIMESTAMP, (UINT32)time(NULL));
 
index e51648c..cd9b4b2 100644 (file)
@@ -207,7 +207,13 @@ static BOOL ParseCommandLine(int argc, char *argv[])
                 _tprintf(help_text);
                 return FALSE;
                        case 'v':
-                               _tprintf(_T("NetXMS Server Version ") NETXMS_VERSION_STRING _T(" Build ") NETXMS_VERSION_BUILD_STRING IS_UNICODE_BUILD_STRING _T("\n"));
+            {
+                                  _tprintf(_T("NetXMS Server Version ") NETXMS_VERSION_STRING _T(" Build ") NETXMS_VERSION_BUILD_STRING IS_UNICODE_BUILD_STRING _T("\n"));
+               String ciphers = NXCPGetSupportedCiphersAsText();
+               _tprintf(_T("NXCP: %d.%d.%d.%d (%s)\n"), 
+                  NXCP_VERSION, CLIENT_PROTOCOL_VERSION_BASE, CLIENT_PROTOCOL_VERSION_MOBILE, CLIENT_PROTOCOL_VERSION_FULL,
+                  ciphers.isEmpty() ? _T("NO ENCRYPTION") : ciphers.getBuffer());
+            }
                                return FALSE;
                        case 'c':
 #ifdef UNICODE