dnsruby 1.55 → 1.56.0

Sign up to get free protection for your applications and to get access to all the features.
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