net-ldap 0.8.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
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:
|