dnsruby 1.50 → 1.51

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.
@@ -99,6 +99,12 @@ else
99
99
 
100
100
  nameserver = (ARGV[0] =~ /^@/) ? ARGV.shift : ""
101
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
108
 
103
109
  zone = ARGV.shift
104
110
  basedir = opt_d!=nil ? opt_d : (ENV["HOME"]!=nil ? ENV["HOME"] : "") + "/.dns-zones"
@@ -175,7 +181,7 @@ else
175
181
 
176
182
  zoneref = zt.transfer(zone)
177
183
  if zoneref==nil
178
- raise RuntimeError, "couldn't transfer zone: " + res.errorstring + "\n"
184
+ raise RuntimeError, "couldn't transfer zone\n"
179
185
  end
180
186
  Marshal.dump(zoneref, File.open(zonefile, File::CREAT|File::RDWR))
181
187
  end
@@ -283,6 +283,9 @@ module Dnsruby
283
283
  server = addr
284
284
  end
285
285
  }
286
+ if (!found)
287
+ raise ArgumentError.new("Recursor can't locate #{server}")
288
+ end
286
289
  end
287
290
  end
288
291
  rescue Exception => e
@@ -282,6 +282,9 @@ module Dnsruby
282
282
  msg = Message.new
283
283
  msg.header.rd = 1
284
284
  msg.add_question(candidate, type, klass)
285
+ msg.do_validation = false
286
+ msg.header.cd = false
287
+ @resolver.do_validation = false
285
288
  @resolver.send_async(msg, q)
286
289
  id, ret, exception = q.pop
287
290
  if (exception == nil && ret && ret.rcode == RCode.NOERROR)
@@ -210,6 +210,8 @@ module Dnsruby
210
210
  hints[server] = AddressCache.new
211
211
  end
212
212
  end
213
+ # @TODO@ Some resolvers (e.g. 8.8.8.8) do not send an additional section -
214
+ # need to make explicit queries for these :(
213
215
  packet.additional.each do |rr|
214
216
  TheLog.debug(";; ADDITIONAL: "+rr.inspect+"\n")
215
217
  server = rr.name.to_s.downcase
@@ -254,7 +256,7 @@ module Dnsruby
254
256
  end
255
257
  end
256
258
  else
257
- warn "Server ["+(@@nameservers)[0].to_s+".] did not give answers"
259
+ raise ResolvError.new( "Server ["+(@@nameservers)[0].to_s+".] did not give answers")
258
260
  end
259
261
 
260
262
  # Disable recursion flag.
@@ -206,7 +206,7 @@ module Dnsruby
206
206
  TheLog.debug("Checking whether to validate, query.cd = #{query.header.cd}")
207
207
  if (((@@validation_policy > ValidationPolicy::ALWAYS_ROOT_ONLY) && (self.trust_anchors().length > 0)) ||
208
208
  # Check query here, and validate if CD is true
209
- (query.header.cd == true))
209
+ ((query.header.cd == true))) # && (query.do_validation)))
210
210
  TheLog.debug("Starting validation")
211
211
 
212
212
  # Validate!
@@ -74,7 +74,10 @@ module Dnsruby
74
74
  rescue ArgumentError
75
75
  @alg = Dnsruby::Algorithms.new(names[2].to_i)
76
76
  end
77
- buf = names[3]
77
+ buf = ""
78
+ (names.length - 3).times {|index|
79
+ buf += names[index + 3]
80
+ }
78
81
 
79
82
 
80
83
  buf.gsub!(/\n/, "")
@@ -22,11 +22,19 @@ module Dnsruby
22
22
  TypeValue = Types::RP #:nodoc: all
23
23
 
24
24
  #Returns a domain name that specifies the mailbox for the responsible person.
25
- attr_accessor :mailbox
25
+ attr_reader :mailbox
26
26
  #A domain name that specifies a TXT record containing further
27
27
  #information about the responsible person.
28
- attr_accessor :txtdomain
28
+ attr_reader :txtdomain
29
+
30
+ def txtdomain=(s)
31
+ @txtdomain = Name.create(s)
32
+ end
29
33
 
34
+ def mailbox=(s)
35
+ @mailbox = Name.create(s)
36
+ end
37
+
30
38
  def from_hash(hash)
31
39
  @mailbox = Name.create(hash[:mailbox])
32
40
  @txtdomain = Name.create(hash[:txtdomain])
@@ -477,7 +477,7 @@ module Dnsruby
477
477
  @buf = nil
478
478
 
479
479
  # RFC 2845 Section 2.3
480
- @klass = "ANY"
480
+ @klass = Classes.ANY
481
481
 
482
482
  @ttl = 0 # RFC 2845 Section 2.3
483
483
  end
@@ -48,7 +48,8 @@ module Dnsruby
48
48
  end
49
49
  new_pos = @rrs.length - @num_sigs
50
50
  if ((@num_sigs == @rrs.length) && @num_sigs > 0) # if we added RRSIG first
51
- if (r.type != @rrs.last.type_covered)
51
+ if (((r.type != @rrs.last.type_covered) && (r.type != Types.RRSIG))||
52
+ ((r.type == Types.RRSIG) && (r.type_covered != @rrs.last.type_covered)))
52
53
  return false
53
54
  end
54
55
  end
@@ -292,6 +293,9 @@ module Dnsruby
292
293
  if (@klass != rec.klass || @name.downcase != rec.name.downcase)
293
294
  return false
294
295
  end
296
+ if (rec.type == Types.RRSIG) && (@type == Types.RRSIG)
297
+ return rec.type_covered == self.type_covered
298
+ end
295
299
  [rec, self].each { |rr|
296
300
  if (rr.type == Types::RRSIG)
297
301
  return ((@type == rr.type_covered) || (rec.type == rr.type_covered))
@@ -111,6 +111,7 @@ module Dnsruby
111
111
 
112
112
  @header.opcode=('UPDATE')
113
113
  @header.rd=(0)
114
+ @do_validation = false
114
115
  end
115
116
 
116
117
  #Ways to create the prerequisite records (exists, notexists, inuse, etc. - RFC2136, section 2.4)
@@ -220,7 +221,22 @@ module Dnsruby
220
221
  type=args[1]
221
222
  ttl=args[2]
222
223
  rdata=args[3]
223
- resource = RR.create("#{name} #{ttl} #{zoneclass} #{type} #{rdata}")
224
+ resource = nil
225
+ if (Types.new(type) == Types.TXT)
226
+ instring = "#{name} #{ttl} #{zoneclass} #{type} ";
227
+ if (String === rdata)
228
+ instring += " '#{rdata}'"
229
+ elsif (Array === rdata)
230
+ rdata.length.times {|rcounter|
231
+ instring += " '#{rdata[rcounter]}' "
232
+ }
233
+ else
234
+ instring += rdata
235
+ end
236
+ resource = RR.create(instring)
237
+ else
238
+ resource = RR.create("#{name} #{ttl} #{zoneclass} #{type} #{rdata}")
239
+ end
224
240
  add_update(resource)
225
241
  return resource
226
242
  end
@@ -231,14 +247,14 @@ module Dnsruby
231
247
  #
232
248
  #2.5.2 - Delete An RRset
233
249
  # update.delete(name, type)
234
- #
250
+ #
235
251
  #
236
252
  #2.5.3 - Delete All RRsets From A Name
237
253
  # update.delete(name)
238
- #
254
+ #
239
255
  #2.5.4 - Delete An RR From An RRset
240
256
  # update.delete(name, type, rdata)
241
- #
257
+ #
242
258
  def delete(*args)
243
259
  ttl = 0
244
260
  klass = Classes.ANY
@@ -247,14 +263,14 @@ module Dnsruby
247
263
  case args.length
248
264
  when 1 # name
249
265
  resource = RR.create("#{args[0]} #{ttl} #{klass} #{Types.ANY} #{rdata}")
250
- add_update(resource)
266
+ add_update(resource)
251
267
  when 2 # name, type
252
268
  resource = RR.create("#{args[0]} #{ttl} #{klass} #{args[1]} #{rdata}")
253
- add_update(resource)
269
+ add_update(resource)
254
270
  when 3 # name, type, rdata
255
271
  resource = RR.create("#{args[0]} #{ttl} IN #{args[1]} #{args[2]}")
256
272
  resource.klass = Classes.NONE
257
- add_update(resource)
273
+ add_update(resource)
258
274
  end
259
275
  return resource
260
276
  end
@@ -217,7 +217,7 @@ module Dnsruby
217
217
  split = line.split(' ') # split on whitespace
218
218
  name = split[0].strip
219
219
  if (name.index"\\")
220
-
220
+
221
221
  ls =[]
222
222
  Name.create(name).labels.each {|el| ls.push(Name.decode(el.to_s))}
223
223
  new_name = ls.join('.')
@@ -331,7 +331,7 @@ module Dnsruby
331
331
  # "." + origin string if necessary
332
332
  if ([Types::MX, Types::NS, Types::AFSDB, Types::NAPTR, Types::RT,
333
333
  Types::SRV, Types::CNAME, Types::MB, Types::MG, Types::MR,
334
- Types::PTR].include?type_was)
334
+ Types::PTR, Types::DNAME].include?type_was)
335
335
  # if (line[line.length-1, 1] != ".")
336
336
  if (!(/\.\z/ =~ line))
337
337
  line = line + "." + @origin.to_s + "."
@@ -359,9 +359,9 @@ module Dnsruby
359
359
  when Types::RP
360
360
  if (!parsed_rr.mailbox.absolute?)
361
361
  parsed_rr.mailbox = parsed_rr.mailbox.to_s + "." + @origin.to_s
362
- if (!parsed_rr.txtdomain.absolute?)
363
- parsed_rr.txtdomain = parsed_rr.txtdomain.to_s + "." + @origin.to_s
364
- end
362
+ end
363
+ if (!parsed_rr.txtdomain.absolute?)
364
+ parsed_rr.txtdomain = parsed_rr.txtdomain.to_s + "." + @origin.to_s
365
365
  end
366
366
  end
367
367
  line = parsed_rr.to_s
@@ -91,7 +91,8 @@ module Dnsruby
91
91
  server=Config.resolve_server(server)
92
92
  xfr = do_transfer(zone, server)
93
93
  break
94
- rescue Exception => exception
94
+ rescue Exception => e
95
+ exception = e
95
96
  end
96
97
  end
97
98
  if (xfr == nil && exception != nil)
@@ -133,7 +134,7 @@ module Dnsruby
133
134
  raise ResolvError.new(rcode.string);
134
135
  end
135
136
 
136
- if (response.question[0].qtype != @transfer_type)
137
+ if (response.question[0].qtype != @transfer_type)
137
138
  raise ResolvError.new("invalid question section")
138
139
  end
139
140
 
@@ -213,7 +214,28 @@ module Dnsruby
213
214
  ret +=", Deletes : " + @deletes.join(",")
214
215
  end
215
216
  end
216
-
217
+
218
+ #Compare two serials according to RFC 1982. Return 0 if equal,
219
+ #-1 if s1 is bigger, 1 if s1 is smaller.
220
+ def compare_serial(s1, s2)
221
+ if s1 == s2
222
+ return 0
223
+ end
224
+ if s1 < s2 and (s2 - s1) < (2**31)
225
+ return 1
226
+ end
227
+ if s1 > s2 and (s1 - s2) > (2**31)
228
+ return 1
229
+ end
230
+ if s1 < s2 and (s2 - s1) > (2**31)
231
+ return -1
232
+ end
233
+ if s1 > s2 and (s1 - s2) < (2**31)
234
+ return -1
235
+ end
236
+ return 0
237
+ end
238
+
217
239
  def parseRR(rec) #:nodoc: all
218
240
  name = rec.name
219
241
  type = rec.type
@@ -228,8 +250,11 @@ module Dnsruby
228
250
  # Remember the serial number in the initial SOA; we need it
229
251
  # to recognize the end of an IXFR.
230
252
  @end_serial = rec.serial
231
- if (@transfer_type == Types.IXFR && @end_serial <= @serial)
253
+ # if ((@transfer_type == Types.IXFR) && (@end_serial <= @serial))
254
+ if ((@transfer_type == Types.IXFR) && (compare_serial(@end_serial, @serial) >= 0))
232
255
  Dnsruby.log.debug("zone up to date")
256
+ raise ZoneSerialError.new("IXFR up to date: expected serial " +
257
+ @serial.to_s + " , got " + rec.serial.to_s);
233
258
  @state = :End
234
259
  else
235
260
  @state = :FirstData
@@ -246,6 +271,7 @@ module Dnsruby
246
271
  else
247
272
  Dnsruby.log.debug("AXFR response - using AXFR")
248
273
  @rtype = Types.AXFR
274
+ @transfer_type = Types.AXFR
249
275
  @axfr = []
250
276
  @axfr << @initialsoa
251
277
  @state = :Axfr
@@ -283,8 +309,8 @@ module Dnsruby
283
309
  @state = :End
284
310
  return
285
311
  elsif (soa_serial != @current_serial)
286
- raise ResolvError.new("IXFR out of sync: expected serial " +
287
- @current_serial + " , got " + soa_serial);
312
+ raise ZoneSerialError.new("IXFR out of sync: expected serial " +
313
+ @current_serial.to_s + " , got " + soa_serial.to_s);
288
314
  else
289
315
  @state = :Ixfr_DelSoa
290
316
  parseRR(rec); # Restart...
@@ -104,7 +104,7 @@ require 'Dnsruby/TheLog'
104
104
  module Dnsruby
105
105
 
106
106
  # @TODO@ Remember to update version in dnsruby.gemspec!
107
- VERSION = 1.50
107
+ VERSION = 1.51
108
108
  def Dnsruby.version
109
109
  return VERSION
110
110
  end
@@ -479,6 +479,10 @@ module Dnsruby
479
479
  class VerifyError < ResolvError
480
480
  end
481
481
 
482
+ #Indicates a zone transfer has failed due to SOA serial mismatch
483
+ class ZoneSerialError < ResolvError
484
+ end
485
+
482
486
  #The Resolv class can be used to resolve addresses using /etc/hosts and /etc/resolv.conf,
483
487
  #
484
488
  #The DNS class may be used to perform more queries. If greater control over the sending
@@ -49,9 +49,10 @@ class TestDlv < Test::Unit::TestCase
49
49
  Dnsruby::PacketSender.clear_caches
50
50
 
51
51
 
52
- res = Dnsruby::Recursor.new()
53
- ret = res.query("ns2.nic.se", Dnsruby::Types.A)
54
- assert(ret.security_level == Dnsruby::Message::SecurityLevel::SECURE)
52
+ # SE no longer in DLV
53
+ # res = Dnsruby::Recursor.new()
54
+ # ret = res.query("ns2.nic.se", Dnsruby::Types.A)
55
+ # assert(ret.security_level == Dnsruby::Message::SecurityLevel::SECURE)
55
56
 
56
57
  # .cz no longer in dlv?
57
58
  # ret = res.query("b.ns.nic.cz", Dnsruby::Types.A)
@@ -59,16 +60,18 @@ class TestDlv < Test::Unit::TestCase
59
60
 
60
61
  # Test .gov
61
62
  # Dnsruby::TheLog.level = Logger::DEBUG
63
+ res = Resolver.new
62
64
  ret = res.query("nih.gov", "NS")
63
65
  assert(ret.security_level = Dnsruby::Message::SecurityLevel::SECURE)
64
66
  end
65
67
 
66
- def test_scrub_non_authoritative
67
- # Dnssec.do_validation_with_recursor(true)
68
- res = Dnsruby::Recursor.new()
69
- ret = res.query("frobbit.se")
70
- res.prune_rrsets_to_rfc5452(ret, "frobbit.se.")
71
- Dnssec.validate(ret)
72
- assert(ret.security_level == Dnsruby::Message::SecurityLevel::SECURE)
73
- end
68
+ # se no longer in dlv
69
+ # def test_scrub_non_authoritative
70
+ ## Dnssec.do_validation_with_recursor(true)
71
+ # res = Dnsruby::Recursor.new()
72
+ # ret = res.query("frobbit.se")
73
+ # res.prune_rrsets_to_rfc5452(ret, "frobbit.se.")
74
+ # Dnssec.validate(ret)
75
+ # assert(ret.security_level == Dnsruby::Message::SecurityLevel::SECURE)
76
+ # end
74
77
  end
@@ -221,4 +221,16 @@ class TestUpdate < Test::Unit::TestCase
221
221
  assert_equal(Classes.ANY, pre[1].klass, 'third class right'); #65
222
222
  assert_equal(Classes.NONE, pre[2].klass, 'forth class right'); #66
223
223
  end
224
+
225
+ def test_txt
226
+ update = Update.new()
227
+ update.add("target_name", "TXT", 100, "test signed update")
228
+ assert(update.to_s.index("test signed update"))
229
+ end
230
+
231
+ def test_array
232
+ update = Update.new
233
+ update.add("target_name", "TXT", 100, ['"test signed update"', 'item#2'])
234
+ assert(update.to_s.index("item"))
235
+ end
224
236
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dnsruby
3
3
  version: !ruby/object:Gem::Version
4
- version: "1.50"
4
+ version: "1.51"
5
5
  platform: ruby
6
6
  authors:
7
7
  - AlexD
@@ -9,7 +9,7 @@ autorequire: dnsruby
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-09-15 00:00:00 +01:00
12
+ date: 2010-11-12 00:00:00 +00:00
13
13
  default_executable:
14
14
  dependencies: []
15
15