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.
data/demo/mx.rb CHANGED
@@ -1,3 +1,5 @@
1
+ #! /usr/bin/env ruby
2
+
1
3
  # --
2
4
  # Copyright 2007 Nominet UK
3
5
  #
@@ -34,16 +36,24 @@ require 'dnsruby'
34
36
  # (Ruby port AlexD, Nominet UK)
35
37
  #
36
38
 
37
- if ARGV.length == 1
38
- dname = ARGV[0]
39
- res = Dnsruby::DNS.new
40
- begin
41
- res.each_resource(dname, 'MX') { |rr|
42
- print rr.preference, "\t", rr.exchange, "\n"
43
- }
44
- rescue Exception => e
45
- print "Can't find MX hosts for #{dname}: ", e, "\n"
39
+ def fatal_error(message)
40
+ puts message
41
+ exit -1
42
+ end
43
+
44
+
45
+ unless ARGV.length == 1
46
+ fatal_error("Usage: #{$0} name")
47
+ end
48
+
49
+
50
+ domain = ARGV[0]
51
+ resolver = Dnsruby::DNS.new
52
+
53
+ begin
54
+ resolver.each_resource(domain, 'MX') do |rr|
55
+ print rr.preference, "\t", rr.exchange, "\n"
46
56
  end
47
- else
48
- print "Usage: #{$0} domain\n"
57
+ rescue Exception => e
58
+ fatal_error("Can't find MX hosts for #{domain}: #{e}")
49
59
  end
@@ -1,3 +1,5 @@
1
+ #! /usr/bin/env ruby
2
+
1
3
  # --
2
4
  # Copyright 2007 Nominet UK
3
5
  #
@@ -33,49 +35,56 @@
33
35
  # Michael Fuhr <mike@fuhr.org>
34
36
  #
35
37
 
38
+ def fatal_error(message)
39
+ puts message
40
+ exit(-1)
41
+ end
42
+
43
+
44
+ unless (1..3).include?(ARGV.length)
45
+ fatal_error("Usage: #{$0} [ @nameserver ] name [ type [ class ] ]")
46
+ end
47
+
48
+
36
49
  require 'dnsruby'
37
- include Dnsruby
38
50
 
39
- res = Dnsruby::Resolver.new
40
- zt=Dnsruby::ZoneTransfer.new
41
51
 
42
- if (ARGV && (ARGV[0] =~ /^@/))
52
+ resolver = Dnsruby::Resolver.new
53
+ zone_transfer = Dnsruby::ZoneTransfer.new
54
+
55
+
56
+ if ARGV[0] =~ /^@/
43
57
  nameserver = ARGV.shift
44
- if (nameserver == "@auth")
45
- res = Dnsruby::Recursor.new
58
+ if nameserver == '@auth'
59
+ resolver = Dnsruby::Recursor.new
46
60
  else
47
- print "Setting nameserver : #{nameserver}\n"
48
- res.nameserver=(nameserver.sub(/^@/, ""))
49
- print "nameservers = #{res.config.nameserver}\n"
50
- zt.server=(nameserver.sub(/^@/, ""))
61
+ puts "Setting nameserver : #{nameserver}"
62
+ resolver.nameserver = (nameserver.sub(/^@/, ''))
63
+ puts "nameservers = #{resolver.config.nameserver}"
64
+ zone_transfer.server = (nameserver.sub(/^@/, ''))
51
65
  end
52
66
  end
53
67
 
54
- raise RuntimeError, "Usage: #{$0} [ \@nameserver ] name [ type [ class ] ]\n" unless (ARGV.length >= 1) && (ARGV.length <= 3)
55
-
56
68
  name, type, klass = ARGV
57
- type ||= "A"
58
- klass ||= "IN"
69
+ type ||= 'A'
70
+ klass ||= 'IN'
59
71
 
60
- if (type.upcase == "AXFR")
61
- rrs = zt.transfer(name) # , klass)
72
+ if type.upcase == 'AXFR'
73
+ rrs = zone_transfer.transfer(name) # , klass)
62
74
 
63
- if (rrs)
64
- rrs.each do |rr|
65
- print rr.to_s + "\n"
66
- end
75
+ if rrs
76
+ rrs.each { |rr| puts rr }
67
77
  else
68
- raise RuntimeError, "zone transfer failed: ", res.errorstring, "\n"
78
+ fatal_error("Zone transfer failed: #{resolver.errorstring}")
69
79
  end
70
80
 
71
81
  else
72
82
 
73
83
  # Dnsruby::TheLog.level=Logger::DEBUG
74
84
  begin
75
- answer = nil
76
- answer = res.query(name, type, klass)
77
- print answer
85
+ answer = resolver.query(name, type, klass)
86
+ puts answer
78
87
  rescue Exception => e
79
- print "query failed: #{e}\n"
88
+ fatal_error("Query failed: #{e}")
80
89
  end
81
90
  end
@@ -1,3 +1,5 @@
1
+ #! /usr/bin/env ruby
2
+
1
3
  # --
2
4
  # Copyright 2007 Nominet UK
3
5
  #
@@ -15,32 +17,36 @@
15
17
  # ++
16
18
 
17
19
  require 'dnsruby'
18
- include Dnsruby
19
20
 
20
21
  # e.g. ruby trace_dns.rb example.com
21
22
 
23
+ unless (1..2).include?(ARGV.length)
24
+ puts "Usage: #{$0} domain [type]"
25
+ exit(-1)
26
+ end
27
+
28
+
22
29
  # Load DLV key
23
- dlv_key = RR.create("dlv.isc.org. IN DNSKEY 257 3 5 BEAAAAPHMu/5onzrEE7z1egmhg/WPO0+juoZrW3euWEn4MxDCE1+lLy2 brhQv5rN32RKtMzX6Mj70jdzeND4XknW58dnJNPCxn8+jAGl2FZLK8t+ 1uq4W+nnA3qO2+DL+k6BD4mewMLbIYFwe0PG73Te9fZ2kJb56dhgMde5 ymX4BI/oQ+cAK50/xvJv00Frf8kw6ucMTwFlgPe+jnGxPPEmHAte/URk Y62ZfkLoBAADLHQ9IrS2tryAe7mbBZVcOwIeU/Rw/mRx/vwwMCTgNboM QKtUdvNXDrYJDSHZws3xiRXF1Rf+al9UmZfSav/4NWLKjHzpT59k/VSt TDN0YUuWrBNh")
24
- Dnssec.add_dlv_key(dlv_key)
30
+ dlv_key = Dnsruby::RR.create("dlv.isc.org. IN DNSKEY 257 3 5 BEAAAAPHMu/5onzrEE7z1egmhg/WPO0+juoZrW3euWEn4MxDCE1+lLy2 brhQv5rN32RKtMzX6Mj70jdzeND4XknW58dnJNPCxn8+jAGl2FZLK8t+ 1uq4W+nnA3qO2+DL+k6BD4mewMLbIYFwe0PG73Te9fZ2kJb56dhgMde5 ymX4BI/oQ+cAK50/xvJv00Frf8kw6ucMTwFlgPe+jnGxPPEmHAte/URk Y62ZfkLoBAADLHQ9IrS2tryAe7mbBZVcOwIeU/Rw/mRx/vwwMCTgNboM QKtUdvNXDrYJDSHZws3xiRXF1Rf+al9UmZfSav/4NWLKjHzpT59k/VSt TDN0YUuWrBNh")
31
+ Dnsruby::Dnssec.add_dlv_key(dlv_key)
25
32
 
26
- res = Dnsruby::Recursor.new
33
+ resolver = Dnsruby::Recursor.new
27
34
  # TheLog.level = Logger::DEBUG
28
35
 
29
36
 
30
- res.recursion_callback=(Proc.new { |packet|
37
+ resolver.recursion_callback = Proc.new do |packet|
38
+ packet.additional.each { |a| puts a }
39
+ puts(";; Received #{packet.answersize} bytes from #{packet.answerfrom}. Security Level = #{packet.security_level.string}\n")
40
+ puts "\n#{'-' * 79}\n"
41
+ end
31
42
 
32
- packet.additional.each { |a| print a.to_s + "\n" }
33
43
 
34
- print(";; Received #{packet.answersize} bytes from #{packet.answerfrom}. Security Level = #{packet.security_level.string}\n\n")
35
- })
44
+ domain = ARGV[0]
45
+ type = ARGV[1] || Types.A
36
46
 
37
- type = ARGV[1]
38
- if (type == nil)
39
- type = Types.A
40
- end
41
47
  begin
42
- ret = res.query(ARGV[0], type)
43
- print "\nRESPONSE : #{ret}\n"
44
- rescue NXDomain
45
- print "Domain doesn't exist\n"
48
+ response = resolver.query(domain, type)
49
+ puts "\nRESPONSE : #{response}"
50
+ rescue Dnsruby::NXDomain
51
+ puts "Domain '#{domain}' doesn't exist"
46
52
  end
@@ -31,6 +31,7 @@ module Dnsruby
31
31
  class Cache # :nodoc: all
32
32
  def initialize()
33
33
  @cache = Hash.new
34
+ @@max_size = 16*1024 # Get this right...
34
35
  @mutex = Mutex.new
35
36
  end
36
37
  def cache
@@ -44,6 +45,9 @@ module Dnsruby
44
45
  def length
45
46
  return @cache.length
46
47
  end
48
+ def Cache.max_size=(length)
49
+ @@max_size = length
50
+ end
47
51
  def add(message)
48
52
  q = message.question[0]
49
53
  key = CacheKey.new(q.qname, q.qtype, q.qclass).to_s
@@ -55,6 +59,10 @@ module Dnsruby
55
59
  TheLog.debug("CACHE ADD : #{q.qname}, #{q.qtype}\n")
56
60
  end
57
61
  @cache[key] = data
62
+
63
+ while @cache.size > @@max_size # keep the cache size reasonable
64
+ @cache.shift
65
+ end
58
66
  }
59
67
  end
60
68
  # This method "fixes up" the response, so that the header and ttls are OK
@@ -290,7 +290,7 @@ module Dnsruby
290
290
  end
291
291
  rescue Exception => e
292
292
  Dnsruby.log.error{"Can't make sense of nameserver : #{server}, exception : #{e}"}
293
- # raise ArgumentError.new("Can't make sense of nameserver : #{server}, exception : #{e}")
293
+ raise ArgumentError.new("Can't make sense of nameserver : #{server}, exception : #{e}")
294
294
  return nil
295
295
  end
296
296
  end
@@ -66,7 +66,7 @@ module Dnsruby
66
66
  @@validation_policy = ValidationPolicy::LOCAL_ANCHORS_THEN_ROOT
67
67
 
68
68
  def Dnssec.validation_policy=(p)
69
- if ((p >= ALWAYS_ROOT_ONY) && (p <= ALWAYS_LOCAL_ANCHORS))
69
+ if ((p >= ValidationPolicy::ALWAYS_ROOT_ONLY) && (p <= ValidationPolicy::ALWAYS_LOCAL_ANCHORS_ONLY))
70
70
  @@validation_policy = p
71
71
  # @TODO@ Should we be clearing the trusted keys now?
72
72
  end
@@ -203,6 +203,7 @@ module Dnsruby
203
203
  end
204
204
  rescue VerifyError => e
205
205
  msg.security_error = e
206
+ msg.security_level = Message::SecurityLevel.BOGUS
206
207
  end
207
208
  end
208
209
 
@@ -240,13 +241,16 @@ module Dnsruby
240
241
  Proc.new{|m, q| validate_with_anchors(m, q)}, msg, query)
241
242
  end
242
243
  end
243
- if (last_level != Message::SecurityLevel.SECURE)
244
+ if (last_level != Message::SecurityLevel.SECURE && last_level != Message::SecurityLevel.BOGUS)
244
245
  last_level, last_error, last_error_level = try_validation(last_level, last_error, last_error_level,
245
246
  Proc.new{|m, q| validate_with_dlv(m, q)}, msg, query)
246
247
  end
247
248
  # Set the message security level!
248
249
  msg.security_level = last_level
249
250
  msg.security_error = last_error
251
+ if (last_error && last_error.index("ification error"))
252
+ msg.security_level = Message::SecurityLevel.BOGUS
253
+ end
250
254
  raise VerifyError.new(last_error) if (last_level < 0)
251
255
  return (msg.security_level.code > Message::SecurityLevel::UNCHECKED)
252
256
  end
@@ -154,6 +154,7 @@ class MessageDecoder #:nodoc: all
154
154
  def get_question
155
155
  name = self.get_name
156
156
  type, klass = self.get_unpack('nn')
157
+ klass = Classes.new(klass)
157
158
  Question.new(name, type, klass)
158
159
  end
159
160
 
@@ -66,7 +66,7 @@ class Question
66
66
  other.is_a?(Question) &&
67
67
  self.qname == other.qname &&
68
68
  self.qtype == other.qtype &&
69
- self.qclass == other.qclass
69
+ self.qclass == Classes.new(other.qclass)
70
70
  end
71
71
 
72
72
  # Returns a string representation of the question record.
@@ -59,6 +59,10 @@ module Dnsruby
59
59
  @@authoritative_cache.clear
60
60
  end
61
61
 
62
+ def PacketSender.recursive_cache_length
63
+ @@recursive_cache.length
64
+ end
65
+
62
66
  attr_accessor :packet_timeout
63
67
 
64
68
  # The port on the resolver to send queries to.
@@ -318,7 +318,11 @@ module Dnsruby
318
318
  @@hints = Hash.new
319
319
  @@hints[0] = temp
320
320
  end
321
- @@nameservers = @@hints.values
321
+ # @@nameservers = @@hints.values
322
+ @@nameservers=[]
323
+ @@hints.each {|key, value|
324
+ @@nameservers.push(key)
325
+ }
322
326
  return @@nameservers
323
327
  end
324
328
 
@@ -427,6 +431,10 @@ module Dnsruby
427
431
  if (Name === n)
428
432
  n = n.to_s # @TODO@ This is a bit crap!
429
433
  end
434
+ if (n == nil)
435
+ TheLog.error("Name is nil")
436
+ raise ResolvError.new("Nameserver invalid!")
437
+ end
430
438
  name = n.tr("","")
431
439
  if (name[name.length-1] != ".")
432
440
  name = name + "."
@@ -142,7 +142,7 @@ module Dnsruby
142
142
  end
143
143
 
144
144
  def payloadsize=(size)
145
- self.klass=size
145
+ self.klass=Classes.new(size)
146
146
  end
147
147
 
148
148
  def options(args)
@@ -242,7 +242,7 @@ module Dnsruby
242
242
  @options.each do |opt|
243
243
  msg.put_pack('n', opt.code)
244
244
  msg.put_pack('n', opt.data.length)
245
- msg.put_bytes(opt.data)
245
+ msg.put_pack('a*', opt.data)
246
246
  end
247
247
  end
248
248
  end
@@ -141,7 +141,7 @@ class RR
141
141
  def RR.new_from_hash(inhash)
142
142
  hash = inhash.clone
143
143
  type = hash[:type] || Types::ANY
144
- klass = hash[:klass] || Classes::IN
144
+ klass = Classes.new(hash[:klass] || Classes::IN)
145
145
  ttl = hash[:ttl] || 0
146
146
  record_class = get_class(type, klass)
147
147
  record = record_class.new
@@ -151,7 +151,7 @@ class RR
151
151
  end
152
152
  record.ttl = ttl
153
153
  record.type = type
154
- record.klass = klass
154
+ record.klass = Classes.new(klass)
155
155
  hash.delete(:name)
156
156
  hash.delete(:type)
157
157
  hash.delete(:ttl)
@@ -266,7 +266,7 @@ class RR
266
266
  record.name = Name.create(name)
267
267
  record.ttl = ttl
268
268
  record.type = rrtype
269
- record.klass = rrclass
269
+ record.klass = Classes.new(rrclass)
270
270
  record
271
271
  end
272
272
 
@@ -283,7 +283,7 @@ class RR
283
283
  record.name = Name.create(name)
284
284
  record.ttl = ttl
285
285
  record.type = rrtype
286
- record.klass = rrclass
286
+ record.klass = Classes.new(rrclass)
287
287
  return record
288
288
  end
289
289
  end
@@ -712,8 +712,8 @@ module Dnsruby
712
712
  # validate it only if it has not been validated already
713
713
  # So, if we need to validate it, send it to the validation thread
714
714
  # Otherwise, send VALIDATED to the requester.
715
- if (((msg.security_level == Message::SecurityLevel::UNCHECKED) ||
716
- (msg.security_level == Message::SecurityLevel::INDETERMINATE)) &&
715
+ if (((msg.security_level == Message::SecurityLevel.UNCHECKED) ||
716
+ (msg.security_level == Message::SecurityLevel.INDETERMINATE)) &&
717
717
  (ValidatorThread.requires_validation?(query, msg, err, res)))
718
718
  validator = ValidatorThread.new(client_id, client_queue, msg, err, query ,self, res)
719
719
  validator.run
@@ -1044,7 +1044,9 @@ module Dnsruby
1044
1044
  rescue VerifyError => e
1045
1045
  # print "FAILED TO VERIFY DS RRSET FOR #{child}\n"
1046
1046
  TheLog.info("FAILED TO VERIFY DS RRSET FOR #{child}")
1047
- return false, nil
1047
+ # return false, nil
1048
+ # raise ResolvError.new("FAILED TO VERIFY DS RRSET FOR #{child}")
1049
+ raise VerifyError.new("FAILED TO VERIFY DS RRSET FOR #{child}")
1048
1050
  end
1049
1051
  end
1050
1052
  end
@@ -1084,7 +1086,8 @@ module Dnsruby
1084
1086
  rescue ResolvError => e
1085
1087
  # print "Error getting DNSKEY for #{child} : #{e}\n"
1086
1088
  TheLog.error("Error getting DNSKEY for #{child} : #{e}")
1087
- return false, nil
1089
+ # return false, nil
1090
+ raise VerifyError.new("Error getting DNSKEY for #{child} : #{e}")
1088
1091
  end
1089
1092
  verified = true
1090
1093
  key_rrset = key_ret.answer.rrset(child, Types.DNSKEY)
@@ -1110,6 +1113,7 @@ module Dnsruby
1110
1113
  verify(key_rrset)
1111
1114
  rescue VerifyError =>e
1112
1115
  verified = false
1116
+ raise VerifyError.new("Couldn't verify DNSKEY and DS records")
1113
1117
  end
1114
1118
  end
1115
1119
  end
@@ -1122,13 +1126,15 @@ module Dnsruby
1122
1126
  if (!verified)
1123
1127
  TheLog.info("Failed to verify DNSKEY for #{child}")
1124
1128
  return false, nil # new_res
1129
+ # raise VerifyError.new("Failed to verify DNSKEY for #{child}")
1125
1130
  end
1126
1131
  # Cache.add(key_ret)
1127
1132
  return key_rrset, new_res
1128
1133
  rescue VerifyError => e
1129
1134
  # print "Verification error : #{e}\n"
1130
1135
  TheLog.info("Verification error : #{e}\n")
1131
- return false, nil # new_res
1136
+ # return false, nil # new_res
1137
+ raise VerifyError.new("Verification error : #{e}\n")
1132
1138
  end
1133
1139
  end
1134
1140
 
@@ -1271,6 +1277,9 @@ module Dnsruby
1271
1277
  msg.security_level = Message::SecurityLevel.INDETERMINATE
1272
1278
  qname = msg.question()[0].qname
1273
1279
  closest_anchor = find_closest_anchor_for(qname)
1280
+ if (!closest_anchor)
1281
+
1282
+ end
1274
1283
  TheLog.debug("Closest anchor for #{qname} is #{closest_anchor} - trying to follow down")
1275
1284
  error = try_to_follow_from_anchor(closest_anchor, msg, qname)
1276
1285
 
@@ -1304,6 +1313,9 @@ module Dnsruby
1304
1313
  if (error)
1305
1314
  raise error
1306
1315
  end
1316
+ if (msg.security_level == Message::SecurityLevel.BOGUS)
1317
+ raise VerifyError.new("Bogus record")
1318
+ end
1307
1319
  if (msg.security_level.code > Message::SecurityLevel::UNCHECKED)
1308
1320
  return true
1309
1321
  else
@@ -1315,7 +1327,15 @@ module Dnsruby
1315
1327
  error = nil
1316
1328
  if (closest_anchor)
1317
1329
  # Then try to descend to the level we're interested in
1318
- actual_anchor = follow_chain(closest_anchor, qname)
1330
+ actual_anchor = false
1331
+ begin
1332
+ actual_anchor = follow_chain(closest_anchor, qname)
1333
+ rescue VerifyError => e
1334
+ TheLog.debug("Broken chain from anchor : #{closest_anchor.name}")
1335
+ msg.security_level = Message::SecurityLevel.BOGUS
1336
+ return e
1337
+ end
1338
+ # @TODO@ We need to de ermine whether there was simply no DS record, or whether there was a failure
1319
1339
  if (!actual_anchor)
1320
1340
  TheLog.debug("Unable to follow chain from anchor : #{closest_anchor.name}")
1321
1341
  msg.security_level = Message::SecurityLevel.INSECURE