diff --git a/CHANGELOG.md b/CHANGELOG.md index be7cb0d..5a8ab0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,17 @@ #### 1.N.N - YYYY-MM-DD +#### 1.0.1 - 2022-04-19 + +- feat(IPSECKEY): added basic support +- doc(README): update for ES module usage +- fix: call is[8|16]BitInt() correctly +- style: replace this.constructor with class name +- test: show more results in test output +- test(CERT): added two test cases +- test(KEY): added valid test + + #### 1.0.0 - 2022-04-18 - style: move rr/index to ./rr diff --git a/README.md b/README.md index 5746f78..3f244f5 100644 --- a/README.md +++ b/README.md @@ -33,28 +33,27 @@ This package is for working with _individual_ Resource Records. For working with Load the index for access to all RR types: ```js -const RR = require('dns-resource-record') +import * as RR from 'dns-resource-record' ``` ### EXAMPLES ```js -const RR = require('dns-resource-record') const exampleRRs = { A: { - owner : 'test.example.com', + owner : 'test.example.com.', type : 'A', address: '192.0.2.127', ttl : 3600, }, AAAA: { - owner : 'test.example.com', + owner : 'test.example.com.', type : 'AAAA', address: '2605:7900:20:a::4', ttl : 3600, }, SOA: { - owner : 'example.com', + owner : 'example.com.', type : 'SOA', mname : 'matt.example.com.', rname : 'ns1.example.com.', @@ -69,7 +68,7 @@ const exampleRRs = { try { console.log(new RR.SOA(exampleRRs.SOA)) SOA(11) [Map] { - 'owner' => 'example.com', + 'owner' => 'example.com.', 'ttl' => 3600, 'class' => 'IN', 'type' => 'SOA', @@ -90,19 +89,18 @@ catch (e) { Validate records by passing a properly formatted JS object to the record-specific class. To validate an A record: ```js -const A = require('dns-resource-record').A -const validatedA = new A(exampleRRs.A) +const validatedA = new RR.A(exampleRRs.A) ``` Manipulate the validated record using pattern named setters: ```js console.log(validatedA.toBind()) -test.example.com 3600 IN A 192.0.2.127 +test.example.com. 3600 IN A 192.0.2.127 validatedA.setAddress('192.0.2.128') console.log(validatedA.toBind()) -test.example.com 3600 IN A 192.0.2.128 +test.example.com. 3600 IN A 192.0.2.128 ``` The setters are named: `set` + `Field`, where field is the resource record field name to modify. Multi-word names are camel cased, so a field named `Certificate Usage` has a setter named `setCertificateUsage`. The RFCs aren't always consistent regarding RR field names so aliases are permissible for interoperability. @@ -112,7 +110,7 @@ The setters are named: `set` + `Field`, where field is the resource record field Get the field names for each RR type with `getFields()`: ```js -> const RR = require('dns-resource-record') +> import * as RR from 'dns-resource-record' > new RR.A(null).getFields() [ 'owner', 'ttl', 'class', 'type', 'address' ] @@ -203,7 +201,7 @@ PRs are welcome, especially PRs with tests. | **DNSKEY** |:white_check_mark:| |:white_check_mark:| | | **DS** |:white_check_mark:| |:white_check_mark:| | | **HINFO** |:white_check_mark:| |:white_check_mark:| | -|**IPSECKEY**| | | | | +|**IPSECKEY**|:white_check_mark:| |:white_check_mark:| | | **KEY** | | | | | | **LOC** |:white_check_mark:|:white_check_mark:|:white_check_mark:|:white_check_mark:| | **MX** |:white_check_mark:|:white_check_mark:|:white_check_mark:|:white_check_mark:| diff --git a/index.js b/index.js index 5395b7e..7f22ea8 100644 --- a/index.js +++ b/index.js @@ -9,6 +9,7 @@ import DNAME from './rr/dname.js' import DNSKEY from './rr/dnskey.js' import DS from './rr/ds.js' import HINFO from './rr/hinfo.js' +import IPSECKEY from './rr/ipseckey.js' import KEY from './rr/key.js' import LOC from './rr/loc.js' import MX from './rr/mx.js' @@ -42,6 +43,7 @@ export { DNSKEY, DS, HINFO, + IPSECKEY, KEY, LOC, MX, diff --git a/package.json b/package.json index b2d9df0..5f1ecf7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dns-resource-record", - "version": "1.0.0", + "version": "1.0.1", "description": "DNS Resource Records", "main": "index.js", "type": "module", diff --git a/rr/aaaa.js b/rr/aaaa.js index 440399e..2469081 100644 --- a/rr/aaaa.js +++ b/rr/aaaa.js @@ -57,7 +57,7 @@ export default class AAAA extends RR { break } - return new this.constructor({ + return new AAAA({ owner : this.fullyQualify(fqdn), ttl : parseInt(ttl, 10), type : 'AAAA', @@ -70,7 +70,7 @@ export default class AAAA extends RR { fromBind (str) { // test.example.com 3600 IN AAAA ... const [ owner, ttl, c, type, ip ] = str.split(/\s+/) - return new this.constructor({ + return new AAAA({ owner, ttl : parseInt(ttl, 10), class : c, diff --git a/rr/caa.js b/rr/caa.js index 67a329e..3777965 100644 --- a/rr/caa.js +++ b/rr/caa.js @@ -84,7 +84,7 @@ export default class CAA extends RR { const tag = unescaped.substring(0, taglen) const fingerprint = unescaped.substring(taglen) - return new this.constructor({ + return new CAA({ owner : this.fullyQualify(fqdn), ttl : parseInt(ttl, 10), type : 'CAA', @@ -102,7 +102,7 @@ export default class CAA extends RR { if (!fields) throw new Error(`unable to parse: ${str}`) const [ owner, ttl, c, type, flags, tag, value ] = fields.slice(1) - return new this.constructor({ + return new CAA({ owner, ttl : parseInt(ttl, 10), class: c, diff --git a/rr/cert.js b/rr/cert.js index 3fb3fb9..30b4749 100644 --- a/rr/cert.js +++ b/rr/cert.js @@ -47,7 +47,7 @@ export default class CERT extends RR { } getRFCs () { - return [ 4398 ] + return [ 2538, 4398 ] } getTypeId () { @@ -58,12 +58,16 @@ export default class CERT extends RR { fromBind (str) { // test.example.com 3600 IN CERT certtype, keytag, algo, cert - const [ owner, ttl, c, type ] = str.split(/\s+/) - return new this.constructor({ + const [ owner, ttl, c, type, certtype, keytag, algo, certificate ] = str.split(/\s+/) + return new CERT({ owner, - ttl : parseInt(ttl, 10), - class: c, + ttl : parseInt(ttl, 10), + class : c, type, + 'cert type': /^[0-9]+$/.test(certtype) ? parseInt(certtype, 10) : certtype, + 'key tag' : parseInt(keytag, 10), + algorithm : parseInt(algo, 10), + certificate, }) } diff --git a/rr/cname.js b/rr/cname.js index edba5da..1d9ecba 100644 --- a/rr/cname.js +++ b/rr/cname.js @@ -46,7 +46,7 @@ export default class CNAME extends RR { // Cfqdn:p:ttl:timestamp:lo const [ fqdn, p, ttl, ts, loc ] = str.substring(1).split(':') - return new this.constructor({ + return new CNAME({ owner : this.fullyQualify(fqdn), ttl : parseInt(ttl, 10), type : 'CNAME', @@ -59,7 +59,7 @@ export default class CNAME extends RR { fromBind (str) { // test.example.com 3600 IN CNAME ... const [ owner, ttl, c, type, cname ] = str.split(/\s+/) - return new this.constructor({ + return new CNAME({ owner, ttl : parseInt(ttl, 10), class: c, diff --git a/rr/dname.js b/rr/dname.js index 7099855..53d3208 100644 --- a/rr/dname.js +++ b/rr/dname.js @@ -44,7 +44,7 @@ export default class DNAME extends RR { const [ fqdn, n, rdata, ttl, ts, loc ] = str.substring(1).split(':') if (n != 39) throw new Error('DNAME fromTinydns, invalid n') - return new this.constructor({ + return new DNAME({ type : 'DNAME', owner : this.fullyQualify(fqdn), target : `${TINYDNS.unpackDomainName(rdata)}.`, @@ -57,7 +57,7 @@ export default class DNAME extends RR { fromBind (str) { // test.example.com 3600 IN DNAME ... const [ owner, ttl, c, type, target ] = str.split(/\s+/) - return new this.constructor({ + return new DNAME({ owner, ttl : parseInt(ttl, 10), class: c, diff --git a/rr/dnskey.js b/rr/dnskey.js index 788f6a4..172ed02 100644 --- a/rr/dnskey.js +++ b/rr/dnskey.js @@ -62,7 +62,7 @@ export default class DNSKEY extends RR { if (!match) throw new Error(`unable to parse DNSKEY: ${str}`) const [ owner, ttl, c, type, flags, protocol, algorithm, publickey ] = match.slice(1) - return new this.constructor({ + return new DNSKEY({ owner, ttl : parseInt(ttl, 10), class : c, diff --git a/rr/ds.js b/rr/ds.js index 3cccaa6..bd5f63d 100644 --- a/rr/ds.js +++ b/rr/ds.js @@ -56,7 +56,7 @@ export default class DS extends RR { fromBind (str) { // test.example.com 3600 IN DS Key Tag Algorithm, Digest Type, Digest const [ owner, ttl, c, type, keytag, algorithm, digesttype ] = str.split(/\s+/) - return new this.constructor({ + return new DS({ owner, ttl : parseInt(ttl, 10), class : c, diff --git a/rr/hinfo.js b/rr/hinfo.js index 8599cdb..9a4d3c5 100644 --- a/rr/hinfo.js +++ b/rr/hinfo.js @@ -44,15 +44,14 @@ export default class HINFO extends RR { if (!match) throw new Error(`unable to parse HINFO: ${str}`) const [ owner, ttl, c, type, cpu, os ] = match.slice(1) - const bits = { + return new HINFO({ owner, ttl : parseInt(ttl, 10), class: c, type, cpu, os, - } - return new this.constructor(bits) + }) } // fromTinydns (str) { diff --git a/rr/ipseckey.js b/rr/ipseckey.js new file mode 100644 index 0000000..c7667fe --- /dev/null +++ b/rr/ipseckey.js @@ -0,0 +1,81 @@ + +import RR from '../rr.js' + +export default class IPSECKEY extends RR { + constructor (opts) { + super(opts) + } + + /****** Resource record specific setters *******/ + setPrecedence (val) { + // an 8-bit precedence for this record. + this.is8bitInt('IPSECKEY', 'precedence', val) + + this.set('precedence', val) + } + + setGatewayType (val) { + // 0 (none), 1 (4-byte IPv4), 2 (16-byte IPv6), 3 (wire encoded domain name) + if (![ 0,1,2,3 ].includes(val)) + throw new Error(`IPSECKEY: Gateway Type is invalid, ${this.citeRFC()}`) + + this.set('gateway type', val) + } + + setAlgorithm (val) { + // unsigned int, 1 octet, values: 1=DSA, 2=RSA + if (![ 1,2 ].includes(val)) + throw new Error(`IPSECKEY: Algorithm invalid, ${this.citeRFC()}`) + + this.set('algorithm', val) + } + + setGateway (val) { + if (this.get('gateway') === 0 && val !== '.') + throw new Error(`IPSECKEY: gateway invalid, ${this.citeRFC()}`) + + this.set('gateway', val) + } + + setPublickey (val) { + if (!val) throw new Error(`IPSECKEY: publickey is required, ${this.citeRFC()}`) + + this.set('publickey', val) + } + + getDescription () { + return 'IPsec Keying' + } + + getRdataFields (arg) { + return [ 'precedence', 'gateway type', 'algorithm', 'gateway', 'publickey' ] + } + + getRFCs () { + return [ 4025 ] + } + + getTypeId () { + return 45 + } + + /****** IMPORTERS *******/ + + fromBind (str) { + // FQDN TTL CLASS IPSECKEY Precedence GatewayType Algorithm Gateway PublicKey + const [ owner, ttl, c, type, prec, gwt, algo, gateway, publickey ] = str.split(/\s+/) + return new IPSECKEY({ + owner, + ttl : parseInt(ttl, 10), + class : c, + type, + precedence : parseInt(prec, 10), + 'gateway type': parseInt(gwt, 10), + algorithm : parseInt(algo, 10), + gateway, + publickey, + }) + } + + /****** EXPORTERS *******/ +} diff --git a/rr/key.js b/rr/key.js index 2789040..2b39306 100644 --- a/rr/key.js +++ b/rr/key.js @@ -9,14 +9,14 @@ export default class KEY extends RR { /****** Resource record specific setters *******/ setFlags (val) { // a 2 octet Flags Field - this.is16bitInt(val) + this.is16bitInt('KEY', 'flags', val) this.set('flags', val) } setProtocol (val) { // 1 octet - this.is8bitInt(val) + this.is8bitInt('KEY', 'protocol', val) this.set('protocol', val) } @@ -45,7 +45,7 @@ export default class KEY extends RR { } getRFCs () { - return [ 2535 ] + return [ 2535, 3445 ] } getTypeId () { @@ -57,7 +57,7 @@ export default class KEY extends RR { fromBind (str) { // test.example.com 3600 IN KEY Flags Protocol Algorithm PublicKey const [ owner, ttl, c, type, flags, protocol, algorithm ] = str.split(/\s+/) - return new this.constructor({ + return new KEY({ owner, ttl : parseInt(ttl, 10), class : c, diff --git a/rr/loc.js b/rr/loc.js index 2d4b956..5b4037b 100644 --- a/rr/loc.js +++ b/rr/loc.js @@ -104,7 +104,7 @@ export default class LOC extends RR { altitude : TINYDNS.octalToUInt32(rdata.substring(48, 64)) - REF.ALTITUDE, } - return new this.constructor({ + return new LOC({ type : 'LOC', owner : this.fullyQualify(fqdn), address : this.toHuman(l), @@ -117,7 +117,7 @@ export default class LOC extends RR { fromBind (str) { const [ owner, ttl, c, type ] = str.split(/\s+/) - return new this.constructor({ + return new LOC({ owner, ttl : parseInt(ttl, 10), class : c, diff --git a/rr/mx.js b/rr/mx.js index 17e6723..7f6d3d1 100644 --- a/rr/mx.js +++ b/rr/mx.js @@ -50,7 +50,7 @@ export default class MX extends RR { // eslint-disable-next-line no-unused-vars const [ owner, ip, x, preference, ttl, ts, loc ] = str.substring(1).split(':') - return new this.constructor({ + return new MX({ type : 'MX', owner : this.fullyQualify(owner), exchange : this.fullyQualify(/\./.test(x) ? x : `${x}.mx.${owner}`), @@ -65,7 +65,7 @@ export default class MX extends RR { // test.example.com 3600 IN MX preference exchange const [ owner, ttl, c, type, preference, exchange ] = str.split(/\s+/) - return new this.constructor({ + return new MX({ owner, ttl : parseInt(ttl, 10), class : c, diff --git a/rr/naptr.js b/rr/naptr.js index 2eb5ab1..91d818a 100644 --- a/rr/naptr.js +++ b/rr/naptr.js @@ -97,7 +97,7 @@ export default class NAPTR extends RR { const replaceLen = TINYDNS.octalToUInt8(rdata.substr(idx, 4)) rec.replacement = TINYDNS.octalToChar(rdata.substr(idx+4, replaceLen)) - return new this.constructor(rec) + return new NAPTR(rec) } fromBind (str) { @@ -118,7 +118,7 @@ export default class NAPTR extends RR { regexp : regexp.trim().replace(/^['"]|['"]/g, ''), replacement: replacement, } - return new this.constructor(bits) + return new NAPTR(bits) } /****** EXPORTERS *******/ diff --git a/rr/ns.js b/rr/ns.js index 784efe8..06cb848 100644 --- a/rr/ns.js +++ b/rr/ns.js @@ -40,7 +40,7 @@ export default class NS extends RR { // eslint-disable-next-line no-unused-vars const [ fqdn, ip, dname, ttl, ts, loc ] = str.substring(1).split(':') - return new this.constructor({ + return new NS({ type : 'NS', owner : this.fullyQualify(fqdn), dname : this.fullyQualify(/\./.test(dname) ? dname : `${dname}.ns.${fqdn}`), @@ -54,7 +54,7 @@ export default class NS extends RR { // test.example.com 3600 IN NS dname const [ owner, ttl, c, type, dname ] = str.split(/\s+/) - return new this.constructor({ + return new NS({ owner, ttl : parseInt(ttl, 10), class: c, diff --git a/rr/nsec.js b/rr/nsec.js index 9c68e77..1d108b9 100644 --- a/rr/nsec.js +++ b/rr/nsec.js @@ -47,7 +47,7 @@ export default class NSEC extends RR { fromBind (str) { // test.example.com 3600 IN NSEC NextDomain TypeBitMaps const [ owner, ttl, c, type, next ] = str.split(/\s+/) - return new this.constructor({ + return new NSEC({ owner, ttl : parseInt(ttl, 10), class : c, diff --git a/rr/nsec3.js b/rr/nsec3.js index 245be26..8ecb16b 100644 --- a/rr/nsec3.js +++ b/rr/nsec3.js @@ -13,7 +13,7 @@ export default class NSEC3 extends RR { // The Hash Algorithm field is represented as an unsigned decimal integer. if (!val) throw new Error(`NSEC3: 'hash algorithm' is required, ${this.citeRFC()}`) - this.is8bitInt(val) + this.is8bitInt('NSEC3', 'hash algorithm', val) this.set('hash algorithm', val) } @@ -22,7 +22,7 @@ export default class NSEC3 extends RR { // The Flags field is represented as an unsigned decimal integer. if (!val) throw new Error(`NSEC3: 'flags' is required, ${this.citeRFC()}`) - this.is8bitInt(val) + this.is8bitInt('NSEC3', 'flags', val) this.set('flags', val) } @@ -31,7 +31,7 @@ export default class NSEC3 extends RR { // The Iterations field is represented as an unsigned decimal integer. 0-65535 if (!val) throw new Error(`NSEC3: 'iterations' is required, ${this.citeRFC()}`) - this.is16bitInt(val) + this.is16bitInt('NSEC3', 'flags', val) this.set('iterations', val) } @@ -80,7 +80,7 @@ export default class NSEC3 extends RR { fromBind (str) { // test.example.com 3600 IN NSEC3 const [ owner, ttl, c, type ] = str.split(/\s+/) - return new this.constructor({ + return new NSEC3({ owner, ttl : parseInt(ttl, 10), class : c, diff --git a/rr/nsec3param.js b/rr/nsec3param.js index daf6f3b..c2a5a4c 100644 --- a/rr/nsec3param.js +++ b/rr/nsec3param.js @@ -13,7 +13,7 @@ export default class NSEC3PARAM extends RR { // The Hash Algorithm field is represented as an unsigned decimal integer. if (!val) throw new Error(`NSEC3PARAM: 'hash algorithm' is required, ${this.citeRFC()}`) - this.is8bitInt(val) + this.is8bitInt('NSEC3PARAM', 'hash algorithm', val) this.set('hash algorithm', val) } @@ -22,7 +22,7 @@ export default class NSEC3PARAM extends RR { // The Flags field is represented as an unsigned decimal integer. if (!val) throw new Error(`NSEC3PARAM: 'flags' is required, ${this.citeRFC()}`) - this.is8bitInt(val) + this.is8bitInt('NSEC3PARAM', 'flags', val) this.set('flags', val) } @@ -31,7 +31,7 @@ export default class NSEC3PARAM extends RR { // The Iterations field is represented as an unsigned decimal integer. 0-65535 if (!val) throw new Error(`NSEC3PARAM: 'iterations' is required, ${this.citeRFC()}`) - this.is16bitInt(val) + this.is16bitInt('NSEC3PARAM', 'iterations', val) this.set('iterations', val) } @@ -65,7 +65,7 @@ export default class NSEC3PARAM extends RR { fromBind (str) { // test.example.com 3600 IN NSEC3PARAM const [ owner, ttl, c, type ] = str.split(/\s+/) - return new this.constructor({ + return new NSEC3PARAM({ owner, ttl : parseInt(ttl, 10), class : c, diff --git a/rr/openpgpkey.js b/rr/openpgpkey.js index b6aa6c0..f3be0ea 100644 --- a/rr/openpgpkey.js +++ b/rr/openpgpkey.js @@ -31,7 +31,7 @@ export default class OPENPGPKEY extends RR { fromBind (str) { // test.example.com 3600 IN OPENPGPKEY const [ owner, ttl, c, type, privatekey ] = str.split(/\s+/) - return new this.constructor({ + return new OPENPGPKEY({ owner, ttl : parseInt(ttl, 10), class : c, diff --git a/rr/ptr.js b/rr/ptr.js index 99b4ed8..bf43f0f 100644 --- a/rr/ptr.js +++ b/rr/ptr.js @@ -36,7 +36,7 @@ export default class PTR extends RR { // ^fqdn:p:ttl:timestamp:lo const [ fqdn, p, ttl, ts, loc ] = str.substring(1).split(':') - return new this.constructor({ + return new PTR({ owner : this.fullyQualify(fqdn), ttl : parseInt(ttl, 10), type : 'PTR', @@ -49,7 +49,7 @@ export default class PTR extends RR { fromBind (str) { // test.example.com 3600 IN PTR dname const [ owner, ttl, c, type, dname ] = str.split(/\s+/) - return new this.constructor({ + return new PTR({ owner, ttl : parseInt(ttl, 10), class: c, diff --git a/rr/rrsig.js b/rr/rrsig.js index a4fd616..a3955d9 100644 --- a/rr/rrsig.js +++ b/rr/rrsig.js @@ -88,7 +88,7 @@ export default class RRSIG extends RR { // fromBind (str) { // // test.example.com 3600 IN RRSIG ... // const [ owner, ttl, c, type ] = str.split(/\s+/) - // return new this.constructor({ + // return new RRSIG({ // owner, // ttl : parseInt(ttl, 10), // class : c, diff --git a/rr/sig.js b/rr/sig.js index 703663d..ef05d2e 100644 --- a/rr/sig.js +++ b/rr/sig.js @@ -87,7 +87,7 @@ export default class SIG extends RR { // fromBind (str) { // // test.example.com 3600 IN SIG ... // const [ owner, ttl, c, type ] = str.split(/\s+/) - // return new this.constructor({ + // return new SIG({ // owner, // ttl : parseInt(ttl, 10), // class : c, diff --git a/rr/smimea.js b/rr/smimea.js index c9c7582..d774e5f 100644 --- a/rr/smimea.js +++ b/rr/smimea.js @@ -58,7 +58,7 @@ export default class SMIMEA extends RR { fromBind (str) { // test.example.com 3600 IN SMIMEA, usage, selector, match, data const [ owner, ttl, c, type, usage, selector, match ] = str.split(/\s+/) - return new this.constructor({ + return new SMIMEA({ owner, ttl : parseInt(ttl, 10), class : c, diff --git a/rr/soa.js b/rr/soa.js index 89dbf8a..fbe9067 100644 --- a/rr/soa.js +++ b/rr/soa.js @@ -89,7 +89,7 @@ export default class SOA extends RR { // example.com TTL IN SOA mname rname serial refresh retry expire minimum const [ owner, ttl, c, type, mname, rname, serial, refresh, retry, expire, minimum ] = str.split(/[\s+]/) - const bits = { + return new SOA({ owner, ttl : parseInt(ttl) || parseInt(minimum), class : c, @@ -101,16 +101,14 @@ export default class SOA extends RR { retry : parseInt(retry , 10), expire : parseInt(expire , 10), minimum: parseInt(minimum, 10), - } - // console.log(bits) - return new this.constructor(bits) + }) } fromTinydns (str) { // Zfqdn:mname:rname:ser:ref:ret:exp:min:ttl:time:lo const [ fqdn, mname, rname, ser, ref, ret, exp, min, ttl, ts, loc ] = str.substring(1).split(':') - return new this.constructor({ + return new SOA({ owner : this.fullyQualify(fqdn), ttl : parseInt(ttl, 10), type : 'SOA', diff --git a/rr/spf.js b/rr/spf.js index 33d33b9..b7de9ac 100644 --- a/rr/spf.js +++ b/rr/spf.js @@ -36,7 +36,7 @@ export default class SPF extends TXT { const [ fqdn, n, rdata, ttl, ts, loc ] = str.substring(1).split(':') if (n != 99) throw new Error('SPF fromTinydns, invalid n') - return new this.constructor({ + return new SPF({ type : 'SPF', owner : this.fullyQualify(fqdn), data : TINYDNS.octalToChar(rdata), diff --git a/rr/srv.js b/rr/srv.js index e67179b..e12f234 100644 --- a/rr/srv.js +++ b/rr/srv.js @@ -76,7 +76,7 @@ export default class SRV extends RR { addr = TINYDNS.unpackDomainName(rdata.substring(24)) } - return new this.constructor({ + return new SRV({ owner : this.fullyQualify(fqdn), ttl : parseInt(ttl, 10), type : 'SRV', @@ -92,7 +92,7 @@ export default class SRV extends RR { fromBind (str) { // test.example.com 3600 IN SRV Priority Weight Port Target const [ owner, ttl, c, type, pri, weight, port, target ] = str.split(/\s+/) - return new this.constructor({ + return new SRV({ owner : owner, ttl : parseInt(ttl, 10), class : c, diff --git a/rr/sshfp.js b/rr/sshfp.js index 28178b4..e3ca61c 100644 --- a/rr/sshfp.js +++ b/rr/sshfp.js @@ -53,7 +53,7 @@ export default class SSHFP extends RR { const fingerprint = TINYDNS.octalToHex(rdata.substring(16)) - return new this.constructor({ + return new SSHFP({ owner : this.fullyQualify(fqdn), ttl : parseInt(ttl, 10), type : 'SSHFP', @@ -68,7 +68,7 @@ export default class SSHFP extends RR { fromBind (str) { // test.example.com 3600 IN SSHFP algo fptype fp const [ owner, ttl, c, type, algo, fptype, fp ] = str.split(/\s+/) - return new this.constructor({ + return new SSHFP({ owner, ttl : parseInt(ttl, 10), class : c, diff --git a/rr/tlsa.js b/rr/tlsa.js index 98cc874..c48c8be 100644 --- a/rr/tlsa.js +++ b/rr/tlsa.js @@ -59,7 +59,7 @@ export default class TLSA extends RR { const match = str.split(/^([^\s]+)\s+([0-9]+)\s+(\w+)\s+(\w+)\s+([0-9]+)\s+([0-9]+)\s+([0-9]+)\s+(.*?)\s*$/) if (!match) throw new Error(`unable to parse TLSA: ${str}`) const [ owner, ttl, c, type, usage, selector, matchtype, cad ] = match.slice(1) - return new this.constructor({ + return new TLSA({ owner : this.fullyQualify(owner), ttl : parseInt(ttl, 10), class : c, diff --git a/rr/uri.js b/rr/uri.js index 6411921..aa06f5b 100644 --- a/rr/uri.js +++ b/rr/uri.js @@ -32,7 +32,7 @@ export default class URI extends RR { const [ fqdn, n, rdata, ttl, ts, loc ] = str.substring(1).split(':') if (n != 256) throw new Error('URI fromTinydns, invalid n') - return new this.constructor({ + return new URI({ type : 'URI', owner : this.fullyQualify(fqdn), priority : TINYDNS.octalToUInt16(rdata.substring(0, 8)), @@ -47,7 +47,7 @@ export default class URI extends RR { fromBind (str) { // test.example.com 3600 IN URI priority, weight, target const [ owner, ttl, c, type, priority, weight, target ] = str.split(/\s+/) - return new this.constructor({ + return new URI({ class : c, type : type, owner, diff --git a/test/base.js b/test/base.js index cc19034..e7203aa 100644 --- a/test/base.js +++ b/test/base.js @@ -71,9 +71,10 @@ export function getDescription (type) { export function getRFCs (type, valid) { describe('getRFCs', function () { - it(`can retrieve RFCs`, async function () { - const r = new type(null) - assert.ok(r.getRFCs().length) + const r = new type(null) + const rfcs = r.getRFCs() + it(`can retrieve RFCs: ${rfcs.join(',')}`, async function () { + assert.ok(rfcs.length) }) }) } @@ -107,8 +108,8 @@ export function fromBind (type, validRecords) { export function getRdataFields (type, rdataFields) { describe('getRdataFields', function () { - it(`can retrieve record fields`, async function () { - const r = new type(null) + const r = new type(null) + it(`can retrieve rdata fields: (${r.getRdataFields('rdata')})`, async function () { assert.deepEqual(r.getRdataFields('rdata'), rdataFields) }) }) @@ -116,8 +117,8 @@ export function getRdataFields (type, rdataFields) { export function getFields (type, rdataFields) { describe('getFields', function () { + const r = new type(null) it(`can retrieve record fields`, async function () { - const r = new type(null) assert.deepEqual(r.getFields('rdata'), rdataFields) assert.deepEqual(r.getFields(), r.getFields('common').concat(rdataFields)) }) @@ -126,8 +127,8 @@ export function getFields (type, rdataFields) { export function getTypeId (type, val) { describe('getTypeId', function () { - it(`can retrieve record type ID`, async function () { - const r = new type(null) + const r = new type(null) + it(`can retrieve record type ID (${r.getTypeId()})`, async function () { assert.deepEqual(r.getTypeId(), val) }) }) diff --git a/test/cert.js b/test/cert.js index 317ce87..f7cae58 100644 --- a/test/cert.js +++ b/test/cert.js @@ -4,14 +4,28 @@ import * as base from './base.js' import CERT from '../rr/cert.js' const validRecords = [ - // { - // owner : 'mail.example.com.', - // ttl : 86400, - // class : 'IN', - // type : 'CERT', - // testB : '', - // testT : '', - // }, + { + owner : 'mail.example.com.', + ttl : 86400, + class : 'IN', + type : 'CERT', + 'cert type' : 'PGP', + 'key tag' : 0, + 'algorithm' : 0, + 'certificate': 'hexidecimalkeystring1', + testB : 'mail.example.com.\t86400\tIN\tCERT\tPGP\t0\t0\thexidecimalkeystring1\n', + }, + { + owner : 'smith.example.com.', + ttl : 86400, + class : 'IN', + type : 'CERT', + 'cert type' : 'PGP', + 'key tag' : 0, + 'algorithm' : 0, + 'certificate': 'hexidecimalkeystring2', + testB : 'smith.example.com.\t86400\tIN\tCERT\tPGP\t0\t0\thexidecimalkeystring2\n', + }, ] const invalidRecords = [ @@ -27,8 +41,8 @@ describe('CERT record', function () { base.getTypeId(CERT, 37) base.toBind(CERT, validRecords) - base.toTinydns(CERT, validRecords) + // base.toTinydns(CERT, validRecords) base.fromBind(CERT, validRecords) - base.fromTinydns(CERT, validRecords) + // base.fromTinydns(CERT, validRecords) }) diff --git a/test/ipseckey.js b/test/ipseckey.js new file mode 100644 index 0000000..83177bf --- /dev/null +++ b/test/ipseckey.js @@ -0,0 +1,79 @@ + +import * as base from './base.js' + +import IPSECKEY from '../rr/ipseckey.js' + +const common = { ttl: 7200, class: 'IN', type: 'IPSECKEY' } + +const validRecords = [ + { + ...common, + owner : '38.2.0.192.in-addr.arpa.', + precedence : 10, + 'gateway type': 1, + algorithm : 2, + gateway : '192.0.2.38', + publickey : 'AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==', + testB : '38.2.0.192.in-addr.arpa.\t7200\tIN\tIPSECKEY\t10\t1\t2\t192.0.2.38\tAQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==\n', + }, + { + ...common, + owner : '38.2.0.192.in-addr.arpa.', + precedence : 10, + 'gateway type': 0, + algorithm : 2, + gateway : '.', + publickey : 'AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==', + testB : '38.2.0.192.in-addr.arpa.\t7200\tIN\tIPSECKEY\t10\t0\t2\t.\tAQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==\n', + }, + { + ...common, + owner : '38.2.0.192.in-addr.arpa.', + precedence : 10, + 'gateway type': 1, + algorithm : 2, + gateway : '192.0.2.3', + publickey : 'AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==', + testB : '38.2.0.192.in-addr.arpa.\t7200\tIN\tIPSECKEY\t10\t1\t2\t192.0.2.3\tAQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==\n', + }, + { + ...common, + owner : '38.1.0.192.in-addr.arpa.', + precedence : 10, + 'gateway type': 3, + algorithm : 2, + gateway : 'mygateway.example.com.', + publickey : 'AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==', + testB : '38.1.0.192.in-addr.arpa.\t7200\tIN\tIPSECKEY\t10\t3\t2\tmygateway.example.com.\tAQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==\n', + }, + { + ...common, + owner : '0.d.4.0.3.0.e.f.f.f.3.f.0.1.2.0.1.0.0.0.0.0.2.8.b.d.0.1.0.0.2.ip6.arpa.', + precedence : 10, + 'gateway type': 2, + algorithm : 2, + gateway : '2001:0db8:0:8002::2000:1', + publickey : 'AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==', + testB : '0.d.4.0.3.0.e.f.f.f.3.f.0.1.2.0.1.0.0.0.0.0.2.8.b.d.0.1.0.0.2.ip6.arpa.\t7200\tIN\tIPSECKEY\t10\t2\t2\t2001:0db8:0:8002::2000:1\tAQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==\n', + }, +] + +const invalidRecords = [ +] + +describe('IPSECKEY record', function () { + base.valid(IPSECKEY, validRecords) + base.invalid(IPSECKEY, invalidRecords, { ttl: 3600 }) + + base.getDescription(IPSECKEY) + base.getRFCs(IPSECKEY, validRecords[0]) + base.getRdataFields(IPSECKEY, [ 'precedence', 'gateway type', 'algorithm', 'gateway', 'publickey' ]) + base.getFields(IPSECKEY, [ 'precedence', 'gateway type', 'algorithm', 'gateway', 'publickey' ]) + base.getTypeId(IPSECKEY, 45) + + base.toBind(IPSECKEY, validRecords) + // base.toTinydns(IPSECKEY, validRecords) + + base.fromBind(IPSECKEY, validRecords) + // base.fromTinydns(IPSECKEY, validRecords) +}) diff --git a/test/key.js b/test/key.js index 1dd6de7..8e657f5 100644 --- a/test/key.js +++ b/test/key.js @@ -4,18 +4,17 @@ import * as base from './base.js' import KEY from '../rr/key.js' const validRecords = [ - // { - // owner : 'example.com.', - // ttl : 3600, - // class : 'IN', - // type : 'KEY', - // flags : 256, - // protocol : 3, - // algorithm: 5, - // publickey: `( AQPSKmynfzW4kyBv015MUG2DeIQ3 Cbl+BBZH4b/0PY1kxkmvHjcZc8no kfzj31GajIQKY+5CptLr3buXA10h WqTkF7H6RfoRqXQeogmMHfpftf6z Mv1LyBUgia7za6ZEzOJBOztyvhjL 742iU/TpPSEDhm2SNKLijfUppn1U aNvv4w== )`, - // testB : '', - // // testT : '', - // }, + { + owner : 'example.com.', + ttl : 3600, + class : 'IN', + type : 'KEY', + flags : 256, + protocol : 3, + algorithm: 5, + publickey: `( AQPSKmynfzW4kyBv015MUG2DeIQ3 Cbl+BBZH4b/0PY1kxkmvHjcZc8no kfzj31GajIQKY+5CptLr3buXA10h WqTkF7H6RfoRqXQeogmMHfpftf6z Mv1LyBUgia7za6ZEzOJBOztyvhjL 742iU/TpPSEDhm2SNKLijfUppn1U aNvv4w== )`, + testB : 'example.com.\t3600\tIN\tKEY\t256\t3\t5\t( AQPSKmynfzW4kyBv015MUG2DeIQ3 Cbl+BBZH4b/0PY1kxkmvHjcZc8no kfzj31GajIQKY+5CptLr3buXA10h WqTkF7H6RfoRqXQeogmMHfpftf6z Mv1LyBUgia7za6ZEzOJBOztyvhjL 742iU/TpPSEDhm2SNKLijfUppn1U aNvv4w== )\n', + }, ] const invalidRecords = [