mirror of
https://github.com/Ylianst/MeshCentral.git
synced 2024-11-26 16:06:33 +03:00
Access permission and CIRA improvements.
This commit is contained in:
parent
7f6945c172
commit
ca94c192ac
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -332,6 +332,7 @@ function run(argv) {
|
||||
amtMei.getMACAddresses(function (result) { mestate.mac = result; });
|
||||
amtMei.getLanInterfaceSettings(0, function (result) { mestate.net0 = result; });
|
||||
amtMei.getLanInterfaceSettings(1, function (result) { mestate.net1 = result; });
|
||||
amtMei.getUuid(function (result) { if ((result != null) && (result.uuid != null)) { mestate.uuid = result.uuid; } });
|
||||
amtMei.getDnsSuffix(function (result) {
|
||||
mestate.dns = result;
|
||||
var str = 'Intel AMT v' + mestate.ver;
|
||||
@ -341,7 +342,7 @@ function run(argv) {
|
||||
if (mestate.ehbc.EHBC == true) { str += ', EHBC enabled'; }
|
||||
str += '.';
|
||||
if (mestate.net0 != null) { str += '\r\nWired ' + ((mestate.net0.enabled == 1) ? 'Enabled' : 'Disabled') + ((mestate.net0.dhcpEnabled == 1) ? ', DHCP' : ', Static') + ', ' + mestate.net0.mac + (mestate.net0.address == '0.0.0.0'?'':(', ' + mestate.net0.address)); }
|
||||
if (mestate.net1 != null) { str += '\r\nWireless ' + ((mestate.net0.enabled == 1) ? 'Enabled' : 'Disabled') + ((mestate.net0.dhcpEnabled == 1) ? ', DHCP' : ', Static') + ', ' + mestate.net0.mac + (mestate.net0.address == '0.0.0.0' ? '' : (', ' + mestate.net0.address)); }
|
||||
if (mestate.net1 != null) { str += '\r\nWireless ' + ((mestate.net1.enabled == 1) ? 'Enabled' : 'Disabled') + ((mestate.net1.dhcpEnabled == 1) ? ', DHCP' : ', Static') + ', ' + mestate.net1.mac + (mestate.net1.address == '0.0.0.0' ? '' : (', ' + mestate.net1.address)); }
|
||||
console.log(str + '.');
|
||||
exit(1);
|
||||
});
|
||||
@ -369,9 +370,10 @@ function run(argv) {
|
||||
startMeScript();
|
||||
} else if (settings.action == 'amtuuid') {
|
||||
// Start running
|
||||
if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; }
|
||||
if ((settings.hostname == null) || (typeof settings.hostname != 'string') || (settings.hostname == '')) { settings.hostname = '127.0.0.1'; }
|
||||
if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; }
|
||||
if (settings.hostname != null) {
|
||||
if ((settings.password == null) || (typeof settings.password != 'string') || (settings.password == '')) { console.log('No or invalid \"password\" specified, use --password [password].'); exit(1); return; }
|
||||
if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; }
|
||||
}
|
||||
settings.protocol = 'http:';
|
||||
settings.localport = 16992;
|
||||
debug(1, "Settings: " + JSON.stringify(settings));
|
||||
@ -573,8 +575,14 @@ function activeToCCMEx3(stack, name, responses, status) {
|
||||
|
||||
// Called to get the UUID of Intel AMT, start by setting up MicroLMS if we are doing the operation on the local computer
|
||||
function getAmtUuid() {
|
||||
// See if MicroLMS needs to be started
|
||||
if ((settings.hostname == '127.0.0.1') || (settings.hostname.toLowerCase() == 'localhost')) { settings.noconsole = true; startLms(getAmtUuidEx); } else { getAmtUuidEx() };
|
||||
if (settings.hostname == null) {
|
||||
var amtMeiModule = require('amt-mei');
|
||||
var amtMei = new amtMeiModule();
|
||||
amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; });
|
||||
amtMei.getUuid(function (result) { if ((result == null) || (result.uuid == null)) { console.log('Failed.'); } else { console.log(result.uuid); } exit(1); });
|
||||
} else {
|
||||
if ((settings.hostname == '127.0.0.1') || (settings.hostname.toLowerCase() == 'localhost')) { settings.noconsole = true; startLms(getAmtUuidEx); return; } else { getAmtUuidEx(); }
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch the computer's UUID by fetching the CIM_ComputerSystemPackage WSMAN object.
|
||||
@ -677,10 +685,22 @@ function saveEntireAmtStateDone() {
|
||||
|
||||
// Get Intel AMT information using MEI
|
||||
// TODO: If this call is called many time at once, it's going to cause issues.
|
||||
var getAmtInfoFetching = null;
|
||||
var getAmtInfoFetchingTimer = null;
|
||||
function getAmtInfo(func, tag) {
|
||||
//console.log('getAmtInfo1');
|
||||
if (amtMei == null) { if (func != null) { func(null, tag); } return; }
|
||||
if (getAmtInfoFetching != null) { getAmtInfoFetching.push({ f: func, t: tag }); return; }
|
||||
getAmtInfoFetching = [{ f: func, t: tag }];
|
||||
amtMeiTmpState = { Flags: 0, TrustedHashes: [] }; // Flags: 1=EHBC, 2=CCM, 4=ACM
|
||||
getAmtInfoFetchingTimer = setTimeout(function () {
|
||||
// MEI failed to respond, break out and reset everthing.
|
||||
for (var i in getAmtInfoFetching) { if (getAmtInfoFetching[i].f != null) { getAmtInfoFetching[i].f(amtMeiTmpState, getAmtInfoFetching[i].t); } }
|
||||
getAmtInfoFetching = null;
|
||||
getAmtInfoFetchingTimer = null;
|
||||
var amtMeiModule = require('amt-mei');
|
||||
amtMei = new amtMeiModule();
|
||||
amtMei.on('error', function (e) { console.log('ERROR: ' + e); exit(1); return; });
|
||||
}, 3000);
|
||||
amtMei.getProtocolVersion(function (result) { if (result != null) { amtMeiTmpState.MeiVersion = result; } });
|
||||
amtMei.getVersion(function (val) {
|
||||
amtMeiTmpState.Versions = {};
|
||||
@ -699,9 +719,10 @@ function getAmtInfo(func, tag) {
|
||||
amtMeiTmpState.TrustedHashes.push({ Active: result.isActive, Default: result.isDefault, HashAlgorithm: result.hashAlgorithm, Name: result.name, Hash: result.certificateHash });
|
||||
if (--exitOnCount == 0) {
|
||||
amtMeiTmpState.Notifications = lmsNotifications; amtMeiState = amtMeiTmpState;
|
||||
//console.log('getAmtInfo2', JSON.stringify(amtMeiState));
|
||||
if (func != null) { func(amtMeiTmpState, tag); }
|
||||
amtMeiTmpState = null;
|
||||
for (var i in getAmtInfoFetching) { if (getAmtInfoFetching[i].f != null) { getAmtInfoFetching[i].f(amtMeiTmpState, getAmtInfoFetching[i].t); } }
|
||||
getAmtInfoFetching = null;
|
||||
clearTimeout(getAmtInfoFetchingTimer);
|
||||
getAmtInfoFetchingTimer = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -1178,6 +1178,7 @@ function createMeshCore(agent) {
|
||||
if (meinfo.ProvisioningState) { intelamt.state = meinfo.ProvisioningState; p = true; }
|
||||
if (meinfo.flags) { intelamt.flags = meinfo.Flags; p = true; }
|
||||
if (meinfo.OsHostname) { intelamt.host = meinfo.OsHostname; p = true; }
|
||||
if (meinfo.UUID) { intelamt.uuid = meinfo.UUID; p = true; }
|
||||
if (p == true) { r.intelamt = intelamt }
|
||||
}
|
||||
func(r);
|
||||
@ -1221,6 +1222,7 @@ function createMeshCore(agent) {
|
||||
amtMei.getProvisioningState(function (result) { amtMeiTmpState.ProvisioningState = result.state; });
|
||||
amtMei.getEHBCState(function (result) { if ((result != null) && (result.EHBC == true)) { amtMeiTmpState.Flags += 1; } });
|
||||
amtMei.getControlMode(function (result) { if (result.controlMode == 1) { amtMeiTmpState.Flags += 2; } if (result.controlMode == 2) { amtMeiTmpState.Flags += 4; } });
|
||||
amtMei.getUuid(function (result) { if ((result != null) && (result.uuid != null)) { amtMeiTmpState.UUID = result.uuid; } });
|
||||
//amtMei.getMACAddresses(function (result) { amtMeiTmpState.mac = result; });
|
||||
amtMei.getDnsSuffix(function (result) { if (result != null) { amtMeiTmpState.dns = result; } if (func != null) { func(amtMeiTmpState); } });
|
||||
}
|
||||
|
@ -105,6 +105,34 @@ function amt_heci() {
|
||||
}, callback, optional);
|
||||
};
|
||||
|
||||
// Fill the left with zeros until the string is of a given length
|
||||
function zeroLeftPad(str, len) {
|
||||
if ((len == null) && (typeof (len) != 'number')) { return null; }
|
||||
if (str == null) str = ''; // If null, this is to generate zero leftpad string
|
||||
var zlp = '';
|
||||
for (var i = 0; i < len - str.length; i++) { zlp += '0'; }
|
||||
return zlp + str;
|
||||
}
|
||||
|
||||
this.getUuid = function getUuid(callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(0x5c, null, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
var result = {};
|
||||
result.uuid = [zeroLeftPad(header.Data.readUInt32LE(0).toString(16), 8),
|
||||
zeroLeftPad(header.Data.readUInt16LE(4).toString(16), 4),
|
||||
zeroLeftPad(header.Data.readUInt16LE(6).toString(16), 4),
|
||||
zeroLeftPad(header.Data.readUInt16BE(8).toString(16), 4),
|
||||
zeroLeftPad(header.Data.slice(10).toString('hex').toLowerCase(), 12)].join('-');
|
||||
opt.unshift(result);
|
||||
} else {
|
||||
opt.unshift(null);
|
||||
}
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
};
|
||||
|
||||
this.getProvisioningState = function getProvisioningState(callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
|
@ -23,15 +23,18 @@ function amt_heci() {
|
||||
|
||||
this._ObjectID = "pthi";
|
||||
this._rq = new Q();
|
||||
this._setupPTHI = function _setupPTHI() {
|
||||
this._setupPTHI = function _setupPTHI()
|
||||
{
|
||||
this._amt = heci.create();
|
||||
this._amt.BiosVersionLen = 65;
|
||||
this._amt.UnicodeStringLen = 20;
|
||||
|
||||
this._amt.Parent = this;
|
||||
this._amt.on('error', function _amtOnError(e) { this.Parent.emit('error', e); });
|
||||
this._amt.on('connect', function _amtOnConnect() {
|
||||
this.on('data', function _amtOnData(chunk) {
|
||||
this._amt.on('connect', function _amtOnConnect()
|
||||
{
|
||||
this.on('data', function _amtOnData(chunk)
|
||||
{
|
||||
//console.log("Received: " + chunk.length + " bytes");
|
||||
var header = this.Parent.getCommand(chunk);
|
||||
//console.log("CMD = " + header.Command + " (Status: " + header.Status + ") Response = " + header.IsResponse);
|
||||
@ -43,12 +46,14 @@ function amt_heci() {
|
||||
params.unshift(header);
|
||||
callback.apply(this.Parent, params);
|
||||
|
||||
if (this.Parent._rq.isEmpty()) {
|
||||
if(this.Parent._rq.isEmpty())
|
||||
{
|
||||
// No More Requests, we can close PTHI
|
||||
this.Parent._amt.disconnect();
|
||||
this.Parent._amt = null;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
// Send the next request
|
||||
this.write(this.Parent._rq.peekQueue().send);
|
||||
}
|
||||
@ -73,9 +78,10 @@ function amt_heci() {
|
||||
var header = Buffer.from('010100000000000000000000', 'hex');
|
||||
header.writeUInt32LE(arguments[0] | 0x04000000, 4);
|
||||
header.writeUInt32LE(arguments[1] == null ? 0 : arguments[1].length, 8);
|
||||
this._rq.enQueue({ cmd: arguments[0], func: arguments[2], optional: args, send: (arguments[1] == null ? header : Buffer.concat([header, arguments[1]])) });
|
||||
this._rq.enQueue({ cmd: arguments[0], func: arguments[2], optional: args , send: (arguments[1] == null ? header : Buffer.concat([header, arguments[1]]))});
|
||||
|
||||
if (!this._amt) {
|
||||
if(!this._amt)
|
||||
{
|
||||
this._setupPTHI();
|
||||
this._amt.connect(heci.GUIDS.AMT, { noPipeline: 1 });
|
||||
}
|
||||
@ -87,7 +93,7 @@ function amt_heci() {
|
||||
this.sendCommand(26, null, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
var i, CodeVersion = header.Data, val = { BiosVersion: CodeVersion.slice(0, this._amt.BiosVersionLen), Versions: [] }, v = CodeVersion.slice(this._amt.BiosVersionLen + 4);
|
||||
for (i = 0; i < CodeVersion.readUInt32LE(this._amt.BiosVersionLen); ++i) {
|
||||
for (i = 0; i < CodeVersion.readUInt32LE(this._amt.BiosVersionLen) ; ++i) {
|
||||
val.Versions[i] = { Description: v.slice(2, v.readUInt16LE(0) + 2).toString(), Version: v.slice(4 + this._amt.UnicodeStringLen, 4 + this._amt.UnicodeStringLen + v.readUInt16LE(2 + this._amt.UnicodeStringLen)).toString() };
|
||||
v = v.slice(4 + (2 * this._amt.UnicodeStringLen));
|
||||
}
|
||||
@ -99,6 +105,34 @@ function amt_heci() {
|
||||
}, callback, optional);
|
||||
};
|
||||
|
||||
// Fill the left with zeros until the string is of a given length
|
||||
function zeroLeftPad(str, len) {
|
||||
if ((len == null) && (typeof (len) != 'number')) { return null; }
|
||||
if (str == null) str = ''; // If null, this is to generate zero leftpad string
|
||||
var zlp = '';
|
||||
for (var i = 0; i < len - str.length; i++) { zlp += '0'; }
|
||||
return zlp + str;
|
||||
}
|
||||
|
||||
this.getUuid = function getUuid(callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
this.sendCommand(0x5c, null, function (header, fn, opt) {
|
||||
if (header.Status == 0) {
|
||||
var result = {};
|
||||
result.uuid = [zeroLeftPad(header.Data.readUInt32LE(0).toString(16), 8),
|
||||
zeroLeftPad(header.Data.readUInt16LE(4).toString(16), 4),
|
||||
zeroLeftPad(header.Data.readUInt16LE(6).toString(16), 4),
|
||||
zeroLeftPad(header.Data.readUInt16BE(8).toString(16), 4),
|
||||
zeroLeftPad(header.Data.slice(10).toString('hex').toLowerCase(), 12)].join('-');
|
||||
opt.unshift(result);
|
||||
} else {
|
||||
opt.unshift(null);
|
||||
}
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
};
|
||||
|
||||
this.getProvisioningState = function getProvisioningState(callback) {
|
||||
var optional = [];
|
||||
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
@ -248,6 +282,46 @@ function amt_heci() {
|
||||
fn.apply(this, opt);
|
||||
}, callback, optional);
|
||||
}
|
||||
this.getLanInterfaceSettings = function getLanInterfaceSettings(index, callback)
|
||||
{
|
||||
var optional = [];
|
||||
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
var ifx = Buffer.alloc(4);
|
||||
ifx.writeUInt32LE(index);
|
||||
this.sendCommand(0x48, ifx, function onGetLanInterfaceSettings(header, fn, opt)
|
||||
{
|
||||
if(header.Status == 0)
|
||||
{
|
||||
var info = {};
|
||||
info.enabled = header.Data.readUInt32LE(0);
|
||||
info.dhcpEnabled = header.Data.readUInt32LE(8);
|
||||
switch(header.Data[12])
|
||||
{
|
||||
case 1:
|
||||
info.dhcpMode = 'ACTIVE'
|
||||
break;
|
||||
case 2:
|
||||
info.dhcpMode = 'PASSIVE'
|
||||
break;
|
||||
default:
|
||||
info.dhcpMode = 'UNKNOWN';
|
||||
break;
|
||||
}
|
||||
info.mac = header.Data.slice(14).toString('hex:');
|
||||
|
||||
var addr = header.Data.readUInt32LE(4);
|
||||
info.address = ((addr >> 24) & 255) + '.' + ((addr >> 16) & 255) + '.' + ((addr >> 8) & 255) + '.' + (addr & 255);
|
||||
opt.unshift(info);
|
||||
fn.apply(this, opt);
|
||||
}
|
||||
else
|
||||
{
|
||||
opt.unshift(null);
|
||||
fn.apply(this, opt);
|
||||
}
|
||||
}, callback, optional);
|
||||
|
||||
};
|
||||
this.unprovision = function unprovision(mode, callback) {
|
||||
var optional = [];
|
||||
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }
|
||||
|
1
db.js
1
db.js
@ -107,6 +107,7 @@ module.exports.CreateDB = function (args, datapath) {
|
||||
obj.clearOldEntries = function (type, days, domain) { var cutoff = Date.now() - (1000 * 60 * 60 * 24 * days); obj.file.remove({ type: type, time: { $lt: cutoff } }, { multi: true }); }
|
||||
obj.getPowerTimeline = function (nodeid, func) { if (obj.databaseType == 1) { obj.file.find({ type: 'power', node: { $in: ['*', nodeid] } }).sort({ time: 1 }).exec(func); } else { obj.file.find({ type: 'power', node: { $in: ['*', nodeid] } }).sort({ time: 1 }, func); } }
|
||||
obj.getLocalAmtNodes = function (func) { obj.file.find({ type: 'node', host: { $exists: true, $ne: null }, intelamt: { $exists: true } }, func); }
|
||||
obj.getAmtUuidNode = function (meshid, uuid, func) { obj.file.find({ type: 'node', meshid: meshid, 'intelamt.uuid': uuid }, func); }
|
||||
|
||||
// This is used to rate limit a number of operation per day. Returns a startValue each new days, but you can substract it and save the value in the db.
|
||||
obj.getValueOfTheDay = function (id, startValue, func) { obj.Get(id, function (err, docs) { var date = new Date(), t = date.toLocaleDateString(); if (docs.length == 1) { var r = docs[0]; if (r.day == t) { func({ _id: id, value: r.value, day: t }); return; } } func({ _id: id, value: startValue, day: t }); }); }
|
||||
|
@ -549,6 +549,7 @@ module.exports.CreateMeshAgent = function (parent, db, ws, req, args, domain) {
|
||||
if (device.intelamt.state != command.intelamt.state) { device.intelamt.state = command.intelamt.state; change = 1; changes.push('AMT state'); }
|
||||
if (device.intelamt.flags != command.intelamt.flags) { device.intelamt.flags = command.intelamt.flags; change = 1; changes.push('AMT flags'); }
|
||||
if (device.intelamt.host != command.intelamt.host) { device.intelamt.host = command.intelamt.host; change = 1; changes.push('AMT host'); }
|
||||
if (device.intelamt.uuid != command.intelamt.uuid) { device.intelamt.uuid = command.intelamt.uuid; change = 1; changes.push('AMT uuid'); }
|
||||
}
|
||||
if (mesh.mtype == 2) {
|
||||
if (device.host != obj.remoteaddr) { device.host = obj.remoteaddr; change = 1; changes.push('host'); }
|
||||
|
@ -227,6 +227,7 @@ function CreateMeshCentralServer(config, args) {
|
||||
//if (obj.servicelog != null) { var s = ''; for (var i in obj.args) { if (i != '_') { if (s.length > 0) { s += ', '; } s += i + "=" + obj.args[i]; } } logInfoEvent('MeshServer started with arguments: ' + s); }
|
||||
|
||||
// Look at passed in arguments
|
||||
if ((obj.args.user != null) && (typeof obj.args.user != 'string')) { delete obj.args.user; }
|
||||
if ((obj.args.ciralocalfqdn != null) && ((obj.args.lanonly == true) || (obj.args.wanonly == true))) { console.log("WARNING: CIRA local FQDN's ignored when server in LAN-only or WAN-only mode."); }
|
||||
if ((obj.args.ciralocalfqdn != null) && (obj.args.ciralocalfqdn.split(',').length > 4)) { console.log("WARNING: Can't have more than 4 CIRA local FQDN's. Ignoring value."); obj.args.ciralocalfqdn = null; }
|
||||
if (obj.args.port == null || typeof obj.args.port != 'number') { if (obj.args.notls == null) { obj.args.port = 443; } else { obj.args.port = 80; } }
|
||||
|
@ -69,7 +69,7 @@ module.exports.CreateMeshRelay = function (parent, ws, req, domain) {
|
||||
obj.parent.authenticate(req.query.user, req.query.pass, obj.domain, function (err, userid, passhint) {
|
||||
if (userid != null) {
|
||||
obj.authenticated = true;
|
||||
// Check is we have agent routing instructions, process this here.
|
||||
// Check if we have agent routing instructions, process this here.
|
||||
if ((req.query.nodeid != null) && (req.query.tcpport != null)) {
|
||||
if (obj.id == undefined) { obj.id = ('' + Math.random()).substring(2); } // If there is no connection id, generate one.
|
||||
var command = { nodeid: req.query.nodeid, action: 'msg', type: 'tunnel', value: '*/meshrelay.ashx?id=' + obj.id, tcpport: req.query.tcpport, tcpaddr: ((req.query.tcpaddr == null) ? '127.0.0.1' : req.query.tcpaddr) };
|
||||
|
@ -167,7 +167,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
|
||||
case 'files':
|
||||
{
|
||||
// Send the full list of server files to the browser app
|
||||
if ((user.siteadmin & 8) != 0) { updateUserFiles(user, ws, domain); }
|
||||
if ((user != null) && (user.siteadmin != null) && (user.siteadmin & 8) != 0) { updateUserFiles(user, ws, domain); }
|
||||
break;
|
||||
}
|
||||
case 'fileoperation':
|
||||
@ -205,7 +205,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
|
||||
if (agent != null) {
|
||||
// Check if we have permission to send a message to that node
|
||||
var rights = user.links[agent.dbMeshKey];
|
||||
if (rights != null || ((rights & 16) != 0)) { // TODO: 16 is console permission, may need more gradular permission checking
|
||||
if ((rights != null) && ((rights.rights & 8) != 0)) { // 8 is remote control permission
|
||||
command.sessionid = ws.sessionId; // Set the session id, required for responses.
|
||||
command.rights = rights.rights; // Add user rights flags to the message
|
||||
delete command.nodeid; // Remove the nodeid since it's implyed.
|
||||
@ -217,7 +217,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
|
||||
if (routing != null) {
|
||||
// Check if we have permission to send a message to that node
|
||||
var rights = user.links[routing.meshid];
|
||||
if (rights != null || ((rights & 16) != 0)) { // TODO: 16 is console permission, may need more gradular permission checking
|
||||
if ((rights != null) && ((rights.rights & 8) != 0)) { // 8 is remote control permission
|
||||
command.fromSessionid = ws.sessionId; // Set the session id, required for responses.
|
||||
command.rights = rights.rights; // Add user rights flags to the message
|
||||
obj.parent.parent.multiServer.DispatchMessageSingleServer(command, routing.serverid);
|
||||
|
85
mpsserver.js
85
mpsserver.js
@ -227,44 +227,75 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
|
||||
obj.db.GetAllType('mesh', function (err, docs) {
|
||||
var mesh = null;
|
||||
for (var i in docs) { if (docs[i]._id.indexOf(meshIdStart) > 0) { mesh = docs[i]; break; } }
|
||||
if (mesh == null) { Debug(1, 'MPS:Mesh not found', username, password);SendUserAuthFail(socket); return -1; }
|
||||
if (mesh == null) { Debug(1, 'MPS:Mesh not found', username, password); SendUserAuthFail(socket); return -1; }
|
||||
|
||||
// Intel AMT GUID (socket.tag.SystemId) will be used at NodeID
|
||||
var systemid = socket.tag.SystemId.split('-').join('');
|
||||
var nodeid = new Buffer(systemid + systemid + systemid, 'hex').toString('base64').replace(/\+/g, '@').replace(/\//g, '$');
|
||||
socket.tag.name = '';
|
||||
socket.tag.nodeid = 'node/' + mesh.domain + '/' + nodeid; // Turn 16bit systemid guid into 48bit nodeid that is base64 encoded
|
||||
socket.tag.meshid = mesh._id;
|
||||
// If this is a agent-less mesh, use the device guid 3 times as ID.
|
||||
if (mesh.mtype == 1) {
|
||||
// Intel AMT GUID (socket.tag.SystemId) will be used as NodeID
|
||||
var systemid = socket.tag.SystemId.split('-').join('');
|
||||
var nodeid = new Buffer(systemid + systemid + systemid, 'hex').toString('base64').replace(/\+/g, '@').replace(/\//g, '$');
|
||||
socket.tag.name = '';
|
||||
socket.tag.nodeid = 'node/' + mesh.domain + '/' + nodeid; // Turn 16bit systemid guid into 48bit nodeid that is base64 encoded
|
||||
socket.tag.meshid = mesh._id;
|
||||
socket.tag.connectTime = Date.now();
|
||||
|
||||
obj.db.Get(socket.tag.nodeid, function (err, nodes) {
|
||||
if (nodes.length == 0) {
|
||||
if (mesh.mtype == 1) {
|
||||
// Node is not in the database, add it. Credentials will be empty until added by the user.
|
||||
var device = { type: 'node', mtype: 1, _id: socket.tag.nodeid, meshid: socket.tag.meshid, name: socket.tag.name, host: null, domain: mesh.domain, intelamt: { user: '', pass: '', tls: 0 } };
|
||||
obj.db.Set(device);
|
||||
obj.db.Get(socket.tag.nodeid, function (err, nodes) {
|
||||
if (nodes.length == 0) {
|
||||
if (mesh.mtype == 1) {
|
||||
// Node is not in the database, add it. Credentials will be empty until added by the user.
|
||||
var device = { type: 'node', mtype: 1, _id: socket.tag.nodeid, meshid: socket.tag.meshid, name: socket.tag.name, host: null, domain: mesh.domain, intelamt: { user: '', pass: '', tls: 0 } };
|
||||
obj.db.Set(device);
|
||||
|
||||
// Event the new node
|
||||
var device2 = common.Clone(device);
|
||||
if (device2.intelamt.pass != undefined) delete device2.intelamt.pass; // Remove the Intel AMT password before eventing this.
|
||||
var change = 'CIRA added device ' + socket.tag.name + ' to mesh ' + mesh.name;
|
||||
obj.parent.DispatchEvent(['*', socket.tag.meshid], obj, { etype: 'node', action: 'addnode', node: device2, msg: change, domain: mesh.domain })
|
||||
// Event the new node
|
||||
var device2 = common.Clone(device);
|
||||
if (device2.intelamt.pass != undefined) delete device2.intelamt.pass; // Remove the Intel AMT password before eventing this.
|
||||
var change = 'CIRA added device ' + socket.tag.name + ' to mesh ' + mesh.name;
|
||||
obj.parent.DispatchEvent(['*', socket.tag.meshid], obj, { etype: 'node', action: 'addnode', node: device2, msg: change, domain: mesh.domain })
|
||||
} else {
|
||||
// New CIRA connection for unknown node, disconnect.
|
||||
console.log('CIRA connection for unknown node with incorrect mesh type. meshid: ' + socket.tag.meshid);
|
||||
socket.end();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Node is already present
|
||||
var node = nodes[0];
|
||||
if (node.intelamt != undefined) { socket.tag.host = node.intelamt.host; }
|
||||
}
|
||||
|
||||
// Add the connection to the MPS connection list
|
||||
obj.ciraConnections[socket.tag.nodeid] = socket;
|
||||
obj.parent.SetConnectivityState(socket.tag.meshid, socket.tag.nodeid, socket.tag.connectTime, 2, 7); // TODO: Right now report power state as "present" (7) until we can poll.
|
||||
SendUserAuthSuccess(socket); // Notify the auth success on the CIRA connection
|
||||
});
|
||||
} else if (mesh.mtype == 2) { // If this is a agent mesh, search the mesh for this device UUID
|
||||
// Intel AMT GUID (socket.tag.SystemId) will be used to search the node
|
||||
obj.db.getAmtUuidNode(mesh._id, socket.tag.SystemId, function (err, nodes) {
|
||||
if (nodes.length == 0) {
|
||||
// New CIRA connection for unknown node, disconnect.
|
||||
console.log('CIRA connection for unknown node with incorrect mesh type. meshid: ' + socket.tag.meshid);
|
||||
console.log('CIRA connection for unknown node. meshid: ' + mesh._id + ', uuid: ' + systemid);
|
||||
socket.end();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Node is already present
|
||||
|
||||
// Node is present
|
||||
var node = nodes[0];
|
||||
if (node.intelamt != undefined) { socket.tag.host = node.intelamt.host; }
|
||||
}
|
||||
socket.tag.nodeid = node._id;
|
||||
socket.tag.meshid = mesh._id;
|
||||
socket.tag.connectTime = Date.now();
|
||||
|
||||
// Add the connection to the MPS connection list
|
||||
obj.ciraConnections[socket.tag.nodeid] = socket;
|
||||
obj.parent.SetConnectivityState(socket.tag.meshid, socket.tag.nodeid, socket.tag.connectTime, 2, 7); // TODO: Right now report power state as "present" (7) until we can poll.
|
||||
SendUserAuthSuccess(socket); // Notify the auth success on the CIRA connection
|
||||
});
|
||||
// Add the connection to the MPS connection list
|
||||
obj.ciraConnections[socket.tag.nodeid] = socket;
|
||||
obj.parent.SetConnectivityState(socket.tag.meshid, socket.tag.nodeid, socket.tag.connectTime, 2, 7); // TODO: Right now report power state as "present" (7) until we can poll.
|
||||
SendUserAuthSuccess(socket); // Notify the auth success on the CIRA connection
|
||||
});
|
||||
} else { // Unknown mesh type
|
||||
// New CIRA connection for unknown node, disconnect.
|
||||
console.log('CIRA connection to a unknown mesh type. meshid: ' + socket.tag.meshid);
|
||||
socket.end();
|
||||
return;
|
||||
}
|
||||
});
|
||||
return 18 + usernameLen + serviceNameLen + methodNameLen + passwordLen;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "meshcentral",
|
||||
"version": "0.1.5-e",
|
||||
"version": "0.1.5-k",
|
||||
"keywords": [
|
||||
"Remote Management",
|
||||
"Intel AMT",
|
||||
|
@ -159,7 +159,7 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
|
||||
}
|
||||
|
||||
obj.ProcessScreenMsg = function (width, height) {
|
||||
//obj.Debug("ProcessScreenMsg: " + width + " x " + height);
|
||||
obj.Debug("ScreenSize: " + width + " x " + height);
|
||||
obj.Canvas.setTransform(1, 0, 0, 1, 0, 0);
|
||||
obj.rotation = 0;
|
||||
obj.FirstDraw = true;
|
||||
|
@ -1468,10 +1468,10 @@
|
||||
function getMeshActions(mesh, meshrights) {
|
||||
if ((meshrights & 4) == 0) return '';
|
||||
var r = '';
|
||||
if ((features & 2) == 0) { // If not LAN-Only
|
||||
r += ' <a style=cursor:pointer;font-size:10px title="Add a new Intel® AMT computer that is located on the internet." onclick=addCiraDeviceToMesh(\"' + mesh._id + '\")>Add CIRA</a>';
|
||||
}
|
||||
if (mesh.mtype == 1) {
|
||||
if ((features & 2) == 0) { // If not LAN-Only
|
||||
r += ' <a style=cursor:pointer;font-size:10px title="Add a new Intel® AMT computer that is located on the internet." onclick=addCiraDeviceToMesh(\"' + mesh._id + '\")>Add CIRA</a>';
|
||||
}
|
||||
if ((features & 1) == 0) { // If not WAN-Only
|
||||
r += ' <a style=cursor:pointer;font-size:10px title="Add a new Intel® AMT computer that is located on the local network." onclick=addDeviceToMesh(\"' + mesh._id + '\")>Add Local</a>';
|
||||
r += ' <a style=cursor:pointer;font-size:10px title="Add a new Intel® AMT computer by scanning the local network." onclick=addAmtScanToMesh(\"' + mesh._id + '\")>Scan Network</a>';
|
||||
@ -2580,7 +2580,7 @@
|
||||
if (mesh.mtype == 2) x += '<a style=cursor:pointer onclick=p10showNodeNetInfoDialog("' + node._id + '") title="Show device network interface information">Interfaces</a> ';
|
||||
if (xxmap != null) x += '<a style=cursor:pointer onclick=p10showNodeLocationDialog("' + node._id + '") title="Show device locations information">Location</a> ';
|
||||
|
||||
if (mesh.mtype == 2) x += '<a style=cursor:pointer onclick=p10showMeshCmdDialog(1,"' + node._id + '") title="Traffic router used to connect to a device thru this server.">Router</a> ';
|
||||
if (((meshrights & 8) != 0) && (mesh.mtype == 2)) x += '<a style=cursor:pointer onclick=p10showMeshCmdDialog(1,"' + node._id + '") title="Traffic router used to connect to a device thru this server.">Router</a> ';
|
||||
|
||||
// RDP link, show this link only of the remote machine is Windows.
|
||||
if (((connectivity & 1) != 0) && (clickOnce == true) && (mesh.mtype == 2) && ((meshrights & 8) != 0)) {
|
||||
@ -2616,11 +2616,11 @@
|
||||
// Show or hide the tabs
|
||||
// mesh.mtype: 1 = Intel AMT only, 2 = Mesh Agent
|
||||
// node.agent.caps (bitmask): 1 = Desktop, 2 = Terminal, 4 = Files, 8 = Console
|
||||
QV('MainDevDesktop', (mesh.mtype == 1) || (node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 1) != 0));
|
||||
QV('MainDevTerminal', (mesh.mtype == 1) || (node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 2) != 0));
|
||||
QV('MainDevFiles', (mesh.mtype == 2) && ((node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 4) != 0)));
|
||||
QV('MainDevAmt', node.intelamt != null);
|
||||
QV('MainDevConsole', consoleRights && (mesh.mtype == 2) && ((node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 8) != 0)));
|
||||
QV('MainDevDesktop', ((mesh.mtype == 1) || (node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 1) != 0)) && (meshrights & 8));
|
||||
QV('MainDevTerminal', ((mesh.mtype == 1) || (node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 2) != 0)) && (meshrights & 8));
|
||||
QV('MainDevFiles', ((mesh.mtype == 2) && ((node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 4) != 0))) && (meshrights & 8));
|
||||
QV('MainDevAmt', (node.intelamt != null) && (meshrights & 8));
|
||||
QV('MainDevConsole', (consoleRights && (mesh.mtype == 2) && ((node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 8) != 0))) && (meshrights & 8));
|
||||
QV('p15uploadCore', (node.agent != null) && (node.agent.caps != null) && ((node.agent.caps & 16) != 0) && (userinfo.siteadmin == 0xFFFFFFFF));
|
||||
QH('p15coreName', ((node.agent != null) && (node.agent.core != null))?node.agent.core:'');
|
||||
|
||||
@ -4041,8 +4041,12 @@
|
||||
c++;
|
||||
count++;
|
||||
|
||||
// Mesh
|
||||
var rights = 'Administrator'; // TODO
|
||||
// Mesh rights
|
||||
var meshrights = meshes[i].links['user/{{{domain}}}/' + userinfo.name.toLowerCase()].rights;
|
||||
var rights = 'Partial Rights';
|
||||
if (meshrights == 0xFFFFFFFF) rights = 'Full Administrator'; else if (meshrights == 0) rights = 'No Rights';
|
||||
|
||||
// Print the mesh information
|
||||
r += '<div style=display:inline-block;width:431px;height:50px;padding-top:1px;padding-bottom:1px;float:left><div style=float:left;width:30px;height:100%></div><div style=height:100%;cursor:pointer onclick=gotoMesh(\'' + i + '\')><div class=mi style=float:left;width:50px;height:50px></div><div style=height:100%><div class=g1></div><div class=e2 style=width:300px><div class=e1>' + EscapeHtml(meshes[i].name) + '</div><div>' + rights + '</div></div><div class=g2 style=float:left></div></div></div></div>';
|
||||
}
|
||||
|
||||
@ -4247,6 +4251,7 @@
|
||||
if ((meshrights & 64) != 0) r += ', Wake Devices';
|
||||
}
|
||||
r = r.substring(2);
|
||||
if (r == '') { r = 'No Rights'; }
|
||||
var x = addHtmlValue('User Name', userid.split('/')[2]);
|
||||
x += addHtmlValue('Permissions', r);
|
||||
var buttons = 1;
|
||||
|
16
webserver.js
16
webserver.js
@ -537,6 +537,22 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
|
||||
obj.authenticate(user.name, req.body.apassword1, domain, function (err, userid) {
|
||||
var user = obj.users[userid];
|
||||
if (user) {
|
||||
// Remove all the mesh links to this user
|
||||
if (user.links != null) {
|
||||
for (var meshid in user.links) {
|
||||
// Get the mesh
|
||||
var mesh = obj.meshes[meshid];
|
||||
if (mesh) {
|
||||
// Remove user from the mesh
|
||||
if (mesh.links[userid] != null) { delete mesh.links[userid]; obj.db.Set(mesh); }
|
||||
// Notify mesh change
|
||||
var change = 'Removed user ' + user.name + ' from mesh ' + mesh.name;
|
||||
obj.parent.DispatchEvent(['*', mesh._id, user._id, userid], obj, { etype: 'mesh', username: user.name, userid: userid, meshid: mesh._id, name: mesh.name, mtype: mesh.mtype, desc: mesh.desc, action: 'meshchange', links: mesh.links, msg: change, domain: domain.id })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the user
|
||||
obj.db.Remove(user._id);
|
||||
delete obj.users[user._id];
|
||||
req.session.destroy(function () { res.redirect(domain.url); });
|
||||
|
Loading…
Reference in New Issue
Block a user