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,135 +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
- #The NSEC3PARAM RR contains the NSEC3 parameters (hash algorithm,
19
- #flags, iterations and salt) needed by authoritative servers to
20
- #calculate hashed owner names. The presence of an NSEC3PARAM RR at a
21
- #zone apex indicates that the specified parameters may be used by
22
- #authoritative servers to choose an appropriate set of NSEC3 RRs for
23
- #negative responses. The NSEC3PARAM RR is not used by validators or
24
- #resolvers.
25
- class NSEC3PARAM < RR
26
- ClassValue = nil #:nodoc: all
27
- TypeValue = Types::NSEC3PARAM #:nodoc: all
28
-
29
- #The Hash Algorithm field identifies the cryptographic hash algorithm
30
- #used to construct the hash-value.
31
- attr_reader :hash_alg
32
- #The Flags field contains 8 one-bit flags that can be used to indicate
33
- #different processing. All undefined flags must be zero. The only
34
- #flag defined by the NSEC3 specification is the Opt-Out flag.
35
- attr_reader :flags
36
- #The Iterations field defines the number of additional times the hash
37
- #function has been performed.
38
- attr_accessor :iterations
39
- #The Salt Length field defines the length of the Salt field in octets,
40
- #ranging in value from 0 to 255.
41
- attr_reader :salt_length
42
-
43
- #The Salt field is appended to the original owner name before hashing
44
- #in order to defend against pre-calculated dictionary attacks.
45
- def salt
46
- return NSEC3.encode_salt(@salt)
47
- end
48
-
49
- def salt=(s)
50
- @salt = NSEC3.decode_salt(s)
51
- @salt_length = @salt.length
52
- end
53
-
54
- def hash_alg=(a)
55
- if (a.instance_of?String)
56
- if (a.length == 1)
57
- a = a.to_i
58
- end
59
- end
60
- begin
61
- alg = Nsec3HashAlgorithms.new(a)
62
- @hash_alg = alg
63
- rescue ArgumentError => e
64
- raise DecodeError.new(e)
65
- end
66
- end
67
-
68
- def types=(t)
69
- @types = NSEC.get_types(t)
70
- end
71
-
72
- def flags=(f)
73
- if (f==0 || f==1)
74
- @flags=f
75
- else
76
- raise DecodeError.new("Unknown NSEC3 flags field - #{f}")
77
- end
78
- end
79
-
80
- # def salt_length=(l) # :nodoc: all
81
- # if ((l < 0) || (l > 255))
82
- # raise DecodeError.new("NSEC3 salt length must be between 0 and 255")
83
- # end
84
- # @salt_length = l
85
- # end
86
- #
87
- def from_data(data) #:nodoc: all
88
- hash_alg, flags, iterations, salt_length, salt = data
89
- self.hash_alg=(hash_alg)
90
- self.flags=(flags)
91
- self.iterations=(iterations)
92
- # self.salt_length=(salt_length)
93
- # self.salt=(salt)
94
- @salt=salt
95
- end
96
-
97
- def from_string(input)
98
- if (input.length > 0)
99
- data = input.split(" ")
100
- self.hash_alg=(data[0]).to_i
101
- self.flags=(data[1]).to_i
102
- self.iterations=(data[2]).to_i
103
- self.salt=(data[3])
104
- # self.salt_length=(data[3].length)
105
- end
106
- end
107
-
108
- def rdata_to_string #:nodoc: all
109
- s = salt()
110
- return "#{@hash_alg.code} #{@flags} #{@iterations} #{s}"
111
- end
112
-
113
- def encode_rdata(msg, canonical=false) #:nodoc: all
114
- # s = salt()
115
- s = @salt
116
- sl = s.length()
117
- if (s == "-")
118
- sl == 0
119
- end
120
- msg.put_pack("ccnc", @hash_alg.code, @flags, @iterations, sl)
121
-
122
- if (sl > 0)
123
- msg.put_bytes(s)
124
- end
125
- end
126
-
127
- def self.decode_rdata(msg) #:nodoc: all
128
- hash_alg, flags, iterations, salt_length = msg.get_unpack("ccnc")
129
- salt = msg.get_bytes(salt_length)
130
- return self.new(
131
- [hash_alg, flags, iterations, salt_length, salt])
132
- end
133
- end
134
- end
135
- end
@@ -1,213 +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
- #Class for EDNS pseudo resource record OPT.
19
- #This class is effectively internal to Dnsruby
20
- #See RFC 2671, RFC 2435 Section 3
21
- # @TODO@ Extended labels RFC2671 section 3
22
- class OPT < RR #:nodoc: all
23
- ClassValue = nil #:nodoc: all
24
- TypeValue = Types::OPT #:nodoc: all
25
- DO_BIT = 0x8000
26
-
27
- # @TODO@ Add BADVERS to an XRCode CodeMapper object
28
-
29
- #Can be called with up to 3 arguments, none of which must be present
30
- #* OPT.new()
31
- #* OPT.new(size)
32
- #* OPT.new(size,flags)
33
- #* OPT.new(size,flags,options)
34
- def initialize(*args)
35
- @type = Types.new('OPT')
36
- @ttl = nil
37
-
38
- @options=nil
39
- if (args.length > 0)
40
- self.payloadsize=(args[0])
41
- if (args.length > 1)
42
- self.flags=(args[1])
43
- if (args.length > 2)
44
- self.options=(args[2])
45
- else
46
- self.options=nil
47
- end
48
- else
49
- self.flags=0
50
- end
51
- else
52
- self.payloadsize=0
53
- end
54
- end
55
-
56
- # From RFC 2671 :
57
- # 4.3. The fixed part of an OPT RR is structured as follows:
58
- #
59
- # Field Name Field Type Description
60
- # ------------------------------------------------------
61
- # NAME domain name empty (root domain)
62
- # TYPE u_int16_t OPT
63
- # CLASS u_int16_t sender's UDP payload size
64
- # TTL u_int32_t extended RCODE and flags
65
- # RDLEN u_int16_t describes RDATA
66
- # RDATA octet stream {attribute,value} pairs
67
-
68
- #4.6. The extended RCODE and flags (which OPT stores in the RR TTL field)
69
- #are structured as follows:
70
- #
71
- # +0 (MSB) +1 (LSB)
72
- # +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
73
- # 0: | EXTENDED-RCODE | VERSION |
74
- # +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
75
- # 2: | Z |
76
- # +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
77
- #
78
- # EXTENDED-RCODE Forms upper 8 bits of extended 12-bit RCODE. Note
79
- # that EXTENDED-RCODE value "0" indicates that an
80
- # unextended RCODE is in use (values "0" through "15").
81
- #
82
- # VERSION Indicates the implementation level of whoever sets
83
- # it. Full conformance with this specification is
84
- # indicated by version "0."
85
-
86
- def flags_from_ttl
87
- if (@ttl)
88
- return [@ttl].pack("N")
89
- else
90
- return [0].pack("N")
91
- end
92
- end
93
-
94
- def xrcode
95
- return ExtendedRCode.new(flags_from_ttl[0, 1].unpack("C")[0])
96
- end
97
-
98
- def xrcode=(c)
99
- code = ExtendedRCode.new(c)
100
- @ttl = (code.code << 24) + (version() << 16) + flags()
101
- end
102
-
103
- def version
104
- return flags_from_ttl[1, 1].unpack("C")[0]
105
- end
106
-
107
- def version=(code)
108
- @ttl = (xrcode().code << 24) + (code << 16) + flags()
109
- end
110
-
111
- def flags
112
- return flags_from_ttl[2, 2].unpack("n")[0]
113
- end
114
-
115
- def flags=(code)
116
- set_flags(code)
117
- end
118
-
119
- def set_flags(code) # Should always be zero
120
- @ttl = (xrcode().code << 24) + (version() << 16) + code
121
- end
122
-
123
- def dnssec_ok
124
- return ((flags() & DO_BIT) == DO_BIT)
125
- end
126
-
127
- def dnssec_ok=(on)
128
- if (on)
129
- set_flags(flags() | DO_BIT)
130
- else
131
- set_flags(flags() & (~DO_BIT))
132
- end
133
- end
134
-
135
- def payloadsize
136
- return @klass.code
137
- end
138
-
139
- def payloadsize=(size)
140
- self.klass=size
141
- end
142
-
143
- def options(args)
144
- if (args==nil)
145
- return @options
146
- elsif args.kind_of?Fixnum
147
- # return list of options with that code
148
- ret = []
149
- @options.each do |option|
150
- if (option.code == args)
151
- ret.push(option)
152
- end
153
- end
154
- return ret
155
- end
156
- end
157
-
158
- def options=(options)
159
- @options = options
160
- end
161
-
162
- def from_data(data)
163
- @options = data
164
- end
165
-
166
- def from_string(input)
167
- raise NotImplementedError
168
- end
169
-
170
- def to_s
171
- ret = "OPT pseudo-record : payloadsize #{payloadsize}, xrcode #{xrcode.code}, version #{version}, flags #{flags}"
172
- if @options
173
- @options.each do |opt|
174
- ret = ret + " " + opt.to_s
175
- end
176
- end
177
- ret = ret + "\n"
178
- return ret
179
- end
180
-
181
- def encode_rdata(msg, canonical=false)
182
- if (@options)
183
- @options.each do |opt|
184
- msg.put_pack('n', opt.code)
185
- msg.put_pack('n', opt.data.length)
186
- msg.put_bytes(opt.data)
187
- end
188
- end
189
- end
190
-
191
- def self.decode_rdata(msg)#:nodoc: all
192
- if (msg.has_remaining)
193
- options = []
194
- while (msg.has_remaining) do
195
- code = msg.get_unpack('n')[0]
196
- len = msg.get_unpack('n')[0]
197
- data = msg.get_bytes(len)
198
- options.push(Option.new(code, data))
199
- end
200
- end
201
- return self.new([options])
202
- end
203
-
204
- class Option
205
- attr_accessor :code, :data
206
- def initialize(code, data)
207
- @code = code
208
- @data = data
209
- end
210
- end
211
- end
212
- end
213
- end
@@ -1,275 +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 3)
19
- #DNSSEC uses public key cryptography to sign and authenticate DNS
20
- #resource record sets (RRsets). Digital signatures are stored in
21
- #RRSIG resource records and are used in the DNSSEC authentication
22
- #process described in [RFC4035]. A validator can use these RRSIG RRs
23
- #to authenticate RRsets from the zone. The RRSIG RR MUST only be used
24
- #to carry verification material (digital signatures) used to secure
25
- #DNS operations.
26
- #
27
- #An RRSIG record contains the signature for an RRset with a particular
28
- #name, class, and type. The RRSIG RR specifies a validity interval
29
- #for the signature and uses the Algorithm, the Signer's Name, and the
30
- #Key Tag to identify the DNSKEY RR containing the public key that a
31
- #validator can use to verify the signature.
32
- class RRSIG < RR
33
- ClassValue = nil #:nodoc: all
34
- TypeValue = Types::RRSIG #:nodoc: all
35
-
36
- # 3.1. RRSIG RDATA Wire Format
37
- #
38
- # The RDATA for an RRSIG RR consists of a 2 octet Type Covered field, a
39
- # 1 octet Algorithm field, a 1 octet Labels field, a 4 octet Original
40
- # TTL field, a 4 octet Signature Expiration field, a 4 octet Signature
41
- # Inception field, a 2 octet Key tag, the Signer's Name field, and the
42
- # Signature field.
43
- #
44
- # 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
45
- # 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
46
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
47
- # | Type Covered | Algorithm | Labels |
48
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
49
- # | Original TTL |
50
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
51
- # | Signature Expiration |
52
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
53
- # | Signature Inception |
54
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
55
- # | Key Tag | /
56
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Signer's Name /
57
- # / /
58
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
59
- # / /
60
- # / Signature /
61
- # / /
62
- # +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
63
-
64
- #The type covered by this RRSIG
65
- attr_reader :type_covered
66
- #The algorithm used for this RRSIG
67
- #See Dnsruby::Algorithms for permitted values
68
- attr_reader :algorithm
69
- #The number of labels in the original RRSIG RR owner name
70
- #Can be used to determine if name was synthesised from a wildcard.
71
- attr_accessor :labels
72
- #The TTL of the covered RRSet as it appears in the authoritative zone
73
- attr_accessor :original_ttl
74
- #The signature expiration
75
- attr_accessor :expiration
76
- #The signature inception
77
- attr_accessor :inception
78
- #The key tag value of the DNSKEY RR that validates this signature
79
- attr_accessor :key_tag
80
- #identifies the owner name of the DNSKEY RR that a validator is
81
- #supposed to use to validate this signature
82
- attr_reader :signers_name
83
-
84
- #contains the cryptographic signature that covers
85
- #the RRSIG RDATA (excluding the Signature field) and the RRset
86
- #specified by the RRSIG owner name, RRSIG class, and RRSIG Type
87
- #Covered field
88
- attr_accessor :signature
89
-
90
- def init_defaults
91
- @algorithm=Algorithms.RSASHA1
92
- @type_covered = Types::A
93
- @original_ttl = 3600
94
- @inception = Time.now.to_i
95
- @expiration = Time.now.to_i
96
- @key_tag = 0
97
- @labels = 0
98
- self.signers_name="."
99
- @signature = "\0"
100
- end
101
-
102
- def algorithm=(a)
103
- if (a.instance_of?String)
104
- if (a.to_i > 0)
105
- a = a.to_i
106
- end
107
- end
108
- begin
109
- alg = Algorithms.new(a)
110
- @algorithm = alg
111
- rescue ArgumentError => e
112
- raise DecodeError.new(e)
113
- end
114
- end
115
-
116
- def type_covered=(t)
117
- begin
118
- type = Types.new(t)
119
- @type_covered = type
120
- rescue ArgumentError => e
121
- raise DecodeError.new(e)
122
- end
123
- end
124
-
125
- def signers_name=(s)
126
- begin
127
- name = Name.create(s)
128
- @signers_name = name
129
- rescue ArgumentError => e
130
- raise DecodeError.new(e)
131
- end
132
- end
133
-
134
-
135
- def from_data(data) #:nodoc: all
136
- type_covered, algorithm, @labels, @original_ttl, expiration, inception,
137
- @key_tag, signers_name, @signature = data
138
- @expiration = expiration
139
- @inception = inception
140
- self.type_covered=(type_covered)
141
- self.signers_name=(signers_name)
142
- self.algorithm=(algorithm)
143
- end
144
-
145
- def from_string(input)
146
- if (input.length > 0)
147
- data = input.split(" ")
148
- self.type_covered=(data[0])
149
- self.algorithm=(data[1])
150
- self.labels=data[2].to_i
151
- self.original_ttl=data[3].to_i
152
- self.expiration=get_time(data[4])
153
- # Brackets may also be present
154
- index = 5
155
- end_index = data.length - 1
156
- if (data[index]=="(")
157
- index = 6
158
- end_index = data.length - 2
159
- end
160
- self.inception=get_time(data[index])
161
- self.key_tag=data[index+1].to_i
162
- self.signers_name=(data[index+2])
163
- # signature can include whitespace - include all text
164
- # until we come to " )" at the end, and then gsub
165
- # the white space out
166
- buf=""
167
- (index+3..end_index).each {|i|
168
- if (comment_index = data[i].index(";"))
169
- buf += data[i].slice(0, comment_index)
170
- # @TODO@ We lose the comments here - we should really keep them for when we write back to string format?
171
- break
172
- else
173
- buf += data[i]
174
- end
175
- }
176
- buf.gsub!(/\n/, "")
177
- buf.gsub!(/ /, "")
178
- #self.signature=Base64.decode64(buf)
179
- self.signature=buf.unpack("m*")[0]
180
- end
181
- end
182
-
183
- def RRSIG.get_time(input)
184
- if (input.kind_of?Fixnum)
185
- return input
186
- end
187
- # RFC 4034, section 3.2
188
- #The Signature Expiration Time and Inception Time field values MUST be
189
- # represented either as an unsigned decimal integer indicating seconds
190
- # since 1 January 1970 00:00:00 UTC, or in the form YYYYMMDDHHmmSS in
191
- # UTC, where:
192
- #
193
- # YYYY is the year (0001-9999, but see Section 3.1.5);
194
- # MM is the month number (01-12);
195
- # DD is the day of the month (01-31);
196
- # HH is the hour, in 24 hour notation (00-23);
197
- # mm is the minute (00-59); and
198
- # SS is the second (00-59).
199
- #
200
- # Note that it is always possible to distinguish between these two
201
- # formats because the YYYYMMDDHHmmSS format will always be exactly 14
202
- # digits, while the decimal representation of a 32-bit unsigned integer
203
- # can never be longer than 10 digits.
204
- if (input.length == 10)
205
- return input.to_i
206
- elsif (input.length == 14)
207
- year = input[0,4]
208
- mon=input[4,2]
209
- day=input[6,2]
210
- hour=input[8,2]
211
- min=input[10,2]
212
- sec=input[12,2]
213
- # @TODO@ REPLACE THIS BY LOCAL CODE - Time.gm DOG SLOW!
214
- return Time.gm(year, mon, day, hour, min, sec).to_i
215
- else
216
- raise DecodeError.new("RRSIG : Illegal time value #{input} - see RFC 4034 section 3.2")
217
- end
218
- end
219
-
220
- def get_time(input)
221
- return RRSIG.get_time(input)
222
- end
223
-
224
- def format_time(time)
225
- return Time.at(time).gmtime.strftime("%Y%m%d%H%M%S")
226
- end
227
-
228
- def rdata_to_string #:nodoc: all
229
- if (@type_covered!=nil)
230
- # signature = Base64.encode64(@signature) # .gsub(/\n/, "")
231
- signature = [@signature].pack("m*").gsub(/\n/, "")
232
- # @TODO@ Display the expiration and inception as
233
- return "#{@type_covered.string} #{@algorithm.string} #{@labels} #{@original_ttl} " +
234
- "#{format_time(@expiration)} ( #{format_time(@inception)} " +
235
- "#{@key_tag} #{@signers_name.to_s(true)} #{signature} )"
236
- else
237
- return ""
238
- end
239
- end
240
-
241
- def encode_rdata(msg, canonical=false) #:nodoc: all
242
- # 2 octets, then 2 sets of 1 octet
243
- msg.put_pack('ncc', @type_covered.to_i, @algorithm.to_i, @labels)
244
- msg.put_pack("NNN", @original_ttl, @expiration, @inception)
245
- msg.put_pack("n", @key_tag)
246
- msg.put_name(@signers_name, canonical, false)
247
- msg.put_bytes(@signature)
248
- end
249
-
250
- def self.decode_rdata(msg) #:nodoc: all
251
- type_covered, algorithm, labels = msg.get_unpack('ncc')
252
- original_ttl, expiration, inception = msg.get_unpack('NNN')
253
- key_tag, = msg.get_unpack('n')
254
- signers_name = msg.get_name
255
- signature = msg.get_bytes
256
- return self.new(
257
- [type_covered, algorithm, labels, original_ttl, expiration,
258
- inception, key_tag, signers_name, signature])
259
- end
260
-
261
- def sig_data
262
- #RRSIG_RDATA is the wire format of the RRSIG RDATA fields
263
- #with the Signer's Name field in canonical form and
264
- #the Signature field excluded;
265
- data = MessageEncoder.new { |msg|
266
- msg.put_pack('ncc', @type_covered.to_i, @algorithm.to_i, @labels)
267
- msg.put_pack("NNN", @original_ttl, @expiration, @inception)
268
- msg.put_pack("n", @key_tag)
269
- msg.put_name(@signers_name, true)
270
- }.to_s
271
- return data
272
- end
273
- end
274
- end
275
- end