net-ldap 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of net-ldap might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.gitignore +7 -0
- data/.travis.yml +19 -1
- data/CONTRIBUTING.md +54 -0
- data/Hacking.rdoc +2 -4
- data/History.rdoc +37 -0
- data/Manifest.txt +0 -4
- data/README.rdoc +8 -0
- data/Rakefile +1 -3
- data/lib/net/ber/core_ext.rb +5 -5
- data/lib/net/ber/core_ext/string.rb +7 -7
- data/lib/net/ber/core_ext/true_class.rb +2 -3
- data/lib/net/ldap.rb +134 -620
- data/lib/net/ldap/connection.rb +692 -0
- data/lib/net/ldap/dataset.rb +18 -4
- data/lib/net/ldap/entry.rb +1 -1
- data/lib/net/ldap/filter.rb +7 -7
- data/lib/net/ldap/password.rb +11 -11
- data/lib/net/ldap/pdu.rb +28 -4
- data/lib/net/ldap/version.rb +1 -1
- data/lib/net/snmp.rb +235 -241
- data/net-ldap.gemspec +7 -33
- data/script/install-openldap +47 -0
- data/script/package +7 -0
- data/script/release +16 -0
- data/test/ber/core_ext/test_array.rb +22 -0
- data/test/ber/core_ext/test_string.rb +25 -0
- data/test/ber/test_ber.rb +126 -0
- data/test/fixtures/openldap/memberof.ldif +33 -0
- data/test/fixtures/openldap/retcode.ldif +76 -0
- data/test/fixtures/openldap/slapd.conf.ldif +67 -0
- data/test/fixtures/seed.ldif +374 -0
- data/test/integration/test_add.rb +28 -0
- data/test/integration/test_ber.rb +30 -0
- data/test/integration/test_bind.rb +22 -0
- data/test/integration/test_delete.rb +31 -0
- data/test/integration/test_open.rb +88 -0
- data/test/integration/test_return_codes.rb +38 -0
- data/test/integration/test_search.rb +77 -0
- data/test/support/vm/openldap/.gitignore +1 -0
- data/test/support/vm/openldap/README.md +32 -0
- data/test/support/vm/openldap/Vagrantfile +33 -0
- data/test/test_dn.rb +44 -0
- data/test/test_entry.rb +62 -56
- data/test/test_filter.rb +98 -2
- data/test/test_filter_parser.rb +16 -0
- data/test/test_helper.rb +54 -0
- data/test/test_ldap.rb +60 -0
- data/test/test_ldap_connection.rb +382 -2
- data/test/test_ldif.rb +26 -1
- data/test/test_password.rb +3 -10
- data/test/test_rename.rb +2 -2
- data/test/test_search.rb +39 -0
- data/test/test_snmp.rb +1 -1
- data/test/test_ssl_ber.rb +40 -0
- metadata +70 -75
- data/.autotest +0 -11
- data/.gemtest +0 -0
- data/.rspec +0 -2
- data/autotest/discover.rb +0 -1
- data/spec/integration/ssl_ber_spec.rb +0 -39
- data/spec/spec.opts +0 -2
- data/spec/spec_helper.rb +0 -28
- data/spec/unit/ber/ber_spec.rb +0 -141
- data/spec/unit/ber/core_ext/array_spec.rb +0 -24
- data/spec/unit/ber/core_ext/string_spec.rb +0 -51
- data/spec/unit/ldap/dn_spec.rb +0 -80
- data/spec/unit/ldap/entry_spec.rb +0 -51
- data/spec/unit/ldap/filter_parser_spec.rb +0 -26
- data/spec/unit/ldap/filter_spec.rb +0 -115
- data/spec/unit/ldap/search_spec.rb +0 -49
- data/spec/unit/ldap_spec.rb +0 -223
- data/test/common.rb +0 -3
data/lib/net/ldap/dataset.rb
CHANGED
@@ -4,11 +4,13 @@
|
|
4
4
|
# to and from LDIF strings and Net::LDAP::Entry objects.
|
5
5
|
class Net::LDAP::Dataset < Hash
|
6
6
|
##
|
7
|
-
# Dataset object comments.
|
8
|
-
|
7
|
+
# Dataset object version, comments.
|
8
|
+
attr_accessor :version
|
9
|
+
attr_reader :comments
|
9
10
|
|
10
11
|
def initialize(*args, &block) # :nodoc:
|
11
12
|
super
|
13
|
+
@version = nil
|
12
14
|
@comments = []
|
13
15
|
end
|
14
16
|
|
@@ -17,6 +19,12 @@ class Net::LDAP::Dataset < Hash
|
|
17
19
|
# entries.
|
18
20
|
def to_ldif
|
19
21
|
ary = []
|
22
|
+
|
23
|
+
if version
|
24
|
+
ary << "version: #{version}"
|
25
|
+
ary << ""
|
26
|
+
end
|
27
|
+
|
20
28
|
ary += @comments unless @comments.empty?
|
21
29
|
keys.sort.each do |dn|
|
22
30
|
ary << "dn: #{dn}"
|
@@ -125,8 +133,14 @@ class Net::LDAP::Dataset < Hash
|
|
125
133
|
if line =~ /^#/
|
126
134
|
ds.comments << line
|
127
135
|
yield :comment, line if block_given?
|
128
|
-
elsif line =~ /^
|
129
|
-
|
136
|
+
elsif line =~ /^version:[\s]*([0-9]+)$/i
|
137
|
+
ds.version = $1
|
138
|
+
yield :version, line if block_given?
|
139
|
+
elsif line =~ /^dn:([\:]?)[\s]*/i
|
140
|
+
# $1 is a colon if the dn-value is base-64 encoded
|
141
|
+
# $' is the dn-value
|
142
|
+
# Avoid the Base64 class because not all Ruby versions have it.
|
143
|
+
dn = ($1 == ":") ? $'.unpack('m').shift : $'
|
130
144
|
ds[dn] = Hash.new { |k,v| k[v] = [] }
|
131
145
|
yield :dn, dn if block_given?
|
132
146
|
elsif line.empty?
|
data/lib/net/ldap/entry.rb
CHANGED
@@ -115,7 +115,7 @@ class Net::LDAP::Entry
|
|
115
115
|
|
116
116
|
##
|
117
117
|
# Read the first value for the provided attribute. The attribute name
|
118
|
-
# is canonicalized prior to reading. Returns nil if the attribute does
|
118
|
+
# is canonicalized prior to reading. Returns nil if the attribute does
|
119
119
|
# not exist.
|
120
120
|
def first(name)
|
121
121
|
self[name].first
|
data/lib/net/ldap/filter.rb
CHANGED
@@ -242,7 +242,7 @@ class Net::LDAP::Filter
|
|
242
242
|
|
243
243
|
# http://tools.ietf.org/html/rfc4515 lists these exceptions from UTF1
|
244
244
|
# charset for filters. All of the following must be escaped in any normal
|
245
|
-
# string using a single backslash ('\') as escape.
|
245
|
+
# string using a single backslash ('\') as escape.
|
246
246
|
#
|
247
247
|
ESCAPES = {
|
248
248
|
"\0" => '00', # NUL = %x00 ; null character
|
@@ -251,10 +251,10 @@ class Net::LDAP::Filter
|
|
251
251
|
')' => '29', # RPARENS = %x29 ; right parenthesis (")")
|
252
252
|
'\\' => '5C', # ESC = %x5C ; esc (or backslash) ("\")
|
253
253
|
}
|
254
|
-
# Compiled character class regexp using the keys from the above hash.
|
254
|
+
# Compiled character class regexp using the keys from the above hash.
|
255
255
|
ESCAPE_RE = Regexp.new(
|
256
|
-
"[" +
|
257
|
-
ESCAPES.keys.map { |e| Regexp.escape(e) }.join +
|
256
|
+
"[" +
|
257
|
+
ESCAPES.keys.map { |e| Regexp.escape(e) }.join +
|
258
258
|
"]")
|
259
259
|
|
260
260
|
##
|
@@ -310,8 +310,8 @@ class Net::LDAP::Filter
|
|
310
310
|
present?(ber.to_s)
|
311
311
|
when 0xa9 # context-specific constructed 9, "extensible comparison"
|
312
312
|
raise Net::LDAP::LdapError, "Invalid extensible search filter, should be at least two elements" if ber.size<2
|
313
|
-
|
314
|
-
# Reassembles the extensible filter parts
|
313
|
+
|
314
|
+
# Reassembles the extensible filter parts
|
315
315
|
# (["sn", "2.4.6.8.10", "Barbara Jones", '1'])
|
316
316
|
type = value = dn = rule = nil
|
317
317
|
ber.each do |element|
|
@@ -327,7 +327,7 @@ class Net::LDAP::Filter
|
|
327
327
|
attribute << type if type
|
328
328
|
attribute << ":#{dn}" if dn
|
329
329
|
attribute << ":#{rule}" if rule
|
330
|
-
|
330
|
+
|
331
331
|
ex(attribute, value)
|
332
332
|
else
|
333
333
|
raise Net::LDAP::LdapError, "Invalid BER tag-value (#{ber.ber_identifier}) in search filter."
|
data/lib/net/ldap/password.rb
CHANGED
@@ -21,17 +21,17 @@ class Net::LDAP::Password
|
|
21
21
|
#
|
22
22
|
attribute_value = ""
|
23
23
|
def generate(type, str)
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
24
|
+
case type
|
25
|
+
when :md5
|
26
|
+
attribute_value = '{MD5}' + Base64.encode64(Digest::MD5.digest(str)).chomp!
|
27
|
+
when :sha
|
28
|
+
attribute_value = '{SHA}' + Base64.encode64(Digest::SHA1.digest(str)).chomp!
|
29
|
+
when :ssha
|
30
|
+
salt = SecureRandom.random_bytes(16)
|
31
|
+
attribute_value = '{SSHA}' + Base64.encode64(Digest::SHA1.digest(str + salt) + salt).chomp!
|
32
|
+
else
|
33
|
+
raise Net::LDAP::LdapError, "Unsupported password-hash type (#{type})"
|
34
|
+
end
|
35
35
|
return attribute_value
|
36
36
|
end
|
37
37
|
end
|
data/lib/net/ldap/pdu.rb
CHANGED
@@ -18,24 +18,48 @@ require 'ostruct'
|
|
18
18
|
# well with our approach.
|
19
19
|
#
|
20
20
|
# Currently, we only support controls on SearchResult.
|
21
|
+
#
|
22
|
+
# http://tools.ietf.org/html/rfc4511#section-4.1.1
|
23
|
+
# http://tools.ietf.org/html/rfc4511#section-4.1.9
|
21
24
|
class Net::LDAP::PDU
|
22
25
|
class Error < RuntimeError; end
|
23
26
|
|
24
|
-
|
25
|
-
# This message packet is a bind request.
|
27
|
+
# http://tools.ietf.org/html/rfc4511#section-4.2
|
26
28
|
BindRequest = 0
|
29
|
+
# http://tools.ietf.org/html/rfc4511#section-4.2.2
|
27
30
|
BindResult = 1
|
31
|
+
# http://tools.ietf.org/html/rfc4511#section-4.3
|
28
32
|
UnbindRequest = 2
|
33
|
+
# http://tools.ietf.org/html/rfc4511#section-4.5.1
|
29
34
|
SearchRequest = 3
|
35
|
+
# http://tools.ietf.org/html/rfc4511#section-4.5.2
|
30
36
|
SearchReturnedData = 4
|
31
37
|
SearchResult = 5
|
38
|
+
# see also SearchResultReferral (19)
|
39
|
+
# http://tools.ietf.org/html/rfc4511#section-4.6
|
40
|
+
ModifyRequest = 6
|
32
41
|
ModifyResponse = 7
|
42
|
+
# http://tools.ietf.org/html/rfc4511#section-4.7
|
43
|
+
AddRequest = 8
|
33
44
|
AddResponse = 9
|
45
|
+
# http://tools.ietf.org/html/rfc4511#section-4.8
|
46
|
+
DeleteRequest = 10
|
34
47
|
DeleteResponse = 11
|
48
|
+
# http://tools.ietf.org/html/rfc4511#section-4.9
|
49
|
+
ModifyRDNRequest = 12
|
35
50
|
ModifyRDNResponse = 13
|
51
|
+
# http://tools.ietf.org/html/rfc4511#section-4.10
|
52
|
+
CompareRequest = 14
|
53
|
+
CompareResponse = 15
|
54
|
+
# http://tools.ietf.org/html/rfc4511#section-4.11
|
55
|
+
AbandonRequest = 16
|
56
|
+
# http://tools.ietf.org/html/rfc4511#section-4.5.2
|
36
57
|
SearchResultReferral = 19
|
58
|
+
# http://tools.ietf.org/html/rfc4511#section-4.12
|
37
59
|
ExtendedRequest = 23
|
38
60
|
ExtendedResponse = 24
|
61
|
+
# unused: http://tools.ietf.org/html/rfc4511#section-4.13
|
62
|
+
IntermediateResponse = 25
|
39
63
|
|
40
64
|
##
|
41
65
|
# The LDAP packet message ID.
|
@@ -125,7 +149,7 @@ class Net::LDAP::PDU
|
|
125
149
|
end
|
126
150
|
|
127
151
|
def status
|
128
|
-
result_code
|
152
|
+
Net::LDAP::ResultCodesNonError.include?(result_code) ? :success : :failure
|
129
153
|
end
|
130
154
|
|
131
155
|
def success?
|
@@ -152,7 +176,7 @@ class Net::LDAP::PDU
|
|
152
176
|
:matchedDN => sequence[1],
|
153
177
|
:errorMessage => sequence[2]
|
154
178
|
}
|
155
|
-
parse_search_referral(sequence[3]) if @ldap_result[:resultCode] ==
|
179
|
+
parse_search_referral(sequence[3]) if @ldap_result[:resultCode] == Net::LDAP::ResultCodeReferral
|
156
180
|
end
|
157
181
|
private :parse_ldap_result
|
158
182
|
|
data/lib/net/ldap/version.rb
CHANGED
data/lib/net/snmp.rb
CHANGED
@@ -3,268 +3,262 @@ require 'net/ldap/version'
|
|
3
3
|
|
4
4
|
# :stopdoc:
|
5
5
|
module Net
|
6
|
-
|
7
|
-
|
6
|
+
class SNMP
|
7
|
+
VERSION = Net::LDAP::VERSION
|
8
|
+
AsnSyntax = Net::BER.compile_syntax({
|
9
|
+
:application => {
|
10
|
+
:primitive => {
|
11
|
+
1 => :integer, # Counter32, (RFC2578 sec 2)
|
12
|
+
2 => :integer, # Gauge32 or Unsigned32, (RFC2578 sec 2)
|
13
|
+
3 => :integer # TimeTicks32, (RFC2578 sec 2)
|
14
|
+
},
|
15
|
+
:constructed => {}
|
16
|
+
},
|
17
|
+
:context_specific => {
|
18
|
+
:primitive => {},
|
19
|
+
:constructed => {
|
20
|
+
0 => :array, # GetRequest PDU (RFC1157 pgh 4.1.2)
|
21
|
+
1 => :array, # GetNextRequest PDU (RFC1157 pgh 4.1.3)
|
22
|
+
2 => :array # GetResponse PDU (RFC1157 pgh 4.1.4)
|
23
|
+
}
|
24
|
+
}
|
25
|
+
})
|
8
26
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
:primitive => {
|
21
|
-
},
|
22
|
-
:constructed => {
|
23
|
-
0 => :array, # GetRequest PDU (RFC1157 pgh 4.1.2)
|
24
|
-
1 => :array, # GetNextRequest PDU (RFC1157 pgh 4.1.3)
|
25
|
-
2 => :array # GetResponse PDU (RFC1157 pgh 4.1.4)
|
26
|
-
}
|
27
|
-
}
|
28
|
-
})
|
29
|
-
|
30
|
-
# SNMP 32-bit counter.
|
31
|
-
# Defined in RFC1155 (Structure of Mangement Information), section 6.
|
32
|
-
# A 32-bit counter is an ASN.1 application [1] implicit unsigned integer
|
33
|
-
# with a range from 0 to 2^^32 - 1.
|
34
|
-
class Counter32
|
35
|
-
def initialize value
|
36
|
-
@value = value
|
37
|
-
end
|
38
|
-
def to_ber
|
39
|
-
@value.to_ber_application(1)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
# SNMP 32-bit gauge.
|
44
|
-
# Defined in RFC1155 (Structure of Mangement Information), section 6.
|
45
|
-
# A 32-bit counter is an ASN.1 application [2] implicit unsigned integer.
|
46
|
-
# This is also indistinguishable from Unsigned32. (Need to alias them.)
|
47
|
-
class Gauge32
|
48
|
-
def initialize value
|
49
|
-
@value = value
|
50
|
-
end
|
51
|
-
def to_ber
|
52
|
-
@value.to_ber_application(2)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
# SNMP 32-bit timer-ticks.
|
57
|
-
# Defined in RFC1155 (Structure of Mangement Information), section 6.
|
58
|
-
# A 32-bit counter is an ASN.1 application [3] implicit unsigned integer.
|
59
|
-
class TimeTicks32
|
60
|
-
def initialize value
|
61
|
-
@value = value
|
62
|
-
end
|
63
|
-
def to_ber
|
64
|
-
@value.to_ber_application(3)
|
65
|
-
end
|
66
|
-
end
|
27
|
+
# SNMP 32-bit counter.
|
28
|
+
# Defined in RFC1155 (Structure of Mangement Information), section 6.
|
29
|
+
# A 32-bit counter is an ASN.1 application [1] implicit unsigned integer
|
30
|
+
# with a range from 0 to 2^^32 - 1.
|
31
|
+
class Counter32
|
32
|
+
def initialize value
|
33
|
+
@value = value
|
34
|
+
end
|
35
|
+
def to_ber
|
36
|
+
@value.to_ber_application(1)
|
37
|
+
end
|
67
38
|
end
|
68
39
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
1 => "tooBig",
|
82
|
-
2 => "noSuchName",
|
83
|
-
3 => "badValue",
|
84
|
-
4 => "readOnly",
|
85
|
-
5 => "genErr"
|
86
|
-
}
|
40
|
+
# SNMP 32-bit gauge.
|
41
|
+
# Defined in RFC1155 (Structure of Mangement Information), section 6.
|
42
|
+
# A 32-bit counter is an ASN.1 application [2] implicit unsigned integer.
|
43
|
+
# This is also indistinguishable from Unsigned32. (Need to alias them.)
|
44
|
+
class Gauge32
|
45
|
+
def initialize value
|
46
|
+
@value = value
|
47
|
+
end
|
48
|
+
def to_ber
|
49
|
+
@value.to_ber_application(2)
|
50
|
+
end
|
51
|
+
end
|
87
52
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
53
|
+
# SNMP 32-bit timer-ticks.
|
54
|
+
# Defined in RFC1155 (Structure of Mangement Information), section 6.
|
55
|
+
# A 32-bit counter is an ASN.1 application [3] implicit unsigned integer.
|
56
|
+
class TimeTicks32
|
57
|
+
def initialize value
|
58
|
+
@value = value
|
59
|
+
end
|
60
|
+
def to_ber
|
61
|
+
@value.to_ber_application(3)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
95
65
|
|
96
|
-
|
97
|
-
|
66
|
+
class SnmpPdu
|
67
|
+
class Error < StandardError; end
|
68
|
+
PduTypes = [
|
69
|
+
:get_request,
|
70
|
+
:get_next_request,
|
71
|
+
:get_response,
|
72
|
+
:set_request,
|
73
|
+
:trap
|
74
|
+
]
|
75
|
+
ErrorStatusCodes = { # Per RFC1157, pgh 4.1.1
|
76
|
+
0 => "noError",
|
77
|
+
1 => "tooBig",
|
78
|
+
2 => "noSuchName",
|
79
|
+
3 => "badValue",
|
80
|
+
4 => "readOnly",
|
81
|
+
5 => "genErr"
|
82
|
+
}
|
98
83
|
|
84
|
+
class << self
|
85
|
+
def parse ber_object
|
86
|
+
n = new
|
87
|
+
n.send :parse, ber_object
|
88
|
+
n
|
89
|
+
end
|
90
|
+
end
|
99
91
|
|
100
|
-
|
101
|
-
|
102
|
-
@community = args[:community] || "public"
|
103
|
-
@pdu_type = args[:pdu_type] # leave nil unless specified; there's no reasonable default value.
|
104
|
-
@error_status = args[:error_status] || 0
|
105
|
-
@error_index = args[:error_index] || 0
|
106
|
-
@variables = args[:variables] || []
|
107
|
-
end
|
92
|
+
attr_reader :version, :community, :pdu_type, :variables, :error_status
|
93
|
+
attr_accessor :request_id, :error_index
|
108
94
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
# Wrap any basic parsing error so it becomes a PDU-format error
|
118
|
-
raise Error.new( "snmp-pdu format error" )
|
119
|
-
end
|
120
|
-
end
|
121
|
-
private :parse
|
95
|
+
def initialize args={}
|
96
|
+
@version = args[:version] || 0
|
97
|
+
@community = args[:community] || "public"
|
98
|
+
@pdu_type = args[:pdu_type] # leave nil unless specified; there's no reasonable default value.
|
99
|
+
@error_status = args[:error_status] || 0
|
100
|
+
@error_index = args[:error_index] || 0
|
101
|
+
@variables = args[:variables] || []
|
102
|
+
end
|
122
103
|
|
123
|
-
|
124
|
-
|
125
|
-
|
104
|
+
#--
|
105
|
+
def parse ber_object
|
106
|
+
begin
|
107
|
+
parse_ber_object ber_object
|
108
|
+
rescue Error
|
109
|
+
# Pass through any SnmpPdu::Error instances
|
110
|
+
raise $!
|
111
|
+
rescue
|
112
|
+
# Wrap any basic parsing error so it becomes a PDU-format error
|
113
|
+
raise Error.new( "snmp-pdu format error" )
|
114
|
+
end
|
115
|
+
end
|
116
|
+
private :parse
|
126
117
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
send :pdu_type=, :get_request
|
131
|
-
parse_get_request data
|
132
|
-
when 1
|
133
|
-
send :pdu_type=, :get_next_request
|
134
|
-
# This PDU is identical to get-request except for the type.
|
135
|
-
parse_get_request data
|
136
|
-
when 2
|
137
|
-
send :pdu_type=, :get_response
|
138
|
-
# This PDU is identical to get-request except for the type,
|
139
|
-
# the error_status and error_index values are meaningful,
|
140
|
-
# and the fact that the variable bindings will be non-null.
|
141
|
-
parse_get_response data
|
142
|
-
else
|
143
|
-
raise Error.new( "unknown snmp-pdu type: #{app_tag}" )
|
144
|
-
end
|
145
|
-
end
|
146
|
-
private :parse_ber_object
|
118
|
+
def parse_ber_object ber_object
|
119
|
+
send :version=, ber_object[0].to_i
|
120
|
+
send :community=, ber_object[1].to_s
|
147
121
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
122
|
+
data = ber_object[2]
|
123
|
+
case (app_tag = data.ber_identifier & 31)
|
124
|
+
when 0
|
125
|
+
send :pdu_type=, :get_request
|
126
|
+
parse_get_request data
|
127
|
+
when 1
|
128
|
+
send :pdu_type=, :get_next_request
|
129
|
+
# This PDU is identical to get-request except for the type.
|
130
|
+
parse_get_request data
|
131
|
+
when 2
|
132
|
+
send :pdu_type=, :get_response
|
133
|
+
# This PDU is identical to get-request except for the type,
|
134
|
+
# the error_status and error_index values are meaningful,
|
135
|
+
# and the fact that the variable bindings will be non-null.
|
136
|
+
parse_get_response data
|
137
|
+
else
|
138
|
+
raise Error.new( "unknown snmp-pdu type: #{app_tag}" )
|
139
|
+
end
|
140
|
+
end
|
141
|
+
private :parse_ber_object
|
167
142
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
143
|
+
#--
|
144
|
+
# Defined in RFC1157, pgh 4.1.2.
|
145
|
+
def parse_get_request data
|
146
|
+
send :request_id=, data[0].to_i
|
147
|
+
# data[1] is error_status, always zero.
|
148
|
+
# data[2] is error_index, always zero.
|
149
|
+
send :error_status=, 0
|
150
|
+
send :error_index=, 0
|
151
|
+
data[3].each do |n,v|
|
152
|
+
# A variable-binding, of which there may be several,
|
153
|
+
# consists of an OID and a BER null.
|
154
|
+
# We're ignoring the null, we might want to verify it instead.
|
155
|
+
unless v.is_a?(Net::BER::BerIdentifiedNull)
|
156
|
+
raise Error.new(" invalid variable-binding in get-request" )
|
157
|
+
end
|
158
|
+
add_variable_binding n, nil
|
159
|
+
end
|
160
|
+
end
|
161
|
+
private :parse_get_request
|
182
162
|
|
163
|
+
#--
|
164
|
+
# Defined in RFC1157, pgh 4.1.4
|
165
|
+
def parse_get_response data
|
166
|
+
send :request_id=, data[0].to_i
|
167
|
+
send :error_status=, data[1].to_i
|
168
|
+
send :error_index=, data[2].to_i
|
169
|
+
data[3].each do |n,v|
|
170
|
+
# A variable-binding, of which there may be several,
|
171
|
+
# consists of an OID and a BER null.
|
172
|
+
# We're ignoring the null, we might want to verify it instead.
|
173
|
+
add_variable_binding n, v
|
174
|
+
end
|
175
|
+
end
|
176
|
+
private :parse_get_response
|
183
177
|
|
184
|
-
def version= ver
|
185
|
-
unless [0,2].include?(ver)
|
186
|
-
raise Error.new("unknown snmp-version: #{ver}")
|
187
|
-
end
|
188
|
-
@version = ver
|
189
|
-
end
|
190
178
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
179
|
+
def version= ver
|
180
|
+
unless [0,2].include?(ver)
|
181
|
+
raise Error.new("unknown snmp-version: #{ver}")
|
182
|
+
end
|
183
|
+
@version = ver
|
184
|
+
end
|
197
185
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
186
|
+
def pdu_type= t
|
187
|
+
unless PduTypes.include?(t)
|
188
|
+
raise Error.new("unknown pdu-type: #{t}")
|
189
|
+
end
|
190
|
+
@pdu_type = t
|
191
|
+
end
|
204
192
|
|
205
|
-
|
206
|
-
|
207
|
-
|
193
|
+
def error_status= es
|
194
|
+
unless ErrorStatusCodes.has_key?(es)
|
195
|
+
raise Error.new("unknown error-status: #{es}")
|
196
|
+
end
|
197
|
+
@error_status = es
|
198
|
+
end
|
208
199
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
@variables ||= []
|
213
|
-
@variables << [name, value]
|
214
|
-
end
|
200
|
+
def community= c
|
201
|
+
@community = c.to_s
|
202
|
+
end
|
215
203
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
end
|
204
|
+
#--
|
205
|
+
# Syntactic sugar
|
206
|
+
def add_variable_binding name, value=nil
|
207
|
+
@variables ||= []
|
208
|
+
@variables << [name, value]
|
209
|
+
end
|
223
210
|
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
request_id.to_ber,
|
232
|
-
error_status.to_ber,
|
233
|
-
error_index.to_ber,
|
234
|
-
[
|
235
|
-
@variables.map {|n,v|
|
236
|
-
[n.to_ber_oid, Net::BER::BerIdentifiedNull.new.to_ber].to_ber_sequence
|
237
|
-
}
|
238
|
-
].to_ber_sequence
|
239
|
-
].to_ber_contextspecific(0)
|
240
|
-
when :get_next_request
|
241
|
-
[
|
242
|
-
request_id.to_ber,
|
243
|
-
error_status.to_ber,
|
244
|
-
error_index.to_ber,
|
245
|
-
[
|
246
|
-
@variables.map {|n,v|
|
247
|
-
[n.to_ber_oid, Net::BER::BerIdentifiedNull.new.to_ber].to_ber_sequence
|
248
|
-
}
|
249
|
-
].to_ber_sequence
|
250
|
-
].to_ber_contextspecific(1)
|
251
|
-
when :get_response
|
252
|
-
[
|
253
|
-
request_id.to_ber,
|
254
|
-
error_status.to_ber,
|
255
|
-
error_index.to_ber,
|
256
|
-
[
|
257
|
-
@variables.map {|n,v|
|
258
|
-
[n.to_ber_oid, v.to_ber].to_ber_sequence
|
259
|
-
}
|
260
|
-
].to_ber_sequence
|
261
|
-
].to_ber_contextspecific(2)
|
262
|
-
else
|
263
|
-
raise Error.new( "unknown pdu-type: #{pdu_type}" )
|
264
|
-
end
|
265
|
-
end
|
266
|
-
private :pdu_to_ber_string
|
211
|
+
def to_ber_string
|
212
|
+
[
|
213
|
+
version.to_ber,
|
214
|
+
community.to_ber,
|
215
|
+
pdu_to_ber_string,
|
216
|
+
].to_ber_sequence
|
217
|
+
end
|
267
218
|
|
219
|
+
#--
|
220
|
+
# Helper method that returns a PDU payload in BER form,
|
221
|
+
# depending on the PDU type.
|
222
|
+
def pdu_to_ber_string
|
223
|
+
case pdu_type
|
224
|
+
when :get_request
|
225
|
+
[
|
226
|
+
request_id.to_ber,
|
227
|
+
error_status.to_ber,
|
228
|
+
error_index.to_ber,
|
229
|
+
[
|
230
|
+
@variables.map {|n,v|
|
231
|
+
[n.to_ber_oid, Net::BER::BerIdentifiedNull.new.to_ber].to_ber_sequence
|
232
|
+
}
|
233
|
+
].to_ber_sequence
|
234
|
+
].to_ber_contextspecific(0)
|
235
|
+
when :get_next_request
|
236
|
+
[
|
237
|
+
request_id.to_ber,
|
238
|
+
error_status.to_ber,
|
239
|
+
error_index.to_ber,
|
240
|
+
[
|
241
|
+
@variables.map {|n,v|
|
242
|
+
[n.to_ber_oid, Net::BER::BerIdentifiedNull.new.to_ber].to_ber_sequence
|
243
|
+
}
|
244
|
+
].to_ber_sequence
|
245
|
+
].to_ber_contextspecific(1)
|
246
|
+
when :get_response
|
247
|
+
[
|
248
|
+
request_id.to_ber,
|
249
|
+
error_status.to_ber,
|
250
|
+
error_index.to_ber,
|
251
|
+
[
|
252
|
+
@variables.map {|n,v|
|
253
|
+
[n.to_ber_oid, v.to_ber].to_ber_sequence
|
254
|
+
}
|
255
|
+
].to_ber_sequence
|
256
|
+
].to_ber_contextspecific(2)
|
257
|
+
else
|
258
|
+
raise Error.new( "unknown pdu-type: #{pdu_type}" )
|
259
|
+
end
|
268
260
|
end
|
261
|
+
private :pdu_to_ber_string
|
262
|
+
end
|
269
263
|
end
|
270
264
|
# :startdoc:
|