Access permission and CIRA improvements.

This commit is contained in:
Ylian Saint-Hilaire 2018-03-26 17:13:32 -07:00
parent 7f6945c172
commit ca94c192ac
29 changed files with 242 additions and 62 deletions

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.

View File

@ -332,6 +332,7 @@ function run(argv) {
amtMei.getMACAddresses(function (result) { mestate.mac = result; }); amtMei.getMACAddresses(function (result) { mestate.mac = result; });
amtMei.getLanInterfaceSettings(0, function (result) { mestate.net0 = result; }); amtMei.getLanInterfaceSettings(0, function (result) { mestate.net0 = result; });
amtMei.getLanInterfaceSettings(1, function (result) { mestate.net1 = 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) { amtMei.getDnsSuffix(function (result) {
mestate.dns = result; mestate.dns = result;
var str = 'Intel AMT v' + mestate.ver; var str = 'Intel AMT v' + mestate.ver;
@ -341,7 +342,7 @@ function run(argv) {
if (mestate.ehbc.EHBC == true) { str += ', EHBC enabled'; } if (mestate.ehbc.EHBC == true) { str += ', EHBC enabled'; }
str += '.'; 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.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 + '.'); console.log(str + '.');
exit(1); exit(1);
}); });
@ -369,9 +370,10 @@ function run(argv) {
startMeScript(); startMeScript();
} else if (settings.action == 'amtuuid') { } else if (settings.action == 'amtuuid') {
// Start running // 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) {
if ((settings.hostname == null) || (typeof settings.hostname != 'string') || (settings.hostname == '')) { settings.hostname = '127.0.0.1'; } 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'; } if ((settings.username == null) || (typeof settings.username != 'string') || (settings.username == '')) { settings.username = 'admin'; }
}
settings.protocol = 'http:'; settings.protocol = 'http:';
settings.localport = 16992; settings.localport = 16992;
debug(1, "Settings: " + JSON.stringify(settings)); 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 // 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() { function getAmtUuid() {
// See if MicroLMS needs to be started if (settings.hostname == null) {
if ((settings.hostname == '127.0.0.1') || (settings.hostname.toLowerCase() == 'localhost')) { settings.noconsole = true; startLms(getAmtUuidEx); } else { getAmtUuidEx() }; 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. // Fetch the computer's UUID by fetching the CIM_ComputerSystemPackage WSMAN object.
@ -677,10 +685,22 @@ function saveEntireAmtStateDone() {
// Get Intel AMT information using MEI // Get Intel AMT information using MEI
// TODO: If this call is called many time at once, it's going to cause issues. // 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) { function getAmtInfo(func, tag) {
//console.log('getAmtInfo1');
if (amtMei == null) { if (func != null) { func(null, tag); } return; } 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 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.getProtocolVersion(function (result) { if (result != null) { amtMeiTmpState.MeiVersion = result; } });
amtMei.getVersion(function (val) { amtMei.getVersion(function (val) {
amtMeiTmpState.Versions = {}; 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 }); amtMeiTmpState.TrustedHashes.push({ Active: result.isActive, Default: result.isDefault, HashAlgorithm: result.hashAlgorithm, Name: result.name, Hash: result.certificateHash });
if (--exitOnCount == 0) { if (--exitOnCount == 0) {
amtMeiTmpState.Notifications = lmsNotifications; amtMeiState = amtMeiTmpState; amtMeiTmpState.Notifications = lmsNotifications; amtMeiState = amtMeiTmpState;
//console.log('getAmtInfo2', JSON.stringify(amtMeiState)); for (var i in getAmtInfoFetching) { if (getAmtInfoFetching[i].f != null) { getAmtInfoFetching[i].f(amtMeiTmpState, getAmtInfoFetching[i].t); } }
if (func != null) { func(amtMeiTmpState, tag); } getAmtInfoFetching = null;
amtMeiTmpState = null; clearTimeout(getAmtInfoFetchingTimer);
getAmtInfoFetchingTimer = null;
} }
}); });
} }

View File

@ -1178,6 +1178,7 @@ function createMeshCore(agent) {
if (meinfo.ProvisioningState) { intelamt.state = meinfo.ProvisioningState; p = true; } if (meinfo.ProvisioningState) { intelamt.state = meinfo.ProvisioningState; p = true; }
if (meinfo.flags) { intelamt.flags = meinfo.Flags; p = true; } if (meinfo.flags) { intelamt.flags = meinfo.Flags; p = true; }
if (meinfo.OsHostname) { intelamt.host = meinfo.OsHostname; 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 } if (p == true) { r.intelamt = intelamt }
} }
func(r); func(r);
@ -1221,6 +1222,7 @@ function createMeshCore(agent) {
amtMei.getProvisioningState(function (result) { amtMeiTmpState.ProvisioningState = result.state; }); amtMei.getProvisioningState(function (result) { amtMeiTmpState.ProvisioningState = result.state; });
amtMei.getEHBCState(function (result) { if ((result != null) && (result.EHBC == true)) { amtMeiTmpState.Flags += 1; } }); 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.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.getMACAddresses(function (result) { amtMeiTmpState.mac = result; });
amtMei.getDnsSuffix(function (result) { if (result != null) { amtMeiTmpState.dns = result; } if (func != null) { func(amtMeiTmpState); } }); amtMei.getDnsSuffix(function (result) { if (result != null) { amtMeiTmpState.dns = result; } if (func != null) { func(amtMeiTmpState); } });
} }

View File

@ -105,6 +105,34 @@ function amt_heci() {
}, callback, optional); }, 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) { this.getProvisioningState = function getProvisioningState(callback) {
var optional = []; var optional = [];
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); } for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }

View File

@ -23,15 +23,18 @@ function amt_heci() {
this._ObjectID = "pthi"; this._ObjectID = "pthi";
this._rq = new Q(); this._rq = new Q();
this._setupPTHI = function _setupPTHI() { this._setupPTHI = function _setupPTHI()
{
this._amt = heci.create(); this._amt = heci.create();
this._amt.BiosVersionLen = 65; this._amt.BiosVersionLen = 65;
this._amt.UnicodeStringLen = 20; this._amt.UnicodeStringLen = 20;
this._amt.Parent = this; this._amt.Parent = this;
this._amt.on('error', function _amtOnError(e) { this.Parent.emit('error', e); }); this._amt.on('error', function _amtOnError(e) { this.Parent.emit('error', e); });
this._amt.on('connect', function _amtOnConnect() { this._amt.on('connect', function _amtOnConnect()
this.on('data', function _amtOnData(chunk) { {
this.on('data', function _amtOnData(chunk)
{
//console.log("Received: " + chunk.length + " bytes"); //console.log("Received: " + chunk.length + " bytes");
var header = this.Parent.getCommand(chunk); var header = this.Parent.getCommand(chunk);
//console.log("CMD = " + header.Command + " (Status: " + header.Status + ") Response = " + header.IsResponse); //console.log("CMD = " + header.Command + " (Status: " + header.Status + ") Response = " + header.IsResponse);
@ -43,12 +46,14 @@ function amt_heci() {
params.unshift(header); params.unshift(header);
callback.apply(this.Parent, params); callback.apply(this.Parent, params);
if (this.Parent._rq.isEmpty()) { if(this.Parent._rq.isEmpty())
{
// No More Requests, we can close PTHI // No More Requests, we can close PTHI
this.Parent._amt.disconnect(); this.Parent._amt.disconnect();
this.Parent._amt = null; this.Parent._amt = null;
} }
else { else
{
// Send the next request // Send the next request
this.write(this.Parent._rq.peekQueue().send); this.write(this.Parent._rq.peekQueue().send);
} }
@ -73,9 +78,10 @@ function amt_heci() {
var header = Buffer.from('010100000000000000000000', 'hex'); var header = Buffer.from('010100000000000000000000', 'hex');
header.writeUInt32LE(arguments[0] | 0x04000000, 4); header.writeUInt32LE(arguments[0] | 0x04000000, 4);
header.writeUInt32LE(arguments[1] == null ? 0 : arguments[1].length, 8); 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._setupPTHI();
this._amt.connect(heci.GUIDS.AMT, { noPipeline: 1 }); this._amt.connect(heci.GUIDS.AMT, { noPipeline: 1 });
} }
@ -87,7 +93,7 @@ function amt_heci() {
this.sendCommand(26, null, function (header, fn, opt) { this.sendCommand(26, null, function (header, fn, opt) {
if (header.Status == 0) { 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); 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() }; 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)); v = v.slice(4 + (2 * this._amt.UnicodeStringLen));
} }
@ -99,6 +105,34 @@ function amt_heci() {
}, callback, optional); }, 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) { this.getProvisioningState = function getProvisioningState(callback) {
var optional = []; var optional = [];
for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); } for (var i = 1; i < arguments.length; ++i) { optional.push(arguments[i]); }
@ -248,6 +282,46 @@ function amt_heci() {
fn.apply(this, opt); fn.apply(this, opt);
}, callback, optional); }, 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) { this.unprovision = function unprovision(mode, callback) {
var optional = []; var optional = [];
for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); } for (var i = 2; i < arguments.length; ++i) { optional.push(arguments[i]); }

1
db.js
View File

@ -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.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.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.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. // 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 }); }); } 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 }); }); }

View File

@ -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.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.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.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 (mesh.mtype == 2) {
if (device.host != obj.remoteaddr) { device.host = obj.remoteaddr; change = 1; changes.push('host'); } if (device.host != obj.remoteaddr) { device.host = obj.remoteaddr; change = 1; changes.push('host'); }

View File

@ -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); } //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 // 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.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.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; } } if (obj.args.port == null || typeof obj.args.port != 'number') { if (obj.args.notls == null) { obj.args.port = 443; } else { obj.args.port = 80; } }

View File

@ -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) { obj.parent.authenticate(req.query.user, req.query.pass, obj.domain, function (err, userid, passhint) {
if (userid != null) { if (userid != null) {
obj.authenticated = true; 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 ((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. 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) }; 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) };

View File

@ -167,7 +167,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
case 'files': case 'files':
{ {
// Send the full list of server files to the browser app // 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; break;
} }
case 'fileoperation': case 'fileoperation':
@ -205,7 +205,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain) {
if (agent != null) { if (agent != null) {
// Check if we have permission to send a message to that node // Check if we have permission to send a message to that node
var rights = user.links[agent.dbMeshKey]; 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.sessionid = ws.sessionId; // Set the session id, required for responses.
command.rights = rights.rights; // Add user rights flags to the message command.rights = rights.rights; // Add user rights flags to the message
delete command.nodeid; // Remove the nodeid since it's implyed. 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) { if (routing != null) {
// Check if we have permission to send a message to that node // Check if we have permission to send a message to that node
var rights = user.links[routing.meshid]; 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.fromSessionid = ws.sessionId; // Set the session id, required for responses.
command.rights = rights.rights; // Add user rights flags to the message command.rights = rights.rights; // Add user rights flags to the message
obj.parent.parent.multiServer.DispatchMessageSingleServer(command, routing.serverid); obj.parent.parent.multiServer.DispatchMessageSingleServer(command, routing.serverid);

View File

@ -227,44 +227,75 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
obj.db.GetAllType('mesh', function (err, docs) { obj.db.GetAllType('mesh', function (err, docs) {
var mesh = null; var mesh = null;
for (var i in docs) { if (docs[i]._id.indexOf(meshIdStart) > 0) { mesh = docs[i]; break; } } 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 // If this is a agent-less mesh, use the device guid 3 times as ID.
var systemid = socket.tag.SystemId.split('-').join(''); if (mesh.mtype == 1) {
var nodeid = new Buffer(systemid + systemid + systemid, 'hex').toString('base64').replace(/\+/g, '@').replace(/\//g, '$'); // Intel AMT GUID (socket.tag.SystemId) will be used as NodeID
socket.tag.name = ''; var systemid = socket.tag.SystemId.split('-').join('');
socket.tag.nodeid = 'node/' + mesh.domain + '/' + nodeid; // Turn 16bit systemid guid into 48bit nodeid that is base64 encoded var nodeid = new Buffer(systemid + systemid + systemid, 'hex').toString('base64').replace(/\+/g, '@').replace(/\//g, '$');
socket.tag.meshid = mesh._id; 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) { obj.db.Get(socket.tag.nodeid, function (err, nodes) {
if (nodes.length == 0) { if (nodes.length == 0) {
if (mesh.mtype == 1) { if (mesh.mtype == 1) {
// Node is not in the database, add it. Credentials will be empty until added by the user. // 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 } }; 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.Set(device);
// Event the new node // Event the new node
var device2 = common.Clone(device); var device2 = common.Clone(device);
if (device2.intelamt.pass != undefined) delete device2.intelamt.pass; // Remove the Intel AMT password before eventing this. 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; 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 }) 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 { } 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. // 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(); socket.end();
return; return;
} }
} else {
// Node is already present // Node is present
var node = nodes[0]; var node = nodes[0];
if (node.intelamt != undefined) { socket.tag.host = node.intelamt.host; } 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 // Add the connection to the MPS connection list
obj.ciraConnections[socket.tag.nodeid] = socket; 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. 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 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; return 18 + usernameLen + serviceNameLen + methodNameLen + passwordLen;
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "meshcentral", "name": "meshcentral",
"version": "0.1.5-e", "version": "0.1.5-k",
"keywords": [ "keywords": [
"Remote Management", "Remote Management",
"Intel AMT", "Intel AMT",

View File

@ -159,7 +159,7 @@ var CreateAgentRemoteDesktop = function (canvasid, scrolldiv) {
} }
obj.ProcessScreenMsg = function (width, height) { 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.Canvas.setTransform(1, 0, 0, 1, 0, 0);
obj.rotation = 0; obj.rotation = 0;
obj.FirstDraw = true; obj.FirstDraw = true;

View File

@ -1468,10 +1468,10 @@
function getMeshActions(mesh, meshrights) { function getMeshActions(mesh, meshrights) {
if ((meshrights & 4) == 0) return ''; if ((meshrights & 4) == 0) return '';
var r = ''; var r = '';
if ((features & 2) == 0) { // If not LAN-Only
r += ' <a style=cursor:pointer;font-size:10px title="Add a new Intel&reg; AMT computer that is located on the internet." onclick=addCiraDeviceToMesh(\"' + mesh._id + '\")>Add CIRA</a>';
}
if (mesh.mtype == 1) { 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&reg; AMT computer that is located on the internet." onclick=addCiraDeviceToMesh(\"' + mesh._id + '\")>Add CIRA</a>';
}
if ((features & 1) == 0) { // If not WAN-Only if ((features & 1) == 0) { // If not WAN-Only
r += ' <a style=cursor:pointer;font-size:10px title="Add a new Intel&reg; 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&reg; 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&reg; AMT computer by scanning the local network." onclick=addAmtScanToMesh(\"' + mesh._id + '\")>Scan Network</a>'; r += ' <a style=cursor:pointer;font-size:10px title="Add a new Intel&reg; 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>&nbsp;'; if (mesh.mtype == 2) x += '<a style=cursor:pointer onclick=p10showNodeNetInfoDialog("' + node._id + '") title="Show device network interface information">Interfaces</a>&nbsp;';
if (xxmap != null) x += '<a style=cursor:pointer onclick=p10showNodeLocationDialog("' + node._id + '") title="Show device locations information">Location</a>&nbsp;'; if (xxmap != null) x += '<a style=cursor:pointer onclick=p10showNodeLocationDialog("' + node._id + '") title="Show device locations information">Location</a>&nbsp;';
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>&nbsp;'; 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>&nbsp;';
// RDP link, show this link only of the remote machine is Windows. // RDP link, show this link only of the remote machine is Windows.
if (((connectivity & 1) != 0) && (clickOnce == true) && (mesh.mtype == 2) && ((meshrights & 8) != 0)) { if (((connectivity & 1) != 0) && (clickOnce == true) && (mesh.mtype == 2) && ((meshrights & 8) != 0)) {
@ -2616,11 +2616,11 @@
// Show or hide the tabs // Show or hide the tabs
// mesh.mtype: 1 = Intel AMT only, 2 = Mesh Agent // mesh.mtype: 1 = Intel AMT only, 2 = Mesh Agent
// node.agent.caps (bitmask): 1 = Desktop, 2 = Terminal, 4 = Files, 8 = Console // 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('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)); 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))); QV('MainDevFiles', ((mesh.mtype == 2) && ((node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 4) != 0))) && (meshrights & 8));
QV('MainDevAmt', node.intelamt != null); 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))); 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)); 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:''); QH('p15coreName', ((node.agent != null) && (node.agent.core != null))?node.agent.core:'');
@ -4041,8 +4041,12 @@
c++; c++;
count++; count++;
// Mesh // Mesh rights
var rights = 'Administrator'; // TODO 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>'; 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'; if ((meshrights & 64) != 0) r += ', Wake Devices';
} }
r = r.substring(2); r = r.substring(2);
if (r == '') { r = 'No Rights'; }
var x = addHtmlValue('User Name', userid.split('/')[2]); var x = addHtmlValue('User Name', userid.split('/')[2]);
x += addHtmlValue('Permissions', r); x += addHtmlValue('Permissions', r);
var buttons = 1; var buttons = 1;

View File

@ -537,6 +537,22 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
obj.authenticate(user.name, req.body.apassword1, domain, function (err, userid) { obj.authenticate(user.name, req.body.apassword1, domain, function (err, userid) {
var user = obj.users[userid]; var user = obj.users[userid];
if (user) { 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); obj.db.Remove(user._id);
delete obj.users[user._id]; delete obj.users[user._id];
req.session.destroy(function () { res.redirect(domain.url); }); req.session.destroy(function () { res.redirect(domain.url); });