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,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