dns-zone 0.1.3 → 0.2.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.
@@ -0,0 +1,38 @@
1
+ # `DNSKEY` resource record.
2
+ #
3
+ # RFC 4034
4
+ class DNS::Zone::RR::DNSKEY < DNS::Zone::RR::Record
5
+
6
+ REGEX_DNSKEY_RDATA = %r{
7
+ (?<flags>\d+)\s*
8
+ (?<protocol>\d+)\s*
9
+ (?<algorithm>\d+)\s*
10
+ (?<key>#{DNS::Zone::RR::REGEX_STRING})\s*
11
+ }mx
12
+
13
+ attr_accessor :flags, :protocol, :algorithm, :key
14
+
15
+ def dump
16
+ parts = general_prefix
17
+ parts << flags
18
+ parts << protocol
19
+ parts << algorithm
20
+ parts << key
21
+ parts.join(' ')
22
+ end
23
+
24
+ def load(string, options = {})
25
+ rdata = load_general_and_get_rdata(string, options)
26
+ return nil unless rdata
27
+
28
+ captures = rdata.match(REGEX_DNSKEY_RDATA)
29
+ return nil unless captures
30
+
31
+ @flags = captures[:flags].to_i
32
+ @protocol = captures[:protocol].to_i
33
+ @algorithm = captures[:algorithm].to_i
34
+ @key = captures[:key].scan(/#{DNS::Zone::RR::REGEX_STRING}/).join
35
+ self
36
+ end
37
+
38
+ end
@@ -0,0 +1,38 @@
1
+ # `DS` resource record.
2
+ #
3
+ # RFC 4034
4
+ class DNS::Zone::RR::DS < DNS::Zone::RR::Record
5
+
6
+ REGEX_DS_RDATA = %r{
7
+ (?<key_tag>\d+)\s*
8
+ (?<algorithm>\d+)\s*
9
+ (?<digest_type>\d+)\s*
10
+ (?<digest>#{DNS::Zone::RR::REGEX_STRING})\s*
11
+ }mx
12
+
13
+ attr_accessor :key_tag, :algorithm, :digest_type, :digest
14
+
15
+ def dump
16
+ parts = general_prefix
17
+ parts << key_tag
18
+ parts << algorithm
19
+ parts << digest_type
20
+ parts << digest
21
+ parts.join(' ')
22
+ end
23
+
24
+ def load(string, options = {})
25
+ rdata = load_general_and_get_rdata(string, options)
26
+ return nil unless rdata
27
+
28
+ captures = rdata.match(REGEX_DS_RDATA)
29
+ return nil unless captures
30
+
31
+ @key_tag = captures[:key_tag].to_i
32
+ @algorithm = captures[:algorithm].to_i
33
+ @digest_type = captures[:digest_type].to_i
34
+ @digest = captures[:digest].scan(/#{DNS::Zone::RR::REGEX_STRING}/).join
35
+ self
36
+ end
37
+
38
+ end
@@ -3,13 +3,9 @@
3
3
  # RFC 1035
4
4
  class DNS::Zone::RR::HINFO < DNS::Zone::RR::Record
5
5
 
6
- REGEX_QUOTES_OPTIONAL = %r{
7
- "#{DNS::Zone::RR::REGEX_STRING}"|#{DNS::Zone::RR::REGEX_STRING}
8
- }mx
9
-
10
6
  REGEX_HINFO_RDATA = %r{
11
- (?<cpu>(?:#{REGEX_QUOTES_OPTIONAL})){1}\s
12
- (?<os>(?:#{REGEX_QUOTES_OPTIONAL})){1}
7
+ (?<cpu>(?:#{DNS::Zone::RR::REGEX_CHARACTER_STRING})){1}\s
8
+ (?<os>(?:#{DNS::Zone::RR::REGEX_CHARACTER_STRING})){1}
13
9
  }mx
14
10
  attr_accessor :cpu
15
11
  attr_accessor :os
@@ -27,8 +23,8 @@ class DNS::Zone::RR::HINFO < DNS::Zone::RR::Record
27
23
  captures = rdata.match(REGEX_HINFO_RDATA)
28
24
  return nil unless captures
29
25
 
30
- @cpu = captures[:cpu].scan(/#{REGEX_QUOTES_OPTIONAL}/).join
31
- @os = captures[:os].scan(/"#{DNS::Zone::RR::REGEX_STRING}"|#{DNS::Zone::RR::REGEX_STRING}/).join
26
+ @cpu = captures[:cpu].scan(/#{DNS::Zone::RR::REGEX_CHARACTER_STRING}/).join
27
+ @os = captures[:os].scan(/#{DNS::Zone::RR::REGEX_CHARACTER_STRING}/).join
32
28
  self
33
29
  end
34
30
 
@@ -0,0 +1,44 @@
1
+ # `NAPTR` resource record.
2
+ #
3
+ # RFC 3403
4
+ class DNS::Zone::RR::NAPTR < DNS::Zone::RR::Record
5
+
6
+ REGEX_NAPTR_RDATA = %r{
7
+ (?<order>\d+)\s*
8
+ (?<pref>\d+)\s*
9
+ (?<flags>#{DNS::Zone::RR::REGEX_CHARACTER_STRING})\s*
10
+ (?<service>#{DNS::Zone::RR::REGEX_CHARACTER_STRING})\s*
11
+ (?<regexp>#{DNS::Zone::RR::REGEX_CHARACTER_STRING})\s*
12
+ (?<replacement>#{DNS::Zone::RR::REGEX_DOMAINNAME}|\.{1})\s*
13
+ }mx
14
+
15
+ attr_accessor :order, :pref, :flags, :service, :regexp, :replacement
16
+
17
+ def dump
18
+ parts = general_prefix
19
+ parts << order
20
+ parts << pref
21
+ parts << %Q{"#{flags}"}
22
+ parts << %Q{"#{service}"}
23
+ parts << %Q{"#{regexp}"}
24
+ parts << replacement
25
+ parts.join(' ')
26
+ end
27
+
28
+ def load(string, options = {})
29
+ rdata = load_general_and_get_rdata(string, options)
30
+ return nil unless rdata
31
+
32
+ captures = rdata.match(REGEX_NAPTR_RDATA)
33
+ return nil unless captures
34
+
35
+ @order = captures[:order].to_i
36
+ @pref = captures[:pref].to_i
37
+ @flags = captures[:flags].scan(/#{DNS::Zone::RR::REGEX_CHARACTER_STRING}/).join
38
+ @service = captures[:service].scan(/#{DNS::Zone::RR::REGEX_CHARACTER_STRING}/).join
39
+ @regexp = captures[:regexp].scan(/#{DNS::Zone::RR::REGEX_CHARACTER_STRING}/).join
40
+ @replacement = captures[:replacement]
41
+ self
42
+ end
43
+
44
+ end
@@ -0,0 +1,32 @@
1
+ # `NSEC` resource record.
2
+ #
3
+ # RFC 4034
4
+ class DNS::Zone::RR::NSEC < DNS::Zone::RR::Record
5
+
6
+ REGEX_NSEC_RDATA = %r{
7
+ (?<next_domain>#{DNS::Zone::RR::REGEX_DOMAINNAME})\s*
8
+ (?<rrset_types>#{DNS::Zone::RR::REGEX_STRING})\s*
9
+ }mx
10
+
11
+ attr_accessor :next_domain, :rrset_types
12
+
13
+ def dump
14
+ parts = general_prefix
15
+ parts << next_domain
16
+ parts << rrset_types
17
+ parts.join(' ')
18
+ end
19
+
20
+ def load(string, options = {})
21
+ rdata = load_general_and_get_rdata(string, options)
22
+ return nil unless rdata
23
+
24
+ captures = rdata.match(REGEX_NSEC_RDATA)
25
+ return nil unless captures
26
+
27
+ @next_domain = captures[:next_domain]
28
+ @rrset_types = captures[:rrset_types]
29
+ self
30
+ end
31
+
32
+ end
@@ -0,0 +1,45 @@
1
+ # `NSEC3` resource record.
2
+ #
3
+ # RFC 5155
4
+ class DNS::Zone::RR::NSEC3 < DNS::Zone::RR::Record
5
+
6
+ REGEX_NSEC3_RDATA = %r{
7
+ (?<algorithm>\d+)\s*
8
+ (?<flags>\d+)\s*
9
+ (?<iterations>\d+)\s*
10
+ (?<salt>\S+)\s*
11
+ (?<next_hashed_owner_name>\S+)\s*
12
+ (?<rrset_types>#{DNS::Zone::RR::REGEX_STRING})\s*
13
+ }mx
14
+
15
+ attr_accessor :algorithm, :flags, :iterations, :salt,
16
+ :next_hashed_owner_name, :rrset_types
17
+
18
+ def dump
19
+ parts = general_prefix
20
+ parts << algorithm
21
+ parts << flags
22
+ parts << iterations
23
+ parts << salt
24
+ parts << next_hashed_owner_name
25
+ parts << rrset_types
26
+ parts.join(' ')
27
+ end
28
+
29
+ def load(string, options = {})
30
+ rdata = load_general_and_get_rdata(string, options)
31
+ return nil unless rdata
32
+
33
+ captures = rdata.match(REGEX_NSEC3_RDATA)
34
+ return nil unless captures
35
+
36
+ @algorithm = captures[:algorithm].to_i
37
+ @flags = captures[:flags].to_i
38
+ @iterations = captures[:iterations].to_i
39
+ @salt = captures[:salt]
40
+ @next_hashed_owner_name = captures[:next_hashed_owner_name]
41
+ @rrset_types = captures[:rrset_types]
42
+ self
43
+ end
44
+
45
+ end
@@ -0,0 +1,38 @@
1
+ # `NSEC3PARAM` resource record.
2
+ #
3
+ # RFC 5155
4
+ class DNS::Zone::RR::NSEC3PARAM < DNS::Zone::RR::Record
5
+
6
+ REGEX_NSEC3PARAM_RDATA = %r{
7
+ (?<algorithm>\d+)\s*
8
+ (?<flags>\d+)\s*
9
+ (?<iterations>\d+)\s*
10
+ (?<salt>\S+)\s*
11
+ }mx
12
+
13
+ attr_accessor :algorithm, :flags, :iterations, :salt
14
+
15
+ def dump
16
+ parts = general_prefix
17
+ parts << algorithm
18
+ parts << flags
19
+ parts << iterations
20
+ parts << salt
21
+ parts.join(' ')
22
+ end
23
+
24
+ def load(string, options = {})
25
+ rdata = load_general_and_get_rdata(string, options)
26
+ return nil unless rdata
27
+
28
+ captures = rdata.match(REGEX_NSEC3PARAM_RDATA)
29
+ return nil unless captures
30
+
31
+ @algorithm = captures[:algorithm].to_i
32
+ @flags = captures[:flags].to_i
33
+ @iterations = captures[:iterations].to_i
34
+ @salt = captures[:salt]
35
+ self
36
+ end
37
+
38
+ end
@@ -0,0 +1,54 @@
1
+ # `RRSIG` resource record.
2
+ #
3
+ # RFC 4034
4
+ class DNS::Zone::RR::RRSIG < DNS::Zone::RR::Record
5
+
6
+ REGEX_RRSIG_RDATA = %r{
7
+ (?<type_covered>\S+)\s*
8
+ (?<algorithm>\d+)\s*
9
+ (?<labels>\d+)\s*
10
+ (?<original_ttl>#{DNS::Zone::RR::REGEX_TTL})\s*
11
+ (?<signature_expiration>\d+)\s*
12
+ (?<signature_inception>\d+)\s*
13
+ (?<key_tag>\d+)\s*
14
+ (?<signer>#{DNS::Zone::RR::REGEX_DOMAINNAME})\s*
15
+ (?<signature>#{DNS::Zone::RR::REGEX_CHARACTER_STRING})\s*
16
+ }mx
17
+
18
+ attr_accessor :type_covered, :algorithm, :labels, :original_ttl, :signature_expiration,
19
+ :signature_inception, :key_tag, :signer, :signature
20
+
21
+ def dump
22
+ parts = general_prefix
23
+ parts << type_covered
24
+ parts << algorithm
25
+ parts << labels
26
+ parts << original_ttl
27
+ parts << signature_expiration
28
+ parts << signature_inception
29
+ parts << key_tag
30
+ parts << signer
31
+ parts << signature
32
+ parts.join(' ')
33
+ end
34
+
35
+ def load(string, options = {})
36
+ rdata = load_general_and_get_rdata(string, options)
37
+ return nil unless rdata
38
+
39
+ captures = rdata.match(REGEX_RRSIG_RDATA)
40
+ return nil unless captures
41
+
42
+ @type_covered = captures[:type_covered]
43
+ @algorithm = captures[:algorithm].to_i
44
+ @labels = captures[:labels].to_i
45
+ @original_ttl = captures[:original_ttl].to_i
46
+ @signature_expiration = captures[:signature_expiration].to_i
47
+ @signature_inception = captures[:signature_inception].to_i
48
+ @key_tag = captures[:key_tag].to_i
49
+ @signer = captures[:signer]
50
+ @signature = captures[:signature]
51
+ self
52
+ end
53
+
54
+ end
@@ -0,0 +1,35 @@
1
+ # `SSHFP` resource record.
2
+ #
3
+ # RFC 4255
4
+ class DNS::Zone::RR::SSHFP < DNS::Zone::RR::Record
5
+
6
+ REGEX_SSHFP_RDATA = %r{
7
+ (?<algorithm_number>\d+)\s*
8
+ (?<fingerprint_type>\d+)\s*
9
+ (?<fingerprint>#{DNS::Zone::RR::REGEX_STRING})\s*
10
+ }mx
11
+
12
+ attr_accessor :algorithm_number, :fingerprint_type, :fingerprint
13
+
14
+ def dump
15
+ parts = general_prefix
16
+ parts << algorithm_number
17
+ parts << fingerprint_type
18
+ parts << fingerprint
19
+ parts.join(' ')
20
+ end
21
+
22
+ def load(string, options = {})
23
+ rdata = load_general_and_get_rdata(string, options)
24
+ return nil unless rdata
25
+
26
+ captures = rdata.match(REGEX_SSHFP_RDATA)
27
+ return nil unless captures
28
+
29
+ @algorithm_number = captures[:algorithm_number].to_i
30
+ @fingerprint_type = captures[:fingerprint_type].to_i
31
+ @fingerprint = captures[:fingerprint]
32
+ self
33
+ end
34
+
35
+ end
@@ -1,6 +1,6 @@
1
1
  module DNS
2
2
  class Zone
3
3
  # Version number (major.minor.tiny)
4
- Version = '0.1.3'
4
+ Version = '0.2.0'
5
5
  end
6
6
  end
@@ -0,0 +1,31 @@
1
+ require 'dns/zone/test_case'
2
+
3
+ class RR_CDNSKEY_Test < DNS::Zone::TestCase
4
+
5
+ # FIXME (lantins): algorithm can be integer _or_ mnemonic!
6
+
7
+ TEST_KEY = 'AQPSKmynfzW4kyBv015MUG2DeIQ3Cbl+BBZH4b/0PY1kxkmvHjcZc8nokfzj31GajIQKY+5CptLr3buXA10hWqTkF7H6RfoRqXQeogmMHfpftf6zMv1LyBUgia7za6ZEzOJBOztyvhjL742iU/TpPSEDhm2SNKLijfUppn1UaNvv4w=='
8
+
9
+ def test_build_rr__cdnskey
10
+ rr = DNS::Zone::RR::CDNSKEY.new
11
+ rr.label = 'example.com.'
12
+ rr.ttl = 86400
13
+ rr.flags = 256
14
+ rr.protocol = 3
15
+ rr.algorithm = 5
16
+ rr.key = TEST_KEY
17
+
18
+ assert_equal "example.com. 86400 IN CDNSKEY 256 3 5 #{TEST_KEY}", rr.dump
19
+ end
20
+
21
+ def test_load_rr__cdnskey
22
+ rr = DNS::Zone::RR::CDNSKEY.new.load("example.com. IN CDNSKEY 256 3 5 #{TEST_KEY}")
23
+ assert_equal 'example.com.', rr.label
24
+ assert_equal 'CDNSKEY', rr.type
25
+ assert_equal 256, rr.flags
26
+ assert_equal 3, rr.protocol
27
+ assert_equal 5, rr.algorithm
28
+ assert_equal TEST_KEY, rr.key
29
+ end
30
+
31
+ end
@@ -0,0 +1,28 @@
1
+ require 'dns/zone/test_case'
2
+
3
+ class RR_CDS_Test < DNS::Zone::TestCase
4
+
5
+ TEST_DIGEST = '2BB183AF5F22588179A53B0A98631FAD1A292118'
6
+
7
+ def test_build_rr__cds
8
+ rr = DNS::Zone::RR::CDS.new
9
+ rr.label = 'dskey.example.com.'
10
+ rr.key_tag = 60485
11
+ rr.algorithm = 5
12
+ rr.digest_type = 1
13
+ rr.digest = TEST_DIGEST
14
+
15
+ assert_equal "dskey.example.com. IN CDS 60485 5 1 #{TEST_DIGEST}", rr.dump
16
+ end
17
+
18
+ def test_load_rr__cds
19
+ rr = DNS::Zone::RR::CDS.new.load("dskey.example.com. IN CDS 60485 5 1 #{TEST_DIGEST}")
20
+ assert_equal 'dskey.example.com.', rr.label
21
+ assert_equal 'CDS', rr.type
22
+ assert_equal 60485, rr.key_tag
23
+ assert_equal 5, rr.algorithm
24
+ assert_equal 1, rr.digest_type
25
+ assert_equal TEST_DIGEST, rr.digest
26
+ end
27
+
28
+ end
@@ -0,0 +1,28 @@
1
+ require 'dns/zone/test_case'
2
+
3
+ class RR_DLV_Test < DNS::Zone::TestCase
4
+
5
+ TEST_DIGEST = '2BB183AF5F22588179A53B0A98631FAD1A292118'
6
+
7
+ def test_build_rr__dlv
8
+ rr = DNS::Zone::RR::DLV.new
9
+ rr.label = 'dlvtest.example.com.'
10
+ rr.key_tag = 60485
11
+ rr.algorithm = 5
12
+ rr.digest_type = 1
13
+ rr.digest = TEST_DIGEST
14
+
15
+ assert_equal "dlvtest.example.com. IN DLV 60485 5 1 #{TEST_DIGEST}", rr.dump
16
+ end
17
+
18
+ def test_load_rr__dlv
19
+ rr = DNS::Zone::RR::DLV.new.load("dlvtest.example.com. IN DLV 60485 5 1 #{TEST_DIGEST}")
20
+ assert_equal 'dlvtest.example.com.', rr.label
21
+ assert_equal 'DLV', rr.type
22
+ assert_equal 60485, rr.key_tag
23
+ assert_equal 5, rr.algorithm
24
+ assert_equal 1, rr.digest_type
25
+ assert_equal TEST_DIGEST, rr.digest
26
+ end
27
+
28
+ end