def prettyIn(self, value): if not has_ipv6: raise error.PySnmpError('IPv6 not supported by platform') if isinstance(value, tuple): value = inet_pton(socket.AF_INET6, value[0]) + int2oct((value[1] >> 8) & 0xff) + int2oct(value[1] & 0xff) return OctetString.prettyIn(self, value)
def n_VersionInfo(self, cbCtx, node): raise error.PySnmpError()
def verifyDispatcherCompatibility(self, snmpEngine): if not self.protoTransport.isCompatibleWithDispatcher( snmpEngine.transportDispatcher): raise error.PySnmpError( 'Transport %r is not compatible with dispatcher %r' % (self.protoTransport, snmpEngine.transportDispatcher))
def unregisterTransportDispatcher(self, recvId=None): if self.transportDispatcher is None: raise error.PySnmpError('Transport dispatcher not registered') self.transportDispatcher.unregisterRecvCbFun(recvId) self.transportDispatcher.unregisterTimerCbFun() self.transportDispatcher = None
def configure(self, snmpEngine, authData, transportTarget, contextName, **options): cache = self._getCache(snmpEngine) if isinstance(authData, CommunityData): if authData.communityIndex not in cache['auth']: config.addV1System(snmpEngine, authData.communityIndex, authData.communityName, authData.contextEngineId, authData.contextName, authData.tag, authData.securityName) cache['auth'][authData.communityIndex] = authData elif isinstance(authData, UsmUserData): authDataKey = authData.userName, authData.securityEngineId if authDataKey not in cache['auth']: config.addV3User(snmpEngine, authData.userName, authData.authProtocol, authData.authKey, authData.privProtocol, authData.privKey, authData.securityEngineId, securityName=authData.securityName) cache['auth'][authDataKey] = authData else: raise error.PySnmpError('Unsupported authentication object') paramsKey = (authData.securityName, authData.securityLevel, authData.mpModel) if paramsKey in cache['parm']: paramsName, useCount = cache['parm'][paramsKey] cache['parm'][paramsKey] = paramsName, useCount + 1 else: paramsName = 'p%s' % self.nextID() config.addTargetParams(snmpEngine, paramsName, authData.securityName, authData.securityLevel, authData.mpModel) cache['parm'][paramsKey] = paramsName, 1 if transportTarget.TRANSPORT_DOMAIN in cache['tran']: transport, useCount = cache['tran'][ transportTarget.TRANSPORT_DOMAIN] transportTarget.verifyDispatcherCompatibility(snmpEngine) cache['tran'][ transportTarget.TRANSPORT_DOMAIN] = transport, useCount + 1 elif config.getTransport(snmpEngine, transportTarget.TRANSPORT_DOMAIN): transportTarget.verifyDispatcherCompatibility(snmpEngine) else: transport = transportTarget.openClientMode() config.addTransport(snmpEngine, transportTarget.TRANSPORT_DOMAIN, transport) cache['tran'][transportTarget.TRANSPORT_DOMAIN] = transport, 1 transportKey = (paramsName, transportTarget.TRANSPORT_DOMAIN, transportTarget.transportAddr, transportTarget.timeout, transportTarget.retries, transportTarget.tagList, transportTarget.iface) if transportKey in cache['addr']: addrName, useCount = cache['addr'][transportKey] cache['addr'][transportKey] = addrName, useCount + 1 else: addrName = 'a%s' % self.nextID() config.addTargetAddr(snmpEngine, addrName, transportTarget.TRANSPORT_DOMAIN, transportTarget.transportAddr, paramsName, transportTarget.timeout * 100, transportTarget.retries, transportTarget.tagList) cache['addr'][transportKey] = addrName, 1 return addrName, paramsName
if len(node) > 2: opt = node[2].attr else: opt = node[1].attr for c in map(None, opt): if c == 'i': ctx['informMode'] = 1 def n_EnterpriseOid(self, (snmpEngine, ctx), node): ctx['EnterpriseOid'] = node[0].attr def n_AgentName(self, (snmpEngine, ctx), node): try: ctx['AgentName'] = socket.gethostbyname(node[0].attr) except socket.error, why: raise error.PySnmpError('Bad agent name %s: %s' % (node[0].attr, why)) def n_GenericTrap(self, (snmpEngine, ctx), node): ctx['GenericTrap'] = node[0].attr def n_SpecificTrap(self, (snmpEngine, ctx), node): ctx['SpecificTrap'] = node[0].attr def n_Uptime(self, (snmpEngine, ctx), node): ctx['Uptime'] = long(node[0].attr) def n_TrapV1Params_exit(self, (snmpEngine, ctx), node): v1Pdu = v1.TrapPDU() v1.apiTrapPDU.setDefaults(v1Pdu) if ctx.has_key('EnterpriseOid'): v1.apiTrapPDU.setEnterprise(v1Pdu, ctx['EnterpriseOid'])
def __init__(self, snmpEngineID=None, maxMessageSize=65507, msgAndPduDsp=None): self.cache = {} self.observer = observer.MetaObserver() if msgAndPduDsp is None: self.msgAndPduDsp = MsgAndPduDispatcher() else: self.msgAndPduDsp = msgAndPduDsp self.messageProcessingSubsystems = { SnmpV1MessageProcessingModel.messageProcessingModelID: SnmpV1MessageProcessingModel(), SnmpV2cMessageProcessingModel.messageProcessingModelID: SnmpV2cMessageProcessingModel(), SnmpV3MessageProcessingModel.messageProcessingModelID: SnmpV3MessageProcessingModel() } self.securityModels = { SnmpV1SecurityModel.securityModelID: SnmpV1SecurityModel(), SnmpV2cSecurityModel.securityModelID: SnmpV2cSecurityModel(), SnmpUSMSecurityModel.securityModelID: SnmpUSMSecurityModel() } self.accessControlModel = { void.Vacm.accessModelID: void.Vacm(), rfc3415.Vacm.accessModelID: rfc3415.Vacm() } self.transportDispatcher = None if self.msgAndPduDsp.mibInstrumController is None: raise error.PySnmpError('MIB instrumentation does not yet exist') snmpEngineMaxMessageSize, = self.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols( '__SNMP-FRAMEWORK-MIB', 'snmpEngineMaxMessageSize') snmpEngineMaxMessageSize.syntax = snmpEngineMaxMessageSize.syntax.clone( maxMessageSize) snmpEngineBoots, = self.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols( '__SNMP-FRAMEWORK-MIB', 'snmpEngineBoots') snmpEngineBoots.syntax += 1 origSnmpEngineID, = self.msgAndPduDsp.mibInstrumController.mibBuilder.importSymbols( '__SNMP-FRAMEWORK-MIB', 'snmpEngineID') if snmpEngineID is None: self.snmpEngineID = origSnmpEngineID.syntax else: origSnmpEngineID.syntax = origSnmpEngineID.syntax.clone( snmpEngineID) self.snmpEngineID = origSnmpEngineID.syntax debug.logger & debug.flagApp and debug.logger( 'SnmpEngine: using custom SNMP Engine ID: %s' % self.snmpEngineID.prettyPrint()) # Attempt to make some of snmp Engine settings persistent. # This should probably be generalized as a non-volatile MIB store. persistentPath = os.path.join(tempfile.gettempdir(), '__pysnmp', self.snmpEngineID.prettyPrint()) debug.logger & debug.flagApp and debug.logger( 'SnmpEngine: using persistent directory: %s' % persistentPath) if not os.path.exists(persistentPath): try: os.makedirs(persistentPath) except OSError: return f = os.path.join(persistentPath, 'boots') try: snmpEngineBoots.syntax = snmpEngineBoots.syntax.clone( open(f).read()) except Exception: pass try: snmpEngineBoots.syntax += 1 except Exception: snmpEngineBoots.syntax = snmpEngineBoots.syntax.clone(1) try: fd, fn = tempfile.mkstemp(dir=persistentPath) os.write(fd, str2octs(snmpEngineBoots.syntax.prettyPrint())) os.close(fd) os.rename(fn, f) except Exception: debug.logger & debug.flagApp and debug.logger( 'SnmpEngine: could not stored SNMP Engine Boots: %s' % sys.exc_info()[1]) else: debug.logger & debug.flagApp and debug.logger( 'SnmpEngine: stored SNMP Engine Boots: %s' % snmpEngineBoots.syntax.prettyPrint())
def processResponsePdu(self, snmpEngine, messageProcessingModel, securityModel, securityName, securityLevel, contextEngineId, contextName, pduVersion, PDU, statusInformation, sendPduHandle, cbCtx): origSendRequestHandle, cbFun, cbCtx = cbCtx # 3.1.1 if sendPduHandle not in self.__pendingReqs: raise error.PySnmpError('Missing sendPduHandle %s' % sendPduHandle) (origTransportDomain, origTransportAddress, origMessageProcessingModel, origSecurityModel, origSecurityName, origSecurityLevel, origContextEngineId, origContextName, origPduVersion, origPdu, origTimeout, origRetryCount, origRetries, origDiscoveryRetries) = self.__pendingReqs.pop(sendPduHandle) snmpEngine.transportDispatcher.jobFinished(id(self)) # 3.1.3 if statusInformation: debug.logger & debug.flagApp and debug.logger( 'processResponsePdu: sendPduHandle %s, statusInformation %s' % (sendPduHandle, statusInformation)) errorIndication = statusInformation['errorIndication'] if errorIndication in (errind.notInTimeWindow, errind.unknownEngineID): origDiscoveryRetries += 1 origRetries = 0 else: origDiscoveryRetries = 0 origRetries += 1 if origRetries > origRetryCount or origDiscoveryRetries > self.__options.get( 'discoveryRetries', 4): debug.logger & debug.flagApp and debug.logger( 'processResponsePdu: sendPduHandle %s, retry count %d exceeded' % (sendPduHandle, origRetries)) cbFun(snmpEngine, origSendRequestHandle, errorIndication, None, cbCtx) return # User-side API assumes SMIv2 if origMessageProcessingModel == 0: reqPDU = rfc2576.v2ToV1(origPdu) pduVersion = 0 else: reqPDU = origPdu pduVersion = 1 try: sendPduHandle = snmpEngine.msgAndPduDsp.sendPdu( snmpEngine, origTransportDomain, origTransportAddress, origMessageProcessingModel, origSecurityModel, origSecurityName, origSecurityLevel, origContextEngineId, origContextName, pduVersion, reqPDU, True, origTimeout, self.processResponsePdu, (origSendRequestHandle, cbFun, cbCtx)) snmpEngine.transportDispatcher.jobStarted(id(self)) self.__pendingReqs[sendPduHandle] = ( origTransportDomain, origTransportAddress, origMessageProcessingModel, origSecurityModel, origSecurityName, origSecurityLevel, origContextEngineId, origContextName, origPduVersion, origPdu, origTimeout, origRetryCount, origRetries, origDiscoveryRetries) return except StatusInformation: statusInformation = sys.exc_info()[1] debug.logger & debug.flagApp and debug.logger( 'processResponsePdu: origSendRequestHandle %s, _sendPdu() failed with %r' % (sendPduHandle, statusInformation)) cbFun(snmpEngine, origSendRequestHandle, statusInformation['errorIndication'], None, cbCtx) return if (origMessageProcessingModel != messageProcessingModel or origSecurityModel != securityModel or origSecurityName != origSecurityName or origContextEngineId and origContextEngineId != contextEngineId or origContextName and origContextName != contextName or origPduVersion != pduVersion): debug.logger & debug.flagApp and debug.logger( 'processResponsePdu: sendPduHandle %s, request/response data mismatch' % sendPduHandle) cbFun(snmpEngine, origSendRequestHandle, 'badResponse', None, cbCtx) return # User-side API assumes SMIv2 if messageProcessingModel == 0: PDU = rfc2576.v1ToV2(PDU, origPdu) # 3.1.2 if v2c.apiPDU.getRequestID(PDU) != v2c.apiPDU.getRequestID(origPdu): debug.logger & debug.flagApp and debug.logger( 'processResponsePdu: sendPduHandle %s, request-id/response-id mismatch' % sendPduHandle) cbFun(snmpEngine, origSendRequestHandle, 'badResponse', None, cbCtx) return cbFun(snmpEngine, origSendRequestHandle, None, PDU, cbCtx)
def test__get_transport_err(self, mock_transport, mock_cmdgen): mock_transport.side_effect = snmp_error.PySnmpError() client = snmp.SNMPClient(self.address, self.port, snmp.SNMP_V3) self.assertRaises(snmp_error.PySnmpError, client._get_transport) mock_cmdgen.assert_called_once_with() mock_transport.assert_called_once_with((client.address, client.port))
def addV3User(snmpEngine, userName, authProtocol=USM_AUTH_NONE, authKey=None, privProtocol=USM_PRIV_NONE, privKey=None, securityEngineId=None, securityName=None, authKeyType=USM_KEY_TYPE_PASSPHRASE, privKeyType=USM_KEY_TYPE_PASSPHRASE): mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder if securityName is None: securityName = userName (securityEngineId, usmUserEntry, tblIdx1, pysnmpUsmSecretEntry, tblIdx2) = __cookV3UserInfo(snmpEngine, securityName, securityEngineId) # Load augmenting table before creating new row in base one pysnmpUsmKeyEntry, = mibBuilder.importSymbols('PYSNMP-USM-MIB', 'pysnmpUsmKeyEntry') # Load clone-from (may not be needed) zeroDotZero, = mibBuilder.importSymbols('SNMPv2-SMI', 'zeroDotZero') snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects( (usmUserEntry.name + (13, ) + tblIdx1, 'destroy'), snmpEngine=snmpEngine) snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects( (usmUserEntry.name + (2, ) + tblIdx1, userName), (usmUserEntry.name + (3, ) + tblIdx1, securityName), (usmUserEntry.name + (4, ) + tblIdx1, zeroDotZero.name), (usmUserEntry.name + (5, ) + tblIdx1, authProtocol), (usmUserEntry.name + (8, ) + tblIdx1, privProtocol), (usmUserEntry.name + (13, ) + tblIdx1, 'createAndGo'), snmpEngine=snmpEngine) if authProtocol not in AUTH_SERVICES: raise error.PySnmpError('Unknown auth protocol %s' % (authProtocol, )) if privProtocol not in PRIV_SERVICES: raise error.PySnmpError('Unknown privacy protocol %s' % (privProtocol, )) pysnmpUsmKeyType, = mibBuilder.importSymbols('__PYSNMP-USM-MIB', 'pysnmpUsmKeyType') authKeyType = pysnmpUsmKeyType.syntax.clone(authKeyType) # Localize authentication key unless given authKey = authKey and rfc1902.OctetString(authKey) masterAuthKey = localAuthKey = authKey if authKeyType < USM_KEY_TYPE_MASTER: # master key is not given masterAuthKey = AUTH_SERVICES[authProtocol].hashPassphrase(authKey or null) if authKeyType < USM_KEY_TYPE_LOCALIZED: # localized key is not given localAuthKey = AUTH_SERVICES[authProtocol].localizeKey( masterAuthKey, securityEngineId) # Localize privacy key unless given privKeyType = pysnmpUsmKeyType.syntax.clone(privKeyType) privKey = privKey and rfc1902.OctetString(privKey) masterPrivKey = localPrivKey = privKey if privKeyType < USM_KEY_TYPE_MASTER: # master key is not given masterPrivKey = PRIV_SERVICES[privProtocol].hashPassphrase( authProtocol, privKey or null) if privKeyType < USM_KEY_TYPE_LOCALIZED: # localized key is not given localPrivKey = PRIV_SERVICES[privProtocol].localizeKey( authProtocol, masterPrivKey, securityEngineId) # Commit only the keys we have snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects( (pysnmpUsmKeyEntry.name + (1, ) + tblIdx1, localAuthKey), snmpEngine=snmpEngine) snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects( (pysnmpUsmKeyEntry.name + (2, ) + tblIdx1, localPrivKey), snmpEngine=snmpEngine) if authKeyType < USM_KEY_TYPE_LOCALIZED: snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects( (pysnmpUsmKeyEntry.name + (3, ) + tblIdx1, masterAuthKey), snmpEngine=snmpEngine) if privKeyType < USM_KEY_TYPE_LOCALIZED: snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects( (pysnmpUsmKeyEntry.name + (4, ) + tblIdx1, masterPrivKey), snmpEngine=snmpEngine) snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects( (pysnmpUsmSecretEntry.name + (4, ) + tblIdx2, 'destroy'), snmpEngine=snmpEngine) # Commit plain-text pass-phrases if we have them snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects( (pysnmpUsmSecretEntry.name + (4, ) + tblIdx2, 'createAndGo'), snmpEngine=snmpEngine) if authKeyType < USM_KEY_TYPE_MASTER: snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects( (pysnmpUsmSecretEntry.name + (1, ) + tblIdx2, userName), (pysnmpUsmSecretEntry.name + (2, ) + tblIdx2, authKey), snmpEngine=snmpEngine) if privKeyType < USM_KEY_TYPE_MASTER: snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects( (pysnmpUsmSecretEntry.name + (1, ) + tblIdx2, userName), (pysnmpUsmSecretEntry.name + (3, ) + tblIdx2, privKey), snmpEngine=snmpEngine) debug.logger & debug.FLAG_SM and debug.logger( 'addV3User: added new table entries ' 'userName "%s" securityName "%s" authProtocol %s ' 'privProtocol %s localAuthKey "%s" localPrivKey "%s" ' 'masterAuthKey "%s" masterPrivKey "%s" authKey "%s" ' 'privKey "%s" by index securityName "%s" securityEngineId ' '"%s"' % (userName, securityName, authProtocol, privProtocol, localAuthKey and localAuthKey.prettyPrint(), localPrivKey and localPrivKey.prettyPrint(), masterAuthKey and masterAuthKey.prettyPrint(), masterPrivKey and masterPrivKey.prettyPrint(), authKey and authKey.prettyPrint(), privKey and privKey.prettyPrint(), securityName, securityEngineId.prettyPrint()))
def addV3User(snmpEngine, userName, authProtocol=USM_AUTH_NONE, authKey=None, privProtocol=USM_PRIV_NONE, privKey=None, securityEngineId=None, securityName=None): mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder if securityName is None: securityName = userName (snmpEngineID, usmUserEntry, tblIdx1, pysnmpUsmSecretEntry, tblIdx2) = __cookV3UserInfo(snmpEngine, userName, securityEngineId) # Load augmenting table before creating new row in base one pysnmpUsmKeyEntry, = mibBuilder.importSymbols('PYSNMP-USM-MIB', 'pysnmpUsmKeyEntry') # Load clone-from (may not be needed) zeroDotZero, = mibBuilder.importSymbols('SNMPv2-SMI', 'zeroDotZero') snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects( (usmUserEntry.name + (13, ) + tblIdx1, 'destroy'), snmpEngine=snmpEngine) snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects( (usmUserEntry.name + (2, ) + tblIdx1, userName), (usmUserEntry.name + (3, ) + tblIdx1, securityName), (usmUserEntry.name + (4, ) + tblIdx1, zeroDotZero.name), (usmUserEntry.name + (5, ) + tblIdx1, authProtocol), (usmUserEntry.name + (8, ) + tblIdx1, privProtocol), (usmUserEntry.name + (13, ) + tblIdx1, 'createAndGo'), snmpEngine=snmpEngine) # Localize keys if authProtocol in AUTH_SERVICES: hashedAuthPassphrase = AUTH_SERVICES[authProtocol].hashPassphrase( authKey and authKey or null) localAuthKey = AUTH_SERVICES[authProtocol].localizeKey( hashedAuthPassphrase, snmpEngineID) else: raise error.PySnmpError('Unknown auth protocol %s' % (authProtocol, )) if privProtocol in PRIV_SERVICES: hashedPrivPassphrase = PRIV_SERVICES[privProtocol].hashPassphrase( authProtocol, privKey and privKey or null) localPrivKey = PRIV_SERVICES[privProtocol].localizeKey( authProtocol, hashedPrivPassphrase, snmpEngineID) else: raise error.PySnmpError('Unknown priv protocol %s' % (privProtocol, )) # Commit localized keys snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects( (pysnmpUsmKeyEntry.name + (1, ) + tblIdx1, localAuthKey), (pysnmpUsmKeyEntry.name + (2, ) + tblIdx1, localPrivKey), (pysnmpUsmKeyEntry.name + (3, ) + tblIdx1, hashedAuthPassphrase), (pysnmpUsmKeyEntry.name + (4, ) + tblIdx1, hashedPrivPassphrase), snmpEngine=snmpEngine) # Commit passphrases snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects( (pysnmpUsmSecretEntry.name + (4, ) + tblIdx2, 'destroy'), snmpEngine=snmpEngine) snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects( (pysnmpUsmSecretEntry.name + (1, ) + tblIdx2, userName), (pysnmpUsmSecretEntry.name + (2, ) + tblIdx2, authKey), (pysnmpUsmSecretEntry.name + (3, ) + tblIdx2, privKey), (pysnmpUsmSecretEntry.name + (4, ) + tblIdx2, 'createAndGo'), snmpEngine=snmpEngine)
def n_OutputOption(self, cbCtx, node): snmpEngine, ctx = cbCtx mibViewProxy = ctx['mibViewProxy'] opt = node[1].attr or node[2].attr for c in opt: if c == 'q': mibViewProxy.buildEqualSign = False mibViewProxy.buildTypeInfo = False elif c == 'Q': mibViewProxy.buildTypeInfo = False elif c == 'f': mibViewProxy.buildModInfo = False mibViewProxy.buildObjectDesc = False mibViewProxy.buildAbsoluteName = True elif c == 's': mibViewProxy.buildModInfo = False mibViewProxy.buildObjectDesc = True elif c == 'S': mibViewProxy.buildObjectDesc = True elif c == 'n': mibViewProxy.buildObjectDesc = False mibViewProxy.buildModInfo = False mibViewProxy.buildNumericName = True mibViewProxy.buildNumericIndices = True mibViewProxy.buildAbsoluteName = True elif c == 'e': mibViewProxy.buildEnums = False elif c == 'b': mibViewProxy.buildNumericIndices = True elif c == 'E': mibViewProxy.buildEscQuotes = True elif c == 'X': mibViewProxy.buildSquareBrackets = True elif c == 'T': mibViewProxy.buildHexVals = True elif c == 'v': mibViewProxy.buildObjectName = False elif c == 'U': mibViewProxy.buildUnits = False elif c == 't': mibViewProxy.buildRawTimeTicks = True pass elif c == 'R': mibViewProxy.buildRawVals = True else: raise error.PySnmpError('Unknown output option %s at %s' % (c, self))
def generator(cbCtx, ast): snmpEngine, ctx = cbCtx _SMGenerator().preorder(cbCtx, ast) # Commit collected data if ctx['versionId'] == 3: def _unhexKey(key): if key.lower().startswith('0x'): key = key[2:] return rfc1902.OctetString(hexValue=key) if 'securityName' not in ctx: raise error.PySnmpError('Security name not specified') if 'securityLevel' not in ctx: raise error.PySnmpError('Security level not specified') if 'securityEngineId' in ctx: securityEngineId = _unhexKey(ctx['securityEngineId']) else: securityEngineId = None if 'contextEngineId' in ctx: ctx['contextEngineId'] = _unhexKey(ctx['contextEngineId']) else: ctx['contextEngineId'] = None if 'localizedAuthKey' in ctx: ctx['authKey'] = _unhexKey(ctx.pop('localizedAuthKey')) authKeyType = config.usmKeyTypeLocalized elif 'masterAuthKey' in ctx: ctx['authKey'] = _unhexKey(ctx.pop('masterAuthKey')) authKeyType = config.usmKeyTypeMaster else: authKeyType = config.usmKeyTypePassphrase if 'localizedPrivKey' in ctx: ctx['privKey'] = _unhexKey(ctx.pop('localizedPrivKey')) privKeyType = config.usmKeyTypeLocalized elif 'masterPrivKey' in ctx: ctx['privKey'] = _unhexKey(ctx.pop('masterPrivKey')) privKeyType = config.usmKeyTypeMaster else: privKeyType = config.usmKeyTypePassphrase if (authKeyType == config.usmKeyTypeLocalized or privKeyType == config.usmKeyTypeLocalized): # Wildcard security engine ID assocciating localized keys # with any authoritative SNMP engine securityEngineId = rfc1902.OctetString(hexValue='0000000000') ctx['securityEngineId'] = securityEngineId if ctx['securityLevel'] == 'noAuthNoPriv': if 'authKey' in ctx: del ctx['authKey'] if 'privKey' in ctx: del ctx['privKey'] elif ctx['securityLevel'] == 'authNoPriv': if 'privKey' in ctx: del ctx['privKey'] if 'authKey' in ctx: if 'authProtocol' not in ctx: ctx['authProtocol'] = config.usmHMACMD5AuthProtocol else: ctx['authProtocol'] = config.usmNoAuthProtocol ctx['authKey'] = None if 'privKey' in ctx: if 'privProtocol' not in ctx: ctx['privProtocol'] = config.usmDESPrivProtocol else: ctx['privProtocol'] = config.usmNoPrivProtocol ctx['privKey'] = None config.addV3User(snmpEngine, ctx['securityName'], ctx['authProtocol'], ctx['authKey'], ctx['privProtocol'], ctx['privKey'], securityEngineId=securityEngineId, securityName=ctx['securityName'], authKeyType=authKeyType, privKeyType=privKeyType) # edit SNMP engine boots/uptime mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder if 'engineBoots' in ctx: snmpEngineBoots, = mibBuilder.importSymbols( '__SNMP-FRAMEWORK-MIB', 'snmpEngineBoots') snmpEngineBoots.setSyntax(snmpEngineBoots.getSyntax().clone( ctx['engineBoots'])) if 'engineTime' in ctx: snmpEngineTime, = mibBuilder.importSymbols('__SNMP-FRAMEWORK-MIB', 'snmpEngineTime') snmpEngineTime.setSyntax(snmpEngineTime.getSyntax().clone( ctx['engineTime'])) else: # SNMPv1/v2c if 'communityName' not in ctx: raise error.PySnmpError('Community name not specified') ctx['securityName'] = 'my-agent' ctx['securityLevel'] = 'noAuthNoPriv' config.addV1System(snmpEngine, ctx['securityName'], ctx['communityName']) ctx['paramsName'] = ctx['securityName'] config.addTargetParams(snmpEngine, ctx['paramsName'], ctx['securityName'], ctx['securityLevel'], ctx['versionId'])
def n_Help(self, cbCtx, node): raise error.PySnmpError()
def getMibInstrum(self, contextName): if not self.contextNames.has_key(contextName): raise error.PySnmpError('Missing contextName %s' % contextName) else: return self.contextNames[contextName]
def error(self, token): raise error.PySnmpError('Command-line parser error at token %s\n' % token)
def processResponsePdu(self, snmpEngine, messageProcessingModel, securityModel, securityName, securityLevel, contextEngineId, contextName, pduVersion, PDU, statusInformation, sendPduHandle, cbInfo): (cbFun, cbCtx) = cbInfo # 3.1.1 if sendPduHandle not in self.__pendingReqs: raise error.PySnmpError('Missing sendPduHandle %s' % sendPduHandle) (origTransportDomain, origTransportAddress, origMessageProcessingModel, origSecurityModel, origSecurityName, origSecurityLevel, origContextEngineId, origContextName, origPduVersion, origPdu, origTimeout, origRetryCount, origRetries, origSendRequestHandle) = self.__pendingReqs[sendPduHandle] del self.__pendingReqs[sendPduHandle] snmpEngine.transportDispatcher.jobFinished(id(self)) # 3.1.3 if statusInformation: debug.logger & debug.flagApp and debug.logger( 'processResponsePdu: sendPduHandle %s, statusInformation %s' % (sendPduHandle, statusInformation)) errorIndication = statusInformation['errorIndication'] # SNMP engine discovery will take extra retries, allow that if errorIndication in (errind.notInTimeWindow, errind.unknownEngineID) and \ origRetries == origRetryCount + 2 or \ errorIndication not in (errind.notInTimeWindow, errind.unknownEngineID) and \ origRetries == origRetryCount: debug.logger & debug.flagApp and debug.logger( 'processResponsePdu: sendPduHandle %s, retry count %d exceeded' % (sendPduHandle, origRetries)) cbFun(origSendRequestHandle, statusInformation['errorIndication'], 0, 0, (), cbCtx) return try: self._sendPdu(snmpEngine, origTransportDomain, origTransportAddress, origMessageProcessingModel, origSecurityModel, origSecurityName, origSecurityLevel, origContextEngineId, origContextName, origPdu, origTimeout, origRetryCount, origRetries + 1, origSendRequestHandle, (self.processResponsePdu, (cbFun, cbCtx))) except StatusInformation: statusInformation = sys.exc_info()[1] debug.logger & debug.flagApp and debug.logger( 'processResponsePdu: origSendRequestHandle %s, _sendPdu() failed with %r' % (sendPduHandle, statusInformation)) cbFun(origSendRequestHandle, statusInformation['errorIndication'], 0, 0, (), cbCtx) return if origMessageProcessingModel != messageProcessingModel or \ origSecurityModel != securityModel or \ origSecurityName != origSecurityName or \ origContextEngineId and origContextEngineId != contextEngineId or \ origContextName and origContextName != contextName or \ origPduVersion != pduVersion: debug.logger & debug.flagApp and debug.logger( 'processResponsePdu: sendPduHandle %s, request/response data mismatch' % sendPduHandle) cbFun(origSendRequestHandle, 'badResponse', 0, 0, (), cbCtx) return # User-side API assumes SMIv2 if messageProcessingModel == 0: PDU = rfc2576.v1ToV2(PDU, origPdu) # 3.1.2 if v2c.apiPDU.getRequestID(PDU) != v2c.apiPDU.getRequestID(origPdu): debug.logger & debug.flagApp and debug.logger( 'processResponsePdu: sendPduHandle %s, request-id/response-id mismatch' % sendPduHandle) cbFun(origSendRequestHandle, 'badResponse', 0, 0, (), cbCtx) return self._handleResponse( snmpEngine, origTransportDomain, origTransportAddress, origMessageProcessingModel, origSecurityModel, origSecurityName, origSecurityLevel, origContextEngineId, origContextName, origPdu, origTimeout, origRetryCount, PDU, origSendRequestHandle, (cbFun, cbCtx), )
def unconfigure(self, snmpEngine, authData=None, contextName=null, **options): cache = self._getCache(snmpEngine) if authData: if isinstance(authData, CommunityData): authDataKey = authData.communityIndex elif isinstance(authData, UsmUserData): authDataKey = authData.userName, authData.securityEngineId else: raise error.PySnmpError('Unsupported authentication object') if authDataKey in cache['auth']: authDataKeys = (authDataKey, ) else: raise error.PySnmpError('Unknown authData %s' % (authData, )) else: authDataKeys = list(cache['auth'].keys()) addrNames, paramsNames = set(), set() for authDataKey in authDataKeys: authDataX = cache['auth'][authDataKey] del cache['auth'][authDataKey] if isinstance(authDataX, CommunityData): config.delV1System(snmpEngine, authDataX.communityIndex) elif isinstance(authDataX, UsmUserData): config.delV3User(snmpEngine, authDataX.userName, authDataX.securityEngineId) else: raise error.PySnmpError('Unsupported authentication object') paramsKey = (authDataX.securityName, authDataX.securityLevel, authDataX.mpModel) if paramsKey in cache['parm']: paramsName, useCount = cache['parm'][paramsKey] useCount -= 1 if useCount: cache['parm'][paramsKey] = paramsName, useCount else: del cache['parm'][paramsKey] config.delTargetParams(snmpEngine, paramsName) paramsNames.add(paramsName) else: raise error.PySnmpError('Unknown target %s' % (paramsKey, )) addrKeys = [x for x in cache['addr'] if x[0] == paramsName] for addrKey in addrKeys: addrName, useCount = cache['addr'][addrKey] useCount -= 1 if useCount: cache['addr'][addrKey] = addrName, useCount else: config.delTargetAddr(snmpEngine, addrName) del cache['addr'][addrKey] addrNames.add(addrKey) if addrKey[1] in cache['tran']: transport, useCount = cache['tran'][addrKey[1]] if useCount > 1: useCount -= 1 cache['tran'][addrKey[1]] = transport, useCount else: config.delTransport(snmpEngine, addrKey[1]) transport.closeTransport() del cache['tran'][addrKey[1]] return addrNames, paramsNames
def addV3User( snmpEngine, userName, authProtocol=usmNoAuthProtocol, authKey=None, privProtocol=usmNoPrivProtocol, privKey=None, securityEngineId=None, securityName=None, # deprecated parameters follow contextEngineId=None): mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder if securityName is None: securityName = userName if securityEngineId is None: # backward compatibility securityEngineId = contextEngineId (snmpEngineID, usmUserEntry, tblIdx1, pysnmpUsmSecretEntry, tblIdx2) = __cookV3UserInfo(snmpEngine, userName, securityEngineId) # Load augmenting table before creating new row in base one pysnmpUsmKeyEntry, = mibBuilder.importSymbols('PYSNMP-USM-MIB', 'pysnmpUsmKeyEntry') # Load clone-from (may not be needed) zeroDotZero, = mibBuilder.importSymbols('SNMPv2-SMI', 'zeroDotZero') snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( ((usmUserEntry.name + (13, ) + tblIdx1, 'destroy'), )) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( ((usmUserEntry.name + (2, ) + tblIdx1, userName), (usmUserEntry.name + (3, ) + tblIdx1, securityName), (usmUserEntry.name + (4, ) + tblIdx1, zeroDotZero.name), (usmUserEntry.name + (5, ) + tblIdx1, authProtocol), (usmUserEntry.name + (8, ) + tblIdx1, privProtocol), (usmUserEntry.name + (13, ) + tblIdx1, 'createAndGo'))) # Localize keys if authProtocol in authServices: hashedAuthPassphrase = authServices[authProtocol].hashPassphrase( authKey and authKey or null) localAuthKey = authServices[authProtocol].localizeKey( hashedAuthPassphrase, snmpEngineID) else: raise error.PySnmpError('Unknown auth protocol %s' % (authProtocol, )) if privProtocol in privServices: hashedPrivPassphrase = privServices[privProtocol].hashPassphrase( authProtocol, privKey and privKey or null) localPrivKey = privServices[privProtocol].localizeKey( authProtocol, hashedPrivPassphrase, snmpEngineID) else: raise error.PySnmpError('Unknown priv protocol %s' % (privProtocol, )) # Commit localized keys snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( ((pysnmpUsmKeyEntry.name + (1, ) + tblIdx1, localAuthKey), (pysnmpUsmKeyEntry.name + (2, ) + tblIdx1, localPrivKey), (pysnmpUsmKeyEntry.name + (3, ) + tblIdx1, hashedAuthPassphrase), (pysnmpUsmKeyEntry.name + (4, ) + tblIdx1, hashedPrivPassphrase))) # Commit passphrases snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( ((pysnmpUsmSecretEntry.name + (4, ) + tblIdx2, 'destroy'), )) snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( ((pysnmpUsmSecretEntry.name + (1, ) + tblIdx2, userName), (pysnmpUsmSecretEntry.name + (2, ) + tblIdx2, authKey), (pysnmpUsmSecretEntry.name + (3, ) + tblIdx2, privKey), (pysnmpUsmSecretEntry.name + (4, ) + tblIdx2, 'createAndGo')))
def bulkCmd(snmpDispatcher, authData, transportTarget, nonRepeaters, maxRepetitions, *varBinds, **options): """Initiate SNMP GETBULK query over SNMPv2c. Based on passed parameters, prepares SNMP GETBULK packet (:RFC:`1905#section-4.2.3`) and schedules its transmission by I/O framework at a later point of time. Parameters ---------- snmpDispatcher: :py:class:`~pysnmp.hlapi.v1arch.asyncore.SnmpDispatcher` Class instance representing SNMP dispatcher. authData: :py:class:`~pysnmp.hlapi.v1arch.CommunityData` or :py:class:`~pysnmp.hlapi.v1arch.UsmUserData` Class instance representing SNMP credentials. transportTarget: :py:class:`~pysnmp.hlapi.v1arch.asyncore.UdpTransportTarget` or :py:class:`~pysnmp.hlapi.v1arch.asyncore.Udp6TransportTarget` Class instance representing transport type along with SNMP peer address. nonRepeaters: int One MIB variable is requested in response for the first `nonRepeaters` MIB variables in request. maxRepetitions: int `maxRepetitions` MIB variables are requested in response for each of the remaining MIB variables in the request (e.g. excluding `nonRepeaters`). Remote SNMP dispatcher may choose lesser value than requested. \*varBinds: :py:class:`~pysnmp.smi.rfc1902.ObjectType` One or more class instances representing MIB variables to place into SNMP request. Other Parameters ---------------- \*\*options : Request options: * `lookupMib` - load MIB and resolve response MIB variables at the cost of slightly reduced performance. Default is `True`. * `cbFun` (callable) - user-supplied callable that is invoked to pass SNMP response data or error to user at a later point of time. Default is `None`. * `cbCtx` (object) - user-supplied object passing additional parameters to/from `cbFun`. Default is `None`. Notes ----- User-supplied `cbFun` callable must have the following call signature: * snmpDispatcher (:py:class:`~pysnmp.hlapi.v1arch.snmpDispatcher`): Class instance representing SNMP dispatcher. * stateHandle (int): Unique request identifier. Can be used for matching multiple ongoing requests with received responses. * errorIndication (str): True value indicates SNMP dispatcher error. * errorStatus (str): True value indicates SNMP PDU error. * errorIndex (int): Non-zero value refers to `varBinds[errorIndex-1]` * varBindTable (tuple): A sequence of sequences (e.g. 2-D array) of variable-bindings represented as :class:`tuple` or :py:class:`~pysnmp.smi.rfc1902.ObjectType` class instances representing a table of MIB variables returned in SNMP response, with up to ``maxRepetitions`` rows, i.e. ``len(varBindTable) <= maxRepetitions``. For ``0 <= i < len(varBindTable)`` and ``0 <= j < len(varBinds)``, ``varBindTable[i][j]`` represents: - For non-repeaters (``j < nonRepeaters``), the first lexicographic successor of ``varBinds[j]``, regardless the value of ``i``, or an :py:class:`~pysnmp.smi.rfc1902.ObjectType` instance with the :py:obj:`~pysnmp.proto.rfc1905.endOfMibView` value if no such successor exists; - For repeaters (``j >= nonRepeaters``), the ``i``-th lexicographic successor of ``varBinds[j]``, or an :py:class:`~pysnmp.smi.rfc1902.ObjectType` instance with the :py:obj:`~pysnmp.proto.rfc1905.endOfMibView` value if no such successor exists. See :rfc:`3416#section-4.2.3` for details on the underlying ``GetBulkRequest-PDU`` and the associated ``GetResponse-PDU``, such as specific conditions under which the server may truncate the response, causing ``varBindTable`` to have less than ``maxRepetitions`` rows. * `cbCtx` (object): Original user-supplied object. Returns ------- stateHandle : int Unique request identifier. Can be used for matching received responses with ongoing requests. Raises ------ PySnmpError Or its derivative indicating that an error occurred while performing SNMP operation. Examples -------- >>> from pysnmp.hlapi.v1arch.asyncore import * >>> >>> def cbFun(snmpDispatcher, stateHandle, errorIndication, >>> errorStatus, errorIndex, varBinds, cbCtx): >>> print(errorIndication, errorStatus, errorIndex, varBinds) >>> >>> snmpDispatcher = snmpDispatcher() >>> >>> stateHandle = bulkCmd( >>> snmpDispatcher, >>> CommunityData('public'), >>> UdpTransportTarget(('demo.snmplabs.com', 161)), >>> 0, 2, >>> ('1.3.6.1.2.1.1', None), >>> cbFun=cbFun >>> ) >>> >>> snmpDispatcher.transportDispatcher.runDispatcher() """ def _cbFun(snmpDispatcher, stateHandle, errorIndication, rspPdu, _cbCtx): if not cbFun: return if errorIndication: cbFun(errorIndication, pMod.Integer(0), pMod.Integer(0), None, cbCtx=cbCtx, snmpDispatcher=snmpDispatcher, stateHandle=stateHandle) return errorStatus = pMod.apiBulkPDU.getErrorStatus(rspPdu) errorIndex = pMod.apiBulkPDU.getErrorIndex(rspPdu) varBindTable = pMod.apiBulkPDU.getVarBindTable(reqPdu, rspPdu) errorIndication, nextVarBinds = pMod.apiBulkPDU.getNextVarBinds( varBindTable[-1], errorIndex=errorIndex) if options.get('lookupMib'): varBindTable = [ vbProcessor.unmakeVarBinds(snmpDispatcher.cache, vbs) for vbs in varBindTable ] nextStateHandle = pMod.getNextRequestID() nextVarBinds = cbFun(errorIndication, errorStatus, errorIndex, varBindTable, cbCtx=cbCtx, snmpDispatcher=snmpDispatcher, stateHandle=stateHandle, nextStateHandle=nextStateHandle, nextVarBinds=nextVarBinds) if not nextVarBinds: return pMod.apiBulkPDU.setRequestID(reqPdu, nextStateHandle) pMod.apiBulkPDU.setVarBinds(reqPdu, nextVarBinds) return snmpDispatcher.sendPdu(authData, transportTarget, reqPdu, cbFun=_cbFun) if authData.mpModel < 1: raise error.PySnmpError( 'GETBULK PDU is only supported in SNMPv2c and SNMPv3') lookupMib, cbFun, cbCtx = [ options.get(x) for x in ('lookupMib', 'cbFun', 'cbCtx') ] if lookupMib: varBinds = vbProcessor.makeVarBinds(snmpDispatcher.cache, varBinds) pMod = api.protoModules[authData.mpModel] reqPdu = pMod.GetBulkRequestPDU() pMod.apiBulkPDU.setDefaults(reqPdu) pMod.apiBulkPDU.setNonRepeaters(reqPdu, nonRepeaters) pMod.apiBulkPDU.setMaxRepetitions(reqPdu, maxRepetitions) pMod.apiBulkPDU.setVarBinds(reqPdu, varBinds) return snmpDispatcher.sendPdu(authData, transportTarget, reqPdu, cbFun=_cbFun)
def n_VarName_exit(self, cbCtx, node): snmpEngine, ctx = cbCtx mibViewCtl = ctx['mibViewController'] if 'modName' in ctx: mibViewCtl.mibBuilder.loadModules(ctx['modName']) if 'objectName' in ctx: objectName = ctx['objectName'] else: objectName = None modName = ctx.get('modName', '') if objectName: oid, label, suffix = mibViewCtl.getNodeName(objectName, modName) else: oid, label, suffix = mibViewCtl.getFirstNodeName(modName) if sys.version_info[0] < 3: intTypes = (int, long) else: intTypes = (int, ) if [x for x in suffix if not isinstance(x, intTypes)]: raise error.PySnmpError('Cant resolve object at: %s' % (suffix, )) modName, nodeDesc, _suffix = mibViewCtl.getNodeLocation(oid) mibNode, = mibViewCtl.mibBuilder.importSymbols(modName, nodeDesc) if not hasattr(self, '_MibTableColumn'): self._MibTableColumn, = mibViewCtl.mibBuilder.importSymbols( 'SNMPv2-SMI', 'MibTableColumn') if isinstance(mibNode, self._MibTableColumn): # Table column if 'objectIndices' in ctx: modName, nodeDesc, _suffix = mibViewCtl.getNodeLocation( mibNode.name[:-1]) mibNode, = mibViewCtl.mibBuilder.importSymbols( modName, nodeDesc) suffix = suffix + mibNode.getInstIdFromIndices( *ctx['objectIndices']) else: if 'objectIndices' in ctx: raise error.PySnmpError('Cant resolve indices: %s' % (ctx['objectIndices'], )) ctx['varName'] = oid + suffix if 'objectName' in ctx: del ctx['objectName'] if 'objectIndices' in ctx: del ctx['objectIndices']