From c0d016618455f48db829edfcd7f151d63d933d8f Mon Sep 17 00:00:00 2001 From: Ylian Saint-Hilaire Date: Thu, 2 Nov 2017 18:44:27 -0700 Subject: [PATCH] Add support for IIS account migration. --- agents/meshcmd.js | 43 ++++++++++++++++++++++++++++++++++--------- meshcentral.db.json | 22 ++++++++++++++++++++++ meshcentral.js | 4 ++-- package.json | 2 +- pass.js | 14 +++++++++++++- webserver.js | 23 +++++++++++++++++------ 6 files changed, 89 insertions(+), 19 deletions(-) create mode 100644 meshcentral.db.json diff --git a/agents/meshcmd.js b/agents/meshcmd.js index 44396c6e..4f6d6eff 100644 --- a/agents/meshcmd.js +++ b/agents/meshcmd.js @@ -37,29 +37,54 @@ function onVerifyServer(clientName, certs) { // Print a debug message function debug(level, message) { if ((settings.debugLevel != null) && (settings.debugLevel >= level)) { console.log(message); } } +// Parse the input arguments into an object +function parceArguments(argv) { + var r = {}; + for (var i in argv) { + i = parseInt(i); + if (argv[i].startsWith('--') == true) { + var key = argv[i].substring(2).toLowerCase(), val = true; + if (((i + 1) < argv.length) && (argv[i + 1].startsWith('--') == false)) { val = argv[i + 1]; } + r[key] = val; + } + } + return r; +} + // Start the router, start by listening to the local port function run(argv) { - console.log('MeshCentral Command v1.0'); + var args = parceArguments(argv); + console.log('MeshCentral Command v1.0b'); var actionpath = 'meshaction.txt'; - if (argv.length >= 2) { actionpath = argv[1]; } - + if (args.actionfile != null) { actionpath = args.actionfile; } // Load the action file var actionfile = null; try { actionfile = fs.readFileSync(actionpath); } catch (e) { } - if (actionfile == null) { console.log('Unable to load \"' + actionpath + '\". Create this file or specify the location as the first argument.'); process.exit(1); } + if (actionfile == null) { console.log('Unable to load \"' + actionpath + '\". Create this file or specify the location using --actionfile [filename].'); process.exit(1); } try { settings = JSON.parse(actionfile); } catch (e) { console.log(actionpath, e); process.exit(1); } + // Set the arguments + if ((typeof args.localport) == 'string') { settings.localport = parseInt(args.localport); } + if ((typeof args.remotenodeid) == 'string') { settings.remoteNodeId = args.remotenodeid; } + if ((typeof args.username) == 'string') { settings.username = args.username; } + if ((typeof args.password) == 'string') { settings.password = args.password; } + if ((typeof args.user) == 'string') { settings.username = args.user; } + if ((typeof args.pass) == 'string') { settings.password = args.pass; } + if ((typeof args.serverid) == 'string') { settings.serverId = args.serverid; } + if ((typeof args.serverhttpshash) == 'string') { settings.serverHttpsHash = args.serverhttpshash; } + if ((typeof args.remoteport) == 'string') { settings.remotePort = parseInt(args.remoteport); } + // Validate meshaction.txt if (settings.action == null) { console.log('No \"action\" specified.'); process.exit(1); } settings.action = settings.action.toLowerCase(); if (settings.action == 'route') { - if ((settings.localPort == null) || (typeof settings.localPort != 'number') || (settings.localPort < 0) || (settings.localPort > 65535)) { console.log('No or invalid \"localPort\" specified.'); process.exit(1); } + if ((settings.localPort == null) || (typeof settings.localPort != 'number') || (settings.localPort < 0) || (settings.localPort > 65535)) { console.log('No or invalid \"localPort\" specified, use --localport [localport].'); process.exit(1); } if ((settings.remoteNodeId == null) || (typeof settings.remoteNodeId != 'string')) { console.log('No or invalid \"remoteNodeId\" specified.'); process.exit(1); } - if ((settings.username == null) || (typeof settings.username != 'string')) { console.log('No or invalid \"username\" specified.'); process.exit(1); } - if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified.'); process.exit(1); } + if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { console.log('No or invalid \"username\" specified, use --username [username].'); process.exit(1); } + if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); process.exit(1); } if ((settings.serverId == null) || (typeof settings.serverId != 'string') || (settings.serverId.length != 96)) { console.log('No or invalid \"serverId\" specified.'); process.exit(1); } if ((settings.serverHttpsHash == null) || (typeof settings.serverHttpsHash != 'string') || (settings.serverHttpsHash.length != 96)) { console.log('No or invalid \"serverHttpsHash\" specified.'); process.exit(1); } - if ((settings.remotePort == null) || (typeof settings.remotePort != 'number') || (settings.remotePort < 0) || (settings.remotePort > 65535)) { console.log('No or invalid \"remotePort\" specified.'); process.exit(1); } + if ((settings.remotePort == null) || (typeof settings.remotePort != 'number') || (settings.remotePort < 0) || (settings.remotePort > 65535)) { console.log('No or invalid \"remotePort\" specified, use --remoteport [remoteport].'); process.exit(1); } } else { console.log('Invalid \"action\" specified.'); process.exit(1); } @@ -167,4 +192,4 @@ function OnMulticastMessage(msg, rinfo) { } } -try { run(process.argv); } catch (e) { /*console.log(e);*/ } +try { run(process.argv); } catch (e) { console.log(e); } diff --git a/meshcentral.db.json b/meshcentral.db.json new file mode 100644 index 00000000..37ba7e34 --- /dev/null +++ b/meshcentral.db.json @@ -0,0 +1,22 @@ +[{ "type":"user", "_id":"user//admin", "name":"admin", "domain":"", "creation":1417814230, "passtype":1, "salt":"X/mGcbCKZUkz+SNegUoRwg==", "hash":"0/wjLzIa0HUmKjcDHCVbVcoH+WU=","siteadmin": 4294967295, "links": { "mesh//0133eb552602d0434e8eea2d9e89aa08371f8e4adbf231a028ac1c95e4208717": { "name":"admin", "rights":4294967295 }, "mesh//0fad5c10dc068da20751fd248497338c800af9691c76921017479eb828bf6205": { "name":"admin", "rights":4294967295 }, "mesh//1bc82505ef750af28b19292eaf2260eae83bc2939a367f1a885efe865b729193": { "name":"admin", "rights":4294967295 }, "mesh//7b3ac5051dd7abf91226f8e4cfb81661dca8410ba663218be05272c963bec254": { "name":"admin", "rights":4294967295 }, "mesh//7b4b43cdad850135f36ab31124b52e47c167fba055ce800267a4dc89fe0e581c": { "name":"admin", "rights":4294967295 }, "mesh//7eadaf3f460cd55c40e45ecd7ade5c787b6230a7956aaffa9d5660db8ad71df4": { "name":"admin", "rights":4294967295 }, "mesh//93c713c5cda428bb06777a7e7cd8075527f8a2f305945ac241852b37b1f30739": { "name":"admin", "rights":4294967295 }, "mesh//acf0460d17df45ff977d2ceb3fcc84ced94a68bc67ef513bbdb1fc59a591bd5d": { "name":"admin", "rights":4294967295 } } }, +{ "type":"user", "_id":"user//bcpd", "name":"bcpd", "domain":"", "creation":1428008504, "passtype":1, "salt":"GaSZAFik/buRLadnZUWS/w==", "hash":"b9yfxrzNC28eU7OPqfJezY98HSY=", "links": { "mesh//0133eb552602d0434e8eea2d9e89aa08371f8e4adbf231a028ac1c95e4208717": { "name":"bcpd", "rights":4294967295 }, "mesh//7b3ac5051dd7abf91226f8e4cfb81661dca8410ba663218be05272c963bec254": { "name":"bcpd", "rights":4294967295 }, "mesh//7b4b43cdad850135f36ab31124b52e47c167fba055ce800267a4dc89fe0e581c": { "name":"bcpd", "rights":4294967295 }, "mesh//7eadaf3f460cd55c40e45ecd7ade5c787b6230a7956aaffa9d5660db8ad71df4": { "name":"bcpd", "rights":4294967295 } } }, +{ "type":"user", "_id":"user//bryan", "name":"Bryan", "domain":"", "creation":1373413118, "passtype":1, "salt":"GoMdgNplNW5Tq1LI38Fi0Q==", "hash":"HSelSEKY8BJWdAV6D0PD4Gwiazg=", "links": { "mesh//542dea438e6065bffa9318c149e9982440dba4ce6ba3ba2b577e0e127b6a7f24": { "name":"Bryan", "rights":4294967295 } } }, +{ "type":"user", "_id":"user//demo", "name":"demo", "domain":"", "creation":1428090949, "passtype":1, "salt":"t8Ni4VFop9c8cHt5DPK4ow==", "hash":"j2JyQ9KuHLZg6Jbuc+DRBB+sxIk=", "links": { "mesh//0133eb552602d0434e8eea2d9e89aa08371f8e4adbf231a028ac1c95e4208717": { "name":"demo", "rights":4294967295 }, "mesh//0fad5c10dc068da20751fd248497338c800af9691c76921017479eb828bf6205": { "name":"demo", "rights":4294967295 }, "mesh//7b3ac5051dd7abf91226f8e4cfb81661dca8410ba663218be05272c963bec254": { "name":"demo", "rights":4294967295 }, "mesh//7b4b43cdad850135f36ab31124b52e47c167fba055ce800267a4dc89fe0e581c": { "name":"demo", "rights":4294967295 }, "mesh//7eadaf3f460cd55c40e45ecd7ade5c787b6230a7956aaffa9d5660db8ad71df4": { "name":"demo", "rights":4294967295 } } }, +{ "type":"user", "_id":"user//devbox%5cdefault", "name":"DevBox%5CDefault", "domain":"", "creation":1426267634, "passtype":1, "salt":"H/D6bP81Ot++TgSTcj3qrQ==", "hash":"fwKPpQCFKJ2/6c/teSQl91ZtRsI=", "links": { "mesh//0fad5c10dc068da20751fd248497338c800af9691c76921017479eb828bf6205": { "name":"DevBox%5CDefault", "rights":4294967295 }, "mesh//7eadaf3f460cd55c40e45ecd7ade5c787b6230a7956aaffa9d5660db8ad71df4": { "name":"DevBox%5CDefault", "rights":4294967295 } } }, +{ "type":"user", "_id":"user//devbox%5cguest", "name":"DevBox%5CGuest", "domain":"", "creation":1426274108, "passtype":1, "salt":"ZhjNOb+BulO6xjq6cMgaDg==", "hash":"7xbj8VbGL1bKC+5sQ57M06j80VA=", "links": { "mesh//0fad5c10dc068da20751fd248497338c800af9691c76921017479eb828bf6205": { "name":"DevBox%5CGuest", "rights":4294967295 }, "mesh//7eadaf3f460cd55c40e45ecd7ade5c787b6230a7956aaffa9d5660db8ad71df4": { "name":"DevBox%5CGuest", "rights":4294967295 } } }, +{ "type":"user", "_id":"user//empty", "name":"Empty", "domain":"", "creation":1416594156, "passtype":1, "salt":"lDetzH6OFHHLffpSkZBcKQ==", "hash":"O+Ao6Lq2o9rSHqnHhm1Tcbxz8sw=", "links": { } }, +{ "type":"user", "_id":"user//empty2", "name":"empty2", "domain":"", "creation":1427217822, "passtype":1, "salt":"/ra8pIDX8XVadXyDAwUgZw==", "hash":"Kw9CQLnXbzJWorjIhgWRoTkUeS8=", "links": { } }, +{ "type":"user", "_id":"user//redge", "name":"redge", "domain":"", "creation":1387230750, "passtype":1, "salt":"cZD5MVAsa/6m18D/jw4Nkg==", "hash":"dsmvqMuupJfedwcuFbZy8sC/1yc=", "links": { "mesh//0133eb552602d0434e8eea2d9e89aa08371f8e4adbf231a028ac1c95e4208717": { "name":"redge", "rights":4294967295 }, "mesh//0fad5c10dc068da20751fd248497338c800af9691c76921017479eb828bf6205": { "name":"redge", "rights":4294967295 }, "mesh//7b3ac5051dd7abf91226f8e4cfb81661dca8410ba663218be05272c963bec254": { "name":"redge", "rights":4294967295 }, "mesh//7b4b43cdad850135f36ab31124b52e47c167fba055ce800267a4dc89fe0e581c": { "name":"redge", "rights":4294967295 }, "mesh//7eadaf3f460cd55c40e45ecd7ade5c787b6230a7956aaffa9d5660db8ad71df4": { "name":"redge", "rights":4294967295 }, "mesh//994a35a3ffcc0b3968080ec73add4bdb5f1317152e7db0b0c3caf7144eb1556e": { "name":"redge", "rights":4294967295 } } }, +{ "type":"user", "_id":"user//rick", "name":"rick", "domain":"", "creation":1386192546, "passtype":1, "salt":"pi9Q9Mwkj4Ji7IMI1oMfjg==", "hash":"oxlmQOVRvW2MF059xkCay+Yyxew=", "links": { } }, +{ "type":"user", "_id":"user//somnathc", "name":"somnathc", "domain":"", "creation":1355529208, "passtype":1, "salt":"EQ4BCdtl6rAFgkzMsg029A==", "hash":"LcCJnuXC4GXOi5jlu3cEGMWB+I8=", "links": { } }, +{ "type":"user", "_id":"user//test", "name":"test", "domain":"", "creation":1443471004, "passtype":1, "salt":"shgKMwOTDILJ9DwitvLYFQ==", "hash":"c5U+yuss5JzMe76I9pkcN3xxwqc=", "links": { } }, +{ "type":"user", "_id":"user//ylian", "name":"ylian", "domain":"", "creation":1398981122, "passtype":1, "salt":"WQYTOkQAKM1mK571bkPrEQ==", "hash":"X8U/zslu/T6NbgsunM1tDiHZXgA=", "links": { "mesh//0fad5c10dc068da20751fd248497338c800af9691c76921017479eb828bf6205": { "name":"ylian", "rights":4294967295 }, "mesh//7b4b43cdad850135f36ab31124b52e47c167fba055ce800267a4dc89fe0e581c": { "name":"ylian", "rights":4294967295 }, "mesh//7eadaf3f460cd55c40e45ecd7ade5c787b6230a7956aaffa9d5660db8ad71df4": { "name":"ylian", "rights":4294967295 } } }, +{ "type":"user", "_id":"user//ylian2", "name":"ylian2", "domain":"", "creation":1499729724, "passtype":1, "salt":"jS2CiOuElkqXe7yIqQtSUg==", "hash":"HDWFHgTJIx7wR4XMPjgKNb5dbIs=", "links": { } }, +{ "type":"user", "_id":"user//%cf%80ele", "name":"%CF%80ele", "domain":"", "creation":1449084349, "passtype":1, "salt":"jGvowGbDG+/HdWysKE5EbA==", "hash":"cR1ieHW5UuKJiSzpYBfzocjfKbM=", "links": { } }, +{ "type":"mesh", "_id":"mesh//0133eb552602d0434e8eea2d9e89aa08371f8e4adbf231a028ac1c95e4208717", "name":"test", "domain":"", "mtype":2, "links": { "user//admin": { "rights":4294967295 }, "user//bcpd": { "rights":4294967295 }, "user//demo": { "rights":4294967295 }, "user//redge": { "rights":4294967295 } } }, +{ "type":"mesh", "_id":"mesh//0fad5c10dc068da20751fd248497338c800af9691c76921017479eb828bf6205", "name":"ylian's%20cube", "domain":"", "mtype":2, "links": { "user//admin": { "rights":4294967295 }, "user//demo": { "rights":4294967295 }, "user//devbox%5cdefault": { "rights":4294967295 }, "user//devbox%5cguest": { "rights":4294967295 }, "user//redge": { "rights":4294967295 }, "user//ylian": { "rights":4294967295 } } }, +{ "type":"mesh", "_id":"mesh//542dea438e6065bffa9318c149e9982440dba4ce6ba3ba2b577e0e127b6a7f24", "name":"test", "domain":"", "mtype":2, "links": { "user//bryan": { "rights":4294967295 } } }, +{ "type":"mesh", "_id":"mesh//7b3ac5051dd7abf91226f8e4cfb81661dca8410ba663218be05272c963bec254", "name":"minidevices", "domain":"", "mtype":2, "links": { "user//admin": { "rights":4294967295 }, "user//bcpd": { "rights":4294967295 }, "user//demo": { "rights":4294967295 }, "user//redge": { "rights":4294967295 } } }, +{ "type":"mesh", "_id":"mesh//7b4b43cdad850135f36ab31124b52e47c167fba055ce800267a4dc89fe0e581c", "name":"meshlab", "domain":"", "mtype":2, "links": { "user//admin": { "rights":4294967295 }, "user//bcpd": { "rights":4294967295 }, "user//demo": { "rights":4294967295 }, "user//redge": { "rights":4294967295 }, "user//ylian": { "rights":4294967295 } } }, +{ "type":"mesh", "_id":"mesh//7eadaf3f460cd55c40e45ecd7ade5c787b6230a7956aaffa9d5660db8ad71df4", "name":"intel%20oregon%20mesh%20lab", "domain":"", "mtype":2, "links": { "user//admin": { "rights":4294967295 }, "user//bcpd": { "rights":4294967295 }, "user//demo": { "rights":4294967295 }, "user//devbox%5cdefault": { "rights":4294967295 }, "user//devbox%5cguest": { "rights":4294967295 }, "user//redge": { "rights":4294967295 }, "user//ylian": { "rights":4294967295 } } }, +{ "type":"mesh", "_id":"mesh//994a35a3ffcc0b3968080ec73add4bdb5f1317152e7db0b0c3caf7144eb1556e", "name":"test", "domain":"", "mtype":2, "links": { "user//redge": { "rights":4294967295 } } }] \ No newline at end of file diff --git a/meshcentral.js b/meshcentral.js index 2535a4ff..4e439eb9 100644 --- a/meshcentral.js +++ b/meshcentral.js @@ -232,7 +232,7 @@ function CreateMeshCentralServer() { if (obj.args.showiplocations) { obj.db.GetAllType('iploc', function (err, docs) { console.log(docs); process.exit(); }); return; } if (obj.args.dbexport) { // Export the entire database to a JSON file - if (obj.args.dbexport == true) { console.log('Use --dbexport [filename]'); process.exit(); } else { obj.db.GetAll(function (err, docs) { obj.fs.writeFileSync(obj.args.dbexport, JSON.stringify(docs)); console.log('Exported ' + docs.length + ' document(s).'); process.exit(); }); } + if (obj.args.dbexport == true) { console.log('Use --dbexport [filename]'); process.exit(); } else { obj.db.GetAll(function (err, docs) { obj.fs.writeFileSync(obj.args.dbexport, JSON.stringify(docs)); console.log('Exported ' + docs.length + ' objects(s).'); process.exit(); }); } return; } if (obj.args.dbimport) { @@ -242,7 +242,7 @@ function CreateMeshCentralServer() { try { json = obj.fs.readFileSync(obj.args.dbimport); } catch (e) { console.log('Invalid JSON file'); process.exit(); } try { json = JSON.parse(json); } catch (e) { console.log('Invalid JSON format'); process.exit(); } if ((json == null) || (typeof json.length != 'number') || (json.length < 1)) { console.log('Invalid JSON format'); } - obj.db.RemoveAll(function () { obj.db.InsertMany(json, function () { console.log('Imported ' + json.length + ' document(s)'); process.exit(); }); }); + obj.db.RemoveAll(function () { obj.db.InsertMany(json, function () { console.log('Imported ' + json.length + ' objects(s)'); process.exit(); }); }); } return; } diff --git a/package.json b/package.json index faa9af99..88b7f97a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "meshcentral", - "version": "0.1.0-d", + "version": "0.1.0-f", "keywords": [ "Remote Management", "Intel AMT", diff --git a/pass.js b/pass.js index c6670f14..33ec419c 100644 --- a/pass.js +++ b/pass.js @@ -39,4 +39,16 @@ exports.hash = function (pwd, salt, fn) { } }); } -}; \ No newline at end of file +}; + +exports.iishash = function (type, pwd, salt, fn) { + if (type == 0) { + fn(null, pwd); + } else if (type == 1) { + const hash = crypto.createHash('sha1'); + hash.update(Buffer.concat([new Buffer(salt, 'base64'), new Buffer(pwd, 'utf16le')])); + fn(null, hash.digest().toString('base64')); + } else { + fn('invalid type'); + } +}; diff --git a/webserver.js b/webserver.js index 6e3a2497..045ecdc7 100644 --- a/webserver.js +++ b/webserver.js @@ -43,6 +43,7 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate obj.tls = require('tls'); obj.path = require('path'); obj.hash = require('./pass').hash; + obj.hash2 = require('./pass').hash2; obj.constants = require('constants'); obj.bodyParser = require('body-parser'); obj.session = require('express-session'); @@ -175,14 +176,24 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate if (user.salt == null) { fn(new Error('invalid password')); } else { - obj.hash(pass, user.salt, function (err, hash) { - if (err) return fn(err); - if (hash == user.hash) return fn(null, user._id); - fn(new Error('invalid password'), null, user.passhint); - }); + if (user.passtype != null) { + // IIS default clear or weak password hashing (SHA-1) + obj.iishash(user.passtype, pass, user.salt, function (err, hash) { + if (err) return fn(err); + if (hash == user.hash) return fn(null, user._id); + fn(new Error('invalid password'), null, user.passhint); + }); + } else { + // Default strong password hashing + obj.hash(pass, user.salt, function (err, hash) { + if (err) return fn(err); + if (hash == user.hash) return fn(null, user._id); + fn(new Error('invalid password'), null, user.passhint); + }); + } } } - + /* obj.restrict = function (req, res, next) { console.log('restrict', req.url);