From 6d0b76cef167d1f619412104e9ea2b67d2b405a0 Mon Sep 17 00:00:00 2001 From: Ilya Etingof Date: Sat, 3 Aug 2019 11:03:19 +0200 Subject: Add USM master and localized keys configuration support Added new optional parameters to `addUsmUser()` and `hlapi.UsmUserData()` functions allowing specifying key material type being passed to the respective routines. Plain-text pass-phrase remains the default, while user can change that to `master` or `localized` types. Refer to RFC3414 for technical details on SNMP USM key localization algorithm. --- CHANGES.txt | 2 +- docs/mibs/PYSNMP-USM-MIB.txt | 15 ++++ docs/source/docs/api-reference.rst | 12 ++- pysnmp/entity/config.py | 65 +++++++++++----- pysnmp/hlapi/__init__.py | 10 +++ pysnmp/hlapi/auth.py | 105 +++++++++++++++++++++----- pysnmp/hlapi/lcd.py | 6 +- pysnmp/smi/mibs/PYSNMP-USM-MIB.py | 5 +- pysnmp/smi/mibs/instances/__PYSNMP-USM-MIB.py | 10 ++- 9 files changed, 184 insertions(+), 46 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index cf8e2dec..88460094 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -2,7 +2,7 @@ Revision 4.4.11, released 2019-08-XX ------------------------------------ -No changes yet +- Added SNMPv3 USM master and localized keys support to LCD configuration Revision 4.4.10, released 2019-07-29 ------------------------------------ diff --git a/docs/mibs/PYSNMP-USM-MIB.txt b/docs/mibs/PYSNMP-USM-MIB.txt index 81e112c7..739ca08e 100644 --- a/docs/mibs/PYSNMP-USM-MIB.txt +++ b/docs/mibs/PYSNMP-USM-MIB.txt @@ -21,6 +21,8 @@ pysnmpUsmMIB MODULE-IDENTITY DESCRIPTION "This MIB module defines objects specific to User Security Model (USM) implementation at PySNMP." + REVISION "201908300000Z" + DESCRIPTION "Added USM key types" REVISION "201707300000Z" DESCRIPTION "Extended authentication key size" REVISION "201704140000Z" @@ -56,6 +58,19 @@ pysnmpUsmDiscovery OBJECT-TYPE DEFVAL { doDiscover } ::= { pysnmpUsmCfg 2 } +pysnmpUsmKeyType OBJECT-TYPE + SYNTAX INTEGER { passphrase (0), master(1), localized(2) } + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION "When configuring USM user, the value of this enumeration + determines how the keys should be treated. The default + value "passphrase" means that given keys are plain-text + pass-phrases, "master" indicates that the keys are pre-hashed + pass-phrases, while "localized" stands for pre-hashed + pass-phrases mixed with SNMP Security Engine ID value." + DEFVAL { passphrase } + ::= { pysnmpUsmCfg 3 } + -- The usmUser Group ************************************************ pysnmpUsmUser OBJECT IDENTIFIER ::= { pysnmpUsmMIBObjects 3 } diff --git a/docs/source/docs/api-reference.rst b/docs/source/docs/api-reference.rst index bc6f5693..b32f4dd0 100644 --- a/docs/source/docs/api-reference.rst +++ b/docs/source/docs/api-reference.rst @@ -217,7 +217,7 @@ User-based The :py:class:`~pysnmp.hlapi.UsmUserData` class provides SNMPv3 User-Based Security Model configuration for SNMP v3 systems. -.. autoclass:: pysnmp.hlapi.UsmUserData(userName, authKey=None, privKey=None, authProtocol=usmNoAuthProtocol, privProtocol=usmNoPrivProtocol, securityEngineId=None) +.. autoclass:: pysnmp.hlapi.UsmUserData(userName, authKey=None, privKey=None, authProtocol=usmNoAuthProtocol, privProtocol=usmNoPrivProtocol, securityEngineId=None, authKeyType=usmKeyTypePassphrase, privKeyType=usmKeyTypePassphrase) **Authentication protocol identifiers** @@ -240,10 +240,16 @@ Security Model configuration for SNMP v3 systems. .. autodata:: pysnmp.hlapi.usmAesBlumenthalCfb192Protocol .. autodata:: pysnmp.hlapi.usmAesBlumenthalCfb256Protocol +**Key material types** + +.. autodata:: pysnmp.hlapi.usmKeyTypePassphrase +.. autodata:: pysnmp.hlapi.usmKeyTypeMaster +.. autodata:: pysnmp.hlapi.usmKeyTypeLocalized + .. note:: - SNMP authentication and encryption keys must be at least *eight* - octets long. + SNMP authentication and encryption keys must be at least *8* + and at most *32* octets long. Transport configuration is I/O framework specific and is described in respective sections. diff --git a/pysnmp/entity/config.py b/pysnmp/entity/config.py index 2a12bc5c..9087c00f 100644 --- a/pysnmp/entity/config.py +++ b/pysnmp/entity/config.py @@ -43,6 +43,11 @@ usmAesCfb192Protocol = aes192.Aes192.serviceID # non-standard but used by many usmAesCfb256Protocol = aes256.Aes256.serviceID # non-standard but used by many vendors usmNoPrivProtocol = nopriv.NoPriv.serviceID +# USM key types (PYSNMP-USM-MIB::pysnmpUsmKeyType) +usmKeyTypePassphrase = 0 +usmKeyTypeMaster = 1 +usmKeyTypeLocalized = 2 + # Auth services authServices = {hmacmd5.HmacMd5.serviceID: hmacmd5.HmacMd5(), hmacsha.HmacSha.serviceID: hmacsha.HmacSha(), @@ -133,7 +138,9 @@ def addV3User(snmpEngine, userName, privProtocol=usmNoPrivProtocol, privKey=None, securityEngineId=None, securityName=None, - # deprecated parameters follow + authKeyType=usmKeyTypePassphrase, + privKeyType=usmKeyTypePassphrase, + # deprecated parameter contextEngineId=None): mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder @@ -141,6 +148,7 @@ def addV3User(snmpEngine, userName, securityName = userName if securityEngineId is None: # backward compatibility securityEngineId = contextEngineId + (snmpEngineID, usmUserEntry, tblIdx1, pysnmpUsmSecretEntry, tblIdx2) = __cookV3UserInfo(snmpEngine, userName, securityEngineId) @@ -162,40 +170,59 @@ def addV3User(snmpEngine, userName, (usmUserEntry.name + (13,) + tblIdx1, 'createAndGo')) ) - # Localize keys - if authProtocol in authServices: - hashedAuthPassphrase = authServices[authProtocol].hashPassphrase( - authKey and authKey or null + if authProtocol not in authServices: + raise error.PySnmpError('Unknown auth protocol %s' % (authProtocol,)) + + if privProtocol not in privServices: + 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 + + masterAuthKey = localAuthKey = authKey + + if authKeyType < usmKeyTypeMaster: # master key is not given + masterAuthKey = authServices[authProtocol].hashPassphrase( + authKey or null ) + + if authKeyType < usmKeyTypeLocalized: # localized key is not given localAuthKey = authServices[authProtocol].localizeKey( - hashedAuthPassphrase, snmpEngineID + masterAuthKey, snmpEngineID ) - else: - raise error.PySnmpError('Unknown auth protocol %s' % (authProtocol,)) - if privProtocol in privServices: - hashedPrivPassphrase = privServices[privProtocol].hashPassphrase( - authProtocol, privKey and privKey or null + # Localize privacy key unless given + + masterPrivKey = localPrivKey = privKey + + privKeyType = pysnmpUsmKeyType.syntax.clone(privKeyType) + + if privKeyType < usmKeyTypeMaster: # master key is not given + masterPrivKey = privServices[privProtocol].hashPassphrase( + authProtocol, privKey or null ) + + if privKeyType < usmKeyTypeLocalized: # localized key is not given localPrivKey = privServices[privProtocol].localizeKey( - authProtocol, hashedPrivPassphrase, snmpEngineID + authProtocol, masterPrivKey, snmpEngineID ) - else: - raise error.PySnmpError('Unknown priv protocol %s' % (privProtocol,)) - # Commit localized keys + # Commit master and 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)) + (pysnmpUsmKeyEntry.name + (3,) + tblIdx1, masterAuthKey), + (pysnmpUsmKeyEntry.name + (4,) + tblIdx1, masterPrivKey)) ) - # Commit passphrases - snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( ((pysnmpUsmSecretEntry.name + (4,) + tblIdx2, 'destroy'),) ) + + # Commit plain-text pass-phrases snmpEngine.msgAndPduDsp.mibInstrumController.writeVars( ((pysnmpUsmSecretEntry.name + (1,) + tblIdx2, userName), (pysnmpUsmSecretEntry.name + (2,) + tblIdx2, authKey), diff --git a/pysnmp/hlapi/__init__.py b/pysnmp/hlapi/__init__.py index df0ad313..8ae16aef 100644 --- a/pysnmp/hlapi/__init__.py +++ b/pysnmp/hlapi/__init__.py @@ -62,3 +62,13 @@ usmAesBlumenthalCfb192Protocol = auth.usmAesBlumenthalCfb192Protocol usmAesBlumenthalCfb256Protocol = auth.usmAesBlumenthalCfb256Protocol """The CFB128-AES-256 Symmetric Encryption Protocol (`draft-blumenthal-aes-usm-04 `_)""" + +usmKeyTypePassphrase = auth.usmKeyTypePassphrase +"""USM key material type - plain-text pass phrase (:RFC:`3414#section-2.6`)""" + +usmKeyTypeMaster = auth.usmKeyTypeMaster +"""USM key material type - hashed pass-phrase AKA master key (:RFC:`3414#section-2.6`)""" + +usmKeyTypeLocalized = auth.usmKeyTypeLocalized +"""USM key material type - hashed pass-phrase hashed with Context SNMP Engine ID (:RFC:`3414#section-2.6`)""" + diff --git a/pysnmp/hlapi/auth.py b/pysnmp/hlapi/auth.py index 2c729b22..13120a6d 100644 --- a/pysnmp/hlapi/auth.py +++ b/pysnmp/hlapi/auth.py @@ -34,21 +34,30 @@ class CommunityData(object): Parameters ---------- - communityIndex: py:class:`str` + communityIndex: :py:class:`str`, :py:class:`~pysnmp.proto.rfc1902.OctetString` Unique index value of a row in snmpCommunityTable. If it is the only positional parameter, it is treated as a *communityName*. - communityName: py:class:`str` + + communityName: :py:class:`str`, :py:class:`~pysnmp.proto.rfc1902.OctetString` SNMP v1/v2c community string. - mpModel: py:class:`int` - SNMP version - 0 for SNMPv1 and 1 for SNMPv2c. - contextEngineId: py:class:`str` + + mpModel: :py:class:`int` + SNMP message processing model AKA SNMP version. Known SNMP versions are: + + * `0` - for SNMP v1 + * `1` - for SNMP v2c (default) + + + contextEngineId: :py:class:`str`, :py:class:`~pysnmp.proto.rfc1902.OctetString` Indicates the location of the context in which management information is accessed when using the community string specified by the above communityName. - contextName: py:class:`str` + + contextName: :py:class:`str`, :py:class:`~pysnmp.proto.rfc1902.OctetString` The context in which management information is accessed when using the above communityName. - tag: py:class:`str` + + tag: :py:class:`str` Arbitrary string that specifies a set of transport endpoints from which a command responder application will accept management requests with given *communityName* or to which @@ -196,6 +205,15 @@ usmAesBlumenthalCfb192Protocol = config.usmAesBlumenthalCfb192Protocol usmAesBlumenthalCfb256Protocol = config.usmAesBlumenthalCfb256Protocol """The CFB128-AES-256 Symmetric Encryption Protocol (`draft-blumenthal-aes-usm-04 `_)""" +usmKeyTypePassphrase = config.usmKeyTypePassphrase +"""USM key material type - plain-text pass phrase (:RFC:`3414#section-2.6`)""" + +usmKeyTypeMaster = config.usmKeyTypeMaster +"""USM key material type - hashed pass-phrase AKA master key (:RFC:`3414#section-2.6`)""" + +usmKeyTypeLocalized = config.usmKeyTypeLocalized +"""USM key material type - hashed pass-phrase hashed with Context SNMP Engine ID (:RFC:`3414#section-2.6`)""" + class UsmUserData(object): """Creates SNMP v3 User Security Model (USM) configuration entry. @@ -212,21 +230,26 @@ class UsmUserData(object): Parameters ---------- - userName: py:class:`str` + userName: :py:class:`str`, :py:class:`~pysnmp.proto.rfc1902.OctetString` A human readable string representing the name of the SNMP USM user. - authKey: py:class:`str` + + Other Parameters + ---------------- + authKey: :py:class:`str`, :py:class:`~pysnmp.proto.rfc1902.OctetString` Initial value of the secret authentication key. If not set, :py:class:`~pysnmp.hlapi.usmNoAuthProtocol` is implied. If set and no *authProtocol* is specified, :py:class:`~pysnmp.hlapi.usmHMACMD5AuthProtocol` takes effect. - privKey: py:class:`str` + + privKey: :py:class:`str`, :py:class:`~pysnmp.proto.rfc1902.OctetString` Initial value of the secret encryption key. If not set, :py:class:`~pysnmp.hlapi.usmNoPrivProtocol` is implied. If set and no *privProtocol* is specified, :py:class:`~pysnmp.hlapi.usmDESPrivProtocol` takes effect. - authProtocol: py:class:`tuple` + + authProtocol: :py:class:`tuple`, :py:class:`~pysnmp.proto.rfc1902.ObjectIdentifier` An indication of whether messages sent on behalf of this USM user can be authenticated, and if so, the type of authentication protocol which is used. @@ -240,7 +263,23 @@ class UsmUserData(object): * :py:class:`~pysnmp.hlapi.usmHMAC192SHA256AuthProtocol` * :py:class:`~pysnmp.hlapi.usmHMAC256SHA384AuthProtocol` * :py:class:`~pysnmp.hlapi.usmHMAC384SHA512AuthProtocol` - privProtocol: py:class:`tuple` + + + securityEngineId: :py:class:`~pysnmp.proto.rfc1902.OctetString` + The snmpEngineID of the authoritative SNMP engine to which a + dateRequest message is to be sent. Will be automatically + discovered from peer if not given. + + See :RFC:`3414#section-2.5.1` for technical explanation. + + securityName: :py:class:`str`, :py:class:`~pysnmp.proto.rfc1902.OctetString` + Together with the snmpEngineID it identifies a row in the + *SNMP-USER-BASED-SM-MIB::usmUserTable* that is to be used + for securing the message. + + See :RFC:`3414#section-2.5.1` for technical explanation. + + privProtocol: :py:class:`tuple`, :py:class:`~pysnmp.proto.rfc1902.ObjectIdentifier` An indication of whether messages sent on behalf of this USM user be encrypted, and if so, the type of encryption protocol which is used. @@ -253,6 +292,29 @@ class UsmUserData(object): * :py:class:`~pysnmp.hlapi.usmAesCfb192Protocol` * :py:class:`~pysnmp.hlapi.usmAesCfb256Protocol` + + authKeyType: :py:class:`int` + Type of `authKey` material. See :RFC:`3414#section-2.6` for + technical explanation. + + Supported key types are: + + * :py:class:`~pysnmp.hlapi.usmKeyTypePassphrase` (default) + * :py:class:`~pysnmp.hlapi.usmKeyTypeMaster` + * :py:class:`~pysnmp.hlapi.usmKeyTypeLocalized` + + + privKeyType: :py:class:`int` + Type of `privKey` material. See :RFC:`3414#section-2.6` for + technical explanation. + + Supported key types are: + + * :py:class:`~pysnmp.hlapi.usmKeyTypePassphrase` (default) + * :py:class:`~pysnmp.hlapi.usmKeyTypeMaster` + * :py:class:`~pysnmp.hlapi.usmKeyTypeLocalized` + + Examples -------- >>> from pysnmp.hlapi import UsmUserData @@ -275,7 +337,9 @@ class UsmUserData(object): authKey=None, privKey=None, authProtocol=None, privProtocol=None, securityEngineId=None, - securityName=None): + securityName=None, + authKeyType=usmKeyTypePassphrase, + privKeyType=usmKeyTypePassphrase): self.userName = userName if securityName is None: self.securityName = userName @@ -302,24 +366,29 @@ class UsmUserData(object): self.privProtocol = privProtocol self.securityEngineId = securityEngineId + self.authKeyType = authKeyType + self.privKeyType = privKeyType def __hash__(self): raise TypeError('%s is not hashable' % self.__class__.__name__) def __repr__(self): - return '%s(userName=%r, authKey=, privKey=, authProtocol=%r, privProtocol=%r, securityEngineId=%r, securityName=%r)' % ( + return '%s(userName=%r, authKey=, privKey=, authProtocol=%r, privProtocol=%r, securityEngineId=%r, securityName=%r, authKeyType=%r, privKeyType=%r)' % ( self.__class__.__name__, self.userName, self.authProtocol, self.privProtocol, self.securityEngineId is None and '' or self.securityEngineId, - self.securityName + self.securityName, + self.authKeyType, + self.privKeyType ) def clone(self, userName=None, authKey=None, privKey=None, authProtocol=None, privProtocol=None, - securityEngineId=None, securityName=None): + securityEngineId=None, securityName=None, + authKeyType=None, privKeyType=None): return self.__class__( userName is None and self.userName or userName, authKey is None and self.authKey or authKey, @@ -327,5 +396,7 @@ class UsmUserData(object): authProtocol is None and self.authProtocol or authProtocol, privProtocol is None and self.privProtocol or privProtocol, securityEngineId is None and self.securityEngineId or securityEngineId, - securityName=securityName is None and self.securityName or securityName + securityName is None and self.securityName or securityName, + authKeyType is None and self.authKeyType or usmKeyTypePassphrase, + privKeyType is None and self.privKeyType or usmKeyTypePassphrase ) diff --git a/pysnmp/hlapi/lcd.py b/pysnmp/hlapi/lcd.py index 9a188b2e..4ffee3fd 100644 --- a/pysnmp/hlapi/lcd.py +++ b/pysnmp/hlapi/lcd.py @@ -58,8 +58,10 @@ class CommandGeneratorLcdConfigurator(AbstractLcdConfigurator): authData.userName, authData.authProtocol, authData.authKey, authData.privProtocol, authData.privKey, - authData.securityEngineId, - securityName=authData.securityName + securityEngineId=authData.securityEngineId, + securityName=authData.securityName, + authKeyType=authData.authKeyType, + privKeyType=authData.privKeyType ) cache['auth'][authDataKey] = authData else: diff --git a/pysnmp/smi/mibs/PYSNMP-USM-MIB.py b/pysnmp/smi/mibs/PYSNMP-USM-MIB.py index b48e3da8..304c7917 100644 --- a/pysnmp/smi/mibs/PYSNMP-USM-MIB.py +++ b/pysnmp/smi/mibs/PYSNMP-USM-MIB.py @@ -34,6 +34,9 @@ if mibBuilder.loadTexts: pysnmpUsmDiscoverable.setDescription('Whether SNMP engi pysnmpUsmDiscovery = MibScalar((1, 3, 6, 1, 4, 1, 20408, 3, 1, 1, 1, 1, 2), Integer32().subtype(subtypeSpec=ConstraintsUnion(SingleValueConstraint(0, 1))).clone(namedValues=NamedValues(("doNotDiscover", 0), ("doDiscover", 1))).clone('doDiscover')).setMaxAccess("readwrite") if mibBuilder.loadTexts: pysnmpUsmDiscovery.setStatus('current') if mibBuilder.loadTexts: pysnmpUsmDiscovery.setDescription('Whether SNMP engine would try to figure out the EngineIDs of its peers by sending discover requests.') +pysnmpUsmKeyType = MibScalar((1, 3, 6, 1, 4, 1, 20408, 3, 1, 1, 1, 1, 3), Integer32().subtype(subtypeSpec=ConstraintsUnion(SingleValueConstraint(0, 2))).clone(namedValues=NamedValues(("passphrase", 0), ("master", 1), ("localized", 2))).clone('passphrase')).setMaxAccess("not-accessible") +if mibBuilder.loadTexts: pysnmpUsmKeyType.setStatus('current') +if mibBuilder.loadTexts: pysnmpUsmKeyType.setDescription('When configuring USM user, the value of this enumeration determines how the keys should be treated. The default value "passphrase" means that given keys are plain-text pass-phrases, "master" indicates that the keys are pre-hashed pass-phrases, while "localized" stands for pre-hashed pass-phrases mixed with SNMP Security Engine ID value.') pysnmpUsmUser = MibIdentifier((1, 3, 6, 1, 4, 1, 20408, 3, 1, 1, 1, 3)) pysnmpUsmSecretTable = MibTable((1, 3, 6, 1, 4, 1, 20408, 3, 1, 1, 1, 2), ) if mibBuilder.loadTexts: pysnmpUsmSecretTable.setStatus('current') @@ -75,4 +78,4 @@ if mibBuilder.loadTexts: pysnmpUsmKeyPriv.setStatus('current') if mibBuilder.loadTexts: pysnmpUsmKeyPriv.setDescription("User's non-localized key used for encryption.") pysnmpUsmMIBCompliances = MibIdentifier((1, 3, 6, 1, 4, 1, 20408, 3, 1, 1, 2, 1)) pysnmpUsmMIBGroups = MibIdentifier((1, 3, 6, 1, 4, 1, 20408, 3, 1, 1, 2, 2)) -mibBuilder.exportSymbols("PYSNMP-USM-MIB", pysnmpUsmCfg=pysnmpUsmCfg, pysnmpUsmDiscoverable=pysnmpUsmDiscoverable, pysnmpUsmKeyEntry=pysnmpUsmKeyEntry, pysnmpUsmKeyTable=pysnmpUsmKeyTable, pysnmpUsmKeyPrivLocalized=pysnmpUsmKeyPrivLocalized, pysnmpUsmMIBCompliances=pysnmpUsmMIBCompliances, pysnmpUsmMIBObjects=pysnmpUsmMIBObjects, pysnmpUsmSecretTable=pysnmpUsmSecretTable, PYSNMP_MODULE_ID=pysnmpUsmMIB, pysnmpUsmSecretEntry=pysnmpUsmSecretEntry, pysnmpUsmMIBConformance=pysnmpUsmMIBConformance, pysnmpUsmUser=pysnmpUsmUser, pysnmpUsmKeyAuth=pysnmpUsmKeyAuth, pysnmpUsmSecretPrivKey=pysnmpUsmSecretPrivKey, pysnmpUsmKeyAuthLocalized=pysnmpUsmKeyAuthLocalized, pysnmpUsmMIB=pysnmpUsmMIB, pysnmpUsmDiscovery=pysnmpUsmDiscovery, pysnmpUsmSecretUserName=pysnmpUsmSecretUserName, pysnmpUsmKeyPriv=pysnmpUsmKeyPriv, pysnmpUsmSecretAuthKey=pysnmpUsmSecretAuthKey, pysnmpUsmSecretStatus=pysnmpUsmSecretStatus, pysnmpUsmMIBGroups=pysnmpUsmMIBGroups) +mibBuilder.exportSymbols("PYSNMP-USM-MIB", pysnmpUsmCfg=pysnmpUsmCfg, pysnmpUsmDiscoverable=pysnmpUsmDiscoverable, pysnmpUsmKeyType=pysnmpUsmKeyType, pysnmpUsmKeyEntry=pysnmpUsmKeyEntry, pysnmpUsmKeyTable=pysnmpUsmKeyTable, pysnmpUsmKeyPrivLocalized=pysnmpUsmKeyPrivLocalized, pysnmpUsmMIBCompliances=pysnmpUsmMIBCompliances, pysnmpUsmMIBObjects=pysnmpUsmMIBObjects, pysnmpUsmSecretTable=pysnmpUsmSecretTable, PYSNMP_MODULE_ID=pysnmpUsmMIB, pysnmpUsmSecretEntry=pysnmpUsmSecretEntry, pysnmpUsmMIBConformance=pysnmpUsmMIBConformance, pysnmpUsmUser=pysnmpUsmUser, pysnmpUsmKeyAuth=pysnmpUsmKeyAuth, pysnmpUsmSecretPrivKey=pysnmpUsmSecretPrivKey, pysnmpUsmKeyAuthLocalized=pysnmpUsmKeyAuthLocalized, pysnmpUsmMIB=pysnmpUsmMIB, pysnmpUsmDiscovery=pysnmpUsmDiscovery, pysnmpUsmSecretUserName=pysnmpUsmSecretUserName, pysnmpUsmKeyPriv=pysnmpUsmKeyPriv, pysnmpUsmSecretAuthKey=pysnmpUsmSecretAuthKey, pysnmpUsmSecretStatus=pysnmpUsmSecretStatus, pysnmpUsmMIBGroups=pysnmpUsmMIBGroups) diff --git a/pysnmp/smi/mibs/instances/__PYSNMP-USM-MIB.py b/pysnmp/smi/mibs/instances/__PYSNMP-USM-MIB.py index 2a83fc37..551e65c2 100644 --- a/pysnmp/smi/mibs/instances/__PYSNMP-USM-MIB.py +++ b/pysnmp/smi/mibs/instances/__PYSNMP-USM-MIB.py @@ -7,17 +7,21 @@ MibScalarInstance, = mibBuilder.importSymbols('SNMPv2-SMI', 'MibScalarInstance') (pysnmpUsmDiscoverable, - pysnmpUsmDiscovery) = mibBuilder.importSymbols( + pysnmpUsmDiscovery, + pysnmpUsmKeyType) = mibBuilder.importSymbols( 'PYSNMP-USM-MIB', 'pysnmpUsmDiscoverable', - 'pysnmpUsmDiscovery' + 'pysnmpUsmDiscovery', + 'pysnmpUsmKeyType' ) __pysnmpUsmDiscoverable = MibScalarInstance(pysnmpUsmDiscoverable.name, (0,), pysnmpUsmDiscoverable.syntax) __pysnmpUsmDiscovery = MibScalarInstance(pysnmpUsmDiscovery.name, (0,), pysnmpUsmDiscovery.syntax) +__pysnmpUsmKeyType = MibScalarInstance(pysnmpUsmKeyType.name, (0,), pysnmpUsmKeyType.syntax) mibBuilder.exportSymbols( "__PYSNMP-USM-MIB", pysnmpUsmDiscoverable=__pysnmpUsmDiscoverable, - pysnmpUsmDiscovery=__pysnmpUsmDiscovery + pysnmpUsmDiscovery=__pysnmpUsmDiscovery, + pysnmpUsmKeyType=__pysnmpUsmKeyType ) -- cgit v1.2.1