1
votes

I want to get information from a snmp device which is configured with auth protocol MD5 and priv protocol 3DES.

The configuration statement is snmp-server user testuser testgroup v3 auth md5 authmd5pwd priv 3des privpwddes

The pysnmp code to access the device is

from pysnmp.hlapi import *

def get(mib):
  errorIndication, errorStatus, errorIndex, varBinds = next(
      getCmd(SnmpEngine(),
             UsmUserData('nmsuser', 'authmd5pwd', 'privpwddes',
                         authProtocol=usmHMACMD5AuthProtocol,
                         privProtocol=usm3DESEDEPrivProtocol),
             UdpTransportTarget(('10.96.158.251', 161)),
             ContextData(),
             ObjectType(ObjectIdentity(mib)))
  )

  if errorIndication:
      print(errorIndication)
  elif errorStatus:
      print('%s at %s' % (errorStatus.prettyPrint(),
                          errorIndex and varBinds[int(errorIndex) - 1][0] or '?'))
  else:
      for varBind in varBinds:
          print(varBind[1])

if __name__ == "__main__":
  get('.1.3.6.1.2.1.1.5.0')

When I execute this I get

     Traceback (most recent call last):
          File "pytest.py", line 24, in 
            get('.1.3.6.1.2.1.1.5.0')
          File "pytest.py", line 11, in get
            ObjectType(ObjectIdentity(mib)))
          File "/usr/local/lib/python2.7/dist-packages/pysnmp-4.4.3-py2.7.egg/pysnmp/hlapi/asyncore/sync/cmdgen.py", line 113, in getCmd
          File "/usr/local/lib/python2.7/dist-packages/pysnmp-4.4.3-py2.7.egg/pysnmp/carrier/asyncore/dispatch.py", line 50, in runDispatcher
        pysnmp.error.PySnmpError: poll error: Traceback (most recent call last):
        ;  File "/usr/local/lib/python2.7/dist-packages/pysnmp-4.4.3-py2.7.egg/pysnmp/carrier/asyncore/dispatch.py", line 46, in runDispatcher
            use_poll=True, map=self.__sockMap, count=1)
        ;  File "/usr/lib/python2.7/asyncore.py", line 220, in loop
            poll_fun(timeout, map)
        ;  File "/usr/lib/python2.7/asyncore.py", line 201, in poll2
            readwrite(obj, flags)
        ;  File "/usr/lib/python2.7/asyncore.py", line 123, in readwrite
            obj.handle_error()
        ;  File "/usr/lib/python2.7/asyncore.py", line 108, in readwrite
            obj.handle_read_event()
        ;  File "/usr/lib/python2.7/asyncore.py", line 449, in handle_read_event
            self.handle_read()
        ;  File "/usr/local/lib/python2.7/dist-packages/pysnmp-4.4.3-py2.7.egg/pysnmp/carrier/asyncore/dgram/base.py", line 163, in handle_read
            self._cbFun(self, transportAddress, incomingMessage)
        ;  File "/usr/local/lib/python2.7/dist-packages/pysnmp-4.4.3-py2.7.egg/pysnmp/carrier/base.py", line 70, in _cbFun
            self, transportDomain, transportAddress, incomingMessage
        ;  File "/usr/local/lib/python2.7/dist-packages/pysnmp-4.4.3-py2.7.egg/pysnmp/entity/engine.py", line 152, in __receiveMessageCbFun
            self, transportDomain, transportAddress, wholeMsg
        ;  File "/usr/local/lib/python2.7/dist-packages/pysnmp-4.4.3-py2.7.egg/pysnmp/proto/rfc3412.py", line 344, in receiveMessage
            statusInformation
        ;  File "/usr/local/lib/python2.7/dist-packages/pysnmp-4.4.3-py2.7.egg/pysnmp/proto/rfc3412.py", line 533, in __expireRequest
            cachedParams['cbCtx'])
        ;  File "/usr/local/lib/python2.7/dist-packages/pysnmp-4.4.3-py2.7.egg/pysnmp/entity/rfc3413/cmdgen.py", line 104, in processResponsePdu
            (origSendRequestHandle, cbFun, cbCtx))
        ;  File "/usr/local/lib/python2.7/dist-packages/pysnmp-4.4.3-py2.7.egg/pysnmp/proto/rfc3412.py", line 153, in sendPdu
            pduVersion, PDU, expectResponse, sendPduHandle
        ;  File "/usr/local/lib/python2.7/dist-packages/pysnmp-4.4.3-py2.7.egg/pysnmp/proto/mpmod/rfc3412.py", line 240, in prepareOutgoingMessage
            securityEngineId, securityName, securityLevel, scopedPDU
        ;  File "/usr/local/lib/python2.7/dist-packages/pysnmp-4.4.3-py2.7.egg/pysnmp/proto/secmod/rfc3414/service.py", line 525, in generateRequestMsg
            None)
        ;  File "/usr/local/lib/python2.7/dist-packages/pysnmp-4.4.3-py2.7.egg/pysnmp/proto/secmod/rfc3414/service.py", line 395, in __generateRequestOrResponseMsg
            (snmpEngineBoots, snmpEngineTime, None), dataToEncrypt
        ;  File "/usr/local/lib/python2.7/dist-packages/pysnmp-4.4.3-py2.7.egg/pysnmp/proto/secmod/eso/priv/des3.py", line 117, in encryptData
            encryptKey, snmpEngineBoots
        ;  File "/usr/local/lib/python2.7/dist-packages/pysnmp-4.4.3-py2.7.egg/pysnmp/proto/secmod/eso/priv/des3.py", line 77, in __getEncryptionKey
            preIV = privKey[24:32]
        ;  File "/usr/local/lib/python2.7/dist-packages/pyasn1/type/univ.py", line 996, in __getitem__
            return self.clone(self._value[i])
        ;  File "/usr/local/lib/python2.7/dist-packages/pysnmp-4.4.3-py2.7.egg/pysnmp/proto/rfc1902.py", line 202, in clone
            return univ.OctetString.clone(self, *args, **kwargs).setFixedLength(self.getFixedLength())
        ;  File "/usr/local/lib/python2.7/dist-packages/pyasn1/type/base.py", line 349, in clone
            return self.__class__(value, **initilaizers)
        ;  File "/usr/local/lib/python2.7/dist-packages/pyasn1/type/univ.py", line 819, in __init__
            base.AbstractSimpleAsn1Item.__init__(self, value, **kwargs)
        ;  File "/usr/local/lib/python2.7/dist-packages/pyasn1/type/base.py", line 246, in __init__
            raise exType('%s at %s' % (exValue, self.__class__.__name__))
        ;ValueConstraintError: , > failed at: ValueConstraintError(" failed at: ValueConstraintError('',)",) at OctetString
1

1 Answers

1
votes

Seems to be a bug in pysnmp 4.4.3 when using 3DES with short-hash HMAC such as MD5.

You can either use some other AUTH algorithm which produces at least 32-octet long hash or pull fixed pysnmp (4.4.4) from its master branch.

Your script seems to work with the simulator once you change username/passphrase.