@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/naptr.js
CHANGED
|
@@ -1,136 +1,135 @@
|
|
|
1
|
-
|
|
2
1
|
import RR from '../rr.js'
|
|
3
2
|
import * as TINYDNS from '../lib/tinydns.js'
|
|
4
3
|
|
|
5
4
|
const rdataRe = /[\r\n\t:\\/]/
|
|
6
5
|
|
|
7
6
|
export default class NAPTR extends RR {
|
|
8
|
-
constructor
|
|
7
|
+
constructor(opts) {
|
|
9
8
|
super(opts)
|
|
10
9
|
}
|
|
11
10
|
|
|
12
|
-
getDescription
|
|
11
|
+
getDescription() {
|
|
13
12
|
return 'Naming Authority Pointer'
|
|
14
13
|
}
|
|
15
14
|
|
|
16
|
-
getQuotedFields
|
|
17
|
-
return [
|
|
15
|
+
getQuotedFields() {
|
|
16
|
+
return ['flags', 'service', 'regexp']
|
|
18
17
|
}
|
|
19
18
|
|
|
20
|
-
getRdataFields
|
|
21
|
-
return [
|
|
19
|
+
getRdataFields(arg) {
|
|
20
|
+
return ['order', 'preference', 'flags', 'service', 'regexp', 'replacement']
|
|
22
21
|
}
|
|
23
22
|
|
|
24
|
-
getRFCs
|
|
25
|
-
return [
|
|
23
|
+
getRFCs() {
|
|
24
|
+
return [2915, 3403]
|
|
26
25
|
}
|
|
27
26
|
|
|
28
|
-
getTypeId
|
|
27
|
+
getTypeId() {
|
|
29
28
|
return 35
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
/****** Resource record specific setters *******/
|
|
33
|
-
setOrder
|
|
32
|
+
setOrder(val) {
|
|
34
33
|
this.is16bitInt('NAPTR', 'order', val)
|
|
35
34
|
this.set('order', val)
|
|
36
35
|
}
|
|
37
36
|
|
|
38
|
-
setPreference
|
|
37
|
+
setPreference(val) {
|
|
39
38
|
this.is16bitInt('NAPTR', 'preference', val)
|
|
40
39
|
this.set('preference', val)
|
|
41
40
|
}
|
|
42
41
|
|
|
43
|
-
setFlags
|
|
44
|
-
if (![
|
|
45
|
-
throw new Error
|
|
42
|
+
setFlags(val) {
|
|
43
|
+
if (!['', 'S', 'A', 'U', 'P'].includes(val.toUpperCase()))
|
|
44
|
+
throw new Error(`NAPTR flags are invalid, ${this.citeRFC()}`)
|
|
46
45
|
|
|
47
46
|
this.set('flags', val.toUpperCase())
|
|
48
47
|
}
|
|
49
48
|
|
|
50
|
-
setService
|
|
49
|
+
setService(val) {
|
|
51
50
|
this.set('service', val)
|
|
52
51
|
}
|
|
53
52
|
|
|
54
|
-
setRegexp
|
|
53
|
+
setRegexp(val) {
|
|
55
54
|
this.set('regexp', val)
|
|
56
55
|
}
|
|
57
56
|
|
|
58
|
-
setReplacement
|
|
57
|
+
setReplacement(val) {
|
|
59
58
|
this.set('replacement', val)
|
|
60
59
|
}
|
|
61
60
|
|
|
62
61
|
/****** IMPORTERS *******/
|
|
63
|
-
fromTinydns
|
|
62
|
+
fromTinydns(opts) {
|
|
64
63
|
// NAPTR via generic, :fqdn:n:rdata:ttl:timestamp:lo
|
|
65
|
-
const [
|
|
64
|
+
const [fqdn, n, rdata, ttl, ts, loc] = opts.tinyline.substring(1).split(':')
|
|
66
65
|
if (n != 35) throw new Error('NAPTR fromTinydns, invalid n')
|
|
67
66
|
|
|
68
67
|
const binRdata = Buffer.from(TINYDNS.octalToChar(rdata), 'binary')
|
|
69
68
|
|
|
70
69
|
const rec = {
|
|
71
|
-
type
|
|
72
|
-
owner
|
|
73
|
-
ttl
|
|
74
|
-
timestamp
|
|
75
|
-
location
|
|
76
|
-
order
|
|
77
|
-
preference: binRdata.readUInt16BE(2,4),
|
|
70
|
+
type: 'NAPTR',
|
|
71
|
+
owner: this.fullyQualify(fqdn),
|
|
72
|
+
ttl: parseInt(ttl, 10),
|
|
73
|
+
timestamp: ts,
|
|
74
|
+
location: loc !== '' && loc !== '\n' ? loc : '',
|
|
75
|
+
order: binRdata.readUInt16BE(0, 2),
|
|
76
|
+
preference: binRdata.readUInt16BE(2, 4),
|
|
78
77
|
}
|
|
79
78
|
|
|
80
79
|
let idx = 4
|
|
81
|
-
const flagsLength = binRdata.readUInt8(idx)
|
|
82
|
-
|
|
80
|
+
const flagsLength = binRdata.readUInt8(idx)
|
|
81
|
+
idx++
|
|
82
|
+
rec.flags = binRdata.slice(idx, flagsLength).toString()
|
|
83
83
|
idx += flagsLength
|
|
84
84
|
|
|
85
|
-
const serviceLen
|
|
86
|
-
|
|
85
|
+
const serviceLen = binRdata.readUInt8(idx)
|
|
86
|
+
idx++
|
|
87
|
+
rec.service = binRdata.slice(idx, idx + serviceLen).toString()
|
|
87
88
|
idx += serviceLen
|
|
88
89
|
|
|
89
|
-
const regexpLen
|
|
90
|
-
|
|
90
|
+
const regexpLen = binRdata.readUInt8(idx)
|
|
91
|
+
idx++
|
|
92
|
+
rec.regexp = binRdata.slice(idx, idx + regexpLen).toString()
|
|
91
93
|
idx += regexpLen
|
|
92
94
|
|
|
93
|
-
const replaceLen
|
|
94
|
-
|
|
95
|
+
const replaceLen = binRdata.readUInt8(idx)
|
|
96
|
+
idx++
|
|
97
|
+
rec.replacement = binRdata.slice(idx, idx + replaceLen).toString()
|
|
95
98
|
|
|
96
99
|
return new NAPTR(rec)
|
|
97
100
|
}
|
|
98
101
|
|
|
99
|
-
fromBind
|
|
102
|
+
fromBind(opts) {
|
|
100
103
|
const str = opts.bindline
|
|
101
104
|
// test.example.com 3600 IN NAPTR order, preference, "flags", "service", "regexp", replacement
|
|
102
|
-
const [
|
|
103
|
-
const [
|
|
105
|
+
const [owner, ttl, c, type, order, preference] = str.split(/\s+/)
|
|
106
|
+
const [flags, service, regexp] = str.match(/(?:").*?(?:"\s)/g)
|
|
104
107
|
const replacement = str.trim().split(/\s+/).pop()
|
|
105
108
|
|
|
106
109
|
const bits = {
|
|
107
|
-
owner
|
|
108
|
-
ttl
|
|
109
|
-
class
|
|
110
|
-
type
|
|
111
|
-
order
|
|
112
|
-
preference
|
|
113
|
-
flags
|
|
114
|
-
service
|
|
115
|
-
regexp
|
|
110
|
+
owner: owner,
|
|
111
|
+
ttl: parseInt(ttl, 10),
|
|
112
|
+
class: c,
|
|
113
|
+
type: type,
|
|
114
|
+
order: parseInt(order, 10),
|
|
115
|
+
preference: parseInt(preference, 10),
|
|
116
|
+
flags: flags.trim().replace(/^['"]|['"]$/g, ''),
|
|
117
|
+
service: service.trim().replace(/^['"]|['"]$/g, ''),
|
|
118
|
+
regexp: regexp.trim().replace(/^['"]|['"]/g, ''),
|
|
116
119
|
replacement: replacement,
|
|
117
120
|
}
|
|
118
121
|
return new NAPTR(bits)
|
|
119
122
|
}
|
|
120
123
|
|
|
121
124
|
/****** EXPORTERS *******/
|
|
122
|
-
toTinydns
|
|
123
|
-
|
|
125
|
+
toTinydns() {
|
|
124
126
|
let rdata =
|
|
125
127
|
TINYDNS.UInt16toOctal(this.get('order')) +
|
|
126
128
|
TINYDNS.UInt16toOctal(this.get('preference')) +
|
|
127
|
-
|
|
128
129
|
TINYDNS.UInt8toOctal(this.get('flags').length) +
|
|
129
130
|
this.get('flags') +
|
|
130
|
-
|
|
131
131
|
TINYDNS.UInt8toOctal(this.get('service').length) +
|
|
132
132
|
TINYDNS.escapeOctal(rdataRe, this.get('service')) +
|
|
133
|
-
|
|
134
133
|
TINYDNS.UInt8toOctal(this.get('regexp').length) +
|
|
135
134
|
TINYDNS.escapeOctal(rdataRe, this.get('regexp'))
|
|
136
135
|
|
package/rr/ns.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
|
|
2
1
|
import RR from '../rr.js'
|
|
3
2
|
|
|
4
3
|
export default class NS extends RR {
|
|
5
|
-
constructor
|
|
4
|
+
constructor(opts) {
|
|
6
5
|
super(opts)
|
|
7
6
|
if (opts === null) return
|
|
8
7
|
}
|
|
9
8
|
|
|
10
9
|
/****** Resource record specific setters *******/
|
|
11
|
-
setDname
|
|
10
|
+
setDname(val) {
|
|
12
11
|
if (!val) throw new Error(`NS: dname is required, ${this.citeRFC()}`)
|
|
13
12
|
|
|
14
13
|
this.isFullyQualified('NS', 'dname', val)
|
|
@@ -18,57 +17,61 @@ export default class NS extends RR {
|
|
|
18
17
|
this.set('dname', val.toLowerCase())
|
|
19
18
|
}
|
|
20
19
|
|
|
21
|
-
getDescription
|
|
20
|
+
getDescription() {
|
|
22
21
|
return 'Name Server'
|
|
23
22
|
}
|
|
24
23
|
|
|
25
|
-
getRdataFields
|
|
26
|
-
return [
|
|
24
|
+
getRdataFields(arg) {
|
|
25
|
+
return ['dname']
|
|
27
26
|
}
|
|
28
27
|
|
|
29
|
-
getRFCs
|
|
30
|
-
return [
|
|
28
|
+
getRFCs() {
|
|
29
|
+
return [1035]
|
|
31
30
|
}
|
|
32
31
|
|
|
33
|
-
getTypeId
|
|
32
|
+
getTypeId() {
|
|
34
33
|
return 2
|
|
35
34
|
}
|
|
36
35
|
|
|
37
36
|
/****** IMPORTERS *******/
|
|
38
|
-
fromTinydns
|
|
37
|
+
fromTinydns(opts) {
|
|
39
38
|
// &fqdn:ip:x:ttl:timestamp:lo
|
|
40
39
|
// eslint-disable-next-line no-unused-vars
|
|
41
|
-
const [
|
|
40
|
+
const [fqdn, ip, dname, ttl, ts, loc] = opts.tinyline
|
|
41
|
+
.substring(1)
|
|
42
|
+
.split(':')
|
|
42
43
|
|
|
43
44
|
return new NS({
|
|
44
|
-
type
|
|
45
|
-
owner
|
|
46
|
-
dname
|
|
47
|
-
|
|
45
|
+
type: 'NS',
|
|
46
|
+
owner: this.fullyQualify(fqdn),
|
|
47
|
+
dname: this.fullyQualify(
|
|
48
|
+
/\./.test(dname) ? dname : `${dname}.ns.${fqdn}`,
|
|
49
|
+
),
|
|
50
|
+
ttl: parseInt(ttl, 10),
|
|
48
51
|
timestamp: ts,
|
|
49
|
-
location
|
|
52
|
+
location: loc !== '' && loc !== '\n' ? loc : '',
|
|
50
53
|
})
|
|
51
54
|
}
|
|
52
55
|
|
|
53
|
-
fromBind
|
|
56
|
+
fromBind(opts) {
|
|
54
57
|
// test.example.com 3600 IN NS dname
|
|
55
|
-
const [
|
|
58
|
+
const [owner, ttl, c, type, dname] = opts.bindline.split(/\s+/)
|
|
56
59
|
|
|
57
60
|
return new NS({
|
|
58
61
|
owner,
|
|
59
|
-
ttl
|
|
62
|
+
ttl: parseInt(ttl, 10),
|
|
60
63
|
class: c,
|
|
61
|
-
type
|
|
64
|
+
type: type,
|
|
62
65
|
dname: dname,
|
|
63
66
|
})
|
|
64
67
|
}
|
|
65
68
|
|
|
66
69
|
/****** EXPORTERS *******/
|
|
67
|
-
toBind
|
|
70
|
+
toBind(zone_opts) {
|
|
68
71
|
return `${this.getPrefix(zone_opts)}\t${this.getFQDN('dname', zone_opts)}\n`
|
|
69
72
|
}
|
|
70
73
|
|
|
71
|
-
toTinydns
|
|
74
|
+
toTinydns() {
|
|
72
75
|
return `&${this.getTinyFQDN('owner')}::${this.getTinyFQDN('dname')}:${this.getTinydnsPostamble()}\n`
|
|
73
76
|
}
|
|
74
77
|
}
|
package/rr/nsec.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
|
|
2
1
|
import RR from '../rr.js'
|
|
3
2
|
|
|
4
3
|
export default class NSEC extends RR {
|
|
5
|
-
constructor
|
|
4
|
+
constructor(opts) {
|
|
6
5
|
super(opts)
|
|
7
6
|
if (opts === null) return
|
|
8
7
|
}
|
|
9
8
|
|
|
10
9
|
/****** Resource record specific setters *******/
|
|
11
|
-
setNextDomain
|
|
12
|
-
if (!val)
|
|
10
|
+
setNextDomain(val) {
|
|
11
|
+
if (!val)
|
|
12
|
+
throw new Error(`NSEC: 'next domain' is required:, ${this.citeRFC()}`)
|
|
13
13
|
|
|
14
14
|
this.isFullyQualified('NSEC', 'next domain', val)
|
|
15
15
|
this.isValidHostname('NSEC', 'next domain', val)
|
|
@@ -18,44 +18,50 @@ export default class NSEC extends RR {
|
|
|
18
18
|
this.set('next domain', val.toLowerCase())
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
setTypeBitMaps
|
|
22
|
-
if (!val)
|
|
21
|
+
setTypeBitMaps(val) {
|
|
22
|
+
if (!val)
|
|
23
|
+
throw new Error(`NSEC: 'type bit maps' is required, ${this.citeRFC()}`)
|
|
23
24
|
|
|
24
25
|
this.set('type bit maps', val)
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
getDescription
|
|
28
|
+
getDescription() {
|
|
28
29
|
return 'Next Secure'
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
getRdataFields
|
|
32
|
-
return [
|
|
32
|
+
getRdataFields(arg) {
|
|
33
|
+
return ['next domain', 'type bit maps']
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
getRFCs
|
|
36
|
-
return [
|
|
36
|
+
getRFCs() {
|
|
37
|
+
return [4034]
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
getTypeId
|
|
40
|
+
getTypeId() {
|
|
40
41
|
return 47
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
/****** IMPORTERS *******/
|
|
44
45
|
|
|
45
|
-
fromBind
|
|
46
|
+
fromBind(opts) {
|
|
46
47
|
// test.example.com 3600 IN NSEC NextDomain TypeBitMaps
|
|
47
|
-
const [
|
|
48
|
+
const [owner, ttl, c, type, next] = opts.bindline.split(/\s+/)
|
|
48
49
|
return new NSEC({
|
|
49
50
|
owner,
|
|
50
|
-
ttl
|
|
51
|
-
class
|
|
52
|
-
type
|
|
53
|
-
'next domain'
|
|
54
|
-
'type bit maps': opts.bindline
|
|
51
|
+
ttl: parseInt(ttl, 10),
|
|
52
|
+
class: c,
|
|
53
|
+
type: type,
|
|
54
|
+
'next domain': next,
|
|
55
|
+
'type bit maps': opts.bindline
|
|
56
|
+
.split(/\s+/)
|
|
57
|
+
.slice(5)
|
|
58
|
+
.filter(removeParens)
|
|
59
|
+
.join(' ')
|
|
60
|
+
.trim(),
|
|
55
61
|
})
|
|
56
62
|
}
|
|
57
63
|
|
|
58
64
|
/****** EXPORTERS *******/
|
|
59
65
|
}
|
|
60
66
|
|
|
61
|
-
const removeParens = a => ![
|
|
67
|
+
const removeParens = (a) => !['(', ')'].includes(a)
|
package/rr/nsec3.js
CHANGED
|
@@ -1,24 +1,26 @@
|
|
|
1
|
-
|
|
2
1
|
import RR from '../rr.js'
|
|
3
2
|
|
|
3
|
+
import * as TINYDNS from '../lib/tinydns.js'
|
|
4
|
+
|
|
4
5
|
export default class NSEC3 extends RR {
|
|
5
|
-
constructor
|
|
6
|
+
constructor(opts) {
|
|
6
7
|
super(opts)
|
|
7
8
|
if (opts === null) return
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
/****** Resource record specific setters *******/
|
|
11
|
-
|
|
12
|
+
setHashAlgorithm(val) {
|
|
12
13
|
// Hash Algorithm is a single octet.
|
|
13
14
|
// The Hash Algorithm field is represented as an unsigned decimal integer.
|
|
14
|
-
if (!val)
|
|
15
|
+
if (!val)
|
|
16
|
+
throw new Error(`NSEC3: 'hash algorithm' is required, ${this.citeRFC()}`)
|
|
15
17
|
|
|
16
18
|
this.is8bitInt('NSEC3', 'hash algorithm', val)
|
|
17
19
|
|
|
18
20
|
this.set('hash algorithm', val)
|
|
19
21
|
}
|
|
20
22
|
|
|
21
|
-
setFlags
|
|
23
|
+
setFlags(val) {
|
|
22
24
|
// The Flags field is represented as an unsigned decimal integer.
|
|
23
25
|
if (!val) throw new Error(`NSEC3: 'flags' is required, ${this.citeRFC()}`)
|
|
24
26
|
|
|
@@ -27,16 +29,17 @@ export default class NSEC3 extends RR {
|
|
|
27
29
|
this.set('flags', val)
|
|
28
30
|
}
|
|
29
31
|
|
|
30
|
-
setIterations
|
|
32
|
+
setIterations(val) {
|
|
31
33
|
// The Iterations field is represented as an unsigned decimal integer. 0-65535
|
|
32
|
-
if (!val)
|
|
34
|
+
if (!val)
|
|
35
|
+
throw new Error(`NSEC3: 'iterations' is required, ${this.citeRFC()}`)
|
|
33
36
|
|
|
34
37
|
this.is16bitInt('NSEC3', 'flags', val)
|
|
35
38
|
|
|
36
39
|
this.set('iterations', val)
|
|
37
40
|
}
|
|
38
41
|
|
|
39
|
-
setSalt
|
|
42
|
+
setSalt(val) {
|
|
40
43
|
// The Salt field is represented as a sequence of case-insensitive
|
|
41
44
|
// hexadecimal digits. Whitespace is not allowed within the
|
|
42
45
|
// sequence. The Salt field is represented as "-" (without the
|
|
@@ -44,56 +47,113 @@ export default class NSEC3 extends RR {
|
|
|
44
47
|
this.set('salt', val)
|
|
45
48
|
}
|
|
46
49
|
|
|
47
|
-
setNextHashedOwnerName
|
|
50
|
+
setNextHashedOwnerName(val) {
|
|
48
51
|
// The Next Hashed Owner Name field is represented as an unpadded
|
|
49
52
|
// sequence of case-insensitive base32 digits, without whitespace
|
|
50
|
-
if (!val)
|
|
53
|
+
if (!val)
|
|
54
|
+
throw new Error(
|
|
55
|
+
`NSEC3: 'next hashed owner name' is required, ${this.citeRFC()}`,
|
|
56
|
+
)
|
|
51
57
|
|
|
52
58
|
this.set('next hashed owner name', val)
|
|
53
59
|
}
|
|
54
60
|
|
|
55
|
-
setTypeBitMaps
|
|
61
|
+
setTypeBitMaps(val) {
|
|
56
62
|
// The Type Bit Maps field is represented as a sequence of RR type mnemonics.
|
|
57
|
-
if (!val)
|
|
63
|
+
if (!val)
|
|
64
|
+
throw new Error(`NSEC3: 'type bit maps' is required, ${this.citeRFC()}`)
|
|
58
65
|
|
|
59
66
|
this.set('type bit maps', val)
|
|
60
67
|
}
|
|
61
68
|
|
|
62
|
-
getDescription
|
|
69
|
+
getDescription() {
|
|
63
70
|
return 'Next Secure'
|
|
64
71
|
}
|
|
65
72
|
|
|
66
|
-
getRdataFields
|
|
67
|
-
return [
|
|
73
|
+
getRdataFields(arg) {
|
|
74
|
+
return [
|
|
75
|
+
'hash algorithm',
|
|
76
|
+
'flags',
|
|
77
|
+
'iterations',
|
|
78
|
+
'salt',
|
|
79
|
+
'next hashed owner name',
|
|
80
|
+
'type bit maps',
|
|
81
|
+
]
|
|
68
82
|
}
|
|
69
83
|
|
|
70
|
-
getRFCs
|
|
71
|
-
return [
|
|
84
|
+
getRFCs() {
|
|
85
|
+
return [5155, 9077]
|
|
72
86
|
}
|
|
73
87
|
|
|
74
|
-
getTypeId
|
|
88
|
+
getTypeId() {
|
|
75
89
|
return 50
|
|
76
90
|
}
|
|
77
91
|
|
|
78
92
|
/****** IMPORTERS *******/
|
|
79
93
|
|
|
80
|
-
fromBind
|
|
81
|
-
// test.example.com
|
|
82
|
-
const [
|
|
94
|
+
fromBind(opts) {
|
|
95
|
+
// test.example.com. 3600 IN NSEC3 1 1 12 aabbccdd (2vptu5timamqttgl4luu9kg21e0aor3s A RRSIG)
|
|
96
|
+
const [owner, ttl, c, type, ha, flags, iterations, salt] =
|
|
97
|
+
opts.bindline.split(/\s+/)
|
|
98
|
+
const rdata = opts.bindline.split(/\(|\)/)[1]
|
|
99
|
+
|
|
83
100
|
return new NSEC3({
|
|
84
101
|
owner,
|
|
85
|
-
ttl
|
|
86
|
-
class
|
|
87
|
-
type
|
|
88
|
-
'hash algorithm'
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
'next hashed owner name':
|
|
93
|
-
'type bit maps'
|
|
102
|
+
ttl: parseInt(ttl, 10),
|
|
103
|
+
class: c,
|
|
104
|
+
type: type,
|
|
105
|
+
'hash algorithm': parseInt(ha, 10),
|
|
106
|
+
flags: parseInt(flags, 10),
|
|
107
|
+
iterations: parseInt(iterations, 10),
|
|
108
|
+
salt,
|
|
109
|
+
'next hashed owner name': rdata.split(/\s+/)[0],
|
|
110
|
+
'type bit maps': rdata.split(/\s+/).slice(1).join('\t'),
|
|
111
|
+
})
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
fromTinydns(opts) {
|
|
115
|
+
const [fqdn, n, rdata, ttl, ts, loc] = opts.tinyline.substring(1).split(':')
|
|
116
|
+
if (n != 50) throw new Error('NSEC3 fromTinydns, invalid n')
|
|
117
|
+
|
|
118
|
+
const bytes = Buffer.from(TINYDNS.octalToChar(rdata), 'binary')
|
|
119
|
+
|
|
120
|
+
return new NSEC3({
|
|
121
|
+
owner: this.fullyQualify(fqdn),
|
|
122
|
+
ttl: parseInt(ttl, 10),
|
|
123
|
+
type: 'NSEC3',
|
|
124
|
+
'hash algorithm': bytes.readUInt8(0),
|
|
125
|
+
flags: bytes.readUInt8(1),
|
|
126
|
+
iterations: bytes.readUInt16BE(2),
|
|
127
|
+
// salt : ,
|
|
128
|
+
// 'next hashed owner name': ,
|
|
129
|
+
// 'type bit maps' : ,
|
|
130
|
+
timestamp: ts,
|
|
131
|
+
location: loc !== '' && loc !== '\n' ? loc : '',
|
|
94
132
|
})
|
|
95
133
|
}
|
|
96
134
|
|
|
97
135
|
/****** EXPORTERS *******/
|
|
98
136
|
|
|
137
|
+
toBind(zone_opts) {
|
|
138
|
+
return `${this.getFQDN('owner', zone_opts)}\t${this.get('ttl')}\t${this.get('class')}\tNSEC3${this.getRdataFields()
|
|
139
|
+
.slice(0, 4)
|
|
140
|
+
.map((f) => '\t' + this.get(f))
|
|
141
|
+
.join('')}\t(${this.getRdataFields()
|
|
142
|
+
.slice(4)
|
|
143
|
+
.map((f) => this.get(f))
|
|
144
|
+
.join('\t')})\n`
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
toTinydns() {
|
|
148
|
+
const dataRe = new RegExp(/[\r\n\t:\\/]/, 'g')
|
|
149
|
+
|
|
150
|
+
return this.getTinydnsGeneric(
|
|
151
|
+
TINYDNS.UInt8toOctal(this.get('hash algorithm')) +
|
|
152
|
+
TINYDNS.UInt8toOctal(this.get('flags')) +
|
|
153
|
+
TINYDNS.UInt16toOctal(this.get('iterations')) +
|
|
154
|
+
TINYDNS.escapeOctal(dataRe, this.get('salt')) +
|
|
155
|
+
TINYDNS.escapeOctal(dataRe, this.get('next hashed owner name')) +
|
|
156
|
+
TINYDNS.escapeOctal(dataRe, this.get('type bit maps')),
|
|
157
|
+
)
|
|
158
|
+
}
|
|
99
159
|
}
|
package/rr/nsec3param.js
CHANGED
|
@@ -1,42 +1,46 @@
|
|
|
1
|
-
|
|
2
1
|
import RR from '../rr.js'
|
|
3
2
|
|
|
4
3
|
export default class NSEC3PARAM extends RR {
|
|
5
|
-
constructor
|
|
4
|
+
constructor(opts) {
|
|
6
5
|
super(opts)
|
|
7
6
|
if (opts === null) return
|
|
8
7
|
}
|
|
9
8
|
|
|
10
9
|
/****** Resource record specific setters *******/
|
|
11
|
-
setHashAlgoritm
|
|
10
|
+
setHashAlgoritm(val) {
|
|
12
11
|
// Hash Algorithm is a single octet.
|
|
13
12
|
// The Hash Algorithm field is represented as an unsigned decimal integer.
|
|
14
|
-
if (!val)
|
|
13
|
+
if (!val)
|
|
14
|
+
throw new Error(
|
|
15
|
+
`NSEC3PARAM: 'hash algorithm' is required, ${this.citeRFC()}`,
|
|
16
|
+
)
|
|
15
17
|
|
|
16
18
|
this.is8bitInt('NSEC3PARAM', 'hash algorithm', val)
|
|
17
19
|
|
|
18
20
|
this.set('hash algorithm', val)
|
|
19
21
|
}
|
|
20
22
|
|
|
21
|
-
setFlags
|
|
23
|
+
setFlags(val) {
|
|
22
24
|
// The Flags field is represented as an unsigned decimal integer.
|
|
23
|
-
if (!val)
|
|
25
|
+
if (!val)
|
|
26
|
+
throw new Error(`NSEC3PARAM: 'flags' is required, ${this.citeRFC()}`)
|
|
24
27
|
|
|
25
28
|
this.is8bitInt('NSEC3PARAM', 'flags', val)
|
|
26
29
|
|
|
27
30
|
this.set('flags', val)
|
|
28
31
|
}
|
|
29
32
|
|
|
30
|
-
setIterations
|
|
33
|
+
setIterations(val) {
|
|
31
34
|
// The Iterations field is represented as an unsigned decimal integer. 0-65535
|
|
32
|
-
if (!val)
|
|
35
|
+
if (!val)
|
|
36
|
+
throw new Error(`NSEC3PARAM: 'iterations' is required, ${this.citeRFC()}`)
|
|
33
37
|
|
|
34
38
|
this.is16bitInt('NSEC3PARAM', 'iterations', val)
|
|
35
39
|
|
|
36
40
|
this.set('iterations', val)
|
|
37
41
|
}
|
|
38
42
|
|
|
39
|
-
setSalt
|
|
43
|
+
setSalt(val) {
|
|
40
44
|
// The Salt field is represented as a sequence of case-insensitive
|
|
41
45
|
// hexadecimal digits. Whitespace is not allowed within the
|
|
42
46
|
// sequence. The Salt field is represented as "-" (without the
|
|
@@ -44,41 +48,40 @@ export default class NSEC3PARAM extends RR {
|
|
|
44
48
|
this.set('salt', val)
|
|
45
49
|
}
|
|
46
50
|
|
|
47
|
-
getDescription
|
|
51
|
+
getDescription() {
|
|
48
52
|
return 'Next Secure Parameters'
|
|
49
53
|
}
|
|
50
54
|
|
|
51
|
-
getRdataFields
|
|
52
|
-
return [
|
|
55
|
+
getRdataFields(arg) {
|
|
56
|
+
return ['hash algorithm', 'flags', 'iterations', 'salt']
|
|
53
57
|
}
|
|
54
58
|
|
|
55
|
-
getRFCs
|
|
56
|
-
return [
|
|
59
|
+
getRFCs() {
|
|
60
|
+
return [5155]
|
|
57
61
|
}
|
|
58
62
|
|
|
59
|
-
getTypeId
|
|
63
|
+
getTypeId() {
|
|
60
64
|
return 51
|
|
61
65
|
}
|
|
62
66
|
|
|
63
67
|
/****** IMPORTERS *******/
|
|
64
68
|
|
|
65
|
-
fromBind
|
|
69
|
+
fromBind(str) {
|
|
66
70
|
// test.example.com 3600 IN NSEC3PARAM
|
|
67
|
-
const [
|
|
71
|
+
const [owner, ttl, c, type] = str.split(/\s+/)
|
|
68
72
|
return new NSEC3PARAM({
|
|
69
73
|
owner,
|
|
70
|
-
ttl
|
|
71
|
-
class
|
|
72
|
-
type
|
|
73
|
-
'hash algorithm'
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
ttl: parseInt(ttl, 10),
|
|
75
|
+
class: c,
|
|
76
|
+
type: type,
|
|
77
|
+
'hash algorithm': '',
|
|
78
|
+
flags: '',
|
|
79
|
+
iterations: '',
|
|
80
|
+
salt: '',
|
|
77
81
|
'next hashed owner name': '',
|
|
78
|
-
'type bit maps'
|
|
82
|
+
'type bit maps': '',
|
|
79
83
|
})
|
|
80
84
|
}
|
|
81
85
|
|
|
82
86
|
/****** EXPORTERS *******/
|
|
83
|
-
|
|
84
87
|
}
|