@nictool/dns-resource-record 1.1.6 → 1.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.
- package/.prettierrc.yml +3 -0
- package/CHANGELOG.md +17 -43
- package/README.md +56 -62
- package/index.js +77 -29
- package/lib/tinydns.js +68 -61
- package/package.json +10 -6
- package/rr/a.js +19 -20
- package/rr/aaaa.js +35 -31
- package/rr/caa.js +41 -39
- package/rr/cert.js +21 -19
- package/rr/cname.js +19 -20
- package/rr/dname.js +19 -19
- package/rr/dnskey.js +48 -41
- package/rr/ds.js +38 -36
- package/rr/hinfo.js +26 -25
- package/rr/ipseckey.js +53 -45
- package/rr/key.js +21 -21
- package/rr/loc.js +67 -54
- package/rr/mx.js +26 -24
- package/rr/naptr.js +51 -52
- package/rr/ns.js +25 -22
- package/rr/nsec.js +26 -20
- package/rr/nsec3.js +90 -30
- package/rr/nsec3param.js +29 -26
- package/rr/nxt.js +67 -0
- package/rr/openpgpkey.js +13 -14
- package/rr/ptr.js +20 -21
- package/rr/rrsig.js +27 -21
- package/rr/sig.js +24 -19
- package/rr/smimea.js +35 -28
- package/rr/soa.js +57 -42
- package/rr/spf.js +20 -17
- package/rr/srv.js +41 -41
- package/rr/sshfp.js +29 -30
- package/rr/tlsa.js +47 -40
- package/rr/tsig.js +48 -0
- package/rr/txt.js +40 -33
- package/rr/uri.js +31 -31
- package/rr/wks.js +44 -0
- package/rr.js +116 -79
- package/.codeclimate.yml +0 -25
- package/DEVELOP.md +0 -23
- package/test/a.js +0 -76
- package/test/aaaa.js +0 -79
- package/test/base.js +0 -138
- package/test/caa.js +0 -104
- package/test/cert.js +0 -48
- package/test/cname.js +0 -41
- package/test/dname.js +0 -53
- package/test/dnskey.js +0 -44
- package/test/ds.js +0 -44
- package/test/fake.js +0 -26
- package/test/hinfo.js +0 -75
- package/test/ipseckey.js +0 -115
- package/test/key.js +0 -37
- package/test/loc.js +0 -71
- package/test/mx.js +0 -75
- package/test/naptr.js +0 -40
- package/test/ns.js +0 -53
- package/test/nsec.js +0 -38
- package/test/nsec3.js +0 -26
- package/test/nsec3param.js +0 -26
- package/test/openpgpkey.js +0 -35
- package/test/ptr.js +0 -54
- package/test/rr.js +0 -196
- package/test/smimea.js +0 -45
- package/test/soa.js +0 -77
- package/test/spf.js +0 -48
- package/test/srv.js +0 -81
- package/test/sshfp.js +0 -62
- package/test/tinydns.js +0 -140
- package/test/tlsa.js +0 -54
- package/test/txt.js +0 -70
- package/test/uri.js +0 -61
package/rr/cert.js
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
|
|
2
1
|
import RR from '../rr.js'
|
|
3
2
|
|
|
4
3
|
export default class CERT extends RR {
|
|
5
|
-
constructor
|
|
4
|
+
constructor(opts) {
|
|
6
5
|
super(opts)
|
|
7
6
|
}
|
|
8
7
|
|
|
9
8
|
/****** Resource record specific setters *******/
|
|
10
|
-
setCertType
|
|
9
|
+
setCertType(val) {
|
|
11
10
|
// The type field is the certificate type
|
|
12
11
|
// the type field as an unsigned decimal integer or as a mnemonic symbol
|
|
13
12
|
// this.is16bitInt('CERT', 'type', val)
|
|
@@ -15,7 +14,7 @@ export default class CERT extends RR {
|
|
|
15
14
|
this.set('cert type', val)
|
|
16
15
|
}
|
|
17
16
|
|
|
18
|
-
setKeyTag
|
|
17
|
+
setKeyTag(val) {
|
|
19
18
|
// The key tag field is the 16-bit value
|
|
20
19
|
// The key tag field is represented as an unsigned decimal integer.
|
|
21
20
|
|
|
@@ -24,7 +23,7 @@ export default class CERT extends RR {
|
|
|
24
23
|
this.set('key tag', val)
|
|
25
24
|
}
|
|
26
25
|
|
|
27
|
-
setAlgorithm
|
|
26
|
+
setAlgorithm(val) {
|
|
28
27
|
// The algorithm field has the same meaning as the algorithm field in DNSKEY
|
|
29
28
|
// The algorithm field is represented as an unsigned decimal integer
|
|
30
29
|
this.is8bitInt('CERT', 'algorithm', val)
|
|
@@ -32,41 +31,44 @@ export default class CERT extends RR {
|
|
|
32
31
|
this.set('algorithm', val)
|
|
33
32
|
}
|
|
34
33
|
|
|
35
|
-
setCertificate
|
|
34
|
+
setCertificate(val) {
|
|
36
35
|
// certificate/CRL portion is represented in base 64 [16] and may be
|
|
37
36
|
// divided into any number of white-space-separated substrings
|
|
38
37
|
this.set('certificate', val)
|
|
39
38
|
}
|
|
40
39
|
|
|
41
|
-
getDescription
|
|
40
|
+
getDescription() {
|
|
42
41
|
return 'Certificate'
|
|
43
42
|
}
|
|
44
43
|
|
|
45
|
-
getRdataFields
|
|
46
|
-
return [
|
|
44
|
+
getRdataFields() {
|
|
45
|
+
return ['cert type', 'key tag', 'algorithm', 'certificate']
|
|
47
46
|
}
|
|
48
47
|
|
|
49
|
-
getRFCs
|
|
50
|
-
return [
|
|
48
|
+
getRFCs() {
|
|
49
|
+
return [2538, 4398]
|
|
51
50
|
}
|
|
52
51
|
|
|
53
|
-
getTypeId
|
|
52
|
+
getTypeId() {
|
|
54
53
|
return 37
|
|
55
54
|
}
|
|
56
55
|
|
|
57
56
|
/****** IMPORTERS *******/
|
|
58
57
|
|
|
59
|
-
fromBind
|
|
58
|
+
fromBind(opts) {
|
|
60
59
|
// test.example.com 3600 IN CERT certtype, keytag, algo, cert
|
|
61
|
-
const [
|
|
60
|
+
const [owner, ttl, c, type, certtype, keytag, algo, certificate] =
|
|
61
|
+
opts.bindline.split(/\s+/)
|
|
62
62
|
return new CERT({
|
|
63
63
|
owner,
|
|
64
|
-
ttl
|
|
65
|
-
class
|
|
64
|
+
ttl: parseInt(ttl, 10),
|
|
65
|
+
class: c,
|
|
66
66
|
type,
|
|
67
|
-
'cert type': /^[0-9]+$/.test(certtype)
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
'cert type': /^[0-9]+$/.test(certtype)
|
|
68
|
+
? parseInt(certtype, 10)
|
|
69
|
+
: certtype,
|
|
70
|
+
'key tag': parseInt(keytag, 10),
|
|
71
|
+
algorithm: parseInt(algo, 10),
|
|
70
72
|
certificate,
|
|
71
73
|
})
|
|
72
74
|
}
|
package/rr/cname.js
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
|
|
2
1
|
import net from 'net'
|
|
3
2
|
|
|
4
3
|
import RR from '../rr.js'
|
|
5
4
|
|
|
6
5
|
export default class CNAME extends RR {
|
|
7
|
-
constructor
|
|
6
|
+
constructor(opts) {
|
|
8
7
|
super(opts)
|
|
9
8
|
}
|
|
10
9
|
|
|
11
10
|
/****** Resource record specific setters *******/
|
|
12
|
-
setCname
|
|
11
|
+
setCname(val) {
|
|
13
12
|
// A <domain-name> which specifies the canonical or primary
|
|
14
13
|
// name for the owner. The owner name is an alias.
|
|
15
14
|
|
|
@@ -25,43 +24,43 @@ export default class CNAME extends RR {
|
|
|
25
24
|
this.set('cname', val.toLowerCase())
|
|
26
25
|
}
|
|
27
26
|
|
|
28
|
-
getDescription
|
|
27
|
+
getDescription() {
|
|
29
28
|
return 'Canonical Name'
|
|
30
29
|
}
|
|
31
30
|
|
|
32
|
-
getRdataFields
|
|
33
|
-
return [
|
|
31
|
+
getRdataFields(arg) {
|
|
32
|
+
return ['cname']
|
|
34
33
|
}
|
|
35
34
|
|
|
36
|
-
getRFCs
|
|
37
|
-
return [
|
|
35
|
+
getRFCs() {
|
|
36
|
+
return [1035, 2181]
|
|
38
37
|
}
|
|
39
38
|
|
|
40
|
-
getTypeId
|
|
39
|
+
getTypeId() {
|
|
41
40
|
return 5
|
|
42
41
|
}
|
|
43
42
|
|
|
44
43
|
/****** IMPORTERS *******/
|
|
45
|
-
fromTinydns
|
|
44
|
+
fromTinydns(opts) {
|
|
46
45
|
// Cfqdn:p:ttl:timestamp:lo
|
|
47
|
-
const [
|
|
46
|
+
const [fqdn, p, ttl, ts, loc] = opts.tinyline.substring(1).split(':')
|
|
48
47
|
|
|
49
48
|
return new CNAME({
|
|
50
|
-
owner
|
|
51
|
-
ttl
|
|
52
|
-
type
|
|
53
|
-
cname
|
|
49
|
+
owner: this.fullyQualify(fqdn),
|
|
50
|
+
ttl: parseInt(ttl, 10),
|
|
51
|
+
type: 'CNAME',
|
|
52
|
+
cname: this.fullyQualify(p),
|
|
54
53
|
timestamp: ts,
|
|
55
|
-
location
|
|
54
|
+
location: loc !== '' && loc !== '\n' ? loc : '',
|
|
56
55
|
})
|
|
57
56
|
}
|
|
58
57
|
|
|
59
|
-
fromBind
|
|
58
|
+
fromBind(opts) {
|
|
60
59
|
// test.example.com 3600 IN CNAME ...
|
|
61
|
-
const [
|
|
60
|
+
const [owner, ttl, c, type, cname] = opts.bindline.split(/\s+/)
|
|
62
61
|
return new CNAME({
|
|
63
62
|
owner,
|
|
64
|
-
ttl
|
|
63
|
+
ttl: parseInt(ttl, 10),
|
|
65
64
|
class: c,
|
|
66
65
|
type,
|
|
67
66
|
cname,
|
|
@@ -70,7 +69,7 @@ export default class CNAME extends RR {
|
|
|
70
69
|
|
|
71
70
|
/****** EXPORTERS *******/
|
|
72
71
|
|
|
73
|
-
toTinydns
|
|
72
|
+
toTinydns() {
|
|
74
73
|
return `C${this.getTinyFQDN('owner')}:${this.get('cname')}:${this.getTinydnsPostamble()}\n`
|
|
75
74
|
}
|
|
76
75
|
}
|
package/rr/dname.js
CHANGED
|
@@ -4,12 +4,12 @@ import RR from '../rr.js'
|
|
|
4
4
|
import * as TINYDNS from '../lib/tinydns.js'
|
|
5
5
|
|
|
6
6
|
export default class DNAME extends RR {
|
|
7
|
-
constructor
|
|
7
|
+
constructor(opts) {
|
|
8
8
|
super(opts)
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
/****** Resource record specific setters *******/
|
|
12
|
-
setTarget
|
|
12
|
+
setTarget(val) {
|
|
13
13
|
if (!val) throw new Error('DNAME: target is required')
|
|
14
14
|
|
|
15
15
|
if (net.isIPv4(val) || net.isIPv6(val))
|
|
@@ -22,44 +22,44 @@ export default class DNAME extends RR {
|
|
|
22
22
|
this.set('target', val.toLowerCase())
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
getDescription
|
|
25
|
+
getDescription() {
|
|
26
26
|
return 'Delegation Name'
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
getRdataFields
|
|
30
|
-
return [
|
|
29
|
+
getRdataFields(arg) {
|
|
30
|
+
return ['target']
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
getRFCs
|
|
34
|
-
return [
|
|
33
|
+
getRFCs() {
|
|
34
|
+
return [2672, 6672]
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
getTypeId
|
|
37
|
+
getTypeId() {
|
|
38
38
|
return 39
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
/****** IMPORTERS *******/
|
|
42
|
-
fromTinydns
|
|
42
|
+
fromTinydns(opts) {
|
|
43
43
|
// DNAME via generic, :fqdn:n:rdata:ttl:timestamp:lo
|
|
44
|
-
const [
|
|
44
|
+
const [fqdn, n, rdata, ttl, ts, loc] = opts.tinyline.substring(1).split(':')
|
|
45
45
|
if (n != 39) throw new Error('DNAME fromTinydns, invalid n')
|
|
46
46
|
|
|
47
47
|
return new DNAME({
|
|
48
|
-
type
|
|
49
|
-
owner
|
|
50
|
-
target
|
|
51
|
-
ttl
|
|
48
|
+
type: 'DNAME',
|
|
49
|
+
owner: this.fullyQualify(fqdn),
|
|
50
|
+
target: TINYDNS.unpackDomainName(rdata)[0],
|
|
51
|
+
ttl: parseInt(ttl, 10),
|
|
52
52
|
timestamp: ts,
|
|
53
|
-
location
|
|
53
|
+
location: loc !== '' && loc !== '\n' ? loc : '',
|
|
54
54
|
})
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
fromBind
|
|
57
|
+
fromBind(opts) {
|
|
58
58
|
// test.example.com 3600 IN DNAME ...
|
|
59
|
-
const [
|
|
59
|
+
const [owner, ttl, c, type, target] = opts.bindline.split(/\s+/)
|
|
60
60
|
return new DNAME({
|
|
61
61
|
owner,
|
|
62
|
-
ttl
|
|
62
|
+
ttl: parseInt(ttl, 10),
|
|
63
63
|
class: c,
|
|
64
64
|
type,
|
|
65
65
|
target,
|
|
@@ -67,7 +67,7 @@ export default class DNAME extends RR {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
/****** EXPORTERS *******/
|
|
70
|
-
toTinydns
|
|
70
|
+
toTinydns() {
|
|
71
71
|
const rdata = TINYDNS.packDomainName(this.get('target'))
|
|
72
72
|
return this.getTinydnsGeneric(rdata)
|
|
73
73
|
}
|
package/rr/dnskey.js
CHANGED
|
@@ -1,117 +1,124 @@
|
|
|
1
|
-
|
|
2
1
|
import RR from '../rr.js'
|
|
3
2
|
|
|
4
3
|
import * as TINYDNS from '../lib/tinydns.js'
|
|
5
4
|
|
|
6
5
|
export default class DNSKEY extends RR {
|
|
7
|
-
constructor
|
|
6
|
+
constructor(opts) {
|
|
8
7
|
super(opts)
|
|
9
8
|
}
|
|
10
9
|
|
|
11
10
|
/****** Resource record specific setters *******/
|
|
12
|
-
setFlags
|
|
11
|
+
setFlags(val) {
|
|
13
12
|
// a 2 octet Flags Field
|
|
14
13
|
this.is16bitInt('DNSKEY', 'flags', val)
|
|
15
14
|
|
|
16
15
|
// the possible values are: 0, 256, and 257; RFC 4034
|
|
17
|
-
if (![
|
|
16
|
+
if (![0, 256, 257].includes(val))
|
|
17
|
+
throw new Error(`DNSKEY: flags invalid, ${this.citeRFC()}`)
|
|
18
18
|
|
|
19
19
|
this.set('flags', val)
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
setProtocol
|
|
22
|
+
setProtocol(val) {
|
|
23
23
|
// 1 octet
|
|
24
24
|
this.is8bitInt('DNSKEY', 'protocol', val)
|
|
25
25
|
|
|
26
26
|
// The Protocol Field MUST be represented as an unsigned decimal integer with a value of 3.
|
|
27
|
-
if (![
|
|
27
|
+
if (![3].includes(val))
|
|
28
|
+
throw new Error(`DNSKEY: protocol invalid, ${this.citeRFC()}`)
|
|
28
29
|
|
|
29
30
|
this.set('protocol', val)
|
|
30
31
|
}
|
|
31
32
|
|
|
32
|
-
setAlgorithm
|
|
33
|
+
setAlgorithm(val) {
|
|
33
34
|
// 1 octet
|
|
34
35
|
this.is8bitInt('DNSKEY', 'algorithm', val)
|
|
35
36
|
|
|
36
37
|
// https://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml
|
|
37
38
|
// 1=RSA/MD5, 2=DH, 3=DSA/SHA-1, 4=EC, 5=RSA/SHA-1
|
|
38
|
-
if (![
|
|
39
|
-
console.error(
|
|
39
|
+
if (![...Array(16).keys(), 253, 254].includes(val))
|
|
40
|
+
console.error(
|
|
41
|
+
`DNSKEY: algorithm (${val}) not recognized, ${this.citeRFC()}`,
|
|
42
|
+
)
|
|
40
43
|
|
|
41
44
|
this.set('algorithm', val)
|
|
42
45
|
}
|
|
43
46
|
|
|
44
|
-
setPublickey
|
|
45
|
-
if (!val)
|
|
47
|
+
setPublickey(val) {
|
|
48
|
+
if (!val)
|
|
49
|
+
throw new Error(`DNSKEY: publickey is required, ${this.citeRFC()}`)
|
|
46
50
|
|
|
47
51
|
this.set('publickey', val)
|
|
48
52
|
}
|
|
49
53
|
|
|
50
|
-
getDescription
|
|
54
|
+
getDescription() {
|
|
51
55
|
return 'DNS Public Key'
|
|
52
56
|
}
|
|
53
57
|
|
|
54
|
-
getRdataFields
|
|
55
|
-
return [
|
|
58
|
+
getRdataFields(arg) {
|
|
59
|
+
return ['flags', 'protocol', 'algorithm', 'publickey']
|
|
56
60
|
}
|
|
57
61
|
|
|
58
|
-
getRFCs
|
|
59
|
-
return [
|
|
62
|
+
getRFCs() {
|
|
63
|
+
return [4034, 6014, 8624]
|
|
60
64
|
}
|
|
61
65
|
|
|
62
|
-
getTypeId
|
|
66
|
+
getTypeId() {
|
|
63
67
|
return 48
|
|
64
68
|
}
|
|
65
69
|
|
|
66
70
|
/****** IMPORTERS *******/
|
|
67
71
|
|
|
68
|
-
fromBind
|
|
72
|
+
fromBind(opts) {
|
|
69
73
|
// test.example.com 3600 IN DNSKEY Flags Protocol Algorithm PublicKey
|
|
70
|
-
const match = opts.bindline.match(
|
|
74
|
+
const match = opts.bindline.match(
|
|
75
|
+
/^([^\s]+)\s+([0-9]+)\s+(\w+)\s+(\w+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+\s*(.*?)\s*$/,
|
|
76
|
+
)
|
|
71
77
|
if (!match) throw new Error(`unable to parse DNSKEY: ${opts.bindline}`)
|
|
72
|
-
const [
|
|
78
|
+
const [owner, ttl, c, type, flags, protocol, algorithm, publickey] =
|
|
79
|
+
match.slice(1)
|
|
73
80
|
|
|
74
81
|
return new DNSKEY({
|
|
75
82
|
owner,
|
|
76
|
-
ttl
|
|
77
|
-
class
|
|
78
|
-
type
|
|
79
|
-
flags
|
|
80
|
-
protocol
|
|
81
|
-
algorithm: parseInt(algorithm,
|
|
83
|
+
ttl: parseInt(ttl, 10),
|
|
84
|
+
class: c,
|
|
85
|
+
type: type,
|
|
86
|
+
flags: parseInt(flags, 10),
|
|
87
|
+
protocol: parseInt(protocol, 10),
|
|
88
|
+
algorithm: parseInt(algorithm, 10),
|
|
82
89
|
publickey: publickey,
|
|
83
90
|
})
|
|
84
91
|
}
|
|
85
92
|
|
|
86
|
-
fromTinydns
|
|
87
|
-
const [
|
|
93
|
+
fromTinydns(opts) {
|
|
94
|
+
const [fqdn, n, rdata, ttl, ts, loc] = opts.tinyline.substring(1).split(':')
|
|
88
95
|
if (n != 48) throw new Error('DNSKEY fromTinydns, invalid n')
|
|
89
96
|
|
|
90
97
|
const bytes = Buffer.from(TINYDNS.octalToChar(rdata), 'binary')
|
|
91
98
|
|
|
92
99
|
return new DNSKEY({
|
|
93
|
-
owner
|
|
94
|
-
ttl
|
|
95
|
-
type
|
|
96
|
-
flags
|
|
97
|
-
protocol
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
timestamp
|
|
101
|
-
location
|
|
100
|
+
owner: this.fullyQualify(fqdn),
|
|
101
|
+
ttl: parseInt(ttl, 10),
|
|
102
|
+
type: 'DNSKEY',
|
|
103
|
+
flags: bytes.readUInt16BE(0),
|
|
104
|
+
protocol: bytes.readUInt8(2),
|
|
105
|
+
algorithm: bytes.readUInt8(3),
|
|
106
|
+
publickey: bytes.slice(4).toString(),
|
|
107
|
+
timestamp: ts,
|
|
108
|
+
location: loc !== '' && loc !== '\n' ? loc : '',
|
|
102
109
|
})
|
|
103
110
|
}
|
|
104
111
|
|
|
105
112
|
/****** EXPORTERS *******/
|
|
106
113
|
|
|
107
|
-
toTinydns
|
|
114
|
+
toTinydns() {
|
|
108
115
|
const dataRe = new RegExp(/[\r\n\t:\\/]/, 'g')
|
|
109
116
|
|
|
110
117
|
return this.getTinydnsGeneric(
|
|
111
118
|
TINYDNS.UInt16toOctal(this.get('flags')) +
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
119
|
+
TINYDNS.UInt8toOctal(this.get('protocol')) +
|
|
120
|
+
TINYDNS.UInt8toOctal(this.get('algorithm')) +
|
|
121
|
+
TINYDNS.escapeOctal(dataRe, this.get('publickey')),
|
|
115
122
|
)
|
|
116
123
|
}
|
|
117
124
|
}
|
package/rr/ds.js
CHANGED
|
@@ -1,104 +1,106 @@
|
|
|
1
|
-
|
|
2
1
|
import RR from '../rr.js'
|
|
3
2
|
|
|
4
3
|
import * as TINYDNS from '../lib/tinydns.js'
|
|
5
4
|
|
|
6
5
|
export default class DS extends RR {
|
|
7
|
-
constructor
|
|
6
|
+
constructor(opts) {
|
|
8
7
|
super(opts)
|
|
9
8
|
}
|
|
10
9
|
|
|
11
10
|
/****** Resource record specific setters *******/
|
|
12
|
-
setKeyTag
|
|
11
|
+
setKeyTag(val) {
|
|
13
12
|
// a 2 octet Key Tag field...in network byte order
|
|
14
13
|
if (!val) throw new Error(`DS: key tag is required`)
|
|
15
|
-
if (val.length > 2)
|
|
14
|
+
if (val.length > 2)
|
|
15
|
+
throw new Error(`DS: key tag is too long, ${this.citeRFC()}`)
|
|
16
16
|
|
|
17
17
|
this.set('key tag', val)
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
setAlgorithm
|
|
20
|
+
setAlgorithm(val) {
|
|
21
21
|
// 1=RSA/MD5, 2=DH, 3=DSA/SHA-1, 4=EC, 5=RSA/SHA-1
|
|
22
|
-
if (![
|
|
22
|
+
if (![1, 2, 3, 4, 5, 253, 254].includes(val))
|
|
23
23
|
throw new Error(`DS: algorithm invalid, ${this.citeRFC()}`)
|
|
24
24
|
|
|
25
25
|
this.set('algorithm', val)
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
setDigestType
|
|
29
|
-
if (![
|
|
28
|
+
setDigestType(val) {
|
|
29
|
+
if (![1, 2].includes(val))
|
|
30
|
+
throw new Error(`DS: digest type invalid, ${this.citeRFC()}`)
|
|
30
31
|
|
|
31
32
|
this.set('digest type', val)
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
setDigest
|
|
35
|
+
setDigest(val) {
|
|
35
36
|
if (!val) throw new Error(`DS: digest is required, ${this.citeRFC()}`)
|
|
36
37
|
|
|
37
38
|
this.set('digest', val)
|
|
38
39
|
}
|
|
39
40
|
|
|
40
|
-
getDescription
|
|
41
|
+
getDescription() {
|
|
41
42
|
return 'Delegation Signer'
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
getRdataFields
|
|
45
|
-
return [
|
|
45
|
+
getRdataFields(arg) {
|
|
46
|
+
return ['key tag', 'algorithm', 'digest type', 'digest']
|
|
46
47
|
}
|
|
47
48
|
|
|
48
|
-
getRFCs
|
|
49
|
-
return [
|
|
49
|
+
getRFCs() {
|
|
50
|
+
return [4034, 4509]
|
|
50
51
|
}
|
|
51
52
|
|
|
52
|
-
getTypeId
|
|
53
|
+
getTypeId() {
|
|
53
54
|
return 43
|
|
54
55
|
}
|
|
55
56
|
|
|
56
57
|
/****** IMPORTERS *******/
|
|
57
58
|
|
|
58
|
-
fromBind
|
|
59
|
+
fromBind(opts) {
|
|
59
60
|
// test.example.com 3600 IN DS Key Tag Algorithm, Digest Type, Digest
|
|
60
|
-
const [
|
|
61
|
+
const [owner, ttl, c, type, keytag, algorithm, digesttype] =
|
|
62
|
+
opts.bindline.split(/\s+/)
|
|
61
63
|
return new DS({
|
|
62
64
|
owner,
|
|
63
|
-
ttl
|
|
64
|
-
class
|
|
65
|
+
ttl: parseInt(ttl, 10),
|
|
66
|
+
class: c,
|
|
65
67
|
type,
|
|
66
|
-
'key tag'
|
|
67
|
-
algorithm
|
|
68
|
+
'key tag': parseInt(keytag, 10),
|
|
69
|
+
algorithm: parseInt(algorithm, 10),
|
|
68
70
|
'digest type': parseInt(digesttype, 10),
|
|
69
|
-
digest
|
|
71
|
+
digest: opts.bindline.split(/\s+/).slice(7).join(' ').trim(),
|
|
70
72
|
})
|
|
71
73
|
}
|
|
72
74
|
|
|
73
|
-
fromTinydns
|
|
74
|
-
const [
|
|
75
|
+
fromTinydns(opts) {
|
|
76
|
+
const [fqdn, n, rdata, ttl, ts, loc] = opts.tinyline.substring(1).split(':')
|
|
75
77
|
if (n != 43) throw new Error('DS fromTinydns, invalid n')
|
|
76
78
|
|
|
77
79
|
const binRdata = Buffer.from(TINYDNS.octalToChar(rdata), 'binary')
|
|
78
80
|
|
|
79
81
|
return new DS({
|
|
80
|
-
owner
|
|
81
|
-
ttl
|
|
82
|
-
type
|
|
83
|
-
'key tag'
|
|
84
|
-
algorithm
|
|
82
|
+
owner: this.fullyQualify(fqdn),
|
|
83
|
+
ttl: parseInt(ttl, 10),
|
|
84
|
+
type: 'DS',
|
|
85
|
+
'key tag': binRdata.readUInt16BE(0),
|
|
86
|
+
algorithm: binRdata.readUInt8(2),
|
|
85
87
|
'digest type': binRdata.readUInt8(3),
|
|
86
|
-
digest
|
|
87
|
-
timestamp
|
|
88
|
-
location
|
|
88
|
+
digest: binRdata.slice(4).toString(),
|
|
89
|
+
timestamp: ts,
|
|
90
|
+
location: loc !== '' && loc !== '\n' ? loc : '',
|
|
89
91
|
})
|
|
90
92
|
}
|
|
91
93
|
|
|
92
94
|
/****** EXPORTERS *******/
|
|
93
95
|
|
|
94
|
-
toTinydns
|
|
96
|
+
toTinydns() {
|
|
95
97
|
const rdataRe = new RegExp(/[\r\n\t:\\/]/, 'g')
|
|
96
98
|
|
|
97
99
|
return this.getTinydnsGeneric(
|
|
98
100
|
TINYDNS.UInt16toOctal(this.get('key tag')) +
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
101
|
+
TINYDNS.UInt8toOctal(this.get('algorithm')) +
|
|
102
|
+
TINYDNS.UInt8toOctal(this.get('digest type')) +
|
|
103
|
+
TINYDNS.escapeOctal(rdataRe, this.get('digest')),
|
|
102
104
|
)
|
|
103
105
|
}
|
|
104
106
|
}
|
package/rr/hinfo.js
CHANGED
|
@@ -1,54 +1,55 @@
|
|
|
1
|
-
|
|
2
1
|
import RR from '../rr.js'
|
|
3
2
|
|
|
4
3
|
import * as TINYDNS from '../lib/tinydns.js'
|
|
5
4
|
|
|
6
5
|
export default class HINFO extends RR {
|
|
7
|
-
constructor
|
|
6
|
+
constructor(opts) {
|
|
8
7
|
super(opts)
|
|
9
8
|
}
|
|
10
9
|
|
|
11
10
|
/****** Resource record specific setters *******/
|
|
12
|
-
setCpu
|
|
11
|
+
setCpu(val) {
|
|
13
12
|
if (val.length > 255) throw new Error('HINFO cpu cannot exceed 255 chars')
|
|
14
13
|
this.set('cpu', val.replace(/^["']|["']$/g, ''))
|
|
15
14
|
}
|
|
16
15
|
|
|
17
|
-
setOs
|
|
16
|
+
setOs(val) {
|
|
18
17
|
if (val.length > 255) throw new Error('HINFO os cannot exceed 255 chars')
|
|
19
18
|
this.set('os', val.replace(/^["']|["']$/g, ''))
|
|
20
19
|
}
|
|
21
20
|
|
|
22
|
-
getDescription
|
|
21
|
+
getDescription() {
|
|
23
22
|
return 'Host Info'
|
|
24
23
|
}
|
|
25
24
|
|
|
26
|
-
getRdataFields
|
|
27
|
-
return [
|
|
25
|
+
getRdataFields(arg) {
|
|
26
|
+
return ['cpu', 'os']
|
|
28
27
|
}
|
|
29
28
|
|
|
30
|
-
getRFCs
|
|
31
|
-
return [
|
|
29
|
+
getRFCs() {
|
|
30
|
+
return [1034, 1035, 8482]
|
|
32
31
|
}
|
|
33
32
|
|
|
34
|
-
getTypeId
|
|
33
|
+
getTypeId() {
|
|
35
34
|
return 13
|
|
36
35
|
}
|
|
37
36
|
|
|
38
|
-
getQuotedFields
|
|
39
|
-
return [
|
|
37
|
+
getQuotedFields() {
|
|
38
|
+
return ['cpu', 'os']
|
|
40
39
|
}
|
|
41
40
|
|
|
42
41
|
/****** IMPORTERS *******/
|
|
43
|
-
fromBind
|
|
42
|
+
fromBind(opts) {
|
|
44
43
|
// test.example.com 3600 IN HINFO DEC-2060 TOPS20
|
|
45
|
-
const match = opts.bindline.match(
|
|
44
|
+
const match = opts.bindline.match(
|
|
45
|
+
/([^\s]+)\s+([0-9]+)\s+(IN)\s+(HINFO)\s+("[^"]+"|[^\s]+)\s+("[^"]+"|[^\s]+)/i,
|
|
46
|
+
)
|
|
46
47
|
if (!match) throw new Error(`unable to parse HINFO: ${opts.bindline}`)
|
|
47
|
-
const [
|
|
48
|
+
const [owner, ttl, c, type, cpu, os] = match.slice(1)
|
|
48
49
|
|
|
49
50
|
return new HINFO({
|
|
50
51
|
owner,
|
|
51
|
-
ttl
|
|
52
|
+
ttl: parseInt(ttl, 10),
|
|
52
53
|
class: c,
|
|
53
54
|
type,
|
|
54
55
|
cpu,
|
|
@@ -56,29 +57,29 @@ export default class HINFO extends RR {
|
|
|
56
57
|
})
|
|
57
58
|
}
|
|
58
59
|
|
|
59
|
-
fromTinydns
|
|
60
|
+
fromTinydns(opts) {
|
|
60
61
|
// HINFO via generic, :fqdn:n:rdata:ttl:timestamp:lo
|
|
61
|
-
const [
|
|
62
|
-
const [
|
|
62
|
+
const [fqdn, , rdata, ttl, ts, loc] = opts.tinyline.substring(1).split(':')
|
|
63
|
+
const [cpu, os] = [...TINYDNS.unpackString(rdata)]
|
|
63
64
|
|
|
64
65
|
return new this.constructor({
|
|
65
|
-
owner
|
|
66
|
-
ttl
|
|
67
|
-
type
|
|
66
|
+
owner: this.fullyQualify(fqdn),
|
|
67
|
+
ttl: parseInt(ttl, 10),
|
|
68
|
+
type: 'HINFO',
|
|
68
69
|
cpu,
|
|
69
70
|
os,
|
|
70
71
|
timestamp: ts,
|
|
71
|
-
location
|
|
72
|
+
location: loc !== '' && loc !== '\n' ? loc : '',
|
|
72
73
|
})
|
|
73
74
|
}
|
|
74
75
|
|
|
75
76
|
/****** EXPORTERS *******/
|
|
76
|
-
toTinydns
|
|
77
|
+
toTinydns() {
|
|
77
78
|
return this.getTinydnsGeneric(
|
|
78
79
|
[
|
|
79
80
|
TINYDNS.packString(this.get('cpu')),
|
|
80
81
|
TINYDNS.packString(this.get('os')),
|
|
81
|
-
].join('')
|
|
82
|
+
].join(''),
|
|
82
83
|
)
|
|
83
84
|
}
|
|
84
85
|
}
|