summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIlya Etingof <etingof@gmail.com>2019-08-03 13:40:49 +0200
committerIlya Etingof <etingof@gmail.com>2019-08-03 15:18:03 +0200
commit65e92864a32600019a24e61594c4f996c1f2d411 (patch)
treeda1e8c32277e14fd5cc911ba3cf300fb576d8d37
parent450943ab97d4a4ae48d0b71e119eae23a2686a61 (diff)
downloadpysnmp-git-65e92864a32600019a24e61594c4f996c1f2d411.tar.gz
Add USM master and localized keys configuration support (#295)
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.
-rw-r--r--CHANGES.txt2
-rw-r--r--docs/mibs/PYSNMP-USM-MIB.txt15
-rw-r--r--docs/source/docs/api-reference.rst12
-rw-r--r--pysnmp/entity/config.py63
-rw-r--r--pysnmp/hlapi/__init__.py2
-rw-r--r--pysnmp/hlapi/v3arch/__init__.py9
-rw-r--r--pysnmp/hlapi/v3arch/auth.py145
-rw-r--r--pysnmp/hlapi/v3arch/lcd.py6
-rw-r--r--pysnmp/smi/mibs/PYSNMP-USM-MIB.py73
-rw-r--r--pysnmp/smi/mibs/instances/__PYSNMP-USM-MIB.py15
10 files changed, 267 insertions, 75 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 511bbb8b..e5ad5a84 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -102,7 +102,7 @@ Revision 5.0.0, released 2019-08-XX
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 78c3e1ed..d2a799f7 100644
--- a/docs/source/docs/api-reference.rst
+++ b/docs/source/docs/api-reference.rst
@@ -213,7 +213,7 @@ User-based
The :py:class:`~pysnmp.hlapi.v3arch.UsmUserData` class provides SNMPv3 User-Based
Security Model configuration for SNMP v3 systems.
-.. autoclass:: pysnmp.hlapi.v3arch.UsmUserData(userName, authKey=None, privKey=None, authProtocol=USM_AUTH_NONE, privProtocol=USM_PRIV_NONE, securityEngineId=None)
+.. autoclass:: pysnmp.hlapi.v3arch.UsmUserData(userName, authKey=None, privKey=None, authProtocol=USM_AUTH_NONE, privProtocol=USM_PRIV_NONE, securityEngineId=None, authKeyType=USM_KEY_TYPE_PASSPHRASE, privKeyType=USM_KEY_TYPE_PASSPHRASE)
**Authentication protocol identifiers**
@@ -236,10 +236,16 @@ Security Model configuration for SNMP v3 systems.
.. autodata:: pysnmp.hlapi.v3arch.USM_PRIV_CFB192_AES_BLUMENTHAL
.. autodata:: pysnmp.hlapi.v3arch.USM_PRIV_CFB256_AES_BLUMENTHAL
+**Key material types**
+
+.. autodata:: pysnmp.hlapi.USM_KEY_TYPE_PASSPHRASE
+.. autodata:: pysnmp.hlapi.USM_KEY_TYPE_MASTER
+.. autodata:: pysnmp.hlapi.USM_KEY_TYPE_LOCALIZED
+
.. 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 5b3940e1..ea6ca00b 100644
--- a/pysnmp/entity/config.py
+++ b/pysnmp/entity/config.py
@@ -51,6 +51,11 @@ USM_PRIV_CFB256_AES_BLUMENTHAL = aes256.AesBlumenthal256.SERVICE_ID # semi-stan
USM_PRIV_NONE = nopriv.NoPriv.SERVICE_ID
+# USM key types (PYSNMP-USM-MIB::pysnmpUsmKeyType)
+USM_KEY_TYPE_PASSPHRASE = 0
+USM_KEY_TYPE_MASTER = 1
+USM_KEY_TYPE_LOCALIZED = 2
+
AUTH_SERVICES = {
hmacmd5.HmacMd5.SERVICE_ID: hmacmd5.HmacMd5(),
hmacsha.HmacSha.SERVICE_ID: hmacsha.HmacSha(),
@@ -164,8 +169,9 @@ def addV3User(snmpEngine, userName,
authProtocol=USM_AUTH_NONE, authKey=None,
privProtocol=USM_PRIV_NONE, privKey=None,
securityEngineId=None,
- securityName=None):
-
+ securityName=None,
+ authKeyType=USM_KEY_TYPE_PASSPHRASE,
+ privKeyType=USM_KEY_TYPE_PASSPHRASE):
mibBuilder = snmpEngine.msgAndPduDsp.mibInstrumController.mibBuilder
if securityName is None:
@@ -198,47 +204,62 @@ def addV3User(snmpEngine, userName,
snmpEngine=snmpEngine
)
- # Localize keys
- if authProtocol in AUTH_SERVICES:
- hashedAuthPassphrase = AUTH_SERVICES[authProtocol].hashPassphrase(
- authKey and authKey or null
+ 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
+
+ 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(
- hashedAuthPassphrase, snmpEngineID
+ masterAuthKey, snmpEngineID
)
- else:
- raise error.PySnmpError('Unknown auth protocol %s' % (authProtocol,))
+ # Localize privacy key unless given
+
+ masterPrivKey = localPrivKey = privKey
- if privProtocol in PRIV_SERVICES:
- hashedPrivPassphrase = PRIV_SERVICES[privProtocol].hashPassphrase(
- authProtocol, privKey and privKey or null
+ privKeyType = pysnmpUsmKeyType.syntax.clone(privKeyType)
+
+ 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, 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.writeMibObjects(
(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),
snmpEngine=snmpEngine
)
- # Commit passphrases
-
snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects(
(pysnmpUsmSecretEntry.name + (4,) + tblIdx2, 'destroy'),
snmpEngine=snmpEngine
)
+ # Commit plain-text pass-phrases
snmpEngine.msgAndPduDsp.mibInstrumController.writeMibObjects(
(pysnmpUsmSecretEntry.name + (1,) + tblIdx2, userName),
(pysnmpUsmSecretEntry.name + (2,) + tblIdx2, authKey),
diff --git a/pysnmp/hlapi/__init__.py b/pysnmp/hlapi/__init__.py
index 6da0e1cd..31aef89a 100644
--- a/pysnmp/hlapi/__init__.py
+++ b/pysnmp/hlapi/__init__.py
@@ -5,5 +5,5 @@
# License: http://snmplabs.com/pysnmp/license.html
#
-# default is synchronous asyncore-based API
+# default is v3arch
from pysnmp.hlapi.v3arch import *
diff --git a/pysnmp/hlapi/v3arch/__init__.py b/pysnmp/hlapi/v3arch/__init__.py
index 565df668..901c488e 100644
--- a/pysnmp/hlapi/v3arch/__init__.py
+++ b/pysnmp/hlapi/v3arch/__init__.py
@@ -60,3 +60,12 @@ usmAesBlumenthalCfb192Protocol = auth.usmAesBlumenthalCfb192Protocol
usmAesBlumenthalCfb256Protocol = auth.usmAesBlumenthalCfb256Protocol
"""The CFB128-AES-256 Symmetric Encryption Protocol (`draft-blumenthal-aes-usm-04 <https:://tools.ietf.org/html/draft-blumenthal-aes-usm-04#section-3>`_)"""
+
+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/v3arch/auth.py b/pysnmp/hlapi/v3arch/auth.py
index 18b4b328..16363546 100644
--- a/pysnmp/hlapi/v3arch/auth.py
+++ b/pysnmp/hlapi/v3arch/auth.py
@@ -18,7 +18,8 @@ __all__ = [
'USM_PRIV_CBC56_DES', 'USM_PRIV_CBC168_3DES',
'USM_PRIV_CFB128_AES', 'USM_PRIV_CFB192_AES',
'USM_PRIV_CFB256_AES', 'USM_PRIV_CFB192_AES_BLUMENTHAL',
- 'USM_PRIV_CFB256_AES_BLUMENTHAL',
+ 'USM_PRIV_CFB256_AES_BLUMENTHAL', 'USM_KEY_TYPE_PASSPHRASE',
+ 'USM_KEY_TYPE_MASTER', 'USM_KEY_TYPE_LOCALIZED',
# backward-compatible constants
'usm3DESEDEPrivProtocol', 'usmAesCfb128Protocol',
'usmAesCfb192Protocol', 'usmAesCfb256Protocol',
@@ -27,7 +28,8 @@ __all__ = [
'usmHMACSHAAuthProtocol', 'usmHMAC128SHA224AuthProtocol',
'usmHMAC192SHA256AuthProtocol', 'usmHMAC256SHA384AuthProtocol',
'usmHMAC384SHA512AuthProtocol', 'usmNoAuthProtocol',
- 'usmNoPrivProtocol'
+ 'usmNoPrivProtocol', 'usmKeyTypePassphrase', 'usmKeyTypeMaster',
+ 'usmKeyTypeLocalized'
]
@@ -59,22 +61,41 @@ USM_PRIV_CBC56_DES = config.USM_PRIV_CBC56_DES
"""The CBC56-DES Symmetric Encryption Protocol (:RFC:`3414#section-8`)"""
USM_PRIV_CBC168_3DES = config.USM_PRIV_CBC168_3DES
-"""The 3DES-EDE Symmetric Encryption Protocol (`draft-reeder-snmpv3-usm-3desede-00 <https:://tools.ietf.org/html/draft-reeder-snmpv3-usm-3desede-00#section-5>`_)"""
+"""The 3DES-EDE Symmetric Encryption Protocol (`draft-reeder-snmpv3-usm-3desede-00 \
+<https:://tools.ietf.org/html/draft-reeder-snmpv3-usm-3desede-00#section-5>`_)"""
USM_PRIV_CFB128_AES = config.USM_PRIV_CFB128_AES
"""The CFB128-AES-128 Symmetric Encryption Protocol (:RFC:`3826#section-3`)"""
USM_PRIV_CFB192_AES = config.USM_PRIV_CFB192_AES
-"""The CFB128-AES-192 Symmetric Encryption Protocol (`draft-blumenthal-aes-usm-04 <https:://tools.ietf.org/html/draft-blumenthal-aes-usm-04#section-3>`_) with Reeder key localization"""
+"""The CFB128-AES-192 Symmetric Encryption Protocol (`draft-blumenthal-aes-usm-04 \
+<https:://tools.ietf.org/html/draft-blumenthal-aes-usm-04#section-3>`_) \
+with Reeder key localization"""
USM_PRIV_CFB256_AES = config.USM_PRIV_CFB256_AES
-"""The CFB128-AES-256 Symmetric Encryption Protocol (`draft-blumenthal-aes-usm-04 <https:://tools.ietf.org/html/draft-blumenthal-aes-usm-04#section-3>`_) with Reeder key localization"""
+"""The CFB128-AES-256 Symmetric Encryption Protocol (`draft-blumenthal-aes-usm-04 \
+<https:://tools.ietf.org/html/draft-blumenthal-aes-usm-04#section-3>`_) \
+with Reeder key localization"""
USM_PRIV_CFB192_AES_BLUMENTHAL = config.USM_PRIV_CFB192_AES_BLUMENTHAL
-"""The CFB128-AES-192 Symmetric Encryption Protocol (`draft-blumenthal-aes-usm-04 <https:://tools.ietf.org/html/draft-blumenthal-aes-usm-04#section-3>`_)"""
+"""The CFB128-AES-192 Symmetric Encryption Protocol (`draft-blumenthal-aes-usm-04 \
+<https:://tools.ietf.org/html/draft-blumenthal-aes-usm-04#section-3>`_)"""
USM_PRIV_CFB256_AES_BLUMENTHAL = config.USM_PRIV_CFB256_AES_BLUMENTHAL
-"""The CFB128-AES-256 Symmetric Encryption Protocol (`draft-blumenthal-aes-usm-04 <https:://tools.ietf.org/html/draft-blumenthal-aes-usm-04#section-3>`_)"""
+"""The CFB128-AES-256 Symmetric Encryption Protocol (`draft-blumenthal-aes-usm-04 \
+<https:://tools.ietf.org/html/draft-blumenthal-aes-usm-04#section-3>`_)"""
+
+# USM key types (PYSNMP-USM-MIB::pysnmpUsmKeyType)
+
+USM_KEY_TYPE_PASSPHRASE = config.USM_KEY_TYPE_PASSPHRASE
+"""USM key material type - plain-text pass phrase (:RFC:`3414#section-2.6`)"""
+
+USM_KEY_TYPE_MASTER = config.USM_KEY_TYPE_MASTER
+"""USM key material type - hashed pass-phrase AKA master key (:RFC:`3414#section-2.6`)"""
+
+USM_KEY_TYPE_LOCALIZED = config.USM_KEY_TYPE_LOCALIZED
+"""USM key material type - hashed pass-phrase hashed with Context SNMP Engine ID \
+(:RFC:`3414#section-2.6`)"""
# Backward-compatible protocol IDs
usmNoAuthProtocol = USM_AUTH_NONE
@@ -93,6 +114,10 @@ usmAesCfb256Protocol = USM_PRIV_CFB256_AES
usmAesBlumenthalCfb192Protocol = USM_PRIV_CFB192_AES_BLUMENTHAL
usmAesBlumenthalCfb256Protocol = USM_PRIV_CFB256_AES_BLUMENTHAL
+usmKeyTypePassphrase = USM_KEY_TYPE_PASSPHRASE
+usmKeyTypeMaster = USM_KEY_TYPE_MASTER
+usmKeyTypeLocalized = USM_KEY_TYPE_LOCALIZED
+
class CommunityData(object):
"""Creates SNMP v1/v2c configuration entry.
@@ -109,21 +134,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
@@ -253,21 +287,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.
@@ -281,7 +320,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.
@@ -294,6 +349,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
@@ -316,8 +394,9 @@ class UsmUserData(object):
authKey=None, privKey=None,
authProtocol=None, privProtocol=None,
securityEngineId=None,
- securityName=None):
-
+ securityName=None,
+ authKeyType=USM_KEY_TYPE_PASSPHRASE,
+ privKeyType=USM_KEY_TYPE_PASSPHRASE):
self.userName = userName
if securityName is None:
@@ -353,6 +432,8 @@ 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__)
@@ -360,17 +441,22 @@ class UsmUserData(object):
def __repr__(self):
return ('%s(userName=%r, authKey=<AUTHKEY>, privKey=<PRIVKEY>, '
'authProtocol=%r, privProtocol=%r, securityEngineId=%r, '
- 'securityName=%r)') % (
- self.__class__.__name__, self.userName,
- self.authProtocol, self.privProtocol,
+ 'securityName=%r, authKeyType=%r, privKeyType=%r)') % (
+ self.__class__.__name__,
+ self.userName,
+ self.authProtocol,
+ self.privProtocol,
self.securityEngineId is None and '<DEFAULT>' 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,
@@ -378,4 +464,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 USM_KEY_TYPE_PASSPHRASE,
+ privKeyType is None and self.privKeyType or USM_KEY_TYPE_PASSPHRASE
+ )
diff --git a/pysnmp/hlapi/v3arch/lcd.py b/pysnmp/hlapi/v3arch/lcd.py
index 0e1eb9c5..f01f6107 100644
--- a/pysnmp/hlapi/v3arch/lcd.py
+++ b/pysnmp/hlapi/v3arch/lcd.py
@@ -67,8 +67,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
diff --git a/pysnmp/smi/mibs/PYSNMP-USM-MIB.py b/pysnmp/smi/mibs/PYSNMP-USM-MIB.py
index 7b1686aa..17ed7f63 100644
--- a/pysnmp/smi/mibs/PYSNMP-USM-MIB.py
+++ b/pysnmp/smi/mibs/PYSNMP-USM-MIB.py
@@ -132,35 +132,39 @@ pysnmpUsmCfg = _PysnmpUsmCfg_ObjectIdentity(
)
-class _PysnmpUsmDiscoverable_Type(Integer32):
- defaultValue = 1
+class _PysnmpUsmKeyType_Type(Integer32):
+ defaultValue = 0
subtypeSpec = Integer32.subtypeSpec
subtypeSpec += ConstraintsUnion(
SingleValueConstraint(
*(0,
- 1)
+ 2)
)
)
namedValues = NamedValues(
- *(("discoverable", 1),
- ("notDiscoverable", 0))
+ *(("passphrase", 0),
+ ("master", 1),
+ ("localized", 2))
)
-
-_PysnmpUsmDiscoverable_Type.__name__ = "Integer32"
-_PysnmpUsmDiscoverable_Object = MibScalar
-pysnmpUsmDiscoverable = _PysnmpUsmDiscoverable_Object(
- (1, 3, 6, 1, 4, 1, 20408, 3, 1, 1, 1, 1, 1),
- _PysnmpUsmDiscoverable_Type()
+_PysnmpUsmKeyType_Type.__name__ = "Integer32"
+_PysnmpUsmKeyType_Object = MibScalar
+pysnmpUsmKeyType = _PysnmpUsmKeyType_Object(
+ (1, 3, 6, 1, 4, 1, 20408, 3, 1, 1, 1, 1, 3),
+ _PysnmpUsmKeyType_Type()
)
-pysnmpUsmDiscoverable.setMaxAccess("read-write")
+pysnmpUsmKeyType.setMaxAccess("not-accessible")
if mibBuilder.loadTexts:
- pysnmpUsmDiscoverable.setStatus("current")
+ pysnmpUsmKeyType.setStatus("current")
if mibBuilder.loadTexts:
- pysnmpUsmDiscoverable.setDescription("""\
-Whether SNMP engine would support its discovery by responding to unknown
-clients.
+ 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.
""")
@@ -194,6 +198,42 @@ if mibBuilder.loadTexts:
Whether SNMP engine would try to figure out the EngineIDs of its peers by
sending discover requests.
""")
+
+
+class _PysnmpUsmDiscoverable_Type(Integer32):
+ defaultValue = 1
+
+ subtypeSpec = Integer32.subtypeSpec
+ subtypeSpec += ConstraintsUnion(
+ SingleValueConstraint(
+ *(0,
+ 1)
+ )
+ )
+ namedValues = NamedValues(
+ *(("discoverable", 1),
+ ("notDiscoverable", 0))
+ )
+
+
+_PysnmpUsmDiscoverable_Type.__name__ = "Integer32"
+_PysnmpUsmDiscoverable_Object = MibScalar
+pysnmpUsmDiscoverable = _PysnmpUsmDiscoverable_Object(
+ (1, 3, 6, 1, 4, 1, 20408, 3, 1, 1, 1, 1, 1),
+ _PysnmpUsmDiscoverable_Type()
+)
+pysnmpUsmDiscoverable.setMaxAccess("read-write")
+if mibBuilder.loadTexts:
+ pysnmpUsmDiscoverable.setStatus("current")
+if mibBuilder.loadTexts:
+ pysnmpUsmDiscoverable.setDescription("""\
+Whether SNMP engine would support its discovery by responding to unknown
+clients.
+""")
+
+
+
+
_PysnmpUsmSecretTable_Object = MibTable
pysnmpUsmSecretTable = _PysnmpUsmSecretTable_Object(
(1, 3, 6, 1, 4, 1, 20408, 3, 1, 1, 1, 2)
@@ -441,6 +481,7 @@ mibBuilder.exportSymbols(
"pysnmpUsmCfg": pysnmpUsmCfg,
"pysnmpUsmDiscoverable": pysnmpUsmDiscoverable,
"pysnmpUsmDiscovery": pysnmpUsmDiscovery,
+ "pysnmpUsmKeyType": pysnmpUsmKeyType,
"pysnmpUsmSecretTable": pysnmpUsmSecretTable,
"pysnmpUsmSecretEntry": pysnmpUsmSecretEntry,
"pysnmpUsmSecretUserName": pysnmpUsmSecretUserName,
diff --git a/pysnmp/smi/mibs/instances/__PYSNMP-USM-MIB.py b/pysnmp/smi/mibs/instances/__PYSNMP-USM-MIB.py
index 5ee026d0..261ee401 100644
--- a/pysnmp/smi/mibs/instances/__PYSNMP-USM-MIB.py
+++ b/pysnmp/smi/mibs/instances/__PYSNMP-USM-MIB.py
@@ -19,10 +19,12 @@ MibScalarInstance, = mibBuilder.importSymbols(
)
(pysnmpUsmDiscoverable,
- pysnmpUsmDiscovery) = mibBuilder.importSymbols(
+ pysnmpUsmDiscovery,
+ pysnmpUsmKeyType) = mibBuilder.importSymbols(
'PYSNMP-USM-MIB',
'pysnmpUsmDiscoverable',
- 'pysnmpUsmDiscovery'
+ 'pysnmpUsmDiscovery',
+ 'pysnmpUsmKeyType'
)
_pysnmpUsmDiscoverable = MibScalarInstance(
@@ -35,8 +37,15 @@ _pysnmpUsmDiscovery = MibScalarInstance(
pysnmpUsmDiscovery.syntax
)
+_pysnmpUsmKeyType = MibScalarInstance(
+ pysnmpUsmKeyType.name, (0,),
+ pysnmpUsmKeyType.syntax
+)
+
+
mibBuilder.exportSymbols(
"__PYSNMP-USM-MIB",
pysnmpUsmDiscoverable=_pysnmpUsmDiscoverable,
- pysnmpUsmDiscovery=_pysnmpUsmDiscovery
+ pysnmpUsmDiscovery=_pysnmpUsmDiscovery,
+ pysnmpUsmKeyType = _pysnmpUsmKeyType
)