@nictool/dns-resource-record 1.2.3 → 1.3.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/CHANGELOG.md +27 -7
- package/README.md +13 -19
- package/index.js +15 -0
- package/lib/tinydns.js +2 -6
- package/package.json +8 -6
- package/rr/aaaa.js +5 -4
- package/rr/apl.js +108 -0
- package/rr/caa.js +16 -10
- package/rr/cert.js +33 -5
- package/rr/cname.js +1 -2
- package/rr/dhcid.js +60 -0
- package/rr/dname.js +1 -2
- package/rr/dnskey.js +38 -11
- package/rr/ds.js +14 -5
- package/rr/hinfo.js +3 -9
- package/rr/hip.js +102 -0
- package/rr/https.js +12 -0
- package/rr/ipseckey.js +22 -9
- package/rr/key.js +15 -5
- package/rr/kx.js +77 -0
- package/rr/loc.js +6 -20
- package/rr/mx.js +3 -7
- package/rr/naptr.js +5 -2
- package/rr/ns.js +2 -6
- package/rr/nsec.js +12 -6
- package/rr/nsec3.js +2 -10
- package/rr/nxt.js +1 -6
- package/rr/openpgpkey.js +2 -3
- package/rr/rp.js +78 -0
- package/rr/rrsig.js +13 -3
- package/rr/smimea.js +44 -17
- package/rr/soa.js +3 -15
- package/rr/spf.js +1 -4
- package/rr/srv.js +3 -7
- package/rr/sshfp.js +20 -3
- package/rr/svcb.js +12 -0
- package/rr/tlsa.js +35 -19
- package/rr/tsig.js +1 -9
- package/rr/txt.js +7 -6
- package/rr/uri.js +1 -2
- package/rr/wks.js +37 -8
- package/rr.js +16 -32
package/rr/rp.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import RR from '../rr.js'
|
|
2
|
+
|
|
3
|
+
import * as TINYDNS from '../lib/tinydns.js'
|
|
4
|
+
|
|
5
|
+
export default class RP extends RR {
|
|
6
|
+
constructor(opts) {
|
|
7
|
+
super(opts)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/****** Resource record specific setters *******/
|
|
11
|
+
setMbox(val) {
|
|
12
|
+
if (!val) this.throwHelp('RP: mbox is required')
|
|
13
|
+
|
|
14
|
+
this.isFullyQualified('RP', 'mbox', val)
|
|
15
|
+
|
|
16
|
+
this.set('mbox', val.toLowerCase())
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
setTxt(val) {
|
|
20
|
+
if (!val) this.throwHelp('RP: txt is required')
|
|
21
|
+
|
|
22
|
+
this.isFullyQualified('RP', 'txt', val)
|
|
23
|
+
|
|
24
|
+
this.set('txt', val.toLowerCase())
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
getDescription() {
|
|
28
|
+
return 'Responsible Person'
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
getRdataFields(arg) {
|
|
32
|
+
return ['mbox', 'txt']
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
getRFCs() {
|
|
36
|
+
return [1183]
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
getTypeId() {
|
|
40
|
+
return 17
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
getCanonical() {
|
|
44
|
+
return {
|
|
45
|
+
owner: 'example.com.',
|
|
46
|
+
ttl: 3600,
|
|
47
|
+
class: 'IN',
|
|
48
|
+
type: 'RP',
|
|
49
|
+
mbox: 'admin.example.com.',
|
|
50
|
+
txt: 'info.example.com.',
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/****** IMPORTERS *******/
|
|
55
|
+
fromBind(opts) {
|
|
56
|
+
// test.example.com 3600 IN RP mbox txt
|
|
57
|
+
const [owner, ttl, c, type, mbox, txt] = opts.bindline.split(/\s+/)
|
|
58
|
+
return new RP({
|
|
59
|
+
owner,
|
|
60
|
+
ttl: parseInt(ttl, 10),
|
|
61
|
+
class: c,
|
|
62
|
+
type,
|
|
63
|
+
mbox,
|
|
64
|
+
txt,
|
|
65
|
+
})
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/****** EXPORTERS *******/
|
|
69
|
+
toBind(zone_opts) {
|
|
70
|
+
return `${this.getPrefix(zone_opts)}\t${this.getFQDN('mbox', zone_opts)}\t${this.getFQDN('txt', zone_opts)}\n`
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
toTinydns() {
|
|
74
|
+
return this.getTinydnsGeneric(
|
|
75
|
+
TINYDNS.packDomainName(this.get('mbox')) + TINYDNS.packDomainName(this.get('txt')),
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
}
|
package/rr/rrsig.js
CHANGED
|
@@ -16,13 +16,23 @@ export default class RRSIG extends RR {
|
|
|
16
16
|
|
|
17
17
|
setAlgorithm(val) {
|
|
18
18
|
// a 1 octet Algorithm field
|
|
19
|
-
|
|
20
|
-
if (![1, 2, 3, 4, 5, 253, 254].includes(val))
|
|
21
|
-
this.throwHelp(`RRSIG: algorithm invalid`)
|
|
19
|
+
if (!this.getAlgorithmOptions().has(val)) this.throwHelp(`RRSIG: algorithm invalid`)
|
|
22
20
|
|
|
23
21
|
this.set('algorithm', val)
|
|
24
22
|
}
|
|
25
23
|
|
|
24
|
+
getAlgorithmOptions() {
|
|
25
|
+
return new Map([
|
|
26
|
+
[1, 'RSA/MD5'],
|
|
27
|
+
[2, 'DH'],
|
|
28
|
+
[3, 'RRSIGA/SHA-1'],
|
|
29
|
+
[4, 'EC'],
|
|
30
|
+
[5, 'RSA/SHA-1'],
|
|
31
|
+
[253],
|
|
32
|
+
[254],
|
|
33
|
+
])
|
|
34
|
+
}
|
|
35
|
+
|
|
26
36
|
setLabels(val) {
|
|
27
37
|
// a 1 octet Labels field
|
|
28
38
|
this.is8bitInt('RRSIG', 'labels', val)
|
package/rr/smimea.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import RR from '../rr.js'
|
|
2
2
|
|
|
3
|
+
import * as TINYDNS from '../lib/tinydns.js'
|
|
4
|
+
|
|
3
5
|
export default class SMIMEA extends RR {
|
|
4
6
|
constructor(opts) {
|
|
5
7
|
super(opts)
|
|
@@ -7,24 +9,47 @@ export default class SMIMEA extends RR {
|
|
|
7
9
|
|
|
8
10
|
/****** Resource record specific setters *******/
|
|
9
11
|
setCertificateUsage(val) {
|
|
10
|
-
if (!
|
|
11
|
-
this.throwHelp(`SMIMEA: certificate usage invalid`)
|
|
12
|
+
if (!this.getCertificateUsageOptions().has(val)) this.throwHelp(`SMIMEA: certificate usage invalid`)
|
|
12
13
|
|
|
13
14
|
this.set('certificate usage', val)
|
|
14
15
|
}
|
|
15
16
|
|
|
17
|
+
getCertificateUsageOptions() {
|
|
18
|
+
return new Map([
|
|
19
|
+
[0, 'CA certificate'],
|
|
20
|
+
[1, 'an end entity certificate'],
|
|
21
|
+
[2, 'the trust anchor'],
|
|
22
|
+
[3, 'domain-issued certificate'],
|
|
23
|
+
])
|
|
24
|
+
}
|
|
25
|
+
|
|
16
26
|
setSelector(val) {
|
|
17
|
-
if (!
|
|
27
|
+
if (!this.getSelectorOptions().has(val)) this.throwHelp(`SMIMEA: selector invalid`)
|
|
18
28
|
|
|
19
29
|
this.set('selector', val)
|
|
20
30
|
}
|
|
21
31
|
|
|
32
|
+
getSelectorOptions() {
|
|
33
|
+
return new Map([
|
|
34
|
+
[0, 'Full certificate'],
|
|
35
|
+
[1, 'SubjectPublicKeyInfo'],
|
|
36
|
+
])
|
|
37
|
+
}
|
|
38
|
+
|
|
22
39
|
setMatchingType(val) {
|
|
23
|
-
if (!
|
|
40
|
+
if (!this.getMatchingTypeOptions().has(val)) this.throwHelp(`SMIMEA: matching type`)
|
|
24
41
|
|
|
25
42
|
this.set('matching type', val)
|
|
26
43
|
}
|
|
27
44
|
|
|
45
|
+
getMatchingTypeOptions() {
|
|
46
|
+
return new Map([
|
|
47
|
+
[0, 'Exact match'],
|
|
48
|
+
[1, 'SHA-256 hash'],
|
|
49
|
+
[2, 'SHA-512 hash'],
|
|
50
|
+
])
|
|
51
|
+
}
|
|
52
|
+
|
|
28
53
|
setCertificateAssociationData(val) {
|
|
29
54
|
this.set('certificate association data', val)
|
|
30
55
|
}
|
|
@@ -34,12 +59,7 @@ export default class SMIMEA extends RR {
|
|
|
34
59
|
}
|
|
35
60
|
|
|
36
61
|
getRdataFields(arg) {
|
|
37
|
-
return [
|
|
38
|
-
'certificate usage',
|
|
39
|
-
'selector',
|
|
40
|
-
'matching type',
|
|
41
|
-
'certificate association data',
|
|
42
|
-
]
|
|
62
|
+
return ['certificate usage', 'selector', 'matching type', 'certificate association data']
|
|
43
63
|
}
|
|
44
64
|
|
|
45
65
|
getRFCs() {
|
|
@@ -58,8 +78,7 @@ export default class SMIMEA extends RR {
|
|
|
58
78
|
|
|
59
79
|
fromBind(opts) {
|
|
60
80
|
// test.example.com 3600 IN SMIMEA, usage, selector, match, data
|
|
61
|
-
const [owner, ttl, c, type, usage, selector, match] =
|
|
62
|
-
opts.bindline.split(/\s+/)
|
|
81
|
+
const [owner, ttl, c, type, usage, selector, match] = opts.bindline.split(/\s+/)
|
|
63
82
|
return new SMIMEA({
|
|
64
83
|
owner,
|
|
65
84
|
ttl: parseInt(ttl, 10),
|
|
@@ -68,11 +87,19 @@ export default class SMIMEA extends RR {
|
|
|
68
87
|
'certificate usage': parseInt(usage, 10),
|
|
69
88
|
selector: parseInt(selector, 10),
|
|
70
89
|
'matching type': parseInt(match, 10),
|
|
71
|
-
'certificate association data': opts.bindline
|
|
72
|
-
.split(/\s+/)
|
|
73
|
-
.slice(7)
|
|
74
|
-
.join(' ')
|
|
75
|
-
.trim(),
|
|
90
|
+
'certificate association data': opts.bindline.split(/\s+/).slice(7).join(' ').trim(),
|
|
76
91
|
})
|
|
77
92
|
}
|
|
93
|
+
|
|
94
|
+
/****** EXPORTERS *******/
|
|
95
|
+
toTinydns() {
|
|
96
|
+
const dataRe = new RegExp(/[\r\n\t:\\/]/, 'g')
|
|
97
|
+
|
|
98
|
+
return this.getTinydnsGeneric(
|
|
99
|
+
TINYDNS.UInt8toOctal(this.get('certificate usage')) +
|
|
100
|
+
TINYDNS.UInt8toOctal(this.get('selector')) +
|
|
101
|
+
TINYDNS.UInt8toOctal(this.get('matching type')) +
|
|
102
|
+
TINYDNS.escapeOctal(dataRe, this.get('certificate association data')),
|
|
103
|
+
)
|
|
104
|
+
}
|
|
78
105
|
}
|
package/rr/soa.js
CHANGED
|
@@ -86,19 +86,8 @@ export default class SOA extends RR {
|
|
|
86
86
|
/****** IMPORTERS *******/
|
|
87
87
|
fromBind(opts) {
|
|
88
88
|
// example.com TTL IN SOA mname rname serial refresh retry expire minimum
|
|
89
|
-
const [
|
|
90
|
-
|
|
91
|
-
ttl,
|
|
92
|
-
c,
|
|
93
|
-
type,
|
|
94
|
-
mname,
|
|
95
|
-
rname,
|
|
96
|
-
serial,
|
|
97
|
-
refresh,
|
|
98
|
-
retry,
|
|
99
|
-
expire,
|
|
100
|
-
minimum,
|
|
101
|
-
] = opts.bindline.split(/[\s+]/)
|
|
89
|
+
const [owner, ttl, c, type, mname, rname, serial, refresh, retry, expire, minimum] =
|
|
90
|
+
opts.bindline.split(/[\s+]/)
|
|
102
91
|
|
|
103
92
|
return new SOA({
|
|
104
93
|
owner,
|
|
@@ -117,8 +106,7 @@ export default class SOA extends RR {
|
|
|
117
106
|
|
|
118
107
|
fromTinydns(opts) {
|
|
119
108
|
// Zfqdn:mname:rname:ser:ref:ret:exp:min:ttl:time:lo
|
|
120
|
-
const [fqdn, mname, rname, ser, ref, ret, exp, min, ttl, ts, loc] =
|
|
121
|
-
opts.tinyline.substring(1).split(':')
|
|
109
|
+
const [fqdn, mname, rname, ser, ref, ret, exp, min, ttl, ts, loc] = opts.tinyline.substring(1).split(':')
|
|
122
110
|
|
|
123
111
|
return new SOA({
|
|
124
112
|
owner: this.fullyQualify(fqdn),
|
package/rr/spf.js
CHANGED
|
@@ -48,10 +48,7 @@ export default class SPF extends TXT {
|
|
|
48
48
|
|
|
49
49
|
/****** EXPORTERS *******/
|
|
50
50
|
toTinydns() {
|
|
51
|
-
const rdata = TINYDNS.escapeOctal(
|
|
52
|
-
new RegExp(/[\r\n\t:\\/]/, 'g'),
|
|
53
|
-
this.get('data'),
|
|
54
|
-
)
|
|
51
|
+
const rdata = TINYDNS.escapeOctal(new RegExp(/[\r\n\t:\\/]/, 'g'), this.get('data'))
|
|
55
52
|
return this.getTinydnsGeneric(rdata)
|
|
56
53
|
}
|
|
57
54
|
}
|
package/rr/srv.js
CHANGED
|
@@ -28,8 +28,7 @@ export default class SRV extends RR {
|
|
|
28
28
|
setTarget(val) {
|
|
29
29
|
if (!val) this.throwHelp(`SRV: target is required`)
|
|
30
30
|
|
|
31
|
-
if (this.isIPv4(val) || this.isIPv6(val))
|
|
32
|
-
this.throwHelp(`SRV: target must be a FQDN`)
|
|
31
|
+
if (this.isIPv4(val) || this.isIPv6(val)) this.throwHelp(`SRV: target must be a FQDN`)
|
|
33
32
|
|
|
34
33
|
this.isFullyQualified('SRV', 'target', val)
|
|
35
34
|
this.isValidHostname('SRV', 'target', val)
|
|
@@ -61,9 +60,7 @@ export default class SRV extends RR {
|
|
|
61
60
|
|
|
62
61
|
if (str[0] === 'S') {
|
|
63
62
|
// patched tinydns with S records
|
|
64
|
-
;[fqdn, addr, port, pri, weight, ttl, ts, loc] = str
|
|
65
|
-
.substring(1)
|
|
66
|
-
.split(':')
|
|
63
|
+
;[fqdn, addr, port, pri, weight, ttl, ts, loc] = str.substring(1).split(':')
|
|
67
64
|
} else {
|
|
68
65
|
// tinydns generic record format
|
|
69
66
|
;[fqdn, n, rdata, ttl, ts, loc] = str.substring(1).split(':')
|
|
@@ -90,8 +87,7 @@ export default class SRV extends RR {
|
|
|
90
87
|
|
|
91
88
|
fromBind(opts) {
|
|
92
89
|
// test.example.com 3600 IN SRV Priority Weight Port Target
|
|
93
|
-
const [owner, ttl, c, type, pri, weight, port, target] =
|
|
94
|
-
opts.bindline.split(/\s+/)
|
|
90
|
+
const [owner, ttl, c, type, pri, weight, port, target] = opts.bindline.split(/\s+/)
|
|
95
91
|
return new SRV({
|
|
96
92
|
owner: owner,
|
|
97
93
|
ttl: parseInt(ttl, 10),
|
package/rr/sshfp.js
CHANGED
|
@@ -8,19 +8,36 @@ export default class SSHFP extends RR {
|
|
|
8
8
|
|
|
9
9
|
/****** Resource record specific setters *******/
|
|
10
10
|
setAlgorithm(val) {
|
|
11
|
-
// 0: reserved 1: RSA 2: DSA 3: ECDSA 4: Ed25519 6: Ed448
|
|
12
11
|
this.is8bitInt('SSHFP', 'algorithm', val)
|
|
13
12
|
|
|
14
13
|
this.set('algorithm', val)
|
|
15
14
|
}
|
|
16
15
|
|
|
16
|
+
getAlgorithmOptions() {
|
|
17
|
+
return new Map([
|
|
18
|
+
[0, 'reserved'],
|
|
19
|
+
[1, 'RSA'],
|
|
20
|
+
[2, 'DSA'],
|
|
21
|
+
[3, 'ECDSA'],
|
|
22
|
+
[4, 'Ed25519'],
|
|
23
|
+
[6, 'Ed448'],
|
|
24
|
+
])
|
|
25
|
+
}
|
|
26
|
+
|
|
17
27
|
setFptype(val) {
|
|
18
|
-
|
|
19
|
-
this.is8bitInt('SSHFP', 'type', val)
|
|
28
|
+
this.is8bitInt('SSHFP', 'fptype', val)
|
|
20
29
|
|
|
21
30
|
this.set('fptype', val)
|
|
22
31
|
}
|
|
23
32
|
|
|
33
|
+
getFptypeOptions() {
|
|
34
|
+
return new Map([
|
|
35
|
+
[0, 'reserved'],
|
|
36
|
+
[1, 'SHA-1'],
|
|
37
|
+
[2, 'SHA-256'],
|
|
38
|
+
])
|
|
39
|
+
}
|
|
40
|
+
|
|
24
41
|
setFingerprint(val) {
|
|
25
42
|
this.set('fingerprint', val)
|
|
26
43
|
}
|
package/rr/svcb.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import RR from '../rr.js'
|
|
2
2
|
|
|
3
|
+
import * as TINYDNS from '../lib/tinydns.js'
|
|
4
|
+
|
|
3
5
|
export default class SVCB extends RR {
|
|
4
6
|
constructor(opts) {
|
|
5
7
|
super(opts)
|
|
@@ -61,4 +63,14 @@ export default class SVCB extends RR {
|
|
|
61
63
|
}
|
|
62
64
|
|
|
63
65
|
/****** EXPORTERS *******/
|
|
66
|
+
|
|
67
|
+
toTinydns() {
|
|
68
|
+
const dataRe = new RegExp(/[\r\n\t:\\/]/, 'g')
|
|
69
|
+
|
|
70
|
+
return this.getTinydnsGeneric(
|
|
71
|
+
TINYDNS.UInt16toOctal(this.get('priority')) +
|
|
72
|
+
TINYDNS.packDomainName(this.get('target name')) +
|
|
73
|
+
TINYDNS.escapeOctal(dataRe, this.get('params')),
|
|
74
|
+
)
|
|
75
|
+
}
|
|
64
76
|
}
|
package/rr/tlsa.js
CHANGED
|
@@ -9,24 +9,47 @@ export default class TLSA extends RR {
|
|
|
9
9
|
|
|
10
10
|
/****** Resource record specific setters *******/
|
|
11
11
|
setCertificateUsage(val) {
|
|
12
|
-
if (!
|
|
13
|
-
this.throwHelp(`TLSA: certificate usage invalid`)
|
|
12
|
+
if (!this.getCertificateUsageOptions().has(val)) this.throwHelp(`TLSA: certificate usage invalid`)
|
|
14
13
|
|
|
15
14
|
this.set('certificate usage', val)
|
|
16
15
|
}
|
|
17
16
|
|
|
17
|
+
getCertificateUsageOptions() {
|
|
18
|
+
return new Map([
|
|
19
|
+
[0, 'CA certificate'],
|
|
20
|
+
[1, 'an end entity certificate'],
|
|
21
|
+
[2, 'the trust anchor'],
|
|
22
|
+
[3, 'domain-issued certificate'],
|
|
23
|
+
])
|
|
24
|
+
}
|
|
25
|
+
|
|
18
26
|
setSelector(val) {
|
|
19
|
-
if (!
|
|
27
|
+
if (!this.getSelectorOptions().has(val)) this.throwHelp(`TLSA: selector invalid`)
|
|
20
28
|
|
|
21
29
|
this.set('selector', val)
|
|
22
30
|
}
|
|
23
31
|
|
|
32
|
+
getSelectorOptions() {
|
|
33
|
+
return new Map([
|
|
34
|
+
[0, 'Full certificate'],
|
|
35
|
+
[1, 'SubjectPublicKeyInfo'],
|
|
36
|
+
])
|
|
37
|
+
}
|
|
38
|
+
|
|
24
39
|
setMatchingType(val) {
|
|
25
|
-
if (!
|
|
40
|
+
if (!this.getMatchingTypeOptions().has(val)) this.throwHelp(`TLSA: matching type`)
|
|
26
41
|
|
|
27
42
|
this.set('matching type', val)
|
|
28
43
|
}
|
|
29
44
|
|
|
45
|
+
getMatchingTypeOptions() {
|
|
46
|
+
return new Map([
|
|
47
|
+
[0, 'Exact match'],
|
|
48
|
+
[1, 'SHA-256 hash'],
|
|
49
|
+
[2, 'SHA-512 hash'],
|
|
50
|
+
])
|
|
51
|
+
}
|
|
52
|
+
|
|
30
53
|
setCertificateAssociationData(val) {
|
|
31
54
|
this.set('certificate association data', val)
|
|
32
55
|
}
|
|
@@ -36,12 +59,7 @@ export default class TLSA extends RR {
|
|
|
36
59
|
}
|
|
37
60
|
|
|
38
61
|
getRdataFields(arg) {
|
|
39
|
-
return [
|
|
40
|
-
'certificate usage',
|
|
41
|
-
'selector',
|
|
42
|
-
'matching type',
|
|
43
|
-
'certificate association data',
|
|
44
|
-
]
|
|
62
|
+
return ['certificate usage', 'selector', 'matching type', 'certificate association data']
|
|
45
63
|
}
|
|
46
64
|
|
|
47
65
|
getRFCs() {
|
|
@@ -60,19 +78,17 @@ export default class TLSA extends RR {
|
|
|
60
78
|
|
|
61
79
|
fromBind(opts) {
|
|
62
80
|
// test.example.com 3600 IN TLSA, usage, selector, match, data
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
/^([^\s]+)\s+([0-9]{1,10})\s+(IN)\s+(TLSA)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+(.*?)$/,
|
|
67
|
-
)
|
|
81
|
+
const regex =
|
|
82
|
+
/^(?<owner>\S+)\s+(?<ttl>\d{1,10})\s+(?<cls>IN)\s+(?<type>TLSA)\s+(?<usage>\d+)\s+(?<selector>\d+)\s+(?<matchtype>\d+)\s+(?<cad>.+)$/i
|
|
83
|
+
const match = opts.bindline.trim().match(regex)
|
|
68
84
|
if (!match) this.throwHelp(`unable to parse TLSA: ${opts.bindline}`)
|
|
69
|
-
const
|
|
70
|
-
|
|
85
|
+
const { owner, ttl, cls, type, usage, selector, matchtype, cad } = match.groups
|
|
86
|
+
|
|
71
87
|
return new TLSA({
|
|
72
88
|
owner: this.fullyQualify(owner),
|
|
73
89
|
ttl: parseInt(ttl, 10),
|
|
74
|
-
class:
|
|
75
|
-
type,
|
|
90
|
+
class: cls.toUpperCase(),
|
|
91
|
+
type: type.toUpperCase(),
|
|
76
92
|
'certificate usage': parseInt(usage, 10),
|
|
77
93
|
selector: parseInt(selector, 10),
|
|
78
94
|
'matching type': parseInt(matchtype, 10),
|
package/rr/tsig.js
CHANGED
|
@@ -13,15 +13,7 @@ export default class TSIG extends RR {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
getRdataFields(arg) {
|
|
16
|
-
return [
|
|
17
|
-
'algorithm name',
|
|
18
|
-
'time signed',
|
|
19
|
-
'fudge',
|
|
20
|
-
'mac',
|
|
21
|
-
'original id',
|
|
22
|
-
'error',
|
|
23
|
-
'other',
|
|
24
|
-
]
|
|
16
|
+
return ['algorithm name', 'time signed', 'fudge', 'mac', 'original id', 'error', 'other']
|
|
25
17
|
}
|
|
26
18
|
|
|
27
19
|
getRFCs() {
|
package/rr/txt.js
CHANGED
|
@@ -70,17 +70,18 @@ export default class TXT extends RR {
|
|
|
70
70
|
|
|
71
71
|
fromBind(opts) {
|
|
72
72
|
// test.example.com 3600 IN TXT "..."
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
const regex =
|
|
74
|
+
/^(?<owner>[\S]{1,255})\s+(?<ttl>\d{1,10})\s+(?<cls>IN)\s+(?<type>\w{3})\s+?\s*(?<rdata>.+?)$/i
|
|
75
|
+
const match = opts.bindline.trim().match(regex)
|
|
76
76
|
if (!match) this.throwHelp(`unable to parse TXT: ${opts.bindline}`)
|
|
77
|
-
|
|
77
|
+
|
|
78
|
+
const { owner, ttl, cls, type, rdata } = match.groups
|
|
78
79
|
|
|
79
80
|
return new this.constructor({
|
|
80
81
|
owner,
|
|
81
82
|
ttl: parseInt(ttl, 10),
|
|
82
|
-
class:
|
|
83
|
-
type,
|
|
83
|
+
class: cls,
|
|
84
|
+
type: type.toUpperCase(),
|
|
84
85
|
data: rdata
|
|
85
86
|
.match(/"([^"]+?)"/g)
|
|
86
87
|
.map((s) => s.replace(/^"|"$/g, ''))
|
package/rr/uri.js
CHANGED
|
@@ -46,8 +46,7 @@ export default class URI extends RR {
|
|
|
46
46
|
|
|
47
47
|
fromBind(opts) {
|
|
48
48
|
// test.example.com 3600 IN URI priority, weight, target
|
|
49
|
-
const [owner, ttl, c, type, priority, weight, target] =
|
|
50
|
-
opts.bindline.split(/\s+/)
|
|
49
|
+
const [owner, ttl, c, type, priority, weight, target] = opts.bindline.split(/\s+/)
|
|
51
50
|
return new URI({
|
|
52
51
|
class: c,
|
|
53
52
|
type: type,
|
package/rr/wks.js
CHANGED
|
@@ -1,19 +1,36 @@
|
|
|
1
1
|
import RR from '../rr.js'
|
|
2
2
|
|
|
3
|
+
import * as TINYDNS from '../lib/tinydns.js'
|
|
4
|
+
|
|
3
5
|
export default class WKS extends RR {
|
|
4
6
|
constructor(opts) {
|
|
5
7
|
super(opts)
|
|
6
|
-
if (opts === null) return
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
/****** Resource record specific setters *******/
|
|
11
|
+
setAddress(val) {
|
|
12
|
+
if (!val) this.throwHelp('WKS: address is required')
|
|
13
|
+
if (!this.isIPv4(val)) this.throwHelp('WKS address must be IPv4')
|
|
14
|
+
this.set('address', val)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
setProtocol(val) {
|
|
18
|
+
if (!val) this.throwHelp('WKS: protocol is required')
|
|
19
|
+
const upper = typeof val === 'string' ? val.toUpperCase() : val
|
|
20
|
+
if (!['TCP', 'UDP', 6, 17].includes(upper)) this.throwHelp('WKS protocol must be TCP or UDP')
|
|
21
|
+
this.set('protocol', upper)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
setBitMap(val) {
|
|
25
|
+
this.set('bit map', val ?? '')
|
|
26
|
+
}
|
|
10
27
|
|
|
11
28
|
getDescription() {
|
|
12
29
|
return 'Well Known Service'
|
|
13
30
|
}
|
|
14
31
|
|
|
15
32
|
getRdataFields(arg) {
|
|
16
|
-
return ['bit map']
|
|
33
|
+
return ['address', 'protocol', 'bit map']
|
|
17
34
|
}
|
|
18
35
|
|
|
19
36
|
getRFCs() {
|
|
@@ -27,19 +44,31 @@ export default class WKS extends RR {
|
|
|
27
44
|
/****** IMPORTERS *******/
|
|
28
45
|
|
|
29
46
|
fromBind(opts) {
|
|
30
|
-
// test.example.com 3600 IN WKS 192.168.1.1 TCP
|
|
31
|
-
const
|
|
32
|
-
|
|
47
|
+
// test.example.com 3600 IN WKS 192.168.1.1 TCP ftp smtp
|
|
48
|
+
const parts = opts.bindline.split(/\s+/)
|
|
49
|
+
const [owner, ttl, c, type, address, protocol] = parts
|
|
33
50
|
return new WKS({
|
|
34
51
|
owner,
|
|
35
52
|
ttl: parseInt(ttl, 10),
|
|
36
53
|
class: c,
|
|
37
54
|
type,
|
|
38
|
-
address,
|
|
39
|
-
protocol,
|
|
40
|
-
|
|
55
|
+
address,
|
|
56
|
+
protocol,
|
|
57
|
+
'bit map': parts.slice(6).join(' ').trim(),
|
|
41
58
|
})
|
|
42
59
|
}
|
|
43
60
|
|
|
44
61
|
/****** EXPORTERS *******/
|
|
62
|
+
|
|
63
|
+
toTinydns() {
|
|
64
|
+
const dataRe = new RegExp(/[\r\n\t:\\/]/, 'g')
|
|
65
|
+
const protoMap = { TCP: 6, UDP: 17, 6: 6, 17: 17 }
|
|
66
|
+
const protoNum = protoMap[this.get('protocol')]
|
|
67
|
+
|
|
68
|
+
return this.getTinydnsGeneric(
|
|
69
|
+
TINYDNS.ipv4toOctal(this.get('address')) +
|
|
70
|
+
TINYDNS.UInt8toOctal(protoNum) +
|
|
71
|
+
TINYDNS.escapeOctal(dataRe, this.get('bit map')),
|
|
72
|
+
)
|
|
73
|
+
}
|
|
45
74
|
}
|