class NETSNMP::V3Session

Abstraction for the v3 semantics.

Public Class Methods

new(context: "", **opts) click to toggle source

@param [String, Integer] version SNMP version (always 3)

Calls superclass method NETSNMP::Session::new
# File lib/netsnmp/v3_session.rb, line 7
def initialize(context: "", **opts)
  @context = context
  @security_parameters = opts.delete(:security_parameters)
  super
  @message_serializer = Message.new(**opts)
end

Public Instance Methods

build_pdu(type, *vars) click to toggle source

@see {NETSNMP::Session#build_pdu}

@return [NETSNMP::ScopedPDU] a pdu

# File lib/netsnmp/v3_session.rb, line 17
def build_pdu(type, *vars)
  engine_id = security_parameters.engine_id
  ScopedPDU.build(type, headers: [engine_id, @context], varbinds: vars)
end
send(pdu) click to toggle source

@see {NETSNMP::Session#send}

# File lib/netsnmp/v3_session.rb, line 23
def send(pdu)
  log { "sending request..." }
  encoded_request = encode(pdu)
  encoded_response = @transport.send(encoded_request)
  response_pdu, * = decode(encoded_response)
  response_pdu
end

Private Instance Methods

decode(stream, security_parameters: @security_parameters) click to toggle source
# File lib/netsnmp/v3_session.rb, line 80
def decode(stream, security_parameters: @security_parameters)
  return_pdu = @message_serializer.decode(stream, security_parameters: security_parameters)

  pdu, *args = return_pdu

  # usmStats: http://oidref.com/1.3.6.1.6.3.15.1.1
  if pdu.type == 8
    case pdu.varbinds.first.oid
    when "1.3.6.1.6.3.15.1.1.1.0" # usmStatsUnsupportedSecLevels
      raise Error, "Unsupported security level"
    when "1.3.6.1.6.3.15.1.1.2.0" # usmStatsNotInTimeWindows
      _, @engine_boots, @engine_time = args
      raise IdNotInTimeWindowError, "Not in time window"
    when "1.3.6.1.6.3.15.1.1.3.0" # usmStatsUnknownUserNames
      raise Error, "Unknown user name"
    when "1.3.6.1.6.3.15.1.1.4.0" # usmStatsUnknownEngineIDs
      raise Error, "Unknown engine ID" unless @security_parameters.must_revalidate?
    when "1.3.6.1.6.3.15.1.1.5.0" # usmStatsWrongDigests
      raise Error, "Authentication failure (incorrect password, community or key)"
    when "1.3.6.1.6.3.15.1.1.6.0" # usmStatsDecryptionErrors
      raise Error, "Decryption error"
    end
  end

  # validate_authentication
  @message_serializer.verify(stream, pdu.auth_param, pdu.security_level, security_parameters: @security_parameters)

  return_pdu
end
encode(pdu) click to toggle source
# File lib/netsnmp/v3_session.rb, line 74
def encode(pdu)
  @message_serializer.encode(pdu, security_parameters: @security_parameters,
                                  engine_boots: @engine_boots,
                                  engine_time: @engine_time)
end
probe_for_engine() click to toggle source

sends a probe snmp v3 request, to get the additional info with which to handle the security aspect

# File lib/netsnmp/v3_session.rb, line 61
def probe_for_engine
  report_sec_params = SecurityParameters.new(security_level: 0,
                                             username: @security_parameters.username)
  pdu = ScopedPDU.build(:get, headers: [])
  log { "sending probe..." }
  encoded_report_pdu = @message_serializer.encode(pdu, security_parameters: report_sec_params)

  encoded_response_pdu = @transport.send(encoded_report_pdu)

  _, engine_id, @engine_boots, @engine_time = decode(encoded_response_pdu, security_parameters: report_sec_params)
  engine_id
end
security_parameters() click to toggle source
# File lib/netsnmp/v3_session.rb, line 54
def security_parameters
  @security_parameters.engine_id = probe_for_engine if @security_parameters.must_revalidate?
  @security_parameters
end
validate(**options) click to toggle source
Calls superclass method NETSNMP::Session#validate
# File lib/netsnmp/v3_session.rb, line 33
def validate(**options)
  super
  if (s = @security_parameters)
    # inspect public API
    unless s.respond_to?(:encode) &&
           s.respond_to?(:decode) &&
           s.respond_to?(:sign)   &&
           s.respond_to?(:verify)
      raise Error, "#{s} doesn't respect the sec params public API (#encode, #decode, #sign)"
    end
  else
    @security_parameters = SecurityParameters.new(security_level: options[:security_level],
                                                  username:       options[:username],
                                                  auth_protocol:  options[:auth_protocol],
                                                  priv_protocol:  options[:priv_protocol],
                                                  auth_password:  options[:auth_password],
                                                  priv_password:  options[:priv_password])

  end
end