From 921e68ff38fe3baf5c5fa629ca40ee6c335bcdc6 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 13 May 2012 05:47:25 +0200 Subject: [PATCH 1/6] Fix Net::DNS::RR::SOA.build_pack --- lib/net/dns/rr/soa.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/net/dns/rr/soa.rb b/lib/net/dns/rr/soa.rb index 8b93250..37f0391 100644 --- a/lib/net/dns/rr/soa.rb +++ b/lib/net/dns/rr/soa.rb @@ -14,6 +14,7 @@ def build_pack @soa_pack = pack_name(@mname) @soa_pack += pack_name(@rname) @soa_pack += [@serial,@refresh,@retry,@expire,@minimum].pack("N5") + @rdlength = @soa_pack.size end def get_data From a7aa75e0df083eeadbf1dc287e80edc709e8470a Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 13 May 2012 05:50:41 +0200 Subject: [PATCH 2/6] Fix warning on unsupported record types in additional records --- lib/net/dns/packet.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/net/dns/packet.rb b/lib/net/dns/packet.rb index eb2cc2a..ade1bbb 100644 --- a/lib/net/dns/packet.rb +++ b/lib/net/dns/packet.rb @@ -542,7 +542,7 @@ def new_from_data(data, from = nil) @additional << rrobj @logger.debug rrobj.inspect rescue NameError => e - warn "Net::DNS supported record type: #{e.message}" + warn "Net::DNS unsupported record type: #{e.message}" end end From 23b747e2f267a91cafd7384b64b709b1f29494f1 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 13 May 2012 06:11:41 +0200 Subject: [PATCH 3/6] Allow creating empty packets --- lib/net/dns/packet.rb | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/net/dns/packet.rb b/lib/net/dns/packet.rb index ade1bbb..efab8a7 100644 --- a/lib/net/dns/packet.rb +++ b/lib/net/dns/packet.rb @@ -97,18 +97,19 @@ class PacketError < Error # Creates a new instance of Net::DNS::Packet class. Arguments are the # canonical name of the resource, an optional type field and an optional - # class field. The record type and class can be omitted; they default - # to +A+ and +IN+. + # class field. If the arguments are omitted, no question is added to the new packet; + # type and class default to +A+ and +IN+ if a name is given. # + # packet = Net::DNS::Packet.new # packet = Net::DNS::Packet.new("www.example.com") # packet = Net::DNS::Packet.new("example.com", Net::DNS::MX) # packet = Net::DNS::Packet.new("example.com", Net::DNS::TXT, Net::DNS::CH) # # This class no longer instantiate object from binary data coming from # network streams. Please use Net::DNS::Packet.parse instead. - def initialize(name, type = Net::DNS::A, cls = Net::DNS::IN) - @header = Net::DNS::Header.new(:qdCount => 1) - @question = [Net::DNS::Question.new(name, type, cls)] + def initialize(name = nil, type = Net::DNS::A, cls = Net::DNS::IN) + @header = Net::DNS::Header.new(:qdCount => name.nil? ? 0 : 1) + @question = name.nil? ? [] : [Net::DNS::Question.new(name, type, cls)] @answer = [] @authority = [] @additional = [] From 5dc5e3ffcc21b5270af4ffdf17ce8ef13f57dba0 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 13 May 2012 07:14:29 +0200 Subject: [PATCH 4/6] Fix Net::DNS::Names.valid? It doesn't make much sense to test for a fixed list of TLDs as the list will change every now and then. Instead add some more checks for syntax correctness, and allow a trailing dot; also make the method accept the root domain ".". --- lib/net/dns/names.rb | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/net/dns/names.rb b/lib/net/dns/names.rb index c1747f5..3726e92 100644 --- a/lib/net/dns/names.rb +++ b/lib/net/dns/names.rb @@ -106,11 +106,19 @@ def dn_comp(name,offset,compnames) end def valid?(name) - if name =~ /^([a-z0-9]([-a-z0-9]*[a-z0-9])?\.)+((a[cdefgilmnoqrstuwxz]|aero|arpa)|(b[abdefghijmnorstvwyz]|biz)|(c[acdfghiklmnorsuvxyz]|cat|com|coop)|d[ejkmoz]|(e[ceghrstu]|edu)|f[ijkmor]|(g[abdefghilmnpqrstuwy]|gov)|h[kmnrtu]|(i[delmnoqrst]|info|int)|(j[emop]|jobs)|k[eghimnprwyz]|l[abcikrstuvy]|(m[acdghklmnopqrstuvwxyz]|mil|mobi|museum)|(n[acefgilopruz]|name|net)|(om|org)|(p[aefghklmnrstwy]|pro)|qa|r[eouw]|s[abcdeghijklmnortvyz]|(t[cdfghjklmnoprtvwz]|travel)|u[agkmsyz]|v[aceginu]|w[fs]|y[etu]|z[amw])$/i - return name - else - raise ArgumentError, "Invalid FQDN: #{name}" + raise ArgumentError, "Invalid FQDN: #{name}" if name.length < 1 or name.length > 255 + + return name if name == '.' # the root domain is the only valid domain that begins with a dot + + parts = name.split('.', -1) + parts.delete_at(parts.length-1) if parts.last.empty? # the domain may end with a dot + + parts.each do |part| + raise ArgumentError, "Invalid FQDN: #{name}" if + not part =~ /^[a-z0-9]([-a-z0-9]*[a-z0-9])?$/i or part.length < 1 or part.length > 63 end + + return name end end From 831ae5fa63356f40237fc5b5fd1655d1328b5403 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 13 May 2012 07:21:09 +0200 Subject: [PATCH 5/6] Net::DNS::RR::SOA.subclass_new_from_string: fix bogus number checks --- lib/net/dns/rr/soa.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/net/dns/rr/soa.rb b/lib/net/dns/rr/soa.rb index 37f0391..0a48655 100644 --- a/lib/net/dns/rr/soa.rb +++ b/lib/net/dns/rr/soa.rb @@ -55,7 +55,7 @@ def subclass_new_from_string(str) @mname = mname if valid? mname @rname = rname if valid? rname @serial,@refresh,@retry,@expire,@minimum = [serial,refresh,ret,expire,minimum].collect do |i| - i.to_i if valid? i.to_i + i.to_i if number? i.to_i end end From bfa61d277c5a3c9bac28c6b9173ff8d462f007a8 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 13 May 2012 07:33:46 +0200 Subject: [PATCH 6/6] Net::DNS::RR::SOA: only check the domain part of a RNAME for validity If the mailbox part of a RNAME contains dots, they have to be masked with backslashes, making the RNAME an invalid domain name. For such a RNAME to be recognized as valid add a RNAME validation method that only checks the domain part for validity. --- lib/net/dns/rr/soa.rb | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/net/dns/rr/soa.rb b/lib/net/dns/rr/soa.rb index 0a48655..9cfa40e 100644 --- a/lib/net/dns/rr/soa.rb +++ b/lib/net/dns/rr/soa.rb @@ -33,7 +33,7 @@ def subclass_new_from_hash(args) raise ArgumentError, "Missing field :#{key}" unless args.has_key? key end @mname = args[:mname] if valid? args[:mname] - @rname = args[:rname] if valid? args[:rname] + @rname = args[:rname] if rname? args[:rname] @serial = args[:serial] if number? args[:serial] @refresh = args[:refresh] if number? args[:refresh] @retry = args[:retry] if number? args[:retry] @@ -50,10 +50,19 @@ def number?(num) end end + def rname?(name) + begin + mailbox, domain = name.split(/(?