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
@@ -1,56 +0,0 @@
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
- module IN
19
- #Class for DNS Address (A) resource records.
20
- #
21
- #RFC 1035 Section 3.4.1
22
- class A < RR
23
- ClassHash[[TypeValue = Types::A, ClassValue = ClassValue]] = self #:nodoc: all
24
-
25
- #The RR's (Resolv::IPv4) address field
26
- attr_accessor :address
27
-
28
- def from_data(data) #:nodoc: all
29
- @address = IPv4.create(data)
30
- end
31
-
32
- #Create the RR from a hash
33
- def from_hash(hash)
34
- @address = IPv4.create(hash[:address])
35
- end
36
-
37
- # Create the RR from a standard string
38
- def from_string(input)
39
- @address = IPv4.create(input)
40
- end
41
-
42
- def rdata_to_string
43
- return @address.to_s
44
- end
45
-
46
- def encode_rdata(msg, canonical=false) #:nodoc: all
47
- msg.put_bytes(@address.address)
48
- end
49
-
50
- def self.decode_rdata(msg) #:nodoc: all
51
- return self.new(IPv4.new(msg.get_bytes(4)))
52
- end
53
- end
54
- end
55
- end
56
- end
@@ -1,54 +0,0 @@
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
- module IN
19
- #Class for DNS IPv6 Address (AAAA) resource records.
20
- #
21
- #RFC 1886 Section 2, RFC 1884 Sections 2.2 & 2.4.4
22
- class AAAA < RR
23
- ClassHash[[TypeValue = Types::AAAA, ClassValue = ClassValue]] = self #:nodoc: all
24
-
25
- # The RR's (Resolv::IPv6) address field
26
- attr_accessor :address
27
-
28
- def from_data(data) #:nodoc: all
29
- @address = IPv6.create(data)
30
- end
31
-
32
- def from_hash(hash) #:nodoc: all
33
- @address = IPv6.create(hash[:address])
34
- end
35
-
36
- def from_string(input) #:nodoc: all
37
- @address = IPv6.create(input)
38
- end
39
-
40
- def rdata_to_string #:nodoc: all
41
- return @address.to_s
42
- end
43
-
44
- def encode_rdata(msg, canonical=false) #:nodoc: all
45
- msg.put_bytes(@address.address)
46
- end
47
-
48
- def self.decode_rdata(msg) #:nodoc: all
49
- return self.new(IPv6.new(msg.get_bytes(16)))
50
- end
51
- end
52
- end
53
- end
54
- end
@@ -1,27 +0,0 @@
1
- #--
2
- #Copyright 2008 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
-
17
- module Dnsruby
18
- class RR
19
- #RFC4431 specifies that the DLV is assigned type 32769, and the
20
- # rdata is identical to that of the DS record.
21
-
22
- class DLV < RR::DS
23
- ClassValue = nil #:nodoc: all
24
- TypeValue = Types::DLV #:nodoc: all
25
- end
26
- end
27
- end
@@ -1,298 +0,0 @@
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
- #RFC4034, section 4
19
- #The NSEC resource record lists two separate things: the next owner
20
- #name (in the canonical ordering of the zone) that contains
21
- #authoritative data or a delegation point NS RRset, and the set of RR
22
- #types present at the NSEC RR's owner name [RFC3845]. The complete
23
- #set of NSEC RRs in a zone indicates which authoritative RRsets exist
24
- #in a zone and also form a chain of authoritative owner names in the
25
- #zone. This information is used to provide authenticated denial of
26
- #existence for DNS data, as described in [RFC4035].
27
- class NSEC < RR
28
- ClassValue = nil #:nodoc: all
29
- TypeValue = Types::NSEC #:nodoc: all
30
-
31
- #The next name which exists after this NSEC
32
- #The Next Domain field contains the next owner name (in the canonical
33
- #ordering of the zone) that has authoritative data or contains a
34
- #delegation point NS RRset
35
- attr_reader :next_domain
36
- #The Type Bit Maps field identifies the RRset types that exist at the
37
- #NSEC RR's owner name
38
- attr_reader :types
39
-
40
- def next_domain=(n)
41
- nxt = Name.create(n)
42
- @next_domain = nxt
43
- end
44
-
45
- def check_name_in_range(n)
46
- # Check if the name is covered by this record
47
- if (@name.wild?)
48
- return check_name_in_wildcard_range(n)
49
- end
50
- if (name.canonically_before(n) && (n.canonically_before(next_domain)))
51
- return true
52
- end
53
- return false
54
- end
55
-
56
- def check_name_in_wildcard_range(n)
57
- # Check if the name is covered by this record
58
- return false if !@name.wild?
59
- return false if @next_domain.canonically_before(n)
60
- # Now just check that the wildcard is *before* the name
61
- # Strip the first label ("*") and then compare
62
- n2 = Name.create(@name)
63
- n2.labels.delete_at(0)
64
- return false if n.canonically_before(n2)
65
- return true
66
- end
67
-
68
- def types=(t)
69
- if (t && t.length > 0)
70
- @types = NSEC.get_types(t)
71
- else
72
- @types = []
73
- end
74
- end
75
-
76
- def self.get_types(t)
77
- types = nil
78
- if (t.instance_of?Array)
79
- # from the wire, already decoded
80
- types =t
81
- elsif (t.instance_of?String)
82
- if (index = t.index";")
83
- t = t[0, index]
84
- end
85
- if (index = t.index")")
86
- t = t[0, index]
87
- end
88
- # List of mnemonics
89
- types=[]
90
- mnemonics = t.split(" ")
91
- mnemonics.each do |m|
92
- type = Types.new(m)
93
- types.push(type)
94
- end
95
- else
96
- raise DecodeError.new("Unknown format of types for Dnsruby::RR::NSEC")
97
- end
98
- return types
99
- end
100
-
101
- def add_type(t)
102
- self.types=(@types + [t])
103
- end
104
-
105
- def self.decode_types(bytes)
106
- types = []
107
- #RFC4034 section 4.1.2
108
- #The RR type space is split into 256 window blocks, each representing
109
- #the low-order 8 bits of the 16-bit RR type space. Each block that
110
- #has at least one active RR type is encoded using a single octet
111
- #window number (from 0 to 255), a single octet bitmap length (from 1
112
- #to 32) indicating the number of octets used for the window block's
113
- #bitmap, and up to 32 octets (256 bits) of bitmap.
114
-
115
- #Blocks are present in the NSEC RR RDATA in increasing numerical
116
- #order.
117
-
118
- # Type Bit Maps Field = ( Window Block # | Bitmap Length | Bitmap )+
119
-
120
- # where "|" denotes concatenation.
121
-
122
- pos = 0
123
- while (pos < bytes.length)
124
- #So, read the first two octets
125
- if (bytes.length-pos < 2)
126
- raise DecodeError.new("NSEC : Expected window number and bitmap length octets")
127
- end
128
- window_number = bytes[pos]
129
- bitmap_length = bytes[pos+1]
130
- if (window_number.class == String) # Ruby 1.9
131
- window_number = window_number.getbyte(0)
132
- bitmap_length = bitmap_length.getbyte(0)
133
- end
134
- pos += 2
135
- bitmap = bytes[pos,bitmap_length]
136
- pos += bitmap_length
137
- #Each bitmap encodes the low-order 8 bits of RR types within the
138
- #window block, in network bit order. The first bit is bit 0. For
139
- #window block 0, bit 1 corresponds to RR type 1 (A), bit 2 corresponds
140
- #to RR type 2 (NS), and so forth. For window block 1, bit 1
141
- #corresponds to RR type 257, and bit 2 to RR type 258. If a bit is
142
- #set, it indicates that an RRset of that type is present for the NSEC
143
- #RR's owner name. If a bit is clear, it indicates that no RRset of
144
- #that type is present for the NSEC RR's owner name.
145
- index = 0
146
- bitmap.each_byte do |char|
147
- if char.to_i != 0
148
- # decode these RR types
149
- 0..8.times do |i|
150
- if (((1 << (7-i)) & char) == (1 << (7-i)))
151
- type = Types.new((256 * window_number) + (8 * index) + i)
152
- #Bits representing pseudo-types MUST be clear, as they do not appear
153
- #in zone data. If encountered, they MUST be ignored upon being read.
154
- if (!([Types::OPT, Types::TSIG].include?(type)))
155
- types.push(type)
156
- end
157
- end
158
- end
159
- end
160
- index += 1
161
- end
162
- end
163
- return types
164
- end
165
-
166
- def encode_types
167
- NSEC.encode_types(self)
168
- end
169
-
170
- def self.encode_types(nsec)
171
- output=""
172
- #types represents all 65536 possible RR types.
173
- #Split up types into sets of 256 different types.
174
- type_codes = []
175
- nsec.types.each do |type|
176
- type_codes.push(type.code)
177
- end
178
- type_codes.sort!
179
- window = -1
180
- 0.step(65536,256) { |step|
181
- # Gather up the RR types for this set of 256
182
- types_to_go = []
183
- while (!type_codes.empty? && type_codes[0] < step)
184
- types_to_go.push(type_codes[0])
185
- # And delete them from type_codes
186
- type_codes=type_codes.last(type_codes.length-1)
187
- break if (type_codes.empty?)
188
- end
189
-
190
- if (!types_to_go.empty?)
191
- # Then create the bitmap for them
192
- bitmap=""
193
- # keep on adding them until there's none left
194
- pos = 0
195
- bitmap_pos = 0
196
- while (!types_to_go.empty?)
197
-
198
- # Check the next eight
199
- byte = 0
200
- pos += 8
201
- while (types_to_go[0] < pos + step-256)
202
- byte = byte | (1 << (pos-1-(types_to_go[0] - (step-256) )))
203
- # Add it to the list
204
- # And remove it from the to_go queue
205
- types_to_go =types_to_go.last(types_to_go.length-1)
206
- break if (types_to_go.empty?)
207
- end
208
- bitmap += " "
209
- if (bitmap[bitmap_pos].class == String)
210
- bitmap.setbyte(bitmap_pos, byte) # Ruby 1.9
211
- else
212
- bitmap[bitmap_pos]=byte
213
- end
214
- bitmap_pos+=1
215
- end
216
-
217
- # Now add data to output bytes
218
- start = output.length
219
- (2+bitmap.length).times do
220
- output += " "
221
- end
222
-
223
- if (output[start].class == String)
224
- output.setbyte(start, window)
225
- output.setbyte(start+1, bitmap.length)
226
- bitmap.length.times do |i|
227
- output.setbyte(start+2+i, bitmap[i].getbyte(0))
228
- end
229
- else
230
- output[start] = window
231
- output[start+1] = bitmap.length
232
- bitmap.length.times do |i|
233
- output[start+2+i] = bitmap[i]
234
- end
235
- end
236
- end
237
- window += 1
238
-
239
- # Are there any more types after this?
240
- if (type_codes.empty?)
241
- # If not, then break (so we don't add more zeros)
242
- break
243
- end
244
- }
245
- if (output[0].class == String)
246
- output = output.force_encoding("ascii-8bit")
247
- end
248
- return output
249
- end
250
-
251
- def from_data(data) #:nodoc: all
252
- next_domain, types = data
253
- self.next_domain=(next_domain)
254
- self.types=(types)
255
- end
256
-
257
- def from_string(input)
258
- if (input.length > 0)
259
- data = input.split(" ")
260
- self.next_domain=(data[0])
261
- len = data[0].length+ 1
262
- if (data[1] == "(")
263
- len = len + data[1].length
264
- end
265
- self.types=(input[len, input.length-len])
266
- @types = NSEC.get_types(input[len, input.length-len])
267
- end
268
- end
269
-
270
- def rdata_to_string #:nodoc: all
271
- if (@next_domain!=nil)
272
- type_strings = []
273
- @types.each do |t|
274
- type_strings.push(t.string)
275
- end
276
- types = type_strings.join(" ")
277
- return "#{@next_domain.to_s(true)} ( #{types} )"
278
- else
279
- return ""
280
- end
281
- end
282
-
283
- def encode_rdata(msg, canonical=false) #:nodoc: all
284
- # Canonical
285
- msg.put_name(@next_domain, canonical, false) # dnssec-bis-updates says NSEC should not be downcased
286
- types = encode_types
287
- msg.put_bytes(types)
288
- end
289
-
290
- def self.decode_rdata(msg) #:nodoc: all
291
- next_domain = msg.get_name
292
- types = decode_types(msg.get_bytes)
293
- return self.new(
294
- [next_domain, types])
295
- end
296
- end
297
- end
298
- end
@@ -1,340 +0,0 @@
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
- #The Flags field contains 8 one-bit flags that can be used to indicate
68
- #different processing. All undefined flags must be zero. The only
69
- #flag defined by the NSEC3 specification is the Opt-Out flag.
70
- attr_reader :flags
71
- #The Iterations field defines the number of additional times the hash
72
- #function has been performed.
73
- attr_accessor :iterations
74
- #The Salt Length field defines the length of the Salt field in octets,
75
- #ranging in value from 0 to 255.
76
- attr_reader :salt_length
77
- #The Hash Length field defines the length of the Next Hashed Owner
78
- #Name field, ranging in value from 1 to 255 octets.
79
- attr_reader :hash_length
80
- #The Next Hashed Owner Name field contains the next hashed owner name
81
- #in hash order.
82
- attr_accessor :next_hashed
83
- #The Type Bit Maps field identifies the RRset types that exist at the
84
- #NSEC RR's owner name
85
- attr_reader :types
86
-
87
- def check_name_in_range(name)
88
- # @TODO@ Check if the name is covered by this record
89
- return false
90
- end
91
-
92
- def check_name_in_wildcard_range(name)
93
- # @TODO@ Check if the name is covered by this record
94
- return false
95
- end
96
-
97
- def calculate_hash
98
- return NSEC3.calculate_hash(@name, @iterations, @salt, @hash_alg)
99
- end
100
-
101
- def NSEC3.calculate_hash(name, iterations, salt, hash_alg)
102
- # RFC5155
103
- #5. Calculation of the Hash
104
-
105
- # Define H(x) to be the hash of x using the Hash Algorithm selected by
106
- # the NSEC3 RR, k to be the number of Iterations, and || to indicate
107
- # concatenation. Then define:
108
- #
109
- # IH(salt, x, 0) = H(x || salt), and
110
- #
111
- # IH(salt, x, k) = H(IH(salt, x, k-1) || salt), if k > 0
112
- #
113
- # Then the calculated hash of an owner name is
114
- #
115
- # IH(salt, owner name, iterations),
116
- #
117
- # where the owner name is in the canonical form, defined as:
118
- #
119
- # The wire format of the owner name where:
120
- #
121
- # 1. The owner name is fully expanded (no DNS name compression) and
122
- # fully qualified;
123
- # 2. All uppercase US-ASCII letters are replaced by the corresponding
124
- # lowercase US-ASCII letters;
125
- # 3. If the owner name is a wildcard name, the owner name is in its
126
- # original unexpanded form, including the "*" label (no wildcard
127
- # substitution);
128
- #
129
- # This form is as defined in Section 6.2 of [RFC 4034].
130
- #
131
-
132
- n = Name.create(name)
133
- out = n.canonical
134
- begin
135
- (0..iterations).each {
136
- out =NSEC3.h(out + salt, hash_alg);
137
- }
138
- return Base32.encode32hex(out).downcase
139
- rescue ArgumentError
140
- TheLog.error("Unknown hash algorithm #{hash_alg} used for NSEC3 hash")
141
- return "Unknown NSEC3 hash algorithm"
142
- end
143
- end
144
-
145
- def h(x) # :nodoc: all
146
- return NSEC3.h(x, @hash_alg)
147
- end
148
-
149
- def NSEC3.h(x, hash_alg) # :nodoc: all
150
- if (Nsec3HashAlgorithms.SHA_1 == hash_alg)
151
- return Digest::SHA1.digest(x)
152
- end
153
- raise ArgumentError.new("Unknown hash algorithm")
154
- end
155
-
156
- def hash_alg=(a)
157
- if (a.instance_of?String)
158
- if (a.length == 1)
159
- a = a.to_i
160
- end
161
- end
162
- begin
163
- alg = Nsec3HashAlgorithms.new(a)
164
- @hash_alg = alg
165
- rescue ArgumentError => e
166
- raise DecodeError.new(e)
167
- end
168
- end
169
-
170
- def types=(t)
171
- if (t && t.length > 0)
172
- @types = NSEC.get_types(t)
173
- else
174
- @types = []
175
- end
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
- return (@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")
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
- if (input == "-")
237
- return ""
238
- end
239
- return [input].pack("H*")
240
- end
241
-
242
- def NSEC3.encode_salt(s)
243
- if (!s || s.length == 0)
244
- return "-"
245
- end
246
- return s.unpack("H*")[0]
247
- end
248
-
249
- def decode_next_hashed(input)
250
- @next_hashed = NSEC3.decode_next_hashed(input)
251
- end
252
-
253
- def NSEC3.decode_next_hashed(input)
254
- return Base32.decode32hex(input)
255
- end
256
-
257
- def encode_next_hashed(n)
258
- return NSEC3.encode_next_hashed(n)
259
- end
260
-
261
- def NSEC3.encode_next_hashed(n)
262
- return Base32.encode32hex(n).downcase
263
- end
264
-
265
- def from_string(input)
266
- if (input.length > 0)
267
- data = input.split
268
- self.hash_alg=(data[0]).to_i
269
- self.flags=(data[1]).to_i
270
- self.iterations=(data[2]).to_i
271
- self.salt=(data[3])
272
-
273
- len = data[0].length + data[1].length + data[2].length + data[3].length + 4
274
- # There may or may not be brackets around next_hashed
275
- if (data[4] == "(")
276
- len = len + data[4].length + 1
277
- end
278
- next_hashed_and_types = (input[len, input.length-len])
279
- data2 = next_hashed_and_types.split()
280
-
281
-
282
- self.next_hashed=decode_next_hashed(data2[0])
283
- self.hash_length=(@next_hashed.length)
284
- len2 = data2[0].length + 1
285
- self.types = next_hashed_and_types[len2, next_hashed_and_types.length - len2]
286
- # self.types=data2[1]
287
- # # len = data[0].length + data[1].length + data[2].length + data[3].length + data[5].length + 7
288
- # # self.types=(input[len, input.length-len])
289
- end
290
- end
291
-
292
- def rdata_to_string #:nodoc: all
293
- if (@next_hashed!=nil)
294
- type_strings = []
295
- @types.each do |t|
296
- type_strings.push(t.string)
297
- end
298
- # salt = NSEC3.encode_salt(@salt)
299
- salt = salt()
300
- next_hashed = encode_next_hashed(@next_hashed)
301
- types = type_strings.join(" ")
302
- return "#{@hash_alg.code} #{@flags} #{@iterations} #{salt} ( #{next_hashed} #{types} )"
303
- else
304
- return ""
305
- end
306
- end
307
-
308
- def encode_rdata(msg, canonical=false) #:nodoc: all
309
- # s = salt()
310
- s = @salt
311
- sl = s.length()
312
- if (s == "-")
313
- sl = 0
314
- end
315
- msg.put_pack("ccnc", @hash_alg.code, @flags, @iterations, sl)
316
- if (sl > 0)
317
- msg.put_bytes(s)
318
- end
319
- msg.put_pack("c", @hash_length)
320
- msg.put_bytes(@next_hashed)
321
- types = NSEC.encode_types(self)
322
- msg.put_bytes(types)
323
- end
324
-
325
- def self.decode_rdata(msg) #:nodoc: all
326
- hash_alg, flags, iterations, salt_length = msg.get_unpack("ccnc")
327
- # Salt may be omitted
328
- salt = []
329
- if (salt_length > 0)
330
- salt = msg.get_bytes(salt_length)
331
- end
332
- hash_length, = msg.get_unpack("c")
333
- next_hashed = msg.get_bytes(hash_length)
334
- types = NSEC.decode_types(msg.get_bytes)
335
- return self.new(
336
- [hash_alg, flags, iterations, salt_length, salt, hash_length, next_hashed, types])
337
- end
338
- end
339
- end
340
- end