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:
- com.sun.management.snmp.SnmpPduFactory
- com.sun.management.snmp.SnmpPduFactoryBER
- com.sun.management.snmp.SnmpPdu
- com.sun.management.snmp.SnmpMsg
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:
- 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.
- The SnmpMsg object is then translated into an SnmpPdu
object.
- The SnmpPdu is analyzed and the corresponding operation
is performed.
Before sending an SNMP packet, Java
DMK performs the following steps:
- 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.
- The SnmpPdu object is translated into an SnmpMsg.
- 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:
- if decodeSnmpPdu() returns null, Java DMK will assume
that the SnmpMsg is unsafe and will drop it.
- if encodeSnmpPdu() returns null, Java DMK will assume
that it cannot send the SnmpPdu safely and will abort the
current request.
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:
- it decodes the SnmpMsg object and returns a fully
initialized SnmpPdu,
- it returns null if it judges the SnmpMsg object to be
unsafe. In this case, Java DMK will drop the SnmpMsg object.
- it throws an SmpStatusException if decoding failed or if
the pdu contains out-of-bounds values. In this case, Java DMK will drop
the SnmpMsg object.
Java DMK expects encodeSnmpPdu()
to behave as follows:
- it encodes the SnmpPdu object and returns a fully
initialized SnmpMsg object.
- it throws an SnmpStatusException if the SnmpPdu
object contains out-of-bounds values.
- it throws an SnmpTooBigException if the SnmpPdu
object does not fit into the internal buffer used by Java DMK.
- it may return null if it fails to secure the SnmpPdu
object. In this case, Java DMK will abort the current request and
reports an error. This probably means that the agent/manager contains a
bug.
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.