UNPKG

ts-zone-file

Version:

This module is designed for manaing a BIND name server.

121 lines (120 loc) 6.12 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const reduce = { zone: 'zones', key: 'keys' }; const MDEND = /^\}/; const strTST = /(?<=\s+|^)(directory|pid-file|secret|key-directory|file)/; const booleanTST = /(?<=\s+|^)(recursion|dnssec-enable|dnssec-validation|inline-signing|notify)/; const arryCONFTST = /(also-notify|listen-on|allow-transfer|allow-recursion)\s/; const mdTST = /(key|zone)\s\"(\S+)\"\s/; const incTST = /include/; // Key Tests const keyCONFTST = /(algorithm)/; exports.parseBINDConfig = async (config) => { // Async Interface for line by line processing const rl = config.split('\n'); let mode; let subMode = undefined; let subOpt = undefined; let subObj; let configObj = { options: {} }; for (const line of rl) { // Mode setters // Options Block if (/options\s{/.test(line)) mode = 'options'; // Controls Block if (/controls\s{/.test(line)) mode = 'controls'; if (incTST.test(line)) configObj.include ? configObj.include.push(/(?<=")(.*)(?=")/.exec(line)[0]) : configObj.include = [/(?<=")(.*)(?=")/.exec(line)[0]]; // Zone/Key Mode Detector if (mdTST.test(line)) { const { modeName, name } = /(?<modeName>key|zone)\s\"(?<name>\S+)\"\s/.exec(line).groups; mode = reduce[modeName]; if (mode === 'keys' && !configObj[mode]) configObj[mode] = [{ name, algorithm: undefined, secret: '' }]; else if (mode === 'keys' && configObj[mode]) configObj[mode].push({ name, algorithm: 'hmac-md5', secret: '' }); if (mode === 'zones' && !configObj[mode]) configObj[mode] = [{ name, file: '', type: 'slave' }]; else if (mode == 'zones' && configObj[mode]) configObj[mode].push({ name, file: '', type: 'master' }); subMode = configObj[mode].length - 1; } /** * inet Configuration on mode controls * {@link http://www.zytrax.com/books/dns/ch7/controls.html} */ if (/inet.*/.test(line) && mode === 'controls') configObj.controls = { inet: { .../(?<!intet\s)(?<source>\d+\.\d+\.\d\.\d|\*)\sallow\s{\s(?<allow>\w+);\s}\skeys\s{\s"(?<keys>.*)"/.exec(line).groups, }, }; if (strTST.test(line)) { typeof subMode !== 'undefined' ? configObj[mode][subMode][strTST.exec(line)[1].replace(/-(\D)/, (a, b) => b.toUpperCase())] = /(?<=")(.*)(?=")/.exec(line)[0] : configObj[mode][strTST.exec(line)[1].replace(/-(\D)/, (a, b) => b.toUpperCase())] = /(?<=")(.*)(?=")/.exec(line)[0]; } // Options Mode String Test // if (configTST.test(line)) configObj.options[configTST.exec(line)[1].replace(/-(\D)/, (a, b) => b.toUpperCase())] = /(?<=")(.*)(?=")/.exec(line)![0]; // Array Configuration Options if (arryCONFTST.test(line)) { const data = /(\{)[\s\S]*?(\}|$)/g .exec(line)[0] .replace(/\{|\}/g, '') .replace(/;|\s+/g, '') .trim() .split(/\s/g); if (data[0].length > 0) { if (mode === 'keys' || mode === 'zones') configObj[mode][configObj[mode].length - 1][arryCONFTST.exec(line)[1].replace(/-(\D)/, (a, b) => b.toUpperCase())] = data; else configObj[mode][arryCONFTST.exec(line)[1].replace(/-(\D)/, (a, b) => b.toUpperCase())] = data; } /\s+\}/.test(line) ? (subOpt = undefined) : (subOpt = arryCONFTST.exec(line)[1].replace(/-(\D)/, (a, b) => b.toUpperCase())); if (mode === 'keys' || mode === 'zones') subObj = configObj[mode].length - 1; } // New line array configuration option if (subOpt && /\s+(\w.*);/g.test(line)) { if (typeof subObj === 'undefined') configObj[mode][subOpt] ? configObj[mode][subOpt].push(/\s+(\w.*);/.exec(line)[1]) : (configObj[mode][subOpt] = [/\s+(\w.*);/.exec(line)[1]]); else configObj[mode][subObj][subOpt] ? configObj[mode][subObj][subOpt].push(/\s+(\w.*);/.exec(line)[1]) : (configObj[mode][subObj][subOpt] = [/\s+(\w.*);/.exec(line)[1]]); } // End of Array Configuration block if (subOpt && /\}/g.test(line)) subObj ? ((subObj = undefined), (subOpt = undefined)) : (subOpt = undefined); /** * Options Block Yes/No Parser */ if (booleanTST.test(line)) { if (typeof subMode === 'undefined') configObj[mode][booleanTST .exec(line)[1] .replace(/-(\D)/, (a, b) => b.toUpperCase()) .replace('Enable', '')] = /(\w+);/g.exec(line)[1] == 'yes' ? true : false; else configObj[mode][subMode][booleanTST .exec(line)[1] .replace(/-(\D)/, (a, b) => b.toUpperCase()) .replace('Enable', '')] = /(\w+);/g.exec(line)[1] == 'yes' ? true : false; } /** * Zone Block Type parser */ if (/type.*/.test(line) && mode === 'zones') configObj[mode][subMode]['type'] = /(?<=type\s).*(?=;)/.exec(line)[0]; // Zone Block Update Policy Parser if (/update-policy\s{/.test(line) && mode === 'zones') configObj[mode][subMode].updatePolicy = { grant: /grant\s+(\S+)\s/.exec(line)[1], zonesub: /\szonesub\s(\S+);/.exec(line)[1] }; if (/(auto-dnssec)/.test(line) && mode === 'zones') configObj.zones[configObj.zones.length - 1].autoDNSSEC = /(?<=auto-dnssec\s)(\w+)/.exec(line)[1]; if (mode === 'keys' && /algorithm.*/.test(line)) configObj.keys[configObj.keys.length - 1].algorithm = /(?<=algorithm\s).*(?=;)/.exec(line)[0]; if (MDEND.test(line)) mode = undefined; } return configObj; };