Copyright 2004 Sun Microsystems, Inc. All rights reserved.
This software is the proprietary information of Sun Microsystems, Inc.
Use is subject to license terms.

Copyright 2004 Sun Microsystems, Inc. Tous droits réservés.
Ce logiciel est proprieté de Sun Microsystems, Inc.
Distribué par des licences qui en restreignent l'utilisation.

Implementing SNMP security with Java DMK 5.1

Java DMK 5.1 provides several means of implementing SNMP security.

First, Java DMK 5.1 provides an SNMP v3 adaptor, which lets you benefit of the SNMP v3 security, as defined by RFC 2574. This should be the preferred mean to implement security whenever secure SNMP agents are needed. All SNMP v3 security aspects are handled completely at SNMP adaptor level. Hence the instrumentation of a MIB does not depend on which protocol version it will be accessed through. MIBs that were developed against Java DMK 4.2 can thus be directly registered into the new SnmpAdaptorServerV3, and will benefit of the whole SNMP v3 security mechanisms.

In addition, earlier versions of Java DMK used to provide a hook - via the SnmpPduFactory, which enabled the implementation of authentication and encryption on top of the SNMP protocol adaptor. This could be used to implement security in a proprietary way over the regular SNMP v1/v2 PDUs. In Java DMK 5.1, this hook has been preserved. It is however recommended to migrate those SNMP applications that need better security than the regular SNMP v1/v2 community-based mechanism to standard SNMP v3 security.

For more information on SNMP v3 security, refer to the AgentV3,AgentEncryptV3,SyncManagerV3 and SyncManagerEncryptV3 examples in the
installDir/SUNWjdmk/5.1/examples/current/Snmp/Agent and installDir/SUNWjdmk/5.1/examples/current/Snmp/Manager directories.

Note that the Java DMK 4.2 applications which have implemented their own PDU factory will have to be revisited if they need to be imported in a Java DMK 5.1 SnmpAdaptorServerV3, as the SnmpPduFactory developed for SNMP v1/v2 PDUs will not be compatible with SNMP v3 PDUs.

The SnmpPduFactory hook provided by Java DMK involves the following Java classes:

The goal of this document is to explain how to use these classes. The first section describes how Java DMK encodes and decodes SNMP packets (and introduces SnmpPdu and SnmpMsg). The second section explains the conversion between SnmpPdu and SnmpMsg (and introduces SnmpPduFactory and SnmpPduFactoryBER). The last section describes how to implement and set up a new SnmpPduFactory object.

How Java DMK decodes and encodes SNMP packets

After receiving an SNMP packet, Java DMK performs the following steps:
  1. The received bytes are translated into an SnmpMsg object by the Message Processing Subsystem. If the SNMP protocol version of the original request was v1/v2, this step simply involves the BER decoding of the ASN.1 Message sequence as defined in RFC 1901. If the SNMP protocol version of the original request was v3, the Message Processing Subsystem will in addition invoke the security subsystem in order to authenticate and decrypt the message.
  2. The SnmpMsg object is then translated into an SnmpPdu object.
  3. The SnmpPdu is analyzed and the corresponding operation is performed.
Before sending an SNMP packet, Java DMK performs the following steps:
  1. An SnmpPdu object is initialized according to the requested operation. This could be either an SnmpPduPacket (v1/v2) or an SnmpScopedPduPacket (v3) - see Javadoc of com.sun.management.snmp.SnmpPdu.
  2. The SnmpPdu object is translated into an SnmpMsg.
  3. The SnmpMsg is then passed to the Message Processing Subsystem, and then translated into bytes. If the SNMP protocol version is v1/v2, this step simply involves the BER encoding of the ASN.1 Message sequence as defined in RFC 1901. If the SNMP protocol version is v3, the Message Processing Subsystem will in addition invoke the Security Subsystem in order to sign and encrypt the message.
The SnmpPdu object is the fully decoded description of the SNMP request. In particular, it includes the operation type (get, set...), the list of variables to be operated upon, the request identifier, the protocol version...
abstract class SnmpPdu {
        ...
        public int version ;
        public int type ;
        public int requestId ;
        public SnmpVarBind[] varBindList ;
        ...
}
The SnmpMsg is a partially decoded representation of the SNMP request. Only the protocol version and security parameters are decoded. All the other parameters remain encoded.

The SnmpMsg class is the base class derived from the Message syntax from RFC 1157 and RFC 1901, and SNMPv3Message from RFC 2572. The SnmpMessage class which was already present in Java DMK 4.2 derives from SnmpMsg and represents a SNMP v1 or v2 Message as described in RFC 1157 and RFC 1901. As SNMP v3 introduces additional security parameters, the SnmpMessage class can only be used for v1/v2 messages. SnmpPduFactory implementations that make direct use of this class will therefore need to be updated if they need to be imported into a Java DMK 5.1 SNMP v3 protocol adaptor. However, they do not need to be changed as long as the old SnmpAdaptorServer is used.

abstract class SnmpMsg {
        ...
        public int version ;
        ...
}
class SnmpMessage extends SnmpMsg {
        ...
        public byte[] community ;
        public byte[] data ;
        ...
}

The SnmpPduFactory interface

When Java DMK needs to translate an SnmpMsg object into an SnmpPduobject, it delegates this task to an object which implements SnmpPduFactory, as follows:
interface SnmpPduFactory {

  // Makes an SnmpPdu from an SnmpMsg
  public SnmpPdu decodeSnmpPdu(SnmpMsg msg) 
  throws SnmpStatusException ;
  
  // Makes an SnmpMsg from an SnmpPdu
  public SnmpMsg encodeSnmpPdu(SnmpPdu pdu, int maxPktSize)
  throws SnmpStatusException, SnmpTooBigException ;
  
}
Note: the SnmpPduFactory also has two additional methods inherited from Java DMK 4.2, decodePdu(...) and encodePdu(...)which are now deprecated but kept for backward compatibility.

Java DMK provides a default implementation of this interface: it is named SnmpPduFactoryBER and it is used automatically unless stated otherwise. The SnmpPduFactoryBER methods control every incoming or outgoing SNMP PDUs:

Therefore, it's possible to implement a security policy, by using an SnmpPduFactory class. However, it is recommended to rely rather on the standard SNMP v3 policy. As a matter of fact, using the SnmpPduFactory to implement additional levels of security does only make sense on a v1/v2 framework, when SNMP v3 is not an option (e.g. the Management Console can only use v2).

Implementing a new SnmpPduFactory class

Java DMK expects decodeSnmpPdu() to behave as follows:
Java DMK expects encodeSnmpPdu() to behave as follows:
As SnmpPdu and SnmpMsg are abstract class, it is recommended to delegate the creation/initialization of these classes to an instance of the provided SnmpPduFactoryBER, and to work on the returned result.

The setPduFactory() method enables the SnmpPduFactory object used by the SNMP adaptor to be changed, as follows:

  ...
  myAdaptor.setPduFactory(new MyFireWallPduFactory()) ;
  ...
In Java DMK 4.2 the SnmpPduFactory was attached to the SnmpPeer object. In Java DMK 5.1 the SnmpPduFactory is attached to the SnmpSession. Factory set via deprecated SnmpPeer API is reused in Java DMK 5.1. It can be changed using the setPduFactory method, as follows:
  ...
  SnmpSession mySession = new SnmpSession() ;
  mySession.setPduFactory(new MyFireWallPduFactory()) ;
  mySession.snmpGet(myPeer, this, myVarBindList) ;
  ...

WARNING : Setting 2 different factories in the peer and the session can lead to unpredictable behavior. Use the same factory is you set it at the 2 levels.