fixed time frame problem in SNMPv3 communications
authorVictor Kirhenshtein <victor@netxms.org>
Sat, 29 Nov 2014 20:30:41 +0000 (22:30 +0200)
committerVictor Kirhenshtein <victor@netxms.org>
Sat, 29 Nov 2014 20:30:41 +0000 (22:30 +0200)
include/nxsnmp.h
src/server/core/node.cpp
src/snmp/libnxsnmp/ber.cpp
src/snmp/libnxsnmp/engine.cpp
src/snmp/libnxsnmp/libnxsnmp.h
src/snmp/libnxsnmp/pdu.cpp
src/snmp/libnxsnmp/security.cpp
src/snmp/libnxsnmp/transport.cpp

index 912dd64..c98bc72 100644 (file)
@@ -432,13 +432,13 @@ private:
 public:
        SNMP_Engine();
        SNMP_Engine(BYTE *id, size_t idLen, int engineBoots = 0, int engineTime = 0);
-       SNMP_Engine(SNMP_Engine *src);
+       SNMP_Engine(const SNMP_Engine *src);
        ~SNMP_Engine();
 
-       BYTE *getId() { return m_id; }
-       size_t getIdLen() { return m_idLen; }
-       int getBoots() { return m_engineBoots; }
-       int getTime() { return m_engineTime; }
+       const BYTE *getId() const { return m_id; }
+       size_t getIdLen() const { return m_idLen; }
+       int getBoots() const { return m_engineBoots; }
+       int getTime() const { return m_engineTime; }
 
        void setBoots(int boots) { m_engineBoots = boots; }
        void setTime(int engineTime) { m_engineTime = engineTime; }
@@ -503,8 +503,8 @@ public:
        void setContextNameA(const char *name) { setContextName(name); }
 #endif
 
-       void setAuthoritativeEngine(SNMP_Engine &engine);
-       SNMP_Engine& getAuthoritativeEngine() { return m_authoritativeEngine; }
+       void setAuthoritativeEngine(const SNMP_Engine &engine);
+       const SNMP_Engine& getAuthoritativeEngine() { return m_authoritativeEngine; }
 };
 
 /**
@@ -589,7 +589,7 @@ public:
    UINT32 getRequestId() { return m_dwRqId; }
    void setRequestId(UINT32 dwId) { m_dwRqId = dwId; }
 
-       void setContextEngineId(BYTE *id, size_t len);
+       void setContextEngineId(const BYTE *id, size_t len);
        void setContextEngineId(const char *id);
        void setContextName(const char *name);
        const char *getContextName() { return m_contextName; }
@@ -638,6 +638,7 @@ public:
        void setSecurityContext(SNMP_SecurityContext *ctx);
        SNMP_SecurityContext *getSecurityContext() { return m_securityContext; }
        const char *getCommunityString() { return (m_securityContext != NULL) ? m_securityContext->getCommunity() : ""; }
+   const SNMP_Engine *getAuthoritativeEngine() { return m_authoritativeEngine; }
 
        void enableEngineIdAutoupdate(bool enabled) { m_enableEngineIdAutoupdate = enabled; }
        bool isEngineIdAutoupdateEnabled() { return m_enableEngineIdAutoupdate; }
index 76ec954..80408d7 100644 (file)
@@ -1138,6 +1138,14 @@ restart_agent_check:
                PostEventEx(pQueue, EVENT_SNMP_OK, m_id, NULL);
                sendPollerMsg(dwRqId, POLLER_INFO _T("Connectivity with SNMP agent restored\r\n"));
             }
+
+            // Update authoritative engine data for SNMPv3
+            if ((pTransport->getSnmpVersion() == SNMP_VERSION_3) && (pTransport->getAuthoritativeEngine() != NULL))
+            {
+                       lockProperties();
+               m_snmpSecurity->setAuthoritativeEngine(*pTransport->getAuthoritativeEngine());
+               unlockProperties();
+            }
          }
          else
          {
index 0724a9e..86274eb 100644 (file)
@@ -197,7 +197,7 @@ bool BER_DecodeContent(UINT32 type, BYTE *data, size_t length, BYTE *buffer)
 /**
  * Encode content
  */
-static size_t EncodeContent(UINT32 type, BYTE *data, size_t dataLength, BYTE *pResult)
+static size_t EncodeContent(UINT32 type, const BYTE *data, size_t dataLength, BYTE *pResult)
 {
    size_t nBytes = 0;
    UINT32 dwTemp;
@@ -320,7 +320,7 @@ static size_t EncodeContent(UINT32 type, BYTE *data, size_t dataLength, BYTE *pR
  * Return value is size of encoded identifier and content in buffer
  * or 0 if there are not enough place in buffer or type is unknown
  */
-size_t BER_Encode(UINT32 type, BYTE *data, size_t dataLength, BYTE *buffer, size_t bufferSize)
+size_t BER_Encode(UINT32 type, const BYTE *data, size_t dataLength, BYTE *buffer, size_t bufferSize)
 {
    size_t bytes = 0;
    BYTE *pbCurrPos = buffer, *pEncodedData;
index 95e2ee0..4450eb4 100644 (file)
@@ -43,7 +43,7 @@ SNMP_Engine::SNMP_Engine(BYTE *id, size_t idLen, int engineBoots, int engineTime
        m_engineTime = engineTime;
 }
 
-SNMP_Engine::SNMP_Engine(SNMP_Engine *src)
+SNMP_Engine::SNMP_Engine(const SNMP_Engine *src)
 {
        m_idLen = src->m_idLen;
        memcpy(m_id, src->m_id, m_idLen);
index 19a85f4..a406741 100644 (file)
@@ -121,6 +121,6 @@ public:
  */
 bool BER_DecodeIdentifier(BYTE *rawData, size_t rawSize, UINT32 *type, size_t *length, BYTE **data, size_t *idLength);
 bool BER_DecodeContent(UINT32 type, BYTE *data, size_t length, BYTE *buffer);
-size_t BER_Encode(UINT32 type, BYTE *data, size_t dataLength, BYTE *buffer, size_t bufferSize);
+size_t BER_Encode(UINT32 type, const BYTE *data, size_t dataLength, BYTE *buffer, size_t bufferSize);
 
 #endif   /* _libnxsnmp_h_ */
index 206b5b1..4888190 100644 (file)
@@ -1016,8 +1016,7 @@ size_t SNMP_PDU::encode(BYTE **ppBuffer, SNMP_SecurityContext *securityContext)
       // Encode varbinds into PDU
                if ((m_version != SNMP_VERSION_3) || ((securityContext != NULL) && (securityContext->getAuthoritativeEngine().getIdLen() != 0)))
                {
-                       dwBytes = BER_Encode(ASN_SEQUENCE, pVarBinds, dwVarBindsSize, 
-                                                                               pbCurrPos, dwBufferSize - dwPDUSize);
+                       dwBytes = BER_Encode(ASN_SEQUENCE, pVarBinds, dwVarBindsSize, pbCurrPos, dwBufferSize - dwPDUSize);
                }
                else
                {
@@ -1365,7 +1364,7 @@ void SNMP_PDU::bindVariable(SNMP_Variable *pVar)
 /**
  * Set context engine ID
  */
-void SNMP_PDU::setContextEngineId(BYTE *id, size_t len)
+void SNMP_PDU::setContextEngineId(const BYTE *id, size_t len)
 {
        m_contextEngineIdLen = min(len, SNMP_MAX_ENGINEID_LEN);
        memcpy(m_contextEngineId, id, m_contextEngineIdLen);
index 4bd3993..293c92f 100644 (file)
@@ -182,7 +182,7 @@ void SNMP_SecurityContext::setPrivPassword(const char *password)
 /**
  * Set authoritative engine ID
  */
-void SNMP_SecurityContext::setAuthoritativeEngine(SNMP_Engine &engine)
+void SNMP_SecurityContext::setAuthoritativeEngine(const SNMP_Engine &engine)
 {
        m_authoritativeEngine = engine;
        recalculateKeys();
index 993edf7..4f3d830 100644 (file)
@@ -73,6 +73,8 @@ void SNMP_Transport::setSecurityContext(SNMP_SecurityContext *ctx)
 {
        delete m_securityContext;
        m_securityContext = ctx;
+   delete m_authoritativeEngine;
+   m_authoritativeEngine = (m_securityContext->getAuthoritativeEngine().getIdLen() > 0) ? new SNMP_Engine(&m_securityContext->getAuthoritativeEngine()) : NULL;
 }
 
 /**
@@ -132,8 +134,9 @@ retry:
                                                }
 
                                                // Cache context engine ID
-                                               if ((m_contextEngine == NULL) && ((*response)->getContextEngineIdLength() != 0))
+                  if (((m_contextEngine == NULL) || (m_contextEngine->getIdLen() == 0)) && ((*response)->getContextEngineIdLength() != 0))
                                                {
+                     delete m_contextEngine;
                                                        m_contextEngine = new SNMP_Engine((*response)->getContextEngineId(), (*response)->getContextEngineIdLength());
                                                }