From 4561468b05f713fed0873240144dc6fa26abd80e Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Sat, 23 Mar 2019 13:28:17 -0700 Subject: [PATCH] More FIDO2 improvements, improved NPM install. --- meshcentral.js | 24 +++- meshuser.js | 12 +- package-lock.json | 291 ++++++++++++++++++++++++++++++++++++--- package.json | 2 - views/default.handlebars | 6 +- webserver.js | 16 ++- 6 files changed, 315 insertions(+), 36 deletions(-) diff --git a/meshcentral.js b/meshcentral.js index 31af7af0..eb1040ef 100644 --- a/meshcentral.js +++ b/meshcentral.js @@ -1596,21 +1596,30 @@ function getConfig(createSampleConfig) { // Check if a list of modules are present and install any missing ones function InstallModules(modules, func) { - if (modules.length > 0) { InstallModule(modules.shift(), InstallModules, modules, func); } else { func(); } + var missingModules = []; + if (modules.length > 0) { + for (var i in modules) { try { var xxmodule = require(modules[i]); } catch (e) { missingModules.push(modules[i]); } } + if (missingModules.length > 0) { InstallModule(missingModules.join(' '), InstallModules, modules, func); } else { func(); } + } } // Check if a module is present and install it if missing +var InstallModuleChildProcess = null; function InstallModule(modulename, func, tag1, tag2) { try { var module = require(modulename); } catch (e) { console.log('Installing ' + modulename + '...'); var child_process = require('child_process'); - child_process.exec('npm install ' + modulename + ' --no-optional --save', { maxBuffer: 512000 }, function (error, stdout, stderr) { + + // Looks like we need to keep a global reference to the child process object for this to work correctly. + InstallModuleChildProcess = child_process.exec('npm install ' + modulename + ' --no-optional --save', { maxBuffer: 512000, timeout: 10000 }, function (error, stdout, stderr) { + InstallModuleChildProcess = null; if (error != null) { console.log('ERROR: Unable to install missing package \'' + modulename + '\', make sure npm is installed: ' + error); process.exit(); return; } func(tag1, tag2); return; }); + return; } func(tag1, tag2); @@ -1633,7 +1642,8 @@ function mainStart(args) { // Check is Windows SSPI will be used var sspi = false; - if (require('os').platform() == 'win32') { for (var i in config.domains) { if (config.domains[i].auth == 'sspi') { sspi = true; } } } + var allsspi = true; + if (require('os').platform() == 'win32') { for (var i in config.domains) { if (config.domains[i].auth == 'sspi') { sspi = true; } else { allsspi = false; } } } // Build the list of required modules var modules = ['ws', 'nedb', 'https', 'yauzl', 'xmldom', 'express', 'archiver', 'multiparty', 'node-forge', 'express-ws', 'compression', 'body-parser', 'connect-redis', 'express-handlebars']; @@ -1642,8 +1652,14 @@ function mainStart(args) { if (config.settings.mongodb != null) { modules.push('mongojs'); } // Add MongoDB if (config.smtp != null) { modules.push('nodemailer'); } // Add SMTP support + // Get the current node version + var nodeVersion = Number(process.version.match(/^v(\d+\.\d+)/)[1]); + // If running NodeJS < 8, install "util.promisify" - if (Number(process.version.match(/^v(\d+\.\d+)/)[1]) < 8) { modules.push('util.promisify'); } + if (nodeVersion < 8) { modules.push('util.promisify'); } + + // if running NodeJS 8 or higher, we can install WebAuthn/FIDO2 support + if ((nodeVersion >= 8) && (allsspi == false)) { modules.push('@davedoesdev/fido2-lib'); } // Install any missing modules and launch the server InstallModules(modules, function () { meshserver = CreateMeshCentralServer(config, args); meshserver.Start(); }); diff --git a/meshuser.js b/meshuser.js index 1a3b0a6d..dbb76f76 100644 --- a/meshuser.js +++ b/meshuser.js @@ -2004,11 +2004,17 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use { if ((obj.webAuthnReqistrationRequest == null) || (parent.f2l == null)) return; + // Figure out the origin + var httpport = ((args.aliasport != null) ? args.aliasport : args.port); + var origin = "https://" + (domain.dns ? domain.dns : parent.certificates.CommonName); + if (httpport != 443) { origin += ':' + httpport; } + var attestationExpectations = { challenge: obj.webAuthnReqistrationRequest.request.challenge.split('+').join('-').split('/').join('_').split('=').join(''), // Convert to Base64URL - origin: "https://devbox.mesh.meshcentral.com", + origin: origin, factor: "either" }; + var clientAttestationResponse = command.response; clientAttestationResponse.id = clientAttestationResponse.rawId; clientAttestationResponse.rawId = new Uint8Array(Buffer.from(clientAttestationResponse.rawId, 'base64')).buffer; @@ -2016,6 +2022,10 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use clientAttestationResponse.response.clientDataJSON = new Uint8Array(Buffer.from(clientAttestationResponse.response.clientDataJSON, 'base64')).buffer; parent.f2l.attestationResult(clientAttestationResponse, attestationExpectations).then(function (regResult) { + // If we register a WebAuthn/FIDO2 key, remove all U2F keys. + // TODO + + // Add the new WebAuthn/FIDO2 keys var keyIndex = parent.crypto.randomBytes(4).readUInt32BE(0); if (user.otphkeys == null) { user.otphkeys = []; } user.otphkeys.push({ name: obj.webAuthnReqistrationRequest.keyname, type: 3, publicKey: regResult.authnrData.get('credentialPublicKeyPem'), counter: regResult.authnrData.get('counter'), keyIndex: keyIndex, keyId: clientAttestationResponse.id }); diff --git a/package-lock.json b/package-lock.json index 5a7b7db2..993959c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,9 +1,59 @@ { "name": "meshcentral", - "version": "0.2.9-q", + "version": "0.3.0-u", "lockfileVersion": 1, "requires": true, "dependencies": { + "@davedoesdev/fido2-lib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@davedoesdev/fido2-lib/-/fido2-lib-2.4.0.tgz", + "integrity": "sha512-qBNCio4amWMxDe7e8VG3wOo3iu/cFxzLpZ+vzRhLDYbQpZVBhJxFyYXCak33+1qPkDHJOSLZBU7x5jyruU1RMA==", + "requires": { + "@peculiar/webcrypto": "^1.0.1", + "asn1js": "^2.0.18", + "cbor": "^4.0.0", + "cose-to-jwk": "^1.1.0", + "jwk-to-pem": "^2.0.0", + "node-jose": "^1.0.0", + "pkijs": "=2.1.58", + "psl": "^1.1.24" + } + }, + "@peculiar/asn1-schema": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-1.0.3.tgz", + "integrity": "sha512-Tfgj9eNJ6cTKEtEuidKenLHMx/Q5M8KEE9hnohHqvdpqHJXWYr5RlT3GjAHPjGXy5+mr7sSfuXfzE6aAkEGN7A==", + "requires": { + "asn1js": "^2.0.22", + "tslib": "^1.9.3" + } + }, + "@peculiar/json-schema": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@peculiar/json-schema/-/json-schema-1.1.5.tgz", + "integrity": "sha512-y5XYA3pf9+c+YKVpWnPtQbNmlNCs2ehNHyMLJvq4K5Fjwc1N64YGy7MNecKW3uYLga+sqbGTQSUdOdlnaRRbpA==", + "requires": { + "tslib": "^1.9.3" + } + }, + "@peculiar/webcrypto": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@peculiar/webcrypto/-/webcrypto-1.0.8.tgz", + "integrity": "sha512-zOCwDimHbQeUgSdBCHnw/69wbA1ks+aUt1MPAttcWNOlXaZjbUppc8shtwX/mzDQYctzNGFlI8Xrayl7lBUe5A==", + "requires": { + "@peculiar/asn1-schema": "^1.0.2", + "@peculiar/json-schema": "^1.1.5", + "asn1js": "^2.0.22", + "pvtsutils": "^1.0.4", + "tslib": "^1.9.3", + "webcrypto-core": "^1.0.10" + } + }, + "@types/node": { + "version": "10.14.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.3.tgz", + "integrity": "sha512-2lhc7S28vo8FwR3Jv3Ifyd77AxEsx+Nl9ajWiac6/eWuvZ84zPK4RE05pfqcn3acIzlZDpQj5F1rIKQZX3ptLQ==" + }, "accepts": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", @@ -101,6 +151,24 @@ "safer-buffer": "~2.1.0" } }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "asn1js": { + "version": "2.0.22", + "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-2.0.22.tgz", + "integrity": "sha512-mKox8OHPmLZY0FUbd8JYsAu2lQk61yFH8gTq4N7AT7NzmUKISpy0LEjV/AfLyE/SNCUicdMDZUFbocsf/9qOTg==", + "requires": { + "pvutils": "^1.0.17" + } + }, "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", @@ -146,6 +214,11 @@ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", "integrity": "sha1-yrHmEY8FEJXli1KBrqjBzSK/wOM=" }, + "base64url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==" + }, "bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", @@ -154,6 +227,11 @@ "tweetnacl": "^0.14.3" } }, + "bignumber.js": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-8.1.1.tgz", + "integrity": "sha512-QD46ppGintwPGuL1KqmwhR0O+N2cZUg8JG/VzwI2e28sM9TqHjQB10lI4QAaMHVbLzwVLLAwEglpKPViWX+5NQ==" + }, "binary-search-tree": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/binary-search-tree/-/binary-search-tree-0.2.5.tgz", @@ -171,6 +249,11 @@ "safe-buffer": "^5.1.1" } }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" + }, "body-parser": { "version": "1.18.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", @@ -243,10 +326,15 @@ "concat-map": "0.0.1" } }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, "bson": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.9.tgz", - "integrity": "sha1-EjGfgyOxJUc5t8a++NPomuBaL1c=" + "integrity": "sha512-IQX9/h7WdMBIW/q/++tGd+emQr0XMdeZ6icnT/74Xk9fnabWn+gZgpE+9V+gujL3hhJOoNrnDVY7tWdzc7NUTg==" }, "buffer": { "version": "5.2.1", @@ -291,6 +379,11 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" }, + "bytestreamjs": { + "version": "1.0.27", + "resolved": "https://registry.npmjs.org/bytestreamjs/-/bytestreamjs-1.0.27.tgz", + "integrity": "sha512-P3eEIZi2olI+lgb7RpGRluJdGoDdSzh0A9hmNP4s7YHiuuw1KRKARxmkdDkDhQCGmV14OVkieTmE/F1/roxiWg==" + }, "camelcase": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", @@ -302,6 +395,17 @@ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, + "cbor": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-4.1.5.tgz", + "integrity": "sha512-WqpISHl7/kk1u1uoaqctGyGiET3+wGN4A6pPsFCzEBztJJlCVxnMB4JwcuuNSrMiV4V6UBlxMkhNzJrUxDWO1A==", + "requires": { + "bignumber.js": "^8.0.2", + "commander": "^2.19.0", + "json-text-sequence": "^0.1", + "nofilter": "^1.0.1" + } + }, "center-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", @@ -339,6 +443,11 @@ "delayed-stream": "~1.0.0" } }, + "commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==" + }, "compress-commons": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-1.2.2.tgz", @@ -502,6 +611,14 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, + "cose-to-jwk": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/cose-to-jwk/-/cose-to-jwk-1.1.0.tgz", + "integrity": "sha512-DbR/XPptfo+kcoA77jWPTe4JS0MrpOXAg0sgVr2FeZMnTGGpppOL072e2hgPHTVbSoMkt5l0qDv/k2xCn+79Cg==", + "requires": { + "cbor": "^4.0.0" + } + }, "crc": { "version": "3.8.0", "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", @@ -555,6 +672,11 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, + "delimit-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/delimit-stream/-/delimit-stream-0.1.0.tgz", + "integrity": "sha1-m4MZR3wOX4rrPONXrjBfwl6hzSs=" + }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -589,6 +711,20 @@ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, + "elliptic": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", + "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -907,12 +1043,23 @@ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" }, - "heapdump": { - "version": "0.3.12", - "resolved": "https://registry.npmjs.org/heapdump/-/heapdump-0.3.12.tgz", - "integrity": "sha512-OSVdkxGd9xAJNEP0RA/ZvKEzGTEjCnkvmMEGF1ScR/87tH92v5Dpv6g/Fs8GvZA9UxdMpxU1G9NEC2D0OxZjJQ==", + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", "requires": { - "nan": "^2.11.1" + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" } }, "http-errors": { @@ -1045,6 +1192,14 @@ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, + "json-text-sequence": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/json-text-sequence/-/json-text-sequence-0.1.1.tgz", + "integrity": "sha1-py8hfcSvxGKf/1/rME3BvVGi89I=", + "requires": { + "delimit-stream": "0.1.0" + } + }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", @@ -1056,6 +1211,16 @@ "verror": "1.10.0" } }, + "jwk-to-pem": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwk-to-pem/-/jwk-to-pem-2.0.1.tgz", + "integrity": "sha512-KKu0WuDDjqw2FlRFp9/vk9TMO/KvgpZVKzdhhYcNyy5OwE8dw9lOK5OQTQHIJ7m+HioI/4P44sAtVuDrQ8KQfw==", + "requires": { + "asn1.js": "^4.5.2", + "elliptic": "^6.2.3", + "safe-buffer": "^5.0.1" + } + }, "keygrip": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.0.2.tgz", @@ -1140,6 +1305,11 @@ "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=" }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, "longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", @@ -1179,6 +1349,16 @@ "mime-db": "~1.37.0" } }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -1210,7 +1390,7 @@ "mongodb": { "version": "2.2.36", "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.36.tgz", - "integrity": "sha1-HFc2gLKEn7D0esu6PcX6Io3pdfU=", + "integrity": "sha512-P2SBLQ8Z0PVx71ngoXwo12+FiSfbNfGOClAao03/bant5DgLNkOPAck5IaJcEk4gKlQhDEURzfR3xuBG1/B+IA==", "requires": { "es6-promise": "3.2.1", "mongodb-core": "2.1.20", @@ -1239,7 +1419,7 @@ "string_decoder": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha1-D8Z9fBQYJd6UKC3VNr7GubzoYKs=", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", "requires": { "safe-buffer": "~5.1.0" } @@ -1249,7 +1429,7 @@ "mongodb-core": { "version": "2.1.20", "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.20.tgz", - "integrity": "sha1-/s6N12tZ7n1/LTE7ZTIsFgSS2PE=", + "integrity": "sha512-IN57CX5/Q1bhDq6ShAR6gIv4koFsZP7L8WOK1S0lR0pVDQaScffSMV5jxubLsmZ7J+UdqmykKw4r9hG3XQEGgQ==", "requires": { "bson": "~1.0.4", "require_optional": "~1.0.0" @@ -1258,7 +1438,7 @@ "mongojs": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/mongojs/-/mongojs-2.6.0.tgz", - "integrity": "sha1-Mz9YBiGg3GSACGXjjjam5h/xaYk=", + "integrity": "sha512-r6tj71DjYcaRTi2jpa+CA6Iq72cTZclB2JKy+Zub+0JPTEq/l2plsAYfF2eHqSYBtZbKNcObvhGYk9E9UKZWJg==", "requires": { "each-series": "^1.0.0", "mongodb": "^2.2.31", @@ -1318,11 +1498,6 @@ } } }, - "nan": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz", - "integrity": "sha1-kOIrzLjKV+pM03zIPTgZtS7qZ2Y=" - }, "nedb": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/nedb/-/nedb-1.8.0.tgz", @@ -1345,6 +1520,31 @@ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.6.tgz", "integrity": "sha512-sol30LUpz1jQFBjOKwbjxijiE3b6pjd74YwfD0fJOKPjF+fONKb2Yg8rYgS6+bK6VDl+/wfr4IYpC7jDzLUIfw==" }, + "node-jose": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/node-jose/-/node-jose-1.1.3.tgz", + "integrity": "sha512-kupfi4uGWhRjnOmtie2T64cLge5a1TZyalEa8uWWWBgtKBcu41A4IGKpI9twZAxRnmviamEUQRK7LSyfFb2w8A==", + "requires": { + "base64url": "^3.0.1", + "es6-promise": "^4.2.6", + "lodash": "^4.17.11", + "long": "^4.0.0", + "node-forge": "^0.8.1", + "uuid": "^3.3.2" + }, + "dependencies": { + "es6-promise": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.6.tgz", + "integrity": "sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==" + }, + "node-forge": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.8.2.tgz", + "integrity": "sha512-mXQ9GBq1N3uDCyV1pdSzgIguwgtVpM7f5/5J4ipz12PKWElmPpVWLDuWl8iXmhysr21+WmX/OJ5UKx82wjomgg==" + } + } + }, "node-windows": { "version": "0.1.14", "resolved": "https://registry.npmjs.org/node-windows/-/node-windows-0.1.14.tgz", @@ -1354,6 +1554,11 @@ "xml": "0.0.12" } }, + "nofilter": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-1.0.2.tgz", + "integrity": "sha512-d38SORxm9UNoDsnPXajV9nBEebKX4/paXAlyRGnSjZuFbLLZDFUO4objr+tbybqsbqGXDWllb6gQoKUDc9q3Cg==" + }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -1464,6 +1669,26 @@ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, + "pkijs": { + "version": "2.1.58", + "resolved": "https://registry.npmjs.org/pkijs/-/pkijs-2.1.58.tgz", + "integrity": "sha512-HEcJ4SbZNdyB7Jb1G7Ot3Y/gd7kZyTDJBMIIZOFselrKrCouhGbQu4rm9Lg8bumBACckq724G9uNsZbNJ6d2gw==", + "requires": { + "asn1js": "^2.0.22", + "bytestreamjs": "^1.0.27", + "pvutils": "^1.0.17" + }, + "dependencies": { + "asn1js": { + "version": "2.0.22", + "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-2.0.22.tgz", + "integrity": "sha512-mKox8OHPmLZY0FUbd8JYsAu2lQk61yFH8gTq4N7AT7NzmUKISpy0LEjV/AfLyE/SNCUicdMDZUFbocsf/9qOTg==", + "requires": { + "pvutils": "^1.0.17" + } + } + } + }, "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", @@ -1496,6 +1721,20 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha1-tYsBCsQMIsVldhbI0sLALHv0eew=" }, + "pvtsutils": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.0.4.tgz", + "integrity": "sha512-lBDyLfPIWZjxHr6Nnl83/iaZgVLczDcpEqWdqRnghzBKXifRU/7D5T6JPYWUAm0sJdFeF9+sNTKto6dj/3P/Kg==", + "requires": { + "@types/node": "^10.12.15", + "tslib": "^1.9.3" + } + }, + "pvutils": { + "version": "1.0.17", + "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.0.17.tgz", + "integrity": "sha512-wLHYUQxWaXVQvKnwIDWFVKDJku9XDCvyhhxoq8dc5MFdIlRenyPI9eSfEtcvgHgD7FlvCyGAlWgOzRnZD99GZQ==" + }, "qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", @@ -1604,7 +1843,7 @@ "require_optional": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", - "integrity": "sha1-TPNaQkf2TKPfjC7yCMxJSxyo/C4=", + "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", "requires": { "resolve-from": "^2.0.0", "semver": "^5.1.0" @@ -1637,7 +1876,7 @@ "semver": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha1-fnQlb7qknHWqfHogXMInmcrIAAQ=" + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" }, "send": { "version": "0.16.2", @@ -1734,7 +1973,7 @@ "thunky": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.0.3.tgz", - "integrity": "sha1-9d9zJFNAewkZHa5z4qjMc/OBqCY=" + "integrity": "sha512-YwT8pjmNcAXBZqrubu22P4FYsh2D4dxRmnWBOL8Jk8bUcRUtc5326kx32tuTmFDAZtLOGEVNl8POAR8j896Iow==" }, "to-buffer": { "version": "1.1.1", @@ -1767,6 +2006,11 @@ } } }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -1879,6 +2123,15 @@ "extsprintf": "^1.2.0" } }, + "webcrypto-core": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/webcrypto-core/-/webcrypto-core-1.0.11.tgz", + "integrity": "sha512-cHxOMKNzRkPlCcQyGTuyaZmAVZlbby0lH9ASaFk5w8x/i3Q809sISA28AMVnkebW2ekcQ2+UtdaVBFUf58xjyA==", + "requires": { + "pvtsutils": "^1.0.3", + "tslib": "^1.9.3" + } + }, "window-size": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", diff --git a/package.json b/package.json index 184af60b..ea47357c 100644 --- a/package.json +++ b/package.json @@ -41,9 +41,7 @@ "multiparty": "^4.2.1", "nedb": "^1.8.0", "node-forge": "^0.7.6", - "nodemailer": "^5.1.1", "otplib": "^10.0.1", - "util.promisify": "^1.0.0", "ws": "^6.1.2", "xmldom": "^0.1.27", "yauzl": "^2.10.0", diff --git a/views/default.handlebars b/views/default.handlebars index 0574839e..1c70b510 100644 --- a/views/default.handlebars +++ b/views/default.handlebars @@ -1494,9 +1494,9 @@ } x += ""; x += "
"; - x += ""; - if ((features & 0x4000) != 0) { x += ""; } - x += ""; + if ((features & 0x00020000) == 0) { x += ""; } + if ((features & 0x00020000) != 0) { x += ""; } + if ((features & 0x00004000) != 0) { x += ""; } x += "

"; setDialogMode(2, "Manage Security Keys", 8, null, x, 'otpauth-hardware-manage'); if (u2fSupported() == false) { QE('d2addkey1', false); } diff --git a/webserver.js b/webserver.js index 0ab2d0f5..4b32ff9a 100644 --- a/webserver.js +++ b/webserver.js @@ -61,12 +61,8 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { obj.interceptor = require('./interceptor'); const constants = (obj.crypto.constants ? obj.crypto.constants : require('constants')); // require('constants') is deprecated in Node 11.10, use require('crypto').constants instead. - // Setup WebAuthn, this is an optional install. - // "npm install @davedoesdev/fido2-lib" - try { - const { Fido2Lib } = require("@davedoesdev/fido2-lib"); - obj.f2l = new Fido2Lib({ attestation: "none" }); - } catch (ex) { console.log(ex); } + // Setup WebAuthn / FIDO2 + try { const { Fido2Lib } = require("@davedoesdev/fido2-lib"); obj.f2l = new Fido2Lib({ attestation: "none" }); } catch (ex) { console.log(ex); } // Variables obj.parent = parent; @@ -365,9 +361,14 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { // If we found a valid key to use, let's validate the response if (webAuthnKey != null) { + // Figure out the origin + var httpport = ((args.aliasport != null) ? args.aliasport : args.port); + var origin = "https://" + (domain.dns ? domain.dns : parent.certificates.CommonName); + if (httpport != 443) { origin += ':' + httpport; } + var assertionExpectations = { challenge: req.session.u2fchallenge, - origin: "https://devbox.mesh.meshcentral.com", + origin: origin, factor: "either", publicKey: webAuthnKey.publicKey, prevCounter: webAuthnKey.counter, @@ -1160,6 +1161,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) { if (domain.yubikey && domain.yubikey.id && domain.yubikey.secret) { features += 0x00004000; } // Indicates Yubikey support if (domain.geolocation == true) { features += 0x00008000; } // Enable geo-location features if ((domain.passwordrequirements != null) && (domain.passwordrequirements.hint === true)) { features += 0x00010000; } // Enable password hints + if (obj.f2l != null) { features += 0x00020000; } // Enable WebAuthn/FIDO2 support // Create a authentication cookie const authCookie = obj.parent.encodeCookie({ userid: user._id, domainid: domain.id }, obj.parent.loginCookieEncryptionKey);