dnsruby 1.44 → 1.45

Sign up to get free protection for your applications and to get access to all the features.
@@ -71,7 +71,7 @@ if (type.upcase == "AXFR")
71
71
 
72
72
  else
73
73
 
74
- Dnsruby::TheLog.level=Logger::DEBUG
74
+ # Dnsruby::TheLog.level=Logger::DEBUG
75
75
  begin
76
76
  answer = nil
77
77
  answer = res.query(name, type, klass)
@@ -255,8 +255,36 @@ module Dnsruby
255
255
  rescue Exception
256
256
  begin
257
257
  # try to resolve server to address
258
- addr = TCPSocket.gethostbyname(ns)[3] # @TODO@ Replace this with Dnsruby call when lookups work
259
- server = addr
258
+ if ns == "localhost"
259
+ server = "127.0.0.1"
260
+ else
261
+ # Use Dnsruby to resolve the servers
262
+ # First, try the default resolvers
263
+ resolver = Resolver.new
264
+ found = false
265
+ begin
266
+ ret = resolver.query(ns)
267
+ ret.answer.each {|rr|
268
+ if ([Types::A, Types::AAAA].include?rr.type)
269
+ addr = rr.address.to_s
270
+ server = addr
271
+ found = true
272
+ end
273
+ }
274
+ rescue Exception
275
+ end
276
+ if (!found)
277
+ # That didn't work - try recursing from the root
278
+ recursor = Recursor.new
279
+ ret = recursor.query(ns)
280
+ ret.answer.each {|rr|
281
+ if ([Types::A, Types::AAAA].include?rr.type)
282
+ addr = rr.address.to_s
283
+ server = addr
284
+ end
285
+ }
286
+ end
287
+ end
260
288
  rescue Exception => e
261
289
  Dnsruby.log.error{"Can't make sense of nameserver : #{server}, exception : #{e}"}
262
290
  # raise ArgumentError.new("Can't make sense of nameserver : #{server}, exception : #{e}")
@@ -416,7 +444,7 @@ module Dnsruby
416
444
  if (name.length == 1)
417
445
  candidates.concat([Name.create(name.to_a)])
418
446
  end
419
- end
447
+ end
420
448
  end
421
449
  return candidates
422
450
  end
@@ -14,6 +14,7 @@
14
14
  #limitations under the License.
15
15
  #++
16
16
  require 'Dnsruby/select_thread'
17
+ require 'ipaddr'
17
18
  #require 'Dnsruby/iana_ports'
18
19
  module Dnsruby
19
20
  class PacketSender # :nodoc: all
@@ -76,7 +77,7 @@ module Dnsruby
76
77
  # The source address to send queries from
77
78
  #
78
79
  # Defaults to localhost
79
- attr_accessor :src_address
80
+ attr_reader :src_address
80
81
 
81
82
  # should the Recursion Desired bit be set on queries?
82
83
  #
@@ -95,6 +96,24 @@ module Dnsruby
95
96
  # dnssec defaults to ON
96
97
  attr_reader :dnssec
97
98
 
99
+ # Set the source address. If the arg is nil, do nothing
100
+ def src_address=(arg)
101
+ if (not arg.nil?)
102
+ @src_address = arg
103
+ end
104
+ # Do some verification to make sure that the source address
105
+ # is of the same type as the server address
106
+ if (@server.nil?)
107
+ return
108
+ else
109
+ si = IPAddr.new(@src_address)
110
+ i = IPAddr.new(@server)
111
+ if (i.ipv4? and si.ipv6?) or (i.ipv6? and si.ipv4?)
112
+ raise ArgumentError.new("Invalid address specified (address family does not match)")
113
+ end
114
+ end
115
+ end
116
+
98
117
  #Sets the TSIG to sign outgoing messages with.
99
118
  #Pass in either a Dnsruby::RR::TSIG, or a key_name and key (or just a key)
100
119
  #Pass in nil to stop tsig signing.
@@ -174,6 +193,17 @@ module Dnsruby
174
193
  #Check server is IP
175
194
  @server=Config.resolve_server(@server)
176
195
 
196
+ begin
197
+ i = IPv4.create(@server)
198
+ @src_address = '0.0.0.0'
199
+ rescue Exception
200
+ begin
201
+ i = IPv6.create(@server)
202
+ @src_address = '::'
203
+ rescue Exception
204
+ Dnsruby.log.error{"Server is neither IPv4 or IPv6!\n"}
205
+ end
206
+ end
177
207
  # ResolverRegister::register_single_resolver(self)
178
208
  end
179
209
 
@@ -320,7 +350,7 @@ module Dnsruby
320
350
  socket = UDPSocket.new()
321
351
  else
322
352
  ipv6 = @src_address =~ /:/
323
- socket = UDPSocket.new(ipv6 ? Socket::AF_INET6 : Socket::AF_INET)
353
+ socket = UDPSocket.new(ipv6.nil? ? Socket::AF_INET : Socket::AF_INET6)
324
354
  end
325
355
  socket.bind(@src_address, src_port)
326
356
  socket.connect(@server, @port)
@@ -292,6 +292,8 @@ module Dnsruby
292
292
  Recursor.set_hints(Hash.new, resolver)
293
293
  @@zones_cache = Hash.new # key zone_name, values Hash of servers and AddressCaches
294
294
  @@zones_cache["."] = @@hints
295
+
296
+ @@authority_cache = Hash.new
295
297
  end
296
298
 
297
299
  def query_no_validation_or_recursion(name, type=Types.A, klass=Classes.IN) # :nodoc: all
@@ -460,7 +460,7 @@ module Dnsruby
460
460
  @tsig = nil
461
461
  @ignore_truncation = false
462
462
  @config = Config.new()
463
- @src_address = '0.0.0.0'
463
+ @src_address = nil
464
464
  @src_port = [0]
465
465
  @recurse = true
466
466
  @single_res_mutex.synchronize {
@@ -63,7 +63,7 @@ module Dnsruby
63
63
  @use_tcp = false
64
64
  @tsig = nil
65
65
  @ignore_truncation = false
66
- @src_address = '0.0.0.0'
66
+ @src_address = nil
67
67
  @src_port = [0]
68
68
  @recurse = true
69
69
  @persistent_udp = false
@@ -73,34 +73,50 @@ module Dnsruby
73
73
  @single_resolvers = []
74
74
  @configured = false
75
75
  @do_caching = true
76
- @config = Config.new
76
+ @config = Config.new
77
77
 
78
78
  if (arg==nil)
79
79
  # Get default config
80
- # @config = Config.new
81
- ## @server = config.nameserver[0]
80
+ @config = Config.new
81
+ @config.get_ready
82
+ @server = @config.nameserver[0]
82
83
  elsif (arg.kind_of?String)
83
84
  @config.get_ready
84
85
  @configured= true
85
- @server=arg
86
+ @config.nameserver=[arg]
87
+ @server = @config.nameserver[0]
88
+ # @server=arg
86
89
  elsif (arg.kind_of?Name)
87
90
  @config.get_ready
88
91
  @configured= true
89
- @server=arg
92
+ @config.nameserver=arg
93
+ @server = @config.nameserver[0]
94
+ # @server=arg
90
95
  elsif (arg.kind_of?Hash)
91
96
  arg.keys.each do |attr|
92
- begin
93
- send(attr.to_s+"=", arg[attr])
94
- rescue Exception
95
- Dnsruby.log.error{"Argument #{attr} not valid\n"}
97
+ if (attr == :server)
98
+ @config.get_ready
99
+ @configured= true
100
+ @config.nameserver=[arg[attr]]
101
+ @server = @config.nameserver[0]
102
+
103
+ else
104
+ begin
105
+ send(attr.to_s+"=", arg[attr])
106
+ rescue Exception
107
+ Dnsruby.log.error{"Argument #{attr} not valid\n"}
108
+ end
96
109
  end
97
- # end
98
110
  end
99
111
  end
100
- #Check server is IP
101
- # @server=Config.resolve_server(@server)
102
- isr = PacketSender.new(*args)
103
- # isr.server = @server
112
+
113
+ isr = PacketSender.new({:server=>@server, :dnssec=>@dnssec,
114
+ :use_tcp=>@use_tcp, :packet_timeout=>@packet_timeout,
115
+ :tsig => @tsig, :ignore_truncation=>@ignore_truncation,
116
+ :src_address=>@src_address, :src_port=>@src_port,
117
+ :do_caching=>@do_caching,
118
+ :recurse=>@recurse, :udp_size=>@udp_size})
119
+
104
120
  @single_resolvers = [isr]
105
121
 
106
122
  # ResolverRegister::register_single_resolver(self)
@@ -109,22 +125,28 @@ module Dnsruby
109
125
  def server=(s)
110
126
  if (!@configured)
111
127
  @config.get_ready
112
- add_config_nameservers
113
128
  end
114
- isr = PacketSender.new(s)
115
- @single_res_mutex.synchronize {
116
- @single_resolvers = [isr]
117
- }
129
+ @server = Config.resolve_server(s).to_s
130
+ isr = PacketSender.new({:server=>@server, :dnssec=>@dnssec,
131
+ :use_tcp=>@use_tcp, :packet_timeout=>@packet_timeout,
132
+ :tsig => @tsig, :ignore_truncation=>@ignore_truncation,
133
+ :src_address=>@src_address, :src_port=>@src_port,
134
+ :do_caching=>@do_caching,
135
+ :recurse=>@recurse, :udp_size=>@udp_size})
136
+
137
+ @single_res_mutex.synchronize {
138
+ @single_resolvers = [isr]
139
+ }
118
140
  end
119
141
 
120
142
  def server
121
- # @single_res_mutex.synchronize {
143
+ # @single_res_mutex.synchronize {
122
144
  if (!@configured)
123
145
  @config.get_ready
124
146
  add_config_nameservers
125
147
  end
126
- return @single_resolvers[0].server
127
- # }
148
+ return @single_resolvers[0].server
149
+ # }
128
150
  end
129
151
 
130
152
  def retry_times=(n) # :nodoc:
@@ -149,5 +171,5 @@ module Dnsruby
149
171
 
150
172
  alias :query_timeout :packet_timeout
151
173
  alias :query_timeout= :packet_timeout=
152
- end
174
+ end
153
175
  end
@@ -19,31 +19,31 @@ require 'Dnsruby/key_cache'
19
19
  require 'Dnsruby/single_verifier'
20
20
  module Dnsruby
21
21
 
22
- # RFC4033, section 7
23
- # "There is one more step that a security-aware stub resolver can take
24
- # if, for whatever reason, it is not able to establish a useful trust
25
- # relationship with the recursive name servers that it uses: it can
26
- # perform its own signature validation by setting the Checking Disabled
27
- # (CD) bit in its query messages. A validating stub resolver is thus
28
- # able to treat the DNSSEC signatures as trust relationships between
29
- # the zone administrators and the stub resolver itself. "
30
- #
31
- # Dnsruby is configured to validate responses by default. However, it is not
32
- # configured with any trusted keys by default. Applications may use the
33
- # verify() method to perform verification with of RRSets of Messages with
34
- # given keys. Alternatively, trusted keys may be added to this class (either
35
- # directly, or by loading the IANA TAR or the DLV ISC ZSK). Validation will then
36
- # be performed from these keys (or the DLV registry, if configured). Negative
37
- # and positive responses are validation.
38
- #
39
- # Messages are tagged with the current security_level (Message::SecurityLevel).
40
- # UNCHECKED means Dnsruby has not attempted to validate the response.
41
- # BOGUS means the response has been checked, and is bogus.
42
- # INSECURE means the response has been validated to be insecure (e.g. in an unsigned zone)
43
- # SECURE means that the response has been verfied to be correct.
44
- #
45
- # Several validators are provided, with each maintaining its own cache of trusted keys.
46
- # If validators are added or removed, the caches of the other validators are not affected.
22
+ # RFC4033, section 7
23
+ # "There is one more step that a security-aware stub resolver can take
24
+ # if, for whatever reason, it is not able to establish a useful trust
25
+ # relationship with the recursive name servers that it uses: it can
26
+ # perform its own signature validation by setting the Checking Disabled
27
+ # (CD) bit in its query messages. A validating stub resolver is thus
28
+ # able to treat the DNSSEC signatures as trust relationships between
29
+ # the zone administrators and the stub resolver itself. "
30
+ #
31
+ # Dnsruby is configured to validate responses by default. However, it is not
32
+ # configured with any trusted keys by default. Applications may use the
33
+ # verify() method to perform verification with of RRSets of Messages with
34
+ # given keys. Alternatively, trusted keys may be added to this class (either
35
+ # directly, or by loading the IANA TAR or the DLV ISC ZSK). Validation will then
36
+ # be performed from these keys (or the DLV registry, if configured). Negative
37
+ # and positive responses are validation.
38
+ #
39
+ # Messages are tagged with the current security_level (Message::SecurityLevel).
40
+ # UNCHECKED means Dnsruby has not attempted to validate the response.
41
+ # BOGUS means the response has been checked, and is bogus.
42
+ # INSECURE means the response has been validated to be insecure (e.g. in an unsigned zone)
43
+ # SECURE means that the response has been verfied to be correct.
44
+ #
45
+ # Several validators are provided, with each maintaining its own cache of trusted keys.
46
+ # If validators are added or removed, the caches of the other validators are not affected.
47
47
  class Dnssec
48
48
  # A class to cache trusted keys
49
49
 
@@ -117,11 +117,23 @@ module Dnsruby
117
117
  }
118
118
  end
119
119
 
120
+ def self.reset
121
+ @@validation_policy = ValidationPolicy::LOCAL_ANCHORS_THEN_ROOT
122
+ @@root_verifier = SingleVerifier.new(SingleVerifier::VerifierType::ROOT)
123
+
124
+ @@dlv_verifier = SingleVerifier.new(SingleVerifier::VerifierType::DLV)
125
+
126
+ # @TODO@ Could add a new one of these for each anchor.
127
+ @@anchor_verifier = SingleVerifier.new(SingleVerifier::VerifierType::ANCHOR)
128
+ @@do_validation_with_recursor = true # Many nameservers don't handle DNSSEC correctly yet
129
+ @@default_resolver = Resolver.new
130
+ end
131
+
120
132
  def self.no_keys?
121
133
  no_keys = true
122
134
  [@@anchor_verifier, @@root_verifier, @@dlv_verifier].each {|v|
123
135
  if (v.trusted_keys.length() > 0 ||
124
- v.trust_anchors.length() > 0)
136
+ v.trust_anchors.length() > 0)
125
137
  no_keys = false
126
138
  end
127
139
  }
@@ -143,7 +155,7 @@ module Dnsruby
143
155
  if (first.class == String)
144
156
  first = first.getbyte(0) # Ruby 1.9
145
157
  end
146
- # print "Reading ITAR : #{line}, first : #{first}\n"
158
+ # print "Reading ITAR : #{line}, first : #{first}\n"
147
159
  next if (first==59) # ";")
148
160
  if (line.strip=~(/^DS /) || line.strip=~(/^DNSKEY /))
149
161
  line = lastname.to_s + ((lastname.absolute?)?".":"") + " " + line
@@ -43,7 +43,7 @@ module Dnsruby
43
43
  @address = address
44
44
  end
45
45
 
46
- # A String representation of thi IPv4 address.
46
+ # A String representation of the IPv4 address.
47
47
  attr_reader :address
48
48
 
49
49
  def to_s #:nodoc:
@@ -47,6 +47,8 @@ module Dnsruby
47
47
  attr_reader :algorithm
48
48
  #The public key
49
49
  attr_reader :key
50
+ #The length (in bits) of the key - NOT key.length
51
+ attr_reader :key_length
50
52
 
51
53
  def init_defaults
52
54
  @make_new_key_tag = false
@@ -293,6 +295,7 @@ module Dnsruby
293
295
  key_text.gsub!(/ /, "")
294
296
  # @key=Base64.decode64(key_text)
295
297
  @key=key_text.unpack("m*")[0]
298
+ public_key
296
299
  get_new_key_tag
297
300
  end
298
301
 
@@ -311,7 +314,7 @@ module Dnsruby
311
314
  # @TODO@ Support other key encodings!
312
315
  return @public_key
313
316
  end
314
-
317
+
315
318
  def rsa_key
316
319
  exponentLength = @key[0]
317
320
  if (exponentLength.class == String)
@@ -330,6 +333,7 @@ module Dnsruby
330
333
  pos += exponentLength
331
334
 
332
335
  modulus = RR::get_num(@key[pos, @key.length])
336
+ @key_length = (@key.length - pos) * 8
333
337
 
334
338
  pkey = OpenSSL::PKey::RSA.new
335
339
  pkey.e = exponent
@@ -350,6 +354,7 @@ module Dnsruby
350
354
  pos += pgy_len
351
355
  y = RR::get_num(@key[pos, pgy_len])
352
356
  pos += pgy_len
357
+ @key_length = (pgy_len * 8)
353
358
 
354
359
  pkey = OpenSSL::PKey::DSA.new
355
360
  pkey.p = p
@@ -401,6 +401,8 @@ module Dnsruby
401
401
  return
402
402
  end
403
403
  else
404
+ # @TODO@ Can we get recvfrom to stop issuing PTR queries when we already
405
+ # know both the FQDN and the IP address?
404
406
  if (ret = socket.recvfrom(packet_size))
405
407
  buf = ret[0]
406
408
  answerport=ret[1][1]
@@ -55,15 +55,15 @@ module Dnsruby
55
55
  end
56
56
 
57
57
  def get_dlv_resolver # :nodoc:
58
- if (Dnssec.do_validation_with_recursor?)
59
- return Recursor.new
60
- else
58
+ # if (Dnssec.do_validation_with_recursor?)
59
+ # return Recursor.new
60
+ # else
61
61
  if (Dnssec.default_resolver)
62
62
  return Dnssec.default_resolver
63
63
  else
64
64
  return Resolver.new
65
65
  end
66
- end
66
+ # end
67
67
  end
68
68
  def add_dlv_key(key)
69
69
  # Is this a ZSK or a KSK?
@@ -168,6 +168,7 @@ module Dnsruby
168
168
  # Wipes the cache of trusted keys
169
169
  def clear_trusted_keys
170
170
  @trusted_keys = KeyCache.new
171
+ @res = nil
171
172
  @discovered_ds_store = []
172
173
  @configured_ds_store = []
173
174
  end
@@ -1061,7 +1062,7 @@ module Dnsruby
1061
1062
  if (!k.zone_key?)
1062
1063
  # print "Discovered DNSKEY is not a zone key - ignoring\n"
1063
1064
  TheLog.debug("Discovered DNSKEY is not a zone key - ignoring")
1064
- return false, new_res
1065
+ return false, child_res
1065
1066
  end
1066
1067
  }
1067
1068
  begin
@@ -1120,7 +1121,7 @@ module Dnsruby
1120
1121
 
1121
1122
  ns_rrset = ns_ret.answer.rrset(name, Types.NS)
1122
1123
  if (!ns_rrset || ns_rrset.length == 0)
1123
- ns_rrset = ns_ret.authority.rrset(name, Types.NS) # @TOO@ Is ths OK?
1124
+ ns_rrset = ns_ret.authority.rrset(name, Types.NS) # @TODO@ Is ths OK?
1124
1125
  end
1125
1126
  if (!ns_rrset || ns_rrset.length == 0 || ns_rrset.name.canonical != name.canonical)
1126
1127
  return nil
@@ -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.44
107
+ VERSION = 1.45
108
108
  def Dnsruby.version
109
109
  return VERSION
110
110
  end
@@ -90,6 +90,7 @@ class TestCache < Test::Unit::TestCase
90
90
  def test_online
91
91
  # Get the records back from the test zone
92
92
  Dnsruby::PacketSender.clear_caches
93
+ Dnsruby::Recursor.clear_caches
93
94
  res = SingleResolver.new("ns0.validation-test-servers.nominet.org.uk.")
94
95
  res.udp_size = 4096
95
96
  query = Message.new("overflow.dnsruby.validation-test-servers.nominet.org.uk", Types.TXT)
@@ -20,12 +20,11 @@ include Dnsruby
20
20
 
21
21
  class TestItar < Test::Unit::TestCase
22
22
  def test_itar
23
- Dnsruby::Dnssec.clear_trusted_keys
24
- Dnsruby::Dnssec.clear_trust_anchors
23
+ Dnsruby::Dnssec.reset
25
24
  Dnsruby::PacketSender.clear_caches
25
+ Dnsruby::Recursor.clear_caches
26
26
  run_test_se(true)
27
- Dnsruby::Dnssec.clear_trusted_keys
28
- Dnsruby::Dnssec.clear_trust_anchors
27
+ Dnsruby::Dnssec.reset
29
28
  Dnsruby::Recursor.clear_caches
30
29
 
31
30
  # Then try to validate some records in the published zones
@@ -37,16 +36,14 @@ class TestItar < Test::Unit::TestCase
37
36
  end
38
37
 
39
38
  def test_with_no_dlv_anchor
40
- Dnsruby::Dnssec.clear_trusted_keys
41
- Dnsruby::Dnssec.clear_trust_anchors
39
+ Dnsruby::Dnssec.reset
42
40
  Dnsruby::PacketSender.clear_caches
43
41
  Dnsruby::Recursor.clear_caches
44
42
  # Make sure we don't have any other anchors configured!
45
43
  res = Dnsruby::Recursor.new
46
44
  ret = res.query("frobbit.se.", Dnsruby::Types.A)
47
45
  assert(ret.security_level == Dnsruby::Message::SecurityLevel::INSECURE, "Level = #{ret.security_level.string}")
48
- Dnsruby::Dnssec.clear_trusted_keys
49
- Dnsruby::Dnssec.clear_trust_anchors
46
+ Dnsruby::Dnssec.reset
50
47
  Dnsruby::PacketSender.clear_caches
51
48
  Dnsruby::Recursor.clear_caches
52
49
  Dnssec.load_itar
@@ -186,11 +186,11 @@ class TestSingleResolver < Test::Unit::TestCase
186
186
 
187
187
  res.server=('a.t.dnsruby.validation-test-servers.nominet.org.uk')
188
188
  ip = res.server
189
- assert_equal('10.0.1.128', ip, 'nameserver() looks up IP.')
189
+ assert_equal('10.0.1.128', ip.to_s, 'nameserver() looks up IP.')
190
190
 
191
191
  res.server=('cname.t.dnsruby.validation-test-servers.nominet.org.uk')
192
192
  ip = res.server
193
- assert_equal(ip, '10.0.1.128', 'nameserver() looks up cname.')
193
+ assert_equal('10.0.1.128', ip.to_s, 'nameserver() looks up cname.')
194
194
  end
195
195
 
196
196
  def test_truncated_response
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.44"
4
+ version: "1.45"
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-03-03 00:00:00 +00:00
12
+ date: 2010-03-17 00:00:00 +00:00
13
13
  default_executable:
14
14
  dependencies: []
15
15