UNPKG

domotz-remote-pawn

Version:

Domotz Agent

131 lines (120 loc) 4.39 kB
/** This file is part of Domotz Agent. * Copyright (C) 2021 Domotz Ltd * * Domotz Agent is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Domotz Agent is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Domotz Agent. If not, see <http://www.gnu.org/licenses/>. */ var FIRST_LINE_REGEXP = new RegExp('^NetBIOS name: ([^,]+), NetBIOS user: ([^,]+),.+'); var SERVICES_REGEXP = new RegExp('^[ ]{2}([^<]+)<(\\d{2})>\\s+Flags: (<([^>]+)>)?(<([^>]+)>)?(<([^>]+)>)?(<([^>]+)>)?'); function factory(q, nmapXml2Js, resourceLocator) { var myConsole = resourceLocator.log.decorateLogs(); return function (xmlBody) { myConsole.debug('Parsing XML nmap output of %s bytes', xmlBody.length); return nmapXml2Js .toJSON(xmlBody) .then(function (body) { var ret = {}; try { var hosts = body.nmaprun.host; hosts.forEach(function (hostRaw) { processHost(hostRaw, ret); }); } catch (e) { myConsole.error('Unparsable XML output: %s', xmlBody); } var arrayRet = []; sortedKeys(ret).forEach(function (key) { arrayRet.push(ret[key]); }); return arrayRet; }) .catch(function () { myConsole.error('Invalid XML: %s', xmlBody); return []; }); }; function processHost(hostRaw, accumulator) { var mac = null; var hostData = {}; try { var script = hostRaw.hostscript[0].script; if (script === undefined) { return; } findMAC(hostRaw, mac, hostData, accumulator); parseOutput(script[0].$.output, hostData); myConsole.info('Host %s has NETBIOS name %s', hostData.mac, hostData.name); } catch (e) { hostData.error = '' + e; } } function findMAC(hostRaw, mac, hostData, accumulator) { hostRaw.address.forEach(function (address) { if (address.$.addrtype === 'mac') { mac = address.$.addr.toUpperCase(); hostData.mac = mac; accumulator[mac] = hostData; } }); } function parseOutput(rawOutput, hostData) { var lines = rawOutput.split('\n'); try { if (!FIRST_LINE_REGEXP.test(lines[0])) { throw Error('Invalid NETBIOS script output'); } var groups = FIRST_LINE_REGEXP.exec(lines[0]); hostData.name = groups[1]; hostData.user = groups[2]; hostData.services = {}; for (var i = 2; i < lines.length; i++) { groups = SERVICES_REGEXP.exec(lines[i]); if (!groups) { continue; } var name = groups[1]; if (hostData.services[name] === undefined) { hostData.services[name] = []; } var tmp = { code: groups[2], flags: [], }; var k = 4; while (true) { var flag = groups[k]; if (flag === undefined) { break; } else { k += 2; tmp.flags.push(flag); } } hostData.services[name].push(tmp); } } catch (e) { hostData.raw = rawOutput; throw e; } } } module.exports.factory = factory; function sortedKeys(obj) { var keys = []; for (var key in obj) { if (obj.hasOwnProperty(key)) { keys.push(key); } } return keys.sort(); }