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,55 +1,55 @@
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
- #Class for DNS DHCP ID (DHCID) resource records.
19
- #RFC 4701
20
- class DHCID < RR
21
- ClassValue = nil #:nodoc: all
22
- TypeValue= Types::DHCID #:nodoc: all
23
-
24
- #The opaque rdata for DHCID
25
- attr_accessor :dhcid_data
26
-
27
- def from_hash(hash) #:nodoc: all
28
- @dhcid_data = hash[:dhcid_data]
29
- end
30
-
31
- def from_data(data) #:nodoc: all
32
- @dhcid_data, = data
33
- end
34
-
35
- def from_string(input) #:nodoc: all
36
- buf = input.gsub(/\n/, "")
37
- buf.gsub!(/ /, "")
38
- @dhcid_data = buf.unpack("m*").first
39
- end
40
-
41
- def rdata_to_string #:nodoc: all
42
- return "#{[@dhcid_data.to_s].pack("m*").gsub("\n", "")}"
43
- end
44
-
45
- def encode_rdata(msg, canonical=false) #:nodoc: all
46
- msg.put_bytes(@dhcid_data)
47
- end
48
-
49
- def self.decode_rdata(msg) #:nodoc: all
50
- dhcid_data, = msg.get_bytes()
51
- return self.new([dhcid_data])
52
- end
53
- end
54
- end
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
+ # Class for DNS DHCP ID (DHCID) resource records.
19
+ # RFC 4701
20
+ class DHCID < RR
21
+ ClassValue = nil #:nodoc: all
22
+ TypeValue= Types::DHCID #:nodoc: all
23
+
24
+ # The opaque rdata for DHCID
25
+ attr_accessor :dhcid_data
26
+
27
+ def from_hash(hash) #:nodoc: all
28
+ @dhcid_data = hash[:dhcid_data]
29
+ end
30
+
31
+ def from_data(data) #:nodoc: all
32
+ @dhcid_data, = data
33
+ end
34
+
35
+ def from_string(input) #:nodoc: all
36
+ buf = input.gsub(/\n/, "")
37
+ buf.gsub!(/ /, "")
38
+ @dhcid_data = buf.unpack("m*").first
39
+ end
40
+
41
+ def rdata_to_string #:nodoc: all
42
+ return "#{[@dhcid_data.to_s].pack("m*").gsub("\n", "")}"
43
+ end
44
+
45
+ def encode_rdata(msg, canonical=false) #:nodoc: all
46
+ msg.put_bytes(@dhcid_data)
47
+ end
48
+
49
+ def self.decode_rdata(msg) #:nodoc: all
50
+ dhcid_data, = msg.get_bytes()
51
+ return self.new([dhcid_data])
52
+ end
53
+ end
54
+ end
55
55
  end
@@ -0,0 +1,27 @@
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,373 +1,373 @@
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 f181or the specific language governing permissions and
14
- #limitations under the License.
15
- #++
16
- module Dnsruby
17
- class RR
18
- #RFC4034, section 2
19
- #DNSSEC uses public key cryptography to sign and authenticate DNS
20
- #resource record sets (RRsets). The public keys are stored in DNSKEY
21
- #resource records and are used in the DNSSEC authentication process
22
- #described in [RFC4035]: A zone signs its authoritative RRsets by
23
- #using a private key and stores the corresponding public key in a
24
- #DNSKEY RR. A resolver can then use the public key to validate
25
- #signatures covering the RRsets in the zone, and thus to authenticate
26
- #them.
27
- class DNSKEY < RR
28
- ClassValue = nil #:nodoc: all
29
- TypeValue = Types::DNSKEY #:nodoc: all
30
-
31
- #Key is revoked
32
- REVOKED_KEY = 0x80
33
-
34
- #Key is a zone key
35
- ZONE_KEY = 0x100
36
-
37
- #Key is a secure entry point key
38
- SEP_KEY = 0x1
39
-
40
- #The flags for the DNSKEY RR
41
- attr_reader :flags
42
- #The protocol for this DNSKEY RR.
43
- #MUST be 3.
44
- attr_reader :protocol
45
- #The algorithm used for this key
46
- #See Dnsruby::Algorithms for permitted values
47
- attr_reader :algorithm
48
- #The public key
49
- attr_reader :key
50
- #The length (in bits) of the key - NOT key.length
51
- attr_reader :key_length
52
-
53
- def init_defaults
54
- @make_new_key_tag = false
55
- self.protocol=3
56
- self.flags=ZONE_KEY
57
- @algorithm=Algorithms.RSASHA1
58
- @public_key = nil
59
- @key_tag = nil
60
- @make_new_key_tag = true
61
- end
62
-
63
- def protocol=(p)
64
- if (p!=3)
65
- raise DecodeError.new("DNSKEY protocol field set to #{p}, contrary to RFC4034 section 2.1.2")
66
- else @protocol = p
67
- end
68
- get_new_key_tag
69
- end
70
-
71
- def algorithm=(a)
72
- if (a.instance_of?String)
73
- if (a.to_i > 0)
74
- a = a.to_i
75
- end
76
- end
77
- begin
78
- alg = Algorithms.new(a)
79
- @algorithm = alg
80
- rescue ArgumentError => e
81
- raise DecodeError.new(e)
82
- end
83
- get_new_key_tag
84
- end
85
-
86
- def revoked=(on)
87
- if (on)
88
- @flags |= REVOKED_KEY
89
- else
90
- @flags &= (~REVOKED_KEY)
91
- end
92
- get_new_key_tag
93
- end
94
-
95
- def revoked?
96
- return ((@flags & REVOKED_KEY) > 0)
97
- end
98
-
99
- def zone_key=(on)
100
- if (on)
101
- @flags |= ZONE_KEY
102
- else
103
- @flags &= (~ZONE_KEY)
104
- end
105
- get_new_key_tag
106
- end
107
-
108
- def zone_key?
109
- return ((@flags & ZONE_KEY) > 0)
110
- end
111
-
112
- def sep_key=(on)
113
- if (on)
114
- @flags |= SEP_KEY
115
- else
116
- @flags &= (~SEP_KEY)
117
- end
118
- get_new_key_tag
119
- end
120
-
121
- def sep_key?
122
- return ((@flags & SEP_KEY) > 0)
123
- end
124
-
125
- def flags=(f)
126
- # Only three values allowed -
127
- # Zone Key flag (bit 7)
128
- # Secure Entry Point flag (bit 15)
129
- # Revoked bit (bit 8) - RFC 5011
130
- if ((f & ~ZONE_KEY & ~SEP_KEY & ~REVOKED_KEY) > 0)
131
- TheLog.info("DNSKEY: Only zone key, secure entry point and revoked flags allowed for DNSKEY" +
132
- " (RFC4034 section 2.1.1) : #{f} entered as input")
133
- end
134
-
135
- @flags = f
136
- get_new_key_tag
137
- end
138
-
139
- # def bad_flags?
140
- # if ((@flags & ~ZONE_KEY & ~SEP_KEY) > 0)
141
- # return true
142
- # end
143
- # return false
144
- # end
145
- #
146
- def from_data(data) #:nodoc: all
147
- flags, protocol, algorithm, @key = data
148
- @make_new_key_tag = false
149
- self.flags=(flags)
150
- self.protocol=(protocol)
151
- self.algorithm=(algorithm)
152
- @make_new_key_tag = true
153
- get_new_key_tag
154
- end
155
-
156
- def from_hash(hash) #:nodoc: all
157
- @make_new_key_tag = false
158
- hash.keys.each do |param|
159
- send(param.to_s+"=", hash[param])
160
- end
161
- @make_new_key_tag = true
162
- get_new_key_tag
163
- end
164
-
165
- def from_string(input)
166
- if (input.length > 0)
167
- @make_new_key_tag = false
168
- data = input.split(" ")
169
- self.flags=(data[0].to_i)
170
- self.protocol=(data[1].to_i)
171
- self.algorithm=(data[2])
172
- # key can include whitespace - include all text
173
- # until we come to " )" at the end, and then gsub
174
- # the white space out
175
- # Also, brackets may or may not be present
176
- # Not to mention comments! ";"
177
- buf = ""
178
- index = 3
179
- end_index = data.length - 1
180
- if (data[index]=="(")
181
- end_index = data.length - 2
182
- index = 4
183
- end
184
- (index..end_index).each {|i|
185
- if (comment_index = data[i].index(";"))
186
- buf += data[i].slice(0, comment_index)
187
- # @TODO@ We lose the comments here - we should really keep them for when we write back to string format?
188
- break
189
- else
190
- buf += data[i]
191
- end
192
- }
193
- self.key=(buf)
194
- @make_new_key_tag = true
195
- get_new_key_tag
196
- end
197
- end
198
-
199
- def rdata_to_string #:nodoc: all
200
- if (@flags!=nil)
201
- # return "#{@flags} #{@protocol} #{@algorithm.string} ( #{Base64.encode64(@key.to_s)} )"
202
- return "#{@flags} #{@protocol} #{@algorithm.string} ( #{[@key.to_s].pack("m*").gsub("\n", "")} ) ; key_tag=#{key_tag}"
203
- else
204
- return ""
205
- end
206
- end
207
-
208
- def encode_rdata(msg, canonical=false) #:nodoc: all
209
- # 2 octets, then 2 sets of 1 octet
210
- msg.put_pack('ncc', @flags, @protocol, @algorithm.code)
211
- msg.put_bytes(@key)
212
- end
213
-
214
- def self.decode_rdata(msg) #:nodoc: all
215
- # 2 octets, then 2 sets of 1 octet
216
- flags, protocol, algorithm = msg.get_unpack('ncc')
217
- key = msg.get_bytes
218
- return self.new(
219
- [flags, protocol, algorithm, key])
220
- end
221
-
222
- # Return the the key tag this key would have had before it was revoked
223
- # If the key is not revoked, then the current key_tag will be returned
224
- def key_tag_pre_revoked
225
- if (!revoked?)
226
- return key_tag
227
- end
228
- new_key = clone
229
- new_key.revoked = false
230
- return new_key.key_tag
231
- end
232
-
233
- def get_new_key_tag
234
- if (@make_new_key_tag)
235
- rdata = MessageEncoder.new {|msg|
236
- encode_rdata(msg)
237
- }.to_s
238
- tag = generate_key_tag(rdata, @algorithm)
239
- @key_tag = tag
240
- end
241
- end
242
-
243
- # Return the tag for this key
244
- def key_tag
245
- if (!@key_tag)
246
- @make_new_key_tag = true
247
- get_new_key_tag
248
- end
249
- return @key_tag
250
- end
251
-
252
- def generate_key_tag(rdata, algorithm)
253
- tag=0
254
- if (algorithm == Algorithms.RSAMD5)
255
- #The key tag for algorithm 1 (RSA/MD5) is defined differently from the
256
- #key tag for all other algorithms, for historical reasons.
257
- d1 = rdata[rdata.length - 3] & 0xFF
258
- d2 = rdata[rdata.length - 2] & 0xFF
259
- tag = (d1 << 8) + d2
260
- else
261
- tag = 0
262
- last = 0
263
- 0.step(rdata.length - 1, 2) {|i|
264
- last = i
265
- d1 = rdata[i]
266
- d2 = rdata[i + 1] || 0 # odd number of bytes possible
267
-
268
- d1 = d1.getbyte(0) if d1.class == String # Ruby 1.9
269
- d2 = d2.getbyte(0) if d2.class == String # Ruby 1.9
270
-
271
- d1 = d1 & 0xFF
272
- d2 = d2 & 0xFF
273
-
274
- tag += ((d1 << 8) + d2)
275
- }
276
- last+=2
277
- if (last < rdata.length)
278
- d1 = rdata[last]
279
-
280
- if (d1.class == String) # Ruby 1.9
281
- d1 = d1.getbyte(0)
282
- end
283
-
284
- d1 = d1 & 0xFF
285
- tag += (d1 << 8)
286
- end
287
- tag += ((tag >> 16) & 0xFFFF)
288
- end
289
- tag=tag&0xFFFF
290
- return tag
291
- end
292
-
293
- def key=(key_text)
294
- begin
295
- key_text.gsub!(/\n/, "")
296
- key_text.gsub!(/ /, "")
297
- # @key=Base64.decode64(key_text)
298
- @key=key_text.unpack("m*")[0]
299
- public_key
300
- get_new_key_tag
301
- rescue Exception
302
- raise ArgumentError.new("Key #{key_text} invalid")
303
- end
304
- end
305
-
306
- def public_key
307
- if (!@public_key)
308
- if [Algorithms.RSASHA1,
309
- Algorithms.RSASHA256,
310
- Algorithms.RSASHA512,
311
- Algorithms.RSASHA1_NSEC3_SHA1].include?(@algorithm)
312
- @public_key = rsa_key
313
- elsif [Algorithms.DSA,
314
- Algorithms.DSA_NSEC3_SHA1].include?(@algorithm)
315
- @public_key = dsa_key
316
- end
317
- end
318
- # @TODO@ Support other key encodings!
319
- return @public_key
320
- end
321
-
322
- def rsa_key
323
- exponentLength = @key[0]
324
- if (exponentLength.class == String)
325
- exponentLength = exponentLength.getbyte(0) # Ruby 1.9
326
- end
327
- pos = 1
328
- if (exponentLength == 0)
329
- key1 = @key[1]
330
- if (key1.class == String) # Ruby 1.9
331
- key1 = key1.getbyte(0)
332
- end
333
- exponentLength = (key1<<8) + key1
334
- pos += 2
335
- end
336
- exponent = RR::get_num(@key[pos, exponentLength])
337
- pos += exponentLength
338
-
339
- modulus = RR::get_num(@key[pos, @key.length])
340
- @key_length = (@key.length - pos) * 8
341
-
342
- pkey = OpenSSL::PKey::RSA.new
343
- pkey.e = exponent
344
- pkey.n = modulus
345
- return pkey
346
- end
347
-
348
- def dsa_key
349
- t = @key[0]
350
- t = t.getbyte(0) if t.class == String
351
- pgy_len = t * 8 + 64
352
- pos = 1
353
- q = RR::get_num(@key[pos, 20])
354
- pos += 20
355
- p = RR::get_num(@key[pos, pgy_len])
356
- pos += pgy_len
357
- g = RR::get_num(@key[pos, pgy_len])
358
- pos += pgy_len
359
- y = RR::get_num(@key[pos, pgy_len])
360
- pos += pgy_len
361
- @key_length = (pgy_len * 8)
362
-
363
- pkey = OpenSSL::PKey::DSA.new
364
- pkey.p = p
365
- pkey.q = q
366
- pkey.g = g
367
- pkey.pub_key = y
368
-
369
- pkey
370
- end
371
- end
372
- end
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 f181or the specific language governing permissions and
14
+ # limitations under the License.
15
+ # ++
16
+ module Dnsruby
17
+ class RR
18
+ # RFC4034, section 2
19
+ # DNSSEC uses public key cryptography to sign and authenticate DNS
20
+ # resource record sets (RRsets). The public keys are stored in DNSKEY
21
+ # resource records and are used in the DNSSEC authentication process
22
+ # described in [RFC4035]: A zone signs its authoritative RRsets by
23
+ # using a private key and stores the corresponding public key in a
24
+ # DNSKEY RR. A resolver can then use the public key to validate
25
+ # signatures covering the RRsets in the zone, and thus to authenticate
26
+ # them.
27
+ class DNSKEY < RR
28
+ ClassValue = nil #:nodoc: all
29
+ TypeValue = Types::DNSKEY #:nodoc: all
30
+
31
+ # Key is revoked
32
+ REVOKED_KEY = 0x80
33
+
34
+ # Key is a zone key
35
+ ZONE_KEY = 0x100
36
+
37
+ # Key is a secure entry point key
38
+ SEP_KEY = 0x1
39
+
40
+ # The flags for the DNSKEY RR
41
+ attr_reader :flags
42
+ # The protocol for this DNSKEY RR.
43
+ # MUST be 3.
44
+ attr_reader :protocol
45
+ # The algorithm used for this key
46
+ # See Dnsruby::Algorithms for permitted values
47
+ attr_reader :algorithm
48
+ # The public key
49
+ attr_reader :key
50
+ # The length (in bits) of the key - NOT key.length
51
+ attr_reader :key_length
52
+
53
+ def init_defaults
54
+ @make_new_key_tag = false
55
+ self.protocol=3
56
+ self.flags=ZONE_KEY
57
+ @algorithm=Algorithms.RSASHA1
58
+ @public_key = nil
59
+ @key_tag = nil
60
+ @make_new_key_tag = true
61
+ end
62
+
63
+ def protocol=(p)
64
+ if (p!=3)
65
+ raise DecodeError.new("DNSKEY protocol field set to #{p}, contrary to RFC4034 section 2.1.2")
66
+ else @protocol = p
67
+ end
68
+ get_new_key_tag
69
+ end
70
+
71
+ def algorithm=(a)
72
+ if (a.instance_of?String)
73
+ if (a.to_i > 0)
74
+ a = a.to_i
75
+ end
76
+ end
77
+ begin
78
+ alg = Algorithms.new(a)
79
+ @algorithm = alg
80
+ rescue ArgumentError => e
81
+ raise DecodeError.new(e)
82
+ end
83
+ get_new_key_tag
84
+ end
85
+
86
+ def revoked=(on)
87
+ if (on)
88
+ @flags |= REVOKED_KEY
89
+ else
90
+ @flags &= (~REVOKED_KEY)
91
+ end
92
+ get_new_key_tag
93
+ end
94
+
95
+ def revoked?
96
+ return ((@flags & REVOKED_KEY) > 0)
97
+ end
98
+
99
+ def zone_key=(on)
100
+ if (on)
101
+ @flags |= ZONE_KEY
102
+ else
103
+ @flags &= (~ZONE_KEY)
104
+ end
105
+ get_new_key_tag
106
+ end
107
+
108
+ def zone_key?
109
+ return ((@flags & ZONE_KEY) > 0)
110
+ end
111
+
112
+ def sep_key=(on)
113
+ if (on)
114
+ @flags |= SEP_KEY
115
+ else
116
+ @flags &= (~SEP_KEY)
117
+ end
118
+ get_new_key_tag
119
+ end
120
+
121
+ def sep_key?
122
+ return ((@flags & SEP_KEY) > 0)
123
+ end
124
+
125
+ def flags=(f)
126
+ # Only three values allowed -
127
+ # Zone Key flag (bit 7)
128
+ # Secure Entry Point flag (bit 15)
129
+ # Revoked bit (bit 8) - RFC 5011
130
+ if ((f & ~ZONE_KEY & ~SEP_KEY & ~REVOKED_KEY) > 0)
131
+ TheLog.info("DNSKEY: Only zone key, secure entry point and revoked flags allowed for DNSKEY" +
132
+ " (RFC4034 section 2.1.1) : #{f} entered as input")
133
+ end
134
+
135
+ @flags = f
136
+ get_new_key_tag
137
+ end
138
+
139
+ # def bad_flags?
140
+ # if ((@flags & ~ZONE_KEY & ~SEP_KEY) > 0)
141
+ # return true
142
+ # end
143
+ # return false
144
+ # end
145
+ #
146
+ def from_data(data) #:nodoc: all
147
+ flags, protocol, algorithm, @key = data
148
+ @make_new_key_tag = false
149
+ self.flags=(flags)
150
+ self.protocol=(protocol)
151
+ self.algorithm=(algorithm)
152
+ @make_new_key_tag = true
153
+ get_new_key_tag
154
+ end
155
+
156
+ def from_hash(hash) #:nodoc: all
157
+ @make_new_key_tag = false
158
+ hash.keys.each do |param|
159
+ send(param.to_s+"=", hash[param])
160
+ end
161
+ @make_new_key_tag = true
162
+ get_new_key_tag
163
+ end
164
+
165
+ def from_string(input)
166
+ if (input.length > 0)
167
+ @make_new_key_tag = false
168
+ data = input.split(" ")
169
+ self.flags=(data[0].to_i)
170
+ self.protocol=(data[1].to_i)
171
+ self.algorithm=(data[2])
172
+ # key can include whitespace - include all text
173
+ # until we come to " )" at the end, and then gsub
174
+ # the white space out
175
+ # Also, brackets may or may not be present
176
+ # Not to mention comments! ";"
177
+ buf = ""
178
+ index = 3
179
+ end_index = data.length - 1
180
+ if (data[index]=="(")
181
+ end_index = data.length - 2
182
+ index = 4
183
+ end
184
+ (index..end_index).each {|i|
185
+ if (comment_index = data[i].index(";"))
186
+ buf += data[i].slice(0, comment_index)
187
+ # @TODO@ We lose the comments here - we should really keep them for when we write back to string format?
188
+ break
189
+ else
190
+ buf += data[i]
191
+ end
192
+ }
193
+ self.key=(buf)
194
+ @make_new_key_tag = true
195
+ get_new_key_tag
196
+ end
197
+ end
198
+
199
+ def rdata_to_string #:nodoc: all
200
+ if (@flags!=nil)
201
+ # return "#{@flags} #{@protocol} #{@algorithm.string} ( #{Base64.encode64(@key.to_s)} )"
202
+ return "#{@flags} #{@protocol} #{@algorithm.string} ( #{[@key.to_s].pack("m*").gsub("\n", "")} ) ; key_tag=#{key_tag}"
203
+ else
204
+ return ""
205
+ end
206
+ end
207
+
208
+ def encode_rdata(msg, canonical=false) #:nodoc: all
209
+ # 2 octets, then 2 sets of 1 octet
210
+ msg.put_pack('ncc', @flags, @protocol, @algorithm.code)
211
+ msg.put_bytes(@key)
212
+ end
213
+
214
+ def self.decode_rdata(msg) #:nodoc: all
215
+ # 2 octets, then 2 sets of 1 octet
216
+ flags, protocol, algorithm = msg.get_unpack('ncc')
217
+ key = msg.get_bytes
218
+ return self.new(
219
+ [flags, protocol, algorithm, key])
220
+ end
221
+
222
+ # Return the the key tag this key would have had before it was revoked
223
+ # If the key is not revoked, then the current key_tag will be returned
224
+ def key_tag_pre_revoked
225
+ if (!revoked?)
226
+ return key_tag
227
+ end
228
+ new_key = clone
229
+ new_key.revoked = false
230
+ return new_key.key_tag
231
+ end
232
+
233
+ def get_new_key_tag
234
+ if (@make_new_key_tag)
235
+ rdata = MessageEncoder.new {|msg|
236
+ encode_rdata(msg)
237
+ }.to_s
238
+ tag = generate_key_tag(rdata, @algorithm)
239
+ @key_tag = tag
240
+ end
241
+ end
242
+
243
+ # Return the tag for this key
244
+ def key_tag
245
+ if (!@key_tag)
246
+ @make_new_key_tag = true
247
+ get_new_key_tag
248
+ end
249
+ return @key_tag
250
+ end
251
+
252
+ def generate_key_tag(rdata, algorithm)
253
+ tag=0
254
+ if (algorithm == Algorithms.RSAMD5)
255
+ # The key tag for algorithm 1 (RSA/MD5) is defined differently from the
256
+ # key tag for all other algorithms, for historical reasons.
257
+ d1 = rdata[rdata.length - 3] & 0xFF
258
+ d2 = rdata[rdata.length - 2] & 0xFF
259
+ tag = (d1 << 8) + d2
260
+ else
261
+ tag = 0
262
+ last = 0
263
+ 0.step(rdata.length - 1, 2) {|i|
264
+ last = i
265
+ d1 = rdata[i]
266
+ d2 = rdata[i + 1] || 0 # odd number of bytes possible
267
+
268
+ d1 = d1.getbyte(0) if d1.class == String # Ruby 1.9
269
+ d2 = d2.getbyte(0) if d2.class == String # Ruby 1.9
270
+
271
+ d1 = d1 & 0xFF
272
+ d2 = d2 & 0xFF
273
+
274
+ tag += ((d1 << 8) + d2)
275
+ }
276
+ last+=2
277
+ if (last < rdata.length)
278
+ d1 = rdata[last]
279
+
280
+ if (d1.class == String) # Ruby 1.9
281
+ d1 = d1.getbyte(0)
282
+ end
283
+
284
+ d1 = d1 & 0xFF
285
+ tag += (d1 << 8)
286
+ end
287
+ tag += ((tag >> 16) & 0xFFFF)
288
+ end
289
+ tag=tag&0xFFFF
290
+ return tag
291
+ end
292
+
293
+ def key=(key_text)
294
+ begin
295
+ key_text.gsub!(/\n/, "")
296
+ key_text.gsub!(/ /, "")
297
+ # @key=Base64.decode64(key_text)
298
+ @key=key_text.unpack("m*")[0]
299
+ public_key
300
+ get_new_key_tag
301
+ rescue Exception
302
+ raise ArgumentError.new("Key #{key_text} invalid")
303
+ end
304
+ end
305
+
306
+ def public_key
307
+ if (!@public_key)
308
+ if [Algorithms.RSASHA1,
309
+ Algorithms.RSASHA256,
310
+ Algorithms.RSASHA512,
311
+ Algorithms.RSASHA1_NSEC3_SHA1].include?(@algorithm)
312
+ @public_key = rsa_key
313
+ elsif [Algorithms.DSA,
314
+ Algorithms.DSA_NSEC3_SHA1].include?(@algorithm)
315
+ @public_key = dsa_key
316
+ end
317
+ end
318
+ # @TODO@ Support other key encodings!
319
+ return @public_key
320
+ end
321
+
322
+ def rsa_key
323
+ exponentLength = @key[0]
324
+ if (exponentLength.class == String)
325
+ exponentLength = exponentLength.getbyte(0) # Ruby 1.9
326
+ end
327
+ pos = 1
328
+ if (exponentLength == 0)
329
+ key1 = @key[1]
330
+ if (key1.class == String) # Ruby 1.9
331
+ key1 = key1.getbyte(0)
332
+ end
333
+ exponentLength = (key1<<8) + key1
334
+ pos += 2
335
+ end
336
+ exponent = RR::get_num(@key[pos, exponentLength])
337
+ pos += exponentLength
338
+
339
+ modulus = RR::get_num(@key[pos, @key.length])
340
+ @key_length = (@key.length - pos) * 8
341
+
342
+ pkey = OpenSSL::PKey::RSA.new
343
+ pkey.e = exponent
344
+ pkey.n = modulus
345
+ return pkey
346
+ end
347
+
348
+ def dsa_key
349
+ t = @key[0]
350
+ t = t.getbyte(0) if t.class == String
351
+ pgy_len = t * 8 + 64
352
+ pos = 1
353
+ q = RR::get_num(@key[pos, 20])
354
+ pos += 20
355
+ p = RR::get_num(@key[pos, pgy_len])
356
+ pos += pgy_len
357
+ g = RR::get_num(@key[pos, pgy_len])
358
+ pos += pgy_len
359
+ y = RR::get_num(@key[pos, pgy_len])
360
+ pos += pgy_len
361
+ @key_length = (pgy_len * 8)
362
+
363
+ pkey = OpenSSL::PKey::DSA.new
364
+ pkey.p = p
365
+ pkey.q = q
366
+ pkey.g = g
367
+ pkey.pub_key = y
368
+
369
+ pkey
370
+ end
371
+ end
372
+ end
373
373
  end