dnsruby 1.50 → 1.51

Sign up to get free protection for your applications and to get access to all the features.
@@ -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