dnsruby 1.60.2 → 1.61.1
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/.travis.yml +5 -5
- data/Gemfile +2 -0
- data/README.md +6 -4
- data/RELEASE_NOTES.md +20 -0
- data/demo/digroot.rb +2 -0
- data/dnsruby.gemspec +2 -0
- data/lib/dnsruby/code_mappers.rb +3 -0
- data/lib/dnsruby/config.rb +23 -4
- data/lib/dnsruby/message/encoder.rb +2 -2
- data/lib/dnsruby/message/header.rb +15 -15
- data/lib/dnsruby/name.rb +20 -2
- data/lib/dnsruby/packet_sender.rb +13 -1
- data/lib/dnsruby/recursor.rb +10 -1
- data/lib/dnsruby/resolver.rb +11 -0
- data/lib/dnsruby/resource/CDNSKEY.rb +17 -0
- data/lib/dnsruby/resource/CDS.rb +35 -0
- data/lib/dnsruby/resource/DNSKEY.rb +15 -6
- data/lib/dnsruby/resource/IN.rb +4 -1
- data/lib/dnsruby/resource/URI.rb +57 -0
- data/lib/dnsruby/resource/generic.rb +3 -0
- data/lib/dnsruby/select_thread.rb +1 -1
- data/lib/dnsruby/single_verifier.rb +14 -4
- data/lib/dnsruby/version.rb +1 -1
- data/lib/dnsruby/zone_transfer.rb +5 -1
- data/test/tc_dns.rb +5 -0
- data/test/tc_resolver.rb +26 -0
- data/test/tc_rr.rb +33 -0
- data/test/tc_soak.rb +4 -0
- data/test/tc_tcp_pipelining.rb +7 -0
- metadata +19 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 809b0ba42057c7e1dbec1239f295b2766b345c08
|
4
|
+
data.tar.gz: fdcd08cf292f773ac6e1423acdbee6d810ffd1c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ec0a38bb9fb0c517736727579606fa82bf04d03b81a918a19e1f660da746e6333c136f7fd9bb51f804d84d4132a6f9ea73a7dab7e3b2235b3c0aa4562efe4fa4
|
7
|
+
data.tar.gz: 2445c9aa9154a253a9c32c300d11b4166eaa2366be18dc8d6732f6ac3b4df5a5e64afa724ca59155ab8b425023239ac86ab309042b19b6d84d0cdd4a4508bdd1
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
[](https://travis-ci.org/alexdalitz/dnsruby)
|
2
2
|
[](https://coveralls.io/r/alexdalitz/dnsruby?branch=master)
|
3
3
|
|
4
|
+
<img src="http://caerkettontech.com/dnsruby/DNSRuby-colour-mid.png" width="200" height="200" />
|
5
|
+
|
4
6
|
Dnsruby
|
5
7
|
=======
|
6
8
|
|
@@ -16,10 +18,10 @@ queries. It is therefore suitable for high volume DNS applications.
|
|
16
18
|
|
17
19
|
The following is a (non-exhaustive) list of features :
|
18
20
|
|
19
|
-
- Implemented RRs : A, AAAA, AFSDB, ANY, CERT, CNAME, DNAME,
|
20
|
-
HINFO, ISDN, LOC, MB, MG, MINFO, MR, MX, NAPTR, NS, NSAP,
|
21
|
-
OPT, PTR, PX, RP, RT, SOA, SPF, SRV, TKEY, TSIG, TXT,
|
22
|
-
X25, DNSKEY, RRSIG, NSEC, NSEC3, NSEC3PARAM, DS, DLV
|
21
|
+
- Implemented RRs : A, AAAA, AFSDB, ANY, CAA, CERT, CNAME, DNAME,
|
22
|
+
GPOS, HINFO, ISDN, LOC, MB, MG, MINFO, MR, MX, NAPTR, NS, NSAP,
|
23
|
+
NXT, OPT, PTR, PX, RP, RT, SOA, SPF, SRV, TKEY, TSIG, TXT,
|
24
|
+
WKS, X25, DNSKEY, RRSIG, NSEC, NSEC3, NSEC3PARAM, DS, DLV
|
23
25
|
|
24
26
|
- Generic RR types supported (RFC3597)
|
25
27
|
|
data/RELEASE_NOTES.md
CHANGED
@@ -1,5 +1,25 @@
|
|
1
1
|
# Release Notes
|
2
2
|
|
3
|
+
## v1.61.1
|
4
|
+
|
5
|
+
* Add Addressable as a gem runtime dependency
|
6
|
+
|
7
|
+
## v1.61.0
|
8
|
+
|
9
|
+
* Add URI, CDS and CDNSKEY records
|
10
|
+
* Supply port to DNS.new as optiona parameter
|
11
|
+
* Supply timeout to zone transfer connect
|
12
|
+
* Fix multi-line strings
|
13
|
+
* Try absolute name as candidate in DNS even if not dot supplied
|
14
|
+
* Do not try to generate candidates if no domain is given
|
15
|
+
* Handle new OpenSSL interface as well as old
|
16
|
+
* Handle new DSA interface
|
17
|
+
* fix encode error select thread issue
|
18
|
+
* handle encoding errors
|
19
|
+
* add punycode support
|
20
|
+
* Make sure dnssec is enabled in verifier and also in digroot demo
|
21
|
+
* Other minor fixes and changes to test code and infrastructure
|
22
|
+
|
3
23
|
## v1.60.2
|
4
24
|
|
5
25
|
* Fix deletion of TXT records with spaces in dynamic updates (thanks Sean Dilda)
|
data/demo/digroot.rb
CHANGED
data/dnsruby.gemspec
CHANGED
data/lib/dnsruby/code_mappers.rb
CHANGED
@@ -162,6 +162,8 @@ module Dnsruby
|
|
162
162
|
NSEC3PARAM= 51 # RFC still pending at time of writing
|
163
163
|
TLSA = 52 # RFC 6698
|
164
164
|
HIP = 55 # RFC 5205
|
165
|
+
CDS = 59 # RFC 7344
|
166
|
+
CDNSKEY = 60 # RFC 7344
|
165
167
|
SPF = 99 # RFC 4408
|
166
168
|
UINFO = 100 # non-standard
|
167
169
|
UID = 101 # non-standard
|
@@ -174,6 +176,7 @@ module Dnsruby
|
|
174
176
|
MAILB = 253 # RFC 1035 (MB, MG, MR)
|
175
177
|
MAILA = 254 # RFC 1035 (obsolete - see MX)
|
176
178
|
ANY = 255 # RFC 1035
|
179
|
+
URI = 256 # RFC 7553
|
177
180
|
CAA = 257 # RFC 6844
|
178
181
|
DLV = 32769 # RFC 4431 (informational)
|
179
182
|
update()
|
data/lib/dnsruby/config.rb
CHANGED
@@ -101,6 +101,7 @@ module Dnsruby
|
|
101
101
|
dom=""
|
102
102
|
nd = 1
|
103
103
|
@ndots = 1
|
104
|
+
@port = 53
|
104
105
|
@apply_search_list = true
|
105
106
|
@apply_domain = true
|
106
107
|
config_hash = Config.default_config_hash
|
@@ -122,6 +123,7 @@ module Dnsruby
|
|
122
123
|
ns = config_hash[:nameserver] if config_hash.include? :nameserver
|
123
124
|
s = config_hash[:search] if config_hash.include? :search
|
124
125
|
nd = config_hash[:ndots] if config_hash.include? :ndots
|
126
|
+
p = config_hash[:port] if config_hash.include? :port
|
125
127
|
@apply_search_list = config_hash[:apply_search_list] if config_hash.include? :apply_search_list
|
126
128
|
@apply_domain= config_hash[:apply_domain] if config_hash.include? :apply_domain
|
127
129
|
dom = config_hash[:domain] if config_hash.include? :domain
|
@@ -132,6 +134,7 @@ module Dnsruby
|
|
132
134
|
@configured = true
|
133
135
|
send("search=",s)
|
134
136
|
send("ndots=",nd)
|
137
|
+
send("port=",p)
|
135
138
|
send("domain=",dom)
|
136
139
|
}
|
137
140
|
Dnsruby.log.info{to_s}
|
@@ -159,6 +162,15 @@ module Dnsruby
|
|
159
162
|
end
|
160
163
|
end
|
161
164
|
|
165
|
+
# Set port
|
166
|
+
def port=(p)
|
167
|
+
@configured = true
|
168
|
+
@port=p
|
169
|
+
if !@port.kind_of?(Integer)
|
170
|
+
raise ArgumentError.new("invalid port config: #{@port.inspect}")
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
162
174
|
# Set the default search path
|
163
175
|
def search=(s)
|
164
176
|
@configured = true
|
@@ -303,6 +315,7 @@ module Dnsruby
|
|
303
315
|
search = nil
|
304
316
|
domain = nil
|
305
317
|
ndots = 1
|
318
|
+
port = 53
|
306
319
|
open(filename) {|f|
|
307
320
|
f.each {|line|
|
308
321
|
line.sub!(/[#;].*/, '')
|
@@ -312,6 +325,8 @@ module Dnsruby
|
|
312
325
|
}
|
313
326
|
next unless keyword
|
314
327
|
case keyword
|
328
|
+
when 'port'
|
329
|
+
port = args[0].to_i
|
315
330
|
when 'nameserver'
|
316
331
|
nameserver += args
|
317
332
|
when 'domain'
|
@@ -337,7 +352,7 @@ module Dnsruby
|
|
337
352
|
end
|
338
353
|
}
|
339
354
|
}
|
340
|
-
return { :nameserver => nameserver, :domain => domain, :search => search, :ndots => ndots }
|
355
|
+
return { :nameserver => nameserver, :domain => domain, :search => search, :ndots => ndots, :port => port }
|
341
356
|
end
|
342
357
|
|
343
358
|
def inspect #:nodoc: all
|
@@ -357,6 +372,7 @@ module Dnsruby
|
|
357
372
|
ret += " domain : #{domain_string}, search : "
|
358
373
|
search.each {|s| ret += s + ", " }
|
359
374
|
ret += " ndots : #{@ndots}"
|
375
|
+
ret += " port : #{@port}"
|
360
376
|
return ret
|
361
377
|
end
|
362
378
|
|
@@ -423,18 +439,21 @@ module Dnsruby
|
|
423
439
|
end
|
424
440
|
end
|
425
441
|
|
426
|
-
def generate_candidates(
|
442
|
+
def generate_candidates(name_in) #:nodoc: all
|
427
443
|
if !@configured
|
428
444
|
parse_config
|
429
445
|
end
|
430
446
|
candidates = []
|
431
|
-
name = Name.create(
|
447
|
+
name = Name.create(name_in)
|
432
448
|
if name.absolute?
|
433
449
|
candidates = [name]
|
434
450
|
else
|
451
|
+
candidates.push(Name.create(name_in.to_s + "."))
|
435
452
|
if (@apply_domain)
|
436
453
|
if @ndots > name.length - 1
|
437
|
-
|
454
|
+
if (@domain != nil)
|
455
|
+
candidates.push(Name.create(name.to_a+@domain))
|
456
|
+
end
|
438
457
|
end
|
439
458
|
end
|
440
459
|
if (!@apply_search_list)
|
@@ -18,7 +18,7 @@ class MessageEncoder #:nodoc: all
|
|
18
18
|
begin
|
19
19
|
@data << d.pack(template)
|
20
20
|
rescue Encoding::CompatibilityError => e
|
21
|
-
raise Dnsruby::
|
21
|
+
raise Dnsruby::EncodeError.new("IDN support currently requires punycode string")
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
@@ -36,7 +36,7 @@ class MessageEncoder #:nodoc: all
|
|
36
36
|
self.put_pack("C", d.length)
|
37
37
|
@data << d
|
38
38
|
rescue Encoding::CompatibilityError => e
|
39
|
-
raise Dnsruby::
|
39
|
+
raise Dnsruby::EncodeError.new("IDN support currently requires punycode string")
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
@@ -190,29 +190,29 @@ class Header
|
|
190
190
|
retval = ";; id = #{@id}\n"
|
191
191
|
|
192
192
|
if (@opcode == OpCode::Update)
|
193
|
-
retval += ";; qr = #{@qr} "
|
194
|
-
"opcode = #{@opcode.string} "
|
193
|
+
retval += ";; qr = #{@qr} " \
|
194
|
+
"opcode = #{@opcode.string} "\
|
195
195
|
"rcode = #{@rcode.string}\n"
|
196
196
|
|
197
|
-
retval += ";; zocount = #{@qdcount} "
|
198
|
-
"prcount = #{@ancount} "
|
199
|
-
"upcount = #{@nscount} "
|
197
|
+
retval += ";; zocount = #{@qdcount} "\
|
198
|
+
"prcount = #{@ancount} " \
|
199
|
+
"upcount = #{@nscount} " \
|
200
200
|
"adcount = #{@arcount}\n"
|
201
201
|
else
|
202
|
-
retval += ";; qr = #{@qr} "
|
203
|
-
"opcode = #{@opcode.string} "
|
204
|
-
"aa = #{@aa} "
|
205
|
-
"tc = #{@tc} "
|
202
|
+
retval += ";; qr = #{@qr} " \
|
203
|
+
"opcode = #{@opcode.string} " \
|
204
|
+
"aa = #{@aa} " \
|
205
|
+
"tc = #{@tc} " \
|
206
206
|
"rd = #{@rd}\n"
|
207
207
|
|
208
|
-
retval += ";; ra = #{@ra} "
|
209
|
-
"ad = #{@ad} "
|
210
|
-
"cd = #{@cd} "
|
208
|
+
retval += ";; ra = #{@ra} " \
|
209
|
+
"ad = #{@ad} " \
|
210
|
+
"cd = #{@cd} " \
|
211
211
|
"rcode = #{rcode.string}\n"
|
212
212
|
|
213
|
-
retval += ";; qdcount = #{@qdcount} "
|
214
|
-
"ancount = #{@ancount} "
|
215
|
-
"nscount = #{@nscount} "
|
213
|
+
retval += ";; qdcount = #{@qdcount} " \
|
214
|
+
"ancount = #{@ancount} " \
|
215
|
+
"nscount = #{@nscount} " \
|
216
216
|
"arcount = #{@arcount}\n"
|
217
217
|
end
|
218
218
|
|
data/lib/dnsruby/name.rb
CHANGED
@@ -26,7 +26,8 @@ module Dnsruby
|
|
26
26
|
# * Name#wild?
|
27
27
|
# * Name#subdomain_of?(other)
|
28
28
|
# * Name#labels
|
29
|
-
#
|
29
|
+
#
|
30
|
+
require 'addressable'
|
30
31
|
class Name
|
31
32
|
include Comparable
|
32
33
|
MaxNameLength=255
|
@@ -52,6 +53,7 @@ module Dnsruby
|
|
52
53
|
if (arg=="")
|
53
54
|
return Name.new([],false)
|
54
55
|
end
|
56
|
+
arg = punycode(arg)
|
55
57
|
return Name.new(split_escaped(arg), /\.\z/ =~ arg ? true : false)
|
56
58
|
# return Name.new(Label.split(arg), /\.\z/ =~ arg ? true : false)
|
57
59
|
when Array
|
@@ -61,6 +63,22 @@ module Dnsruby
|
|
61
63
|
end
|
62
64
|
end
|
63
65
|
|
66
|
+
def self.punycode(d)
|
67
|
+
begin
|
68
|
+
c = Addressable::URI.parse("http://" + d.to_s)
|
69
|
+
ret = c.normalized_host.sub("http://", "")
|
70
|
+
if (!d.end_with?".")
|
71
|
+
return ret.chomp(".")
|
72
|
+
end
|
73
|
+
if (!ret.end_with?".")
|
74
|
+
return ret + "."
|
75
|
+
end
|
76
|
+
return ret
|
77
|
+
rescue Exception => e
|
78
|
+
return d
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
64
82
|
def self.split_escaped(arg) #:nodoc: all
|
65
83
|
encodedlabels = name2encodedlabels(arg)
|
66
84
|
return encodedlabels
|
@@ -317,7 +335,7 @@ module Dnsruby
|
|
317
335
|
i=0;
|
318
336
|
|
319
337
|
while (i < length )
|
320
|
-
c=presentation.unpack("x#{i}C1")
|
338
|
+
c=presentation.unpack("x#{i}C1")[0]
|
321
339
|
if (c == 46) # ord('.')
|
322
340
|
endstring = presentation[i+1, presentation.length-(i+1)]
|
323
341
|
return Label.new(wire),endstring
|
@@ -331,7 +331,14 @@ module Dnsruby
|
|
331
331
|
client_query_id = Time.now + rand(10000) # is this safe?!
|
332
332
|
end
|
333
333
|
|
334
|
-
|
334
|
+
begin
|
335
|
+
query_packet = make_query_packet(msg, use_tcp)
|
336
|
+
rescue EncodeError => err
|
337
|
+
Dnsruby.log.error { "#{err}" }
|
338
|
+
st = SelectThread.instance
|
339
|
+
st.push_exception_to_select(client_query_id, client_queue, err, nil)
|
340
|
+
return
|
341
|
+
end
|
335
342
|
|
336
343
|
if (msg.do_caching && (msg.class != Update))
|
337
344
|
# Check the cache!!
|
@@ -622,6 +629,11 @@ module Dnsruby
|
|
622
629
|
# Should send error back up to Resolver here, and then NOT QUERY AGAIN!!!
|
623
630
|
return sig_value
|
624
631
|
end
|
632
|
+
if ((response.header.get_header_rcode == RCode.FORMERR) &&
|
633
|
+
(query.header.arcount == 0))
|
634
|
+
# Raise an error
|
635
|
+
return true
|
636
|
+
end
|
625
637
|
# Should check that question section is same as question that was sent! RFC 5452
|
626
638
|
# If it's not an update...
|
627
639
|
if (query.class == Update)
|
data/lib/dnsruby/recursor.rb
CHANGED
@@ -153,7 +153,7 @@ module Dnsruby
|
|
153
153
|
end
|
154
154
|
end
|
155
155
|
attr_accessor :nameservers, :callback, :recurse, :ipv6_ok
|
156
|
-
attr_reader :hints
|
156
|
+
attr_reader :hints, :dnssec
|
157
157
|
# The resolver to use for the queries
|
158
158
|
attr_accessor :resolver
|
159
159
|
|
@@ -164,6 +164,11 @@ module Dnsruby
|
|
164
164
|
@@zones_cache = nil
|
165
165
|
@@nameservers = nil
|
166
166
|
|
167
|
+
def dnssec=(dnssec_on)
|
168
|
+
@dnssec = dnssec_on
|
169
|
+
@resolver.dnssec = dnssec_on
|
170
|
+
end
|
171
|
+
|
167
172
|
def initialize(res = nil)
|
168
173
|
if (res)
|
169
174
|
@resolver = res
|
@@ -174,6 +179,7 @@ module Dnsruby
|
|
174
179
|
@resolver = Resolver.new
|
175
180
|
end
|
176
181
|
end
|
182
|
+
@resolver.dnssec = @dnssec
|
177
183
|
@ipv6_ok = false
|
178
184
|
end
|
179
185
|
# Initialize the hint servers. Recursive queries need a starting name
|
@@ -196,6 +202,7 @@ module Dnsruby
|
|
196
202
|
@resolver = resolver
|
197
203
|
if (resolver.single_resolvers.length == 0)
|
198
204
|
resolver = Resolver.new()
|
205
|
+
resolver.dnssec = @dnssec
|
199
206
|
end
|
200
207
|
if (hints && hints.length > 0)
|
201
208
|
resolver.nameservers=hints
|
@@ -372,6 +379,7 @@ module Dnsruby
|
|
372
379
|
end
|
373
380
|
|
374
381
|
def Recursor.clear_caches(resolver = Resolver.new)
|
382
|
+
resolver.dnssec = @dnssec
|
375
383
|
Recursor.set_hints(Hash.new, resolver)
|
376
384
|
@@zones_cache = Hash.new # key zone_name, values Hash of servers and AddressCaches
|
377
385
|
@@zones_cache["."] = @@hints
|
@@ -613,6 +621,7 @@ module Dnsruby
|
|
613
621
|
}
|
614
622
|
end
|
615
623
|
resolver = Resolver.new({:nameserver=>nameservers})
|
624
|
+
resolver.dnssec = @dnssec
|
616
625
|
servers = []
|
617
626
|
resolver.single_resolvers.each {|s|
|
618
627
|
servers.push(s.server)
|
data/lib/dnsruby/resolver.rb
CHANGED
@@ -891,6 +891,14 @@ module Dnsruby
|
|
891
891
|
return
|
892
892
|
end
|
893
893
|
|
894
|
+
begin
|
895
|
+
msg.encode
|
896
|
+
rescue EncodeError => err
|
897
|
+
Dnsruby.log.error { "Can't encode " + msg.to_s + " : #{err}" }
|
898
|
+
client_queue.push([client_query_id, err])
|
899
|
+
return
|
900
|
+
end
|
901
|
+
|
894
902
|
tick_needed = false
|
895
903
|
# add to our data structures
|
896
904
|
# @mutex.synchronize{
|
@@ -1124,6 +1132,9 @@ module Dnsruby
|
|
1124
1132
|
increment_resolver_priority(resolver) unless response.cached
|
1125
1133
|
stop_querying(client_query_id)
|
1126
1134
|
# @TODO@ Does the client want notified at this point?
|
1135
|
+
elsif error.kind_of?(EncodeError)
|
1136
|
+
Dnsruby.log.debug{'Encode error - sending to client'}
|
1137
|
+
send_result_and_stop_querying(client_queue, client_query_id, select_queue, response, error)
|
1127
1138
|
else
|
1128
1139
|
# - if it was any other error, then remove that server from the list for that query
|
1129
1140
|
# If a Too Many Open Files error, then don't remove, but let retry work.
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Dnsruby
|
2
|
+
class RR
|
3
|
+
# RFC4034, section 2
|
4
|
+
# DNSSEC uses public key cryptography to sign and authenticate DNS
|
5
|
+
# resource record sets (RRsets). The public keys are stored in DNSKEY
|
6
|
+
# resource records and are used in the DNSSEC authentication process
|
7
|
+
# described in [RFC4035]: A zone signs its authoritative RRsets by
|
8
|
+
# using a private key and stores the corresponding public key in a
|
9
|
+
# DNSKEY RR. A resolver can then use the public key to validate
|
10
|
+
# signatures covering the RRsets in the zone, and thus to authenticate
|
11
|
+
# them.
|
12
|
+
class CDNSKEY < DNSKEY
|
13
|
+
ClassValue = nil #:nodoc: all
|
14
|
+
TypeValue = Types::CDNSKEY #:nodoc: all
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# --
|
2
|
+
# Copyright 2018 Caerketton Tech Ltd
|
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 4
|
19
|
+
# The DS Resource Record refers to a DNSKEY RR and is used in the DNS
|
20
|
+
# DNSKEY authentication process. A DS RR refers to a DNSKEY RR by
|
21
|
+
# storing the key tag, algorithm number, and a digest of the DNSKEY RR.
|
22
|
+
# Note that while the digest should be sufficient to identify the
|
23
|
+
# public key, storing the key tag and key algorithm helps make the
|
24
|
+
# identification process more efficient. By authenticating the DS
|
25
|
+
# record, a resolver can authenticate the DNSKEY RR to which the DS
|
26
|
+
# record points. The key authentication process is described in
|
27
|
+
# [RFC4035].
|
28
|
+
|
29
|
+
class CDS < DS
|
30
|
+
|
31
|
+
ClassValue = nil #:nodoc: all
|
32
|
+
TypeValue = Types::CDS #:nodoc: all
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -340,8 +340,12 @@ module Dnsruby
|
|
340
340
|
@key_length = (@key.length - pos) * 8
|
341
341
|
|
342
342
|
pkey = OpenSSL::PKey::RSA.new
|
343
|
-
|
344
|
-
|
343
|
+
begin
|
344
|
+
pkey.set_key(modulus, exponent, nil) # use set_key, present in later versions of openssl gem
|
345
|
+
rescue NoMethodError
|
346
|
+
pkey.e = exponent # set_key not available in earlier versions, use this approach instead
|
347
|
+
pkey.n = modulus
|
348
|
+
end
|
345
349
|
return pkey
|
346
350
|
end
|
347
351
|
|
@@ -361,10 +365,15 @@ module Dnsruby
|
|
361
365
|
@key_length = (pgy_len * 8)
|
362
366
|
|
363
367
|
pkey = OpenSSL::PKey::DSA.new
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
+
begin
|
369
|
+
pkey.set_pgq(p,g,q)
|
370
|
+
pkey.set_key(y, nil) # use set_pgq and set_key, present in later versions of openssl gem
|
371
|
+
rescue NoMethodError
|
372
|
+
pkey.p = p # set_key not available in earlier versions, use this approach instead
|
373
|
+
pkey.q = q
|
374
|
+
pkey.g = g
|
375
|
+
pkey.pub_key = y
|
376
|
+
end
|
368
377
|
|
369
378
|
pkey
|
370
379
|
end
|
data/lib/dnsruby/resource/IN.rb
CHANGED
@@ -19,7 +19,11 @@ module Dnsruby
|
|
19
19
|
Types::NS => NS,
|
20
20
|
Types::CNAME => CNAME,
|
21
21
|
Types::DNAME => DNAME,
|
22
|
+
Types::URI => URI,
|
23
|
+
Types::DS => DS,
|
24
|
+
Types::CDS => CDS,
|
22
25
|
Types::DNSKEY => DNSKEY,
|
26
|
+
Types::CDNSKEY => CDNSKEY,
|
23
27
|
Types::SOA => SOA,
|
24
28
|
Types::PTR => PTR,
|
25
29
|
Types::HINFO => HINFO,
|
@@ -45,7 +49,6 @@ module Dnsruby
|
|
45
49
|
Types::ANY => ANY,
|
46
50
|
Types::RRSIG => RRSIG,
|
47
51
|
Types::NSEC => NSEC,
|
48
|
-
Types::DS => DS,
|
49
52
|
Types::NSEC3 => NSEC3,
|
50
53
|
Types::NSEC3PARAM => NSEC3PARAM,
|
51
54
|
Types::DLV => DLV,
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Dnsruby
|
2
|
+
class RR
|
3
|
+
class URI < RR
|
4
|
+
ClassValue = nil #:nodoc: all
|
5
|
+
TypeValue= Types::URI #:nodoc: all
|
6
|
+
|
7
|
+
# The NAPTR RR order field
|
8
|
+
attr_accessor :priority
|
9
|
+
|
10
|
+
# The NAPTR RR order field
|
11
|
+
attr_accessor :weight
|
12
|
+
|
13
|
+
# The NAPTR RR order field
|
14
|
+
attr_accessor :target
|
15
|
+
|
16
|
+
def from_hash(hash) #:nodoc: all
|
17
|
+
@priority = hash[:priority]
|
18
|
+
@weight = hash[:weight]
|
19
|
+
@target = hash[:target]
|
20
|
+
end
|
21
|
+
|
22
|
+
def from_data(data) #:nodoc: all
|
23
|
+
@priority, @weight, @target = data
|
24
|
+
end
|
25
|
+
|
26
|
+
def from_string(input) #:nodoc: all
|
27
|
+
if (input.strip.length > 0)
|
28
|
+
values = input.split(" ")
|
29
|
+
@priority = values [0].to_i
|
30
|
+
@weight = values [1].to_i
|
31
|
+
@target = values [2].gsub!("\"", "")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def rdata_to_string #:nodoc: all
|
36
|
+
"#{@priority} #{@weight} \"#{@target}\""
|
37
|
+
end
|
38
|
+
|
39
|
+
def encode_rdata(msg, canonical=false) #:nodoc: all
|
40
|
+
if (@priority != nil)
|
41
|
+
msg.put_pack('n', @priority)
|
42
|
+
msg.put_pack('n', @weight)
|
43
|
+
msg.put_bytes(@target)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.decode_rdata(msg) #:nodoc: all
|
48
|
+
priority, = msg.get_unpack('n')
|
49
|
+
weight, = msg.get_unpack('n')
|
50
|
+
target = msg.get_bytes
|
51
|
+
return self.new([priority, weight, target])
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -152,9 +152,12 @@ require 'dnsruby/resource/OPT'
|
|
152
152
|
require 'dnsruby/resource/TSIG'
|
153
153
|
require 'dnsruby/resource/TKEY'
|
154
154
|
require 'dnsruby/resource/DNSKEY'
|
155
|
+
require 'dnsruby/resource/CDNSKEY'
|
155
156
|
require 'dnsruby/resource/RRSIG'
|
156
157
|
require 'dnsruby/resource/NSEC'
|
157
158
|
require 'dnsruby/resource/DS'
|
159
|
+
require 'dnsruby/resource/CDS'
|
160
|
+
require 'dnsruby/resource/URI'
|
158
161
|
require 'dnsruby/resource/NSEC3'
|
159
162
|
require 'dnsruby/resource/NSEC3PARAM'
|
160
163
|
require 'dnsruby/resource/DLV'
|
@@ -194,7 +194,7 @@ module Dnsruby
|
|
194
194
|
rescue SelectWakeup
|
195
195
|
# If SelectWakeup, then just restart this loop - the select call will be made with the new data
|
196
196
|
next
|
197
|
-
rescue IOError => e
|
197
|
+
rescue IOError, EncodeError => e
|
198
198
|
# print "IO Error =: #{e}\n"
|
199
199
|
exceptions = clean_up_closed_sockets
|
200
200
|
exceptions.each { |exception| send_exception_to_client(*exception) }
|
@@ -65,6 +65,7 @@ module Dnsruby
|
|
65
65
|
@@recursor = Recursor.new
|
66
66
|
end
|
67
67
|
end
|
68
|
+
@@recursor.dnssec = true
|
68
69
|
return @@recursor
|
69
70
|
end
|
70
71
|
|
@@ -72,12 +73,15 @@ module Dnsruby
|
|
72
73
|
# if (Dnssec.do_validation_with_recursor?)
|
73
74
|
# return Recursor.new
|
74
75
|
# else
|
76
|
+
resolver = nil
|
75
77
|
if (Dnssec.default_resolver)
|
76
|
-
|
78
|
+
resolver = Dnssec.default_resolver
|
77
79
|
else
|
78
|
-
|
80
|
+
resolver = Resolver.new
|
79
81
|
end
|
80
82
|
# end
|
83
|
+
resolver.dnssec = true
|
84
|
+
return resolver
|
81
85
|
end
|
82
86
|
def add_dlv_key(key)
|
83
87
|
# Is this a ZSK or a KSK?
|
@@ -848,6 +852,7 @@ module Dnsruby
|
|
848
852
|
end
|
849
853
|
end
|
850
854
|
end
|
855
|
+
res.dnssec = true
|
851
856
|
# query = Message.new(name, Types.DNSKEY)
|
852
857
|
# query.do_validation = false
|
853
858
|
ret = nil
|
@@ -1011,6 +1016,7 @@ module Dnsruby
|
|
1011
1016
|
end
|
1012
1017
|
end
|
1013
1018
|
end
|
1019
|
+
parent_res.dnssec = true
|
1014
1020
|
end
|
1015
1021
|
# Use that Resolver to query for DS record and NS for children
|
1016
1022
|
ds_rrset = current_anchor
|
@@ -1068,6 +1074,7 @@ module Dnsruby
|
|
1068
1074
|
child_res = Resolver.new
|
1069
1075
|
end
|
1070
1076
|
end
|
1077
|
+
child_res.dnssec = true
|
1071
1078
|
end
|
1072
1079
|
end
|
1073
1080
|
# Query for DNSKEY record, and verify against DS in parent.
|
@@ -1143,11 +1150,14 @@ module Dnsruby
|
|
1143
1150
|
if (Dnssec.do_validation_with_recursor?)
|
1144
1151
|
return get_recursor
|
1145
1152
|
else
|
1153
|
+
resolver = nil
|
1146
1154
|
if (Dnssec.default_resolver)
|
1147
|
-
|
1155
|
+
resolver = Dnssec.default_resolver
|
1148
1156
|
else
|
1149
|
-
|
1157
|
+
resolver = Resolver.new
|
1150
1158
|
end
|
1159
|
+
resolver.dnssec = true
|
1160
|
+
return resolver
|
1151
1161
|
end
|
1152
1162
|
end
|
1153
1163
|
|
data/lib/dnsruby/version.rb
CHANGED
@@ -33,6 +33,8 @@ module Dnsruby
|
|
33
33
|
attr_reader :tsig
|
34
34
|
# Returns the tsigstate of the last transfer (nil if no TSIG signed transfer has occurred)
|
35
35
|
attr_reader :last_tsigstate
|
36
|
+
# Sets the connect timeout in seconds
|
37
|
+
attr_accessor :connect_timeout
|
36
38
|
|
37
39
|
# Sets the TSIG to sign the zone transfer with.
|
38
40
|
# Pass in either a Dnsruby::RR::TSIG, or a key_name and key (or just a key)
|
@@ -54,6 +56,7 @@ module Dnsruby
|
|
54
56
|
@tsig = nil
|
55
57
|
@axfr = nil
|
56
58
|
@src_address = nil
|
59
|
+
@connect_timeout = 5
|
57
60
|
end
|
58
61
|
|
59
62
|
# Perform a zone transfer (RFC1995)
|
@@ -107,7 +110,8 @@ module Dnsruby
|
|
107
110
|
def do_transfer(zone, server) #:nodoc: all
|
108
111
|
@transfer_type = Types.new(@transfer_type)
|
109
112
|
@state = :InitialSoa
|
110
|
-
socket =
|
113
|
+
socket = Socket.tcp(server, @port, @src_address, connect_timeout: @connect_timeout)
|
114
|
+
# socket = TCPSocket.new(server, @port, @src_address)
|
111
115
|
begin
|
112
116
|
# Send an initial query
|
113
117
|
msg = Message.new(zone, @transfer_type, @klass)
|
data/test/tc_dns.rb
CHANGED
@@ -248,5 +248,10 @@ class TestDNS < Minitest::Test
|
|
248
248
|
# assert_equal(a[0].name.to_s, 'a.t.dnsruby.validation-test-servers.nominet.org.uk',"Correct name (with persistent socket and #{method})")
|
249
249
|
end
|
250
250
|
|
251
|
+
def test_port
|
252
|
+
d = DNS.new({:port => 5353})
|
253
|
+
assert_true(d.to_s.include?"5353")
|
254
|
+
end
|
255
|
+
|
251
256
|
end
|
252
257
|
end
|
data/test/tc_resolver.rb
CHANGED
@@ -374,5 +374,31 @@ class TestRawQuery < Minitest::Test
|
|
374
374
|
assert_equal KEY, options[:key]
|
375
375
|
assert_equal ALGO, options[:algorithm]
|
376
376
|
end
|
377
|
+
|
378
|
+
def test_threads
|
379
|
+
resolver = Dnsruby::Resolver.new(nameserver: ["8.8.8.8", "8.8.4.4"])
|
380
|
+
resolver.query("google.com", "MX")
|
381
|
+
resolver.query("google.com", "MX")
|
382
|
+
resolver.query("google.com", "MX")
|
383
|
+
begin
|
384
|
+
resolver.query("googlöe.com", "MX")
|
385
|
+
rescue Dnsruby::ResolvError => e
|
386
|
+
# fine
|
387
|
+
end
|
388
|
+
resolver.query("google.com", "MX")
|
389
|
+
resolver.query("google.com", "MX")
|
390
|
+
begin
|
391
|
+
resolver.query("googlöe.com", "MX")
|
392
|
+
rescue Dnsruby::ResolvError => e
|
393
|
+
# fine
|
394
|
+
end
|
395
|
+
begin
|
396
|
+
resolver.query("googlöe.com", "MX")
|
397
|
+
rescue Dnsruby::ResolvError => e
|
398
|
+
# fine
|
399
|
+
end
|
400
|
+
# Dnsruby::Cache.delete("googlöe.com", "MX")
|
401
|
+
|
402
|
+
end
|
377
403
|
end
|
378
404
|
|
data/test/tc_rr.rb
CHANGED
@@ -285,6 +285,39 @@ class TestRR < Minitest::Test
|
|
285
285
|
update.encode
|
286
286
|
end
|
287
287
|
|
288
|
+
def test_uri
|
289
|
+
rrString = "_ftp._tcp.\t300\tIN\tURI\t10\ 1 \"ftp://ftp1.example.com/public\""
|
290
|
+
rr = RR.create(rrString)
|
291
|
+
assert(rrString.to_s == rr.to_s)
|
292
|
+
m = Dnsruby::Message.new
|
293
|
+
m.add_additional(rr)
|
294
|
+
m2 = Message.decode(m.encode)
|
295
|
+
rr2 = m2.additional()[0]
|
296
|
+
assert(rr == rr2)
|
297
|
+
end
|
298
|
+
|
299
|
+
def test_cds
|
300
|
+
rrString = "dskey.example.com.\t86400\tIN\tCDS\t60485 RSASHA1 1 ( 2BB183AF5F22588179A53B0A98631FAD1A292118 )"
|
301
|
+
rr = RR.create(rrString)
|
302
|
+
assert(rrString.to_s == rr.to_s)
|
303
|
+
m = Dnsruby::Message.new
|
304
|
+
m.add_additional(rr)
|
305
|
+
m2 = Message.decode(m.encode)
|
306
|
+
rr2 = m2.additional()[0]
|
307
|
+
assert(rr.to_s == rr2.to_s)
|
308
|
+
end
|
309
|
+
|
310
|
+
def test_cdnskey
|
311
|
+
rrString = "tjeb.nl.\t3600\tIN\tCDNSKEY\t256 3 RSASHA1-NSEC3-SHA1 ( AwEAAcglEOS7bECRK5fqTuGTMJycmDhTzmUu/EQbAhKJOYJxDb5SG/RYqsJgzG7wgtGy0W1aP7I4k6SPtHmwcqjLaZLVUwRNWCGr2adjb9JTFyBR7F99Ngi11lEGM6Uiw/eDRk66lhoSGzohjj/rmhRTV6gN2+0ADPnafv3MBkPgryA3 ) ; key_tag=53177"
|
312
|
+
rr = RR.create(rrString)
|
313
|
+
assert(rrString.to_s == rr.to_s)
|
314
|
+
m = Dnsruby::Message.new
|
315
|
+
m.add_additional(rr)
|
316
|
+
m2 = Message.decode(m.encode)
|
317
|
+
rr2 = m2.additional()[0]
|
318
|
+
assert(rr.to_s == rr2.to_s)
|
319
|
+
end
|
320
|
+
|
288
321
|
def test_cert
|
289
322
|
rr = RR.create("test.kht.se. 60 IN CERT PGP 0 0 mQGiBDnY2vERBAD3cOxqoAYHYzS+xttvuyN9wZS8CrgwLIlT8Ewo/CCFI11PEO+gJyNPvWPRQsyt1SE60reaIsie2bQTg3DYIg0PmH+ZOlNkpKesPULzdlw4Rx3dD/M3Lkrm977h4Y70ZKC+tbvoYKCCOIkUVevny1PVZ+mB94rb0mMgawSTrct03QCg/w6aHNJFQV7O9ZQ1Fir85M3RS8cEAOo4/1ASVudz3qKZQEhU2Z9O2ydXqpEanHfGirjWYi5RelVsQ9IfBSPFaPAWzQ24nvQ18NU7TgdDQhP4meZXiVXcLBR5Mee2kByf2KAnBUF9aah5s8wZbSrC6u8xEZLuiauvWmCUIWe0Ylc1/L37XeDjrBI2pT+k183X119d6Fr1BACGfZVGsot5rxBUEFPPSrBqYXG/0hRYv9Eq8a4rJAHK2IUWYfivZgL4DtrJnHlha+H5EPQVYkIAN3nGjXoHmosY+J3Sk+GyR+dCBHEwCkoHMKph3igczCEfxAWgqKeYd5mf+QQq2JKrkn2jceiIO7s3CrepeEFAjDSGuxhZjPJVm7QoRGFuaWVsIFAuIE1haG9uZXkgPGRhbm1AcHJpbWUuZ3VzaGkub3JnPohOBBARAgAOBQI52NrxBAsDAQICGQEACgkQ+75aMGJLskn6LgCbBXUD7UmGla5e1zyhuY667hP3F+UAoJIeDZJyRFkQAmb+u8KekRyLD1MLtDJEYW5pZWwgTWFob25leSAoU2Vjb25kYXJ5IEVtYWlsKSA8Z3VzaGlAZ3VzaGkub3JnPohgBBMRAgAgBQJF1J/XAhsjBgsJCAcDAgQVAggDBBYCAwECHgECF4AACgkQ+75aMGJLskkVhACggsivQ9qLhfdA1rGm6f8LRJBSC4wAoI930h+/hshClj6AkNwGRtHdf5XJuQINBDnY2vQQCAD2Qle3CH8IF3KiutapQvMF6PlTETlPtvFuuUs4INoBp1ajFOmPQFXz0AfGy0OplK33TGSGSfgMg71l6RfUodNQ+PVZX9x2Uk89PY3bzpnhV5JZzf24rnRPxfx2vIPFRzBhznzJZv8V+bv9kV7HAarTW56NoKVyOtQa8L9GAFgr5fSI/VhOSdvNILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsYjY67VYy4XTjTNP18F1dDox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMIPWakXUGfnHy9iUsiGSa6q6Jew1XpMgs7AAICB/9eGjzF2gDh6U7I72x/6bSdlExx2LvIF92OZKc0S55IOS4Lgzs7Hbfm1aOL4oJt7wBg94xkF4cerxz7y8R9J+k3GNl14KOjbYaMAh1rdxdAzikYMH1p1hS78GMtwxky6jE5en87BGGMmnbC84JlxwN+MD7diu8D0Gkgjj/pxOp32D5jEe02wBPVjFTpFLJjpFniLUY6AohRDEdSuZwWPuoKVWhpeWkasNn5qgwGyDREbXpyPsU02BkwE4JiGs+JMMdOn9KMh5dxiuwsMM9gHiQZS3mSNBBKPWI5ZXsdStVFvapjf2FUFDXLUbTROPv1Xhqf0u7YYORFnWeVtvzKIxVaiEYEGBECAAYFAjnY2vQACgkQ+75aMGJLsklBWgCeN7z9xk52y/aoaCuF6hYb0d+3k98AoMRxvHuXI1Nc2FXY/x65PwHiUbaY")
|
290
323
|
rr = RR.create("all.rr.org. IN CERT 6 0 0 FFsAyW1dVK7hIGuvhN56r26UwJx/")
|
data/test/tc_soak.rb
CHANGED
data/test/tc_tcp_pipelining.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dnsruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.61.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Dalitz
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-07-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pry
|
@@ -128,6 +128,20 @@ dependencies:
|
|
128
128
|
- - "~>"
|
129
129
|
- !ruby/object:Gem::Version
|
130
130
|
version: '0.7'
|
131
|
+
- !ruby/object:Gem::Dependency
|
132
|
+
name: addressable
|
133
|
+
requirement: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - "~>"
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '2.5'
|
138
|
+
type: :runtime
|
139
|
+
prerelease: false
|
140
|
+
version_requirements: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - "~>"
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '2.5'
|
131
145
|
description: |-
|
132
146
|
Dnsruby is a pure Ruby DNS client library which implements a
|
133
147
|
stub resolver. It aims to comply with all DNS RFCs, including
|
@@ -194,6 +208,8 @@ files:
|
|
194
208
|
- lib/dnsruby/resource/AFSDB.rb
|
195
209
|
- lib/dnsruby/resource/APL.rb
|
196
210
|
- lib/dnsruby/resource/CAA.rb
|
211
|
+
- lib/dnsruby/resource/CDNSKEY.rb
|
212
|
+
- lib/dnsruby/resource/CDS.rb
|
197
213
|
- lib/dnsruby/resource/CERT.rb
|
198
214
|
- lib/dnsruby/resource/DHCID.rb
|
199
215
|
- lib/dnsruby/resource/DLV.rb
|
@@ -230,6 +246,7 @@ files:
|
|
230
246
|
- lib/dnsruby/resource/TLSA.rb
|
231
247
|
- lib/dnsruby/resource/TSIG.rb
|
232
248
|
- lib/dnsruby/resource/TXT.rb
|
249
|
+
- lib/dnsruby/resource/URI.rb
|
233
250
|
- lib/dnsruby/resource/X25.rb
|
234
251
|
- lib/dnsruby/resource/domain_name.rb
|
235
252
|
- lib/dnsruby/resource/generic.rb
|