Configuring Users

 

The USM model of the SNMPv3 specification provides the following to facilitate secure communication between SNMPv3 entities.

This is done by authenticating the user who sends the message. The management applications originate requests on behalf of a principal or a user. This principal is configured to guard the message against security attacks. Similarly, agent entities have users configured to communicate with management applications. Unauthorized users are not allowed to communicate with these entities.

 

The USMUserTablelink to javadocs class maintains the table of configured users in the SNMPv3 entity. When an application wishes to configure a new user, an instance of the USMUserEntrylink to javadocs needs to be created and added to this table. USMUserEntry holds configuration data specific to each user for a given SNMPv3 entity. In other words, the authentication key and privacy key are localized keys that are derived using the respective passwords and the authoritative engineID. Therefore, a management application needs to know the engineID of the agent to create a user entry. The SnmpEngineEntrylink to javadocs class holds data specific to a particular SNMPv3 entity and provides a unique mapping between the internet address and port of an entity to the engineID. The SnmpEngineTablelink to javadocs class maintains the table of known engines.

 

Discovery

 

SNMPv3 entities acting as management applications use the IP address and port of the peer entity to find the engineID of those peer agent entities. The SnmpEngineEntry class supports the discovery process through which the engineID value is known before they can communicate. SnmpEngineEntry represents a particular SNMP entity and provides a unique mapping between the internet address and port of an SNMP entity. This SNMP entity may act as an agent or as a manager entity. The SnmpEngineEntry class also maintains the host, port, time, and boots values for each SNMP entity. For the entities acting as a manager, these values represent the remote SNMP agent values. For the entities acting as an agent, the values represent their own values.

 

Each SnmpEngineEntry object created is added to the SnmpEngineTable. The SnmpEngineTable maintains a table of SnmpEngineEntry objects.

 

Method I

 

Following are the steps to perform the discovery process using the discoverEngineID() method.

  1. Create SnmpEngineEntry and add it to the SnmpEngineTable. The following code illustrates how applications access SnmpEngineTable and add an entry to it.

SnmpEngineEntry snmpEntry = new SnmpEngineEntry(String address, int port);

//Get the SnmpEngineTable reference

SnmpEngineTable engineTable = SnmpAPI.getSnmpEngine();

//Add the entry to the list of SnmpEngineEntry objects

engineTable.addEntry(snmpEntry);

 

Note that applications do not have to instantiate the SnmpEngineTable. It is instantiated from the SnmpAPI constructor. The getSnmpEngine() method of the SnmpAPI class gets the SnmpEngineTable reference. The addEntry() adds the SnmpEngineEntry to the list of SnmpEngineEntry objects maintained in SnmpEngineTable class.

  1. Perform the discovery process using the discoverEngineID() method.

snmpEntry.discoverEngineID(SnmpSession session);

 

The discoverEngineID() performs a synchronous discovery process to find the engineID of the SNMP peer entity. This sends a NoAuthNoPriv message with userName "initial" to the host and port of this SnmpEngineEntry instance.

  1. Validate the discovery process. If the discovery is not successful, the removeEntry() method is called to delete the SnmpEngineEntry from the list of SnmpEngineEntry objects.

 

if(snmpEntry.getEngineID() == null)

{

System.out.println("Discovery failed.");

engineTable.removeEntry(snmpEntry);

}

else

{

System.out.println("Discovery succeeded.");

}

 

Method II

 

Discovery can also be done without using the discoverEngineID() method. This is a simple GET request made with userName set to "initial". Following are the steps to perform the discovery.

  1. After adding the entry to the SnmpEngineTable, use setCommand() to send an SNMP GET request. The command constants are defined in the SnmpAPI class. The following command sets the constant to GET_REQ_MSG to perform an SNMP GET operation.

engineTable.addEntry(snmpEntry);

pdu.setVersion(SnmpAPI.SNMP_VERSION_3);

pdu.setCommand(SnmpAPI.GET_REQ_MSG);

  1. The setUserName() method sets the principal on whose behalf the request is to be made.

pdu.setUserName("initial".getBytes());

  1. The syncSend(pdu) method sends SnmpPDU synchronously.

SnmpPDU res_pdu = session.syncSend(pdu);

  1. Validate the response PDU to find out if the discovery is successful.

if(res_pdu == null)

{

//request timed out

//remove entry

}

else

{

SnmpOID oid = res_pdu.getObjectID(0);

String unknownEngineIdOID = ".1.3.6.1.6.3.15.1.1.4.0";

if(oid != null && oid.toString().equals(unknownEngineIdOID))

{

//discovery succeeded

}

else

{

//discovery failed

//remove entry

}

}

 

Time Synchronization

 

After the engineID for a given IP address and port is discovered, time synchronization can be performed. The following code performs time sync with the remote host. The engineBoots and engineTime are updated in the SnmpEngineEntry when the response is received. The following code creates an instance of USMUserEntry with the user name and the engineID.

 

SnmpEngineEntry snmpEntry = engineTable.getEntry(host, port);

byte[] engineID = snmpEntry.getEngineID();

byte[] userName = "userName".getBytes();

USMUserEntry usmEntry = new USMUserEntry(userName, engineID);

 

Applications can configure the security level using the setSecurityLevel(byte level) method of USMUserEntry. The security level is set to one of the following.

usmEntry.setSecurityLevel(Snmp3Message.AUTH_PRIV);

 

If authenticated communication is required, the authentication protocol and the password or authentication key must be set after setting the security level. The supported authentication protocols are MD5 and SHA. The constants NO_AUTH, MD5_AUTH, and SHA_AUTH are defined in USMUserEntry.

 

Method I

 

Following are the steps to perform time synchronization using the timeSync() method.

  1. Set the authentication parameters, authentication password, authentication protocol, and authentication key.

//Set authentication password and protocol

byte[] authPassword = "authPwd".getbytes();

usmEntry.setAuthPassword(authPassword);

usmEntry.setAuthProtocol(USMUserEntry.MD5_AUTH);

//Set authentication key

byte[] authKey = USMUtils.password_to_key(usmEntry.getAuthProtocol(), authPassword, authPassword.length, engineID);

usmEntry.setAuthKey(authKey);

usmEntry.setSecurityLevel(Snmp3Message.AUTH_NO_PRIV);

 

Note that if the authentication password is set by the application, it is converted to the authentication key using authProtocol, user name, and engine ID available in the entry. If authentication key is supplied by the application, it is directly used in authenticated communication with the peer SNMP entities.

  1. Then, configure the privacy parameters, privacy password, privacy protocol, and privacy key, using the following commands.

//Set privacy password and protocol

byte[] privPassword = "privPwd".getbytes();

usmEntry.setPrivPassword(privPassword);

usmEntry.setPrivProtocol(USMUserEntry.CBC_DES);

//Set privacy key

byte[] privKey = USMUtils.password_to_key(usmEntry.getAuthProtocol(), privPassword, privPassword.length, engineID);

usmEntry.setPrivKey(privKey);

usmEntry.setSecurityLevel(Snmp3Message.AUTH_PRIV);

  1. Now that the entry is configured with the required security parameters, it can be added to USMUserTable. The setEngineEntry() method sets the SnmpEngineEntry reference. When a new USMUserEntry instance is created, its corresponding SnmpEngineEntry should be set to maintain the timeliness values for the authentication purpose. The following code illustrates how applications access USMUserTable and add an entry to it.

usmEntry.setEngineEntry(snmpEntry);

usmTable.addEntry(usmEntry);

  1. Now, perform the time synchronization with the remote host by using the timeSync() method. Once the response is received, the engineBoots and engineTime is updated in the SnmpEngineEntry.

usmEntry.timeSync(session);

  1. Validate the time synchronization process.

if(snmpEntry.getEngineTime()>0 || snmpEntry.getEngineBoots()>0)

{

>System.out.println("Time Sync successful.");

}

else

{

System.out.println("Time Sync failed.");

usmTable.removeEntry(usmEntry);

}

 

Method II

 

Time synchronization can also be done without using the timeSync() method. This is a simple GET request made for the specified user. Following are the steps to perform the time synchronization.

  1. After adding the entry to the SnmpEngineTable, use setCommand() to send an SNMP GET request. The command constants are defined in the SnmpAPI class. The following command sets the constant to GET_REQ_MSG to perform an SNMP GET operation.

usmTable.addEntry(usmEntry);

SnmpPDU pdu = new SnmpPDU();

pdu.setVersion(SnmpAPI.SNMP_VERSION_3);

pdu.setCommand(SnmpAPI.GET_REQ_MSG);

  1. Use the setUserName() method to set the principal and the syncSend(pdu) method to send SnmpPDU synchronously.

pdu.setUserName(userName);

SnmpPDU res_pdu = session.syncSend(pdu);

  1. Validate the response PDU to find out if the time synchronization is successful.

 

if(res_pdu == null)

{

//timeSync failed

//remove entry

}

else

{

SnmpOID oid = res_pdu.getObjectID(0);

String notInTimeWindowsOID = ".1.3.6.1.6.3.15.1.1.2.0" ;

if(oid != null && oid.toString().equals(notInTimeWindowsOID))

{

//timeSync succeeded

}

else

{

//timeSync failed

//remove entry

}

}

 

Utility Methods

 

The USMUtilslink to javadocs class provides general SNMPv3-related functionality, such as digest authentication, password to key conversion functions, etc. The following section explains the utility methods available in USMUtils.

 

Applications can add both SnmpEngineEntry and USMUserEntry objects to the respective tables by using the following static utility method init_v3_parameters() available in USMUtils.

 

USMUtils.init_v3_parameters(String userName, int authProtocol, String authPassword, String privPassword, String targetHost, int port, SnmpSession session)

 

The init_v3_parameters() method does the following.

The getDigest() method returns the USMUserEntry.MD5_AUTH or USMUserEntry.SHA_AUTH digest. The getKeyChange() method returns the keyChange value required for a key change operation.

 

Using High-Level API

 

The Bean components of the high-level API can be used for the SNMPv3 operations. The Bean has the necessary methods for setting the SNMPv3 parameters and for performing SNMPv3 requests. After setting the basic parameters, the security parameters can be set as follows.

 

// Set the "SHA" authentication protocol

target.setAuthProtocol(SnmpServer.SHA_AUTH);

// Set the authentication password

target.setAuthPassword("authPwd");

// Set the privacy password

target.setPrivPassword("privPwd");

// Set the security level

target.setSecurityLevel(Snmp3Message.AUTH_PRIV);

 

The parameter information can be updated using the following command.

 

target.create_v3_tables();

 

The create_v3_tables() method is used to create new users and add them to the userTable in USMUserTable. The return values of this method are 1, 0, -1, -2, and -3.

The update succeeds only if the configuration set in the management application matches with that of the SNMP agent. The reasons for the failure could be any of the following.

 

 



Copyright © 2012, ZOHO Corp. All Rights Reserved.