socialcast-net-ldap 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/.gemtest +0 -0
  2. data/COPYING +272 -0
  3. data/Gemfile +10 -0
  4. data/Gemfile.lock +29 -0
  5. data/Hacking.rdoc +16 -0
  6. data/History.txt +137 -0
  7. data/LICENSE +56 -0
  8. data/Manifest.txt +45 -0
  9. data/README.txt +70 -0
  10. data/Rakefile +124 -0
  11. data/lib/net-ldap.rb +1 -0
  12. data/lib/net/ber.rb +341 -0
  13. data/lib/net/ber/ber_parser.rb +168 -0
  14. data/lib/net/ber/core_ext.rb +72 -0
  15. data/lib/net/ber/core_ext/array.rb +79 -0
  16. data/lib/net/ber/core_ext/bignum.rb +19 -0
  17. data/lib/net/ber/core_ext/false_class.rb +7 -0
  18. data/lib/net/ber/core_ext/fixnum.rb +63 -0
  19. data/lib/net/ber/core_ext/string.rb +57 -0
  20. data/lib/net/ber/core_ext/true_class.rb +9 -0
  21. data/lib/net/ldap.rb +1539 -0
  22. data/lib/net/ldap/dataset.rb +174 -0
  23. data/lib/net/ldap/entry.rb +208 -0
  24. data/lib/net/ldap/filter.rb +781 -0
  25. data/lib/net/ldap/password.rb +52 -0
  26. data/lib/net/ldap/pdu.rb +279 -0
  27. data/lib/net/ldif.rb +34 -0
  28. data/lib/net/snmp.rb +295 -0
  29. data/spec/integration/ssl_ber_spec.rb +33 -0
  30. data/spec/spec.opts +2 -0
  31. data/spec/spec_helper.rb +5 -0
  32. data/spec/unit/ber/ber_spec.rb +109 -0
  33. data/spec/unit/ber/core_ext/string_spec.rb +51 -0
  34. data/spec/unit/ldap/entry_spec.rb +51 -0
  35. data/spec/unit/ldap/filter_spec.rb +83 -0
  36. data/spec/unit/ldap_spec.rb +48 -0
  37. data/test/common.rb +3 -0
  38. data/test/test_entry.rb +59 -0
  39. data/test/test_filter.rb +115 -0
  40. data/test/test_ldif.rb +68 -0
  41. data/test/test_password.rb +17 -0
  42. data/test/test_rename.rb +79 -0
  43. data/test/test_snmp.rb +114 -0
  44. data/test/testdata.ldif +101 -0
  45. data/testserver/ldapserver.rb +210 -0
  46. data/testserver/testdata.ldif +101 -0
  47. metadata +178 -0
@@ -0,0 +1,52 @@
1
+ #----------------------------------------------------------------------------
2
+ #
3
+ # Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
4
+ #
5
+ # Gmail: garbagecat10
6
+ #
7
+ # This program is free software; you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation; either version 2 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program; if not, write to the Free Software
19
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
+ #
21
+ #---------------------------------------------------------------------------
22
+
23
+ require 'digest/sha1'
24
+ require 'digest/md5'
25
+
26
+ class Net::LDAP::Password
27
+ class << self
28
+ # Generate a password-hash suitable for inclusion in an LDAP attribute.
29
+ # Pass a hash type (currently supported: :md5 and :sha) and a plaintext
30
+ # password. This function will return a hashed representation.
31
+ #
32
+ #--
33
+ # STUB: This is here to fulfill the requirements of an RFC, which
34
+ # one?
35
+ #
36
+ # TODO, gotta do salted-sha and (maybe)salted-md5. Should we provide
37
+ # sha1 as a synonym for sha1? I vote no because then should you also
38
+ # provide ssha1 for symmetry?
39
+ def generate(type, str)
40
+ digest, digest_name = case type
41
+ when :md5
42
+ [Digest::MD5.new, 'MD5']
43
+ when :sha
44
+ [Digest::SHA1.new, 'SHA']
45
+ else
46
+ raise Net::LDAP::LdapError, "Unsupported password-hash type (#{type})"
47
+ end
48
+ digest << str.to_s
49
+ return "{#{digest_name}}#{[digest.digest].pack('m').chomp }"
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,279 @@
1
+ # LDAP PDU support classes
2
+ #
3
+ #----------------------------------------------------------------------------
4
+ #
5
+ # Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
6
+ #
7
+ # Gmail: garbagecat10
8
+ #
9
+ # This program is free software; you can redistribute it and/or modify
10
+ # it under the terms of the GNU General Public License as published by
11
+ # the Free Software Foundation; either version 2 of the License, or
12
+ # (at your option) any later version.
13
+ #
14
+ # This program is distributed in the hope that it will be useful,
15
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
+ # GNU General Public License for more details.
18
+ #
19
+ # You should have received a copy of the GNU General Public License
20
+ # along with this program; if not, write to the Free Software
21
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22
+ #
23
+ #---------------------------------------------------------------------------
24
+
25
+ require 'ostruct'
26
+
27
+ ##
28
+ # Defines the Protocol Data Unit (PDU) for LDAP. An LDAP PDU always looks
29
+ # like a BER SEQUENCE with at least two elements: an INTEGER message ID
30
+ # number and an application-specific SEQUENCE. Some LDAPv3 packets also
31
+ # include an optional third element, a sequence of "controls" (see RFC 2251
32
+ # section 4.1.12 for more information).
33
+ #
34
+ # The application-specific tag in the sequence tells us what kind of packet
35
+ # it is, and each kind has its own format, defined in RFC-1777.
36
+ #
37
+ # Observe that many clients (such as ldapsearch) do not necessarily enforce
38
+ # the expected application tags on received protocol packets. This
39
+ # implementation does interpret the RFC strictly in this regard, and it
40
+ # remains to be seen whether there are servers out there that will not work
41
+ # well with our approach.
42
+ #
43
+ # Currently, we only support controls on SearchResult.
44
+ class Net::LDAP::PDU
45
+ class Error < RuntimeError; end
46
+
47
+ ##
48
+ # This message packet is a bind request.
49
+ BindRequest = 0
50
+ BindResult = 1
51
+ UnbindRequest = 2
52
+ SearchRequest = 3
53
+ SearchReturnedData = 4
54
+ SearchResult = 5
55
+ ModifyResponse = 7
56
+ AddResponse = 9
57
+ DeleteResponse = 11
58
+ ModifyRDNResponse = 13
59
+ SearchResultReferral = 19
60
+ ExtendedRequest = 23
61
+ ExtendedResponse = 24
62
+
63
+ ##
64
+ # The LDAP packet message ID.
65
+ attr_reader :message_id
66
+ alias_method :msg_id, :message_id
67
+
68
+ ##
69
+ # The application protocol format tag.
70
+ attr_reader :app_tag
71
+
72
+ attr_reader :search_entry
73
+ attr_reader :search_referrals
74
+ attr_reader :search_parameters
75
+ attr_reader :bind_parameters
76
+
77
+ ##
78
+ # Returns RFC-2251 Controls if any.
79
+ attr_reader :ldap_controls
80
+ alias_method :result_controls, :ldap_controls
81
+ # Messy. Does this functionality belong somewhere else?
82
+
83
+ def initialize(ber_object)
84
+ begin
85
+ @message_id = ber_object[0].to_i
86
+ # Grab the bottom five bits of the identifier so we know which type of
87
+ # PDU this is.
88
+ #
89
+ # This is safe enough in LDAP-land, but it is recommended that other
90
+ # approaches be taken for other protocols in the case that there's an
91
+ # app-specific tag that has both primitive and constructed forms.
92
+ @app_tag = ber_object[1].ber_identifier & 0x1f
93
+ @ldap_controls = []
94
+ rescue Exception => ex
95
+ raise Net::LDAP::PDU::Error, "LDAP PDU Format Error: #{ex.message}"
96
+ end
97
+
98
+ case @app_tag
99
+ when BindResult
100
+ parse_bind_response(ber_object[1])
101
+ when SearchReturnedData
102
+ parse_search_return(ber_object[1])
103
+ when SearchResultReferral
104
+ parse_search_referral(ber_object[1])
105
+ when SearchResult
106
+ parse_ldap_result(ber_object[1])
107
+ when ModifyResponse
108
+ parse_ldap_result(ber_object[1])
109
+ when AddResponse
110
+ parse_ldap_result(ber_object[1])
111
+ when DeleteResponse
112
+ parse_ldap_result(ber_object[1])
113
+ when ModifyRDNResponse
114
+ parse_ldap_result(ber_object[1])
115
+ when SearchRequest
116
+ parse_ldap_search_request(ber_object[1])
117
+ when BindRequest
118
+ parse_bind_request(ber_object[1])
119
+ when UnbindRequest
120
+ parse_unbind_request(ber_object[1])
121
+ when ExtendedResponse
122
+ parse_ldap_result(ber_object[1])
123
+ else
124
+ raise LdapPduError.new("unknown pdu-type: #{@app_tag}")
125
+ end
126
+
127
+ parse_controls(ber_object[2]) if ber_object[2]
128
+ end
129
+
130
+ ##
131
+ # Returns a hash which (usually) defines the members :resultCode,
132
+ # :errorMessage, and :matchedDN. These values come directly from an LDAP
133
+ # response packet returned by the remote peer. Also see #result_code.
134
+ def result
135
+ @ldap_result || {}
136
+ end
137
+
138
+ ##
139
+ # This returns an LDAP result code taken from the PDU, but it will be nil
140
+ # if there wasn't a result code. That can easily happen depending on the
141
+ # type of packet.
142
+ def result_code(code = :resultCode)
143
+ @ldap_result and @ldap_result[code]
144
+ end
145
+
146
+ ##
147
+ # Return serverSaslCreds, which are only present in BindResponse packets.
148
+ #--
149
+ # Messy. Does this functionality belong somewhere else? We ought to
150
+ # refactor the accessors of this class before they get any kludgier.
151
+ def result_server_sasl_creds
152
+ @ldap_result && @ldap_result[:serverSaslCreds]
153
+ end
154
+
155
+ def parse_ldap_result(sequence)
156
+ sequence.length >= 3 or raise Net::LDAP::PDU::Error, "Invalid LDAP result length."
157
+ @ldap_result = {
158
+ :resultCode => sequence[0],
159
+ :matchedDN => sequence[1],
160
+ :errorMessage => sequence[2]
161
+ }
162
+ end
163
+ private :parse_ldap_result
164
+
165
+ ##
166
+ # A Bind Response may have an additional field, ID [7], serverSaslCreds,
167
+ # per RFC 2251 pgh 4.2.3.
168
+ def parse_bind_response(sequence)
169
+ sequence.length >= 3 or raise Net::LDAP::PDU::Error, "Invalid LDAP Bind Response length."
170
+ parse_ldap_result(sequence)
171
+ @ldap_result[:serverSaslCreds] = sequence[3] if sequence.length >= 4
172
+ @ldap_result
173
+ end
174
+ private :parse_bind_response
175
+
176
+ # Definition from RFC 1777 (we're handling application-4 here).
177
+ #
178
+ # Search Response ::=
179
+ # CHOICE {
180
+ # entry [APPLICATION 4] SEQUENCE {
181
+ # objectName LDAPDN,
182
+ # attributes SEQUENCE OF SEQUENCE {
183
+ # AttributeType,
184
+ # SET OF AttributeValue
185
+ # }
186
+ # },
187
+ # resultCode [APPLICATION 5] LDAPResult
188
+ # }
189
+ #
190
+ # We concoct a search response that is a hash of the returned attribute
191
+ # values.
192
+ #
193
+ # NOW OBSERVE CAREFULLY: WE ARE DOWNCASING THE RETURNED ATTRIBUTE NAMES.
194
+ #
195
+ # This is to make them more predictable for user programs, but it may not
196
+ # be a good idea. Maybe this should be configurable.
197
+ def parse_search_return(sequence)
198
+ sequence.length >= 2 or raise Net::LDAP::PDU::Error, "Invalid Search Response length."
199
+ @search_entry = Net::LDAP::Entry.new(sequence[0])
200
+ sequence[1].each { |seq| @search_entry[seq[0]] = seq[1] }
201
+ end
202
+ private :parse_search_return
203
+
204
+ ##
205
+ # A search referral is a sequence of one or more LDAP URIs. Any number of
206
+ # search-referral replies can be returned by the server, interspersed with
207
+ # normal replies in any order.
208
+ #--
209
+ # Until I can think of a better way to do this, we'll return the referrals
210
+ # as an array. It'll be up to higher-level handlers to expose something
211
+ # reasonable to the client.
212
+ def parse_search_referral(uris)
213
+ @search_referrals = uris
214
+ end
215
+ private :parse_search_referral
216
+
217
+ ##
218
+ # Per RFC 2251, an LDAP "control" is a sequence of tuples, each consisting
219
+ # of an OID, a boolean criticality flag defaulting FALSE, and an OPTIONAL
220
+ # Octet String. If only two fields are given, the second one may be either
221
+ # criticality or data, since criticality has a default value. Someday we
222
+ # may want to come back here and add support for some of more-widely used
223
+ # controls. RFC-2696 is a good example.
224
+ def parse_controls(sequence)
225
+ @ldap_controls = sequence.map do |control|
226
+ o = OpenStruct.new
227
+ o.oid, o.criticality, o.value = control[0], control[1], control[2]
228
+ if o.criticality and o.criticality.is_a?(String)
229
+ o.value = o.criticality
230
+ o.criticality = false
231
+ end
232
+ o
233
+ end
234
+ end
235
+ private :parse_controls
236
+
237
+ # (provisional, must document)
238
+ def parse_ldap_search_request(sequence)
239
+ s = OpenStruct.new
240
+ s.base_object, s.scope, s.deref_aliases, s.size_limit, s.time_limit,
241
+ s.types_only, s.filter, s.attributes = sequence
242
+ @search_parameters = s
243
+ end
244
+ private :parse_ldap_search_request
245
+
246
+ # (provisional, must document)
247
+ def parse_bind_request sequence
248
+ s = OpenStruct.new
249
+ s.version, s.name, s.authentication = sequence
250
+ @bind_parameters = s
251
+ end
252
+ private :parse_bind_request
253
+
254
+ # (provisional, must document)
255
+ # UnbindRequest has no content so this is a no-op.
256
+ def parse_unbind_request(sequence)
257
+ nil
258
+ end
259
+ private :parse_unbind_request
260
+ end
261
+
262
+ module Net
263
+ ##
264
+ # Handle the renamed constants.
265
+ def self.const_missing(name) #:nodoc:
266
+ case name.to_s
267
+ when "LdapPdu"
268
+ warn "Net::#{name} has been deprecated. Use Net::LDAP::PDU instead."
269
+ Net::LDAP::PDU
270
+ when "LdapPduError"
271
+ warn "Net::#{name} has been deprecated. Use Net::LDAP::PDU::Error instead."
272
+ Net::LDAP::PDU::Error
273
+ when 'LDAP'
274
+ else
275
+ super
276
+ end
277
+ end
278
+ end # module Net
279
+
data/lib/net/ldif.rb ADDED
@@ -0,0 +1,34 @@
1
+ # $Id$
2
+ #
3
+ # Net::LDIF for Ruby
4
+ #
5
+ #
6
+ #
7
+ # Copyright (C) 2006 by Francis Cianfrocca. All Rights Reserved.
8
+ #
9
+ # Gmail: garbagecat10
10
+ #
11
+ # This program is free software; you can redistribute it and/or modify
12
+ # it under the terms of the GNU General Public License as published by
13
+ # the Free Software Foundation; either version 2 of the License, or
14
+ # (at your option) any later version.
15
+ #
16
+ # This program is distributed in the hope that it will be useful,
17
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ # GNU General Public License for more details.
20
+ #
21
+ # You should have received a copy of the GNU General Public License
22
+ # along with this program; if not, write to the Free Software
23
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24
+ #
25
+ #
26
+
27
+ # THIS FILE IS A STUB.
28
+
29
+ module Net
30
+ class LDIF
31
+ end
32
+ end
33
+
34
+
data/lib/net/snmp.rb ADDED
@@ -0,0 +1,295 @@
1
+ # $Id$
2
+ #
3
+ # NET::SNMP
4
+ #
5
+ #----------------------------------------------------------------------------
6
+ #
7
+ # Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
8
+ #
9
+ # Gmail: garbagecat10
10
+ #
11
+ # This program is free software; you can redistribute it and/or modify
12
+ # it under the terms of the GNU General Public License as published by
13
+ # the Free Software Foundation; either version 2 of the License, or
14
+ # (at your option) any later version.
15
+ #
16
+ # This program is distributed in the hope that it will be useful,
17
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ # GNU General Public License for more details.
20
+ #
21
+ # You should have received a copy of the GNU General Public License
22
+ # along with this program; if not, write to the Free Software
23
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24
+ #
25
+ #---------------------------------------------------------------------------
26
+ #
27
+ #
28
+
29
+ module Net
30
+
31
+ class SNMP
32
+ VERSION = '0.1.0'
33
+
34
+ AsnSyntax = Net::BER.compile_syntax({
35
+ :application => {
36
+ :primitive => {
37
+ 1 => :integer, # Counter32, (RFC2578 sec 2)
38
+ 2 => :integer, # Gauge32 or Unsigned32, (RFC2578 sec 2)
39
+ 3 => :integer # TimeTicks32, (RFC2578 sec 2)
40
+ },
41
+ :constructed => {
42
+ }
43
+ },
44
+ :context_specific => {
45
+ :primitive => {
46
+ },
47
+ :constructed => {
48
+ 0 => :array, # GetRequest PDU (RFC1157 pgh 4.1.2)
49
+ 1 => :array, # GetNextRequest PDU (RFC1157 pgh 4.1.3)
50
+ 2 => :array # GetResponse PDU (RFC1157 pgh 4.1.4)
51
+ }
52
+ }
53
+ })
54
+
55
+ # SNMP 32-bit counter.
56
+ # Defined in RFC1155 (Structure of Mangement Information), section 6.
57
+ # A 32-bit counter is an ASN.1 application [1] implicit unsigned integer
58
+ # with a range from 0 to 2^^32 - 1.
59
+ class Counter32
60
+ def initialize value
61
+ @value = value
62
+ end
63
+ def to_ber
64
+ @value.to_ber_application(1)
65
+ end
66
+ end
67
+
68
+ # SNMP 32-bit gauge.
69
+ # Defined in RFC1155 (Structure of Mangement Information), section 6.
70
+ # A 32-bit counter is an ASN.1 application [2] implicit unsigned integer.
71
+ # This is also indistinguishable from Unsigned32. (Need to alias them.)
72
+ class Gauge32
73
+ def initialize value
74
+ @value = value
75
+ end
76
+ def to_ber
77
+ @value.to_ber_application(2)
78
+ end
79
+ end
80
+
81
+ # SNMP 32-bit timer-ticks.
82
+ # Defined in RFC1155 (Structure of Mangement Information), section 6.
83
+ # A 32-bit counter is an ASN.1 application [3] implicit unsigned integer.
84
+ class TimeTicks32
85
+ def initialize value
86
+ @value = value
87
+ end
88
+ def to_ber
89
+ @value.to_ber_application(3)
90
+ end
91
+ end
92
+ end
93
+
94
+ class SnmpPdu
95
+ class Error < StandardError; end
96
+
97
+ PduTypes = [
98
+ :get_request,
99
+ :get_next_request,
100
+ :get_response,
101
+ :set_request,
102
+ :trap
103
+ ]
104
+ ErrorStatusCodes = { # Per RFC1157, pgh 4.1.1
105
+ 0 => "noError",
106
+ 1 => "tooBig",
107
+ 2 => "noSuchName",
108
+ 3 => "badValue",
109
+ 4 => "readOnly",
110
+ 5 => "genErr"
111
+ }
112
+
113
+ class << self
114
+ def parse ber_object
115
+ n = new
116
+ n.send :parse, ber_object
117
+ n
118
+ end
119
+ end
120
+
121
+ attr_reader :version, :community, :pdu_type, :variables, :error_status
122
+ attr_accessor :request_id, :error_index
123
+
124
+
125
+ def initialize args={}
126
+ @version = args[:version] || 0
127
+ @community = args[:community] || "public"
128
+ @pdu_type = args[:pdu_type] # leave nil unless specified; there's no reasonable default value.
129
+ @error_status = args[:error_status] || 0
130
+ @error_index = args[:error_index] || 0
131
+ @variables = args[:variables] || []
132
+ end
133
+
134
+ #--
135
+ def parse ber_object
136
+ begin
137
+ parse_ber_object ber_object
138
+ rescue Error
139
+ # Pass through any SnmpPdu::Error instances
140
+ raise $!
141
+ rescue
142
+ # Wrap any basic parsing error so it becomes a PDU-format error
143
+ raise Error.new( "snmp-pdu format error" )
144
+ end
145
+ end
146
+ private :parse
147
+
148
+ def parse_ber_object ber_object
149
+ send :version=, ber_object[0].to_i
150
+ send :community=, ber_object[1].to_s
151
+
152
+ data = ber_object[2]
153
+ case (app_tag = data.ber_identifier & 31)
154
+ when 0
155
+ send :pdu_type=, :get_request
156
+ parse_get_request data
157
+ when 1
158
+ send :pdu_type=, :get_next_request
159
+ # This PDU is identical to get-request except for the type.
160
+ parse_get_request data
161
+ when 2
162
+ send :pdu_type=, :get_response
163
+ # This PDU is identical to get-request except for the type,
164
+ # the error_status and error_index values are meaningful,
165
+ # and the fact that the variable bindings will be non-null.
166
+ parse_get_response data
167
+ else
168
+ raise Error.new( "unknown snmp-pdu type: #{app_tag}" )
169
+ end
170
+ end
171
+ private :parse_ber_object
172
+
173
+ #--
174
+ # Defined in RFC1157, pgh 4.1.2.
175
+ def parse_get_request data
176
+ send :request_id=, data[0].to_i
177
+ # data[1] is error_status, always zero.
178
+ # data[2] is error_index, always zero.
179
+ send :error_status=, 0
180
+ send :error_index=, 0
181
+ data[3].each {|n,v|
182
+ # A variable-binding, of which there may be several,
183
+ # consists of an OID and a BER null.
184
+ # We're ignoring the null, we might want to verify it instead.
185
+ unless v.is_a?(Net::BER::BerIdentifiedNull)
186
+ raise Error.new(" invalid variable-binding in get-request" )
187
+ end
188
+ add_variable_binding n, nil
189
+ }
190
+ end
191
+ private :parse_get_request
192
+
193
+ #--
194
+ # Defined in RFC1157, pgh 4.1.4
195
+ def parse_get_response data
196
+ send :request_id=, data[0].to_i
197
+ send :error_status=, data[1].to_i
198
+ send :error_index=, data[2].to_i
199
+ data[3].each {|n,v|
200
+ # A variable-binding, of which there may be several,
201
+ # consists of an OID and a BER null.
202
+ # We're ignoring the null, we might want to verify it instead.
203
+ add_variable_binding n, v
204
+ }
205
+ end
206
+ private :parse_get_response
207
+
208
+
209
+ def version= ver
210
+ unless [0,2].include?(ver)
211
+ raise Error.new("unknown snmp-version: #{ver}")
212
+ end
213
+ @version = ver
214
+ end
215
+
216
+ def pdu_type= t
217
+ unless PduTypes.include?(t)
218
+ raise Error.new("unknown pdu-type: #{t}")
219
+ end
220
+ @pdu_type = t
221
+ end
222
+
223
+ def error_status= es
224
+ unless ErrorStatusCodes.has_key?(es)
225
+ raise Error.new("unknown error-status: #{es}")
226
+ end
227
+ @error_status = es
228
+ end
229
+
230
+ def community= c
231
+ @community = c.to_s
232
+ end
233
+
234
+ #--
235
+ # Syntactic sugar
236
+ def add_variable_binding name, value=nil
237
+ @variables ||= []
238
+ @variables << [name, value]
239
+ end
240
+
241
+ def to_ber_string
242
+ [
243
+ version.to_ber,
244
+ community.to_ber,
245
+ pdu_to_ber_string
246
+ ].to_ber_sequence
247
+ end
248
+
249
+ #--
250
+ # Helper method that returns a PDU payload in BER form,
251
+ # depending on the PDU type.
252
+ def pdu_to_ber_string
253
+ case pdu_type
254
+ when :get_request
255
+ [
256
+ request_id.to_ber,
257
+ error_status.to_ber,
258
+ error_index.to_ber,
259
+ [
260
+ @variables.map {|n,v|
261
+ [n.to_ber_oid, Net::BER::BerIdentifiedNull.new.to_ber].to_ber_sequence
262
+ }
263
+ ].to_ber_sequence
264
+ ].to_ber_contextspecific(0)
265
+ when :get_next_request
266
+ [
267
+ request_id.to_ber,
268
+ error_status.to_ber,
269
+ error_index.to_ber,
270
+ [
271
+ @variables.map {|n,v|
272
+ [n.to_ber_oid, Net::BER::BerIdentifiedNull.new.to_ber].to_ber_sequence
273
+ }
274
+ ].to_ber_sequence
275
+ ].to_ber_contextspecific(1)
276
+ when :get_response
277
+ [
278
+ request_id.to_ber,
279
+ error_status.to_ber,
280
+ error_index.to_ber,
281
+ [
282
+ @variables.map {|n,v|
283
+ [n.to_ber_oid, v.to_ber].to_ber_sequence
284
+ }
285
+ ].to_ber_sequence
286
+ ].to_ber_contextspecific(2)
287
+ else
288
+ raise Error.new( "unknown pdu-type: #{pdu_type}" )
289
+ end
290
+ end
291
+ private :pdu_to_ber_string
292
+
293
+ end
294
+ end
295
+