working certificate issuing for agents
authorVictor Kirhenshtein <victor@netxms.org>
Sun, 5 Mar 2017 20:34:35 +0000 (22:34 +0200)
committerVictor Kirhenshtein <victor@netxms.org>
Sun, 5 Mar 2017 20:34:35 +0000 (22:34 +0200)
32 files changed:
include/nms_agent.h
include/nms_cscp.h
include/nxcldefs.h
include/nxcpapi.h
src/agent/core/nxagentd.cpp
src/agent/core/nxagentd.h
src/agent/core/session.cpp
src/agent/core/tunnel.cpp
src/client/libnxclient/main.cpp
src/java/client/netxms-base/src/main/java/org/netxms/base/NXCPCodes.java
src/java/client/netxms-client/src/main/java/org/netxms/client/constants/RCC.java
src/java/client/netxms-client/src/main/resources/messages.properties
src/java/client/netxms-client/src/main/resources/messages_ar.properties
src/java/client/netxms-client/src/main/resources/messages_cs.properties
src/java/client/netxms-client/src/main/resources/messages_de.properties
src/java/client/netxms-client/src/main/resources/messages_es.properties
src/java/client/netxms-client/src/main/resources/messages_fr.properties
src/java/client/netxms-client/src/main/resources/messages_pt.properties
src/java/client/netxms-client/src/main/resources/messages_ru.properties
src/java/client/netxms-client/src/main/resources/messages_zh_CN.properties
src/libnetxms/message.cpp
src/libnetxms/nxcp.cpp
src/server/core/cert.cpp
src/server/core/config.cpp
src/server/core/console.cpp
src/server/core/debug.cpp
src/server/core/main.cpp
src/server/core/session.cpp
src/server/core/tunnel.cpp
src/server/include/agent_tunnel.h
src/server/include/nms_core.h
src/server/libnxsrv/main.cpp

index 762c975..262d99a 100644 (file)
 #define ERR_SERVER_ID_UNSET         ((UINT32)920)
 #define ERR_NO_SUCH_INSTANCE        ((UINT32)921)
 #define ERR_OUT_OF_STATE_REQUEST    ((UINT32)922)
+#define ERR_ENCRYPTION_ERROR        ((UINT32)923)
 
 /**
  * Bulk data reconciliation DCI processing status codes
index 67fd32f..24b2eab 100644 (file)
@@ -450,10 +450,10 @@ typedef struct
 #define CMD_GET_PERSISTENT_STORAGE     0x00D3
 #define CMD_DELETE_PSTORAGE_VALUE      0x00D4
 #define CMD_SET_PSTORAGE_VALUE         0x00D5
-//#define CMD_DEL_SITUATION_INSTANCE     0x00D6
-//#define CMD_UPDATE_SITUATION           0x00D7
-//#define CMD_SITUATION_DATA             0x00D8
-//#define CMD_SITUATION_CHANGE           0x00D9
+#define CMD_GET_UNBOUND_AGENT_TUNNELS  0x00D6
+#define CMD_BIND_AGENT_TUNNEL          0x00D7
+#define CMD_REQUEST_CERTIFICATE        0x00D8
+#define CMD_NEW_CERTIFICATE            0x00D9
 #define CMD_CREATE_MAP                 0x00DA
 #define CMD_UPLOAD_FILE                0x00DB
 #define CMD_DELETE_FILE                0x00DC
index 7f94e69..2530f98 100644 (file)
@@ -415,130 +415,132 @@ enum SessionState
 /**
  * Request completion codes
  */
-#define RCC_SUCCESS                  ((UINT32)0)
-#define RCC_COMPONENT_LOCKED         ((UINT32)1)
-#define RCC_ACCESS_DENIED            ((UINT32)2)
-#define RCC_INVALID_REQUEST          ((UINT32)3)
-#define RCC_TIMEOUT                  ((UINT32)4)
-#define RCC_OUT_OF_STATE_REQUEST     ((UINT32)5)
-#define RCC_DB_FAILURE               ((UINT32)6)
-#define RCC_INVALID_OBJECT_ID        ((UINT32)7)
-#define RCC_ALREADY_EXIST            ((UINT32)8)
-#define RCC_COMM_FAILURE             ((UINT32)9)
-#define RCC_SYSTEM_FAILURE           ((UINT32)10)
-#define RCC_INVALID_USER_ID          ((UINT32)11)
-#define RCC_INVALID_ARGUMENT         ((UINT32)12)
-#define RCC_DUPLICATE_DCI            ((UINT32)13)
-#define RCC_INVALID_DCI_ID           ((UINT32)14)
-#define RCC_OUT_OF_MEMORY            ((UINT32)15)
-#define RCC_IO_ERROR                 ((UINT32)16)
-#define RCC_INCOMPATIBLE_OPERATION   ((UINT32)17)
-#define RCC_OBJECT_CREATION_FAILED   ((UINT32)18)
-#define RCC_OBJECT_LOOP              ((UINT32)19)
-#define RCC_INVALID_OBJECT_NAME      ((UINT32)20)
-#define RCC_INVALID_ALARM_ID         ((UINT32)21)
-#define RCC_INVALID_ACTION_ID        ((UINT32)22)
-#define RCC_OPERATION_IN_PROGRESS    ((UINT32)23)
-#define RCC_DCI_COPY_ERRORS          ((UINT32)24)
-#define RCC_INVALID_EVENT_CODE       ((UINT32)25)
-#define RCC_NO_WOL_INTERFACES        ((UINT32)26)
-#define RCC_NO_MAC_ADDRESS           ((UINT32)27)
-#define RCC_NOT_IMPLEMENTED          ((UINT32)28)
-#define RCC_INVALID_TRAP_ID          ((UINT32)29)
-#define RCC_DCI_NOT_SUPPORTED        ((UINT32)30)
-#define RCC_VERSION_MISMATCH         ((UINT32)31)
-#define RCC_NPI_PARSE_ERROR          ((UINT32)32)
-#define RCC_DUPLICATE_PACKAGE        ((UINT32)33)
-#define RCC_PACKAGE_FILE_EXIST       ((UINT32)34)
-#define RCC_RESOURCE_BUSY            ((UINT32)35)
-#define RCC_INVALID_PACKAGE_ID       ((UINT32)36)
-#define RCC_INVALID_IP_ADDR          ((UINT32)37)
-#define RCC_ACTION_IN_USE            ((UINT32)38)
-#define RCC_VARIABLE_NOT_FOUND       ((UINT32)39)
-#define RCC_BAD_PROTOCOL             ((UINT32)40)
-#define RCC_ADDRESS_IN_USE           ((UINT32)41)
-#define RCC_NO_CIPHERS               ((UINT32)42)
-#define RCC_INVALID_PUBLIC_KEY       ((UINT32)43)
-#define RCC_INVALID_SESSION_KEY      ((UINT32)44)
-#define RCC_NO_ENCRYPTION_SUPPORT    ((UINT32)45)
-#define RCC_INTERNAL_ERROR           ((UINT32)46)
-#define RCC_EXEC_FAILED              ((UINT32)47)
-#define RCC_INVALID_TOOL_ID          ((UINT32)48)
-#define RCC_SNMP_ERROR               ((UINT32)49)
-#define RCC_BAD_REGEXP               ((UINT32)50)
-#define RCC_UNKNOWN_PARAMETER        ((UINT32)51)
-#define RCC_FILE_IO_ERROR            ((UINT32)52)
-#define RCC_CORRUPTED_MIB_FILE       ((UINT32)53)
-#define RCC_TRANSFER_IN_PROGRESS     ((UINT32)54)
-#define RCC_INVALID_JOB_ID           ((UINT32)55)
-#define RCC_INVALID_SCRIPT_ID        ((UINT32)56)
-#define RCC_INVALID_SCRIPT_NAME      ((UINT32)57)
-#define RCC_UNKNOWN_MAP_NAME         ((UINT32)58)
-#define RCC_INVALID_MAP_ID           ((UINT32)59)
-#define RCC_ACCOUNT_DISABLED         ((UINT32)60)
-#define RCC_NO_GRACE_LOGINS          ((UINT32)61)
-#define RCC_CONNECTION_BROKEN        ((UINT32)62)
-#define RCC_INVALID_CONFIG_ID        ((UINT32)63)
-#define RCC_DB_CONNECTION_LOST       ((UINT32)64)
-#define RCC_ALARM_OPEN_IN_HELPDESK   ((UINT32)65)
-#define RCC_ALARM_NOT_OUTSTANDING    ((UINT32)66)
-#define RCC_NOT_PUSH_DCI             ((UINT32)67)
-#define RCC_CONFIG_PARSE_ERROR       ((UINT32)68)
-#define RCC_CONFIG_VALIDATION_ERROR  ((UINT32)69)
-#define RCC_INVALID_GRAPH_ID         ((UINT32)70)
-#define RCC_LOCAL_CRYPTO_ERROR          ((UINT32)71)
-#define RCC_UNSUPPORTED_AUTH_TYPE       ((UINT32)72)
-#define RCC_BAD_CERTIFICATE                     ((UINT32)73)
-#define RCC_INVALID_CERT_ID          ((UINT32)74)
-#define RCC_SNMP_FAILURE             ((UINT32)75)
-#define RCC_NO_L2_TOPOLOGY_SUPPORT      ((UINT32)76)
-#define RCC_INVALID_PSTORAGE_KEY     ((UINT32)77)
-#define RCC_NO_SUCH_INSTANCE         ((UINT32)78)
-#define RCC_INVALID_EVENT_ID         ((UINT32)79)
-#define RCC_AGENT_ERROR              ((UINT32)80)
-#define RCC_UNKNOWN_VARIABLE         ((UINT32)81)
-#define RCC_RESOURCE_NOT_AVAILABLE   ((UINT32)82)
-#define RCC_JOB_CANCEL_FAILED        ((UINT32)83)
-#define RCC_INVALID_POLICY_ID        ((UINT32)84)
-#define RCC_UNKNOWN_LOG_NAME         ((UINT32)85)
-#define RCC_INVALID_LOG_HANDLE       ((UINT32)86)
-#define RCC_WEAK_PASSWORD            ((UINT32)87)
-#define RCC_REUSED_PASSWORD          ((UINT32)88)
-#define RCC_INVALID_SESSION_HANDLE   ((UINT32)89)
-#define RCC_CLUSTER_MEMBER_ALREADY   ((UINT32)90)
-#define RCC_JOB_HOLD_FAILED          ((UINT32)91)
-#define RCC_JOB_UNHOLD_FAILED        ((UINT32)92)
-#define RCC_ZONE_ID_ALREADY_IN_USE   ((UINT32)93)
-#define RCC_INVALID_ZONE_ID          ((UINT32)94)
-#define RCC_ZONE_NOT_EMPTY           ((UINT32)95)
-#define RCC_NO_COMPONENT_DATA        ((UINT32)96)
-#define RCC_INVALID_ALARM_NOTE_ID    ((UINT32)97)
-#define RCC_ENCRYPTION_ERROR         ((UINT32)98)
-#define RCC_INVALID_MAPPING_TABLE_ID ((UINT32)99)
-#define RCC_NO_SOFTWARE_PACKAGE_DATA ((UINT32)100)
-#define RCC_INVALID_SUMMARY_TABLE_ID ((UINT32)101)
-#define RCC_USER_LOGGED_IN           ((UINT32)102)
-#define RCC_XML_PARSE_ERROR          ((UINT32)103)
-#define RCC_HIGH_QUERY_COST          ((UINT32)104)
-#define RCC_LICENSE_VIOLATION        ((UINT32)105)
-#define RCC_CLIENT_LICENSE_EXCEEDED  ((UINT32)106)
-#define RCC_OBJECT_ALREADY_EXISTS    ((UINT32)107)
-#define RCC_NO_HDLINK                ((UINT32)108)
-#define RCC_HDLINK_COMM_FAILURE      ((UINT32)109)
-#define RCC_HDLINK_ACCESS_DENIED     ((UINT32)110)
-#define RCC_HDLINK_INTERNAL_ERROR    ((UINT32)111)
-#define RCC_NO_LDAP_CONNECTION       ((UINT32)112)
-#define RCC_NO_ROUTING_TABLE         ((UINT32)113)
-#define RCC_NO_FDB                   ((UINT32)114)
-#define RCC_NO_LOCATION_HISTORY      ((UINT32)115)
-#define RCC_OBJECT_IN_USE            ((UINT32)116)
-#define RCC_NXSL_COMPILATION_ERROR   ((UINT32)117)
-#define RCC_NXSL_EXECUTION_ERROR     ((UINT32)118)
-#define RCC_UNKNOWN_CONFIG_VARIABLE  ((UINT32)119)
-#define RCC_UNSUPPORTED_AUTH_METHOD  ((UINT32)120)
-#define RCC_NAME_ALEARDY_EXISTS      ((UINT32)121)
-#define RCC_CATEGORY_IN_USE          ((UINT32)122)
-#define RCC_CATEGORY_NAME_EMPTY      ((UINT32)123)
+#define RCC_SUCCESS                   ((UINT32)0)
+#define RCC_COMPONENT_LOCKED          ((UINT32)1)
+#define RCC_ACCESS_DENIED             ((UINT32)2)
+#define RCC_INVALID_REQUEST           ((UINT32)3)
+#define RCC_TIMEOUT                   ((UINT32)4)
+#define RCC_OUT_OF_STATE_REQUEST      ((UINT32)5)
+#define RCC_DB_FAILURE                ((UINT32)6)
+#define RCC_INVALID_OBJECT_ID         ((UINT32)7)
+#define RCC_ALREADY_EXIST             ((UINT32)8)
+#define RCC_COMM_FAILURE              ((UINT32)9)
+#define RCC_SYSTEM_FAILURE            ((UINT32)10)
+#define RCC_INVALID_USER_ID           ((UINT32)11)
+#define RCC_INVALID_ARGUMENT          ((UINT32)12)
+#define RCC_DUPLICATE_DCI             ((UINT32)13)
+#define RCC_INVALID_DCI_ID            ((UINT32)14)
+#define RCC_OUT_OF_MEMORY             ((UINT32)15)
+#define RCC_IO_ERROR                  ((UINT32)16)
+#define RCC_INCOMPATIBLE_OPERATION    ((UINT32)17)
+#define RCC_OBJECT_CREATION_FAILED    ((UINT32)18)
+#define RCC_OBJECT_LOOP               ((UINT32)19)
+#define RCC_INVALID_OBJECT_NAME       ((UINT32)20)
+#define RCC_INVALID_ALARM_ID          ((UINT32)21)
+#define RCC_INVALID_ACTION_ID         ((UINT32)22)
+#define RCC_OPERATION_IN_PROGRESS     ((UINT32)23)
+#define RCC_DCI_COPY_ERRORS           ((UINT32)24)
+#define RCC_INVALID_EVENT_CODE        ((UINT32)25)
+#define RCC_NO_WOL_INTERFACES         ((UINT32)26)
+#define RCC_NO_MAC_ADDRESS            ((UINT32)27)
+#define RCC_NOT_IMPLEMENTED           ((UINT32)28)
+#define RCC_INVALID_TRAP_ID           ((UINT32)29)
+#define RCC_DCI_NOT_SUPPORTED         ((UINT32)30)
+#define RCC_VERSION_MISMATCH          ((UINT32)31)
+#define RCC_NPI_PARSE_ERROR           ((UINT32)32)
+#define RCC_DUPLICATE_PACKAGE         ((UINT32)33)
+#define RCC_PACKAGE_FILE_EXIST        ((UINT32)34)
+#define RCC_RESOURCE_BUSY             ((UINT32)35)
+#define RCC_INVALID_PACKAGE_ID        ((UINT32)36)
+#define RCC_INVALID_IP_ADDR           ((UINT32)37)
+#define RCC_ACTION_IN_USE             ((UINT32)38)
+#define RCC_VARIABLE_NOT_FOUND        ((UINT32)39)
+#define RCC_BAD_PROTOCOL              ((UINT32)40)
+#define RCC_ADDRESS_IN_USE            ((UINT32)41)
+#define RCC_NO_CIPHERS                ((UINT32)42)
+#define RCC_INVALID_PUBLIC_KEY        ((UINT32)43)
+#define RCC_INVALID_SESSION_KEY       ((UINT32)44)
+#define RCC_NO_ENCRYPTION_SUPPORT     ((UINT32)45)
+#define RCC_INTERNAL_ERROR            ((UINT32)46)
+#define RCC_EXEC_FAILED               ((UINT32)47)
+#define RCC_INVALID_TOOL_ID           ((UINT32)48)
+#define RCC_SNMP_ERROR                ((UINT32)49)
+#define RCC_BAD_REGEXP                ((UINT32)50)
+#define RCC_UNKNOWN_PARAMETER         ((UINT32)51)
+#define RCC_FILE_IO_ERROR             ((UINT32)52)
+#define RCC_CORRUPTED_MIB_FILE        ((UINT32)53)
+#define RCC_TRANSFER_IN_PROGRESS      ((UINT32)54)
+#define RCC_INVALID_JOB_ID            ((UINT32)55)
+#define RCC_INVALID_SCRIPT_ID         ((UINT32)56)
+#define RCC_INVALID_SCRIPT_NAME       ((UINT32)57)
+#define RCC_UNKNOWN_MAP_NAME          ((UINT32)58)
+#define RCC_INVALID_MAP_ID            ((UINT32)59)
+#define RCC_ACCOUNT_DISABLED          ((UINT32)60)
+#define RCC_NO_GRACE_LOGINS           ((UINT32)61)
+#define RCC_CONNECTION_BROKEN         ((UINT32)62)
+#define RCC_INVALID_CONFIG_ID         ((UINT32)63)
+#define RCC_DB_CONNECTION_LOST        ((UINT32)64)
+#define RCC_ALARM_OPEN_IN_HELPDESK    ((UINT32)65)
+#define RCC_ALARM_NOT_OUTSTANDING     ((UINT32)66)
+#define RCC_NOT_PUSH_DCI              ((UINT32)67)
+#define RCC_CONFIG_PARSE_ERROR        ((UINT32)68)
+#define RCC_CONFIG_VALIDATION_ERROR   ((UINT32)69)
+#define RCC_INVALID_GRAPH_ID          ((UINT32)70)
+#define RCC_LOCAL_CRYPTO_ERROR           ((UINT32)71)
+#define RCC_UNSUPPORTED_AUTH_TYPE        ((UINT32)72)
+#define RCC_BAD_CERTIFICATE           ((UINT32)73)
+#define RCC_INVALID_CERT_ID           ((UINT32)74)
+#define RCC_SNMP_FAILURE              ((UINT32)75)
+#define RCC_NO_L2_TOPOLOGY_SUPPORT       ((UINT32)76)
+#define RCC_INVALID_PSTORAGE_KEY      ((UINT32)77)
+#define RCC_NO_SUCH_INSTANCE          ((UINT32)78)
+#define RCC_INVALID_EVENT_ID          ((UINT32)79)
+#define RCC_AGENT_ERROR               ((UINT32)80)
+#define RCC_UNKNOWN_VARIABLE          ((UINT32)81)
+#define RCC_RESOURCE_NOT_AVAILABLE    ((UINT32)82)
+#define RCC_JOB_CANCEL_FAILED         ((UINT32)83)
+#define RCC_INVALID_POLICY_ID         ((UINT32)84)
+#define RCC_UNKNOWN_LOG_NAME          ((UINT32)85)
+#define RCC_INVALID_LOG_HANDLE        ((UINT32)86)
+#define RCC_WEAK_PASSWORD             ((UINT32)87)
+#define RCC_REUSED_PASSWORD           ((UINT32)88)
+#define RCC_INVALID_SESSION_HANDLE    ((UINT32)89)
+#define RCC_CLUSTER_MEMBER_ALREADY    ((UINT32)90)
+#define RCC_JOB_HOLD_FAILED           ((UINT32)91)
+#define RCC_JOB_UNHOLD_FAILED         ((UINT32)92)
+#define RCC_ZONE_ID_ALREADY_IN_USE    ((UINT32)93)
+#define RCC_INVALID_ZONE_ID           ((UINT32)94)
+#define RCC_ZONE_NOT_EMPTY            ((UINT32)95)
+#define RCC_NO_COMPONENT_DATA         ((UINT32)96)
+#define RCC_INVALID_ALARM_NOTE_ID     ((UINT32)97)
+#define RCC_ENCRYPTION_ERROR          ((UINT32)98)
+#define RCC_INVALID_MAPPING_TABLE_ID  ((UINT32)99)
+#define RCC_NO_SOFTWARE_PACKAGE_DATA  ((UINT32)100)
+#define RCC_INVALID_SUMMARY_TABLE_ID  ((UINT32)101)
+#define RCC_USER_LOGGED_IN            ((UINT32)102)
+#define RCC_XML_PARSE_ERROR           ((UINT32)103)
+#define RCC_HIGH_QUERY_COST           ((UINT32)104)
+#define RCC_LICENSE_VIOLATION         ((UINT32)105)
+#define RCC_CLIENT_LICENSE_EXCEEDED   ((UINT32)106)
+#define RCC_OBJECT_ALREADY_EXISTS     ((UINT32)107)
+#define RCC_NO_HDLINK                 ((UINT32)108)
+#define RCC_HDLINK_COMM_FAILURE       ((UINT32)109)
+#define RCC_HDLINK_ACCESS_DENIED      ((UINT32)110)
+#define RCC_HDLINK_INTERNAL_ERROR     ((UINT32)111)
+#define RCC_NO_LDAP_CONNECTION        ((UINT32)112)
+#define RCC_NO_ROUTING_TABLE          ((UINT32)113)
+#define RCC_NO_FDB                    ((UINT32)114)
+#define RCC_NO_LOCATION_HISTORY       ((UINT32)115)
+#define RCC_OBJECT_IN_USE             ((UINT32)116)
+#define RCC_NXSL_COMPILATION_ERROR    ((UINT32)117)
+#define RCC_NXSL_EXECUTION_ERROR      ((UINT32)118)
+#define RCC_UNKNOWN_CONFIG_VARIABLE   ((UINT32)119)
+#define RCC_UNSUPPORTED_AUTH_METHOD   ((UINT32)120)
+#define RCC_NAME_ALEARDY_EXISTS       ((UINT32)121)
+#define RCC_CATEGORY_IN_USE           ((UINT32)122)
+#define RCC_CATEGORY_NAME_EMPTY       ((UINT32)123)
+#define RCC_AGENT_FILE_DOWNLOAD_ERROR ((UINT32)124)
+#define RCC_INVALID_TUNNEL_ID         ((UINT32)125)
 
 /**
  * Mask bits for NXCModifyEventTemplate()
index fd3b3b4..e65390c 100644 (file)
@@ -72,6 +72,7 @@ private:
 
 public:
    NXCPMessage(int version = NXCP_VERSION);
+   NXCPMessage(UINT16 code, UINT32 id, int version = NXCP_VERSION);
    NXCPMessage(NXCPMessage *msg);
    NXCPMessage(NXCP_MESSAGE *rawMag, int version = NXCP_VERSION);
    ~NXCPMessage();
index 0dc3c1a..124e8c1 100644 (file)
@@ -160,6 +160,7 @@ TCHAR g_szListenAddress[MAX_PATH] = _T("*");
 TCHAR g_szConfigIncludeDir[MAX_PATH] = AGENT_DEFAULT_CONFIG_D;
 TCHAR g_szConfigPolicyDir[MAX_PATH] = AGENT_DEFAULT_CONFIG_D;
 TCHAR g_szLogParserDirectory[MAX_PATH] = _T("");
+TCHAR g_certificateDirectory[MAX_PATH] = _T("");
 TCHAR g_masterAgent[MAX_PATH] = _T("not_set");
 TCHAR g_szSNMPTrapListenAddress[MAX_PATH] = _T("*");
 UINT16 g_wListenPort = AGENT_LISTEN_PORT;
@@ -752,6 +753,12 @@ BOOL Initialize()
    nxlog_debug(6, _T("Log parser policy directory: %s"), g_szLogParserDirectory);
        CreateFolder(g_szLogParserDirectory);
 
+   // Initialize certificate directory
+   _sntprintf(g_certificateDirectory, MAX_PATH, _T("%s%scertificates") FS_PATH_SEPARATOR, g_szDataDirectory,
+              ((tail != '\\') && (tail != '/')) ? FS_PATH_SEPARATOR : _T(""));
+   nxlog_debug(6, _T("Certificate directory: %s"), g_certificateDirectory);
+   CreateFolder(g_certificateDirectory);
+
    nxlog_debug(6, _T("Configuration policy directory: %s"), g_szConfigPolicyDir);
 
 #ifdef _WIN32
@@ -808,6 +815,7 @@ BOOL Initialize()
 
        if (!(g_dwFlags & AF_SUBAGENT_LOADER))
        {
+          g_commThreadPool = ThreadPoolCreate(2, 32, _T("COMM"));
           if (g_dwFlags & AF_ENABLE_SNMP_PROXY)
           {
              g_snmpProxyThreadPool = ThreadPoolCreate(2, 128, _T("SNMPPROXY"));
@@ -1137,6 +1145,7 @@ void Shutdown()
    {
       ThreadPoolDestroy(g_snmpProxyThreadPool);
    }
+   ThreadPoolDestroy(g_commThreadPool);
 
    UnloadAllSubAgents();
    CloseLocalDatabase();
index 56b24d1..f5c0872 100644 (file)
@@ -656,6 +656,7 @@ extern TCHAR g_szListenAddress[];
 extern TCHAR g_szConfigIncludeDir[];
 extern TCHAR g_szConfigPolicyDir[];
 extern TCHAR g_szLogParserDirectory[];
+extern TCHAR g_certificateDirectory[];
 extern TCHAR g_szDataDirectory[];
 extern TCHAR g_masterAgent[];
 extern TCHAR g_szSNMPTrapListenAddress[];
@@ -684,6 +685,7 @@ extern UINT32 g_rejectedConnections;
 extern CommSession **g_pSessionList;
 extern MUTEX g_hSessionListAccess;
 extern ThreadPool *g_snmpProxyThreadPool;
+extern ThreadPool *g_commThreadPool;
 
 #ifdef _WIN32
 extern TCHAR g_windowsEventSourceName[];
index 4d9f853..e03d2de 100644 (file)
@@ -37,6 +37,11 @@ void ClearDataCollectionConfiguration();
 ThreadPool *g_snmpProxyThreadPool = NULL;
 
 /**
+ * Communication request processing thread pool
+ */
+ThreadPool *g_commThreadPool = NULL;
+
+/**
  * Next free session ID
  */
 static VolatileCounter s_sessionId = 0;
index 91f7f3e..8c57ef9 100644 (file)
@@ -46,6 +46,12 @@ private:
    bool sendMessage(const NXCPMessage *msg);
    NXCPMessage *waitForMessage(UINT16 code, UINT32 id) { return (m_queue != NULL) ? m_queue->waitForMessage(code, id, 5000) : NULL; }
 
+   void processBindRequest(NXCPMessage *request);
+
+   X509_REQ *createCertificateRequest(const char *cn, EVP_PKEY **pkey);
+   bool saveCertificate(X509 *cert, EVP_PKEY *key);
+   void loadCertificate();
+
    void debugPrintf(int level, const TCHAR *format, ...);
 
    void recvThread();
@@ -145,7 +151,18 @@ void Tunnel::recvThread()
             TCHAR buffer[64];
             debugPrintf(6, _T("Received message %s"), NXCPMessageCodeName(msg->getCode(), buffer));
          }
-         m_queue->put(msg);
+         switch(msg->getCode())
+         {
+            case CMD_BIND_AGENT_TUNNEL:
+               ThreadPoolExecute(g_commThreadPool, this, &Tunnel::processBindRequest, msg);
+               msg = NULL; // prevent message deletion
+               break;
+            default:
+               m_queue->put(msg);
+               msg = NULL; // prevent message deletion
+               break;
+         }
+         delete msg;
       }
       else if (result != MSGRECV_TIMEOUT)
       {
@@ -177,6 +194,74 @@ bool Tunnel::sendMessage(const NXCPMessage *msg)
 }
 
 /**
+ * Load certificate for this tunnel
+ */
+void Tunnel::loadCertificate()
+{
+   BYTE addressHash[18];
+   m_address.buildHashKey(addressHash);
+
+   TCHAR prefix[48];
+   BinToStr(addressHash, 18, prefix);
+
+   TCHAR name[MAX_PATH];
+   _sntprintf(name, MAX_PATH, _T("%s%s.crt"), g_certificateDirectory, prefix);
+   FILE *f = _tfopen(name, _T("r"));
+   if (f == NULL)
+   {
+      debugPrintf(4, _T("Cannot open file \"%s\" (%s)"), name, _tcserror(errno));
+      return;
+   }
+
+   X509 *cert = PEM_read_X509(f, NULL, NULL, NULL);
+   fclose(f);
+
+   if (cert == NULL)
+   {
+      debugPrintf(4, _T("Cannot load certificate from file \"%s\""), name);
+      return;
+   }
+
+   _sntprintf(name, MAX_PATH, _T("%s%s.key"), g_certificateDirectory, prefix);
+   f = _tfopen(name, _T("r"));
+   if (f == NULL)
+   {
+      debugPrintf(4, _T("Cannot open file \"%s\" (%s)"), name, _tcserror(errno));
+      X509_free(cert);
+      return;
+   }
+
+   EVP_PKEY *key = PEM_read_PrivateKey(f, NULL, NULL, (void *)"nxagentd");
+   fclose(f);
+
+   if (key == NULL)
+   {
+      debugPrintf(4, _T("Cannot load private key from file \"%s\""), name);
+      X509_free(cert);
+      return;
+   }
+
+   if (SSL_CTX_use_certificate(m_context, cert) == 1)
+   {
+      if (SSL_CTX_use_PrivateKey(m_context, key) == 1)
+      {
+         debugPrintf(4, _T("Certificate and private key loaded"));
+      }
+      else
+      {
+         debugPrintf(4, _T("Cannot set private key"));
+      }
+   }
+   else
+   {
+      debugPrintf(4, _T("Cannot set certificate"));
+   }
+
+   X509_free(cert);
+   EVP_PKEY_free(key);
+}
+
+/**
  * Connect to server
  */
 bool Tunnel::connectToServer()
@@ -224,6 +309,7 @@ bool Tunnel::connectToServer()
       return false;
    }
    SSL_CTX_set_options(m_context, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION);
+   loadCertificate();
 
    m_ssl = SSL_new(m_context);
    if (m_ssl == NULL)
@@ -260,7 +346,7 @@ bool Tunnel::connectToServer()
       break;
    }
 
-   // Check server vertificate
+   // Check server certificate
    X509 *cert = SSL_get_peer_certificate(m_ssl);
    if (cert == NULL)
    {
@@ -362,6 +448,206 @@ void Tunnel::checkConnection()
 }
 
 /**
+ * Create certificate request
+ */
+X509_REQ *Tunnel::createCertificateRequest(const char *cn, EVP_PKEY **pkey)
+{
+   RSA *key = RSA_generate_key(NETXMS_RSA_KEYLEN, 17, NULL, NULL);
+   if (key == NULL)
+   {
+      debugPrintf(4, _T("call to RSA_generate_key() failed"));
+      return NULL;
+   }
+
+   X509_REQ *req = X509_REQ_new();
+   if (req != NULL)
+   {
+      X509_REQ_set_version(req, 1);
+      X509_NAME *subject = X509_REQ_get_subject_name(req);
+      if (subject != NULL)
+      {
+         X509_NAME_add_entry_by_txt(subject,"O", MBSTRING_UTF8, (const BYTE *)"netxms.org", -1, -1, 0);
+         X509_NAME_add_entry_by_txt(subject,"CN", MBSTRING_UTF8, (const BYTE *)cn, -1, -1, 0);
+
+         EVP_PKEY *ekey = EVP_PKEY_new();
+         if (ekey != NULL)
+         {
+            EVP_PKEY_assign_RSA(ekey, key);
+            key = NULL; // will be freed by EVP_PKEY_free
+            X509_REQ_set_pubkey(req, ekey);
+            if (X509_REQ_sign(req, ekey, EVP_sha256()) > 0)
+            {
+               *pkey = ekey;
+            }
+            else
+            {
+               debugPrintf(4, _T("call to X509_REQ_sign() failed"));
+               X509_REQ_free(req);
+               req = NULL;
+               EVP_PKEY_free(ekey);
+            }
+         }
+         else
+         {
+            debugPrintf(4, _T("call to EVP_PKEY_new() failed"));
+            X509_REQ_free(req);
+            req = NULL;
+         }
+      }
+      else
+      {
+         debugPrintf(4, _T("call to X509_REQ_get_subject_name() failed"));
+         X509_REQ_free(req);
+         req = NULL;
+      }
+   }
+   else
+   {
+      debugPrintf(4, _T("call to X509_REQ_new() failed"));
+   }
+
+   if (key != NULL)
+      RSA_free(key);
+   return req;
+}
+
+/**
+ * Save certificate
+ */
+bool Tunnel::saveCertificate(X509 *cert, EVP_PKEY *key)
+{
+   BYTE addressHash[18];
+   m_address.buildHashKey(addressHash);
+
+   TCHAR prefix[48];
+   BinToStr(addressHash, 18, prefix);
+
+   TCHAR name[MAX_PATH];
+   _sntprintf(name, MAX_PATH, _T("%s%s.crt"), g_certificateDirectory, prefix);
+   FILE *f = _tfopen(name, _T("w"));
+   if (f == NULL)
+   {
+      debugPrintf(4, _T("Cannot open file \"%s\" (%s)"), name, _tcserror(errno));
+      return false;
+   }
+   int rc = PEM_write_X509(f, cert);
+   fclose(f);
+   if (rc != 1)
+   {
+      debugPrintf(4, _T("PEM_write_X509(\"%s\") failed"), name);
+      return false;
+   }
+
+   _sntprintf(name, MAX_PATH, _T("%s%s.key"), g_certificateDirectory, prefix);
+   f = _tfopen(name, _T("w"));
+   if (f == NULL)
+   {
+      debugPrintf(4, _T("Cannot open file \"%s\" (%s)"), name, _tcserror(errno));
+      return false;
+   }
+   rc = PEM_write_PrivateKey(f, key, EVP_des_ede3_cbc(), NULL, 0, 0, (void *)"nxagentd");
+   fclose(f);
+   if (rc != 1)
+   {
+      debugPrintf(4, _T("PEM_write_PrivateKey(\"%s\") failed"), name);
+      return false;
+   }
+
+   debugPrintf(4, _T("Certificate and private key saved"));
+   return true;
+}
+
+/**
+ * Process tunnel bind request
+ */
+void Tunnel::processBindRequest(NXCPMessage *request)
+{
+   NXCPMessage response(CMD_REQUEST_COMPLETED, request->getId());
+
+   uuid guid = request->getFieldAsGUID(VID_GUID);
+   char *cn = guid.toString().getUTF8String();
+
+   EVP_PKEY *key = NULL;
+   X509_REQ *req = createCertificateRequest(cn, &key);
+   free(cn);
+
+   if (req != NULL)
+   {
+      BYTE *buffer = NULL;
+      int len = i2d_X509_REQ(req, &buffer);
+      if (len > 0)
+      {
+         NXCPMessage certRequest(CMD_REQUEST_CERTIFICATE, request->getId());
+         certRequest.setField(VID_CERTIFICATE, buffer, len);
+         sendMessage(&certRequest);
+         OPENSSL_free(buffer);
+
+         NXCPMessage *certResponse = waitForMessage(CMD_NEW_CERTIFICATE, request->getId());
+         if (certResponse != NULL)
+         {
+            UINT32 rcc = certResponse->getFieldAsUInt32(VID_RCC);
+            if (rcc == ERR_SUCCESS)
+            {
+               size_t certLen;
+               const BYTE *certData = certResponse->getBinaryFieldPtr(VID_CERTIFICATE, &certLen);
+               if (certData != NULL)
+               {
+                  X509 *cert = d2i_X509(NULL, &certData, certLen);
+                  if (cert != NULL)
+                  {
+                     if (saveCertificate(cert, key))
+                     {
+                        response.setField(VID_RCC, ERR_SUCCESS);
+                     }
+                     else
+                     {
+                        response.setField(VID_RCC, ERR_IO_FAILURE);
+                     }
+                     X509_free(cert);
+                  }
+                  else
+                  {
+                     debugPrintf(4, _T("certificate data is invalid"));
+                     response.setField(VID_RCC, ERR_ENCRYPTION_ERROR);
+                  }
+               }
+               else
+               {
+                  debugPrintf(4, _T("certificate data missing in server response"));
+                  response.setField(VID_RCC, ERR_INTERNAL_ERROR);
+               }
+            }
+            else
+            {
+               debugPrintf(4, _T("certificate request failed (%d)"), rcc);
+               response.setField(VID_RCC, rcc);
+            }
+            delete certResponse;
+         }
+         else
+         {
+            debugPrintf(4, _T("timeout waiting for certificate request completion"));
+            response.setField(VID_RCC, ERR_REQUEST_TIMEOUT);
+         }
+      }
+      else
+      {
+         debugPrintf(4, _T("call to i2d_X509_REQ() failed"));
+         response.setField(VID_RCC, ERR_ENCRYPTION_ERROR);
+      }
+      X509_REQ_free(req);
+      EVP_PKEY_free(key);
+   }
+   else
+   {
+      response.setField(VID_RCC, ERR_ENCRYPTION_ERROR);
+   }
+
+   sendMessage(&response);
+   delete request;
+}
+
+/**
  * Create tunnel object from configuration record
  */
 Tunnel *Tunnel::createFromConfig(TCHAR *config)
index d5c816f..413d36a 100644 (file)
@@ -203,9 +203,15 @@ const TCHAR LIBNXCLIENT_EXPORTABLE *NXCGetErrorText(UINT32 error)
       _T("Object is in use and cannot be deleted"),
       _T("Script compilation error"),
       _T("Script execution error"),
-      _T("Unknown configuration variable")
+      _T("Unknown configuration variable"),
+      _T("Authentication method not supported"),
+      _T("Object with given name already exists"),
+      _T("Category is used in event processing policy"),
+      _T("Category name is empty"),
+      _T("Unable to download file from agent"),
+      _T("Invalid tunnel ID")
    };
-       return (error <= RCC_UNKNOWN_CONFIG_VARIABLE) ? errorText[error] : _T("No text message for this error");
+       return (error <= RCC_INVALID_TUNNEL_ID) ? errorText[error] : _T("No text message for this error");
 }
 
 #if defined(_WIN32) && !defined(UNDER_CE)
index 375b26e..6937630 100644 (file)
@@ -107,7 +107,7 @@ public class NXCPCodes
        public static final int CMD_CREATE_ACTION = 0x0051;
        public static final int CMD_DELETE_ACTION = 0x0052;
        public static final int CMD_ACTION_DATA = 0x0053;
-       public static final int CMD_GET_CONTAINER_CAT_LIST = 0x0054;
+       public static final int CMD_SETUP_AGENT_TUNNEL = 0x0054;
        public static final int CMD_EXECUTE_LIBRARY_SCRIPT = 0x0055;
        public static final int CMD_GET_PREDICTION_ENGINES = 0x0056;
        public static final int CMD_GET_PREDICTED_DATA = 0x0057;
@@ -237,10 +237,10 @@ public class NXCPCodes
        public static final int CMD_GET_PERSISTENT_STORAGE = 0x00D3;
        public static final int CMD_DELETE_PSTORAGE_VALUE = 0x00D4;
        public static final int CMD_SET_PSTORAGE_VALUE = 0x00D5;
-//     public static final int CMD_DEL_SITUATION_INSTANCE = 0x00D6;
-//     public static final int CMD_UPDATE_SITUATION = 0x00D7;
-//     public static final int CMD_SITUATION_DATA = 0x00D8;
-//     public static final int CMD_SITUATION_CHANGE = 0x00D9;
+       public static final int CMD_GET_UNBOUND_AGENT_TUNNELS = 0x00D6;
+       public static final int CMD_BIND_AGENT_TUNNEL = 0x00D7;
+       public static final int CMD_REQUEST_CERTIFICATE = 0x00D8;
+       public static final int CMD_NEW_CERTIFICATE = 0x00D9;
        public static final int CMD_CREATE_MAP = 0x00DA;
        public static final int CMD_UPLOAD_FILE = 0x00DB;
        public static final int CMD_DELETE_FILE = 0x00DC;
index 5916fa8..30c1a31 100644 (file)
@@ -118,6 +118,7 @@ public final class RCC extends CommonRCC
    public static final int CATEGORY_IN_USE = 122;
    public static final int CATEGORY_NAME_EMPTY = 123;
    public static final int AGENT_FILE_DOWNLOAD_ERROR = 124;
+   public static final int INVALID_TUNNEL_ID = 125;
        
        // SNMP-specific, has no corresponding RCC_xxx constants in C library
        public static final int BAD_MIB_FILE_HEADER = 1001;
index 6d48bd9..88e9f86 100644 (file)
@@ -119,10 +119,11 @@ RCC_0117=Script compilation error (%s)
 RCC_0118=Script execution error (%s)
 RCC_0119=Unknown configuration variable
 RCC_0120=Authentication method not supported
-RCC_0121=Object name already exists
+RCC_0121=Object with given name already exists
 RCC_0122=Category is used in event processing policy
 RCC_0123=Category name is empty
 RCC_0124=Unable to download file from agent
+RCC_0125=Invalid tunnel ID
 RCC_1001=Bad MIB file header
 RCC_1002=Bad MIB file data
 RCC_UNKNOWN=Error %d
index 6d48bd9..88e9f86 100644 (file)
@@ -119,10 +119,11 @@ RCC_0117=Script compilation error (%s)
 RCC_0118=Script execution error (%s)
 RCC_0119=Unknown configuration variable
 RCC_0120=Authentication method not supported
-RCC_0121=Object name already exists
+RCC_0121=Object with given name already exists
 RCC_0122=Category is used in event processing policy
 RCC_0123=Category name is empty
 RCC_0124=Unable to download file from agent
+RCC_0125=Invalid tunnel ID
 RCC_1001=Bad MIB file header
 RCC_1002=Bad MIB file data
 RCC_UNKNOWN=Error %d
index 6d48bd9..88e9f86 100644 (file)
@@ -119,10 +119,11 @@ RCC_0117=Script compilation error (%s)
 RCC_0118=Script execution error (%s)
 RCC_0119=Unknown configuration variable
 RCC_0120=Authentication method not supported
-RCC_0121=Object name already exists
+RCC_0121=Object with given name already exists
 RCC_0122=Category is used in event processing policy
 RCC_0123=Category name is empty
 RCC_0124=Unable to download file from agent
+RCC_0125=Invalid tunnel ID
 RCC_1001=Bad MIB file header
 RCC_1002=Bad MIB file data
 RCC_UNKNOWN=Error %d
index 51829c7..0106e8c 100644 (file)
@@ -119,10 +119,11 @@ RCC_0117=Script Kompilierungsfehler (%s)
 RCC_0118=Script Ausf\u00fchrungsfehler (%s)
 RCC_0119=Unbekannte Konfigurationsvariable
 RCC_0120=Authentifizierungsmethode wird nicht unterst\u00fctzt
-RCC_0121=Objename existiert bereits
+RCC_0121=Objekt mit diesem Namen existiert bereits
 RCC_0122=Kategorie wird in Eventverarbeitungsrichtlinie benutzt
 RCC_0123=Kategoriename ist leer
 RCC_0124=Die Datei konnte nicht vom Agenten geladen werden
+RCC_0125=Ung\u00fcltige Tunnel-ID
 RCC_1001=Fehlerhafter MIB Header
 RCC_1002=Fehlerhafte MIB Daten
 RCC_UNKNOWN=Fehler %d
index f439540..4872701 100644 (file)
@@ -1,41 +1,41 @@
-RCC_0000= Petici\u00f3n completada con \u00e9xito
-RCC_0001= Componente bloqueado por %s
-RCC_0002= Acceso denegado
-RCC_0003= Petici\u00f3n inv\u00e1lida
-RCC_0004= Caducidad de la petici\u00f3n
-RCC_0005= La petici\u00f3n est\u00e1 fuera de estado
-RCC_0006= Fallo en la base de datos
-RCC_0007= ID de objeto inv\u00e1lido
-RCC_0008= IP conflict with node %s
-RCC_0009= Fallo en la comunicaci\u00f3n
-RCC_0010= Fallo del sistema
-RCC_0011= ID de usuario inv\u00e1lido
-RCC_0012= Argumento inv\u00e1lido
-RCC_0013= DCI duplicado
-RCC_0014= ID de DCI inv\u00e1lido
-RCC_0015= Sin memoria
-RCC_0016= Error de Entrada/Salida
-RCC_0017= Operaci\u00f3n incompatible
-RCC_0018= La creaci\u00f3n del objeto ha fallado
-RCC_0019= Se ha detectado un bucle en las relaciones del objeto
-RCC_0020= Nombre de objeto inv\u00e1lido
-RCC_0021= ID de alarma inv\u00e1lido
-RCC_0022= ID de acci\u00f3n inv\u00e1lido
-RCC_0023= Operaci\u00f3n en progreso
-RCC_0024= El copiado ha fallado en uno o m\u00e1s DCI(s)
-RCC_0025= C\u00f3digo de evento inv\u00e1lido o desconocido
-RCC_0026= Sin interfaces adecuados para enviar el paquete m\u00e1gico
-RCC_0027= Sin direcci\u00f3n MAC en el interfaz
-RCC_0028= Comando no implementado
-RCC_0029= ID de registro de configuraci\u00f3n de traps inv\u00e1lido
-RCC_0030= La petici\u00f3n del monitor no est\u00e1 soportada por el agente
-RCC_0031= Las versiones del cliente y del servidor son incompatibles
-RCC_0032= Error al analizar el fichero de informaci\u00f3n del paquete
-RCC_0033= El paquete con las propiedades especificadas ya est\u00e1 instalado en el servidor
-RCC_0034= El fichero de paquete ya existe en el servidor
-RCC_0035= El recurso del servidor est\u00e1 ocupado
-RCC_0036= ID de paquete inv\u00e1lido
-RCC_0037= Direcci\u00f3n IP inv\u00e1lida
+RCC_0000=Petici\u00f3n completada con \u00e9xito
+RCC_0001=Componente bloqueado por %s
+RCC_0002=Acceso denegado
+RCC_0003=Petici\u00f3n inv\u00e1lida
+RCC_0004=Caducidad de la petici\u00f3n
+RCC_0005=La petici\u00f3n est\u00e1 fuera de estado
+RCC_0006=Fallo en la base de datos
+RCC_0007=ID de objeto inv\u00e1lido
+RCC_0008=IP conflict with node %s
+RCC_0009=Fallo en la comunicaci\u00f3n
+RCC_0010=Fallo del sistema
+RCC_0011=ID de usuario inv\u00e1lido
+RCC_0012=Argumento inv\u00e1lido
+RCC_0013=DCI duplicado
+RCC_0014=ID de DCI inv\u00e1lido
+RCC_0015=Sin memoria
+RCC_0016=Error de Entrada/Salida
+RCC_0017=Operaci\u00f3n incompatible
+RCC_0018=La creaci\u00f3n del objeto ha fallado
+RCC_0019=Se ha detectado un bucle en las relaciones del objeto
+RCC_0020=Nombre de objeto inv\u00e1lido
+RCC_0021=ID de alarma inv\u00e1lido
+RCC_0022=ID de acci\u00f3n inv\u00e1lido
+RCC_0023=Operaci\u00f3n en progreso
+RCC_0024=El copiado ha fallado en uno o m\u00e1s DCI(s)
+RCC_0025=C\u00f3digo de evento inv\u00e1lido o desconocido
+RCC_0026=Sin interfaces adecuados para enviar el paquete m\u00e1gico
+RCC_0027=Sin direcci\u00f3n MAC en el interfaz
+RCC_0028=Comando no implementado
+RCC_0029=ID de registro de configuraci\u00f3n de traps inv\u00e1lido
+RCC_0030=La petici\u00f3n del monitor no est\u00e1 soportada por el agente
+RCC_0031=Las versiones del cliente y del servidor son incompatibles
+RCC_0032=Error al analizar el fichero de informaci\u00f3n del paquete
+RCC_0033=El paquete con las propiedades especificadas ya est\u00e1 instalado en el servidor
+RCC_0034=El fichero de paquete ya existe en el servidor
+RCC_0035=El recurso del servidor est\u00e1 ocupado
+RCC_0036=ID de paquete inv\u00e1lido
+RCC_0037=Direcci\u00f3n IP inv\u00e1lida
 RCC_0038= La acci\u00f3n es utilizada en una pol\u00edtica de tratamiento de eventos
 RCC_0039= Variable no encontrada
 RCC_0040= El servidor utiliza un protocolo de comunicaciones incompatible
@@ -119,10 +119,11 @@ RCC_0117=Script compilation error (%s)
 RCC_0118=Script execution error (%s)
 RCC_0119=Unknown configuration variable
 RCC_0120=Authentication method not supported
-RCC_0121=Object name already exists
+RCC_0121=Object with given name already exists
 RCC_0122=Category is used in event processing policy
 RCC_0123=Category name is empty
 RCC_0124=Unable to download file from agent
+RCC_0125=Invalid tunnel ID
 RCC_1001=Error en la cabecera del fichero MIB
 RCC_1002=Error en los datos del fichero MIB
 RCC_UNKNOWN= Error %d
index 6d48bd9..88e9f86 100644 (file)
@@ -119,10 +119,11 @@ RCC_0117=Script compilation error (%s)
 RCC_0118=Script execution error (%s)
 RCC_0119=Unknown configuration variable
 RCC_0120=Authentication method not supported
-RCC_0121=Object name already exists
+RCC_0121=Object with given name already exists
 RCC_0122=Category is used in event processing policy
 RCC_0123=Category name is empty
 RCC_0124=Unable to download file from agent
+RCC_0125=Invalid tunnel ID
 RCC_1001=Bad MIB file header
 RCC_1002=Bad MIB file data
 RCC_UNKNOWN=Error %d
index 6d48bd9..88e9f86 100644 (file)
@@ -119,10 +119,11 @@ RCC_0117=Script compilation error (%s)
 RCC_0118=Script execution error (%s)
 RCC_0119=Unknown configuration variable
 RCC_0120=Authentication method not supported
-RCC_0121=Object name already exists
+RCC_0121=Object with given name already exists
 RCC_0122=Category is used in event processing policy
 RCC_0123=Category name is empty
 RCC_0124=Unable to download file from agent
+RCC_0125=Invalid tunnel ID
 RCC_1001=Bad MIB file header
 RCC_1002=Bad MIB file data
 RCC_UNKNOWN=Error %d
index d0fa844..1b7c3cc 100644 (file)
@@ -1,40 +1,40 @@
-RCC_0000= \u0417\u0430\u043f\u0440\u043e\u0441 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d \u0443\u0441\u043f\u0435\u0448\u043d\u043e
-RCC_0001= \u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c %s
-RCC_0002= \u041e\u0442\u043a\u0430\u0437\u0430\u043d\u043e \u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0435
-RCC_0003= \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441
-RCC_0004= \u041f\u0440\u0435\u0432\u044b\u0448\u0435\u043d\u043e \u0432\u0440\u0435\u043c\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u043e\u0442\u0432\u0435\u0442\u0430 \u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441
-RCC_0005= \u041d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441
-RCC_0006= \u041e\u0448\u0438\u0431\u043a\u0430 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445
-RCC_0007= \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043e\u0431\u044a\u0435\u043a\u0442\u0430
-RCC_0008= \u041a\u043e\u043d\u0444\u043b\u0438\u043a\u0442 IP c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c %s
-RCC_0009= \u0421\u0431\u043e\u0439 \u0441\u0432\u044f\u0437\u0438
-RCC_0010= \u0421\u0431\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b
-RCC_0011= \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f
-RCC_0012= \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442
-RCC_0013= \u0414\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u0435\u0442\u0440\u0438\u043a\u0438
-RCC_0014= \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043c\u0435\u0442\u0440\u0438\u043a\u0438
-RCC_0015= \u041f\u0435\u0440\u0435\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438
-RCC_0016= \u041e\u0448\u0438\u0431\u043a\u0430 \u0432\u0432\u043e\u0434\u0430/\u0432\u044b\u0432\u043e\u0434\u0430
-RCC_0017= \u041d\u0435\u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f
-RCC_0018= \u0421\u0431\u043e\u0439 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430
-RCC_0019= \u041e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0430 \u043f\u0435\u0442\u043b\u044f \u0432 \u0441\u0432\u044f\u0437\u044f\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u0430
-RCC_0020= \u041d\u0435\u0432\u0435\u0440\u043d\u043e\u0435 \u0438\u043c\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430
-RCC_0021= \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0442\u0440\u0435\u0432\u043e\u0433\u0438
-RCC_0022= \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f
-RCC_0023= \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f
-RCC_0024= \u0421\u0431\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0434\u043d\u043e\u0439 \u0438\u043b\u0438 \u0431\u043e\u043b\u0435\u0435 \u043c\u0435\u0442\u0440\u0438\u043a
-RCC_0025= \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0438\u043b\u0438 \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0439 \u043a\u043e\u0434 \u0441\u043e\u0431\u044b\u0442\u0438\u044f
-RCC_0026= \u041e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e (magic) \u043f\u0430\u043a\u0435\u0442\u0430
-RCC_0027= \u041e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438\u0439 (MAC) \u0430\u0434\u0440\u0435\u0441 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430
-RCC_0028= \u041a\u043e\u043c\u0430\u043d\u0434\u0430 \u043d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430
-RCC_0029= \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0437\u0430\u043f\u0438\u0441\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043b\u043e\u0432\u0443\u0448\u043a\u0438 SNMP
-RCC_0030= \u0417\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0441\u0431\u043e\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0430\u0433\u0435\u043d\u0442\u043e\u043c
-RCC_0031= \u041d\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0442 \u0432\u0435\u0440\u0441\u0438\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430
-RCC_0032= \u041e\u0448\u0438\u0431\u043a\u0430 \u0440\u0430\u0437\u0431\u043e\u0440\u0430 \u0444\u0430\u0439\u043b\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043f\u0430\u043a\u0435\u0442\u0430
-RCC_0033= \u041f\u0430\u043a\u0435\u0442 \u0441 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438 \u0443\u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435
-RCC_0034= \u0424\u0430\u0439\u043b \u043f\u0430\u043a\u0435\u0442\u0430 \u0443\u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435
-RCC_0035= \u0420\u0435\u0441\u0443\u0440\u0441 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0437\u0430\u043d\u044f\u0442
-RCC_0036= \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043f\u0430\u043a\u0435\u0442\u0430
+RCC_0000=\u0417\u0430\u043f\u0440\u043e\u0441 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d \u0443\u0441\u043f\u0435\u0448\u043d\u043e
+RCC_0001=\u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c %s
+RCC_0002=\u041e\u0442\u043a\u0430\u0437\u0430\u043d\u043e \u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0435
+RCC_0003=\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441
+RCC_0004=\u041f\u0440\u0435\u0432\u044b\u0448\u0435\u043d\u043e \u0432\u0440\u0435\u043c\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u043e\u0442\u0432\u0435\u0442\u0430 \u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441
+RCC_0005=\u041d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441
+RCC_0006=\u041e\u0448\u0438\u0431\u043a\u0430 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445
+RCC_0007=\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043e\u0431\u044a\u0435\u043a\u0442\u0430
+RCC_0008=\u041a\u043e\u043d\u0444\u043b\u0438\u043a\u0442 IP c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c %s
+RCC_0009=\u0421\u0431\u043e\u0439 \u0441\u0432\u044f\u0437\u0438
+RCC_0010=\u0421\u0431\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b
+RCC_0011=\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f
+RCC_0012=\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442
+RCC_0013=\u0414\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u0435\u0442\u0440\u0438\u043a\u0438
+RCC_0014=\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043c\u0435\u0442\u0440\u0438\u043a\u0438
+RCC_0015=\u041f\u0435\u0440\u0435\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438
+RCC_0016=\u041e\u0448\u0438\u0431\u043a\u0430 \u0432\u0432\u043e\u0434\u0430/\u0432\u044b\u0432\u043e\u0434\u0430
+RCC_0017=\u041d\u0435\u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f
+RCC_0018=\u0421\u0431\u043e\u0439 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430
+RCC_0019=\u041e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0430 \u043f\u0435\u0442\u043b\u044f \u0432 \u0441\u0432\u044f\u0437\u044f\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u0430
+RCC_0020=\u041d\u0435\u0432\u0435\u0440\u043d\u043e\u0435 \u0438\u043c\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430
+RCC_0021=\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0442\u0440\u0435\u0432\u043e\u0433\u0438
+RCC_0022=\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f
+RCC_0023=\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f
+RCC_0024=\u0421\u0431\u043e\u0439 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0434\u043d\u043e\u0439 \u0438\u043b\u0438 \u0431\u043e\u043b\u0435\u0435 \u043c\u0435\u0442\u0440\u0438\u043a
+RCC_0025=\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0438\u043b\u0438 \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0439 \u043a\u043e\u0434 \u0441\u043e\u0431\u044b\u0442\u0438\u044f
+RCC_0026=\u041e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e (magic) \u043f\u0430\u043a\u0435\u0442\u0430
+RCC_0027=\u041e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438\u0439 (MAC) \u0430\u0434\u0440\u0435\u0441 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430
+RCC_0028=\u041a\u043e\u043c\u0430\u043d\u0434\u0430 \u043d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430
+RCC_0029=\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0437\u0430\u043f\u0438\u0441\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043b\u043e\u0432\u0443\u0448\u043a\u0438 SNMP
+RCC_0030=\u0417\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0441\u0431\u043e\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0430\u0433\u0435\u043d\u0442\u043e\u043c
+RCC_0031=\u041d\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0442 \u0432\u0435\u0440\u0441\u0438\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430
+RCC_0032=\u041e\u0448\u0438\u0431\u043a\u0430 \u0440\u0430\u0437\u0431\u043e\u0440\u0430 \u0444\u0430\u0439\u043b\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043f\u0430\u043a\u0435\u0442\u0430
+RCC_0033=\u041f\u0430\u043a\u0435\u0442 \u0441 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c\u0438 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438 \u0443\u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435
+RCC_0034=\u0424\u0430\u0439\u043b \u043f\u0430\u043a\u0435\u0442\u0430 \u0443\u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435
+RCC_0035=\u0420\u0435\u0441\u0443\u0440\u0441 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0437\u0430\u043d\u044f\u0442
+RCC_0036=\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043f\u0430\u043a\u0435\u0442\u0430
 RCC_0037= \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0430\u0434\u0440\u0435\u0441 IP
 RCC_0038= \u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u044f
 RCC_0039= \u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430
@@ -90,39 +90,40 @@ RCC_0088= \u041f\u0430\u0440\u043e\u043b\u044c \u0438\u0441\u043f\u043e\u043b\u0
 RCC_0089= \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0434\u0435\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0440 \u0441\u0435\u0441\u0441\u0438\u0438
 RCC_0090= \u0423\u0437\u0435\u043b \u0443\u0436\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0447\u043b\u0435\u043d\u043e\u043c \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430
 RCC_0091= \u0417\u0430\u0434\u0430\u043d\u0438\u0435 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043e
-RCC_0092= \u041f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u043e\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u043e
-RCC_0093= \u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0437\u043e\u043d\u044b \u0443\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f
-RCC_0094= \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0437\u043e\u043d\u044b
-RCC_0095= \u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u043d\u0435\u043f\u0443\u0441\u0442\u0443\u044e \u0437\u043e\u043d\u0443
-RCC_0096= \u041e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435
-RCC_0097= \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0443\u0437\u043b\u0430-\u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u0442\u0440\u0435\u0432\u043e\u0433\u0438
-RCC_0098= \u041e\u0448\u0438\u0431\u043a\u0430 \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u044f
-RCC_0099= \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f
-RCC_0100= \u041d\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0433\u043e \u043f\u0430\u043a\u0435\u0442\u0430
-RCC_0101= \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0441\u0432\u043e\u0434\u043d\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043c\u0435\u0442\u0440\u0438\u043a
-RCC_0102= \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u043e\u0448\u0435\u043b \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443
-RCC_0103= \u041e\u0448\u0438\u0431\u043a\u0430 \u0440\u0430\u0437\u0431\u043e\u0440\u0430 XML
-RCC_0104= \u0412\u044b\u0441\u043e\u043a\u0430\u044f \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u0430
-RCC_0105= \u041d\u0430\u0440\u0443\u0448\u0435\u043d\u0438\u0435 \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u0438
-RCC_0106= \u041f\u0440\u0435\u0432\u044b\u0448\u0435\u043d\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439
-RCC_0107= \u041e\u0431\u044a\u0435\u043a\u0442 \u0441 \u0442\u0430\u043a\u0438\u043c \u0438\u043c\u0435\u043d\u0435\u043c \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442
-RCC_0108= \u0421\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441\u043e \u0441\u043b\u0443\u0436\u0431\u043e\u0439 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e
-RCC_0109= \u041e\u0448\u0438\u0431\u043a\u0430 \u0441\u0432\u044f\u0437\u0438 \u043f\u0440\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0438 \u0441\u043e \u0441\u043b\u0443\u0436\u0431\u043e\u0439 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438
-RCC_0110= \u041e\u0442\u043a\u0430\u0437 \u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0435 \u043f\u0440\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0438 \u0441\u043e \u0441\u043b\u0443\u0436\u0431\u043e\u0439 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438
-RCC_0111= \u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0438 \u0441\u043e \u0441\u043b\u0443\u0436\u0431\u043e\u0439 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438
-RCC_0112= \u041d\u0435\u0442 \u0441\u0432\u044f\u0437\u0438 \u0441 LDAP \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c
-RCC_0113= \u0422\u0430\u0431\u043b\u0438\u0446\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430
-RCC_0114= \u0422\u0430\u0431\u043b\u0438\u0446\u0430 MAC \u0430\u0434\u0440\u0435\u0441\u043e\u0432 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430
-RCC_0115= \u0418\u0441\u0442\u043e\u0440\u0438\u044f \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430
-RCC_0116= \u041e\u0431\u044a\u0435\u043a\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0438 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0443\u0434\u0430\u043b\u0435\u043d
-RCC_0117= \u041e\u0448\u0438\u0431\u043a\u0430 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0441\u043a\u0440\u0438\u043f\u0442\u0430 (%s)
-RCC_0118= \u041e\u0448\u0438\u0431\u043a\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u043a\u0440\u0438\u043f\u0442\u0430 (%s)
-RCC_0119= \u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f
-RCC_0120= \u041c\u0435\u0442\u043e\u0434 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f
-RCC_0121=Object name already exists
-RCC_0122=Category is used in event processing policy
-RCC_0123=Category name is empty
-RCC_0124=Unable to download file from agent
-RCC_1001= \u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0444\u0430\u0439\u043b\u0430 MIB
-RCC_1002= \u041d\u0435\u0432\u0435\u0440\u043d\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0444\u0430\u0439\u043b\u0430 MIB
-RCC_UNKNOWN= \u041e\u0448\u0438\u0431\u043a\u0430 %d
+RCC_0092=\u041f\u0440\u0438\u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u043e\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u043e
+RCC_0093=\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0437\u043e\u043d\u044b \u0443\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f
+RCC_0094=\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0437\u043e\u043d\u044b
+RCC_0095=\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u043d\u0435\u043f\u0443\u0441\u0442\u0443\u044e \u0437\u043e\u043d\u0443
+RCC_0096=\u041e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u043e \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435
+RCC_0097=\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0443\u0437\u043b\u0430-\u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u0442\u0440\u0435\u0432\u043e\u0433\u0438
+RCC_0098=\u041e\u0448\u0438\u0431\u043a\u0430 \u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u0438\u044f
+RCC_0099=\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f
+RCC_0100=\u041d\u0435\u0442 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e\u0433\u043e \u043f\u0430\u043a\u0435\u0442\u0430
+RCC_0101=\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0441\u0432\u043e\u0434\u043d\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043c\u0435\u0442\u0440\u0438\u043a
+RCC_0102=\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u043e\u0448\u0435\u043b \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443
+RCC_0103=\u041e\u0448\u0438\u0431\u043a\u0430 \u0440\u0430\u0437\u0431\u043e\u0440\u0430 XML
+RCC_0104=\u0412\u044b\u0441\u043e\u043a\u0430\u044f \u0441\u0442\u043e\u0438\u043c\u043e\u0441\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441\u0430
+RCC_0105=\u041d\u0430\u0440\u0443\u0448\u0435\u043d\u0438\u0435 \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u0438
+RCC_0106=\u041f\u0440\u0435\u0432\u044b\u0448\u0435\u043d\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439
+RCC_0107=\u041e\u0431\u044a\u0435\u043a\u0442 \u0441 \u0442\u0430\u043a\u0438\u043c \u0438\u043c\u0435\u043d\u0435\u043c \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442
+RCC_0108=\u0421\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441\u043e \u0441\u043b\u0443\u0436\u0431\u043e\u0439 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e
+RCC_0109=\u041e\u0448\u0438\u0431\u043a\u0430 \u0441\u0432\u044f\u0437\u0438 \u043f\u0440\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0438 \u0441\u043e \u0441\u043b\u0443\u0436\u0431\u043e\u0439 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438
+RCC_0110=\u041e\u0442\u043a\u0430\u0437 \u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0435 \u043f\u0440\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0438 \u0441\u043e \u0441\u043b\u0443\u0436\u0431\u043e\u0439 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438
+RCC_0111=\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0440\u0438 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0438 \u0441\u043e \u0441\u043b\u0443\u0436\u0431\u043e\u0439 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438
+RCC_0112=\u041d\u0435\u0442 \u0441\u0432\u044f\u0437\u0438 \u0441 LDAP \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c
+RCC_0113=\u0422\u0430\u0431\u043b\u0438\u0446\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430
+RCC_0114=\u0422\u0430\u0431\u043b\u0438\u0446\u0430 MAC \u0430\u0434\u0440\u0435\u0441\u043e\u0432 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430
+RCC_0115=\u0418\u0441\u0442\u043e\u0440\u0438\u044f \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430
+RCC_0116=\u041e\u0431\u044a\u0435\u043a\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0438 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0443\u0434\u0430\u043b\u0435\u043d
+RCC_0117=\u041e\u0448\u0438\u0431\u043a\u0430 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0441\u043a\u0440\u0438\u043f\u0442\u0430 (%s)
+RCC_0118=\u041e\u0448\u0438\u0431\u043a\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u043a\u0440\u0438\u043f\u0442\u0430 (%s)
+RCC_0119=\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f
+RCC_0120=\u041c\u0435\u0442\u043e\u0434 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f
+RCC_0121=\u041e\u0431\u044a\u0435\u043a\u0442 \u0441 \u0442\u0430\u043a\u0438\u043c \u0438\u043c\u0435\u043d\u0435\u043d \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442
+RCC_0122=\u041a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439
+RCC_0123=\u0418\u043c\u044f \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438 \u043f\u0443\u0441\u0442\u043e\u0435
+RCC_0124=\u041d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0444\u0430\u0439\u043b \u0441 \u0430\u0433\u0435\u043d\u0442\u0430 
+RCC_0125=\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0442\u0443\u043d\u043d\u0435\u043b\u044f
+RCC_1001=\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0444\u0430\u0439\u043b\u0430 MIB
+RCC_1002=\u041d\u0435\u0432\u0435\u0440\u043d\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0444\u0430\u0439\u043b\u0430 MIB
+RCC_UNKNOWN=\u041e\u0448\u0438\u0431\u043a\u0430 %d
index a563b91..247a78b 100644 (file)
@@ -119,10 +119,11 @@ RCC_0117=Script compilation error (%s)
 RCC_0118=Script execution error (%s)
 RCC_0119=Unknown configuration variable
 RCC_0120=Authentication method not supported
-RCC_0121=Object name already exists
+RCC_0121=Object with given name already exists
 RCC_0122=Category is used in event processing policy
 RCC_0123=Category name is empty
 RCC_0124=Unable to download file from agent
+RCC_0125=Invalid tunnel ID
 RCC_1001=Bad MIB file header
 RCC_1002=Bad MIB file data
 RCC_UNKNOWN=Error %d
index 4ac68cf..7b75d34 100644 (file)
@@ -98,6 +98,20 @@ NXCPMessage::NXCPMessage(int version)
 }
 
 /**
+ * Create message with given code and ID
+ */
+NXCPMessage::NXCPMessage(UINT16 code, UINT32 id, int version)
+{
+   m_code = code;
+   m_id = id;
+   m_fields = NULL;
+   m_flags = 0;
+   m_version = version;
+   m_data = NULL;
+   m_dataSize = 0;
+}
+
+/**
  * Create a copy of prepared CSCP message
  */
 NXCPMessage::NXCPMessage(NXCPMessage *msg)
index 19edb46..d66b245 100644 (file)
@@ -252,10 +252,10 @@ TCHAR LIBNETXMS_EXPORTABLE *NXCPMessageCodeName(WORD code, TCHAR *pszBuffer)
                _T("CMD_GET_PERSISTENT_STORAGE"),
                _T("CMD_DELETE_PSTORAGE_VALUE"),
                _T("CMD_UPDATE_PSTORAGE_VALUE"),
-               _T("CMD_DEL_SITUATION_INSTANCE"), //Should be changed to new value
-               _T("CMD_UPDATE_SITUATION"), //Should be changed to new value
-               _T("CMD_SITUATION_DATA"), //Should be changed to new value
-               _T("CMD_SITUATION_CHANGE"), //Should be changed to new value
+               _T("CMD_GET_UNBOUND_AGENT_TUNNELS"),
+               _T("CMD_BIND_AGENT_TUNNEL"),
+               _T("CMD_REQUEST_CERTIFICATE"),
+               _T("CMD_NEW_CERTIFICATE"),
                _T("CMD_CREATE_MAP"),
                _T("CMD_UPLOAD_FILE"),
                _T("CMD_DELETE_FILE"),
index bf32c5c..94ccaa3 100644 (file)
 /**
  * Server certificate file information
  */
+TCHAR g_serverCACertificatePath[MAX_PATH] = _T("");
 TCHAR g_serverCertificatePath[MAX_PATH] = _T("");
 char g_serverCertificatePassword[MAX_PASSWORD] = "";
 
 /**
  * Server certificate
  */
+static X509 *s_serverCACertificate = NULL;
 static X509 *s_serverCertificate = NULL;
 static EVP_PKEY *s_serverCertificateKey = NULL;
 
@@ -54,6 +56,160 @@ static X509_STORE *s_trustedCertificateStore = NULL;
 static Mutex s_certificateStoreLock;
 
 /**
+ * Issue certificate signed with server's certificate
+ */
+X509 *IssueCertificate(X509_REQ *request, const char *cn, int days)
+{
+   nxlog_debug(4, _T("IssueCertificate: new certificate request (CN override: %hs)"), (cn != NULL) ? cn : "<not set>");
+
+   X509_NAME *requestSubject = X509_REQ_get_subject_name(request);
+   if (requestSubject == NULL)
+   {
+      nxlog_debug(4, _T("IssueCertificate: cannot get subject from certificate request"));
+      return NULL;
+   }
+
+   X509 *cert = X509_new();
+   if (cert == NULL)
+   {
+      nxlog_debug(4, _T("IssueCertificate: call to X509_new() failed"));
+      return NULL;
+   }
+
+   if (X509_set_version(cert, 2) != 1)
+   {
+      nxlog_debug(4, _T("IssueCertificate: call to X509_set_version() failed"));
+      X509_free(cert);
+      return NULL;
+   }
+
+   ASN1_INTEGER *serial = M_ASN1_INTEGER_new();
+   ASN1_INTEGER_set(serial, 0);
+   int rc = X509_set_serialNumber(cert, serial);
+   M_ASN1_INTEGER_free(serial);
+   if (rc != 1)
+   {
+      nxlog_debug(4, _T("IssueCertificate: cannot set certificate serial number"));
+      X509_free(cert);
+      return NULL;
+   }
+
+   X509_NAME *subject;
+   if (cn != NULL)
+   {
+      subject = X509_NAME_dup(requestSubject);
+      if (subject != NULL)
+      {
+         int idx = X509_NAME_get_index_by_NID(subject, NID_commonName, -1);
+         if (idx != -1)
+         {
+            X509_NAME_ENTRY *entry = X509_NAME_get_entry(subject, idx);
+            if (entry != NULL)
+            {
+               X509_NAME_ENTRY_set_data(entry, MBSTRING_UTF8, (const BYTE *)cn, -1);
+            }
+            else
+            {
+               nxlog_debug(4, _T("IssueCertificate: cannot get CN from certificate subject"));
+            }
+         }
+         else
+         {
+            nxlog_debug(4, _T("IssueCertificate: cannot find CN index in certificate subject"));
+         }
+      }
+      else
+      {
+         nxlog_debug(4, _T("IssueCertificate: call to X509_NAME_dup() failed"));
+      }
+   }
+   else
+   {
+      subject = requestSubject;
+   }
+
+   if (subject == NULL)
+   {
+      X509_free(cert);
+      return NULL;
+   }
+
+   rc = X509_set_subject_name(cert, subject);
+   if (subject != requestSubject)
+      X509_NAME_free(subject);
+   if (rc != 1)
+   {
+      nxlog_debug(4, _T("IssueCertificate: call to X509_set_subject_name() failed"));
+      X509_free(cert);
+      return NULL;
+   }
+
+   X509_NAME *issuerName = X509_get_subject_name(s_serverCertificate);
+   if (issuerName == NULL)
+   {
+      nxlog_debug(4, _T("IssueCertificate: cannot get CA subject name"));
+      X509_free(cert);
+      return NULL;
+   }
+
+   if (X509_set_issuer_name(cert, issuerName) != 1)
+   {
+      nxlog_debug(4, _T("IssueCertificate: call to X509_set_issuer_name() failed"));
+      X509_free(cert);
+      return NULL;
+   }
+
+   EVP_PKEY *pubkey = X509_REQ_get_pubkey(request);
+   if (pubkey == NULL)
+   {
+      nxlog_debug(4, _T("IssueCertificate: call to X509_REQ_get_pubkey() failed"));
+      X509_free(cert);
+      return NULL;
+   }
+
+   if (X509_REQ_verify(request, pubkey) != 1)
+   {
+      nxlog_debug(4, _T("IssueCertificate: certificate request verification failed"));
+      EVP_PKEY_free(pubkey);
+      X509_free(cert);
+      return NULL;
+   }
+
+   rc = X509_set_pubkey(cert, pubkey);
+   EVP_PKEY_free(pubkey);
+   if (rc != 1)
+   {
+      nxlog_debug(4, _T("IssueCertificate: call to X509_set_pubkey() failed"));
+      X509_free(cert);
+      return NULL;
+   }
+
+   if (X509_gmtime_adj(X509_get_notBefore(cert), 0) == NULL)
+   {
+      nxlog_debug(4, _T("IssueCertificate: cannot set start time"));
+      X509_free(cert);
+      return NULL;
+   }
+
+   if (X509_gmtime_adj(X509_get_notAfter(cert), days * 86400) == NULL)
+   {
+      nxlog_debug(4, _T("IssueCertificate: cannot set end time"));
+      X509_free(cert);
+      return NULL;
+   }
+
+   if (X509_sign(cert, s_serverCertificateKey, EVP_sha256()) == 0)
+   {
+      nxlog_debug(4, _T("IssueCertificate: call to X509_sign() failed"));
+      X509_free(cert);
+      return NULL;
+   }
+
+   nxlog_debug(4, _T("IssueCertificate: new certificate issued successfully"));
+   return cert;
+}
+
+/**
  * Get CN from certificate
  */
 bool GetCertificateCN(X509 *cert, TCHAR *buffer, size_t size)
@@ -255,6 +411,7 @@ bool ValidateAgentCertificate(X509 *cert)
       nxlog_debug(3, _T("ValidateAgentCertificate: cannot create certificate store"));
    }
 
+   X509_STORE_add_cert(store, s_serverCACertificate);
    X509_STORE_add_cert(store, s_serverCertificate);
    bool valid = false;
 
@@ -300,6 +457,10 @@ void ReloadCertificates()
           if (s_serverCertificate != NULL)
              X509_STORE_add_cert(s_trustedCertificateStore, s_serverCertificate);
 
+      // Add server's CA certificate as trusted
+          if (s_serverCACertificate != NULL)
+         X509_STORE_add_cert(s_trustedCertificateStore, s_serverCACertificate);
+
                _sntprintf(szBuffer, 256, _T("SELECT cert_data,subject FROM certificates WHERE cert_type=%d"), CERT_TYPE_TRUSTED_CA);
                DB_HANDLE hdb = DBConnectionPoolAcquireConnection();
                hResult = DBSelect(hdb, szBuffer);
@@ -368,13 +529,30 @@ void InitCertificates()
  */
 bool LoadServerCertificate(RSA **serverKey)
 {
-   if (g_serverCertificatePath[0] == 0)
+   if ((g_serverCACertificatePath[0] == 0) || (g_serverCertificatePath[0] == 0))
    {
       nxlog_write(MSG_SERVER_CERT_NOT_SET, NXLOG_INFO, NULL);
       return false;
    }
 
-   FILE *f = _tfopen(g_serverCertificatePath, _T("r"));
+   // Load server CA certificate
+   FILE *f = _tfopen(g_serverCACertificatePath, _T("r"));
+   if (f == NULL)
+   {
+      nxlog_write(MSG_CANNOT_LOAD_SERVER_CERT, NXLOG_ERROR, "ss", g_serverCACertificatePath, _tcserror(errno));
+      return false;
+   }
+   s_serverCACertificate = PEM_read_X509(f, NULL, NULL, NULL);
+   fclose(f);
+   if (s_serverCACertificate == NULL)
+   {
+      TCHAR buffer[1024];
+      nxlog_write(MSG_CANNOT_LOAD_SERVER_CERT, NXLOG_ERROR, "ss", g_serverCACertificatePath, _ERR_error_tstring(ERR_get_error(), buffer));
+      return false;
+   }
+
+   // Load server certificate and private key
+   f = _tfopen(g_serverCertificatePath, _T("r"));
    if (f == NULL)
    {
       nxlog_write(MSG_CANNOT_LOAD_SERVER_CERT, NXLOG_ERROR, "ss", g_serverCertificatePath, _tcserror(errno));
@@ -421,8 +599,20 @@ bool SetupServerTlsContext(SSL_CTX *context)
    if ((s_serverCertificate == NULL) || (s_serverCertificateKey == NULL))
       return false;
 
+   X509_STORE *store = X509_STORE_new();
+   if (store == NULL)
+   {
+      nxlog_debug(3, _T("SetupServerTlsContext: cannot create certificate store"));
+      return false;
+   }
+   X509_STORE_add_cert(store, s_serverCACertificate);
+   X509_STORE_add_cert(store, s_serverCertificate);
+   SSL_CTX_set_cert_store(context, store);
    SSL_CTX_use_certificate(context, s_serverCertificate);
    SSL_CTX_use_PrivateKey(context, s_serverCertificateKey);
+   SSL_CTX_add_client_CA(context, s_serverCertificate);
+   SSL_CTX_set_verify(context, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, NULL);
+   SSL_CTX_set_verify_depth(context, 0);
    return true;
 }
 
index 3b2ca17..e685ee1 100644 (file)
@@ -30,6 +30,7 @@ extern char g_szCodePage[];
 extern TCHAR *g_moduleLoadList;
 extern TCHAR *g_pdsLoadList;
 extern InetAddressList g_peerNodeAddrList;
+extern TCHAR g_serverCACertificatePath[];
 extern TCHAR g_serverCertificatePath[];
 extern char g_serverCertificatePassword[];
 
@@ -86,6 +87,7 @@ static NX_CFG_TEMPLATE m_cfgTemplate[] =
    { _T("PeerNode"), CT_STRING, 0, 0, MAX_DB_STRING, 0, s_peerNode, NULL },
    { _T("PerfDataStorageDriver"), CT_STRING_LIST, '\n', 0, 0, 0, &g_pdsLoadList, NULL },
    { _T("ProcessAffinityMask"), CT_LONG, 0, 0, 0, 0, &g_processAffinityMask, NULL },
+   { _T("ServerCACertificate"), CT_STRING, 0, 0, MAX_PATH, 0, g_serverCACertificatePath, NULL },
    { _T("ServerCertificate"), CT_STRING, 0, 0, MAX_PATH, 0, g_serverCertificatePath, NULL },
    { _T("ServerCertificatePassword"), CT_MB_STRING, 0, 0, MAX_PASSWORD, 0, g_serverCertificatePassword, NULL },
    { _T(""), CT_END_OF_LIST, 0, 0, 0, 0, NULL, NULL }
index 792938d..97b3abd 100644 (file)
@@ -35,6 +35,7 @@ extern ThreadPool *g_schedulerThreadPool;
 
 void ShowPredictionEngines(CONSOLE_CTX console);
 void ShowAgentTunnels(CONSOLE_CTX console);
+UINT32 BindAgentTunnel(UINT32 tunnelId, UINT32 nodeId);
 
 /**
  * Format string to show value of global flag
@@ -1075,6 +1076,32 @@ int ProcessConsoleCommand(const TCHAR *pszCmdLine, CONSOLE_CTX pCtx)
          ConsoleWrite(pCtx, _T("ERROR: Invalid or missing node id(s)\n\n"));
       }
    }
+   else if (IsCommand(_T("TUNNEL"), szBuffer, 2))
+   {
+      pArg = ExtractWord(pArg, szBuffer);
+      if (IsCommand(_T("BIND"), szBuffer, 1))
+      {
+         pArg = ExtractWord(pArg, szBuffer);
+         UINT32 tunnelId = _tcstoul(szBuffer, NULL, 0);
+
+         ExtractWord(pArg, szBuffer);
+         UINT32 nodeId = _tcstoul(szBuffer, NULL, 0);
+
+         if ((tunnelId != 0) && (nodeId != 0))
+         {
+            UINT32 rcc = BindAgentTunnel(tunnelId, nodeId);
+            ConsolePrintf(pCtx, _T("Bind tunnel %d to node %d: RCC = %d\n\n"), tunnelId, nodeId, rcc);
+         }
+         else
+         {
+            ConsoleWrite(pCtx, _T("ERROR: Invalid or missing argument(s)\n\n"));
+         }
+      }
+      else
+      {
+         ConsoleWrite(pCtx, _T("ERROR: Invalid TUNNEL subcommand\n\n"));
+      }
+   }
    else if (IsCommand(_T("HELP"), szBuffer, 2) || IsCommand(_T("?"), szBuffer, 1))
    {
       ConsoleWrite(pCtx,
index ddbdf12..ae7c919 100644 (file)
@@ -1,6 +1,6 @@
 /* 
 ** NetXMS - Network Management System
-** Copyright (C) 2003-2016 Victor Kirhenshtein
+** Copyright (C) 2003-2017 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
index c31b1d8..4d91e80 100644 (file)
@@ -408,7 +408,7 @@ static bool InitCryptografy()
       if (g_pServerKey == NULL)
       {
          nxlog_debug(1, _T("Generating RSA key pair..."));
-         g_pServerKey = RSA_generate_key(NETXMS_RSA_KEYLEN, 17, NULL, 0);
+         g_pServerKey = RSA_generate_key(NETXMS_RSA_KEYLEN, 17, NULL, NULL);
          if (g_pServerKey != NULL)
          {
             int fd = _topen(szKeyFile, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, 0600);
index 9f3ead2..581d7fa 100644 (file)
@@ -71,6 +71,7 @@ NXCPMessage *ForwardMessageToReportingServer(NXCPMessage *request, ClientSession
 void RemovePendingFileTransferRequests(ClientSession *session);
 bool UpdateAddressListFromMessage(NXCPMessage *msg);
 void FillComponentsMessage(NXCPMessage *msg);
+void GetUnboundAgentTunnels(NXCPMessage *msg);
 void GetPredictionEngines(NXCPMessage *msg);
 bool GetPredictedData(ClientSession *session, const NXCPMessage *request, NXCPMessage *response, DataCollectionTarget *dcTarget);
 
@@ -1457,6 +1458,12 @@ void ClientSession::processingThread()
          case CMD_DELETE_REPOSITORY:
             CALL_IN_NEW_THREAD(deleteRepository, pMsg);
             break;
+         case CMD_GET_UNBOUND_AGENT_TUNNELS:
+            getUnboundAgentTunnels(pMsg);
+            break;
+         case CMD_BIND_AGENT_TUNNEL:
+            bindAgentTunnel(pMsg);
+            break;
          case CMD_GET_PREDICTION_ENGINES:
             getPredictionEngines(pMsg);
             break;
@@ -13074,11 +13081,7 @@ void ClientSession::deleteMappingTable(NXCPMessage *request)
  */
 void ClientSession::getWirelessStations(NXCPMessage *request)
 {
-   NXCPMessage msg;
-
-   // Prepare response message
-   msg.setCode(CMD_REQUEST_COMPLETED);
-   msg.setId(request->getId());
+   NXCPMessage msg(CMD_REQUEST_COMPLETED, request->getId());
 
    // Get object id and check object class and access rights
        Node *node = (Node *)FindObjectById(request->getFieldAsUInt32(VID_OBJECT_ID), OBJECT_NODE);
@@ -13115,11 +13118,7 @@ void ClientSession::getWirelessStations(NXCPMessage *request)
  */
 void ClientSession::getSummaryTables(UINT32 rqId)
 {
-   NXCPMessage msg;
-
-   // Prepare response message
-   msg.setCode(CMD_REQUEST_COMPLETED);
-   msg.setId(rqId);
+   NXCPMessage msg(CMD_REQUEST_COMPLETED, rqId);
 
    DB_HANDLE hdb = DBConnectionPoolAcquireConnection();
    DB_RESULT hResult = DBSelect(hdb, _T("SELECT id,menu_path,title,flags,guid FROM dci_summary_tables"));
@@ -13158,11 +13157,7 @@ void ClientSession::getSummaryTables(UINT32 rqId)
  */
 void ClientSession::getSummaryTableDetails(NXCPMessage *request)
 {
-   NXCPMessage msg;
-
-   // Prepare response message
-   msg.setCode(CMD_REQUEST_COMPLETED);
-   msg.setId(request->getId());
+   NXCPMessage msg(CMD_REQUEST_COMPLETED, request->getId());
 
        if (m_dwSystemAccess & SYSTEM_ACCESS_MANAGE_SUMMARY_TBLS)
        {
@@ -13229,11 +13224,7 @@ void ClientSession::getSummaryTableDetails(NXCPMessage *request)
  */
 void ClientSession::modifySummaryTable(NXCPMessage *request)
 {
-   NXCPMessage msg;
-
-   // Prepare response message
-   msg.setCode(CMD_REQUEST_COMPLETED);
-   msg.setId(request->getId());
+   NXCPMessage msg(CMD_REQUEST_COMPLETED, request->getId());
 
        if (m_dwSystemAccess & SYSTEM_ACCESS_MANAGE_SUMMARY_TBLS)
        {
@@ -13255,11 +13246,7 @@ void ClientSession::modifySummaryTable(NXCPMessage *request)
  */
 void ClientSession::deleteSummaryTable(NXCPMessage *request)
 {
-   NXCPMessage msg;
-
-   // Prepare response message
-   msg.setCode(CMD_REQUEST_COMPLETED);
-   msg.setId(request->getId());
+   NXCPMessage msg(CMD_REQUEST_COMPLETED, request->getId());
 
        if (m_dwSystemAccess & SYSTEM_ACCESS_MANAGE_SUMMARY_TBLS)
        {
@@ -13310,11 +13297,7 @@ void ClientSession::querySummaryTable(NXCPMessage *request)
  */
 void ClientSession::queryAdHocSummaryTable(NXCPMessage *request)
 {
-   NXCPMessage msg;
-
-   // Prepare response message
-   msg.setCode(CMD_REQUEST_COMPLETED);
-   msg.setId(request->getId());
+   NXCPMessage msg(CMD_REQUEST_COMPLETED, request->getId());
 
    SummaryTable *tableDefinition = new SummaryTable(request);
 
@@ -13378,11 +13361,7 @@ void ClientSession::forwardToReportingServer(NXCPMessage *request)
  */
 void ClientSession::getSubnetAddressMap(NXCPMessage *request)
 {
-   NXCPMessage msg;
-
-   // Prepare response message
-   msg.setCode(CMD_REQUEST_COMPLETED);
-   msg.setId(request->getId());
+   NXCPMessage msg(CMD_REQUEST_COMPLETED, request->getId());
 
    // Get node id and check object class and access rights
    Subnet *subnet = (Subnet *)FindObjectById(request->getFieldAsUInt32(VID_OBJECT_ID), OBJECT_SUBNET);
@@ -13422,11 +13401,7 @@ void ClientSession::getSubnetAddressMap(NXCPMessage *request)
  */
 void ClientSession::getEffectiveRights(NXCPMessage *request)
 {
-   NXCPMessage msg;
-
-   // Prepare response message
-   msg.setCode(CMD_REQUEST_COMPLETED);
-   msg.setId(request->getId());
+   NXCPMessage msg(CMD_REQUEST_COMPLETED, request->getId());
 
    // Get node id and check object class and access rights
    NetObj *object = FindObjectById(request->getFieldAsUInt32(VID_OBJECT_ID));
@@ -13734,11 +13709,7 @@ void ClientSession::uploadUserFileToAgent(NXCPMessage *request)
  */
 void ClientSession::getSwitchForwardingDatabase(NXCPMessage *request)
 {
-   NXCPMessage msg;
-
-   // Prepare response message
-   msg.setCode(CMD_REQUEST_COMPLETED);
-   msg.setId(request->getId());
+   NXCPMessage msg(CMD_REQUEST_COMPLETED, request->getId());
 
    // Get node id and check object class and access rights
    Node *node = (Node *)FindObjectById(request->getFieldAsUInt32(VID_OBJECT_ID), OBJECT_NODE);
@@ -13778,11 +13749,7 @@ void ClientSession::getSwitchForwardingDatabase(NXCPMessage *request)
  */
 void ClientSession::getRoutingTable(NXCPMessage *request)
 {
-   NXCPMessage msg;
-
-   // Prepare response message
-   msg.setCode(CMD_REQUEST_COMPLETED);
-   msg.setId(request->getId());
+   NXCPMessage msg(CMD_REQUEST_COMPLETED, request->getId());
 
    // Get node id and check object class and access rights
    Node *node = (Node *)FindObjectById(request->getFieldAsUInt32(VID_OBJECT_ID), OBJECT_NODE);
@@ -13843,11 +13810,7 @@ void ClientSession::getRoutingTable(NXCPMessage *request)
  */
 void ClientSession::getLocationHistory(NXCPMessage *request)
 {
-   NXCPMessage msg;
-
-   // Prepare response message
-   msg.setCode(CMD_REQUEST_COMPLETED);
-   msg.setId(request->getId());
+   NXCPMessage msg(CMD_REQUEST_COMPLETED, request->getId());
 
    // Get node id and check object class and access rights
    Node *node = (Node *)FindObjectById(request->getFieldAsUInt32(VID_OBJECT_ID), OBJECT_MOBILEDEVICE);
@@ -13913,10 +13876,7 @@ void ClientSession::getLocationHistory(NXCPMessage *request)
  */
 void ClientSession::getScreenshot(NXCPMessage *request)
 {
-   NXCPMessage msg;
-
-   msg.setCode(CMD_REQUEST_COMPLETED);
-   msg.setId(request->getId());
+   NXCPMessage msg(CMD_REQUEST_COMPLETED, request->getId());
 
    TCHAR* sessionName = request->getFieldAsString(VID_NAME);
    if(sessionName == NULL)
@@ -13979,11 +13939,7 @@ void ClientSession::getScreenshot(NXCPMessage *request)
  */
 void ClientSession::compileScript(NXCPMessage *request)
 {
-   NXCPMessage msg;
-
-   // Prepare response message
-   msg.setCode(CMD_REQUEST_COMPLETED);
-   msg.setId(request->getId());
+   NXCPMessage msg(CMD_REQUEST_COMPLETED, request->getId());
 
        TCHAR *source = request->getFieldAsString(VID_SCRIPT);
        if (source != NULL)
@@ -14027,9 +13983,7 @@ void ClientSession::compileScript(NXCPMessage *request)
  */
 void ClientSession::cleanAgentDciConfiguration(NXCPMessage *request)
 {
-   NXCPMessage msg;
-   msg.setCode(CMD_REQUEST_COMPLETED);
-   msg.setId(request->getId());
+   NXCPMessage msg(CMD_REQUEST_COMPLETED, request->getId());
 
    UINT32 objectId = request->getFieldAsUInt32(VID_NODE_ID);
        NetObj *object = FindObjectById(objectId);
@@ -14078,9 +14032,7 @@ void ClientSession::cleanAgentDciConfiguration(NXCPMessage *request)
  */
 void ClientSession::resyncAgentDciConfiguration(NXCPMessage *request)
 {
-   NXCPMessage msg;
-   msg.setCode(CMD_REQUEST_COMPLETED);
-   msg.setId(request->getId());
+   NXCPMessage msg(CMD_REQUEST_COMPLETED, request->getId());
 
    UINT32 objectId = request->getFieldAsUInt32(VID_NODE_ID);
        NetObj *object = FindObjectById(objectId);
@@ -14118,9 +14070,7 @@ void ClientSession::resyncAgentDciConfiguration(NXCPMessage *request)
  */
 void ClientSession::getSchedulerTaskHandlers(NXCPMessage *request)
 {
-   NXCPMessage msg;
-   msg.setCode(CMD_REQUEST_COMPLETED);
-   msg.setId(request->getId());
+   NXCPMessage msg(CMD_REQUEST_COMPLETED, request->getId());
    GetSchedulerTaskHandlers(&msg, m_dwSystemAccess);
    msg.setField(VID_RCC, RCC_SUCCESS);
    sendMessage(&msg);
@@ -14131,9 +14081,7 @@ void ClientSession::getSchedulerTaskHandlers(NXCPMessage *request)
  */
 void ClientSession::getScheduledTasks(NXCPMessage *request)
 {
-   NXCPMessage msg;
-   msg.setCode(CMD_REQUEST_COMPLETED);
-   msg.setId(request->getId());
+   NXCPMessage msg(CMD_REQUEST_COMPLETED, request->getId());
    GetScheduledTasks(&msg, m_dwUserId, m_dwSystemAccess);
    msg.setField(VID_RCC, RCC_SUCCESS);
    sendMessage(&msg);
@@ -14144,9 +14092,7 @@ void ClientSession::getScheduledTasks(NXCPMessage *request)
  */
 void ClientSession::addScheduledTask(NXCPMessage *request)
 {
-   NXCPMessage msg;
-   msg.setCode(CMD_REQUEST_COMPLETED);
-   msg.setId(request->getId());
+   NXCPMessage msg(CMD_REQUEST_COMPLETED, request->getId());
    UINT32 result = CreateScehduledTaskFromMsg(request, m_dwUserId, m_dwSystemAccess);
    msg.setField(VID_RCC, result);
    sendMessage(&msg);
@@ -14157,9 +14103,7 @@ void ClientSession::addScheduledTask(NXCPMessage *request)
  */
 void ClientSession::updateScheduledTask(NXCPMessage *request)
 {
-   NXCPMessage msg;
-   msg.setCode(CMD_REQUEST_COMPLETED);
-   msg.setId(request->getId());
+   NXCPMessage msg(CMD_REQUEST_COMPLETED, request->getId());
    UINT32 result = UpdateScheduledTaskFromMsg(request, m_dwUserId, m_dwSystemAccess);
    msg.setField(VID_RCC, result);
    sendMessage(&msg);
@@ -14170,9 +14114,7 @@ void ClientSession::updateScheduledTask(NXCPMessage *request)
  */
 void ClientSession::removeScheduledTask(NXCPMessage *request)
 {
-   NXCPMessage msg;
-   msg.setCode(CMD_REQUEST_COMPLETED);
-   msg.setId(request->getId());
+   NXCPMessage msg(CMD_REQUEST_COMPLETED, request->getId());
    UINT32 result = RemoveScheduledTask(request->getFieldAsUInt32(VID_SCHEDULED_TASK_ID), m_dwUserId, m_dwSystemAccess);
    msg.setField(VID_RCC, result);
    sendMessage(&msg);
@@ -14183,9 +14125,7 @@ void ClientSession::removeScheduledTask(NXCPMessage *request)
  */
 void ClientSession::getPredictionEngines(NXCPMessage *request)
 {
-   NXCPMessage msg;
-   msg.setCode(CMD_REQUEST_COMPLETED);
-   msg.setId(request->getId());
+   NXCPMessage msg(CMD_REQUEST_COMPLETED, request->getId());
    GetPredictionEngines(&msg);
    msg.setField(VID_RCC, RCC_SUCCESS);
    sendMessage(&msg);
@@ -14196,13 +14136,9 @@ void ClientSession::getPredictionEngines(NXCPMessage *request)
  */
 void ClientSession::getPredictedData(NXCPMessage *request)
 {
-   NXCPMessage msg;
+   NXCPMessage msg(CMD_REQUEST_COMPLETED, request->getId());
    bool success = false;
 
-   // Prepare response message
-   msg.setCode(CMD_REQUEST_COMPLETED);
-   msg.setId(request->getId());
-
    NetObj *object = FindObjectById(request->getFieldAsUInt32(VID_OBJECT_ID));
    if (object != NULL)
    {
@@ -14239,15 +14175,43 @@ void ClientSession::getPredictedData(NXCPMessage *request)
       sendMessage(&msg);
 }
 
+/**
+ * Get list of unbound agent tunnels
+ */
+void ClientSession::getUnboundAgentTunnels(NXCPMessage *request)
+{
+   NXCPMessage msg(CMD_REQUEST_COMPLETED, request->getId());
+   if (m_dwSystemAccess & SYSTEM_ACCESS_REGISTER_AGENTS)
+   {
+      GetUnboundAgentTunnels(&msg);
+      msg.setField(VID_RCC, RCC_SUCCESS);
+      writeAuditLog(AUDIT_SYSCFG, true, 0, _T("Read list of unbound agent tunnels"));
+   }
+   else
+   {
+      msg.setField(VID_RCC, RCC_ACCESS_DENIED);
+      writeAuditLog(AUDIT_SYSCFG, false, 0, _T("Access denied on reading list of unbound agent tunnels"));
+   }
+   sendMessage(&msg);
+}
+
+/**
+ * Bind agent tunnel to node
+ */
+void ClientSession::bindAgentTunnel(NXCPMessage *request)
+{
+   NXCPMessage msg(CMD_REQUEST_COMPLETED, request->getId());
+
+   sendMessage(&msg);
+}
+
 #ifdef WITH_ZMQ
 /**
  * Manage subscription for ZMQ forwarder
  */
 void ClientSession::zmqManageSubscription(NXCPMessage *request, zmq::SubscriptionType type, bool subscribe)
 {
-   NXCPMessage msg;
-   msg.setCode(CMD_REQUEST_COMPLETED);
-   msg.setId(request->getId());
+   NXCPMessage msg(CMD_REQUEST_COMPLETED, request->getId());
 
    UINT32 objectId = request->getFieldAsUInt32(VID_OBJECT_ID);
    NetObj *object = FindObjectById(objectId);
@@ -14297,14 +14261,9 @@ void ClientSession::zmqManageSubscription(NXCPMessage *request, zmq::Subscriptio
 
 void ClientSession::zmqListSubscriptions(NXCPMessage *request, zmq::SubscriptionType type)
 {
-   NXCPMessage msg;
-   msg.setCode(CMD_REQUEST_COMPLETED);
-   msg.setId(request->getId());
-
+   NXCPMessage msg(CMD_REQUEST_COMPLETED, request->getId());
    ZmqFillSubscriptionListMessage(&msg, type);
-
    msg.setField(VID_RCC, RCC_SUCCESS);
-
    sendMessage(&msg);
 }
 
index 922cb13..4f19a76 100644 (file)
@@ -85,6 +85,51 @@ static void UnregisterTunnel(AgentTunnel *tunnel)
 }
 
 /**
+ * Bind agent tunnel
+ */
+UINT32 BindAgentTunnel(UINT32 tunnelId, UINT32 nodeId)
+{
+   AgentTunnel *tunnel = NULL;
+   s_tunnelListLock.lock();
+   for(int i = 0; i < s_unboundTunnels.size(); i++)
+   {
+      if (s_unboundTunnels.get(i)->getId() == tunnelId)
+      {
+         tunnel = s_unboundTunnels.get(i);
+         tunnel->incRefCount();
+         break;
+      }
+   }
+   s_tunnelListLock.unlock();
+
+   if (tunnel == NULL)
+   {
+      nxlog_debug(4, _T("BindAgentTunnel: unbound tunnel with ID %d not found"), tunnelId);
+      return RCC_INVALID_TUNNEL_ID;
+   }
+
+   UINT32 rcc = tunnel->bind(nodeId);
+   tunnel->decRefCount();
+   return rcc;
+}
+
+/**
+ * Get list of unbound agent tunnels into NXCP message
+ */
+void GetUnboundAgentTunnels(NXCPMessage *msg)
+{
+   s_tunnelListLock.lock();
+   UINT32 fieldId = VID_ELEMENT_LIST_BASE;
+   for(int i = 0; i < s_unboundTunnels.size(); i++)
+   {
+      s_unboundTunnels.get(i)->fillMessage(msg, fieldId);
+      fieldId += 10;
+   }
+   msg->setField(VID_NUM_ELEMENTS, (UINT32)s_unboundTunnels.size());
+   s_tunnelListLock.unlock();
+}
+
+/**
  * Show tunnels in console
  */
 void ShowAgentTunnels(CONSOLE_CTX console)
@@ -135,12 +180,14 @@ AgentTunnel::AgentTunnel(SSL_CTX *context, SSL *ssl, SOCKET sock, const InetAddr
    m_ssl = ssl;
    m_sslLock = MutexCreate();
    m_recvThread = INVALID_THREAD_HANDLE;
+   m_requestId = 0;
    m_nodeId = nodeId;
    m_state = AGENT_TUNNEL_INIT;
    m_systemName = NULL;
    m_platformName = NULL;
    m_systemInfo = NULL;
    m_agentVersion = NULL;
+   m_bindRequestId = 0;
 }
 
 /**
@@ -204,16 +251,19 @@ void AgentTunnel::recvThread()
       {
          case CMD_KEEPALIVE:
             {
-               NXCPMessage response;
-               response.setCode(CMD_KEEPALIVE);
-               response.setId(msg->getId());
+               NXCPMessage response(CMD_KEEPALIVE, msg->getId());
                sendMessage(&response);
             }
             break;
          case CMD_SETUP_AGENT_TUNNEL:
             setup(msg);
             break;
+         case CMD_REQUEST_CERTIFICATE:
+            processCertificateRequest(msg);
+            break;
          default:
+            m_queue.put(msg);
+            msg = NULL; // prevent message deletion
             break;
       }
       delete msg;
@@ -293,6 +343,115 @@ void AgentTunnel::setup(const NXCPMessage *request)
 }
 
 /**
+ * Bind tunnel to node
+ */
+UINT32 AgentTunnel::bind(UINT32 nodeId)
+{
+   if ((m_state != AGENT_TUNNEL_UNBOUND) || (m_bindRequestId != 0))
+      return RCC_OUT_OF_STATE_REQUEST;
+
+   Node *node = (Node *)FindObjectById(nodeId, OBJECT_NODE);
+   if (node == NULL)
+      return RCC_INVALID_OBJECT_ID;
+
+   NXCPMessage msg;
+   msg.setCode(CMD_BIND_AGENT_TUNNEL);
+   msg.setId(InterlockedIncrement(&m_requestId));
+   msg.setField(VID_SERVER_ID, g_serverId);
+   msg.setField(VID_GUID, node->getGuid());
+
+   m_bindRequestId = msg.getId();
+   m_bindGuid = node->getGuid();
+   sendMessage(&msg);
+
+   NXCPMessage *response = waitForMessage(CMD_REQUEST_COMPLETED, msg.getId());
+   if (response == NULL)
+      return RCC_TIMEOUT;
+
+   UINT32 rcc = response->getFieldAsUInt32(VID_RCC);
+   delete response;
+   if (rcc != ERR_SUCCESS)
+      debugPrintf(4, _T("Bind failed: agent error %d (%s)"), rcc, AgentErrorCodeToText(rcc));
+   return AgentErrorToRCC(rcc);
+}
+
+/**
+ * Process certificate request
+ */
+void AgentTunnel::processCertificateRequest(NXCPMessage *request)
+{
+   NXCPMessage response(CMD_NEW_CERTIFICATE, request->getId());
+
+   if ((request->getId() == m_bindRequestId) && (m_bindRequestId != 0) && (m_state == AGENT_TUNNEL_UNBOUND))
+   {
+      size_t certRequestLen;
+      const BYTE *certRequestData = request->getBinaryFieldPtr(VID_CERTIFICATE, &certRequestLen);
+      if (certRequestData != NULL)
+      {
+         X509_REQ *certRequest = d2i_X509_REQ(NULL, &certRequestData, certRequestLen);
+         if (certRequest != NULL)
+         {
+            char *cn = m_bindGuid.toString().getUTF8String();
+            X509 *cert = IssueCertificate(certRequest, cn, 365);
+            free(cn);
+            if (cert != NULL)
+            {
+               BYTE *buffer = NULL;
+               int len = i2d_X509(cert, &buffer);
+               if (len > 0)
+               {
+                  response.setField(VID_RCC, ERR_SUCCESS);
+                  response.setField(VID_CERTIFICATE, buffer, len);
+                  OPENSSL_free(buffer);
+                  debugPrintf(4, _T("Certificate issued"));
+               }
+               else
+               {
+                  debugPrintf(4, _T("Cannot encode certificate"));
+                  response.setField(VID_RCC, ERR_ENCRYPTION_ERROR);
+               }
+               X509_free(cert);
+            }
+            else
+            {
+               debugPrintf(4, _T("Cannot issue certificate"));
+               response.setField(VID_RCC, ERR_ENCRYPTION_ERROR);
+            }
+         }
+         else
+         {
+            debugPrintf(4, _T("Cannot decode certificate request data"));
+            response.setField(VID_RCC, ERR_BAD_ARGUMENTS);
+         }
+      }
+      else
+      {
+         debugPrintf(4, _T("Missing certificate request data"));
+         response.setField(VID_RCC, ERR_BAD_ARGUMENTS);
+      }
+   }
+   else
+   {
+      response.setField(VID_RCC, ERR_OUT_OF_STATE_REQUEST);
+   }
+
+   sendMessage(&response);
+}
+
+/**
+ * Fill NXCP message with tunnel data
+ */
+void AgentTunnel::fillMessage(NXCPMessage *msg, UINT32 baseId) const
+{
+   msg->setField(baseId, m_id);
+   msg->setField(baseId + 1, m_nodeId);
+   msg->setField(baseId + 2, m_systemName);
+   msg->setField(baseId + 3, m_systemInfo);
+   msg->setField(baseId + 4, m_platformName);
+   msg->setField(baseId + 5, m_agentVersion);
+}
+
+/**
  * Incoming connection data
  */
 struct ConnectionRequest
index 04d4770..c177f7b 100644 (file)
@@ -49,18 +49,27 @@ protected:
    SSL *m_ssl;
    MUTEX m_sslLock;
    THREAD m_recvThread;
+   MsgWaitQueue m_queue;
+   VolatileCounter m_requestId;
    UINT32 m_nodeId;
    AgentTunnelState m_state;
    TCHAR *m_systemName;
    TCHAR *m_platformName;
    TCHAR *m_systemInfo;
    TCHAR *m_agentVersion;
+   UINT32 m_bindRequestId;
+   uuid m_bindGuid;
    
    void debugPrintf(int level, const TCHAR *format, ...);
    
    void recvThread();
    static THREAD_RESULT THREAD_CALL recvThreadStarter(void *arg);
    
+   bool sendMessage(NXCPMessage *msg);
+   NXCPMessage *waitForMessage(UINT16 code, UINT32 id) { return m_queue.waitForMessage(code, id, 5000); }
+
+   void processCertificateRequest(NXCPMessage *request);
+
    void setup(const NXCPMessage *request);
 
 public:
@@ -68,7 +77,7 @@ public:
    virtual ~AgentTunnel();
    
    void start();
-   bool sendMessage(NXCPMessage *msg);
+   UINT32 bind(UINT32 nodeId);
 
    UINT32 getId() const { return m_id; }
    const InetAddress& getAddress() const { return m_address; }
@@ -78,6 +87,8 @@ public:
    const TCHAR *getAgentVersion() const { return m_agentVersion; }
    bool isBound() const { return m_nodeId != 0; }
    UINT32 getNodeId() const { return m_nodeId; }
+
+   void fillMessage(NXCPMessage *msg, UINT32 baseId) const;
 };
 
 /**
index 66bc100..d18cbf9 100644 (file)
@@ -757,6 +757,8 @@ private:
    void addRepository(NXCPMessage *request);
    void modifyRepository(NXCPMessage *request);
    void deleteRepository(NXCPMessage *request);
+   void getUnboundAgentTunnels(NXCPMessage *request);
+   void bindAgentTunnel(NXCPMessage *request);
    void getPredictionEngines(NXCPMessage *request);
    void getPredictedData(NXCPMessage *request);
 #ifdef WITH_ZMQ
@@ -1163,6 +1165,7 @@ BOOL ValidateUserCertificate(X509 *pCert, const TCHAR *pszLogin, BYTE *pChalleng
 bool ValidateAgentCertificate(X509 *cert);
 void ReloadCertificates();
 bool GetCertificateCN(X509 *cert, TCHAR *buffer, size_t size);
+X509 *IssueCertificate(X509_REQ *request, const char *cn, int days);
 #endif
 
 #ifndef _WIN32
index e94344b..c7d6160 100644 (file)
@@ -71,6 +71,8 @@ static struct
    { ERR_NO_SESSION_AGENT, _T("Session agent not available") },
    { ERR_SERVER_ID_UNSET, _T("Server ID is not set") },
    { ERR_NO_SUCH_INSTANCE, _T("No such instance") },
+   { ERR_OUT_OF_STATE_REQUEST, _T("Request is out of state") },
+   { ERR_ENCRYPTION_ERROR, _T("Encryption error") },
    { -1, NULL }
 };
 
@@ -94,6 +96,8 @@ UINT32 LIBNXSRV_EXPORTABLE AgentErrorToRCC(UINT32 err)
 {
    switch(err)
    {
+      case ERR_SUCCESS:
+         return RCC_SUCCESS;
       case ERR_ACCESS_DENIED:
          return RCC_ACCESS_DENIED;
       case ERR_IO_FAILURE:
@@ -106,6 +110,10 @@ UINT32 LIBNXSRV_EXPORTABLE AgentErrorToRCC(UINT32 err)
          return RCC_NO_SUCH_INSTANCE;
       case ERR_REQUEST_TIMEOUT:
          return RCC_TIMEOUT;
+      case ERR_ENCRYPTION_ERROR:
+         return RCC_ENCRYPTION_ERROR;
+      case ERR_OUT_OF_STATE_REQUEST:
+         return RCC_OUT_OF_STATE_REQUEST;
    }
    return RCC_AGENT_ERROR;
 }