dnsruby 1.55 → 1.56.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.
Files changed (158) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +96 -0
  3. data/Rakefile +30 -29
  4. data/demo/axfr.rb +93 -93
  5. data/demo/check_soa.rb +99 -99
  6. data/demo/check_zone.rb +59 -59
  7. data/demo/digdlv.rb +43 -43
  8. data/demo/digroot.rb +34 -34
  9. data/demo/example_recurse.rb +14 -14
  10. data/demo/mresolv.rb +30 -30
  11. data/demo/mx.rb +31 -31
  12. data/demo/rubydig.rb +37 -37
  13. data/demo/to_resolve.txt +3088 -3088
  14. data/demo/trace_dns.rb +46 -46
  15. data/lib/dnsruby.rb +161 -526
  16. data/lib/dnsruby/DNS.rb +305 -0
  17. data/lib/{Dnsruby/Cache.rb → dnsruby/cache.rb} +152 -152
  18. data/lib/{Dnsruby → dnsruby}/code_mapper.rb +48 -52
  19. data/lib/dnsruby/code_mappers.rb +295 -0
  20. data/lib/{Dnsruby/Config.rb → dnsruby/config.rb} +454 -454
  21. data/lib/{Dnsruby → dnsruby}/dnssec.rb +91 -91
  22. data/lib/{Dnsruby/Hosts.rb → dnsruby/hosts.rb} +125 -125
  23. data/lib/{Dnsruby → dnsruby}/ipv4.rb +26 -26
  24. data/lib/{Dnsruby → dnsruby}/ipv6.rb +42 -42
  25. data/lib/{Dnsruby → dnsruby}/key_cache.rb +29 -29
  26. data/lib/dnsruby/message/decoder.rb +164 -0
  27. data/lib/dnsruby/message/encoder.rb +75 -0
  28. data/lib/dnsruby/message/header.rb +249 -0
  29. data/lib/dnsruby/message/message.rb +629 -0
  30. data/lib/dnsruby/message/question.rb +86 -0
  31. data/lib/dnsruby/message/section.rb +96 -0
  32. data/lib/{Dnsruby → dnsruby}/name.rb +141 -141
  33. data/lib/dnsruby/packet_sender.rb +661 -0
  34. data/lib/{Dnsruby/Recursor.rb → dnsruby/recursor.rb} +235 -233
  35. data/lib/dnsruby/resolv.rb +113 -0
  36. data/lib/dnsruby/resolver.rb +1192 -0
  37. data/lib/dnsruby/resource/A.rb +56 -0
  38. data/lib/dnsruby/resource/AAAA.rb +54 -0
  39. data/lib/{Dnsruby → dnsruby}/resource/AFSDB.rb +68 -68
  40. data/lib/{Dnsruby → dnsruby}/resource/CERT.rb +105 -105
  41. data/lib/{Dnsruby → dnsruby}/resource/DHCID.rb +54 -54
  42. data/lib/dnsruby/resource/DLV.rb +27 -0
  43. data/lib/{Dnsruby → dnsruby}/resource/DNSKEY.rb +372 -372
  44. data/lib/{Dnsruby → dnsruby}/resource/DS.rb +255 -255
  45. data/lib/{Dnsruby → dnsruby}/resource/HINFO.rb +71 -71
  46. data/lib/{Dnsruby → dnsruby}/resource/HIP.rb +29 -29
  47. data/lib/{Dnsruby → dnsruby}/resource/IN.rb +30 -30
  48. data/lib/{Dnsruby → dnsruby}/resource/IPSECKEY.rb +31 -31
  49. data/lib/{Dnsruby → dnsruby}/resource/ISDN.rb +62 -62
  50. data/lib/{Dnsruby → dnsruby}/resource/KX.rb +65 -65
  51. data/lib/{Dnsruby → dnsruby}/resource/LOC.rb +263 -263
  52. data/lib/{Dnsruby → dnsruby}/resource/MINFO.rb +69 -69
  53. data/lib/{Dnsruby → dnsruby}/resource/MX.rb +65 -65
  54. data/lib/{Dnsruby → dnsruby}/resource/NAPTR.rb +98 -98
  55. data/lib/{Dnsruby → dnsruby}/resource/NSAP.rb +171 -171
  56. data/lib/dnsruby/resource/NSEC.rb +275 -0
  57. data/lib/dnsruby/resource/NSEC3.rb +332 -0
  58. data/lib/dnsruby/resource/NSEC3PARAM.rb +135 -0
  59. data/lib/dnsruby/resource/OPT.rb +272 -0
  60. data/lib/{Dnsruby → dnsruby}/resource/PX.rb +70 -70
  61. data/lib/{Dnsruby → dnsruby}/resource/RP.rb +75 -75
  62. data/lib/dnsruby/resource/RR.rb +421 -0
  63. data/lib/dnsruby/resource/RRSIG.rb +275 -0
  64. data/lib/dnsruby/resource/RRSet.rb +190 -0
  65. data/lib/{Dnsruby → dnsruby}/resource/RT.rb +67 -67
  66. data/lib/{Dnsruby → dnsruby}/resource/SOA.rb +94 -94
  67. data/lib/dnsruby/resource/SPF.rb +29 -0
  68. data/lib/dnsruby/resource/SRV.rb +112 -0
  69. data/lib/{Dnsruby → dnsruby}/resource/SSHFP.rb +14 -14
  70. data/lib/dnsruby/resource/TKEY.rb +163 -0
  71. data/lib/dnsruby/resource/TSIG.rb +593 -0
  72. data/lib/{Dnsruby → dnsruby}/resource/TXT.rb +191 -191
  73. data/lib/dnsruby/resource/X25.rb +55 -0
  74. data/lib/{Dnsruby → dnsruby}/resource/domain_name.rb +25 -25
  75. data/lib/{Dnsruby → dnsruby}/resource/generic.rb +80 -80
  76. data/lib/dnsruby/resource/resource.rb +25 -0
  77. data/lib/{Dnsruby → dnsruby}/select_thread.rb +148 -148
  78. data/lib/{Dnsruby/SingleResolver.rb → dnsruby/single_resolver.rb} +60 -60
  79. data/lib/{Dnsruby → dnsruby}/single_verifier.rb +344 -344
  80. data/lib/dnsruby/the_log.rb +44 -0
  81. data/lib/dnsruby/update.rb +278 -0
  82. data/lib/dnsruby/validator_thread.rb +124 -0
  83. data/lib/dnsruby/version.rb +3 -0
  84. data/lib/{Dnsruby → dnsruby}/zone_reader.rb +93 -93
  85. data/lib/{Dnsruby → dnsruby}/zone_transfer.rb +377 -377
  86. data/test/spec_helper.rb +16 -0
  87. data/test/tc_axfr.rb +31 -34
  88. data/test/tc_cache.rb +32 -32
  89. data/test/tc_dlv.rb +28 -28
  90. data/test/tc_dns.rb +73 -76
  91. data/test/tc_dnskey.rb +31 -32
  92. data/test/tc_dnsruby.rb +50 -44
  93. data/test/tc_ds.rb +36 -36
  94. data/test/tc_escapedchars.rb +252 -255
  95. data/test/tc_hash.rb +17 -21
  96. data/test/tc_header.rb +48 -57
  97. data/test/tc_hip.rb +19 -22
  98. data/test/tc_ipseckey.rb +18 -21
  99. data/test/tc_keith.rb +300 -0
  100. data/test/tc_message.rb +87 -0
  101. data/test/tc_misc.rb +83 -87
  102. data/test/tc_name.rb +81 -84
  103. data/test/tc_naptr.rb +18 -21
  104. data/test/tc_nsec.rb +55 -55
  105. data/test/tc_nsec3.rb +23 -24
  106. data/test/tc_nsec3param.rb +20 -21
  107. data/test/tc_packet.rb +90 -93
  108. data/test/tc_packet_unique_push.rb +48 -51
  109. data/test/tc_question.rb +30 -33
  110. data/test/tc_queue.rb +16 -17
  111. data/test/tc_recur.rb +16 -17
  112. data/test/tc_res_config.rb +38 -41
  113. data/test/tc_res_env.rb +29 -32
  114. data/test/tc_res_file.rb +26 -29
  115. data/test/tc_res_opt.rb +62 -65
  116. data/test/tc_resolver.rb +287 -242
  117. data/test/tc_rr-opt.rb +70 -63
  118. data/test/tc_rr-txt.rb +68 -71
  119. data/test/tc_rr-unknown.rb +45 -48
  120. data/test/tc_rr.rb +76 -70
  121. data/test/tc_rrset.rb +21 -22
  122. data/test/tc_rrsig.rb +19 -20
  123. data/test/tc_single_resolver.rb +294 -297
  124. data/test/tc_soak.rb +199 -202
  125. data/test/tc_soak_base.rb +29 -34
  126. data/test/tc_sshfp.rb +20 -23
  127. data/test/tc_tcp.rb +32 -35
  128. data/test/tc_tkey.rb +41 -44
  129. data/test/tc_tsig.rb +81 -84
  130. data/test/tc_update.rb +108 -111
  131. data/test/tc_validator.rb +29 -29
  132. data/test/tc_verifier.rb +81 -82
  133. data/test/ts_dnsruby.rb +16 -15
  134. data/test/ts_offline.rb +62 -63
  135. data/test/ts_online.rb +115 -115
  136. metadata +155 -90
  137. data/README +0 -59
  138. data/lib/Dnsruby/DNS.rb +0 -305
  139. data/lib/Dnsruby/PacketSender.rb +0 -656
  140. data/lib/Dnsruby/Resolver.rb +0 -1189
  141. data/lib/Dnsruby/TheLog.rb +0 -44
  142. data/lib/Dnsruby/message.rb +0 -1230
  143. data/lib/Dnsruby/resource/A.rb +0 -56
  144. data/lib/Dnsruby/resource/AAAA.rb +0 -54
  145. data/lib/Dnsruby/resource/DLV.rb +0 -27
  146. data/lib/Dnsruby/resource/NSEC.rb +0 -298
  147. data/lib/Dnsruby/resource/NSEC3.rb +0 -340
  148. data/lib/Dnsruby/resource/NSEC3PARAM.rb +0 -135
  149. data/lib/Dnsruby/resource/OPT.rb +0 -213
  150. data/lib/Dnsruby/resource/RRSIG.rb +0 -275
  151. data/lib/Dnsruby/resource/SPF.rb +0 -29
  152. data/lib/Dnsruby/resource/SRV.rb +0 -112
  153. data/lib/Dnsruby/resource/TKEY.rb +0 -163
  154. data/lib/Dnsruby/resource/TSIG.rb +0 -593
  155. data/lib/Dnsruby/resource/X25.rb +0 -55
  156. data/lib/Dnsruby/resource/resource.rb +0 -678
  157. data/lib/Dnsruby/update.rb +0 -278
  158. data/lib/Dnsruby/validator_thread.rb +0 -124
@@ -0,0 +1,332 @@
1
+ # --
2
+ # Copyright 2007 Nominet UK
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ # ++
16
+ require 'digest/sha1'
17
+ module Base32
18
+ module_function
19
+ def encode32hex(str)
20
+ str.gsub(/\G(.{5})|(.{1,4}\z)/mn) do
21
+ full = $1; frag = $2
22
+ n, c = (full || frag.ljust(5, "\0")).unpack('NC')
23
+ full = ((n << 8) | c).to_s(32).rjust(8, '0')
24
+ if frag
25
+ full[0, (frag.length * 8 + 4).div(5)].ljust(8, '=').upcase
26
+ else
27
+ full.upcase
28
+ end
29
+ end
30
+ end
31
+
32
+ HEX = '[0-9a-v]'
33
+ def decode32hex(str)
34
+ str.gsub(/\G\s*(#{HEX}{8}|#{HEX}{7}=|#{HEX}{5}={3}|#{HEX}{4}={4}|#{HEX}{2}={6}|(\S))/imno) do
35
+ raise 'invalid base32' if $2
36
+ s = $1
37
+ s.tr('=', '0').to_i(32).divmod(256).pack('NC')[0,
38
+ (s.count('^=') * 5).div(8)]
39
+ end
40
+ end
41
+ end
42
+
43
+ module Dnsruby
44
+ class RR
45
+ # The NSEC3 Resource Record (RR) provides authenticated denial of
46
+ # existence for DNS Resource Record Sets.
47
+ #
48
+ # The NSEC3 RR lists RR types present at the original owner name of the
49
+ # NSEC3 RR. It includes the next hashed owner name in the hash order
50
+ # of the zone. The complete set of NSEC3 RRs in a zone indicates which
51
+ # RRSets exist for the original owner name of the RR and form a chain
52
+ # of hashed owner names in the zone. This information is used to
53
+ # provide authenticated denial of existence for DNS data. To provide
54
+ # protection against zone enumeration, the owner names used in the
55
+ # NSEC3 RR are cryptographic hashes of the original owner name
56
+ # prepended as a single label to the name of the zone. The NSEC3 RR
57
+ # indicates which hash function is used to construct the hash, which
58
+ # salt is used, and how many iterations of the hash function are
59
+ # performed over the original owner name.
60
+ class NSEC3 < RR
61
+ ClassValue = nil #:nodoc: all
62
+ TypeValue = Types::NSEC3 #:nodoc: all
63
+
64
+ # The Hash Algorithm field identifies the cryptographic hash algorithm
65
+ # used to construct the hash-value.
66
+ attr_reader :hash_alg
67
+
68
+ # The Flags field contains 8 one-bit flags that can be used to indicate
69
+ # different processing. All undefined flags must be zero. The only
70
+ # flag defined by the NSEC3 specification is the Opt-Out flag.
71
+ attr_reader :flags
72
+
73
+ # The Iterations field defines the number of additional times the hash
74
+ # function has been performed.
75
+ attr_accessor :iterations
76
+
77
+ # The Salt Length field defines the length of the Salt field in octets,
78
+ # ranging in value from 0 to 255.
79
+ attr_reader :salt_length
80
+
81
+ # The Hash Length field defines the length of the Next Hashed Owner
82
+ # Name field, ranging in value from 1 to 255 octets.
83
+ attr_reader :hash_length
84
+
85
+ # The Next Hashed Owner Name field contains the next hashed owner name
86
+ # in hash order.
87
+ attr_accessor :next_hashed
88
+
89
+ # The Type Bit Maps field identifies the RRset types that exist at the
90
+ # NSEC RR's owner name
91
+ attr_reader :types
92
+
93
+ def check_name_in_range(_name)
94
+ # @TODO@ Check if the name is covered by this record
95
+ false
96
+ end
97
+
98
+ def check_name_in_wildcard_range(_name)
99
+ # @TODO@ Check if the name is covered by this record
100
+ false
101
+ end
102
+
103
+ def calculate_hash
104
+ NSEC3.calculate_hash(@name, @iterations, @salt, @hash_alg)
105
+ end
106
+
107
+ def NSEC3.calculate_hash(name, iterations, salt, hash_alg)
108
+ # RFC5155
109
+ # 5. Calculation of the Hash
110
+
111
+ # Define H(x) to be the hash of x using the Hash Algorithm selected by
112
+ # the NSEC3 RR, k to be the number of Iterations, and || to indicate
113
+ # concatenation. Then define:
114
+ #
115
+ # IH(salt, x, 0) = H(x || salt), and
116
+ #
117
+ # IH(salt, x, k) = H(IH(salt, x, k-1) || salt), if k > 0
118
+ #
119
+ # Then the calculated hash of an owner name is
120
+ #
121
+ # IH(salt, owner name, iterations),
122
+ #
123
+ # where the owner name is in the canonical form, defined as:
124
+ #
125
+ # The wire format of the owner name where:
126
+ #
127
+ # 1. The owner name is fully expanded (no DNS name compression) and
128
+ # fully qualified;
129
+ # 2. All uppercase US-ASCII letters are replaced by the corresponding
130
+ # lowercase US-ASCII letters;
131
+ # 3. If the owner name is a wildcard name, the owner name is in its
132
+ # original unexpanded form, including the '*' label (no wildcard
133
+ # substitution);
134
+ #
135
+ # This form is as defined in Section 6.2 of [RFC 4034].
136
+ #
137
+
138
+ n = Name.create(name)
139
+ out = n.canonical
140
+ begin
141
+ (iterations + 1).times { out = NSEC3.h(out + salt, hash_alg) }
142
+ return Base32.encode32hex(out).downcase
143
+ rescue ArgumentError
144
+ TheLog.error("Unknown hash algorithm #{hash_alg} used for NSEC3 hash")
145
+ return 'Unknown NSEC3 hash algorithm'
146
+ end
147
+ end
148
+
149
+ def h(x) # :nodoc: all
150
+ NSEC3.h(x, @hash_alg)
151
+ end
152
+
153
+ def NSEC3.h(x, hash_alg) # :nodoc: all
154
+ if Nsec3HashAlgorithms.SHA_1 == hash_alg
155
+ return Digest::SHA1.digest(x)
156
+ end
157
+ raise ArgumentError.new('Unknown hash algorithm')
158
+ end
159
+
160
+ def hash_alg=(a)
161
+ if a.instance_of?(String)
162
+ if a.length == 1
163
+ a = a.to_i
164
+ end
165
+ end
166
+ begin
167
+ alg = Nsec3HashAlgorithms.new(a)
168
+ @hash_alg = alg
169
+ rescue ArgumentError => e
170
+ raise DecodeError.new(e)
171
+ end
172
+ end
173
+
174
+ def types=(t)
175
+ @types = (t && t.length > 0) ? NSEC.get_types(t) : []
176
+ end
177
+
178
+ def add_type(t)
179
+ self.types = (@types + [t])
180
+ end
181
+
182
+ OPT_OUT = 1
183
+ def flags=(f)
184
+ if f == 0 || f == OPT_OUT
185
+ @flags = f
186
+ else
187
+ raise DecodeError.new("Unknown NSEC3 flags field - #{f}")
188
+ end
189
+ end
190
+
191
+ # If the Opt-Out flag is set, the NSEC3 record covers zero or more
192
+ # unsigned delegations.
193
+ def opt_out?
194
+ @flags == OPT_OUT
195
+ end
196
+
197
+ # def salt_length=(l)
198
+ # if ((l < 0) || (l > 255))
199
+ # raise DecodeError.new('NSEC3 salt length must be between 0 and 255')
200
+ # end
201
+ # @salt_length = l
202
+ # end
203
+ #
204
+ def hash_length=(l)
205
+ if (l < 0) || (l > 255)
206
+ raise DecodeError.new("NSEC3 hash length must be between 0 and 255 but was #{l}")
207
+ end
208
+ @hash_length = l
209
+ end
210
+
211
+ def from_data(data) #:nodoc: all
212
+ hash_alg, flags, iterations, _salt_length, salt, hash_length, next_hashed, types = data
213
+ self.hash_alg = hash_alg
214
+ self.flags = flags
215
+ self.iterations = iterations
216
+ # self.salt_length=(salt_length)
217
+ # self.salt=(salt)
218
+ @salt = salt
219
+ self.hash_length = hash_length
220
+ self.next_hashed = next_hashed
221
+ self.types = types
222
+ end
223
+
224
+ # The Salt field is appended to the original owner name before hashing
225
+ # in order to defend against pre-calculated dictionary attacks.
226
+ def salt
227
+ return NSEC3.encode_salt(@salt)
228
+ end
229
+
230
+ def salt=(s)
231
+ @salt = NSEC3.decode_salt(s)
232
+ @salt_length = @salt.length
233
+ end
234
+
235
+ def NSEC3.decode_salt(input)
236
+ input == '-' ? '' : [input].pack('H*')
237
+ end
238
+
239
+ def NSEC3.encode_salt(s)
240
+ (!s || s.length == 0) ? '-' : s.unpack('H*')[0]
241
+ end
242
+
243
+ def decode_next_hashed(input)
244
+ @next_hashed = NSEC3.decode_next_hashed(input)
245
+ end
246
+
247
+ def NSEC3.decode_next_hashed(input)
248
+ return Base32.decode32hex(input)
249
+ end
250
+
251
+ def encode_next_hashed(n)
252
+ return NSEC3.encode_next_hashed(n)
253
+ end
254
+
255
+ def NSEC3.encode_next_hashed(n)
256
+ return Base32.encode32hex(n).downcase
257
+ end
258
+
259
+ def from_string(input)
260
+ if input.length > 0
261
+ data = input.split
262
+ self.hash_alg = (data[0]).to_i
263
+ self.flags = (data[1]).to_i
264
+ self.iterations = (data[2]).to_i
265
+ self.salt = (data[3])
266
+
267
+ len = data[0].length + data[1].length + data[2].length + data[3].length + 4
268
+ # There may or may not be brackets around next_hashed
269
+ if data[4] == '('
270
+ len += data[4].length + 1
271
+ end
272
+ next_hashed_and_types = (input[len, input.length-len])
273
+ data2 = next_hashed_and_types.split()
274
+
275
+
276
+ self.next_hashed = decode_next_hashed(data2[0])
277
+ self.hash_length = @next_hashed.length
278
+ len2 = data2[0].length + 1
279
+ self.types = next_hashed_and_types[len2, next_hashed_and_types.length - len2]
280
+ # self.types=data2[1]
281
+ # # len = data[0].length + data[1].length + data[2].length + data[3].length + data[5].length + 7
282
+ # # self.types=(input[len, input.length-len])
283
+ end
284
+ end
285
+
286
+ def rdata_to_string #:nodoc: all
287
+ if @next_hashed
288
+ type_strings = []
289
+ @types.each { |t| type_strings << t.string }
290
+ # salt = NSEC3.encode_salt(@salt)
291
+ salt = salt() # TODO: Remove this?
292
+ next_hashed = encode_next_hashed(@next_hashed)
293
+ types = type_strings.join(' ')
294
+ "#{@hash_alg.code} #{@flags} #{@iterations} #{salt} ( #{next_hashed} #{types} )"
295
+ else
296
+ ''
297
+ end
298
+ end
299
+
300
+ def encode_rdata(msg, canonical=false) #:nodoc: all
301
+ # s = salt()
302
+ s = @salt
303
+ sl = s.length
304
+ if s == '-'
305
+ sl = 0
306
+ end
307
+ msg.put_pack('ccnc', @hash_alg.code, @flags, @iterations, sl)
308
+ if sl > 0
309
+ msg.put_bytes(s)
310
+ end
311
+ msg.put_pack('c', @hash_length)
312
+ msg.put_bytes(@next_hashed)
313
+ types = NSEC.encode_types(self)
314
+ msg.put_bytes(types)
315
+ end
316
+
317
+ def self.decode_rdata(msg) #:nodoc: all
318
+ hash_alg, flags, iterations, salt_length = msg.get_unpack('ccnc')
319
+ # Salt may be omitted
320
+ salt = []
321
+ if salt_length > 0
322
+ salt = msg.get_bytes(salt_length)
323
+ end
324
+ hash_length, = msg.get_unpack('c')
325
+ next_hashed = msg.get_bytes(hash_length)
326
+ types = NSEC.decode_types(msg.get_bytes)
327
+ return self.new(
328
+ [hash_alg, flags, iterations, salt_length, salt, hash_length, next_hashed, types])
329
+ end
330
+ end
331
+ end
332
+ end
@@ -0,0 +1,135 @@
1
+ # --
2
+ # Copyright 2007 Nominet UK
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ # ++
16
+ module Dnsruby
17
+ class RR
18
+ # The NSEC3PARAM RR contains the NSEC3 parameters (hash algorithm,
19
+ # flags, iterations and salt) needed by authoritative servers to
20
+ # calculate hashed owner names. The presence of an NSEC3PARAM RR at a
21
+ # zone apex indicates that the specified parameters may be used by
22
+ # authoritative servers to choose an appropriate set of NSEC3 RRs for
23
+ # negative responses. The NSEC3PARAM RR is not used by validators or
24
+ # resolvers.
25
+ class NSEC3PARAM < RR
26
+ ClassValue = nil #:nodoc: all
27
+ TypeValue = Types::NSEC3PARAM #:nodoc: all
28
+
29
+ # The Hash Algorithm field identifies the cryptographic hash algorithm
30
+ # used to construct the hash-value.
31
+ attr_reader :hash_alg
32
+ # The Flags field contains 8 one-bit flags that can be used to indicate
33
+ # different processing. All undefined flags must be zero. The only
34
+ # flag defined by the NSEC3 specification is the Opt-Out flag.
35
+ attr_reader :flags
36
+ # The Iterations field defines the number of additional times the hash
37
+ # function has been performed.
38
+ attr_accessor :iterations
39
+ # The Salt Length field defines the length of the Salt field in octets,
40
+ # ranging in value from 0 to 255.
41
+ attr_reader :salt_length
42
+
43
+ # The Salt field is appended to the original owner name before hashing
44
+ # in order to defend against pre-calculated dictionary attacks.
45
+ def salt
46
+ return NSEC3.encode_salt(@salt)
47
+ end
48
+
49
+ def salt=(s)
50
+ @salt = NSEC3.decode_salt(s)
51
+ @salt_length = @salt.length
52
+ end
53
+
54
+ def hash_alg=(a)
55
+ if (a.instance_of?String)
56
+ if (a.length == 1)
57
+ a = a.to_i
58
+ end
59
+ end
60
+ begin
61
+ alg = Nsec3HashAlgorithms.new(a)
62
+ @hash_alg = alg
63
+ rescue ArgumentError => e
64
+ raise DecodeError.new(e)
65
+ end
66
+ end
67
+
68
+ def types=(t)
69
+ @types = NSEC.get_types(t)
70
+ end
71
+
72
+ def flags=(f)
73
+ if (f==0 || f==1)
74
+ @flags=f
75
+ else
76
+ raise DecodeError.new("Unknown NSEC3 flags field - #{f}")
77
+ end
78
+ end
79
+
80
+ # def salt_length=(l) # :nodoc: all
81
+ # if ((l < 0) || (l > 255))
82
+ # raise DecodeError.new("NSEC3 salt length must be between 0 and 255")
83
+ # end
84
+ # @salt_length = l
85
+ # end
86
+ #
87
+ def from_data(data) #:nodoc: all
88
+ hash_alg, flags, iterations, salt_length, salt = data
89
+ self.hash_alg=(hash_alg)
90
+ self.flags=(flags)
91
+ self.iterations=(iterations)
92
+ # self.salt_length=(salt_length)
93
+ # self.salt=(salt)
94
+ @salt=salt
95
+ end
96
+
97
+ def from_string(input)
98
+ if (input.length > 0)
99
+ data = input.split(" ")
100
+ self.hash_alg=(data[0]).to_i
101
+ self.flags=(data[1]).to_i
102
+ self.iterations=(data[2]).to_i
103
+ self.salt=(data[3])
104
+ # self.salt_length=(data[3].length)
105
+ end
106
+ end
107
+
108
+ def rdata_to_string #:nodoc: all
109
+ s = salt()
110
+ return "#{@hash_alg.code} #{@flags} #{@iterations} #{s}"
111
+ end
112
+
113
+ def encode_rdata(msg, canonical=false) #:nodoc: all
114
+ # s = salt()
115
+ s = @salt
116
+ sl = s.length()
117
+ if (s == "-")
118
+ sl == 0
119
+ end
120
+ msg.put_pack("ccnc", @hash_alg.code, @flags, @iterations, sl)
121
+
122
+ if (sl > 0)
123
+ msg.put_bytes(s)
124
+ end
125
+ end
126
+
127
+ def self.decode_rdata(msg) #:nodoc: all
128
+ hash_alg, flags, iterations, salt_length = msg.get_unpack("ccnc")
129
+ salt = msg.get_bytes(salt_length)
130
+ return self.new(
131
+ [hash_alg, flags, iterations, salt_length, salt])
132
+ end
133
+ end
134
+ end
135
+ end