More access control improvements, RPi icon.

This commit is contained in:
Ylian Saint-Hilaire 2019-12-27 15:18:43 -08:00
parent e80acec96b
commit c3efdb39c1
16 changed files with 699 additions and 833 deletions

View File

@ -1919,13 +1919,10 @@ function createMeshCore(agent) {
switch (cmd) { switch (cmd) {
case 'help': { // Displays available commands case 'help': { // Displays available commands
var fin = '', f = '', availcommands = 'version,help,info,osinfo,args,print,type,dbkeys,dbget,dbset,dbcompact,eval,parseuri,httpget,nwslist,plugin,wsconnect,wssend,wsclose,notify,ls,ps,kill,amt,netinfo,location,power,wakeonlan,setdebug,smbios,rawsmbios,toast,lock,users,sendcaps,openurl,amtreset,amtccm,amtacm,amtdeactivate,amtpolicy,getscript,getclip,setclip,log,av,cpuinfo,sysinfo,apf,scanwifi,scanamt,wallpaper'; var fin = '', f = '', availcommands = 'version,help,info,osinfo,args,print,type,dbkeys,dbget,dbset,dbcompact,eval,parseuri,httpget,nwslist,plugin,wsconnect,wssend,wsclose,notify,ls,ps,kill,amt,netinfo,location,power,wakeonlan,setdebug,smbios,rawsmbios,toast,lock,users,sendcaps,openurl,amtreset,amtccm,amtacm,amtdeactivate,amtpolicy,getscript,getclip,setclip,log,av,cpuinfo,sysinfo,apf,scanwifi,scanamt,wallpaper';
if (process.platform == 'win32') if (process.platform == 'win32') { availcommands += ',safemode,wpfhwacceleration'; }
{
availcommands += ',safemode,wpfhwacceleration';
}
availcommands = availcommands.split(',').sort(); availcommands = availcommands.split(',').sort();
while (availcommands.length > 0) { while (availcommands.length > 0) {
if (f.length > 100) { fin += (f + ',\r\n'); f = ''; } if (f.length > 90) { fin += (f + ',\r\n'); f = ''; }
f += (((f != '') ? ', ' : ' ') + availcommands.shift()); f += (((f != '') ? ', ' : ' ') + availcommands.shift());
} }
if (f != '') { fin += f; } if (f != '') { fin += f; }

View File

@ -12,10 +12,10 @@
/*jshint node: true */ /*jshint node: true */
/*jshint strict: false */ /*jshint strict: false */
/*jshint esversion: 6 */ /*jshint esversion: 6 */
"use strict"; 'use strict';
const crypto = require("crypto"); const crypto = require('crypto');
const common = require("./common.js"); const common = require('./common.js');
var HttpInterceptorAuthentications = {}; var HttpInterceptorAuthentications = {};
//var RedirInterceptorAuthentications = {}; //var RedirInterceptorAuthentications = {};
@ -28,8 +28,8 @@ module.exports.CreateHttpInterceptor = function (args) {
obj.randomValueHex = function (len) { return crypto.randomBytes(Math.ceil(len / 2)).toString('hex').slice(0, len); }; obj.randomValueHex = function (len) { return crypto.randomBytes(Math.ceil(len / 2)).toString('hex').slice(0, len); };
obj.args = args; obj.args = args;
obj.amt = { acc: "", mode: 0, count: 0, error: false }; // mode: 0:Header, 1:LengthBody, 2:ChunkedBody, 3:UntilClose obj.amt = { acc: '', mode: 0, count: 0, error: false }; // mode: 0:Header, 1:LengthBody, 2:ChunkedBody, 3:UntilClose
obj.ws = { acc: "", mode: 0, count: 0, error: false, authCNonce: obj.randomValueHex(10), authCNonceCount: 1 }; obj.ws = { acc: '', mode: 0, count: 0, error: false, authCNonce: obj.randomValueHex(10), authCNonceCount: 1 };
obj.blockAmtStorage = false; obj.blockAmtStorage = false;
// Private method // Private method
@ -38,7 +38,7 @@ module.exports.CreateHttpInterceptor = function (args) {
// Process data coming from Intel AMT // Process data coming from Intel AMT
obj.processAmtData = function (data) { obj.processAmtData = function (data) {
obj.amt.acc += data; // Add data to accumulator obj.amt.acc += data; // Add data to accumulator
data = ""; data = '';
var datalen = 0; var datalen = 0;
do { do {
datalen = data.length; datalen = data.length;
@ -53,7 +53,7 @@ module.exports.CreateHttpInterceptor = function (args) {
if (obj.amt.mode == 0) { // Header Mode if (obj.amt.mode == 0) { // Header Mode
// Decode the HTTP header // Decode the HTTP header
headerend = obj.amt.acc.indexOf('\r\n\r\n'); headerend = obj.amt.acc.indexOf('\r\n\r\n');
if (headerend < 0) return ""; if (headerend < 0) return '';
var headerlines = obj.amt.acc.substring(0, headerend).split('\r\n'); var headerlines = obj.amt.acc.substring(0, headerend).split('\r\n');
obj.amt.acc = obj.amt.acc.substring(headerend + 4); obj.amt.acc = obj.amt.acc.substring(headerend + 4);
obj.amt.directive = headerlines[0].split(' '); obj.amt.directive = headerlines[0].split(' ');
@ -98,7 +98,7 @@ module.exports.CreateHttpInterceptor = function (args) {
} else if (obj.amt.mode == 2) { // Chunked Body Mode } else if (obj.amt.mode == 2) { // Chunked Body Mode
// Send data one chunk at a time // Send data one chunk at a time
headerend = obj.amt.acc.indexOf('\r\n'); headerend = obj.amt.acc.indexOf('\r\n');
if (headerend < 0) return ""; if (headerend < 0) return '';
var chunksize = parseInt(obj.amt.acc.substring(0, headerend), 16); var chunksize = parseInt(obj.amt.acc.substring(0, headerend), 16);
if ((chunksize == 0) && (obj.amt.acc.length >= headerend + 4)) { if ((chunksize == 0) && (obj.amt.acc.length >= headerend + 4)) {
// Send the ending chunk (NOTE: We do not support trailing headers) // Send the ending chunk (NOTE: We do not support trailing headers)
@ -114,16 +114,16 @@ module.exports.CreateHttpInterceptor = function (args) {
} }
} else if (obj.amt.mode == 3) { // Until Close Mode } else if (obj.amt.mode == 3) { // Until Close Mode
r = obj.amt.acc; r = obj.amt.acc;
obj.amt.acc = ""; obj.amt.acc = '';
return r; return r;
} }
return ""; return '';
}; };
// Process data coming from the Browser // Process data coming from the Browser
obj.processBrowserData = function (data) { obj.processBrowserData = function (data) {
obj.ws.acc += data; // Add data to accumulator obj.ws.acc += data; // Add data to accumulator
data = ""; data = '';
var datalen = 0; var datalen = 0;
do { do {
datalen = data.length; datalen = data.length;
@ -138,7 +138,7 @@ module.exports.CreateHttpInterceptor = function (args) {
if (obj.ws.mode == 0) { // Header Mode if (obj.ws.mode == 0) { // Header Mode
// Decode the HTTP header // Decode the HTTP header
headerend = obj.ws.acc.indexOf('\r\n\r\n'); headerend = obj.ws.acc.indexOf('\r\n\r\n');
if (headerend < 0) return ""; if (headerend < 0) return '';
var headerlines = obj.ws.acc.substring(0, headerend).split('\r\n'); var headerlines = obj.ws.acc.substring(0, headerend).split('\r\n');
obj.ws.acc = obj.ws.acc.substring(headerend + 4); obj.ws.acc = obj.ws.acc.substring(headerend + 4);
obj.ws.directive = headerlines[0].split(' '); obj.ws.directive = headerlines[0].split(' ');
@ -199,7 +199,7 @@ module.exports.CreateHttpInterceptor = function (args) {
} else if (obj.amt.mode == 2) { // Chunked Body Mode } else if (obj.amt.mode == 2) { // Chunked Body Mode
// Send data one chunk at a time // Send data one chunk at a time
headerend = obj.amt.acc.indexOf('\r\n'); headerend = obj.amt.acc.indexOf('\r\n');
if (headerend < 0) return ""; if (headerend < 0) return '';
var chunksize = parseInt(obj.amt.acc.substring(0, headerend), 16); var chunksize = parseInt(obj.amt.acc.substring(0, headerend), 16);
if (isNaN(chunksize)) { // TODO: Check this path if (isNaN(chunksize)) { // TODO: Check this path
// Chunk is not in this batch, move one // Chunk is not in this batch, move one
@ -226,10 +226,10 @@ module.exports.CreateHttpInterceptor = function (args) {
} }
} else if (obj.ws.mode == 3) { // Until Close Mode } else if (obj.ws.mode == 3) { // Until Close Mode
r = obj.ws.acc; r = obj.ws.acc;
obj.ws.acc = ""; obj.ws.acc = '';
return r; return r;
} }
return ""; return '';
}; };
// Parse authentication values from the HTTP header // Parse authentication values from the HTTP header
@ -249,9 +249,9 @@ module.exports.CreateHttpInterceptor = function (args) {
// Compute the MD5 digest hash for a set of values // Compute the MD5 digest hash for a set of values
obj.ComputeDigesthash = function (username, password, realm, method, path, qop, nonce, nc, cnonce) { obj.ComputeDigesthash = function (username, password, realm, method, path, qop, nonce, nc, cnonce) {
var ha1 = crypto.createHash('md5').update(username + ":" + realm + ":" + password).digest("hex"); var ha1 = crypto.createHash('md5').update(username + ':' + realm + ':' + password).digest('hex');
var ha2 = crypto.createHash('md5').update(method + ":" + path).digest("hex"); var ha2 = crypto.createHash('md5').update(method + ':' + path).digest('hex');
return crypto.createHash('md5').update(ha1 + ":" + nonce + ":" + nc + ":" + cnonce + ":" + qop + ":" + ha2).digest("hex"); return crypto.createHash('md5').update(ha1 + ':' + nonce + ':' + nc + ':' + cnonce + ':' + qop + ':' + ha2).digest('hex');
}; };
return obj; return obj;
@ -266,8 +266,8 @@ module.exports.CreateRedirInterceptor = function (args) {
obj.randomValueHex = function (len) { return crypto.randomBytes(Math.ceil(len / 2)).toString('hex').slice(0, len); }; obj.randomValueHex = function (len) { return crypto.randomBytes(Math.ceil(len / 2)).toString('hex').slice(0, len); };
obj.args = args; obj.args = args;
obj.amt = { acc: "", mode: 0, count: 0, error: false, direct: false }; obj.amt = { acc: '', mode: 0, count: 0, error: false, direct: false };
obj.ws = { acc: "", mode: 0, count: 0, error: false, direct: false, authCNonce: obj.randomValueHex(10), authCNonceCount: 1 }; obj.ws = { acc: '', mode: 0, count: 0, error: false, direct: false, authCNonce: obj.randomValueHex(10), authCNonceCount: 1 };
obj.RedirectCommands = { StartRedirectionSession: 0x10, StartRedirectionSessionReply: 0x11, EndRedirectionSession: 0x12, AuthenticateSession: 0x13, AuthenticateSessionReply: 0x14 }; obj.RedirectCommands = { StartRedirectionSession: 0x10, StartRedirectionSessionReply: 0x11, EndRedirectionSession: 0x12, AuthenticateSession: 0x13, AuthenticateSessionReply: 0x14 };
obj.StartRedirectionSessionReplyStatus = { SUCCESS: 0, TYPE_UNKNOWN: 1, BUSY: 2, UNSUPPORTED: 3, ERROR: 0xFF }; obj.StartRedirectionSessionReplyStatus = { SUCCESS: 0, TYPE_UNKNOWN: 1, BUSY: 2, UNSUPPORTED: 3, ERROR: 0xFF };
@ -280,7 +280,7 @@ module.exports.CreateRedirInterceptor = function (args) {
// Process data coming from Intel AMT // Process data coming from Intel AMT
obj.processAmtData = function (data) { obj.processAmtData = function (data) {
obj.amt.acc += data; // Add data to accumulator obj.amt.acc += data; // Add data to accumulator
data = ""; data = '';
var datalen = 0; var datalen = 0;
do { datalen = data.length; data += obj.processAmtDataEx(); } while (datalen != data.length); // Process as much data as possible do { datalen = data.length; data += obj.processAmtDataEx(); } while (datalen != data.length); // Process as much data as possible
return data; return data;
@ -298,11 +298,11 @@ module.exports.CreateRedirInterceptor = function (args) {
//console.log(obj.amt.acc.charCodeAt(0)); //console.log(obj.amt.acc.charCodeAt(0));
switch (obj.amt.acc.charCodeAt(0)) { switch (obj.amt.acc.charCodeAt(0)) {
case obj.RedirectCommands.StartRedirectionSessionReply: { case obj.RedirectCommands.StartRedirectionSessionReply: {
if (obj.amt.acc.length < 4) return ""; if (obj.amt.acc.length < 4) return '';
if (obj.amt.acc.charCodeAt(1) == obj.StartRedirectionSessionReplyStatus.SUCCESS) { if (obj.amt.acc.charCodeAt(1) == obj.StartRedirectionSessionReplyStatus.SUCCESS) {
if (obj.amt.acc.length < 13) return ""; if (obj.amt.acc.length < 13) return '';
var oemlen = obj.amt.acc.charCodeAt(12); var oemlen = obj.amt.acc.charCodeAt(12);
if (obj.amt.acc.length < 13 + oemlen) return ""; if (obj.amt.acc.length < 13 + oemlen) return '';
r = obj.amt.acc.substring(0, 13 + oemlen); r = obj.amt.acc.substring(0, 13 + oemlen);
obj.amt.acc = obj.amt.acc.substring(13 + oemlen); obj.amt.acc = obj.amt.acc.substring(13 + oemlen);
return r; return r;
@ -310,9 +310,9 @@ module.exports.CreateRedirInterceptor = function (args) {
break; break;
} }
case obj.RedirectCommands.AuthenticateSessionReply: { case obj.RedirectCommands.AuthenticateSessionReply: {
if (obj.amt.acc.length < 9) return ""; if (obj.amt.acc.length < 9) return '';
var l = common.ReadIntX(obj.amt.acc, 5); var l = common.ReadIntX(obj.amt.acc, 5);
if (obj.amt.acc.length < 9 + l) return ""; if (obj.amt.acc.length < 9 + l) return '';
var authstatus = obj.amt.acc.charCodeAt(1); var authstatus = obj.amt.acc.charCodeAt(1);
var authType = obj.amt.acc.charCodeAt(4); var authType = obj.amt.acc.charCodeAt(4);
@ -337,17 +337,17 @@ module.exports.CreateRedirInterceptor = function (args) {
} }
default: { default: {
obj.amt.error = true; obj.amt.error = true;
return ""; return '';
} }
} }
} }
return ""; return '';
}; };
// Process data coming from the Browser // Process data coming from the Browser
obj.processBrowserData = function (data) { obj.processBrowserData = function (data) {
obj.ws.acc += data; // Add data to accumulator obj.ws.acc += data; // Add data to accumulator
data = ""; data = '';
var datalen = 0; var datalen = 0;
do { datalen = data.length; data += obj.processBrowserDataEx(); } while (datalen != data.length); // Process as much data as possible do { datalen = data.length; data += obj.processBrowserDataEx(); } while (datalen != data.length); // Process as much data as possible
return data; return data;
@ -356,39 +356,39 @@ module.exports.CreateRedirInterceptor = function (args) {
// Process data coming from the Browser in the accumulator // Process data coming from the Browser in the accumulator
obj.processBrowserDataEx = function () { obj.processBrowserDataEx = function () {
var r; var r;
if (obj.ws.acc.length == 0) return ""; if (obj.ws.acc.length == 0) return '';
if (obj.ws.direct == true) { if (obj.ws.direct == true) {
var data = obj.ws.acc; var data = obj.ws.acc;
obj.ws.acc = ""; obj.ws.acc = '';
return data; return data;
} else { } else {
switch (obj.ws.acc.charCodeAt(0)) { switch (obj.ws.acc.charCodeAt(0)) {
case obj.RedirectCommands.StartRedirectionSession: { case obj.RedirectCommands.StartRedirectionSession: {
if (obj.ws.acc.length < 8) return ""; if (obj.ws.acc.length < 8) return '';
r = obj.ws.acc.substring(0, 8); r = obj.ws.acc.substring(0, 8);
obj.ws.acc = obj.ws.acc.substring(8); obj.ws.acc = obj.ws.acc.substring(8);
return r; return r;
} }
case obj.RedirectCommands.EndRedirectionSession: { case obj.RedirectCommands.EndRedirectionSession: {
if (obj.ws.acc.length < 4) return ""; if (obj.ws.acc.length < 4) return '';
r = obj.ws.acc.substring(0, 4); r = obj.ws.acc.substring(0, 4);
obj.ws.acc = obj.ws.acc.substring(4); obj.ws.acc = obj.ws.acc.substring(4);
return r; return r;
} }
case obj.RedirectCommands.AuthenticateSession: { case obj.RedirectCommands.AuthenticateSession: {
if (obj.ws.acc.length < 9) return ""; if (obj.ws.acc.length < 9) return '';
var l = common.ReadIntX(obj.ws.acc, 5); var l = common.ReadIntX(obj.ws.acc, 5);
if (obj.ws.acc.length < 9 + l) return ""; if (obj.ws.acc.length < 9 + l) return '';
var authType = obj.ws.acc.charCodeAt(4); var authType = obj.ws.acc.charCodeAt(4);
if (authType == obj.AuthenticationType.DIGEST && obj.args.user && obj.args.pass) { if (authType == obj.AuthenticationType.DIGEST && obj.args.user && obj.args.pass) {
var authurl = "/RedirectionService"; var authurl = '/RedirectionService';
if (obj.amt.digestRealm) { if (obj.amt.digestRealm) {
// Replace this authentication digest with a server created one // Replace this authentication digest with a server created one
// We have everything we need to authenticate // We have everything we need to authenticate
var nc = obj.ws.authCNonceCount; var nc = obj.ws.authCNonceCount;
obj.ws.authCNonceCount++; obj.ws.authCNonceCount++;
var digest = obj.ComputeDigesthash(obj.args.user, obj.args.pass, obj.amt.digestRealm, "POST", authurl, obj.amt.digestQOP, obj.amt.digestNonce, nc, obj.ws.authCNonce); var digest = obj.ComputeDigesthash(obj.args.user, obj.args.pass, obj.amt.digestRealm, 'POST', authurl, obj.amt.digestQOP, obj.amt.digestNonce, nc, obj.ws.authCNonce);
// Replace this authentication digest with a server created one // Replace this authentication digest with a server created one
// We have everything we need to authenticate // We have everything we need to authenticate
@ -434,18 +434,18 @@ module.exports.CreateRedirInterceptor = function (args) {
} }
default: { default: {
obj.ws.error = true; obj.ws.error = true;
return ""; return '';
} }
} }
} }
return ""; return '';
}; };
// Compute the MD5 digest hash for a set of values // Compute the MD5 digest hash for a set of values
obj.ComputeDigesthash = function (username, password, realm, method, path, qop, nonce, nc, cnonce) { obj.ComputeDigesthash = function (username, password, realm, method, path, qop, nonce, nc, cnonce) {
var ha1 = crypto.createHash('md5').update(username + ":" + realm + ":" + password).digest("hex"); var ha1 = crypto.createHash('md5').update(username + ':' + realm + ':' + password).digest('hex');
var ha2 = crypto.createHash('md5').update(method + ":" + path).digest("hex"); var ha2 = crypto.createHash('md5').update(method + ':' + path).digest('hex');
return crypto.createHash('md5').update(ha1 + ":" + nonce + ":" + nc + ":" + cnonce + ":" + qop + ":" + ha2).digest("hex"); return crypto.createHash('md5').update(ha1 + ':' + nonce + ':' + nc + ':' + cnonce + ':' + qop + ':' + ha2).digest('hex');
}; };
return obj; return obj;

View File

@ -80,7 +80,7 @@ module.exports.CreateMeshRelay = function (parent, ws, req, domain, user, cookie
var agent = parent.wsagents[command.nodeid]; var agent = parent.wsagents[command.nodeid];
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
rights = user.links[agent.dbMeshKey]; rights = user.links[agent.dbMeshKey]; // TODO: Need to include user group / node rights
mesh = parent.meshes[agent.dbMeshKey]; mesh = parent.meshes[agent.dbMeshKey];
if ((rights != null) && (mesh != null) || ((rights & 16) != 0)) { // TODO: 16 is console permission, may need more gradular permission checking if ((rights != null) && (mesh != null) || ((rights & 16) != 0)) { // TODO: 16 is console permission, may need more gradular permission checking
if (ws.sessionId) { command.sessionid = ws.sessionId; } // Set the session id, required for responses. if (ws.sessionId) { command.sessionid = ws.sessionId; } // Set the session id, required for responses.
@ -98,7 +98,7 @@ module.exports.CreateMeshRelay = function (parent, ws, req, domain, user, cookie
var routing = parent.parent.GetRoutingServerId(command.nodeid, 1); // 1 = MeshAgent routing type var routing = parent.parent.GetRoutingServerId(command.nodeid, 1); // 1 = MeshAgent routing type
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
rights = user.links[routing.meshid]; rights = user.links[routing.meshid]; // TODO: Need to include user groups / node rights
mesh = parent.meshes[routing.meshid]; mesh = parent.meshes[routing.meshid];
if (rights != null || ((rights & 16) != 0)) { // TODO: 16 is console permission, may need more gradular permission checking if (rights != null || ((rights & 16) != 0)) { // TODO: 16 is console permission, may need more gradular permission checking
if (ws.sessionId) { command.fromSessionid = ws.sessionId; } // Set the session id, required for responses. if (ws.sessionId) { command.fromSessionid = ws.sessionId; } // Set the session id, required for responses.

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,7 @@
/*jshint strict:false */ /*jshint strict:false */
/*jshint -W097 */ /*jshint -W097 */
/*jshint esversion: 6 */ /*jshint esversion: 6 */
"use strict"; 'use strict';
// Construct a Intel AMT MPS server object // Construct a Intel AMT MPS server object
module.exports.CreateMpsServer = function (parent, db, args, certificates) { module.exports.CreateMpsServer = function (parent, db, args, certificates) {
@ -24,9 +24,9 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
var tlsSessionStore = {}; // Store TLS session information for quick resume. var tlsSessionStore = {}; // Store TLS session information for quick resume.
var tlsSessionStoreCount = 0; // Number of cached TLS session information in store. var tlsSessionStoreCount = 0; // Number of cached TLS session information in store.
const constants = (require('crypto').constants ? require('crypto').constants : require('constants')); // require('constants') is deprecated in Node 11.10, use require('crypto').constants instead. const constants = (require('crypto').constants ? require('crypto').constants : require('constants')); // require('constants') is deprecated in Node 11.10, use require('crypto').constants instead.
const common = require("./common.js"); const common = require('./common.js');
const net = require("net"); const net = require('net');
const tls = require("tls"); const tls = require('tls');
const MAX_IDLE = 90000; // 90 seconds max idle time, higher than the typical KEEP-ALIVE periode of 60 seconds const MAX_IDLE = 90000; // 90 seconds max idle time, higher than the typical KEEP-ALIVE periode of 60 seconds
if (obj.args.mpstlsoffload) { if (obj.args.mpstlsoffload) {
@ -42,9 +42,9 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
obj.server.listen(args.mpsport, function () { console.log("MeshCentral Intel(R) AMT server running on " + certificates.AmtMpsName + ":" + args.mpsport + ((args.mpsaliasport != null) ? (", alias port " + args.mpsaliasport) : "") + "."); }).on("error", function (err) { console.error("ERROR: MeshCentral Intel(R) AMT server port " + args.mpsport + " is not available."); if (args.exactports) { process.exit(); } }); obj.server.listen(args.mpsport, function () { console.log("MeshCentral Intel(R) AMT server running on " + certificates.AmtMpsName + ":" + args.mpsport + ((args.mpsaliasport != null) ? (", alias port " + args.mpsaliasport) : "") + "."); }).on("error", function (err) { console.error("ERROR: MeshCentral Intel(R) AMT server port " + args.mpsport + " is not available."); if (args.exactports) { process.exit(); } });
obj.server.on('tlsClientError', function (err, tlssocket) { if (args.mpsdebug) { var remoteAddress = tlssocket.remoteAddress; if (tlssocket.remoteFamily == 'IPv6') { remoteAddress = '[' + remoteAddress + ']'; } console.log('MPS:Invalid TLS connection from ' + remoteAddress + ':' + tlssocket.remotePort + '.'); } }); obj.server.on('tlsClientError', function (err, tlssocket) { if (args.mpsdebug) { var remoteAddress = tlssocket.remoteAddress; if (tlssocket.remoteFamily == 'IPv6') { remoteAddress = '[' + remoteAddress + ']'; } console.log('MPS:Invalid TLS connection from ' + remoteAddress + ':' + tlssocket.remotePort + '.'); } });
obj.parent.updateServerState("mps-port", args.mpsport); obj.parent.updateServerState('mps-port', args.mpsport);
obj.parent.updateServerState("mps-name", certificates.AmtMpsName); obj.parent.updateServerState('mps-name', certificates.AmtMpsName);
if (args.mpsaliasport != null) { obj.parent.updateServerState("mps-alias-port", args.mpsaliasport); } if (args.mpsaliasport != null) { obj.parent.updateServerState('mps-alias-port', args.mpsaliasport); }
const APFProtocol = { const APFProtocol = {
UNKNOWN: 0, UNKNOWN: 0,
@ -202,47 +202,47 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
function onConnection(socket) { function onConnection(socket) {
connectionCount++; connectionCount++;
if (obj.args.mpstlsoffload) { if (obj.args.mpstlsoffload) {
socket.tag = { first: true, clientCert: null, accumulator: "", activetunnels: 0, boundPorts: [], socket: socket, host: null, nextchannelid: 4, channels: {}, nextsourceport: 0 }; socket.tag = { first: true, clientCert: null, accumulator: '', activetunnels: 0, boundPorts: [], socket: socket, host: null, nextchannelid: 4, channels: {}, nextsourceport: 0 };
} else { } else {
socket.tag = { first: true, clientCert: socket.getPeerCertificate(true), accumulator: "", activetunnels: 0, boundPorts: [], socket: socket, host: null, nextchannelid: 4, channels: {}, nextsourceport: 0 }; socket.tag = { first: true, clientCert: socket.getPeerCertificate(true), accumulator: '', activetunnels: 0, boundPorts: [], socket: socket, host: null, nextchannelid: 4, channels: {}, nextsourceport: 0 };
} }
socket.setEncoding("binary"); socket.setEncoding('binary');
parent.debug('mps', "New CIRA connection"); parent.debug('mps', "New CIRA connection");
// Setup the CIRA keep alive timer // Setup the CIRA keep alive timer
socket.setTimeout(MAX_IDLE); socket.setTimeout(MAX_IDLE);
socket.on("timeout", () => { ciraTimeoutCount++; parent.debug('mps', "CIRA timeout, disconnecting."); try { socket.end(); } catch (e) { } }); socket.on('timeout', () => { ciraTimeoutCount++; parent.debug('mps', "CIRA timeout, disconnecting."); try { socket.end(); } catch (e) { } });
socket.addListener("data", function (data) { socket.addListener('data', function (data) {
if (args.mpsdebug) { var buf = Buffer.from(data, "binary"); console.log("MPS <-- (" + buf.length + "):" + buf.toString('hex')); } // Print out received bytes if (args.mpsdebug) { var buf = Buffer.from(data, 'binary'); console.log("MPS <-- (" + buf.length + "):" + buf.toString('hex')); } // Print out received bytes
socket.tag.accumulator += data; socket.tag.accumulator += data;
// Detect if this is an HTTPS request, if it is, return a simple answer and disconnect. This is useful for debugging access to the MPS port. // Detect if this is an HTTPS request, if it is, return a simple answer and disconnect. This is useful for debugging access to the MPS port.
if (socket.tag.first == true) { if (socket.tag.first == true) {
if (socket.tag.accumulator.length < 3) return; if (socket.tag.accumulator.length < 3) return;
//if (!socket.tag.clientCert.subject) { console.log("MPS Connection, no client cert: " + socket.remoteAddress); socket.write('HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nConnection: close\r\n\r\nMeshCentral2 MPS server.\r\nNo client certificate given.'); socket.end(); return; } //if (!socket.tag.clientCert.subject) { console.log("MPS Connection, no client cert: " + socket.remoteAddress); socket.write('HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nConnection: close\r\n\r\nMeshCentral2 MPS server.\r\nNo client certificate given.'); socket.end(); return; }
if (socket.tag.accumulator.substring(0, 3) == "GET") { if (args.mpsdebug) { console.log("MPS Connection, HTTP GET detected: " + socket.remoteAddress); } socket.write("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n<!DOCTYPE html><html><head><meta charset=\"UTF-8\"></head><body>MeshCentral2 MPS server.<br />Intel&reg; AMT computers should connect here.</body></html>"); socket.end(); return; } if (socket.tag.accumulator.substring(0, 3) == 'GET') { if (args.mpsdebug) { console.log("MPS Connection, HTTP GET detected: " + socket.remoteAddress); } socket.write("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n<!DOCTYPE html><html><head><meta charset=\"UTF-8\"></head><body>MeshCentral2 MPS server.<br />Intel&reg; AMT computers should connect here.</body></html>"); socket.end(); return; }
// If the MQTT broker is active, look for inbound MQTT connections // If the MQTT broker is active, look for inbound MQTT connections
if (parent.mqttbroker != null) { if (parent.mqttbroker != null) {
var chunk = Buffer.from(socket.tag.accumulator, "binary"); var chunk = Buffer.from(socket.tag.accumulator, 'binary');
var packet_len = 0; var packet_len = 0;
if (chunk.readUInt8(0) == 16) { packet_len = getMQTTPacketLength(chunk); } if (chunk.readUInt8(0) == 16) { packet_len = getMQTTPacketLength(chunk); }
if (chunk.readUInt8(0) == 16 && (socket.tag.accumulator.length < packet_len)) return; // Minimum MQTT detection if (chunk.readUInt8(0) == 16 && (socket.tag.accumulator.length < packet_len)) return; // Minimum MQTT detection
// check if it is MQTT, need more initial packet to probe // check if it is MQTT, need more initial packet to probe
if (chunk.readUInt8(0) == 16 && ((chunk.slice(4, 8).toString() === "MQTT") || (chunk.slice(5, 9).toString() === "MQTT") if (chunk.readUInt8(0) == 16 && ((chunk.slice(4, 8).toString() === 'MQTT') || (chunk.slice(5, 9).toString() === 'MQTT')
|| (chunk.slice(6, 10).toString() === "MQTT") || (chunk.slice(7, 11).toString() === "MQTT"))) { || (chunk.slice(6, 10).toString() === 'MQTT') || (chunk.slice(7, 11).toString() === 'MQTT'))) {
parent.debug("mps", "MQTT connection detected."); parent.debug('mps', "MQTT connection detected.");
socket.removeAllListeners("data"); socket.removeAllListeners("data");
socket.removeAllListeners("close"); socket.removeAllListeners("close");
socket.setNoDelay(true); socket.setNoDelay(true);
socket.serialtunnel = SerialTunnel(); socket.serialtunnel = SerialTunnel();
socket.serialtunnel.xtransport = 'mps'; socket.serialtunnel.xtransport = 'mps';
socket.serialtunnel.xip = socket.remoteAddress; socket.serialtunnel.xip = socket.remoteAddress;
socket.on("data", function (b) { socket.serialtunnel.updateBuffer(Buffer.from(b, "binary")) }); socket.on('data', function (b) { socket.serialtunnel.updateBuffer(Buffer.from(b, 'binary')) });
socket.serialtunnel.forwardwrite = function (b) { socket.write(b, "binary") } socket.serialtunnel.forwardwrite = function (b) { socket.write(b, 'binary') }
socket.on("close", function () { socket.serialtunnel.emit("end"); }); socket.on('close', function () { socket.serialtunnel.emit('end'); });
// Pass socket wrapper to the MQTT broker // Pass socket wrapper to the MQTT broker
parent.mqttbroker.handle(socket.serialtunnel); parent.mqttbroker.handle(socket.serialtunnel);
@ -533,7 +533,7 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
var request = data.substring(5, 5 + requestLen); var request = data.substring(5, 5 + requestLen);
//var wantResponse = data.charCodeAt(5 + requestLen); //var wantResponse = data.charCodeAt(5 + requestLen);
if (request == "tcpip-forward") { if (request == 'tcpip-forward') {
var addrLen = common.ReadInt(data, 6 + requestLen); var addrLen = common.ReadInt(data, 6 + requestLen);
if (len < 14 + requestLen + addrLen) return 0; if (len < 14 + requestLen + addrLen) return 0;
var addr = data.substring(10 + requestLen, 10 + requestLen + addrLen); var addr = data.substring(10 + requestLen, 10 + requestLen + addrLen);
@ -545,7 +545,7 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
return 14 + requestLen + addrLen; return 14 + requestLen + addrLen;
} }
if (request == "cancel-tcpip-forward") { if (request == 'cancel-tcpip-forward') {
var addrLen = common.ReadInt(data, 6 + requestLen); var addrLen = common.ReadInt(data, 6 + requestLen);
if (len < 14 + requestLen + addrLen) return 0; if (len < 14 + requestLen + addrLen) return 0;
var addr = data.substring(10 + requestLen, 10 + requestLen + addrLen); var addr = data.substring(10 + requestLen, 10 + requestLen + addrLen);
@ -557,7 +557,7 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
return 14 + requestLen + addrLen; return 14 + requestLen + addrLen;
} }
if (request == "udp-send-to@amt.intel.com") { if (request == 'udp-send-to@amt.intel.com') {
var addrLen = common.ReadInt(data, 6 + requestLen); var addrLen = common.ReadInt(data, 6 + requestLen);
if (len < 26 + requestLen + addrLen) return 0; if (len < 26 + requestLen + addrLen) return 0;
var addr = data.substring(10 + requestLen, 10 + requestLen + addrLen); var addr = data.substring(10 + requestLen, 10 + requestLen + addrLen);
@ -748,14 +748,14 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
} }
} }
socket.addListener("close", function () { socket.addListener('close', function () {
socketClosedCount++; socketClosedCount++;
parent.debug('mps', 'CIRA connection closed'); parent.debug('mps', 'CIRA connection closed');
try { delete obj.ciraConnections[socket.tag.nodeid]; } catch (e) { } try { delete obj.ciraConnections[socket.tag.nodeid]; } catch (e) { }
obj.parent.ClearConnectivityState(socket.tag.meshid, socket.tag.nodeid, 2); obj.parent.ClearConnectivityState(socket.tag.meshid, socket.tag.nodeid, 2);
}); });
socket.addListener("error", function () { socket.addListener('error', function () {
socketErrorCount++; socketErrorCount++;
//console.log("MPS Error: " + socket.remoteAddress); //console.log("MPS Error: " + socket.remoteAddress);
}); });
@ -802,7 +802,7 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
*/ */
function SendChannelOpen(socket, direct, channelid, windowsize, target, targetport, source, sourceport) { function SendChannelOpen(socket, direct, channelid, windowsize, target, targetport, source, sourceport) {
var connectionType = ((direct == true) ? "direct-tcpip" : "forwarded-tcpip"); var connectionType = ((direct == true) ? 'direct-tcpip' : 'forwarded-tcpip');
if ((target == null) || (target == null)) target = ''; // TODO: Reports of target being undefined that causes target.length to fail. This is a hack. if ((target == null) || (target == null)) target = ''; // TODO: Reports of target being undefined that causes target.length to fail. This is a hack.
Write(socket, String.fromCharCode(APFProtocol.CHANNEL_OPEN) + common.IntToStr(connectionType.length) + connectionType + common.IntToStr(channelid) + common.IntToStr(windowsize) + common.IntToStr(-1) + common.IntToStr(target.length) + target + common.IntToStr(targetport) + common.IntToStr(source.length) + source + common.IntToStr(sourceport)); Write(socket, String.fromCharCode(APFProtocol.CHANNEL_OPEN) + common.IntToStr(connectionType.length) + connectionType + common.IntToStr(channelid) + common.IntToStr(windowsize) + common.IntToStr(-1) + common.IntToStr(target.length) + target + common.IntToStr(targetport) + common.IntToStr(source.length) + source + common.IntToStr(sourceport));
} }
@ -837,11 +837,11 @@ module.exports.CreateMpsServer = function (parent, db, args, certificates) {
function Write(socket, data) { function Write(socket, data) {
if (args.mpsdebug) { if (args.mpsdebug) {
// Print out sent bytes // Print out sent bytes
var buf = Buffer.from(data, "binary"); var buf = Buffer.from(data, 'binary');
console.log('MPS --> (' + buf.length + '):' + buf.toString('hex')); console.log('MPS --> (' + buf.length + '):' + buf.toString('hex'));
socket.write(buf); socket.write(buf);
} else { } else {
socket.write(Buffer.from(data, "binary")); socket.write(Buffer.from(data, 'binary'));
} }
} }

View File

@ -11,7 +11,7 @@
/*jshint strict:false */ /*jshint strict:false */
/*jshint -W097 */ /*jshint -W097 */
/*jshint esversion: 6 */ /*jshint esversion: 6 */
"use strict"; 'use strict';
// Construct a Mesh Multi-Server object. This is used for MeshCentral-to-MeshCentral communication. // Construct a Mesh Multi-Server object. This is used for MeshCentral-to-MeshCentral communication.
module.exports.CreateMultiServer = function (parent, args) { module.exports.CreateMultiServer = function (parent, args) {
@ -552,14 +552,10 @@ module.exports.CreateMultiServer = function (parent, args) {
if (msg.fromNodeid != null) { msg.nodeid = msg.fromNodeid; delete msg.fromNodeid; } if (msg.fromNodeid != null) { msg.nodeid = msg.fromNodeid; delete msg.fromNodeid; }
var cmdstr = JSON.stringify(msg); var cmdstr = JSON.stringify(msg);
for (userid in obj.parent.webserver.wssessions) { // Find all connected users for this mesh and send the message for (userid in obj.parent.webserver.wssessions) { // Find all connected users for this mesh and send the message
var user = obj.parent.webserver.users[userid]; if (parent.webserver.GetMeshRights(userid, msg.meshid) != 0) { // TODO: Look at what rights are needed for message routing
if (user) { var sessions = obj.parent.webserver.wssessions[userid];
var rights = user.links[msg.meshid]; // Send the message to all users on this server
if (rights != null) { // TODO: Look at what rights are needed for message routing for (i in sessions) { sessions[i].send(cmdstr); }
var sessions = obj.parent.webserver.wssessions[userid];
// Send the message to all users on this server
for (i in sessions) { sessions[i].send(cmdstr); }
}
} }
} }
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "meshcentral", "name": "meshcentral",
"version": "0.4.6-p", "version": "0.4.6-q",
"keywords": [ "keywords": [
"Remote Management", "Remote Management",
"Intel AMT", "Intel AMT",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 46 KiB

View File

@ -1155,6 +1155,14 @@ a {
border: none; border: none;
} }
.i7 {
background: url(../images/icons50.png) -300px 0px;
height: 50px;
width: 50px;
cursor: pointer;
border: none;
}
.j1 { .j1 {
background: url(../images/icons16.png) 0px 0px; background: url(../images/icons16.png) 0px 0px;
height: 16px; height: 16px;
@ -1203,6 +1211,14 @@ a {
border: none; border: none;
} }
.j7 {
background: url(../images/icons16.png) -96px 0px;
height: 16px;
width: 16px;
cursor: pointer;
border: none;
}
.relayIcon16 { .relayIcon16 {
background: url(../images/icon-relay.png); background: url(../images/icon-relay.png);
height: 16px; height: 16px;
@ -1339,7 +1355,7 @@ a {
float: left; float: left;
} }
.si0 { .si1 {
background: url(../images/icons16.png) 0px 0px; background: url(../images/icons16.png) 0px 0px;
height: 16px; height: 16px;
width: 16px; width: 16px;
@ -1347,7 +1363,7 @@ a {
float: left; float: left;
} }
.si1 { .si2 {
background: url(../images/icons16.png) -16px 0px; background: url(../images/icons16.png) -16px 0px;
height: 16px; height: 16px;
width: 16px; width: 16px;
@ -1355,7 +1371,7 @@ a {
float: left; float: left;
} }
.si2 { .si3 {
background: url(../images/icons16.png) -32px 0px; background: url(../images/icons16.png) -32px 0px;
height: 16px; height: 16px;
width: 16px; width: 16px;
@ -1363,7 +1379,7 @@ a {
float: left; float: left;
} }
.si3 { .si4 {
background: url(../images/icons16.png) -48px 0px; background: url(../images/icons16.png) -48px 0px;
height: 16px; height: 16px;
width: 16px; width: 16px;
@ -1371,7 +1387,7 @@ a {
float: left; float: left;
} }
.si4 { .si5 {
background: url(../images/icons16.png) -64px 0px; background: url(../images/icons16.png) -64px 0px;
height: 16px; height: 16px;
width: 16px; width: 16px;
@ -1379,7 +1395,7 @@ a {
float: left; float: left;
} }
.si5 { .si6 {
background: url(../images/icons16.png) -80px 0px; background: url(../images/icons16.png) -80px 0px;
height: 16px; height: 16px;
width: 16px; width: 16px;
@ -1387,6 +1403,14 @@ a {
float: left; float: left;
} }
.si7 {
background: url(../images/icons16.png) -96px 0px;
height: 16px;
width: 16px;
border: none;
float: left;
}
.mi { .mi {
background: url(../images/meshicon50.png) 0px 0px; background: url(../images/meshicon50.png) 0px 0px;
height: 50px; height: 50px;

View File

@ -8,8 +8,7 @@
"nl": "0", "nl": "0",
"xloc": [ "xloc": [
"default.handlebars->container->masthead->7->notificationCount", "default.handlebars->container->masthead->7->notificationCount",
"default-mobile.handlebars->9->229", "default-mobile.handlebars->9->229"
{ "$ref": "#" }
] ]
}, },
{ {
@ -5610,7 +5609,7 @@
{ {
"en": "free", "en": "free",
"fr": "libre", "fr": "libre",
"pt": "Livre", "pt": "livre",
"ja": "無料", "ja": "無料",
"cs": "volné", "cs": "volné",
"nl": "vrij", "nl": "vrij",

View File

@ -1327,7 +1327,7 @@
count++; count++;
// Mesh rights // Mesh rights
var meshrights = meshes[i].links[userinfo._id].rights; var meshrights = GetMeshRights(meshes[i]);
var rights = "Partial Rights"; var rights = "Partial Rights";
if (meshrights == 0xFFFFFFFF) rights = "Full Administrator"; else if (meshrights == 0) rights = "No Rights"; if (meshrights == 0xFFFFFFFF) rights = "Full Administrator"; else if (meshrights == 0) rights = "No Rights";
@ -1576,8 +1576,7 @@
if (desktop && !xxdialogMode && xxcurrentView == 10) { if (desktop && !xxdialogMode && xxcurrentView == 10) {
// Check what keys we are allows to send // Check what keys we are allows to send
if (currentNode != null) { if (currentNode != null) {
var mesh = meshes[currentNode.meshid]; var meshrights = GetMeshRights(currentNode.meshid);
var meshrights = mesh.links[userinfo._id].rights;
var inputAllowed = ((meshrights == 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0))); var inputAllowed = ((meshrights == 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0)));
if (inputAllowed == false) return false; if (inputAllowed == false) return false;
var limitedInputAllowed = ((meshrights != 0xFFFFFFFF) && (((meshrights & 8) != 0) && ((meshrights & 256) == 0) && ((meshrights & 4096) != 0))); var limitedInputAllowed = ((meshrights != 0xFFFFFFFF) && (((meshrights & 8) != 0) && ((meshrights & 256) == 0) && ((meshrights & 4096) != 0)));
@ -1594,8 +1593,7 @@
if (desktop && !xxdialogMode && xxcurrentView == 10) { if (desktop && !xxdialogMode && xxcurrentView == 10) {
// Check what keys we are allows to send // Check what keys we are allows to send
if (currentNode != null) { if (currentNode != null) {
var mesh = meshes[currentNode.meshid]; var meshrights = GetMeshRights(currentNode.meshid);
var meshrights = mesh.links[userinfo._id].rights;
var inputAllowed = ((meshrights == 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0))); var inputAllowed = ((meshrights == 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0)));
if (inputAllowed == false) return false; if (inputAllowed == false) return false;
var limitedInputAllowed = ((meshrights != 0xFFFFFFFF) && (((meshrights & 8) != 0) && ((meshrights & 256) == 0) && ((meshrights & 4096) != 0))); var limitedInputAllowed = ((meshrights != 0xFFFFFFFF) && (((meshrights & 8) != 0) && ((meshrights & 256) == 0) && ((meshrights & 4096) != 0)));
@ -1612,8 +1610,7 @@
if (desktop && !xxdialogMode && xxcurrentView == 10) { if (desktop && !xxdialogMode && xxcurrentView == 10) {
// Check what keys we are allows to send // Check what keys we are allows to send
if (currentNode != null) { if (currentNode != null) {
var mesh = meshes[currentNode.meshid]; var meshrights = GetMeshRights(currentNode.meshid);
var meshrights = mesh.links[userinfo._id].rights;
var inputAllowed = ((meshrights == 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0))); var inputAllowed = ((meshrights == 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0)));
if (inputAllowed == false) return false; if (inputAllowed == false) return false;
var limitedInputAllowed = ((meshrights != 0xFFFFFFFF) && (((meshrights & 8) != 0) && ((meshrights & 256) == 0) && ((meshrights & 4096) != 0))); var limitedInputAllowed = ((meshrights != 0xFFFFFFFF) && (((meshrights & 8) != 0) && ((meshrights & 256) == 0) && ((meshrights & 4096) != 0)));
@ -1655,9 +1652,7 @@
// Go thru the list of nodes and display them // Go thru the list of nodes and display them
for (var i in nodes) { for (var i in nodes) {
if (nodes[i].v == false) continue; if (nodes[i].v == false) continue;
var mesh2 = meshes[nodes[i].meshid], meshlinks = mesh2.links[userinfo._id]; //var meshrights = GetNodeRights(nodes[i]);
if (meshlinks == null) continue;
var meshrights = meshlinks.rights;
if (sort == 0) { if (sort == 0) {
// Mesh header // Mesh header
@ -1668,7 +1663,7 @@
if (meshes[nodes[i].meshid].mtype == 1) { extra = '<span style=color:lightgray>' + ", Intel&reg; AMT only" + '</span>'; } if (meshes[nodes[i].meshid].mtype == 1) { extra = '<span style=color:lightgray>' + ", Intel&reg; AMT only" + '</span>'; }
if (current != null) { if (c == 2) { r += '<td><div style=width:301px></div></td>'; } if (r != '') { r += '</tr></table>'; } } if (current != null) { if (c == 2) { r += '<td><div style=width:301px></div></td>'; } if (r != '') { r += '</tr></table>'; } }
r += '<div class=DevSt style=padding-top:4px><span style=float:right>'; r += '<div class=DevSt style=padding-top:4px><span style=float:right>';
//r += getMeshActions(mesh2, meshrights); //r += getMeshActions(meshes[nodes[i].meshid], meshrights);
r += '</span><span id=MxMESH style=cursor:pointer onclick=goForward("' + nodes[i].meshid + '")>' + EscapeHtml(meshes[nodes[i].meshid].name) + '</span>' + extra + '<span id=DevxHeader' + deviceHeaderId + ' style=color:lightgray></span></div>'; r += '</span><span id=MxMESH style=cursor:pointer onclick=goForward("' + nodes[i].meshid + '")>' + EscapeHtml(meshes[nodes[i].meshid].name) + '</span>' + extra + '<span id=DevxHeader' + deviceHeaderId + ' style=color:lightgray></span></div>';
current = nodes[i].meshid; current = nodes[i].meshid;
displayedMeshes[current] = 1; displayedMeshes[current] = 1;
@ -1726,20 +1721,17 @@
// Display all empty meshes, we need to do this because users can add devices to these at any time. // Display all empty meshes, we need to do this because users can add devices to these at any time.
if (sort == 0) { if (sort == 0) {
for (var i in meshes) { for (var i in meshes) {
var mesh = meshes[i], meshlink = mesh.links[userinfo._id]; var mesh = meshes[i];
if (meshlink != null) { if (IsMeshViewable(mesh)) {
var meshrights = meshlink.rights; if ((current != '') && (r != '')) { r += '</tr></table>'; }
if (displayedMeshes[mesh._id] == null) { r += '<div><div colspan=3 class=DevSt><span style=float:right>';
if ((current != '') && (r != '')) { r += '</tr></table>'; } //r += getMeshActions(mesh, meshrights);
r += '<div><div colspan=3 class=DevSt><span style=float:right>'; r += '</span><span id=MxMESH style=cursor:pointer onclick=goForward("' + mesh._id + '")>' + EscapeHtml(mesh.name) + '</span></div>';
//r += getMeshActions(mesh, meshrights); if (mesh.mtype == 1) { r += '<div style=padding:10px><i>' + "No Intel&reg; AMT devices in this group"; }
r += '</span><span id=MxMESH style=cursor:pointer onclick=goForward("' + mesh._id + '")>' + EscapeHtml(mesh.name) + '</span></div>'; if (mesh.mtype == 2) { r += '<div style=padding:10px><i>' + "No devices in this group"; }
if (mesh.mtype == 1) { r += '<div style=padding:10px><i>' + "No Intel&reg; AMT devices in this group"; } r += '.</i></div></div>';
if (mesh.mtype == 2) { r += '<div style=padding:10px><i>' + "No devices in this group"; } current = mesh._id;
r += '.</i></div></div>'; count++;
current = mesh._id;
count++;
}
} }
} }
} }
@ -1813,11 +1805,6 @@
gotoDevice(nodeid, xxcurrentView, true); gotoDevice(nodeid, xxcurrentView, true);
} }
function getNodeRights(nodeid) {
var node = getNodeFromId(nodeid), mesh = meshes[node.meshid];
return mesh.links[userinfo._id].rights;
}
var currentDevicePanel = 0; var currentDevicePanel = 0;
var currentNode; var currentNode;
var powerTimelineNode = null; var powerTimelineNode = null;
@ -1837,7 +1824,7 @@
if (node == null) { goBack(); return; } if (node == null) { goBack(); return; }
var mesh = meshes[node.meshid]; var mesh = meshes[node.meshid];
if (mesh == null) { goBack(); return; } if (mesh == null) { goBack(); return; }
var meshrights = mesh.links[userinfo._id].rights; var meshrights = GetMeshRights(mesh);
if (!currentNode || currentNode._id != node._id || refresh == true) { if (!currentNode || currentNode._id != node._id || refresh == true) {
currentNode = node; currentNode = node;
@ -2008,8 +1995,7 @@
} }
function setupDeviceMenu(op, obj) { function setupDeviceMenu(op, obj) {
var meshrights = 0; var meshrights = GetNodeRights(currentNode);
if (currentNode) { meshrights = meshes[currentNode.meshid].links[userinfo._id].rights; }
if (op != null) { currentDevicePanel = op; } if (op != null) { currentDevicePanel = op; }
QV('p10general', currentDevicePanel == 0); QV('p10general', currentDevicePanel == 0);
QV('p10desktop', currentDevicePanel == 1); // Show if we have remote control rights or desktop view only rights QV('p10desktop', currentDevicePanel == 1); // Show if we have remote control rights or desktop view only rights
@ -2027,7 +2013,7 @@
function deviceActionFunction() { function deviceActionFunction() {
if (xxdialogMode) return; if (xxdialogMode) return;
var meshrights = meshes[currentNode.meshid].links[userinfo._id].rights; var meshrights = GetNodeRights(currentNode);
var x = "Select an operation to perform on this device." + '<br /><br />'; var x = "Select an operation to perform on this device." + '<br /><br />';
var y = '<select id=d2deviceop style=float:right;width:170px>'; var y = '<select id=d2deviceop style=float:right;width:170px>';
if ((meshrights & 64) != 0) { y += '<option value=100>' + "Wake-up" + '</option>'; } // Wake-up permission if ((meshrights & 64) != 0) { y += '<option value=100>' + "Wake-up" + '</option>'; } // Wake-up permission
@ -2117,7 +2103,7 @@
function editDeviceAmtSettings(nodeid, func) { function editDeviceAmtSettings(nodeid, func) {
if (xxdialogMode) return; if (xxdialogMode) return;
var x = '', node = getNodeFromId(nodeid), buttons = 3, meshrights = getNodeRights(nodeid); var x = '', node = getNodeFromId(nodeid), buttons = 3, meshrights = GetNodeRights(node);
if ((meshrights & 4) == 0) return; if ((meshrights & 4) == 0) return;
x += addHtmlValue("Username", '<input id=dp10username style=width:170px maxlength=32 autocomplete=nope placeholder="admin" onchange=validateDeviceAmtSettings() onkeyup=validateDeviceAmtSettings() />'); x += addHtmlValue("Username", '<input id=dp10username style=width:170px maxlength=32 autocomplete=nope placeholder="admin" onchange=validateDeviceAmtSettings() onkeyup=validateDeviceAmtSettings() />');
x += addHtmlValue("Password", '<input id=dp10password type=password style=width:170px autocomplete=nope maxlength=32 onchange=validateDeviceAmtSettings() onkeyup=validateDeviceAmtSettings() />'); x += addHtmlValue("Password", '<input id=dp10password type=password style=width:170px autocomplete=nope maxlength=32 onchange=validateDeviceAmtSettings() onkeyup=validateDeviceAmtSettings() />');
@ -2166,9 +2152,8 @@
function p10showiconselector() { function p10showiconselector() {
if (xxdialogMode) return; if (xxdialogMode) return;
var mesh = meshes[currentNode.meshid]; var rights = GetNodeRights(currentNode);
var meshrights = mesh.links[userinfo._id].rights; if ((rights & 4) == 0) return;
if ((meshrights & 4) == 0) return;
var x = '<table align=center><td>'; var x = '<table align=center><td>';
x += '<div style=display:inline-block class=i1 onclick=p10setIcon(1)></div>'; x += '<div style=display:inline-block class=i1 onclick=p10setIcon(1)></div>';
@ -2245,7 +2230,7 @@
var mesh = meshes[currentNode.meshid]; var mesh = meshes[currentNode.meshid];
var deskState = 0; var deskState = 0;
if (desktop != null) { deskState = desktop.State; } if (desktop != null) { deskState = desktop.State; }
var meshrights = mesh.links[userinfo._id].rights; var meshrights = GetNodeRights(currentNode);
// Show the right buttons // Show the right buttons
QV('disconnectbutton1', (deskState != 0)); QV('disconnectbutton1', (deskState != 0));
@ -3096,7 +3081,7 @@
if (currentMesh == null) return; if (currentMesh == null) return;
QH('p20meshName', EscapeHtml(currentMesh.name)); QH('p20meshName', EscapeHtml(currentMesh.name));
var meshtype = format("Unknown #{0}", currentMesh.mtype); var meshtype = format("Unknown #{0}", currentMesh.mtype);
var meshrights = currentMesh.links[userinfo._id].rights; var meshrights = GetMeshRights(currentMesh);
if (currentMesh.mtype == 1) meshtype = "Intel&reg; AMT only, no agent"; if (currentMesh.mtype == 1) meshtype = "Intel&reg; AMT only, no agent";
if (currentMesh.mtype == 2) meshtype = "Managed using a software agent"; if (currentMesh.mtype == 2) meshtype = "Managed using a software agent";
@ -3229,7 +3214,7 @@
} }
function p20validateAddMeshUserDialog() { function p20validateAddMeshUserDialog() {
var meshrights = currentMesh.links[userinfo._id].rights; var meshrights = GetMeshRights(currentMesh);
var nc = !Q('p20fulladmin').checked; var nc = !Q('p20fulladmin').checked;
QE('p20fulladmin', meshrights == 0xFFFFFFFF); QE('p20fulladmin', meshrights == 0xFFFFFFFF);
QE('p20editmesh', nc && (meshrights == 0xFFFFFFFF)); QE('p20editmesh', nc && (meshrights == 0xFFFFFFFF));
@ -3278,7 +3263,7 @@
function p20viewuser(userid) { function p20viewuser(userid) {
if (xxdialogMode) return; if (xxdialogMode) return;
userid = decodeURIComponent(userid); userid = decodeURIComponent(userid);
var r = [], cmeshrights = currentMesh.links[userinfo._id].rights, meshrights = currentMesh.links[userid].rights; var r = [], cmeshrights = GetMeshRights(currentMesh), meshrights = GetMeshRights(currentMesh, userid);
if (meshrights == 0xFFFFFFFF) r.push("Full Administrator"); else { if (meshrights == 0xFFFFFFFF) r.push("Full Administrator"); else {
if ((meshrights & 1) != 0) r.push("Edit Device Group"); if ((meshrights & 1) != 0) r.push("Edit Device Group");
if ((meshrights & 2) != 0) r.push("Manage Device Group Users"); if ((meshrights & 2) != 0) r.push("Manage Device Group Users");
@ -3361,6 +3346,49 @@
if (((b & 8) || x) && f) f(x, t); if (((b & 8) || x) && f) f(x, t);
} }
//
// Access Control Functions
// These must match server
//
// Get the right of a user on a given device group
function GetMeshRights(mesh, user) {
if (mesh == null) { return 0; }
if (user == null) { user = userinfo._id; }
if (typeof mesh == 'string') { mesh = meshes[mesh] }
if ((mesh == null) || (mesh.links == null)) { return 0; }
var rights = mesh.links[user];
if (rights == null) { return 0; }
return rights.rights;
}
// Returns true if the user can view the given device group
function IsMeshViewable(mesh, user) {
if (mesh == null) { return 0; }
if (user == null) { user = userinfo._id; }
if (typeof mesh == 'string') { mesh = meshes[mesh] }
if ((mesh == null) || (mesh.links == null)) { return false; }
var rights = mesh.links[user];
if (rights == null) { return false; }
return true;
}
// Return the user rights for a given node
function GetNodeRights(node, user) {
if (node == null) { return 0; }
if (user == null) { user = userinfo._id; }
if (typeof node == 'string') { node = getNodeFromId(node); if (node == null) { return 0; } }
var mesh = meshes[node.meshid];
if ((mesh == null) || (mesh.links == null)) { return 0; }
var meshlinks = mesh.links[user];
if (meshlinks == null) { return 0; }
return meshlinks.rights;
}
//
// Generic Methods
//
function putstore(name, val) { try { if ((typeof (localStorage) === 'undefined') || (localStorage.getItem(name) == val)) return; if (val == null) { localStorage.removeItem(name); } else { localStorage.setItem(name, val); } } catch (e) { } if (name[0] != '_') { var s = {}; for (var i = 0, len = localStorage.length; i < len; ++i) { var k = localStorage.key(i); if (k[0] != '_') { s[k] = localStorage.getItem(k); } } meshserver.send({ action: 'userWebState', state: JSON.stringify(s) }); } } function putstore(name, val) { try { if ((typeof (localStorage) === 'undefined') || (localStorage.getItem(name) == val)) return; if (val == null) { localStorage.removeItem(name); } else { localStorage.setItem(name, val); } } catch (e) { } if (name[0] != '_') { var s = {}; for (var i = 0, len = localStorage.length; i < len; ++i) { var k = localStorage.key(i); if (k[0] != '_') { s[k] = localStorage.getItem(k); } } meshserver.send({ action: 'userWebState', state: JSON.stringify(s) }); } }
function getstore(name, val) { try { if (typeof (localStorage) === 'undefined') return val; var v = localStorage.getItem(name); if ((v == null) || (v == null)) return val; return v; } catch (e) { return val; } } function getstore(name, val) { try { if (typeof (localStorage) === 'undefined') return val; var v = localStorage.getItem(name); if ((v == null) || (v == null)) return val; return v; } catch (e) { return val; } }
function center() { QS('dialog').left = ((((getDocWidth() - 300) / 2)) + 'px'); deskAdjust(); deskAdjust(); /*drawDeviceTimeline();*/ } function center() { QS('dialog').left = ((((getDocWidth() - 300) / 2)) + 'px'); deskAdjust(); deskAdjust(); /*drawDeviceTimeline();*/ }

View File

@ -2587,8 +2587,7 @@
if (!xxdialogMode && xxcurrentView == 11 && desktop && Q('DeskControl').checked) { if (!xxdialogMode && xxcurrentView == 11 && desktop && Q('DeskControl').checked) {
// Check what keys we are allows to send // Check what keys we are allows to send
if (currentNode != null) { if (currentNode != null) {
var mesh = meshes[currentNode.meshid]; var meshrights = GetMeshRights(currentNode.meshid);
var meshrights = mesh.links[userinfo._id].rights;
var inputAllowed = ((meshrights == 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0))); var inputAllowed = ((meshrights == 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0)));
if (inputAllowed == false) return false; if (inputAllowed == false) return false;
var limitedInputAllowed = ((meshrights != 0xFFFFFFFF) && (((meshrights & 8) != 0) && ((meshrights & 256) == 0) && ((meshrights & 4096) != 0))); var limitedInputAllowed = ((meshrights != 0xFFFFFFFF) && (((meshrights & 8) != 0) && ((meshrights & 256) == 0) && ((meshrights & 4096) != 0)));
@ -2647,8 +2646,7 @@
if (!xxdialogMode && xxcurrentView == 11 && desktop && Q('DeskControl').checked) { if (!xxdialogMode && xxcurrentView == 11 && desktop && Q('DeskControl').checked) {
// Check what keys we are allows to send // Check what keys we are allows to send
if (currentNode != null) { if (currentNode != null) {
var mesh = meshes[currentNode.meshid]; var meshrights = GetMeshRights(currentNode.meshid);
var meshrights = mesh.links[userinfo._id].rights;
var inputAllowed = ((meshrights == 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0))); var inputAllowed = ((meshrights == 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0)));
if (inputAllowed == false) return false; if (inputAllowed == false) return false;
var limitedInputAllowed = ((meshrights != 0xFFFFFFFF) && (((meshrights & 8) != 0) && ((meshrights & 256) == 0) && ((meshrights & 4096) != 0))); var limitedInputAllowed = ((meshrights != 0xFFFFFFFF) && (((meshrights & 8) != 0) && ((meshrights & 256) == 0) && ((meshrights & 4096) != 0)));
@ -2682,8 +2680,7 @@
if (!xxdialogMode && xxcurrentView == 11 && desktop && Q('DeskControl').checked) { if (!xxdialogMode && xxcurrentView == 11 && desktop && Q('DeskControl').checked) {
// Check what keys we are allows to send // Check what keys we are allows to send
if (currentNode != null) { if (currentNode != null) {
var mesh = meshes[currentNode.meshid]; var meshrights = GetMeshRights(currentNode.meshid);
var meshrights = mesh.links[userinfo._id].rights;
var inputAllowed = ((meshrights == 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0))); var inputAllowed = ((meshrights == 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0)));
if (inputAllowed == false) return false; if (inputAllowed == false) return false;
var limitedInputAllowed = ((meshrights != 0xFFFFFFFF) && (((meshrights & 8) != 0) && ((meshrights & 256) == 0) && ((meshrights & 4096) != 0))); var limitedInputAllowed = ((meshrights != 0xFFFFFFFF) && (((meshrights & 8) != 0) && ((meshrights & 256) == 0) && ((meshrights & 4096) != 0)));
@ -2783,10 +2780,9 @@
for (var i in nodes) { for (var i in nodes) {
var node = nodes[i]; var node = nodes[i];
if (node.v == false) continue; if (node.v == false) continue;
var mesh2 = meshes[node.meshid], meshlinks = mesh2.links[userinfo._id]; var mesh2 = meshes[node.meshid];
if (meshlinks == null) continue;
var meshrights = meshlinks.rights;
if ((view == 3) && (mesh2.mtype == 1)) continue; if ((view == 3) && (mesh2.mtype == 1)) continue;
var meshrights = GetNodeRights(node);
if (sort == 0) { if (sort == 0) {
// Mesh header // Mesh header
if (node.meshid != current) { if (node.meshid != current) {
@ -2948,37 +2944,34 @@
if ((sort == 0) && (Q('SearchInput').value == '') && (view < 3)) { if ((sort == 0) && (Q('SearchInput').value == '') && (view < 3)) {
var deviceHeaderId2 = deviceHeaderId; var deviceHeaderId2 = deviceHeaderId;
for (var i in meshes) { for (var i in meshes) {
var mesh = meshes[i], meshlink = mesh.links[userinfo._id]; var mesh = meshes[i], meshrights = GetMeshRights(mesh);
if (meshlink != null) { if (displayedMeshes[mesh._id] == null) {
var meshrights = meshlink.rights; if ((current != '') && (r != '')) { r += '</tr></table>'; }
if (displayedMeshes[mesh._id] == null) { r += '<table style=width:100%;padding-top:4px cellpadding=0 cellspacing=0><tr><td colspan=3 class=DevSt>';
if ((current != '') && (r != '')) { r += '</tr></table>'; }
r += '<table style=width:100%;padding-top:4px cellpadding=0 cellspacing=0><tr><td colspan=3 class=DevSt>';
// Collapsing header & start collapsing area // Collapsing header & start collapsing area
deviceHeaderId2++; deviceHeaderId2++;
var collapsed = CollapsedGroups[mesh._id]; var collapsed = CollapsedGroups[mesh._id];
r += '<img class=collapseImage id=\"DevxColImg' + deviceHeaderId2 + '\" src=images/c' + ((collapsed === true)?'1':'2') + '.png height=8 width=8 style=margin-left:2px;margin-right:2px;cursor:pointer onclick=toggleCollapseGroup(\"' + deviceHeaderId2 + '\",\"' + mesh._id + '\")></img>'; // Collapse action r += '<img class=collapseImage id=\"DevxColImg' + deviceHeaderId2 + '\" src=images/c' + ((collapsed === true)?'1':'2') + '.png height=8 width=8 style=margin-left:2px;margin-right:2px;cursor:pointer onclick=toggleCollapseGroup(\"' + deviceHeaderId2 + '\",\"' + mesh._id + '\")></img>'; // Collapse action
r += '<span id=MxMESH style=cursor:pointer onclick=gotoMesh("' + mesh._id + '")>' + EscapeHtml(mesh.name) + '</span><span>'; r += '<span id=MxMESH style=cursor:pointer onclick=gotoMesh("' + mesh._id + '")>' + EscapeHtml(mesh.name) + '</span><span>';
r += getMeshActions(mesh, meshrights); r += getMeshActions(mesh, meshrights);
r += '</span></td></tr><tr>'; r += '</span></td></tr><tr>';
if (mesh.mtype == 1) { if (mesh.mtype == 1) {
r += '<td><div style=padding:10px><i>' + "No Intel&reg; AMT devices in this mesh"; r += '<td><div style=padding:10px><i>' + "No Intel&reg; AMT devices in this mesh";
if ((meshrights & 4) != 0) { r += ', <a href=# style=cursor:pointer onclick=\'return addDeviceToMesh(\"' + mesh._id + '\")\'>' + "add one" + '</a>'; } if ((meshrights & 4) != 0) { r += ', <a href=# style=cursor:pointer onclick=\'return addDeviceToMesh(\"' + mesh._id + '\")\'>' + "add one" + '</a>'; }
}
if (mesh.mtype == 2) {
r += '<td>';
r += '<div id=DevxCol' + deviceHeaderId2 + ((collapsed === true)?' style=display:none':'') + '>'; // Open collapse div
r += '<div style=padding:10px><i>' + "No devices in this group";
if ((meshrights & 4) != 0) { r += ', <a href=# style=cursor:pointer onclick=\'return addAgentToMesh(\"' + mesh._id + '\")\'>' + "add one" + '</a>'; }
}
r += '.</i></div></td>';
r += '</div>'; // End collapsing area
current = mesh._id;
count++;
} }
if (mesh.mtype == 2) {
r += '<td>';
r += '<div id=DevxCol' + deviceHeaderId2 + ((collapsed === true)?' style=display:none':'') + '>'; // Open collapse div
r += '<div style=padding:10px><i>' + "No devices in this group";
if ((meshrights & 4) != 0) { r += ', <a href=# style=cursor:pointer onclick=\'return addAgentToMesh(\"' + mesh._id + '\")\'>' + "add one" + '</a>'; }
}
r += '.</i></div></td>';
r += '</div>'; // End collapsing area
current = mesh._id;
count++;
} }
} }
} }
@ -3107,8 +3100,8 @@
function toggleKvmDevice(node) { function toggleKvmDevice(node) {
if (typeof node == 'string') { node = getNodeFromId(node); } // Convert nodeid to node if needed if (typeof node == 'string') { node = getNodeFromId(node); } // Convert nodeid to node if needed
var mesh = meshes[node.meshid], meshrights = mesh.links[userinfo._id].rights; var rights = GetNodeRights(node);
if ((meshrights & 8) || (meshrights & 256)) { // Requires remote control rights or desktop view only rights if ((rights & 8) || (rights & 256)) { // Requires remote control rights or desktop view only rights
//var conn = 0; //var conn = 0;
//if ((node.conn & 1) != 0) { conn = 1; } else if ((node.conn & 6) != 0) { conn = 2; } // Check what type of connect we can do (Agent vs AMT) //if ((node.conn & 1) != 0) { conn = 1; } else if ((node.conn & 6) != 0) { conn = 2; } // Check what type of connect we can do (Agent vs AMT)
if (node.conn & 1) { connectMultiDesktop(node, 1); } if (node.conn & 1) { connectMultiDesktop(node, 1); }
@ -3133,8 +3126,8 @@
for (var i in nodes) { for (var i in nodes) {
var node = nodes[i], nodeid = nodes[i]._id; var node = nodes[i], nodeid = nodes[i]._id;
if ((multiDesktop[nodeid] == null) && ((multiDesktopFilter.length == 0) || (multiDesktopFilter.indexOf('devid_' + nodeid) >= 0))) { if ((multiDesktop[nodeid] == null) && ((multiDesktopFilter.length == 0) || (multiDesktopFilter.indexOf('devid_' + nodeid) >= 0))) {
var mesh = meshes[node.meshid], meshrights = mesh.links[userinfo._id].rights; var rights = GetNodeRights(node);
if ((meshrights & 8) || (meshrights & 256)) { // Requires remote control rights or desktop view only rights if ((rights & 8) || (rights & 256)) { // Requires remote control rights or desktop view only rights
//var conn = 0; //var conn = 0;
//if ((node.conn & 1) != 0) { conn = 1; } else if ((node.conn & 6) != 0) { conn = 2; } // Check what type of connect we can do (Agent vs AMT) //if ((node.conn & 1) != 0) { conn = 1; } else if ((node.conn & 6) != 0) { conn = 2; } // Check what type of connect we can do (Agent vs AMT)
if ((node.conn & 1) && (node.v == true)) { count++; } if ((node.conn & 1) && (node.v == true)) { count++; }
@ -3646,9 +3639,8 @@
// Display the "Uninstall Agent" option if allowed and we selected connected devices. // Display the "Uninstall Agent" option if allowed and we selected connected devices.
for (var i in nodeids) { for (var i in nodeids) {
var node = getNodeFromId(nodeids[i]); var node = getNodeFromId(nodeids[i]);
var mesh = meshes[node.meshid]; var rights = GetNodeRights(node);
var meshrights = mesh.links[userinfo._id].rights; if (((node.conn & 1) != 0) && ((rights & 32768) != 0)) { addedOptions += '<option value=104>' + "Uninstall Agent" + '</option>'; break; }
if (((node.conn & 1) != 0) && ((meshrights & 32768) != 0)) { addedOptions += '<option value=104>' + "Uninstall Agent" + '</option>'; break; }
} }
var x = "Select an operation to perform on all selected devices. Actions will be performed only with proper rights." + '<br /><br />'; var x = "Select an operation to perform on all selected devices. Actions will be performed only with proper rights." + '<br /><br />';
@ -3790,19 +3782,18 @@
var nodeid = contextelement.children[1].attributes.onclick.value; var nodeid = contextelement.children[1].attributes.onclick.value;
var node = getNodeFromId(nodeid.substring(12, nodeid.length - 18)); var node = getNodeFromId(nodeid.substring(12, nodeid.length - 18));
var mesh = meshes[node.meshid]; var mesh = meshes[node.meshid];
var meshlinks = mesh.links[userinfo._id]; var rights = GetNodeRights(node);
var meshrights = meshlinks.rights; var consoleRights = ((rights & 16) != 0);
var consoleRights = ((meshrights & 16) != 0);
// Check if we have terminal and file access // Check if we have terminal and file access
var terminalAccess = ((meshrights == 0xFFFFFFFF) || ((meshrights & 512) == 0)); var terminalAccess = ((rights == 0xFFFFFFFF) || ((rights & 512) == 0));
var fileAccess = ((meshrights == 0xFFFFFFFF) || ((meshrights & 1024) == 0)); var fileAccess = ((rights == 0xFFFFFFFF) || ((rights & 1024) == 0));
QV('cxdesktop', ((mesh.mtype == 1) || (node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 1) != 0) || (node.intelamt && (node.intelamt.state == 2))) && ((meshrights & 8) || (meshrights & 256))); QV('cxdesktop', ((mesh.mtype == 1) || (node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 1) != 0) || (node.intelamt && (node.intelamt.state == 2))) && ((rights & 8) || (rights & 256)));
QV('cxterminal', ((mesh.mtype == 1) || (node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 2) != 0) || (node.intelamt && (node.intelamt.state == 2))) && (meshrights & 8) && terminalAccess); QV('cxterminal', ((mesh.mtype == 1) || (node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 2) != 0) || (node.intelamt && (node.intelamt.state == 2))) && (rights & 8) && terminalAccess);
QV('cxfiles', ((mesh.mtype == 2) && ((node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 4) != 0))) && (meshrights & 8) && fileAccess); QV('cxfiles', ((mesh.mtype == 2) && ((node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 4) != 0))) && (rights & 8) && fileAccess);
QV('cxevents', (node.intelamt != null) && ((node.intelamt.state == 2) || (node.conn & 2)) && (meshrights & 8)); QV('cxevents', (node.intelamt != null) && ((node.intelamt.state == 2) || (node.conn & 2)) && (rights & 8));
QV('cxconsole', (consoleRights && (mesh.mtype == 2) && ((node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 8) != 0))) && (meshrights & 8)); QV('cxconsole', (consoleRights && (mesh.mtype == 2) && ((node.agent == null) || (node.agent.caps == null) || ((node.agent.caps & 8) != 0))) && (rights & 8));
} }
return haltEvent(event); return haltEvent(event);
@ -4488,11 +4479,6 @@
gotoDevice(nodeid, xxcurrentView, true); gotoDevice(nodeid, xxcurrentView, true);
} }
function getNodeRights(nodeid) {
var node = getNodeFromId(nodeid), mesh = meshes[node.meshid];
return mesh.links[userinfo._id].rights;
}
var currentNode; var currentNode;
var powerTimelineNode = null; var powerTimelineNode = null;
var powerTimelineReq = null; var powerTimelineReq = null;
@ -4515,7 +4501,7 @@
//disconnectAllKvmFunction(); //disconnectAllKvmFunction();
var node = getNodeFromId(nodeid); var node = getNodeFromId(nodeid);
var mesh = meshes[node.meshid]; var mesh = meshes[node.meshid];
var meshrights = mesh.links[userinfo._id].rights; var meshrights = GetNodeRights(node);
if (!currentNode || currentNode._id != node._id || refresh == true) { if (!currentNode || currentNode._id != node._id || refresh == true) {
currentNode = node; currentNode = node;
@ -4857,13 +4843,13 @@
function deviceActionFunction() { function deviceActionFunction() {
if (xxdialogMode) return; if (xxdialogMode) return;
var meshrights = meshes[currentNode.meshid].links[userinfo._id].rights; var rights = GetNodeRights(currentNode);
var x = "Select an operation to perform on this device." + '<br /><br />'; var x = "Select an operation to perform on this device." + '<br /><br />';
var y = '<select id=d2deviceop style=float:right;width:250px>'; var y = '<select id=d2deviceop style=float:right;width:250px>';
if ((meshrights & 64) != 0) { y += '<option value=100>' + "Wake-up" + '</option>'; } // Wake-up permission if ((rights & 64) != 0) { y += '<option value=100>' + "Wake-up" + '</option>'; } // Wake-up permission
if ((meshrights & 8) != 0) { y += '<option value=4>' + "Sleep" + '</option><option value=3>' + "Reset" + '</option><option value=2>' + "Power off" + '</option>'; } // Remote control permission if ((rights & 8) != 0) { y += '<option value=4>' + "Sleep" + '</option><option value=3>' + "Reset" + '</option><option value=2>' + "Power off" + '</option>'; } // Remote control permission
if ((currentNode.conn & 16) != 0) { y += '<option value=103>' + "Send MQTT Message" + '</option>'; } if ((currentNode.conn & 16) != 0) { y += '<option value=103>' + "Send MQTT Message" + '</option>'; }
if (((currentNode.conn & 1) != 0) && ((meshrights & 32768) != 0)) { y += '<option value=104>' + "Uninstall Agent" + '</option>'; } if (((currentNode.conn & 1) != 0) && ((rights & 32768) != 0)) { y += '<option value=104>' + "Uninstall Agent" + '</option>'; }
y += '</select>'; y += '</select>';
x += addHtmlValue("Operation", y); x += addHtmlValue("Operation", y);
setDialogMode(2, "Device Action", 3, deviceActionFunctionEx, x); setDialogMode(2, "Device Action", 3, deviceActionFunctionEx, x);
@ -4975,7 +4961,7 @@
function editDeviceAmtSettings(nodeid, func, arg) { function editDeviceAmtSettings(nodeid, func, arg) {
if (xxdialogMode) return; if (xxdialogMode) return;
var x = '', node = getNodeFromId(nodeid), buttons = 3, meshrights = getNodeRights(nodeid); var x = '', node = getNodeFromId(nodeid), buttons = 3, meshrights = GetNodeRights(node);
if ((meshrights & 4) == 0) return; if ((meshrights & 4) == 0) return;
x += addHtmlValue("Username", '<input id=dp10username style=width:230px maxlength=32 autocomplete=nope placeholder="admin" onchange=validateDeviceAmtSettings() onkeyup=validateDeviceAmtSettings() />'); x += addHtmlValue("Username", '<input id=dp10username style=width:230px maxlength=32 autocomplete=nope placeholder="admin" onchange=validateDeviceAmtSettings() onkeyup=validateDeviceAmtSettings() />');
x += addHtmlValue("Password", '<input id=dp10password type=password style=width:230px autocomplete=nope maxlength=32 onchange=validateDeviceAmtSettings() onkeyup=validateDeviceAmtSettings() />'); x += addHtmlValue("Password", '<input id=dp10password type=password style=width:230px autocomplete=nope maxlength=32 onchange=validateDeviceAmtSettings() onkeyup=validateDeviceAmtSettings() />');
@ -5049,7 +5035,7 @@
// List all available alternative groups // List all available alternative groups
var y = '<select id=p10newGroup style=width:236px>', count = 0; var y = '<select id=p10newGroup style=width:236px>', count = 0;
for (var i in meshes) { for (var i in meshes) {
var meshrights = meshes[i].links[userinfo._id].rights; var meshrights = GetMeshRights(i);
if ((meshes[i]._id != targetMeshId) && (meshrights & 4)) { count++; y += '<option value=\'' + meshes[i]._id + '\'>' + meshes[i].name + '</option>'; } if ((meshes[i]._id != targetMeshId) && (meshrights & 4)) { count++; y += '<option value=\'' + meshes[i]._id + '\'>' + meshes[i].name + '</option>'; }
} }
y += '</select>'; y += '</select>';
@ -5195,17 +5181,16 @@
function p10showiconselector() { function p10showiconselector() {
if (xxdialogMode) return; if (xxdialogMode) return;
var mesh = meshes[currentNode.meshid]; if ((GetNodeRights(currentNode) & 4) == 0) return;
var meshrights = mesh.links[userinfo._id].rights;
if ((meshrights & 4) == 0) return;
var x = '<br><div style=display:inline-block;width:40px></div>'; var x = '<br><div style=display:inline-block;width:16px></div>';
x += '<div tabindex=0 style=display:inline-block class=i1 onclick=p10setIcon(1) onkeypress="if (event.key==\'Enter\') p10setIcon(1)"></div>'; x += '<div tabindex=0 style=display:inline-block class=i1 onclick=p10setIcon(1) onkeypress="if (event.key==\'Enter\') p10setIcon(1)"></div>';
x += '<div tabindex=0 style=display:inline-block class=i2 onclick=p10setIcon(2) onkeypress="if (event.key==\'Enter\') p10setIcon(2)"></div>'; x += '<div tabindex=0 style=display:inline-block class=i2 onclick=p10setIcon(2) onkeypress="if (event.key==\'Enter\') p10setIcon(2)"></div>';
x += '<div tabindex=0 style=display:inline-block class=i3 onclick=p10setIcon(3) onkeypress="if (event.key==\'Enter\') p10setIcon(3)"></div>'; x += '<div tabindex=0 style=display:inline-block class=i3 onclick=p10setIcon(3) onkeypress="if (event.key==\'Enter\') p10setIcon(3)"></div>';
x += '<div tabindex=0 style=display:inline-block class=i4 onclick=p10setIcon(4) onkeypress="if (event.key==\'Enter\') p10setIcon(4)"></div>'; x += '<div tabindex=0 style=display:inline-block class=i4 onclick=p10setIcon(4) onkeypress="if (event.key==\'Enter\') p10setIcon(4)"></div>';
x += '<div tabindex=0 style=display:inline-block class=i5 onclick=p10setIcon(5) onkeypress="if (event.key==\'Enter\') p10setIcon(5)"></div>'; x += '<div tabindex=0 style=display:inline-block class=i5 onclick=p10setIcon(5) onkeypress="if (event.key==\'Enter\') p10setIcon(5)"></div>';
x += '<div tabindex=0 style=display:inline-block class=i6 onclick=p10setIcon(6) onkeypress="if (event.key==\'Enter\') p10setIcon(6)"></div><br><br>'; x += '<div tabindex=0 style=display:inline-block class=i6 onclick=p10setIcon(6) onkeypress="if (event.key==\'Enter\') p10setIcon(6)"></div>';
x += '<div tabindex=0 style=display:inline-block class=i7 onclick=p10setIcon(7) onkeypress="if (event.key==\'Enter\') p10setIcon(7)"></div><br><br>';
setDialogMode(2, "Icon Selection", 0, null, x); setDialogMode(2, "Icon Selection", 0, null, x);
QV('id_dialogclose', true); QV('id_dialogclose', true);
} }
@ -5292,14 +5277,14 @@
var mesh = meshes[currentNode.meshid]; var mesh = meshes[currentNode.meshid];
var deskState = 0; var deskState = 0;
if (desktop != null) { deskState = desktop.State; } if (desktop != null) { deskState = desktop.State; }
var meshrights = mesh.links[userinfo._id].rights; var rights = GetNodeRights(currentNode);
// Show the right buttons // Show the right buttons
QV('disconnectbutton1span', (deskState != 0)); QV('disconnectbutton1span', (deskState != 0));
QV('connectbutton1span', (deskState == 0) && ((meshrights & 8) || (meshrights & 256)) && (mesh.mtype == 2) && (currentNode.agent.caps & 1)); QV('connectbutton1span', (deskState == 0) && ((rights & 8) || (rights & 256)) && (mesh.mtype == 2) && (currentNode.agent.caps & 1));
QV('connectbutton1hspan', QV('connectbutton1hspan',
(deskState == 0) && (deskState == 0) &&
(meshrights & 8) && (rights & 8) &&
((mesh.mtype == 1) || ((mesh.mtype == 1) ||
((currentNode.intelamt != null) && ((currentNode.intelamt != null) &&
(currentNode.intelamt.state == 2) && (currentNode.intelamt.state == 2) &&
@ -5314,7 +5299,7 @@
QV('d7meshkvm', (webRtcDesktop) || ((mesh.mtype == 2) && (currentNode.agent.caps & 1) && ((deskState == false) || (desktop.contype == 1)))); QV('d7meshkvm', (webRtcDesktop) || ((mesh.mtype == 2) && (currentNode.agent.caps & 1) && ((deskState == false) || (desktop.contype == 1))));
// Enable buttons // Enable buttons
var inputAllowed = (meshrights == 0xFFFFFFFF) || (((meshrights & 8) != 0) && ((meshrights & 256) == 0) && ((meshrights & 4096) == 0)); var inputAllowed = (rights == 0xFFFFFFFF) || (((rights & 8) != 0) && ((rights & 256) == 0) && ((rights & 4096) == 0));
var online = ((currentNode.conn & 1) != 0); // If Agent (1) connected, enable remote desktop var online = ((currentNode.conn & 1) != 0); // If Agent (1) connected, enable remote desktop
QE('connectbutton1', online); QE('connectbutton1', online);
var hwonline = ((currentNode.conn & 6) != 0); // If CIRA (2) or AMT (4) connected, enable hardware terminal var hwonline = ((currentNode.conn & 6) != 0); // If CIRA (2) or AMT (4) connected, enable hardware terminal
@ -5330,8 +5315,8 @@
QE('deskkeys', deskState == 3); QE('deskkeys', deskState == 3);
// Display this only if we have Chat & Notify permissions // Display this only if we have Chat & Notify permissions
QV('DeskChatButton', ((meshrights & 16384) != 0) && (browserfullscreen == false) && (inputAllowed) && (mesh.mtype == 2) && online); QV('DeskChatButton', ((rights & 16384) != 0) && (browserfullscreen == false) && (inputAllowed) && (mesh.mtype == 2) && online);
QV('DeskNotifyButton', ((meshrights & 16384) != 0) && (browserfullscreen == false) && (currentNode.agent) && (currentNode.agent.id < 5) && (inputAllowed) && (mesh.mtype == 2) && online); QV('DeskNotifyButton', ((rights & 16384) != 0) && (browserfullscreen == false) && (currentNode.agent) && (currentNode.agent.id < 5) && (inputAllowed) && (mesh.mtype == 2) && online);
QV('DeskToolsButton', (inputAllowed) && (mesh.mtype == 2) && online); QV('DeskToolsButton', (inputAllowed) && (mesh.mtype == 2) && online);
QV('DeskOpenWebButton', (browserfullscreen == false) && (inputAllowed) && (mesh.mtype == 2) && online); QV('DeskOpenWebButton', (browserfullscreen == false) && (inputAllowed) && (mesh.mtype == 2) && online);
@ -5339,7 +5324,7 @@
QV('DeskControlSpan', inputAllowed) QV('DeskControlSpan', inputAllowed)
QV('deskActionsBtn', (browserfullscreen == false)); QV('deskActionsBtn', (browserfullscreen == false));
QV('deskActionsSettings', (browserfullscreen == false)); QV('deskActionsSettings', (browserfullscreen == false));
if (meshrights & 8) { Q('DeskControl').checked = (getstore('DeskControl', 1) == 1); } else { Q('DeskControl').checked = false; } if (rights & 8) { Q('DeskControl').checked = (getstore('DeskControl', 1) == 1); } else { Q('DeskControl').checked = false; }
if (online == false) QV('DeskTools', false); if (online == false) QV('DeskTools', false);
} }
@ -6966,8 +6951,8 @@
consoleNode = currentNode; consoleNode = currentNode;
var mesh = meshes[consoleNode.meshid]; var mesh = meshes[consoleNode.meshid];
var meshrights = mesh.links[userinfo._id].rights; var rights = GetNodeRights(currentNode);
if ((meshrights & 16) != 0) { if ((rights & 16) != 0) {
if (consoleNode.consoleText == null) { consoleNode.consoleText = ''; } if (consoleNode.consoleText == null) { consoleNode.consoleText = ''; }
if (samenode == false) { if (samenode == false) {
QH('p15agentConsoleText', consoleNode.consoleText); QH('p15agentConsoleText', consoleNode.consoleText);
@ -7443,8 +7428,7 @@
count++; count++;
// Mesh rights // Mesh rights
var meshrights = 0; var meshrights = GetMeshRights(meshes[i]);
if (meshes[i].links[userinfo._id]) { meshrights = meshes[i].links[userinfo._id].rights; }
var rights = "Partial Rights"; var rights = "Partial Rights";
if (meshrights == 0xFFFFFFFF) rights = "Full Administrator"; else if (meshrights == 0) rights = "No Rights"; if (meshrights == 0xFFFFFFFF) rights = "Full Administrator"; else if (meshrights == 0) rights = "No Rights";
@ -7511,8 +7495,7 @@
if (currentMesh == null) return; if (currentMesh == null) return;
QH('p20meshName', EscapeHtml(currentMesh.name)); QH('p20meshName', EscapeHtml(currentMesh.name));
var meshtype = format("Unknown #{0}", currentMesh.mtype); var meshtype = format("Unknown #{0}", currentMesh.mtype);
var meshrights = 0; var meshrights = GetMeshRights(currentMesh);
try { meshrights = currentMesh.links[userinfo._id].rights; } catch (ex) { }
if (currentMesh.mtype == 1) meshtype = "Intel&reg; AMT only, no agent"; if (currentMesh.mtype == 1) meshtype = "Intel&reg; AMT only, no agent";
if (currentMesh.mtype == 2) meshtype = "Managed using a software agent"; if (currentMesh.mtype == 2) meshtype = "Managed using a software agent";
@ -7580,10 +7563,9 @@
if (meshrights & 1) { x += '<br><input type=button value=' + "Notes" + ' title=\"' + "View notes about this device group" + '\" onclick=showNotes(false,"' + encodeURIComponent(currentMesh._id) + '") />'; } if (meshrights & 1) { x += '<br><input type=button value=' + "Notes" + ' title=\"' + "View notes about this device group" + '\" onclick=showNotes(false,"' + encodeURIComponent(currentMesh._id) + '") />'; }
x += '<br style=clear:both><br>'; x += '<br style=clear:both><br>';
var currentMeshLinks = currentMesh.links[userinfo._id]; if (meshrights & 2) { x += '<a href=# onclick="return p20showAddMeshUserDialog()" style=cursor:pointer;margin-right:10px><img src=images/icon-addnew.png border=0 height=12 width=12> ' + "Add Users" + '</a>'; }
if (currentMeshLinks && ((currentMeshLinks.rights & 2) != 0)) { x += '<a href=# onclick="return p20showAddMeshUserDialog()" style=cursor:pointer;margin-right:10px><img src=images/icon-addnew.png border=0 height=12 width=12> ' + "Add Users" + '</a>'; }
if ((meshrights & 4) != 0) { if (meshrights & 4) {
if (currentMesh.mtype == 1) { if (currentMesh.mtype == 1) {
x += '<a href=# onclick=\'return addCiraDeviceToMesh(\"' + currentMesh._id + '\")\' style=cursor:pointer;margin-right:10px title=\"' + "Add a new Intel&reg; AMT computer that is located on the internet." + '\"><img src=images/icon-installmesh.png border=0 height=12 width=12> ' + "Install CIRA" + '</a>'; x += '<a href=# onclick=\'return addCiraDeviceToMesh(\"' + currentMesh._id + '\")\' style=cursor:pointer;margin-right:10px title=\"' + "Add a new Intel&reg; AMT computer that is located on the internet." + '\"><img src=images/icon-installmesh.png border=0 height=12 width=12> ' + "Install CIRA" + '</a>';
x += '<a href=# onclick=\'return addDeviceToMesh(\"' + currentMesh._id + '\")\' style=cursor:pointer;margin-right:10px title=\"' + "Add a new Intel&reg; AMT computer that is located on the local network." + '\"><img src=images/icon-installmesh.png border=0 height=12 width=12> ' + "Install local" + '</a>'; x += '<a href=# onclick=\'return addDeviceToMesh(\"' + currentMesh._id + '\")\' style=cursor:pointer;margin-right:10px title=\"' + "Add a new Intel&reg; AMT computer that is located on the local network." + '\"><img src=images/icon-installmesh.png border=0 height=12 width=12> ' + "Install local" + '</a>';
@ -7838,7 +7820,7 @@
Q('dp20username').focus(); Q('dp20username').focus();
} else { } else {
setDialogMode(2, "Edit User Device Group Permissions", 7, p20showAddMeshUserDialogEx, x, userid); setDialogMode(2, "Edit User Device Group Permissions", 7, p20showAddMeshUserDialogEx, x, userid);
var cmeshrights = currentMesh.links[userinfo._id].rights, meshrights = currentMesh.links[userid].rights; var cmeshrights = GetMeshRights(currentMesh), meshrights = GetMeshRights(currentMesh, userid);
if (meshrights == 0xFFFFFFFF) { if (meshrights == 0xFFFFFFFF) {
Q('p20fulladmin').checked = true; Q('p20fulladmin').checked = true;
} else { } else {
@ -7877,7 +7859,7 @@
} }
function p20validateAddMeshUserDialog() { function p20validateAddMeshUserDialog() {
var meshrights = currentMesh.links[userinfo._id].rights; var meshrights = GetMeshRights(currentMesh);
var ok = true; var ok = true;
if (Q('dp20username')) { if (Q('dp20username')) {
var xusers = Q('dp20username').value.split(','); var xusers = Q('dp20username').value.split(',');
@ -7964,7 +7946,7 @@
function p20viewuser(userid) { function p20viewuser(userid) {
if (xxdialogMode) return; if (xxdialogMode) return;
var xuserid = decodeURIComponent(userid); var xuserid = decodeURIComponent(userid);
var cmeshrights = currentMesh.links[userinfo._id].rights, meshrights = currentMesh.links[xuserid].rights; var cmeshrights = GetMeshRights(currentMesh), meshrights = GetMeshRights(currentMesh, xuserid);
if (((userinfo._id) != xuserid) && (cmeshrights == 0xFFFFFFFF || (((cmeshrights & 2) != 0) && (meshrights != 0xFFFFFFFF)))) { if (((userinfo._id) != xuserid) && (cmeshrights == 0xFFFFFFFF || (((cmeshrights & 2) != 0) && (meshrights != 0xFFFFFFFF)))) {
p20showAddMeshUserDialog(userid); p20showAddMeshUserDialog(userid);
} else { } else {
@ -10063,7 +10045,49 @@
if (pname == null) { Q('p43iframe').src = ''; } else { QH('p43title', title); Q('p43iframe').src = '/pluginadmin.ashx?pin=' + pname; go(43); } if (pname == null) { Q('p43iframe').src = ''; } else { QH('p43title', title); Q('p43iframe').src = '/pluginadmin.ashx?pin=' + pname; go(43); }
} }
//
// Access Control Functions
// These must match server
//
// Get the right of a user on a given device group
function GetMeshRights(mesh, user) {
if (mesh == null) { return 0; }
if (user == null) { user = userinfo._id; }
if (typeof mesh == 'string') { mesh = meshes[mesh] }
if ((mesh == null) || (mesh.links == null)) { return 0; }
var rights = mesh.links[user];
if (rights == null) { return 0; }
return rights.rights;
}
// Returns true if the user can view the given device group
function IsMeshViewable(mesh, user) {
if (mesh == null) { return 0; }
if (user == null) { user = userinfo._id; }
if (typeof mesh == 'string') { mesh = meshes[mesh] }
if ((mesh == null) || (mesh.links == null)) { return false; }
var rights = mesh.links[user];
if (rights == null) { return false; }
return true;
}
// Return the user rights for a given node
function GetNodeRights(node, user) {
if (node == null) { return 0; }
if (user == null) { user = userinfo._id; }
if (typeof node == 'string') { node = getNodeFromId(node); if (node == null) { return 0; } }
var mesh = meshes[node.meshid];
if ((mesh == null) || (mesh.links == null)) { return 0; }
var meshlinks = mesh.links[user];
if (meshlinks == null) { return 0; }
return meshlinks.rights;
}
//
// Generic methods // Generic methods
//
function joinPaths() { var x = []; for (var i in arguments) { var w = arguments[i]; if ((w != null) && (w != '')) { while (w.endsWith('/') || w.endsWith('\\')) { w = w.substring(0, w.length - 1); } while (w.startsWith('/') || w.startsWith('\\')) { w = w.substring(1); } x.push(w); } } return x.join('/'); } function joinPaths() { var x = []; for (var i in arguments) { var w = arguments[i]; if ((w != null) && (w != '')) { while (w.endsWith('/') || w.endsWith('\\')) { w = w.substring(0, w.length - 1); } while (w.startsWith('/') || w.startsWith('\\')) { w = w.substring(1); } x.push(w); } } return x.join('/'); }
function putstore(name, val) { function putstore(name, val) {
try { try {

View File

@ -2065,7 +2065,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
if ((splitpath.length < 3) || (splitpath[0] != 'user' && splitpath[0] != 'mesh') || (splitpath[1] != domain.id)) return null; // Basic validation if ((splitpath.length < 3) || (splitpath[0] != 'user' && splitpath[0] != 'mesh') || (splitpath[1] != domain.id)) return null; // Basic validation
var objid = splitpath[0] + '/' + splitpath[1] + '/' + splitpath[2]; var objid = splitpath[0] + '/' + splitpath[1] + '/' + splitpath[2];
if (splitpath[0] == 'user' && (objid != user._id)) return null; // User validation, only self allowed if (splitpath[0] == 'user' && (objid != user._id)) return null; // User validation, only self allowed
if (splitpath[0] == 'mesh') { var link = user.links[objid]; if ((link == null) || (link.rights == null) || ((link.rights & 32) == 0)) { return null; } } // Check mesh server file rights if (splitpath[0] == 'mesh') { if ((obj.GetMeshRights(user, objid) & 32) == 0) { return null; } } // Check mesh server file rights
if (splitpath[1] != '') { serverpath += '-' + splitpath[1]; } // Add the domain if needed if (splitpath[1] != '') { serverpath += '-' + splitpath[1]; } // Add the domain if needed
serverpath += ('/' + splitpath[0] + '-' + splitpath[2]); serverpath += ('/' + splitpath[0] + '-' + splitpath[2]);
for (var i = 3; i < splitpath.length; i++) { if (obj.common.IsFilenameValid(splitpath[i]) == true) { serverpath += '/' + splitpath[i]; filename = splitpath[i]; } else { return null; } } // Check that each folder is correct for (var i = 3; i < splitpath.length; i++) { if (obj.common.IsFilenameValid(splitpath[i]) == true) { serverpath += '/' + splitpath[i]; filename = splitpath[i]; } else { return null; } } // Check that each folder is correct
@ -2265,8 +2265,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
if (!node.intelamt) { console.log('ERR: Not AMT node'); try { ws.close(); } catch (e) { } return; } // Disconnect websocket if (!node.intelamt) { console.log('ERR: Not AMT node'); try { ws.close(); } catch (e) { } return; } // Disconnect websocket
// Check if this user has permission to manage this computer // Check if this user has permission to manage this computer
var meshlinks = user.links[node.meshid]; if ((obj.GetMeshRights(user, node.meshid) & MESHRIGHT_REMOTECONTROL) == 0) { console.log('ERR: Access denied (2)'); try { ws.close(); } catch (e) { } return; }
if ((!meshlinks) || (!meshlinks.rights) || ((meshlinks.rights & MESHRIGHT_REMOTECONTROL) == 0)) { console.log('ERR: Access denied (2)'); try { ws.close(); } catch (e) { } return; }
// Check what connectivity is available for this node // Check what connectivity is available for this node
var state = parent.GetConnectivityState(req.query.host); var state = parent.GetConnectivityState(req.query.host);
@ -2998,9 +2997,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
// If required, check if this user has rights to do this // If required, check if this user has rights to do this
if ((obj.parent.config.settings != null) && ((obj.parent.config.settings.lockagentdownload == true) || (domain.lockagentdownload == true))) { if ((obj.parent.config.settings != null) && ((obj.parent.config.settings.lockagentdownload == true) || (domain.lockagentdownload == true))) {
var user = obj.users[req.session.userid]; if ((domain.id != mesh.domain) || ((obj.GetMeshRights(req.session.userid, mesh) & 1) == 0)) { res.sendStatus(401); return; }
if ((user == null) || (mesh.links[user._id] == null) || ((mesh.links[user._id].rights & 1) == 0)) { res.sendStatus(401); return; }
if (domain.id != mesh.domain) { res.sendStatus(401); return; }
} }
var meshidhex = Buffer.from(req.query.meshid.replace(/\@/g, '+').replace(/\$/g, '/'), 'base64').toString('hex').toUpperCase(); var meshidhex = Buffer.from(req.query.meshid.replace(/\@/g, '+').replace(/\$/g, '/'), 'base64').toString('hex').toUpperCase();
@ -3168,9 +3165,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
// If required, check if this user has rights to do this // If required, check if this user has rights to do this
if ((obj.parent.config.settings != null) && ((obj.parent.config.settings.lockagentdownload == true) || (domain.lockagentdownload == true))) { if ((obj.parent.config.settings != null) && ((obj.parent.config.settings.lockagentdownload == true) || (domain.lockagentdownload == true))) {
var user = obj.users[req.session.userid]; if ((domain.id != mesh.domain) || ((obj.GetMeshRights(req.session.userid, mesh) & 1) == 0)) { res.sendStatus(401); return; }
if ((user == null) || (mesh.links[user._id] == null) || ((mesh.links[user._id].rights & 1) == 0)) { res.sendStatus(401); return; }
if (domain.id != mesh.domain) { res.sendStatus(401); return; }
} }
var meshidhex = Buffer.from(req.query.meshid.replace(/\@/g, '+').replace(/\$/g, '/'), 'base64').toString('hex').toUpperCase(); var meshidhex = Buffer.from(req.query.meshid.replace(/\@/g, '+').replace(/\$/g, '/'), 'base64').toString('hex').toUpperCase();
@ -3257,9 +3252,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
// If needed, check if this user has rights to do this // If needed, check if this user has rights to do this
if ((obj.parent.config.settings != null) && ((obj.parent.config.settings.lockagentdownload == true) || (domain.lockagentdownload == true))) { if ((obj.parent.config.settings != null) && ((obj.parent.config.settings.lockagentdownload == true) || (domain.lockagentdownload == true))) {
var user = obj.users[req.session.userid]; if ((domain.id != mesh.domain) || ((obj.GetMeshRights(req.session.userid, mesh) & 1) == 0)) { res.sendStatus(401); return; }
if ((user == null) || (mesh.links[user._id] == null) || ((mesh.links[user._id].rights & 1) == 0)) { res.sendStatus(401); return; }
if (domain.id != mesh.domain) { res.sendStatus(401); return; }
} }
var meshidhex = Buffer.from(req.query.id.replace(/\@/g, '+').replace(/\$/g, '/'), 'base64').toString('hex').toUpperCase(); var meshidhex = Buffer.from(req.query.id.replace(/\@/g, '+').replace(/\$/g, '/'), 'base64').toString('hex').toUpperCase();
@ -3297,9 +3290,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
var node = docs[0]; var node = docs[0];
// Check if we have right to this node // Check if we have right to this node
var rights = 0; if (obj.GetMeshRights(user, node.meshid) == 0) { res.sendStatus(401); return; }
for (var i in user.links) { if (i == node.meshid) { rights = user.links[i].rights; } }
if (rights == 0) { res.sendStatus(401); return; }
// Get the list of power events and send them // Get the list of power events and send them
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'text/csv', 'Content-Disposition': 'attachment; filename="powerevents.csv"' }); res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0', 'Content-Type': 'text/csv', 'Content-Disposition': 'attachment; filename="powerevents.csv"' });
@ -3772,8 +3763,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
if (agent == null) return; if (agent == null) return;
// Check we have agent rights // Check we have agent rights
var rights = user.links[agent.dbMeshKey].rights; if (((obj.GetMeshRights(user, agent.dbMeshKey) & MESHRIGHT_AGENTCONSOLE) != 0) || (user.siteadmin == 0xFFFFFFFF)) { agent.close(disconnectMode); }
if ((rights != null) && ((rights & MESHRIGHT_AGENTCONSOLE) != 0) || (user.siteadmin == 0xFFFFFFFF)) { agent.close(disconnectMode); }
}; };
// Send the core module to the mesh agent // Send the core module to the mesh agent
@ -3787,8 +3777,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
if (agent == null) return; if (agent == null) return;
// Check we have agent rights // Check we have agent rights
var rights = user.links[agent.dbMeshKey].rights; if (((obj.GetMeshRights(user, agent.dbMeshKey) & MESHRIGHT_AGENTCONSOLE) != 0) || (user.siteadmin == 0xFFFFFFFF)) {
if ((rights != null) && ((rights & MESHRIGHT_AGENTCONSOLE) != 0) || (user.siteadmin == 0xFFFFFFFF)) {
if (coretype == 'clear') { if (coretype == 'clear') {
// Clear the mesh agent core // Clear the mesh agent core
agent.agentCoreCheck = 1000; // Tell the agent object we are using a custom core. agent.agentCoreCheck = 1000; // Tell the agent object we are using a custom core.
@ -3907,6 +3896,32 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
} }
}; };
//
// Access Control Functions
//
// Return the node and rights for a given nodeid
obj.GetNodeWithRights = function (domain, user, nodeid, func) {
// Perform user pre-validation
if ((user == null) || (nodeid == null)) { func(null, 0, false); return; } // Invalid user
if (typeof user == 'string') { user = obj.users[user]; }
if ((user == null) || (user.links == null)) { func(null, 0, false); return; } // No rights
// Perform node pre-validation
if (obj.common.validateString(nodeid, 0, 128) == false) { func(null, 0, false); return; } // Invalid nodeid
const snode = nodeid.split('/');
if ((snode.length != 3) || (snode[0] != 'node')) { func(null, 0, false); return; } // Invalid nodeid
if ((domain != null) && (snode[1] != domain.id)) { func(null, 0, false); return; } // Invalid domain
// Check that we have permissions for this node.
db.Get(nodeid, function (err, nodes) {
if ((nodes == null) || (nodes.length != 1)) { func(null, 0, false); return; } // No such nodeid
var rights = user.links[nodes[0].meshid];
if (rights == null) { func(null, 0, false); return; } // No rights to this mesh
func(nodes[0], rights.rights, true);
});
}
// Returns a list of all meshes that this user has some rights too // Returns a list of all meshes that this user has some rights too
obj.GetAllMeshWithRights = function (user, rights) { obj.GetAllMeshWithRights = function (user, rights) {
if (typeof user == 'string') { user = obj.users[user]; } if (typeof user == 'string') { user = obj.users[user]; }
@ -4076,9 +4091,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
if (typeof command.sessionid != 'string') return; if (typeof command.sessionid != 'string') return;
var splitsessionid = command.sessionid.split('/'); var splitsessionid = command.sessionid.split('/');
// Check that we are in the same domain and the user has rights over this node. // Check that we are in the same domain and the user has rights over this node.
if ((splitsessionid[0] == 'user') && (splitsessionid[1] == domainid)) { if ((splitsessionid.length == 4) && (splitsessionid[0] == 'user') && (splitsessionid[1] == domainid)) {
// Check if this user has rights to get this message // Check if this user has rights to get this message
//if (mesh.links[user._id] == null || ((mesh.links[user._id].rights & 16) == 0)) return; // TODO!!!!!!!!!!!!!!!!!!!!! if (obj.GetMeshRights(splitsessionid[0] + '/' + splitsessionid[1] + '/' + splitsessionid[2], meshid) == 0) return; // TODO: Check if this is ok
// See if the session is connected. If so, go ahead and send this message to the target node // See if the session is connected. If so, go ahead and send this message to the target node
var ws = obj.wssessions2[command.sessionid]; var ws = obj.wssessions2[command.sessionid];
@ -4101,7 +4116,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
// Check that we are in the same domain and the user has rights over this node. // Check that we are in the same domain and the user has rights over this node.
if ((splituserid[0] == 'user') && (splituserid[1] == domainid)) { if ((splituserid[0] == 'user') && (splituserid[1] == domainid)) {
// Check if this user has rights to get this message // Check if this user has rights to get this message
//if (mesh.links[user._id] == null || ((mesh.links[user._id].rights & 16) == 0)) return; // TODO!!!!!!!!!!!!!!!!!!!!! if (obj.GetMeshRights(command.userid, meshid) == 0) return; // TODO: Check if this is ok
// See if the session is connected // See if the session is connected
var sessions = obj.wssessions[command.userid]; var sessions = obj.wssessions[command.userid];
@ -4120,16 +4135,13 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
} else { // Route this command to the mesh } else { // Route this command to the mesh
command.nodeid = nodeid; command.nodeid = nodeid;
var cmdstr = JSON.stringify(command); var cmdstr = JSON.stringify(command);
for (var userid in obj.wssessions) { // Find all connected users for this mesh and send the message if (obj.GetMeshRights(userid, meshid) == 0) return; // TODO: Check if this is ok
var user = obj.users[userid];
if ((user != null) && (user.links != null)) { // Find all connected users for this mesh and send the message
var rights = user.links[meshid]; for (var userid in obj.wssessions) {
if (rights != null) { // TODO: Look at what rights are needed for message routing var xsessions = obj.wssessions[userid];
var xsessions = obj.wssessions[userid]; // Send the message to all users on this server
// Send the message to all users on this server for (i in xsessions) { try { xsessions[i].send(cmdstr); } catch (e) { } }
for (i in xsessions) { try { xsessions[i].send(cmdstr); } catch (e) { } }
}
}
} }
// Send the message to all users of other servers // Send the message to all users of other servers