Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Embedded SNMP4j log access fail and success

Tags:

logging

snmp4j

I am using SNMP4j to write an agent in java, and that is progressing well. I can get and set valued (SNMPv1 only for now, but v3 is coming).

My next requirement is to log in my application log (not the SNMP4J log) specifically these three things:

  1. New User logged in from
  2. New Failed SNMP connection attempt by user from
  3. SNMP SET used to write values by from .

I have used org.snmp4j.log.LogAdapter to pipe the SNMP4j logging into my debug log, but that is not the specific logging I want.

I have played with org.snmp4j.event.AuthenticationFailureListener to log when an authentication fail happens. That seems to be SNMPv3 only, and it does not give me the failed username.

Does anyone know how to do this? the Listener archetecture seems to be partly in place, is there more to that which I cant find? I could use the source code and add my own logging where needed, but what are the license implications of that? SNMP uses Apache 2.0 license

like image 427
Jon Avatar asked Jan 19 '16 11:01

Jon


1 Answers

I did the following to have full access to the request and response PDUs:

For the authentication failure logging:

  1. Extend the AuthenticationFailureEvent.class. In my case I added the security name and status info to the constructor of the event class.
  2. Extend the MessageDispatcherImpl.class and override the method dispatchMessage():

    switch (status) {
      case SnmpConstants.SNMP_MP_UNSUPPORTED_SECURITY_MODEL :
      case SnmpConstants.SNMPv3_USM_AUTHENTICATION_FAILURE :
      case SnmpConstants.SNMPv3_USM_UNSUPPORTED_SECURITY_LEVEL :
      case SnmpConstants.SNMPv3_USM_UNKNOWN_SECURITY_NAME :
      case SnmpConstants.SNMPv3_USM_AUTHENTICATION_ERROR :
      case SnmpConstants.SNMPv3_USM_NOT_IN_TIME_WINDOW :
      case SnmpConstants.SNMPv3_USM_UNSUPPORTED_AUTHPROTOCOL :
      case SnmpConstants.SNMPv3_USM_UNKNOWN_ENGINEID :
      case SnmpConstants.SNMP_MP_WRONG_USER_NAME :
      case SnmpConstants.SNMPv3_TSM_INADEQUATE_SECURITY_LEVELS :
      case SnmpConstants.SNMP_MP_USM_ERROR : {
        // create an extended version of the failure event
        AuthenticationFailureEvent event = new ExtendedAuthenticationFailureEvent(this,incomingAddress,securityName.getValue(),sourceTransport, status, statusInfo, wholeMessage);
        fireAuthenticationFailure(event);
        break;
      }
    }
    
  3. In your agent class override the initMessageDispatcher() method:

    protected void initMessageDispatcher() {
      ...
      dispatcher = new ExtendedMessageDispatcherImpl();
      ...
    }
    
  4. Add your logging class as listener to this dispatcher (for example in the finishInit() method of your agent):

    dispatcher.addAuthenticationFailureListener(loggingHandler);
    

For the request logging:

Just implement the CommandResponderinterface in your logging class and add it to your session:

getSession().addCommandResponder(loggingHandler);

For the response logging:

  1. Create a method e.g. logResponsePdu(PDU pdu) in your logging class.

  2. Extend MessageDispatcherImpl.class and override the method returnResponsePdu().

    public int returnResponsePdu(int messageProcessingModel, int securityModel, byte[] securityName, int securityLevel, PDU pdu, int maxSizeResponseScopedPDU, StateReference stateReference, StatusInformation statusInformation) throws MessageException {
      int result = super.returnResponsePdu(messageProcessingModel, securityModel, securityName, securityLevel, pdu, maxSizeResponseScopedPDU, stateReference, statusInformation);
      // log response message
      loggingHandler.logResponsePdu(pdu);
      return result;
    }
    

The result in my case is logging in form of:

Request received! From: (ip removed), security name: (login name), PDU type: SET, OID: 1.3.6.1.2.1.1.5.0 = 'Test Name'

Request PDU: SET[{contextEngineID=(data removed), contextName=private}, requestID=(data removed), errorStatus=0, errorIndex=0, VBS[1.3.6.1.2.1.1.5.0 = Test Name]]

Response sent! Error status: Success, PDU type: RESPONSE, OID: 1.3.6.1.2.1.1.5.0 = 'Test Name'

Response PDU! PDU: RESPONSE[{contextEngineID=(data removed), contextName=private}, requestID=(data removed), errorStatus=0, errorIndex=0, VBS[1.3.6.1.2.1.1.5.0 = Test Name]]

Maybe it is not the best way to do it, but it works.I hope I could help you with this.

like image 97
Blakhar Avatar answered Nov 09 '22 17:11

Blakhar