netsnmp 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.rubocop.yml +11 -0
- data/.rubocop_todo.yml +69 -0
- data/.travis.yml +6 -14
- data/Gemfile +7 -5
- data/README.md +66 -32
- data/Rakefile +7 -9
- data/lib/netsnmp/client.rb +42 -39
- data/lib/netsnmp/encryption/aes.rb +22 -22
- data/lib/netsnmp/encryption/des.rb +20 -21
- data/lib/netsnmp/encryption/none.rb +3 -3
- data/lib/netsnmp/errors.rb +1 -0
- data/lib/netsnmp/message.rb +31 -30
- data/lib/netsnmp/oid.rb +5 -4
- data/lib/netsnmp/pdu.rb +66 -69
- data/lib/netsnmp/scoped_pdu.rb +5 -7
- data/lib/netsnmp/security_parameters.rb +73 -54
- data/lib/netsnmp/session.rb +22 -24
- data/lib/netsnmp/timeticks.rb +8 -10
- data/lib/netsnmp/v3_session.rb +11 -13
- data/lib/netsnmp/varbind.rb +53 -49
- data/lib/netsnmp/version.rb +2 -1
- data/lib/netsnmp.rb +32 -12
- data/netsnmp.gemspec +10 -10
- data/spec/client_spec.rb +69 -49
- data/spec/handlers/celluloid_spec.rb +14 -10
- data/spec/oid_spec.rb +5 -3
- data/spec/pdu_spec.rb +14 -7
- data/spec/security_parameters_spec.rb +50 -18
- data/spec/session_spec.rb +9 -6
- data/spec/spec_helper.rb +14 -65
- data/spec/support/Dockerfile +3 -3
- data/spec/support/celluloid.rb +12 -6
- data/spec/support/request_examples.rb +19 -8
- data/spec/support/specs.sh +39 -0
- data/spec/support/{start_docker.sh → start-docker.sh} +4 -4
- data/spec/timeticks_spec.rb +2 -0
- data/spec/v3_session_spec.rb +8 -4
- data/spec/varbind_spec.rb +12 -0
- metadata +13 -9
data/lib/netsnmp.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require "netsnmp/version"
|
3
4
|
require "openssl"
|
4
5
|
require "io/wait"
|
5
6
|
require "securerandom"
|
6
7
|
require "ipaddr"
|
7
8
|
|
8
|
-
|
9
9
|
# core structures
|
10
10
|
|
11
11
|
begin
|
@@ -18,24 +18,23 @@ rescue LoadError
|
|
18
18
|
module StringExtensions
|
19
19
|
refine String do
|
20
20
|
# Bitwise XOR operator for the String class
|
21
|
-
def xor(
|
22
|
-
b1 =
|
23
|
-
return b1
|
24
|
-
|
21
|
+
def xor(other)
|
22
|
+
b1 = unpack("C*")
|
23
|
+
return b1 unless other
|
24
|
+
|
25
25
|
b2 = other.unpack("C*")
|
26
|
-
longest = [b1.length,b2.length].max
|
27
|
-
b1 = [0]*(longest-b1.length) + b1
|
28
|
-
b2 = [0]*(longest-b2.length) + b2
|
29
|
-
b1.zip(b2).map{ |a,b| a^b }.pack("C*")
|
26
|
+
longest = [b1.length, b2.length].max
|
27
|
+
b1 = [0] * (longest - b1.length) + b1
|
28
|
+
b2 = [0] * (longest - b2.length) + b2
|
29
|
+
b1.zip(b2).map { |a, b| a ^ b }.pack("C*")
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
|
37
36
|
module NETSNMP
|
38
|
-
def self.
|
37
|
+
def self.debug=(io)
|
39
38
|
@debug_output = io
|
40
39
|
end
|
41
40
|
|
@@ -55,7 +54,6 @@ module NETSNMP
|
|
55
54
|
end
|
56
55
|
end
|
57
56
|
|
58
|
-
|
59
57
|
require "netsnmp/errors"
|
60
58
|
|
61
59
|
require "netsnmp/timeticks"
|
@@ -73,3 +71,25 @@ require "netsnmp/encryption/des"
|
|
73
71
|
require "netsnmp/encryption/aes"
|
74
72
|
|
75
73
|
require "netsnmp/client"
|
74
|
+
|
75
|
+
unless Numeric.method_defined?(:positive?)
|
76
|
+
# Ruby 2.3 Backport (Numeric#positive?)
|
77
|
+
#
|
78
|
+
module PosMethods
|
79
|
+
def positive?
|
80
|
+
self > 0
|
81
|
+
end
|
82
|
+
end
|
83
|
+
Numeric.__send__(:include, PosMethods)
|
84
|
+
end
|
85
|
+
|
86
|
+
unless String.method_defined?(:+@)
|
87
|
+
# Backport for +"", to initialize unfrozen strings from the string literal.
|
88
|
+
#
|
89
|
+
module LiteralStringExtensions
|
90
|
+
def +@
|
91
|
+
frozen? ? dup : self
|
92
|
+
end
|
93
|
+
end
|
94
|
+
String.__send__(:include, LiteralStringExtensions)
|
95
|
+
end
|
data/netsnmp.gemspec
CHANGED
@@ -1,29 +1,29 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require File.expand_path("../lib/netsnmp/version", __FILE__)
|
2
4
|
|
3
5
|
Gem::Specification.new do |gem|
|
4
6
|
gem.name = "netsnmp"
|
5
7
|
gem.summary = "SNMP Client library"
|
6
|
-
gem.description =
|
7
|
-
Wraps the net-snmp core usage into idiomatic ruby.
|
8
|
-
It is designed to support as many environments and concurrency frameworks as possible.
|
9
|
-
DESC
|
10
|
-
gem.requirements = [
|
8
|
+
gem.description = <<-DESC
|
9
|
+
Wraps the net-snmp core usage into idiomatic ruby.
|
10
|
+
It is designed to support as many environments and concurrency frameworks as possible.
|
11
|
+
DESC
|
12
|
+
gem.requirements = ["net-snmp"]
|
11
13
|
gem.version = NETSNMP::VERSION
|
12
14
|
gem.license = "Apache-2.0"
|
13
15
|
gem.authors = ["Tiago Cardoso"]
|
14
16
|
gem.email = "cardoso_tiago@hotmail.com"
|
15
17
|
gem.homepage = ""
|
16
18
|
gem.platform = Gem::Platform::RUBY
|
17
|
-
gem.required_ruby_version = '>=2.1.0'
|
18
19
|
gem.metadata["allowed_push_host"] = "https://rubygems.org/"
|
19
20
|
|
20
21
|
# Manifest
|
21
|
-
gem.files = `git ls-files`.split("\n") - Dir[
|
22
|
+
gem.files = `git ls-files`.split("\n") - Dir["tmp/**/*"]
|
22
23
|
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
23
|
-
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
24
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
24
25
|
gem.require_paths = ["lib"]
|
25
26
|
|
26
|
-
gem.executables = Dir["bin/*"].map { |e| File.basename e }
|
27
27
|
gem.add_development_dependency "rake", ["~> 10.1", ">= 10.1.0"]
|
28
28
|
gem.add_development_dependency "rspec", ["~> 3.5", ">= 3.5.0"]
|
29
29
|
|
data/spec/client_spec.rb
CHANGED
@@ -1,25 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative "support/request_examples"
|
2
4
|
|
3
5
|
RSpec.describe NETSNMP::Client do
|
4
6
|
let(:host) { "localhost" }
|
5
7
|
|
6
|
-
let(:device_options)
|
7
|
-
|
8
|
-
|
9
|
-
|
8
|
+
let(:device_options) do
|
9
|
+
{
|
10
|
+
peername: "localhost",
|
11
|
+
port: SNMPPORT
|
12
|
+
}
|
13
|
+
end
|
10
14
|
describe "v1" do
|
11
15
|
it_behaves_like "an snmp client" do
|
12
|
-
let(:protocol_options)
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
+
let(:protocol_options) do
|
17
|
+
{
|
18
|
+
version: "1",
|
19
|
+
community: "public"
|
20
|
+
}
|
21
|
+
end
|
16
22
|
let(:get_oid) { "1.3.6.1.2.1.1.5.0" }
|
17
23
|
let(:next_oid) { "1.3.6.1.2.1.1.6.0" }
|
18
24
|
let(:walk_oid) { "1.3.6.1.2.1.1" }
|
19
25
|
let(:set_oid) { "1.3.6.1.2.1.1.3.0" } # sysUpTimeInstance
|
20
26
|
let(:get_result) { "DEVICE-192.168.1.1" }
|
21
27
|
let(:next_result) { "The Cloud" }
|
22
|
-
let(:walk_result)
|
28
|
+
let(:walk_result) do
|
29
|
+
<<-WALK
|
23
30
|
1.3.6.1.2.1.1.1.0: Device description
|
24
31
|
1.3.6.1.2.1.1.2.0: 1.3.6.1.4.1.3454
|
25
32
|
1.3.6.1.2.1.1.3.0: Timeticks: (78171676) 9 days, 1:8:36.76
|
@@ -28,24 +35,27 @@ RSpec.describe NETSNMP::Client do
|
|
28
35
|
1.3.6.1.2.1.1.6.0: The Cloud
|
29
36
|
1.3.6.1.2.1.1.7.0: 72
|
30
37
|
1.3.6.1.2.1.1.8.0: Timeticks: (0) 0 days, 0:0:0.0
|
31
|
-
WALK
|
32
|
-
|
38
|
+
WALK
|
39
|
+
end
|
33
40
|
let(:set_oid_result) { 43 }
|
34
41
|
end
|
35
42
|
end
|
36
43
|
describe "v2" do
|
37
44
|
it_behaves_like "an snmp client" do
|
38
|
-
let(:protocol_options)
|
39
|
-
|
40
|
-
|
41
|
-
|
45
|
+
let(:protocol_options) do
|
46
|
+
{
|
47
|
+
version: "2c",
|
48
|
+
community: "public"
|
49
|
+
}
|
50
|
+
end
|
42
51
|
let(:get_oid) { "1.3.6.1.2.1.1.5.0" }
|
43
52
|
let(:next_oid) { "1.3.6.1.2.1.1.6.0" }
|
44
53
|
let(:walk_oid) { "1.3.6.1.2.1.1" }
|
45
54
|
let(:set_oid) { "1.3.6.1.2.1.1.3.0" }
|
46
55
|
let(:get_result) { "DEVICE-192.168.1.1" }
|
47
56
|
let(:next_result) { "The Cloud" }
|
48
|
-
let(:walk_result)
|
57
|
+
let(:walk_result) do
|
58
|
+
<<-WALK
|
49
59
|
1.3.6.1.2.1.1.1.0: Device description
|
50
60
|
1.3.6.1.2.1.1.2.0: 1.3.6.1.4.1.3454
|
51
61
|
1.3.6.1.2.1.1.3.0: Timeticks: (78171676) 9 days, 1:8:36.76
|
@@ -54,27 +64,28 @@ WALK
|
|
54
64
|
1.3.6.1.2.1.1.6.0: The Cloud
|
55
65
|
1.3.6.1.2.1.1.7.0: 72
|
56
66
|
1.3.6.1.2.1.1.8.0: Timeticks: (0) 0 days, 0:0:0.0
|
57
|
-
WALK
|
58
|
-
|
67
|
+
WALK
|
68
|
+
end
|
59
69
|
let(:set_oid_result) { 43 }
|
60
|
-
|
61
70
|
end
|
62
71
|
end
|
63
72
|
|
64
|
-
|
65
73
|
describe "v3" do
|
66
74
|
let(:extra_options) { {} }
|
67
|
-
let(:version_options)
|
68
|
-
|
69
|
-
|
70
|
-
|
75
|
+
let(:version_options) do
|
76
|
+
{
|
77
|
+
version: "3",
|
78
|
+
context: "a172334d7d97871b72241397f713fa12"
|
79
|
+
}
|
80
|
+
end
|
71
81
|
let(:get_oid) { "1.3.6.1.2.1.1.5.0" }
|
72
82
|
let(:next_oid) { "1.3.6.1.2.1.1.6.0" }
|
73
83
|
let(:set_oid) { "1.3.6.1.2.1.1.3.0" } # sysUpTimeInstance
|
74
84
|
let(:walk_oid) { "1.3.6.1.2.1.1.9.1.3" }
|
75
85
|
let(:get_result) { "tt" }
|
76
86
|
let(:next_result) { "KK12" }
|
77
|
-
let(:walk_result)
|
87
|
+
let(:walk_result) do
|
88
|
+
<<-WALK
|
78
89
|
1.3.6.1.2.1.1.9.1.3.1: The SNMP Management Architecture MIB.
|
79
90
|
1.3.6.1.2.1.1.9.1.3.2: The MIB for Message Processing and Dispatching.
|
80
91
|
1.3.6.1.2.1.1.9.1.3.3: The management information definitions for the SNMP User-based Security Model.
|
@@ -83,9 +94,9 @@ WALK
|
|
83
94
|
1.3.6.1.2.1.1.9.1.3.6: The MIB module for managing IP and ICMP implementations
|
84
95
|
1.3.6.1.2.1.1.9.1.3.7: The MIB module for managing UDP implementations
|
85
96
|
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}
|
97
|
+
WALK
|
98
|
+
end
|
99
|
+
let(:set_oid_result) { 43 }
|
89
100
|
context "with a no auth no priv policy" do
|
90
101
|
let(:user_options) { { username: "unsafe", security_level: :noauth } }
|
91
102
|
it_behaves_like "an snmp client" do
|
@@ -95,12 +106,11 @@ WALK
|
|
95
106
|
# is here so that I test the set call at least once, although I'm sure it'll work always
|
96
107
|
# for v3
|
97
108
|
describe "#set" do
|
98
|
-
let(:extra_options) { {
|
99
|
-
context: "0886e1397d572377c17c15036a1e6c66" } }
|
109
|
+
let(:extra_options) { { context: "0886e1397d572377c17c15036a1e6c66" } }
|
100
110
|
it "updates the value of the oid" do
|
101
111
|
prev_value = subject.get(oid: set_oid)
|
102
112
|
expect(prev_value).to be_a(Integer)
|
103
|
-
|
113
|
+
|
104
114
|
# without type
|
105
115
|
subject.set(oid: set_oid, value: set_oid_result)
|
106
116
|
expect(subject.get(oid: set_oid)).to eq(set_oid_result)
|
@@ -108,56 +118,66 @@ WALK
|
|
108
118
|
subject.set(oid: set_oid, value: prev_value)
|
109
119
|
end
|
110
120
|
end
|
111
|
-
|
112
121
|
end
|
113
122
|
end
|
114
123
|
context "with an only auth policy" do
|
115
124
|
context "speaking md5" do
|
116
|
-
let(:user_options)
|
117
|
-
|
125
|
+
let(:user_options) do
|
126
|
+
{ username: "authmd5", security_level: :auth_no_priv,
|
127
|
+
auth_password: "maplesyrup", auth_protocol: :md5 }
|
128
|
+
end
|
118
129
|
it_behaves_like "an snmp client" do
|
119
130
|
let(:protocol_options) { version_options.merge(user_options).merge(extra_options) }
|
120
131
|
end
|
121
132
|
end
|
122
133
|
context "speaking sha" do
|
123
|
-
let(:user_options)
|
124
|
-
|
134
|
+
let(:user_options) do
|
135
|
+
{ username: "authsha", security_level: :auth_no_priv,
|
136
|
+
auth_password: "maplesyrup", auth_protocol: :sha }
|
137
|
+
end
|
125
138
|
it_behaves_like "an snmp client" do
|
126
139
|
let(:protocol_options) { version_options.merge(user_options).merge(extra_options) }
|
127
140
|
end
|
128
141
|
end
|
129
|
-
|
130
142
|
end
|
131
143
|
context "with an auth priv policy" do
|
132
144
|
context "auth in md5, encrypting in des" do
|
133
|
-
let(:user_options)
|
134
|
-
|
135
|
-
|
145
|
+
let(:user_options) do
|
146
|
+
{ username: "authprivmd5des", auth_password: "maplesyrup",
|
147
|
+
auth_protocol: :md5, priv_password: "maplesyrup",
|
148
|
+
priv_protocol: :des }
|
149
|
+
end
|
136
150
|
it_behaves_like "an snmp client" do
|
137
151
|
let(:protocol_options) { version_options.merge(user_options).merge(extra_options) }
|
138
152
|
end
|
139
153
|
end
|
140
154
|
context "auth in sha, encrypting in des" do
|
141
|
-
let(:user_options)
|
142
|
-
|
143
|
-
|
155
|
+
let(:user_options) do
|
156
|
+
{ username: "authprivshades", auth_password: "maplesyrup",
|
157
|
+
auth_protocol: :sha, priv_password: "maplesyrup",
|
158
|
+
priv_protocol: :des }
|
159
|
+
end
|
144
160
|
it_behaves_like "an snmp client" do
|
145
161
|
let(:protocol_options) { version_options.merge(user_options).merge(extra_options) }
|
146
162
|
end
|
147
163
|
end
|
148
164
|
|
149
165
|
context "auth in md5, encrypting in aes" do
|
150
|
-
let(:user_options)
|
151
|
-
|
152
|
-
|
166
|
+
let(:user_options) do
|
167
|
+
{ username: "authprivmd5aes", auth_password: "maplesyrup",
|
168
|
+
auth_protocol: :md5, priv_password: "maplesyrup",
|
169
|
+
priv_protocol: :aes }
|
170
|
+
end
|
153
171
|
it_behaves_like "an snmp client" do
|
154
172
|
let(:protocol_options) { version_options.merge(user_options).merge(extra_options) }
|
155
173
|
end
|
156
174
|
end
|
157
175
|
context "auth in sha, encrypting in aes" do
|
158
|
-
let(:user_options)
|
159
|
-
|
160
|
-
|
176
|
+
let(:user_options) do
|
177
|
+
{ username: "authprivshaaes", auth_password: "maplesyrup",
|
178
|
+
auth_protocol: :sha, priv_password: "maplesyrup",
|
179
|
+
priv_protocol: :aes }
|
180
|
+
end
|
161
181
|
it_behaves_like "an snmp client" do
|
162
182
|
let(:protocol_options) { version_options.merge(user_options).merge(extra_options) }
|
163
183
|
end
|
@@ -1,12 +1,16 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "celluloid/io"
|
2
4
|
require_relative "../support/request_examples"
|
3
|
-
require_relative
|
5
|
+
require_relative "../support/celluloid"
|
4
6
|
|
5
7
|
RSpec.describe "with cellulloid", type: :celluloid do
|
6
8
|
include CelluloidHelpers
|
7
|
-
let(:user_options)
|
8
|
-
|
9
|
-
|
9
|
+
let(:user_options) do
|
10
|
+
{ username: "authprivmd5des", auth_password: "maplesyrup",
|
11
|
+
auth_protocol: :md5, priv_password: "maplesyrup",
|
12
|
+
priv_protocol: :des }
|
13
|
+
end
|
10
14
|
|
11
15
|
let(:get_oid) { "1.3.6.1.2.1.1.5.0" }
|
12
16
|
let(:next_oid) { "1.3.6.1.2.1.1.6.0" }
|
@@ -14,7 +18,8 @@ RSpec.describe "with cellulloid", type: :celluloid do
|
|
14
18
|
let(:walk_oid) { "1.3.6.1.2.1.1.9.1.3" }
|
15
19
|
let(:get_result) { "tt" }
|
16
20
|
let(:next_result) { "KK12" }
|
17
|
-
let(:walk_result)
|
21
|
+
let(:walk_result) do
|
22
|
+
<<-WALK
|
18
23
|
1.3.6.1.2.1.1.9.1.3.1: The SNMP Management Architecture MIB.
|
19
24
|
1.3.6.1.2.1.1.9.1.3.2: The MIB for Message Processing and Dispatching.
|
20
25
|
1.3.6.1.2.1.1.9.1.3.3: The management information definitions for the SNMP User-based Security Model.
|
@@ -23,14 +28,14 @@ RSpec.describe "with cellulloid", type: :celluloid do
|
|
23
28
|
1.3.6.1.2.1.1.9.1.3.6: The MIB module for managing IP and ICMP implementations
|
24
29
|
1.3.6.1.2.1.1.9.1.3.7: The MIB module for managing UDP implementations
|
25
30
|
1.3.6.1.2.1.1.9.1.3.8: View-based Access Control Model for SNMP.
|
26
|
-
WALK
|
27
|
-
|
31
|
+
WALK
|
32
|
+
end
|
28
33
|
|
29
34
|
around(:each) do |example|
|
30
35
|
within_io_actor { example.run }
|
31
36
|
end
|
32
37
|
let(:proxy) { CelluloidHelpers::Proxy.new("localhost", SNMPPORT) }
|
33
|
-
after(:each) { proxy.close }
|
38
|
+
after(:each) { proxy.close }
|
34
39
|
|
35
40
|
it_behaves_like "an snmp client" do
|
36
41
|
subject { NETSNMP::Client.new(options) }
|
@@ -38,5 +43,4 @@ WALK
|
|
38
43
|
let(:protocol_options) { user_options }
|
39
44
|
let(:extra_options) { { version: 3, context: "a172334d7d97871b72241397f713fa12" } }
|
40
45
|
end
|
41
|
-
|
42
46
|
end
|
data/spec/oid_spec.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
RSpec.describe NETSNMP::OID do
|
2
|
-
#let(:code) { "SNMPv2-MIB::sysDescr.0" }
|
4
|
+
# let(:code) { "SNMPv2-MIB::sysDescr.0" }
|
3
5
|
let(:code) { "1.3.6.1.2.1.1.1.0" }
|
4
6
|
subject { described_class.build(code) }
|
5
|
-
|
7
|
+
|
6
8
|
describe ".build" do
|
7
|
-
it { expect(described_class.build([1,3,6,1,2,1,1,1,0]).to_s).to eq(code) }
|
9
|
+
it { expect(described_class.build([1, 3, 6, 1, 2, 1, 1, 1, 0]).to_s).to eq(code) }
|
8
10
|
it { expect(described_class.build(".#{code}").to_s).to eq(code) }
|
9
11
|
it { expect { described_class.build("blablabla") }.to raise_error(NETSNMP::Error) }
|
10
12
|
end
|
data/spec/pdu_spec.rb
CHANGED
@@ -1,12 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
RSpec.describe NETSNMP::PDU do
|
2
4
|
let(:get_request_oid) { ".1.3.6.1.2.1.1.1.0" }
|
3
|
-
let(:encoded_get_pdu)
|
4
|
-
|
5
|
+
let(:encoded_get_pdu) do
|
6
|
+
"0'\002\001\000\004\006public\240\032\002\002?*\002\001\000\002\001\0000\0160\f\006\b+\006\001\002\001\001\001\000\005\000"
|
7
|
+
end
|
8
|
+
let(:encoded_response_pdu) do
|
9
|
+
"0+\002\001\000\004\006public\242\036\002\002'\017\002\001\000\002\001\0000\0220\020\006\b+\006\001\002\001\001\001\000\004\004test"
|
10
|
+
end
|
5
11
|
|
6
12
|
describe "#to_der" do
|
7
|
-
let(:pdu_get)
|
8
|
-
|
9
|
-
|
13
|
+
let(:pdu_get) do
|
14
|
+
described_class.build(:get, headers: [0, "public"],
|
15
|
+
request_id: 16170)
|
16
|
+
end
|
10
17
|
|
11
18
|
context "v1" do
|
12
19
|
before { pdu_get.add_varbind(oid: get_request_oid) }
|
@@ -22,8 +29,8 @@ RSpec.describe NETSNMP::PDU do
|
|
22
29
|
it { expect(pdu_response.request_id).to be(9999) }
|
23
30
|
|
24
31
|
it { expect(pdu_response.varbinds.length).to be(1) }
|
25
|
-
it { expect(pdu_response.varbinds[0].oid).to eq("1.3.6.1.2.1.1.1.0") }
|
26
|
-
it { expect(pdu_response.varbinds[0].value).to eq("test") }
|
32
|
+
it { expect(pdu_response.varbinds[0].oid).to eq("1.3.6.1.2.1.1.1.0") }
|
33
|
+
it { expect(pdu_response.varbinds[0].value).to eq("test") }
|
27
34
|
end
|
28
35
|
end
|
29
36
|
end
|
@@ -1,34 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# FROM https://tools.ietf.org/html/rfc3414#appendix-A.2.1
|
2
4
|
RSpec.describe NETSNMP::SecurityParameters do
|
3
|
-
let(:engine_id) {"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02".b
|
5
|
+
let(:engine_id) { "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02".b }
|
4
6
|
let(:password) { "maplesyrup" }
|
5
7
|
describe "#passkey" do
|
6
8
|
context "md5" do
|
7
|
-
subject { described_class.new(security_level: :auth_no_priv, auth_protocol: :md5, username: "username", engine_id: engine_id, auth_password: "maplesyrup"
|
9
|
+
subject { described_class.new(security_level: :auth_no_priv, auth_protocol: :md5, username: "username", engine_id: engine_id, auth_password: "maplesyrup") }
|
8
10
|
it { expect(subject.send(:passkey, password)).to eq("\x9f\xaf\x32\x83\x88\x4e\x92\x83\x4e\xbc\x98\x47\xd8\xed\xd9\x63".b) }
|
9
11
|
end
|
10
12
|
context "sha" do
|
11
|
-
subject { described_class.new(security_level: :auth_priv, auth_protocol: :sha, username: "username", engine_id: engine_id,
|
13
|
+
subject { described_class.new(security_level: :auth_priv, auth_protocol: :sha, username: "username", engine_id: engine_id, auth_password: "maplesyrup", priv_password: "maplesyrup") }
|
12
14
|
it { expect(subject.send(:passkey, password).b).to eq("\x9f\xb5\xcc\x03\x81\x49\x7b\x37\x93\x52\x89\x39\xff\x78\x8d\x5d\x79\x14\x52\x11".b) }
|
13
15
|
end
|
14
16
|
end
|
15
17
|
|
16
|
-
|
17
18
|
describe "keys" do
|
18
|
-
let(:md5_sec)
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
19
|
+
let(:md5_sec) do
|
20
|
+
described_class.new(security_level: :auth_priv,
|
21
|
+
auth_protocol: :md5,
|
22
|
+
priv_protocol: :des,
|
23
|
+
username: "username",
|
24
|
+
auth_password: password,
|
25
|
+
priv_password: password,
|
26
|
+
engine_id: engine_id)
|
27
|
+
end
|
28
|
+
let(:sha_sec) do
|
29
|
+
described_class.new(security_level: :auth_priv,
|
30
|
+
auth_protocol: :sha,
|
31
|
+
priv_protocol: :des,
|
32
|
+
username: "username",
|
33
|
+
auth_password: password,
|
34
|
+
priv_password: password,
|
35
|
+
engine_id: engine_id)
|
36
|
+
end
|
32
37
|
it do
|
33
38
|
expect(md5_sec.send(:auth_key)).to eq("\x52\x6f\x5e\xed\x9f\xcc\xe2\x6f\x89\x64\xc2\x93\x07\x87\xd8\x2b".b)
|
34
39
|
expect(md5_sec.send(:priv_key)).to eq("\x52\x6f\x5e\xed\x9f\xcc\xe2\x6f\x89\x64\xc2\x93\x07\x87\xd8\x2b".b)
|
@@ -37,4 +42,31 @@ RSpec.describe NETSNMP::SecurityParameters do
|
|
37
42
|
end
|
38
43
|
end
|
39
44
|
|
45
|
+
context "#must_revalidate?" do
|
46
|
+
let(:security_options) do
|
47
|
+
{ username: "authprivmd5des", auth_password: "maplesyrup",
|
48
|
+
auth_protocol: :md5, priv_password: "maplesyrup",
|
49
|
+
priv_protocol: :des, security_level: :auth_priv }
|
50
|
+
end
|
51
|
+
subject { described_class.new(**security_options) }
|
52
|
+
context "for v3" do
|
53
|
+
context "when initialized" do
|
54
|
+
it { expect(subject.must_revalidate?).to be_truthy }
|
55
|
+
end
|
56
|
+
context "when given a new engine id" do
|
57
|
+
before { subject.engine_id = "NEWENGINE" }
|
58
|
+
it { expect(subject.must_revalidate?).to be_falsy }
|
59
|
+
context "when limit surpasses" do
|
60
|
+
before do
|
61
|
+
subject.instance_variable_set(:@timeliness, Process.clock_gettime(Process::CLOCK_MONOTONIC, :second) - 150)
|
62
|
+
end
|
63
|
+
it { expect(subject.must_revalidate?).to be_truthy }
|
64
|
+
context "when given a new engine id" do
|
65
|
+
before { subject.engine_id = "UPDATEDENGINE" }
|
66
|
+
it { expect(subject.must_revalidate?).to be_falsy }
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
40
72
|
end
|
data/spec/session_spec.rb
CHANGED
@@ -1,11 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
RSpec.describe NETSNMP::Session do
|
2
4
|
let(:host) { "localhost" }
|
3
|
-
let(:options)
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
let(:options) do
|
6
|
+
{
|
7
|
+
version: "2c",
|
8
|
+
context: "public",
|
9
|
+
port: SNMPPORT
|
10
|
+
}
|
11
|
+
end
|
8
12
|
subject { described_class.new(host, options) }
|
9
13
|
after { subject.close }
|
10
|
-
|
11
14
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,20 +1,23 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "simplecov" if ENV["COVERAGE"]
|
4
|
+
require "coveralls"
|
3
5
|
Coveralls.wear!
|
4
6
|
|
5
|
-
SimpleCov
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
if defined?(SimpleCov)
|
8
|
+
SimpleCov.start do
|
9
|
+
minimum_coverage 85
|
10
|
+
add_filter ".bundle"
|
11
|
+
add_filter "/spec/"
|
12
|
+
end
|
13
|
+
end
|
10
14
|
|
11
|
-
require
|
15
|
+
require "bundler/setup"
|
12
16
|
Bundler.require(:default, :test)
|
13
17
|
|
14
|
-
require
|
15
|
-
|
18
|
+
require "netsnmp"
|
16
19
|
|
17
|
-
SNMPPORT =
|
20
|
+
SNMPPORT = (ENV["SNMP_PORT"] || 1161).to_i
|
18
21
|
|
19
22
|
# This file was generated by the `rspec --init` command. Conventionally, all
|
20
23
|
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
@@ -57,58 +60,4 @@ RSpec.configure do |config|
|
|
57
60
|
# `true` in RSpec 4.
|
58
61
|
mocks.verify_partial_doubles = true
|
59
62
|
end
|
60
|
-
|
61
|
-
# The settings below are suggested to provide a good initial experience
|
62
|
-
# with RSpec, but feel free to customize to your heart's content.
|
63
|
-
=begin
|
64
|
-
# These two settings work together to allow you to limit a spec run
|
65
|
-
# to individual examples or groups you care about by tagging them with
|
66
|
-
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
|
67
|
-
# get run.
|
68
|
-
config.filter_run :focus
|
69
|
-
config.run_all_when_everything_filtered = true
|
70
|
-
|
71
|
-
# Allows RSpec to persist some state between runs in order to support
|
72
|
-
# the `--only-failures` and `--next-failure` CLI options. We recommend
|
73
|
-
# you configure your source control system to ignore this file.
|
74
|
-
config.example_status_persistence_file_path = "spec/examples.txt"
|
75
|
-
|
76
|
-
# Limits the available syntax to the non-monkey patched syntax that is
|
77
|
-
# recommended. For more details, see:
|
78
|
-
# - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax
|
79
|
-
# - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
80
|
-
# - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching
|
81
|
-
config.disable_monkey_patching!
|
82
|
-
|
83
|
-
# This setting enables warnings. It's recommended, but in some cases may
|
84
|
-
# be too noisy due to issues in dependencies.
|
85
|
-
config.warnings = true
|
86
|
-
|
87
|
-
# Many RSpec users commonly either run the entire suite or an individual
|
88
|
-
# file, and it's useful to allow more verbose output when running an
|
89
|
-
# individual spec file.
|
90
|
-
if config.files_to_run.one?
|
91
|
-
# Use the documentation formatter for detailed output,
|
92
|
-
# unless a formatter has already been configured
|
93
|
-
# (e.g. via a command-line flag).
|
94
|
-
config.default_formatter = 'doc'
|
95
|
-
end
|
96
|
-
|
97
|
-
# Print the 10 slowest examples and example groups at the
|
98
|
-
# end of the spec run, to help surface which specs are running
|
99
|
-
# particularly slow.
|
100
|
-
config.profile_examples = 10
|
101
|
-
|
102
|
-
# Run specs in random order to surface order dependencies. If you find an
|
103
|
-
# order dependency and want to debug it, you can fix the order by providing
|
104
|
-
# the seed, which is printed after each run.
|
105
|
-
# --seed 1234
|
106
|
-
config.order = :random
|
107
|
-
|
108
|
-
# Seed global randomization in this process using the `--seed` CLI option.
|
109
|
-
# Setting this allows you to use `--seed` to deterministically reproduce
|
110
|
-
# test failures related to randomization by passing the same `--seed` value
|
111
|
-
# as the one that triggered the failure.
|
112
|
-
Kernel.srand config.seed
|
113
|
-
=end
|
114
63
|
end
|