netsnmp 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.coveralls.yml +1 -0
  3. data/.travis.yml +4 -4
  4. data/Gemfile +5 -1
  5. data/README.md +124 -63
  6. data/lib/netsnmp.rb +66 -10
  7. data/lib/netsnmp/client.rb +93 -75
  8. data/lib/netsnmp/encryption/aes.rb +84 -0
  9. data/lib/netsnmp/encryption/des.rb +80 -0
  10. data/lib/netsnmp/encryption/none.rb +17 -0
  11. data/lib/netsnmp/errors.rb +1 -3
  12. data/lib/netsnmp/message.rb +81 -0
  13. data/lib/netsnmp/oid.rb +18 -137
  14. data/lib/netsnmp/pdu.rb +106 -64
  15. data/lib/netsnmp/scoped_pdu.rb +23 -0
  16. data/lib/netsnmp/security_parameters.rb +198 -0
  17. data/lib/netsnmp/session.rb +84 -275
  18. data/lib/netsnmp/v3_session.rb +81 -0
  19. data/lib/netsnmp/varbind.rb +65 -156
  20. data/lib/netsnmp/version.rb +2 -1
  21. data/netsnmp.gemspec +2 -8
  22. data/spec/client_spec.rb +147 -99
  23. data/spec/handlers/celluloid_spec.rb +33 -20
  24. data/spec/oid_spec.rb +11 -5
  25. data/spec/pdu_spec.rb +22 -22
  26. data/spec/security_parameters_spec.rb +40 -0
  27. data/spec/session_spec.rb +0 -23
  28. data/spec/support/celluloid.rb +24 -0
  29. data/spec/support/request_examples.rb +36 -0
  30. data/spec/support/start_docker.sh +15 -1
  31. data/spec/v3_session_spec.rb +21 -0
  32. data/spec/varbind_spec.rb +2 -51
  33. metadata +30 -76
  34. data/lib/netsnmp/core.rb +0 -12
  35. data/lib/netsnmp/core/client.rb +0 -15
  36. data/lib/netsnmp/core/constants.rb +0 -153
  37. data/lib/netsnmp/core/inline.rb +0 -20
  38. data/lib/netsnmp/core/libc.rb +0 -48
  39. data/lib/netsnmp/core/libsnmp.rb +0 -44
  40. data/lib/netsnmp/core/structures.rb +0 -167
  41. data/lib/netsnmp/core/utilities.rb +0 -13
  42. data/lib/netsnmp/handlers/celluloid.rb +0 -27
  43. data/lib/netsnmp/handlers/em.rb +0 -56
  44. data/spec/core/libc_spec.rb +0 -2
  45. data/spec/core/libsnmp_spec.rb +0 -32
  46. data/spec/core/structures_spec.rb +0 -54
  47. data/spec/handlers/em_client_spec.rb +0 -34
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+ module NETSNMP
3
+ # Abstraction for the v3 semantics.
4
+ class V3Session < Session
5
+
6
+ # @param [String, Integer] version SNMP version (always 3)
7
+ def initialize(version: 3, context: "", **opts)
8
+ @context = context
9
+ @security_parameters = opts.delete(:security_parameters)
10
+ super
11
+ end
12
+
13
+ # @see {NETSNMP::Session#build_pdu}
14
+ #
15
+ # @return [NETSNMP::ScopedPDU] a pdu
16
+ def build_pdu(type, *vars)
17
+ engine_id = security_parameters.engine_id
18
+ pdu = ScopedPDU.build(type, headers: [engine_id, @context], varbinds: vars)
19
+ end
20
+
21
+ # @see {NETSNMP::Session#send}
22
+ def send(*)
23
+ pdu, _ = super
24
+ pdu
25
+ end
26
+
27
+ private
28
+
29
+ def validate(**options)
30
+ super
31
+ if s = @security_parameters
32
+ # inspect public API
33
+ unless s.respond_to?(:encode) &&
34
+ s.respond_to?(:decode) &&
35
+ s.respond_to?(:sign) &&
36
+ s.respond_to?(:verify)
37
+ raise Error, "#{s} doesn't respect the sec params public API (#encode, #decode, #sign)"
38
+ end
39
+ else
40
+ @security_parameters = SecurityParameters.new(security_level: options[:security_level],
41
+ username: options[:username],
42
+ auth_protocol: options[:auth_protocol],
43
+ priv_protocol: options[:priv_protocol],
44
+ auth_password: options[:auth_password],
45
+ priv_password: options[:priv_password])
46
+
47
+ end
48
+ end
49
+
50
+ def security_parameters
51
+ if @security_parameters.engine_id.empty?
52
+ @security_parameters.engine_id = probe_for_engine
53
+ end
54
+ @security_parameters
55
+ end
56
+
57
+ # sends a probe snmp v3 request, to get the additional info with which to handle the security aspect
58
+ #
59
+ def probe_for_engine
60
+ report_sec_params = SecurityParameters.new(security_level: 0,
61
+ username: @security_parameters.username)
62
+ pdu = ScopedPDU.build(:get, headers: [])
63
+ encoded_report_pdu = Message.encode(pdu, security_parameters: report_sec_params)
64
+
65
+ encoded_response_pdu = @transport.send(encoded_report_pdu)
66
+
67
+ _, engine_id, @engine_boots, @engine_time = decode(encoded_response_pdu, security_parameters: report_sec_params)
68
+ engine_id
69
+ end
70
+
71
+ def encode(pdu)
72
+ Message.encode(pdu, security_parameters: @security_parameters,
73
+ engine_boots: @engine_boots,
74
+ engine_time: @engine_time)
75
+ end
76
+
77
+ def decode(stream, security_parameters: @security_parameters)
78
+ Message.decode(stream, security_parameters: security_parameters)
79
+ end
80
+ end
81
+ end
@@ -1,181 +1,90 @@
1
+ # frozen_string_literal: true
1
2
  module NETSNMP
2
3
  # Abstracts the PDU variable structure into a ruby object
3
4
  #
4
5
  class Varbind
5
- Error = Class.new(Error)
6
6
 
7
- attr_reader :struct
7
+ attr_reader :oid, :value
8
8
 
9
- # @param [FFI::Pointer] pointer to the variable list
10
- def initialize(pointer)
11
- @struct = Core::Structures::VariableList.new(pointer)
9
+ def initialize(oid , value: nil, type: nil)
10
+ @oid = OID.build(oid)
11
+ @type = type
12
+ @value = convert_val(value) if value
12
13
  end
13
- end
14
-
15
-
16
- # Abstracts the Varbind used for the PDU Request
17
- class RequestVarbind < Varbind
18
14
 
19
- # @param [RequestPDU] pdu the request pdu for this varbind
20
- # @param [OID] oid the oid for this varbind
21
- # @param [Object] value the value for the oid
22
- # @param [Hash] options additional options
23
- # @option options [Symbol, Integer, nil] :type C net-snmp type flag,
24
- # type-label for value (see #convert_type), if not set it's inferred from the value
25
- #
26
- def initialize(pdu, oid, value, options={})
27
- type = case options[:type]
28
- when Integer then options[:type] # assume that the code is properly passed
29
- when Symbol then convert_type(options[:type]) # DSL-specific API
30
- when nil then infer_from_value(value)
31
- else
32
- raise Error, "#{options[:type]} is an unsupported type"
33
- end
34
-
35
- value_length = case type
36
- when Core::Constants::ASN_NULL,
37
- Core::Constants::SNMP_NOSUCHOBJECT,
38
- Core::Constants::SNMP_NOSUCHINSTANCE,
39
- Core::Constants::SNMP_ENDOFMIBVIEW
40
- 0
41
- else value ? value.size : 0
42
- end
43
- value = convert_value(value, type)
44
-
45
- pointer = Core::LibSNMP.snmp_pdu_add_variable(pdu.pointer, oid.pointer, oid.length, type, value, value_length)
46
- super(pointer)
15
+ def to_s
16
+ "#<#{self.class}:0x#{object_id.to_s(16)} @oid=#{@oid} @value=#{@value}>"
47
17
  end
48
18
 
49
-
50
- private
51
-
52
- # @param [Object] value value to infer the type from
53
- # @return [Integer] the C net-snmp flag indicating the type
54
- # @raise [Error] when the value is from an unexpected type
55
- #
56
- def infer_from_value(value)
57
- case value
58
- when String then Core::Constants::ASN_OCTET_STR
59
- when Fixnum then Core::Constants::ASN_INTEGER
60
- when OID then Core::Constants::ASN_OBJECT_ID
61
- when nil then Core::Constants::ASN_NULL
62
- else raise Error, "#{value} is from an unsupported type"
63
- end
19
+ def to_der
20
+ to_asn.to_der
64
21
  end
65
22
 
66
- # @param [Symbol] symbol_type symbol representing the type
67
- # @return [Integer] the C net-snmp flag indicating the type
68
- # @raise [Error] when the symbol is unsupported
69
- #
70
- def convert_type(symbol_type)
71
- case symbol_type
72
- when :integer then Core::Constants::ASN_INTEGER
73
- when :gauge then Core::Constants::ASN_GAUGE
74
- when :counter then Core::Constants::ASN_COUNTER
75
- when :timeticks then Core::Constants::ASN_TIMETICKS
76
- when :unsigned then Core::Constants::ASN_UNSIGNED
77
- when :boolean then Core::Constants::ASN_BOOLEAN
78
- when :string then Core::Constants::ASN_OCTET_STR
79
- when :binary then Core::Constants::ASN_BIT_STR
80
- when :ip_address then Core::Constants::ASN_IPADDRESS
81
- else
82
- raise Error, "#{symbol_type} cannot be converted"
83
- end
84
- end
85
-
86
- # @param [Object] value the value to convert
87
- # @param [Integer] type the C net-snmp level object type flakg
88
- #
89
- # @return [FFI::Pointer] pointer to the memory location where the value is stored
90
- #
91
- def convert_value(value, type)
92
- case type
93
- when Core::Constants::ASN_INTEGER,
94
- Core::Constants::ASN_GAUGE,
95
- Core::Constants::ASN_COUNTER,
96
- Core::Constants::ASN_TIMETICKS,
97
- Core::Constants::ASN_UNSIGNED
98
- new_val = FFI::MemoryPointer.new(:long)
99
- new_val.write_long(value)
100
- new_val
101
- when Core::Constants::ASN_OCTET_STR,
102
- Core::Constants::ASN_BIT_STR,
103
- Core::Constants::ASN_OPAQUE
104
- value
105
- when Core::Constants::ASN_IPADDRESS
106
- # TODO
107
- when Core::Constants::ASN_OBJECT_ID
108
- value.pointer
109
- when Core::Constants::ASN_NULL,
110
- Core::Constants::SNMP_NOSUCHOBJECT,
111
- Core::Constants::SNMP_NOSUCHINSTANCE,
112
- Core::Constants::SNMP_ENDOFMIBVIEW
113
- nil
23
+ def to_asn
24
+ asn_oid = OID.to_asn(@oid)
25
+ asn_val = if @type
26
+ asn_type, asn_val = convert_to_asn(@type, @value)
27
+ OpenSSL::ASN1::ASN1Data.new(asn_val, asn_type, :APPLICATION)
28
+ else
29
+ case @value
30
+ when String
31
+ OpenSSL::ASN1::OctetString
32
+ when Integer
33
+ OpenSSL::ASN1::Integer
34
+ when true, false
35
+ OpenSSL::ASN1::Boolean
36
+ when nil
37
+ OpenSSL::ASN1::Null
114
38
  else
115
- raise Error, "Unknown variable type: #{type}"
39
+ raise Error, "#{@value}: unsupported varbind type"
40
+ end.new(@value)
116
41
  end
42
+ OpenSSL::ASN1::Sequence.new( [asn_oid, asn_val] )
117
43
  end
118
- end
119
-
120
- # Abstracts the Varbind used for the PDU Response
121
- #
122
- class ResponseVarbind < Varbind
123
44
 
124
- attr_reader :value, :oid_code
125
45
 
126
- # @param [FFI::Pointer] pointer pointer to the response varbind structure
127
- #
128
- # @note it loads the value and oid code on initialization
129
- #
130
- def initialize(pointer)
131
- super
132
- @value = load_varbind_value
133
- @oid_code = load_oid_code
46
+ def convert_val(asn_value)
47
+ case asn_value
48
+ when OpenSSL::ASN1::Primitive
49
+ val = asn_value.value
50
+ val = val.to_i if val.is_a?(OpenSSL::BN)
51
+ val
52
+ when OpenSSL::ASN1::ASN1Data
53
+ # application data
54
+ convert_application_asn(asn_value)
55
+ when OpenSSL::BN
56
+ else
57
+ asn_value # assume it's already primitive
58
+ end
134
59
  end
135
60
 
136
- private
137
-
138
- # @return [String] the oid code from the varbind
139
- def load_oid_code
140
- OID.read_pointer(@struct[:name], @struct[:name_length])
61
+ def convert_to_asn(typ, value)
62
+ return [typ, value] unless typ.is_a?(Symbol)
63
+ case typ
64
+ when :ipaddress then 0
65
+ when :counter32 then 1
66
+ when :gauge then 2
67
+ when :timetick then [3, [ value].pack("N") ]
68
+ when :opaque then 4
69
+ when :nsap then 5
70
+ when :counter64 then 6
71
+ when :uinteger then 7
72
+ end
141
73
  end
142
74
 
143
- # @return [Object] the value for the varbind (a ruby type, a string, an integer, a symbol etc...)
144
- #
145
- def load_varbind_value
146
- object_type = @struct[:type]
147
- case object_type
148
- when Core::Constants::ASN_OCTET_STR,
149
- Core::Constants::ASN_OPAQUE
150
- @struct[:val][:string].read_string(@struct[:val_len])
151
- when Core::Constants::ASN_INTEGER
152
- @struct[:val][:integer].read_long
153
- when Core::Constants::ASN_UINTEGER,
154
- Core::Constants::ASN_TIMETICKS,
155
- Core::Constants::ASN_COUNTER,
156
- Core::Constants::ASN_GAUGE
157
- @struct[:val][:integer].read_ulong
158
- when Core::Constants::ASN_IPADDRESS
159
- @struct[:val][:objid].read_string(@struct[:val_len]).unpack('CCCC').join(".")
160
- when Core::Constants::ASN_NULL
161
- nil
162
- when Core::Constants::ASN_OBJECT_ID
163
- OID.from_pointer(@struct[:val][:objid], @struct[:val_len] / OID.default_size)
164
- when Core::Constants::ASN_COUNTER64
165
- counter = Core::Structures::Counter64.new(@struct[:val][:counter64])
166
- counter[:high] * 2^32 + counter[:low]
167
- when Core::Constants::ASN_BIT_STR
168
- # XXX not sure what to do here. Is this obsolete?
169
- when Core::Constants::SNMP_ENDOFMIBVIEW
170
- :endofmibview
171
- when Core::Constants::SNMP_NOSUCHOBJECT
172
- :nosuchobject
173
- when Core::Constants::SNMP_NOSUCHINSTANCE
174
- :nosuchinstance
175
- else
176
- raise Error, "#{object_type} is an invalid type"
75
+ def convert_application_asn(asn)
76
+ case asn.tag
77
+ when 0 # IP Address
78
+ when 1 # ASN counter 32
79
+ asn.value.unpack("n*")[0] || 0
80
+ when 2 # gauge
81
+ when 3 # timeticks
82
+ asn.value.unpack("N*")[0] || 0
83
+ when 4 # opaque
84
+ when 5 # NSAP
85
+ when 6 # ASN Counter 64
86
+ when 7 # ASN UInteger
177
87
  end
178
88
  end
179
-
180
89
  end
181
90
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module NETSNMP
2
- VERSION = '0.0.2'.freeze
3
+ VERSION = '0.1.0'
3
4
  end
data/netsnmp.gemspec CHANGED
@@ -14,8 +14,8 @@ DESC
14
14
  gem.email = "cardoso_tiago@hotmail.com"
15
15
  gem.homepage = ""
16
16
  gem.platform = Gem::Platform::RUBY
17
- gem.required_ruby_version = '>=2.0.0'
18
- gem.metadata["allowed_push_hosts"] = "https://rubygems.org/"
17
+ gem.required_ruby_version = '>=2.1.0'
18
+ gem.metadata["allowed_push_host"] = "https://rubygems.org/"
19
19
 
20
20
  # Manifest
21
21
  gem.files = `git ls-files`.split("\n") - Dir['tmp/**/*']
@@ -24,14 +24,8 @@ DESC
24
24
  gem.require_paths = ["lib"]
25
25
 
26
26
  gem.executables = Dir["bin/*"].map { |e| File.basename e }
27
- gem.add_runtime_dependency "ffi", ["~> 1.9"]
28
- unless RUBY_PLATFORM == "java"
29
- gem.add_runtime_dependency "RubyInline", ["~> 3.12"]
30
- end
31
-
32
27
  gem.add_development_dependency "rake", ["~> 10.4.2"]
33
28
  gem.add_development_dependency "rspec", ["~> 3.3.0"]
34
29
 
35
- gem.add_development_dependency "em-synchrony", ["~> 1.0.4"]
36
30
  gem.add_development_dependency "celluloid-io", ["~> 0.17.2"]
37
31
  end
data/spec/client_spec.rb CHANGED
@@ -1,119 +1,167 @@
1
+ require_relative "support/request_examples"
2
+
1
3
  RSpec.describe NETSNMP::Client do
2
4
  let(:host) { "localhost" }
3
- let(:host_options) { {
5
+
6
+ let(:device_options) { {
4
7
  peername: "localhost",
5
- port: SNMPPORT,
6
- username: "simulator",
7
- auth_password: "auctoritas",
8
- auth_protocol: :md5,
9
- priv_password: "privatus",
10
- priv_protocol: :des
8
+ port: SNMPPORT
11
9
  } }
12
-
13
- subject { described_class.new(host, options) }
14
-
15
- describe "establishing session" do
16
- let(:oid) { "1.3.6.1.2.1.1.5.0" } # sysName.0
17
- context "with a wrong auth password" do
18
- let(:options) { host_options.merge( auth_password: "auctoritas2", timeout: 5) }
19
- it {
20
- expect {
21
- subject.get(oid)
22
- }.to raise_error(NETSNMP::ConnectionFailed)
10
+ describe "v1" do
11
+ it_behaves_like "an snmp client" do
12
+ let(:protocol_options) { {
13
+ version: "1",
14
+ community: "public"
15
+ } }
16
+ let(:get_oid) { "1.3.6.1.2.1.1.5.0" }
17
+ let(:next_oid) { "1.3.6.1.2.1.1.6.0" }
18
+ let(:walk_oid) { "1.3.6.1.2.1.1" }
19
+ let(:set_oid) { "1.3.6.1.2.1.1.3.0" } # sysUpTimeInstance
20
+ let(:get_result) { "DEVICE-192.168.1.1" }
21
+ let(:next_result) { "The Cloud" }
22
+ let(:walk_result) { <<-WALK
23
+ 1.3.6.1.2.1.1.1.0: Device description
24
+ 1.3.6.1.2.1.1.2.0: 1.3.6.1.4.1.3454
25
+ 1.3.6.1.2.1.1.3.0: 78171676
26
+ 1.3.6.1.2.1.1.4.0: The Owner
27
+ 1.3.6.1.2.1.1.5.0: DEVICE-192.168.1.1
28
+ 1.3.6.1.2.1.1.6.0: The Cloud
29
+ 1.3.6.1.2.1.1.7.0: 72
30
+ 1.3.6.1.2.1.1.8.0: 0
31
+ WALK
23
32
  }
33
+ let(:set_oid_result) { 43 }
24
34
  end
25
- context "with a wrong priv password" do
26
- let(:options) { host_options.merge( priv_password: "privatus2", timeout: 5) }
27
- it {
28
- expect {
29
- subject.get(oid)
30
- }.to raise_error(NETSNMP::ConnectionFailed)
35
+ end
36
+ describe "v2" do
37
+ it_behaves_like "an snmp client" do
38
+ let(:protocol_options) { {
39
+ version: "2c",
40
+ community: "public"
41
+ } }
42
+ let(:get_oid) { "1.3.6.1.2.1.1.5.0" }
43
+ let(:next_oid) { "1.3.6.1.2.1.1.6.0" }
44
+ let(:walk_oid) { "1.3.6.1.2.1.1" }
45
+ let(:set_oid) { "1.3.6.1.2.1.1.3.0" }
46
+ let(:get_result) { "DEVICE-192.168.1.1" }
47
+ let(:next_result) { "The Cloud" }
48
+ let(:walk_result) { <<-WALK
49
+ 1.3.6.1.2.1.1.1.0: Device description
50
+ 1.3.6.1.2.1.1.2.0: 1.3.6.1.4.1.3454
51
+ 1.3.6.1.2.1.1.3.0: 78171676
52
+ 1.3.6.1.2.1.1.4.0: The Owner
53
+ 1.3.6.1.2.1.1.5.0: DEVICE-192.168.1.1
54
+ 1.3.6.1.2.1.1.6.0: The Cloud
55
+ 1.3.6.1.2.1.1.7.0: 72
56
+ 1.3.6.1.2.1.1.8.0: 0
57
+ WALK
31
58
  }
32
- end
59
+ let(:set_oid_result) { 43 }
33
60
 
34
- context "with an unexisting user" do
35
- let(:options) { host_options.merge(username: "simulata", timeout: 5) }
36
- it {
37
- expect {
38
- subject.get(oid)
39
- }.to raise_error(NETSNMP::ConnectionFailed)
40
- }
41
61
  end
42
62
  end
43
63
 
44
- describe "#get" do
45
- let(:oid) { "1.3.6.1.2.1.1.5.0" } # sysName.0
46
- let(:value) { subject.get(oid) }
47
- let(:options) { host_options.merge(context: "a172334d7d97871b72241397f713fa12") }
48
- it "fetches the varbinds for a given oid" do
49
- expect(value).to eq("tt")
50
- end
51
- end
52
64
 
53
- describe "#get_next" do
54
- let(:oid) { "1.3.6.1.2.1.1.5.0" } # sysName.0
55
- let(:value) { subject.get_next(oid) }
56
- let(:options) { host_options.merge(context: "a172334d7d97871b72241397f713fa12") }
57
- it "fetches the varbinds for the next oid" do
58
- expect(value).to start_with("KK12")
59
- end
60
- end
65
+ describe "v3" do
66
+ let(:extra_options) { {} }
67
+ let(:version_options) { {
68
+ version: "3",
69
+ context: "a172334d7d97871b72241397f713fa12",
70
+ } }
71
+ let(:get_oid) { "1.3.6.1.2.1.1.5.0" }
72
+ let(:next_oid) { "1.3.6.1.2.1.1.6.0" }
73
+ let(:set_oid) { "1.3.6.1.2.1.1.3.0" } # sysUpTimeInstance
74
+ let(:walk_oid) { "1.3.6.1.2.1.1.9.1.3" }
75
+ let(:get_result) { "tt" }
76
+ let(:next_result) { "KK12" }
77
+ let(:walk_result) { <<-WALK
78
+ 1.3.6.1.2.1.1.9.1.3.1: The SNMP Management Architecture MIB.
79
+ 1.3.6.1.2.1.1.9.1.3.2: The MIB for Message Processing and Dispatching.
80
+ 1.3.6.1.2.1.1.9.1.3.3: The management information definitions for the SNMP User-based Security Model.
81
+ 1.3.6.1.2.1.1.9.1.3.4: The MIB module for SNMPv2 entities
82
+ 1.3.6.1.2.1.1.9.1.3.5: The MIB module for managing TCP implementations
83
+ 1.3.6.1.2.1.1.9.1.3.6: The MIB module for managing IP and ICMP implementations
84
+ 1.3.6.1.2.1.1.9.1.3.7: The MIB module for managing UDP implementations
85
+ 1.3.6.1.2.1.1.9.1.3.8: View-based Access Control Model for SNMP.
86
+ WALK
87
+ }
88
+ let(:set_oid_result) { 43}
89
+ context "with a no auth no priv policy" do
90
+ let(:user_options) { { username: "unsafe", security_level: :noauth } }
91
+ it_behaves_like "an snmp client" do
92
+ let(:protocol_options) { version_options.merge(user_options).merge(extra_options) }
93
+ # why is this here? that variation/notification community causes the simulagtor to go down
94
+ # until I find the origin of the issue and patched it with an appropriated community, this
95
+ # is here so that I test the set call at least once, although I'm sure it'll work always
96
+ # for v3
97
+ describe "#set" do
98
+ let(:extra_options) { { #community: "variation/notification",
99
+ context: "0886e1397d572377c17c15036a1e6c66" } }
100
+ it "updates the value of the oid" do
101
+ prev_value = subject.get(oid: set_oid)
102
+ expect(prev_value).to be_a(Integer)
103
+
104
+ # without type
105
+ subject.set(oid: set_oid, value: set_oid_result)
106
+ expect(subject.get(oid: set_oid)).to eq(set_oid_result)
61
107
 
62
- describe "#walk" do
63
- let(:oid) { "1.3.6.1.2.1.1.9.1.3" } # sysORDescr
64
- let(:value) { subject.walk(oid) }
65
- let(:options) { host_options.merge(context: "a172334d7d97871b72241397f713fa12") }
66
- it "fetches the varbinds for the next oid" do
67
- expect(value.next).to eq(["#{oid}.1","The SNMP Management Architecture MIB."])
68
- expect(value.next).to eq(["#{oid}.2","The MIB for Message Processing and Dispatching."])
69
- expect(value.next).to eq(["#{oid}.3","The management information definitions for the SNMP User-based Security Model."])
70
- expect(value.next).to eq(["#{oid}.4","The MIB module for SNMPv2 entities"])
71
- expect(value.next).to eq(["#{oid}.5","The MIB module for managing TCP implementations"])
72
- expect(value.next).to eq(["#{oid}.6","The MIB module for managing IP and ICMP implementations"])
73
- expect(value.next).to eq(["#{oid}.7","The MIB module for managing UDP implementations"])
74
- expect(value.next).to eq(["#{oid}.8","View-based Access Control Model for SNMP."])
75
- expect{ value.next }.to raise_error(StopIteration)
76
- end
77
- end
108
+ subject.set(oid: set_oid, value: prev_value)
109
+ end
110
+ end
78
111
 
79
- describe "#get_bulk" do
80
- let(:oid) { "1.3.6.1.2.1.1.9.1.3" }
81
- let(:value) { subject.get_bulk(oid) }
82
- let(:options) { host_options.merge(context: "a172334d7d97871b72241397f713fa12") }
83
- it "fetches the varbinds for the next oid" do
84
- expect(value.next).to eq(["#{oid}.1","The SNMP Management Architecture MIB."])
85
- expect(value.next).to eq(["#{oid}.2","The MIB for Message Processing and Dispatching."])
86
- expect(value.next).to eq(["#{oid}.3","The management information definitions for the SNMP User-based Security Model."])
87
- expect(value.next).to eq(["#{oid}.4","The MIB module for SNMPv2 entities"])
88
- expect(value.next).to eq(["#{oid}.5","The MIB module for managing TCP implementations"])
89
- expect(value.next).to eq(["#{oid}.6","The MIB module for managing IP and ICMP implementations"])
90
- expect(value.next).to eq(["#{oid}.7","The MIB module for managing UDP implementations"])
91
- expect(value.next).to eq(["#{oid}.8","View-based Access Control Model for SNMP."])
92
- expect(value.next).to eq(["1.3.6.1.2.1.1.9.1.4.1",2])
93
- expect(value.next).to eq(["1.3.6.1.2.1.1.9.1.4.2",2])
94
- expect{ value.next }.to raise_error(StopIteration)
112
+ end
95
113
  end
96
- end
97
-
98
-
99
- # TODO: use this oid to test error calls
100
- # let(:oid) { "SNMPv2-MIB::sysORDescr.1" }
114
+ context "with an only auth policy" do
115
+ context "speaking md5" do
116
+ let(:user_options) { { username: "authmd5", security_level: :auth_no_priv,
117
+ auth_password: "maplesyrup", auth_protocol: :md5 } }
118
+ it_behaves_like "an snmp client" do
119
+ let(:protocol_options) { version_options.merge(user_options).merge(extra_options) }
120
+ end
121
+ end
122
+ context "speaking sha" do
123
+ let(:user_options) { { username: "authsha", security_level: :auth_no_priv,
124
+ auth_password: "maplesyrup", auth_protocol: :sha } }
125
+ it_behaves_like "an snmp client" do
126
+ let(:protocol_options) { version_options.merge(user_options).merge(extra_options) }
127
+ end
128
+ end
101
129
 
102
- describe "#set" do
103
- let(:options) { host_options.merge(context: "0886e1397d572377c17c15036a1e6c66") } # write cache
104
- let(:oid) { "1.3.6.1.2.1.1.3.0" } # sysUpTimeInstance
105
- let(:new_value) { 43 }
106
- after { subject.set(oid, value: 42) }
107
- it "updates the value of the oid" do
108
- expect(subject.get(oid)).to be(42)
109
-
110
- # without type
111
- subject.set(oid, value: 43)
112
- expect(subject.get(oid)).to be(43)
113
-
114
- subject.set(oid, value: 44, type: :integer)
115
- expect(subject.get(oid)).to be(44)
130
+ end
131
+ context "with an auth priv policy" do
132
+ context "auth in md5, encrypting in des" do
133
+ let(:user_options) { { username: "authprivmd5des", auth_password: "maplesyrup",
134
+ auth_protocol: :md5, priv_password: "maplesyrup",
135
+ priv_protocol: :des } }
136
+ it_behaves_like "an snmp client" do
137
+ let(:protocol_options) { version_options.merge(user_options).merge(extra_options) }
138
+ end
139
+ end
140
+ context "auth in sha, encrypting in des" do
141
+ let(:user_options) { { username: "authprivshades", auth_password: "maplesyrup",
142
+ auth_protocol: :sha, priv_password: "maplesyrup",
143
+ priv_protocol: :des } }
144
+ it_behaves_like "an snmp client" do
145
+ let(:protocol_options) { version_options.merge(user_options).merge(extra_options) }
146
+ end
147
+ end
116
148
 
149
+ context "auth in md5, encrypting in aes" do
150
+ let(:user_options) { { username: "authprivmd5aes", auth_password: "maplesyrup",
151
+ auth_protocol: :md5, priv_password: "maplesyrup",
152
+ priv_protocol: :aes } }
153
+ it_behaves_like "an snmp client" do
154
+ let(:protocol_options) { version_options.merge(user_options).merge(extra_options) }
155
+ end
156
+ end
157
+ context "auth in sha, encrypting in aes" do
158
+ let(:user_options) { { username: "authprivshaaes", auth_password: "maplesyrup",
159
+ auth_protocol: :sha, priv_password: "maplesyrup",
160
+ priv_protocol: :aes } }
161
+ it_behaves_like "an snmp client" do
162
+ let(:protocol_options) { version_options.merge(user_options).merge(extra_options) }
163
+ end
164
+ end
117
165
  end
118
166
  end
119
167
  end