Permalink
Browse files

Enhanced community handling for TrapListener

  • Loading branch information...
hallidave committed Nov 17, 2011
1 parent 361d6bc commit 9e6403ed7fdaa1aa3267e895d9178d71a40b4112
Showing with 33 additions and 6 deletions.
  1. +11 −2 lib/snmp/manager.rb
  2. +22 −4 test/test_manager.rb
View
@@ -561,7 +561,7 @@ class TrapListener
class Config < Options
option :host, :Host, 'localhost'
option :port, :Port, 162
- option :community, :Community, 'public'
+ option :community, :Community, nil
option :server_transport, :ServerTransport, UDPServerTransport
option :max_recv_bytes, :MaxReceiveBytes, 8000
option :mib_dir, :MibDir, MIB::DEFAULT_MIB_PATH
@@ -595,6 +595,11 @@ def create_transport
# 2. handler for a specific SNMP version
# 3. default handler
#
+ # The default for the :community option is 'nil' allows traps with any
+ # community to be accepted. To only accept traps from a specific community,
+ # the community may also be set to a string (e.g. 'public') or a list of
+ # strings (e.g. ['public', 'my_private_community'] ).
+ #
def initialize(options={}, &block)
config = Config.new(options)
@transport = config.create_transport
@@ -687,7 +692,7 @@ def process_traps(trap_listener)
data, source_ip, source_port = @transport.recvfrom(@max_bytes)
begin
message = Message.decode(data, @mib)
- if @community == message.community
+ if community_allowed? message.community
trap = message.pdu
if trap.kind_of?(InformRequest)
@transport.send(message.response.encode, source_ip, source_port)
@@ -704,6 +709,10 @@ def process_traps(trap_listener)
end
end
+ def community_allowed?(msg_community)
+ @community.nil? || @community == msg_community || !(Array(@community) & Array(msg_community)).empty?
+ end
+
def select_handler(trap)
@lock.synchronize do
if trap.kind_of?(SNMPv2_Trap)
View
@@ -289,15 +289,33 @@ def test_oid_handler
assert(oid_called)
end
- def test_reject_wrong_community
+ ##
+ # Should filter traps with a 'public' community if that community is not accepted
+ #
+ def test_reject_community
+ assert !public_trap_passes?("test")
+ assert !public_trap_passes?(["foo", "bar"])
+ assert !public_trap_passes?([])
+ end
+
+ ##
+ # Should accept traps with a 'public' community if that community is allowed.
+ #
+ def test_accept_community
+ assert public_trap_passes? "public"
+ assert public_trap_passes? ["test", "public"]
+ assert public_trap_passes? nil
+ end
+
+ def public_trap_passes?(community_filter)
default_called = false
m = TrapListener.new(
- :Community => "test",
- :ServerTransport => TrapTestTransport.new) do |manager|
+ :community => community_filter,
+ :server_transport => TrapTestTransport.new) do |manager|
manager.on_trap_default { default_called = true }
end
m.join
- assert(!default_called)
+ default_called
end
end

0 comments on commit 9e6403e

Please sign in to comment.