@nictool/dns-resource-record 1.4.0 → 1.6.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 +30 -1
- package/README.md +49 -42
- package/lib/readme.js +84 -0
- package/lib/tinydns.js +20 -10
- package/package.json +3 -2
- package/rr/a.js +13 -5
- package/rr/aaaa.js +19 -11
- package/rr/apl.js +49 -2
- package/rr/caa.js +30 -23
- package/rr/cert.js +44 -7
- package/rr/cname.js +22 -5
- package/rr/dhcid.js +17 -2
- package/rr/dname.js +15 -5
- package/rr/dnskey.js +31 -8
- package/rr/ds.js +23 -6
- package/rr/hinfo.js +28 -10
- package/rr/hip.js +43 -2
- package/rr/https.js +38 -9
- package/rr/ipseckey.js +20 -16
- package/rr/key.js +26 -17
- package/rr/kx.js +18 -2
- package/rr/loc.js +24 -14
- package/rr/mx.js +16 -6
- package/rr/naptr.js +39 -20
- package/rr/ns.js +23 -5
- package/rr/nsec.js +21 -6
- package/rr/nsec3.js +71 -7
- package/rr/nsec3param.js +52 -22
- package/rr/nxt.js +22 -7
- package/rr/openpgpkey.js +28 -8
- package/rr/ptr.js +23 -5
- package/rr/rp.js +23 -2
- package/rr/rrsig.js +106 -10
- package/rr/sig.js +111 -13
- package/rr/smimea.js +23 -6
- package/rr/soa.js +36 -6
- package/rr/spf.js +17 -3
- package/rr/srv.js +28 -11
- package/rr/sshfp.js +24 -8
- package/rr/svcb.js +37 -10
- package/rr/tlsa.js +26 -9
- package/rr/tsig.js +155 -13
- package/rr/txt.js +46 -12
- package/rr/uri.js +20 -8
- package/rr/wks.js +42 -2
- package/rr.js +109 -7
package/rr/cert.js
CHANGED
|
@@ -11,8 +11,29 @@ export default class CERT extends RR {
|
|
|
11
11
|
setCertType(val) {
|
|
12
12
|
// The type field is the certificate type
|
|
13
13
|
// the type field as an unsigned decimal integer or as a mnemonic symbol
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
if (val === undefined || val === null || val === '') {
|
|
15
|
+
this.throwHelp('cert type is required')
|
|
16
|
+
}
|
|
17
|
+
// Accept both mnemonic and numeric, but validate mnemonic
|
|
18
|
+
if (typeof val === 'string') {
|
|
19
|
+
const types = {
|
|
20
|
+
PKIX: 1,
|
|
21
|
+
SPKI: 2,
|
|
22
|
+
PGP: 3,
|
|
23
|
+
IPKIX: 4,
|
|
24
|
+
ISPKI: 5,
|
|
25
|
+
IPGP: 6,
|
|
26
|
+
ACPKIX: 7,
|
|
27
|
+
IACPKIX: 8,
|
|
28
|
+
URI: 253,
|
|
29
|
+
OID: 254,
|
|
30
|
+
}
|
|
31
|
+
if (!Object.hasOwn(types, val)) {
|
|
32
|
+
this.throwHelp(`CERT: unknown cert type mnemonic: ${val}`)
|
|
33
|
+
}
|
|
34
|
+
} else {
|
|
35
|
+
this.is16bitInt('CERT', 'cert type', val)
|
|
36
|
+
}
|
|
16
37
|
this.set('cert type', val)
|
|
17
38
|
}
|
|
18
39
|
|
|
@@ -54,6 +75,9 @@ export default class CERT extends RR {
|
|
|
54
75
|
setCertificate(val) {
|
|
55
76
|
// certificate/CRL portion is represented in base 64 [16] and may be
|
|
56
77
|
// divided into any number of white-space-separated substrings
|
|
78
|
+
if (val === undefined || val === null || val === '') {
|
|
79
|
+
this.throwHelp('certificate is required and cannot be empty')
|
|
80
|
+
}
|
|
57
81
|
this.set('certificate', val)
|
|
58
82
|
}
|
|
59
83
|
|
|
@@ -73,10 +97,23 @@ export default class CERT extends RR {
|
|
|
73
97
|
return 37
|
|
74
98
|
}
|
|
75
99
|
|
|
100
|
+
getCanonical() {
|
|
101
|
+
return {
|
|
102
|
+
owner: 'mail.example.com.',
|
|
103
|
+
ttl: 3600,
|
|
104
|
+
class: 'IN',
|
|
105
|
+
type: 'CERT',
|
|
106
|
+
'cert type': 'PGP',
|
|
107
|
+
'key tag': 0,
|
|
108
|
+
algorithm: 0,
|
|
109
|
+
certificate: 'hexidecimalkeystring1',
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
76
113
|
/****** IMPORTERS *******/
|
|
77
114
|
|
|
78
|
-
fromTinydns(
|
|
79
|
-
const [owner, n, rdata, ttl, ts, loc] =
|
|
115
|
+
fromTinydns({ tinyline }) {
|
|
116
|
+
const [owner, n, rdata, ttl, ts, loc] = tinyline.slice(1).split(':')
|
|
80
117
|
if (n != 37) this.throwHelp('CERT fromTinydns, invalid n')
|
|
81
118
|
|
|
82
119
|
const bytes = Buffer.from(TINYDNS.octalToChar(rdata), 'binary')
|
|
@@ -106,13 +143,13 @@ export default class CERT extends RR {
|
|
|
106
143
|
algorithm: bytes.readUInt8(4),
|
|
107
144
|
certificate: bytes.slice(5).toString(),
|
|
108
145
|
timestamp: ts,
|
|
109
|
-
location: loc
|
|
146
|
+
location: loc?.trim() ?? '',
|
|
110
147
|
})
|
|
111
148
|
}
|
|
112
149
|
|
|
113
|
-
fromBind(
|
|
150
|
+
fromBind({ bindline }) {
|
|
114
151
|
// test.example.com 3600 IN CERT certtype, keytag, algo, cert
|
|
115
|
-
const [owner, ttl, c, type, certtype, keytag, algo, certificate] =
|
|
152
|
+
const [owner, ttl, c, type, certtype, keytag, algo, certificate] = bindline.split(/\s+/)
|
|
116
153
|
return new CERT({
|
|
117
154
|
owner,
|
|
118
155
|
ttl: parseInt(ttl, 10),
|
package/rr/cname.js
CHANGED
|
@@ -25,6 +25,10 @@ export default class CNAME extends RR {
|
|
|
25
25
|
return 'Canonical Name'
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
getTags() {
|
|
29
|
+
return ['common']
|
|
30
|
+
}
|
|
31
|
+
|
|
28
32
|
getRdataFields(arg) {
|
|
29
33
|
return ['cname']
|
|
30
34
|
}
|
|
@@ -37,10 +41,20 @@ export default class CNAME extends RR {
|
|
|
37
41
|
return 5
|
|
38
42
|
}
|
|
39
43
|
|
|
44
|
+
getCanonical() {
|
|
45
|
+
return {
|
|
46
|
+
owner: 'www.example.com.',
|
|
47
|
+
ttl: 3600,
|
|
48
|
+
class: 'IN',
|
|
49
|
+
type: 'CNAME',
|
|
50
|
+
cname: 'web.example.com.',
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
40
54
|
/****** IMPORTERS *******/
|
|
41
|
-
fromTinydns(
|
|
55
|
+
fromTinydns({ tinyline }) {
|
|
42
56
|
// Cfqdn:p:ttl:timestamp:lo
|
|
43
|
-
const [fqdn, p, ttl, ts, loc] =
|
|
57
|
+
const [fqdn, p, ttl, ts, loc] = tinyline.slice(1).split(':')
|
|
44
58
|
|
|
45
59
|
return new CNAME({
|
|
46
60
|
owner: this.fullyQualify(fqdn),
|
|
@@ -48,13 +62,13 @@ export default class CNAME extends RR {
|
|
|
48
62
|
type: 'CNAME',
|
|
49
63
|
cname: this.fullyQualify(p),
|
|
50
64
|
timestamp: ts,
|
|
51
|
-
location: loc
|
|
65
|
+
location: loc?.trim() ?? '',
|
|
52
66
|
})
|
|
53
67
|
}
|
|
54
68
|
|
|
55
|
-
fromBind(
|
|
69
|
+
fromBind({ bindline }) {
|
|
56
70
|
// test.example.com 3600 IN CNAME ...
|
|
57
|
-
const [owner, ttl, c, type, cname] =
|
|
71
|
+
const [owner, ttl, c, type, cname] = bindline.split(/\s+/)
|
|
58
72
|
return new CNAME({
|
|
59
73
|
owner,
|
|
60
74
|
ttl: parseInt(ttl, 10),
|
|
@@ -65,6 +79,9 @@ export default class CNAME extends RR {
|
|
|
65
79
|
}
|
|
66
80
|
|
|
67
81
|
/****** EXPORTERS *******/
|
|
82
|
+
getWireRdata() {
|
|
83
|
+
return this.wirePackDomain(this.get('cname'))
|
|
84
|
+
}
|
|
68
85
|
|
|
69
86
|
toTinydns() {
|
|
70
87
|
return `C${this.getTinyFQDN('owner')}:${this.get('cname')}:${this.getTinydnsPostamble()}\n`
|
package/rr/dhcid.js
CHANGED
|
@@ -40,9 +40,24 @@ export default class DHCID extends RR {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
/****** IMPORTERS *******/
|
|
43
|
-
|
|
43
|
+
fromTinydns({ tinyline }) {
|
|
44
|
+
// DHCID via generic, :fqdn:49:rdata:ttl:timestamp:lo
|
|
45
|
+
const [fqdn, n, rdata, ttl, ts, loc] = tinyline.slice(1).split(':')
|
|
46
|
+
if (n != 49) this.throwHelp('DHCID fromTinydns, invalid n')
|
|
47
|
+
|
|
48
|
+
return new DHCID({
|
|
49
|
+
owner: this.fullyQualify(fqdn),
|
|
50
|
+
ttl: parseInt(ttl, 10),
|
|
51
|
+
type: 'DHCID',
|
|
52
|
+
data: TINYDNS.octalToBase64(rdata),
|
|
53
|
+
timestamp: ts,
|
|
54
|
+
location: loc?.trim() ?? '',
|
|
55
|
+
})
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
fromBind({ bindline }) {
|
|
44
59
|
// host.example.com 3600 IN DHCID <base64data>
|
|
45
|
-
const parts =
|
|
60
|
+
const parts = bindline.split(/\s+/)
|
|
46
61
|
const [owner, ttl, c, type] = parts
|
|
47
62
|
return new DHCID({
|
|
48
63
|
owner,
|
package/rr/dname.js
CHANGED
|
@@ -35,10 +35,20 @@ export default class DNAME extends RR {
|
|
|
35
35
|
return 39
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
getCanonical() {
|
|
39
|
+
return {
|
|
40
|
+
owner: 'example.com.',
|
|
41
|
+
ttl: 3600,
|
|
42
|
+
class: 'IN',
|
|
43
|
+
type: 'DNAME',
|
|
44
|
+
target: 'example.net.',
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
38
48
|
/****** IMPORTERS *******/
|
|
39
|
-
fromTinydns(
|
|
49
|
+
fromTinydns({ tinyline }) {
|
|
40
50
|
// DNAME via generic, :fqdn:n:rdata:ttl:timestamp:lo
|
|
41
|
-
const [fqdn, n, rdata, ttl, ts, loc] =
|
|
51
|
+
const [fqdn, n, rdata, ttl, ts, loc] = tinyline.slice(1).split(':')
|
|
42
52
|
if (n != 39) this.throwHelp('DNAME fromTinydns, invalid n')
|
|
43
53
|
|
|
44
54
|
return new DNAME({
|
|
@@ -47,13 +57,13 @@ export default class DNAME extends RR {
|
|
|
47
57
|
target: TINYDNS.unpackDomainName(rdata)[0],
|
|
48
58
|
ttl: parseInt(ttl, 10),
|
|
49
59
|
timestamp: ts,
|
|
50
|
-
location: loc
|
|
60
|
+
location: loc?.trim() ?? '',
|
|
51
61
|
})
|
|
52
62
|
}
|
|
53
63
|
|
|
54
|
-
fromBind(
|
|
64
|
+
fromBind({ bindline }) {
|
|
55
65
|
// test.example.com 3600 IN DNAME ...
|
|
56
|
-
const [owner, ttl, c, type, target] =
|
|
66
|
+
const [owner, ttl, c, type, target] = bindline.split(/\s+/)
|
|
57
67
|
return new DNAME({
|
|
58
68
|
owner,
|
|
59
69
|
ttl: parseInt(ttl, 10),
|
package/rr/dnskey.js
CHANGED
|
@@ -79,6 +79,10 @@ export default class DNSKEY extends RR {
|
|
|
79
79
|
return 'DNS Public Key'
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
+
getTags() {
|
|
83
|
+
return ['dnssec']
|
|
84
|
+
}
|
|
85
|
+
|
|
82
86
|
getRdataFields(arg) {
|
|
83
87
|
return ['flags', 'protocol', 'algorithm', 'publickey']
|
|
84
88
|
}
|
|
@@ -91,14 +95,33 @@ export default class DNSKEY extends RR {
|
|
|
91
95
|
return 48
|
|
92
96
|
}
|
|
93
97
|
|
|
98
|
+
getCanonical() {
|
|
99
|
+
return {
|
|
100
|
+
owner: 'example.com.',
|
|
101
|
+
ttl: 3600,
|
|
102
|
+
class: 'IN',
|
|
103
|
+
type: 'DNSKEY',
|
|
104
|
+
flags: 256,
|
|
105
|
+
protocol: 3,
|
|
106
|
+
algorithm: 5,
|
|
107
|
+
publickey: 'AQPSKAsj8...',
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
94
111
|
/****** IMPORTERS *******/
|
|
95
112
|
|
|
96
|
-
fromBind(
|
|
113
|
+
fromBind({ bindline }) {
|
|
97
114
|
// test.example.com 3600 IN DNSKEY Flags Protocol Algorithm PublicKey
|
|
98
|
-
const regex =
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
const
|
|
115
|
+
const regex =
|
|
116
|
+
/^(?<owner>\S+)\s+(?<ttl>\d+)\s+(?<cls>\w+)\s+(?<type>DNSKEY)\s+(?<flags>\d+)\s+(?<protocol>\d+)\s+(?<algorithm>\d+)\s+(?<publickey>\S.*)$/i
|
|
117
|
+
|
|
118
|
+
const match = bindline.trim().match(regex)
|
|
119
|
+
|
|
120
|
+
if (!match) {
|
|
121
|
+
this.throwHelp(`unable to parse DNSKEY: ${bindline}`)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const { owner, ttl, c, type, flags, protocol, algorithm, publickey } = match.groups
|
|
102
125
|
|
|
103
126
|
return new DNSKEY({
|
|
104
127
|
owner,
|
|
@@ -112,8 +135,8 @@ export default class DNSKEY extends RR {
|
|
|
112
135
|
})
|
|
113
136
|
}
|
|
114
137
|
|
|
115
|
-
fromTinydns(
|
|
116
|
-
const [fqdn, n, rdata, ttl, ts, loc] =
|
|
138
|
+
fromTinydns({ tinyline }) {
|
|
139
|
+
const [fqdn, n, rdata, ttl, ts, loc] = tinyline.substring(1).split(':')
|
|
117
140
|
if (n != 48) this.throwHelp('DNSKEY fromTinydns, invalid n')
|
|
118
141
|
|
|
119
142
|
const bytes = Buffer.from(TINYDNS.octalToChar(rdata), 'binary')
|
|
@@ -127,7 +150,7 @@ export default class DNSKEY extends RR {
|
|
|
127
150
|
algorithm: bytes.readUInt8(3),
|
|
128
151
|
publickey: bytes.slice(4).toString(),
|
|
129
152
|
timestamp: ts,
|
|
130
|
-
location: loc
|
|
153
|
+
location: loc?.trim() ?? '',
|
|
131
154
|
})
|
|
132
155
|
}
|
|
133
156
|
|
package/rr/ds.js
CHANGED
|
@@ -50,6 +50,10 @@ export default class DS extends RR {
|
|
|
50
50
|
return 'Delegation Signer'
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
getTags() {
|
|
54
|
+
return ['dnssec']
|
|
55
|
+
}
|
|
56
|
+
|
|
53
57
|
getRdataFields(arg) {
|
|
54
58
|
return ['key tag', 'algorithm', 'digest type', 'digest']
|
|
55
59
|
}
|
|
@@ -62,11 +66,24 @@ export default class DS extends RR {
|
|
|
62
66
|
return 43
|
|
63
67
|
}
|
|
64
68
|
|
|
69
|
+
getCanonical() {
|
|
70
|
+
return {
|
|
71
|
+
owner: 'example.com.',
|
|
72
|
+
ttl: 3600,
|
|
73
|
+
class: 'IN',
|
|
74
|
+
type: 'DS',
|
|
75
|
+
'key tag': 12345,
|
|
76
|
+
algorithm: 5,
|
|
77
|
+
'digest type': 1,
|
|
78
|
+
digest: 'ABCDEF123...',
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
65
82
|
/****** IMPORTERS *******/
|
|
66
83
|
|
|
67
|
-
fromBind(
|
|
84
|
+
fromBind({ bindline }) {
|
|
68
85
|
// test.example.com 3600 IN DS Key Tag Algorithm, Digest Type, Digest
|
|
69
|
-
const [owner, ttl, c, type, keytag, algorithm, digesttype] =
|
|
86
|
+
const [owner, ttl, c, type, keytag, algorithm, digesttype] = bindline.split(/\s+/)
|
|
70
87
|
return new DS({
|
|
71
88
|
owner,
|
|
72
89
|
ttl: parseInt(ttl, 10),
|
|
@@ -75,12 +92,12 @@ export default class DS extends RR {
|
|
|
75
92
|
'key tag': parseInt(keytag, 10),
|
|
76
93
|
algorithm: parseInt(algorithm, 10),
|
|
77
94
|
'digest type': parseInt(digesttype, 10),
|
|
78
|
-
digest:
|
|
95
|
+
digest: bindline.split(/\s+/).slice(7).join(' ').trim(),
|
|
79
96
|
})
|
|
80
97
|
}
|
|
81
98
|
|
|
82
|
-
fromTinydns(
|
|
83
|
-
const [fqdn, n, rdata, ttl, ts, loc] =
|
|
99
|
+
fromTinydns({ tinyline }) {
|
|
100
|
+
const [fqdn, n, rdata, ttl, ts, loc] = tinyline.slice(1).split(':')
|
|
84
101
|
if (n != 43) this.throwHelp('DS fromTinydns, invalid n')
|
|
85
102
|
|
|
86
103
|
const binRdata = Buffer.from(TINYDNS.octalToChar(rdata), 'binary')
|
|
@@ -94,7 +111,7 @@ export default class DS extends RR {
|
|
|
94
111
|
'digest type': binRdata.readUInt8(3),
|
|
95
112
|
digest: binRdata.slice(4).toString(),
|
|
96
113
|
timestamp: ts,
|
|
97
|
-
location: loc
|
|
114
|
+
location: loc?.trim() ?? '',
|
|
98
115
|
})
|
|
99
116
|
}
|
|
100
117
|
|
package/rr/hinfo.js
CHANGED
|
@@ -22,6 +22,10 @@ export default class HINFO extends RR {
|
|
|
22
22
|
return 'Host Info'
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
getTags() {
|
|
26
|
+
return ['obsolete']
|
|
27
|
+
}
|
|
28
|
+
|
|
25
29
|
getRdataFields(arg) {
|
|
26
30
|
return ['cpu', 'os']
|
|
27
31
|
}
|
|
@@ -34,31 +38,45 @@ export default class HINFO extends RR {
|
|
|
34
38
|
return 13
|
|
35
39
|
}
|
|
36
40
|
|
|
41
|
+
getCanonical() {
|
|
42
|
+
return {
|
|
43
|
+
owner: 'test.example.com.',
|
|
44
|
+
ttl: 3600,
|
|
45
|
+
class: 'IN',
|
|
46
|
+
type: 'HINFO',
|
|
47
|
+
cpu: 'DEC-2060',
|
|
48
|
+
os: 'TOPS20',
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
37
52
|
getQuotedFields() {
|
|
38
53
|
return ['cpu', 'os']
|
|
39
54
|
}
|
|
40
55
|
|
|
41
56
|
/****** IMPORTERS *******/
|
|
42
|
-
fromBind(
|
|
57
|
+
fromBind({ bindline }) {
|
|
43
58
|
// test.example.com 3600 IN HINFO DEC-2060 TOPS20
|
|
44
|
-
const regex =
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const
|
|
59
|
+
const regex =
|
|
60
|
+
/^(?<owner>\S+)\s+(?<ttl>\d{1,10})\s+(?<class>IN)\s+(?<type>HINFO)\s+(?:"(?<qCPU>[^"]*)"|(?<uCPU>\S+))\s+(?:"(?<qOS>[^"]*)"|(?<uOS>\S+))$/i
|
|
61
|
+
|
|
62
|
+
const match = bindline.trim().match(regex)
|
|
63
|
+
if (!match) this.throwHelp(`unable to parse HINFO: ${bindline}`)
|
|
64
|
+
|
|
65
|
+
const { owner, ttl, class: c, type, qCPU, uCPU, qOS, uOS } = match.groups
|
|
48
66
|
|
|
49
67
|
return new HINFO({
|
|
50
68
|
owner,
|
|
51
69
|
ttl: parseInt(ttl, 10),
|
|
52
70
|
class: c,
|
|
53
71
|
type,
|
|
54
|
-
cpu,
|
|
55
|
-
os,
|
|
72
|
+
cpu: qCPU ?? uCPU,
|
|
73
|
+
os: qOS ?? uOS,
|
|
56
74
|
})
|
|
57
75
|
}
|
|
58
76
|
|
|
59
|
-
fromTinydns(
|
|
77
|
+
fromTinydns({ tinyline }) {
|
|
60
78
|
// HINFO via generic, :fqdn:n:rdata:ttl:timestamp:lo
|
|
61
|
-
const [fqdn, , rdata, ttl, ts, loc] =
|
|
79
|
+
const [fqdn, , rdata, ttl, ts, loc] = tinyline.slice(1).split(':')
|
|
62
80
|
const [cpu, os] = [...TINYDNS.unpackString(rdata)]
|
|
63
81
|
|
|
64
82
|
return new this.constructor({
|
|
@@ -68,7 +86,7 @@ export default class HINFO extends RR {
|
|
|
68
86
|
cpu,
|
|
69
87
|
os,
|
|
70
88
|
timestamp: ts,
|
|
71
|
-
location: loc
|
|
89
|
+
location: loc?.trim() ?? '',
|
|
72
90
|
})
|
|
73
91
|
}
|
|
74
92
|
|
package/rr/hip.js
CHANGED
|
@@ -59,9 +59,50 @@ export default class HIP extends RR {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
/****** IMPORTERS *******/
|
|
62
|
-
|
|
62
|
+
fromTinydns({ tinyline }) {
|
|
63
|
+
// HIP via generic, :fqdn:55:rdata:ttl:timestamp:lo
|
|
64
|
+
const [fqdn, n, rdata, ttl, ts, loc] = tinyline.slice(1).split(':')
|
|
65
|
+
if (n != 55) this.throwHelp('HIP fromTinydns, invalid n')
|
|
66
|
+
|
|
67
|
+
const bytes = Buffer.from(TINYDNS.octalToChar(rdata), 'binary')
|
|
68
|
+
const hitLen = bytes.readUInt8(0)
|
|
69
|
+
const pkAlgorithm = bytes.readUInt8(1)
|
|
70
|
+
const pkLen = bytes.readUInt16BE(2)
|
|
71
|
+
|
|
72
|
+
const hit = bytes
|
|
73
|
+
.slice(4, 4 + hitLen)
|
|
74
|
+
.toString('hex')
|
|
75
|
+
.toUpperCase()
|
|
76
|
+
const publicKey = bytes.slice(4 + hitLen, 4 + hitLen + pkLen).toString('base64')
|
|
77
|
+
|
|
78
|
+
const rvsNames = []
|
|
79
|
+
let pos = 4 + hitLen + pkLen
|
|
80
|
+
while (pos < bytes.length) {
|
|
81
|
+
const [name, newPos] = TINYDNS.unpackDomainName(
|
|
82
|
+
[...bytes.slice(pos)]
|
|
83
|
+
.map((b) => (b < 32 || b > 126 ? TINYDNS.UInt8toOctal(b) : String.fromCharCode(b)))
|
|
84
|
+
.join(''),
|
|
85
|
+
)
|
|
86
|
+
pos += newPos
|
|
87
|
+
if (name !== '.') rvsNames.push(name)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return new HIP({
|
|
91
|
+
owner: this.fullyQualify(fqdn),
|
|
92
|
+
ttl: parseInt(ttl, 10),
|
|
93
|
+
type: 'HIP',
|
|
94
|
+
'pk algorithm': pkAlgorithm,
|
|
95
|
+
hit,
|
|
96
|
+
'public key': publicKey,
|
|
97
|
+
'rendezvous servers': rvsNames.join(' '),
|
|
98
|
+
timestamp: ts,
|
|
99
|
+
location: loc?.trim() ?? '',
|
|
100
|
+
})
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
fromBind({ bindline }) {
|
|
63
104
|
// owner ttl IN HIP pk-algorithm HIT public-key [rendezvous-server...]
|
|
64
|
-
const parts =
|
|
105
|
+
const parts = bindline.split(/\s+/)
|
|
65
106
|
const [owner, ttl, c, type, pkAlgorithm, hit, publicKey] = parts
|
|
66
107
|
return new HIP({
|
|
67
108
|
owner,
|
package/rr/https.js
CHANGED
|
@@ -32,6 +32,10 @@ export default class HTTPS extends RR {
|
|
|
32
32
|
return 'HTTP Semantics'
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
getTags() {
|
|
36
|
+
return ['common']
|
|
37
|
+
}
|
|
38
|
+
|
|
35
39
|
getRdataFields(arg) {
|
|
36
40
|
return ['priority', 'target name', 'params']
|
|
37
41
|
}
|
|
@@ -44,11 +48,23 @@ export default class HTTPS extends RR {
|
|
|
44
48
|
return 65
|
|
45
49
|
}
|
|
46
50
|
|
|
51
|
+
getCanonical() {
|
|
52
|
+
return {
|
|
53
|
+
owner: 'example.com.',
|
|
54
|
+
ttl: 3600,
|
|
55
|
+
class: 'IN',
|
|
56
|
+
type: 'HTTPS',
|
|
57
|
+
priority: 1,
|
|
58
|
+
'target name': 'example.com.',
|
|
59
|
+
params: 'alpn="h2,h3"',
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
47
63
|
/****** IMPORTERS *******/
|
|
48
64
|
|
|
49
|
-
fromBind(
|
|
65
|
+
fromBind({ bindline }) {
|
|
50
66
|
// test.example.com 3600 IN HTTPS Priority TargetName Params
|
|
51
|
-
const [owner, ttl, c, type, pri, fqdn] =
|
|
67
|
+
const [owner, ttl, c, type, pri, fqdn] = bindline.split(/\s+/)
|
|
52
68
|
return new HTTPS({
|
|
53
69
|
owner,
|
|
54
70
|
ttl: parseInt(ttl, 10),
|
|
@@ -56,20 +72,31 @@ export default class HTTPS extends RR {
|
|
|
56
72
|
type,
|
|
57
73
|
priority: parseInt(pri, 10),
|
|
58
74
|
'target name': fqdn,
|
|
59
|
-
params:
|
|
75
|
+
params: bindline.split(/\s+/).slice(6).join(' ').trim(),
|
|
60
76
|
})
|
|
61
77
|
}
|
|
62
78
|
|
|
63
|
-
fromTinydns({
|
|
79
|
+
fromTinydns({ tinyline }) {
|
|
80
|
+
const [owner, _typeId, rd, ttl, ts, loc] = tinyline.slice(1).split(':')
|
|
81
|
+
|
|
64
82
|
if (rd.length < 6) {
|
|
65
83
|
this.throwHelp(`HTTPS: RDATA too short: ${rd}`)
|
|
66
84
|
}
|
|
67
85
|
|
|
68
|
-
const
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
const
|
|
86
|
+
const binary = Buffer.from(TINYDNS.octalToChar(rd), 'binary')
|
|
87
|
+
const priority = binary.readUInt16BE(0)
|
|
88
|
+
|
|
89
|
+
let pos = 2
|
|
90
|
+
const labels = []
|
|
91
|
+
while (true) {
|
|
92
|
+
const len = binary.readUInt8(pos)
|
|
93
|
+
pos += 1
|
|
94
|
+
if (len === 0) break
|
|
95
|
+
labels.push(binary.slice(pos, pos + len).toString())
|
|
96
|
+
pos += len
|
|
97
|
+
}
|
|
98
|
+
const targetName = `${labels.join('.')}.`
|
|
99
|
+
const params = binary.slice(pos).toString()
|
|
73
100
|
|
|
74
101
|
return new HTTPS({
|
|
75
102
|
owner: this.fullyQualify(owner),
|
|
@@ -78,6 +105,8 @@ export default class HTTPS extends RR {
|
|
|
78
105
|
priority,
|
|
79
106
|
'target name': targetName,
|
|
80
107
|
params,
|
|
108
|
+
timestamp: ts,
|
|
109
|
+
location: loc?.trim() ?? '',
|
|
81
110
|
})
|
|
82
111
|
}
|
|
83
112
|
|
package/rr/ipseckey.js
CHANGED
|
@@ -71,6 +71,10 @@ export default class IPSECKEY extends RR {
|
|
|
71
71
|
return 'IPsec Keying'
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
getTags() {
|
|
75
|
+
return ['security']
|
|
76
|
+
}
|
|
77
|
+
|
|
74
78
|
getRdataFields(arg) {
|
|
75
79
|
return ['precedence', 'gateway type', 'algorithm', 'gateway', 'publickey']
|
|
76
80
|
}
|
|
@@ -98,9 +102,9 @@ export default class IPSECKEY extends RR {
|
|
|
98
102
|
}
|
|
99
103
|
|
|
100
104
|
/****** IMPORTERS *******/
|
|
101
|
-
fromBind(
|
|
105
|
+
fromBind({ bindline }) {
|
|
102
106
|
// FQDN TTL CLASS IPSECKEY Precedence GatewayType Algorithm Gateway PublicKey
|
|
103
|
-
const [owner, ttl, c, type, prec, gwt, algo, gateway, publickey] =
|
|
107
|
+
const [owner, ttl, c, type, prec, gwt, algo, gateway, publickey] = bindline.split(/\s+/)
|
|
104
108
|
return new IPSECKEY({
|
|
105
109
|
owner,
|
|
106
110
|
ttl: parseInt(ttl, 10),
|
|
@@ -114,32 +118,32 @@ export default class IPSECKEY extends RR {
|
|
|
114
118
|
})
|
|
115
119
|
}
|
|
116
120
|
|
|
117
|
-
fromTinydns(
|
|
118
|
-
const [fqdn, n, rdata, ttl, ts, loc] =
|
|
121
|
+
fromTinydns({ tinyline }) {
|
|
122
|
+
const [fqdn, n, rdata, ttl, ts, loc] = tinyline.slice(1).split(':')
|
|
119
123
|
if (n != 45) this.throwHelp('IPSECKEY fromTinydns, invalid n')
|
|
120
124
|
|
|
121
|
-
const precedence = TINYDNS.octalToUInt8(rdata.
|
|
122
|
-
const gwType = TINYDNS.octalToUInt8(rdata.
|
|
123
|
-
const algorithm = TINYDNS.octalToUInt8(rdata.
|
|
125
|
+
const precedence = TINYDNS.octalToUInt8(rdata.slice(0, 4))
|
|
126
|
+
const gwType = TINYDNS.octalToUInt8(rdata.slice(4, 8))
|
|
127
|
+
const algorithm = TINYDNS.octalToUInt8(rdata.slice(8, 12))
|
|
124
128
|
|
|
125
129
|
let len, gateway, octalKey
|
|
126
130
|
|
|
127
131
|
switch (gwType) {
|
|
128
132
|
case 0: // no gateway
|
|
129
|
-
gateway = rdata.
|
|
130
|
-
octalKey = rdata.
|
|
133
|
+
gateway = rdata.slice(12, 13) // should always be: '.'
|
|
134
|
+
octalKey = rdata.slice(13)
|
|
131
135
|
break
|
|
132
136
|
case 1: // 4-byte IPv4 address
|
|
133
|
-
gateway = TINYDNS.octalToIPv4(rdata.
|
|
134
|
-
octalKey = rdata.
|
|
137
|
+
gateway = TINYDNS.octalToIPv4(rdata.slice(12, 28))
|
|
138
|
+
octalKey = rdata.slice(28)
|
|
135
139
|
break
|
|
136
140
|
case 2: // 16-byte IPv6
|
|
137
|
-
gateway = TINYDNS.
|
|
138
|
-
octalKey = rdata.
|
|
141
|
+
gateway = TINYDNS.octalToIPv6(rdata.slice(12, 76))
|
|
142
|
+
octalKey = rdata.slice(76)
|
|
139
143
|
break
|
|
140
144
|
case 3: // wire encoded domain name
|
|
141
|
-
;[gateway, len] = TINYDNS.unpackDomainName(rdata.
|
|
142
|
-
octalKey = rdata.
|
|
145
|
+
;[gateway, len] = TINYDNS.unpackDomainName(rdata.slice(12))
|
|
146
|
+
octalKey = rdata.slice(12 + len)
|
|
143
147
|
break
|
|
144
148
|
}
|
|
145
149
|
|
|
@@ -153,7 +157,7 @@ export default class IPSECKEY extends RR {
|
|
|
153
157
|
gateway,
|
|
154
158
|
publickey: TINYDNS.octalToBase64(octalKey),
|
|
155
159
|
timestamp: ts,
|
|
156
|
-
location: loc
|
|
160
|
+
location: loc?.trim() ?? '',
|
|
157
161
|
})
|
|
158
162
|
}
|
|
159
163
|
|