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.
- checksums.yaml +4 -4
- data/README.md +96 -0
- data/Rakefile +30 -29
- data/demo/axfr.rb +93 -93
- data/demo/check_soa.rb +99 -99
- data/demo/check_zone.rb +59 -59
- data/demo/digdlv.rb +43 -43
- data/demo/digroot.rb +34 -34
- data/demo/example_recurse.rb +14 -14
- data/demo/mresolv.rb +30 -30
- data/demo/mx.rb +31 -31
- data/demo/rubydig.rb +37 -37
- data/demo/to_resolve.txt +3088 -3088
- data/demo/trace_dns.rb +46 -46
- data/lib/dnsruby.rb +161 -526
- data/lib/dnsruby/DNS.rb +305 -0
- data/lib/{Dnsruby/Cache.rb → dnsruby/cache.rb} +152 -152
- data/lib/{Dnsruby → dnsruby}/code_mapper.rb +48 -52
- data/lib/dnsruby/code_mappers.rb +295 -0
- data/lib/{Dnsruby/Config.rb → dnsruby/config.rb} +454 -454
- data/lib/{Dnsruby → dnsruby}/dnssec.rb +91 -91
- data/lib/{Dnsruby/Hosts.rb → dnsruby/hosts.rb} +125 -125
- data/lib/{Dnsruby → dnsruby}/ipv4.rb +26 -26
- data/lib/{Dnsruby → dnsruby}/ipv6.rb +42 -42
- data/lib/{Dnsruby → dnsruby}/key_cache.rb +29 -29
- data/lib/dnsruby/message/decoder.rb +164 -0
- data/lib/dnsruby/message/encoder.rb +75 -0
- data/lib/dnsruby/message/header.rb +249 -0
- data/lib/dnsruby/message/message.rb +629 -0
- data/lib/dnsruby/message/question.rb +86 -0
- data/lib/dnsruby/message/section.rb +96 -0
- data/lib/{Dnsruby → dnsruby}/name.rb +141 -141
- data/lib/dnsruby/packet_sender.rb +661 -0
- data/lib/{Dnsruby/Recursor.rb → dnsruby/recursor.rb} +235 -233
- data/lib/dnsruby/resolv.rb +113 -0
- data/lib/dnsruby/resolver.rb +1192 -0
- data/lib/dnsruby/resource/A.rb +56 -0
- data/lib/dnsruby/resource/AAAA.rb +54 -0
- data/lib/{Dnsruby → dnsruby}/resource/AFSDB.rb +68 -68
- data/lib/{Dnsruby → dnsruby}/resource/CERT.rb +105 -105
- data/lib/{Dnsruby → dnsruby}/resource/DHCID.rb +54 -54
- data/lib/dnsruby/resource/DLV.rb +27 -0
- data/lib/{Dnsruby → dnsruby}/resource/DNSKEY.rb +372 -372
- data/lib/{Dnsruby → dnsruby}/resource/DS.rb +255 -255
- data/lib/{Dnsruby → dnsruby}/resource/HINFO.rb +71 -71
- data/lib/{Dnsruby → dnsruby}/resource/HIP.rb +29 -29
- data/lib/{Dnsruby → dnsruby}/resource/IN.rb +30 -30
- data/lib/{Dnsruby → dnsruby}/resource/IPSECKEY.rb +31 -31
- data/lib/{Dnsruby → dnsruby}/resource/ISDN.rb +62 -62
- data/lib/{Dnsruby → dnsruby}/resource/KX.rb +65 -65
- data/lib/{Dnsruby → dnsruby}/resource/LOC.rb +263 -263
- data/lib/{Dnsruby → dnsruby}/resource/MINFO.rb +69 -69
- data/lib/{Dnsruby → dnsruby}/resource/MX.rb +65 -65
- data/lib/{Dnsruby → dnsruby}/resource/NAPTR.rb +98 -98
- data/lib/{Dnsruby → dnsruby}/resource/NSAP.rb +171 -171
- data/lib/dnsruby/resource/NSEC.rb +275 -0
- data/lib/dnsruby/resource/NSEC3.rb +332 -0
- data/lib/dnsruby/resource/NSEC3PARAM.rb +135 -0
- data/lib/dnsruby/resource/OPT.rb +272 -0
- data/lib/{Dnsruby → dnsruby}/resource/PX.rb +70 -70
- data/lib/{Dnsruby → dnsruby}/resource/RP.rb +75 -75
- data/lib/dnsruby/resource/RR.rb +421 -0
- data/lib/dnsruby/resource/RRSIG.rb +275 -0
- data/lib/dnsruby/resource/RRSet.rb +190 -0
- data/lib/{Dnsruby → dnsruby}/resource/RT.rb +67 -67
- data/lib/{Dnsruby → dnsruby}/resource/SOA.rb +94 -94
- data/lib/dnsruby/resource/SPF.rb +29 -0
- data/lib/dnsruby/resource/SRV.rb +112 -0
- data/lib/{Dnsruby → dnsruby}/resource/SSHFP.rb +14 -14
- data/lib/dnsruby/resource/TKEY.rb +163 -0
- data/lib/dnsruby/resource/TSIG.rb +593 -0
- data/lib/{Dnsruby → dnsruby}/resource/TXT.rb +191 -191
- data/lib/dnsruby/resource/X25.rb +55 -0
- data/lib/{Dnsruby → dnsruby}/resource/domain_name.rb +25 -25
- data/lib/{Dnsruby → dnsruby}/resource/generic.rb +80 -80
- data/lib/dnsruby/resource/resource.rb +25 -0
- data/lib/{Dnsruby → dnsruby}/select_thread.rb +148 -148
- data/lib/{Dnsruby/SingleResolver.rb → dnsruby/single_resolver.rb} +60 -60
- data/lib/{Dnsruby → dnsruby}/single_verifier.rb +344 -344
- data/lib/dnsruby/the_log.rb +44 -0
- data/lib/dnsruby/update.rb +278 -0
- data/lib/dnsruby/validator_thread.rb +124 -0
- data/lib/dnsruby/version.rb +3 -0
- data/lib/{Dnsruby → dnsruby}/zone_reader.rb +93 -93
- data/lib/{Dnsruby → dnsruby}/zone_transfer.rb +377 -377
- data/test/spec_helper.rb +16 -0
- data/test/tc_axfr.rb +31 -34
- data/test/tc_cache.rb +32 -32
- data/test/tc_dlv.rb +28 -28
- data/test/tc_dns.rb +73 -76
- data/test/tc_dnskey.rb +31 -32
- data/test/tc_dnsruby.rb +50 -44
- data/test/tc_ds.rb +36 -36
- data/test/tc_escapedchars.rb +252 -255
- data/test/tc_hash.rb +17 -21
- data/test/tc_header.rb +48 -57
- data/test/tc_hip.rb +19 -22
- data/test/tc_ipseckey.rb +18 -21
- data/test/tc_keith.rb +300 -0
- data/test/tc_message.rb +87 -0
- data/test/tc_misc.rb +83 -87
- data/test/tc_name.rb +81 -84
- data/test/tc_naptr.rb +18 -21
- data/test/tc_nsec.rb +55 -55
- data/test/tc_nsec3.rb +23 -24
- data/test/tc_nsec3param.rb +20 -21
- data/test/tc_packet.rb +90 -93
- data/test/tc_packet_unique_push.rb +48 -51
- data/test/tc_question.rb +30 -33
- data/test/tc_queue.rb +16 -17
- data/test/tc_recur.rb +16 -17
- data/test/tc_res_config.rb +38 -41
- data/test/tc_res_env.rb +29 -32
- data/test/tc_res_file.rb +26 -29
- data/test/tc_res_opt.rb +62 -65
- data/test/tc_resolver.rb +287 -242
- data/test/tc_rr-opt.rb +70 -63
- data/test/tc_rr-txt.rb +68 -71
- data/test/tc_rr-unknown.rb +45 -48
- data/test/tc_rr.rb +76 -70
- data/test/tc_rrset.rb +21 -22
- data/test/tc_rrsig.rb +19 -20
- data/test/tc_single_resolver.rb +294 -297
- data/test/tc_soak.rb +199 -202
- data/test/tc_soak_base.rb +29 -34
- data/test/tc_sshfp.rb +20 -23
- data/test/tc_tcp.rb +32 -35
- data/test/tc_tkey.rb +41 -44
- data/test/tc_tsig.rb +81 -84
- data/test/tc_update.rb +108 -111
- data/test/tc_validator.rb +29 -29
- data/test/tc_verifier.rb +81 -82
- data/test/ts_dnsruby.rb +16 -15
- data/test/ts_offline.rb +62 -63
- data/test/ts_online.rb +115 -115
- metadata +155 -90
- data/README +0 -59
- data/lib/Dnsruby/DNS.rb +0 -305
- data/lib/Dnsruby/PacketSender.rb +0 -656
- data/lib/Dnsruby/Resolver.rb +0 -1189
- data/lib/Dnsruby/TheLog.rb +0 -44
- data/lib/Dnsruby/message.rb +0 -1230
- data/lib/Dnsruby/resource/A.rb +0 -56
- data/lib/Dnsruby/resource/AAAA.rb +0 -54
- data/lib/Dnsruby/resource/DLV.rb +0 -27
- data/lib/Dnsruby/resource/NSEC.rb +0 -298
- data/lib/Dnsruby/resource/NSEC3.rb +0 -340
- data/lib/Dnsruby/resource/NSEC3PARAM.rb +0 -135
- data/lib/Dnsruby/resource/OPT.rb +0 -213
- data/lib/Dnsruby/resource/RRSIG.rb +0 -275
- data/lib/Dnsruby/resource/SPF.rb +0 -29
- data/lib/Dnsruby/resource/SRV.rb +0 -112
- data/lib/Dnsruby/resource/TKEY.rb +0 -163
- data/lib/Dnsruby/resource/TSIG.rb +0 -593
- data/lib/Dnsruby/resource/X25.rb +0 -55
- data/lib/Dnsruby/resource/resource.rb +0 -678
- data/lib/Dnsruby/update.rb +0 -278
- 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
|
data/lib/Dnsruby/resource/OPT.rb
DELETED
|
@@ -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
|