@nictool/dns-resource-record 1.6.1 → 1.7.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 +33 -0
- package/README.md +323 -199
- package/dist/dns-rr.min.js +26 -0
- package/dist/dns-rr.min.js.map +7 -0
- package/index.js +12 -11
- package/lib/binary.js +108 -0
- package/lib/bind.js +94 -0
- package/lib/dns-query.js +67 -0
- package/lib/tinydns.js +128 -44
- package/lib/wire.js +519 -0
- package/package.json +23 -6
- package/rr/TEMPLATE.js +124 -0
- package/rr/a.js +8 -48
- package/rr/aaaa.js +13 -80
- package/rr/apl.js +123 -27
- package/rr/caa.js +27 -50
- package/rr/cert.js +58 -87
- package/rr/cname.js +7 -63
- package/rr/dhcid.js +20 -30
- package/rr/dname.js +9 -36
- package/rr/dnskey.js +38 -32
- package/rr/ds.js +43 -57
- package/rr/hinfo.js +21 -40
- package/rr/hip.js +88 -26
- package/rr/https.js +28 -40
- package/rr/ipseckey.js +97 -18
- package/rr/key.js +39 -29
- package/rr/kx.js +16 -27
- package/rr/loc.js +42 -12
- package/rr/mx.js +16 -51
- package/rr/naptr.js +58 -33
- package/rr/ns.js +8 -36
- package/rr/nsec.js +89 -18
- package/rr/nsec3.js +62 -26
- package/rr/nsec3param.js +56 -53
- package/rr/nxt.js +57 -18
- package/rr/openpgpkey.js +24 -30
- package/rr/ptr.js +7 -47
- package/rr/rp.js +17 -32
- package/rr/rrsig.js +80 -85
- package/rr/sig.js +70 -45
- package/rr/smimea.js +33 -33
- package/rr/soa.js +31 -49
- package/rr/spf.js +10 -17
- package/rr/srv.js +22 -62
- package/rr/sshfp.js +25 -53
- package/rr/svcb.js +27 -40
- package/rr/tlsa.js +34 -34
- package/rr/tsig.js +87 -24
- package/rr/txt.js +40 -59
- package/rr/uri.js +19 -29
- package/rr/wks.js +154 -22
- package/rr.js +290 -109
- package/lib/readme.js +0 -84
package/rr/ds.js
CHANGED
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
import RR from '../rr.js'
|
|
2
2
|
|
|
3
3
|
import * as TINYDNS from '../lib/tinydns.js'
|
|
4
|
+
import * as BINARY from '../lib/binary.js'
|
|
4
5
|
|
|
5
6
|
export default class DS extends RR {
|
|
7
|
+
static typeName = 'DS'
|
|
8
|
+
static typeId = 43
|
|
9
|
+
static RFCs = [4034, 4509, 9619]
|
|
10
|
+
static rdataFields = [['key tag', 'u16'], 'algorithm', 'digest type', ['digest', 'str']]
|
|
11
|
+
static tags = ['dnssec']
|
|
12
|
+
|
|
6
13
|
constructor(opts) {
|
|
7
14
|
super(opts)
|
|
8
15
|
}
|
|
9
16
|
|
|
10
17
|
/****** Resource record specific setters *******/
|
|
11
|
-
setKeyTag(val) {
|
|
12
|
-
// a 2 octet Key Tag field...in network byte order
|
|
13
|
-
if (!val) this.throwHelp(`DS: key tag is required`)
|
|
14
|
-
if (val.length > 2) this.throwHelp(`DS: key tag is too long`)
|
|
15
|
-
|
|
16
|
-
this.set('key tag', val)
|
|
17
|
-
}
|
|
18
|
-
|
|
19
18
|
setAlgorithm(val) {
|
|
20
19
|
if (!this.getAlgorithmOptions().has(val)) this.throwHelp(`DS: algorithm invalid`)
|
|
21
20
|
|
|
@@ -40,32 +39,10 @@ export default class DS extends RR {
|
|
|
40
39
|
this.set('digest type', val)
|
|
41
40
|
}
|
|
42
41
|
|
|
43
|
-
setDigest(val) {
|
|
44
|
-
if (!val) this.throwHelp(`DS: digest is required`)
|
|
45
|
-
|
|
46
|
-
this.set('digest', val)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
42
|
getDescription() {
|
|
50
43
|
return 'Delegation Signer'
|
|
51
44
|
}
|
|
52
45
|
|
|
53
|
-
getTags() {
|
|
54
|
-
return ['dnssec']
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
getRdataFields(arg) {
|
|
58
|
-
return ['key tag', 'algorithm', 'digest type', 'digest']
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
getRFCs() {
|
|
62
|
-
return [4034, 4509]
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
getTypeId() {
|
|
66
|
-
return 43
|
|
67
|
-
}
|
|
68
|
-
|
|
69
46
|
getCanonical() {
|
|
70
47
|
return {
|
|
71
48
|
owner: 'example.com.',
|
|
@@ -81,50 +58,59 @@ export default class DS extends RR {
|
|
|
81
58
|
|
|
82
59
|
/****** IMPORTERS *******/
|
|
83
60
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
const
|
|
61
|
+
fromTinydns(opts) {
|
|
62
|
+
const { tinyline } = opts
|
|
63
|
+
const { owner, typeId, rdata, ttl, timestamp, location } = this.parseTinydnsLine(tinyline)
|
|
64
|
+
if (typeId != this.getTypeId()) this.throwHelp('DS fromTinydns, invalid n')
|
|
65
|
+
|
|
66
|
+
const binRdata = TINYDNS.octalRdataToBytes(rdata)
|
|
67
|
+
|
|
87
68
|
return new DS({
|
|
88
69
|
owner,
|
|
89
|
-
ttl
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
70
|
+
ttl,
|
|
71
|
+
type: 'DS',
|
|
72
|
+
'key tag': (binRdata[0] << 8) | binRdata[1],
|
|
73
|
+
algorithm: binRdata[2],
|
|
74
|
+
'digest type': binRdata[3],
|
|
75
|
+
digest: BINARY.bytesToHex(binRdata.subarray(4)).toUpperCase(),
|
|
76
|
+
timestamp,
|
|
77
|
+
location,
|
|
96
78
|
})
|
|
97
79
|
}
|
|
98
80
|
|
|
99
|
-
|
|
100
|
-
const
|
|
101
|
-
if (n != 43) this.throwHelp('DS fromTinydns, invalid n')
|
|
102
|
-
|
|
103
|
-
const binRdata = Buffer.from(TINYDNS.octalToChar(rdata), 'binary')
|
|
104
|
-
|
|
81
|
+
fromWire({ owner, cls, ttl, rdata }) {
|
|
82
|
+
const dv = new DataView(rdata.buffer, rdata.byteOffset)
|
|
105
83
|
return new DS({
|
|
106
|
-
owner
|
|
107
|
-
ttl
|
|
84
|
+
owner,
|
|
85
|
+
ttl,
|
|
86
|
+
class: cls,
|
|
108
87
|
type: 'DS',
|
|
109
|
-
'key tag':
|
|
110
|
-
algorithm:
|
|
111
|
-
'digest type':
|
|
112
|
-
digest:
|
|
113
|
-
timestamp: ts,
|
|
114
|
-
location: loc?.trim() ?? '',
|
|
88
|
+
'key tag': dv.getUint16(0),
|
|
89
|
+
algorithm: rdata[2],
|
|
90
|
+
'digest type': rdata[3],
|
|
91
|
+
digest: BINARY.bytesToHex(rdata.subarray(4)).toUpperCase(),
|
|
115
92
|
})
|
|
116
93
|
}
|
|
117
94
|
|
|
118
95
|
/****** EXPORTERS *******/
|
|
119
96
|
|
|
120
97
|
toTinydns() {
|
|
121
|
-
const rdataRe = new RegExp(/[\r\n\t:\\/]/, 'g')
|
|
122
|
-
|
|
123
98
|
return this.getTinydnsGeneric(
|
|
124
99
|
TINYDNS.UInt16toOctal(this.get('key tag')) +
|
|
125
100
|
TINYDNS.UInt8toOctal(this.get('algorithm')) +
|
|
126
101
|
TINYDNS.UInt8toOctal(this.get('digest type')) +
|
|
127
|
-
TINYDNS.
|
|
102
|
+
TINYDNS.packHex(this.get('digest').replace(/\s+/g, '')),
|
|
128
103
|
)
|
|
129
104
|
}
|
|
105
|
+
|
|
106
|
+
getWireRdata() {
|
|
107
|
+
const digestBytes = BINARY.hexToBytes(this.get('digest').replace(/\s+/g, ''))
|
|
108
|
+
const bytes = new Uint8Array(4 + digestBytes.length)
|
|
109
|
+
const dv = new DataView(bytes.buffer, bytes.byteOffset)
|
|
110
|
+
dv.setUint16(0, this.get('key tag'))
|
|
111
|
+
bytes[2] = this.get('algorithm')
|
|
112
|
+
bytes[3] = this.get('digest type')
|
|
113
|
+
bytes.set(digestBytes, 4)
|
|
114
|
+
return bytes
|
|
115
|
+
}
|
|
130
116
|
}
|
package/rr/hinfo.js
CHANGED
|
@@ -3,6 +3,15 @@ import RR from '../rr.js'
|
|
|
3
3
|
import * as TINYDNS from '../lib/tinydns.js'
|
|
4
4
|
|
|
5
5
|
export default class HINFO extends RR {
|
|
6
|
+
static typeName = 'HINFO'
|
|
7
|
+
static typeId = 13
|
|
8
|
+
static RFCs = [1034, 1035, 8482]
|
|
9
|
+
static rdataFields = [
|
|
10
|
+
['cpu', 'qcharstr'],
|
|
11
|
+
['os', 'qcharstr'],
|
|
12
|
+
]
|
|
13
|
+
static tags = ['obsolete']
|
|
14
|
+
|
|
6
15
|
constructor(opts) {
|
|
7
16
|
super(opts)
|
|
8
17
|
}
|
|
@@ -22,22 +31,6 @@ export default class HINFO extends RR {
|
|
|
22
31
|
return 'Host Info'
|
|
23
32
|
}
|
|
24
33
|
|
|
25
|
-
getTags() {
|
|
26
|
-
return ['obsolete']
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
getRdataFields(arg) {
|
|
30
|
-
return ['cpu', 'os']
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
getRFCs() {
|
|
34
|
-
return [1034, 1035, 8482]
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
getTypeId() {
|
|
38
|
-
return 13
|
|
39
|
-
}
|
|
40
|
-
|
|
41
34
|
getCanonical() {
|
|
42
35
|
return {
|
|
43
36
|
owner: 'test.example.com.',
|
|
@@ -49,31 +42,7 @@ export default class HINFO extends RR {
|
|
|
49
42
|
}
|
|
50
43
|
}
|
|
51
44
|
|
|
52
|
-
getQuotedFields() {
|
|
53
|
-
return ['cpu', 'os']
|
|
54
|
-
}
|
|
55
|
-
|
|
56
45
|
/****** IMPORTERS *******/
|
|
57
|
-
fromBind({ bindline }) {
|
|
58
|
-
// test.example.com 3600 IN HINFO DEC-2060 TOPS20
|
|
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
|
|
66
|
-
|
|
67
|
-
return new HINFO({
|
|
68
|
-
owner,
|
|
69
|
-
ttl: parseInt(ttl, 10),
|
|
70
|
-
class: c,
|
|
71
|
-
type,
|
|
72
|
-
cpu: qCPU ?? uCPU,
|
|
73
|
-
os: qOS ?? uOS,
|
|
74
|
-
})
|
|
75
|
-
}
|
|
76
|
-
|
|
77
46
|
fromTinydns({ tinyline }) {
|
|
78
47
|
// HINFO via generic, :fqdn:n:rdata:ttl:timestamp:lo
|
|
79
48
|
const [fqdn, , rdata, ttl, ts, loc] = tinyline.slice(1).split(':')
|
|
@@ -91,6 +60,18 @@ export default class HINFO extends RR {
|
|
|
91
60
|
}
|
|
92
61
|
|
|
93
62
|
/****** EXPORTERS *******/
|
|
63
|
+
|
|
64
|
+
getWireRdata() {
|
|
65
|
+
const cpu = new TextEncoder().encode(this.get('cpu'))
|
|
66
|
+
const os = new TextEncoder().encode(this.get('os'))
|
|
67
|
+
const result = new Uint8Array(2 + cpu.length + os.length)
|
|
68
|
+
result[0] = cpu.length
|
|
69
|
+
result.set(cpu, 1)
|
|
70
|
+
result[1 + cpu.length] = os.length
|
|
71
|
+
result.set(os, 2 + cpu.length)
|
|
72
|
+
return result
|
|
73
|
+
}
|
|
74
|
+
|
|
94
75
|
toTinydns() {
|
|
95
76
|
return this.getTinydnsGeneric(
|
|
96
77
|
[TINYDNS.packString(this.get('cpu')), TINYDNS.packString(this.get('os'))].join(''),
|
package/rr/hip.js
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import RR from '../rr.js'
|
|
2
2
|
|
|
3
3
|
import * as TINYDNS from '../lib/tinydns.js'
|
|
4
|
+
import * as BINARY from '../lib/binary.js'
|
|
5
|
+
import * as WIRE from '../lib/wire.js'
|
|
4
6
|
|
|
5
7
|
export default class HIP extends RR {
|
|
8
|
+
static typeName = 'HIP'
|
|
9
|
+
static typeId = 55
|
|
10
|
+
static RFCs = [8005]
|
|
11
|
+
static rdataFields = ['pk algorithm', 'hit', 'public key', 'rendezvous servers']
|
|
12
|
+
|
|
6
13
|
constructor(opts) {
|
|
7
14
|
super(opts)
|
|
8
15
|
}
|
|
@@ -32,18 +39,6 @@ export default class HIP extends RR {
|
|
|
32
39
|
return 'Host Identity Protocol'
|
|
33
40
|
}
|
|
34
41
|
|
|
35
|
-
getRdataFields(arg) {
|
|
36
|
-
return ['pk algorithm', 'hit', 'public key', 'rendezvous servers']
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
getRFCs() {
|
|
40
|
-
return [8005]
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
getTypeId() {
|
|
44
|
-
return 55
|
|
45
|
-
}
|
|
46
|
-
|
|
47
42
|
getCanonical() {
|
|
48
43
|
return {
|
|
49
44
|
owner: 'example.com.',
|
|
@@ -64,22 +59,19 @@ export default class HIP extends RR {
|
|
|
64
59
|
const [fqdn, n, rdata, ttl, ts, loc] = tinyline.slice(1).split(':')
|
|
65
60
|
if (n != 55) this.throwHelp('HIP fromTinydns, invalid n')
|
|
66
61
|
|
|
67
|
-
const bytes =
|
|
68
|
-
const hitLen = bytes
|
|
69
|
-
const pkAlgorithm = bytes
|
|
70
|
-
const pkLen = bytes
|
|
62
|
+
const bytes = Uint8Array.from(TINYDNS.octalToChar(rdata), (c) => c.charCodeAt(0))
|
|
63
|
+
const hitLen = bytes[0]
|
|
64
|
+
const pkAlgorithm = bytes[1]
|
|
65
|
+
const pkLen = (bytes[2] << 8) | bytes[3]
|
|
71
66
|
|
|
72
|
-
const hit = bytes
|
|
73
|
-
|
|
74
|
-
.toString('hex')
|
|
75
|
-
.toUpperCase()
|
|
76
|
-
const publicKey = bytes.slice(4 + hitLen, 4 + hitLen + pkLen).toString('base64')
|
|
67
|
+
const hit = BINARY.bytesToHex(bytes.subarray(4, 4 + hitLen)).toUpperCase()
|
|
68
|
+
const publicKey = BINARY.bytesToBase64(bytes.subarray(4 + hitLen, 4 + hitLen + pkLen))
|
|
77
69
|
|
|
78
70
|
const rvsNames = []
|
|
79
71
|
let pos = 4 + hitLen + pkLen
|
|
80
72
|
while (pos < bytes.length) {
|
|
81
73
|
const [name, newPos] = TINYDNS.unpackDomainName(
|
|
82
|
-
[...bytes.
|
|
74
|
+
[...bytes.subarray(pos)]
|
|
83
75
|
.map((b) => (b < 32 || b > 126 ? TINYDNS.UInt8toOctal(b) : String.fromCharCode(b)))
|
|
84
76
|
.join(''),
|
|
85
77
|
)
|
|
@@ -102,8 +94,20 @@ export default class HIP extends RR {
|
|
|
102
94
|
|
|
103
95
|
fromBind({ bindline }) {
|
|
104
96
|
// owner ttl IN HIP pk-algorithm HIT public-key [rendezvous-server...]
|
|
97
|
+
// The public key may be split across multiple lines and joined with spaces
|
|
98
|
+
// by the zone parser. Base64 chars are [A-Za-z0-9+/=]; domain names contain '.'.
|
|
105
99
|
const parts = bindline.split(/\s+/)
|
|
106
|
-
const [owner, ttl, c, type, pkAlgorithm, hit
|
|
100
|
+
const [owner, ttl, c, type, pkAlgorithm, hit] = parts
|
|
101
|
+
const rest = parts.slice(6)
|
|
102
|
+
const keyParts = []
|
|
103
|
+
const rvsParts = []
|
|
104
|
+
for (const token of rest) {
|
|
105
|
+
if (/^[A-Za-z0-9+/=]+$/.test(token)) {
|
|
106
|
+
keyParts.push(token)
|
|
107
|
+
} else {
|
|
108
|
+
rvsParts.push(token)
|
|
109
|
+
}
|
|
110
|
+
}
|
|
107
111
|
return new HIP({
|
|
108
112
|
owner,
|
|
109
113
|
ttl: parseInt(ttl, 10),
|
|
@@ -111,8 +115,34 @@ export default class HIP extends RR {
|
|
|
111
115
|
type,
|
|
112
116
|
'pk algorithm': parseInt(pkAlgorithm, 10),
|
|
113
117
|
hit,
|
|
118
|
+
'public key': keyParts.join(''),
|
|
119
|
+
'rendezvous servers': rvsParts.join(' ').trim(),
|
|
120
|
+
})
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
fromWire({ owner, cls, ttl, rdata }) {
|
|
124
|
+
const dv = new DataView(rdata.buffer, rdata.byteOffset)
|
|
125
|
+
const hitLen = rdata[0]
|
|
126
|
+
const pkAlgorithm = rdata[1]
|
|
127
|
+
const pkLen = dv.getUint16(2)
|
|
128
|
+
const hit = BINARY.bytesToHex(rdata.subarray(4, 4 + hitLen)).toUpperCase()
|
|
129
|
+
const publicKey = BINARY.bytesToBase64(rdata.subarray(4 + hitLen, 4 + hitLen + pkLen))
|
|
130
|
+
const rvsNames = []
|
|
131
|
+
let pos = 4 + hitLen + pkLen
|
|
132
|
+
while (pos < rdata.length) {
|
|
133
|
+
const { fqdn, end } = this.wireUnpackDomain(rdata, pos)
|
|
134
|
+
rvsNames.push(fqdn)
|
|
135
|
+
pos = end
|
|
136
|
+
}
|
|
137
|
+
return new HIP({
|
|
138
|
+
owner,
|
|
139
|
+
ttl,
|
|
140
|
+
class: cls,
|
|
141
|
+
type: 'HIP',
|
|
142
|
+
'pk algorithm': pkAlgorithm,
|
|
143
|
+
hit,
|
|
114
144
|
'public key': publicKey,
|
|
115
|
-
'rendezvous servers':
|
|
145
|
+
'rendezvous servers': rvsNames.join(' '),
|
|
116
146
|
})
|
|
117
147
|
}
|
|
118
148
|
|
|
@@ -124,8 +154,9 @@ export default class HIP extends RR {
|
|
|
124
154
|
}
|
|
125
155
|
|
|
126
156
|
toTinydns() {
|
|
127
|
-
const
|
|
128
|
-
const
|
|
157
|
+
const hitHex = this.get('hit')
|
|
158
|
+
const hitBytes = BINARY.hexToBytes(hitHex)
|
|
159
|
+
const pkBytes = BINARY.base64ToBytes(this.get('public key'))
|
|
129
160
|
const rs = this.get('rendezvous servers')
|
|
130
161
|
|
|
131
162
|
let rdata = ''
|
|
@@ -140,4 +171,35 @@ export default class HIP extends RR {
|
|
|
140
171
|
|
|
141
172
|
return this.getTinydnsGeneric(rdata)
|
|
142
173
|
}
|
|
174
|
+
|
|
175
|
+
getWireRdata() {
|
|
176
|
+
const hitHex = this.get('hit')
|
|
177
|
+
const hitBytes = BINARY.hexToBytes(hitHex)
|
|
178
|
+
const pkBytes = BINARY.base64ToBytes(this.get('public key'))
|
|
179
|
+
const rs = this.get('rendezvous servers')
|
|
180
|
+
|
|
181
|
+
const rsNames = rs ? rs.split(/\s+/) : []
|
|
182
|
+
const rsDomains = rsNames.map((name) => WIRE.wirePackDomain(name))
|
|
183
|
+
const rsTotalLen = rsDomains.reduce((sum, b) => sum + b.length, 0)
|
|
184
|
+
|
|
185
|
+
const totalLen = 1 + 1 + 2 + hitBytes.length + pkBytes.length + rsTotalLen
|
|
186
|
+
const bytes = new Uint8Array(totalLen)
|
|
187
|
+
const dv = new DataView(bytes.buffer, bytes.byteOffset)
|
|
188
|
+
|
|
189
|
+
let pos = 0
|
|
190
|
+
bytes[pos++] = hitBytes.length
|
|
191
|
+
bytes[pos++] = this.get('pk algorithm')
|
|
192
|
+
dv.setUint16(pos, pkBytes.length)
|
|
193
|
+
pos += 2
|
|
194
|
+
bytes.set(hitBytes, pos)
|
|
195
|
+
pos += hitBytes.length
|
|
196
|
+
bytes.set(pkBytes, pos)
|
|
197
|
+
pos += pkBytes.length
|
|
198
|
+
for (const rdomain of rsDomains) {
|
|
199
|
+
bytes.set(rdomain, pos)
|
|
200
|
+
pos += rdomain.length
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return bytes
|
|
204
|
+
}
|
|
143
205
|
}
|
package/rr/https.js
CHANGED
|
@@ -1,8 +1,19 @@
|
|
|
1
1
|
import RR from '../rr.js'
|
|
2
2
|
|
|
3
3
|
import * as TINYDNS from '../lib/tinydns.js'
|
|
4
|
+
import * as WIRE from '../lib/wire.js'
|
|
4
5
|
|
|
5
6
|
export default class HTTPS extends RR {
|
|
7
|
+
static typeName = 'HTTPS'
|
|
8
|
+
static typeId = 65
|
|
9
|
+
static RFCs = [9460]
|
|
10
|
+
static tags = ['common']
|
|
11
|
+
static rdataFields = [
|
|
12
|
+
['priority', 'u16'],
|
|
13
|
+
['target name', 'fqdn'],
|
|
14
|
+
['params', 'svcparams'],
|
|
15
|
+
]
|
|
16
|
+
|
|
6
17
|
constructor(opts) {
|
|
7
18
|
super(opts)
|
|
8
19
|
}
|
|
@@ -32,22 +43,6 @@ export default class HTTPS extends RR {
|
|
|
32
43
|
return 'HTTP Semantics'
|
|
33
44
|
}
|
|
34
45
|
|
|
35
|
-
getTags() {
|
|
36
|
-
return ['common']
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
getRdataFields(arg) {
|
|
40
|
-
return ['priority', 'target name', 'params']
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
getRFCs() {
|
|
44
|
-
return [9460]
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
getTypeId() {
|
|
48
|
-
return 65
|
|
49
|
-
}
|
|
50
|
-
|
|
51
46
|
getCanonical() {
|
|
52
47
|
return {
|
|
53
48
|
owner: 'example.com.',
|
|
@@ -77,36 +72,19 @@ export default class HTTPS extends RR {
|
|
|
77
72
|
}
|
|
78
73
|
|
|
79
74
|
fromTinydns({ tinyline }) {
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
this.throwHelp(`HTTPS: RDATA too short: ${rd}`)
|
|
84
|
-
}
|
|
85
|
-
|
|
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()
|
|
75
|
+
const { owner, typeId, rdata, ttl, timestamp, location } = this.parseTinydnsLine(tinyline)
|
|
76
|
+
if (typeId != this.getTypeId()) this.throwHelp('HTTPS fromTinydns, invalid n')
|
|
77
|
+
const { priority, targetName, params } = TINYDNS.parseSvcbLikeRdata(rdata, 'HTTPS')
|
|
100
78
|
|
|
101
79
|
return new HTTPS({
|
|
102
|
-
owner
|
|
103
|
-
ttl
|
|
80
|
+
owner,
|
|
81
|
+
ttl,
|
|
104
82
|
type: 'HTTPS',
|
|
105
83
|
priority,
|
|
106
84
|
'target name': targetName,
|
|
107
85
|
params,
|
|
108
|
-
timestamp
|
|
109
|
-
location
|
|
86
|
+
timestamp,
|
|
87
|
+
location,
|
|
110
88
|
})
|
|
111
89
|
}
|
|
112
90
|
|
|
@@ -121,4 +99,14 @@ export default class HTTPS extends RR {
|
|
|
121
99
|
TINYDNS.escapeOctal(dataRe, this.get('params')),
|
|
122
100
|
)
|
|
123
101
|
}
|
|
102
|
+
|
|
103
|
+
getWireRdata() {
|
|
104
|
+
const targetBytes = this.wirePackDomain(this.get('target name'))
|
|
105
|
+
const paramsBytes = WIRE.svcParamsToWire(this.get('params'))
|
|
106
|
+
const result = new Uint8Array(2 + targetBytes.length + paramsBytes.length)
|
|
107
|
+
new DataView(result.buffer).setUint16(0, this.get('priority'))
|
|
108
|
+
result.set(targetBytes, 2)
|
|
109
|
+
result.set(paramsBytes, 2 + targetBytes.length)
|
|
110
|
+
return result
|
|
111
|
+
}
|
|
124
112
|
}
|
package/rr/ipseckey.js
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
import RR from '../rr.js'
|
|
2
2
|
|
|
3
3
|
import * as TINYDNS from '../lib/tinydns.js'
|
|
4
|
+
import * as BINARY from '../lib/binary.js'
|
|
5
|
+
import * as WIRE from '../lib/wire.js'
|
|
4
6
|
|
|
5
7
|
export default class IPSECKEY extends RR {
|
|
8
|
+
static typeName = 'IPSECKEY'
|
|
9
|
+
static typeId = 45
|
|
10
|
+
static RFCs = [4025]
|
|
11
|
+
static rdataFields = ['precedence', 'gateway type', 'algorithm', 'gateway', 'publickey']
|
|
12
|
+
static tags = ['security']
|
|
13
|
+
|
|
6
14
|
constructor(opts) {
|
|
7
15
|
super(opts)
|
|
8
16
|
}
|
|
@@ -62,8 +70,7 @@ export default class IPSECKEY extends RR {
|
|
|
62
70
|
}
|
|
63
71
|
|
|
64
72
|
setPublickey(val) {
|
|
65
|
-
|
|
66
|
-
|
|
73
|
+
if (val) this.isBase64('IPSECKEY', 'publickey', val)
|
|
67
74
|
this.set('publickey', val)
|
|
68
75
|
}
|
|
69
76
|
|
|
@@ -71,22 +78,6 @@ export default class IPSECKEY extends RR {
|
|
|
71
78
|
return 'IPsec Keying'
|
|
72
79
|
}
|
|
73
80
|
|
|
74
|
-
getTags() {
|
|
75
|
-
return ['security']
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
getRdataFields(arg) {
|
|
79
|
-
return ['precedence', 'gateway type', 'algorithm', 'gateway', 'publickey']
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
getRFCs() {
|
|
83
|
-
return [4025]
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
getTypeId() {
|
|
87
|
-
return 45
|
|
88
|
-
}
|
|
89
|
-
|
|
90
81
|
getCanonical() {
|
|
91
82
|
return {
|
|
92
83
|
owner: '38.2.0.192.in-addr.arpa.',
|
|
@@ -161,6 +152,49 @@ export default class IPSECKEY extends RR {
|
|
|
161
152
|
})
|
|
162
153
|
}
|
|
163
154
|
|
|
155
|
+
fromWire({ owner, cls, ttl, rdata }) {
|
|
156
|
+
const precedence = rdata[0]
|
|
157
|
+
const gwType = rdata[1]
|
|
158
|
+
const algorithm = rdata[2]
|
|
159
|
+
let gateway, keyStart
|
|
160
|
+
switch (gwType) {
|
|
161
|
+
case 0:
|
|
162
|
+
gateway = '.'
|
|
163
|
+
keyStart = 3
|
|
164
|
+
break
|
|
165
|
+
case 1:
|
|
166
|
+
gateway = [...rdata.subarray(3, 7)].join('.')
|
|
167
|
+
keyStart = 7
|
|
168
|
+
break
|
|
169
|
+
case 2: {
|
|
170
|
+
const dv = new DataView(rdata.buffer, rdata.byteOffset + 3)
|
|
171
|
+
const groups = []
|
|
172
|
+
for (let i = 0; i < 16; i += 2) groups.push(dv.getUint16(i).toString(16).padStart(4, '0'))
|
|
173
|
+
gateway = groups.join(':')
|
|
174
|
+
keyStart = 19
|
|
175
|
+
break
|
|
176
|
+
}
|
|
177
|
+
case 3: {
|
|
178
|
+
const { fqdn, end } = this.wireUnpackDomain(rdata, 3)
|
|
179
|
+
gateway = fqdn
|
|
180
|
+
keyStart = end
|
|
181
|
+
break
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
const publickey = BINARY.bytesToBase64(rdata.subarray(keyStart))
|
|
185
|
+
return new IPSECKEY({
|
|
186
|
+
owner,
|
|
187
|
+
ttl,
|
|
188
|
+
class: cls,
|
|
189
|
+
type: 'IPSECKEY',
|
|
190
|
+
precedence,
|
|
191
|
+
'gateway type': gwType,
|
|
192
|
+
algorithm,
|
|
193
|
+
gateway,
|
|
194
|
+
publickey,
|
|
195
|
+
})
|
|
196
|
+
}
|
|
197
|
+
|
|
164
198
|
/****** EXPORTERS *******/
|
|
165
199
|
|
|
166
200
|
toTinydns() {
|
|
@@ -190,4 +224,49 @@ export default class IPSECKEY extends RR {
|
|
|
190
224
|
|
|
191
225
|
return this.getTinydnsGeneric(rdata)
|
|
192
226
|
}
|
|
227
|
+
|
|
228
|
+
getWireRdata() {
|
|
229
|
+
const pubkeyBytes = BINARY.base64ToBytes(this.get('publickey'))
|
|
230
|
+
const gwType = this.get('gateway type')
|
|
231
|
+
|
|
232
|
+
let gwBytes
|
|
233
|
+
switch (gwType) {
|
|
234
|
+
case 0:
|
|
235
|
+
gwBytes = new Uint8Array(0)
|
|
236
|
+
break
|
|
237
|
+
case 1:
|
|
238
|
+
gwBytes = new Uint8Array(4)
|
|
239
|
+
this.get('gateway')
|
|
240
|
+
.split('.')
|
|
241
|
+
.forEach((part, i) => {
|
|
242
|
+
gwBytes[i] = parseInt(part, 10)
|
|
243
|
+
})
|
|
244
|
+
break
|
|
245
|
+
case 2:
|
|
246
|
+
gwBytes = new Uint8Array(16)
|
|
247
|
+
{
|
|
248
|
+
const parts = this.get('gateway').split(':')
|
|
249
|
+
let pos = 0
|
|
250
|
+
for (const part of parts) {
|
|
251
|
+
if (part === '') continue
|
|
252
|
+
const val = parseInt(part, 16)
|
|
253
|
+
gwBytes[pos++] = (val >>> 8) & 0xff
|
|
254
|
+
gwBytes[pos++] = val & 0xff
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
break
|
|
258
|
+
case 3:
|
|
259
|
+
gwBytes = WIRE.wirePackDomain(this.get('gateway'))
|
|
260
|
+
break
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const bytes = new Uint8Array(3 + gwBytes.length + pubkeyBytes.length)
|
|
264
|
+
bytes[0] = this.get('precedence')
|
|
265
|
+
bytes[1] = gwType
|
|
266
|
+
bytes[2] = this.get('algorithm')
|
|
267
|
+
bytes.set(gwBytes, 3)
|
|
268
|
+
bytes.set(pubkeyBytes, 3 + gwBytes.length)
|
|
269
|
+
|
|
270
|
+
return bytes
|
|
271
|
+
}
|
|
193
272
|
}
|