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,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
|
-
#
|
127
|
-
#
|
128
|
-
#
|
129
|
-
#
|
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
|
-
#
|
140
|
-
#
|
141
|
-
#
|
142
|
-
#
|
143
|
-
#
|
144
|
-
#
|
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
|
-
#
|
173
|
-
#
|
174
|
-
#
|
175
|
-
#
|
176
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
223
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|