dnsruby 1.58.0 → 1.59.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0542a8574fb4f542e8cdfac4b3efa08335954d76
4
- data.tar.gz: 540ef10a9ec536cf6d19cfba946429ac30771c63
3
+ metadata.gz: 30959b577be6d8f64a67832ec6418fd157ece057
4
+ data.tar.gz: 94af23844c0a0f1d53b405b0720c9253364ad890
5
5
  SHA512:
6
- metadata.gz: 793cd5fa6961776a89b2b1e508fe78573cbf6f52c64dd47b62afe2a4173c4448a9e5291be7a8e95837f862aa48a0b37dd710ba0490872d0db4b780468945df8f
7
- data.tar.gz: 604d96ae611adce512eba2a95a93229603d0b85e4f234c3ce4f7d19e78842a8c76aeb70deefd502f2c577d28943e6de1cf6af5e8b5e3e034c4dee5915d8b5ab7
6
+ metadata.gz: 2237405083ea6ba078a24a172d681b8fde6f770d61fab1617cf4683f576ade793af97edadabe2e76fd649dc0d1eb868eb8bd931021b151ad64b8d0f3c99fc271
7
+ data.tar.gz: b7f1a0e23ca45cbe15410bd604754c26688ca835edb39dcc340ac4aece8d76c3e67d6ed06a9c2c3488caf2d56c6a5d526fca80f1c6933b43c4e3f0f1ff7a6bce
data/LICENSE ADDED
@@ -0,0 +1,11 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
@@ -1,5 +1,20 @@
1
1
  # Release Notes
2
2
 
3
+ ## v1.59.0
4
+
5
+ * Add LICENSE file
6
+ * Add Cache max_size (gihub issue 64)
7
+ * Disable caching for SOA lookups in demo check_soa.rb
8
+ * Fix for invalid nameserver in config
9
+ * Fix encoding for OPT data (thanks Craig Despeaux)
10
+ * Various test system fixes
11
+ * OPT fixes
12
+ * DNSSEC verification failure handling wrt lack of DS chain
13
+ * DNSSEC validation policy name constants
14
+ * Fix for BOGUS DLV chains
15
+ * demo upgrades
16
+ * Resolver hints improvements
17
+
3
18
 
4
19
  ## v1.58.0
5
20
 
data/Rakefile CHANGED
@@ -29,4 +29,5 @@ create_task(:test, 'test/ts_dnsruby.rb')
29
29
  create_task(:test_offline, 'test/ts_offline.rb')
30
30
  create_task(:test_online, 'test/ts_online.rb')
31
31
  create_task(:soak, 'test/tc_soak.rb')
32
-
32
+ create_task(:message, 'test/tc_message.rb')
33
+ create_task(:cache, 'test/tc_cache.rb')
@@ -1,6 +1,9 @@
1
+ #! /usr/bin/env ruby
2
+
1
3
  # --
2
4
  # Copyright 2007 Nominet UK
3
5
  #
6
+
4
7
  # Licensed under the Apache License, Version 2.0 (the "License");
5
8
  # you may not use this file except in compliance with the License.
6
9
  # You may obtain a copy of the License at
@@ -59,9 +62,16 @@
59
62
  # Michael Fuhr <mike@fuhr.org>
60
63
  #
61
64
 
65
+ unless (1..2).include?(ARGV.length)
66
+ puts "Usage: #{$0} [ -fqs ] [ -D directory ] [ @nameserver ] zone"
67
+ exit(-1)
68
+ end
69
+
70
+
62
71
  require 'getoptLong'
63
72
  require 'dnsruby'
64
73
 
74
+
65
75
  # ------------------------------------------------------------------------------
66
76
  # Read any command-line options and check syntax.
67
77
  # ------------------------------------------------------------------------------
@@ -89,110 +99,99 @@ opts.each do |opt, arg|
89
99
  end
90
100
  end
91
101
 
92
- if (ARGV.length < 1) || (ARGV.length > 2)
93
- print "Usage: #{$0} [ -fqs ] [ -D directory ] [ @nameserver ] zone\n"
94
- else
95
- # ------------------------------------------------------------------------------
96
- # Get the nameserver (if specified) and set up the zone transfer directory
97
- # hierarchy.
98
- # ------------------------------------------------------------------------------
99
-
100
- nameserver = (ARGV[0] =~ /^@/) ? ARGV.shift : ""
101
- nameserver = nameserver.sub(/^@/, "")
102
- res = nil
103
- if nameserver
104
- res = Dnsruby::Resolver.new(nameserver)
105
- else
106
- res = Dnsruby::Resolver.new
107
- end
102
+ # ------------------------------------------------------------------------------
103
+ # Get the nameserver (if specified) and set up the zone transfer directory
104
+ # hierarchy.
105
+ # ------------------------------------------------------------------------------
108
106
 
109
- zone = ARGV.shift
110
- basedir = opt_d!=nil ? opt_d : (ENV["HOME"]!=nil ? ENV["HOME"] : "") + "/.dns-zones"
111
- zonedir = zone.split(/\./).reverse.join("/")
112
- zonefile = basedir + "/" + zonedir + "/axfr"
107
+ nameserver = (ARGV[0] =~ /^@/) ? ARGV.shift : ''
108
+ nameserver = nameserver.sub(/^@/, '')
109
+ resolver = nameserver ? Dnsruby::Resolver.new(nameserver) : Dnsruby::Resolver.new
113
110
 
114
- # Don't worry about the 0777 permissions here - the current umask setting
115
- # will be applied.
116
- if !(FileTest.directory?basedir)
117
- Dir.mkdir(basedir, 0777) or raise RuntimeError, "can't mkdir #{basedir}: #{$!}\n"
118
- end
111
+ zone = ARGV.shift
112
+ basedir = opt_d || File.join((ENV['HOME'] || ''), '.dns-zones')
113
+ zonedir = zone.split(/\./).reverse.join("/")
114
+ zonefile = File.join(basedir, zonedir, 'axfr')
119
115
 
120
- dir = basedir
121
- zonedir.split("/").each do |subdir|
122
- dir += "/" + subdir
123
- if (!FileTest.directory?dir)
124
- Dir.mkdir(dir, 0777) or raise RuntimeError, "can't mkdir #{dir}: #{$!}\n"
125
- end
126
- end
116
+ # Don't worry about the 0777 permissions here - the current umask setting
117
+ # will be applied.
118
+ # NOTE: mkdir will raise an error on failure so I don't think 'or' works here.
119
+ unless FileTest.directory?(basedir)
120
+ Dir.mkdir(basedir, 0777) or raise RuntimeError, "can't mkdir #{basedir}: #{$!}\n"
121
+ end
127
122
 
128
- # ------------------------------------------------------------------------------
129
- # Get the zone.
130
- # ------------------------------------------------------------------------------
123
+ dir = basedir
124
+ # NOTE: What are we doing here? Could this be replaced by mkdir_p?
125
+ zonedir.split('/').each do |subdir|
126
+ dir += '/' + subdir
127
+ unless FileTest.directory?(dir)
128
+ Dir.mkdir(dir, 0777) or raise RuntimeError, "can't mkdir #{dir}: #{$!}\n"
129
+ end
130
+ end
131
131
 
132
- zonearray = nil
132
+ # ------------------------------------------------------------------------------
133
+ # Get the zone.
134
+ # ------------------------------------------------------------------------------
133
135
 
134
- if (FileTest.exist?(zonefile) && !opt_f)
135
- zoneref = Marshal.load(File.open(zonefile))
136
- if (zoneref==nil)
137
- raise RuntimeError, "couldn't retrieve zone from #{zonefile}: #{$!}\n"
138
- end
136
+ if FileTest.exist?(zonefile) && !opt_f
137
+ zoneref = Marshal.load(File.open(zonefile))
138
+ if zoneref.nil?
139
+ raise RuntimeError, "couldn't retrieve zone from #{zonefile}: #{$!}\n"
140
+ end
139
141
 
140
- # ----------------------------------------------------------------------
141
- # Check the SOA serial number if desired.
142
- # ----------------------------------------------------------------------
142
+ # ----------------------------------------------------------------------
143
+ # Check the SOA serial number if desired.
144
+ # ----------------------------------------------------------------------
143
145
 
144
- if (opt_s)
145
- serial_file, serial_zone = nil
146
+ if opt_s
147
+ serial_file = serial_zone = nil
146
148
 
147
- zoneref.each do |rr|
148
- if (rr.type == "SOA")
149
- serial_file = rr.serial
150
- break
151
- end
152
- end
153
- if serial_file==nil
154
- raise RuntimeError, "no SOA in #{zonefile}\n"
149
+ zoneref.each do |rr|
150
+ if (rr.type == 'SOA')
151
+ serial_file = rr.serial
152
+ break
155
153
  end
154
+ end
155
+ if serial_file.nil?
156
+ raise RuntimeError, "no SOA in #{zonefile}\n"
157
+ end
156
158
 
157
- soa = res.query(zone, "SOA")
158
- if soa==nil
159
- raise RuntimeError, "couldn't get SOA for #{zone}: " + res.errorstring + "\n"
160
- end
159
+ soa = resolver.query(zone, 'SOA')
160
+ if soa.nil?
161
+ raise RuntimeError, "couldn't get SOA for #{zone}: " + resolver.errorstring + "\n"
162
+ end
161
163
 
162
- soa.answer.each do |rr|
163
- if (rr.type == "SOA")
164
- serial_zone = rr.serial
165
- break
166
- end
164
+ soa.answer.each do |rr|
165
+ if rr.type == 'SOA'
166
+ serial_zone = rr.serial
167
+ break
167
168
  end
169
+ end
168
170
 
169
- if (serial_zone != serial_file)
170
- opt_f = true
171
- end
171
+ if serial_zone != serial_file
172
+ opt_f = true
172
173
  end
173
- else
174
- opt_f = true
175
174
  end
175
+ else
176
+ opt_f = true
177
+ end
176
178
 
177
- if (opt_f)
178
- print "nameserver = #{nameserver}, zone=#{zone}"
179
- zt = Dnsruby::ZoneTransfer.new
180
- zt.server=(nameserver) if nameserver!=""
179
+ if opt_f
180
+ print "nameserver = #{nameserver}, zone=#{zone}"
181
+ zt = Dnsruby::ZoneTransfer.new
182
+ zt.server = nameserver if nameserver != ''
181
183
 
182
- zoneref = zt.transfer(zone)
183
- if zoneref==nil
184
- raise RuntimeError, "couldn't transfer zone\n"
185
- end
186
- Marshal.dump(zoneref, File.open(zonefile, File::CREAT|File::RDWR))
184
+ zoneref = zt.transfer(zone)
185
+ if zoneref.nil?
186
+ raise RuntimeError, "couldn't transfer zone\n"
187
187
  end
188
+ Marshal.dump(zoneref, File.open(zonefile, File::CREAT | File::RDWR))
189
+ end
188
190
 
189
- # ------------------------------------------------------------------------------
190
- # Print the records in the zone.
191
- # ------------------------------------------------------------------------------
191
+ # ------------------------------------------------------------------------------
192
+ # Print the records in the zone.
193
+ # ------------------------------------------------------------------------------
192
194
 
193
- if (!opt_q)
194
- zoneref.each do |z|
195
- print z.to_s + "\n"
196
- end
197
- end
195
+ unless opt_q
196
+ zoneref.each { |z| puts z }
198
197
  end
@@ -1,3 +1,5 @@
1
+ #! /usr/bin/env ruby
2
+
1
3
  # --
2
4
  # Copyright 2007 Nominet UK
3
5
  #
@@ -35,7 +37,7 @@
35
37
  # The original Bourne Shell and C versions were printed in
36
38
  # "DNS and BIND" by Paul Albitz & Cricket Liu.
37
39
  #
38
- # This Perl version was written by Michael Fuhr <mike@fuhr.org>.
40
+ # The Perl version was written by Michael Fuhr <mike@fuhr.org>.
39
41
  #
40
42
  # = SEE ALSO
41
43
  #
@@ -43,116 +45,135 @@
43
45
 
44
46
  require 'dnsruby'
45
47
 
46
- # ------------------------------------------------------------------------------
47
- # Get the domain from the command line.
48
- # ------------------------------------------------------------------------------
48
+ NO_DOMAIN_SPECIFIED = -1
49
+ NO_NAMESERVERS = -2
49
50
 
50
- if ARGV.length ==1
51
- domain = ARGV[0]
52
51
 
53
- # ------------------------------------------------------------------------------
54
- # Find all the nameservers for the domain.
55
- # ------------------------------------------------------------------------------
52
+ def fatal_error(message, exit_code)
53
+ puts message
54
+ exit(exit_code)
55
+ end
56
56
 
57
- res = Dnsruby::Resolver.new
58
57
 
59
- # res.defnames=(0)
60
- res.retry_times=(2)
61
- ns_req = nil
62
- begin
63
- ns_req = res.query(domain, "NS")
64
- rescue Exception => e
65
- print "Error : #{e}"
66
- return
67
- end
68
- if (ns_req.header.ancount == 0)
69
- print "No nameservers found for #{domain}\n"
70
- return
71
- end
58
+ def usage
59
+ fatal_error("Usage: #{$0} domain", NO_DOMAIN_SPECIFIED)
60
+ end
72
61
 
73
- # Send out non-recursive queries
74
- res.recurse=(0)
75
62
 
63
+ def create_resolver
64
+ resolver = Dnsruby::Resolver.new
65
+ resolver.retry_times = 2
66
+ resolver.recurse = 0 # Send out non-recursive queries
67
+ # disable caching otherwise SOA is cached from first nameserver queried
68
+ resolver.do_caching = false
69
+ resolver
70
+ end
76
71
 
77
- # ------------------------------------------------------------------------------
78
- # Check the SOA record on each nameserver.
79
- # ------------------------------------------------------------------------------
80
72
 
81
- (ns_req.answer.select {|r| r.type == "NS"}).each do |nsrr|
73
+ def get_ns_response(resolver, domain)
74
+ ns_response = resolver.query(domain, 'NS')
75
+ if ns_response.header.ancount == 0
76
+ fatal_error("No nameservers found for #{domain}.", NO_NAMESERVERS)
77
+ end
78
+ ns_response
79
+ end
82
80
 
83
- # ----------------------------------------------------------------------
84
- # Set the resolver to query this nameserver.
85
- # ----------------------------------------------------------------------
86
- ns = nsrr.domainname
87
81
 
82
+ # Finds all the nameserver domains for the domain.
83
+ def get_ns_domains(resolver, domain)
84
+ ns_response = get_ns_response(resolver, domain)
85
+ ns_answers = ns_response.answer.select { |r| r.type == 'NS'}
86
+ ns_answers.map(&:domainname)
87
+ end
88
+
89
+
90
+ def process_ns_domain(resolver, domain, ns_domain)
91
+
92
+ a_response = begin
88
93
  # In order to lookup the IP(s) of the nameserver, we need a Resolver
89
94
  # object that is set to our local, recursive nameserver. So we create
90
95
  # a new object just to do that.
96
+ local_resolver = Dnsruby::Resolver.new
91
97
 
92
- local_res = Dnsruby::Resolver.new
93
- a_req=nil
94
- begin
95
- a_req = local_res.query(ns, 'A')
98
+ local_resolver.query(ns_domain, 'A')
99
+ rescue Exception => e
100
+ puts "Cannot find address for #{ns_domain}: #{e}"
101
+ return
102
+ end
103
+
104
+ a_answers = a_response.answer.select {|r| r.type == 'A'}
105
+ a_answers.each do |a_answer|
106
+
107
+ # ----------------------------------------------------------------------
108
+ # Ask this IP.
109
+ # ----------------------------------------------------------------------
110
+ ip_address = a_answer.address
111
+ resolver.nameserver = ip_address.to_s
112
+ print "#{ns_domain} (#{ip_address}): "
113
+
114
+ # ----------------------------------------------------------------------
115
+ # Get the SOA record.
116
+ # ----------------------------------------------------------------------
117
+ soa_response = begin
118
+ resolver.query(domain, 'SOA', 'IN')
96
119
  rescue Exception => e
97
- print "Can not find address for #{ns}: #{e}\n"
98
- next
120
+ puts "Error : #{e}"
121
+ return
122
+ end
123
+
124
+ # ----------------------------------------------------------------------
125
+ # Is this nameserver authoritative for the domain?
126
+ # ----------------------------------------------------------------------
127
+
128
+ unless soa_response.header.aa
129
+ print "isn't authoritative for #{domain}\n"
130
+ return
131
+ end
132
+
133
+ # ----------------------------------------------------------------------
134
+ # We should have received exactly one answer.
135
+ # ----------------------------------------------------------------------
136
+
137
+ unless soa_response.header.ancount == 1
138
+ puts "expected 1 answer, got #{soa_response.header.ancount}."
139
+ return
99
140
  end
100
141
 
101
- (a_req.answer.select {|r| r.type == 'A'}).each do |r|
102
- ip = r.address
103
- # ----------------------------------------------------------------------
104
- # Ask this IP.
105
- # ----------------------------------------------------------------------
106
-
107
- res.nameserver=(ip.to_s)
108
-
109
- print "#{ns} (#{ip}): "
110
-
111
- # ----------------------------------------------------------------------
112
- # Get the SOA record.
113
- # ----------------------------------------------------------------------
114
- soa_req=nil
115
- begin
116
- soa_req = res.query(domain, 'SOA', 'IN')
117
- rescue Exception => e
118
- print "Error : #{e}\n"
119
- next
120
- end
121
-
122
- # ----------------------------------------------------------------------
123
- # Is this nameserver authoritative for the domain?
124
- # ----------------------------------------------------------------------
125
-
126
- unless (soa_req.header.aa)
127
- print "isn't authoritative for #{domain}\n"
128
- next
129
- end
130
-
131
- # ----------------------------------------------------------------------
132
- # We should have received exactly one answer.
133
- # ----------------------------------------------------------------------
134
-
135
- unless (soa_req.header.ancount == 1)
136
- print "expected 1 answer, got ", soa_req.header.ancount, "\n"
137
- next
138
- end
139
-
140
- # ----------------------------------------------------------------------
141
- # Did we receive an SOA record?
142
- # ----------------------------------------------------------------------
143
-
144
- unless ((soa_req.answer)[0].type == "SOA")
145
- print "expected SOA, got ", (soa_req.answer)[0].type, "\n"
146
- next
147
- end
148
-
149
- # ----------------------------------------------------------------------
150
- # Print the serial number.
151
- # ----------------------------------------------------------------------
152
-
153
- print "has serial number ", (soa_req.answer)[0].serial, "\n"
142
+ # ----------------------------------------------------------------------
143
+ # Did we receive an SOA record?
144
+ # ----------------------------------------------------------------------
145
+
146
+ answer_type = soa_response.answer[0].type
147
+ unless answer_type == 'SOA'
148
+ puts "expected SOA, got #{answer_type}"
149
+ return
154
150
  end
151
+
152
+ # ----------------------------------------------------------------------
153
+ # Print the serial number.
154
+ # ----------------------------------------------------------------------
155
+
156
+ puts "has serial number #{soa_response.answer[0].serial}"
155
157
  end
156
- else
157
- print "Usage: #{$0} domain\n"
158
158
  end
159
+
160
+
161
+ def main
162
+
163
+ # Get domain from command line, printing usage and exiting if none provided:
164
+ domain = ARGV.fetch(0) { usage }
165
+
166
+ resolver = create_resolver
167
+
168
+ ns_domains = get_ns_domains(resolver, domain)
169
+
170
+ # ------------------------------------------------------------------------------
171
+ # Check the SOA record on each nameserver.
172
+ # ------------------------------------------------------------------------------
173
+ ns_domains.each do |ns_domain_name|
174
+ process_ns_domain(resolver, domain, ns_domain_name)
175
+ end
176
+ end
177
+
178
+
179
+ main