@nictool/dns-resource-record 1.1.5 → 1.1.7
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 +6 -1
- package/README.md +14 -18
- package/package.json +11 -6
- package/rr/nsec3.js +51 -10
- package/rr/sshfp.js +2 -2
- package/rr.js +5 -2
- package/test/a.js +2 -2
- package/test/nsec3.js +17 -3
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,11 @@ Notable changes to this project are documented in this file.
|
|
|
6
6
|
#### Unreleased
|
|
7
7
|
|
|
8
8
|
|
|
9
|
+
### [1.1.6] - 2022-06-21
|
|
10
|
+
|
|
11
|
+
- doc(sshfp): added RFC 7479, 8709
|
|
12
|
+
|
|
13
|
+
|
|
9
14
|
### [1.1.5] - 2022-06-03
|
|
10
15
|
|
|
11
16
|
- ci: auto-populate node LTS versions to run CI tests with
|
|
@@ -305,5 +310,5 @@ Notable changes to this project are documented in this file.
|
|
|
305
310
|
[0.2.1]: https://github.com/NicTool/dns-resource-record/releases/tag/0.2.1
|
|
306
311
|
[0.2.0]: https://github.com/NicTool/dns-resource-record/releases/tag/0.2.0
|
|
307
312
|
[1.1.4]: https://github.com/NicTool/dns-resource-record/releases/tag/1.1.4
|
|
308
|
-
|
|
309
313
|
[1.1.5]: https://github.com/NicTool/dns-resource-record/releases/tag/1.1.5
|
|
314
|
+
[1.1.6]: https://github.com/NicTool/dns-resource-record/releases/tag/1.1.6
|
package/README.md
CHANGED
|
@@ -5,28 +5,24 @@
|
|
|
5
5
|
|
|
6
6
|
DNS resource record parser, validator, importer, and exporter.
|
|
7
7
|
|
|
8
|
-
|
|
9
8
|
## SYNOPSIS
|
|
10
9
|
|
|
11
10
|
This module is used to:
|
|
12
11
|
|
|
13
12
|
- validate well formedness and RFC compliance of DNS resource records
|
|
14
|
-
- import RRs from:
|
|
15
|
-
- JS object
|
|
16
|
-
- JSON
|
|
17
|
-
- [BIND](https://www.isc.org/bind/) zone [file format](https://bind9.readthedocs.io/en/latest/reference.html#zone-file)
|
|
18
|
-
- tinydns [data format](https://cr.yp.to/djbdns/tinydns-data.html)
|
|
19
|
-
- export RRs to:
|
|
20
|
-
- BIND zone files
|
|
21
|
-
- tinydns data
|
|
22
|
-
- maradns
|
|
23
|
-
- JS object
|
|
24
|
-
- JSON
|
|
25
|
-
|
|
26
|
-
This package intends to import and export RFC compliant DNS resource records. Please [raise an issue](https://github.com/NicTool/dns-resource-record/issues) if you cannot pass a valid resource record or you can pass an invalid resource record.
|
|
13
|
+
- import RRs from and from the following formats:
|
|
27
14
|
|
|
28
|
-
|
|
15
|
+
| **RR format** | **import** | **export** |
|
|
16
|
+
| :------------------------------------------------------: | :----------------: | :----------------: |
|
|
17
|
+
| **JSON** | :white_check_mark: | :white_check_mark: |
|
|
18
|
+
| **[BIND](https://www.isc.org/bind/)** | :white_check_mark: | :white_check_mark: |
|
|
19
|
+
| **[Tinydns](https://cr.yp.to/djbdns/tinydns-data.html)** | :white_check_mark: | :white_check_mark: |
|
|
20
|
+
| **MaraDNS** | | :white_check_mark: |
|
|
21
|
+
| **JS** | :white_check_mark: | :white_check_mark: |
|
|
29
22
|
|
|
23
|
+
This package intends to import and export RFC compliant DNS resource records. Please [raise an issue](https://github.com/NicTool/dns-resource-record/issues) if you a valid resource record fails to pass or an invalid resource record passes.
|
|
24
|
+
|
|
25
|
+
This package is for working with _individual_ Resource Records. For working with zones of RRs, use [dns-zone](https://github.com/NicTool/dns-zone).
|
|
30
26
|
|
|
31
27
|
## USAGE
|
|
32
28
|
|
|
@@ -195,7 +191,7 @@ PRs are welcome, especially PRs with tests.
|
|
|
195
191
|
| **A** |:white_check_mark:|:white_check_mark:|:white_check_mark:|:white_check_mark:|
|
|
196
192
|
| **AAAA** |:white_check_mark:|:white_check_mark:|:white_check_mark:|:white_check_mark:|
|
|
197
193
|
| **CAA** |:white_check_mark:|:white_check_mark:|:white_check_mark:|:white_check_mark:|
|
|
198
|
-
| **CERT**
|
|
194
|
+
| **CERT** |:white_check_mark:| |:white_check_mark:| |
|
|
199
195
|
| **CNAME** |:white_check_mark:|:white_check_mark:|:white_check_mark:|:white_check_mark:|
|
|
200
196
|
| **DNAME** |:white_check_mark:|:white_check_mark:|:white_check_mark:|:white_check_mark:|
|
|
201
197
|
| **DNSKEY** |:white_check_mark:|:white_check_mark:|:white_check_mark:|:white_check_mark:|
|
|
@@ -207,8 +203,8 @@ PRs are welcome, especially PRs with tests.
|
|
|
207
203
|
| **MX** |:white_check_mark:|:white_check_mark:|:white_check_mark:|:white_check_mark:|
|
|
208
204
|
| **NAPTR** |:white_check_mark:|:white_check_mark:|:white_check_mark:|:white_check_mark:|
|
|
209
205
|
| **NS** |:white_check_mark:|:white_check_mark:|:white_check_mark:|:white_check_mark:|
|
|
210
|
-
| **NSEC**
|
|
211
|
-
| **NSEC3**
|
|
206
|
+
| **NSEC** |:white_check_mark:| |:white_check_mark:| |
|
|
207
|
+
| **NSEC3** |:white_check_mark:|:white_check_mark:|:white_check_mark:| |
|
|
212
208
|
| **NSEC3PARAM**| | | | |
|
|
213
209
|
| **OPENPGPKEY**| | | | |
|
|
214
210
|
| **PTR** |:white_check_mark:|:white_check_mark:|:white_check_mark:|:white_check_mark:|
|
package/package.json
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nictool/dns-resource-record",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.7",
|
|
4
4
|
"description": "DNS Resource Records",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"
|
|
9
|
-
"
|
|
8
|
+
"format:check": "npm run prettier; npm run lint",
|
|
9
|
+
"format": "npm run prettier -- --write && npm run lint --fix",
|
|
10
|
+
"lint": "npx eslint **/*.js",
|
|
11
|
+
"lint:fix": "npm run lint -- --fix",
|
|
12
|
+
"prettier": "npx prettier --ignore-path .gitignore --check .",
|
|
13
|
+
"prettier:fix": "npx prettier --ignore-path .gitignore --write .",
|
|
10
14
|
"test": "npx mocha",
|
|
11
|
-
"versions": "npx dependency-version-checker check"
|
|
15
|
+
"versions": "npx dependency-version-checker check",
|
|
16
|
+
"watch": "npm run test -- --watch"
|
|
12
17
|
},
|
|
13
18
|
"repository": {
|
|
14
19
|
"type": "git",
|
|
@@ -34,7 +39,7 @@
|
|
|
34
39
|
},
|
|
35
40
|
"homepage": "https://github.com/NicTool/dns-resource-record#readme",
|
|
36
41
|
"devDependencies": {
|
|
37
|
-
"eslint": "^8.
|
|
38
|
-
"mocha": "^
|
|
42
|
+
"eslint": "^8.56.0",
|
|
43
|
+
"mocha": "^10.3.0"
|
|
39
44
|
}
|
|
40
45
|
}
|
package/rr/nsec3.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
import RR from '../rr.js'
|
|
3
3
|
|
|
4
|
+
import * as TINYDNS from '../lib/tinydns.js'
|
|
5
|
+
|
|
4
6
|
export default class NSEC3 extends RR {
|
|
5
7
|
constructor (opts) {
|
|
6
8
|
super(opts)
|
|
@@ -8,7 +10,7 @@ export default class NSEC3 extends RR {
|
|
|
8
10
|
}
|
|
9
11
|
|
|
10
12
|
/****** Resource record specific setters *******/
|
|
11
|
-
|
|
13
|
+
setHashAlgorithm (val) {
|
|
12
14
|
// Hash Algorithm is a single octet.
|
|
13
15
|
// The Hash Algorithm field is represented as an unsigned decimal integer.
|
|
14
16
|
if (!val) throw new Error(`NSEC3: 'hash algorithm' is required, ${this.citeRFC()}`)
|
|
@@ -77,23 +79,62 @@ export default class NSEC3 extends RR {
|
|
|
77
79
|
|
|
78
80
|
/****** IMPORTERS *******/
|
|
79
81
|
|
|
80
|
-
fromBind (
|
|
81
|
-
// test.example.com
|
|
82
|
-
const [ owner, ttl, c, type ] =
|
|
82
|
+
fromBind (opts) {
|
|
83
|
+
// test.example.com. 3600 IN NSEC3 1 1 12 aabbccdd (2vptu5timamqttgl4luu9kg21e0aor3s A RRSIG)
|
|
84
|
+
const [ owner, ttl, c, type, ha, flags, iterations, salt ] = opts.bindline.split(/\s+/)
|
|
85
|
+
const rdata = opts.bindline.split(/\(|\)/)[1]
|
|
86
|
+
|
|
83
87
|
return new NSEC3({
|
|
84
88
|
owner,
|
|
85
89
|
ttl : parseInt(ttl, 10),
|
|
86
90
|
class : c,
|
|
87
91
|
type : type,
|
|
88
|
-
'hash algorithm' :
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
'next hashed owner name':
|
|
93
|
-
'type bit maps' : '',
|
|
92
|
+
'hash algorithm' : parseInt(ha, 10),
|
|
93
|
+
flags : parseInt(flags, 10),
|
|
94
|
+
iterations : parseInt(iterations, 10),
|
|
95
|
+
salt,
|
|
96
|
+
'next hashed owner name': rdata.split(/\s+/)[0],
|
|
97
|
+
'type bit maps' : rdata.split(/\s+/).slice(1).join('\t'),
|
|
98
|
+
})
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
fromTinydns (opts) {
|
|
102
|
+
const [ fqdn, n, rdata, ttl, ts, loc ] = opts.tinyline.substring(1).split(':')
|
|
103
|
+
if (n != 50) throw new Error('NSEC3 fromTinydns, invalid n')
|
|
104
|
+
|
|
105
|
+
const bytes = Buffer.from(TINYDNS.octalToChar(rdata), 'binary')
|
|
106
|
+
|
|
107
|
+
return new NSEC3({
|
|
108
|
+
owner : this.fullyQualify(fqdn),
|
|
109
|
+
ttl : parseInt(ttl, 10),
|
|
110
|
+
type : 'NSEC3',
|
|
111
|
+
'hash algorithm': bytes.readUInt8(0),
|
|
112
|
+
flags : bytes.readUInt8(1),
|
|
113
|
+
iterations : bytes.readUInt16BE(2),
|
|
114
|
+
// salt : ,
|
|
115
|
+
// 'next hashed owner name': ,
|
|
116
|
+
// 'type bit maps' : ,
|
|
117
|
+
timestamp : ts,
|
|
118
|
+
location : loc !== '' && loc !== '\n' ? loc : '',
|
|
94
119
|
})
|
|
95
120
|
}
|
|
96
121
|
|
|
97
122
|
/****** EXPORTERS *******/
|
|
98
123
|
|
|
124
|
+
toBind (zone_opts) {
|
|
125
|
+
return `${this.getFQDN('owner', zone_opts)}\t${this.get('ttl')}\t${this.get('class')}\tNSEC3${this.getRdataFields().slice(0,4).map(f => '\t' + this.get(f)).join('')}\t(${this.getRdataFields().slice(4).map(f => this.get(f)).join('\t')})\n`
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
toTinydns () {
|
|
129
|
+
const dataRe = new RegExp(/[\r\n\t:\\/]/, 'g')
|
|
130
|
+
|
|
131
|
+
return this.getTinydnsGeneric(
|
|
132
|
+
TINYDNS.UInt8toOctal(this.get('hash algorithm')) +
|
|
133
|
+
TINYDNS.UInt8toOctal(this.get('flags')) +
|
|
134
|
+
TINYDNS.UInt16toOctal(this.get('iterations')) +
|
|
135
|
+
TINYDNS.escapeOctal(dataRe, this.get('salt')) +
|
|
136
|
+
TINYDNS.escapeOctal(dataRe, this.get('next hashed owner name')) +
|
|
137
|
+
TINYDNS.escapeOctal(dataRe, this.get('type bit maps'))
|
|
138
|
+
)
|
|
139
|
+
}
|
|
99
140
|
}
|
package/rr/sshfp.js
CHANGED
|
@@ -9,7 +9,7 @@ export default class SSHFP extends RR {
|
|
|
9
9
|
|
|
10
10
|
/****** Resource record specific setters *******/
|
|
11
11
|
setAlgorithm (val) {
|
|
12
|
-
// 0: reserved
|
|
12
|
+
// 0: reserved 1: RSA 2: DSA 3: ECDSA 4: Ed25519 6: Ed448
|
|
13
13
|
this.is8bitInt('SSHFP', 'algorithm', val)
|
|
14
14
|
|
|
15
15
|
this.set('algorithm', val)
|
|
@@ -35,7 +35,7 @@ export default class SSHFP extends RR {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
getRFCs () {
|
|
38
|
-
return [ 4255 ]
|
|
38
|
+
return [ 4255, 7479, 8709 ]
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
getTypeId () {
|
package/rr.js
CHANGED
|
@@ -104,8 +104,11 @@ export default class RR extends Map {
|
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
setType (t) {
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
switch (t) {
|
|
108
|
+
case '':
|
|
109
|
+
case undefined:
|
|
110
|
+
throw new Error(`type is required`)
|
|
111
|
+
}
|
|
109
112
|
|
|
110
113
|
if (t.toUpperCase() !== this.constructor.name)
|
|
111
114
|
throw new Error(`type ${t} doesn't match ${this.constructor.name}`)
|
package/test/a.js
CHANGED
|
@@ -44,8 +44,8 @@ const invalidRecords = [
|
|
|
44
44
|
{ ...defaults, address: undefined, msg: /address is required/ },
|
|
45
45
|
{ ...defaults, address: '1.x.2.3', msg: /address must be IPv4/ },
|
|
46
46
|
{ ...defaults, address: '.1.2.3', msg: /address must be IPv4/ },
|
|
47
|
-
{ ...defaults, type: '', msg: /
|
|
48
|
-
{ ...defaults, type: undefined, msg: /type
|
|
47
|
+
{ ...defaults, type: '', msg: /type is required/ },
|
|
48
|
+
{ ...defaults, type: undefined, msg: /type is required/ },
|
|
49
49
|
{ ...defaults, ttl: '', msg: /TTL must be numeric/ },
|
|
50
50
|
{ ...defaults, ttl: -299, msg: /TTL must be a 32-bit integer/ },
|
|
51
51
|
{ ...defaults, ttl: 2147483648, msg: /TTL must be a 32-bit integer/ },
|
package/test/nsec3.js
CHANGED
|
@@ -3,7 +3,21 @@ import * as base from './base.js'
|
|
|
3
3
|
|
|
4
4
|
import NSEC3 from '../rr/nsec3.js'
|
|
5
5
|
|
|
6
|
+
const defaults = { class: 'IN', ttl: 3600, type: 'NSEC3' }
|
|
7
|
+
|
|
6
8
|
const validRecords = [
|
|
9
|
+
{
|
|
10
|
+
...defaults,
|
|
11
|
+
owner : 'test.example.com.',
|
|
12
|
+
'hash algorithm' : 1,
|
|
13
|
+
flags : 1,
|
|
14
|
+
iterations : 12,
|
|
15
|
+
salt : 'aabbccdd',
|
|
16
|
+
'type bit maps' : 'A\tRRSIG',
|
|
17
|
+
'next hashed owner name': '2vptu5timamqttgl4luu9kg21e0aor3s',
|
|
18
|
+
testB : 'test.example.com.\t3600\tIN\tNSEC3\t1\t1\t12\taabbccdd\t(2vptu5timamqttgl4luu9kg21e0aor3s\tA\tRRSIG)\n',
|
|
19
|
+
testT : ':test.example.com:50:\\001\\001\\000\\014aabbccdd2vptu5timamqttgl4luu9kg21e0aor3sA\\011RRSIG:3600::\n',
|
|
20
|
+
},
|
|
7
21
|
]
|
|
8
22
|
|
|
9
23
|
const invalidRecords = [
|
|
@@ -18,9 +32,9 @@ describe('NSEC3 record', function () {
|
|
|
18
32
|
base.getFields(NSEC3, [ 'hash algorithm', 'flags', 'iterations', 'salt', 'next hashed owner name', 'type bit maps' ])
|
|
19
33
|
base.getTypeId(NSEC3, 50)
|
|
20
34
|
|
|
21
|
-
|
|
22
|
-
|
|
35
|
+
base.toBind(NSEC3, validRecords)
|
|
36
|
+
base.toTinydns(NSEC3, validRecords)
|
|
23
37
|
|
|
24
|
-
|
|
38
|
+
base.fromBind(NSEC3, validRecords)
|
|
25
39
|
// base.fromTinydns(NSEC3, validRecords)
|
|
26
40
|
})
|