dnsruby 1.58.0 → 1.59.0

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