RFC 1353

Definitions of Managed Objects for Administration of SNMP Parties

๐Ÿ“… published July 1992, from ietf

RFC 1353: Definitions of Managed Objects for Administration of SNMP Parties ๐ŸŽ€

okay bestie, this is RFC 1353 ๐Ÿ’– and it's all about Definitions of Managed Objects for Administration of SNMP Parties โœจ. It's from the Network Working Group ๐Ÿซถ and it's dated July 1992 ๐Ÿ—“๏ธ.

The authors are K. McCloghrie at Hughes LAN Systems, Inc., J. Davin at MIT Laboratory for Computer Science, and J. Galvin at Trusted Information Systems, Inc. ๐Ÿ‘‘ The category is an IAB standards track protocol ๐Ÿ“ˆ. The header doesn't list anything it obsoletes or updates.


Status of This Memo ๐Ÿ“œ

So this document specifies an IAB standards track protocol for the Internet community, and it's asking for discussion and suggestions for improvements ๐Ÿ—ฃ๏ธ. For the standardization state and status of this protocol, check the current edition of the "IAB Official Protocol Standards" ๐Ÿ“š. Distribution of this memo is unlimited ๐ŸŒˆ.

Abstract ๐Ÿฆ‹

This memo defines a chunk of the Management Information Base (MIB) for network management protocols in TCP/IP-based internets ๐ŸŒ. It describes the SNMP parties from [8] as objects defined using the Internet Standard SMI [1]. These definitions are consistent with the SNMP Security protocols in [9] ๐Ÿ”.

Table of Contents ๐Ÿ—‚๏ธ

   1. The Network Management Framework ...........................    2
   2. Objects ....................................................    2
   2.1 Format of Definitions .....................................    3
   3. Overview ...................................................    3
   3.1 Structure .................................................    3
   3.2 Instance Identifiers ......................................    3
   3.3 Textual Conventions .......................................    4
   4. Definitions ................................................    4
   4.1 The SNMP Party Public Database Group ......................    9
   4.2 The SNMP Party Secrets Database Group .....................   15
   4.3 The SNMP Access Privileges Database Group .................   18
   4.4 The MIB View Database Group ...............................   21
   5. Acknowledgments ............................................   25
   6. References .................................................   25
   7. Security Considerations.....................................   26
   8. Authors' Addresses..........................................   26

1. The Network Management Framework ๐ŸŒธ

the Internet-standard Network Management Framework is made up of three components ๐Ÿงฉ. They are:

  • RFC 1155 defines the SMI, the mechanisms used for describing and naming objects for the purpose of management. RFC 1212 defines a more concise description mechanism, which is wholly consistent with the SMI.
  • RFC 1156 defines MIB-I, the core set of managed objects for the Internet suite of protocols. RFC 1213, defines MIB-II, an evolution of MIB-I based on implementation experience and new operational requirements.
  • RFC 1157 defines the SNMP, the protocol used for network access to managed objects.

And the Framework lets people define new objects for experimenting and evaluating stuff ๐Ÿงชโœจ.

2. Objects ๐Ÿ’…

Managed objects are reached through a virtual information store called the Management Information Base, or MIB ๐Ÿ—„๏ธ. Objects in the MIB are defined using the subset of Abstract Syntax Notation One (ASN.1) [5] that the SMI defines. Each object has a name, a syntax, and an encoding. The name is an object identifier, an administratively assigned name that specifies an object type. The object type together with an object instance uniquely identifies one specific instantiation of the object. For human convenience, we often use a text string, the OBJECT DESCRIPTOR, to refer to the object type too ๐Ÿ™ˆ.

The syntax of an object type defines the abstract data structure for that type, and ASN.1 is the language used for this. But the SMI [1] deliberately restricts which ASN.1 constructs you can use, and it does that explicitly for simplicity ๐Ÿงผ.

The encoding of an object type is simply how that type is represented using its syntax. Tied implicitly to syntax and encoding is how the object type is represented when it's sent over the network ๐Ÿ“ก.

The SMI specifies the use of the basic encoding rules of ASN.1 [6], subject to the additional requirements imposed by SNMP ๐ŸŽ€.

2.1. Format of Definitions

Section 4 has the specification of every object type in this MIB module ๐Ÿ“. The object types are defined using the conventions from the SMI, as amended by the extensions in [7].

3. Overview ๐Ÿงš

3.1. Structure

This MIB has definitions for four tables, a bunch of OBJECT IDENTIFIER assignments, and some conventions for initial use with some of those assignments ๐ŸŒˆ. The four tables are the SNMP Party Public database, the SNMP Party Secrets database, the SNMP Access Control database, and the SNMP Views database.

The Party Public and Party Secrets databases are separate tables on purpose, so they can sit in different parts of the MIB tree namespace ๐ŸŒณ. The Party Secrets database holds secret information, and security demands that only parties using both authentication and privacy can access it. So it lives in its own branch of the MIB tree, which is the easiest way to accommodate that limit ๐Ÿ”’.

The Party Public database is the opposite vibe, with public info about SNMP parties ๐Ÿ“ข. It has the parties' clocks, which need to be readable (but not writeable) by unauthenticated queries. That's because an unauthenticated query of a party's clock is the first step in re-establishing clock synchronization (see [9]) โฐ.

The objects in this MIB are organized into four groups. All four of the groups are mandatory for SNMP implementations that realize the security framework and mechanisms defined in [8] and [9] ๐Ÿ’ช.

3.2. Instance Identifiers

In all four of the tables in this MIB, the object instances are identified by values with an underlying syntax of OBJECT IDENTIFIER ๐Ÿชช. For the Party Public database and the Party Secrets database, the index variable is the party identifier. For the Access Control database and the Views database, there are two index variables, and both have a syntax of OBJECT IDENTIFIER. (Check the INDEX clauses in the MIB definitions below for the specific variables ๐Ÿ‘€.)

According to RFC 1212 [7], section 4.1.6, the syntax of the object(s) in an INDEX clause tells you how to form the instance-identifier ๐Ÿงฎ. For each index object that's object identifier-valued, its contribution to the instance identifier is:

      `n+1' sub-identifiers, where `n' is the number of sub-identifiers
      in the value (the first sub-identifier is `n' itself, following
      this, each sub-identifier in the value is copied).

3.3. Textual Conventions

The datatypes Party, Clock, and TAddress are used as textual conventions in this document ๐Ÿท๏ธ. These textual conventions have NO effect on either the syntax nor the semantics of any managed object. Objects defined using these conventions are always encoded by means of the rules that define their primitive type. So no changes to the SMI or the SNMP are needed to accommodate them, since they're only adopted for the convenience of readers ๐Ÿ“–.

4. Definitions ๐Ÿ“š

Here's the main event, the MIB module itself ๐Ÿ’–.

          RFC1353-MIB DEFINITIONS ::= BEGIN

          IMPORTS
                  system, mib, private, internet    FROM RFC1155-SMI
                  OBJECT-TYPE                       FROM RFC-1212;

          snmpParties     OBJECT IDENTIFIER ::= { mib-2 20 }
          partyAdmin      OBJECT IDENTIFIER ::= { snmpParties 1 }
          partyPublic     OBJECT IDENTIFIER ::= { snmpParties 2 }

          snmpSecrets     OBJECT IDENTIFIER ::= { mib-2 21 }
          partyPrivate    OBJECT IDENTIFIER ::= { snmpSecrets 1 }
          partyAccess     OBJECT IDENTIFIER ::= { snmpSecrets 2 }
          partyViews      OBJECT IDENTIFIER ::= { snmpSecrets 3 }


          --                  Textual Conventions

          --    A textual convention denoting a SNMP party identifier:

          Party ::= OBJECT IDENTIFIER


          --    A party's authentication clock - a non-negative integer
          -- which is incremented as specified/allowed by the party's
          -- Authentication Protocol.
          --    For noAuth, a party's authentication clock is unused and
          -- its value is undefined.
          --    For md5AuthProtocol, a party's authentication clock is a
          -- relative clock with 1-second granularity.

          Clock ::= INTEGER (0..2147483647)


          --    A textual convention denoting a transport service
          -- address.
          --    For rfc1351Domain, a TAddress is 6 octets long,
          -- the initial 4 octets containing the IP-address in
          -- network-byte order and the last 2 containing the
          -- UDP port in network-byte order.

          TAddress ::= OCTET STRING


          --- Definitions of Security Protocols

          partyProtocols
              OBJECT IDENTIFIER ::= { partyAdmin 1 }

          noAuth                  -- The protocol without authentication
              OBJECT IDENTIFIER ::= { partyProtocols 1 }

          noPriv                  -- The protocol without privacy
              OBJECT IDENTIFIER ::= { partyProtocols 3 }

          desPrivProtocol         -- The DES Privacy Protocol
              OBJECT IDENTIFIER ::= { partyProtocols 4 }

          md5AuthProtocol         -- The MD5 Authentication Protocol
              OBJECT IDENTIFIER ::= { partyProtocols 5 }


          --- definitions of Transport Domains

          transportDomains
              OBJECT IDENTIFIER ::= { partyAdmin 2 }

          rfc1351Domain --- RFC-1351 (SNMP over UDP, using SNMP Parties)
              OBJECT IDENTIFIER ::= { transportDomains 1 }

          --- definitions of Proxy Domains

          proxyDomains
              OBJECT IDENTIFIER ::= { partyAdmin 3 }

          noProxy                --- Local operation
              OBJECT IDENTIFIER ::= { proxyDomains 1 }


          ---    Definition of Initial Party Identifiers

          --  When devices are installed, they need to be configured
          --  with an initial set of SNMP parties.  The configuration
          --  of SNMP parties requires (among other things) the
          --  assignment of several OBJECT IDENTIFIERs.  Any local
          --  network administration can obtain the delegated
          --  authority necessary to assign its own OBJECT
          --  IDENTIFIERs.  However, to provide for those
          --  administrations who have not obtained the necessary
          --  authority, this document allocates a branch of the
          --  naming tree for use with the following conventions.

          initialPartyId
              OBJECT IDENTIFIER ::= { partyAdmin 4 }

          --  Note these are identified as "initial" party identifiers
          --  since these allow secure SNMP communication to proceed,
          --  thereby allowing further SNMP parties to be configured
          --  through use of the SNMP itself.

the rest of section 4 is coming up in the next part ๐Ÿ‘€๐Ÿซถ

okay so this is where the spec hands out a starter pack of pre-made SNMP parties for an IP address a.b.c.d ๐ŸŽ€ six of them, numbered 1 through 6, each with its own vibe ๐Ÿ’…

          --  The following definitions identify a party identifier,
          --  and specify the initial values of various object
          --  instances indexed by that identifier.  In addition,
          --  the initial MIB view and access control parameters
          --  assigned, by convention, to these parties are identified.

          --    Party Identifiers for use as initial SNMP parties
          --       at IP address  a.b.c.d

          -- partyIdentity            = { initialPartyId a b c d 1 }
          -- partyTDomain             = { rfc1351Domain }
          -- partyTAddress            = a.b.c.d, 161
          -- partyProxyFor            = { noProxy }
          -- partyAuthProtocol        = { noAuth }
          -- partyAuthClock           = 0
          -- partySecretsAuthPrivate  = ''h    (the empty string)
          -- partyAuthPublic          = ''h    (the empty string)
          -- partyAuthLifetime        = 0
          -- partyPrivProtocol        = { noPriv }
          -- partySecretsPrivPrivate  = ''h    (the empty string)
          -- partyPrivPublic          = ''h    (the empty string)

          -- partyIdentity            = { initialPartyId a b c d 2 }
          -- partyTDomain             = { rfc1351Domain }
          -- partyTAddress            = assigned by local administration
          -- partyProxyFor            = { noProxy }
          -- partyAuthProtocol        = { noAuth }
          -- partyAuthClock           = 0
          -- partySecretsAuthPrivate  = ''h    (the empty string)
          -- partyAuthPublic          = ''h    (the empty string)
          -- partyAuthLifetime        = 0
          -- partyPrivProtocol        = { noPriv }
          -- partySecretsPrivPrivate  = ''h    (the empty string)
          -- partyPrivPublic          = ''h    (the empty string)

          -- partyIdentity            = { initialPartyId a b c d 3 }
          -- partyTDomain             = { rfc1351Domain }
          -- partyTAddress            = a.b.c.d, 161
          -- partyProxyFor            = { noProxy }
          -- partyAuthProtocol        = { md5AuthProtocol }
          -- partyAuthClock           = 0
          -- partySecretsAuthPrivate  = assigned by local administration
          -- partyAuthPublic          = ''h    (the empty string)
          -- partyAuthLifetime        = 300
          -- partyPrivProtocol        = { noPriv }
          -- partySecretsPrivPrivate  = ''h    (the empty string)
          -- partyPrivPublic          = ''h    (the empty string)

          -- partyIdentity            = { initialPartyId a b c d 4 }
          -- partyTDomain             = { rfc1351Domain }
          -- partyTAddress            = assigned by local administration
          -- partyProxyFor            = { noProxy }
          -- partyAuthProtocol        = { md5AuthProtocol }
          -- partyAuthClock           = 0
          -- partySecretsAuthPrivate  = assigned by local administration
          -- partyAuthPublic          = ''h    (the empty string)
          -- partyAuthLifetime        = 300
          -- partyPrivProtocol        = { noPriv }
          -- partySecretsPrivPrivate  = ''h    (the empty string)
          -- partyPrivPublic          = ''h    (the empty string)

          -- partyIdentity            = { initialPartyId a b c d 5 }
          -- partyTDomain             = { rfc1351Domain }
          -- partyTAddress            = a.b.c.d, 161
          -- partyProxyFor            = { noProxy }
          -- partyAuthProtocol        = { md5AuthProtocol }
          -- partyAuthClock           = 0
          -- partySecretsAuthPrivate  = assigned by local administration
          -- partyAuthPublic          = ''h    (the empty string)
          -- partyAuthLifetime        = 300
          -- partyPrivProtocol        = { desPrivProtocol }
          -- partySecretsPrivPrivate  = assigned by local administration
          -- partyPrivPublic          = ''h    (the empty string)

          -- partyIdentity            = { initialPartyId a b c d 6 }
          -- partyTDomain             = { rfc1351Domain }
          -- partyTAddress            = assigned by local administration
          -- partyProxyFor            = { noProxy }
          -- partyAuthProtocol        = { md5AuthProtocol }
          -- partyAuthClock           = 0
          -- partySecretsAuthPrivate  = assigned by local administration
          -- partyAuthPublic          = ''h    (the empty string)
          -- partyAuthLifetime        = 300
          -- partyPrivProtocol        = { desPrivProtocol }
          -- partySecretsPrivPrivate  = assigned by local administration
          -- partyPrivPublic          = ''h   (the empty string)

parties 1 and 2 are the no-auth, no-priv babes ๐Ÿ“ parties 3 and 4 bring md5 authentication ๐Ÿ” and party 5 and party 6 take it up a notch with DES privacy too ๐Ÿ”ฅ the spec also says what the addresses look like for each one, so some are a.b.c.d, 161 and some are "assigned by local administration" ๐ŸŒธ

next up are the starter access control parameters. these are the who-can-talk-to-who rules, each one pairing a target with a subject and listing privileges as numbers ๐Ÿ‘‘

          --  The initial access control parameters assigned, by
          --  convention, to these parties are:

          -- aclTarget     = { initialPartyId a b c d 1 }
          -- aclSubject    = { initialPartyId a b c d 2 }
          -- aclPrivileges = 3 (Get & Get-Next)

          -- aclTarget     = { initialPartyId a b c d 2 }
          -- aclSubject    = { initialPartyId a b c d 1 }
          -- aclPrivileges = 20 (GetResponse & Trap)

          -- aclTarget     = { initialPartyId a b c d 3 }
          -- aclSubject    = { initialPartyId a b c d 4 }
          -- aclPrivileges = 11 (Get, Get-Next & Set)

          -- aclTarget     = { initialPartyId a b c d 4 }
          -- aclSubject    = { initialPartyId a b c d 3 }
          -- aclPrivileges = 20 (GetResponse & Trap)

          -- aclTarget     = { initialPartyId a b c d 5 }
          -- aclSubject    = { initialPartyId a b c d 6 }
          -- aclPrivileges = 11 (Get, Get-Next & Set)

          -- aclTarget     = { initialPartyId a b c d 6 }
          -- aclSubject    = { initialPartyId a b c d 5 }
          -- aclPrivileges = 20 (GetResponse & Trap)

and then the starter MIB views ๐Ÿ‘€ these say which subtrees each party gets to see, and whether each one is included or excluded, all tied back to those same party identifiers

          --  The initial MIB views assigned, by convention, to
          --  these parties are:

          -- viewParty    = { initialPartyId a b c d 1 }
          -- viewSubtree  = { system }
          -- viewStatus   = { included }
          -- viewMask     = { ''h }

          -- viewParty    = { initialPartyId a b c d 1 }
          -- viewSubtree  = { snmpParties }
          -- viewStatus   = { included }
          -- viewMask     = { ''h }

          -- viewParty    = { initialPartyId a b c d 3 }
          -- viewSubtree  = { internet }
          -- viewStatus   = { included }
          -- viewMask     = { ''h }

          -- viewParty    = { initialPartyId a b c d 3 }
          -- viewSubtree  = { partyPrivate }
          -- viewStatus   = { excluded }
          -- viewMask     = { ''h }

          -- viewParty    = { initialPartyId a b c d 5 }
          -- viewSubtree  = { internet }
          -- viewStatus   = { included }
          -- viewMask     = { ''h }

now for the real object definitions, starting with the Party Public Database group ๐Ÿงš the comment says implementing these objects is mandatory, and that's a whole vibe ๐Ÿ“Œ


          --   The SNMP Party Public Database Group
          --
          -- The non-secret party information.
          --
          -- Implementation of the objects in this group is mandatory.

          partyTable OBJECT-TYPE
              SYNTAX  SEQUENCE OF PartyEntry
              ACCESS  not-accessible
              STATUS  mandatory
              DESCRIPTION
                      "The SNMP Party Public database.

                      An agent must ensure that there is, at all times,
                      a one-to-one correspondence between entries in
                      this table and entries in the partySecretsTable.

                      The creation/deletion of instances in this table
                      via SNMP Set-Requests is not allowed.  Instead,
                      entries in this table are created/deleted as a
                      side-effect of the creation/deletion of
                      corresponding entries in the partySecretsTable.

                      Thus, a SNMP Set-Request whose varbinds contain a
                      reference to a non-existent instance of a
                      partyTable object, but no reference to the
                      corresponding instance of a partySecretsTable
                      object, will be rejected."
          ::= { partyPublic 1 }
heads up bestie: the partyTable can't be created or deleted straight through SNMP Set-Requests ๐Ÿ™… entries show up and vanish as a side-effect of the matching partySecretsTable entries, and a Set-Request that points at a partyTable instance without the matching partySecretsTable instance gets rejected ๐Ÿ’€

the partyEntry is where the non-secret party info lives, and the spec is very clear that it's not the whole story ๐Ÿซถ

          partyEntry OBJECT-TYPE
              SYNTAX  PartyEntry
              ACCESS  not-accessible
              STATUS  mandatory
              DESCRIPTION
                      "Locally held non-secret information about a
                      particular SNMP party, which is available for
                      access by network management.  Note that this does
                      not include all locally held information about a
                      party.  In particular, it does not include the
                      'last-timestamp' (i.e., the timestamp of the last
                      authentic message received) or the 'nonce'
                      values."
              INDEX  { partyIdentity }
              ::= { partyTable 1 }

          PartyEntry ::=
              SEQUENCE {
                  partyIdentity
                      Party,
                  partyTDomain
                      OBJECT IDENTIFIER,
                  partyTAddress
                      TAddress,
                  partyProxyFor
                      Party,
                  partyAuthProtocol
                      OBJECT IDENTIFIER,
                  partyAuthClock
                      Clock,
                  partyAuthPublic
                      OCTET STRING,
                  partyAuthLifetime
                      INTEGER,
                  partyPrivProtocol
                      OBJECT IDENTIFIER,
                  partyPrivPublic

                      OCTET STRING,
                  partyMaxMessageSize
                      INTEGER,
                  partyStatus
                      INTEGER
              }

and now the first few columns of that entry, starting with the party identity itself ๐ŸŒˆ

          partyIdentity  OBJECT-TYPE
              SYNTAX  Party
              ACCESS  read-write
              STATUS  mandatory
              DESCRIPTION
                      "A party identifier uniquely identifying a
                      particular SNMP party."
              ::= { partyEntry 1 }

          partyTDomain  OBJECT-TYPE
              SYNTAX  OBJECT IDENTIFIER
              ACCESS  read-write
              STATUS  mandatory
              DESCRIPTION
                      "Indicates the kind of transport service by which
                      the party receives network management traffic. An
                      example of a transport domain is 'rfc1351Domain'
                      (SNMP over UDP)."
              DEFVAL  { rfc1351Domain }
              ::= { partyEntry 2 }

          partyTAddress  OBJECT-TYPE
              SYNTAX  TAddress
              ACCESS  read-write
              STATUS  mandatory
              DESCRIPTION
                      "The transport service address by which the party
                      receives network management traffic, formatted
                      according to the corresponding value of
                      partyTDomain.  For rfc1351Domain, partyTAddress is
                      formatted as a 4-octet IP Address concatenated
                      with a 2-octet UDP port number."
              DEFVAL  { '000000000000'h }
              ::= { partyEntry 3 }

          partyProxyFor OBJECT-TYPE
              SYNTAX  Party
              ACCESS  read-write
              STATUS  mandatory
              DESCRIPTION
                      "The identity of a second SNMP party or other
                      management entity with which interaction may be
                      necessary to satisfy received management requests.
                      In this context, the distinguished value { noProxy
                      } signifies that the party responds to received
                      management requests by entirely local mechanisms."
              DEFVAL  { noProxy }
              ::= { partyEntry 4 }

ok the address and identity columns are giving everything they need to be giving โœจ the auth and privacy columns are next, and they get a little more intense ๐Ÿ”๐Ÿ‘€

okay the party stuff is where this gets SO juicy ๐Ÿ’…๐ŸŽ€

          partyAuthProtocol OBJECT-TYPE
              SYNTAX  OBJECT IDENTIFIER
              ACCESS  read-write
              STATUS  mandatory
              DESCRIPTION
                      "The authentication protocol by which all messages
                      generated by the party are authenticated as to
                      origin and integrity.  In this context, the value
                      { noAuth } signifies that messages generated by
                      the party are not authenticated."
              DEFVAL  { md5AuthProtocol }
              ::= { partyEntry 5 }

          partyAuthClock OBJECT-TYPE
              SYNTAX  Clock
              ACCESS  read-write
              STATUS  mandatory
              DESCRIPTION
                      "The authentication clock which represents the
                      local notion of the current time specific to the
                      party.  This value must not be decremented unless
                      the party's secret information is changed
                      simultaneously, at which time the party's nonce
                      and last-timestamp values must also be reset to
                      zero, and the new value of the clock,
                      respectively."
              DEFVAL  { 0 }
              ::= { partyEntry 6 }

          partyAuthPublic OBJECT-TYPE
              SYNTAX  OCTET STRING -- for md5AuthProtocol: (SIZE (0..16))
              ACCESS  read-write
              STATUS  mandatory
              DESCRIPTION
                      "A publically-readable value for the party.

                      Depending on the party's authentication protocol,
                      this value may be needed to support the party's
                      authentication protocol.  Alternatively, it may be
                      used by a manager during the procedure for
                      altering secret information about a party.  (For
                      example, by altering the value of an instance of
                      this object in the same SNMP Set-Request used to
                      update an instance of partyAuthPrivate, a
                      subsequent Get-Request can determine if the Set-
                      Request was successful in the event that no
                      response to the Set-Request is received, see RFC
                      1352.)

                      The length of the value is dependent on the
                      party's authentication protocol.  If not used by
                      the authentication protocol, it is recommended
                      that agents support values of any length up to and
                      including the length of the corresponding
                      partyAuthPrivate object."
              DEFVAL  { ''h }      -- the empty string
              ::= { partyEntry 7 }

          partyAuthLifetime OBJECT-TYPE
              SYNTAX  INTEGER (0..2147483647)
              ACCESS  read-write
              STATUS  mandatory
              DESCRIPTION
                      "The lifetime (in units of seconds) which
                      represents an administrative upper bound on
                      acceptable delivery delay for protocol messages
                      generated by the party."
              DEFVAL  { 300 }
              ::= { partyEntry 8 }

          partyPrivProtocol OBJECT-TYPE
              SYNTAX  OBJECT IDENTIFIER
              ACCESS  read-write
              STATUS  mandatory
              DESCRIPTION
                      "The privacy protocol by which all protocol
                      messages received by the party are protected from
                      disclosure.  In this context, the value { noPriv }
                      signifies that messages received by the party are
                      not protected."
              DEFVAL  { noPriv }
              ::= { partyEntry 9 }

          partyPrivPublic OBJECT-TYPE
              SYNTAX  OCTET STRING -- for desPrivProtocol: (SIZE (0..16))
              ACCESS  read-write
              STATUS  mandatory
              DESCRIPTION

                      "A publically-readable value for the party.

                      Depending on the party's privacy protocol, this
                      value may be needed to support the party's privacy
                      protocol.  Alternatively, it may be used by a
                      manager as a part of its procedure for altering
                      secret information about a party.  (For example,
                      by altering the value of an instance of this
                      object in the same SNMP Set-Request used to update
                      an instance of partyPrivPrivate, a subsequent
                      Get-Request can determine if the Set-Request was
                      successful in the event that no response to the
                      Set-Request is received, see RFC 1352.)

                      The length of the value is dependent on the
                      party's privacy protocol.  If not used by the
                      privacy protocol, it is recommended that agents
                      support values of any length up to and including
                      the length of the corresponding partyPrivPrivate
                      object."
              DEFVAL  { ''h }     -- the empty string
              ::= { partyEntry 10 }

          partyMaxMessageSize OBJECT-TYPE
              SYNTAX  INTEGER (484..65507)
              ACCESS  read-write
              STATUS  mandatory
              DESCRIPTION
                      "The maximum length in octets of a SNMP message
                      which this party will accept.  For parties which
                      execute at an agent, the agent initializes this
                      object to the maximum length supported by the
                      agent, and does not let the object be set to any
                      larger value.  For parties which do not execute at
                      the agent, the agent must allow the manager to set
                      this object to any legal value, even if it is
                      larger than the agent can generate."
              DEFVAL  { 484 }
              ::= { partyEntry 11 }

          partyStatus OBJECT-TYPE
              SYNTAX  INTEGER  { valid(1), invalid(2) }
              ACCESS  read-only
              STATUS  mandatory
              DESCRIPTION
                      "The status of the locally-held information on a
                      particular SNMP party.

                      The instance of this object for a particular party
                      and the instance of partySecretsStatus for the
                      same party always have the same value.

                      This object will typically provide unrestricted
                      read-only access to the status of parties.  In
                      contrast, partySecretsStatus will typically
                      provide restricted read-write access to the status
                      of parties."
              ::= { partyEntry 12 }


          --   The SNMP Party Secrets Database Group

          -- The secret party information
          --
          -- Implementation of the objects in this group is mandatory.

          partySecretsTable OBJECT-TYPE
              SYNTAX  SEQUENCE OF PartySecretsEntry
              ACCESS  not-accessible
              STATUS  mandatory
              DESCRIPTION
                      "The SNMP Party Secrets database."
          ::= { partyPrivate 1 }

          partySecretsEntry OBJECT-TYPE
              SYNTAX  PartySecretsEntry
              ACCESS  not-accessible
              STATUS  mandatory
              DESCRIPTION
                      "Locally held secret information about a
                      particular SNMP party, which is available for
                      access by network management.

                      When a SNMP Set-Request is used to update the
                      values of instances of objects in this table, it
                      is recommended that the same SNMP Set-Request also
                      alter the value of a non-secret object instance
                      (e.g., an instance of partyAuthPublic or
                      partyPrivPublic).  This allows a Get-Request of
                      that non-secret object instance to determine if
                      the Set-Request was successful in the event that
                      no response which matches the Set-Request is
                      received, see RFC 1352."
              INDEX  { partySecretsIdentity }
              ::= { partySecretsTable 1 }

          PartySecretsEntry ::=
              SEQUENCE {
                  partySecretsIdentity
                      Party,
                  partySecretsAuthPrivate
                      OCTET STRING,
                  partySecretsPrivPrivate
                      OCTET STRING,
                  partySecretsStatus
                      INTEGER
              }

          partySecretsIdentity  OBJECT-TYPE
              SYNTAX  Party
              ACCESS  read-write
              STATUS  mandatory
              DESCRIPTION
                      "A party identifier uniquely identifying a
                      particular SNMP party."
              ::= { partySecretsEntry 1 }

          partySecretsAuthPrivate OBJECT-TYPE
              SYNTAX  OCTET STRING   -- for md5AuthProtocol: (SIZE (16))
              ACCESS  read-write
              STATUS  mandatory
              DESCRIPTION
                      "An encoding of the party's private authentication
                      key which may be needed to support the
                      authentication protocol.  Although the value of
                      this variable may be altered by a management
                      operation (e.g., a SNMP Set-Request), its value
                      can never be retrieved by a management operation:
                      when read, the value of this variable is the zero
                      length OCTET STRING.

                      The private authentication key is NOT directly
                      represented by the value of this variable, but
                      rather it is represented according to an encoding.
                      This encoding is the bitwise exclusive-OR of the
                      old key with the new key, i.e., of the old private
                      authentication key (prior to the alteration) with
                      the new private authentication key (after the
                      alteration).  Thus, when processing a received
                      protocol Set operation, the new private
                      authentication key is obtained from the value of
                      this variable as the result of a bitwise
                      exclusive-OR of the variable's value and the old
                      private authentication key.  In calculating the
                      exclusive-OR, if the old key is shorter than the
                      new key, zero-valued padding is appended to the
                      old key.  If no value for the old key exists, a
                      zero-length OCTET STRING is used in the
                      calculation."
              DEFVAL  { ''h }     -- the empty string
              ::= { partySecretsEntry 2 }

okay so this is where the secrets live ๐Ÿ”๐Ÿคซ partySecretsPrivPrivate holds the party's private encryption key, the one the privacy protocol might need. you can change it with a Set, but you can literally never read it back. every read hands you back a zero-length OCTET STRING, so it's giving write-only diary ๐Ÿ™ˆ๐Ÿ’œ

          partySecretsPrivPrivate OBJECT-TYPE
              SYNTAX  OCTET STRING   -- for desPrivProtocol: (SIZE (16))
              ACCESS  read-write
              STATUS  mandatory
              DESCRIPTION
                      "An encoding of the party's private encryption key
                      which may be needed to support the privacy
                      protocol.  Although the value of this variable may
                      be altered by a management operation (e.g., a SNMP
                      Set-Request), its value can never be retrieved by
                      a management operation: when read, the value of
                      this variable is the zero length OCTET STRING.

                      The private encryption key is NOT directly
                      represented by the value of this variable, but
                      rather it is represented according to an encoding.
                      This encoding is the bitwise exclusive-OR of the
                      old key with the new key, i.e., of the old private
                      encryption key (prior to the alteration) with the
                      new private encryption key (after the alteration).
                      Thus, when processing a received protocol Set
                      operation, the new private encryption key is
                      obtained from the value of this variable as the
                      result of a bitwise exclusive-OR of the variable's
                      value and the old private encryption key.  In
                      calculating the exclusive-OR, if the old key is
                      shorter than the new key, zero-valued padding is
                      appended to the old key.  If no value for the old
                      key exists, a zero-length OCTET STRING is used in
                      the calculation."
              DEFVAL  { ''h }     -- the empty string
              ::= { partySecretsEntry 3 }

ok the sneaky part ๐Ÿ•ต๏ธโ€โ™€๏ธโœจ the value you store isn't the key itself. it's the XOR of the old key and the new key. so when a Set comes in, the new key gets worked out by XOR-ing the incoming value with the old key. if the old key is shorter, zero padding gets added to the end of it first, and if there's no old key at all, a zero-length string is used instead. the default is the empty string, the big "nothing here" energy ๐Ÿซถ


partySecretsStatus is the on/off switch for all the local stuff a party needs ๐Ÿ’… setting it to valid(1) makes sure valid local knowledge exists, which means the party has to show up in both this table and the partyTable. making a partyTable entry happens as a direct result of making one here (not in the aclTable or viewTable, those don't get made this way).

setting invalid(2) wipes out all the local knowledge for that party ๐Ÿ’€ that includes anything in the partyTable, partySecretsTable, aclTable, and viewTable that points at it. whether the agent actually deletes the invalidated row is up to the implementation, so management stations need to be ready to get back rows that aren't in use. to tell them apart, look at partySecretsStatus.

          partySecretsStatus OBJECT-TYPE
              SYNTAX  INTEGER  { valid(1), invalid(2) }
              ACCESS  read-write
              STATUS  mandatory
              DESCRIPTION
                      "The status of the locally-held information on a
                      particular SNMP party.

                      Setting an instance of this object to the value
                      'valid(1)' has the effect of ensuring that valid
                      local knowledge exists for the corresponding
                      party.  For valid local knowledge to exist, there
                      must be corresponding instances of each object in
                      this table and in the partyTable.  Thus, the
                      creation of instances in the partyTable (but not
                      in the aclTable or viewTable) occurs as a direct
                      result of the creation of instances in this table.

                      Setting an instance of this object to the value
                      'invalid(2)' has the effect of invalidating all
                      local knowledge of the corresponding party,
                      including the invalidating of any/all entries in
                      the partyTable, the partySecretsTable, the
                      aclTable, and the viewTable which reference said
                      party.

                      It is an implementation-specific matter as to
                      whether the agent removes an invalidated entry
                      from the table.  Accordingly, management stations
                      must be prepared to receive from agents tabular
                      information corresponding to entries not currently
                      in use.  Proper interpretation of such entries
                      requires examination of the relevant
                      partySecretsStatus object."
              DEFVAL  { valid }
              ::= { partySecretsEntry 4 }

next up is the access privileges database ๐Ÿ‘‘ this group is the one that lets SNMP itself configure brand new parties or fiddle with who's allowed to do what to whom. implementing it is mandatory, no skipping!

          --  The SNMP Access Privileges Database Group

          --  This group of objects allows the SNMP itself to be used to
          --  configure new SNMP parties, or to manipulate the access
          --  privileges of existing parties.
          --
          --  Implementation of the objects in this group is mandatory.


          aclTable OBJECT-TYPE
              SYNTAX  SEQUENCE OF AclEntry
              ACCESS  not-accessible
              STATUS  mandatory
              DESCRIPTION
                      "The access privileges database."
          ::= { partyAccess 1 }
          aclEntry OBJECT-TYPE
              SYNTAX  AclEntry
              ACCESS  not-accessible
              STATUS  mandatory
              DESCRIPTION
                      "The access privileges for a particular requesting
                      SNMP party in accessing a particular target SNMP
                      party."
              INDEX  { aclTarget, aclSubject }
              ::= { aclTable 1 }

          AclEntry ::=
              SEQUENCE {
                  aclTarget
                      Party,
                  aclSubject
                      Party,
                  aclPrivileges
                      INTEGER,
                  aclStatus
                      INTEGER
              }

so each acl row is about a pair: a target (the party whose management operations are being limited) and a subject (the party asking for them) ๐ŸŽฏ the row's index is the target and subject together.

          aclTarget OBJECT-TYPE
              SYNTAX  Party
              ACCESS  read-write
              STATUS  mandatory
              DESCRIPTION
                      "The target SNMP party whose performance of
                      management operations is constrained by this set
                      of access privileges."
              ::= { aclEntry 1 }

          aclSubject OBJECT-TYPE
              SYNTAX  Party
              ACCESS  read-write
              STATUS  mandatory
              DESCRIPTION
                      "The subject SNMP party whose requests for
                      management operations to be performed is
                      constrained by this set of access privileges."
              ::= { aclEntry 2 }

          aclPrivileges OBJECT-TYPE
              SYNTAX  INTEGER (0..31)
              ACCESS  read-write
              STATUS  mandatory
              DESCRIPTION

                      "The access privileges which govern what
                      management operations a particular target party
                      may perform when requested by a particular subject
                      party.  These privileges are specified as a sum of
                      values, where each value specifies a SNMP PDU type
                      by which the subject party may request a permitted
                      operation.  The value for a particular PDU type is
                      computed as 2 raised to the value of the ASN.1
                      context-specific tag for the appropriate SNMP PDU
                      type.  The values (for the tags defined in RFC
                      1157) are defined in RFC 1351 as:

                       Get         :   1
                       GetNext     :   2
                       GetResponse :   4
                       Set         :   8
                       Trap        :  16

                      The null set is represented by the value zero."
              DEFVAL  { 3 }      -- Get & Get-Next
              ::= { aclEntry 3 }

ok the math for aclPrivileges is actually cute ๐Ÿงฎโœจ each PDU type gets a value of 2 to the power of its ASN.1 tag, and you add them all up into one total. Get is 1, GetNext is 2, GetResponse is 4, Set is 8, and Trap is 16. nothing allowed at all is just zero, and the default is 3, which is Get plus GetNext (aka the "just looking, thanks" combo) ๐Ÿ‘€

          aclStatus OBJECT-TYPE
              SYNTAX  INTEGER  { valid(1), invalid(2) }
              ACCESS  read-write
              STATUS  mandatory
              DESCRIPTION
                      "The status of the access privileges for a
                      particular requesting SNMP party in accessing a
                      particular target SNMP party.  Setting an instance
                      of this object to the value 'invalid(2)' has the
                      effect of invalidating the corresponding access
                      privileges.

                      It is an implementation-specific matter as to
                      whether the agent removes an invalidated entry
                      from the table.  Accordingly, management stations
                      must be prepared to receive from agents tabular
                      information corresponding to entries not currently
                      in use.  Proper interpretation of such entries
                      requires examination of the relevant aclStatus
                      object."
              DEFVAL  { valid }
              ::= { aclEntry 4 }

aclStatus is the same vibe as partySecretsStatus ๐Ÿซ  invalid(2) kills the access privileges for that requesting/target pair, but whether the row actually gets removed is up to the agent. so yeah, management stations need to be ready for leftover rows, and they tell live from dead by checking aclStatus.


now the MIB view database ๐ŸชŸ this group does the same job for views, letting SNMP configure parties or change their views, and yep, it's mandatory too.

          --   The MIB View Database Group

          --  This group of objects allows the SNMP itself to be used to
          --  configure new SNMP parties, or to manipulate the MIB
          --  MIB views of existing parties.
          --
          --  Implementation of the objects in this group is mandatory.


          viewTable OBJECT-TYPE
              SYNTAX  SEQUENCE OF ViewEntry
              ACCESS  not-accessible
              STATUS  mandatory
              DESCRIPTION
                      "The table contained in the local database which
                      defines local MIB views.  Each SNMP party has a
                      single MIB view which is defined by two
                      collections of view subtrees: the included view
                      subtrees, and the excluded view subtrees.  Every
                      such subtree, both included and excluded, is
                      defined in this table.

                      To determine if a particular object instance is in
                      a particular SNMP party's MIB view, compare the
                      object instance's Object Identifier with each
                      entry (for this party) in this table.  If none
                      match, then the object instance is not in the MIB
                      view.  If one or more match, then the object
                      instance is included in, or excluded from, the MIB
                      view according to the value of viewStatus in the
                      entry whose value of viewSubtree has the most
                      sub-identifiers.  If multiple entries match and
                      have the same number of sub-identifiers, then the
                      lexicographically greatest instance of viewStatus
                      determines the inclusion or exclusion.

                      An object instance's Object Identifier X matches
                      an entry in this table when the number of sub-
                      identifiers in X is at least as many as in the
                      value of viewSubtree for the entry, and each sub-
                      identifier in the value of viewSubtree matches its
                      corresponding sub-identifier in X.  Two sub-
                      identifiers match either if the corresponding bit
                      of viewMask is zero (the 'wild card' value), or if
                      they are equal.

                      Due to this 'wild card' capability, we introduce
                      the term, a 'family' of view subtrees, to refer to
                      the set of subtrees defined by a particular
                      combination of values of viewSubtree and viewMask.
                      In the case where no 'wild card' is defined in
                      viewMask, the family of view subtrees reduces to a
                      single view subtree."
          ::= { partyViews 1 }

          viewEntry OBJECT-TYPE
              SYNTAX  ViewEntry
              ACCESS  not-accessible
              STATUS  mandatory
              DESCRIPTION
                      "Information on a particular family of view
                      subtrees included in or excluded from a particular
                      SNMP party's MIB view."
              INDEX  { viewParty, viewSubtree }
              ::= { viewTable 1 }

the view check is basically a matching game ๐ŸŽฎ each party's MIB view is built from two piles of view subtrees, the included ones and the excluded ones. to see if an object instance is in a party's view, you compare its Object Identifier against that party's entries. no matches means it's not in the view. if there are matches, the entry with the most sub-identifiers decides whether it's included or excluded, and if two matches have the same number of sub-identifiers, the lexicographically greatest viewStatus wins ๐Ÿ†

the 'wild card' bit is where it gets extra ๐ŸŒˆ a sub-identifier matches if the matching bit in viewMask is zero, or if the two sub-identifiers are just equal. that's why the spec talks about a "family" of view subtrees, meaning every subtree you get from one combo of viewSubtree and viewMask. if viewMask has no wild cards at all, the family is just one subtree, and that's that ๐Ÿ’–

ViewEntry ::=
    SEQUENCE {
        viewParty
            Party,
        viewSubtree
            OBJECT IDENTIFIER,
        viewStatus
            INTEGER,
        viewMask
            OCTET STRING
    }

viewParty  OBJECT-TYPE
    SYNTAX  Party
    ACCESS  read-write
    STATUS  mandatory
    DESCRIPTION
            "The SNMP party whose single MIB view includes or
            excludes a particular family of view subtrees."
    ::= { viewEntry 1 }

viewSubtree OBJECT-TYPE
    SYNTAX  OBJECT IDENTIFIER
    ACCESS  read-write
    STATUS  mandatory
    DESCRIPTION
            "The view subtree which, in combination with the
            corresponding instance of viewMask, defines a
            family of view subtrees.  This family is included
            in, or excluded from the particular SNMP party's
            MIB view, according to the value of the
            corresponding instance of viewStatus."
    ::= { viewEntry 2 }

viewStatus OBJECT-TYPE
    SYNTAX  INTEGER  {
                included(1),
                excluded(2),
                invalid(3)
            }
    ACCESS  read-write
    STATUS  mandatory
    DESCRIPTION
            "The status of a particular family of view
            subtrees within the particular SNMP party's MIB
            view.  The value 'included(1)' indicates that the
            corresponding instances of viewSubtree and
            viewMask define a family of view subtrees included
            in the MIB view.  The  value 'excluded(2)'
            indicates that the corresponding instances of
            viewSubtree and viewMask define a family of view
            subtrees excluded from the MIB view.

            Setting an instance of this object to the value
            'invalid(3)' has the effect of invalidating the
            presence or absence of the corresponding family of
            view subtrees in the corresponding SNMP party's
            MIB view.

            It is an implementation-specific matter as to
            whether the agent removes an invalidated entry
            from the table.  Accordingly, management stations
            must be prepared to receive from agents tabular
            information corresponding to entries not currently
            in use.  Proper interpretation of such entries
            requires examination of the relevant viewStatus
            object."
    DEFVAL  { included }
    ::= { viewEntry 3 }

viewMask  OBJECT-TYPE
    SYNTAX  OCTET STRING (SIZE (0..16))
    ACCESS  read-write
    STATUS  mandatory
    DESCRIPTION
            "The bit mask which, in combination with the
            corresponding instance of viewSubtree, defines a
            family of view subtrees.

            Each bit of this bit mask corresponds to a sub-
            identifier of viewSubtree, with the most
            significant bit of the i-th octet of this octet
            string value (extended if necessary, see below)
            corresponding to the (8*i - 7)-th sub-identifier,
            and the least significant bit of the i-th octet of
            this octet string corresponding to the (8*i)-th
            sub-identifier, where i is in the range 1 through
            16.

            Each bit of this bit mask specifies whether or not
            the corresponding sub-identifiers must match when
            determining if an Object Identifier is in this
            family of view subtrees; a '1' indicates that an
            exact match must occur; a '0' indicates 'wild
            card', i.e., any sub-identifier value matches.

            Thus, the Object Identifier X of an object
            instance is contained in a family of view subtrees
            if the following criteria are met:

                 for each sub-identifier of the value of
                 viewSubtree, either:

                      the i-th bit of viewMask is 0, or

                      the i-th sub-identifier of X is equal to
                      the i-th sub-identifier of the value of
                      viewSubtree.

            If the value of this bit mask is M bits long and
            there are more than M sub-identifiers in the
            corresponding instance of viewSubtree, then the
            bit mask is extended with 1's to be the required
            length.

            Note that when the value of this object is the
            zero-length string, this extension rule results in
            a mask of all-1's being used (i.e., no 'wild
            card'), and the family of view subtrees is the one
            view subtree uniquely identified by the
            corresponding instance of viewSubtree."
    DEFVAL  { ''h }
    ::= { viewEntry 4 }


END

5. Acknowledgments โœจ

this doc was cooked on behalf of the SNMP Security Working Group of the Internet Engineering Task Force ๐Ÿซถ the authors wanna give a big thank you to the working group members and everyone else who helped make this happen ๐Ÿ’–

6. References ๐Ÿ“š

[1] Rose, M., and K. McCloghrie, "Structure and Identification of Management Information for TCP/IP based internets", RFC 1155, Performance Systems International, Hughes LAN Systems, May 1990.

[2] McCloghrie, K., and M. Rose, "Management Information Base for Network Management of TCP/IP-based Internets", RFC 1156, Hughes LAN Systems and Performance Systems International, May 1990.

[3] Case, J., M. Fedor, M. Schoffstall, and J. Davin, The Simple Network Management Protocol", RFC 1157, University of Tennessee at Knoxville, Performance Systems International, Performance Systems International, and the MIT Laboratory for Computer Science, May 1990.

[4] McCloghrie K., and M. Rose, Editors, "Management Information Base for Network Management of TCP/IP-based internets", RFC 1213, Performance Systems International, March 1991.

[5] Information processing systems - Open Systems Interconnection - Specification of Abstract Syntax Notation One (ASN.1), International Organization for Standardization, International Standard 8824, December 1987.

[6] Information processing systems - Open Systems Interconnection - Specification of Basic Encoding Rules for Abstract Notation One (ASN.1), International Organization for Standardization, International Standard 8825, December 1987.

[7] Rose, M., and K. McCloghrie, Editors, "Concise MIB Definitions", RFC 1212, Performance Systems International, Hughes LAN Systems, March 1991.

[8] Davin, J., Galvin, J., and K. McCloghrie, "SNMP Administrative Model", RFC 1351, MIT Laboratory for Computer Science, Trusted Information Systems, Inc., Hughes LAN Systems, Inc., July 1992.

[9] Galvin, J., McCloghrie, K., and J. Davin, "SNMP Security Protocols", RFC 1352, Trusted Information Systems, Inc., Hughes LAN Systems, Inc., MIT Laboratory for Computer Science, July 1992.

Security Considerations ๐Ÿ”

okay bestie, this part is SERIOUS ๐Ÿ˜ญ security issues are discussed in section 3.1. and also in RFCs 1351 and 1352, so go read those before you do anything with this stuff ๐Ÿ™ˆ

Authors' Addresses ๐Ÿฆ‹

Keith McCloghrie
Hughes LAN Systems, Inc.
Mountain View, CA 94043

Phone:  (415) 966-7934
EMail:  kzm@hls.com


James R. Davin
MIT Laboratory for Computer Science
545 Technology Square
Cambridge, MA 02139

Phone:  (617) 253-6020
EMail:  jrd@ptt.lcs.mit.edu


James M. Galvin
Trusted Information Systems, Inc.
3060 Washington Road, Route 97
Glenwood, MD 21738

Phone:  (301) 854-6889
EMail:  galvin@tis.com
๐Ÿ“ฆ where this page comes from