dnsruby 1.30 → 1.31

Sign up to get free protection for your applications and to get access to all the features.
@@ -39,10 +39,18 @@ module Dnsruby
39
39
  #The Salt Length field defines the length of the Salt field in octets,
40
40
  #ranging in value from 0 to 255.
41
41
  attr_reader :salt_length
42
+
42
43
  #The Salt field is appended to the original owner name before hashing
43
44
  #in order to defend against pre-calculated dictionary attacks.
44
- attr_accessor :salt
45
-
45
+ def salt
46
+ return NSEC3.encode_salt(@salt)
47
+ end
48
+
49
+ def salt=(s)
50
+ @salt = NSEC3.decode_salt(s)
51
+ @salt_length = @salt.length
52
+ end
53
+
46
54
  def hash_alg=(a)
47
55
  if (a.instance_of?String)
48
56
  if (a.length == 1)
@@ -50,11 +58,11 @@ module Dnsruby
50
58
  end
51
59
  end
52
60
  begin
53
- alg = Algorithms.new(a)
61
+ alg = Nsec3HashAlgorithms.new(a)
54
62
  @hash_alg = alg
55
63
  rescue ArgumentError => e
56
64
  raise DecodeError.new(e)
57
- end
65
+ end
58
66
  end
59
67
 
60
68
  def types=(t)
@@ -69,19 +77,19 @@ module Dnsruby
69
77
  end
70
78
  end
71
79
 
72
- def salt_length=(l)
73
- if ((l < 0) || (l > 255))
74
- raise DecodeError.new("NSEC3 salt length must be between 0 and 255")
75
- end
76
- @salt_length = l
77
- end
78
-
80
+ # def salt_length=(l) # :nodoc: all
81
+ # if ((l < 0) || (l > 255))
82
+ # raise DecodeError.new("NSEC3 salt length must be between 0 and 255")
83
+ # end
84
+ # @salt_length = l
85
+ # end
86
+ #
79
87
  def from_data(data) #:nodoc: all
80
88
  hash_alg, flags, iterations, salt_length, salt = data
81
89
  self.hash_alg=(hash_alg)
82
90
  self.flags=(flags)
83
91
  self.iterations=(iterations)
84
- self.salt_length=(salt_length)
92
+ # self.salt_length=(salt_length)
85
93
  self.salt=(salt)
86
94
  end
87
95
 
@@ -92,21 +100,26 @@ module Dnsruby
92
100
  self.flags=(data[1]).to_i
93
101
  self.iterations=(data[2]).to_i
94
102
  self.salt=(data[3])
95
- self.salt_length=(data[3].length)
103
+ # self.salt_length=(data[3].length)
96
104
  end
97
105
  end
98
106
 
99
107
  def rdata_to_string #:nodoc: all
100
- if (@next_hashed!=nil)
101
- return "#{@hash_alg.code} #{@flags} #{@iterations} #{@salt}"
102
- else
103
- return ""
104
- end
108
+ s = salt()
109
+ return "#{@hash_alg.code} #{@flags} #{@iterations} #{s}"
105
110
  end
106
111
 
107
112
  def encode_rdata(msg, canonical=false) #:nodoc: all
108
- msg.put_pack("ccnc", @hash_alg.code, @flags, @iterations, @salt_length)
109
- msg.put_bytes(@salt)
113
+ s = salt()
114
+ sl = s.length()
115
+ if (s == "-")
116
+ sl == 0
117
+ end
118
+ msg.put_pack("ccnc", @hash_alg.code, @flags, @iterations, sl)
119
+
120
+ if (sl > 0)
121
+ msg.put_bytes(s)
122
+ end
110
123
  end
111
124
 
112
125
  def self.decode_rdata(msg) #:nodoc: all
@@ -165,7 +165,13 @@ module Dnsruby
165
165
  # the white space out
166
166
  buf=""
167
167
  (index+3..end_index).each {|i|
168
+ if (comment_index = data[i].index(";"))
169
+ buf += data[i].slice(0, comment_index)
170
+ # @TODO@ We lose the comments here - we should really keep them for when we write back to string format?
171
+ break
172
+ else
168
173
  buf += data[i]
174
+ end
169
175
  }
170
176
  buf.gsub!(/\n/, "")
171
177
  buf.gsub!(/ /, "")
@@ -23,6 +23,7 @@ module Dnsruby
23
23
  # (RRSet)."
24
24
  # This class also stores the RRSIG records which cover the RRSet
25
25
  class RRSet
26
+ include Comparable
26
27
  # The number of RRSIGs stored in this RRSet
27
28
  attr_reader :num_sigs
28
29
  def initialize(rrs = [])
@@ -90,9 +91,19 @@ module Dnsruby
90
91
  end
91
92
 
92
93
  return privateAdd(r)
93
- return true
94
+ # return true
94
95
  end
95
-
96
+
97
+ def <=>(other)
98
+ # return 1 if ((!other) || !(other.name) || !(other.type))
99
+ # return -1 if (!@name)
100
+ if (@name.canonical == other.name.canonical)
101
+ return @type.code <=> other.type.code
102
+ else
103
+ return @name <=> other.name
104
+ end
105
+ end
106
+
96
107
  def sort_canonical
97
108
  #Make a list, for all the RRs, where each RR contributes
98
109
  #the canonical RDATA encoding
@@ -492,11 +492,10 @@ module Dnsruby
492
492
  # push_to_client(client_id, client_queue, msg, err)
493
493
  client_queue.push([client_id, Resolver::EventType::RECEIVED, msg, err])
494
494
  notify_queue_observers(client_queue, client_id)
495
- # @TODO@ Do we need to validate this? The response has come from the cache -
495
+ # Do we need to validate this? The response has come from the cache -
496
496
  # validate it only if it has not been validated already
497
497
  # So, if we need to validate it, send it to the validation thread
498
498
  # Otherwise, send VALIDATED to the requester.
499
- # Should we really just be checking (level != SECURE) ?
500
499
  if (((msg.security_level == Message::SecurityLevel::UNCHECKED) ||
501
500
  (msg.security_level == Message::SecurityLevel::INDETERMINATE)) &&
502
501
  (ValidatorThread.requires_validation?(query, msg, err, res)))
@@ -641,7 +641,7 @@ module Dnsruby
641
641
 
642
642
  sigrecs.each {|sig|
643
643
  if ((key.key_tag == sig.key_tag) && (key.algorithm == sig.algorithm))
644
- # print "Found key #{key.key_tag}\n"
644
+ # print "Found key #{key.key_tag}\n"
645
645
  return key, sig
646
646
  end
647
647
  }
@@ -654,10 +654,8 @@ module Dnsruby
654
654
  #
655
655
  # Returns true if the RRSet verified, false otherwise.
656
656
  def verify_rrset(rrset, keys = nil)
657
- # @TODO@ Finer-grained reporting than "false".
658
657
  # print "Verify_rrset #{rrset.name}, #{rrset.type}\n"
659
658
  sigrecs = rrset.sigs
660
- # return false if (rrset.num_sigs == 0)
661
659
  if (rrset.rrs.length == 0)
662
660
  raise VerifyError.new("No RRSet to veryify")
663
661
  end
@@ -755,7 +753,7 @@ module Dnsruby
755
753
  expiration_diff = (sigrec.expiration.to_i - Time.now.to_i).abs
756
754
  rrset.ttl = ([rrset.ttl, sigrec.ttl, sigrec.original_ttl,
757
755
  expiration_diff].sort)[0]
758
- # print "VERIFIED OK\n"
756
+ # print "VERIFIED OK\n"
759
757
  return true
760
758
  end
761
759
 
@@ -252,8 +252,8 @@ module Dnsruby
252
252
  resource = RR.create("#{args[0]} #{ttl} #{klass} #{args[1]} #{rdata}")
253
253
  add_update(resource)
254
254
  when 3 # name, type, rdata
255
- klass = Classes.NONE
256
- resource = RR.create("#{args[0]} #{ttl} #{klass} #{args[1]} #{args[2]}")
255
+ resource = RR.create("#{args[0]} #{ttl} IN #{args[1]} #{args[2]}")
256
+ resource.klass = Classes.NONE
257
257
  add_update(resource)
258
258
  end
259
259
  return resource
@@ -75,7 +75,17 @@ require 'Dnsruby/TheLog'
75
75
  #* NotImp < ResolvError
76
76
  #
77
77
  #* Refused < ResolvError
78
+ #
79
+ #* NotZone < ResolvError
80
+ #
81
+ #* YXDomain < ResolvError
82
+ #
83
+ #* YXRRSet < ResolvError
78
84
  #
85
+ #* NXRRSet < ResolvError
86
+ #
87
+ #* NotAuth < ResolvError
88
+ #
79
89
  #* OtherResolvError < ResolvError
80
90
  #
81
91
  #== I/O
@@ -377,7 +387,14 @@ module Dnsruby
377
387
  # Referred to as Algoriths.RSASHA1_NSEC3_SHA1
378
388
  add_pair("RSASHA1-NSEC3-SHA1", 7)
379
389
  end
380
-
390
+
391
+ # http://www.iana.org/assignments/dnssec-nsec3-parameters/dnssec-nsec3-parameters.xhtml
392
+ class Nsec3HashAlgorithms < CodeMapper
393
+ RESERVED = 0
394
+ update()
395
+ add_pair("SHA-1", 1)
396
+ end
397
+
381
398
  #An error raised while querying for a resource
382
399
  class ResolvError < StandardError
383
400
  end
@@ -405,6 +422,27 @@ module Dnsruby
405
422
  #The requested operation was refused by the remote resolver
406
423
  class Refused < ResolvError
407
424
  end
425
+
426
+ #The update RR is outside the zone (in dynamic update)
427
+ class NotZone < ResolvError
428
+ end
429
+
430
+ #Some name that ought to exist, does not exist (in dynamic update)
431
+ class YXDomain < ResolvError
432
+ end
433
+
434
+ #Some RRSet that ought to exist, does not exist (in dynamic update)
435
+ class YXRRSet < ResolvError
436
+ end
437
+
438
+ #Some RRSet that ought not to exist, does exist (in dynamic update)
439
+ class NXRRSet < ResolvError
440
+ end
441
+
442
+ #The nameserver is not responsible for the zone (in dynamic update)
443
+ class NotAuth < ResolvError
444
+ end
445
+
408
446
 
409
447
  #Another kind of resolver error has occurred
410
448
  class OtherResolvError < ResolvError
@@ -34,6 +34,11 @@ class DnskeyTest < Test::Unit::TestCase
34
34
  assert(dnskey2.to_s == dnskey.to_s, "#{dnskey.to_s} not equal to \n#{dnskey2.to_s}")
35
35
  end
36
36
 
37
+ def test_from_string_with_comments
38
+ k = Dnsruby::RR.create("tjeb.nl. 3600 IN DNSKEY 256 3 7 AwEAAcglEOS7bECRK5fqTuGTMJycmDhTzmUu/EQbAhKJOYJxDb5SG/RYqsJgzG7wgtGy0W1aP7I4k6SPtHmwcqjLaZLVUwRNWCGr2adjb9JTFyBR7F99Ngi11lEGM6Uiw/eDRk66lhoSGzohjj/rmhRTV6gN2+0ADPnafv3MBkPgryA3 ;{id = 53177 (zsk), size = 1024b}")
39
+ assert_equal(53177, k.key_tag)
40
+ end
41
+
37
42
  def test_dnskey_from_data
38
43
  dnskey = Dnsruby::RR.create(INPUT)
39
44
  m = Dnsruby::Message.new
@@ -13,6 +13,11 @@ class NsecTest < Test::Unit::TestCase
13
13
 
14
14
  nsec2 = Dnsruby::RR.create(nsec.to_s)
15
15
  assert(nsec2.to_s == nsec.to_s)
16
+
17
+ s = "tjeb.nl. 3600 IN NSEC dragon.tjeb.nl. A NS SOA MX AAAA RRSIG NSEC DNSKEY"
18
+ nsec = Dnsruby::RR.create(s)
19
+ assert(nsec.types.include?(Types.A))
20
+ assert(nsec.types.include?(Types.DNSKEY))
16
21
  end
17
22
 
18
23
  def test_nsec_from_data
@@ -12,7 +12,7 @@ class Nsec3Test < Test::Unit::TestCase
12
12
  assert(nsec.opt_out?)
13
13
  assert_equal(12, nsec.iterations)
14
14
  assert_equal("aabbccdd", nsec.salt)
15
- assert_equal(Dnsruby::Algorithms.RSAMD5, nsec.hash_alg)
15
+ assert_equal(Dnsruby::Nsec3HashAlgorithms.SHA_1, nsec.hash_alg)
16
16
 
17
17
  nsec2 = Dnsruby::RR.create(nsec.to_s)
18
18
  assert(nsec2.to_s == nsec.to_s)
@@ -39,19 +39,44 @@ class Nsec3Test < Test::Unit::TestCase
39
39
  nsec3 = m2.additional()[0]
40
40
  assert_equal(nsec.to_s, nsec3.to_s)
41
41
  end
42
-
42
+
43
+ def test_calculate_hash
44
+ input = [
45
+ [ "example" , "0p9mhaveqvm6t7vbl5lop2u3t2rp3tom"],
46
+ [ "a.example" , "35mthgpgcu1qg68fab165klnsnk3dpvl"],
47
+ [ "ai.example" , "gjeqe526plbf1g8mklp59enfd789njgi"],
48
+ [ "ns1.example" , "2t7b4g4vsa5smi47k61mv5bv1a22bojr"],
49
+ [ "ns2.example" , "q04jkcevqvmu85r014c7dkba38o0ji5r"],
50
+ [ "w.example" , "k8udemvp1j2f7eg6jebps17vp3n8i58h"],
51
+ [ "*.w.example" , "r53bq7cc2uvmubfu5ocmm6pers9tk9en"],
52
+ [ "x.w.example" , "b4um86eghhds6nea196smvmlo4ors995"],
53
+ [ "y.w.example" , "ji6neoaepv8b5o6k4ev33abha8ht9fgc"],
54
+ [ "x.y.w.example" , "2vptu5timamqttgl4luu9kg21e0aor3s"],
55
+ [ "xx.example" , "t644ebqk9bibcna874givr6joj62mlhv"],
56
+ [ "2t7b4g4vsa5smi47k61mv5bv1a22bojr.example" , "kohar7mbb8dc2ce8a9qvl8hon4k53uhi"]
57
+ ]
58
+ input.each {|name, hash|
59
+ nsec3 = Dnsruby::RR.create({:type => Dnsruby::Types.NSEC3, :name => name, :salt => "aabbccdd", :iterations => 12, :hash_alg => 1})
60
+ n = nsec3.calculate_hash
61
+ assert_equal(n, hash, "Expected #{hash} but got #{n} for #{name}")
62
+ c = Dnsruby::RR::NSEC3.calculate_hash(name, 12, Dnsruby::RR::NSEC3.decode_salt("aabbccdd"), 1)
63
+ assert_equal(c, hash, "Expected #{hash} but got #{c} for #{name}")
64
+ }
65
+ #
66
+ end
67
+
43
68
  def test_nsec_other_stuff
44
69
  nsec = Dnsruby::RR.create(INPUT)
45
- begin
46
- nsec.salt_length=256
47
- fail
48
- rescue DecodeError
49
- end
50
- begin
51
- nsec.hash_length=256
52
- fail
53
- rescue DecodeError
54
- end
70
+ # begin
71
+ # nsec.salt_length=256
72
+ # fail
73
+ # rescue DecodeError
74
+ # end
75
+ # begin
76
+ # nsec.hash_length=256
77
+ # fail
78
+ # rescue DecodeError
79
+ # end
55
80
  # Be liberal in what you accept...
56
81
  # begin
57
82
  # nsec.hash_alg = 8
@@ -8,7 +8,7 @@ class Nsec3ParamTest < Test::Unit::TestCase
8
8
  def test_nsec_from_string
9
9
  nsec = Dnsruby::RR.create(INPUT)
10
10
 
11
- assert_equal(Dnsruby::Algorithms.RSAMD5, nsec.hash_alg)
11
+ assert_equal(Dnsruby::Nsec3HashAlgorithms.SHA_1, nsec.hash_alg)
12
12
  assert_equal(0, nsec.flags)
13
13
  assert_equal(12, nsec.iterations)
14
14
  assert_equal("aabbccdd", nsec.salt)
@@ -25,6 +25,14 @@ class Nsec3ParamTest < Test::Unit::TestCase
25
25
  m2 = Dnsruby::Message.decode(data)
26
26
  nsec3 = m2.additional()[0]
27
27
  assert_equal(nsec.to_s, nsec3.to_s)
28
+
29
+ end
30
+
31
+ def test_from_real_string
32
+ r = Dnsruby::RR.create("tjeb.nl. 3600 IN NSEC3PARAM 1 0 5 beef")
33
+ assert_equal(Dnsruby::Name.create("tjeb.nl."), r.name)
34
+ assert_equal("beef", r.salt)
35
+ assert_equal(Dnsruby::Nsec3HashAlgorithms.SHA_1, r.hash_alg)
28
36
  end
29
37
 
30
38
  end
@@ -29,4 +29,9 @@ class RrsigTest < Test::Unit::TestCase
29
29
  rrsig2 = Dnsruby::RR.create(rrsig.to_s)
30
30
  assert(rrsig2.to_s == rrsig.to_s)
31
31
  end
32
+
33
+ def test_string_with_comments
34
+ r = Dnsruby::RR.create("tjeb.nl. 3600 IN RRSIG NSEC3PARAM 7 2 3600 20090630164649 20090602164649 53177 tjeb.nl. Fw70WQMviRFGyeze3MUpfafaAcWIvHRpnq4ZK3lxexrR1p+rLxK5C4qVKU71XYrPYR7XEBxgUG1oyKNOhFOVyx31EjC462dz7Vxn6UDpD1LIwNnD28+oHfS9AFzGKcn4zUZqT+8IvOO1jiS9c3Y8WAkOloN9AwGIIKWU8zAp1n4= ;{id = 53177}")
35
+ assert_equal("Fw70WQMviRFGyeze3MUpfafaAcWIvHRpnq4ZK3lxexrR1p+rLxK5C4qVKU71XYrPYR7XEBxgUG1oyKNOhFOVyx31EjC462dz7Vxn6UDpD1LIwNnD28+oHfS9AFzGKcn4zUZqT+8IvOO1jiS9c3Y8WAkOloN9AwGIIKWU8zAp1n4=", ([r.signature].pack("m*")).gsub(/\n/,"").chomp)
36
+ end
32
37
  end
@@ -72,4 +72,5 @@ class TestTKey < Test::Unit::TestCase
72
72
  #@TODO@ Test TKEY against server!
73
73
 
74
74
  end
75
+
75
76
  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.30"
4
+ version: "1.31"
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: 2009-05-18 00:00:00 +01:00
12
+ date: 2009-06-04 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies: []
15
15